From d073d7de53d1484010cb976914b36ab288dca819 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 1 Nov 2021 21:03:31 +0900 Subject: [PATCH 001/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20View=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 +- .../MountainListScene/MountainCell.swift | 76 +++++++++++++++++++ .../MountainListViewController.swift | 54 ++++++++++++- .../MountainListViewCoordinator.swift | 3 +- 4 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa/MountainListScene/MountainCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 199b0a0..1bc8492 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; + 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -52,6 +53,7 @@ 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -93,8 +95,9 @@ 5428FDB9272F8BD9002F9D40 /* MountainListScene */ = { isa = PBXGroup; children = ( - 54296950272FC3290070B362 /* MountainListViewController.swift */, 54296952272FC3530070B362 /* MountainListViewCoordinator.swift */, + 54296950272FC3290070B362 /* MountainListViewController.swift */, + 985EEF62272FDA98002413D9 /* MountainCell.swift */, ); path = MountainListScene; sourceTree = ""; @@ -270,6 +273,7 @@ 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, + 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift new file mode 100644 index 0000000..a951b1c --- /dev/null +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -0,0 +1,76 @@ +// +// MountainCell.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/01. +// + +import UIKit + +final class MountainCell: UITableViewCell { + + static let identifier = "MountainCell" + + private var name: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 17, weight: .bold) + return label + }() + + private var height: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 12, weight: .bold) + label.textColor = .systemGray2 + return label + }() + + private var location: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = UIFont.systemFont(ofSize: 12, weight: .light) + label.textColor = .systemGray2 + return label + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.name, self.height]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.spacing = 10 + stackView.distribution = .fillEqually + return stackView + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.configureView() + self.accessoryType = .disclosureIndicator + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configureView() { + self.addSubview(self.stackView) + let stackViewConstrain = [ + self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), + self.stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), + ] + NSLayoutConstraint.activate(stackViewConstrain) + + self.addSubview(self.location) + let locationConstrain = [ + self.location.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10), + self.location.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), + self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), + ] + NSLayoutConstraint.activate(locationConstrain) + } + + func update(mountain: Mountain) { + self.name.text = mountain.name + self.height.text = mountain.height + self.location.text = mountain.location + } +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 190adc9..8774d4b 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -8,13 +8,65 @@ import UIKit class MountainListViewController: UIViewController { + weak var coordinator: MountainListViewCoordinator? + private var tableView: UITableView = { + let tableView = UITableView() + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.register(MountainCell.self, forCellReuseIdentifier: MountainCell.identifier) + return tableView + }() + override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .yellow + self.configureTableView() + self.configureView() + } + + private func configureTableView() { + self.tableView.delegate = self + self.tableView.dataSource = self } + private func configureView() { + self.view.addSubview(self.tableView) + let tableViewConstrain = [ + self.tableView.topAnchor.constraint(equalTo: self.view.topAnchor), + self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + self.tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + ] + NSLayoutConstraint.activate(tableViewConstrain) + } +} +extension MountainListViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dummy.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = self.tableView.dequeueReusableCell(withIdentifier: MountainCell.identifier, for: indexPath) + as? MountainCell + else { + return UITableViewCell() + } + cell.update(mountain: dummy[indexPath.row]) + + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + self.tableView.deselectRow(at: indexPath, animated: true) + } +} +struct Mountain { + let name: String + let height: String + let location: String } + +let dummy = [Mountain(name: "백두산", height: "1000m", location: "북한"), + Mountain(name: "한라산", height: "2000m", location: "제주도")] diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 6a730e7..7ef649c 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -22,7 +22,8 @@ class MountainListViewCoordinator: Coordinator { func startPush() -> UINavigationController { let mountainListViewController = MountainListViewController() mountainListViewController.coordinator = self - navigationController.setViewControllers([mountainListViewController], animated: true) + self.navigationController.setViewControllers([mountainListViewController], animated: true) + self.navigationController.navigationBar.topItem?.title = "산 목록" return navigationController } From 59527dc56cfe43cf6c60e1a9065abb335459ae6d Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 1 Nov 2021 21:27:09 +0900 Subject: [PATCH 002/465] [Feat] Init RecordingView --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 + .../RecordingViewController+Extension.swift | 12 +++ .../RecordingViewController.swift | 88 ++++++++++++++++++- 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 199b0a0..c7723c1 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; + DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -52,6 +53,7 @@ 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -69,6 +71,7 @@ isa = PBXGroup; children = ( 54296948272FBFAB0070B362 /* RecordingViewController.swift */, + DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, ); path = RecordingScene; @@ -275,6 +278,7 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, + DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift new file mode 100644 index 0000000..ad44b68 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -0,0 +1,12 @@ +// +// RecordingViewController+Extension.swift +// SanTa +// +// Created by 김민창 on 2021/11/01. +// + +import UIKit + +extension RecordingViewController { + +} diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index ee3e178..647aff6 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -9,9 +9,95 @@ import UIKit class RecordingViewController: UIViewController { weak var coordinator: RecordingViewCoordinator? + + let kilometerLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .headline) + label.text = "0.00" + label.textColor = .white + return label + }() + + let kilometerTextLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .title3) + label.text = "킬로미터" + label.textColor = .white + return label + }() + + let timeLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "00:00 00\"" + label.textColor = .white + return label + }() + + let altitudeLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "0" + label.textColor = .white + return label + }() + + let walkLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "0" + label.textColor = .white + return label + }() + + let timeTextLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "시간" + label.textColor = .white + return label + }() + + let altitudeTextLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "고도" + label.textColor = .white + return label + }() + + let walkTextLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.text = "걸음" + label.textColor = .white + return label + }() + + + let calculateStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.spacing = 10 + stackView.distribution = .fillEqually + + return stackView + }() + + + let calculateTextStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.spacing = 10 + stackView.distribution = .fillEqually + + return stackView + }() override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .blue + self.configureViews() } } From 98979849bea0ba05715a518433842ec06393cdd7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 1 Nov 2021 22:03:05 +0900 Subject: [PATCH 003/465] =?UTF-8?q?[Feat]=20RecordingView=20Label=20Constr?= =?UTF-8?q?aints=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController+Extension.swift | 47 ++++++++++++++++++- .../RecordingViewController.swift | 31 +++++++++--- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index ad44b68..8a4ab8d 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -8,5 +8,50 @@ import UIKit extension RecordingViewController { - + func configureViews() { + self.view.backgroundColor = .systemBlue + + [self.timeLabel, self.altitudeLabel, self.walkLabel].forEach { + self.calculateStackView.addArrangedSubview($0) + } + + [self.timeTextLabel, self.altitudeTextLabel, self.walkTextLabel].forEach { + self.calculateTextStackView.addArrangedSubview($0) + } + + self.view.addSubview(kilometerLabel) + self.view.addSubview(kilometerTextLabel) + self.view.addSubview(calculateStackView) + self.view.addSubview(calculateTextStackView) + + let kilometerLabelConstraints = [ + self.kilometerLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 80), + self.kilometerLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width/2 + 30), + self.kilometerLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) + ] + + let kilometerTextLabelConstraints = [ + self.kilometerTextLabel.topAnchor.constraint(equalTo: self.kilometerLabel.bottomAnchor, constant: 16), + self.kilometerTextLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) + ] + + let calculateStackViewConstraints = [ + self.calculateStackView.topAnchor.constraint(equalTo: self.kilometerTextLabel.bottomAnchor, constant: 64), + self.calculateStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), + self.calculateStackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8), + self.calculateStackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8) + ] + + let calculateTextStackViewConstraints = [ + self.calculateTextStackView.topAnchor.constraint(equalTo: self.calculateStackView.bottomAnchor, constant: 8), + self.calculateTextStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), + self.calculateTextStackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8), + self.calculateTextStackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8) + ] + + NSLayoutConstraint.activate(kilometerLabelConstraints) + NSLayoutConstraint.activate(kilometerTextLabelConstraints) + NSLayoutConstraint.activate(calculateStackViewConstraints) + NSLayoutConstraint.activate(calculateTextStackViewConstraints) + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 647aff6..df5f5f7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -12,7 +12,10 @@ class RecordingViewController: UIViewController { let kilometerLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .headline) + label.font = .boldSystemFont(ofSize: 110) + label.translatesAutoresizingMaskIntoConstraints = false + label.adjustsFontSizeToFitWidth = true + label.textAlignment = .center label.text = "0.00" label.textColor = .white return label @@ -21,55 +24,69 @@ class RecordingViewController: UIViewController { let kilometerTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "킬로미터" + label.textAlignment = .center label.textColor = .white return label }() let timeLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title2) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "00:00 00\"" + label.textAlignment = .center label.textColor = .white return label }() let altitudeLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title2) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "0" + label.textAlignment = .center label.textColor = .white return label }() let walkLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title2) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "0" + label.textAlignment = .center label.textColor = .white return label }() let timeTextLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title3) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "시간" + label.textAlignment = .center label.textColor = .white return label }() let altitudeTextLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title3) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "고도" + label.textAlignment = .center label.textColor = .white return label }() let walkTextLabel: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title3) + label.translatesAutoresizingMaskIntoConstraints = false label.text = "걸음" + label.textAlignment = .center label.textColor = .white return label }() From 30fe6b9489db07bb3087e819aa62c2f4cf2abeb5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 1 Nov 2021 23:38:49 +0900 Subject: [PATCH 004/465] =?UTF-8?q?[Feat]=20RecordingView=20Button=20Const?= =?UTF-8?q?raints=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/SceneDelegate.swift | 8 ++- .../RecordingViewController+Extension.swift | 55 ++++++++++++++++++- .../RecordingViewController.swift | 19 ++++++- .../Base.lproj/LaunchScreen.storyboard | 17 ++++-- 4 files changed, 89 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 18e4a5e..7c14690 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,9 +14,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) - self.appCoordinator = AppCoordinator(window) - - appCoordinator?.start() + // self.appCoordinator = AppCoordinator(window) + // + // appCoordinator?.start() + self.window?.rootViewController = RecordingViewController() + self.window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index 8a4ab8d..39cadbe 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -8,7 +8,28 @@ import UIKit extension RecordingViewController { - func configureViews() { + func configureButton() { + [self.pauseButton, self.stopButton, self.locationButton].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.tintColor = .white + $0.layer.masksToBounds = true + $0.layer.cornerRadius = $0.frame.width/2 + } + + var pauseConfiguration = UIButton.Configuration.plain() + pauseConfiguration.image = UIImage(systemName: "pause.fill") + pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) + + self.pauseButton.backgroundColor = .black + self.pauseButton.configuration = pauseConfiguration + + self.stopButton.backgroundColor = .black + self.stopButton.setImage(UIImage(systemName: "stop.fill"), for: .normal) + self.locationButton.setImage(UIImage(systemName: "location.fill"), for: .normal) + } + + + func configureConstraints() { self.view.backgroundColor = .systemBlue [self.timeLabel, self.altitudeLabel, self.walkLabel].forEach { @@ -19,10 +40,15 @@ extension RecordingViewController { self.calculateTextStackView.addArrangedSubview($0) } + [self.stopButton, self.pauseButton, self.locationButton].forEach { + self.buttonStackView.addArrangedSubview($0) + } + self.view.addSubview(kilometerLabel) self.view.addSubview(kilometerTextLabel) self.view.addSubview(calculateStackView) self.view.addSubview(calculateTextStackView) + self.view.addSubview(buttonStackView) let kilometerLabelConstraints = [ self.kilometerLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 80), @@ -49,9 +75,36 @@ extension RecordingViewController { self.calculateTextStackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8) ] + let pauseButtonSizeConstraints = [ + self.pauseButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/4), + self.pauseButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/4) + ] + + let stopButtonSizeConstraints = [ + self.stopButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/6), + self.stopButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/6) + ] + + let locationButtonSizeConstraints = [ + self.locationButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/6), + self.locationButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/6) + ] + + NSLayoutConstraint.activate(pauseButtonSizeConstraints) + NSLayoutConstraint.activate(stopButtonSizeConstraints) + NSLayoutConstraint.activate(locationButtonSizeConstraints) + + let buttonStackViewConstraints = [ + self.buttonStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), + self.buttonStackView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -80) + ] + NSLayoutConstraint.activate(kilometerLabelConstraints) NSLayoutConstraint.activate(kilometerTextLabelConstraints) NSLayoutConstraint.activate(calculateStackViewConstraints) NSLayoutConstraint.activate(calculateTextStackViewConstraints) + NSLayoutConstraint.activate(buttonStackViewConstraints) + + self.view.layoutIfNeeded() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index df5f5f7..d48b6d4 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -112,9 +112,26 @@ class RecordingViewController: UIViewController { return stackView }() + + let pauseButton = UIButton() + let stopButton = UIButton() + let locationButton = UIButton() + + let buttonStackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.spacing = 18 + stackView.distribution = .fill + stackView.alignment = .center + return stackView + }() + override func viewDidLoad() { super.viewDidLoad() - self.configureViews() + + self.configureConstraints() + self.configureButton() } } diff --git a/SanTa/SanTa/Resources/Base.lproj/LaunchScreen.storyboard b/SanTa/SanTa/Resources/Base.lproj/LaunchScreen.storyboard index 865e932..95ebb54 100644 --- a/SanTa/SanTa/Resources/Base.lproj/LaunchScreen.storyboard +++ b/SanTa/SanTa/Resources/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,10 @@ - - + + + - + + @@ -11,10 +13,10 @@ - + - + @@ -22,4 +24,9 @@ + + + + + From 8807b43062db07c765abe9aa8c729885324c0317 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 1 Nov 2021 23:41:35 +0900 Subject: [PATCH 005/465] =?UTF-8?q?[Fix]=20SceneDelegate=20Root=20Window?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/SceneDelegate.swift | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 7c14690..18e4a5e 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,11 +14,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) - // self.appCoordinator = AppCoordinator(window) - // - // appCoordinator?.start() - self.window?.rootViewController = RecordingViewController() - self.window?.makeKeyAndVisible() + self.appCoordinator = AppCoordinator(window) + + appCoordinator?.start() } func sceneDidDisconnect(_ scene: UIScene) { From 03953b717865a09a291b760089b51f3f27713ae8 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 2 Nov 2021 11:03:07 +0900 Subject: [PATCH 006/465] =?UTF-8?q?[Feat]=20MapView=20Layout=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A7=88=EC=BB=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alert을 이용해 사용자로 부터 위치 정보를 활성화할 수 있게 권한을 획득한다. MapKit을 사용하여 화면에 지도를 표시한다. 위치 서비스가 꺼져 있다면 대한민국의 전체를 보여줄 수 있게 축척 및 위치를 조절한다. 위치 서비스가 켜져 있다면 현재 위치가 보이도록 축척 및 위치를 조절한다. MapKit 클러스터링 기능을 활용한다. 44x44 크기 이내에 존재하여 겹치는 마커들은 중간위치에 숫자로 표시한다. --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 ++ .../xcshareddata/xcschemes/SanTa.xcscheme | 86 +++++++++++++++++++ .../MapScene/ClusterAnnotationView.swift | 42 +++++++++ SanTa/SanTa/MapScene/MapViewController.swift | 76 +++++++++++++++- .../MapScene/MountainAnnotationView.swift | 29 +++++++ SanTa/SanTa/Resources/Info.plist | 4 + 6 files changed, 242 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme create mode 100644 SanTa/SanTa/MapScene/ClusterAnnotationView.swift create mode 100644 SanTa/SanTa/MapScene/MountainAnnotationView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 9ade598..0a3bda6 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -19,6 +19,8 @@ 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296952272FC3530070B362 /* MountainListViewCoordinator.swift */; }; 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296954272FC3EC0070B362 /* SettingsViewController.swift */; }; 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */; }; + 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695A273026B10070B362 /* MountainAnnotationView.swift */; }; + 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */; }; 54731B65272F84D300534097 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54731B64272F84D300534097 /* MapViewModel.swift */; }; 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851281272A6AD500407F28 /* AppDelegate.swift */; }; 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851283272A6AD500407F28 /* SceneDelegate.swift */; }; @@ -45,6 +47,8 @@ 54296952272FC3530070B362 /* MountainListViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewCoordinator.swift; sourceTree = ""; }; 54296954272FC3EC0070B362 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewCoordinator.swift; sourceTree = ""; }; + 5429695A273026B10070B362 /* MountainAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotationView.swift; sourceTree = ""; }; + 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterAnnotationView.swift; sourceTree = ""; }; 54731B64272F84D300534097 /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = ""; }; 5485127E272A6AD500407F28 /* SanTa.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SanTa.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54851281272A6AD500407F28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -145,6 +149,8 @@ 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */, 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */, 54296946272FBD4B0070B362 /* MapViewCoordinator.swift */, + 5429695A273026B10070B362 /* MountainAnnotationView.swift */, + 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */, ); path = MapScene; sourceTree = ""; @@ -277,6 +283,7 @@ files = ( 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, + 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, @@ -291,6 +298,7 @@ 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, + 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme new file mode 100644 index 0000000..2774787 --- /dev/null +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift new file mode 100644 index 0000000..582f529 --- /dev/null +++ b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift @@ -0,0 +1,42 @@ +// +// ClusterAnnotationView.swift +// SanTa +// +// Created by shin jae ung on 2021/11/01. +// + +import MapKit + +class ClusterAnnotationView: MKAnnotationView { + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + collisionMode = .circle + centerOffset = CGPoint(x: 0, y: -10) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForDisplay() { + super.prepareForDisplay() + + if let cluster = annotation as? MKClusterAnnotation { + let count = cluster.memberAnnotations.count + + image = UIGraphicsImageRenderer(size: CGSize(width: 40, height: 40)).image { _ in + UIColor.white.setFill() + UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 40, height: 40)).fill() + UIColor.blue.setFill() + UIBezierPath(ovalIn: CGRect(x: 5, y: 5, width: 30, height: 30)).fill() + + let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.white, + NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)] + let text = count > 99 ? "99+" : "\(count)" + let size = text.size(withAttributes: attributes) + let rect = CGRect(x: 20 - size.width / 2, y: 20 - size.height / 2, width: size.width, height: size.height) + text.draw(in: rect, withAttributes: attributes) + } + } + } +} diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 71063d4..efe7d33 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -4,15 +4,85 @@ // // Created by shin jae ung on 2021/10/28. // - -import UIKit +import MapKit class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? + private var mapView = MKMapView() + private var manager: CLLocationManager? override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .red + self.configureViews() + self.registerAnnotationView() + self.configureCoreLocationManager() + self.testCoordinates() + } + + private func configureViews() { + self.mapView = MKMapView(frame: view.bounds) + self.mapView.showsUserLocation = true + self.view.addSubview(self.mapView) + } + + private func registerAnnotationView() { + self.mapView.register( + MountainAnnotationView.self, + forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier + ) + self.mapView.register( + ClusterAnnotationView.self, + forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier + ) + } + + private func configureCoreLocationManager() { + self.manager = CLLocationManager() + self.manager?.requestWhenInUseAuthorization() + self.manager?.requestAlwaysAuthorization() + self.manager?.delegate = self + self.manager?.desiredAccuracy = kCLLocationAccuracyBest + self.manager?.startUpdatingLocation() + } + + private func render(_ location: CLLocation) { + let coordinate = CLLocationCoordinate2D( + latitude: location.coordinate.latitude, + longitude: location.coordinate.longitude + ) + let span = MKCoordinateSpan( + latitudeDelta: 0.01, + longitudeDelta: 0.01 + ) + let region = MKCoordinateRegion(center: coordinate, span: span) + self.mapView.setRegion(region, animated: true) + } + + private func testCoordinates() { + for _ in 0...200 { + let latitude = Double.random(in: 36.0..<37.0) + let longitude = -Double.random(in: 121.0..<122.0) + let pin = MKPointAnnotation() + pin.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + mapView.addAnnotation(pin) + } + } +} + +extension MapViewController: MKMapViewDelegate { + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + return MountainAnnotationView( + annotation: annotation, + reuseIdentifier: MountainAnnotationView.ReuseID + ) } } +extension MapViewController: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let location = locations.first { + manager.stopUpdatingLocation() + self.render(location) + } + } +} diff --git a/SanTa/SanTa/MapScene/MountainAnnotationView.swift b/SanTa/SanTa/MapScene/MountainAnnotationView.swift new file mode 100644 index 0000000..84b8a56 --- /dev/null +++ b/SanTa/SanTa/MapScene/MountainAnnotationView.swift @@ -0,0 +1,29 @@ +// +// MountainAnnotationView.swift +// SanTa +// +// Created by shin jae ung on 2021/11/01. +// + +import UIKit +import MapKit + +class MountainAnnotationView: MKMarkerAnnotationView { + static let ReuseID = "MountainAnnotation" + + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + clusteringIdentifier = "mountain" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForDisplay() { + super.prepareForDisplay() + displayPriority = .defaultHigh + markerTintColor = .blue + glyphImage = UIImage(systemName: "play.fill") + } +} diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index 0eb786d..c3c0992 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,6 +2,10 @@ + NSLocationWhenInUseUsageDescription + Please allow to see current location + NSLocationAlwaysAndWhenInUseUsageDescription + Please allow to use app on background UIApplicationSceneManifest UIApplicationSupportsMultipleScenes From a0fabd07b5733173be28854cb131ee027efea1ef Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 2 Nov 2021 15:27:04 +0900 Subject: [PATCH 007/465] =?UTF-8?q?[Refactor]=20RecordingViews=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController+Extension.swift | 25 ++++++++ .../RecordingViewController.swift | 61 ++----------------- 2 files changed, 30 insertions(+), 56 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index 39cadbe..fcc4b62 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -28,6 +28,31 @@ extension RecordingViewController { self.locationButton.setImage(UIImage(systemName: "location.fill"), for: .normal) } + func configureLabel() { + [self.kilometerLabel, self.kilometerTextLabel, self.timeLabel, self.timeLabel, self.altitudeLabel, self.walkLabel, self.timeTextLabel, self.altitudeTextLabel, self.walkTextLabel].forEach { + $0.textAlignment = .center + $0.textColor = .white + $0.translatesAutoresizingMaskIntoConstraints = false + } + } + + func configureStackView() { + [self.calculateStackView, self.calculateTextStackView, self.buttonStackView].forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .horizontal + } + + self.calculateStackView.spacing = 10 + self.calculateStackView.distribution = .fillEqually + + self.calculateTextStackView.spacing = 10 + self.calculateTextStackView.distribution = .fillEqually + + self.buttonStackView.spacing = 18 + self.buttonStackView.distribution = .fill + self.buttonStackView.alignment = .center + } + func configureConstraints() { self.view.backgroundColor = .systemBlue diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index d48b6d4..d0e70f1 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -13,124 +13,73 @@ class RecordingViewController: UIViewController { let kilometerLabel: UILabel = { let label = UILabel() label.font = .boldSystemFont(ofSize: 110) - label.translatesAutoresizingMaskIntoConstraints = false label.adjustsFontSizeToFitWidth = true - label.textAlignment = .center label.text = "0.00" - label.textColor = .white return label }() let kilometerTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "킬로미터" - label.textAlignment = .center - label.textColor = .white return label }() let timeLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "00:00 00\"" - label.textAlignment = .center - label.textColor = .white return label }() let altitudeLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "0" - label.textAlignment = .center - label.textColor = .white return label }() let walkLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "0" - label.textAlignment = .center - label.textColor = .white return label }() let timeTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "시간" - label.textAlignment = .center - label.textColor = .white return label }() let altitudeTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "고도" - label.textAlignment = .center - label.textColor = .white return label }() let walkTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) - label.translatesAutoresizingMaskIntoConstraints = false label.text = "걸음" - label.textAlignment = .center - label.textColor = .white return label }() - - let calculateStackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .horizontal - stackView.spacing = 10 - stackView.distribution = .fillEqually - - return stackView - }() - - - let calculateTextStackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .horizontal - stackView.spacing = 10 - stackView.distribution = .fillEqually - - return stackView - }() - let pauseButton = UIButton() let stopButton = UIButton() let locationButton = UIButton() - let buttonStackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .horizontal - stackView.spacing = 18 - stackView.distribution = .fill - stackView.alignment = .center - - return stackView - }() + let calculateStackView = UIStackView() + let calculateTextStackView = UIStackView() + let buttonStackView = UIStackView() override func viewDidLoad() { super.viewDidLoad() + self.configureLabel() + self.configureStackView() self.configureConstraints() self.configureButton() } From 191b2cf33c4dbbfdc812021ca0f562054484baac Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 2 Nov 2021 16:05:55 +0900 Subject: [PATCH 008/465] =?UTF-8?q?[Fix]=20=ED=81=B4=EB=9F=AC=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=A7=81=EC=9D=B4=20=EC=A0=81=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 37 ++++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index efe7d33..59c0dbe 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -9,7 +9,7 @@ import MapKit class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var mapView = MKMapView() - private var manager: CLLocationManager? + private var manager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() @@ -22,6 +22,7 @@ class MapViewController: UIViewController { private func configureViews() { self.mapView = MKMapView(frame: view.bounds) self.mapView.showsUserLocation = true + self.mapView.delegate = self self.view.addSubview(self.mapView) } @@ -37,12 +38,11 @@ class MapViewController: UIViewController { } private func configureCoreLocationManager() { - self.manager = CLLocationManager() - self.manager?.requestWhenInUseAuthorization() - self.manager?.requestAlwaysAuthorization() - self.manager?.delegate = self - self.manager?.desiredAccuracy = kCLLocationAccuracyBest - self.manager?.startUpdatingLocation() + self.manager.requestWhenInUseAuthorization() + self.manager.requestAlwaysAuthorization() + self.manager.delegate = self + self.manager.desiredAccuracy = kCLLocationAccuracyBest + self.manager.startUpdatingLocation() } private func render(_ location: CLLocation) { @@ -59,22 +59,25 @@ class MapViewController: UIViewController { } private func testCoordinates() { - for _ in 0...200 { + for _ in 0..<200 { let latitude = Double.random(in: 36.0..<37.0) let longitude = -Double.random(in: 121.0..<122.0) - let pin = MKPointAnnotation() - pin.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) - mapView.addAnnotation(pin) + let mountainAnnotaion = MountainAnnotaion() + mountainAnnotaion.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + self.mapView.addAnnotation(mountainAnnotaion) } } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - return MountainAnnotationView( - annotation: annotation, - reuseIdentifier: MountainAnnotationView.ReuseID - ) + if let _ = annotation as? MountainAnnotaion { + return MountainAnnotationView( + annotation: annotation, + reuseIdentifier: MountainAnnotationView.ReuseID + ) + } + return nil } } @@ -86,3 +89,7 @@ extension MapViewController: CLLocationManagerDelegate { } } } + +class MountainAnnotaion: NSObject, MKAnnotation { + var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) +} From ca0da64f20ae6da0952eef3782ab41d9f52b39cd Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 2 Nov 2021 16:41:36 +0900 Subject: [PATCH 009/465] =?UTF-8?q?[Feat]=20DispatchTimer=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 ++- SanTa/SanTa/Application/SceneDelegate.swift | 8 +-- .../SanTa/RecordingScene/RecordingTimer.swift | 50 +++++++++++++++++++ .../RecordingViewController.swift | 7 +++ 4 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 SanTa/SanTa/RecordingScene/RecordingTimer.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 0a3bda6..548e15c 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -31,7 +31,7 @@ 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - + DAB37D4C2731166B00EC523F /* RecordingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingTimer.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -61,7 +61,7 @@ 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - + DAB37D4B2731166B00EC523F /* RecordingTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTimer.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -81,6 +81,7 @@ 54296948272FBFAB0070B362 /* RecordingViewController.swift */, DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, + DAB37D4B2731166B00EC523F /* RecordingTimer.swift */, ); path = RecordingScene; sourceTree = ""; @@ -299,6 +300,7 @@ 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, + DAB37D4C2731166B00EC523F /* RecordingTimer.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 18e4a5e..da4d56c 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,9 +14,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) - self.appCoordinator = AppCoordinator(window) - - appCoordinator?.start() +// self.appCoordinator = AppCoordinator(window) +// +// appCoordinator?.start() + self.window?.rootViewController = RecordingViewController() + self.window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/SanTa/SanTa/RecordingScene/RecordingTimer.swift b/SanTa/SanTa/RecordingScene/RecordingTimer.swift new file mode 100644 index 0000000..080645c --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingTimer.swift @@ -0,0 +1,50 @@ +// +// RecordingTimer.swift +// SanTa +// +// Created by 김민창 on 2021/11/02. +// + +import Foundation + + +final class RecordingTimer { + var timer: DispatchSourceTimer? + + var currentTime = 0 { + didSet { + self.timerConverter() + } + } + + init() { + self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) + self.timer?.schedule(deadline: .now(), repeating: 1) + self.timer?.setEventHandler(handler: { [weak self] in + self?.currentTime += 1 + }) + + self.resume() + } + + private func timerConverter() { + let seconds = currentTime % 60 + let minutes = (currentTime / 60) % 60 + let hours = (currentTime / 3600) + + print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) + } + + func suspend() { + timer?.suspend() + } + + func resume() { + timer?.resume() + } + + func cancel() { + timer?.cancel() + timer = nil + } +} diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index d0e70f1..8c5b808 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -75,6 +75,8 @@ class RecordingViewController: UIViewController { let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() + var timer: RecordingTimer? + override func viewDidLoad() { super.viewDidLoad() @@ -82,5 +84,10 @@ class RecordingViewController: UIViewController { self.configureStackView() self.configureConstraints() self.configureButton() + self.configure() + } + + private func configure() { + timer = RecordingTimer() } } From 30b6740f7e7c4454cb58026d47ca1bc4bb1a4d2a Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 2 Nov 2021 17:33:06 +0900 Subject: [PATCH 010/465] =?UTF-8?q?[Feat]=20CoreLocation=20=EA=B2=BD?= =?UTF-8?q?=EB=8F=84,=20=EC=9C=84=EB=8F=84,=20=EA=B3=A0=EB=8F=84=20Delegat?= =?UTF-8?q?e=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 +- .../SanTa/RecordingScene/RecordingTimer.swift | 50 ------------ .../RecordingViewController.swift | 4 +- .../RecordingScene/RecordingViewModel.swift | 79 +++++++++++++++++++ 4 files changed, 85 insertions(+), 56 deletions(-) delete mode 100644 SanTa/SanTa/RecordingScene/RecordingTimer.swift create mode 100644 SanTa/SanTa/RecordingScene/RecordingViewModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 548e15c..781e1c8 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -31,7 +31,7 @@ 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - DAB37D4C2731166B00EC523F /* RecordingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingTimer.swift */; }; + DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -61,7 +61,7 @@ 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - DAB37D4B2731166B00EC523F /* RecordingTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTimer.swift; sourceTree = ""; }; + DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -81,7 +81,7 @@ 54296948272FBFAB0070B362 /* RecordingViewController.swift */, DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, - DAB37D4B2731166B00EC523F /* RecordingTimer.swift */, + DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, ); path = RecordingScene; sourceTree = ""; @@ -300,7 +300,7 @@ 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, - DAB37D4C2731166B00EC523F /* RecordingTimer.swift in Sources */, + DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/RecordingTimer.swift b/SanTa/SanTa/RecordingScene/RecordingTimer.swift deleted file mode 100644 index 080645c..0000000 --- a/SanTa/SanTa/RecordingScene/RecordingTimer.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// RecordingTimer.swift -// SanTa -// -// Created by 김민창 on 2021/11/02. -// - -import Foundation - - -final class RecordingTimer { - var timer: DispatchSourceTimer? - - var currentTime = 0 { - didSet { - self.timerConverter() - } - } - - init() { - self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) - self.timer?.schedule(deadline: .now(), repeating: 1) - self.timer?.setEventHandler(handler: { [weak self] in - self?.currentTime += 1 - }) - - self.resume() - } - - private func timerConverter() { - let seconds = currentTime % 60 - let minutes = (currentTime / 60) % 60 - let hours = (currentTime / 3600) - - print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) - } - - func suspend() { - timer?.suspend() - } - - func resume() { - timer?.resume() - } - - func cancel() { - timer?.cancel() - timer = nil - } -} diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 8c5b808..b8900f2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -75,7 +75,7 @@ class RecordingViewController: UIViewController { let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() - var timer: RecordingTimer? + var timer: RecordingViewModel? override func viewDidLoad() { super.viewDidLoad() @@ -88,6 +88,6 @@ class RecordingViewController: UIViewController { } private func configure() { - timer = RecordingTimer() + timer = RecordingViewModel() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift new file mode 100644 index 0000000..9d767e8 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -0,0 +1,79 @@ +// +// RecordingTimer.swift +// SanTa +// +// Created by 김민창 on 2021/11/02. +// + +import Foundation +import CoreLocation +import Combine + +class RecordingViewModel: NSObject { + private var locationManager = CLLocationManager() + private var timer: DispatchSourceTimer? + + private var currentTime = 0 { + didSet { + self.timeConverter() + } + } + + override init() { + super.init() + self.configureTimer() + self.configureLocationManager() + } + + private func configureTimer() { + self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) + self.timer?.schedule(deadline: .now(), repeating: 1) + self.timer?.setEventHandler(handler: { [weak self] in + self?.currentTime += 1 + }) + + self.resume() + } + + private func configureLocationManager() { + locationManager.requestWhenInUseAuthorization() + locationManager.startUpdatingLocation() + locationManager.delegate = self + } + + private func timeConverter() { + let seconds = currentTime % 60 + let minutes = (currentTime / 60) % 60 + let hours = (currentTime / 3600) + + print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) + } + + func suspend() { + timer?.suspend() + } + + func resume() { + timer?.resume() + } + + func cancel() { + timer?.cancel() + timer = nil + } +} + +extension RecordingViewModel: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let lastLocation = locations.last { + print("위도: \(lastLocation.coordinate.latitude)") + print("경도: \(lastLocation.coordinate.longitude)") + print("고도: \(lastLocation.altitude)") + } + } + + func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { + // GPS를 켜지 않았을 경우 + print(error) + } +} From 16e9cca739b3c99bed45f3feec0f406467e19dcc Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 2 Nov 2021 21:49:48 +0900 Subject: [PATCH 011/465] =?UTF-8?q?[Feat]=20CoreMotion=20StepCount,=20Dist?= =?UTF-8?q?ance=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingViewModel.swift | 23 ++++++++++++++++--- SanTa/SanTa/Resources/Info.plist | 2 ++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 9d767e8..5a23a82 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -7,20 +7,25 @@ import Foundation import CoreLocation +import CoreMotion import Combine class RecordingViewModel: NSObject { + private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? + private var date: Date? private var currentTime = 0 { didSet { self.timeConverter() + self.checkPedoMeter() } } override init() { super.init() + self.date = Date() self.configureTimer() self.configureLocationManager() } @@ -36,9 +41,9 @@ class RecordingViewModel: NSObject { } private func configureLocationManager() { - locationManager.requestWhenInUseAuthorization() - locationManager.startUpdatingLocation() - locationManager.delegate = self + self.locationManager.requestWhenInUseAuthorization() + self.locationManager.startUpdatingLocation() + self.locationManager.delegate = self } private func timeConverter() { @@ -49,6 +54,18 @@ class RecordingViewModel: NSObject { print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) } + private func checkPedoMeter() { + guard let date = self.date else { return } + + pedoMeter.queryPedometerData(from: date, to: Date()) { data, error in + guard let activityData = data, + error == nil else { return } + + print("Steps: \(activityData.numberOfSteps)") + print("Distance \(activityData.distance)") + } + } + func suspend() { timer?.suspend() } diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index c3c0992..24dc5da 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,6 +2,8 @@ + NSMotionUsageDescription + Allow my app to access motion usage. NSLocationWhenInUseUsageDescription Please allow to see current location NSLocationAlwaysAndWhenInUseUsageDescription From a9b8bb8e7193e590861117a03ef25cb7b3f16954 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 2 Nov 2021 21:50:56 +0900 Subject: [PATCH 012/465] [Fix] SceneDelegate Fix --- SanTa/SanTa/Application/SceneDelegate.swift | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index da4d56c..18e4a5e 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,11 +14,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) -// self.appCoordinator = AppCoordinator(window) -// -// appCoordinator?.start() - self.window?.rootViewController = RecordingViewController() - self.window?.makeKeyAndVisible() + self.appCoordinator = AppCoordinator(window) + + appCoordinator?.start() } func sceneDidDisconnect(_ scene: UIScene) { From 6ae5b6e2abd417e524a1ce96d9a83eb8f65e924c Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 2 Nov 2021 21:27:52 +0900 Subject: [PATCH 013/465] =?UTF-8?q?[Feat]=20=EB=B9=84=ED=96=89=EA=B8=B0=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC,=20=EC=B6=95=EC=B2=99,=20=EB=82=98=EC=B9=A8?= =?UTF-8?q?=EB=B0=98=20=ED=91=9C=EC=8B=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 51 +++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 59c0dbe..9f8a636 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -9,7 +9,9 @@ import MapKit class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var mapView = MKMapView() + private var startButton = UIButton() private var manager = CLLocationManager() + private var userTrackingButton = MKUserTrackingButton() override func viewDidLoad() { super.viewDidLoad() @@ -21,9 +23,49 @@ class MapViewController: UIViewController { private func configureViews() { self.mapView = MKMapView(frame: view.bounds) + self.view.addSubview(self.mapView) self.mapView.showsUserLocation = true + self.mapView.showsScale = true + self.mapView.showsCompass = true self.mapView.delegate = self - self.view.addSubview(self.mapView) + + self.view.addSubview(self.startButton) + self.startButton.backgroundColor = .blue + self.startButton.translatesAutoresizingMaskIntoConstraints = false + self.startButton.setTitle("시작", for: .normal) + self.startButton.setTitleColor(.white, for: .normal) + self.startButton.titleLabel?.font = .boldSystemFont(ofSize: 25) + self.startButton.layer.cornerRadius = 50 + self.startButton.layer.shadowColor = UIColor.gray.cgColor + self.startButton.layer.shadowOpacity = 1 + self.startButton.layer.shadowRadius = 3 + self.startButton.layer.shadowOffset = CGSize(width: 0, height: 3) + + let startButtonConstraints = [ + self.startButton.widthAnchor.constraint(equalToConstant: 100), + self.startButton.heightAnchor.constraint(equalToConstant: 100), + self.startButton.bottomAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: -150), + self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) + ] + NSLayoutConstraint.activate(startButtonConstraints) + + self.userTrackingButton = .init(mapView: mapView) + self.view.addSubview(self.userTrackingButton) + self.userTrackingButton.isHidden = true + self.userTrackingButton.backgroundColor = .white + self.userTrackingButton.translatesAutoresizingMaskIntoConstraints = false + self.userTrackingButton.layer.cornerRadius = 10 + self.userTrackingButton.clipsToBounds = true + let userTrackingButtonConstraints = [ + self.userTrackingButton.widthAnchor.constraint(equalToConstant: 50), + self.userTrackingButton.heightAnchor.constraint(equalToConstant: 50), + self.userTrackingButton.leftAnchor.constraint( + equalTo: self.mapView.rightAnchor, + constant: -100 + ), + self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) + ] + NSLayoutConstraint.activate(userTrackingButtonConstraints) } private func registerAnnotationView() { @@ -88,6 +130,13 @@ extension MapViewController: CLLocationManagerDelegate { self.render(location) } } + + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + if manager.authorizationStatus == .authorizedWhenInUse || + manager.authorizationStatus == .authorizedAlways { + userTrackingButton.isHidden = false + } + } } class MountainAnnotaion: NSObject, MKAnnotation { From 5a509d9d7e938ebedad745fdae64fbd9ed491904 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 2 Nov 2021 12:01:45 +0900 Subject: [PATCH 014/465] =?UTF-8?q?[Feat]=20=EB=AA=A8=EB=93=A0=20=EC=85=80?= =?UTF-8?q?=20UISwitch=20=ED=8F=AC=ED=95=A8=ED=95=98=EC=97=AC=20View=20?= =?UTF-8?q?=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 +- .../MountainListViewController.swift | 1 - SanTa/SanTa/SettingsScene/SettingsCell.swift | 65 +++++++ .../SettingsViewController.swift | 168 +++++++++++++++++- 4 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa/SettingsScene/SettingsCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 0a3bda6..43790c8 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; + 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* SettingsCell.swift */; }; /* End PBXBuildFile section */ @@ -61,6 +62,7 @@ 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; + 985EEF64273010BD002413D9 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -121,8 +123,9 @@ 5428FDBB272F8C32002F9D40 /* SettingsScene */ = { isa = PBXGroup; children = ( - 54296954272FC3EC0070B362 /* SettingsViewController.swift */, 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */, + 54296954272FC3EC0070B362 /* SettingsViewController.swift */, + 985EEF64273010BD002413D9 /* SettingsCell.swift */, ); path = SettingsScene; sourceTree = ""; @@ -297,6 +300,7 @@ 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, + 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 8774d4b..b3149e3 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -53,7 +53,6 @@ extension MountainListViewController: UITableViewDelegate, UITableViewDataSource return UITableViewCell() } cell.update(mountain: dummy[indexPath.row]) - return cell } diff --git a/SanTa/SanTa/SettingsScene/SettingsCell.swift b/SanTa/SanTa/SettingsScene/SettingsCell.swift new file mode 100644 index 0000000..72e590f --- /dev/null +++ b/SanTa/SanTa/SettingsScene/SettingsCell.swift @@ -0,0 +1,65 @@ +// +// SettingsCell.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/01. +// + +import UIKit + +class SettingsCell: UITableViewCell { + + static let identifier = "SettingsCell" + + private var title: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 17) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private var controlSwitch: UISwitch = { + let controlSwitch = UISwitch() + controlSwitch.translatesAutoresizingMaskIntoConstraints = false + controlSwitch.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) + return controlSwitch + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.selectionStyle = .none + self.configureView() + + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc func onClickSwitch(sender: UISwitch) { + print(title.text!, controlSwitch.isOn) + } + + func configureView() { + self.contentView.addSubview(self.title) + let locationConstrain = [ + self.title.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10), + self.title.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + ] + NSLayoutConstraint.activate(locationConstrain) + + self.contentView.addSubview(self.controlSwitch) + let switchConstrain = [ + self.controlSwitch.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10), + self.controlSwitch.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), + ] + NSLayoutConstraint.activate(switchConstrain) + } + + func update(option: Option) { + self.title.text = option.text + self.controlSwitch.isOn = option.check + } +} + + diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 5350520..582f194 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -9,10 +9,176 @@ import UIKit class SettingsViewController: UIViewController { weak var coordinator: SettingsViewCoordinator? + + private var headerView: UIView = { + let headerView = UIView() + headerView.translatesAutoresizingMaskIntoConstraints = false + headerView.backgroundColor = .white + return headerView + }() + + private var headerTitle: UILabel = { + let headerTitle = UILabel() + headerTitle.translatesAutoresizingMaskIntoConstraints = false + headerTitle.text = "설정" + headerTitle.font = UIFont.systemFont(ofSize: 20, weight: .bold) + return headerTitle + }() + private var tableView: UITableView = { + let tableView = UITableView() + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.register(SettingsCell.self, forCellReuseIdentifier: SettingsCell.identifier) + return tableView + }() + override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .brown + self.configureTableView() + self.configureView() + } + + private func configureTableView() { + self.tableView.dataSource = self + self.tableView.delegate = self + self.tableView.backgroundColor = .systemGray5 + } + + private func configureView() { + self.view.backgroundColor = .white + self.view.addSubview(self.headerView) + let headerViewConstrain = [ + self.headerView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), + self.headerView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.headerView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.headerView.heightAnchor.constraint(equalToConstant: 50.0), + ] + NSLayoutConstraint.activate(headerViewConstrain) + + self.headerView.addSubview(self.headerTitle) + let headerTitleConstrain = [ + self.headerTitle.centerXAnchor.constraint(equalTo: self.headerView.centerXAnchor), + self.headerTitle.centerYAnchor.constraint(equalTo: self.headerView.centerYAnchor), + ] + NSLayoutConstraint.activate(headerTitleConstrain) + + self.view.addSubview(self.tableView) + let tableViewConstrain = [ + self.tableView.topAnchor.constraint(equalTo: self.headerView.bottomAnchor), + self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + self.tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + ] + NSLayoutConstraint.activate(tableViewConstrain) + } +} + +extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { + + func numberOfSections(in tableView: UITableView) -> Int { + return 4 + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 10.0 + } + + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return " " + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == 0 { + return settings.photoSettings.count + } else if section == 1 { + return settings.autoSettins.count + } else if section == 2 { + return settings.voiceSettings.count + } else { + return settings.mapSettings.count + } + } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = self.tableView.dequeueReusableCell(withIdentifier: SettingsCell.identifier, for: indexPath) + as? SettingsCell + else { + return UITableViewCell() + } + if indexPath.section == 0 { + cell.update(option: settings.photoSettings[indexPath.row]) + } else if indexPath.section == 1 { + cell.update(option: settings.autoSettins[indexPath.row]) + } else if indexPath.section == 2 { + cell.update(option: settings.voiceSettings[indexPath.row]) + } else { + cell.update(option: settings.mapSettings[indexPath.row]) + } + return cell } } + +struct Option { + let text: String + let check: Bool +} + +struct Settings { + let photoSettings: [Option] + let autoSettins: [Option] + let voiceSettings: [Option] + let mapSettings: [Option] +} + +let photoSettings1 = Option(text: "사진 기록하기", check: true) +let photoSettings2 = Option(text: "지도에 사진표시", check: true) + +let autoSettins1 = Option(text: "자동 일시정지/재시작", check: false) +let autoSettins2 = Option(text: "자동 일시정지/재시작 음성 안내", check: false) + +let voiceSettings1 = Option(text: "1킬로미터 마다 음성 안내", check: true) + +let mapSetting1 = Option(text: "지도 형식", check: true) +let mapSetting2 = Option(text: "지도에 등산로 표시", check: true) + +let settings = Settings(photoSettings: [photoSettings1, photoSettings2], + autoSettins: [autoSettins1, autoSettins2], + voiceSettings: [voiceSettings1], + mapSettings: [mapSetting1, mapSetting2]) + +//protocol OptionKey { +// var text: String { get } +//} +// +//struct ToggleOption: OptionKey { +// let text: String +// let check: Bool +//} + +//struct ListOption: OptionKey { +// let text: String +// let list: [String] +//} +// +//struct Settings { +// let photoSettings: [OptionKey] +// let autoSettins: [OptionKey] +// let voiceSettings: [OptionKey] +// let mapSettings: [OptionKey] +//} +// +//let photoSettings1 = ToggleOption(text: "사진 기록하기", check: true) +//let photoSettings2 = ToggleOption(text: "지도에 사진표시", check: true) +// +//let autoSettins1 = ToggleOption(text: "자동 일시정지/재시작", check: false) +//let autoSettins2 = ToggleOption(text: "자동 일시정지/재시작 음성 안내", check: false) +// +//let voiceSettings1 = ToggleOption(text: "1킬로미터 마다 음성 안내", check: true) +// +//let mapSetting1 = ListOption(text: "지도 형식", list: ["정보지도, 일반지도, 위성지도"]) +//let mapSetting2 = ToggleOption(text: "지도에 등산로 표시", check: true) +// +//let settings = Settings(photoSettings: [photoSettings1, photoSettings2], +// autoSettins: [autoSettins1, autoSettins2], +// voiceSettings: [voiceSettings1], +// mapSettings: [mapSetting1, mapSetting2]) From b35b7280d3a36a08731b314a141cbef4ba56fb10 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 2 Nov 2021 14:19:11 +0900 Subject: [PATCH 015/465] =?UTF-8?q?[Fix]=20ToggleOptionCell=20constrait=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 23 +++++++++++++++++++ ...tingsCell.swift => ToggleOptionCell.swift} | 14 +++++------ 2 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 SanTa/SanTa/SettingsScene/MapOptionCell.swift rename SanTa/SanTa/SettingsScene/{SettingsCell.swift => ToggleOptionCell.swift} (79%) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift new file mode 100644 index 0000000..3402079 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -0,0 +1,23 @@ +// +// MapOptionCell.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/02. +// + +import UIKit + +class MapOptionCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/SanTa/SanTa/SettingsScene/SettingsCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift similarity index 79% rename from SanTa/SanTa/SettingsScene/SettingsCell.swift rename to SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 72e590f..46bd18a 100644 --- a/SanTa/SanTa/SettingsScene/SettingsCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -7,9 +7,9 @@ import UIKit -class SettingsCell: UITableViewCell { +class ToggleOptionCell: UITableViewCell { - static let identifier = "SettingsCell" + static let identifier = "ToggleOptionCell" private var title: UILabel = { let label = UILabel() @@ -37,28 +37,28 @@ class SettingsCell: UITableViewCell { } @objc func onClickSwitch(sender: UISwitch) { - print(title.text!, controlSwitch.isOn) + } func configureView() { self.contentView.addSubview(self.title) let locationConstrain = [ - self.title.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10), + self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), self.title.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), ] NSLayoutConstraint.activate(locationConstrain) self.contentView.addSubview(self.controlSwitch) let switchConstrain = [ - self.controlSwitch.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10), + self.controlSwitch.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), self.controlSwitch.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), ] NSLayoutConstraint.activate(switchConstrain) } - func update(option: Option) { + func update(option: ToggleOption) { self.title.text = option.text - self.controlSwitch.isOn = option.check + self.controlSwitch.isOn = option.toggle } } From aaf4b50558eeb643c4f09115dac7f2cf06ad3212 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 2 Nov 2021 21:39:43 +0900 Subject: [PATCH 016/465] =?UTF-8?q?[Feat]=20=EC=84=A4=EC=A0=95=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=A7=80=EB=8F=84=20=ED=98=95=EC=8B=9DCell=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84,=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EB=B7=B0?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 15 +- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 57 ++++++- SanTa/SanTa/SettingsScene/PaddingLabel.swift | 34 ++++ .../SettingsViewController.swift | 156 +++++++++--------- .../SettingsScene/ToggleOptionCell.swift | 14 +- 5 files changed, 183 insertions(+), 93 deletions(-) create mode 100644 SanTa/SanTa/SettingsScene/PaddingLabel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 43790c8..09d1b74 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -32,7 +32,9 @@ 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* SettingsCell.swift */; }; - + 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; + 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; + 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -63,6 +65,9 @@ 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; 985EEF64273010BD002413D9 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; + 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; + 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; + 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -125,7 +130,9 @@ children = ( 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */, 54296954272FC3EC0070B362 /* SettingsViewController.swift */, - 985EEF64273010BD002413D9 /* SettingsCell.swift */, + 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */, + 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */, + 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, ); path = SettingsScene; sourceTree = ""; @@ -285,6 +292,7 @@ buildActionMask = 2147483647; files = ( 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, + 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, @@ -295,12 +303,13 @@ 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, + 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, - 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */, + 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 3402079..6c161e2 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -8,16 +8,55 @@ import UIKit class MapOptionCell: UITableViewCell { - - override func awakeFromNib() { - super.awakeFromNib() - // Initialization code + + static let identifier = "MapOptionCell" + + private(set) var title: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 17) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private var map: UILabel = { + let label = PaddingLabel() + label.padding(top: 5, bottom: 5, left: 10, right: 10) + label.font = UIFont.systemFont(ofSize: 12) + label.textColor = .white + label.backgroundColor = .darkGray + label.translatesAutoresizingMaskIntoConstraints = false + label.clipsToBounds = true + label.layer.cornerRadius = 5 + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.configureView() } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - - // Configure the view for the selected state + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } + private func configureView() { + self.contentView.addSubview(self.title) + let locationConstrain = [ + self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), + self.title.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + ] + NSLayoutConstraint.activate(locationConstrain) + + self.contentView.addSubview(self.map) + let mapConstrain = [ + self.map.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), + self.map.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), + ] + NSLayoutConstraint.activate(mapConstrain) + } + + func update(option: MapOption) { + self.title.text = option.text + self.map.text = option.map.description + } } diff --git a/SanTa/SanTa/SettingsScene/PaddingLabel.swift b/SanTa/SanTa/SettingsScene/PaddingLabel.swift new file mode 100644 index 0000000..7304f09 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/PaddingLabel.swift @@ -0,0 +1,34 @@ +// +// PaddingLabel.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/02. +// 참고: https://gist.github.com/konnnn/d43af3bd525bb4c58f5c29fb14575b0d + +import UIKit + +class PaddingLabel: UILabel { + + var insets = UIEdgeInsets.zero + + override func drawText(in rect: CGRect) { + super.drawText(in: rect.inset(by: self.insets)) + } + + override var intrinsicContentSize: CGSize { + get { + var contentSize = super.intrinsicContentSize + contentSize.height += self.insets.top + self.insets.bottom + contentSize.width += self.insets.left + self.insets.right + return contentSize + } + } + + func padding(top: CGFloat, bottom: CGFloat, left: CGFloat, right: CGFloat) { + self.frame = CGRect(x: 0, + y: 0, + width: self.frame.width + left + right, + height: self.frame.height + top + bottom) + self.insets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right) + } +} diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 582f194..5a19b8b 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -28,7 +28,8 @@ class SettingsViewController: UIViewController { private var tableView: UITableView = { let tableView = UITableView() tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.register(SettingsCell.self, forCellReuseIdentifier: SettingsCell.identifier) + tableView.register(ToggleOptionCell.self, forCellReuseIdentifier: ToggleOptionCell.identifier) + tableView.register(MapOptionCell.self, forCellReuseIdentifier: MapOptionCell.identifier) return tableView }() @@ -71,6 +72,17 @@ class SettingsViewController: UIViewController { ] NSLayoutConstraint.activate(tableViewConstrain) } + + private func showMapActionSheet(cellTitle: String) { + let alert = UIAlertController(title: "지도형식", message: nil, preferredStyle: .actionSheet) + Map.allCases.forEach { + alert.addAction(UIAlertAction(title: $0.description, style: .default, handler: { action in + print(cellTitle, action.title!) + })) + } + alert.addAction(UIAlertAction(title: "닫기", style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + } } extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { @@ -88,97 +100,85 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if section == 0 { - return settings.photoSettings.count - } else if section == 1 { - return settings.autoSettins.count - } else if section == 2 { - return settings.voiceSettings.count - } else { - return settings.mapSettings.count - } + return settings[section].count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = self.tableView.dequeueReusableCell(withIdentifier: SettingsCell.identifier, for: indexPath) - as? SettingsCell - else { + switch settings[indexPath.section][indexPath.item] { + case let option as ToggleOption: + guard let cell = self.tableView.dequeueReusableCell(withIdentifier: ToggleOptionCell.identifier, + for: indexPath) as? ToggleOptionCell + else { + return UITableViewCell() + } + cell.update(option: option) + cell.delegate = self + return cell + case let option as MapOption: + guard let cell = self.tableView.dequeueReusableCell(withIdentifier: MapOptionCell.identifier, + for: indexPath) as? MapOptionCell + else { + return UITableViewCell() + } + cell.update(option: option) + return cell + default: return UITableViewCell() } - if indexPath.section == 0 { - cell.update(option: settings.photoSettings[indexPath.row]) - } else if indexPath.section == 1 { - cell.update(option: settings.autoSettins[indexPath.row]) - } else if indexPath.section == 2 { - cell.update(option: settings.voiceSettings[indexPath.row]) - } else { - cell.update(option: settings.mapSettings[indexPath.row]) - } - return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let cell = tableView.cellForRow(at: indexPath) as? MapOptionCell else { return } + guard let title = cell.title.text else { return } + self.showMapActionSheet(cellTitle: title) + self.tableView.deselectRow(at: indexPath, animated: true) } } -struct Option { - let text: String - let check: Bool +extension SettingsViewController: ToggleOptionCellDelegate { + func toggleOptionCellSwitchChanged(_ cell: ToggleOptionCell, title: String, switchOn: Bool) { + print(title, switchOn) + } +} + +//MARK: - dummy data + +enum Map: String, CustomStringConvertible, CaseIterable { + case infomation = "정보지도" + case normal = "일반지도" + case satellite = "위성지도" + + var description: String { + return self.rawValue + } } -struct Settings { - let photoSettings: [Option] - let autoSettins: [Option] - let voiceSettings: [Option] - let mapSettings: [Option] +protocol Option { + var text: String { get } } -let photoSettings1 = Option(text: "사진 기록하기", check: true) -let photoSettings2 = Option(text: "지도에 사진표시", check: true) +struct ToggleOption: Option { + let text: String + let toggle: Bool +} -let autoSettins1 = Option(text: "자동 일시정지/재시작", check: false) -let autoSettins2 = Option(text: "자동 일시정지/재시작 음성 안내", check: false) +struct MapOption: Option { + let text: String + let map: Map +} -let voiceSettings1 = Option(text: "1킬로미터 마다 음성 안내", check: true) +let photoSettings1 = ToggleOption(text: "사진 기록하기", toggle: true) +let photoSettings2 = ToggleOption(text: "지도에 사진표시", toggle: true) -let mapSetting1 = Option(text: "지도 형식", check: true) -let mapSetting2 = Option(text: "지도에 등산로 표시", check: true) +let autoSettins1 = ToggleOption(text: "자동 일시정지/재시작", toggle: false) +let autoSettins2 = ToggleOption(text: "자동 일시정지/재시작 음성 안내", toggle: false) -let settings = Settings(photoSettings: [photoSettings1, photoSettings2], - autoSettins: [autoSettins1, autoSettins2], - voiceSettings: [voiceSettings1], - mapSettings: [mapSetting1, mapSetting2]) +let voiceSettings1 = ToggleOption(text: "1킬로미터 마다 음성 안내", toggle: true) -//protocol OptionKey { -// var text: String { get } -//} -// -//struct ToggleOption: OptionKey { -// let text: String -// let check: Bool -//} - -//struct ListOption: OptionKey { -// let text: String -// let list: [String] -//} -// -//struct Settings { -// let photoSettings: [OptionKey] -// let autoSettins: [OptionKey] -// let voiceSettings: [OptionKey] -// let mapSettings: [OptionKey] -//} -// -//let photoSettings1 = ToggleOption(text: "사진 기록하기", check: true) -//let photoSettings2 = ToggleOption(text: "지도에 사진표시", check: true) -// -//let autoSettins1 = ToggleOption(text: "자동 일시정지/재시작", check: false) -//let autoSettins2 = ToggleOption(text: "자동 일시정지/재시작 음성 안내", check: false) -// -//let voiceSettings1 = ToggleOption(text: "1킬로미터 마다 음성 안내", check: true) -// -//let mapSetting1 = ListOption(text: "지도 형식", list: ["정보지도, 일반지도, 위성지도"]) -//let mapSetting2 = ToggleOption(text: "지도에 등산로 표시", check: true) -// -//let settings = Settings(photoSettings: [photoSettings1, photoSettings2], -// autoSettins: [autoSettins1, autoSettins2], -// voiceSettings: [voiceSettings1], -// mapSettings: [mapSetting1, mapSetting2]) +let mapSetting1 = MapOption(text: "지도 형식", map: .infomation) +let mapSetting2 = ToggleOption(text: "지도에 등산로 표시", toggle: true) + +let settings: [[Option]] = [[photoSettings1, photoSettings2], + [autoSettins1, autoSettins2], + [voiceSettings1], + [mapSetting1, mapSetting2]] diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 46bd18a..45239df 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -7,10 +7,16 @@ import UIKit +protocol ToggleOptionCellDelegate: AnyObject { + func toggleOptionCellSwitchChanged(_ cell: ToggleOptionCell, title: String, switchOn: Bool) +} + class ToggleOptionCell: UITableViewCell { static let identifier = "ToggleOptionCell" + weak var delegate: ToggleOptionCellDelegate? + private var title: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 17) @@ -29,7 +35,6 @@ class ToggleOptionCell: UITableViewCell { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none self.configureView() - } required init?(coder: NSCoder) { @@ -37,10 +42,13 @@ class ToggleOptionCell: UITableViewCell { } @objc func onClickSwitch(sender: UISwitch) { - + guard let title = self.title.text else { return } + self.delegate?.toggleOptionCellSwitchChanged(self, + title: title, + switchOn: self.controlSwitch.isOn) } - func configureView() { + private func configureView() { self.contentView.addSubview(self.title) let locationConstrain = [ self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), From 2d74e53f0c4bddfe40b1028d17d8b5caa0127d88 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 2 Nov 2021 16:05:55 +0900 Subject: [PATCH 017/465] =?UTF-8?q?[Fix]=20=ED=81=B4=EB=9F=AC=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=A7=81=EC=9D=B4=20=EC=A0=81=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 37 ++++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index efe7d33..59c0dbe 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -9,7 +9,7 @@ import MapKit class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var mapView = MKMapView() - private var manager: CLLocationManager? + private var manager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() @@ -22,6 +22,7 @@ class MapViewController: UIViewController { private func configureViews() { self.mapView = MKMapView(frame: view.bounds) self.mapView.showsUserLocation = true + self.mapView.delegate = self self.view.addSubview(self.mapView) } @@ -37,12 +38,11 @@ class MapViewController: UIViewController { } private func configureCoreLocationManager() { - self.manager = CLLocationManager() - self.manager?.requestWhenInUseAuthorization() - self.manager?.requestAlwaysAuthorization() - self.manager?.delegate = self - self.manager?.desiredAccuracy = kCLLocationAccuracyBest - self.manager?.startUpdatingLocation() + self.manager.requestWhenInUseAuthorization() + self.manager.requestAlwaysAuthorization() + self.manager.delegate = self + self.manager.desiredAccuracy = kCLLocationAccuracyBest + self.manager.startUpdatingLocation() } private func render(_ location: CLLocation) { @@ -59,22 +59,25 @@ class MapViewController: UIViewController { } private func testCoordinates() { - for _ in 0...200 { + for _ in 0..<200 { let latitude = Double.random(in: 36.0..<37.0) let longitude = -Double.random(in: 121.0..<122.0) - let pin = MKPointAnnotation() - pin.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) - mapView.addAnnotation(pin) + let mountainAnnotaion = MountainAnnotaion() + mountainAnnotaion.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + self.mapView.addAnnotation(mountainAnnotaion) } } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - return MountainAnnotationView( - annotation: annotation, - reuseIdentifier: MountainAnnotationView.ReuseID - ) + if let _ = annotation as? MountainAnnotaion { + return MountainAnnotationView( + annotation: annotation, + reuseIdentifier: MountainAnnotationView.ReuseID + ) + } + return nil } } @@ -86,3 +89,7 @@ extension MapViewController: CLLocationManagerDelegate { } } } + +class MountainAnnotaion: NSObject, MKAnnotation { + var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) +} From 200138d3cb9c525143eef3d2e3eacc8316a2e2a3 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 3 Nov 2021 12:27:24 +0900 Subject: [PATCH 018/465] =?UTF-8?q?[Fix]=20Merge=20=EA=B3=BC=EC=A0=95?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A4=91=EB=B3=B5=EB=90=9C=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 3e4176b..319039d 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -12,7 +12,6 @@ class MapViewController: UIViewController { private var startButton = UIButton() private var manager = CLLocationManager() private var userTrackingButton = MKUserTrackingButton() - private var manager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() @@ -145,7 +144,3 @@ extension MapViewController: CLLocationManagerDelegate { class MountainAnnotaion: NSObject, MKAnnotation { var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) } - -class MountainAnnotaion: NSObject, MKAnnotation { - var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) -} From 6cd1df07b9ff2719dbe9f51b7d73e195bfb51ced Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 16:56:13 +0900 Subject: [PATCH 019/465] [Feat] ViewModel Bindings --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 ++-- SanTa/SanTa/RecordingScene/Record.swift | 22 +++++ .../SanTa/RecordingScene/RecordingModel.swift | 96 +++++++++++++++++++ .../RecordingViewController.swift | 40 +++++++- .../RecordingScene/RecordingViewModel.swift | 89 ++--------------- 5 files changed, 172 insertions(+), 91 deletions(-) create mode 100644 SanTa/SanTa/RecordingScene/Record.swift create mode 100644 SanTa/SanTa/RecordingScene/RecordingModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 900765e..87fcd6e 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -30,13 +30,13 @@ 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; - DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* SettingsCell.swift */; }; 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; + DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; - + DAB37D4E2732557100EC523F /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4D2732557100EC523F /* Record.swift */; }; + DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -65,13 +65,13 @@ 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; - DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - 985EEF64273010BD002413D9 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; - + DAB37D4D2732557100EC523F /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; + DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -92,6 +92,8 @@ DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, + DAB37D4F273256B900EC523F /* RecordingModel.swift */, + DAB37D4D2732557100EC523F /* Record.swift */, ); path = RecordingScene; sourceTree = ""; @@ -306,11 +308,13 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, + DAB37D4E2732557100EC523F /* Record.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, + DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift new file mode 100644 index 0000000..c1ba006 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -0,0 +1,22 @@ +// +// Record.swift +// SanTa +// +// Created by 김민창 on 2021/11/03. +// + +import Foundation + +struct Record { + let time: String + let step: Int + let distance: Double? + + let locations: [Location] +} + +struct Location { + let latitude: Double + let longitude: Double + let altitude: Double +} diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift new file mode 100644 index 0000000..7d51549 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -0,0 +1,96 @@ +// +// RecordingModel.swift +// SanTa +// +// Created by 김민창 on 2021/11/03. +// + +import Foundation +import CoreLocation +import CoreMotion +import Combine + +class RecordingModel: NSObject { + private let pedoMeter = CMPedometer() + private var locationManager = CLLocationManager() + private var timer: DispatchSourceTimer? + private var date: Date? + + private var currentTime = 0 { + didSet { + self.timeConverter() + self.checkPedoMeter() + } + } + + override init() { + super.init() + self.date = Date() + self.configureTimer() + self.configureLocationManager() + } + + private func configureTimer() { + self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) + self.timer?.schedule(deadline: .now(), repeating: 1) + self.timer?.setEventHandler(handler: { [weak self] in + self?.currentTime += 1 + }) + + self.resume() + } + + private func configureLocationManager() { + self.locationManager.requestWhenInUseAuthorization() + self.locationManager.startUpdatingLocation() + self.locationManager.delegate = self + } + + private func timeConverter() { + let seconds = currentTime % 60 + let minutes = (currentTime / 60) % 60 + let hours = (currentTime / 3600) + + print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) + } + + private func checkPedoMeter() { + guard let date = self.date else { return } + + pedoMeter.queryPedometerData(from: date, to: Date()) { data, error in + guard let activityData = data, + error == nil else { return } + + print("Steps: \(activityData.numberOfSteps)") + print("Distance \(activityData.distance)") + } + } + + func suspend() { + timer?.suspend() + } + + func resume() { + timer?.resume() + } + + func cancel() { + timer?.cancel() + timer = nil + } +} + +extension RecordingModel: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let lastLocation = locations.last { + print("위도: \(lastLocation.coordinate.latitude)") + print("경도: \(lastLocation.coordinate.longitude)") + print("고도: \(lastLocation.altitude)") + } + } + + func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { + // GPS를 켜지 않았을 경우 + print(error) + } +} diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b8900f2..f63e72c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -6,6 +6,7 @@ // import UIKit +import Combine class RecordingViewController: UIViewController { weak var coordinator: RecordingViewCoordinator? @@ -75,7 +76,8 @@ class RecordingViewController: UIViewController { let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() - var timer: RecordingViewModel? + private var recordingViewModel = RecordingViewModel() + private var subscriptions = Set() override func viewDidLoad() { super.viewDidLoad() @@ -84,10 +86,40 @@ class RecordingViewController: UIViewController { self.configureStackView() self.configureConstraints() self.configureButton() - self.configure() + self.configureBindings() } - private func configure() { - timer = RecordingViewModel() + private func configureBindings() { + recordingViewModel.$currentTime + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] time in + self?.timeLabel.text = time + }) + .store(in: &subscriptions) + + recordingViewModel.$kilometer + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] kilometer in + self?.kilometerLabel.text = kilometer + }) + .store(in: &subscriptions) + + recordingViewModel.$altitude + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] altitude in + self?.altitudeLabel.text = altitude + }) + .store(in: &subscriptions) + + recordingViewModel.$walk + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] walk in + self?.walkLabel.text = walk + }) + .store(in: &subscriptions) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 5a23a82..bbad75c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -6,91 +6,18 @@ // import Foundation -import CoreLocation -import CoreMotion import Combine -class RecordingViewModel: NSObject { - private let pedoMeter = CMPedometer() - private var locationManager = CLLocationManager() - private var timer: DispatchSourceTimer? - private var date: Date? +class RecordingViewModel: ObservableObject { + @Published private(set) var currentTime = "" + @Published private(set) var kilometer = "" + @Published private(set) var altitude = "" + @Published private(set) var walk = "" - private var currentTime = 0 { - didSet { - self.timeConverter() - self.checkPedoMeter() - } - } - - override init() { - super.init() - self.date = Date() - self.configureTimer() - self.configureLocationManager() - } - - private func configureTimer() { - self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) - self.timer?.schedule(deadline: .now(), repeating: 1) - self.timer?.setEventHandler(handler: { [weak self] in - self?.currentTime += 1 - }) - - self.resume() - } + private var recording: RecordingModel? - private func configureLocationManager() { - self.locationManager.requestWhenInUseAuthorization() - self.locationManager.startUpdatingLocation() - self.locationManager.delegate = self + init() { + recording = RecordingModel() } - private func timeConverter() { - let seconds = currentTime % 60 - let minutes = (currentTime / 60) % 60 - let hours = (currentTime / 3600) - - print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) - } - - private func checkPedoMeter() { - guard let date = self.date else { return } - - pedoMeter.queryPedometerData(from: date, to: Date()) { data, error in - guard let activityData = data, - error == nil else { return } - - print("Steps: \(activityData.numberOfSteps)") - print("Distance \(activityData.distance)") - } - } - - func suspend() { - timer?.suspend() - } - - func resume() { - timer?.resume() - } - - func cancel() { - timer?.cancel() - timer = nil - } -} - -extension RecordingViewModel: CLLocationManagerDelegate { - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - if let lastLocation = locations.last { - print("위도: \(lastLocation.coordinate.latitude)") - print("경도: \(lastLocation.coordinate.longitude)") - print("고도: \(lastLocation.altitude)") - } - } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - // GPS를 켜지 않았을 경우 - print(error) - } } From 08a8c9b3181ad92d1d7a0ba1db3a00ec30d349fd Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 17:18:41 +0900 Subject: [PATCH 020/465] [Feat] Model Bindings --- SanTa/SanTa/Application/SceneDelegate.swift | 8 ++-- .../SanTa/RecordingScene/RecordingModel.swift | 25 ++++++++---- .../RecordingScene/RecordingViewModel.swift | 39 ++++++++++++++++++- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 18e4a5e..da4d56c 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,9 +14,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) - self.appCoordinator = AppCoordinator(window) - - appCoordinator?.start() +// self.appCoordinator = AppCoordinator(window) +// +// appCoordinator?.start() + self.window?.rootViewController = RecordingViewController() + self.window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 7d51549..9f7e0b9 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -10,11 +10,17 @@ import CoreLocation import CoreMotion import Combine -class RecordingModel: NSObject { +class RecordingModel: NSObject, ObservableObject { + @Published private(set) var time = "" + @Published private(set) var kilometer = "" + @Published private(set) var altitude = "" + @Published private(set) var walk = "" + private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? private var date: Date? + private var location = [Location]() private var currentTime = 0 { didSet { @@ -51,18 +57,20 @@ class RecordingModel: NSObject { let minutes = (currentTime / 60) % 60 let hours = (currentTime / 3600) - print(NSString(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds)) + time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) } private func checkPedoMeter() { guard let date = self.date else { return } - pedoMeter.queryPedometerData(from: date, to: Date()) { data, error in + pedoMeter.queryPedometerData(from: date, to: Date()) { [weak self] data, error in guard let activityData = data, error == nil else { return } - print("Steps: \(activityData.numberOfSteps)") - print("Distance \(activityData.distance)") + self?.walk = "\(activityData.numberOfSteps)" + + guard let distance = activityData.distance else { return } + self?.kilometer = "\(distance)" } } @@ -83,9 +91,10 @@ class RecordingModel: NSObject { extension RecordingModel: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let lastLocation = locations.last { - print("위도: \(lastLocation.coordinate.latitude)") - print("경도: \(lastLocation.coordinate.longitude)") - print("고도: \(lastLocation.altitude)") + location.append(Location(latitude: Double(lastLocation.coordinate.latitude), + longitude: Double(lastLocation.coordinate.longitude), + altitude: Double(lastLocation.altitude))) + altitude = "\(lastLocation.altitude)" } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index bbad75c..3ba0c2e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -14,10 +14,45 @@ class RecordingViewModel: ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" - private var recording: RecordingModel? + private var recording = RecordingModel() + private var subscriptions = Set() init() { - recording = RecordingModel() + configureBindings() + } + + private func configureBindings() { + recording.$time + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] time in + self?.currentTime = time + }) + .store(in: &subscriptions) + + recording.$kilometer + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] kilometer in + self?.kilometer = kilometer + }) + .store(in: &subscriptions) + + recording.$altitude + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] altitude in + self?.altitude = altitude + }) + .store(in: &subscriptions) + + recording.$walk + .receive(on: DispatchQueue.main) + .sink (receiveCompletion: { print ("completion: \($0)") }, + receiveValue: { [weak self] walk in + self?.walk = walk + }) + .store(in: &subscriptions) } } From 04a61ab7c1b9442af8323b2664de5cba73b1d81f Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 17:41:16 +0900 Subject: [PATCH 021/465] [Feat] Convert Meter to Km in Model --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 9f7e0b9..4bdfd7c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -70,7 +70,10 @@ class RecordingModel: NSObject, ObservableObject { self?.walk = "\(activityData.numberOfSteps)" guard let distance = activityData.distance else { return } - self?.kilometer = "\(distance)" + let transformatKilometer = Double(truncating: distance) / 1000 + let distanceString = String(format: "%.2f", transformatKilometer) + + self?.kilometer = "\(distanceString)" } } From 51c8110752a84b814e9481497e13aa5ac9d1a346 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 17:42:38 +0900 Subject: [PATCH 022/465] [Feat] Convert Altitude to Int --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 4bdfd7c..c7ec800 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -97,7 +97,7 @@ extension RecordingModel: CLLocationManagerDelegate { location.append(Location(latitude: Double(lastLocation.coordinate.latitude), longitude: Double(lastLocation.coordinate.longitude), altitude: Double(lastLocation.altitude))) - altitude = "\(lastLocation.altitude)" + altitude = "\(Int(lastLocation.altitude))" } } From e1eb87eced77d222de15cf7010d6da16876ab810 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Wed, 3 Nov 2021 18:01:56 +0900 Subject: [PATCH 023/465] =?UTF-8?q?[Feat]=20=EC=A7=80=EB=8F=84=EC=97=90=20?= =?UTF-8?q?=EC=A0=84=EA=B5=AD=20=EC=82=B0=20=EB=A7=88=EC=BB=A4=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asset에 생성한 JSON 추가 MountainEntity 정의 MountainExtractor 생성 MapViewRepository 생성 MapViewUseCase 생성 MapViewModel 생성 MountainAnnotation 생성 MapViewCoordinator 수정 MapViewController convenience init 추가 test 마커 삭제 --- SanTa/SanTa.xcodeproj/project.pbxproj | 22 +- SanTa/SanTa/Entities/MountainEntity.swift | 32 + SanTa/SanTa/MapScene/MapViewController.swift | 45 +- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 6 +- SanTa/SanTa/MapScene/MapViewModel.swift | 18 + SanTa/SanTa/MapScene/MapViewRepository.swift | 32 + SanTa/SanTa/MapScene/MapViewUseCase.swift | 21 + SanTa/SanTa/MapScene/MountainAnnotation.swift | 25 + .../Persistences/MountainExtractor.swift | 24 + .../Contents.json | 12 + .../MountainsWithLocation.json | 12122 ++++++++++++++++ 11 files changed, 12333 insertions(+), 26 deletions(-) create mode 100644 SanTa/SanTa/Entities/MountainEntity.swift create mode 100644 SanTa/SanTa/MapScene/MountainAnnotation.swift create mode 100644 SanTa/SanTa/Persistences/MountainExtractor.swift create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 900765e..c59457c 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; + 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; + 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */; }; 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296944272FBC6E0070B362 /* AppCoordinator.swift */; }; @@ -30,16 +33,17 @@ 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; - DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* SettingsCell.swift */; }; 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; + DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; - /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; + 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; + 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewUseCase.swift; sourceTree = ""; }; 54296944272FBC6E0070B362 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; @@ -65,13 +69,11 @@ 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; - DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - 985EEF64273010BD002413D9 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; - /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -144,6 +146,7 @@ 5428FDBE272F8D43002F9D40 /* Entities */ = { isa = PBXGroup; children = ( + 49FEEDB82732584000D37CCA /* MountainEntity.swift */, ); path = Entities; sourceTree = ""; @@ -151,6 +154,7 @@ 54296943272FB8410070B362 /* Persistences */ = { isa = PBXGroup; children = ( + 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */, ); path = Persistences; sourceTree = ""; @@ -165,6 +169,7 @@ 54296946272FBD4B0070B362 /* MapViewCoordinator.swift */, 5429695A273026B10070B362 /* MountainAnnotationView.swift */, 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */, + 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */, ); path = MapScene; sourceTree = ""; @@ -215,8 +220,8 @@ 5428FDBE272F8D43002F9D40 /* Entities */, 54731B62272F808300534097 /* Application */, 54731B61272F7F7600534097 /* MapScene */, - 5428FDB5272F89F0002F9D40 /* RecordingScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, + 5428FDB5272F89F0002F9D40 /* RecordingScene */, 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB9272F8BD9002F9D40 /* MountainListScene */, 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, @@ -310,14 +315,17 @@ 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, + 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, + 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, + 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, diff --git a/SanTa/SanTa/Entities/MountainEntity.swift b/SanTa/SanTa/Entities/MountainEntity.swift new file mode 100644 index 0000000..4fd417f --- /dev/null +++ b/SanTa/SanTa/Entities/MountainEntity.swift @@ -0,0 +1,32 @@ +// +// MountainEntity.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/03. +// + +import Foundation + +struct MountainEntity: Codable { + + struct MountainDetail: Codable { + let mountainName, mountainRegion, mountainHeight, mountainShortDescription: String + + enum CodingKeys: String, CodingKey { + case mountainName = "MNTN_NM" + case mountainRegion = "MNTN_LOCPLC_REGION_NM" + case mountainHeight = "MNTN_HG_VL" + case mountainShortDescription = "DETAIL_INFO_DTCONT" + } + } + + let mountain: MountainDetail + let latitude: Double + let longitude: Double + + enum CodingKeys: String, CodingKey { + case mountain = "mountain" + case latitude = "latitude" + case longitude = "longitude" + } +} diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 319039d..27e2b06 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -12,13 +12,36 @@ class MapViewController: UIViewController { private var startButton = UIButton() private var manager = CLLocationManager() private var userTrackingButton = MKUserTrackingButton() + private var viewModel: MapViewModel? + + convenience init(viewModel: MapViewModel) { + self.init() + self.viewModel = viewModel + } override func viewDidLoad() { super.viewDidLoad() self.configureViews() self.registerAnnotationView() self.configureCoreLocationManager() - self.testCoordinates() + self.configureViewModel() + } + + private func configureViewModel() { + self.viewModel?.markersShouldUpdate = { self.configureMarkers() } + self.viewModel?.viewDidLoad() + } + + private func configureMarkers() { + self.viewModel?.mountains?.forEach{ mountainEntity in + let mountainAnnotation = MountainAnnotation( + title: mountainEntity.mountain.mountainName, + subtitle: mountainEntity.mountain.mountainHeight, + latitude: mountainEntity.latitude, + longitude: mountainEntity.longitude + ) + self.mapView.addAnnotation(mountainAnnotation) + } } private func configureViews() { @@ -42,7 +65,7 @@ class MapViewController: UIViewController { self.startButton.layer.shadowOpacity = 1 self.startButton.layer.shadowRadius = 3 self.startButton.layer.shadowOffset = CGSize(width: 0, height: 3) - + let startButtonConstraints = [ self.startButton.widthAnchor.constraint(equalToConstant: 100), self.startButton.heightAnchor.constraint(equalToConstant: 100), @@ -101,21 +124,11 @@ class MapViewController: UIViewController { let region = MKCoordinateRegion(center: coordinate, span: span) self.mapView.setRegion(region, animated: true) } - - private func testCoordinates() { - for _ in 0..<200 { - let latitude = Double.random(in: 36.0..<37.0) - let longitude = -Double.random(in: 121.0..<122.0) - let mountainAnnotaion = MountainAnnotaion() - mountainAnnotaion.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) - self.mapView.addAnnotation(mountainAnnotaion) - } - } } extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - if let _ = annotation as? MountainAnnotaion { + if let _ = annotation as? MountainAnnotation { return MountainAnnotationView( annotation: annotation, reuseIdentifier: MountainAnnotationView.ReuseID @@ -135,12 +148,8 @@ extension MapViewController: CLLocationManagerDelegate { func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { if manager.authorizationStatus == .authorizedWhenInUse || - manager.authorizationStatus == .authorizedAlways { + manager.authorizationStatus == .authorizedAlways { userTrackingButton.isHidden = false } } } - -class MountainAnnotaion: NSObject, MKAnnotation { - var coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) -} diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index acb6006..f4b13e2 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -15,9 +15,13 @@ class MapViewCoordinator: Coordinator { } func startPush() -> MapViewController { - let mapViewController = MapViewController() + let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self return mapViewController } + + private func injectDependencies() -> MapViewModel { + return MapViewModel(useCase: MapViewUseCase(repository: DefaultMapViewRespository(mountainExtractor: MountainExtractor()))) + } } diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index 3e99104..b7944c9 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -6,3 +6,21 @@ // import Foundation + +class MapViewModel { + private let useCase: MapViewUseCase + private(set) var mountains: [MountainEntity]? + var markersShouldUpdate: () -> Void + + init(useCase: MapViewUseCase) { + self.useCase = useCase + self.markersShouldUpdate = { } + } + + func viewDidLoad() { + self.useCase.prepareMountainMarkers { [weak self] mountains in + self?.mountains = mountains + self?.markersShouldUpdate() + } + } +} diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index 6b36c03..89c34ad 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -6,3 +6,35 @@ // import Foundation + +protocol MapViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) +} + +class DefaultMapViewRespository { + enum JSONDecodeError: Error { + case decodingFailed + } + + private let mountainExtractor: MountainExtractor + + init(mountainExtractor: MountainExtractor) { + self.mountainExtractor = mountainExtractor + } +} + +extension DefaultMapViewRespository: MapViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + self.mountainExtractor.extract { result in + switch result { + case .failure(let error): + return completion(.failure(error)) + case .success(let dataAsset): + guard let decodedObjects = try? JSONDecoder().decode([MountainEntity].self, from: dataAsset.data) else { + return completion(.failure(JSONDecodeError.decodingFailed)) + } + completion(.success(decodedObjects)) + } + } + } +} diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index b9b04d7..38e2930 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -6,3 +6,24 @@ // import Foundation +import OSLog + +class MapViewUseCase { + private let repository: MapViewRepository + + init(repository: MapViewRepository) { + self.repository = repository + } + + func prepareMountainMarkers(completion: @escaping ([MountainEntity]?) -> Void) { + self.repository.fetchMountains { result in + switch result { + case .failure(let error): + os_log(.error, log: .default, "\(error.localizedDescription)") + completion(nil) + case .success(let mountains): + completion(mountains) + } + } + } +} diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift new file mode 100644 index 0000000..33ed817 --- /dev/null +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -0,0 +1,25 @@ +// +// MountainAnnotation.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/03. +// + +import MapKit + +class MountainAnnotation: NSObject, MKAnnotation { + var title: String? + var subtitle: String? + var latitude: Double + var longitude: Double + var coordinate: CLLocationCoordinate2D { + CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + } + + init(title: String, subtitle: String, latitude: Double, longitude: Double) { + self.title = title + self.subtitle = subtitle + self.latitude = latitude + self.longitude = longitude + } +} diff --git a/SanTa/SanTa/Persistences/MountainExtractor.swift b/SanTa/SanTa/Persistences/MountainExtractor.swift new file mode 100644 index 0000000..edd397e --- /dev/null +++ b/SanTa/SanTa/Persistences/MountainExtractor.swift @@ -0,0 +1,24 @@ +// +// MountainExtractor.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/03. +// + +import Foundation +import UIKit + +class MountainExtractor { + + enum ExtractError: Error { + case extractionFailed + } + + func extract(completion: @escaping (Result) -> Void) { + guard let dataAsset = NSDataAsset(name: "MountainsWithLocation") else { + return completion(.failure(ExtractError.extractionFailed)) + } + + completion(.success(dataAsset)) + } +} diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json new file mode 100644 index 0000000..d107816 --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json @@ -0,0 +1,12 @@ +{ + "data" : [ + { + "filename" : "MountainsWithLocation.json", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json new file mode 100644 index 0000000..42eace2 --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json @@ -0,0 +1,12122 @@ +[ + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기 제 1봉인 화악산(1,468m)에서 동남쪽으로 뻗어 내린 능선상에 솟아 있는 가덕산은 몽덕산과 북배산의 능선 중간에 자리잡고 있다. 억새산이라고 할만큼 가을철에 억새가 볼만하다.수백평의 억새밭인 가덕산 정상에 오르면 서북방향으로 화악산이 보이고, 남쪽으로는 목동평야와 북배산, 계관산 너머로 삼악산으로 이어지는 능선이 한눈에 들어 온다. 동쪽으로는 의암호와 춘천호, 그리고 호반의 도시, 춘천시가 보인다.가덕산은 계관산, 북배산, 몽덕산과 더불어 네 개의 산을 연결하여 등산하는 유명한 종주코스이다. 이 능선에 구축된 등산길은 넓게 길이 잘 뚫려 있고 굴곡이 심하지 않아 겨울철 능선 종주산행지로 적격이다.", + "MNTN_HG_VL" : "858", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "가덕산" + }, + "longitude" : 127.61222220000001, + "latitude" : 37.940555600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제주도 다음으로 큰 섬인 거제도에는 해발 500m가 넘는 산이 7개가 있다. 그 중에서도 가라산은 도토리 키재기에서 1등을 차지해 `거제도 제1봉'이란 이름을 얻고 있는 산이다. 그래서인지 높이는 얼마 안되지만, 산행하기가 쉽지 않다.경상남도 남단 거제시의 최고봉으로 주봉은 가래봉이다. 산길에 서면 해안선이 가장 긴 한국 제2의 섬 거제도와 주변의 여러 섬은 물론 북쪽으로 진해시·마산시ㆍ고성군, 서쪽으로 통영시를 마주하고, 남·동쪽으로 남해를 굽어볼 수 있다. 부산 영도가 지척이고 갠 날은 쓰시마섬[對馬島]이 가물거릴 만큼 조망이 뛰어나다.가라산 곁에 계룡산(鷄龍山:566m)·노자산(老子山: 565m)·앵산(鶯山:507m)·산방산(山芳山:507m)·선자산(扇子山:507m)·옥녀봉(玉女 峰:555m) 등 500m대 비탈산이 많아 농지가 적지만 바다로 둘려 수산물이 풍부하다. 계룡산∼가라산 종주(약 25㎞)보다 노자산∼가라산 쪽이 인기다. 두 산은 1cm 사이라는 거제 유머가 있다.봄이면 고로쇠 약수 채취로 붐비고 해양성기후에 잘 자라는 아열대식물인 동백나무·팔손이나무·소철·종려나무 등 600여 종이 우거졌다. 노자산의 천연기념물인 학동의 동백림(233)은 세계적인 팔색조(八色鳥:204) 번식지이며, 서불의 불로초 신화에 얽힌 신선산의 산삼 또한 손꼽는다. 거제 해금강이 보 이는 학동고개에서 오르면 벼늘[露積]바위ㆍ선녀바위가 있는 주능선 삼거리에 닿고, 다도해의 수묵화가 펼쳐진다.거제 10대 명산의 수봉(首峰)까지는 젖봉바위·매바위 등에서 암벽등반도 즐기며 들맞이재와 안부를 지나면 잡목 울창한 정상 못미처 봉화대와 기우단이 있고 견암봉(見岩峰) 밑에 신라시대의 견암사지가 있다. 하산은 다대산성(多大山城)을 거치는 다대포구 쪽과 산정 밑 전망대바위-속가심바구 또는 원추리바위-에서 해금강 배타는 데로 가는 두 길이 있다.육로는 통영과 마산·진주·부산 등이 국도로 연결된 1일권으로 편리하다. 뱃길은 정기 여객선과 쾌속선이 옥포·고현·성포항에서 부산·통영·진해로 가며, 부산까지 40분으로 육상보다 낫다. 항공편은 수시로 헬리콥터가 김해와 연결된다. 근처의 명사·여차(몽돌)·덕원·함목·학동(몽돌)해수욕장 등도 가볼 만하다.", + "MNTN_HG_VL" : "580", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 남부면 다대리", + "MNTN_NM" : "가라산" + }, + "longitude" : 128.62708369999999, + "latitude" : 34.753540999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 춘천시와 홍천군의 경계를 이루는 산으로, 산 정상에 서면 탁 트인 시야와 발 아래로 펼쳐진 소양호의 풍경이 등산객들의 발걸음을 멈추게 하는 곳이다. 산자락을 감싸 흐르는 조그마한 폭포의 물소리가 사람들의 마음을 시원하게 해주는 가리산은 우거진 숲과 노송들이 어루러져 비경을 이루고 있다.소양호 쪽으로 하산하여 물노리 선착장에서 유람선을 타고 소양댐 선착장까지 나올 수 있어, 산행도 하고 배를 타는 재미가 있다.산이름인 가리는 '단으로 묶은 곡식이나 땔나무 따위를 차곡차곡 쌓아둔 큰 더미'를 뜻하는 순우리말로서, 산봉우리가 노적가리처럼 고깔 모양으로 생긴 데서 유래한다. 태백산맥 중 내지(內地) 산맥의 일부를 이룬다. 제1봉 남쪽에서 홍천강이 발원하여 북한강의 지류인 소양강의 수원(水源)을 이룬다.능선은 완만한 편이나, 정상 일대는 좁은 협곡을 사이에 둔 3개의 암봉으로 이루어져 있으며 강원 제1의 전망대라고 할 만큼 조망이 뛰어나, 소양호를 비롯하여 북쪽으로 향로봉에서 설악산을 거쳐 오대산으로 힘차게 뻗어나간 백두대간 등 강원 내륙의 고산준령이 한눈에 보인다. 정상 부근에서는 소양호로 갈 수 있는 가삽고개가 있는데, 그 형태가 계단식 분지형으로 이루어져 있다.북쪽 산록은 소양호에 미치고 동쪽 산록에 홍천광산이 있다. 산기슭에는 숲이 우거져 있고 갖가지 기암괴석이 즐비하며, 산 정상과 계곡에는 향토 수종인 참나무가 주종을 이루며 자라고 있다. 아래쪽에는 두릅나무·철쭉·싸리나무·산초나무 등 관목류와 약용으로 사용되는 피나물·애기똥풀·양지꽃 등 야생화가 서식하고 있다. 강원도에서 진달래가 가장 많이 피는 산으로도 유명하다.1998년 가리산 자연휴영림으로 개장되어 통나무집·야영장·체육시설 등 편의시설이 있다. 휴양림 입구에는 높이 8m의 용소폭포가 있고, 주변에 스키장·온천·수타사·팔봉산 등의 관광지가 있다.", + "MNTN_HG_VL" : "1051", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면ㆍ동면, 홍천군 두촌면ㆍ화촌면", + "MNTN_NM" : "가리산" + }, + "longitude" : 127.9609203, + "latitude" : 37.873404200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산은 험준한 암릉으로 이루어진 산이다.산 아래에서 볼 때 정산 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입금지구역으로 주의를 요하는 곳이다.백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산(774.3m)은 험준한 암릉으로 이루어진 산이다. 산 아래에서 볼때 정상 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입 금지구역으로 주의를 요하는 곳이다.정상에서의 사방 조망은 경기 제일의 고봉인 화악산, 명지산에 이어 세번째로 높은 국망봉(1,168m)과 신로봉으로 이어지는 능선이 파노라마를 이룬다. 도평교를 하산 지점으로 잡을 경우 하산길은 지루함을 느낄만큼 계곡길의 연속이다.가리산이란 명칭은 현재 폐광된 산 입구의 가리광산에서 유래됐다는 설이 전해진다. 가리란 바로 비료의 주성분 가운데 하나인 칼륨의 일본식 발음이다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면 장암리", + "MNTN_NM" : "가리산" + }, + "longitude" : 127.9609203, + "latitude" : 37.873404200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가리왕산은 태백산의 지붕역활을 하고 있으며 경사도가 완만한 등산로로 유명하다. 산 능선에는 고산식물인 주목, 잣나무, 단풍나무등 각종 수목이 울창하며 산삼등 많은 산약초가 자라고 있다.회동리 입구에는 자연휴양림이 조성되어 각종 편의시설이 설치되어 있고 등산로 산행시간은 총 6시간 정도 소요된다. 군립공원으로 지정, 개발계획에 있으며 숙암방면 입구는 약 4km 구간에 철쭉이 밀집 자생하고 있다.", + "MNTN_HG_VL" : "1562", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 회동리ㆍ북평면, 평창군 진부면", + "MNTN_NM" : "가리왕산" + }, + "longitude" : 128.56326319999999, + "latitude" : 37.462132500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "공주시 반포면 상신리는 계룡산 자락이 감싸고 있는 마을로, 뒷산을 ‘솥봉’ 또는 ‘가마봉’이라 부르는데 지명에 얽힌 슬픈 전설이 전해진다. 아주 오랜 옛날 산 아랫마을에 석공 부부와 두 딸이 단란하게 살고 있었다. 어느 날 석공이 독이 있는 음식을 잘못 먹고 급사하게 되자, 그의 아내와 두 딸은 산속에서 나물을 캐고 나무를 해서 먹고 살아야 했다. 그러던 어느 날 석공의 아내가 산나물을 뜯고 있다가 마침 사냥을 나온 인근 고을의 원님과 마주치게 되었다.원님은 한눈에 이 여인에게 반하여 억지로 끌고 가서 자신의 시중을 들라고 명령하였다. 석공의 아내는 완강하게 거부하였고, 원님은 만약 끝까지 싫다고 한다면 가마솥의 끓는 물에 집어넣어 죽이겠노라고 협박하였다. 그래도 여인이 끝내 싫다 하니 원님은 처음 만났던 그 산속으로 여인을 다시 데리고 가 부하들로 하여금 가마솥을 걸게 하고 물을 끓인 후 사공의 아내를 빠뜨려 죽이고 말았다. 그 후 석공의 두 딸이 어머니의 처참한 시신을 발견하고, 통곡을 하며 복수를 다짐한 끝에 10여 년의 시간이 흐른 후 사냥 나온 원님을 향해 화살을 쏘아 죽였다.죽은 여인의 혼은 이승을 맴돌며 지금도 비오는 밤이나 안개가 낀 날에 큰 울음소리를 낸다고 한다. 산중턱에 솥을 걸었던 자리는 사람 형상의 바위가 생겨나 ‘사람바위’ 혹은 ‘아내바위’라 불렀고, 그 산은 솥봉 또는 가마봉이라 불리게 되었다고 한다.", + "MNTN_HG_VL" : "416", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 반포면", + "MNTN_NM" : "가마봉" + }, + "longitude" : 128.1766667, + "latitude" : 37.886111100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 홍천군 내천면과 인제군 상남면의 경계에 걸쳐 있는 가마봉은 산을 즐겨 타는 등반객들에게도 잘 알려지지 않아 자연 그대로의 정경을 간직한 산이다.산행기점인 김부리는 신라의 마지막 왕인 김부(金傅)에서 유래한 지명인데 세월이 흐르면서 현재 `金富'로 변했다고 한다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 인제군 남면", + "MNTN_NM" : "가마봉" + }, + "longitude" : 128.1766667, + "latitude" : 37.886111100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가야산은 경남 합천군 가야면과 거창군 가북면, 경북 성주군 가천면 수륜면을 한몸에 품고있다. 우리나라 12대 명산중의 하나로 산세가 천하에서 으뜸이고, 지덕은 해동에서 제일이라 하여, 대한 8경에 속하는 명산이다. 가야산 지역이 옛날 가야국이 있었던 곳이고 이 산이 가야국에서 가장 높고 훌륭한 산이었기 때문에 자연스럽게 가야의 산이라 불렀다고 한다.가야산은 소머리 같다 해서 우두산(산 머리의 큰 바위 아래에 소의 코라는 뜻의 우비정이란 샘도 있다) 이라는 이름외에 상왕산, 설산, 중향산 등으로도 불리워졌다. '택리지'에 기암괴봉을 불꽃에 비유하여 석화성(石火星)이라고 하였는데, 가야산은 보는 방향에 따라서 한송이 연꽃으로도 보였다가 서쪽으로 겹겹이 솟은 산봉우리 사이사이 또는 골짜기에 하얀구름이 잠기면 많은 섬이 떠 있는 바다가 된다.해발 1천m가 넘는 고봉들이 불꽃처럼 솟아 있는 자태하며, 북에서 남으로 이르는 장쾌한 대덕유의 줄기와 아스라히 떠오른 구름위로 지리산을 볼 수 있는 조망, 홍류동천의 아름다운 계곡 등 장중하고 덕성스러운 모습을 곳곳에서 볼 수 있다.가야산 고스락에 서면 금오산, 팔공산, 비슬산이 보이고 화왕산, 자굴산이 보이는가 하면 가까이에 두무산, 오도산, 비계산, 조금 멀리에 백운산, 수도산, 대덕산 등이 보인다.여기에 우리나라 3보 사찰중 하나인 해인사가 들어서고, 조선시대 때 강화도에서 팔만대장경을 옮겨온 이후 불교의 성지로 자리메김하였다. 근래에는 백련암에서 수도했던 성철 스님으로 인하여 더욱 유명해졌다.", + "MNTN_HG_VL" : "1433", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군ㆍ거창군, 경상북도 성주군", + "MNTN_NM" : "가야산" + }, + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충남 서산시와 예산군의 경계를 이루는 가야산은 예산, 당진, 서산, 태안 지역에서 무소불위의 힘을 떨치는 산이다. 산은 그 자체로 서해를 향해 호령할 듯 섰다. 산세 또한 그 근방에서 찾아 볼 수 없는 암산으로 기암들이 징검다리 마냥 하늘을 받치고 있다. 백두대간 칠현산에서 분기한 금북정맥의 산답게 당찬 힘을 발휘한다. 가야산에서 석문봉까지 암릉을 형성한 후 두 줄기로 나뉘어 일락산과 옥양봉, 수정봉을 향해 갈래 친다.가야산 자락에는 사방 곳곳에 백제에서 조선시대에 걸쳐 이어진 문화재가 산자락마다 있다. 가야산 서쪽으로는 커다란 은행나무를 품고 있는 고풍스런 해미읍성이 자릴 꿰차고 있으며 북쪽에는 보물 143호로 지정된 대웅전이 있는 개심사가 있다. 북동쪽 자락에는 조선시대의 명지관인 정만인이 점지한 남원군묘와 육관대사로 알려진 풍수지리도사인 손석우의 묘가 있다. 그뿐만 아니다. 남쪽에는 충남 서북부를 대표하는 1500여년 된 역사를 자랑하는 백제시대의 수덕사가 명성을 떨치고 있다.", + "MNTN_HG_VL" : "678", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 운산면·예산군 덕산면", + "MNTN_NM" : "가야산" + }, + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", + "MNTN_NM" : "가야산" + }, + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가야산은 진안 장안산에서 시작해 광양 백운산에서 끝을 맺는 듯하던 호남정맥이 남으로 국사봉과 봉화산으로 뻗어 내리다가 동쪽으로 다시 한번 여세를 몰아 일으킨 산이다. 정상에 오르면 광양 백운산과 백두대간에서 시작하는 지리산 천왕봉은 물론 주릉의 모습까지 한 눈에 조망되는 작지만 알찬 산이다.광양만을 바라보며 우뚝 솟아있어 시내 어디에서나 보이며 또 쉽게 오를 수 있어 광양시민들에게 사랑받는 산이다. 산에서 내려다보이는 광양만은 예부터 전남과 경남을 잇는 해상교역의 요충지이자 수산물의 보고이기도 하다.불과 500미터에 가까운 낮은 산이지만 이곳에는 암장이 있다. 병풍암, 동굴바위, 전망대바위, 처마바위, 적벽 등은 1989년 강신복, 김병석씨가 처음 개척한 이래 현재 70여개 루트가 열려 있고, 도로에서 암장까지는 약 30분이면 갈 수 있어 이곳 바위꾼들의 암벽 훈련 장소로 제격이다. 산행 시간은 어느 코스를 잡아 올라서든 4시간이면 충분하다.", + "MNTN_HG_VL" : "497", + "MNTN_LOCPLC_REGION_NM" : "전남 광양시 옥곡면", + "MNTN_NM" : "가야산" + }, + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가야산은 나주시 가야동 영산강변에 피라미드 형상으로 아름답게 솟은 산이다.나지막한 산세지만 발아래 바로 영산강을 끼고 있어 나주 평야 전체를 바라볼 수 있다. 특히 북쪽 기슭에 위태롭게 매달려 있는 앙암은 강과함께 어우러져 뛰어난 경관을 자랑한다.", + "MNTN_HG_VL" : "189", + "MNTN_LOCPLC_REGION_NM" : "전라남도 나주시 남평읍 수원리", + "MNTN_NM" : "가야산" + }, + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가은산은 금수산(1015.8m) 정상에서 남쪽 말목산(720m)으로 흐르는 산줄기와 중계탑이 서 있는 802봉, 남서쪽으로 흐르는 산줄기에 있는 산이다. 가은산은 청풍호반을 사이에 두고 청풍호의 최고 경승지 옥순·구담봉과 마주 서 있다. 그래서 제천 지역의 그 어느 산에서보다 청풍호반의 아름다운 풍광을 만끽할 수 있다. 또한 등산로 곳곳에 기암괴석과 그 사이에서 자라는 노송들이 한데 어울려 한 폭의 동양화를 그려낸다. 뿐만 아니라 남쪽에는 월악산 영봉과 만수봉으로 이어지는 들쑥날쑥한 능선이 막힘없이 펼쳐진다. 등산로 곳곳에 물개바위, 기와집바위, 손바닥바위, 시계바위, 곰바위 등 독특한 이름을 갖고 있는 기암들이 있어 산행의 즐거움을 더한다. 가은산은 원래 ‘가는산’으로 불렸다고 한다. 전설에 의하면 옛날 마고할미가 이 산에 놀러 왔다가 반지를 잃어버려 모든 능선과 골짜기를 뒤지며 찾다가 아흔아홉번째 골짜기에서 비로소 찾게 되었다. 그리고 나서 “한 골짜기만 더 있었어도 한양이 들어설 골짜기인데, 내가 눌러 앉아 살려 해도 한양이 되지 못하므로 떠나겠다”는 말을 남기고 떠났다는 데서 ‘가는산’이란 이름이 붙었다고 한다.", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면", + "MNTN_NM" : "가은산" + }, + "longitude" : 128.25128050000001, + "latitude" : 36.955438000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1241", + "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상북도 청도군, 경상남도 밀양시", + "MNTN_NM" : "가지산" + }, + "longitude" : 129.00305599999999, + "latitude" : 35.621110999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신라말 원표대사(元表大師)가 인도에 계실 때 신비한 기운이 삼한의 밖 아득히 먼 곳으로부터 비쳐와 그 기운만을 바라보고 산을 넘고 바다를 건너 오묘한 곳을 찾아내 자리를 잡으니 산세가 인도의 가지산, 중국의 가지산과 같아서 가지산이라 명하고 지어진 절이 보림사로 창건에 얽힌 이야기가 전해져 오듯 국보와 보물이 많이 있으며 가지산은 규모는 작지만 산세가 좋아 정상에서 둘러보면 금방 명산이라는 것을 느낄 수 있다.특히 가을철에는 산 전체가 단풍으로 붉게 물들어 그 아름다움은 극치에 달하고 정상부의 바위들은 돌을 깍아세운 듯 하다. 한편 보림사 봉덕 계곡은 사시사철 깨끗한 물이 흐르고 있어 많은 탐방객들이 찾고 있으며 여름철에는 최고의 가족 휴양지로 꼽힌다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 장평면 우산리", + "MNTN_NM" : "가지산" + }, + "longitude" : 129.00305599999999, + "latitude" : 35.621110999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월출산에서 남으로 뻗은 능선이 강진군 성전면과 영암군 학산면을 잇는 회랑에서 2번국도에 길을 내주는등 잠시 바닥에 깔렸다가 고도를 높여 별매산을 만들고 서쪽으로 진행하며 영암군과 해남군사이의 장벽을 이룬다. 이 산줄기는 동으로부터 별매산, 가학산, 흑석산, 두억봉, 418봉등으로 이어지며 계속 서진한뒤 영암호에 이른다.봄철 철쭉철이면 철쭉군락지가 산재한 이 산줄기의 곳곳이 붉게 물들어 장관을 연출한다. 높지 않으면서도 수려한 봉우리들이 중첩되고 조망도 시원한 산들이 가학산, 흑석산이다. 별매산(465m)에서 흑석산(黑石山,650m)으로 이어지는 능선에 우뚝 솟아 있는 가학산의 정상부는 거대한 돔형의 바위 봉으로 되어 있어 해발에 비해 웅장함을 자랑하고 있다.가학산 정상은 평평하고 넓은 공터를 이루고 있으나 양쪽이 절벽으로 이루어져 있어 주의해야 하는 곳이다. 정상에서 북동쪽으로 월출산이 손에 잡힐 듯 가까이 보이고, 남쪽으로는 두륜산이 아스라히 보인다. 가학산 주능선은 온통 바위능선으로 되어 있어 등산로 이외 탈출로가 많지 않은 산이다.", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면 당산리", + "MNTN_NM" : "가학산" + }, + "longitude" : 126.6408333, + "latitude" : 34.680277799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "192", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 서구, 경기도 김포시", + "MNTN_NM" : "가현산" + }, + "longitude" : 126.6497777, + "latitude" : 37.626327199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "398", + "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시", + "MNTN_NM" : "각산" + }, + "longitude" : 128.0564378, + "latitude" : 34.937731300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "각호산은 백두대간상의 삼도봉에서 상촌면을 사이에 두고 백두대간과 상당부분 나란히 북으로 뻗어내리며 석기봉-민주지산-각호산-삼봉산 등을 솟구치게 한 뒤 황간부근을 흐르는 초경천에서 끝나는 길다란 능선의 한 봉우리이다.건각들일 경우 삼도봉-석기봉-민주지산-각호산을 잇는 코스로 종주하기도 하여 민주지산 범주안에 넣어버리는 예도 있으나 독자코스로 오르는 예가 많다.정상은 두 개의 암봉으로 이루어져 있으며 멀리 동쪽과 서쪽면에서 이산을 바라보면 m자형을 이루고 있는 산이다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 상촌면 물한리", + "MNTN_NM" : "각호산" + }, + "longitude" : 127.8456499, + "latitude" : 36.0625936 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "각화산은 태백산 남쪽 15Km 지점 경북 봉화군 춘양면 석현리에 위칙하고 있으며, 가을에는 정상을 오르는 등산로에 단풍이 곱게 물들어 많은 사람들이 찾는다.각화산이란 명칭은 시라 문무왕 16년 (676년)원효대사가 춘양면 서동리에 있던 람화사(覽華寺)를 이 산자락 밑으로 이전한 뒤 생각\"각\"자로 바꿔 부른데서 기인한다. 이 람화사에는 보물 52호로 지정된 3층 석탑이 있으며, 각화사에서 2Km 떨어진 곳에는 조선왕조실록을 보관하던 조선 5대사고 가운데 하나인 태백산고지지(사적348호)가 위치하고 있으며 산림이 무성하여 찾기가 힘들고 오전에 등반해야 하산을 할 수 있다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 춘양면", + "MNTN_NM" : "각화산" + }, + "longitude" : 128.9002778, + "latitude" : 37.009999999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "각희산은 화암국민관광지에서 동대천 북쪽으로 병풍처럼 펼친 듯 솟아 있는 산이며, 동대천을 사이에 두고 행산과 화암약수터가 있는 군의산과 마주하고 있다. 동대천을 거슬러 올라가면 남전산과 지억산이 버티고 있다. 동대천변의 화암8경을 보려는 사람들의 발길은 끊이지 않는데 반해 각희산은 등산로가 잘 알려지지 않아 아직 태고의 신비를 고스란히 간직하고 있다. 각희산 바로 옆 행산과 군의산, 남전산과 지억산이 어깨를 두르고 있다. 정상에서 보면 청옥산, 민둥산이 보이고 그 뒤로 두위봉도 보인다. 각희산은 예로부터 신성시하여 나라에서 벌채를 금지했던 곳으로 알려져 있다.", + "MNTN_HG_VL" : "1083", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면, 임계면", + "MNTN_NM" : "각희산" + }, + "longitude" : 128.81333330000001, + "latitude" : 37.360833300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "502", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면 신기리", + "MNTN_NM" : "간대산" + }, + "longitude" : 126.5258333, + "latitude" : 36.826666699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "간월산은 왕봉재(간월재)에서 천화현(배내고개) 사이에 해발 1068.8m 고봉 일대를 말하는 것으로 상북면 등억에서 배내에 걸쳐 있다. 간(肝)은 우리 민족이 오래 전부터 써오던 신성이라는 뜻이며 월(月)은 신명이라 하여에서 유래되어 평원을 의미하는 벌의 뜻이다. 그러므로 간월산은 평원이 있는 신성한 산으로 신불산과 밝얼산과 같은 뜻을 지니고 있다. 또한 간월이라는 이름은 다음과 같이 肝月, 看月, 澗月, 澗越, 肝越 등 다양하게 쓰이기도 한다.한반도의 남동단인 영남지방에 해발 1000m가 넘는 고헌산, 가지산, 운문산, 천황산, 간월산, 신불산, 취서산 등의 준봉이 일대 산군을 이루며 솟아 있는데 이 산군을 유럽의 알프스와 풍광이 버금간다는 뜻에서 영남알프스라하고 영남 산악인들에게는 천혜의 등산대상이 되고 있는 곳이다.간월산은 신불산 북쪽의 준봉으로서\"영남 알프스\"의 일부분을 구성하고 있으며 홍류폭포 등의 절경과 최근 자연휴양림이 조성돼 찾는 이들이 많아졌다.간월산에서 발원해 언양 쪽으로 흐르는 시냇물 작괘천은 각양각색의 바위들 사이로 옥류가 굽이치는 아름다움은 절경이다. 간월산 기슭의 등억온천은 게르마늄 함량이 높아 피부병과 무좀에 특효가 있고 당뇨와 고혈압, 신경통 등에도 효험이 있는 것으로 알려져 있다.억새가 만개하는 가을, 봄 순으로 많이 찾는다. 억새 테마산행을 위한 간월산-신불산-영축산 연계산행의 산행기점으로도 인기 있다.", + "MNTN_HG_VL" : "1069", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "간월산" + }, + "longitude" : 129.04077340000001, + "latitude" : 35.551204400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 원주시 지정면에 위치한 간현봉은 1985년 국민관광지로 지정되었다. 국민관광지로 지정이 되면서 주차장과 위락시설등이 들어섰고 사람들의 발길이 더욱 부산해졌다.간현봉은 강원도 원주시 지정면 간현유원지에 있는 386m의 나즈막한 산이다. 낮은 산이지만 산행의 값어치는 대단하다.북쪽으로 이어지는 능선은 소나무암릉으로 수십미터의 절벽과 굽이치며 흐르는 강물이 잘 조화되어 다른곳에서 느낄 수 없는 아름다움을 느끼게 한다. 산행 초입에는 매우 아름다운 두몽폭포가 자리잡고 있어 산행을 더욱 뜻깊게 한다. 별 볼일 없을 것같은 산에 이처럼 아름다운 폭포와 뛰어난 암릉지대가 있다", + "MNTN_HG_VL" : "386", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 지정면", + "MNTN_NM" : "간현봉" + }, + "longitude" : 127.8095197, + "latitude" : 37.357180800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갈두산이 위치한 해남군은 한반도 육지부에서 최남단에 위치한 군이다.그것을 증명이라도 하듯 갈두리에 '땅끝비'가 있기도 하다.해남은 우리나라최남단이라는 지리적 특성으로 인하여 조선시대에는 유배지로 지정됐다. 유배자의 35%가 전라도로 보내졌는데, 그중 50%가 해남으로 유배되었다고 한다.갈두산은 해남군에서도 최남단에 위치한 산으로 예부터 산자락에 칡이 많았다는데서 산 이름이 유래됐다. 일명 사자봉으로도 불리는 갈두산의 모산은 해남군 최고봉인 두륜산(703m)이다.정상에 있는 봉화대는 옛날 이곳에서 불을 지퍼 뱃길을 유도했다고 한다. 봉화대에서 남쪽 아래 500m 거리가 우리나라 육지부의 최남단, 북위 34도 17분 38초, 동경 126도 6분 01초 지점으로 조국의 무궁함과 땅끝임을 알리는 높이 10m에 바닥면적 3.6m인 땅끝탑이 세워져 있다.", + "MNTN_HG_VL" : "155", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남 송지면", + "MNTN_NM" : "갈두산" + }, + "longitude" : 126.4638211, + "latitude" : 34.475259000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갈모봉은 작은군자산에서 옥녀봉으로 이어지는 능선상의 675m 봉에서 남쪽으로 뻗어 내린 지능선상 최고봉이다.갈모봉 동남쪽 아래는 장성봉에서 발원한 계류가 흐르는 선유동계곡이 유명하다. 일명 선유구곡(仙遊九曲)으로 불리는 이 계곡은 절경을 이루는 아홉 개의 명소들이 하나같이 희고 반들반들한 화강암으로 되어 있어 경치가 더욱 돋보인다.갈모봉은 온 산이 온통 기암괴석으로 이루어져 있어, 산행 코스마다 산의 경관이 새롭게 다가오며 그런 새로움에 취해 힘든 줄 모르고 산행 할 수 있는 곳이다. 갈모봉 산행 코스를 따라 만나게 되는 기암을 순서별로 보면 칠형제바위, 공기돌, 폭포바위, 두부바위, 우주선바위, 찐빵바위, 도마뱀바위, 벌통바위, 모녀바위, 치마바위, 비행기바위 등 10여개가 넘는다. 선유동계곡은 경관이 빼어나 신선이 노닐었다는 전설이 깃든 곳으로, 이곳의 아름다움에 반하여 조선 유학의 대학자인 퇴계(退溪) 이황(李滉)선생과 우암(尤唵) 송시열(宋時烈)선생이 말년을 보냈다고 한다.선유동계곡의 절경을 9곡으로 나누어 부르고 있는데, 제1경은 석굴형 바위인 선유동문(仙遊洞門)을 말하며, 제2곡은 마치 하늘을 떠받치는 형상을 하였다 하여 경천벽(擎天壁)을 말한다. 제3곡은 층암절벽으로 학이 둥지를 트는 형상인 학소대(鶴巢臺,일명 학소암)이고, 제4곡은 옛날 도사들이 바위로 금단을 끓였다는 연단로(鍊丹爐)를 말한다.제5곡은 연단로 상류 폭포지대인 와룡폭(臥龍瀑)을 말하며, 제6곡은 난가대(爛柯臺)로, 옛날 어느 나무꾼이 신선이 바둑 두는 것을 구경하다가 도끼자루 썩는 줄 몰랐다는 전설이 깃든 곳이다.난가대와 마주보고 있는 제7곡은 바위 바닥이 바둑판 형상으로 되어 있어 기국암(碁局巖)이라 부르며, 제8곡은 거북이 모습을 닮은 바위인 구암(龜巖)을 말한다. 제9곡은 옛날 신선이 숨어 살았다는 은선암(隱仙巖)을 말한다.", + "MNTN_HG_VL" : "582", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시, 충청북도 괴산군", + "MNTN_NM" : "갈모봉" + }, + "longitude" : 128.26813920000001, + "latitude" : 34.973953000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "img alt=\"\"style=\"width: 684px; height: 424px\"src=\"\/fckeditor\/data\/image\/%EA%B0%88%EB%AF%B8%EB%B4%89(%EC%86%8C%EB%A3%A1%EB%B4%89)-%EA%B4%91%EC%A3%BC%EA%B4%91%EC%97%AD%EC%8B%9C.jpg\"\/", + "MNTN_HG_VL" : "372", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구 선교동, 내남동", + "MNTN_NM" : "갈미봉" + }, + "longitude" : 128.60611109999999, + "latitude" : 37.516666700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "548", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "갈미봉" + }, + "longitude" : 128.60611109999999, + "latitude" : 37.516666700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "촉새봉(십자봉,985m)에서 남쪽으로 강원도와 충청북도를 가르며 뻗어 내린 능선이 옥녀봉에 이르면 동쪽과 서쪽으로 갈라진다.옥녀봉에서 동쪽으로 이어지는 능선은 시루봉(734m), 비지재, 강승갱이재를 지나 오청산(655m)으로 이어지고, 서쪽으로 가지를 친 능선상의 최고봉이 갈미봉이다. 갈미봉에서 남서쪽으로 능선이 휘어지며 세가닥으로 능선이 갈라져, 목계의 제내편봉(288m), 오량리의 묵봉산(490m)과 청계봉(390m)을 일으키고 그 여맥을 남한강 물 속으로 잠긴다.갈미봉 정상은 약 20여평의 공터로 둘레를 참나무와 잡목으로 울타리를 친 듯 둘러싸여 있는 게 흠이다.", + "MNTN_HG_VL" : "595", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 충주시", + "MNTN_NM" : "갈미봉" + }, + "longitude" : 128.60611109999999, + "latitude" : 37.516666700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갈전산은 산청,거창군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳 경계에서 양분 되어 한줄기는 덕갈산을 거쳐 생초면 소재지 방향으로 달리고 다른 한줄기가 바로 갈전산을 거쳐 철마산, 소룡산, 바랑산을 거쳐 황매산으로 길게 이어져 있다.갈전산은 덕갈산과 마주보고 있어 생초면소재지 까지 뻗어 있는 덕갈산 줄기를 조망하기에 좋은 곳이다. 날씨가 좋으면 덕유산과 함양군의 고봉들도 조망이 가능하며 지리산과 그 아래 산들도 조 망이 가능하다. 갈전산은 규모가 크거나 산세가 수려하지는 않다. 하지만 이웃한 철마산과 함께 연결하여 산세를 본다면 결코 작은 산이라고 말할 수 없다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 생초면", + "MNTN_NM" : "갈전산" + }, + "longitude" : 127.866356, + "latitude" : 35.556904500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "예로부터 수덕이 뛰어나 삼각산의 영광을 뒷받침한 경기 오악중 북악에 속하는 이 산은 지형적 특성으로 삼국시대에부터 전략적인 요충지로 6.25전쟁 때까지 치열한 격전이 있던 곳이다. 그런 연유로 산자락 설마치계곡 양쪽으로 영국군 전전비와 대한의열단 전적비가 세워져 있다. 바위 사이로 검은빛과 푸른빛이 동시에 흘러나온다 하여 감악(紺岳), 즉 감색바위라고 하였다.또한 조선 명종때 구월산 청석골을 거점으로 활약하던 임꺽정의 중간거점이 있던 곳으로 그와 연관된 지명이 곳곳에 산재해 있다. 정상에는 현재도 군사시설이 있으며, 북한산 진흥왕 순수비와 유사한 일명 삐뜰대왕비 설인귀비가 위치해 있다. 이 비는 아직도 전쟁때 탄흔자국을 가지고 있으며 파주군 향토유적 제 8호로 지정되어 있다. 전체적인 산세는 암릉과 작은 암봉들이 조화를 이루고 있으며 간간이 절벽지대가 있으므로 주의를 요한다.원래 감악사, 운계사, 범륜사, 운림사 등의 4개 사찰이 있었다는데 현재는 1970년 옛 운계사 터에 재창건한 범륜사만 남아 있다.서울에서 그리 멀지 않으며, 의정부 북쪽 회천에서 양주시 남면을 지나 설마리를 거쳐 감악산 계곡을 따라 들어가면 높이 20여 미터에 달하는 운계폭포가 나온다. 폭포 뒤로 범륜사가 있고 그뒤로 전형적인 암산의 모습을 띤 감악산이 보인다. 맑은 날에는 개성의 송악산과 북한산이 보인다.", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 남면, 연천군 전곡읍, 파주시 적성면", + "MNTN_NM" : "감악산" + }, + "longitude" : 126.9689597, + "latitude" : 37.941738699999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "감악산은 치악산 동쪽에 있는 높이 945m의 바위산으로, 정상까지의 산행거리가 짧고 경사도 급하지 않아 초보자도 쉽게 찾을 수 있는 산이다.원주시 신림면. 충북 제천시 봉양읍 경계에 소재, 원주시의 남동단에 위치하고 있으며 치악산과 이웃하고 있어 빛을 보지 못하고 있으나 정상에는 석기암을 잇는 암봉과 암릉이 치악산 못지않는 절경을 지니고 있다.여름철 황둔리에서 황치리로 이어지는 시원한 계곡과 해발 945m의 바위산으로 정상까지의 산행거리가 짧고 경사도 급하지 않아 초보자도 쉽게 오를 수 있어 많은 등반객의 사랑을 받고 있다.정상 밑에는 백련사라는 절이 있으며 이곳까지 길이 잘 뚫려 있어 자동차 통행이 가능하다. 주능선에 우뚝 솟은 암봉들은 올라서기에 다소 위험하지만 굳이 바위에 올라가지 않아도 되므로 무리하게 올라서려하지 않는게 좋다.", + "MNTN_HG_VL" : "945", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면", + "MNTN_NM" : "감악산" + }, + "longitude" : 126.9689597, + "latitude" : 37.941738699999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "감악산" + }, + "longitude" : 126.9689597, + "latitude" : 37.941738699999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "지리산 자락을 밟는 근교산행은 언제나 산꾼들을 설레게 한다. 어디라 할 것 없이 속속들이 드러나 있을 것 같은 이\"어머니산\"의 또다른 속내를 경험해 볼 수 있기 때문이다. 다 같은 무명의 봉우리들이라도 지리산의 혈통을 이어 받았다면 여러가지 면에서 양상이 달라진다. 산의 기세가 다르고, 조망이 다르고, 오르는 사람들의 감흥이 다르다.감투봉,이방산(二方山)은 구곡산 같이 지리산 위성봉으로서 천왕봉 산행이 곤란할때 적절하게 이용할 수 있는 매력있는 산인데 등산로가 명확하지 않아 독도에 자신이 있어야 즐거운 산행이 보장되나 무엇보다 원시림 그대로이기 때문에 매력만점 산행지로는 손색이 없는 산이다.이방산 등산로 입구의 덕교리 마을 앞에는 파구정이란 곳이 있는데 임진왜란 때에 손씨 3형제가 이끄는 의병들이 잠복하였다가 왜적을 맞아서 싸워 이긴 곳으로 왜구를 파멸시켰다고 하여 이런 이름이 유래하였다.삼장면과 시천면 사이에 우뚝 솟은 이방산은 임진왜란 때 의병을 일으킨 유서 깊은 곳으로서 그 발자취가 역력하며, 삼장면 덕교리에서 해발 600미터에 이르는 이방산을 넘어서면 시천면 사리인 마근담에 이르게 되는데 이곳은 웅석봉에서 남으로 뻗은 지맥이 갈라진 골짜기로 인적이 드문 깊은 산골이다.", + "MNTN_HG_VL" : "768", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 시천면 사리", + "MNTN_NM" : "감투봉" + }, + "longitude" : 126.92702130000001, + "latitude" : 37.3404472 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갑장산은 아름다움이 으뜸이요(甲), 사장(四長)을 이룬다는 뜻에서 그 이름이 비롯된 산이다. 고려 충렬왕이 승장사에서 잠시 쉬었다 가며 ‘영남의 으뜸 산’이라 하여 갑장이라 명명했다는 설도 전한다. 상산 삼악의 하나인 연악(淵岳)이라고도 한다. 연악이란 이름은 구룡연에서 유래되었다. 구룡연은 갑장사 뒤 사거리에서 웃승장 방향으로 50미터 정도 내려가면 우측에 있는데, 천제와 기우제를 지내던 신성스런 연못이다. 구룡연에서 북쪽으로 문필봉이 우뚝 솟아 있는데, 바위 3개가 붓처럼 뭉쳐져 있다. 이 문필봉의 정기를 받아 갑장산 주변에 장원급제한 인물들이 많이 나왔다고 하여 장원향이라는 이름을 남기기도 하였다. 용포 쪽에는 백운 이규보가 1196년 요양하며 시를 남긴 용담사터가 있고, 승장계곡에는 옥류정과 승장폭포, 그리고 상주 사장사(四長寺), 갑장사(甲長寺), 승장사(勝長寺), 북장사(北長寺), 남장사(南長寺)) 중 하나였던 승장사터가 있다. 갑장산 정상 부근에는 고려 공민왕 22년(1373) 나옹선사가 창건한 갑장사가 자리 잡고 있다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 지천동, 낙동면", + "MNTN_NM" : "갑장산" + }, + "longitude" : 128.1886111, + "latitude" : 36.347222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갑하산은 계룡산국립공원에 인접해 있는 아기자기한 암릉과 숲이 잘 어우러진 전망이 좋은 산이다. 유성에서 계룡산의 동학사 가는 길목 옆에 자리 잡고 있어 접근하기도 쉽고 산세가 험하지 않아 어느 때 찾아가도 등산의 재미를 만끽할 수 있다. 특히, 봄에는 온 산에 진달래가 붉게 물들고 여름에는 안진바위 골짜기의 넓은 암반과 폭포가 시원하며, 가을 단풍과 겨울의 설경이 아름답다. 산 이름은 옛날에 이 지역이 갑소여서 갑골, 갑동의 지명에서 유래된 듯하며, 이 산은 세 개의 봉우리가 불상을 닮았다고 하여 삼불봉이라고 부르기도 한다. 이 산 아래의 안진바위마을은 조선 태종 임금이 유성에서 목욕을 하고 신도안으로 갈 때 냇가의 바위에서 쉬어 갔다고 해서 유래됐고, 두리봉 아래의 매평마을은 매화낙지형의 명당자리여서 사람들이 모여 살았었는데 현재는 국립대전현충원이 자리 잡고 있다.<>우산봉은 계룡산 천황봉에서 산줄기가 백운봉, 도덕봉을 휘돌아 갑하산을 거쳐 치달리다가 금강에 떨어지기 전에 불끈 솟아 올린 봉우리이다. 이 산의 등마루는 숲과 암릉이 적당히 어우러진 가운데, 특히 소나무가 많아서 걷기가 편하고 봄에는 진달래와 철쭉이 흐드러지게 피어난다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성구·충남 공주시 반포면", + "MNTN_NM" : "갑하산" + }, + "longitude" : 127.27722369999999, + "latitude" : 36.367463499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대구 팔공산 능선에 있는 관봉을 말한다.높이 5.6m의 자연석에 부조한 4.15m의 석조여래좌상을 가리킨다. 부처가 갓을 쓰고있다고 해서 갓바위부처로 불린다. 이 부처의 소속사찰인 선본사 사적기에 따르면 신라 선덕여왕 7년(638년) 원광법사의 수제자인 의현대사가 돌아가신 어머니를 기리기 위해 만든 것이라 한다.", + "MNTN_HG_VL" : "852", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 와촌면", + "MNTN_NM" : "갓바위" + }, + "longitude" : 128.73777670000001, + "latitude" : 35.980165100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운달산과 마주한 높은 계곡이 냉곡이다. 운달산에서 한줄기 내려와 산북면 전두리와 구별하였으며, 산밑에 김룡사가 있다. 김룡사 경내를 통과하여 계곡을 올라서면 정상까지 갈 수 있고 삼각점이 있다. 정상에서 전망이 아주 좋다.김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다.다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다.그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", + "MNTN_HG_VL" : "673", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 김용리", + "MNTN_NM" : "갓산" + }, + "longitude" : 140.02699709999999, + "latitude" : 38.549490599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "순창읍에서 10km의 가까운 거리에 있는 강천산은 호남의 소금강이라고 불릴 정도로 도처에 기봉이 솟아 있고, 크고 작은 수많은 바위 사이로 폭포를 이루고 있으며, 4km에 이르는 깊은 계곡과 계곡을 뒤덮은 울창한 숲은 자연 그대로의 아름다움을 고이 간직하고 있다.원래는 생김새가 용이 꼬리를 치며 승천하는 모습과 닮았다 하여 용천산(龍天山)이라 불렸다. 또한 유서깊은 강천사와 삼인대 5층 석탑, 금성산성 등 문화유적이 산재하고, 비경이 많이 숨겨져 있다. 일명 광덕산이라고도 불리는 강천산은 1981년 국내에서 최초로 군립공원으로 지정된 곳이기도 하며, 길이 76m의 현수교가 지상 50m 높이에 설치돼 있어 웅장함을 더해주고 있다.볼거리는 11월 초순에 절정을 이루는 단풍과 4월 초순에 만개하는 산벚꽃이 유명한데, 산 입구의 강천호 주변뿐 아니라 등산로 어디에서나 즐길 수 있다. 산 암봉 아래에는 887년(신라 진성여왕 1) 도선국사(道詵國師)가 세운 강천사가 있다.이 곳의 석탑은 전라북도 유형문화재 92호로 지정되었고, 절 입구의 모과나무는 전라북도기념물 97호이다. 그 밖에 순창 삼인대(三印臺:전북유형문화재 27), 금성산성(金城山城:전북기념물 52) 등의 문화유적이 있다. 내장산(內藏山:763.5m)·백양사(白羊寺)·담양댐 등과도 가깝다.", + "MNTN_HG_VL" : "586", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 팔덕면, 전라남도 담양군 용면", + "MNTN_NM" : "강천산" + }, + "longitude" : 127.048889, + "latitude" : 35.404167000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "379", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대전", + "MNTN_NM" : "개머리산" + }, + "longitude" : 127.4697881, + "latitude" : 36.387103499999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오대산을 지나 설악산으로 달리던 백두대간이 갈전곡봉에 이르러 서쪽으로 가지를 뻗은 산이 개인산이다.<>개인산은 개인, 삼봉, 방동약수로 유명하며 이 약수 섞인 물은 개인산의 북면을 흐르는 방대천과 서남면을 돌아가 방대천을 합하는 20킬로미터의 내린천으로 흘러들어 차례로 소양강, 북한강, 한강이 된다. 계곡은 수려하나 보이지 않고 산날은 치솟았지만 바위를 드러내지 않는다. 공기 좋고 물이 맑아 전염병이 들지 않고 먹거리가 많다. 입구는 좁고 안은 너른 형세다.<>이런 곳은 여덟 군데 살둔, 달둔, 월둔, 아침가리, 명지가리, 적가리, 곁가리, 연가리의 ‘삼둔오갈’을 두었는데 물, 불, 바람 즉 흉년, 전염병, 전쟁을 피할 수 있는 곳으로 내우외환이 끊이지 않았던 불행한 시대에 개인산은 많은 민추들을 보듬어 주었음을 역사는 전한다. 그리하여 개인산은 지리산과 금강산처럼 장엄하거나 빼어나진 않지만 그 어느 것보다 한국적인 산이다.", + "MNTN_HG_VL" : "1342", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 상남면ㆍ홍천군 내면", + "MNTN_NM" : "개인산" + }, + "longitude" : 128.4002778, + "latitude" : 37.861666700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "449", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "개좌산" + }, + "longitude" : 129.14583329999999, + "latitude" : 35.250555599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "497", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", + "MNTN_NM" : "개천산" + }, + "longitude" : 126.91560149999999, + "latitude" : 34.9044934 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "128", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강서구", + "MNTN_NM" : "개화산" + }, + "longitude" : 126.8038889, + "latitude" : 37.582777800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고성 동쪽의 거류면에 솟은 거류산은 고성의 진산이다. 기암과 청송, 진달래 산성 등 야산이 갖출 수 있는 조건들을 두루 갖추고 있다. 정상 가까이에 약수터가 있고 조망이 일품으로 다도해가 시원하게 보인다. 건너편 들녘에는 구절산이 보이고, 고성 전역과 한려해상의 전경이 한눈에 들어오는 산정에는 2천여 년 전 소가야 때 신라의 침공을 막기 위해 쌓은 거류산성의 흔적이 남아 있다. 이 성은 소가야 마지막 왕이 신라의 침입 때 피신처로 사용하였으나 신라가 가야를 합병함에 따라 폐성되었지만 곳곳에 산성의 자취가 남아 있고, 지금은 유적지로서 복원되었다. 소가야 때는 태조산(太朝山)이라 불렀고 조선 초기에는 거리산(巨吏山)으로, 조선 말엽에 거류산으로 부르게 되었다. 또한 거류산이 깎아지른 듯 삼각형 모양으로 서 있는 모습이 스위스의 마터호른을 닮았다고 해서 일명 고성의 ‘마터호른’으로 불리기도 한다.", + "MNTN_HG_VL" : "572", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 거류면", + "MNTN_NM" : "거류산" + }, + "longitude" : 128.37976710000001, + "latitude" : 34.995313600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "인천대공원 정문을 나와 부평방향으로 가다가 서울외곽순환고속국도를 타기 위해 장수 IC로 들어가면 점점 진입로가 높아지면서 오른쪽으로 군부대유격장이 들어온다. 유격장의 남쪽으로 우뚝 솟아 있는 봉우리가 거마산이다. 유격장이 있는 골짜기를 경계로 남쪽 봉우리를 중심으로 거마산, 북쪽 봉우리가 부천시에 속하는 성주산이다.", + "MNTN_HG_VL" : "214", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 남동구 장수동", + "MNTN_NM" : "거마산" + }, + "longitude" : 126.76766720000001, + "latitude" : 37.471848100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1184", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", + "MNTN_NM" : "거망산" + }, + "longitude" : 127.7369444, + "latitude" : 35.683055600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산곡 버스정류장에서 산곡초등학교 앞을 지나 동쪽 계곡길을 곧바로 올려다 보이는 능선 안부를 향해 올라가면 주능선 안부에 이른다. 여기서 오른쪽(남) 능선을 따라 545봉을 지나 정상에 오르고 서남능선으로 내려간 안부에서 왼쪽 (동남) 계곡길을 따라 과학동에 이른다.", + "MNTN_HG_VL" : "596", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 중부면, 퇴촌면", + "MNTN_NM" : "거문봉" + }, + "longitude" : 126.96611110000001, + "latitude" : 38.702222200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 평창군 용평면과 대화면 사이에 솟아 있는 거문산은 오대산에서 서쪽으로 뻗어 내린 산줄기가 계방산에 이르러 남쪽으로 이어지면서 백적산(1,141m)에서 서쪽으로 가지를 친 능선이 금당산(1,173m)을 빚어 놓고 그 여력으로 우뚝 솟은 산이다. 이 산을 일으키고 남쪽으로 뻗어 내린 지맥은 평창강과 대화천을 가라앉힌다.금당산(錦塘山)·백적산(白積山)·형제봉(兄弟峰) 등과 함께 한국의 척량부(脊梁部)를 이루는 태백산맥(太白山脈)의 일부를 구성한다. 중부지방을 북서쪽으로 흐르는 한강(漢江)의 지류인 평창강(平昌江)의 발원지를 이룬다.", + "MNTN_HG_VL" : "1173", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "거문산" + }, + "longitude" : 129.1552418, + "latitude" : 35.301902699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "기장군 철마면에 위치한 거문산(543m)은 여름 등산지로 권할만한 곳이다.산행을 시작해 1시간이면 정상에 닿을 수 있고 휴식을 포함해 3시간이면 완주할 정도로 코스가 짧은데다 우거진 녹음이 있기 때문이다. 또 사람이 적게 다닌 곳이라 곳곳에 탐스럽게 열린 산딸기를 따먹어 가면서 산을 오르는 즐거움을 맛볼 수 있으며 고사리 같은 산나물이 군락 이룬 자연을 구경할 수도 있다. 하산길에 수십 년된 우리의 전통 초가를 감상할 수 있는 것도 산행재미를 더해준다.", + "MNTN_HG_VL" : "543", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면 웅천리", + "MNTN_NM" : "거문산" + }, + "longitude" : 129.1552418, + "latitude" : 35.301902699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", + "MNTN_NM" : "거열산" + }, + "longitude" : 127.87636500000001, + "latitude" : 35.715445299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "건흥산(乾興山, 572m)과 취우령(驟雨嶺, 792m. 일명 아홉산)은 거창군 거창읍과 마리면의 경계에 자리한 산이다. 거창읍을 한 눈에 굽어보는 산에는 백제 부흥군이 신라에 대항해 싸운 거열산성이 자리하며, 673년에는 신라의 아진함(阿珍含)이 당군과의 싸움에서 장렬하게 전사한 역사의 현장이기도 하다.또 이 산의 서녘자락으로는 위천(渭川)이 흘러간다. 위천은 백두대간 덕유산 주능선의 동녘에서 비롯되는 소정천, 분계천, 산수천, 월성천, 창선천 등 여러 골물이 어우러져 흐른 넉넉한 물길이며 거창을 지나 합천호에 모였다가 다시 황강, 낙동강을 거쳐 남해에 이른다.약수터와 거열산성이 있어 거창군민들의 산책로로 인기 높은 건흥산 정상에 서면 거창군의 첩첩 산들이 이루는 파노라마가 장관이다. 또 멀리 수도-가야산과 지리산, 덕유산 능선도 볼 수 있다.", + "MNTN_HG_VL" : "792", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍, 마리면", + "MNTN_NM" : "건흥산(거열산)" + }, + "longitude" : 127.87636500000001, + "latitude" : 35.715445299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "하남시청에서 동쪽으로 5킬로미터 떨어져 있는 산으로 일설에 의하면 검단선사가 은거하였다 하여 검단산으로 불린다. 산행 초입은 야산과 같아 느낌을 주지만 산 중간쯤 오르면 어느 산 못지않게 뛰어난 숲과 아름다운 풍경과 고사목이 군데군데 널려 있다.정상은 넓은 공터로 사방이 확 트여 있고 팔당댐은 물론, 북한강과 남한강의 합류 지점인 양수리 일대를 시원하게 내려다 볼 수 있으며 예봉산, 운길산, 도봉산, 북한산 등을 조망할 수 있다.검단산 산행 들머리인 배알미동은 ‘도성을 떠나는 사람들이 이곳부터는 임금이 거처하는 곳이 보이지 않거나, 또는 멀리서 도성 근처로 다가오는 길손이 이곳에 들면 임금을 배알할 수 있게 된다’는 설이 전해지는 마을이다. 검단산은 최근에 지어진 ‘통일정사’로 인해 불경을 들으며 산행을 시작할 수 있다.", + "MNTN_HG_VL" : "658", + "MNTN_LOCPLC_REGION_NM" : "경기도 하남시 천현동", + "MNTN_NM" : "검단산" + }, + "longitude" : 127.2472779, + "latitude" : 37.521461799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1017", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", + "MNTN_NM" : "검마산" + }, + "longitude" : 129.233304, + "latitude" : 36.745343099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "검봉은 춘천시 남산면 강촌리 북한강변에 솟아 있으며 구곡폭포로 유명한 봉화산(487m)과 산줄기를 잇고 있다. 봉화산과 이웃해 있어 구곡폭포 방향을 산행 기점으로 삼을 수도 있으나 구곡폭포에서 문배마을에 이르는 널따란 길이 나 있어 산행 첫머리로는 어울리지 않아 강촌리 강선사를 들머리로 하는 것이 보통이다.검봉은 칼을 세워 놓은 것처럼 생겼다고 해서 칼봉으로도 불린다. 또 주위 경관이 아름다워 사계절 내내 많은 관광객이 찾고 있으며 특히 겨울철에는 빙벽 교육 장소로도 인기 있다.강촌역 뒤 강선사로 오르면 첫 번째 봉우리에서 오른쪽으로는 의암호가 보이며 왼쪽으로는 경기도와 경계 지점인 도계휴게소 및 강촌휴게소가 보인다. 아득하게 보이는 발아래 경치를 감상 한 뒤 능선을 따라 2~3시간 정도 오르면 아홉 구비 계곡을 돌아 볼 수 있는 구곡정이 나타나며 50여 미터 높이의 구곡폭포에서물안개를 일으키며 떨어지는 물줄기가 보인다.", + "MNTN_HG_VL" : "530", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", + "MNTN_NM" : "검봉" + }, + "longitude" : 127.5986521, + "latitude" : 37.805322400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "530", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "검봉산" + }, + "longitude" : 127.5986521, + "latitude" : 37.805322400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "804", + "MNTN_LOCPLC_REGION_NM" : "", + "MNTN_NM" : "견두산" + }, + "longitude" : 127.4004582, + "latitude" : 35.347366200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "804", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시, 전라남도 구례군", + "MNTN_NM" : "견두산" + }, + "longitude" : 127.4004582, + "latitude" : 35.347366200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 포천군과 가평군의 경계를 이루는 지점에 위치한 산으로 경기도내에서 아주 드물게 1000미터급 산이 즐비한 곳이기도 하다. 명지산, 귀목봉, 민둥산, 개이빨산(견치봉), 국망봉, 광덕산등의 1000미터급 산과 청계산, 강씨봉, 신로봉, 가리산, 백운산등 8-900미터급의 산들이 뒤를 잇는다.", + "MNTN_HG_VL" : "1120", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면\/가평군", + "MNTN_NM" : "견치봉" + }, + "longitude" : 127.4186675, + "latitude" : 38.013648500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "호남정맥의 마루금에 위치한 경각산은 구이저수지 서쪽에서 모악산을 마주보며 우뚝 솟아있다. 경각산(鯨角山)의 한자 그대로 고래등에 난 뿔처럼 생긴 두 개의 바위가 정상부에 솟아, 산 아래에서 바라보면 모악산 방향으로 머리를 둔 고래의 모습과 흡사하다. 이 때문에 어머니를 상징하는 모악산과 달리 경각산은 남성을 상징한다.산 정상에서는 전주와 익산 시내, 미륵산, 고덕산, 마이산, 오봉산이 선명하게 보인다. 특히 가을 단풍과 겨울 선경으로 이름 높지만, 모악산에 비해 상대적으로 덜 알려져 있어 주말에도 호젓한 산행을 할 수 있다. 패러글라이딩 활공장이 있어 날씨가 좋은 날에는 하늘 높이 날아가는 패러글라이딩의 모습도 볼 수 있다.경각산 아래 정각사는 고려말기에acirc;건된 태고종 사찰로 많은 고승들의 수도oacute;가 되었다고 전해진다.", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 신덕면", + "MNTN_NM" : "경각산" + }, + "longitude" : 127.15733539999999, + "latitude" : 35.728343799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군,임실군", + "MNTN_NM" : "경각산" + }, + "longitude" : 127.15733539999999, + "latitude" : 35.728343799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경운산(慶雲山)은 남으로 주촌 고개에서 북으로 삼계로타리(14번 국도)까지 4.9Km로주촌면, 내외동, 삼계동을 포함한 전형적인 시내 근교 산으로 많은 시민들이 체육공원겸 당일 산행지로 애용하고 있는 산이다. 산 정상은 해발 378m로 크게 높지 않으나 김해 시내와 주촌, 칠산, 장유면과 멀리부산시까지 한 눈에 발라볼 수 있어 전망이 확 트인 시원한 산이다. 동으로는 수인사, 경원사등 사찰과 유치원, 초.중학교가 있으며 서로는 선지사, 태안사등 많은 사찰과 자연 부락을 안고 있다. 이 산은 2002년 국립지리원에서 발행한(1:50,000 지형도)에는 競雲山으로 표기되어있으며\"신동국여지승람\"에서는 운참산(雲站山)으로 불리었다. 조선 전기까지 운참사(雲站寺)가 있었다는 기록이 있으나 지금은 사찰터를 찾지 못하고 있다.", + "MNTN_HG_VL" : "378", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", + "MNTN_NM" : "경운산" + }, + "longitude" : 128.85577259999999, + "latitude" : 35.250136099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "몽덕산(680m)에서 뻗어 내린 능선이 가덕산(858m),북배산(867m)을 일으키고 싸리재를 지나 서남쪽으로 이어지는 능선에 우뚝 솟아 있는 계관산은 강원도 춘천시 서면과 경기도 가평군 북면의 경계를 이루는 산이다.몽덕산에서 계관산으로 이어지는 주능선 마루에는 폭 20여 미터에 방화선이 만들어져 있는데 이곳에 억새풀이 빼곡이 들어 서 있다. 가을이면 황금빛으로 물들어 산행 재미를 더해 준다. 정상에 서면 북으로는 북배산, 그 뒤로 가덕산과 몽덕산이 가까이 보이고, 그 오른쪽으로 용화산과 오봉산이 한눈에 들어오며, 동쪽 발 아래로는 물위에 떠 있는 듯한 춘천시내와 의암호가 거울처럼 보인다.서북쪽으로는 구나무산, 월출봉, 백둔봉, 명지산, 수덕산, 화악산 등의 산맥이 줄지어 솟아 있다.", + "MNTN_HG_VL" : "736", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 강원도 춘천시", + "MNTN_NM" : "계관산" + }, + "longitude" : 127.6083333, + "latitude" : 37.883055599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "계룡산은 백두대간에서 갈라져나온 금남정맥의 한 줄기를 이루는 산으로, 충남 공주시와 논산시의 경계를 이루고 있다. 산세가 마치 닭의 벼슬을 쓴 용의 형상을 했다고 해서 계룡산으로 불리게 되었다고 한다.계룡산은 조선조 초기에 씌어진 예언서인 〈정감록〉의 `왕도입지설'로 유명한 산으로,정상인 천황봉(天皇峰)을 중심으로 쌀개봉(830.6m), 관음봉(765.8m), 문필봉(735.6m), 삼불봉(777.1m), 연천봉(742.9m)이 주능선에 줄지어 솟아 있다. 계룡산 산자락 곳곳에 문화 유적이 산재해 있는데, 동북쪽에는 동학사가,서북쪽에는 갑사가,서남쪽에는 신원사 사찰이 자리잡고 있다. 특히 갑사에는 보물 제257호인 부도(浮屠)와 보물 제256호인 철당간 및 지주.보물 제478호인 동종(銅鐘)등의 문화재가 있으며, 〈월인석보〉를 찍어낸 목판도 소장되어 있다. 〈월인석보〉는 세종29년(1447년)에 간행된 〈석보상절〉과 세종 31년에 간행된 〈월인천강지곡〉을 합편하여, 세조가 1459년에 간행한 것이다.상봉을 중심으로 동쪽에 동학사, 서쪽에 갑사, 남쪽에 신원사가 자리하여 현재까지도 보존되고 북쪽의 구룡사는 절터만 남아 있다. 계룡사에는 노루, 담비, 청설모, 황매화 등 희귀 동.식물 1227종이 서식하고 있으며, 계룡 8경으로 꼽히는 천황봉(일출), 삼불봉(설화), 연천봉(낙조), 관음봉(한운), 동학계곡(신록), 은선폭포(운무), 갑사계곡(단풍), 남매탑(명월) 등은 울창한 숲과 기암절벽을 더불어 장관을 이루고 있다.", + "MNTN_HG_VL" : "847", + "MNTN_LOCPLC_REGION_NM" : "대전광역시, 충청남도 공주시 계룡면ㆍ논산시 상월면ㆍ계룡시 신도안면", + "MNTN_NM" : "계룡산" + }, + "longitude" : 127.20583329999999, + "latitude" : 36.342500000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제주도에 이어 두 번째로 큰 섬인 거제도는 총 면적 399.3㎢에 부속 섬 60여개를 안고 있는 큰 섬이다. 거제도에는 계룡산을 비롯하여 옥녀봉(555m),산방산(507m), 노자산(565m), 앵산(507m) 등 500m급의 크고 작은 산들이 솟아 있다.주능선에 용이 승천하는 듯한 형상의 바위가 솟아 있어 계룡산이라 이름 붙여진 이 산은 봄에는 진달래, 가을이면 억새로 비경을 자아내고 있다.이곳 향토사학자들은 '계룡산하 구백만(鷄龍山下 九百萬)'이라고 표현한 〈정감록〉의 계룡산은 거제도에 있는 계룡산을 말한다고 주장하고 있다. 6.25때 충청도 계룡산에 피난 갔던 수많은 사람들은 피해를 입었지만, 이곳 거제 계룡산은 많은 주민과 피란민, 포로들까지 피해를 입지 않은 곳이었기 때문이라 한다.", + "MNTN_HG_VL" : "845", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", + "MNTN_NM" : "계룡산" + }, + "longitude" : 127.20583329999999, + "latitude" : 36.342500000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "566", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 신현읍, 거제면", + "MNTN_NM" : "계룡산" + }, + "longitude" : 127.20583329999999, + "latitude" : 36.342500000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "775", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "계명산" + }, + "longitude" : 127.977, + "latitude" : 36.989999999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "양주군 백석면과의 사이에 있는 해발 622미터의 아담한 높이의 산으로, 고찰인 보광사가 있기도 하다.평평한 산 정상에서 바라보면 북으로 파주군과 양주군의 나지막한 산들이 건너다 보이고, 동쪽으로 죽 늘어선 불국산, 사패산, 도봉산 암봉, 남쪽으로 북한산 백운대의 당당한 모습이 보인다.산행은 보광사에서 시작하여 도솔암을 오른 후 헬기장을 거쳐 정상에 오른 후, 서릉을 거쳐 보광사로 하산하는 것이 좋다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 석현면", + "MNTN_NM" : "계명산" + }, + "longitude" : 127.977, + "latitude" : 36.989999999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "계명산은 충주시내 동복쪽에 위치하여 마즈막재(620m)를 사이에 두고 동남쪽의 남산(636mㆍ금봉산)과 더불어 충주시를 두팔로 감싸 안듯 병풍을 두르고 있다. 또한 충주댐을 끼고 있어 산 위에 올라서면 충주호가 굽어보이고 월악산의 선경이 호반 위로 펼쳐진다. 충주시내가 가깝기 때문에 시민들이 많이 찾는 도심의 산이다.산 이름과 관련해 다음과 같은 유래가 전한다. 충주가 삼국시대 백제 영토로 있을 때였다. 왕족을 자칭하는 성주가 마고성의 성주도 겸하며 충주읍성(예성) 내관과의 왕래가 잦았다. 그러던 어느날 마고성주의 딸이 심항산 밑을 지나다가 지네에게 물려 갖은 약을 다 써봤으나 상처가 악화되어 죽고 말았다. 그날부터 성주는 관민들에게 지네를 모두 잡아 치우라고 명을 내렸지만 그 피해가 날로 심해졌다. 성주는 하는 수 없이 심항산 마루에 제단을 설치하고 매일 정심기도를 올렸다. 그러던 어느날 꿈에 용두백발을 한 신선이 나타나 “지네는 닭과 상극이니 많은 닭을 산에 방목하라 그러면 근절시킬 수 있을 것이다.”하고 일렀다.성주는 많은 닭을 방목했고 지네가 근절됐다. 그러나 또다시 지네가 번성할까 두려워 계속 닭을 놓아기르니 산 곳곳에 닭이 밟지 않은 데가 없었다. 그래서 원래 오동산, 심항산 등으로 불리던 이름이 계족산이라 부르게 됐는데 풍수설에 충주에 큰 부자가 안 나는 것은 계족산이 닭발의 형상이고 분산을 뜻한다고 해 1958년 충주시에서 산 이름을 여명을 알리는 뜻의 계명산으로 개칭했다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "충북 충주시 안림동ㆍ용탄동ㆍ종민동", + "MNTN_NM" : "계명산" + }, + "longitude" : 127.977, + "latitude" : 36.989999999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고고산은 강원도 영월군 영월읍 문산리와 중동면 연하리, 정선군 신동읍 고성리와 경계를 이루며 동강변에 솟아 있는 산이다.설악산 용아름의 축소판인 암릉은 이 산의 백미로 구들장 같은 바위들이 층층이 쌓여 있고 암릉 위에는 분재와 같은 노송들이 뿌리를 내려 거대한 한 폭의 동양화를 연상하게 한다. 북릉을 타고 전망바위 정상에서 북으로 보면 신병산과 능암덕산이 마주 보이고 오른쪽으로는 백운산과 곰봉 사이를 가로 지르는 동강이 조망된다.", + "MNTN_HG_VL" : "854", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군, 정선군", + "MNTN_NM" : "고고산" + }, + "longitude" : 128.57913009999999, + "latitude" : 37.220578799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경원선 철도가 휴전선에 막혀 더 이상 달리지 못하고 멈추는 곳에 고대산이 솟아 있다. 고대산은 등산객들이 자유롭게 산행을 할 수 있는 산 중에서 휴전선에 가장 가깝게 위치해 있는 산이다. 경기도 최북단인 연천군 신서면 신탄리와 강원도 철원군 사이에 있는 고대산 정상에서는 북녘의 철원평야와 6·25 때 격전지인 백마고지, 금학산과 지장봉, 북대산, 향로봉은 물론 한탄강 기슭의 종자산까지 한눈에 들어온다. 분단의 한, 망향의 한이 굽이쳐 북녘이 그리울 때, 멀리서나마 북녘땅을 바라볼 수 있는 3대 명산으로 고대산, 복계산, 지장봉을 꼽는데 해마다 6월이면 분단 상황을 체험해 보려는 많은 등산인들이 고대산을 찾는다. 수려한 전망과 적당한 코스 등 최적의 산행코스를 갖췄음에도 전략적 요충지라는 이유로 웬만한 지도에는 감춰진 산이다. 휴전선과 가장 가까운 곳에 있기 때문에 여태껏 사람들에게 잘 알려지지 않았다는 것이 이 산이 간직한 매력이기도 하다.", + "MNTN_HG_VL" : "832", + "MNTN_LOCPLC_REGION_NM" : "경기도 연천군 신서면·강원도 철원군 철원읍", + "MNTN_NM" : "고대산" + }, + "longitude" : 127.1549062, + "latitude" : 38.198599399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "고덕산" + }, + "longitude" : 127.1788889, + "latitude" : 35.772222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고덕산은 전주시 남동쪽에 있는 산으로 등산인들에게 잘 알려져 있는 명산은 아니지만 전주시민들에게는 더할 나위 없이 좋은 휴식공간을 제공한다. 산자락에 남고산성, 남고사, 만경대, 관성묘 등의 많은 유적들을 품고 있는 산이기도 하다.산행 들머리는 관성묘 입구 마을로 한다. 삼경사 갈림길 능선을 따라 오르는 등산 코스는 오가는 이들이 적어 호젓하게 산행을 즐길 수 있다. 능선을 따라 오르면 산성터가 나타난다. 남고산성은 고덕산과 천경대, 만경대, 억경대 등 봉우리를 이어쌓은 산성이다. 남동쪽으로는 남원, 고창으로 통하는 교통상의 중요한 곳을 지키고, 북쪽으로는 전주를 내려다 보는 자리에 위치하고 있다.후백제를 세운 견훤이 이곳에 고덕산성을 쌓았다는 이야기가 전해오며, 조선 순조 13년(1813)에 성을 고쳐 쌓고 남고산성이라 했다. 이 성은 유래가 매우 오래된 것으로 알려져 있는데, 「세종실록지리지」와 「동국여지승람」에도 기록이 보인다. 순조 13년에 보수공사를 할 때 성 안에는 4개의 연못과 25개의 우물이 있었으며, 민가 100여 채가 있었다고 한다. 서쪽에는 비밀문이 하나 있었으며 동서남북에 각각 하나씩 포루가 설치되어 있고, 관청, 창고, 화약고, 무기고를 비롯한 각종 건물이 많았다.정상은 널따란 헬기장으로, 북서쪽으로는 전주시가지가 내려다보이며 운장산, 만덕산, 모악산 등이 고덕산을 감싸 듯 둘러 서 있다.", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전북 전주시 완산구, 완주군 구이면ㆍ상관면", + "MNTN_NM" : "고덕산" + }, + "longitude" : 127.1788889, + "latitude" : 35.772222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고두산은 더덕이 많고 사람들에게 잘 알려지지 않은 전형적인 강원지방 산이다. 이 산은 특히 산더덕이 풍부한데 정상방면 능선은 온통 더덕 향이다. 곳곳에 수북히 쌓인 멧돼지 배설물도 이 산이 인적이 드문 깊은 산임을 알게 한다.산이 깊은 탓에 고두산은 조망이 그리 좋지는 않다. 특히 정상은 굴참나무가 빽빽이 들어서 있어 주위를 둘러보기 힘들다. 대신 약수봉 전망바위가 정상의 조망을 대신한다. 북으로 보이는 금당산과 금당산 아래로 흐르는 평창강과 아찔하게 펼쳐진 금당계곡이 시원함으로 다가온다.", + "MNTN_HG_VL" : "1030", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면", + "MNTN_NM" : "고두산" + }, + "longitude" : -72.60738649999999, + "latitude" : 41.833431300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "계방서정맥(桂芳西正脈)이라 불리는 산줄기 도미(掉尾)를 장식하며, 경기의 곡창지대인 여주 들녁에 우뚝 서 한 바다에 고래 등처럼 떠 있는 이산은 '고달산(高達山)'으로 불리기도 하며, 예로부터 고려장을 하던 '고려산'으로 불리었다.서남쪽으로 위치한 우두산(牛頭山) 남쪽에 사적 제382호로 지정된 '고달사지(高達寺址)'라는 사적지를 가지고 있으며, 금동마을 뒤쪽으로는 고려장 굴이 있어 옛 고려장 관습에 흔적을 가지고 있는 산이다.산세는 육산으로 가파른 경사를 이루고 있으며, 지제면 대평리쪽은 골프장 개발공사로 자연이 훼손되고 등산로가 없어졌으므로 여주 북내면쪽으로만 산행이 가능하다. 고달사지는 국보 제4호로 지정된 고달사부도를 위시해, 보물 3점, 향토유적지등이 있어, 산행과 문화재 탐방을 함께 할 수 있는 산이다.", + "MNTN_HG_VL" : "543", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면, 양평군 지제면", + "MNTN_NM" : "고래산" + }, + "longitude" : 127.658602, + "latitude" : 37.417704200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙조를 찾아 떠날 산행지는 요즘 들어 일몰 관광지로 인기를 끌고 있는 강화도 고려산(高麗山)이다. 고려산은 읍내에서 5킬로미터쯤 떨어져 있으며 원래 이름은 오련산이었으나 고려가 몽고의 침략을 받아 도읍을 강화로 천도하면서 송도의 고려산 이름을 따 고려산으로 고쳐 부르게 되었다고 한다. 또한, 고려산은 연개소문이 태어난 곳이라는 전설이 있으며 주능선에 오르면 탁 트인 서해 바다의 시원스런 조망은 물론, 황해도의 연백군 해안과 예성강 하구를 조망할 수 있어 민족분단의 현실을 직접 눈으로 확인 할 수 있는 곳이기도 하다. 현재 고려산에는 백련사, 청련사, 적석사, 원통암 등 세 개의 사찰과 한 개의 암자가 있다. 그 중 청련사의 분위기가 제일 뛰어나나 남향에 자리한 사찰 전등사 역시 이에 뒤지지 않을 만큼 그윽하고 멋스러운 풍경을 자랑한다. 적석사 서쪽 절 정상 낙조봉에서 바라보는 서해 일몰은 강화 8경 중 하나로 꼽힌다. 게다가 인천시 기념물 제26호로 지정되어 있는 고창, 화순의 고인돌군도 만나 볼 수 있어 아이들과 함께 하는 가족산행지로 더 없이 좋은 곳이다.", + "MNTN_HG_VL" : "436", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 강화읍, 하점면, 송해면, 내가면", + "MNTN_NM" : "고려산" + }, + "longitude" : 126.4372675, + "latitude" : 37.744586699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "예로부터 신령스런 산으로 여겨왔던 고령산은 숲이 울창하지는 않지만 봄과 가을이면 능선 따라 꽃과 단풍이 고와 분위기 있는 등산을 즐기기 좋다. 파주시 광탄면 기산리와 영장리, 장흥면 석현리, 양주시 장흥계곡에 걸쳐 있으며, 숲이 울창하게 우거져 있다. 높이가 별로 높지 않으나, 경기도 북서지역에서는 감악산(675m)과 더불어 가장 높은 산으로 꼽힌다. 북쪽으로 양주시가, 남쪽으로 북한산 백운대가, 동쪽으로 불국산, 사패산, 도봉산 등의 봉우리가 있다.산 아래에 있는 보광사는 894년(진성여왕 8) 도선국사가 왕명으로 창건하였고 임진왜란 때 소실되었다가 여러 차례 중수하였다. 1634년(인조 9년)에 주조된 범종이 크기는 작지만 화려한 모습을 띄고있어 조선조 시대의 범종 양식을 잘 보여준다. 산기슭에는 도솔암이 있는데, 말 그대로 소나무로 둘러싸인 암자이다. 도솔암에서 조금 더 오르면 정상이다. 정상은 평탄한 공터이며, 북쪽으로 감악산이 보인다. 정상 남쪽의 봉우리는 군사지역으로 산행할 수 없다.고령산은 1634년에 주조한 보광사 범종과 조선 후기에 편찬된 《양주목읍지》에 각각 고령산(高嶺山)과 고령산(高靈山)으로 기록되어 있어 높고 신령스러운 산으로 여겼음을 알 수 있다. 산정에서 북서편으로 능촌교를 지나면 영조대왕의 생모인 숙빈 최씨의 묘소인 소령원(昭岺園)이 있다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 장흥계곡", + "MNTN_NM" : "고령산" + }, + "longitude" : 126.92749999999999, + "latitude" : 37.7575 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고루포기산은 강원도 강릉시 왕산면과 평창군 도암면의 경계를 이루는 산으로, 주변의 발왕산, 제왕산, 능경봉의 명성에 가려 찾는 이들이 많지 않았던 산이다.태백산맥의 지맥인 해안 산맥에 딸린 산으로, 북서쪽의 빗면은 한때 대관령 스키장이 있었던 곳이다. 부근의 횡계리(橫溪里) 일대는 평탄면을 이룬다.서쪽에는 남한강의 지류인 송천(松川)이 감입곡류를 이루면서 남쪽으로 흘러 하안단구를 이룬다. 북동쪽 빗면으로 흐르는 수계는 왕산면 왕산리(旺山里)에서 강릉 남대천(南大川)의 지류로 흘러든다.", + "MNTN_HG_VL" : "1238", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "고루포기산" + }, + "longitude" : 128.73346340000001, + "latitude" : 37.647446599999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고리봉은 전북 남원시 주생면ㆍ금지면ㆍ대강면에 자리잡고 있는 호남정맥의 줄기다. 지리산을 지척에 두고 맥을 달리하는 바위산으로 곡성에서 남원 방향으로 향하다보면 금지들이라 불리는 평원에서 옹골차게 솟은 산이다.골산(骨山)의 전형을 보여주는 고리봉의 이름은 소금배를 묶어두었던 ‘고리(還)’에서 유래한다. 지금 남원 시내를 관통하며 흘러내리는 요천은 남원 관광단지 앞 물줄기만 둑을 쌓아 뱃놀이가 가능하지만, 100여 년 전까지만 해도 하동을 출발한 소금배가 섬진강에 이어 요천 물줄기를 거슬러 남원성 동쪽 오수정(참나무정)까지 올라와 닻을 내렸다고 한다.당시 소금배가 중간 정박지로 금지평원에 머물기 위해 배 끈을 묶어두었던 쇠고리를 바로 고리봉 동쪽 절벽에 박아 놓았다는 것이다. 이렇게 소금배와 얽힌 전설이 전하는 고리봉은 조망도 좋지만 산세가 뛰어난 산이다. 동서 양쪽 사면은 거대한 바위 병풍을 연상케 할 만큼 웅장한 산세를 과시하고, 능선은 소나무가 울창한 가운데 부드러운 육산과 아기자기한 암릉이 번갈아 이어져 산행의 즐거움까지 더해진다.", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "전북 남원시 주생면ㆍ금지면ㆍ대강면", + "MNTN_NM" : "고리봉(두리봉)" + }, + "longitude" : 127.5351143, + "latitude" : 35.377140400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "153", + "MNTN_LOCPLC_REGION_NM" : "전라북도 군산시", + "MNTN_NM" : "고봉산" + }, + "longitude" : 126.79034540000001, + "latitude" : 37.692349399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "크게 화려하거나 요란하지 않지만 그런 대로 쏠쏠하게 볼거리가 있고 전망도 좋은 산이다.해발 500여 미터정도의 나지막한 산이지만 정상에 오르면 멀리 영광쪽 바다에 배가 떠다니는 모습이 보이고 무등산을 물론 광주시내까지도 조명할 수 있는 산이다. 광주에서 거리도 그리 멀지 않아 당일치기로 다녀와도 무리가 없다. 작은 규모에 비해 등산로는 꽤 가파른 편이며 아기자기한 암벽미도 그만이다.", + "MNTN_HG_VL" : "98", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 성송면\/전라남도 장성군 삼계면 부성리", + "MNTN_NM" : "고성산" + }, + "longitude" : 127.17472220000001, + "latitude" : 37.048333300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "186", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군간성읍 금수리", + "MNTN_NM" : "고성산" + }, + "longitude" : 127.17472220000001, + "latitude" : 37.048333300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "546", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", + "MNTN_NM" : "고성산" + }, + "longitude" : 127.17472220000001, + "latitude" : 37.048333300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;계곡과 억새로 유명한 영남알프스의 산gt;이른바 '영남알프스'는 억새산행으로 유명한 산군이다. 취서~신불산 구간이 그렇고, 재약산 사자평이 그렇다. 당연히 가을이 되면 많은 등산인들이 몰린다. 고헌산(1032.8m)은 이 산군에 속하면서도 동쪽에 치우쳐 있다. 유명한 비구니사찰인 석남사를 품고 있는 가지산(1240m)이 바로 옆에 있어 언양에서 들어선 등산인들은 대부분 가지산으로 몰리기 마련이다. 그렇기에 고헌산은 오히려 호젓한 억새산행을 만끽할 수 있는 대상 산이다. 뿐만 아니라 고헌산 대통골은 더위만 살짝 앗아갈 적당한 온도의 계곡물, 암벽등반의 묘미도 함께 즐길 수 있는 곳이다. 반면 경험자의 안내와 암벽등반 장비가 필요하다. 계곡 옆으로 우회로가 있어 위험한 구간은 돌아가면 되지만 긴장을 늦추어서는 안 된다. 대통골 초입은 강산교라는 작은 다리를 지나자마자 사방댐 표석이 있는 곳이나 다리 위에 새로 지은 전원주택을 돌아가면 보인다. 2시간 정도 걸리는 계곡갈림길까지가 좋다. 갈림길에서 왼쪽 계곡을 100m 정도 올라 오른쪽 능선을 타고 주능선으로 가길 권한다. 더 올라가면 계곡이 음습하고 암벽들도 어려워진다. 딱히 돌아갈 만한 길도 없고 낙석의 위험도 있다.", + "MNTN_HG_VL" : "1033", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 언양읍, 상북면, 두서면, 경북 경주시 산내면", + "MNTN_NM" : "고헌산" + }, + "longitude" : 129.08707190000001, + "latitude" : 35.646332800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1033", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 언양읍, 상북면, 두서면, 경북 경주시 산내면", + "MNTN_NM" : "고헌산" + }, + "longitude" : 129.08707190000001, + "latitude" : 35.646332800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "억새군락으로 유명한 영남알프스로 불리는 7개 산 중 하나인 고헌산은 경부고속국도 언양IC에서 서북쪽에 솟아 있는 산이다. 서쪽으로 영남알프스 산 중 가장 높은 가지산과 가까이 있다. 산 동쪽 아래에는 사연댐이 있다.고헌산은 상북면과 언양읍 두서면의 경계를 이루고 있는 높은 산이다. 태양을 숭배하는 민족들한 발자국이라도 태양에 가까운 높은 산은 태양신에 접근하기 쉬운 것으로 생각하였으며 또 하늘의 신이 하계 할 때는 하늘에 가까운 높은 산으로 내려오는 것으로 믿고 있었다. 이 고헌산은 언양 사람들이 가뭄이 되면 기우제를 지내던 곳이기도 한데, 기우제를 지내는 것은 비가 내리고 안 내리는 것이 오로지 신의 작용에 의한 것이라 믿는 우주관에서 비롯된 것이라 할 수 있다. 그들은 용샘이 있는 높은 정상에서 부정을 피해 하늘과 산신과 비를 다스리는 용신에게 정성껏 비를 빌었다한다.경부고속도로 언양 IC에서 서북방향으로 9㎞ (석남사길)쯤 들어간 장성리 쪽에서 북으로 보이는 산으로 서쪽으로 가지산이, 남으로는 신불산 간월산과 영취산(취서산)이 이어져 있으며, 산꼭대기는 돌멱으로 이루어져 있으며, 산 아래 동쪽에는 사연댐이 있다.", + "MNTN_HG_VL" : "1033", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 두서면, 경상북도 경주시 산내면", + "MNTN_NM" : "고헌산" + }, + "longitude" : 129.08707190000001, + "latitude" : 35.646332800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "곡달산" + }, + "longitude" : 127.4664193, + "latitude" : 37.657477 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "곡달산이 자리한 설악면은 경기도에서 오지다.ucirc;평호수와 용문산 줄기가 감싸는 곳에 마을이 형성되어 교통이 불편하고 접근하기가 쉽지 않다. 경춘국도에서ucirc;평댐을 건너 이십리를 달리면 솔치재가 나온다. 이 고개에서 오르는 코스가 가장 무난하다.otilde;otilde;히 오른다 해도 정상까지 두 시간이면 충분하다.산행에 들기 전에 물을 준비하는 것을 잊지 말아야 한다. 솔치재 휴게소나 서쪽의 도로를 따라가다가 작은 개울에서 물을 구할 수 있다. 곡달산 산행 중에는 샘이라고는atilde;을 수 없다. 한우재에서 오를 수도 있으나 정상까지 비탈을 오르는 단조로움이 있다.정상에 오른 후 솔고개로 하산하거나 금강사로 하산할 수 있다. 금강사 쪽에서 오를 수도 있겠으나 골프장이 생긴 후로 다니는 사람이 드물다. 지금 한acirc; 공사중인 동서고속도로가 준공되고 설악면 나들목이 생기면 이 산은 서울에서 30분도 안 걸리는 서울 근교의 산으로 각광받을 것으로 보인다. 힘들지 않게 봉우리를 오르내릴 수 있어 가족 산행이나 실버 산행지로 권할 만하다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", + "MNTN_NM" : "곡달산" + }, + "longitude" : 127.4664193, + "latitude" : 37.657477 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "715", + "MNTN_LOCPLC_REGION_NM" : "전라남도 곡성군 오곡면", + "MNTN_NM" : "곤방산" + }, + "longitude" : 128.99863020000001, + "latitude" : 37.713526999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 영월군 하동면 와석리 곡골 동쪽에 우뚝 솟은 곰봉은 산자락 곳곳에 산나물이 즐비하게 자생할 정도로 오염되지 않은 청정지역이다. 곰봉 정상에는 돌을 고여놓고 가마솥을 얹어 놓은 듯한 형상인 자동차 크기의 바위가 세 개 놓여 있다. 정상에 곰 모양의 바위가 있어 곰봉이라 부른다.국립지리원에서 발행한 지형도에 마대산은 표기되어 있으나 곰봉은 이름도 없이 산을 의미하는 기호에 산 높이만 적혀 있다. 이 산은 마대산보다 암릉이 잘 발달되어 있어 전망이 좋다. 암릉에는 소나무가 우거져 있으며, 그 뒤로는 산들이 첩첩하게 서 있어 매우 아름답다.산행은 희귀한 민화를 전시하고 있는 조선민화박물관을 출발하여 암릉을 타고 올라 855m 봉우리에서 시루봉을 지나 정상에 오른다.", + "MNTN_HG_VL" : "1015", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "곰봉" + }, + "longitude" : 128.65944440000001, + "latitude" : 37.2841667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "공덕산은 백두대간이 포암산(961)과 조령산(1017)으로 남하하다가 대미산에서 지맥을 갈래쳐 여우목고개를 지나 일군 산이다. 교통이 불편해 아직 원시림 그대로의 거친 수림을 간직한 산으로 산 중턱 바위사면에 불상이 조각되어 있어 사불산이라고도 불린다.이름에서도 불교적 색채를 느낄 수 있듯이 이 산은 불교를 전파한 고승들과 오랜 인연을 맺고 있다. 신라 진평왕때 창건된 대승사는 1400여년의 역사를 지켜오면서 수많은 고승대덕을 배출하였다. 대웅전에는 보물 575호인 목각탱화와 관련문서가 모셔져 있고 선실에는 보물 991호인 금동보살좌상이 있다.또 멀지 않은 거리에 비구니승들의 수도처인 윤필암이 있어 쉬엄쉬엄 오르는 수행코스로도 손색이 없는 산이다.등산로 입구에는 옛날 중국을 다녀온 나옹이 기념으로 심었다는 아람드리 전나무가 반겨주고 산행내내 아람드리 참나무와 소나무가 반겨주는산, 종주중 반정도는 육산으로서 울창한 나무숲에 가려 원시림은 때묻은 속세의 모든 일들을 잊어버리게 하고 나머지 반은 노송과 함께 어우러진 암릉길은 속세에 나가 어려운 풍파를 헤쳐나가기 위하여 사전 수련을 하듯이 전개되는 바위길의 묘미를 볼 수 있는 산이다.즉 육산과 바위산위 공존하는 산으로 대승사에서 남쪽 능선을 따라 공덕산 823봉까지는 길이 아주 좋은 육산으로 울창한 숲에 가려 조망이 없어 실망을 하는 산이나 823봉부터 윤필암 하산길 까지는 노송과 바위가 어울려 한폭의 동양화를 연출하는 상반된 얼굴을 보이는 산이다.", + "MNTN_HG_VL" : "913", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 동로면", + "MNTN_NM" : "공덕산" + }, + "longitude" : 128.2832276, + "latitude" : 36.7557683 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "공덕산은 경북 문경시 산북면과 동로면의 경계를 이루는 산이다. 주능선은 백두대간 포암산(961m)과 조령산(1017m)으로 뻗어 내리다가 대미산(1115m)에서 지맥이 갈라져otilde;주봉(842m)과 함께 나란히 우뚝 솟아올라 있다.이 산은 지형도상의 공덕산뿐만 아니라 예전부터 사불산(四佛山)이라고도 불리는 산이다. 공덕산 정상에서 서쪽으로 능선을 따르다 832미터 봉에서 윤필암으로 내려서는 능선에 네 면에 불상이 새겨진 바위가 있어 사불암이라 했고, 사불산이라 불리게 되었다고 한다.이름난 산에는 이름난 절이 있기 마련이듯 공덕산에도 예외는 아니다. 신라 진평왕 9년(587년)에acirc;건되어 많은 고승대덕을 배출한 대승사가 그렇다. 비구니스님들의 수도oacute;인 윤필암, ‘ucirc;산은 나를 보고 말없이 살라 하고\/acirc;공은 나를 보고 티 없이 살라하네’로 시작하는 선시를 지은 나옹선사가 득도하였다는 묘적암, 보현암을 부속암자로 거느리고 있는 거찰들이 있다.", + "MNTN_HG_VL" : "913", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면ㆍ동로면", + "MNTN_NM" : "공덕산" + }, + "longitude" : 128.2832276, + "latitude" : 36.7557683 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "공작산은 강원도 홍천군 동면과 화촌면의 경계를 이루는 산으로, 공작이 날개를 펼친 듯한 산세에 암봉과 노송이 어우러져 한 폭의 동양화를 연상케 하는 산이다.정상에서 서남쪽 능선을 따라 6km 산자락에 있는 수타사에서 노천리에 이르는 약 8km길이의 수타계곡은 암반과 계곡의 경치가 뛰어나 여름철 계곡 피서지로 이름난 곳이다. 정상에서 바라보면 홍천군 일원이 한눈에 들어오며, 풍치가 아름답고 깎아 세운 듯한 암벽이 장관을 이루는 곳이다.정상에서 서남쪽 능선 약 6km 아래에 있는 수타사와 노천리까지 이어지는 약 8km의 수타계곡은 갖가지 멋진 바위들과 아름다운 풍경이 비할 데 없다. 산 정상에서 바라보면 홍천군 일원이 한눈에 들어오며, 봄에는 철쭉과 가을철에는 단풍이 노송과 함께 깍아 지른 듯한 바위와의 모습이 보는이의 마음을 사로잡고 눈덮인 겨울산 역시 등산객들을 매료시키는 곳이기도 하다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 화촌면", + "MNTN_NM" : "공작산" + }, + "longitude" : 128.0100592, + "latitude" : 37.715563299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 창념읍과 고암면 사이에 자리잡은 화왕산과 이 화왕산 꼭대기에서 동남쪽 능선으로 뻗어내린 관룡산은 경상남도 창녕군에서 한 번쯤 곡 가봐야 할 진산이다.높지는 않지만 경관이 수려하고 낙동강 하류지대에 솟아올라 있어 산세가 제법 크게 느껴진다. 두 산은 마치 ㄷ자를 오른쪽으로 90도 가량 돌려놓은 듯한 지형이다.가을에는 억새풀이 봄에는 진달래가 유명한 산이다. 또한 사적이나 문화재가 많아 ‘제2의 경주’라고 불리기도 한다. 그러므로 아이들과 함께 하는 가벼운 산행지로 매우 좋다. 그러나 시간은 한정되고 둘러 볼 것은 많으므로 볼거리를 미리 정해 두어야 한다.", + "MNTN_HG_VL" : "740", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 고암면", + "MNTN_NM" : "관룡산" + }, + "longitude" : 128.5534586, + "latitude" : 35.531947600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "391", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", + "MNTN_NM" : "관모산" + }, + "longitude" : 126.7655213, + "latitude" : 37.451878399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "391", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍", + "MNTN_NM" : "관모산" + }, + "longitude" : 126.7655213, + "latitude" : 37.451878399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "관악산은 서울시 관악구와 금천구, 경기도 과천시와 안양시에 걸쳐 있어 북한산,도봉산과 더불어 누구나 쉽게 찾는 친근한 산이다. 멀리서 보면 온통 바위로 뒤덮여 있는 산세를 가진 관악산은 해발은 낮으나 등산로 곳곳에 위험한 암릉이 있어 조심해야 한다.관악산은 예로부터 불의 산(火山)이라 하여 조선 태조가 궁터를 지금의 경복궁 자리로 옮길 때, 무학대사가 이곳은 관악산과 마주 보이는 자리로 관악산의 화기가 궁을 눌러서 내우외환이 끊이지 않을 것이라며 반대했지만, 정도전의 남쪽에 한강이 가로질러 있어서 영향이 없을 것이라는 주장을 받아 들여 지금의 경복궁을 창건하였다 한다. 그후 태종때 왕자의 난, 세조의 왕위 찬탈, 임진왜란, 병자호란, 그리고 경복궁에 발생한 수차례의 화재가 발생한 것을 풍수지리설로 해석하는 이도 있다. 대원군은 경복궁을 재건할 때 관악산의 화기를 누르기 위해 경복궁 정문인 광화문 앞에 바다의 신으로 상상의 동물인 해태 조각상을 만들어 세웠다.관악산 연주대는 고려가 망하자 남은 유신 열 사람이 관악산 절에 숨어살며 경복궁을 바라보며 통곡을 했다 하여, 임금을 사모한다는 뜻으로 연주대(戀主臺)라 불려 지게 되었다 한다. 이성계가 연주암을 중창한 뒤, 태종의 두 아들인 양녕대군과 효령대군은 태종이 왕위를 셋째 충녕대군(세종)에게 물려줄 뜻을 알고 관악산에 입산하였다 한다. 예전에 관악산을 삼성산이라 부른 것은 신라의 고승 원효,의상,윤필이 이 산에서 세 승려가 일막,이막,삼막의 세 암자를 짓고 따로 수도하여 득도하였다 하여 붙여진 것으로 전해지고 있다. 임진왜란때 일막,이막은 소실되고 삼막사(三幕寺)만 남았다는 것이다.", + "MNTN_HG_VL" : "632", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구ㆍ금천구, 경기도 안양시ㆍ과천시", + "MNTN_NM" : "관악산" + }, + "longitude" : 126.9610024, + "latitude" : 37.442938499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "변산은 호남의 5대 명산 중에 하나로 서해에 접한 반도를 형성한 산 군을 말하며, 행정구역상으로는 전북 부안군 하서면, 상서면, 변산면, 진서면, 보안면에 접해 있는 산이다.의상봉(509m), 삼예봉(355m), 덕성봉(328m), 상여봉(398m), 옥녀봉(433m), 쌍선봉(459m), 신산봉(486m), 삼신산(486m), 갑남산 등을 통칭하여 변산이라 부르고 있다. 변산 반도는 산군이 형성된 내륙 쪽을 내변산, 해안 쪽을 외변산으로 구분하여 부르고 있다. 관음봉이 솟아 있는 변산반도에는 직소폭포, 분옥담, 선녀탕, 와룡소와 낙조대, 망포대 등 널리 알려진 명승지들이 산재해 있으며 관음봉 등산로에는 낙조대 아래에 월명암과 관음봉 아래 내소사 등 유서 깊은 사찰들이 자리해 있다.백제 무왕 34년(633년)에 혜구스님이 창건한 내소사는 `다시 태어나서 온다'는 뜻으로 소래사(蘇來寺)로 불러 오다가, 조선 인조 11년(1633년)에 청민선사가 중건한 뒤부터 내소사로 이름이 바뀌었다고 한다. 이 지방에서는 `춘변산 추내장(春邊山 秋內臟)이란 말이 전해지는데 이는 봄에는 변산반도, 가을엔 내장산의 경치가 최고라는 것을 한마디로 표현한 것이다. 관음봉은 일명 세봉(細峰), 가는봉이라 불리고 있으며, 거대한 바위절벽을 두르고 있어 보는 이로 하여금 감탄을 자아내게 한다.관음봉 산행은 남여치에서 시작하여 쌍선봉, 낙조대, 월명암, 봉래구곡, 직소폭포, 재백이재를 거쳐 관음봉을 오른 뒤 내소사로 하산하는 코스가 많이 이용되고 있다. 이 중 낙조대는 서해의 해지는 풍경을 보러 오는 사람들로 늦은 시간에도 사람들의 발길이 끊이지 않는 곳이며, 30여미터의 높이에서 떨어지는 직소폭포는 부안 3절(扶安三絶)의 하나로 채석강과 더불어 변산을 상징하는 명소다.", + "MNTN_HG_VL" : "433", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군", + "MNTN_NM" : "관음봉" + }, + "longitude" : 127.20027779999999, + "latitude" : 36.351944400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "관음산은 북동쪽으로 명성산과 주능선이 이어져있다. 정상에서 북쪽 산자락에는 관광명소인 산정호수가 자리잡고 있으며, 남쪽으로는 드라이브코스인 영평천이 흐르고 있어 볼거리가 많은 곳이다.관음산에서 동쪽으로 이어지는 사향산은 군사시설로 입산이 통제되어 있는 곳이다.주위의 명성산 국망봉, 백운산 그늘에 가려 별로 알려지지 않은 산이지만 그만큼 호젓한 산행을 즐기기에 좋다.관음산의 특징은 바위가 별로 없는 '육산'이라는 점이다. 정상에 서 북쪽 사자락에는 관광명소인 산정호수가 자리잡고 있으며, 남쪽으로는 드라이브 코스인 영평천이 흐르고 있어, 볼거리가 많다. 산행 들머리는 영중면 파주골, 영북면 산정리와 쇠골, 낭유고개 등이다.이 중 파주골은 후고구려를 건국한 궁예가 명성산에서 왕건에게 패한 후 도주했던 곳이라 해서 패주동으로 불리다가 훗날 파주골로 되었다. 파주골 식당을 지나 계곡 초입에는 폐광터가 있다. 남쪽으로는 바위에서 바람이 솟아난다는 풍혈산, 북쪽으로는 낭유 고개 너머 사향산과 명성산이 솟아있다.", + "MNTN_HG_VL" : "733", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영북면", + "MNTN_NM" : "관음산" + }, + "longitude" : 127.310757, + "latitude" : 38.028650900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "관인봉은 정상에서 남봉으로 뻗어내린 능선과 평행선을 이루고 주능선은 대부분 암릉과 암벽지대로 이루어져 있고, 이러한 천혜의 지형을 이용행 보가산성을 축조한 석축이 남아있다. 지장봉계곡을 사이에 두고 서로 마주보고 있는 삼형제봉과 지장봉은 일직선으로 연결되어있고 관인봉은 관인북봉 위쪽에서 예각으로 좌회전하여 서진하면 지장봉과 만난다.경기도 포천군 관인면 서북단에 위치한 관인봉 일원은 예로부터 전략적 요충지로 삼국시대 때 고구려, 백제, 신라가 영토 분쟁을 하였던 곳이다. 삼국시대 초기에는 백제 땅이었다가 고구려 광개토왕 6년(396년)에는 고구려령이 되었고, 신라 진흥왕 12년(551년)에는 신라의 국토에 편입되어 경덕왕 16년(757년)에는 칠성군에 속해 있었다는 기록이 있다. 신라 말에는 궁예가 태봉국을 건국하여 철원에 도읍을 정하였을 때 태봉국의 영역에 속하게 되었다한다. 태봉국왕인 궁예의 폭정에 못 견딘 어진(仁) 관리(官)들이 관직을 버리고 이 지역에 모여 살았다는 유래로 이 지역이 관인으로 불리게 되었다 한다.정상에서 조망은 북으로는 철원군의 고대산(高臺山.832m)과 금학산(金鶴山.947m)이, 동쪽으로는 고남산(古南山.644m)이, 남쪽으로는 종자산(種子山.643m), 서쪽으로는 지장봉(地藏峰.877m)이 관인봉을 감싸고 있다. 울창한 수림으로 수량이 많은 큰골은 계곡 피서지로서 유명하고 가을 단풍도 좋다.", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시", + "MNTN_NM" : "관인봉" + }, + "longitude" : 126.2227778, + "latitude" : 40.032499999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "광교산은 원래 광악산이었는데 928년 왕건이 후백제 견훤을 평정하고 나서 산근처에 행궁을 차리고 군사를 위로할 때 산 정상에서 불빛이 하늘로 솟아오르는 것을 보고 이 산은 '부처님의 가르침을 주는 산' 이라 하여 이름을 광교산으로 붙였다고 전해진다.광교산은 물이 풍부한 산으로 광교저수지, 낙생저수지, 고기동 물놀이터가 시민의 사랑을 받고 있으며 국가보물 제9호 서봉사지 현오국사타비, 경기도 문화재 제38호 김준용 장군 승전비가 있다.", + "MNTN_HG_VL" : "582", + "MNTN_LOCPLC_REGION_NM" : "경기도", + "MNTN_NM" : "광교산" + }, + "longitude" : 127.01508370000001, + "latitude" : 37.3280368 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "지형적으로는 공주시 유구읍, 아산시 송악면, 천안시 광덕면이 광덕산을 끼고있다. 산세가 높으며 나무들이 오래되어 경관이 보기가 좋은곳이다. 특히 노약자도 많이 이용하는데산림과에서 만든 소방도로로 이용을 많이 한다.", + "MNTN_HG_VL" : "638", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 천안시 광덕리", + "MNTN_NM" : "광덕산" + }, + "longitude" : 127.034266, + "latitude" : 36.693891999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충남 아산시 송악면과 천안시 광덕면의 경계를 이룬 광덕산은 높이에 비해 산세와 조망이 뛰어난 산으로 정평이 나 있다. 온양온천을 지척에 두고 있어 온천산행지로도 널리 알려진 광덕산은 천안, 아산, 공주의 분기점이자 금북정맥 상의 각흘고개와 갈재고개 사이의 무명봉에서 북쪽으로 갈래 쳐 천안시와 아산시를 가르며 뻗은 산줄기의 최고봉으로서, 흔히 내포지방이라 일컫는 아산, 당진, 서산뿐 아니라 평택, 천안, 대전 등 충남북 일원을 한눈에 조망할 수 있는 산이다. 크고 풍후(豊厚)하여 옛날부터 덕이 있다고 하는 광덕산은 난리가 나거나 불길한 큰 일이 있으면 산이 운다는 전설이 있으며 계곡에는 언제나 맑은 물이 흘러 곡교천의 상류가 되며 남록인 공주시 사곡면 운암리에는 유서 깊은 마곡사가 자리하고 있다.또한 호두나무가 풍성한 광덕사 주변은 갑신정변을 일으켰던 풍운아 김옥균, 임시정부 주석 김구 선생 등 역사적인 인물들이 은신했던 곳으로도 알려져 있다.", + "MNTN_HG_VL" : "699", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 광덕면, 아산시 송악면", + "MNTN_NM" : "광덕산" + }, + "longitude" : 127.034266, + "latitude" : 36.693891999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한북정맥에 들머리가 되는 광덕산은 경기도에서는 가장 북쪽에 위치한 산이며, 강원도 화천군과 철원군의 경계를 이루고 있으며, 거의 정상 부위까지 군사 비상도로가 개설되어 있고 산자락 곳곳에 군사시설이 있어 지형적으로 군사 요충지임을 말해주는 산이다.가을이면 오색단풍의 물경이 겨울이면 설경이 아름다운 곳이다. 이 산은 교통편이 좋아 쉽게 찾을 수 있고, 또 주위에 백암산, 적근산, 복주산 등 여러 산과 백운계곡이 유원지화되어 있어 올때마다 새로움을 느낄 수 있다.", + "MNTN_HG_VL" : "699", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 철원군 서면, 화천군 사내면", + "MNTN_NM" : "광덕산" + }, + "longitude" : 127.034266, + "latitude" : 36.693891999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1046", + "MNTN_LOCPLC_REGION_NM" : "경기도 안산", + "MNTN_NM" : "광덕산" + }, + "longitude" : 127.034266, + "latitude" : 36.693891999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마산의 진산 무학산과 마주하고 있으며 여항산과 무학산을 이어주는 낙남정맥의 종주길이기도 하다. 무학산의 유명세에 눌리고 광려천 깊숙이 숨어 있어 그동안 알려지지 않았다. 최근 들어 내서읍이 개발되어 접근이 쉬워지고 낙남정맥을 종주하는 산꾼들에 의해 조금씩 알려지면서 찾는 사람들이 늘고 있다. 봄이면 광려산과 대산 사이 능선의 진달래와 얼레지 군락은 어느 유명산 못지않은 장관을 연출한다.내서읍 삼계마을 뒤쪽에 솟은 상투봉은 이 산의 주릉에 변화를 주고 있지만 산세는 부드럽다. 남릉은 쌀재에서 무학산의 산릉을 이어받아 길게 북으로 치달려 올라 감천마을을 포용하면서 옥수골을 만들어 놓는다. 동릉은 함안군으로 흘러나가고, 북쪽 사면은 산세를 열어 여항산으로 산기운을 보내고 있다.", + "MNTN_HG_VL" : "752", + "MNTN_LOCPLC_REGION_NM" : "경남 마산시 내서읍", + "MNTN_NM" : "광려산" + }, + "longitude" : 128.49108480000001, + "latitude" : 35.189903700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "괘관산은 함양군 서하면과 병곡면의 경계에 자리한 해발 1252미터의 듬직한 산이다. 덕유산과 남덕유산을 지나 전라남도와 경상남도의 경계를 이루며 남하하던 백두대간인 백운산에 이르러 동쪽으로 곁가지를 일으킨다. 이 산줄기는 다시 남과 북의 두 줄기로 나누어지고, 그중 남녘으로 내린 산줄기는 함양땅의 원통재(일명 빼빼재)를 내려 37번 도로에 이른다. 원통재에서 숨을 고른 산줄기는 서하면과 병곡면의 경계를 이루며 동북으로 힘차게 달려 괘관산과 도성산(1044m)을 일으킨 후 남간 상류에 이르러 끝을 맺는다.괘관산이란 이름은 북쪽의 서하면에서 바라보면 뾰족한 정수리가 ‘갓 걸이 산’으로 생각하기 십상이다. 그러나 괘관이란 이름에는 깊은 뜻이 숨어 있었으니 괘관이란 관에서 제정한 관을 쓰지 않고 걸어둔다는 뜻으로 벼슬을 내놓고 물러남을 이르는 말이다. 또한 경기도 개성의 경덕궁 북쪽에 괘관현이란 고개가 있었는데 조선 초 태조 이성계의 등극 때 고려의 유신들이 이 고개에서 관을 벗어 던지고 갔다 전한다.", + "MNTN_HG_VL" : "1252", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 서하면ㆍ병곡면", + "MNTN_NM" : "괘관산" + }, + "longitude" : 127.6988889, + "latitude" : 35.605277800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진주와 함안의 경계지점에 터잡고 있는 계방산과 방어산은 가족산행지로는 더없이 좋은 곳이다.계방산은 500m급의 산에 불과하지만 능선의 굴곡이 심한데다 군데군데 암반을 올라야 하고 끝없이 이어지는 소나무터널이 산행의 묘미를 한층 더하게 해 준다. 여기다 방어산 7부능선에 터잡은 보물 159호\"\"마애약사삼존불\"\"도 만날 수 있고 능선에 오르면 남강에서 불어오는 싱그러운 바람을 맞으며 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "451", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진주, 함안", + "MNTN_NM" : "괘방산" + }, + "longitude" : 128.99863020000001, + "latitude" : 37.713526999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 강릉시 강동면 정동진역과 안인진역 사이에 위치해 있다. 이 산은 서울 경복궁에서 정동(正東)에 있다 하여 붙여진 이름인 정동진의 열차역이 산행들머리다.해수욕장이 있는 등명에서 서쪽으로 솟은 산이 괘방산으로 등명과 산 정상 사이에 락가사가 동해바다를 향해 자리잡고 있다. 등명락가사에서 북으로 500m거리인 대포동은 96년 9월 18일 북한 무장공비들이 잠수함으로 침투한 곳이다. 이 사건을 계기로 괘방산에다 안보체험 등산로를 개설하게 되어 이 산이 유명하게 되었다. 당시 침투했던 잠수함은 대포동 바닷가에 전시하고 통일공원이 조성되어 있다.괘방산이라는 산 이름은 옛날 과거에 급제하면 이 산 어디엔가에 두루마기에다 급제자의 이름을 쓴 방을 붙여 고을 사람들에게 알렸다는 데서 생긴 이름이라 전해지고 있다.", + "MNTN_HG_VL" : "339", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 강동면", + "MNTN_NM" : "괘방산" + }, + "longitude" : 128.99863020000001, + "latitude" : 37.713526999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "괘일산(掛日山)은 해질녘 해가 산에 걸려있다고 해서 괘일이라는 이름을 썼다고 한다. 또한 그다지 높지 않은 산이지만 산세가 범상치 않아 예전부터 명산의 대열에 끼였으며, 호남정맥마루금에 솟아 담양 산성산에서 맥을 받아 광주 무등산으로 맥을 넘겨주는 이산은 멀리서 보면눈이 쌓인 것처럼 정상부 바위 벼랑이 하얗게 빛나 그런 이름을 얻었다고 한다.", + "MNTN_HG_VL" : "455", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 무정면", + "MNTN_NM" : "괘일산" + }, + "longitude" : 127.6522222, + "latitude" : 37.538611099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "518", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시", + "MNTN_NM" : "교룡산" + }, + "longitude" : 127.3522969, + "latitude" : 35.429327299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구나무산 서남쪽 산자락에는 일명 물안골로 불리는 용추계곡이 자리잡고 있으며 이 계곡에는 용추폭포, 미륵바위, 소바위, 곰바위 등 볼거리가 널려 있다. 이름 그대로 구나무가 많아 구나무산이라 불린다.구나무는 참나무와 모양이 비슷한데 나무껍질이 두터워 병마게 재료로 많이 사용된다. 1930-40년대에는 구나무로 숯을 구웠다고 하는데 산행 중에 더러 숯가마를 볼 수도 있다. 구나무산은 아기자기한 면은 없으나 바위하나 없는 육산이라 험로가 없고 산행시간도 비교적 짧아 간편한 산행을 즐기는 이에게는 적격인 산이다.서울에서 가까운 거리에 있으면서도 주변의 명산들에 가려 빛을 보지 못하다가 최근에 등산객들이 많이 찾고있는 산이다. 주변에 청평자연휴양림, 아침고요수목원 등 도시나 복잡한 유원지를 피해 호젓히 자연속에서 여유로운 시간을 보내기에 좋은 곳이 많다.", + "MNTN_HG_VL" : "859", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", + "MNTN_NM" : "구나무산" + }, + "longitude" : 127.4788889, + "latitude" : 37.880833299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구담봉은 충주호에 솟아 있는 높이 335미터의 작은 산으로 단양 8경의 하나이다. 물속에 비친 바위가 거북 무늬를 띠고 있어 구담봉으로 불리고 있다.이 산은 아담한 규모의 산으로 옥순봉과 함께 충주호 수상관광의 백미를 이루며 호수에서 보는 절경 못지않게 산행코스 또한 아기자기하다. 또한 제비봉과 금수산, 멀리는 월악산이 감싸고 있다. 퇴계 이황은 이 같은 구담봉의 장관을 보고 “중국의 소상팔경이 이보다 나을 수는 없을 것”이라고 극찬했다고 한다.조선 인종 때 백의재상 이지번이 벼슬을 버리고 이곳에 은거, 푸른 소를 타고 강산을 청유하며 칡넝쿨을 구담의 양안에 매고 비학을 만들어 타고 왕래하니 사람들이 이를 보고 신선이라 불렀다는 이야기도 전해져 온다.구담봉 산행은 제천시 수산면 경계선에 위치한 계란재에서 시작한다. 이 고개 오른쪽으로 제천시 구역임을 알리는 환영구조물이 있고 작은 주차장이 있다. 월악산국립공원 관리공단측에서 이 길만을 정규등산로로 개방하고 있다.", + "MNTN_HG_VL" : "373", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면 괴곡리, 계란리", + "MNTN_NM" : "구담봉" + }, + "longitude" : 128.24787660000001, + "latitude" : 36.941200700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구담보은 물속에 비친 바위가 거북 무늬를 띠고 있어 붙여진 이름이다. 퇴계이항은 구밤보의 장관을 보고\"중국의 소상팔경이 이보다 나을 수는 없을것\"이라고 극찬했다고 한다.구담봉은 서북쪽으로 가까이 이어져 있는 옥순봉(玉荀峰.290m)과 함께 단양 8경 중의 하나로 손꼽히는 경관을 자랑하고 있다. 충북 제천시 수산면과 단양군 단양읍의 경계를 이루는 계란재에서 북동쪽으로 충주호 방향으로 뻗어 내린 능선에 솟아 있는 구담봉을 올라보면 주변 풍광에 누구나 탄성을 자아내게 한다.", + "MNTN_HG_VL" : "373", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 단양군", + "MNTN_NM" : "구담봉" + }, + "longitude" : 128.24787660000001, + "latitude" : 36.941200700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부산광역시의 대표적인 진산 중의 하나인 구덕산은 울창한 수림을 자랑하고 있다.구덕산은 해발 562m로 북구 학장동과 사하구 당리동, 서구 서대신동의 경계에 솟아 있다. 태백산맥의 말단 금정산 줄기 끝자락에 위치하고 있으며, 북동쪽으로는 엄광산에, 남서쪽으로는 시약산에 각각 이어져 있다.산기슭에는 구덕사가 있고, 시민의 휴식공간으로도 널리 이용되고 있는 대신공원과 한때 대규모 꽃 재배단지로 유명했던 꽃마을, 구덕수원지 등을 품고 있어 곳곳에 원예수와 꽃이 재배되어 시민들의 산책로로도 많이 이용된다. 구덕고개 밑으로는 구덕 터널이 뚫려 있다. 예전에는 이 산을 구덕산(舊德山) 또는 엄광산(嚴光山)이라고 불렀다.", + "MNTN_HG_VL" : "562", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 북구, 사하구, 서구", + "MNTN_NM" : "구덕산" + }, + "longitude" : 128.99967799999999, + "latitude" : 35.122726499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구두산은 설천면사무소가 있는 남양마을 조금 못미쳐 있는 문의마을 산길을 따라 오른다. 문의마을에서 걸어 올라가면 1시간, 차량으로는 약10분 정도 걸린다.구두산 정상에서 바라보면 삼면은 바다요 남쪽은 연봉이다. 크고 작은 섬은 여기저기 떠 있고 그 사이를 떠가는 일엽편주, 물위를 날듯 하얀 물줄기를 가르며 경쾌하게 달리는 한려수도의 쾌속선 엔젤호, 바다 건너 넓은 들녘과 높고 낮은 산, 그리고 촌락이 군데군데 떼지어 모여 앉아 있다.동으로 삼천포, 사천, 북으로 바다건너 금오산의 성급한 산줄기가 내리 뻗고 서쪽으로 섬진강 하류, 광양, 모두가 고요 속에 잠겨 한 편의 시를 읊고 있는 기분이다. 산정에서 북쪽으로 조금 내려가면 남해대교가 굽어보인다.", + "MNTN_HG_VL" : "618", + "MNTN_LOCPLC_REGION_NM" : "경상남도 남해군 설천면 덕신리", + "MNTN_NM" : "구두산" + }, + "longitude" : 128.60313009999999, + "latitude" : 35.179795800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구룡산(九龍山) 정상은 해발307.7m의 서울특별시 서초구 염곡동, 내곡동, 양재동과 강남구 개포동 일대에 위치한 산이다. 구룡산은 열 마리의 용이 승천하는 것을 인근을 지나가던 임신한 여성이 보고 크게 놀라 소리를 질러 용 한마리가 떨어져 죽고, 아홉 마리만 하늘로 승천하였다고 한다. 아홉 마리의 용이 승천하면서 남긴 흔적이 구룡산이라 불리게 되었으며, 하늘에 승천하지 못하고 죽은 용이 있던 자리가 물이 되어 양재천(良才川)이 되었다는 전설이 있다. 실제로 산을 자세히 보면 9개의 계곡으로 이루어져 있다.정상보다 낮은 이 산의 주봉(主峰)은 국수봉(國守峰)이라고 하는데, 조선시대 전부터 정상에 봉수대(烽燧臺)가 있어 국가를 지킨다고 해서 붙여진 것으로 이 곳에는 바위굴 국수방(國守房)이 있어 봉수군(烽燧軍)이 기거했다고 한다. 『여지도서』 광주목에\"관아의 남쪽 30리에 있다. 봉수대가 설치되어 있다\"고 기록되어 있다.내곡동에 있는 헌인릉과 함께 구룡산 기슭에 세종대왕이 묻힌 영릉(英陵)이 있었으나, 1469년(예종 1년)에 여주로 천장(遷葬)하였다. 초장지(初葬地)였던 구룡산 내곡동에 국가정보원이 들어서 있다.구룡산 제2봉인 국수봉전망대는 서울 강남.강북과 경기도 한강하류와 상류지역까지를 관망할 수 있는 최적지로 주.야경 조망명소이다.약 300m의 산으로 산높이나 길이 험하지 않아 가족과의 산행코드로는 제격이며, 접근성도 용이하여 부담없이 즐길 수 있다.구룡산에는 능인선원과 자룡사가 있다. 2015년 9월 13일 능인선원에 세계 최대 약사여래좌불을 점안하여 이름을\"서울약사대불\"이라 하였다.이 산에는 자작나무과인 수피가 얇은 종잇장처럼 벗겨지는 물박달나무 군락지가 산재해 있으며, 그 외에 신갈나무, 리기다소나무, 아까시나무 등이 있다. 관악산, 청계산, 우면산 등과 산자락이 이어진다.", + "MNTN_HG_VL" : "308", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 염곡동ㆍ내곡동, 강남구 개포동", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;대청호 전망대라 불리는 조망 명산gt;1980년 대청댐의 완공으로 문의면 4075세대가 물에 잠겼다. 댐 건설로 주변지역은 잦은 홍수와 가뭄으로부터 벗어났지만 고향을 잃은 이들에겐 그 무엇으로도 위로가 되지 않았다. 물끄러미 물속만 들여다 볼 수밖에. 대청댐 서쪽 바로 옆으로 솟은 구룡산. 정상에서 대청호 조망은 물론, 대청댐 주변 풍광이 한눈에 들어온다. 이 때문에 구룡산은 실향민들에게 조금이나마 위로가 될 수 있는 곳이기도 하다. 또한 이곳은 군사정권 시절 군인들이 보초를 서던 곳이기도 했다. 건너편으로 훤하게 들여다보이는 ‘청남대’ 때문. 당시에는 대통령 전용 별장이었지만 지금은 시민들에게 개방되어 있다. 이처럼 구룡산은 대청호 인근에서 전망대 역할을 하고 있다고 해도 과언이 아니다. 하지만 이 외에도 정상 바로 아래의 장승공원과 현암사가 있어 등산객들은 물론 대청호를 찾은 많은 관광객들을 불러 모으고 있다. 장승공원 입구까지는 승용차로도 갈 수 있으니 부담 없이 산을 오를 수 있다.", + "MNTN_HG_VL" : "373", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면 덕유리, 현도면 하석리", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구룡산은 강원도 영월군 수주면을 감싸 흐르는 서만이 강변에서 북쪽으로 솟아 있는 산이다. 구룡산 남쪽 산자락 끝에 위치한 '섬안'이라는 마을을 동, 남, 서쪽으로 감싸 흐르는 강줄기 이름이 서만이강인데 옛날 명칭은 '섬안이강'이라고 전해지고 있다.정상에 오르면 치악산과 매화산이 스카이라인을 이루고, 산갓봉, 화채봉, 백덕산, 사자산, 돼지봉, 배거리산 등 숲겨지 명산들이 주변에 있고, 선달산과 소백산, 금수산까지 보인다. 때묻지 않고 수수하며 능선과 깨끗한 계곡이 좋고, 사철 등산하기에도 그만이다.", + "MNTN_HG_VL" : "283", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "370", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 현도면, 문의면", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "373", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면 덕유리, 현도면 하석리", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여름철 등산지는 열차를 이용하는 편이 보다 편리하다. 중앙선 판대역에 내려 철길을 따라 원주쪽으로 조금 이동한 후 통운판대 출장소가 있으며, 이집 뒤쪽으로 돌아서 연화정사에 이르게 된다.연화정사는 일요일에 학생들을 모아 포교하는 아담한 사찰이다. 절에서 나와 동쪽 길을 따라 고개를 넘으면 하구재 마을에 당도한다. 지리내미골을 통해 400봉에 올라 정상으로 가는 도중에 암봉이 있는데, 이곳에서는 구룡골 일대를 한눈에 조망할 수 있다.", + "MNTN_HG_VL" : "479", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 지정면", + "MNTN_NM" : "구룡산" + }, + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구만산(九萬山)은 낙동정맥의 가지산에서 서쪽으로 뻗은 운문지맥에 솟은 산이다. 구만산은 근oacute;의 억산(962m), 육화산(670m)과 함께 숫자로 된 재미있는 이름을 가졌다. 구만산은임진왜란 당시 구만명이 이 산으로 피했다고 붙여진 이름이라고 한다. 구만산 서쪽에는 4km의ucirc;정한 구만계곡이 있다.능선에 오르면 주변으로 펼쳐진 영남알프스의 연봉들을 감상할 수 있고 능선 곳곳에서 툭툭 불거져 나온 기암들이 많아 풍광이 좋다. 또 같은 산줄기에 솟은 억산이나 육산과 연계한 산행도 할만 해 자신의 일정이나uuml;력에 따라 다양한 코스를 계획할 수 있다.교통이 편리한 밀양시 산내면 쪽을 들머리로 잡는 게 좋다.", + "MNTN_HG_VL" : "785", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산내면, 경상북도 청도군 매전면", + "MNTN_NM" : "구만산" + }, + "longitude" : 128.88059190000001, + "latitude" : 35.626136899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "785", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "구만산" + }, + "longitude" : 128.88059190000001, + "latitude" : 35.626136899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "애오라지 산만 찾아다니는 산꾼들이라도 경주에 들어서면 가슴이 설렌다. 어딜 가나 역사와 전통의 향기에 마주치게 되는 천년고도인 것이다.비록 산만 찾아 나선 길이라 해도 언제 어디서 뜻밖의 문화유산과 접하게 될지 모른다는 기대감을 가져도 좋은 것이 경주쪽 산행이다. 산행초입에는 천도교의 유적지이자 성지인 용담정(龍潭亭)이 들어서 있어 색다른 경주의 역사유적을 만나는 기쁨도 있다.", + "MNTN_HG_VL" : "594", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", + "MNTN_NM" : "구미산" + }, + "longitude" : 129.1364494, + "latitude" : 35.884555400000004 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "세종식록지리지에 상주 삼명산의 하나라고 했을 정도로 빼어난 산세를 가지고 있다. 그래서 속리산이 아니면서도 속리산국립공원의 남쪽 경계에 포함되었다. 지금은 거의가 보은군 땅이다.25번 국도를 타고가다 보면 금방 눈에 띄다. 군계일학인 까닭이다. 자락에는 시루를 엎어놓은 듯한 봉우리까지 있어 정말 신령스런 산이라는 생각이 들게 한다. 그래서인지 구령산(九靈山)이라고도 했다. 구병산은 충북 보은군과 경북 상주군의 속리산 국립공원 남쪽 국도변에 자리잡고 있다.예로부터 보은 지방에서는 속리산의 천황봉은 지아비 산, 구병산은 지어미 산, 금적산은 아들 산이라 하여 이들을 '삼산'이라 일컫는다. 속리산의 명성에 가려 일반인에게는 잘 알려져 있지 않아 산 전체가 깨끗하고 조용하며 보존이 잘 되어 있는 편이다. 보은군청에서는 속리산과 구병산을 잇는 43.9km 구간을 1999년 5월 17일 '충북 알프스'로 업무표장 등록을 하여 관광상품으로 널리 홍보하고 있다. 6·25전쟁 때 폐허가 된 토골사 터가 있고 절 터 앞뒤로 수백년 생의 참나무들이 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 보은군 마로면ㆍ속리산면", + "MNTN_NM" : "구병산" + }, + "longitude" : 127.8616372, + "latitude" : 36.469489500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "세종식록지리지에 상주 삼명산의 하나라고 했을 정도로 빼어난 산세를 가지고 있다. 그래서 속리산이 아니면서도 속리산국립공원의 남쪽 경계에 포함되었다. 지금은 거의가 보은군 땅이다.25번 국도를 타고가다 보면 금방 눈에 띄다. 군계일학인 까닭이다. 자락에는 시루를 엎어놓은 듯한 봉우리까지 있어 정말 신령스런 산이라는 생각이 들게 한다. 그래서인지 구령산(九靈山)이라고도 했다. 구병산은 충북 보은군과 경북 상주군의 속리산 국립공원 남쪽 국도변에 자리잡고 있다.예로부터 보은 지방에서는 속리산의 천황봉은 지아비 산, 구병산은 지어미 산, 금적산은 아들 산이라 하여 이들을 '삼산'이라 일컫는다. 속리산의 명성에 가려 일반인에게는 잘 알려져 있지 않아 산 전체가 깨끗하고 조용하며 보존이 잘 되어 있는 편이다. 보은군청에서는 속리산과 구병산을 잇는 43.9km 구간을 1999년 5월 17일 '충북 알프스'로 업무표장 등록을 하여 관광상품으로 널리 홍보하고 있다. 6·25전쟁 때 폐허가 된 토골사 터가 있고 절 터 앞뒤로 수백년 생의 참나무들이 있다.", + "MNTN_HG_VL" : "877", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화남면 평온리, 보은군 마로면 적암리, 외속리면 구병리", + "MNTN_NM" : "구병산" + }, + "longitude" : 127.8616372, + "latitude" : 36.469489500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구봉대산(870m)은 강원도 영월군 수주면 북쪽에 아홉 봉우리를 자랑하며 솟은 산이다. 우리나라 5대 적멸보궁 중 하나인 사자산 법흥사 적멸보궁을 감싸 안은 우백호의 자리에 해당하기도 한다. 백덕산(1349m)에서 사자산 지나 삿갓봉(1028m)으로 이어지는 서쪽의 산줄기 중간에서 남쪽으로 뻗어 내린 구봉대산은 북쪽의 1봉에서 남쪽 9봉에 이르는 각 봉우리마다 사람이 태어나서 죽을 때까지의 과정을 뜻하는 단어들이 각각 이름으로 붙어있다.4봉부터는 등반을 해야 할 정도로 암릉구간이 곳곳에 나타나지만 모두 우회하는 길이 아래로 나 있어 힘들지 않게 산행할 수 있다. 법흥사에서 출발해 계곡을 따라 1봉에 올라 능선 따라 9봉까지 간 다음 다시 법흥사로 내려오면 된다. 총 산행시간은 4시간 정도 걸린다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면", + "MNTN_NM" : "구봉대산" + }, + "longitude" : 128.25140740000001, + "latitude" : 37.362444199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 김제시 금구면과 금산면의 경계를 이루는 구성산은 모악산이 서북쪽으로 가지를 친 지맥선상에 위치해 있다.모악산과 마주한 형태로 서있는 구성산은 그리 높지는 않지만 정상에 서면 만경강과 동진강이 빚어놓은 김제 평야의 광활함이 한눈에 들어온다. 모악산의 명성에 눌려 찾는 등산객들이 별로 많지는 않지만 그만큼 훼손 안된 자연의 상태를 유지하고 있다.이 산과 모악산에서 모아진 수자원으로 이루어진 금평저수지 주변에는 각종 신흥종교가 번창했던 곳으로 산 남쪽 기슭에 자리잡은 학선암과 전주-금산간 도로변의 유서 깊은 국신사를 비롯, 도처에 기도처가 남아 있어 신흥종교 신봉자들이 적지 않게 찾아온다.", + "MNTN_HG_VL" : "488", + "MNTN_LOCPLC_REGION_NM" : "전라북도 김제시 금구면, 금산면", + "MNTN_NM" : "구성산" + }, + "longitude" : 127.0233333, + "latitude" : 35.747777800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "바다와 인접한 구수산은 짭짤한 바다내음을 맡으며 산을 오를 수 있다. 그리 높지않은 산으로 일반인들에게 잘 알려지지 않은 탓인지 등산객들의 발길은 뜸하다.원불교 창시자인 소태산 박중빈(1891-1943)이 태어나 득도한 영산성지 북서쪽에 자리한 산이다. 바다와 인접한 산인 만큼 정상이나 주능선에서 휘둘러 보는 조망이 일품이다. 북쪽으로는 계마리 금정산(264m)의 왼쪽, 서해바다에 떠 있는 위도가 가물거린다. 금정산 오른쪽 아래로는 옛날 우리나라로 불교가 처음 들어왔다는 법성포가 뚜렷하게 보인다.산자락 끄트머리에는 원불교의 상징인 동그란 원이 산꼭대기 바위벽에 그려져 있는 옥녀봉(152m)이 솟아 있다.", + "MNTN_HG_VL" : "351", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군", + "MNTN_NM" : "구수산" + }, + "longitude" : 128.552392, + "latitude" : 35.938760000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "갓봉은 북동쪽에 위치한 구수산의 하위 봉우리지만 갓봉에서 봉화령을 거쳐 뱀골봉으로 이어지는 남북으로 길게 뻗은 능선은 총 8.6킬로미터에 이르러 구수산 정상을 거치지 않는 하루 산행으로 능히 만족스러운 산이다. 특히 봉화령을 지나면서 뱀골봉까지 펼쳐진 능선길은 아름다운 서해바다를 바라보며 산행할 수 있어 일품이다.원불교 창시자인 소태산 박중빈이 태어나 득도한 영산성지 북서쪽에 자리하고 있으며, 북쪽으로 금정산이, 서쪽으로는 위도가 보인다. 우리나라 불교가 처음 들어왔다는 법성포도 뚜렷하다.갓봉 직전 갈림길에서 수리봉으로 향하는 등산로가 나 있으나 정비가 되지 않아 길이 험해 대부분은 갓봉에서 뱀골봉까지 이어진 등산로를 이용한다.모재봉에서 내려서는 길은 가라프고, 봉화령에서 오르는 암릉구간은 미끄럽기 때문에 겨울철에는 조심해야 한다.능선상에 샘이 없으므로 산행시 물을 충분히 준비하는 것이 좋다.", + "MNTN_HG_VL" : "344", + "MNTN_LOCPLC_REGION_NM" : "전라북도 영광군 백수읍", + "MNTN_NM" : "구수산 갓봉" + }, + "longitude" : 126.4066955, + "latitude" : 35.300632200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고성군이 남해와 접해있는 지역 중에 대부분을 차지하고 있는 동해면의 산역은 수양산과 철마산, 그리고 구절봉의 이음이 전부다. 거류면의 거류산과 마주보면서 남북으로 길게 뻗은 산줄기는 겉에서 보기에는 그저 평범한 산세를 지니고 있어 산객의 관심을 끌지 못하고 있지만, 남서쪽 계곡에 자리잡고 있는 폭포암 근처에 있는 삼단폭으로 된 구절폭포는 작은 규모에 비해 절경을 지니고 있다. 북릉은 동으로 굽어져 철마산과 이어져 있고, 남릉은 당동만에 자락을 씻고 있다. 정상에 서면 건너편 거류산역과 벽방산의 산경이 한 눈에 들어오고 수양산릉 넘어있는 남해의 시원한 경관이 산객의 마음을 열어준다.", + "MNTN_HG_VL" : "521", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 동해면", + "MNTN_NM" : "구절산" + }, + "longitude" : 128.42027780000001, + "latitude" : 35.024722199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산에 아홉 개의 큰 절들이 있다는 데서 유래했다고 전하며, '무수산(無愁山)'으로 불린다고 한다. 신풍면 백룡리, 입동리, 선학리에 걸쳐있는 산으로 예전에 아홉 개의 절이 있었으나 현재는 다 없어졌다.굴티 오른쪽, 오름실 아래쪽에 위치하고 있다.", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 신풍면", + "MNTN_NM" : "구절산" + }, + "longitude" : 128.42027780000001, + "latitude" : 35.024722199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "등산로 곳곳에 전설이 담겨있는 명소가 산재한 구절산은 연엽산의 남쪽에 자리하고 있다. 강원도 춘천시 동산면과 홍천군 북방면의 경계를 이루고 있으나 일반인들에게는 널리 알려지지 않아 비교적 훼손이 덜 된 산이다.강원도 춘천시의 동녘 경계에 한 마리 거대한 용이 물을 마시러 하늘에서 내려온 듯 그 머리를 맑고 푸른 소양호로 향한 듬직한 산세의 산이 해발 899미터의 대룡산이거니와 그 정상에서 정남향으로 길게 능선이 달려 응봉(759m)과 연엽산(850m)이 거대한 비늘인양 솟아 있고, 다시 그 남녘의 엉치 부분에 까마득한 아홉 폭의 절벽 병풍을 펼친 산이 구절산(750.4m)이다.활엽수의 시원한 녹색 차양 사이로 멀리 연엽산의 아름다운 모습이 둥두렷이 떠오르는 능선길을 따르노라면 문득 높다란 암벽이 앞을 가로막는다. 왼쪽으로 돌아가는 길을 찾아 다시 오르면 어느 틈에 삼각점이 기다리는 정상이다. 삼각점에서 조금 떨어진 곳에 춘천 그냥산악회가 1993년 1월에 설치한 약 1미터의 금속팻말에는 ‘구절산 760m’라고 새겨져 있다.", + "MNTN_HG_VL" : "750", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천군 북방면", + "MNTN_NM" : "구절산" + }, + "longitude" : 128.42027780000001, + "latitude" : 35.024722199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구천산의 정상 아래에는 망바위가 있고 망바위에 올라서면 남쪽으로 원동의 토곡산과 천태산, 금오산이 동북쪽으로 가지산, 천황산, 운문산 등 영남 알프스의 준봉들이 눈에 쏙 들어온다. 망바위에서 조금 더 가면 구천산 정상(620m). 누군가 정상 바위 위에 정성스럽게 돌탑을 쌓아 놓았다. 정상 가는 길은 제법 길이 험하기 때문에 조심해야 한다.만어산의 옛 이름은 마야사산이다. 마야사는 고기를 일컫는 옛말이다. 사기에는 만어산에 나찰녀 다섯이 있어서 동해의 독용과 왕래하면서 사귀었다. 그런 이유로 때때로 번개가 치고 비가 내려 4년 동안 오곡이 익지 못했다. 왕은 주술로써 이것을 금하려 했으나 금하지 못하고 부처에 청하여 설법했더니 그제야 나찰녀는 오계를 받아 그 후로는 재해가 없어지고 동해의 물고기와 용이 산 중에 가득찬 돌이 되어서 각각 종과 경쇠의 소리가 난다고 전한다.이러한 전설을 뒷받침하듯 산복부에는 만어군이라 일컫는 너덜겅이 넓고 길게 이어져 장관이다. 돌부리가 한결같이 동해를 향해 누운 듯한 바위군들은 두드리면 맑은 쇳소리가 나 신비감을 자아낸다. 밀양강이 활처럼 휘어져 흐르고 밀양의 큰 들인 상남벌이 너르게 펼쳐져 있는 모습을 보면서 산행하면 즐거움이 한층 더할 것이다.", + "MNTN_HG_VL" : "620", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진", + "MNTN_NM" : "구천산" + }, + "longitude" : 128.87570880000001, + "latitude" : 35.440996499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 장마면, 계성면", + "MNTN_NM" : "구현산" + }, + "longitude" : 128.53222220000001, + "latitude" : 35.513055600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산 모양이 '닭의 볏(계관)'처럼 생겼다 하여 비슬산이라고도 한다.산행은 사람의 흔적을 거의 찾아볼 수 없어, 독립된 산으로서의 산행보다는 인근의 석대산-구현산-화왕산을 연계하는 코스를 이용하는 것이 좋다. 산길은 후반부에 해당하는 구현고개에 닿을 때까지 등산객의 흔적을 거의 발견할 수 없었을 정도로 깨끗하고 묵은 산길이 큰 매력이었다. 석대산 정상까지 이어지는 암릉구간은 산행의 재미를 더해준다. 화왕산(756m)은 그리 높은 산은 아니지만 화려한 암릉으로 유명한 산이다.석대산 바위 구간은 규모 면에서는 이에 미치지 못하지만 아기자기함과 시원하게 트인 조망은 일품이다. 화왕산에서 구현산올 흐르는 남북 능선에과 비탈은 전체가 온통 바위로 까려 있고 능선에는 진달래가 많다.", + "MNTN_HG_VL" : "581", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕", + "MNTN_NM" : "구현산" + }, + "longitude" : 128.53222220000001, + "latitude" : 35.513055600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;송이 향 진동하는 화왕산 전망대gt;창녕의 진산인 화왕산(757m)에서 곧장 남쪽으로 뻗어 내린 산줄기 끝에 뿔처럼 솟은 산이 구현산(579m)이다. 산꾼들 사이에서는 이 산줄기가 화왕지맥으로 통한다. 구현산 산행은 보통 남쪽의 삼성암에서 올라 돌탑봉, 556봉을 지나 구현산, 쌍교산을 거쳐 여초리로 내려서거나 여초저수지에서 석대산으로 올랐다가 구현산, 쌍교산을 거쳐 법성불원으로 내려서는 코스를 택한다. 또 구현산에서 비들재 지나 화왕산, 관룡산까지 이어가는 능선산행도 인기다. 법성불원에서 쌍교산으로 오르는 길이 꽤 가파르다. 이후 능선은 걷기 좋은 산길이다. 쌍교산을 지나면서 조망이 트이는 바위들이 곳곳에 나타나고 화왕산과 관룡산 방면의 조망이 빼어나다. 특히 삼성암으로 갈리는 556봉과 석대산에서의 조망은 그야말로 압권이다. 남쪽으로 옥천저수지 건너 우뚝 솟아 오른 병봉(674m)과 영취산(681m)이 가슴 시원한 풍광으로 펼쳐진다. 구현산 일대는 온통 소나무로 가득하다. 송이 생산지로도 유명해 일대 마을마다 가을이면 송이채취로 온 마을이 떠들썩하다.", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 장마면, 계성면", + "MNTN_NM" : "구현산" + }, + "longitude" : 128.53222220000001, + "latitude" : 35.513055600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충주시 앙성면에 위치한 국망산의 옛이름은 금방산이었다.국망산으로 불리워지게 된 세월은 그리 길지않다. 임오군란 당시 명성황후가 이곳으로 피난을 오게 됐다. 피난을 와서 한양소식이 궁금한 황후는 매일 이 산마루에 올라가 한양을 바라보며 초조해 했었다는데서 국망산이라 불려지게 된 것이다.당시 황후는 충주목사인 민옹식의 집으로 피난을 가기로 하였으나 피난지가 알려지면 신변이 위험할 것 같아 이곳으로 피한 것이다. 황후가 피신한 집은 가난한 초가집이었는데 그 집에는 이도령이라는 총각이 홀어머니를 모시고 나무장사를 하면서 살고 있었다. 이도령은 가난하였으나 황후를 극진히 대접하였다.황후가 피난생활을 마치고 환도한 후 이 도령을 불러 사례하고자 하였으나 사양하여 황후는 이 도령에게 음성군수를 시켰다. 이도령은 군수 재직중 선정을 베풀어 주민들로부터 칭송을 받았으며 그 후 5개 마을의 군수를 지냈다. 마을에서는 이 도령의 집을 이음성집이라 부르고 그의 집터를 대궐터라고 부르고 있다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면 본평리", + "MNTN_NM" : "국망산" + }, + "longitude" : 127.73527780000001, + "latitude" : 37.0777778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국봉은 충북 단양군 적성면과 제천시 청풍면의 경계를 이루는 산으로, 금수산에서 북서쪽으로 이어지는 능선이 갑오고개에서 맥을 낮추었다가 북서쪽 동산(東山.896m)으로 이어지는 능선상 700m봉에서 동쪽으로 뻗어 내린 지능선에 솟아 있는 산이다.국봉에 이르는 등산로에는 약 100여 미터 높이의 만경대를 비롯해 촛대바위 등 암릉이 곳곳에 널려 있어 산행시 주의를 요하는 곳이다. 국봉 정상은 굴참나무로 둘러 싸여 전망이 시원치 않으나 능선 곳곳의 암릉이 주변의 경관을 보여 주어 산행 재미를 더해준다.", + "MNTN_HG_VL" : "628", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군, 제천시", + "MNTN_NM" : "국봉" + }, + "longitude" : 126.41918939999999, + "latitude" : 34.803756900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경주 주변에 있는 모든 산들의 산세가 왕도에 대하여 경의를 표하는 자세인데, 유독 국수봉만은 그 자세가 나라에 반역하는 것처럼 등을 돌리고 앉았다 하여, 나라國자와 원수讐자의 이름을 붙여 국수봉으로 불리워 왔다. 또한 구전에 의하면 신라 때에 형을 받은 죄인들은 이곳에 유배시켰다 한다.지금의 은을암 주지 스님은 讐자를 守자로 바꾸어 재치있게 國守峰으로 표기하고 있다. 스님 말씀에 讐자를 守자로 표기한 것은, 서라벌을 등지고 일본을 향하고 있는 것은 신란 경주에 등 돌렸다기보다는 일본으로부터 나라를 지킨다고 보아야 한다는 것이다.높거나 험하지 않아 부담없는 산행이나 아침운동을 즐기기에 적당한 산이다.", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "국수봉" + }, + "longitude" : 127.27972219999999, + "latitude" : 37.4091667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국통산은 우보면 나호리에 위치한 산으로서 해발 336.8m로 그리 높지 않은 산이나 정상부위의 등산로에서 맑은날 내려다보면 동북쪽으로 금성산, 동쪽으로 선암산, 뱀산, 동남쪽으로 옥녀봉, 남쪽으로 팔공산과 매봉산이 보이며 북서쪽으로는 마정산, 선방산 등이 관측된다.", + "MNTN_HG_VL" : "337", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 우보면 나호리", + "MNTN_NM" : "국통산" + }, + "longitude" : 128.6382653, + "latitude" : 36.198841799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "403", + "MNTN_LOCPLC_REGION_NM" : "전라남도 함평군,영광군", + "MNTN_NM" : "군유산" + }, + "longitude" : 126.41355950000001, + "latitude" : 35.156066299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "199", + "MNTN_LOCPLC_REGION_NM" : "경기도 시흥", + "MNTN_NM" : "군자봉" + }, + "longitude" : 126.805131, + "latitude" : 37.358890000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산행은 쌍곡리에서 시작한다. 쌍곡계곡에서 시원스런 나무숲 사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2미터 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다. 원효굴에서 조금 더 가면 첫 봉우리에 이른다. 다시 고개 하나를 지나면정상이다. 하산은 서남쪽 고개를 돌아 계곡을 타고 내려온다. 큰군자산 종주 코스는 비지정등산로이며 현재 국립공원 지정등산로는 소금강 - 큰군자산 - 도마골 정도니 그 외 등산로는 허가를 받아야 한다.", + "MNTN_HG_VL" : "948", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면", + "MNTN_NM" : "군자산" + }, + "longitude" : 127.87860019999999, + "latitude" : 36.737540799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "굴암산은 경남 김해시와 진해시를 북남으로 가르고, 부산광역시마저 능선으로 금을 그은 요충의 산이다. 지리산에서 비롯되어 김해의 동신어산(459.6m)까지 산줄기를 이어간 낙남정맥의 주능선은 창원시와 김해시의 경계를 이룬 용지봉(723m)에서 한줄기 곁가지를 남쪽으로 뻗어 내린다. 이 산줄기는 성주사로 유명한 불모산(802m)을 일으킨 후 다시 두 줄기로 나누어진다. 남쪽으로 내리는 한 줄기는 웅산(703m), 장복산(582.2m), 천자봉(503m) 등을 일으키고, 동녘으로 달리는 또 다른 한 줄기는 화산(798m)과 굴암산, 보배산(479m)을 일으킨 후 남해바다에 스르르 잠기게 된다. 3월말 정상에서면 벚꽃이 만개해 인산인해를 이루는 진해시와 낙동강 하구둑, 가덕도, 안골포, 거제도 등이 푸른 남해와 어울린 멋진 풍광을 볼 수 있다.인근 주민들이 팔판천이라 부르는 계곡이 있어 팔판산이라고도 한다. 능선 남쪽 자락 끝부분에는 용추폭포가 있다. 사람들의 발길이 없어 호젓한 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "663", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 웅동, 김해시 장유면, 부산광역시 강서구 지사동", + "MNTN_NM" : "굴암산" + }, + "longitude" : 128.78995459999999, + "latitude" : 35.157104699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "궁산은 궁산이란 이름 외에 파산, 성산, 진산, 관산등의 이름을 가지고 있다. 백제의 옛날 고성지가 있었으며, 조선조 화가인 겸재 정선이 양천 현령으로 재임하면서 그림을그렸던 소악루가 있고 오랜 세월동안 인물을 배출한 양천 향교가 있다. 임진 왜란때 의병의 집결장소였으며, 조선시대에는 우리고장의 행정 중심지 였다. 한강과 마주하고 있으며 북쪽으론 경사가 가파르며 남쪽으로는 완만하다. 정상 부근엔 평지가 있고 한강 전경을 볼수 있는 조망소도 위치하고있다.", + "MNTN_HG_VL" : "74", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강서구 가양동", + "MNTN_NM" : "궁산" + }, + "longitude" : 128.4833333, + "latitude" : 35.868333300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금정면 세류리의 기동 마을에서 북서쪽으로 조금 떨어진 곳에 있는 이 산은 산 정상부에 산성이 있었다 하여 궁성산이라 이름 붙었다. 현재는 대부분 도괴된 상태로 그 흔적만이 일부 남아 있다.이 궁성산성은 그 유래에 대한 기록이 전혀 없어 정확한 축성연대와 용도 등은 알 길이 없다. 하지만 주민들은 임진왜란 당시 이곳에서 군사와 말을 훈련시키고 화살을 쏘는 연습장으로 활용되어 '활터'라 불렀다고 전한다.지형상으로는 장흥 유치나 금정 청룡리를 경유해 쳐들어오는 왜구를 방어하기 위한 산성으로 판단된다.또한 일부에서는 월출산과 활성산에서 전달된 신호를 전하는 봉화대였을 것이라는 주장도 있다.또한 역사적으로 임진왜란과 한국전쟁을 온몸으로 겪으면서 아파했던 곳이기도 하다. 등산로가 잘 닦여있지 않으며, 가시덤불이 너무 많아 힘든 면이 있지만 겨울에는 나름대로의 묘미를 주기도 한다.궁성산은 산의 높이가 484.2m로 규모가 큰 것도 아니고 산세가 수려하지도 않다. 그러나 역사적으로 임진왜란이나 6.25동란을 거치며 전쟁의 소용돌이가 끊이지 않았던 곳으로 아픈 역사의 단면을 간직한 곳이다.", + "MNTN_HG_VL" : "484", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 금정면, 나주시 봉황면", + "MNTN_NM" : "궁성산" + }, + "longitude" : 128.19955880000001, + "latitude" : 37.106391000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동쪽과 북쪽은 지세가 험하여 일반등산화 이상을 싣고 등반하여야 하는 곳이다.자연 경관은 산불피해를 입어서 앙상한 나뭇가지들이 있어 경관을 헤치고 있다.강원도 삼척시 미로면에 위치한 근산은 삼척에서 자랑하는 미로 8경중의 하나이다. 강을 건너는 나무다리가 오십개나 있었다 해서 이름 지어진 오십천에 물을 보태는 근산은 삼척에서 바라보면 마치 우산을 펼쳐 세워 놓은 것처럼 보인다.원시림을 그대로 간직하고 있고 동해바다를 끼고 오르는 산과 바다를 즐길 수 있는 산행을 즐길 수 있다", + "MNTN_HG_VL" : "514", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면", + "MNTN_NM" : "근산" + }, + "longitude" : 129.1358333, + "latitude" : 37.407777799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "505", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면 내미로리", + "MNTN_NM" : "근산" + }, + "longitude" : 129.1358333, + "latitude" : 37.407777799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강과 바다 들녘이 어우러진 서남쪽 끝머리에 자리 잡은 해남에는 먼 이북의 아름다운 금강산과 토시 하나 틀리지 않는 똑같은 이름을 가지고 있는 금강산이 자리하고 있다. 기암괴석으로 된 암장과 아열대 수림으로 덮여 있고, 봄이면 춘란이 무리지어 갈잎 속에 꽃대를 올려 개화를 시작한다.lsquo;옥녀탄금rsquo;의 형상이라는 해남읍의 지형에서 가야금을 타는 선녀에 해당하는 금강산은 병풍처럼 해남읍을 두르고 있고 정상에는 금강산성이 성곽을 이루고 있으며 아래로는 은적사, 금강폭포, 미암 등이 자리하고 있다. 해남에 이름 있는 많은 산들의 유명세에 가려서 사람들이 많이 찾는 곳은 아니지만 비교적 산을 오르기 쉬우며 사람의 발길이 닿지 않는 야생의 모습을 그대로 간직하고 있는 산이다. 크고 작은 돌무더기와 암벽들을 산길 곳곳에서 접하게 되고, 인적이 드물어 사람의 흔적이 묻어나지 않은 억새풀 숲과 수목들로 가득 차 있어 조바심을 내지 않고 트레킹 하는 기분으로 천천히 오르기에 알맞은 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "481", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 마산면", + "MNTN_NM" : "금강산" + }, + "longitude" : 128.10495800000001, + "latitude" : 38.6566951 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진도의 금강이라 불리고 있는 金骨山. 군내면 둔전리에 위치한 금골산은 200미터도 채 안 되는 낮은 산이지만 개골산이라는 다른 이름이 말해주듯 산 전체가 기암괴석으로 형성된아름다운 산으로 석굴 세 개와 더불어 금성초등학교의 교정에 있는 고려말에 세워진 5층석탑(보물 제 529호)과 산 중턱의 굴에 마애여래좌상(전남 문화재자료 제 110호)이 음각되어 있으며 해언사라는 절이 있었는데 최근에 복원되었다.1498년 정언벼 슬을 지낸 이주(李胄)가 무오사화때 이곳에 유배되어 금골산의 아름 다움에 감탄,『금골산록』을 지어 서거정의 동문선에 실려 오늘에 전 해오고 있다.석수가 수만 년에 걸쳐 예술품을 조각해 놓은 듯 층층인가 하면 구멍이고, 구멍인가 하면 기둥이고, 사람인가 하면 짐승인 모습을 보여주며 기암의 색깔 또한 황색, 백색, 흑색, 회색 등으로 다양하다.산 아래 자리한 아담한 학교에 있는 보물 제 529호 금골산 오층 석탑은 진도의 기나긴 연륜을 대변한다. 산 중턱에는 욕심을 내서는 안 된다는 전설을 안고 있는 굴암이 있다.산 위에는 세 개의 석굴이 있는데, 맨 왼쪽 굴 북쪽 벽에는 1470년 정후에 조성한 것으로 알려진 좌우 3.5m 크기의 미륵불이 있다. 이 미륵불 배꼽에서 쌀이 나와 석굴에서 깨우침을 얻으려는 수도자들의 양식이 되어 왔으나 그 중 한사람이 욕심을 부려 더 이상 나오지 않게 되었다는 전설이 전해진다.또 서거정의 동문선 금골산록편에는\"\"영험이 많은 금골산이 매년 빛을 발해 유행병 등 재앙을 막았으나 미륵불이 조성된 후 빛을 발한 적이 없다\"\"라고 해 민간신앙의 변천 모습을 보여준다.", + "MNTN_HG_VL" : "196", + "MNTN_LOCPLC_REGION_NM" : "전라남도 진도군 군내면", + "MNTN_NM" : "금골산" + }, + "longitude" : 126.29486300000001, + "latitude" : 34.539684000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 거창군의 분지 가운데에 우뚝 솟아있는 금귀봉은 산의 모양이 탕건의 모양을 하여 `탕근산'이라고도 불린다.또 금귀봉 정상에는 아직까지 봉수대의 흔적이 남아있어 주변 마을 사람들은 봉수산이라고도 부른다.금귀봉에는 많은 문화유적이 있는데 현재도 샘터와 금귀사 절터 등이 남아있다. 또한 금귀봉의 동남쪽 기슭 석장골에는 지난 71년 발굴된 고려 초기의 문마 벽화고분과 양평리 석조여래입상 등의 문화 유적이 있다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", + "MNTN_NM" : "금귀봉" + }, + "longitude" : 127.9513889, + "latitude" : 35.729999999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 괴산군의 최남단에 위치한 금단산은 주위의 도명산이나 낙영산 등의 유명세에 밀려 잘 알려지지 않은 산이다. 그러나 안으로 들어가보면 우거진 송림과 바위지대가 잘 어우러져 있고 용대천 계곡 남쪽에 위치하고 있어 정상에서의 조망이 좋고 아직까지 때묻지 않은 자연경관을 자랑하고 있어 색다른 곳을 찾는 등산객들에게 권하고 싶은 산이다.샘이 없어 사담마을에서 반드시 식수를 준비해야 한다. 높은 절벽과 노송이 군락을 이루고 있으며 계류가 맑아 여름철 피서객들이 많이 찾고 있다.", + "MNTN_HG_VL" : "767", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "금단산" + }, + "longitude" : 127.2472779, + "latitude" : 37.521461799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금당산은 광주 풍암지구를 병풍처럼 둘러싸고 있는 산으로 북쪽으로는 옥녀봉, 서쪽으로는 황새봉을 거느리고 있다.옥녀봉에서 황새봉에 이르는 능선을 따라 걷다보면 무등산 정상인 천황봉을 비롯해 동화사터와 장불재, 광주 월드컵 경기장이 한눈에 바라보이고, 광주 시가지와 멀리 어등산이 어렴풋이 눈에 들어온다. 서쪽으로는 함평 들녘으로 떨어지는 아름다운 일몰을 감상할 수도 있다.광주시 서구청에서 8.2킬로미터에 이르는 산책로를 정비해 노약자나 어린이들도 쉽게 접근이 가능하다. 등산로 곳곳에는 쉼터와 체육시설 등을 설치하고 나무 이름표를 달아놓아 어린이들의 자연학습장으로도 좋다. 주변의 아파트 단지를 따라 많은 등산로가 개설되어 있어 작은 산이지만 다양한 코스를 즐길 수 있는 것이 장점이다.", + "MNTN_HG_VL" : "304", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 서구 풍암동", + "MNTN_NM" : "금당산" + }, + "longitude" : 126.88861110000001, + "latitude" : 35.117777799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금당산은 강원도 평창군 봉평면과 대화면 경계를 이루는 산으로 평창강 상류의 금당계곡을 끼고 있어 물놀이를 겸할 수 있는 가족단위 산행지로 적합한 곳이다.산 자락 밑에 흐르는 금당계곡에는 높이 60m의 직벽으로 된 봉황대라는 곳이 있는데 이곳은 옛날부터 봉황새 이외의 다른 새는 근접을 하지 못했다고 한다.강원도 산골로 이름 높은 평창군 일대는 오대산(1,563m), 계방산 (1,577m) 등 1,000m를 넘는 고산이 운집해 있다. 신리 쪽에서 바라보면 왼쪽의 거문산(1,175m)이 훨씬 높아 보이고 밋밋한 평행선의 능선 끝 오른쪽에 약간 튀어 오른 금당산의 정상이 보인다.정상에서는 동쪽의 잠두, 백석산의 능선이 선명하게 조망되며 이곳에서 바라보는 잠두산은 누에가 기어가는 모습 그대로의 형상이다. 금당산 정상은 펑퍼짐한 봉우리로서 태기산, 회령봉, 계방산 등의 조망이 더욱 좋은 위치이다.금당산은 봄에는 진달래, 여름에는 원시림을 방불케 하는 울창한 나무숲, 가을에는 오색의 단풍 물결, 겨울에는 눈꽃으로 아름다움을 나타내고 있는 산이다.계곡의 물은 아주 깨끗하며 계곡물이 매우 차기 때문에 한여름에도 산행로가 선선함을 느낄 수 있다.", + "MNTN_HG_VL" : "1173", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 용평면", + "MNTN_NM" : "금당산" + }, + "longitude" : 126.88861110000001, + "latitude" : 35.117777799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "191", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 남동구, 부평구", + "MNTN_NM" : "금마산" + }, + "longitude" : 127.0982281, + "latitude" : 36.838459 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금물산은 경기도 양평군과 강원도 횡성군의 경계를 이루고 있다. 예전에 도둑이 많이 나타나서 붙여진 도둑고개에서 동쪽 횡성 방향으로 내려가면 왼쪽에 나타나는 산이다.산은 그다지 높지 않으나 주능선 길이가 10km를 넘어 계곡이 길고 깊다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑아 가재와 식용 개구리가 많다.금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서북으로 뻗어나가고 있다.\"성지봉\"이라는 이름은 옛날 임금의 행차가 쉬어갔다고 하여 붙여진 이름이라 하며, 이곳은 여름에는 길섶의 풀이 웃자라 긴팔, 긴바지가 아니면 통과하기 힘들다.성지봉에서 정상까지는 봉우리가 두 개 있어 길이 오르락 내리락 한다.정상은 일부 바위도 있으며, 특히 양평 쪽으로 뻗은 서봉과의 사이에 자리하고 있는 계곡 쪽으로는 절벽을 이루고 있다.조망도 좋아 동쪽으로는 가리산이 보이고, 북쪽으로는 넓은 시동리와 유치리 일대의 분지가 보인다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼 만하다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 횡성군", + "MNTN_NM" : "금물산" + }, + "longitude" : 127.8491667, + "latitude" : 37.553611099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "390", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성구", + "MNTN_NM" : "금병산" + }, + "longitude" : 127.7452778, + "latitude" : 37.8125 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "춘천시에서 남쪽으로 8킬로미터 지점에 자리 잡은 산으로 일명 진병산(陳兵山)으로 불리며, 춘천시를 에워싼 산들 중 최고봉이라고 할 수 있는 대룡산(899m)에서 남서쪽으로 뻗어내린 능선이 수리봉(645m)을 솟구친 후 그 맥이 원창고개에서 잠시 가라앉았다가 마지막으로 솟은 산이다. 사계절 중 겨울에 오르기 가장 좋은 산으로 가을이면 낙엽이 무릎까지 빠질 정도로 수목이 울창하다. 김유정의 고향 실례마을을 품고 있는 산이며, 춘천의 문인들이 그의 소설 제목을 따서 만부방길, 동백꽃길, 봄봄길 등의 이름을 붙인 정겨운 등산길이 눈길을 끈다. 본래 금병산 정상은 참나무숲으로 에워싸여 조망이 어려웠지만, 최근 춘천시에서 100여 평 정도 깨끗하게 베어내 이제는 사방으로 막힘없는 조망을 즐길 수 있다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신동면, 동산면", + "MNTN_NM" : "금병산" + }, + "longitude" : 127.7452778, + "latitude" : 37.8125 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금수봉은 계룡산 천황봉에서 뻗어나온 산줄기가 민목재를 지나서 백운봉(535.5m)에서 두갈래로 갈라져 오른쪽에 금수봉을 왼쪽에 도덕봉을 빚어 놓았다. 이 같은 명산의 정기를 이어받은 금수봉은 정상 에 올라서서 사방을 내려다보면 주위의 풍경이 비단에 수를 놓은 것 같다고 하여 금수봉이라고 부른다.대전의 금수봉은 이름 그대로 아름다운 산이다. 맑은 개울이 있고 짙은 숲이 있으며 아기자기한 바위등성이가 있다.봄에는 꽃이 아름답고 가을에는 단풍이 곱다. 금수봉 바로 옆의 봉우리 이름은 '백운봉'이다. 금수봉과 백운봉 고운 이름을 가진 두 산이 한 곳에 있는 곳은 우리나라에서 여기뿐일 것이다.금수봉은 큰암벽이 없이 우거진 수림으로 감싸고 있어 초여름 비단같은 신록에 산꽃이 수를 놓은듯이 박힌 아름다운 산으로 유성구에서 수통골 계곡에 레포츠 공원을 조성하여 놓아 시민들이 많이 찾고 있다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성", + "MNTN_NM" : "금수봉" + }, + "longitude" : 127.2811111, + "latitude" : 36.328888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금수산, 이름 그대로 비단에 수를 놓은 듯한 모양을 하고 있다. 월악산 국립공원권 최북단에 위치한 이 산의 이름은 본래 백악산이었다. 조선조 중엽 퇴계 이황 선생이 단양 군수로 있던 시절, 너무도 아름다운 경치에 감탄해 금수산으로 이름을 고쳐 부르게 되었다고 한다.특히 가을 경치가 빼어난 아름다운 암산으로, 봄속에 겨울을 만날 수 있는 신비한 산이다.매년 4월초까지 얼음이 얼다가 처서가 지나면 얼음이 녹는 얼음골에는 돌구덩이를 30cm정도 들추면 밤톨만한 얼음 덩어리가 가을까지 나오고 있어 자연의 신비감을 더해준다. 금수산 주능선은 상어 이빨을 연상케하는 암릉길로 스릴 만점이다.산 중턱에는 바위틈에서 한해나 장마에도 꾸준한 물줄기를 뿜어내고 있어, 산을 찾는 이들의 목을 축여주고 있다. 발길마다 눈길마다 은은히 차고 도는 풍경에 취해 걷다 보면, 어느새 산 정상. 그곳에서 내려다 보면 다소곳이 트인 산세와 충주호의 푸른 물이 어우러져 은은한 채색이 베인 화선지 위에 선 기분이 든다.", + "MNTN_HG_VL" : "1016", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면ㆍ단양군 적성면", + "MNTN_NM" : "금수산" + }, + "longitude" : 128.25666799999999, + "latitude" : 36.983795800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구미역에서 남서쪽으로 약 4km 떨어져 우뚝 솟은 금오산은 1970년 도립공원으로 지정된 산이다. 산 전체가 바위로 이루어져 기암절벽과 경사가 심한 산세를 이루고 있으며, 산아래 대혜폭포까지 케이블카가 설치되어 있다.", + "MNTN_HG_VL" : "977", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시, 칠곡군 북삼읍, 김천시 남면", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "예산의 주산 금오산은 높지는 않지만 산세가 수려하고 주변 경관이 아름답다. 백제 말엽 의각대사가 석달 동안 기도하던 중에 금빛 까마귀 한 쌍이 나는 것을 보고 따라갔더니 맑고 향기로운 샘물이 있더라는 것이다. 그래서 그 자리에 향천사를 세우고 이 산의 이름을 금오산이라 불렀다고 전한다.산정에 오르면 예산의 전경이 한눈에 내려다보이며 청명한 날이면 동남쪽 저 멀리 계룡산이 손바닥만큼 아물거리며, 서쪽으로는 드넓은 예당평야와 삽교천 무한천을 배경으로 도립공원 가야산의 준봉들이 아름다운 저녁 노을 속에 잠겨든다. 남으로는 백제의 최후 항전지인 임존성의 아름다운 산세가 예당호에 얼비치고, 북쪽의 광대한 ‘소들’의 기름진 들녘에 아산호와 삼교천호와 더불어 곡창을 이룬다.산중턱에 있는 용바위는 옛날에 원님이 이곳에서 기우제를 올리면 비를 내리게 해주었다는 전설이 전해져 내려오는 곳으로, 많은 군민의 심신을 단련하는 등산로로 손색이 없어 각광받고 있다. 또한 금오산 동쪽의 유서 깊은 향천사와 북쪽의 탈해사에는 약수가 샘솟는 샘터가 있어 등산 후 지친 심신을 식혀줌에 부족함이 없다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "충남 예산군 예산읍", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "지리산 왕시리봉에서 섬진강을 내려다보면 굽이쳐 가던 섬진강 끝자락에 삼각형 실루엣으로 우뚝 솟은 산이 눈길을 사로잡는데, 하동의 진산인 금오산(849m)이다. 금오산 정상은 남해 조망이 일품이다. 오른쪽으로 광양제철소와 화력발전소, 정면으로 다도해의 수많은 섬들이 점점이 떠 있고, 왼쪽 사천만 뒤로 우뚝한 와룡산의 멋진 자태 또한 일품이다. 정상에 선 중계탑으로 인해 실제로 오를 수 있는 정상부가 한쪽으로 밀려나 있는 게 아쉽다.남해를 비추며 떠오르는 달맞이와 해맞이, 아름다움을 간직한 해넘이는 금오산이 자랑하는 최고의 볼거리다. 달맞이 전망대로는 금오산 남쪽의 너덜지대에 위치한 석굴암이 최고로 꼽힌다. 달이 없는 밤이라도 불야성을 이룬 광양제철소의 야경 또한 황홀한 볼거리를 제공한다.석굴암과 봉수대, 비구니도량 금성암 등 산행하면서 둘러볼 수 있는 볼거리 외에도 1973년 완공된 남해대교와 충무공의 얼을 기리는 충렬사, 그 앞 노량 앞바다에 떠 있는 거북선 등 많은 명소가 있다.", + "MNTN_HG_VL" : "849", + "MNTN_LOCPLC_REGION_NM" : "경남 하동군 금남면ㆍ진교면", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산보다 일출이 유명한 향일암으로 더 잘 알려진 산이다. 한국의 4대 기도처로 꼽히는 향일암은 이름부터가 해를 향해 있다는 뜻으로 풍수지리상 금거북이가 경전을 등에 모시고 바다속으로 들어가는 형상을 하고 있으며 암자가 소재한 산의 이름도 쇠 금(金)자, 큰 바다거북 오(鰲)자를 써서 금오산이다.한때 거북 구 자를 써서 영구암(靈龜庵)이라 부른 적이 있고 현재 영구암이란 편액이 남아 있기도 하다. 이러한 전설을 더욱 그럴 듯 하게 꾸며주는 것이 이 일대 바위의 무늬다. 바위마다 한결같이 거북의 등무늬를 닮은 문양이 나 있는 것이다. 항일암에서 백미를 이루는 경관은 원효대사가 수도했다는 관음전 앞에서 바라보는 풍경이다.동쪽으로는 많은 섬들이 웅집해 있느나 동쪽은 구름한점 없는 하늘처럼 짙푸른 바닷물만 일렁인다. 수평선 위로 떠오르는 해돋이는 그 어느곳에서도 찾아 볼 수가 없다.항일암 뒷편으로 오르면 흔들바위에서 부터 시야가 확 트이는 바위지대에 이른다. 촛대바위, 기둥바위 등 기이한 형상의 바위들이 짙푸른 바다와 어우러진 멋진 경관은 산행길에는 좀체 보기 드문 선경이다.이로써 금오산은 비록 높이는 낮아도 명산이라 일러 부족함이 없는 산이다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 돌산읍", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;고운 물빛 굽어보는 낙동강변 명산gt;금오산은 낙동정맥 영축산에서 남서로 갈라진 영축지맥에 있는 산으로 경남 밀양시와 양산시를 가르고 있다. 남쪽으로 천태산(630.9m), 북쪽으로는 만어산(670.4m)을 거느리고 이 일대 6~7백미터 산들의 형님 노릇을 하는 산이다. 정상에 서면 멀리 영남알프스와 남쪽의 낙동강 조망이 시원하다. 삼랑진을 중심으로 밀양강과 낙동강이 만나는 멋진 풍경을 볼 수 있고, 낙동철교 아래 고운 물빛과 어울린 은빛 모래톱이 장관이다. 금오산 높이는 정상석에 760.5미터(2003년 지형도와 동일), 경남관광 길잡이의 안내도에는 765미터, 2008년 지형도에는 766미터로 각각 다르게 나와 있다. 정상 주변에 펼쳐진 500미터 정도의 암릉 구간은 바위 자체로도 멋있지만 아무데나 주저앉아도 그대로 조망명소가 된다. 금오산을 중심으로 밀양호, 천태호, 안태호, 감물저수지, 국전저수지 등이 펼쳐지는 게 특징이다. 산행은 주변의 만어산, 천태산과 연계가 가능하다.", + "MNTN_HG_VL" : "766", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍·단장면, 양산시 원동면", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼랑진과 원동에 걸쳐 있는 금오산과 천태산은 낙동강을 끼고 있어 주위 경관이 수려할 뿐 아니라 경부선열차를 이용할 수 있어 교통도 편리하다.금오산만 오를 경우 4시간, 금오산- 천태산 코스는 6시간30분, 금오산-매봉산 코스는 6시간 정도 소요된다. 3~4개의 바위봉우리로 뭉쳐진 채 힘차게 단일봉 형상을 한 금오산은 멀리서 보아도 그 자태가 당당하여 천태,만어산을 거느린 `맏형 산'으로 손색이 없다.주변에 삼랑진양수발전소가 안태호 천태호 등 인공호수와 더불어 명소로 등장했고 가락국 때부터 있어온 부은암은 이 곳을 찾는 사람들에게 오늘과 어제를 가르쳐 주는 역사의 현장이다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼량진읍, 양산 원동", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "766", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍·단장면, 양산시 원동면", + "MNTN_NM" : "금오산" + }, + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "속리산과 구병산 사이에 빼꼼히 솟아오른 금적산은 충북 보은군 삼승면에 그 터를 두고 있다. 예로부터 전국민이 3일간 먹을 수 있는 보배가 묻혀 있다고 전해오는 이 산은 주변에 어울린 명산을 닮아 수려한 산세를 자랑하고 있다.또한 이 산은 이름과 관련하여 금으로 된 동물이야기를 전설로 전하고 있다. 옛날 이 산에는 금송아지와 금비둘기가 살고 있었다. 금송아지는 금비둘기를 아내로 맞이하기 위하여 산기슭에 밭을 일구어 금비둘기가 좋아하는 여러 가지 곡식을 가꾸었다. 양지 바른 곳에 집을 짓고 바위아래 옹달샘을 파서 보금자리도 마련했다.그런 다음 금비둘기에게 청혼하여 둘은 결혼을 하게 되었고 금슬좋은 부부로 행복한 나날을 보내고 있었다.그러던 어느날 금송아지는 밭을 갈다가 넘어지는 바람에 두눈을 잃고 말았다. 금비둘기는 눈먼 남편을 위하여 열심히 봉양하였으나 금비둘기의 벌이로 금송아지를 먹이기에는 역부족이었다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 삼승면 서원리", + "MNTN_NM" : "금적산" + }, + "longitude" : 127.70805559999999, + "latitude" : 36.406388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙안읍성 북쪽에 솟은 금전산은 낙안의 진산이다. 옛 이름은 쇠산이었으나 백여년 전에 금전산으로 바뀌게 되었으며 한자 뜻풀이로 보면 금(金)으로 된 돈(錢) 산이 된다. 그러나 금강암 스님의 말에 의하면 금전산은 불가에서 유래한 이름으로 부처의 뛰어난 제자들인 오백비구(오백나한) 중 금전비구에서 산 이름을 따왔다고 한다. 또한 풍수지리를 공부하는 사람들은 금전산의 산세를 이렇게 해석하기도 한다.금전산 북동쪽에는 옥녀봉이 있고 동남쪽 줄기에는 오봉산과 제석산이 있다. 서남쪽에는 백이산이 있는데 전체적으로 놓고 볼 때 이것은 옥녀산발형이라 말할 수 있다. 풀어 말한다면 옥녀가 장군에게 투구와 떡을 드리려고 화장을 하기 위해 거울 앞에서 머리를 풀어헤친 형상이라고 한다. 이러한 말을 뒷받침하듯 낙안읍성 남쪽에 있는 평촌리 평촌못은 옥녀의 거울에 해당하는 조건을 완벽하게 갖춘 못이기 때문에 예부터 낙안에는 미인들이 여느 지역보다 유난히 많이 났다고 한다.금전산 산행 초입에 높이가 10여미터 되는 형제바위가 있는데 원래는 두 개가 사이좋게 서 있었다고 한다. 그런데 80년대 초반 동생바위가 허물어져 형님바위만 남았다고 한다. 들어갈 때는 금강문이고 나갈 때는 해탈문이라는 바위굴을 나서면 금강암에 오른다. 금강암은 백제 위덕왕 때 창건되었다고 한다. 금강암을 지나면 의상대라 불리는 바위에 올라설 수 있다.", + "MNTN_HG_VL" : "668", + "MNTN_LOCPLC_REGION_NM" : "전남 순천시 낙안면", + "MNTN_NM" : "금전산" + }, + "longitude" : 127.3497222, + "latitude" : 34.924722199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부산시의 동래온천 북쪽 4km되는 곳에 있으며, 일부는 경남 양산군에 속해 있다.무한의 보고인 바다와 더불어 산자락은 풍요로운 삶의 터전이 되고 있는 부산의 모산이기도 하다.산세는 능선이 완만하게 뻗어내려 요란스러움이 없고, 고담봉을 비롯하여 부채바위,나비바위,대륙봉 등 암장이 있으며, 능선 언저리에는 곳곳에 억새 밭이 있고 날등 어디서 보나 낙동강과 부산시내를 내려다 볼 수 있어 가슴이 후련하다.고당봉,의상봉,상계봉,서문을 연결한 날등에는 외침을 대비한 조선 숙종 29년에 쌓은 국내 최대규모의 금정산성이 자연석으로 축조되어 있고, 동쪽 산록에는 대찰 범어서와 많은 암자가 있다.범어사는 합천 해인사, 양산 통도사, 순천 송광사, 구례 화엄사와 더불어 우리나라 5대 사찰 중의 하나로 많은 불교 역사유적을 간직한 유명한 사찰이며 인근에금강공원과 동래온천이 있다.산정에는 높이 3장(丈:1장은 10자) 정도의 돌이 있고 샘은 둘레가 10여 자[尺]이고 깊이가 7치[寸]로서 늘 물이 차 있으며 가뭄에도 마르지 않고 금빛이 났는데, 금색 물고기가 5가지 색의 구름을 타고 하늘에서 내려와 그 샘에서 놀았다는 전설에서 산이름이 유래되었다고 전해진다.", + "MNTN_HG_VL" : "801", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 금정구ㆍ북구, 경상남도 양산시", + "MNTN_NM" : "금정산" + }, + "longitude" : 129.05547390000001, + "latitude" : 35.283041900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포천읍에서 북쪽으로 약 10km 떨어진 나즈막한 산으로 교통이 편리하고 산길이 짧아 산을 처음 오르는 사람이나 여성들에게 인기가 있다. 산중턱에 금룡사라는 절과 커다란 미륵불상이 자리하고 있어 문화적 가치도 높은 산이다.정상에는 삼각점이 있고, 백운산,국망봉,청계산 등 조망이 뛰어나다.봄의 진달래, 늦가을의 낙엽, 겨울의 설경 또한 좋으며 계곡은 능선 북쪽편이 좋다.산록에는 사시사철 철철 넘치는 석간수가 있고, 일동에는 유황,하와이,사이판온천 등이 있다.", + "MNTN_HG_VL" : "569", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영중면 금주리", + "MNTN_NM" : "금주산" + }, + "longitude" : 127.272735, + "latitude" : 37.957242299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "자연경관이 좋고 등산로가 원만하여 누구나 쉽게 오를수 있고, 산림욕 하기 좋다. 산을 오르면서 동식물들을 접할수 있어 자연학습에 도움이 많이 된다. 정상에 올라가면 비봉산과 인제읍 시가지가 한눈에 내려다 보이며 경관이 좋다.", + "MNTN_HG_VL" : "662", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 인제읍 상동리", + "MNTN_NM" : "기룡산" + }, + "longitude" : 129.0124543, + "latitude" : 36.120247200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "기룡산은 화북면과 자영면을 경계 짓는 산으로, 일반인에게는 그리 알려지지 않은 관계로 아직은 때 묻지 않은 능선을 따라 호젓하게 산행을 즐길 수 있는 산이다. 정상에서 남쪽으로 3.3킬로미터 떨어진 고깔산과 연계해 능선을 이을 수 있으며 남쪽 아래 영천댐(자양호)의 시원하고 넓은 호수를 굽어보는 맛은 일품이다.북쪽 보현산 천문대를 건너다보며 정상 서릉을 따라 이어지는 아기자기한 암릉을 오르내리는 길은 기룡산의 백미라 할 수 있다. 정상 남쪽 아래에는 신라천년 고찰인 묘각사가 있고 기룡산이란 이름도 이 묘각사를 창건할 당시 동해 용왕이 의상대사에게 설법을 청하고자 말처럼 달려왔다는데서 연유한 이름이라 한다.기룡산 정상 부근은 조망 즐기기에 좋은 암릉으로 되어 있으며 정상에는 무인산불감시카메라와 2000년 해맞이기념비가 있다. 탑전리 너머로 천문대가 자리하고 있는 보현산과 면봉산이 보이며 동쪽으로는 낙동정맥 산줄기를 따라 운주산과 침곡산이 있다. 서쪽으로는 방가산과 봉림산, 화산이 산줄기를 이으며 자리잡고 있다.영천호에서 고깔산을 따라 기룡산까지 이어지는 능선은 마치 승천을 기다리는 잠룡의 모습처럼 그 산세가 웅장하고 정상의 산불감시탑은 용의 뿔처럼 보인다.", + "MNTN_HG_VL" : "875", + "MNTN_LOCPLC_REGION_NM" : "경북 영천시 자양면", + "MNTN_NM" : "기룡산" + }, + "longitude" : 129.0124543, + "latitude" : 36.120247200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "271", + "MNTN_LOCPLC_REGION_NM" : "전라북도 전주", + "MNTN_NM" : "기린봉" + }, + "longitude" : 127.1736111, + "latitude" : 35.809722200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "383", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "기마봉" + }, + "longitude" : 129.02803879999999, + "latitude" : 37.651583500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "기백산은 1983년 함양군이 군립공원으로 지정했으며, 옛 이름은 지우산(知雨山)이다. 기백산 자락의 거창, 안의 지역은 기백산의 날씨 변화에 따라 비가 내릴 것을 미리 알 수 있었다고 한다. 백두대간인 덕유산 능선이 무룡산, 삿갓봉, 장수 덕유산으로 구비쳐오다 남덕유에서 갈라져 남동 방향으로 꺾어진 뒤 월봉산, 금원산을 일으킨 다음 거창 쪽으로 깊숙이 들어와 솟았다. 산 고스락 남쪽에 원추리와 싸리나무군락으로 이루는 기백평전이 펼쳐져 있으며 지우샘이 솟아 맞은편 황석산과 수망령에서 시작한 물줄기와 합하여 안의 지우천을 이룬다. 지우천이 흐르는 장수동은 옛 안의 삼동 가운데 하나인 심진동으로 지금은 용추사 계곡으로 더 알려져 장수사 조계문, 용추폭포, 용추사들의 명소가 널려있다. 또 기백산 안봉에서 솟기 시작한 물줄기는 고학천 용폭을 이루고 쌀다리와 용원정 명소를 간직하고 있다.", + "MNTN_HG_VL" : "1331", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 위천면·함양군 안의면", + "MNTN_NM" : "기백산" + }, + "longitude" : 127.7850818, + "latitude" : 35.709718100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "704", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시", + "MNTN_NM" : "기양산" + }, + "longitude" : 128.15472220000001, + "latitude" : 36.295277800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정상 아래에 석이바위라는 멋진 조망처가 있는데, 옛날에 기우제를 지내던 장소로 산 이름은 여기에서 유래한다. 주민들은 물비리산 또는 물빌이산이라고 부른다. 기우산성(祈雨山城)과 산자락을 따라 삼국시대 말기에 조성된 것으로 추정되는 14기의 신월리 고분군이 남아 있다. 인근 조양산(朝陽山; 684m)과 연계된 산행코스가 개발되어 있으며, 소요시간은 4시간이다. 산행은 상월리에서 시작하여 우암사와 석이바위를 거쳐 정상에 오른 뒤 719봉과 북동릉 산행을 경유하여 조양산에 오르고 송림지대를 따라 성불사로 내려오는 코스이다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 신월리", + "MNTN_NM" : "기우산" + }, + "longitude" : 128.6730556, + "latitude" : 37.3561111 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "까치산은 경상북도 청도군 운문면 방음리 말음 마을에 있다.말음 마울의 말음의 뜻은 계곡의 경관이 빼어나고 산중유곡이라 하여, 옛날에 신선과 선녀들이 모여 놀던 곳으로, 선녀들이 노닐 때마다 부르는 노래 소리가 언제나 끝 후렴만 들려오고 주된 부분은 들리지 않아 끝소리를 다서 말음이라 한 것이 마을 이름으로 되었다.산행들머리는 방음리에 내려 포장길안으로 100m 쯤 마을로 들어서면 ‘원두막’이라는 간판이 보이고 그 위에 2채의 빨간 벽돌집이 보인다.", + "MNTN_HG_VL" : "571", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면 방음리", + "MNTN_NM" : "까치산" + }, + "longitude" : 126.8467055, + "latitude" : 37.531767500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "295", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군", + "MNTN_NM" : "까치절산" + }, + "longitude" : 126.8746556, + "latitude" : 37.471224599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "꾀꼬리봉은 충북 제천시 덕산면 억수리 깊은 협곡인 용하구곡 청벽대 남쪽에 위치한 산으로, 월악산 국립공원권에 속한다. 비경지대인 청벽대에서 남쪽 직선거리로 약 2km 지점에 수석처럼 솟아 있는 꾀꼬리봉은 예로부터 다른 산에 비해 꾀꼬리가 많이 살았기 때문에 붙여진 이름이라고 한다. 기암과 노송이 어울려져있고,용하구곡 물줄기도 시원스럽게 보인다. 용하구곡으로 내려서면 선녀가 목욕을 즐겼다는 선미대가 보이고 용하구곡 물줄기를 따라 30 분가량 걸으면 청벽대가 반긴다.용하구곡 물줄기는 잠시 속세와 적을 끊은 무릉도원을 연상케한다.정상에서의 조망은 북쪽에서부터 하설산,문수봉,대미산이 용하초등교를 감싸고 있고 남쪽에서 서쪽으로는 백두대간이 보이고,서북쪽으로는 메밀봉과 월악산이 첩첩산중을 이룬다.꾀꼬리봉 산행의 백미는 하산길에 있다. 전망대바위?암벽지대? 일주암을 거쳐 용하구곡으로 내려오는 코스는 급경사 암벽지대가 많아 초심자에게는 다소 부담스럽지만 보조자일이 설치돼 있어 큰 어려움은 없다.", + "MNTN_HG_VL" : "890", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면 월악리", + "MNTN_NM" : "꾀꼬리봉" + }, + "longitude" : 127.3522222, + "latitude" : 36.486944399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙동강 1300리 중에서 유일하게 낙동이라는 지명을 가진 상주시 낙동면 낙동리에 낙동강과 어우러져 솟아있는 산이 나각산(螺角山)이다. 산체가 둥글어 소라 형국이고 정상 능선에는 뿔 모양을 하고 있다. 하나는 둥글어 원봉이고 또 하나는 첨봉인데 두 개가 쌍립하여 기묘하다. 부의 상징인 노적봉과 귀를 보장하는 필봉을 겸한 셈이다.산세가 부드럽고 완만하여 가족 동반 산행을 하기에 좋은 산으로 소나무가 많이 우거져 있어 삼림욕을 하기에도 적당한 곳이다.특이한 것은 이 산은 원래 강으로서, 융기되어 만들어졌다는 것을 바위에 박혀 있는 강돌과 등산로 주변에 흩어져 있는 둥근돌 등을 보면 금방 알 수가 있고 정상 주변의 바위에는 군락을 이루고 있는 부처손들이 특징이다.산행시간이 짧기 때문에 비봉산과 연계해 산행하는 것이 좋으며 산행 후 낙단교 휴양단지에서 낙동강을 감상하며 휴식을 취하는 것도 좋다.", + "MNTN_HG_VL" : "240", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 낙동면 물량리", + "MNTN_NM" : "나각산" + }, + "longitude" : 128.30134760000001, + "latitude" : 36.382563500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "544", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "나래산" + }, + "longitude" : 127.1250915, + "latitude" : 35.612496 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "662", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 광하리", + "MNTN_NM" : "나팔봉" + }, + "longitude" : 128.60795680000001, + "latitude" : 37.346452900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "475", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 용정동, 용암동", + "MNTN_NM" : "낙가산" + }, + "longitude" : 126.3276408, + "latitude" : 37.691369100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙가산의 산명은 신라 선덕여왕 4년 금강산 보덕암에서 수도하던 회정스님이 이곳 봉황이 날아와 집을 짓는 형국의 명당에 자리잡고 절을 세울 때, 관세음보살이 계신다는 인도 남해의 보타 낙가산의 이름을 따라 뒷산을 낙가산이라 불리게 되었다고 하며, 해명산, 상봉산보다 낮으나 주변 경관이 좋다.강화도의 끝, 외포리 항구에서 배를 타고 들어가다 보면 누에고치처럼 나지막히 자리잡은 석모도(席毛島)라는 섬이 있다. 이곳에는 300m 남짓한 산들이 섬 가운데에 길게 누워있는데 그 많은 봉우리안에 낙가산이 자리잡고 있다. 석모도의 주봉은 해명산이지만, 낙가산과 줄기를 같이하는 해명산(327m)과 상봉산(316m)에 비해 더 잘 알려진 까닭은 유명 사찰인 보문사가 있기 때문이다.산은 야트막하고 작지만 맵시 있고 적당한 다리품을 팔기에 그만이다. 보문사는 절 위에 모신 눈썹바위의 불상이 영험하다고 하여 불자들의 발길이 끊이지 않는데 눈썹바위에서 내려다보는 서해의 절경이 장관이다. 점점이 흩어져 있는 자그마한 암초들과 무인도는 절로 경탄을 자아낸다. 이 광경은 일찍이 강화 8경으로 알려졌을 정도로 뛰어나다.", + "MNTN_HG_VL" : "267", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", + "MNTN_NM" : "낙가산" + }, + "longitude" : 126.3276408, + "latitude" : 37.691369100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "483", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 용정동, 용암동", + "MNTN_NM" : "낙가산" + }, + "longitude" : 126.3276408, + "latitude" : 37.691369100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙영산은 속리산(1,058)을 조산(祖山)으로 백악산(858)과 도명산(642)사이에 기암절벽을 이룬 산이다. 남과 북으로 용대천과 화양구곡을 안고 있으며 암골미(岩骨美)가 뛰어나 괴산의 명산으로 불리고 있다.낙영산은 속리산국립공원권에 속한 산답게 산자락 곳곳에 두꺼비바위,코끼리바위등 기암을 가지고 있으며, 암릉이 산재해 있어 아기자기한 암릉산행 묘미와 시원스런 조망을 동시에 즐길 수 있는 곳이다. 또 이 산자락에 위치한 공림사(公林寺)도 볼 만 하다. 공림사는 법주사의 말사로 신라 경문왕(861-874)때 자정선사가 창건한 천년 고찰이다.정상에 서면 백두대간 주능선에 장쾌한 모습과 속리산 연봉들에 아름다운 모습을 볼 수 있고 산행 후에는 용대천과 화양구곡에서 깨끗한 자연을 만끽 할 수 있다. 하지만 암벽지대가 많아 다소 위험한 곳이 있으므로 주의해야 한다.", + "MNTN_HG_VL" : "746", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "낙영산" + }, + "longitude" : 127.81869210000001, + "latitude" : 36.640329199999996 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남군자산은 북쪽에 위치한 군자산(948m)에 비해 덜 유명한 곳이지만 기암절벽이 만들어내는 경치와 산에서 흘러나오는 깨끗한 물은 군자산 못지 않은 곳이다. 또한 남쪽에 약 2km에 걸쳐 있는 선유계곡은 보기만 해도 남군자산 등반에서 흘린 땀을 씻어준다. 그래서 이곳은 등산과 피서를 함께 할 수 있는 장점을 가지고 있다.산행을 시작하면 누구라도 압도당할 수 밖에 없는 집채만한 바위 덩어리들이 하늘을 가리운다. 이것이 삼형제바위, 수천톤이 됨직한 바위 세 개가 조각품을 전시해 놓은 듯 하다.관평 사람들은 이산을 소군자산,혹은 남봉이라 부른다. 북으로 보이는 군자산의 웅장한 산세가 보이며 북동쪽으로는 칠보산, 남동쪽으로는 대야산이 대야산 너머로는 속리산 문장대로 이어지는 능선이 그림같이 펼쳐진다. 한편 선유계곡은 조선시대 학자 이황이 이곳 경치가 좋아 아홉달을 돌아다니며 구경하고 선유동(仙遊洞)이라 이름 붙인 곳이다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면 관평리", + "MNTN_NM" : "남군자산" + }, + "longitude" : 127.8718618, + "latitude" : 36.691155799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "치악산 국립공원의 최고봉인 비로봉(1,288m)에서 남쪽 치악재 방향으로 뻗어 내린 능선 상에 우뚝 솟은 남대봉은 강원도 원주시 판부면과 신림면의 경계를 이루는 산이다.남대봉에서는 상원사, 영원사 등 치악산의 이름난 절 3개곳중 둘이 보이고 절이 있는 상원골과 영원골등 2개의 긴 계곡도 보인다. 둘다 구룡사가 있는구룡계곡에 못지 않는 계곡이다. 또한 4계절마다 그 모습을 달리하며 호젓한 등산로 때문에 많은 산악인과 관광객의 발길이 끊이지 않고 있다.정상 동남쪽 아래에 있는 상원사 대웅전 앞에는 꿩과 구렁이의 보은의 전설을 간직한 삼층석탑 2기가 눈길을 끈다. 정상에 서면 북쪽으로 고둔치와 치악산맥의 연릉과 치악산 정상인 비로봉이 아스라히 보인다.", + "MNTN_HG_VL" : "1182", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 판부면, 신림면", + "MNTN_NM" : "남대봉" + }, + "longitude" : 128.0519444, + "latitude" : 37.308333300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간상에 있는 남덕유산은 거창군, 함양군 장수군의 경계선에 솟아 있다.덕유산 산행하면 으레 향적봉을 목표로 하는 것이 일반적이다. 그래서 거의 모든 등산로가 향적봉을 향해 뚫려 있으나 등산인들이 별로 찾지 않는 남덕유도 향적봉에 견줄만한 산세를 지닌 산이다.남덕유산 정상에는 맑은 참샘이 있어 겨울에는 김이 무럭무럭 나는 온수이고, 여름에는 손을 담글 수 없는 찬물이 솟아 오르는데 천지 자연의 신비한 이치는 사람으로서 말하기 어렵고 그저 그렇게 되려니하고 인정하기란 너무 오묘한 자연의 신비감이 있다.남덕유산은 3대강의 발원샘을 갖고 있다는 것이 특징이다. 임진왜란 당시 나라를 구하기 위해 왜구들과 싸웠던 덕유산 의병들이 넘나들었던 육십령은 금강(錦江)의 발원샘이며 정상 남쪽 기슭 참샘은 거룩한 논개의 충정을 담고 있는 진주 남강(南江)의 첫물길이 되며 북쪽 바른 골과 삿갓골샘은 낙동강(洛東江)의 지류 황강(黃江)의 첫물길이다.삿갈골샘에는 대피소가 있어 백두대간을 종주하는 산악인의 쉼터로 인기 있고, 동서 사면은 가을 단풍이 특히 좋다. 그리고 적설량이 많아 설경 또한 뛰어난 산이다.", + "MNTN_HG_VL" : "1507", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "남덕유산" + }, + "longitude" : 127.67942360000001, + "latitude" : 35.768681399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해발 164미터의 남망산은 접도의 주산(主山)으로 산 자uuml;가 접도라 해도 과언이 아니다. 접도는 진도군 동남쪽에 위치한 아주 작은 섬으로 예부터 접섬, 금갑도, 갑도, 접배도 등으로 불리던 유배지였다. 지금은 진도와 접도를 잇는 연육교가 있어 접근이 수월하다. 남망산(南望山)은 산을 이루는 기암들이 모두 남쪽바다를 바라보고 있어서 붙은 이름이다. 높이는 낮지만 ª게는 1시간, 길게는 총 12킬로미터의 5시간yen;리 코스 등 다양하게 등산로가 조성되어 일정에 맞는 산행코스를 선택할 수 있는 것이 장점이다. 또 이정표 설치 및 등산로 정비가 잘 되어있어 길atilde;기의 어려움이 없으며 흙길도 걷고 바닷길도 걷는 이색산행을 즐길 수 있다. 솔섬에서 작은여미로 이어지는 길에는 몽돌해변에 맨발uuml;험 등산로가 조성되어 있으며 쥐바위에서 거북바위 구간에는 웰빙등산로가 만들어져 가족 산행지로도 제격이다. 가뭄에는 전 구간에 물이 없으므로 사전에 식수를 준비해야 한다.", + "MNTN_HG_VL" : "164", + "MNTN_LOCPLC_REGION_NM" : "전남 진도군 의신면", + "MNTN_NM" : "남망산" + }, + "longitude" : 128.4297943, + "latitude" : 34.841193799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남병산은 강원도 평창군 대화면과 방림면, 평창읍의 경계를 이루는 산이다. 남병산은 북쪽 멀리 오대산에서 서쪽 계방산으로 이어지는 능선에 솟아 있는 산이다.첩첩 산중인 평창의 가리왕산(1,560m)과 이웃하고 있다. 주변에 유명한 오대산, 계방산, 발왕산 등 높고 큰 산이 많아 국도변에 위치하여 있으면서도 지나쳐 버리는 산으로 취급되어 왔으나 인적이 드문 관계로 해묵은 수목이 군락을 이루어 볼만하다.육산 남병산에는 그러나 평창강가로 지긋이 다가서 있어서 정상능선에서 평창강을 내려다 보는 각별한 맛이 있다. 또한 20여평의 공터로 사방이 확 트여 전망이 좋은 편이다. 북동쪽으로는 중왕산과 가리왕산이, 동으로는 청옥산이, 남으로는 장암산과 삼방산이, 서쪽으로는 백덕산, 중대갈봉과 장미산, 절구봉이 스카이라인을 이룬다. 평창강은 우리나라의 대표적인 사행하천(구비가 많은)으로 계방산에서 발원하여 장평에서 흥정산, 태기산에서 발원한 흥정천을 합치고 금당계곡을 흘러내려와 방림에서 백덕산에서 흘러내려온 계촌천을 합쳐 평창을 지나고 주천을 거쳐 영월에서 동강과 합류, 남한강이 되어 흘러내려간다.", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "남병산" + }, + "longitude" : 128.45249999999999, + "latitude" : 37.427499999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남암산은 문수산 남쪽 산으로 김신기 산이라고도 한다. 그 유래는 경순왕이 나라가 어려워지자 영축산을 찾아 문수보살의 계시르 받고자 삼호까지 왔을 때, 한 동자가 앞을 인도하다가 무거에서 자취를 감추자, 경순왕은 문수보살이 자기를 저버렸음을 깨닫고, 고려에 나라르 바치니, 그의 장남 마이태자는 개골산으로 들어가 인생을 마감하고 둘째 차남 범공은 불가에 의지하다가 결국은 남암산에 김신암을 짓고 여기서 생을 마감했다.조망이 탁월해 울산과 주변의 산이란 산은 모두 볼 수 있다. 북쪽 정면으로 삼태봉, 파헤친 곳 국수봉, 그 뒤 치술령, 그 왼쪽으로 무학산 연화산 백운산 고헌산 문복산 운문령 상운산 가지산 배내봉 간월산 신불산 영축산 투구봉 시살등 오룡산 염수봉 채바우골만당 천마산 토곡산, 그 앞 능선엔 정족산 천선상이 그야말로 파노라마처럼 펼쳐진다. 울산 시가지와 온산공단 그리고 탁 트인 동해바다도 볼 수 있다.", + "MNTN_HG_VL" : "543", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", + "MNTN_NM" : "남암산" + }, + "longitude" : 129.21700000000001, + "latitude" : 35.512999999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진안고원의 남부 백운면과 성수면, 마령면의 경계에 남쪽 고덕산과 더불어 암봉, 암릉으로 이루어진 내동산이 솟아 있다. 진안읍 마이산에서 암릉 줄기가 서남쪽 진안 성수면과 임실 성수면 방향으로 길게 뻗어 내리면서 나웅대(545m), 광대봉(609m)을 일구어 놓고 널따란 마령평야를 지난 남쪽에 고덕산과 함께 빚어 놓은 산이다. 동남쪽 덕현리 산기슭에 안겨 있는 약수암과 내동폭포 주변 일대의 사철 변화무쌍한 풍경은 오가는 길손들의 발목을 붙잡는다. 약수암은 보잘 것 없는 초라한 암자이지만 이 산과 약수암은 일명 ‘백마산 백마사’라고도 불리고 있다. 남북으로 길게 뻗어있는 이 산은 지금까지 오지로 알려진 백운면에 속해 있었기 때문에 사람들이 찾는 기회는 많지 않은 편이었다. 그러나 암릉선을 타고 남북을 종주하는 등산 코스가 등산인들에게 사랑을 받기 시작했다. 남릉에서 북릉을 타면서 조망되는 경치가 일품이기 때문이다. 북으로 마이산의 두 말귀와 운장산, 그리고 동쪽으로 덕태산, 선각산과 성수산, 팔공산이 하늘과 맞닿아 늘어서 있는 가운데 산들과 산 사이로 펼쳐진 백운평야는 한국의 전형적인 농촌 풍경이다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 백운면, 마령면, 성수면", + "MNTN_NM" : "내동산" + }, + "longitude" : 127.36805560000001, + "latitude" : 35.690277799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전라북도 부안군 변산면, 전서면, 보안면, 상서면, 하서면의 5개면에 걸쳐 산악과 해안 일대를 포괄하고 있는 변산반도는 아름다운 해안선을 다라 수많은 절경이 이어지는 우리나라 유일의 반도공원이다.호남정맥에서 나뉘어 온 하나의 산줄기가 서해로 튕겨 나온 듯한 변산반도 내변산에는 의상봉(509m), 신선봉(486m), 쌍선봉(459m) 등 기암 괴석으로 이루어진 산봉우리와 그 사이 직소폭포, 봉래구곡, 낙조대 등 승경이 곳곳에 산재하고 있다.그 주변에는 유천도요지, 구암 지석묘군, 호벌치와 우금산성 등의 역사 유적지와 '내소사'와 '월명암' 이라는 역사깊은 사찰이 있다대부분의 봉우리들이 바위로 이루어져 기묘함을 더하고 그 사이의 계곡에는 폭포와 소, 담 과 여울이 어울려 아름다움을 보태준다.1995년 내변산에 부안댐이 완공되어 물이 차면서 중계계곡이 호수로 변해, 천연적인 단애를 이룬 기암괴석과 어울려 절경을 이룬다.내변산의 직소폭포는 30m 높이에서 힘찬 물줄기가 쏟아지고 폭포 아래에는 푸르른 옥녀담이 출렁대며 여러 개의 크고 작은 폭포를 이루고 있는데 이를 봉래구곡이라 부른다. 곳곳의 계곡에서 내려오는 물줄기들은 백천내로 변산댐에 이르면서 곳곳에 시원한 경치를 만들어 내기도 한다.", + "MNTN_HG_VL" : "459", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면 진서면", + "MNTN_NM" : "내변산" + }, + "longitude" : 126.5713382, + "latitude" : 35.631484299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보경사와 청하골 계곡으로 유명한 내연산은 상생폭포, 관음폭포, 연산폭포 등 12개의 폭포를 거느리고 있는 산으로 산 전체가 거의 육산으로 완만한 능선으로 이어져 있다.내연산 산행 들머리는 유서 깊은 보경사로 이 절은 신라 진평왕 25년에 지명법사가 창건하였다고 한다.지명법사가 진나라에서 유학하고 돌아올 때 신비한 팔면경을 가져와 진평왕에게 진언, 내연산 아래 큰 연못에 거울을 묻고 그 위에 금당을 세운 뒤 사찰을 세워 보경사라 이름을 지었다고 한다.", + "MNTN_HG_VL" : "711", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 송라면ㆍ청하면ㆍ죽장면, 영덕군 남정면", + "MNTN_NM" : "내연산" + }, + "longitude" : 129.28364629999999, + "latitude" : 36.278844499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "그 산 밖에서 볼 수 없는 천하의 명승을 그 산의 내부에 숨기고 있다' 는 뜻의 이름을 지닌 내장산. 기암절벽, 계곡, 폭포와 단풍 등 산이 갖춰야 할 품세를 빠짐없이 갖춘 천혜의 가을산이다.내장산은 전북 정읍시와 순창군의 경계를 이루는 산으로 천하 제일의 단풍 명소로 손꼽히고 있다. 내장사 경내에 있는 정혜루기에 의하면 내장산은 구례의 지리산, 영암의 월출산, 장흥의 천관산, 부안의 능가산(변산)과 더불어 호남의 5대 명산의 하나로 기록돼 있다.말발굽 형태로 이루어진 능선에 기기묘묘하게 솟은 기암절벽과 울창한 단풍숲이 어우러져 가을철이면 단풍 산행지로 각광을 받고 있다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 내장동, 순창군 복흥면ㆍ쌍치면", + "MNTN_NM" : "내장산" + }, + "longitude" : 126.8879786, + "latitude" : 35.479702199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "냉산은 구미 해평면, 도개면, 군위군 소보면의 경계에 위치하고 있는 아담한 산으로 잘 알려지지 않은 산이다.낙동강 동쪽에 위치하며, 팔공산맥(八公山脈)에 속한다. 일명 `태조봉(太祖峰)'이라고도 한다. 고려 태조가 견훤을 정벌하기 위해 축성한 숭신산성이 있고, 산 초입에 신라에 불교를 처음 전한 아도화상이 창건한 것으로 전해진 도리사가 유명하다.도리사는 신라에 최초로 불교를 전한 아도화상(阿道和尙)이 세웠다고 전해지며, 경내에 있는 극락전(極樂殿)과 5층석탑(五層石塔)은 보물로 지정되어 있다.", + "MNTN_HG_VL" : "693", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면, 도개리", + "MNTN_NM" : "냉산" + }, + "longitude" : 128.4007306, + "latitude" : 36.258746899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "429", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시,고양시", + "MNTN_NM" : "노고산" + }, + "longitude" : 126.94474719999999, + "latitude" : 37.6841309 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "노목산은 백두대간의 금대봉(1,418m)에서 서북으로 뻗은 지맥선상에 위치해 있다. 산세가 부드러운 노목산은 노나무산이라고도 불리는데 정상 북동쪽 아래에 있는 백전 2리 노나무마을에서 유래되었다.노목산 산행은 정선과 사북읍을 잇는 노나무재에서 시작된다. 이곳에서 15분 정도 오르면 주릉선에 오르게 되고 정상은 능선길을 따라 1시간 30분여 더 오르면 당도할 수 있다. 삼각점이 있는 정상에서는 이름을 알 수 없는 연봉과 백두대간의 장중하게 앉아 있는 모습을 한눈에 볼 수 있다. 정상 부근에는 이름도 모를 꽃들이 지천에 널려 있다. 노목산은 산세가 부드러워 산행에 별 어려움은 없다.", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍, 동면", + "MNTN_NM" : "노목산" + }, + "longitude" : 128.84527779999999, + "latitude" : 37.254444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;원시림 간직한 오지의 산gt;백두대간의 금대봉(1418m)에서 서북쪽으로 뻗은 지맥이 민둥산(1119m)과 지억산(1117m)으로 가는 중간지점에 자리잡고 있는 산으로 아직 원시림을 간직하고 있는 오지의 산이다. 일명 노나무산이라고도 불린다. 노나무, 즉 개오동나무와는 관련이 없다. 그 유래는 산 정상 북동쪽 아래 백전2리 노나무 마을에서 유래한 것이다. 옛날 매년 음력 정월 보름에 솟대를 세우고 마을의 안녕을 빌었는데 이 풍습을 ‘노대를 지낸다’ 하여 노나무골이라 불렀다. 또한 마을을 감싸고 있는 산을 노목산이라 칭했다. 삼각점이 있는 정상에 오르면 북쪽은 이름을 알 수 없는 연봉들이 중첩하고 동쪽은 아련히 백두대간이 마루금을 긋고 있다. 남쪽은 백운산(1426m), 두리봉(1466m)이 날개 죽지를 펴고 있다. 민둥산과 지억산이 서쪽으로 가깝다. 조망도 일품이지만 넓은 헬기장의 가을꽃이 노목산의 자랑이다. 각시취, 절굿대, 노란색을 뽐내는 마타리, 빨간 모자를 쓴 산비장이, 수리취, 그늘취, 참취, 어수리, 산솜방망이, 산오이풀, 엉겅퀴, 싸리나무꽃, 억새꽃이 지천에 피어난다.", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍·동면", + "MNTN_NM" : "노목산" + }, + "longitude" : 128.84527779999999, + "latitude" : 37.254444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍, 동면", + "MNTN_NM" : "노목산" + }, + "longitude" : 128.84527779999999, + "latitude" : 37.254444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "노성산은 논산8경 중 제8경인 노성산성이 있는 산이다. 이 산성은 백제시대에 축성된 것으로 자연적인 지세를 교묘하게 이용하여 둘레 약 1킬로미터를 석축으로 거의 완벽하게 쌓은 성지이다. 동면, 북면, 서면을 활석을 다듬어 네모지게 하여 쌓았고, 봉우리 정상에는 장대지로 추정되는 곳과 동벽으로 약간 내려온 곳에 봉수대로 보이는 곳이 남아있다. 성내에는 우물지가 4개소 있고, 건물지로 보이는 여러 개의 유지가 있으며 백제시대의 기와편과 토기편 그리고 고려, 조선시대에 이르기까지 다양한 유물들이 산재해 있다.동쪽으로 계룡산이 막아서고 남쪽으로는 논산평야가 바라다 보이며 북쪽으로는 공주, 서쪽으로는 부여 방면이 한눈에 조망되는 요지로, 연산 황산성과 함께 백제와 신라가 대치했던 방어선에 위치한 산성이다. 그 중요성 때문에 노성산성은 삼국시대부터 조선시대에 이르기까지 계속해서 사용했던 것으로 전해진다.노성산에는 논산시민들이 해맞이를 즐기는 넓은 공터가 있다. 이곳에 오르면 우리나라 3대 곡창지대 중 하나인 논산평야가 황금빛으로 물들어 풍요롭게 보인다. 더 멀리 기운찬 계룡산의 향적봉, 국사봉, 천황봉, 그리고 관음봉으로 이어지는 마루금이 인상적이다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "충남 논산시 노성면", + "MNTN_NM" : "노성산" + }, + "longitude" : 127.5040697, + "latitude" : 37.127014500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "이 산은 백제, 신라, 고구려가 각축을 벌이던 토성으로 옛 문헌에는\"노성산은 음죽현의 주산이며 영산이다.\"라 하고 전설에 의하면 노성산, 마국산, 설성산 사이에 용맹한 말 한 마리가 나타나니 세산에 주둔한 장수가 서로 차지하려다 다툼을 벌였는데 이기는 순서대로 말 머리, 몸통, 꼬리를 차지하기로 했다고 한다. 노성산 장수가 말머리를 몸통은 마국산 장수가 설성산 장수가 꼬리를 차지하여 노성산 정상바위를 말머리 바위라 하며 산의 높이는 310m로 낮으나 산 정상에서 보면 충북 감곡, 안성, 일죽, 여주, 양평까지 보인다.", + "MNTN_HG_VL" : "310", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 설성면", + "MNTN_NM" : "노성산" + }, + "longitude" : 127.5040697, + "latitude" : 37.127014500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "노악산은 갑장산, 천봉산과 더불어 상주 3악을 이루며 상주 서북을 병풍처럼 둘러막고 있는 상주의 진산이다. 노악산에는 국사봉, 옥녀봉, 정상인 상상봉과 큰골, 작은골, 물골, 능암뒷골, 홰나무골, 절골 등이 있다. 등산로는 종주 코스, 중궁암 코스, 홰나무골 코스, 북장사 코스 등 다양하게 개발되어 있고 산세 또한 빼어나서 ‘영남 8경’의 하나로 알려진 산이다. 서쪽 기슭에 북장사, 남동쪽 기슭에 남장사를 품고 있는데 두 사찰 모두 신라 때 창건된 유서 깊은 절이다. 특히 남장사 일대는 늦가을 정취가 인상 깊은 명승지로서 ‘경북 8경’의 하나로 손꼽히기도 하다. 늦가을이면 남장마을의 집집마다 곶감을 널어 말리는 풍경이 정겹다. 이 남장마을은 곶감의 명산지다. 또 남장사 입구의 옛 상주초등학교 남장분교에 전국 유일의 장승공원이 들어서 있다.한편 산경표와 국립지리정보원 발행 지형도에 노악산은 노음산이라 하는데 예전부터 산 아래 주민들은 노음산, 또는 논산으로 불러왔다. 그러나 남장사 일주문에는 ‘노악산 남장사(露嶽山 南長寺)’라는 현판이 걸려 있다. 상주초교 교가에는 노악산으로 되어 있다.", + "MNTN_HG_VL" : "726", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 남장동, 외서면, 내서면", + "MNTN_NM" : "노악산(노음산)" + }, + "longitude" : 128.09666669999999, + "latitude" : 36.438888899999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "일명 노악산이라고도 하는 노음산의 산행 기점은 남장사 입구에 있는 제실저수지이며, 산행코스가 쉽다. 산 아래에는 여러가지 자생식물과 잡목이 섞여 자라며 위로갈수록 참나무, 단풍나무등의 관목들이 많이 있고, 특히 동쪽산 아래에 울창한 숲 속에 있는 남장사는 이름난 명승지이며 서쪽 아래로는 북장사가 있다.", + "MNTN_HG_VL" : "725", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 외서면, 내서면", + "MNTN_NM" : "노음산" + }, + "longitude" : 128.09666669999999, + "latitude" : 36.438888899999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오대산국립공원권에 속해 있는 노인봉은, 강원도 강릉시와 평창군의 경계를 이루고 있는 산으로, 유명한 소금강계곡을 산자락에 거느리고 있다. 금강산의 축소판이라 일컫는 '소금강'이라는 이름은 율곡선생이 청학동을 탐방하고 쓴 〈청학산기〉에서 유래되었으며 무릉계옆 바위에 아직 '소금강'이라는 글씨가 남아 있다.산의 정상에는 기묘하게 생긴 화강암 봉우리가 우뚝 솟아 있으며, 그 모습을 멀리서 바라보면 백발노인과 같이 보인다 하여 노인봉이라 붙여졌다 한다.정상에서 소금강계곡으로 내려서면 낙영폭포가 나타난다. 낙영폭포에서 무릉계까지 7km 가량 이어지는 소금강계곡은 30여개의 다리를 건너야 하는 아기자기한 산행길이다. 낙영폭포를 지나면,광폭포,삼폭포,백운대를 지나 만물상으로 이어진다.", + "MNTN_HG_VL" : "1338", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "노인봉" + }, + "longitude" : 128.6394444, + "latitude" : 37.782499999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "노추산은 강릉시 왕산면 대기리와 정선군 북면 구절리 사이의 경계를 이루는 산으로 해발 1322미터며 북쪽에는 조고봉, 서쪽에는 상원산 남동쪽에는 덕우산, 동쪽에는 사달산을 거느리고 있다. 강릉시에서의 등산로는 왕산면 대기리 늑막골 코스와 왕산면 고단2리 새목재에서 사달산으로 오르는 코스가 나 있지만 경관이 별로 좋지 않아서 등산객들은 거의 정선 쪽 코스를 이용한다. 노추산에는 이성대가 있는데 이곳은 강릉과 정선의 유림들이 힘을 합쳐 설총과 율곡 이이를 기리기 위하여 세운 누각으로 겨울철이나 갑자기 눈·비가 올 때는 대피소 역할도 하고 있다. 중국 노나라의 공자와 추나라 맹자의 기상이 서려 있다 하여 노추산이라 불린다. 신라시대 설총과 조선시대 율곡 이이 선생이 입산, 수학한 곳으로 등산로가 잘 개설되어 있다. 동북쪽으로는 완만한 구릉이지만, 남쪽 정선 방면의 경사면은 심한 굴곡을 이루고 있다. 이름의 유래나 전설로도 명산이요, 산수의 경치로도 명산이다.", + "MNTN_HG_VL" : "1322", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면·정선군 북면", + "MNTN_NM" : "노추산" + }, + "longitude" : 128.74063749999999, + "latitude" : 37.570945199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "뇌암산은 삼척시 각곡면에 자리해 있으며 국립지리원 발행 5만분의 1지형도에는 벼락바위로 표기되어 있으나 근동에서는 뇌암산이라 부른다.사람들의 발길이 잘 닿지 않아 표지기는 물론 등산로도 제대로 나 있지 않지만 경치가 빼어나고 맑은 물이 곳곳에 연이어 있다. 이 산 초입에 있는 덕풍계곡은 자연경관이 빼어나고 마을과 멀리 떨어져 있어 조용하며 여러 개의 폭포가 산재하고 있을 뿐만 아니라 병풍처럼 둘러싸인 산세가 수려하여 등산을 겸한 가족단위 피서지로 적합한 곳이다. 한여름에도 살을 에는 듯한 계류가 흐르고 있다.교통이 조금 불편한 것이 흠이지만 불편을 무릅쓰고 찾아가 볼 만한 곳이다. 오지여행 전문가들이 마지막 남은 오지로 꼽는 곳이기도 하다.", + "MNTN_HG_VL" : "812", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "뇌암산" + }, + "longitude" : 126.987933, + "latitude" : 34.699324500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 문경에 위치한 뇌정산은 백두대간이 속리산을 일구기 전에 백화산에서 동남쪽으로 뻗친 능선위로 투박하게 빚어놓은 산이다.산 이름 탓인지 이 산에는 벼락이 잘 치고 물 난리도 많이 나서 인근 마을에서는 `뇌정산'이라고 부르는 것을 금기시하고 있다. 현재는 안에서 스스로 다스린다는 뜻을 지닌 내정산이라 부르고 있으나 여전히 인적이 드물어 지도에는 초입만 겨우 표시되어 있는 정도다. 때문에 사전에 산행 지도를 준비해야 하며 산행시 각별히 방향 설정에 주의해야 한다.활엽수가 많은 산인데 특히 895봉에서 서쪽 세능 따라 내력는 구간은 곱게 물들은 낙엽이 발이 빠질 만큼 두껍게 깔려 가을의 정취를 한층 느끼게 한다. 또 중간의 바위 언덕에서 빼어난 희양산의 거대한 암봉과 신라 선문구산으로서 지금도 비구니의 수도도량으로 유명한 봉암사를 내려다보는 경관이 빼어나다.", + "MNTN_HG_VL" : "991", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 마성면", + "MNTN_NM" : "뇌정산" + }, + "longitude" : 127.4956402, + "latitude" : 36.6244364 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;꽃대궐 차린 백두대간의 산gt;눌의산은 경상북도 김천시, 충청북도 영동군 경계에 있는 백두대간의 산으로 '눌의'는 눌하다 혹은 더디다의 의미로 김천과 영동 인정의 교류가 뜸했다는 뜻을 가지며 이에 따라 이 산을 찾는 이들이 적어 호젓한 산행을 할 수 있는 곳으로 알려졌다. 하지만 백두대간을 종주하는 사람들을 통해 입소문이 나기 시작해 점차 자연의 순수함과 사람의 손길이 공존하는 곳이 되어가고 있다. 추풍령에서 눌의산까지는 고도차가 500m가 넘는다. 200m대의 추풍령에서 743m의 눌의산까지 오르기 위해서는 깔딱 일어선 능선을 따라 한참 올라야 한다. 등산로 초입부터 곳곳에 오른쪽과 왼쪽 방향으로 등산로가 나뉘지만 왼쪽으로 방향을 잡아서 오르면 된다. 표지기가 자주 눈에 띄지만 야간산행을 하며 길을 헤맸다는 등산인들이 많기에 초입 부분에서 독도에 주의하는 것이 좋다. 추풍령~눌의산~괘방령은 백두대간 구간이라 등산로가 뚜렷하고 아무래도 사람의 발길이 자주 닿다보니 단단하게 다져진 흙길 덕분에 길이 좋다.", + "MNTN_HG_VL" : "743", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", + "MNTN_NM" : "눌의산" + }, + "longitude" : 127.9811368, + "latitude" : 36.196130199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "743", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", + "MNTN_NM" : "눌의산" + }, + "longitude" : 127.9811368, + "latitude" : 36.196130199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "눌의산은 추풍령 뒤쪽에 자리잡은 산으로 등산인들의 발길이 뜸하여 호젓한 산행을 즐길 수 있는 곳이다. 이 산의 이름인 `눌의'는 한자어로 정의가 눌하다 혹은 더디다는 뜻이니 추풍령 영마루를 사이하는 충청도와 경상도의 양쪽 인정의 교류가 뜸하다는 것을 뜻한다.정상에 봉수대가 있는 것으로도 알 수 있듯이 주변 조망이 뛰어나다. 또한 옛날에는 요긴한 거점구실을 했을 것이라는 것을 짐작할 수 있다. 나라에 긴급을 다투거나 외적이 침범했을 때 활활 타는 봉화를 피워올려 제몫의 역할을 다했을 눌의산의 늠름함이 살아 있다. 추풍령에서 시작하는 산행길은 사람들의 발길이 뜸하다보니 깨끗함을 자랑하고 산새들의 울음소리가 한적한 산행길을 함께 한다.", + "MNTN_HG_VL" : "743", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", + "MNTN_NM" : "눌의산" + }, + "longitude" : 127.9811368, + "latitude" : 36.196130199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "능걸산은 걷기 편하고 숲이 좋은 오솔길과 기차바위 부근의 경관이 빼어난 암릉, 영남 알프스의 걸출한 산들을 한 눈에 볼 수 있는 시야까지, 삼박자를 두루 갖춘 산이다. 벌판처럼 시야가 툭 트인 정상에서는 사방이 산으로, 남쪽에는 금정산과 양산이 펼쳐져 있고, 서쪽에는 어곡산, 매봉, 토곡산이 우뚝하다. 동쪽에는 천성산과 화엄벌 억새밭이 유명하다. 능걸산 남동 날등에 펼처진 암릉 구간에는 수십은 넉넉히 앉을 만한 마당바위전망대 뒤 한 칸 높은 곳에 더 탐스런 너럭바위전망대가 숨어있고 울퉁불퉁한 바위능선길을 온몸으로 기어오르는 암릉 구간이 도사리고 있다. 암릉 구간 아래로는 빽빽한 철쭉이 군락을 이루고 있는 반면 매봉산이 있는 구간은 외제가 아닌 순수 국산 융단을 깔아 놓았다. 많은 이들이 천마산이라 부르기도 하지만 산림청에는 능걸산이라는 이름으로 등록되어 있다. 흔한 이정표도 하나 없지만 먼저 다녀간 이들이 남겨놓은 탄탄한 길이 곧 이정표가 되어 많은 등산인들이 즐겨 찾고 있다.", + "MNTN_HG_VL" : "783", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 상북면", + "MNTN_NM" : "능걸산" + }, + "longitude" : 129.00995800000001, + "latitude" : 35.420667199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제왕산의 모산으로 오르기가 다소 힘드나 찾는이가 적어 자연이 그대로 보존된 산이다. 백두대간이 동해를 끼고 설악산(1708)과 오대산(1563), 황병산(1407)을 일으키고, 대관령에서 몸을 낮췄다가 다시 솟아오른 산이 능경봉이다. 겨울철에는 무릎이 빠질 정도로 눈이 많이 쌓이는 곳이나, 비교적 힘들이지 않고 눈덮힌 겨울산을 즐길 수 있는 곳이다.능경봉 산행 들머리는 해발 850m가 넘는 대관령 고개마루인 대관령 남쪽휴게소에서 시작된다. 대관령에는 고갯길을 내고 두 번씩이나 죽음을 당한 고형산(高荊山)이라는 사람 얘기가 유명하다. 본래 대관령 고갯길은 오솔길이었으나, 이 고갯길을 조선시대 중종때 고형산이라는 사람이 사재를 털어 수개월 간에 걸쳐 우마차가 다닐수 있도록 넓혀 놓았다. 따라서 강릉과 한양간의 교통이 편리해졌다.", + "MNTN_HG_VL" : "1123", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "능경봉" + }, + "longitude" : 128.7647929, + "latitude" : 37.672805199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "능동산은 영남알프스의 산군 중에 하나이며 가지산과 천황산, 재약산의 유명세에 가려 그 이름이 묻혀 버렸다. 석남재에서 천황산에 뻗은 산줄기의 중간지점에 우뚝 솟아 있는 산이며, 언양에서 얼음골로 넘어가는 도로가 개통되기 전에는 주변의 산세속에서 아주 깊이 뭍혀 있었던 산이였다.그러나 언양과 밀양을 잇는 도로가 개통되면서 지금은 석남터널에서 가까이 보이고, 또 천황산에 가는 길목의 능선에 위치하고 있어서 많은 등산객들이 지나는 산이다. 특히 이 산에서 천황산과 배내봉 방향의 능선이 갈라지고 있으므로 영남알프스 종주길에 반드시 거치게 되는 지점에 위치하고 있다.능동산 산행은 석남사 주차장 안쪽에서 시작된다. 포근한 산길에 경쾌한 걸음으로 40여 분 후 전망대에 오르는데 여기서 영남 알프스 1000m 고지들이 시야에 전개되고 시원한 바람까지 불어온다. 능동산은 영남 알프스 중앙에 위치해있기 때문에 정상에 오르면 전망을 두루두루 관망할 수 있다. 정상에는 돌무더기를 쌓아 두었는데 아마도 등산객들이 소원성취와 안전을 기원하면서 돌을 하나 둘 올리다보니 돌무더기로 변한 듯 싶다. 하산은 반대쪽으로 하면 된다.", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "능동산" + }, + "longitude" : 129.01635809999999, + "latitude" : 35.584783199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "468", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "능천산" + }, + "longitude" : 128.70815569999999, + "latitude" : 35.908877799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "다락산은 발왕산(1458m)의 산줄기가 남으로 뻗어 내리다 자개천과 송천에 이르러 더 나아가지 못하고 동서로 길게 누우며 솟아오른 형상이다.발왕산에서 뻗어내린 능선상의 마지막 봉우리이다. 송천을 사이에 두고 노추산을 마주 보고 있다. 산 남쪽의 구절리는 오지마을로 남아 있다가 1960년 대 산업철도 구절선이 생기면서 탄광촌으로 흥청거리기도 했으나 광맥이 끊기고 몰려들었던 사람도 다 떠난 지금은 다시 고즈넉한 옛 모습이다.등산로마다 숲이 우거졌고 야생란을 위시한 자생식물이 남아있으며, 자개천의 푸른 물빛이 오염되지 않은 비경을 이루는 깨끗한 산이다. 원시의 냄새를 풍기는 다락산의 초본류는 그 무성하고 수수한 모양새로 그런 것을 좋아하게 마련인 등산객을 유혹한다. 산 꽃 촬영에 적당한 산이다.", + "MNTN_HG_VL" : "1018", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선 북면", + "MNTN_NM" : "다락산" + }, + "longitude" : 128.7215238, + "latitude" : 37.5263499 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "388", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 봉곡동,부곡동", + "MNTN_NM" : "다봉산" + }, + "longitude" : 128.30615879999999, + "latitude" : 36.167700500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "201", + "MNTN_LOCPLC_REGION_NM" : "경상북도 합천군", + "MNTN_NM" : "단봉산" + }, + "longitude" : 128.2624572, + "latitude" : 35.567715799999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경부고속도로 건천나들목에서 남쪽으로 바라다 보이는 산이다. 산은 건천읍 송선리 우중골에 있으며, 산 7-8부 능선에는 4개의 바위가 둘러싸인 천연굴이 있는데 옛날에는 상인암(上人巖, 일명 탱바위)이라고 불리었다고 한다. 화랑들은 이 바위굴 속에 불상을 새기고 그 위에 지붕을 덮어 석굴사원을 만들었다. 이 절을 신선사(神仙寺) 또는 단석사(斷石寺)라고 부른다. 내부의 마애불상은 국보 제199호로 지정되었다. 단석산은 경주에서 가장 높은 산으로 백제에 대한 신라의 국방의 요충지였다.이 지역은 진달래 군락지로 봄철 산악 애호가들의 사랑을 받고 있으며, 인근 조래봉(657m)과 더불어 등산 코스로 각광을 받고 있다. 단석산으로 올라가려면 방내리에서 큰골로 가는 숲길이 있는데 화랑도량의 표시인 화랑바위가 있고, 화랑들을 불러 면회하던 급제바위가 있으며 정상 가까이에 올라가면 김유신이 칼 쓰기 연습을 하다가 남았다는 기둥바위가 있으니 사람들이 고단석이라 부른다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", + "MNTN_NM" : "단석산" + }, + "longitude" : 129.09134510000001, + "latitude" : 35.793620900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "136", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 봉화읍", + "MNTN_NM" : "달봉산" + }, + "longitude" : 128.11477009999999, + "latitude" : 36.141345600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태백의 한 지맥이 동해를 향해 꿈틀대다 크게 용트림해 만들었을까, 아니면 동해가 뒤집히면서 푸른 하늘과 응어리지어 그 정수를 한 곳에 모아둔 것인가? 그리 높지 않으면서도 정상은 큰 바위덩어리로 되어있어 장엄한 맛을 주는 산이다. 또 정상에 서면 동해가 짙푸른 윤기를 발산하며 넘실대고 있어 상쾌함이 등산복을 간지럽힌다.부산에서 1시간 남짓 걸리며 산행시간도 3시간 30분에 불과해 초심자나 가족단위 등산객에게는 안성맞춤의 산이다. 특히 정상 부근의 바위는 특별한 장비가 없이도 몸의 밸런스와 리듬만으로 바위틈새를 타고 오를 수 있어 암벽등반의 묘미도 느끼기에 충분하다.이 산 초입에 있는 일광광산은 지난 날 일본인들이 철광을 캐던 곳으로 지금은 폐광이 되어 있으나 광산마을이 그대로 있고 탄광도 거의 원형 그대로 남아있어 학생들에게는 자연학습의 장소로도 좋다.안부와 바위 틈새는 철쭉 군락지대로 부산근교에서는 정상 주변의 경관이 제일 아름다운 곳이다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "부산시 기장군", + "MNTN_NM" : "달음산" + }, + "longitude" : 129.21083329999999, + "latitude" : 35.307777799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옥천 이원의 달이산은 비단폭 같은 푸른 금강 물줄기와 벗하며 뻗어 있다. 달이산은 이원 사람들에게는 정다운 산이며 달을 연상하게 하는 산이다.달이산 줄기의 전체적인 가닥은 ‘H’자 모양이다. 서쪽 세로 획이 원줄기로 금강 물줄기와 벗하고 있다. 또 멀리서 보면 날카롭거나 까다로워 보이지 않고 순하고 무던하게 보이지만 산에 들어서면 곳곳에 기암절벽이 도사리고 있는 외유내강의 산이라 할 수 있다. 까마득한 바위 낭떠러지가 여러 곳에 있고 그 위는 넓은 암반이어서 쉬기도 좋고 조망하기도 좋다.달이산의 기암괴봉 중 으뜸인 것은 ‘H’자의 가로지른 획 가운데 자리 잡고 있는 암봉이다.정상에서 507미터의 서봉으로 건너가는 산등성이에 있는 둥근 투구모양의 봉우리가 그것이다. 남쪽은 높고 아득한 바위 낭떠러지이며 동쪽도 밧줄을 잡고 오르도록 되어 있을 만큼 높은 바위벽이다. 북쪽과 서쪽도 바위벽이기는 하지만 그리 높지는 않아 오르내릴 만하다.", + "MNTN_HG_VL" : "555", + "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 이원면", + "MNTN_NM" : "달이산(월이산)" + }, + "longitude" : 127.6561111, + "latitude" : 36.228888900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "당산은 경기도 양평과 여주, 강원도 원주에 접해 있는 산으로 서울에서 가깝고 높이도 그리 부담스럽지 않아 주말 가족산행지로 적지이다. 이 산에는 험준한 바위지대가 없는 대신 넓은 계곡이 환히 트여 있어 산행 코스로는 손색이 없다.산에는 다래나무 군락과 호랑이, 산신령 석고상이 모셔져 있는 자연석굴이 있고 정상은 참나무 수림으로 덮여 있어 시야가 그리 넓지는 못하지만 동쪽으로 수리봉 줄기 너머 구룡산이 보인다.또한 철도산행을 할 수 있는 산으로 중앙선 열차를 이용 판대역에서 하차한다. 판대역에서 이천교를 건너 아래 배내마을을 지나 서남쪽으로 차도를 따라 나가면 포장도로와 만나고 길 건너가 솔치마을이다.솔치 마을을 지나 물탕골을 통해 당산으로 오르게 된다. 물탕골은 숲이 우거져 있고 절터가 있는 지점에서 계류를 건너 왼쪽 능선으로 오르게 되는데 도중 묘지에서 우측 계곡으로 내려가면 석간수가 나온다.정상은 넝쿨로 덮혀있고, 남쪽 능선에 바위를 감고 있는 특이한 소나무가 있다.", + "MNTN_HG_VL" : "541", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 여주군, 강원도 원주시", + "MNTN_NM" : "당산" + }, + "longitude" : 126.90199010000001, + "latitude" : 37.534027799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "516", + "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시", + "MNTN_NM" : "대곡산" + }, + "longitude" : 128.53958030000001, + "latitude" : 35.1897935 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가평역 서쪽에 위치한 대금산은 명지산(1267m) 남서봉에서 남쪽으로 이어지는 연인산 - 우정봉 - 매봉 - 깃대봉 - 약수봉에 이어 자리하고 있는 산이다. 대금산에서 계속 이어지는 산릉은 592.7미터봉에 이르러 짧은 능선을 남쪽 청우산에 맡긴 다음, 남동으로 나아가 불기산 - 주발봉 - 호명산을 빚어 놓은 다음 여맥을 청평호 일원 북한강에 가라앉힌다. 대금산은 일제 때 이 산에 있던 소림광산에서 말(馬)만큼 큰 금광석이 나왔다고 해서 그렇게 불리기 시작했다 전해진다. 대금산 아래 두밀리의 옛 지명은 ‘삼이곡’이었고, 예부터 나라에 난리가 날 때면 다른 지방 사람들이 이곳을 피난처로 이용한 오지였다고 한다.", + "MNTN_HG_VL" : "706", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", + "MNTN_NM" : "대금산" + }, + "longitude" : 128.69916670000001, + "latitude" : 34.949444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 거제시 장목면 대금리와 연초면에 있는 산으로 대금산이란 이름은 신라시대에 쇠를 생산했던 곳이라 하여 붙여진 것이다. 그리 높지 않은 산이지만 산세가 순하고 비단폭 같은 풀이 온 산을 덮고 있어 크게 비단을 두른 산이라는 뜻의 같은 이름으로 불리기도 한다.더구나 호위봉인 358미터, 285미터의 중봉이 이 산에 비해 낮기 때문에 상대적으로 우뚝해 보이고 정상이 바위 봉우리라 실제 높이보다 우람하고 드높게 보인다.중봉을 가리켜 중금산이라고도 하며 조선 말기에 축성한 성이 있는데 대금, 시방, 율천 등 3개 마을 주민들이 성을 쌓고 군량을 저장하여 남해안의 각 진에 공급하는 일에 함께 참여했다는 산성이다. 이곳에는 약수터와 기우제를 올리던 제단이 있고 약수터에는 칠석과 보름에 많은 사람들이 찾아와 목욕하고 음용하기도 한다. 멀리서 보면 잘생긴 여인이 아기를 품은 듯한 이 산은 봄이면 진달래가 온 산을 붉게 불태우고, 정상에서 본 중금산성과 소금산성은 마치 여인의 젖가슴과 같이 생겼고, 어머니의 품속에서 소록소록 잠을 자는 아기와 같은 형국을 하고 있다.최근에는 산 중턱까지 도로가 뚫려 자동차로 오를 수도 있어 일요일이면 사람들로 붐빈다. 산행은 장목면 시방(일명 살방)에서 붓골을 거쳐 정상에 오르는 것이 대표적 코스며 정상에 오르면 멀리 대마도와 부산, 마산, 진해가 눈 아래 있음을 느낄 수 있다.", + "MNTN_HG_VL" : "439", + "MNTN_LOCPLC_REGION_NM" : "거제도 연초면ㆍ장목면", + "MNTN_NM" : "대금산" + }, + "longitude" : 128.69916670000001, + "latitude" : 34.949444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태백과 정선 경계를 이룬 대덕산은 초원 산릉과 여름 꽃으로 이름난 산이다. 보름 간격으로 바뀌어 피어나는 야생화는 초원 산릉을 이룬 정상부를 말 그대로 천상의 화원으로 가꾸곤 한다. 게다가 폭 200~300미터에 길이 약 1킬로미터의 정상 능선은 함백산에서 금대봉을 거쳐 매봉으로 이어지는 백두대간뿐 아니라 두타산을 거쳐 오대산까지 이어지는 산릉도 한눈에 들어오는 등 멋진 조망을 제공한다. 8월 대덕산 초원능선은 둥근이질풀, 마타리, 제비꼬깔, 산박하가 만개하고, 9월로 들어서면 보랏빛 산비장이와 자줏빛 쑥부쟁이가 활짝 피는 등 야생화 100여 종이 만개한다. 대덕산의 산행기점은 한강 발원지로 이름난 태백시 삼수동 검룡소에서 시작한다.", + "MNTN_HG_VL" : "1310", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", + "MNTN_NM" : "대덕산" + }, + "longitude" : 128.56, + "latitude" : 37.131943999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대덕산은 이웃한 삼도봉과 함께 경남,북과 전북의 3도를 나눈다. 산 이름이 대덕으로 불리우게 된 것은 이곳으로 살러오는 사람들마다 모두 큰 재산을 모음에 따라 산의 덕을 입었다는데서 연유됐다.대덕산은 가야산을 향해 뻗은 능선을 사이에 두고 경북 김천과 경남 거창을 갈라 놓은 삼도 분기점, 즉 해발1,250m의 초첨산을 옆에 둔 명산으로, 옛날에는 다락산, 다악산으로 불리었고 정사에는 기우단이 있었다고 전하는 명산이다.부드럽게 생겼으면서도 우직한 남성다운 덕기가 어린 이 산은 옛부터 수많은 인걸들을 배출했고, 또한 이 산이 있는 무풍동은 남사고의 십승지지중 하나로 알려진 고장이기에 유명하다.또한 영·호남 지방의 분수령으로 금강의 지류인 무풍천과 낙동강의 지류인 감천(甘川)이 각각 동서 사면에서 발원한다. 산 서쪽은 덕유산국립공원, 남동쪽은 가야산국립공원이 인접한다.", + "MNTN_HG_VL" : "425", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대덕면, 전라북도 무주군 무풍면", + "MNTN_NM" : "대덕산" + }, + "longitude" : 128.56, + "latitude" : 37.131943999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "육백산과 오봉산,도화산을 마주보며 도계읍내를 감싸고 서 있는 산이다.정상을 향 하는 주능선에 올라 서면 도계읍내의 전경은 물론 주변의 겹겹이 쌓여 있는수 많은 크고 작은 산들의 조망이 일품이다.이 산은 도계읍내 도심권에 위치하고 있으며 산의 규모가 작은 편이라 외지의 등산객보다는 주로 도계읍민들의 등산과 운동 코스로 사랑받고 있다.", + "MNTN_HG_VL" : "1290", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍", + "MNTN_NM" : "대덕산" + }, + "longitude" : 128.56, + "latitude" : 37.131943999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대덕산은 대부분 바위로 이루어진 산으로 경사가 급한 편이다.임휴사방면 등산로는 나팔바위 등 가파른 바위로 이루어져 있어 힘들게 오른 만큼 앞산에서볼 수 있는 경치 중 가장 아름답게 느껴지는 곳이다.임휴사는 1988년 전국 70여개 전통사찰중이의 하나로 문공부에 등록된 유서 깊은 사찰이다.신라 경명왕 5년(921년) 영조대사(靈照大師)께서 최초 창건하셨고 서기 1811년(순조11년)에 무주선사가 중창하였다.고려 태조 왕건이 팔공산에서 후백제 견훤과 동수대전에 패하여 이곳으로 와 군사 및 재정비하고관음성현께 기도 드린후 편히 쉬어갔다 하여 임휴사라 했다.매자골이란 옛날 매화(梅花) 낙화지(洛花地)에서 연유되었다. 지금으로부터 300年 전에 대덕산에성기도사가 있었다. 도사가 이 곡의 지세를 목형으로 보았다. 그런 어느 해 이른 봄 이 골짜기에매화가 탐스럽게 피더니 구암동(지금의 송현동)에 떨어졌다 하여 매자골이라고 부르게 되었다.", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구 송현동", + "MNTN_NM" : "대덕산" + }, + "longitude" : 128.56, + "latitude" : 37.131943999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "큰 두메의 산'을 뜻하는 대둔산은 전북과 충남 두 도에 걸쳐있는 도립공원이다. 특이하게도 대둔산은 두 얼굴을 지니고 있다.주능선을 경계로 완주군 방향인 남쪽은 바위 얼굴이고, 북쪽은 순후한 시골 아낙네의 얼굴을 한 금산군과 논산시의 얼굴이다. 남면의 전북 지역은 가파른 비탈에 기암괴봉이 숲처럼 솟아 있어 아기자기하고 멋스러운데 비해 북면의 충남 지역은 울창한 숲이 우거져 장중해 보인다.경관이 뛰어나서 소금강이라 불리기도 하는데, 멀리서 바라보면 늘어 선 암벽이 마치 한 폭의 병풍을 연상케 한다. 그리 높지 않은 산이지만 정상인 마천대를 기점으로 충남 논산시,금산군 그리고 전북 완주군에 산자락을 펼치고 있다. 이 산은 임금바위,장군봉,동심바위,신선바위등 온통 바위로 이루어져 있으며, 이 중에서도 임금바위와 입석대를 잇는 높이 70m, 길이 50m, 폭 50cm인 금강구름다리와 삼선구름다리는 대둔산의 상징이기도 하다.", + "MNTN_HG_VL" : "879", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산시 벌곡면ㆍ금산군 진산면, 전라북도 완주군 온주면", + "MNTN_NM" : "대둔산" + }, + "longitude" : 127.32330930000001, + "latitude" : 36.120049700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "899", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "대룡산" + }, + "longitude" : 127.8202778, + "latitude" : 37.844999999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "206", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", + "MNTN_NM" : "대명산" + }, + "longitude" : 127.5283333, + "latitude" : 37.205277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산이라고 하기에는 염치가 없을 정도로 나즈막한 높이의 대모산은 서울시 강남구에 위치해 있다. 예전에는 국수봉이라고도 불리웠는데 언제부터 대모산으로 부르게 되었는지 확실치 않다.서울 변두리에 위치해 있어 잊혀지다시피한 산이었으나 인근에 아파트가 들어선 후로는 시민들의 휴식처로서의 역할을 톡톡히 하고 있다. 이른 아침 가벼운 산책을 하려는 시민들의 발길이 끊이지 않고 주말이면 많은 사람들이 이곳에 나와 도심의 찌든 때를 씻는다.이 산의 남쪽 기슭에는 헌인릉이 있어 둘러볼 만한데 헌인릉이란 조선 3대 태종과 그 왕비의 능침인 헌릉과 제23대 순조와 그 왕비의 능침인 인릉을 합쳐서 부르는 이름이다.", + "MNTN_HG_VL" : "293", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강남구", + "MNTN_NM" : "대모산" + }, + "longitude" : 127.0783333, + "latitude" : 37.475000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "창선섬에서 가장 높은 산, 대방산은 오르는 길이 세 갈래다. 길이 편해 등산객들이 제일 많이 오르는 코스는 옥천마을에 있는 운대암 사찰 앞을 지나서 창선저수지 위로 난 길을 따라 오르는 동쪽길이다.이 외에도 사포에서 오르는 서쪽길과 상신에서 오르는 북쪽길도 있다. 대방산(臺芳山) 산길을 굽이굽이 돌아 산마루에 오르면, 깊은 계곡 아래 저수지 물빛은 내리쬐는 햇빛이 반사되어 은하수를 만든다. 반짝이는 은하수를 돌아가면 구름에 떠 있다 하여 이름 지어진 운대암이 있다. 옥천마을 동쪽길을 따라 오르다보면 8부능선쯤 경사면에 석축을 쌓은 건물지로 보이는 평탄지가 여러 곳에 보인다.이 곳이 봉수대에 근무하는 병사들의 거주지였던 곳으로 추정하고 있다. 200m정도 더 올라가게 되면 대방산의 정상에 도달하게 된다. 여기에서 동쪽을 바라보면 넓은 강진 바다가 펼쳐지고 서쪽으로 눈을 돌려 바라보면 남해의 진산인 망운산이 보인다. 그리고 남쪽으로 보면 금산이 있고 북쪽으로는 사천 각산이 보인다.아래로 펼쳐진 앵강만은 남해안의 황금어장이다.섬 속의 섬 창선의 아름다움을 가장 가까이서 조망할 수 있는 곳이다. 가을에 대방산에서 내려다보는 단풍으로 물든 경치 또한 일품이다. 대방산 역시 중요한 군사적 요충지였던 관계로 봉수대가 설치되어 있다. 대방산 봉수대는 남해 해안에서 발생한 모든 상황을 육지로 전달하는 중간봉수로서 최남단에 위치한 금산봉수대와 사천 각산에 있는 봉수대의 교량역할을 한 중요한 지역이다.봉수대가 있는 대방산 정상은 장방형의 평탄한 자연암반으로 형성되어 있는데, 이 자연 암반 위에 직접 봉화를 올린 것으로 보인다. 축성법은 토석혼축으로 되어 있고, 현재에는 상당히 양호하게 보존되어 있는 상태이다.소요 시간 :2시간최적 탐방시기 :10월 \/가을볼거리 : 운대암, 봉수대숲길 명소 : 정상에서의 조망, 창선저수지", + "MNTN_HG_VL" : "468", + "MNTN_LOCPLC_REGION_NM" : "경상남도 남해 창선면", + "MNTN_NM" : "대방산" + }, + "longitude" : 127.98564090000001, + "latitude" : 34.858767200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대부산은 경기도 양평군 옥천면에 위치한 산으로 유명산과 이웃하고 있는 산이다. 소구니산, 유명산, 어비산, 대부산, 용문산으로 이루어진 이 곳의 산군은 경기도내에서 정말 보기 드문 경치를 자랑한다.70년대초 이곳에 고랭지채소를 키우기 위해 산에 불을 질러 나무를 다 태워 버렸기 때문에 초원의 느낌을 맛볼 수 있기도 하다. 또한 이곳은 페러글라이딩 장소로도 많이 이용되기 때문에 산행을 하다보면 하늘을 날고 있는 낙하산을 심심지 않게 볼 수 있기도 하다.예로부터 홍수 때면 물고기가 산을 뛰어 넘는다고 하여 어비산이 되었으며, 마주보는 유명산과 함께 설악면과 옥천면을 가르는 산이라 하여 마을에서는 대부산이라고도 부른다. 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이루는 곳에 어비계곡이 흐른다.", + "MNTN_HG_VL" : "743", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면", + "MNTN_NM" : "대부산" + }, + "longitude" : 127.48808649999999, + "latitude" : 37.5675995 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대성산은 충북 옥천군과 충남 금산군을 가르며 남북으로 뻗쳐있는 산줄기 가운데 있는 산이다. 천태산과 장룡산 외 새봉, 마성산, 용봉 등도 이 산줄기를 따라 이어져있다. 이 줄기는 백제와 신라의 경계였으며 모두가 아름답다. 천태산은 그 아름다움이 널리 알려진지 오래며 기암괴석이 많은 장룡산은 물론 대성산도 폭포가 많은 산으로 유명하다. 이 지역 주민들은 대성산 품안에 열 개의 폭포가 있다고 자랑한다.하지만 폭포만이 매력의 전부가 아니다. 폭포가 아니어도 여기저기 솟아 있는 바위봉우리에서 바라보는 조망이 좋다. 이 봉우리들은 천길 낭떠러지를 이루며 좁고 깊은 골짜기 위에 우뚝 솟아있기 때문에 조망이 좋고 무척 시원하다.대성산은 열 개의 폭포와 함께 열 개의 조망이 있는 산이라 할 수 있다. 그 가운데 유난히 뾰족해 멀리서 눈에 잘 띄는 국사봉 위의 조망대는 아예 ‘전망대’라는 정식 이름까지 붙여져 있다. 천길 벼랑 위에 있는 이 전망대에서는 옥천 일대가 발아래 펼쳐지고 멀리 속리산, 덕유산, 민주지산, 백화산, 포성봉과 함께 주행봉, 황악산 등을 조망할 수 있어 좋다.", + "MNTN_HG_VL" : "706", + "MNTN_LOCPLC_REGION_NM" : "충북 옥천군 이원면, 충남 금산군 군북면", + "MNTN_NM" : "대성산" + }, + "longitude" : 127.5427778, + "latitude" : 38.2308333 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대암산 정상 부근에는 큰 용늪, 작은 용늪이라 불리는 고지습원이 있는데, 작은 용늪은 이미 그 원래의 모습을 상실하여 숲으로 변해버리고 말았다. 큰 용늪은 우리나라에서 유일한 고지습원으로 연중 안개끼는 날이 많은 특수한 환경이 조성되고 있어 생태계 연구에 좋은 자료를 제공하고 있다.큰 용늪에는 물이끼, 삿갓사초, 꼬리조팝나무, 꽃쥐손이풀 등의 식물군락이 있으며, 손바닥 난초, 비로용담, 끈끈이주걱 등의 희귀식물도 자라고 있다. 그 밖에 식물성 플랑크톤 63종, 돌말 19종과 천연기념물인 산양과 검독수리가 관찰된 바 있으며, 도룡뇽, 무당개구리, 줄흰나비 등도 볼 수 있다. 또 이 지역과 연결된 두타연계곡에서는 열목어를 비롯한 특산 어류 10여 종이 살고 있다.대암산·대우산 천연보호구역은 분지·습원등 지형적으로 다양한 특징을 지니고 있고, 기후조건이 특이하여 희귀동식물이 자라고 있다. 또한 동식물의 남북한계·동서 구분의 현상이 나타나는 등 식물생태학·식물지리학적·식물분류학적 연구가치가 매우 큰 지역일 뿐만 아니라 다양한 동물상, 특이한 지형·지세 및 기후적 특성 등 다양한 자연 환경을 가지고 있어 학술적 가치가 크므로 쳔연기념물로 지정·보호하고 있다.", + "MNTN_HG_VL" : "1313", + "MNTN_LOCPLC_REGION_NM" : "강원 양구군 동면, 인제군 서화면", + "MNTN_NM" : "대암산" + }, + "longitude" : 128.1350874, + "latitude" : 38.211199499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대야산은 백두대간에 자리잡고 있으면서 대간능선이 꿈틀이고 지나며 아름다운 보석들을 흩뿌려 놓은 문경의 산들 중에서도 그 명성을 높이 사고 있는 명산이다. 경북 문경시(聞慶市) 가은읍(加恩邑) 완장리(完章里)에 속한 대야산은 대간 마루금을 경계로 충북 괴산군(槐山郡) 청천면(靑川面) 삼송리(三松里)와 접하고 있다. 내\/외선유동을 거느리고 있는 대야산은 2002년 세계 산의 해를 맞아 문경의 주흘산, 황장산, 희양산과 함께 산림청에서 선정한 한국 100대 명산에 올라서 있다. 예로부터 명산으로 받들어 온 대야산은 여러 기록들에 ‘大耶山’으로 적고 있으며 특히 철 종 조의 대동지지[(大東地志(1861년 이후 추정)]에는「大耶山 曦陽山南支上峯曰毘盧爲仙遊 洞主山西距淸州華陽洞三十里(희양산남지상봉왈비로위선유동주산서거청주화양동삼십리: 대야산은 희양산의 남쪽 갈래로 제일 높은 봉우리가 비로봉이고, 선유동의 주산이다. 서쪽의 청주 화양동이 30리다)라고 기록하고 있어 대야산 정상을‘비로봉(毘盧峯)’으로 부르고 있음을 알 수가 있다.", + "MNTN_HG_VL" : "931", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 청천면", + "MNTN_NM" : "대야산" + }, + "longitude" : 127.9324859, + "latitude" : 36.670577600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대운산은 울산광역시와 부산광역시, 경남 양산시의 경계에 있는 산이다. 금정산에서 원효산, 천성산을 이어가는 낙동정맥이 그 중간에서 동쪽으로 곁가지를 내려 백운산(520m), 철마산(604m), 거문산(543m), 달음산(588m), 용천산(545m) 등을 차례로 일으킨다. 그 중 최고봉인 대운산은 2개 광역시와 경상남도의 경계선을 긋는 중요한 곳에 자리하고 있으며, 장안사, 척판암, 내원암 등 역사의 향기가 가득한 명찰을 자락에 품고 있는 남녘의 명산이다.대운산을 오르는 산길은 다양하나 겨레의 영원한 스승 원효대사의 발자취를 찾아 기장군 장안읍에 자리한 장안사를 거쳐 오를 수 있다. 장안사는 신라 문무왕 13년(서기 673년) 원효대사가 창건한, 오랜 역사를 자랑하는 고찰이다.‘불광산(대운산의 다른 이름) 대운사’라고 쓰인 문을 지나 들어선 장안사 뜨락에는 동백꽃이 뚝뚝 지고 고목들이 연륜을 알려주는 경내에는 불향이 그득 넘친다. 장안사 절문을 나서면 오른쪽에 참으로 특이한 해우소(변소)가 보인다. 굵은 왕대를 엮어 울타리를 두른 멋진 해우소. 볼 일이 급하지 않더라도 잠시 들러 왕대나무 화장실의 멋을 엿보아야 한다.", + "MNTN_HG_VL" : "742", + "MNTN_LOCPLC_REGION_NM" : "경남 양산시 웅상읍, 울산시 온양면, 부산시 기장군", + "MNTN_NM" : "대운산" + }, + "longitude" : 129.21184489999999, + "latitude" : 35.402419600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "덕갈산은 산청,거창,함양군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳에서 양분 되어 한줄기는 갈전, 철마, 소룡, 바랑산을 거쳐 황매산으로 뻗어있고 또하나가 바로 덕갈산 줄 기를 이루며 그 끝은 태봉산까지 길게 이어져 있다. 마치 떡가래처럼 널어져 있는 형세를 하고 있으며 그 줄기위에서는 지리산을 정면으로 바라볼수 있어 주변의 1000m 내외의 산들과 구별되어 산중에 제왕임을 한눈에 알 수 있게한다. 또한 덕유산에서 지리산으로 흐르다 출렁이면서 솟아 오 른 고봉들도 조망이 가능하여 덕갈산을 방문한 등산객에게만 산행의 참맛을 선사한다. 덕갈산은 가슴을 확트이게하고 눈을 즐겁게 하는 산으로 자신을 자랑하기보다는 주변 산들의 기상 과 기세를 칭찬하는 겸손한 산이다.", + "MNTN_HG_VL" : "669", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군,거창군,함양군", + "MNTN_NM" : "덕갈산" + }, + "longitude" : 127.86333329999999, + "latitude" : 35.576111099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산자락에 천년고찰 봉복사를 안고 있는 덕고산은 사찰 안에 덕고산 봉복사(德高山 鳳腹寺)라는 현판이 걸려 있어 그렇게 불리는데, 강원도 횡성군 청일면과 홍천군 서석면의 사이에 서서 경계를 이룬다.태기산과 성골계곡을 사이에 두고 마주보고 있는 덕고산은 삼한시대 말 진한의 마지막 왕인 태기왕이 새로 일어나는 신라군에 쫓기어 이곳에 성을 쌓고 군사를 길러 신라군과 싸웠다는 전설을 안고 있다. 그래서 이 산의 성골 골짜기에서는 태기왕 때의 것으로 보이는 허물어진 성벽 일부와 기와조각, 샘터 등이 발견되고 있다.산기슭에는 복조리의 재료인 산죽(山竹:시누대)이 많이 자란다.수림이 빽빽하여 정상에서의 조망이 시원하지는 않지만 깊고 조용한 산이다. 산행 들머리에는 신라시대의 것으로 6·25전쟁 때 총탄에 맞은 흔적이 여러 군데 있는 것을 빼고는 비교적 원형이 잘 보존되어 있는 삼층석탑(강원유형문화재 60)이 있다.", + "MNTN_HG_VL" : "1125", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 홍천군", + "MNTN_NM" : "덕고산" + }, + "longitude" : 128.16441259999999, + "latitude" : 37.471818200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "종남산에서 남릉을 따라 4Km 지점에 종남산과 같은 형태의 산봉이 솟아있는데 이 산이 덕대산이다. 산 아래에 있는 초동면에 이 산의 정기를 받아 인물이 많이 난다는 뜻에서 붙여진 이름으로 산의 전체적인 형세는 종남산과 더불어 내륙산의 모습을 하고 있다. 북릉은 종남산에 중봉을 거쳐 연결되고 동릉은 남산마을 쪽으로 급하게 쏟아지고 있다. 서릉은 무안면 쪽으로 길게 뻗어나가면서 완만한 산세를 펼치고 있지만 산세를 열고 있는 쪽은 남쪽사면으로 초동면을 품고 있다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 하남읍 남전리", + "MNTN_NM" : "덕대산" + }, + "longitude" : 128.0386111, + "latitude" : 36.087499999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "덕두산은 남원 운봉고원(해발 500m)의 동쪽에 철쭉군락지 바래봉과 함께 지리산국립공원의 서부지역의 북단 가장자리에 솟아 있다. 이 산은 험준한 산악지대요 울창한 산림에다 봄의 철쭉, 약초 등이 많이 자라고 있어 등산객보다는 봄나물, 약초캐는 아낙네들의 발길이 더 잦은 곳이다. 산행은 중군리 중군마을이나 인월리 용계마을에서 시작할 수 있으나 중군마을에서 시작하여 신인월로 하산하는 것이 좋다.", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원 운봉읍, 동면, 산내면", + "MNTN_NM" : "덕두산" + }, + "longitude" : 127.5807889, + "latitude" : 35.427014999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "덕룡산과 주작산은 높이에 따라 산세가 좌우되지 않는다는 사실을 깨닫게 하는 산이다. 해남 두륜산과 이어져 있고 높이라야 고작 400미터를 조금 넘지만 산세만 놓고 보면 1000미터 높이의 산에 뒤지지 않는다. 이 산은 웅장하면서도 창끝처럼 날카롭게 솟구친 암릉과 암릉 사이의 초원능선 등 능선이 표현할 수 있는 아름다움과 힘의 진수를 보여준다. 두륜산과 경계를 이루는 오소재에서 주작산, 덕룡산, 소석문까지 이어지는 11킬로미터 암릉은 마치 봉황이 날개를 펴고 하늘로 비상하는 형상이다. 봄이면 산꾼의 가슴을 태워버릴 듯 암릉에 흐드러지게 핀 진달래가 탄성을 자아내게 하고, 여름이면 은빛으로 빛나는 다도해와 누렇게 익은 보리밭의 조망, 가을이면 억새와 단풍 그리고 사시사철 신이 빚어 놓은 만물상이 연이어지는 스릴 넘치는 암릉이 산행의 백미다. 주작산은 강진군 신전면, 도암면, 해남군 옥천면, 북일면을 경계하고, 덕룡산은 강진군 도암면과 신전면을 경계한다. 덕룡산 정상에서 조망은 북으로 흑석산과 만의산, 만덕산과 월출산, 북동으로 궁성산과 국사봉, 수인산과 제암산, 동으로 천관산과 일림산, 남으로 두륜산과 상황봉, 서쪽은 두륜산과 첨찰산이 보인다.", + "MNTN_HG_VL" : "433", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", + "MNTN_NM" : "덕룡산" + }, + "longitude" : 126.7021027, + "latitude" : 34.540005299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "474", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍 수철리 449", + "MNTN_NM" : "덕봉산" + }, + "longitude" : 129.23928380000001, + "latitude" : 37.388126799999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "덕성산은 경기도 안성에 위치한 산으로 칠현산, 칠장산의 세 산이 능선상으로 바로 이웃하여 연결되어 있어 세산을 이어 종주 할 수도 있는 산이다. 칠현산, 칠장산은 걸미 삼거리에서 신대 마을로 들어가는 도중에 우측으로 지름길이 있어 이용할 수 있으며, 신대마을에서 칠장사까지는 약 40분이 소요된다.칠장사는 신라 때 창건 되었으며, 해소 국사비(보물 488호)와 인목대비의 친필족자(지방 문화재)가 있다.또한 덕성산은 정상에서 서쪽 능선으로 하산하는 길은 수림이 매우 우거져 있어 심마니들이 이용하는 길 같기도 하다.", + "MNTN_HG_VL" : "519", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 금광면", + "MNTN_NM" : "덕성산" + }, + "longitude" : 126.96856200000001, + "latitude" : 37.318686999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충남 예산에 자리잡은 덕숭산은 기기묘묘한 형상의 괴석들이 많아 절묘한 산세를 뽐내며 1973년 3월 6일 도립공원으로 지정되었다. 호서의 금강산이라 불릴 만큼 아름다운 경관을 갖추고 있는데다 아담한 산세 곳곳에 유명한 암자들이 배치되어 있어 찾는 이들의 발길이 끊이지 않는 곳이다.그 중 비구니의 도량으로 알려진 수덕사는 고려 충렬왕 34년(1308)에 창건된 사찰로 국보 제 49호로 지정된 대웅전이 있는데 이 건물은 무량수전과 더불어 현존하는 목조건물 중 가장 오래된 것이다. 부처님의 진본사리가 안치된 황화루를 비롯, 김일엽 스님의 거쳐였던 환희대, 만공스님을 기리기 위한 미륵불상등 수행의 역사를 조망할 수 있는 흔적들이 눈길을 끈다. 수덕사와 창건연대가 같은 정혜사는 구한말에 만공 스님이 한국 선불교를 중흥시킨 곳으로 청방, 정강, 용성 등의 대스님이 거쳐갔던 명소다. 덕숭산은 이밖에도 만공탑, 여승당, 보덕사 등 많은 문화재를 간직하고 있으며 주변에 온천이 있어 배낭 하나 메고 가볍게 떠날 수 있는 가족 나들이 코스로 손색 없는 산이다.", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면", + "MNTN_NM" : "덕숭산(수덕산)" + }, + "longitude" : 126.6187789, + "latitude" : 36.672609600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "163", + "MNTN_LOCPLC_REGION_NM" : "경기도 평택시,안성시", + "MNTN_NM" : "덕암산" + }, + "longitude" : 127.12527780000001, + "latitude" : 37.066666699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "덕우산은 강릉시 왕산면 고단리와 정선군 임계면 송계리의 경계를 이루는 산으로 해발 1007 m 이며 이산은 백두대간이 첩첩이 병풍처럼 두러쳐진 한가운데에 위치하여 정상에서 바라보면 먼저 고루포기산, 서득봉, 화란봉, 대화실산, 두리봉, 석병산, 자병산, 상월산, 등이 시계 방향으로 돌며 보이고 서쪽으로는 노추산과 사달산이 보이는 전망좋은 산이다. 덕우산에는 피나무골 샘터가 있는데 이산에서 발원한 물은 송게촌과 어울여 남한강의 원류가 된다. 강릉시에서 오를 수 있는 등산로은 고단 1리 고단초교 뒷등으로 통현사를 거쳐 오르는 코스와 남한강 발원지 피나무골 샘터 표지석에서 고냉지 채소밭을 거쳐 오르는 코스와 배모탱이 안고단 마을에서 둥우리재를 거쳐 오르는 코스로 3개 등산로가 있다. 백두대간이 첩첩이 병풍처럼 둘러쳐진 다운데에 위치하여 동서를 길게 드러누운것이 마치 소가 한가롭게 여물을 되새김질 하는 와우형의 산이다.", + "MNTN_HG_VL" : "1007", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선군 임계면", + "MNTN_NM" : "덕우산" + }, + "longitude" : 127.74638899999999, + "latitude" : 35.860556000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "단양팔경에 속하는 하선암과 사인암 사이에 솟아있는 덕절산은 미개의 산으로 태고의 자연미를 그대로 보존하고 있다.겉으로 보기엔 평범한 육산의 형태를 많이 보여주지만 실지 산행시엔 암릉을 타고 올라가는 재미가 쏠쏠한 산이다.덕을 마디마디 산으로 만든다는 의미인지 덕을 끊어 버리고 산으로 남겠다는 것인지 모르겠지만 덕절산은 그 이름이 들려주는 느낌으로는 아주 후덕한 단양의 인심을 떠올리는 산이다. 후덕함속의 날카로운 비수를 간직한 산답게 숨겨놓은 비경이 많은 것이 특징이다. 특히 암릉에 온갓 풍상을 꿋꿋하게 버티며 자라고 있는 노송들의 자태가 청년의 기상에 노년의 완숙미가 함께 풍기는 모양새로 소나무의 미학을 보여주고 있었다.정상에서의 조망은 일품이다. 동으로는 소백산의 각 연봉, 남으로는 황정산과 도락산의 절경들이 웅장함을 더한다. 북으로는 충주호가 은빛물결을 출렁이며 산사람들을 유혹하고 있다.", + "MNTN_HG_VL" : "780", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", + "MNTN_NM" : "덕절산" + }, + "longitude" : 128.3307547, + "latitude" : 36.897567299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "138", + "MNTN_LOCPLC_REGION_NM" : "경기도 평택시", + "MNTN_NM" : "덕지산" + }, + "longitude" : 126.9354044, + "latitude" : 37.061012400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진안의 동쪽으로는 성수산, 팔공산, 선각산, 삿갓봉 등 해발 1000미터 이상 되는 봉우리가 병풍처럼 둘러싸고 있다. 이 웅장한 산줄기에 덕태산이 자리하고 있다. 덕태산에는 수많은 미개척 계곡과 전인미답의 능선이 원시림에 가려 있으며, 험준한 절벽과 갖가지 형상의 바위가 도처에 산재해있다. 봄철 골짜기를 가득 메운 철쭉과 가을철 은근한 단풍은 암릉과 울창한 숲이 어우러져 빼어난 경치를 자랑하는 백운동계곡과 함께 덕태산의 자랑이다.능선의 동쪽으로는 시루봉과 함께 금남호남정맥 마루금이 지나고, 남쪽으로는 선각산과 함께 섬진강 발원지인 데미샘을 품고 있다. 정상에 서면 지리산과 남덕유산, 마이산과 내동산, 고덕산 등이 사방으로 조망되는데, 호쾌하게 뻗은 산줄기를 보고 있자면 감탄사가 절로 나온다.덕태산에는 ‘라장사’의 전설과, ‘점전바위’ 사이에 풀잎을 꽂으면 아들을 낳는다는 전설이 전해져 온다.", + "MNTN_HG_VL" : "1113", + "MNTN_LOCPLC_REGION_NM" : "전북 진안군 백운면", + "MNTN_NM" : "덕태산" + }, + "longitude" : 127.4473366, + "latitude" : 35.6892979 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "환선굴'로 유명해진 덕항산은 강원도 삼척시 신기면에 자리해 있다.이 산은 동남으로 펼쳐진 병풍암을 비롯하여 깎아놓은 듯 반듯한 암석과 거대한 암벽들이 수려한 산세를 이루며 동으로는 오십천으로 합류하는 12km길이의 무릉천이 흐르고 있어 산행하기 적합한 곳이다.", + "MNTN_HG_VL" : "1073", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면ㆍ태백시 하사미동", + "MNTN_NM" : "덕항산" + }, + "longitude" : 129.01166670000001, + "latitude" : 37.308888899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다. 또한 기슭에는 고찰 도갑사(道岬寺)가 있고 이곳에는 국보로 지정된 해탈문, 보물로 지정된 석조여래좌상 등이 있다. 특히, 도갑산을 포함한 월출산이 국립공원으로 지정된 후 관광지로서 각광을 받고 있다.", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 군서면", + "MNTN_NM" : "도갑산" + }, + "longitude" : 126.6725, + "latitude" : 34.744444399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도고산은 충남 아산시 도고면에 자리해 있으며 산가에 도고저수지를 끼고 있다. 산 정상에는 조선시대에 통신수단으로 사용하던 봉화대 유적이 원형에 가깝게 잘 보존되어 있다. 정상에 서면 예당평야와 아산만은 물론 멀리 천안시까지 한눈에 들어와 서해안의 초계와 방어를 위한 군사적 요지로 유명하다.옛날 천지가 개벽할 때 온 천지에 물이 찼는데, 산꼭대기만 도구통만하게 남았다는 설화에서 산 이름이 유래한다.삽교천방조제가 세워지기 전에는 바로 산 밑까지 바닷물이 들어왔으며, 주봉인 국사봉에는 봉수대가 남아 있다. 1390년(고려 공양왕 2) 6월에 서해안에 침입한 왜구가 이곳에 진을 치고 약탈을 자행하자 윤사덕과 유용생이 이끄는 관군이 물리쳤다는 기록도 남아 있다.도고면에서는 가파른 곳에는 로프를 설치했으며 등산로 곳곳에는 쉴 수 있는 긴 의자를 만들어 놓았고, 안내판도 세워놓았다.인근에 도고온천이 있어 산행과 온천을 겸한 여행지로 알맞다. 도고중학교에서 출발하여 정상에 오른 뒤 다시 내려오는 코스가 개발되어 있으며 약 2시간 30분 소요된다. 주변에는 중요민속자료 194호로 지정된 아산 성준경가옥 등의 문화재가 있다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "충남 아산시 도고면, 예산군 예산읍", + "MNTN_NM" : "도고산" + }, + "longitude" : 126.895, + "latitude" : 36.725000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국립지리원 발행의 지형도에는 도덕봉(道德峰 534m)이라 표기되어 있으나 마을 주민들은 흑룡산(黑龍山)이라 부른다. 이 산은 도덕봉과 한줄기인 백운봉(白雲峰 536m), 금수봉(錦繡峰 532m), 빈계산(牝鷄山 415m)등을 포함하고 있다.도덕봉 정상 동쪽은 거대한 절벽이 장관이고 굴골에는 큰 동굴과 작은 석관 2개, 폭포 등으로 어우러진 계곡 오솔길 주변은 단풍이 좋다. 남릉은 서면이 50-100m의 암벽을 이루고 암릉 끝에는 커다란 수통굴이 있다. 일제때 구리를 캐던 곳으로 추정되는 구리골을 경유하여 수통굴로 가면 굴속에는 무속인들의 움집이 한채 있고 굴속 끝에는 작고 맑은 샘이 있어 산행길의 쉼터로 그만이다. 옛날에 이 골짜기에 도독이 많이 살고 있던 데서 산 이름이 유래한다.조망은 주변 숲에 가려져 시야가 좁고 트인 경관을 구경키 어렵다. 봄철에는 진달래가 붉게 물들고 산벚꽃이 많이 핀다.", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "충남 공주시 반포면, 대전 유성구", + "MNTN_NM" : "도덕봉 (흑룡산)" + }, + "longitude" : 127.2780556, + "latitude" : 36.348888899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우암 송시열 선생이\"도를 깨닫고 스스로 즐길 만한 곳이다\"해서 도락산이라 명명한 이 산은 경북과 충북의 도경계선에 근접해 있다.월악산국립공원권에 속해 있는 산으로, 충북 단양군 단양읍과 대강면의 경계를 이루고 있으며 도락산 산자락에는 단양 8경 중 4경인 사인암,상선암,중선암,하선암 등이 있어 관광의 보고이기도 하다.", + "MNTN_HG_VL" : "965", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면, 대강면", + "MNTN_NM" : "도락산" + }, + "longitude" : 128.31169420000001, + "latitude" : 36.856228899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한북정맥 분기점에 위치해 있으며, 경기 제1의 비경지대 도마치계곡을 안고 있는 도마치봉은 백운계곡, 도마치계곡, 반암계곡이 모아지는 삼각지점에 자리해 수려한 산세와 사방으로 거칠 것 없는 시원한 시야를 갖추고 있는 산이다.궁예가 왕건에게 쫓기면서 도망친 산이라는 설과, 사람과 말이 모두 걸어서 넘었다는 전설로 '도마치'가 되었다는 이 산은 비경지대인 도마치계곡이 민간인 출입금지구역으로 되어 있어 아쉬움이 남는다.자연보존상태가 좋으나 정상 접급이 길고 험준하다. 정상 일대에서는 시야를 가릴 큰 나무는 없다. 도마치봉에서는 국망봉과 국망봉에서 가리산으로 이어지는 능선이 눈 앞에 보이고, 신로령에서 국망봉으로 이어지는 밋밋한 능선이 시야에 들어 온다.", + "MNTN_HG_VL" : "937", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", + "MNTN_NM" : "도마치봉" + }, + "longitude" : 127.39564439999999, + "latitude" : 38.038512799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "뛰어난 풍광으로 우암 송시열이 낙향하여 머물던 화양구곡 중앙부에 위치한 도명산은 국립공원 속리산에 속하여 있으며 태고의 신비와 자연의 오묘한 섭리를 안고 있는 산이다. 첨성대 바위, 흔들바위 등 자연이 빚어낸 기묘한 형태에 기암과 암릉(岩陵)이 곳곳에 산재해 있으며 특히 정상부를 차지하고 있는 기암 덩어리인 정상 바위는 가히 일품이라 할 수 있다.정상은 크고 작은 바위 다섯 개가 하나로 정상을 이루고 있다. 정상에서의 조망은 북쪽 아래로는 화양동 계곡과 군자산, 칠보산이 펼쳐지고, 동쪽으로는 대하산, 남쪽으로는 낙영산, 주봉산, 멀리 속리산 능선과 문장대가 들어온다. 주변에는 분재처럼 자란 소나무가 정취를 더한다. 화양동계곡은 기암괴석으로 이뤄진 절경이 아홉 곳이나 된다고 해서 '화양구곡'(華陽九曲) 또는 '화양동 소금강'으로 불린다. 이곳은 경치가 너무 아름답고 물이 맑아 조선시대의 조선조 대유학자였던 우암 송시열 선생이 조정을 물러나와 은거하던 곳으로도 유명하다.이곳에 반한 조선 후기의 유학자 우암 송시열은 화양동주(洞主)로서 은거하며 이곳이 중국의 무이구곡을 닮았다 하여 9곡의 이름을 짓고 경천벽·금사담\\·첨성대 등의 바위에 글씨를 새겼다.제1곡 경천벽은 깎아지른 층암절벽이 하늘을 떠받치고 있으며, 화양2교 옆의 2곡 운영담은 구름이 비치는 담 주변에 넓은 모래사장이 있다. 3곡은 우암이 새벽에 올라 효종의 승하를 통곡했다는 읍궁암으로 민박집과 식당이 많다. 서원철폐의 빌미가 된 화양서원을 거쳐 하마소와 채운사 등의 명소가 있다.제일 수려한 4곡 금사담은 금모래가 반짝이며 넓은 암반 위에 우암의 암서재가 노송 사이에 있다. 화양3교 직전 바른쪽 낙영산 정상의 기암절벽인 5곡 첨성대는 별을 관측하던 곳이다. 더 가면 심곡에 큰 2층바위인 6곡 능운대가 나오며 7곡 와룡암, 8곡 학소대, 9곡 파천이 있다.", + "MNTN_HG_VL" : "642", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "도명산" + }, + "longitude" : 127.8167474, + "latitude" : 36.652938800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도봉산은 서울 근교의 산으로 예로부터 북한산과 하나의 산으로 취급되어 왔다. 우이령을 경계로 북한산과 나란히 솟아 있어 현재 두 산을 북한산국립공원에 함께 포함시키고 있다. 북한산 면적 55㎢에 비해 도봉산은 약 24㎢로 절반에 불과하나 산세가 아름다워 등산객이 끊이지 않는 곳이다.주능선상에는 최고봉인 자운봉을 비롯해 만장봉, 선인봉, 주봉 등의 암봉과 서쪽으로 다섯개의 암봉이 나란히 줄지어 있는 오봉이 있다. 선인봉, 만장봉, 주봉, 우이암은 각기 거대한 암벽들이다. 도봉산은 우람한 기암괴석과 뾰족히 솟은 암봉들이 장관을 이루며, 사방으로 뻗은 계곡을 따라 녹음이 우거져 명소를 만들고 있다.사계절 모두 즐겨 찾는 산이지만 가을이면 단풍의 물결이 여느 산 못지 않다. 도봉산의 3대 계곡은 문사동계곡, 망월사계곡(원도봉계곡), 보문사계곡(무수골) 이다. 이 계곡들이 바로 산행기점과 연결된다. 도봉산은 등산코스가 다양한데 그 중에서 우이동, 도봉유원지, 망월사역(장수원), 성황당 코스가 대표적이다.도봉산의 주봉은 자운봉(740.2m)으로, 정상을 기점으로 등산로가 사방으로 거미줄 같이 수십 가닥이 펼쳐져 있다. 모두 합쳐 100여개의 산행 코스가 있다. 그 중 도봉산 등산로의 핵심은 포대능선으로, 이 산의 등뼈를 이루는 포대능선-자운봉-칼바위-우이암 능선으로 이어진다. 포대능선은 능선 중간에 대공포진지인 포대(砲臺)가 있었다고 해서 붙여진 이름이다. 도봉산 산행 들머리는 수 없이 많지만 크게 분류하면, 안골유원지, 회룡사입구, 원도봉유원지, 도봉유원지, 성황당, 우이동, 송추 7개 코스를 꼽을 수 있다. 빼어난 암릉미를 자랑하는 도봉산은 어느 코스이든 바위 암릉이 곳곳에 도사리고 있어 주의가 필요하다. 수도권 등산객이 많이 몰리는 휴일에는 주능선인 포대능선 등에 정체 현상이 벌어질 정도로 붐빈다. 갈림길이 무수히 많아 길을 잃을 수 있으므로 사전에 지도를 꼼꼼히 챙겨야 되는 산이다.", + "MNTN_HG_VL" : "740", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 도봉구, 경기도 의정부시 호원동ㆍ양주시 장흥면", + "MNTN_NM" : "도봉산(자운봉)" + }, + "longitude" : 127.0156843, + "latitude" : 37.700463499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "소백산 국립공원에 속하는 도솔봉은 충북 단양과 경북 영주의 경계를 이루는 산으로 형제봉과 더불어 가장 한적한 육산으로 꼽히고 있다. 도솔봉은 소백산의 축소판이라 불릴만큼 한 키나 되는 철쭉과 진달래가 화원을 이루며 각종 고산식물이 많다. 또한 숲길 가득 수목이 울창하고 계곡마다 꽃피는 초본류가 무성하여 발길 닿는 곳마다 풍치가 그만이다.정상 도솔봉을 주축으로 삼형제봉과 묘적봉을 거느리고 우뚝 솟아 있으며, 능선에는 바위지대와 억새등이 있다.정상 암봉에 서면 중령에서 장엄하게 뻗어 오른 소백산의 장릉을 끝까지 바라볼 수 있어 황홀하고, 남쪽으로는 활같이 구부러지면서 황정산으로 이어내린 백두대간이 아련하기만 하고, 단양팔경으로 유명한 산야가 펼쳐 보인다.", + "MNTN_HG_VL" : "1314", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시, 충청북도 단양군", + "MNTN_NM" : "도솔봉" + }, + "longitude" : 128.42567840000001, + "latitude" : 36.876253699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운산과 도솔봉은 동서로 나란히 능선상으로 이웃하고 있다. 동쪽 봉우리가 백운산, 서쪽 봉우리가 도솔봉으로 둘 다 1,100미터가 넘는 고산으로 그 위용이 당당하다. 백운산 서쪽의 도솔봉(1123.4m)에서 광양만으로 이어진 도솔봉 능선은 사람의 발길이 닿지않은 원시의 그리움이 그대로 보존된 곳이다. 산짐승이나 다녔음직한 그 호젓한 능선길은 진달래 철쭉이 군락을 이루고 있어 봄에는 황홀한 경관을 연출한다.도솔봉 자락은 조선의 학자이자 우국지사인 매천(梅泉) 황현의 고향답게 백운란·백운원추리·고로쇠나무·철쭉 등이 백운산에 못지 않다. 특히 봄철이면 백운산의 고로쇠나무 수액을 마시기 위해 전국에서 많은 산꾼들이 모여드는 곳으로도 유명하다.전라남도에서 지리산 다음으로 높은 산이 백운산이며, 조계산, 무등산과 같이 남해안을 따라 산맥을 형성한다. 또 광양읍에서 북쪽 약 12km지점에 위치하며 주봉은 동주리봉, 형제봉, 도솔봉, 백운산 매봉을 잇고 있다. 4개의 지능은 남쪽으로 뻗어 바다로 빠진다.", + "MNTN_HG_VL" : "1125", + "MNTN_LOCPLC_REGION_NM" : "전라남도 광양", + "MNTN_NM" : "도솔봉" + }, + "longitude" : 128.42567840000001, + "latitude" : 36.876253699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도일봉은 경기도 양평군의 상징산인 용문산과 마주한 산이다. 용문면과 단월면의 경계를 이루는 높이 864 m의 중봉으로 용문산의 명성에 가려 아직 찾는 사람이 적어서 오염되지 않은 깨끗한 계곡을 간직하고 있다.등산로 입구인 상현마을에서 약 30여분 정도 오르다보면 중원폭포가 나온다. 이곳은 도일봉과 중원산을 오르는 갈림길이자 휴식처이다. 약 8km에 달하는 중원계곡은 요즘 보기 드문 청정계곡이다. 중원계곡의 입구는 길과 담, 벼랑이 모두 바위로 이루어져 있는데 '폭포' 라는 이름에 비해 높이는 겨우 2미터정도다.하지만 발광하듯 쏟아져내리는 물길은 산행하며 쏟아 부운 온갖 기운을 충만하게 채워준다. 무성한 숲이 개울위까지 차양을 치고 있어 여름에도 더위가 끼여들 틈이 없어 계곡안은 냉기류가 감돈다. 5m 높이에서 떨어져 하얀 포말을 일으키는 중원폭포와 바위에 부딪혀 하얀 웨딩드레스를 펼친 듯이 떨어지는 치마폭포도 보는 이의 가슴을 시원하게 쓸어내려 준다. 도일봉에는 소나무가 많아서 산행길 내내 소나무숲향기가 함께 해서 더욱 좋다.", + "MNTN_HG_VL" : "864", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", + "MNTN_NM" : "도일봉" + }, + "longitude" : 127.61333329999999, + "latitude" : 37.575000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "상주시 화북면과 문경시 농암면 경계에 솟은 도장산은 계곡미가 빼어난 경북의 숨은 명산이다. 용추에서ucirc;룡, 황룡이 살았다하여 쌍용계곡이라 불리는 골yen;기를 따라 선녀들이 내려와 목욕을 하였다는 선녀탕, 암반 아래에 명주실 한#376;래가 들어간다는 깊은 용추(용소) 등 오랜 세월 풍화를 겪은 기암괴석과 맑고 깊은 물이 어우러져 시원한 절경을 자아낸다.도장산이 걸쳐있는 상주시 화북면은 십승지 중 하나인 우복동otilde;(牛腹洞川)의 명당터로 알려져 있다. 그리하여 예부터 ‘삼산삼수(三山三水)의 고장’으로 불리어왔는데 도장산이 속리산(1057.7m),ucirc;화산(984m)과 함께 삼산에 속해 경치 좋고 사람 살기 좋은 곳으로 꼽혀왔다. 상주시에서는 이 삼산을 하나로 엮어 2007년 ‘우복동otilde;’ 산행 코스를 정비하였다. 이 중 도장산은 5.2킬로미터 구간이 조성되어 있다.도장산 정상은 밋밋한 편이다. 그러나 속리산을 조망하기에는 더 없이 좋다. 정상에 서면 속리산otilde;황봉으로부터 뻗어지는 문장대까지 한눈에 볼 수 있다. 산자락에 위치한 심원사는 원효대사가acirc;건한 고찰로서 고즈넉하고 소박한 암자의 모습을 간직하고 있다.", + "MNTN_HG_VL" : "828", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면 용유리, 문경시 농암면", + "MNTN_NM" : "도장산" + }, + "longitude" : 127.94232150000001, + "latitude" : 36.552953100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "828", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시", + "MNTN_NM" : "도장산" + }, + "longitude" : 127.94232150000001, + "latitude" : 36.552953100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 영덕군에 위치한 동대산은 곳곳에 절경을 숨기고 있는 지역의 명산이다. 타지에는 많이 알려지지 않았지만 경관이 뛰어나 발빠른 등산인들이 호젓한 산행을 즐기며 오염되지 않은 산채가 많아 약초꾼들이 은밀히 오가는 곳이다.향로봉 내연산 문수산의 디딤돌로 발판이 되어 잠깐 솟구처오른 동대산은 바데산을 머리에 이고 동서로 여러갈래의 골짜기를 만들어 놓고있다.서쪽 마실골과 북서쪽 경방골은 아직도 자연의 신비감을 그대로 간직하고 있는 절경의 골짜기들이다. 바데산 동대산 내연산 서쪽으로 길게 패인 하옥리 계곡은 경관이 배어나 여름이면 사람공해를 이룬다. 바데산에서 동대산으로 가는 날등길을 걸으며 드넓은 동해바다를 바라보는 눈망울도 쉽게 깜박여지지 않는다.하옥리 계곡에서 갈치기한 마실골은 기암절벽이 골 양옆에 솟구친 가운데 맑고 푸른 물이 소와 담에 담겨 있으며 골짜기와 산사면은 온통 울창 숲으로 우거져 있다. 골 깊숙히 들어가면 널다란 암반이 나타나고 때를 잘 마추어 이 마실골에 들어서면 수백마리의 나비떼를 만나게 된다.동대산 일원은 동해의 습한 기운과 서쪽의 차가운 기운이 맞닿아 안개가 자주 낀다. 때문에 이곳 지형을 잘 알지 못하는 이들은 특히 봄철 안개가 자주 낄 때 조심해야 한다.경방골과 물텀벙이골은 골이 깊고 바위와 절벽이 어우러져 누구든 이 골짜기를 들어오면 한여름에는 담소에 몸을 던지기 일수이다. 여름산행은 바데산으로 올라가서 동대산을 거처 후줄근하게 땀으로 샤워를 한몸 경방골로 내려오며 말끔히 헹궈내는 방법도 솔솔한 재미가 있다.", + "MNTN_HG_VL" : "791", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영덕군", + "MNTN_NM" : "동대산" + }, + "longitude" : 129.28397870000001, + "latitude" : 36.310201900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "최고봉인 비로봉을 비롯하여 호령봉, 상왕봉, 두로봉, 동대봉의 5개 대를 합쳐 오대산이라 부른다.오대산은 주봉인 비로봉을 비롯해서 다섯 개의 연봉이 주축을 이루면서 마치 연꽃처럼 피어올라 있으며, 이들 연봉의 사이사이에도 노인봉, 계방산, 복용산 등 그만그만한 준봉들이 숱하게 솟아있고 오대산 일대의 주요 산마루는 거의 대부분이 평정봉으로 그 풍치는 마치 우아한 여성의 성격을 띠고 있는 것이 특징이다.태백산맥의 중추를 이루며 산세가 만만치 않아 주요 코스 이외에는 아직도 개발이 안된 부분이 많은 산이다. 월정사 일대의 전나무들과 단풍이 유명하고 상원사 적멸보궁 등의 명소가 많아 관광객이 끊이지 않는다. 75. 2. 1 일 11번째 국립 공원으로 지정됨 태백산맥에서 남서 방향으로 뻗어 충청북도와 남도를 거쳐 태안 반도에 이르는 차령산맥의 분기점이 되는 오대산은 한강 발원지의 하나인 오대천 상류를 둘러싸고 수려한 계곡을 조성하고 있다.연꽃 같은 산세의 화심의 명당에는 적멸보궁이 있고, 동대산록에는 고찰 월정사가 있으며, 상원사에서 적멸보궁까지는 완만한 길을 지그재그로 오르게 된다.", + "MNTN_HG_VL" : "1434", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면", + "MNTN_NM" : "동대산" + }, + "longitude" : 129.28397870000001, + "latitude" : 36.310201900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "융단같은 능선길을 마음대로 달릴 수 있는 산이 부산광역시의 근교에 터잡고 있다. 김해 백두산 동신어산 종주능선이 바로 이 같은 곳이다. 이 종주능선길은 부드러우면서도 아기자기한데다 산악동호인들의 발길조차 전혀 닿지 않아 근교의 새로운 워킹산행지로 인기를 끌기에 충분하다.백두산 동신어산 종주능선상에서는 또 부산을 둘러싸고 있는 산군의 능선을 모 두 조망할 수 있다. 금정산 주능선길은 물론 영남알프스의 남쪽능선, 낙동 낙남정맥상의 산군, 그리고 김해 무척산 물금 오봉산 원동 토곡산 울산 원효, 천성산 등 동부경남의 크고 작은 산을 눈으로 확인할 수 있다.", + "MNTN_HG_VL" : "460", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해 상동면", + "MNTN_NM" : "동신어산" + }, + "longitude" : 128.92087570000001, + "latitude" : 35.270207599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 평창군 방림면과 영월군 수주면 경계를 이루는 백선산 남쪽 능선 가운데쯤 되는 곳에서 남서쪽으로 갈라지는 또 다른 능선이 있다.돼지봉은 이 남서릉의 최고봉으로 산세가 빼어나고 알려지지 않은 비경이 많은 산이다. 낙화함을 연상케하는 수십길 바위절벽, 그 바위절벽 위에 4평 남짓한 요선정이라는 정자가 서 있다. 요선정은 수백년정 무릉마을에 살았던 이(李), 원(元), 곽(郭)씨등 세 문중에서 뜻을 모아 세운 것으로 전해지고 있는데 요선정의 뜻을 신선을 맞이한다는 것이다. 정자 옆으로는 15척 높이의 마애석불이 서 있다. 이 정자 및 무릉계곡에는 억겁 세월의 물결에 깎인 화강암이 기묘한 형상을 한 채 깔려 한 폭의 동양화를 연상케 하는데, 이 곳을 요선암이라 부르게 된 이유는 조선 중기의 풍류가이며 강릉부사를 지낸 양사연이 이곳 경치에 반하여 선녀탕 위 바위에 요선암이라는 글자를 생긴데서 연유한다.이 산에 들어서면 첫째 공가와 초목의 향기가 예사롭지 않음을 직감하게 되고 티 없이 깨끗하게 유지되고 있는 산이다. 정상에는 삼각점이 매설되어 있으며 깃발이 세워져 있다. 정상에서 조망은 동쪽으로 굽이굽이 돌아 흐르는 평창강과 주천강이 무릉도원을 이루면서 흘러 특히 아름답고 북의 백덕산 서편의 치악산 장릉이 아련하다.", + "MNTN_HG_VL" : "818", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "돼지봉" + }, + "longitude" : 126.9708945, + "latitude" : 37.530080300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "250", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", + "MNTN_NM" : "두개비산" + }, + "longitude" : 127.88284899999999, + "latitude" : 37.727337299999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "춘천 소양호에 에워싸인 두루봉은 오랜 세월 등산인들을 등지고 있어 태고적 자연 상태 그대로를 보존하고 있는 산이다.바위지대와 굴참나무숲, 낙엽송숲길을 지나 정상에 이르면 확 트인 조망에 가슴까지 시원해지는 기분이다. 북으로는 마적산 오봉산 부용산 봉화산이 한눈에 들고 동으로는 사명산 바위봉 곧은봉 가리산이 소양호에 산영을 담그고 있다.", + "MNTN_HG_VL" : "1226", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "두루봉" + }, + "longitude" : 127.53547759999999, + "latitude" : 36.507948900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한반도의 최남단에 위치한 두륜산(700m)은 백두대간에서 뻗은 호남정맥이 바다에 이르면서 마지막으로 솟아 오른 산이다.전남 해남군 삼산면과 현산면의 경계를 이루는 산으로 일명 대둔산(大芚山)이라고도 불린다. 임진왜란 당시 전국의 산야를 누비며 왜적을 몰아낸 서산대사는 이곳 두륜산을 '만고에 깨지지 않고 삼재가 미치지 않는 산' 이라 했다. 삼재가 들지 않는다는 것은 홍수나 재해에서 안전하다는 뜻이다.실제로 두륜산은 북으로는 월출산이 하늘을 받쳐주고 남으로는 달마산이 지축을 맺어 주고 있어 옛 조상들로부터 풍수지리적으로 인정받은 산이다. 상상의 산이며 산의 조종으로 알려진 곤륜산과 백두산에서 연유했다는 뜻에서 두 산의 한자씩을 따 두륜산이라 이름 지었다고 한다.", + "MNTN_HG_VL" : "700", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 삼산면ㆍ북일면ㆍ북평면ㆍ현산면", + "MNTN_NM" : "두륜산" + }, + "longitude" : 126.6193897, + "latitude" : 34.4792889 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정읍에서 약 12킬로미터 떨어진 곳으로 갑오동학혁명의 진원지인 고부면 신중리 죽산마을에 동학혁명모의탑이 세워져 있다. 정읍시는 동학농민운동의 시발 지이자 주요무대다. 특히 고부면은 동학농민운동의 진원지로 모의탑이 세워져 있다. 덕천면의 황토현 전적지(사적 295)를 중심으로 고부관아터, 만석보터, 전봉준 고택지(사적 293) 등 많은 관련 유적이 있다.이 산은 정읍시와 고창군 일대는 물론 내장산, 방장산, 입암산 등 명산이 한눈에 들어오는 확 트인 전망이 유명한 산이다. 정상에는 넓은 공간에 큰 바위와 나무와 초지가 서로 어우러져 휴식을 취하기에 좋다.두승산 이름의 유래는 옛날 고부관아에서 도량형의 기준이 되는 말(斗)과 되(升)를 돌로 만들어 고부군의 진산인 이 산의 남쪽 봉우리(말봉) 바위 위에 설치해 놓았다. 이후 사람들은 이 산을 ‘말과 되가 있는 산’ 이라 하여 두승산이라 부르게 되었다.정상부에는 작은 봉우리가 몇 개 있는데, 세 번째 봉우리가 정상이고 네 번째 봉우리가 말봉이다. 두승산 주위로는 동학혁명에 관한 역사 유적지가 많다. 특히 고부면은 동학농민운동에 앞장선 전봉준 고택지(사적 293) 등 많은 관련 유적이 있어 산행 후 역사 공부를 겸해 둘러봄직 하다.", + "MNTN_HG_VL" : "444", + "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 고부면ㆍ덕천면ㆍ소성면", + "MNTN_NM" : "두승산" + }, + "longitude" : 126.7980117, + "latitude" : 35.606852199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "사북읍 뒤편에 있는 강원 정선 두위봉은 탄광으로 널리 알려져 있지만 최근에는 초여름 철쭉산행지로 각광받고 있다. 이 산에는 빽빽하게 군락을 이룬 철쭉지대가 수만 평이 넘도록 펼쳐져 있어 마치 연분홍 양탄자가 깔려있는 듯한 착각에 빠진다. 탁 트인 시야와 초원지대 한 가운데 고인 맑은 연못, 수령 1천 8백년을 자랑하는 국내 최고의 주목, 깎아지른 듯한 절벽 등 갖가지 절경도 접할 수 있다.두위봉은 산이 두루뭉실하다 하여 ‘두리봉’으로도 부른다. 특이한 것은 정상이 주능선의 1킬로미터 거리에 두 개가 있다. 삼각점이 있는 봉우리가 정상이었는데, 철쭉기념비를 세워놓은 바위로 된 봉우리가 경관이 더 좋아 1999년 이곳에 정상 표지석을 세웠다고 한다.자미원이나 함백마을에서 올라가면 만나는 능선의 아라리 고개에서 도사곡으로 갈라지는 사이의 주능선과 계곡의 등산로가 울창한 산림으로 우거져 있다. 정상에서 아라리 고개 사이에 참나무 군락지, 도사곡 및 자미원에서 오르는 등산로 주위에 자작나무 군락지가 있고 도사곡에는 국내에서 나이가 가장 많다는 주목나무가 있다.", + "MNTN_HG_VL" : "1470", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면, 사북읍·영월군 중동면 직동리", + "MNTN_NM" : "두위봉" + }, + "longitude" : 128.7534191, + "latitude" : 37.212416400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "두타산은 부처가 누워있는 형상으로 박달령을 사이에 두고 청옥산과 마주하고 서 있다. 울창한 수림과 기암절벽에 노송이 뿌리를 내려 산세가 수려한 두타산은 강원도 국민관광지 1호로 지정돼 있다.두타산의 '두타(頭陀)'란 '속세의 번뇌를 버리고 불도를 닦는 수행'을 말한다. 이는 두타산이 불교와 인연이 깊은 불교의 도량임을 미루어 짐작할 수 있다. 지금은 삼화사,관음암,천은사가 남아 있지만 10여개의 사찰이 있다는 옛기록으로 보아 무릉계는 불교가 크게 번성했던 두타의 도량이었던 같다.", + "MNTN_HG_VL" : "1357", + "MNTN_LOCPLC_REGION_NM" : "강원도 동해시 삼화동, 삼척시 미로면ㆍ하장면", + "MNTN_NM" : "두타산" + }, + "longitude" : 129.09999999999999, + "latitude" : 37.259999999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "두타산은 진천군 초평면, 괴산군 도안면과 증평읍의 경계를 이루고 있으며, 능선이 마치 부처가 누워있는 모습을 하고 있다. 진천의 상산8경 중 하나인 고찰 영수사를 산자락에 품고 있으며 은은한 종소리와 함께 아름다움을 간직한 명산으로 손꼽힌다.두타산 정상엔 삼국시대에 축조된 것으로 추정되는 석성이 자리하고 있는데, 길이 1킬로미터, 높이 1.2미터의 규모로 성내에는 두 개의 우물터가 있으며, 이따금 통일신라시대의 토기편과 기와 조각 등이 발견 되고 있으며 고려 시대의 유물도 출토된 적이 있다.두타산이란 산 지명은 단군이 팽우에게 높은 산과 냇물 등 산천을 다스리게 했는데, 그때 하루도 빠짐없이 비가 내려 온 산천이 모두 물에 잠기게 되자 사람들이 높은 곳으로 피난을 가야했다. 이때 팽우는 이 산에 머물게 되었고 산꼭대기가 섬처럼 조금 남아 있었다고 하여 두타산이라 이름 지었다고 한다.두타산의 산행기점은 진천 쪽 초평저수지에서 영수사를 거쳐 오르는 길과 대평주유소 전 동잠교에서 계곡을 따라 큰재로 오른 후 북동쪽 능선을 타고 정상에 오르는 길이 자주 이용된다. 이외에 증평읍 자양마을에서 오르는 길이 있지만 접근이 어렵고 능선을 넘어 다시 계곡으로 떨어져야하므로 거의 이용되지 않고 있다.", + "MNTN_HG_VL" : "599", + "MNTN_LOCPLC_REGION_NM" : "충북 진천군 초평면, 괴산군 도안면, 증평읍", + "MNTN_NM" : "두타산" + }, + "longitude" : 129.09999999999999, + "latitude" : 37.259999999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "둔덕산은 문경팔경의 하나인 용추를 품고 운강 이강년 선생의 탄생설화가 얽힌 산이다. 백두대간이 조항산을 지나면서 동쪽으로 가지를 쳐 만들어진 둔덕산은 멋진 경승지를 품고 있음에도 근처의 대야산이나 희양산의 명성에 가려져 아직까지 호젓한 산행을 즐길 수 있는 문경의 숨은 명산이다.둔덕산이 있는 가은읍 완장리 자락에는 이 산의 자랑거리가 집중되어 있는데 괴선의 외선유동에 비견되는 용추를 품고 있는 내선유동계곡과 이강년 선생의 생가터, 조선조 이재 선생의 후학들이 그를 기려 세웠다는 학천정 등 유서 깊은 정자가 그것이다. 따라서 둔덕산 산행은 볼거리가 풍부한 완장리를 기점으로 원점회귀 하는 코스를 가장 추천할 만하다.둔덕산은 국운이 위태롭던 한 말에 일본 침략자에 항거 경상도, 충청도, 강원도에 걸쳐 13년간 오로지 의병대장으로서 활동하고 순국한 전국도창의대장 운강 이강년 선생 탄생과 관련 있는데, 이강년 선생이 태어나기 3일전부터 둔덕산이 ‘웅웅’ 소리를 내며 울었다고 한다. 당시 사람들은 둔덕산이 우는 것은 처음 있는 일이라고 하며 신기해했으나 운강 선생이 태어나자 울음을 그쳤다고 한다.", + "MNTN_HG_VL" : "970", + "MNTN_LOCPLC_REGION_NM" : "경북 문경시 가은읍, 농암면", + "MNTN_NM" : "둔덕산" + }, + "longitude" : 127.9733714, + "latitude" : 36.651080700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "둔지미산은 충북 단양군 어상천면과 가곡면 사이에 아담하게 솟아오른 봉우리로 삼태산(876m)에서 남한강으로 뻗은 능선상의 가장 끄트머리에 있는 산이다.이 산이 소재한 단양에는 비경지대가 많아 신단양 8경이 등장했다. 그 중 하나가 절벽기암이 병풍을 두른 듯 비경을 이룬 영춘 북벽인데 이 보다 두배나 높은 수직절벽의 비경지대가 바로 둔지미산의 노갈봉이다.노갈봉은 노인이 갈잎으로 만든 도롱이를 쓰고 남한강물에 낚시대를 드리운 산세를 하고 있다고 해서 붙여진 것이라고 전해진다.노갈봉 정상에 이르면 멀리 북동쪽으로 태화산과 영춘, 마대산이 보이고 발 밑으로 푸른 남한강이 내려다 보인다. 무더운 여름날에는 노갈봉에서 웃통을 드러낸채 발밑에 보이는 강물로 뛰어들어 한바탕 헤엄을 치고싶은 생각이 절로든다. 그렇다고 수직절벽에서 뛰어내리는 것은 둔지미산 명예드럽힌죄로 적용될 지도 모른다. 고개를 쪼금들어 강너머를 보면 용산봉이 방끗이 웃고있다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "둔지미산" + }, + "longitude" : 128.40333330000001, + "latitude" : 37.059166699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "둔철산은 황매산에서 흘러내린 능선이 정수산을 거쳐 경호강에 산자락을 내리면서 우뚝 솟아있는 산이다. 산청읍과 신안면, 신등면 사이에 있으면서 웅석봉과 마주하며 철을 생산했다는 전설을 갖고 있다. 그러나 둔철(屯鐵)이라는 지명은 생산보다는 보관했다는 말에 더욱 설득력이 있다.산 동쪽 해발 500미터에는 넓은 분지가 조성되어 있어 대단위 목장과 농장으로 활용하고 있다. 서쪽으로는 산청시내가 내려다보이고 경호강을 사이에 두고 왕산 및 칠봉산과 웅석봉이 병풍처럼 펼쳐져 있다.동쪽은 사정천이 흐르며 북쪽은 철쭉으로 유명한 황매산과 수려한 암군으로 각광받고 있는 모산재가 둘러싸고 있는 산이다. 정상에 서면 사방 막힘이 없고 지리산에서 가지내린 수많은 산군을 조망할 수 있어 가슴이 후련하다.범학에서 계곡을 따라 오르면 와폭과 깨끗한 담과 소가 오염되지 않아 좋다. 그러나 길이 희미해서 한여름이면 오르기 힘들다. 척지에서 오를 수 있고 정취암에서 능선을 타고 대성산~둔철산으로 갈 수 있으나 여름보다 겨울에 산행하는 것이 적당하다. 정취암은 의상대사가 창건했으며 문가학이라는 도인이 여우로부터 둔갑술을 배웠다고 전해온다.", + "MNTN_HG_VL" : "812", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 산청읍 척지리", + "MNTN_NM" : "둔철산" + }, + "longitude" : 127.9456586, + "latitude" : 35.387092799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "둥지봉은 국립공원 소백산의 주맥인 형제봉과 신선봉 사이에서 서북쪽으로 뻗어나온 지맥으로 등반객의 발길이 거의 닿지 않은 천연의 코스이다.그 안쪽으로 형제봉과 만나는 산면을 따라 6~7km에 이르는 대산골 계곡이 이어진다. 대산골은 소백산 일대에서 가장 풍부한 수량과 비경을 자랑하지만 일반에 잘 알려져 있지 않아 천연의 비경을 그대로 간직한 곳이다.암릉구간이 길고 굴곡이 심해 다소 힘든 코스이긴 하지만 하산하면서 대산골의 맑은 물에 몸을 눕힐 수 있어 더 이상의 여름철 피서산행코스도 없을 것이다.", + "MNTN_HG_VL" : "822", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "둥지봉" + }, + "longitude" : 128.2316715, + "latitude" : 36.946938699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "368", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "드름산" + }, + "longitude" : 127.70006979999999, + "latitude" : 37.839205199999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "등선봉은 넓은 의미의 삼악산에 속하지만 독자적인 산행이 가능하다는 점에서 독립봉으로 보아야 한다. 대체로 암릉과 암봉으로 이루어져서 산행한 후 높은 성취감을 느낄 수 있다.삼악산이 정상을 중심으로 산괴가 몰려있는 형세인 반면 등선봉은 능선을 이루며 길게 뻗어있는 것이 삼악산과 다른 점이다. 이 산은 삼악산의 한 봉우리로 주봉인 용화봉(645m)과 청운봉(546m)의 능선과 이어져 있으며 일명 성봉이라 불리기도 한다. 궁예와 왕건이 싸웠다는 이 산에는 성터의 흔적이 남아 있다. 산행기점은 강촌교 북단에서 가평쪽으로 10m지점이다.등선봉은 강원도 춘천과 강촌사이에 있어 낭만의 열차, 경춘선을 이용해서 가는 열차산행지이다. 강촌역에 내리면 수많은 청춘남녀들이 낭만을 찾아 열차여행을 하는 코스다.", + "MNTN_HG_VL" : "632", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 강촌", + "MNTN_NM" : "등선봉" + }, + "longitude" : 127.6465845, + "latitude" : 37.831663900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "춘천 소양댐 선착장에 닿으면 동쪽으로 두 산이 보이는데 정면으로 물고기 머리처럼 솟아 오른 산이 가리산(1051m)이고 그 옆에 병풍처럼 서 있는 산이 두루봉(545m)이다. 등잔봉은 가리산에 가려 보이지 않는 산으로 가리산맥 중간지점인 홍천고개에서 남쪽으로 펑퍼짐하게 버티고 서 있는 산이다. 등잔봉 사이에는 새득이봉(935m)봉이 솟아있다정상은 펑퍼짐한 초원지대로 인접해 있는 새득이봉이나 가리산이 뾰족한데 비해 둥그스름해서 넉넉해 보여 작은 들판으로 생각이 드는 곳이다. 하산은 밤가시 마을로 하는데 예부터 밤나무가 많아 밤가시 마을이라 불렸다는 이름의 유래가 흥미롭다.", + "MNTN_HG_VL" : "834", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "등잔봉" + }, + "longitude" : 127.8280278, + "latitude" : 36.755976400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고흥읍에서 율리치를 지나 고개를 넘어 송정리로 들어서면 천등산과 벼락산이 한눈에 든다. 천등산 정상부와 함께 겹쳐 보이는 바위산이 그 앞에 보이는데, 이 산 이름은 딸각산이다.바위를 밟고 오르노라면\"딸각딸각\"소리가 난다 해서 그곳 주민들은 그렇게 부른다고 한다. 그러나 옛 기록에는 월각산(月角山)이라 기록하고 있다.\"딸각\"이\"달각\"으로, 달각이 월각으로 변한 것이다. 산행은 산 중턱을 가로 넘는 임도가 세 가닥이 나 있어 어떤면에서는 쉽게 오를 수 있는 산이지만 임도 때문에 오히려 산행의 맛이 덜할 수도 있다.", + "MNTN_HG_VL" : "420", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", + "MNTN_NM" : "딸각산" + }, + "longitude" : 127.25388890000001, + "latitude" : 34.548055599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "떡갈봉은 충주호를 사이에 두고 월악산과 마주보며 수석처럼 솟아 오른 산으로 월악산에 비해 덩치는 작지만 정상에서의 조망은 큰 산 못지 않다. 정상에 올라 내려보는 아름다운 충주호와 월악산 북사면을 샅샅이 훑어보는 독특한 조망이 있어 관심을 끄는 산이다.본래 이 산자락에는 4개의 마을이 있었는데 충주호가 생기면서 마을이 수장되고 주민들은 이주하게 되었다. 그러나 가을이 되면 예전 주민들을 이 산에서 쉽게 만나 볼 수 있다.", + "MNTN_HG_VL" : "544", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", + "MNTN_NM" : "떡갈봉" + }, + "longitude" : 127.43776750000001, + "latitude" : 36.235260099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용인시내에서 동북쪽으로 보이는 길고 높은 산릉이 광주산맥이다.그 중에서 중절모같이 생긴 산이 광주의 태화산인데 태화산 북쪽에 뾰족한 삼각형산을 아는 사람은 별로 없다. 높이는 품은 태화산에 손색이 없는 이 산이용인시 제1봉인 말아가리산(마구산)이다.말아가리산은 정상의 바위가 퉁점에서 보면 말이 입을 벌린 모습에서말아가리라 이름 붙여진 산으로, 포곡읍 유운리에서 보면 말머리 모습으로 보이는 말과 인연이있는 산이다.", + "MNTN_HG_VL" : "595", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 처인구 포곡읍 금어리", + "MNTN_NM" : "마구산" + }, + "longitude" : 127.2254866, + "latitude" : 37.264675199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우리나라에서 다섯번째로 큰 섬인 강화도에는 고려산, 혈구산, 진강산, 마니산 등 400m 이상의 4개산이 남북으로 일직선상에 솟아 있는데 그 중 제일 높은 산이 마니산이다. 〈고려사〉〈세종실록지리지〉〈태종실록〉 등 조선 초기에 발간된 문헌에는 머리산, 우두머리산이란 뜻의 마리산(摩利山) 또는 두악(頭嶽)으로 쓰여 있다. 그래서 지금도 마리산이라는 이름을 혼용해서 사용하고 있지만, 오랫 동안 마니산이라 불러왔는데 새삼 마리산이라고 하여 혼동을 줄 필요는 없을 것같다.마니산은 비교적 낮고 수도권에 가까운 거리에 있어 친정을 찾는 기분으로 편하게 찾을 수 있다. 해발이 낮더라도 주능선이 암릉으로 되어 있으니 등산의 묘미도 한껏 만끽할 수 있는 산이다.동남으로 가느다랗게 뻗은 능선을 따라 오르다 보면 망망한 서해를 조망할 수 있다. 조국순례 안내판이 있는 '개미허리'에서 98개의 계단길을 올라가면 사적 제 136호인 '참성단'(塹星壇)을 만날 수 있다. 이곳에서 매년 개천절과 전국체전때마다 성화가 채화된다. 참성단은 단군 왕검 재위 51년(BC2283년)에 운사(雲師)인 배달신(倍達臣)이 마리산에 쌓은 제단으로, 〈삼국사기〉에 의하면,고구려.신라.백제의 여러 왕들이 이 곳에서 하늘에 제사를 지냈다. 고려 공민왕 때와 조선 인조.숙종 때 각각 보수되어 현재 이른다. 이 단은 화강석을 쌓아올려 만든 것으로, 밑부분은 둥글고 윗부분은 사각형이며, 높이가 총6m에 달한다. 참성단 위에 오르면, 동쪽으로 정상이 손에 잡힐 듯 가깝게 보이고, 남쪽 아래로는 푸른 물결이 넘실거리는 넓은 바다가 발아래로 펼쳐지고, 동남쪽 멀리 인천시가지가 아득히 보인다.정상 서쪽 산기슭에는 신라 선덕여왕 8년(639년)에 창건했다는 정수사와 함허대사(涵虛大師)가 수도하였다는 함허동천이 자리잡고 있다. 함허동천에는 1백여m의 암반위로 물이 흐르고, 암반에는 함허대사가 새겼다는 '涵虛洞天'(함허동천)이란 글자가 음각 되어 있다. 외침을 자주 받았던 고려가 부처의 힘으로 나라를 지켜 보려고 강화도에서 크게 불사를 펼쳤던 까닭인지 강화도에는 내력 있는 절이 많다.", + "MNTN_HG_VL" : "472", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 화도면", + "MNTN_NM" : "마니산" + }, + "longitude" : 126.434827, + "latitude" : 37.611603000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마니산에는 거대한 바위성 같은 바위절벽을 안고 선 향로봉이 있다. 수려한 산세를 가졌지만, 아직도 이 산을 찾는 이가 그리 많지 않다. 바로 서쪽에 영동의 명산 천태산의 명성에 가려져 있기 때문이다.향로봉의 동면 아래에 있는 중심이 마을쪽은 좌우가 모두 깍아지른 바위벼랑이며 향로봉 둘레 575봉과 564봉의 남면 모두가 엄청난 높이의 낭떠러지를 이루고 있어 장관이다. 전체적인 마니산의 지형은 한 마리의 문어가 금강을 향해 발을 뻗친 모양이다. 그 발 끝에는 어류산, 시루봉, 노고산, 봉화산, 동골산이 있다. 동면에는 마니산 성터와 공민왕의 거처였다는 절터가 있다. 마니산 능선에서 고려 공민왕때 홍건적의 난을 피해 들어 왔을 때 쌓은 산성벽이 지금도 남아있다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군, 옥천군", + "MNTN_NM" : "마니산" + }, + "longitude" : 126.434827, + "latitude" : 37.611603000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마대산은 우리나라의 마지막 비경지대를 간직한 산으로 강원도 영월군 하동면과 충북 단양군 영춘면의 경계를 이루고 있다. 마대산 서쪽 아래로는 고씨동굴 앞을 흐르는 남한강의 수려한 풍광과 북으로 흐르는 옥동천이 남한강으로 합수되어 보기드문 비경을 연출한다.이 산이 특히 유명해 진 것은 조선의 방랑시인이자 풍자시인인 김병연 속칭 김삿삿이 숨어 살던 터에 복원한 집과 무덤 등 유적이 있기 때문이다. 한 여름이면 자연과 위대한 시선의 흔적을 밟으려는 외지인들로 붐빈다", + "MNTN_HG_VL" : "1052", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 충청북도 단양군 영춘면", + "MNTN_NM" : "마대산" + }, + "longitude" : 128.573329, + "latitude" : 37.087678099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "162", + "MNTN_LOCPLC_REGION_NM" : "경기도 오산", + "MNTN_NM" : "마등산" + }, + "longitude" : 127.10383539999999, + "latitude" : 37.144254599999996 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "마래산" + }, + "longitude" : 127.7422222, + "latitude" : 34.763611099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강릉대학교의 뒷산으로 숲길 이용이 많은 산이다. 주로 여성들과 노약자들의 등산로로 애용되는 곳이며 위험지역은 없으며 경사도도 무난한 편이다. 많은 이들이 이용하는등산로라서 이정표와 운동기구등 시설물 설치가 꼭 필요한 곳이다. 해발이 낮고 나무로 인하여 조망권은 별로 좋지 못하다.", + "MNTN_HG_VL" : "113", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "마명산" + }, + "longitude" : 127.4127778, + "latitude" : 37.4791667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전라남도 고흥군은 보성에서 끝날듯하던 한반도 남단이 벌교를 지나 계속 남쪽으로 내달으면서 형성된 반도를 이룬 군이다. 때문에 고흥 하면 바다만 보일 것만 같은 선입견을 갖기 마련이다.하지만 실제 고흥땅을 밟으면 해발 500~600m대 높이의 산들이 수없이 많다는 사실을 깨닫게 된다. 말이 엎드려 있는 형상이라는 이름을 갖고 있듯 마복산은 해창벌에서 바라보면 그저 동서로 길 게 뻗은 동네 뒷산처럼 평범하게 느껴진다. 하지만 파고들면 생각지도 못했던 모습에 마음을 빼앗기고 만다. 산등성이에는 수많은 지릉이 흘러내리고 그 지릉마다 바위꽃이 활짝 피어 있어 마치 금강산이나 설악산의 축소판을 보는 듯하다. 이러한 경관 때문에 마복산은 소개골산(少皆骨山)이라 불리기도 한다.마복산이 지닌 또 하나의 자랑거리는 다도해 전경이다.산 남쪽 바다는 다도해 해상국립공원으로 지정되어 있을 만큼 아름다운 곳이다. 산 등성이에 올라 푸른 바다 위를 떠다니는 듯한 올망졸망한 섬들 부드러운 선으로 이어지는 해안선과 그 사이사이 들어앉은 포구를 바라 보노라면 보는 이마저도 바다에 떠 있는 듯한 느낌에 사로잡히고 만다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", + "MNTN_NM" : "마복산" + }, + "longitude" : 127.3888716, + "latitude" : 34.536739400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마분봉과 구왕봉, 희양산은 모두 백두대간 충청북도쪽 산자락에 있는 은터에서 올라간다. 마분봉은 백두대간에서 갈라져 나온 암릉으로 이루어진 능선이며 이 능선을 통과하면 악휘봉 근처에서 백두대간에 올라설 수 있다. 백두대간 능선에 이르면 진행방향으로 보아 악휘봉이 뒤쪽에 있고 구왕봉과 희양산은 멀리 떨어져 있다.마분봉을 연풍사람들은『말똥바우』라 부르며『말똥바우』에 비가 묻어 오면 바쁘게 비설겆이를 한다. 연풍지역의 비는 늘 이곳부터 시작되기 때문이다. 마분봉의 유난히 뾰족한 봉우리가 말똥을 연상케도 하지만 실제로 정상 가까이 가보면 화강암 덩어리들이 말똥처럼 보인다. 특히 정상에는 또 하나의 말똥이 사발을 엎어놓은 듯이 보여 어느 모로 보나 말똥바우가 틀림없는 듯 하다.등산로에는 곳곳에 밧줄이 설치되어 있으며, 세미 클라이밍 지대는 있으나 특히 위험한 곳은 없다.", + "MNTN_HG_VL" : "776", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면", + "MNTN_NM" : "마분봉" + }, + "longitude" : 128.00587999999999, + "latitude" : 36.722050899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 중원 상모면과 괴산 연풍면 그리고 문경읍과 경계를 이루는 마역봉(馬驛峰)은 임진왜란때 신립장군의 한이서린 조령삼관문을 안고 있는 산이다.주말 산행 코스로 인기를 누리고 있는 신선봉(967m) 동쪽 1.5km 거리에 독립봉으로 우뚝 솟은 마역봉은 927m 의 높이에 비해 의외로 쉽게 오를수가 있다. 출발지점인 지릅재가 표고가 해발 650m 이기때문이다.산행의 들머리는 조령삼관문에서 오르거나 신선봉을 경유해도 되고 또 다른 코스는 소조령 3번 국도에서 고사리 마을을 지나 조령산 휴양림 매표소에 도착한 후 매표소에서 삼관문쪽 길을 따라 50m쯤 가면 급커브를 돌면서 왼쪽으로 훤히 뚫린 산길이 보이는데 여기가 신선봉과 마패봉의 중간능선으로 오르는 등산로다.산길을 접어들면 200여미터 거리에 비닐포장 가건물을 지어 놓고 밤낮없이 정성을 드리는 장소가 있는데, 바위 위로는 10여미터 폭포가 흘러내려 장관을 이룬다. 길은 폭포의 오른쪽 반석을 타고 올라 계류를 건너 물길을 따라 오르게 되는데 계곡이 v자 모양의 협곡으로 물이 흐를 때는 장관을 이룬다. 계류 옆으로 난 바위를 따라 조금 더 오르면 왼쪽으로 거대한 바위가 나타나는데 이것이 바로 치마바위이다.바위의 동쪽끝에서 바라보고 있노라면 그 끝자락은 분명히 곱디고운 여인이 치마가 땅에 닿을까봐 조심스레 치마폭을 추스리고 있는 것 같은 모습처럼 느껴진다. 혹시나 여인의 속살이라도 보일 것 같아 겸연쩍어진다. 마역봉은 뚜렷한 정상이 없이 50여미터 더 가면 전망대가 나오는데 월악산을 중심으로 한 북바위, 수리봉, 덕주봉, 만수봉, 포암산등 바위산의 진면목을 보여준다. 단순히 마역봉을 등산하기보다는 신선봉과 함께 등산하는 것이 일반적이다.소요 시간 :약 2시간 20분 소요최적 탐방 시기 : 9월 \/ 가을(단풍)볼거리 : 문경새재, 용유담, 신선봉, 각연사, 고산구곡, 화양동구곡숲길 명소 : 치마바위, 남쪽 계곡의 오솔길", + "MNTN_HG_VL" : "940", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 충주시 상모면", + "MNTN_NM" : "마역봉" + }, + "longitude" : 128.07108489999999, + "latitude" : 36.828661099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 이천시는 광주산맥의 줄기가 뻗어내려 북부에 여러 구릉을 기복시키고, 남부는 차령산맥에 연접하므로 북 서쪽은 산맥들로 이루어져 높고, 남동쪽은 점점 낮아진다. 북서쪽은 천덕봉(630m), 정개산(461m), 양각산(386m), 설봉산(394m), 건지산(411m), 마옥산(445.4m) 등이 솟아 있으며, 남동쪽에는 마이산(472m), 팔성산(378m), 백족산(402m) 등이 뻗어 있다. 중앙부에는 복하천이 남한강으로 흘러 들어가며 남동부에는 청미천이 음성군과 경계를 이룬다.마옥산은 마국산, 마고산, 마곡산 등으로 불리우기도 하며 여러 문헌을 통해 옛날에 오음산이라 부리웠음을 알 수 있다. 마옥산은 산이 중첩되고 험준하며 골이 깊기로 으뜸이다. 모가면 서쪽에 위치해 동남쪽은 설성면 서남쪽은 안성군 일죽면과 경계를 이루는데 굴바위, 병풍바위, 말바위, 구모바위등 유서 깊은 전설을 간직한 기암괴석들이 산재해 있고 군내 제일의 산간부락인 산내리. 대죽리등이 기슭에 위치해 있다. 또 복잡하게 얽힌 산줄기로 인해 사람이 되고 싶은 여우와 마옥산 99골짜기의 전설이 전해 내려오기도 한다.이산에는 안양사라는 대찰이 있었다고 하나 폐사된지 오래되어 지금은 그 정확한 위치조차 알 수 없고 마국산의 일맥인 소고리 서쪽 산골짜기에는 동쪽을 향한 넓은 바위 면에 뛰어난 솜씨로 선각된 마애여래좌상과 적극적이고 과장된 표현이 눈길을 끈 마애삼존불상이 있으며 조선시대 백자요지, 폐사지에 방치된 채 남아있는 부도 등의 유적이 있다.마국산의 심장부가 되는 산내리 서쪽산기슭에는 중종때 우의정을 지낸 영창부원군 권균의 묘소와 신도비가 있고 산내리 마을상단에 그의 사묘가 있다.서울에서 그리 멀지 않고, 인파도 붐비지 않는 호젓한 산행지로 각광을 받고 있는 곳이다. 수목이 울창하고 수려한 계곡과 기이한 암봉이 있는 산은 아니지만, 영창대군의 초라한 능묘와 사연이 있는 듯한 산속의 빈집이 특이한 점같아 보이며 때묻지 않고 깨끗한 산이라 좋다.", + "MNTN_HG_VL" : "446", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 일죽면 고은리", + "MNTN_NM" : "마옥산" + }, + "longitude" : 127.450046, + "latitude" : 37.167619700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마이산은 옛날 용출산, 동금산 등으로 불려 오다가 이조때 태종이 말 귀를 닮았다고 한 뒤부터 마이산이라 칭하게 됐다. 재미있는 것은 마이산은 바라보는 방향에 따라 그 모습이 달라 보인다는 것이다.그래서 마이산의 기이한 모습과 특이한 경관 때문에 여러 가지 이름을 갖고 있다. 붓끝같다해서 문필봉, 바위가 많아서 개골산, 방향을 달리해 보면 돛대를 닮아 돛대봉, 용의 뿔 같다해서 용각봉 등으로 불려진다.마이산은 동서로 큰 암수봉우리 두개가 있다. 동편 숫봉우리는 거대한 남성을 닮았다 하여 서다산(西多山)이라는 옛 이름도 지니고 있는데, 강한 양기를 품고 있어 산길이 험준하여 등산을 할 수가 없다. 서편에 있는 암마이봉은 나긋나긋하게 손짓하는 여성처럼 많은 등산객을 맞이하고 있다. 마이산에서 북쪽으로 흐르는 물은 금강 물줄기를 이루고, 남쪽으로 흐르는 물줄기는 섬진강으로 흐른다. 그 흐름이 반원을 그리고 있어 마이산은 금강과 섬진강의 분수령이 되고 있으며 두 강의 물줄기는 마이산을 중심으로 태극을 이루고 있다.마이산은 조선을 개국한 이성계와 인연이 깊은 산이다. 이성계는 마이산을 속금산(束金山)이라 불렀다. 일찍이 큰 꿈을 품었던 이성계는 금산 등 전국 각지의 명산을 찾아 기도를 올렸는데, 기도가 끝난 어느 날 밤 꿈에 신이 나타나 금척(모든 제도의 표준임을 말하며를 마음대로 헤아리도록 하라\"\"라고 했다 한다. 그 뒤 고려 우왕 6년(1380년) 고려의 장군 이성계는 전라도 운봉땅 황산에서 왜구를 무찌르고 개선 길에 마이산을 보고 놀랐다. 꿈에 신에게서 금척을 받은 장소가 바로 마이산이기 때문이었다.", + "MNTN_HG_VL" : "687", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍ㆍ마령면", + "MNTN_NM" : "마이산" + }, + "longitude" : 127.404811, + "latitude" : 35.762177399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청평사라는 명찰을 품은 오봉산의 남쪽에 자리한 산이다. 북쪽으로 오봉산(779m)과 연결되어 있고, 동쪽으로는 봉화산(736m)과 맞대고 있다. 마적산은 오봉산의 주능선이 서남쪽으로 나가다가 정남 방향으로 꺾이면서 최고봉인 785고지를 만들고 일직선으로 뻗어 내려가면서 크고 작은 여러 개의 봉우리를 일구고 있다. 마적산 산행의 백미라 하면 하산을 하면서 소양호를 감상 할 수 있다는 것이다.능선에는 주로 떡갈나무, 상수리나무 같은 참나무류가 숲을 이루고 있으며 도중에 무수한 칡덩쿨과 드룹나무 군락이 있다. 정상에서는 춘천시와 시가지를 가로지르는 소양강이 눈에 들어온다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신북읍, 북산면", + "MNTN_NM" : "마적산" + }, + "longitude" : 127.79229549999999, + "latitude" : 37.952335800000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : " 마정산은 해발 402M의 산으로 군위읍내에 위치하고 있어 주민의 발걸음이 빈번한 지역이다. 따라서 지자체에서 순환등산로 및 생활체육시설을 설치하여 주민의 복지증진을 꾀하였다. 마정산은 북서방향으로 길게 늘어진 능선으로 동쪽으로 선암산, 국통산이 관측되며 북쪽으로 선방산이 관측된다. 서쪽으로는 읍내와 위천, 중앙고속도로 등이 조망된다. 연말 군민의 해돋이 장소로 이용되는 구간이다.", + "MNTN_HG_VL" : "402", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 군위읍 용대리", + "MNTN_NM" : "마정산" + }, + "longitude" : 129.11215920000001, + "latitude" : 35.420248999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "311", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구", + "MNTN_NM" : "마집봉" + }, + "longitude" : 126.9887555, + "latitude" : 35.134134000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "274", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군, 경상북도 칠곡군", + "MNTN_NM" : "마천산" + }, + "longitude" : 128.46111110000001, + "latitude" : 35.899722200000006 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조령산 (제3관문)을 사이에 두고 깃대봉과 마주하며 충청북도 쪽으로는 신선봉과 맞닿아 있다. 백두대간이 지나는 산으로 지도에는 마역봉이라 기록되어 있으나 이 지방에서는 마폐봉이라 부르고 있다. 오르는 길은 조령관(제3관문) 못미처 충청북도 쪽에서 오르는 길이 잘 나 있으나 조령관(제3관문) 군막터를 지나 성벽을 따라 오르는 길도 있다. 오르는 시간은 1시간이면 충분하며 내려가는 길은 여러 곳이 있다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 각서리", + "MNTN_NM" : "마폐봉" + }, + "longitude" : 128.07108489999999, + "latitude" : 36.828661099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "광산의 갱도 막바지를 뜻하는 막장을 닮은 계곡의 끝에 서 있다하여 이름 붙은 막장봉은 기암괴봉과 낙랑장송이 어우러져 장관을 이룬 산이다. 달팽이 바위, 이빨바위, 삼형제바위 등 이름도 독특한 기암과 비탈 곳곳을 장식한 소나무가 만들어 내는 한 폭의 수묵화는 탄성을 절로 나게 한다. 이 산은 서쪽의 장성봉과 한 줄기로 이어져 있으며 북으로는 칠보산을, 남으로는 대야산을 마주보고 있다.작은 금강산이라는 불리워지는 쌍곡계곡은 괴산에서 연풍방면으로 12km정도에 위치하며 괴산팔경의 하나로 계곡의 경치가 아름답고 물이 맑아 사철 관광객이 끊이지 않는다. 쌍곡계곡을 흐르고 있는 냇물을 쌍천이라고하는데, 도수리고개에서 시작한 맑은 물이 군자산, 비학산, 보가산의 계곡사이로 구비치며 내곡천, 외곡천의 두줄기로 흘러 쌍계라 하였으며 이로 말미암아 골짜기 이름도 쌍곡이라 하였다.조선시대 이름 난 학자 퇴계 이황, 송강 정철등 수많은 학자와 문인들이 쌍계의 산수경치를 사랑하여 이곳에 머물렀다고 하는 쌍곡계곡은 호롱소, 소금강, 떡바위, 문수암, 고쌍벽, 곡용소, 쌍곡폭포, 선녀탕, 곡장암등 구곡을 이루며 푸른숲과 기암절벽 사이사이로 맑은 계곡물이 흐르고 있어 화양동, 선유동과함께 명승으로 알려져 있다.", + "MNTN_HG_VL" : "868", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군", + "MNTN_NM" : "막장봉" + }, + "longitude" : 127.9484282, + "latitude" : 36.706101400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만덕산은 완주군 소양면 화심에서 진안으로 가는 구 도로에 우뚝 솟아 있다. 그리고 임진왜란 당시 왜군을 맞아 치열한 전투를 벌였던 역사적 전적지이며 6·25 때 공비 출몰이 심했던 곳 중 하나로 곰티재를 지키고 있는 수문장과 같은 곳이다. 만덕산은 한자로 일만 만(萬)과 큰 덕(德)을 써서 만인에게 덕을 베푸는 산이라는 뜻이다. 그 이름 덕분인지 주민들의 말에 따르면 수많은 전란을 겪으면서도 지역 주민들은 큰 화를 입지 않았다고 한다. 암봉과 육산으로 조화를 이루어 가을 단풍, 겨울 설경의 풍치가 한 폭의 그림과도 같다. 특히 이 산의 동남쪽 기슭에 자리 잡고 있는 미륵사 일대의 경관은 일품이며 바로 아래 높이 50미터의 만덕폭포와 그 주변의 풍광은 등산객들의 발길을 사로잡는데 부족함이 없다. 겨울철의 빙폭은 젊은 산악인들의 빙벽 훈련장으로 사랑을 받고 있다. 전주에서 가깝고 교통이 편리한데다 등산 코스가 다양하여 모악산 다음으로 전주시민이 즐겨 찾는 곳이다.", + "MNTN_HG_VL" : "766", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 상관면, 소양면", + "MNTN_NM" : "만덕산" + }, + "longitude" : 126.7438889, + "latitude" : 34.592222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만덕산은 강진읍 남쪽에 위치한 높이 412미터의 야트막한 산으로 마을 뒷산처럼 보잘것 없지만, 산 안으로 파고들면 앙팡지고 아기자기한데다 능선에는 상당한 크기의 암석들이 많으며, 그윽한 정취마저 넘치는 산이다. 산기슭에는 천년고찰 백련사와 조선 말기의 실학자 다산선생의 실학정신이 깃들어 있는 다산초당 등 역사적 자취를 더듬어 볼만한 곳이 있어 등산과 유적지 답사를 겸한 산행으로 제격이다.산세 또한 부드러워 가족산행지로도 권장할 만하다. 바람재에서 석문사에 이르는 등산로는 사람들의 발길이 닿지 않아 잡목과 잡초가 등산로를 뒤덮고 있으나 이정표가 군데군데 설치되어 있어 산행하는 데는 큰 어려움이 없다. 백련사 주변으로는 천연기념물 제151호로 지정된 1500여 그루 동백나무가 1.3헥타르에 걸쳐 자라고 있으며, 특히 절 앞에 많이 모여 자란다.", + "MNTN_HG_VL" : "412", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 강진읍, 도암면", + "MNTN_NM" : "만덕산" + }, + "longitude" : 126.7438889, + "latitude" : 34.592222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만복대는 지리산의 많은 봉우리들 중 하나이다. 만복대라는 이름은 지리산의 많은 복을 차지하고 있다고 해서 붙여진 이름으로 조망이 뛰어난 곳이다. 또한 만복대 능선은 경사가 완만해 나이든 산악인들도 무난하게 정상에 오를 수 있다. 펑퍼짐한 시골 아낙의 엉덩이처럼 풍만하고 넉넉해 보이는 만복대는 산을 찾는 이들을 심성 좋게 품어준다.만복대는 북풍한설에 피어난 설화가 아름답기로도 유명하지만, 뭐니 뭐니 해도 지리산 최고의 억새능선이라는 수식어가 가장 어울린다. 가을철이면 금빛으로 출렁이는 억새의 군무가 저 멀리 병풍처럼 둘러친 지리산 주능선의 웅장함과 어우러져 장쾌한 풍경을 연출한다. 잡목이 많이 자라 예전만 못하다며 아쉬워하는 사람들도 있지만, 그래도 여전히 만복대 억세군락은 특유의 아름다움을 간직하고 있다. 봄철 산수유꽃이 필 때면 산동면 위안리의 상위, 하위 등 산수유마을에서 노란 산수유꽃을 감상하고 만복대에 올라도 좋다.", + "MNTN_HG_VL" : "1433", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 산내면 덕동리", + "MNTN_NM" : "만복대" + }, + "longitude" : 127.3930556, + "latitude" : 35.412222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만수산은 부여를 대표하는 고찰 무량사로 널리 알려진 산이다. 무량사는 신라 문무왕때 창건된 사찰로 경내에 보물 제 356호인 극락전과 삼존불, 정림사지 5층 석탑, 석등등 고려시대부터 조선조에 이르는 문화재를 많이 보존하고 있다.또한 생육신의 하나인 매월당 김시습의 혼이 깃든 곳이기도 하다. 수양대군(세조)이 단종을 몰아내고 왕이 되자 전국 각지의 절을 돌아다니며 승려 생활을 하던 김시습이 입적했던 이 사찰 입구에는 8각 원당형으로 된 그의 부도가 서 있다. 정상 서편에 근접해 있는 휴양림에는 편의시설도 갖추어져 있다.비록 산은 낮지만 수림에 덮인 능선이 병풍을 두른 듯 사찰 일대를 감싸고 있으면서 만만찮은 산세를 이루고 있어 등산할 만한 산이다.", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "충청남도 부여군 외산면, 보령시 미산면", + "MNTN_NM" : "만수산" + }, + "longitude" : 126.7113622, + "latitude" : 36.338012800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미양역에서 시내 쪽으로 600m 가다가 오른쪽에 역전시장으로 들어서면 팔각정 휴게소에 오른다.(택시 2,000원) 왼쪽 휴게소 정자 안으로 길 따라 나서면 청룡사 절이 나오고 용두산 용두연이 나온다.만어산 기슭에 자리잡고 있는 만어사 절앞 너른 계곡에는 온통 크고작은 바위들이 지천으로 널려있다. 절앞 바위들은 1만마리의 고기들이 부처님을 찾아와 설법을 듣고 바로 성불한뒤 모두 바위로 변했다고 한다.산행들머리는 되돌아 나와 휴게소 전면 헬기장을 지나 산길 따라 오르면 산행이 시작된다. 중계탑을 지나 체육공원으로 이어지고 주위에 갈림길이 많이 나와 있는 산행로이지만 반드시 능선을 탄다는 생각으로 오르면 무난하다.만어산 정상은 지금가지 지나온 코스를 눈여겨 보면 구비구비 아득하다. 서편에 우뚝 선 봉우리가 대마도를 보았다는 대마도 만댕이다. 만어마을 뒤에 우뚝 서 있고, 또한 정상에는 마치 통시간(뒷간)처럼 생긴 통시바위가 있다.", + "MNTN_HG_VL" : "670", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍 우곡리", + "MNTN_NM" : "만어산" + }, + "longitude" : 128.84601649999999, + "latitude" : 35.454823300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만연산은 화순읍 쪽에서 바라보면 바위군들이 날카로운 바위무리가 솟아있고 곳곳에 너덜이 있어 험하게 보인다.만연산 골짜기에 만연사가 있다. 이 절집은 고려시대인 1208년 만연선사에 의하여 창건되었다고 전하는데 만연선사가 무등산 원효사에서 수도를 마치고 조계산 송광사로 돌아가는 도중에 무등의 주봉을 넘어 남으로 내려오다가 만연사 중턱에 이르러 피곤한 몸을 잠시 쉬어가고자 앉은 사이 언뜻 잠이 들어 꿈을 꾸었는데 16나한이 석가모니불을 모실 역사를 하고 있는 꿈이었다.잠을 깨 사방을 둘러보니 어느새 눈이 내려 주위가 온통 백색인데 신기하게도 선사가 누운 자리 주변만 녹아 김이 모락모락 올라오고 있었다. 그 길로 이곳에 토굴을 짓고 수도를 하다가 만연사를 세웠다는 것이다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 화순읍", + "MNTN_NM" : "만연산" + }, + "longitude" : 126.9923874, + "latitude" : 35.091793699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 주맥인 영취산에서 나누어진 금남호남정맥이 팔공산에서 지맥을 분기해 솟구친 산이 바로 만행산이다. 이 산의 이름은 불가에서 스님들이 탐욕을 없애기 위해 걸식하며 산야을 돌아다니면서 수행을 닦는 두타행과 같은 뜻을 담고 있다.남쪽 산자락에 가람을 배치한 귀정사의 옛 이름은 만행사인데 백제때 한 고승의 설법에 취해 왕이 3일동안 이곳에 머물렀다고 하여 귀정사로 이름을 바꾸었다고 전해지며 현재는 비구니사찰이다. 지도상에는 주봉의 이름을 본따 천황산으로 표기되어 있으나 본래는 `만행산'이 올바른 표기라 하겠다.봄철에 철쭉이 한창일 때의 이산은 춘심을 억제하기 힘들만큼 온통 붉은 빛으로 가득차게 된다. 보현사와 귀정사등 천년고찰이 들어서 있고 상사바위로 올라서 정상까지 이르는 능선길은 산행의 묘미를 만끽하기에 충분하다. 비교적 잘 다듬어진 등산로와 중간 중간의 안내 표지판은 등산을 보다 수월하게 하는데 큰 도움이 되고 있으며, 정상까지 오를 수 있는 지름길도 있어 비교적 가볍게 다녀올 수 있는 산이다.", + "MNTN_HG_VL" : "909", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시", + "MNTN_NM" : "만행산" + }, + "longitude" : 127.450621, + "latitude" : 35.525928700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "말목산은 충주호가 내려다보이는 충북 단양군 적성면에 위치한 산이다. 많은 암봉으로 이루어진 말목산은 마항산(馬項山)이라고도 부르는데 산의 형세가 말의 목처럼 생겼다하여 붙여진 이름이다. 또한 마항산 자락에 있는 하진리에는 옛날 장군감이 태어나자 그와 걸맞는 말도 함께 태어났지만 장군감과 말이 모두 하진의 뒷산에서 죽어 이 산을 말목산이라 하였다는 전설도 전해오고 있다.말목산의 산행은 충주호와 맞닿은 하진리 마을회관에서 시작한다. 마을회관에서 북서로 난 길을 따라 20여분 정도 오르면 송전철탑이 나오는데 여기서부터는 급경사로 된 숲터널이 이어진다. 이곳을 지나면 너덜지대가 나타나고 또다시 급경사 사면이 시작된다. 여기에서 30분 정도 가쁜 숨을 몰아쉬면 도착하는 곳이 690m봉이다. 정상은 남쪽으로 난 능선길을 40분 정도 더 가야 도달할 수 있다. 정상까지의 능선길은 충주호가 바로 내려다보여 전망이 매우 좋다.말목산은 구담봉과 옥순봉을 비롯하여 설마동계곡과 장회탄,이호대등 조화신공의 자연경관과 유람선이 주유하는 풍경까지 곁들인 수려한 절경을 내려다 볼 수 있는 망루같은 산이며, 4개소의 큰 전망대에서 내려다 보면 감탄을 금치 못한다.", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 적성면 하진리", + "MNTN_NM" : "말목산" + }, + "longitude" : 128.27165919999999, + "latitude" : 36.941253699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "망경대산은 백둣대간의 상의 함백산을 모산으로 두위봉을 지나 질운산과 예미산을 지나 수라리재에서 잠시 능선을 가라앉았다가 다시 솟구친 산이다. 강원도 영월군 중동면과 하동면 경계를 이루고 있는 망경대산은 등반 경력을 가진 산악 동호인에게 조차 생소한 산이다. 10여년 전까지만해도 탄광이 들어서 있어서 산행지와 거리가 멀었다. 탄광이 빠져나가면서 이 산 인근의 산꾼들이 오르내리기 시작하여 지금은 등산로를 찾기가 수월해 졌다. 정상에 서면 남쪽으로 와석리 무릉계곡과 마대산 줄기가 장쾌한 파노라마로 펼쳐져 있고 멀리 선달산에서 소백산으로 이어지는 백두대간이 광활하게 펼쳐진다.망경대산의 산이름은 어린 단종이 숙부인 수양대군에게 왕위를 찬탈당하였다는 소식을 들은 충신 추익환이 산위에 올라 한양을 바라보며 눈물을 흘렸다는 데에서 유래되었다고 전해지며 영월 영모전에는 추익환이 단종에게 산머루를 진상하는 그림이 보관되어 있다.정상은 헬기장으로 이루어져 사방 막힘이 없이 좋은 조망을 보여준다. 북으로는 가리왕산 능선이 하늘금을 그리고 북동쪽으로는 예미산, 질운산, 두위봉으로 이어지는 능선이 보이고 동으로는 단풍산과 매봉산, 장산이 시야에 들어오고 그너머 태백산에서 선달산으로 이어지는 백두대간의 주능선이 한눈에 들어온다.남서쪽으로는 하동면 옥동리 마을이 분지처럼 보이고 산자락을 굽이치며 흐르는 옥동천이 그림같고 서쪽으로는 응봉산 방면으로 부드럽게 뻗은 능선이 시야에 들어온다.", + "MNTN_HG_VL" : "1088", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면", + "MNTN_NM" : "망경대산" + }, + "longitude" : 128.61972220000001, + "latitude" : 37.161388900000013 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충주호를 끼고 비단같은 풍광으로 우뚝 솟은 금수산 서쪽에 자리잡은 망덕봉은 금수산과 줄기를 같이하는 봉우리다. 금수산 정상에서 직선거리 1.5km지점에 솟아 있으니 금수산의 일부분이라 할 수 있다.정상에서 서쪽 고사리 봉으로 이어지는 암릉길이 너무 좋다. 낙타등 처럼 튀어나온 암봉을 그 지역에서는 용아장성이라고 부른다. 바위 안부에서 용아장성으로 오르는 길은 약 40m 에 이르는 절벽이다. 발디딤과 손잡이가 양호하여 전문인은 쉽게 오를 수 있은나 초보자는 주의를 기울여야 한다.암봉 꼭대기에 오르면 노송군락과 충주호를 끼고 앉은 월악산의 자태가 빼어나다. 북쪽 아래로는 바위절벽 아래에 숨은 듯이 보이는 천년고찰 정방사가 보이고 능강계곡이 매우 아름답게 보인다. 용아릉에서 고사리봉 못미쳐서 안부 사거리에서 우측길 능강천으로 내려오면 계곡에 물이 많고 능강교 아래는 맑은 물이 흐르는 정비된 넓은 계곡이 유원지처럼 물놀이 하기에 좋다.안부 사거리에서 좌측길로 내려서면 수천평의 억새밭이 있고 내려서면 술모기 등산 기점으로 내려설 수 있다.", + "MNTN_HG_VL" : "926", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", + "MNTN_NM" : "망덕봉" + }, + "longitude" : 128.22201559999999, + "latitude" : 36.989854299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "망산(397m)은 거제도 최남단에 위치한다. 덕분에 가는 길이 즐겁다. 신거제대교로 견내랑을 지나 어느 방향으로 달리더라도 탁 트인 해안가 절경과 쪽빛바다가 이어진다. 산 정상에 오르면 지금까지 봐왔던 단편적인 절경이 다도해라는 한폭의 초대형 풍경화로 다가온다. 망산은 조선 말기 국운이 기울면서 왜구의 침범이 잦자 주민들이 자발적으로 산 정상에 올라 왜구 선박의 감시를 위해 망을 보았다 해서 명명됐다. 그래서 망산은 울창한 숲으로 인한 산 자체의 빼어난 아름다움보다는 조망이 뛰어나다는 점이 우선 부각된다. 그런 점에서 오늘날의 ‘망’은 한려해상국립공원의 비경을 관찰하는 조망처로 해석하면 될 듯하다. 날씨가 청명하면 대마도와 부산도 볼 수 있다. 등산로는 크게 네 가닥인데 깎아지른 듯한 해안을 끼고 마을을 형성하고 있다. 망산 앞바다에 작은 섬들을 거느린 대·소병대도가 점점이 떠있어 이 섬들을 바라보고 지키는 곳이라 하여 여차(汝次)라 한다.", + "MNTN_HG_VL" : "375", + "MNTN_LOCPLC_REGION_NM" : "경남 거제시 일운면", + "MNTN_NM" : "망산" + }, + "longitude" : 128.60480910000001, + "latitude" : 34.711878899999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "686", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", + "MNTN_NM" : "망실봉" + }, + "longitude" : 127.90437300000001, + "latitude" : 35.708252100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "망우산(망우리공원)은 중랑구의 동남측과 구리시와 경계에 걸쳐있으며, 행정구역상 서울시 중랑구 망우동, 면목동, 경기도 구리시에 남북으로 길게 위치하고 있다. 망우산(망우리공원)을 중심으로 서남쪽으로 용마산과 동남쪽으로 아차산과 경계를 이루고 있으며,지형은 남북으로 형성된 주 능선축을 중심으로 동서방향의 부능선이 수지형으로 발달되어 계곡을 형성하고있다. 표고는 최고 287.71m, 최저 40.2m로 표고차는 약 247m로 다소 높은편이며 표고별 면적 구성비는 50~250m 사이에 고르게 분포 되어 있다. 경사는 면적분포를 보면10~20% 경사지가 전체의 62.0%로 완경사지가 가장 많은면적을 차지하고 있으나, 시설입지가 가능한 완경사지가 가장 많은 면적을 차지하고 있으나, 시설 입지가 가능한 완경사지의 대부분이 묘지가 분포 되어 있어 시설부지 조성이 어려운 실정이다. 식생은 망우로를 중심으로 부지의 북측은 참나무류(16.02%), 아까시나무(14.53%), 잣나무(6.93%)등이 우점하고있으며, 전체적으로 양호한 수림대를 형성하고 있다. 단, 망우로 남측은 전반적으로 묘지가 분포되어 있어초지(34.99%)로 나타나고 있다. 경관은 남북방향의 능선축을 따라 멀리 북서측의 망우동 전경과 남동측의 구리시 전경이 파노라믹한 경관을 형성하고 있어 탁월한 조망효과를 연출하고 있다. 망우산(망우리공원)에서는 우리나라 어린이운동의 효시인 방정환, 3.1운동의 민족대표 33인중 한 분인 오세창, 한용운, 우두보급의 선구자로 의학자이며, 국어학자인 지석영, 임시정부 내무부서기를 역임한 문병훤, 동아일보 주필과 한국민주당 창당을 주도했던 장덕수, 제헌국회의원이며 진보당 당수였던 조봉암 등의 묘소가 있으며, 이들 일곱 분의 애국지사 및 유명인사 연보비가 공원 내 산책로 조성과 함께 지난 1997년 2월에 설치되었으며, 이어서 1998년 2월에 시인 박인환, 문일평, 서병호, 서동일, 오재영, 서광조, 유상규, 교육가 오긍선 등여덟 분의 연보기가 추가로 설치되어 역사의 교육장으로 이용되고 있다. 또한 , 망우동 산57-1번지 일대 망우산(망우리공원) 내의 내부순환도로 5.2km 를 아스콘으로 포장하여 산책로로 만들었으며, 산책로의 이름을 공모하여 1998년 5월 사색의 길로 정하고, 도시환경과 자연관찰로, 종합안내판, 나무정자, 약수터 등이 설치되어 구민과 이용자의 휴식 및 자연공원으로 많은 시민들이 찾고 있다.", + "MNTN_HG_VL" : "282", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 중랑구 망우동, 면목동, 구리시", + "MNTN_NM" : "망우산" + }, + "longitude" : -69.771065399999998, + "latitude" : 44.229377100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남해에서 최고 높이를 자랑하는 망운산, 그러나 남해 명산인 금산에 가려 그 진가가 꼭꼭 숨겨진 곳이다. 또한 망운산을 오르는 사람은 이곳이 알려지는 것을 싫어한다. 깨끗한 풍모, 드넓은 기상을 많은 사람들과 공유하기 싫은 탓이겠다. 금산이 남해를 찾는 손님들의 산이라면, 망운산은 남해인들이 가장 아끼는 늠름한 기상이다.고현면 대곡마을에 있는 화방사에서 조용한 산사의 정적을 뒤로 하며 산길을 올라 정상에 오를 수 있다. 정상에서 보는 주변 바다 위에 점점이 떠있는 자그마한 섬들과 강진만, 연죽저수지, 청정해역의 서상 앞바다, 멀리는 지리산, 여천공단, 여수, 삼천포까지 한눈에 들어온다. 정상에는 기우제를 지냈던 흔적인 듯, 평평하게 북쪽을 향하도록 되어 있고, 옆에는 제관이 앉을 수 있도록 돌로 된 의자가 놓여있다. 남해에 비가 오지 않을 경우 제일 먼저 이곳에서 기우제를 지내고, 그래도 비가 오지 않을 경우 상주리 앞바다 세존도에서 기우제를 지냈다고 한다. 정상 반대편에 있는 연대봉에는 봉수대의 흔적이 남아 있다.5월에는 철쭉군락지의 꽃들이 만개해 많은 사람들이 찾는다. 정상까지는 1시간 30분 정도 걸린다.", + "MNTN_HG_VL" : "785", + "MNTN_LOCPLC_REGION_NM" : "경남 남해군 서면 노구리, 남해읍 아산리 일원", + "MNTN_NM" : "망운산" + }, + "longitude" : 127.8446545, + "latitude" : 34.844905300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통방산의 서쪽에 위치한 매곡산은 호젓한 맛이 일품이다. 주위에 통방산이 자리하며 청평가도를 따라가면 우측으로 고동산, 화야산, 뽀루봉의 줄기가 이어서 바로 바라다 보인다.산이 높지는 않지만 일반인들이 이 산의 존재를 잘 모르기 때문이다. 또한 사람들의 발길이 적어 나무들과 산을 흘러내리는 물이 별 방해를 받지 않고 살고 있다. 그래서 이 산을 오르다 보면 다른 산들에 비해 유난히 숲이 울창하고 계곡의 물소리 또한 나무들의 사색을 방해하지 않으려는 듯 조용조용 흐르는 것을 알게 된다. 요즘은 산을 즐기는 사람들에 의해 조금씩 알려지고 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면", + "MNTN_NM" : "매곡산" + }, + "longitude" : 126.8894794, + "latitude" : 35.198389200000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상북도 양산", + "MNTN_NM" : "매봉산" + }, + "longitude" : 127.0088236, + "latitude" : 37.544227499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼랑진과 원동에 걸쳐 있는 매봉산, 금오산, 천태산은 낙동강을 끼고 있어 주위 경관이 수려할 뿐 아니라 경부선열차를 이용할 수 있어 교통도 편리하다. 금오산만 오를 경우 4시간, 금오산- 천태산 코스는 6시간30분, 금오산-매봉산 코스는 6시간 정도 소요된다.산행기점은 삼량진역에서 안태행버스를 타고 종점에 내리면 상점이 눈에 들어온다. 이 상점 옆으로 계류가 흐르는 냇가가 있는데 이 길로 오르면 포장도와 만난다. 포장도를 건너 노란색 물탱크옆 작은길로 접어들면 본격적인 산행이 시작된다.", + "MNTN_HG_VL" : "755", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양 삼량진", + "MNTN_NM" : "매봉산" + }, + "longitude" : 127.0088236, + "latitude" : 37.544227499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "220", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 고아읍 괴평리", + "MNTN_NM" : "매봉산" + }, + "longitude" : 127.0088236, + "latitude" : 37.544227499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "매봉산은 치악산국립공원 동남쪽 끝머리인 성남리 동쪽 선바위봉(1,001m)에서 감악산으로 이어지는 능선상의 최고봉이다. 감악산(945m)을 마주보고 있는 이 산은 예로부터 산삼이 발견되고 있는 산으로 유명하고 옛날 정상에서 매를 풀어 토끼와 꿩사냥을 하였다하여 매봉산이라 불리었다.치악산 국립공원 구역에서 살짝 비껴 앉은 이 산은 주변산에 비해 호젓한 산행을 즐길 수 있으며 겨울철에는 적설량이 많아 겨울산행을 즐기기에도 안성맞춤이다. 가을이면 치악산에서 매봉까지 병풍처럼 펼쳐지는 오색단풍이 일품이다.정상에 서면 북으로 당골계곡, 남으로 감악산, 동으로 사자산, 백덕산 등 주변 산악지대가 장관을 이루고 있다. 또 당골계곡 너머로 치악산 비로봉과 매화산이 단아한 자태를 드러낸다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면, 영월군 수주면", + "MNTN_NM" : "매봉산" + }, + "longitude" : 127.0088236, + "latitude" : 37.544227499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영월군 동쪽 상동읍과 중동면의 경계를 이루는 매봉산은 정상에 오르면 사방으로 터진 시원한 조망이 일품이다. 산행기점은 아시내 마을이다. 아시내를 출발하여 멧둔골을 경유하여 정상에 오른 후, 서봉 - 남릉 - 원천계곡, 또는 849봉을 경유하여 주채마을로 내려선다.정상은 둥그스름한 토봉이며, 남쪽은 천혜의 절벽으로 이루어져 있고 , 북쪽은 부드러운 사면으로 이루어진 산으로 기암절벽에 어우러진 노송과 울창한 숲을 간직한 비경의 산이다.", + "MNTN_HG_VL" : "1095", + "MNTN_LOCPLC_REGION_NM" : "강원 영월 상동읍. 중동면", + "MNTN_NM" : "매봉산" + }, + "longitude" : 127.0088236, + "latitude" : 37.544227499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "매악산 하면 산이 험하고 힘든 산으로 생각하기 쉬우나 사벌면 일대에 솟아 있는 산들이 대부분 200m미만의 낮은 구릉과 평야지대로써 이 산 주변에는 이만한 높이의 산이 없기 때문에 주변 사람들이 산에 오르기가 힘이 든다고 해서 유래되었다고 한다.시원스럽게 펼쳐치는 넓은 평야와 굽이쳐 흐르는 낙동강, 상주 유일의 억새숲으로 뒤덮인 덕암산과 낙동강 1300리 물길중 제일 아름답다는 경천대. 그리고 낙동강변에 솟은 비봉산, 쉰등, 나각산 상주의 삼악인 노악산, 갑장산, 천봉산이 그림처럼 조망되는 곳이다.", + "MNTN_HG_VL" : "335", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 사벌면 매호리", + "MNTN_NM" : "매악산" + }, + "longitude" : 127.0843701, + "latitude" : 35.729759000000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정상에서 서남쪽으로 능선이 이어지면서 치악산과 합해지고, 동쪽으로는 백악산과 마주보는 큰 산이다. 그 동안은 이웃한 치악산의 명성에 가려 세상에 알려지지 않았다.그러나 봄철이면 철쭉과 진달래가 붉게 물들어 여성적인 아름다움을 간직하고 있어 산행을 권할 만하다.옛날 신선이 살았다는 전설을 간직한 신선봉이 있다.(연중 입산 및 등산 불가 지역입니다.) 치악산 국립공원 내에 속하는데 치악산에 비해 찾는 이가 거의 없으니 의외로 호젓한 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "954", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면", + "MNTN_NM" : "매화산" + }, + "longitude" : 128.09546739999999, + "latitude" : 35.773327199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 합천군 가야면에 위치한 매화산은 가야산국립공원에 속해 있으면서도 가야산의 유명세에 아직 빛을 발하지 못하는 명산이다. 흡사 금강산 축소판과 같은 산세에 날카로운 바위능선이 있는가 하면 울창한 상록수림이 녹색과 붉은색의 조화를 이루기도 한다.매화산은 가야남산·천불산이라고도 부른다. 가야산의 지맥으로 산세가 웅장하며 가야산에 버금가는 다양한 산세를 지니고 있다. 불가에서는 천불산으로 부르는데, 이는 천개의 불상이 능선을 뒤덮고 있는 모습과 같다고 하여 붙여진 명칭이다.단풍이 수려하려면 기암괴석이 발달돼야 하는데 매화산이 바로 그런 산이다. 암봉 사이사이에 단풍이 물들어 그 사이로 뚫린 등산로를 통과하는 산행의 묘미는 특히 일품이다. 봄이면 진달래꽃, 가을이면 붉게 물든 단풍이 절정에 이르고, 겨울이면 소나무 숲이 어울려 설경이 가히 천하제일의 절경을 빚어낸 찬탄을 금치 못하게 한다.", + "MNTN_HG_VL" : "1085", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 가야면", + "MNTN_NM" : "매화산" + }, + "longitude" : 128.09546739999999, + "latitude" : 35.773327199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 홍천군 내면에 소재해 있는 맹현봉은 우리나라 최후의 오지라는 강원도 심산유곡으로 내린천변에 맹렬한 형상으로 솟아있는 산이다. 명현봉 서쪽에서 정상밑으로 난 운리동골은 커다란 암반과 소, 폭포가 어울어져 수려한 골짜기를 이루며 사방으로 뛰어난 경관을 갖추고 있다.이 산은 사람들의 발길이 닿지 않은 깊은 산이면서도 위험한 코스가 별로 없는데 지류가 여러갈래로 나눠져 있으므로 정상쪽으로 이어지는 주류를 잘 선택해야 한다. 특히 운리동골 입구를 지나 2km남짓 되는 곳에서 골이 오른쪽으로 크게 휘는 곳에서 길을 잃기 쉬우므로 유의해야 한다. 맹현봉 정상은 널찍한 헬리포트가 닦여 있는데 정상에서의 하산길은 두 갈래다.", + "MNTN_HG_VL" : "1214", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "맹현봉" + }, + "longitude" : 128.3197222, + "latitude" : 37.830833299999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월악산 국립공원권에 속하는 만수봉(萬壽峰)과 하설산(1028) 사이에 자리한 용하구곡(用夏九曲)을 굽어보며 기암 절벽으로 솟아 있는 메밀봉은 월악산 국립공원권에서는 산 높이가 비교적 낮은 산에 속하나 경관면에서는 여느 명산 못지 않게 경치가 뛰어 난 곳이다.남북으로 대판골과 용초골이라는 때묻지 않은 비경을 간직한 계곡이 흐르며 산행 기점 모두가 용하구곡에 있어 여름철 산행지로는 최상의 조건을 가지고 있는 산이다. 암릉 능선은 시원한 조망과 아기자기한 산행 묘미를 주며, 용초골 계곡 산행의 비경은 신비로움을 더해주며, 옛날 용이 승천하였다는 용초폭포는 깊이가 두 길이 넘는 소(沼)를 거느리고 있어 보는 이의 가슴속까지 시원하게 해준다.", + "MNTN_HG_VL" : "839", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면, 한수면", + "MNTN_NM" : "메밀봉" + }, + "longitude" : 127.0053193, + "latitude" : 37.482602999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포항시와 청송군의 경계에 솟은 면봉산은 포항시에서가장 높은 산으로 남동쪽으로 보현산, 북동쪽으로 베틀봉과 이어진다. 낙동강의 길안천이 북사면에서, 금호강의 자호천이 동사면에서 발원한다. 교통이 불편해 찾는 이가 많지 않지만, 그 때문에 아직도 청정 계곡과 숨은 비경을 간직하고 있다.정상에서 건너편 보현산 천문대가 손에 잡힐 듯 가까이 있고, 주변으로 나무가 없고, 넓은 초지를 형성하고 있어 지역 사람들은 ‘민봉산’으로 부르기도 한다. 산 정상에는 청송군과 포항시에서 각각 정상석을 세워놓았는데, 청송군에서는 1205미터 포항시에서는 1113미터라고 정상 높이를 표기하고 있다. 교통이 불편한 탓에 산행은 원점회귀 코스를 택하게 되는데, 주로 두마리 마을회관을 들머리와 날머리로 이용하고 있는데, 10년 전 폐교된 두마분교를 주차장으로 이용한다.2004년 설립된 면봉상 기상레이더 관측소가 있으며, 이에 따른 임도가 산 정상까지 나 있다.", + "MNTN_HG_VL" : "1113", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군 현동면 ·현서면, 경상북도 포항시 북구 죽장면", + "MNTN_NM" : "면봉산" + }, + "longitude" : 129.02324719999999, + "latitude" : 36.170616500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "면산은 창말의 앞에 있다 해서 마을 사람들이 붙인 이름이다. 이 산은 사람들이 많이 찾지 않아 처녀림의 신비함을 간직하고 있으며 정상에서는 노루와 같은 야생동물들의 흔적을 쉽게 발견할 수 있다. 이 산 부근의 다른 산들도 여전히 사람들의 시선에서 벗어나 있어 훼손되지 않은 곳이 많다.정상에 오르면 대덕산, 매봉산이 뾰족하다. 금대봉, 함백산 중계탑 사이로 장산, 그 뒤로도 끝없는 산이 이어진다. 서쪽에 강원탄광이 위치하고 영동선(嶺東線)이 통리(桶里)를 넘어 동해시에 이른다. 낙동강 상류의 작은 지류가 발원한다.", + "MNTN_HG_VL" : "1245", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", + "MNTN_NM" : "면산" + }, + "longitude" : 129.09562510000001, + "latitude" : 37.100704499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "명위산이 위치해 있는 충주시 동량면 하천리는 옛날에 토정(土亭)이 살았던 곳으로 `하천팔경 또는 개천팔경(開天八景)' 이라는 명소(名所)를 가지고 있으며, 풍수학적으로 화를 피할 수 있는 피난지로 알려진 곳이다. 이곳에 충주 호반과 어우러져 수석처럼 아름답게 솟아 있는 면위산에는 남쪽 능선에 2개의 옥녀봉이 있으며, 옥녀봉에는 물맛 좋은 약수가 있어 옛날 선녀들이 내려와 물맛과 이 곳의 경치를 즐기다가 하늘로 올라갔다는 전설이 전해지고 있다. 약수는 중탕과 상탕, 2곳이 있다.면위산은 옥녀봉으로 많이 불리우며 부산으로 불리게 된지는 얼마되지 않는다. 일제시대 때 지명정리를 하면서 동네사람들로부터 면위산(免危山) 이란 말을 며느리산으로 잘못 듣고 며느리 부(婦)자를 써서 부산(婦山)으로 잘못 쓰게 된 것이라고 한다. 이 산은 마을 이름을 따서 하천팔경(荷川八景), 또는 하늘을 연다는 뜻인 개천팔경(開天八景)이라는 명소들을 산자락에 거느리고 있어 산행의 즐거움을 배가시 키고 있다.", + "MNTN_HG_VL" : "780", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면", + "MNTN_NM" : "면위산" + }, + "longitude" : 128.05472219999999, + "latitude" : 37.041388900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "329", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시", + "MNTN_NM" : "명덕산" + }, + "longitude" : 127.1847222, + "latitude" : 36.426944399999996 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "명봉산은 작지만 오밀조밀한 맛이 있다. 능선에는 노송이 많고 때묻지 않은 채 유지되고 있으며, 산길은 점토질이 많아 걷는 촉감이 매우 좋고 포근한 분위기에 젖게 하는 매력적인 산이다.시골집 같이 정겨운 분위기의 염불암, 원시림처럼 우거져 침침하기까지 한 북릉의 숲, 신선과 사람이 바둑을 두었다는 신선바위, 수량이 풍부해 보기만 해도 시원한 계곡, 수령이 500년 가까이 된 커다란 느티나무 등이 곳곳에 흩어져 있어 이것들을 둘러보노라면 산에 오르내리는 일이 지겹거나 힘들지가 않다.", + "MNTN_HG_VL" : "599", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 문막", + "MNTN_NM" : "명봉산" + }, + "longitude" : 127.8568085, + "latitude" : 37.297361400000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도에서 화악산(1,468.3m)에 이어 두 번째로 높은 명지산은 정상을 오를 수 있는 산으로는 최고봉이다. 거대한 산맥을 이룬 명지산은 산 크기만큼이나 등산로도 많이 있으나 어느 길이나 정상까지 3시간 이상 소요된다. 서울에서 가까운 곳에 있으면서도 아직 오염되지 않은 깨끗한 계곡과 울창한 수림을 간직하고 있다.가평천을 사이에 두고 화악산과 마주보고 있는 명지산은 정상을 기점으로 사방으로 산자락을 펼치며, 귀목봉, 사향봉, 백둔봉 등을 거느리고 있는 웅장한 산이다. 명지산의 울창한 수림은 일상에 지쳐 산을 찾는 이들을 포근히 감싸안는데 그 깊이를 가늠할 수 없다.사계절이 다 아름다운 명지산은 특히 봄에는 진달래와 쩔쭉이 온산에 흐드러져 봄날의 산행을 즐기는 이들을 황홀경에 젖게 만든다. 가을 단풍은 가평 팔경 중 제 4경으로 지정 되었다. 우리나라 가을 산은 어디나 아름답지만 명지산의 단풍은 수십년 묵은 고목과 기암괴석들과 조화를 이루어 더욱 더 깊이를 더 한다. 또한 겨울에는 적설량이 많아 설화가 장관을 이뤄 겨울산행을 나선 이들을 반긴다.명지산 입구인 익근리에서 약 1Km가량 올라가면 규모가 작은 사찰인 승천사가 나타나고, 이어서 2Km가량 더 가면 등산로 왼쪽으로 높이 6m에서 시원한 물줄기가 쏟아 내리는 명지폭포를 만나게 된다. 한여름 불볕더위도 식혀 버리는 명지폭포 아래 깊은 웅덩이는 옛날에 명주실 한타레가 다 들어갈 정도로 깊어 명지폭포로 이름이 붙여졌다 한다.", + "MNTN_HG_VL" : "1252", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ하면", + "MNTN_NM" : "명지산" + }, + "longitude" : 127.43194440000001, + "latitude" : 37.941666699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시", + "MNTN_NM" : "모락산" + }, + "longitude" : 126.98119699999999, + "latitude" : 37.369781099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "모락산은 낮은 산이지만 암봉이 연이어 솟아있고 숲이 우겨져 있어 암봉을 오르내리는 아기자기한 산행의 맛을 느낄 수 있다. 고스락에 서면 조망이 좋아 북쪽의 관악산, 동쪽의ucirc;계산, 백운산, 광교산을 볼 수 있고 서쪽으로 수리산이 보인다. 도시 가운데 산이라 여러 곳에 갖가지 운동기구와 의자 등 쉴 수 있는 시설도 많다.근래 발행된 지도에는 모락산(帽洛山)으로 표기 되어있지만 모락산(慕洛山)이 옳은 이름이라는 주장도 있다.조선시대 제7대 임금인 세조가 12세기에 등극한 단종을 사사하고 왕위에 오른 것을 목격한 임영대군(1418~1469, 세종대왕의 넷°아들)은 왕위도 좋지만 혈족 간에 살생까지 한 세조에게 반감이 생겨 매일 이 산에 올라 옛 중국의 수도인 낙양을 사모하여 소임하였다하여 모락산이라 부르고 있다고 전해진다.", + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시 오전동, 내손동", + "MNTN_NM" : "모락산" + }, + "longitude" : 126.98119699999999, + "latitude" : 37.369781099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "모악산은 전라북도 김제시 금산면과 전주시 완산구와 완주군 구이면의 경계를 이루는 산으로 호남정맥에 솟아 있다.예로부터 호남사경의 하나인 '모악춘경'으로 유명한 모악산은 봄이면 온 산을 벚꽃으로 뒤덮는다. 특히, 금산사에 이르는 벚꽃 길은 바람 불어 꽃잎이 휘날리면 마치 눈이 내리는 듯한 환상에 빠질 정도로 화려하다. 그러나 모악산이란 이름에서 알 수 있듯이 '악'자를 품고 있는 이 산의 산행은 결코 만만치 않다. 구이쪽에서 정상을 향해 오르는 길은 특히 험하여 정상을 얼마 남겨두지 않을 무렵에는 웬만큼 산에 단련이 된 사람이라 할지라도 숨이 턱에 차 오른다. 모든 산이 그렇듯 모악산 역시 마지막 고비와의 힘겨운 줄다리기를 치른 후에야 비로소 정상에 오르는 기쁨을 맛볼 수 있다.정상에 오르면 전주시내와 호남의 넓은 들판이 한눈에 들어와 보는 것만으로도 풍요로운 마음이 드는 호남평야의 전경을 마음껏 즐길 수 있다. 김제쪽으로 하산하는 길은 비교적 수월해 쉬엄쉬엄 주위의 경치를 감상하며 내려오면 된다. 비록 800m도 채 안되는 모악산이지만 덩치와는 다르게 구비구비에 다양한 풍경들을 연출해 산행하는 이들의 시선을 즐겁게 한다. 1971년 도립공원으로 지정된 이 산은 미륵신앙과 많은 연관을 가지고 있어 산자락 곳곳에 이와 관련된 흔적이 많이 남아있다.", + "MNTN_HG_VL" : "795", + "MNTN_LOCPLC_REGION_NM" : "전라북도 김제시 금산면ㆍ전주시 완산구ㆍ완주군 구이면", + "MNTN_NM" : "모악산" + }, + "longitude" : 127.0843701, + "latitude" : 35.729759000000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "함평군 해보면 광암리 북쪽을 병풍처럼 에워싸고 있는 산이 모악산이다. 이 산은 아늑한 분위기인 남쪽 산자락에 마치 어머니가 아기를 품안에 안듯이 서해안 최고 고찰 용천사를 숨기고 있는 산이다. 모악산은 단풍나무가 많아 특히 가을 단풍이 천하절경을 이루고 산자락에 일명 꽃무릇이라 불리는 상사화(相思花)가 군락을 이루어 개화기인 9월에는 온 산을 붉게 물들여 보는 이의 가슴마저 불타게 하고 있으며 이는 한국백경 중 일경에 속한다.모악산을 본격적으로 오르고 내리는 등산 기점은 용천사, 그래서 용천사를 둘러보지 않을 수 없습니다. 명산마다 명찰이 있듯이 모악산을 더욱 빛나게 해주고 있는 명찰 용천사는 모악산의 핵(劾)에 해당됩니다.", + "MNTN_HG_VL" : "348", + "MNTN_LOCPLC_REGION_NM" : "전라남도 함평, 영광", + "MNTN_NM" : "모악산" + }, + "longitude" : 127.0843701, + "latitude" : 35.729759000000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "모후산은 섬진7지맥의 한 봉우리로 백아산의 산줄기를 타고 내려와 동복천을 앞에 두고 멈춰선 곳이다. 이 산은 광주 무등산과 순천시 조계산의 그늘에 가려 잘 알려지지 않았으나 유마사, 주암호, 사평폭포 등의 명소가 곳곳에 있고, 항상 푸른 계곡물이 넘쳐 있어 관광객과 등산객에게 각광을 받고 있다. 또한 우리나라 최초의 고려인삼 시배지이기도 하다.모후산은 고려 공민왕 10년(1361) 홍건적이 쳐들어왔을 때 왕과 왕비가 태후를 모시고 이곳까지 피난을 왔던 산이다. 공민왕은 수려한 산세에 반해 가궁을 짓고 환궁할 때까지 1여년 남짓 머물렀다고 한다. 그 뒤 나복산을 어머니의 품속 같은 산이라 하여 모후산으로 바꾸었다.또한 임진왜란 때 이곳 동복현감인 서하당 김성원이 노모를 구하기 위하여 필사적으로 싸우다가 순절하였다고 하여 모후산을 모호산(母護山)이라 부르고 마을 이름도 모호촌이라 하였다.", + "MNTN_HG_VL" : "944", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 남면, 동북면", + "MNTN_NM" : "모후산" + }, + "longitude" : 127.1838229, + "latitude" : 35.033538200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "229", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군", + "MNTN_NM" : "목령산" + }, + "longitude" : 127.4357262, + "latitude" : 36.735338599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "목우산은 강원도 영월군 하동면 내리와 녹전리의 경계를 이루는 산이다. 이 산을 녹전리쪽에서 올려다 보면 마치 황소가 엎드려 있는 것처럼 보여 목우산이라 부르는데 내리쪽에서 보면 정상을 이룬 바위가 상여처럼 보인다고 해서 내리 주민들은 이 산을 생애봉(상여봉의 방언)이라 부르기도 한다.정상은 멋진 기암과 노송들이 그림처럼 조화를 이루고 있다. 정상 바위에 걸터앉아 사위를 휘둘러보는 조망은 가히일품이다. 서쪽 영월 방면으로 패어져 나간 옥동천이 마대산과 운교산 산모퉁이를 감싸며 자취를 감추고, 멀리로는 태화산이 하늘금을 이룬다. 태화산 오른쪽인 북서쪽 운교산 너머로는 망경대산, 예미산, 질운산 산릉이 펼쳐진다. 운교산 아래로는 분지 속 평화로운 녹전리와 함께 녹색 비단을 펼친 듯S자로 굽도는 옥동천이 내려다보인다. 북으로는 단풍산과 매봉산이 멀리 함백산과 함께 시야에 들어온다.동으로는 상동읍 내덕리 방면 깊고 길게 패어진 옥동천 상류 멀리로 태백산 정상이 마주 보인다. 태백산은 영월 청령포에서 죽은 단종의 넋이 어려있는 곳. 그래서 목우산 정상 바위는 옛날 주민들이 태백산을 향해 제사를 올릴 때 제단으로 사용하기도 했다. 남쪽 조망은 등골이 섬뜩해져 허리부터 젖혀진다. 수십 길 절벽 건너 선달산과 어래산이 멀리 백두대간과 함께 마주 보이고, 그 아래로는 내리천의 수십 개 지계곡들이 마치 주름치마처럼 패여 있다.", + "MNTN_HG_VL" : "1066", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면", + "MNTN_NM" : "목우산" + }, + "longitude" : 128.75353079999999, + "latitude" : 37.078150299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가평군청에서 북쪽으로 20km 떨어진 산으로 경기도 가평군과 강원도 춘천시의 경계를 이루고 있다.즐겨 찾는 이가 많지 않아 호젓한 산행으로 그만이다. 능선에는 싸리, 억새숲을 이루고 있어, 전망도 매우 좋다.정상에는 나무하나 없이 밋밋한 좁은 부위의 마루턱을 이루고 있는데 어떤 시설물이라도 있었던 것인지 여기저기 나무기둥 같은게 보인다. 여기서의 전망은 좋아서 북으로 가덕산과 그위로 몽덕산을 잇는 연릉이 일직선으로 뻗어 나간 모습을 볼수 있는가 하면 남으로 계관산을 잇는 역시 한일자로 굽이굽이 이어지는 억새수풀 능선이 그림처럼 아스라이 전개되는 모습이 장관이다.", + "MNTN_HG_VL" : "690", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "몽덕산" + }, + "longitude" : 127.60406380000001, + "latitude" : 37.9545265 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "추풍령 방향으로 향하던 백두대간이 속리산에서 서북 방향으로 가지를 친 지능선에 솟아 있는 묘봉은 문장대(887)와 상학봉(834) 사이에 수려한 암골미를 자랑하는 산이다.속리산(1,087)을 모산(母山)으로 하는 산답게 기암괴석이 많으며, 절골을 비롯한 깨끗한 계곡을 남북으로 가지고 있다. 절골에 자리한 미타사는 용화분지를 안고 있는 사찰로 사담리 공림사와 법주사를 양분하는 자리에 있으며, 일설에는 법주사의 전신인 용화사가 있던 터라고 추정하고 있다.묘봉의 거대한 평암봉은 물론 능선에서도 백악산, 낙영산 등 조망이 뛰어나다. 이 산은 절벽지대가 있는 산으로 산행시 주의를 요하며, 정상에서 서북 방향 능선(상학봉봉쪽)은 등산로가 험하므로 출입을 삼가 하는 것이 좋다.", + "MNTN_HG_VL" : "874", + "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 산외면 신정리, 경상북도 봉화군 석포면", + "MNTN_NM" : "묘봉" + }, + "longitude" : 127.8344726, + "latitude" : 36.569043200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "묘적봉은 충북 단양군과 경북 영풍군의 경계를 이루는 소백산국립공원 최남단에 위치한 산이다. 이 산은 일반적으로 소백산국립공원과 동떨어진 산으로 생각하나 죽령 남쪽 약 10km거리인 묘적봉 일원까지가 소백산 국립공원에 속한다.도솔봉을 포함한 묘적봉 일대에는 취나물군락과 철쭉군락이 주능선에 형성되어 있다. 대부분의 등산객들이 죽령 북쪽의 소백산맥을 주로 이용하기 때문에 아직까지 묘적봉은 잘 알려지지 않은 산이므로 도솔봉과 함께 종주하기도 한다. 정상은 암봉으로 되어 있고 동쪽에는 광장이 있으며 바라보는 죽령과 소백산의 자태는 가희 장관이다.", + "MNTN_HG_VL" : "1148", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군, 경상북도 영주시", + "MNTN_NM" : "묘적봉" + }, + "longitude" : 128.42409409999999, + "latitude" : 36.876874999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", + "MNTN_NM" : "무갑산" + }, + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;갑옷을 두른 무사의 형상gt;서울에서 가까운 경기도 광주시 초월면에 있는 무갑산은 600m가 채 안되는 산으로 숲이 울창한 흙산이다. 또 관산, 검은골 등 아름답고 깊은 골짜기에 맑은 물이 시원하다. 정상 일대 외에는 바위도 그리 없고 대부분 편안한 흙길이며 가끔 산행의 맛을 잃지 않을 만큼 적당히 가파른 산길이 나서기도 하며 곳곳에 암벽도 볼 수 있다. 능선으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다. '무갑산' 이란 이름의 유래에 관하여 두 가지 설이 있다. '임진왜란 때에 왜병들에게 항복하기를 거부한 무인들이 은둔한 데서 무갑산이라 했다'는 이야기와 '산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다' 는 이야기다. 무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다. 마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다고 한다.", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", + "MNTN_NM" : "무갑산" + }, + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면에 솟아있는 무갑산은 정상으로 오르는 계곡길이 아름답기로 소문난 산이다. 또한 서울 근교에 있으면서도 오지에 온 듯한 느낌이 들게 하는 곳이다. 무갑산은 능선상으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다.숲이 울창하며 골자기의 개울이 아름답고 물이 맑으며 시원한 산, 볕이 내리쬐는암릉과 기암괴봉보다 숲속 그늘의 흙길이 편안하고 가끔 알맞게 가파른 산, 거기다가 산을 내려와 시원한 개울 가에서 물을 퍼다가 등멱이라도 할 수 있는 산이다.'무갑산' 이란 이름은 산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다.마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다. 광주는 자기의 명산지로 조선시대에는 훌륭한 백자를 생산했다. 이처럼 광주고을이 도자기로 유명했던 것도 무갑산에서 많은 땔감을 쉽게 댈 수 있었기 때문이었다 한다.", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월읍", + "MNTN_NM" : "무갑산" + }, + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "광주시가지에서 동쪽으로 불과 10km 거리에 자리하고 있는 무등산은 도립공원으로 지정되어 있다.산의 형세가 험하지 않고 대부분이 흙으로 이루어져 있어 누구나 쉽게 오를 수 있으며, 곳곳에 맑은 물이 흐르고 있다. 특히 산위에는 서석대, 규봉, 입석대등의 웅장한 바위들이 있으며 산기슭과 중턱에는 약사암, 증심사, 원효사 등의 이름난 절들이 자리잡고 있다. 1972년 도립공원으로 지정되었으며 산 아래에는 각종 놀이 및 편의시설이 들어서 있다.", + "MNTN_HG_VL" : "1187", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구, 전라남도 담양군 남면ㆍ화순군 이서면", + "MNTN_NM" : "무등산" + }, + "longitude" : 126.9887555, + "latitude" : 35.134134000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "바다와 접한 고성군의 산역이 그렇듯이 해발 600m 미만의 산들이 부드러운 산줄기를 서로 이어가면서 나름대로의 산역을 만들고 잇다. 무량산은 고성읍 북서쪽에 위치하면서 대가면의 중심을 이루는 산으로 양화마을을 병풍처럼 둘러싸는 형세로 동서로 길게 뻗어 있다. 산세는 그저 평범한 내륙산의 전형이지만 주릉을 따라 드문드문 자리잡은 암봉이 그런대로 변화를 주고 있다. 남릉에 봉화대가 아직도 있고, 특히 주릉에 올라서면서 숨어있는 정상을 찾는 재미도 있다. 헤아릴 수 없다는 뜻의 산명도 아마 쉽게 정상을 가름할 수 없는 데서 온 것이 아닌가 싶다.", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 고성읍 무량리", + "MNTN_NM" : "무량산" + }, + "longitude" : 128.26166670000001, + "latitude" : 35.021666699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 김해시 진례면과 한림면 위치한 무릉 산은 남북으로 뻗어있는 산으로 낙남정맥의 한 줄길인 황새봉과 이어져 있다. 비교적 덜 알려져 있어 식생과 등산로의 상태는 좋은 편이나 탐방객이 적은 관계로 관목이 우겨져 있고 등로도 희미해 탐방시 주의를 요한다.", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 한림면, 진례면", + "MNTN_NM" : "무릉산" + }, + "longitude" : 128.56579629999999, + "latitude" : 35.328721999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무릉산은 칠북면의 중심산역으로 작대산의 북쪽에 위치하면서 둥그스럼한 산릉에 부드러움을 더하고 있다. 낙동강에 산자락을 내밀고 있는 북릉은 북면 온천이 있는 마금산역에 손을 내밀면서 느긋하게 산세를 일으키고 있다.", + "MNTN_HG_VL" : "556", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 북면, 함안군 칠북면", + "MNTN_NM" : "무릉산" + }, + "longitude" : 128.56579629999999, + "latitude" : 35.328721999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무성산(614m)은 충남 공주시 사곡면 정안면, 우성면 경계를 이루는 산이다. 공주시에서 북서쪽으로 마치 한 마리 누에가 기어가는 듯이 보이는 산이다. 속리산에서 북서쪽으로 갈라진 한남금북정맥은 경기도 안성 동쪽 칠현산에서 두 가닥으로 갈라진다.무성산은 서쪽 명가천을 사이에 두고 마곡사를 내려다보고 있다. 그러나 마곡사 명성이 대단했던 까닭에 아직까지 무성산에 훌륭한 등산코스가 숨어 있다는 것을 아는 이는 많지 않다.홍길동이 쌓았다는 전설을 간직하고 있는 성터 석탑지대에서 휘둘러보는 파노라마는 막힘이 없다. 북쪽으로는 국사봉에서 차령을 지나 광덕산 방면으로 이어지는 금북정맥이 하늘금을 이룬다. 동쪽으로는 정안천이 흐르는 화봉리 분지 너머로 북쪽 멀리 금북정맥 국사봉으로부터 가지쳐 나온 높고 낮은 산릉들이 일렁이는 파도인 듯 시야에 와닿는다.남동쪽으로는 공주시 뒤로 계룡산이 가물거리고 백마강이 흘러가는 방향인 남소쪽 멀리로는 청양 칠갑산이 넘실대는 산릉 위로 고개를 내밀고 있다. 서쪽 조망도 일품이다. 예부터 전해지는 십승지의 한 곳인 유구를 감싸고 칠갑산으로 달아나는 금북정맥이 하늘금을 이루고, 금북정맥 아래로는 운암리 마곡사를 감싸고 있는 태화산(614m)이 아늑한 분위기로 시야에 들어온다.", + "MNTN_HG_VL" : "614", + "MNTN_LOCPLC_REGION_NM" : "충남 공주시 우성면 한천리", + "MNTN_NM" : "무성산" + }, + "longitude" : 127.07295019999999, + "latitude" : 36.562825400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고성읍에서 사천으로 가는 국도상에서 왼쪽으로 바라보면 KBS 송신용 안테나가 서있는 산봉이 눈에 띈다. 이 산이 마을 사람들은 청량산으로 부르기도 하는 무이산으로 주봉이 국도에 인접해 있다. 언뜻 보기에는 흔히 볼 수 있는 산으로 생각되나 산으로 접근하면 분위기가 달라진다.", + "MNTN_HG_VL" : "549", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 상리면", + "MNTN_NM" : "무이산" + }, + "longitude" : 128.2110145, + "latitude" : 34.979779600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무제봉은 충북 진천군 이월면과 백곡면의 경계를 이루는 곳에 위치하고 있다. 무제봉은 산세는 험해 보이지만 등산로가 잘돼있어 오르기가 수월하다. 무제봉의 남동쪽으로는 옥녀봉이 능선으로 연결되어 있다.능선에 오르면 소나무가 우거져 있는 육산이다. 이 옥녀봉 동쪽 아래로는 노원리의 궁동마을이 있는데 이 마을은 중국의 원나라 홀필열 황제의 황후 기씨가 탄생한 곳이다. 지금도 동리 뒤에는 황제가 기씨 황후를 위하여 지어주었다는 궁동이라는 궁궐터가 남아있다. 이곳 무제봉 인근은 어댕이,신계리 아래세월 등 듣기에도 생소한 단어들의 지명 이름이 특이하다.", + "MNTN_HG_VL" : "573", + "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 이월면 선계리", + "MNTN_NM" : "무제봉" + }, + "longitude" : 127.68741199999999, + "latitude" : 37.166568599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무척산은 신어산, 불모산과 더불어 김해의 3대 명산으로 꼽힌다. 그다지 높지 않고 산줄기가 시원스럽지도 않지만 산천으로 둘러싸인 경치 좋은 뜻의 생림동천(生林洞天)이란 말을 만들어 낼 정도로 아름다운 산이다. 또한 기묘한 바위들이 자리 잡고 있어 그 멋스러움이 더욱 특출나 보인다. 특히 낙동강과 이어져 있어 굽이쳐 흐르는 낙동강의 조망이 탁월하며 산허리 부분에 괴상하게 생긴 암봉이 많아 경치가 수려하다.무척산은 산 이름도 다양하다. 무척산 외에도 무착산, 무쌍산, 식산으로도 불린다. 식산은 북풍을 막아주고 낙동강 물줄기를 끌어들여 들을 기름지게 해 김해 고을을 먹여 살리는 산이라 하여 부르는 이름이다. 또 산의 형세가 밥상을 받는 모양과 같다고 해 식산, 식산 대신 밥상이라고도 부른다.다양하게 불려지는 이름뿐만 아니라 무척산은 많은 설화를 간직하고 있는 산이다. 이 산의 정상 바로 밑에 천지못이 있는데, 이 연못은 김수로 왕릉의 물줄기를 잡기 위해 설치됐다는 전설을 갖고 있다. 또한 고찰 모은암은 김수로왕이 어머니의 은혜를 갚기 위해 지었다고 전해진다. 가락국의 불교를 중흥시키기 위해 창건되었다는 백운암도 유명하다.하늘벽, 가야벽, 탕건바위, 장군봉 등 개척된 암장이 여럿 있으며 부산, 경남 클라이머에게 인기가 높다.", + "MNTN_HG_VL" : "702", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 생림면, 상동면", + "MNTN_NM" : "무척산" + }, + "longitude" : 128.87060070000001, + "latitude" : 35.340642799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "학이 춤을 추는 듯한 형상의 바위를 정상에 가지고 있어 무학봉이라 불리는 이 산은 한북정맥 주능선의 위치한 백운산(904)에서 동남 방향으로 가지를 친 지능선에 자리잡고 있으며, 수려한 산세와 백옥 같은 바위 위에 맑은 계류가 흘러 여름철 산행지로 적합하다. 백운산 유명세에 가려 찾는 이가 많치 않은 만큼 자연 그대로의 모습을 가지고 있어 상큼함을 느낄수 있는 산이다.겨울철 설경으로 유명한 산은 아무래도 설악산, 한라산, 치악산, 소백산 등을 으뜸으로 치는 것이 상례다. 그러나 수도권에서 그리 멀지 않은 경기도 포천군 이동면 도평리에 위치한 백운산은 38선 이북으로 10km 나 더 북쪽에 위치하며 위도상으로는 설악산과 거의 같아 겨울철 설경이 뛰어나고 산세도 아기자기하다.", + "MNTN_HG_VL" : "832", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면, 경기도 포천시", + "MNTN_NM" : "무학봉" + }, + "longitude" : 127.0250484, + "latitude" : 37.5628417 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 끝자락인 지리산 삼신봉에서 시작되는 낙남정맥의 상좌격인 무학봉은 마산의 진산(鎭山)으로 마산만과 진해만을 굽어보며 바다를 향해 학이 날개를 펼친 듯 아름다운 형상을 하고 있다.명산이 갖추어야 할 면모를 두루 갖추고 있는 이 산은 바닷가에 위치한 산답게 시원한 조망을 만끽할 수 있으며 주능선 등로엔 억새밭과 암봉 전망대가 있어 편안한 느낌을 준다.대곡산 아래쪽에는 `만날고개'가 있는데 이곳은 가정형편이 어려워 댓가를 받고 시집 보낸 딸을 그리워하던 어미와 그 딸이 그리움을 참지 못해 고갯마루에 올랐다가 우연히 만났다는 애틋한 전설이 전해지는 고개다. 무학산의 옛이름은 풍장산이었는데 신라말 최치원이 이곳에 머물면서 산세를 보니 학이 나는 형세같다하여 무학산이라 불리우게 되었다한다.", + "MNTN_HG_VL" : "761", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 교방동", + "MNTN_NM" : "무학산" + }, + "longitude" : 128.5357745, + "latitude" : 35.211068699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수성구(壽城區)는 신라시대에 위화군(#21919;火郡, 上村昌郡이라고도함)인데 경덕왕이 수창군(壽昌郡)이라하였다.고려초에 수성군(壽城郡)으로 바뀌어 현종 9년(1018)에 수성군사(壽城郡司)로 경주에 속했다가 공양왕 2년(1390)에 해안현(解顔縣, 慶州任內에 속했는데 그 시대는 미상이다)을 겸하여 감무(監務)를 두었다.조선 태조3년(1394)에 대구겸관으로 삼았다가 태종 14년(1414)에 대구에 합속(合屬)시켰으며, 1419년에 수성현사(壽城縣司)로수성구 전체 면적의 76.6%가 녹지지역 전지역 공원화로 숲에 덮힌 아름다운 도시경관 창출(녹지지역 76.6%)공항, 역, 터미널 근접으로 교통 편리함 수성구지형]비슬산 주봉에서 동쪽 경산쪽으로 이어지는 屛風山있는데 좌측은 法伊山 우측은 聖岩山이다대구광역시 범물동 욱수동 대흥동 삼덕동 행정구역 大德마을 위치한 大德山(600)으로 이름붙여저 부르고 있다大德山 맞은편 案에 있다고 하여 봉우리가 案山(470.5)이다.기암으로 이루어지고 안산 정상에는 거북상이#52287;는이에게 속삭임의 경관은알려주고 있다.침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고 수백종의 자생식물이자라며 사계 꽃과 단풍들이 수성구 두리봉유래]만촌동 태초에 세상이 전부 물에 잠기었을 때 봉우리에 두루미 한 마리가 앉을 정도만 남았다 하여 두리봉이라 불리다가 두봉골로 바꿔 불렀다 한다. 하지만 이 지명은 상당히 윤색된 설화를 지닌 것으로 보여진다. 그리고 처음에 그러한 설화를 지녔더라도 두봉골로 이름이 바뀌고 부터는 그 설화를 잃어버리고 단순히 두개의 봉우리 사이에 있는 골짜기란 의미로 전락해 버렸다. 현재 오성고등학교가 위치한 지점에서부터 대구산업정보대 서편을 가리키는데, 두봉골(무학산유래]지산동 현재 학산재(鶴山齋)가 있는 곳의 뒷산을 가리키며 학이 날아오는 기세와 같이 생겼다는 설이 있고, 학이 날아와 즐겨 앉았던 산이라 그렇게 부른다는 설이 있다.조일골유래]지산동 골짜기가 동남쪽으로 틔여 있어 아침에 해가 뜨면 가장 먼저 따뜻하게 비치는 곳이라 하여 조일골 이라고 부른다.", + "MNTN_HG_VL" : "200", + "MNTN_LOCPLC_REGION_NM" : "대구 수성구 황금동", + "MNTN_NM" : "무학산" + }, + "longitude" : 128.5357745, + "latitude" : 35.211068699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "설악산 용아능선의 축소판 형상이라 하여 `작은 용아릉' 이라 불리는 문덕봉은 다섯 개에 암봉을 가진 남원의 화산 (火山)이다. 전북에서는 암릉 산행코스로 단연 돋보이는 산이며, 인위적으로 설치한 안전시설이 없어 자연 그대로에 암릉 산행을 즐길 수 있는 산이다.험난한 코스가 있는 산으로 암벽등반에 경험이 없거나, 담력이 약한 사람은 경험자를 동행(同行) 하는 것이 필요하며, 우천시는 산행을 피하는 것이 좋다. 문덕봉은 아기자기한 산행 묘미가 있는 산으로, 산행 내내 지리산 산줄기와 섬진강 강줄기를 바라보며 걷는 재미는 다른 산에서 느낄 수 없는 독특한 즐거움이다. 또한 명당 자리로 알려져 있어 기우제를 지내는 곳으로도 유명하다.정상에 서면 동북쪽으로 남원시가지는 한눈에 내려다 보이고 섬진강으로 합류되는 남원 요천이 광활한 금지평야의 젖줄이 되고 있음을 보여 주고 있다. 석양의 햇살에 눈이 부신 서쪽의 옥정호와 운암댐에서 흘러내리는 섬진강 물줄기 너머로 저 멀리 순창의 광덕산과 담양의 추월산이 어렴풋하게 보인다.", + "MNTN_HG_VL" : "598", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 금지면, 대강면, 주생면", + "MNTN_NM" : "문덕봉" + }, + "longitude" : 127.5351143, + "latitude" : 35.377140400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "인천 앞 바다가 조망되는 경기의 명산 용문산(1157) 정상에서 동북쪽으로 3km 거리에 위치한 문례봉은 용문봉(947)과 용조봉(635), 중원산(800) 사이로 용계골과 조계골을 거느리고 있는 산이다.다른 산에 비해 정상으로의 접근 거리가 길어 잘 알려지지 않은 산이다. 용계골과 조계골은 용문산 주변 계곡 중에서 뛰어난 계곡미로 인해 `용계조계(龍溪鳥溪)'로 오래 전부터 많이 알려진 곳이며, 용계골은 군사시설이 자리하고 있어 출입이 통제된 지역이다. 전반적인 산세는 지능선 쪽으로 암릉과 절벽이 있고, 정상부는 육산 형태를 이루고 있으므로 산행시 주의를 해야 한다.폭산 또는 천사봉이라고도 한다.", + "MNTN_HG_VL" : "992", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", + "MNTN_NM" : "문례봉" + }, + "longitude" : 127.603212, + "latitude" : 37.6410093 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문복대는 경북 예천군과 문경시, 충북 단양군의 경계지점에 위치한 저수재와 벌재사이에 있는 백두대간상의 산이다. 문복대는 이 산에서 한줄기가 북으로 뻗어 수리봉.신선봉과 단양팔경 중 유명한 상.중.하선암이 있는 도락산을 두고 있다. 이 산 밑에 배나무골,호박골,세작골,성골을 두고 있으며, 이 골짜기들이 모두 동로면 석항리를 이루고 있다. 석항리를 돌목이라고도 하는데 아직까지 남아있는 아름다운 우리의 이름이다.백두대간이 죽령, 도솔봉, 향적봉, 저수령을 지나서 문경시 관내로 들어오면서 처음으로 큰산을 두고 있는데 바로 운봉산이다. 석항리 사람들은 ‘문복대’라고 부르고 있으나 산이름에 ‘대’가 붙어 있어 이상하게 생각하고 알아본 결과 옛 이름이 운봉산, 운봉재라 하였다 한다. 운봉재라고 부르는 것은 문복대의 벌재 방향으로 잘록이 부분을 통해 석항리 주민들이 산 너머의 마을로 오가던 길이 있다는 데서 그렇게 불렀다고 한다.정상에서 바라보는 경천호 주변의 붕어입을 한 천주산과 공덕산이 장관이다. 조망지로서 최적의 장소다.", + "MNTN_HG_VL" : "1074", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 석항리", + "MNTN_NM" : "문복대" + }, + "longitude" : 128.34853440000001, + "latitude" : 36.804896200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1013", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "문복산" + }, + "longitude" : 129.03833330000001, + "latitude" : 35.679166700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 문경 동로면에 위치한 운봉산은 백두대간이 죽령, 도솔봉, 향적봉, 저수령을 지나서 문경시 관내로 들어오면서 솟구친 산이다. `문봉재'라고 많이 알려져 있으나 옛이름은 운봉산이다. 1\/5,000지도에는 문봉재라고 되어 있다. 이 문봉재는 저수령과 벌재 사이에 있는데 이 산에서 한줄기가 북으로 뻗어 수리봉·신선봉과 유명한 단양팔경 중 상·중·하 선암이 있는 도락산을 두고 있다.산새가 아름답고 골짜기 마다 운치가 있어 산행의 즐거움을 더한다. 이 산 밑에 배나무골, 호박골, 세작골, 성골을 두고 있으며 이 골짜기들이 모두 동로면 석항리를 이루고 있다. 석항을 돌목이라고 하는데 아직까지 남아있는 예쁜 우리마을 이름이다. 오늘도 돌목 뒷산인 운봉산은 봄, 여름, 가을 돌목사람들을 지키며 묵묵히 있다.", + "MNTN_HG_VL" : "1074", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면", + "MNTN_NM" : "문봉재 (운봉산)" + }, + "longitude" : 128.507882, + "latitude" : 38.2876695 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간이 동로면 벌재를 지나 대미산을 빚어놓고 대미산 정상에 못 미친 1,045m고지에서 북으로 한줄기 뻗어 문수봉을 솟아 놓았다. 충북 제천시 덕산면과 경북 문경시 동로면의 경계를 이룬 문수봉은 월악산 국립공원에 속해 있으며 육산으로 이루어져 있어 등반하기 수월한 산이다. 폭포, 탕, 소 등이 사방 곳곳에 흩어져 있어 여름철 가족 피서지로 적합한 이 산의 자랑은 단연 용하구곡이다. 용하구곡이란 이름 자체가 `여름을 갖고 논다'는 뜻에서 비롯된만큼 더위를 씻어내는 야영지로서의 조건을 다 갖추고 있다.옛날 시인 묵객들이 시문을 겨뤘던 청벽대에서부터 선미대, 가학정, 석운대, 수룡대, 우화굴,세심폭, 활래담 마지막 9경인 강서대에 이르기까지 편편한 반석과 깨끗한 물줄기가 절경을 이룬다. 능선 안부에서 곰취, 취나물, 신선초 등 무공해 산나물을 채취하는 재미도 솔솔하며 봄에는 능선안부께에 철쭉나무 군락이 터널을 이루어 산행의 묘미를 더해준다.", + "MNTN_HG_VL" : "1517", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 경상북도 문경시", + "MNTN_NM" : "문수봉" + }, + "longitude" : 126.9717141, + "latitude" : 37.632514 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간 주능선에 위치한 문수봉은 태백산 천제단을 마주하고 있으며 풍수 지리적으로 영험한 기(氣)가 있다 하여 무속 신앙인들과 이와 유사한 사람들의 기도처가 많은 산이다.산 정상부가 돌무더기로 되어 있어 이색적인 느낌을 주는 산이고 정상에는 태고때부터 하늘에 제사를 지내던 천제단이 있다. 삼국사기에 왕이 친히 천제를 올렸다는 기록이 있고 세종실록지리지에는 신라에서 오악 가운데 태백산을 북악으로 받들어 봄,가을에 제사를 지냈다고 한다. 천제단을 중심으로 북쪽지점에 태백산의 주봉인 가장 높은 장군봉, 남동쪽으로 능선을 타고 가면 멀리 수만개의 바위로 이루어진 문수봉이 있다. 서울에서 내려온 한 처사가 쌓고 있는 조그마한 돌탑이 있다.신라 진평왕때 자장율사가 이 봉우리에 문수보살을 모시기 위해 망경사를 지었다고 하며, 그 외 사찰로도 백단사, 유일사, 만덕사, 청원사등이 있다.태백산은 겨울의 눈과 설화가 환상적이다. 주목과 어우러진 설화는 동화속의 설경이다. 적설량이 많고 바람이 세차기로 유명하여 눈이 잘 녹지 않고 쌓인다. 세차게 몰아치는 바람이 눈을 달려 설화를 만든다.", + "MNTN_HG_VL" : "1162", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "문수봉" + }, + "longitude" : 126.9717141, + "latitude" : 37.632514 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문수산은 일명 청량산이라고도 하는데 이 산을 가리켜 신라 문수 보살이 산세가 청량하고 아름다워 여기에 살았으므로 처음에는 청량산으로 부르다가 다시 문수산으로 바뀌었다. 청량산은 중국의 산서성 오대현에 있는 오대산의 별명으로 5봉이 솟았고 꼭대기에는 나무가 없어 흙을 모아 놓은 대처럼 생겼고 산의 특성상 여름에 덥지 않으므로 청량산이라 했다. 지금 문수사 절 현판에 청량산으로 표기되어 있다.이 산 정상 넓은 초원에는 중계탑이 있고 서쪽의 신불산 능선과 남쪽의 천성산,대운산,동쪽의 울산시가지와 동해까지 막힘없이 조망할 수 있어서 좋다. 능선길에는 이정표가 세워져 있어서 좋고 곳곳에 쉼터가 있으며 정상 남쪽에는 유명한 문수사가 있는데 매우 아담하게 단장되어 있다. 그리고 가을에는 문수사 주변의 단풍이 절경이다.", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "341", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 산동면 인덕리", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산 좋고 물 좋기로 소문난 봉화에는 청량산, 청옥산, 문수산 등 명산이 여럿이다. 또 산마다 명수로 알려진 약수터가 있어 찾는 발걸음이 끊이질 않는다. 선달산 아래 오전약수와 옥돌봉 아래 주실령 남동쪽의 문수산 두내약수, 그리고 문수산 자락 끄트머리의 다덕약수 등이 유명하다.문수산 산행들머리로는 개단1리 월계마을이 애용된다. 봉화에서 버스가 다녀 접근성이 좋고 울창한 춘양목 숲에 둘러싸인 축서사가 있기 때문이다. 봉화를 대표할 만한 절집인 축서사에는 신라시대의 작품인 석불좌상(보물 995호)과 고려시대의 석등이 있다.축서사 북쪽의 잣나무 군락지를 따라 오르면 1시간 30분쯤 걸리고 좀 더 강도 높은 산행을 하려면 동쪽의 계곡을 따라 오르면 된다.정상인 서봉에 서면 산 천지인 봉화의 멋진 하늘금을 제대로 조망할 수 있다.", + "MNTN_HG_VL" : "1205", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 춘양면, 봉성면, 물야면", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 청량면 삼동면, 범서읍", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "김포가도를 달려 월곶면에 이르면 김포평야의 자그마한 야산들 사이로 문수산이 우뚝 서있고 강화도를 갈 때 쉽게 지나치는 산이다. 강화도를 가다가 보면 강화대교를 건너기 직전 우측으로 얼핏보기에도 대단해보이는 산성을 볼 수 있는데 이 것이 바로 문수산성이다.문수산성은 문수산 정상을 중심에 두고\"\"⊃\"\"자 모양으로 이루어진 총연장 6km의 산성으로 산성내에 문수사와 문수산 산림욕장이 위치해있다. 문수산은 낮지만 인천광역시 앞바다에 떠있는 월미도, 서울특별시 삼각산,개성 송악산까지 보이는 서부전선의 전방산이다. 문수산에서 가까운 김포군 대곶면 약암리에 약암온천이 있다.약암온천은 중탄산천으로 특히 피부질환 및 피부미용에 효과가 있다.또한 미네랄천탕과 식염천탕이 함께 있어 양쪽탕을 번갈아가며 온천욕을 할 수 있는 것도 특징이다.", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "경기도 김포시 월곶면", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉화는 산 좋고 물 좋기로 소문난 곳이다. 청량산, 청옥산, 문수산이 대표적인 봉화의 산이며 선달산 아래 오전약수, 옥돌봉 아래 주실령 남동쪽 문수산 두내약수 그리고 문수산 자락 끄트머리의 다덕약수가 봉화의 약수들이다. 깊은 산, 깊은 골 천혜의 자연 속 깊숙한 곳에 자리했다.정상부에는 참나무 군락지가 형성되어 있고 발길이 뜸한 산으로 늦가을 낙옆에 빠지는 만추산행의 멋을 만끽할수 있으며 축서사에서 오르는 등산로는 경사가 급하며 주실령에서 진입할 경우 능선을 따라서 산행을 즐길수 있다. 정상은 삼각점과 철제구조물이 있어 그 모습이 초라하지만 봉화군의 중심에 위치하고 있으며 앞을 가로막을 산들이 없어 조망은 좋다.문수산은 시선이 닿는 저끝 어디하나 트인곳 없이 산마루 금으로 둘러싸여 커다란 바루속에 우뚝 솟은 형세다. 정상에서 맑은날에는 태백산, 소백산, 청량산, 일월산이 멀리보이며 특히, 두내 약수탕에서 오르는 등산로 입구의 서벽임도에는 하늘을 찌를 듯 곧게 자란 붉은 줄기의 춘양목 군락지가 임도를 따라 형성되어 있어 가족나들이 산책로로 인기가 있다.", + "MNTN_HG_VL" : "1205", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면, 춘양면, 봉성면", + "MNTN_NM" : "문수산" + }, + "longitude" : 126.53889650000001, + "latitude" : 37.739061399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간에서 갈라진 산줄기가 경기도에 이르러 화악산과 명지산 등 고산을 일구고, 운악산과 천마산으로 이어져 북한강가에 이르러 빚어놓은 산이 문안산이다.산은 낮으나 북한강가에 자리잡고 있어 경치가 뛰어나고 험한 곳이 없어 어린아이를 동반한 가족 산행지로 적합한 곳이다. 봄에는 능선길의 진달래가 볼만하고 하산길엔 북한강이 한눈에 들어온다 .문안산이라는 이름의 유래는 날씨가 좋은 날 정상에 오르면 서울의 문안까지 환히 보여서 붙은 이름이라고 한다.", + "MNTN_HG_VL" : "536", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 화도읍 금남리", + "MNTN_NM" : "문안산" + }, + "longitude" : 127.329767, + "latitude" : 37.621951000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문암산은 정북녘에 자리한 방태산을 위시해 오대산, 계방산, 회령봉, 응봉산 등의 기라성 같은 명산이 한 바퀴 원을 그리며 둘러싸고 있다. ‘돌꽃산(石化山)’이라는 별명에 어울리는 아름다운 바위경관과 듬직한 산세가 멋지고 유명한 내린천의 상류와 자운천, 문암천이 동서녘 자락을 스치며 지난다.철따라 온갖 들꽃들이 앞다투어 피어나는 남북으로 길게 뻗은 주능선을 걷노라면 주변의 내로라하는 산들과 어울린 풍경에 콧노래가 절로 나오는 멋진 산이다. 지역 사람들은 문암산을 ‘석화산’이라 부른다. 이름처럼 푸른 숲 사이로 툭툭 삐져나온 바위전망대가 많아 저마다 조망이 시원스럽다.", + "MNTN_HG_VL" : "1146", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "문암산" + }, + "longitude" : 128.37694440000001, + "latitude" : 37.782499999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "인천 남구 문학동에 있는 높이 217미터의 문학산은 학산이나 남산이라고도 불린다. 지금은 들어볼 수 없지만 예전에는 산봉우리가 마치 사람이 배꼽을 내놓고 누워있는 모양을 하고 있어 배꼽산이라고 했다. 하지만 현재는 그 형세가 많이 달라졌을 뿐만 아니라 기억하고 있는 이 조차 드물어 문학산이라고 부른다.문학산 봉우리와 노적봉 사이에는 관교동에서 청학동으로 넘어가는 긴 고갯길이 있는데 이 길을 삼호현, 삼해주현, 사모현 등으로 부른다. 백제 근초고왕 때(372년) 중국으로 가는 바닷길 한나루로 가는 길목으로 1600년 전 고개를 넘으면서 전송나온 사람들과 이별하던 곳이라고 한다. 삼호현은 이곳까지 따라온 가족이나 친지들이 능허대 쪽으로 멀어져 가는 사신들이 무사히 잘 다녀오기를 빌면서 크게 세 번 불렀다 해 생긴 이름이다.문학산 정상은 산의 동남부에 위치한 군사지역이며, 산지의 서쪽 봉우리는 연경산으로 정상부에 ‘연경정’이 있다. 정상부 및 남서쪽은 군사지역으로 일반인의 출입이 통제되고 있다. 산의 북쪽은 제2경인고속도로 관통, 동쪽은 문학월드컵경기장이 있다.", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 남구 문학동", + "MNTN_NM" : "문학산" + }, + "longitude" : 126.67919689999999, + "latitude" : 37.431407100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산 이름에서부터 대단한 품위가 느껴지는 산, 문형산. 문형(文衡)이란 고려나 조선 때에 대제학(大提學)의 별칭으로, 학자들에게 가장 품격 높은 벼슬이다. 정2품에 해당하는 관직이기는 했으나 정승 부럽지 않은 벼슬이었고 한번 오르면 죽을 때까지 명예가 지켜지는 자리였다. ‘삼왕비불여일정승(三王妃不如一政丞)이며 삼정승불여일선생(三政丞不如一先生)’이라는 말 또한 대제학을 기리는 것이었으니 문형은 대단한 명예가 따르는 자리였다.정상은 너름 공터다. 운동시설이 있고 긴 의자가 두 개 놓여 있다. 북쪽으로만 조망이 좋다. 멀리 분당시가지와 영장(414.2m)이 뚜렷하다. 뒤로는 서울이 보인다.정상 표석 앞면에는 ‘文衡山 497m’ 뒷면에는 ‘1995년 광주문화원에서 주관하고 동원산악회에서 건립한 이 표석은 1998년에 훼손되어 오포면 이장협의회에서 복원하였음’이라 적혔다. 옆면에는 ‘1999년 1월 1일 오포면 이장협의회 증’이라는 글씨가 음각되었다.문형산의 본디 이름은 문수산이라는 설이 있다. 문수보살을 모신 산이라는 뜻인 듯하다. 또 다른 이름으로 신증동국여지승람에 ‘문현산’이 보인다. 오늘날 산 이름은 고려말 대제학을 지낸 이가 이곳에 들러 쉬면서 경치가 아름다워 ‘문형산’이라 하자 마을 이름까지 덩달아 ‘문형리’가 되었다는 것이다. 장상표석에 기록된 내용이다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 오포읍", + "MNTN_NM" : "문형산" + }, + "longitude" : 127.1875, + "latitude" : 37.369166700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", + "MNTN_NM" : "미궐산" + }, + "longitude" : 126.9933333, + "latitude" : 36.440833300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미남봉은 산 형상이 잘생긴 남자의 옆얼굴처럼 생겼다고 해서 붙여진 이름이며, 속리산국립공원권에 속하는 산으로 상학봉(834)과 금단산(767)을 마주하고 있는 산이다. 속리산국립공원은 다른 곳에 비해 계곡의 규모가 크고 수량이 많은 것이 특징이다.묘봉(874)과 상학봉은 돌출 된 기암괴석으로 산세가 이루어져 있는데 반해 이산은 정상부만 100m 정도에 거암(巨岩)이 돌출해 있는 것을 제외하고는 거의 육산으로 느낄 만큼 돌출바위가 없이 감추어진 산세를 가지고 있고 수려한 비경을 연출해 말 그대로 속세를 떠난 산 (俗離山) 의 모습을 보여준다.정상이 돌출바위 지대로 조망이 시원스레 열려 있으며, 백두대간의 연봉과 문장대, 상학봉 일대가 그림처럼 아름답게 보이는 산이다. 곳곳에 숨겨진 바위지대가 있으므로 산행시 방심해서는 안 되는 산이다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 산외면, 경상북도 상주시 화북면", + "MNTN_NM" : "미남봉" + }, + "longitude" : 129.07159820000001, + "latitude" : 35.206026399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미녀봉의 본 이름은 문재산(文載山)이다. 그러나 미인이 머리를 풀고 누워있는 형상이라 하여 미녀봉(美女峰)으로 널리 불린다. 미녀봉에는 두 가지 전설이 전한다. 옛날 바다였던 이곳에 장군이 탄 나룻배가 표류하자 옥황상제가 딸을 지상으로 보내 구하고자 했다. 장군은 딸과 사랑하게 되었고 그런 딸을 보고 노한 옥황상제는 너희 둘은 영원히 산으로 누워 있으라는 형벌을 내렸다고 한다. 또 다른 전설은 예쁜oacute;녀가 어머니 병을 고치기 위해 미녀봉에만 있는 약초를 캐려 했는데 뱀에 물려 죽자 불쌍히 여긴 산신이 죽은oacute;녀의 모습대로 만든 산이 미녀봉이라 한다. 88고속도로 인터uuml;인지에서 바라보는 미녀봉은 참으로 감탄스럽기 그지없다. 잘 다듬어진 이마, 세련된 화장술로 그려낸 듯한 눈썹, 오똑한 코, 힘겨워 헤 벌리고 있는 입, 봉긋 달덩이oacute;럼 솟아오른 젖가슴, 아이를 잉태한 듯한 볼록한 배 등 산봉우리들이 모여 하나의 아름답고 고운 여인 형상을 빚고 있다. 미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀봉을 눈부시게 만든다.", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가조면, 합천군 봉산면", + "MNTN_NM" : "미녀봉(숙성산)" + }, + "longitude" : 128.0521684, + "latitude" : 35.682698299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "88고속도로를 타고 가조인터체인지 부군에서 동남쪽으로 쳐다보면 긴 머리카락을 늘 어 떠리고 반듯이 누워있는 미녀모양의 산을 발견하고 누구나 깜짝 놀란다. 미녀봉이라 알려졌지만 머리 가슴 배의 뚜렷한 봉우리가 모여 이룬 산이라 미녀산이 옳다. 정상의 위치와 높이도 893M봉이 아니라 동쪽의 930M가 더 합당하다. 황강의 지류인 가천에 긴 머리칼을 풀어 담그고 단아한 이마, 까만 눈썹, 오똑한 콧날, 헤 벌린 입, 또렷한 턱과 목을 거쳐 불룩 솟은 젖가슴 아래로 아기를 잉태한 듯 불룩한 배, 이런 모습은 산봉들이 어울려 빚어낸 자연의 걸작품으로 손색이 없다.미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아 오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀산을 눈부시게 만든다. 미녀산속에 널려있는 선바위, 음양석등 자연숭배사상이 엿보이고 산 전체가 하나의 여체로 만들어져 성적 호기심을 자아내게 만든 것은 거창 미녀산이 우리나라에서 유일하다.전해오는 전설이 두 가지 있다. 옛날에 이곳은 바다였는데, 어느 장군이 나룻배를 탄 채 표류하고 있었다. 이를 본 옥황상제가 딸을 보내 구하라고 했으나, 딸을 본 장군은 한눈에 반해 서로 사랑하게 되었다. 이에 옥황상제는 두 사람을 산으로 만들어 영원히 누워 있는 형벌을 내렸는데, 바로 미녀산과 장군봉이라는 전설이다.또 하나는 병으로 위독한 어머니의 약을 구하러 이 산에만 있다는 약초를 캐러 올랐다가 뱀에 물려 죽자 이를 불쌍하게 여긴 산신이 산의 형세를 죽은 처녀의 모습대로 만들었다는 이야기다.", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면", + "MNTN_NM" : "미녀산" + }, + "longitude" : 128.0521684, + "latitude" : 35.682698299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통영시 서남단의 미륵도에 위치한 야트막한 산이나 미륵신앙의 본거지로 불교인들 사이에는 꽤 알려진 산이다. 그래서인지 이 작은 산에는 용화사, 관음사, 도솔암, 미래사 등 크고 작은 사찰과 암자가 많다.또 임해봉(臨海峰)이라는 이름의 정상은 지난날 봉화대로서 다도해를 지킨 역사적 장소로도 기억될 만 하다. 미륵산은 한국 제일의 미항이며 충무공이 왜적을 격파한 전승지로 유명한 통영과 국내 유일의 해저터널로 연결되어 있다. 일명 `판대굴'로 불리는 이 해저터널은 일제시대 일본인이 건설한 것이나 예측된 수명을 넘어 지금도 사용되고 있어 당시 일본의 기술력을 짐작할 수 있는 표본으로 각광받고 있다.정상에 오르면 비진도, 거제도 , 한산도, 칠천도 등 한려수도를 보석처럼 장식하는 크고 작은 섬들을 한 눈에 조망할 수 있어 그 아름다움에 당황할 정도이다.", + "MNTN_HG_VL" : "458", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 산양읍ㆍ봉평동", + "MNTN_NM" : "미륵산" + }, + "longitude" : 128.4163241, + "latitude" : 34.810502800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미륵산은 넓디넓은 호남평야 한가운데 위치한 작은 산이만 그 무게는 결코 가볍지 않다. 백제의 무왕이 된 서동과 선화공주 이야기를 간직한 미륵사가 있던 곳이고, 정상에는 마한시대 것으로 추정하는 마륵산성이 남아있기도 하다. 산 구경하기 어려운 익산땅에서 미륵산은 등산인들의 유일한 휴식처가 되기 때문에 사람들의 발길이 끊이질 않는다.정상은 주변의 넓은 평야지대로 인해 초록의 바다 위에 우뚝 솟은 섬처럼 거칠 것 없는 조망이 일품이다. 동남북 대둔산을 잇는 금남정맥 줄기가 부드럽게 이어져 있고 익산시가지가 훤히 내려다보인다. 다만 아쉬운 것은 정상에 위치한 두 개의 무덤에 훼손 방지를 위해 날카로운 철조망이 처져 있어 절대 들어오지 말라는 듯 위협한다.정상에서 동쪽으로 내려서면 미륵산성을 만난다. 일부 복원된 산성의 규모만으로도 그 크기를 짐작할 정도로 아주 크며 주변으로 높은 산이 없어 멀리까지 관찰할 수 있는 이점이 있는 곳이다.미륵산을 중심으로 금마, 삼기면 일대에는 마한 선인들이 남긴 민속놀이와 미륵산록에 찬란하게 꽃피웠던 백제문화를 보존 전승하기 위하여 매년 10월 8일에 축제를 벌인다. 축제에는 마한 때 유래된 것으로 보여지는, 깃대를 앞으로 숙여 세배를 하는 금마기세배(金馬旗歲拜)놀이를 비롯한 많은 민속놀이가 벌어진다. 특히 ‘콩 깍자, 콩 깍자’로 시작되는 ‘지게 목발 노래’는 지방무형문화재 1호로 지정된 농요(農謠)이다.", + "MNTN_HG_VL" : "430", + "MNTN_LOCPLC_REGION_NM" : "전북 익산시 금마면ㆍ낭산면ㆍ삼기면", + "MNTN_NM" : "미륵산" + }, + "longitude" : 128.4163241, + "latitude" : 34.810502800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미륵산은 강원도 원주시에서 남쪽으로 약 22km 거리인 원주시 귀래면에 위치해 있다. 기암괴봉과 노송이 어우러져 한 폭의 동양화를 연상케 하는 산이다.미륵산은 정상에 거대한 미륵불상이 새겨져 있는 것으로 유명하다. 수석처럼 멋드러진 암봉이 12개나 치솟아 독특한 산세를 나타내며 바위틈을 비집고 붙어있는 노송이 그 절묘함을 더한다. 겨울철에는 노송과 암벽에 피어 있는 설화가 일품이다.산은 그다지 높지 않으나 부드러운 능선길과 아기자기한 암릉길이 조화를 이루고 있어 산행의 정취와 묘미를 느끼게 한다.정상인 신선대에서 북동쪽을 보면 백운산과 치악산맥이 보이며 동으로는 십자봉이, 남서쪽 멀리로는 남한강 물줄기가 보인다.신선대 아래의 미륵불상을 지나고 동쪽 능선을 따라 20분 정도 내려가면 황산사이다. 신라 경순왕 때 창건된 고찰이다. 정상에서 아기자기한 암릉으로 이어지는 남릉을 타노라면 한 폭 그림속을 거니는 기분이다. 암릉마다 분재와 같이 아름다운 노송들이 속세의 때가 묻지 않은 그대로다.산행을 마치고 황산사 를 내려오면 시원한 계곡이 흐르기에 산행의 흐른땀을 씻어준다.", + "MNTN_HG_VL" : "696", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면", + "MNTN_NM" : "미륵산" + }, + "longitude" : 128.4163241, + "latitude" : 34.810502800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "168", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 금호리,해평리,낙성리", + "MNTN_NM" : "미석산" + }, + "longitude" : 128.3761111, + "latitude" : 36.205277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "미타산은 경남 의령군 부림면과 합천군 적중면의 경계에 자리한 해발 662미터의 아담한 산이다. 또 서쪽으로 능선길을 이어가면 천황산(655m), 국사봉(688m) 등 여럿의 청산이 솟구쳐 산행의 묘미를 더해준다. 봄날 진달래 군락지가 장관을 이루며, 9부 능선에는 약 2킬로미터에 이르는 토석 혼축으로 된 도지정기념물인 삼국시대 축성된 미타산성이 있다. 미타산 중턱에는 옛 묵방초등학교를 절로 개조한 불관사가 있다.그리고 미타산 기슭에는 지금부터 약 1300여년 전 통일신라시대 때에 창건되었다는 고찰 유학사가 있다. 유학사는 원래 미타산의 8부 능선에 자라잡고 있었으나 조선초기 태조 이성계의 왕사를 지낸 무학대사가 유학사에 들러 사찰이 앉은 위치가 풍수지리에 맞지 않다고 하여 지금의 위치에 절을 옮겨왔다고 구전으로 전해지고 있다. 현재 미타산의 8부 능선 예전의 사지에는 지금도 절터의 흔적이 완연히 남아있다.", + "MNTN_HG_VL" : "662", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 부림면ㆍ합천군 적중면", + "MNTN_NM" : "미타산" + }, + "longitude" : 128.28888889999999, + "latitude" : 35.5152778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의령", + "MNTN_NM" : "미타산" + }, + "longitude" : 128.28888889999999, + "latitude" : 35.5152778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "민둥산은 1,023m의 제법 높은 산으로 주변에는 국망봉, 강씨봉, 청계산,귀목봉 등 산세가 아름다운 산들이 모여있다.민둥산은 민드기봉, 민덕산이라고도 하며 적목리 서쪽 한북정맥에 솟아있는 산이다. 주능선을 경계로 서쪽은 경기도 포천군 이동면 연곡리로, 조금 더 지역을 좁혀 설명하면 개이빨산(1,110m)과 강씨봉(830m) 사이 능선에서 가장 높은 산이다. 현지 사람들은 민덕산이라고도 부른다.이 민둥산은 제비울 분지와 억새밭을 가지고 있는 가을철 풍광이 좋은 산이다. 가평군 용수동쪽으로는 수량이 많고 깨끗한 가평천을 산행기점으로 하고 있어 여름철 피서 산행지로도 적합한 곳이다. 주능선 좌우로 시원한 조망을 즐길 수 있으며, 강씨봉이나 개이빨산으로 연계 산행이 가능하다. 민드기재에서부터 정상으로 이어지는 능선에는 키를 넘는 억새 밭이 펼쳐져 있어 늦가을이면 하얀 억새꽃을 머리에 인 산의 정취가 일품이다. 또한 적설량이 많은 산으로 알려져 겨울에 능선을 종주하는 산행이 인상적이다.", + "MNTN_HG_VL" : "1023", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 가평군 북면", + "MNTN_NM" : "민둥산" + }, + "longitude" : 128.77488750000001, + "latitude" : 37.270854200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 정선군 남면에 위치한 민둥산은 약수산행과 억새산행, 철도산행지로 유명하다. 이름 그대로 7부 능선을 넘어서면 나무가 거의 없어 민둥민둥한 형세다. 예전에는 ‘한치뒷산’이라 불리던 이곳은, 곤드레, 딱주기나물 등이 잘 자라나도록 하기 위해 일부러 불을 낸 것이, 나무 한 그루 없는 민둥산으로 변하게 했다고 전해진다. 그러나 가을이면 온통 황금빛 억새로 한껏 치장한다. 제주도 동부 오름지대, 창녕 화왕산, 장흥 천관산, 포천 명성산, 밀양 사자평 등과 함께 억새군락지로 손꼽히는 억새평원을 자랑한다. 매년 억새꽃 축제가 열릴 만큼 20만평에 이르는 억새평원은 은빛으로 출렁이고 가을 정취를 만끽하기에 제격이다. 산세는 대체로 완만한 경사를 이루고 있으며, 등산로 정비도 잘 되어 있어 초보자들도 쉽게 오를 수 있다. 민둥산은 정선군 중앙부에 위치하여 동쪽으로 함백산, 남쪽으로 백운산, 서쪽으로 가리왕산, 북쪽으로 괘병산 등이 자리해 있어 동서남북으로 조망이 좋다. 민둥산의 또 다른 특색은 석회암이 빗물에 용해되어 지반이 내려앉는 독특한 카르스트 지형으로 돌리네가 형성되어 있는 것이다.", + "MNTN_HG_VL" : "1118", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면", + "MNTN_NM" : "민둥산" + }, + "longitude" : 128.77488750000001, + "latitude" : 37.270854200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "민주지산(1,241.7m)은 추풍령 남서쪽 약 25km 지점에 있으며 산행의 기점은 정상의 동북쪽 방향인 한천마을과 남쪽 아래의 대불리로 크게 나눌 수 있다. 삼도봉, 석기봉이 명소이며, 석기봉 동쪽에는 원시숲과 화전민터가 있어 옛 주민들의 생활상을 엿볼 수 있고, 물한리에서 멀지 않은 곳에는 1972년에 지은 황룡사가 있다.석기봉과 삼도봉으로 이어지는 주능선은 봄이면 온통 산죽과 진달래가 군락을 이뤄 꽃산행을 즐기게 된다. 다른 산의 진달래가 무리지어 군락을 이루는데 반해 이 곳 진달래는 능선을 따라 도열해 있는 것이 특징이다.물한계곡을 끼고있어 심산유곡으로 아직도 때묻지않은 계곡이 돋보이며, 각종 잡목과 진달래 철쭉 등이 꽉 들어차 장관을 이루고 있다. 옥소(玉沼) 응주암 의용곡폭포 등이 절경을 이루며, 삼도봉에는 충북, 경북, 전북 등 3도인이 모여 세운 3도봉 대화합탑이 있다.", + "MNTN_HG_VL" : "1242", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 상촌면ㆍ용화면, 전라북도 무주군 설천면, 경상북도 김천시 부항면", + "MNTN_NM" : "민주지산" + }, + "longitude" : 127.8490946, + "latitude" : 36.040040900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "바라산은 백운산, 광교산과 능선으로 연결되는 이웃한 산으로 이들 산은 경부고속도로와 서울특별시, 수원간의 옛 도로 사이에 약 10여km에 걸쳐 수원까지 뻗어 있다.동서로 흘러내린 계곡에는 동막천과 백운(의왕) 저수지 및 광교저수지 등 유원지화 되어 가는 곳도 있으나 능선은 매우 한적하고, 완만하며 수목이 우거져 있어 오붓하게 산행을 할 수 있는 당일 산행이며, 주위에 일왕저수지, 광교저수지, 파장저수지, 하광교 소류지, 백운저수지, 운중저수지 등이 산재해 있어 특히 주말이면 낚시 인파로 항상 붐비는 곳이기도 하다.", + "MNTN_HG_VL" : "428", + "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시, 성남시", + "MNTN_NM" : "바라산" + }, + "longitude" : 127.0196199, + "latitude" : 37.372872800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "바랑산은 화순 너릿재에서 광주로 넘어오는 국도변에 들어앉은 쓰레기 매립장을 곁에 두고 있다.매립장이 들어선 것은 2000년도, 동구지역에서 발생하는 쓰레기는 이 곳에서 처리되고 있다. 정상으로 바로 이어지는 등산로는 가파라서, 등산하기에는 힘들고 동구환경관리사업소 사무실 옆 우회로가 등산에 적합하다. 숲길은 비교적 깔끔하게 잘 정비되었으며, 등산로 주변에는 소나무가 빽빽하게 식생하고 있다. 30분 정도 올라가면 헬기장이 있으며, 그 곳을 지나 왼쪽으로 바랑산 정상으로 가는 등산로가 나있다.참나무, 벚나무, 갈참나무 등 국립공원 못지 않은 다양한 식생을 갖추고 있으며, 그 변화도 다양하다. 정상(320m)에서는 무등산의 여러 봉우리들이 한 눈에 들어와 무등산의 장엄함을 감상하기에 충분하다.", + "MNTN_HG_VL" : "602", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구 소태동,용산동", + "MNTN_NM" : "바랑산" + }, + "longitude" : 127.27, + "latitude" : 36.130000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "호남의 금강이라 부르기에 손색이 없는 대둔산은 충남 논산시와 금산군, 전북 완주군 등 3개군에 걸쳐 있다. 최고봉인 마천대를 중심으로 기암괴석들이 제각기 위용을 자랑하며 늘어서 있다. 대둔산은 두 얼굴을 가지고 있다. 기경의 절벽을 이루는 전북 완주쪽과 순후한 시골아낙 같은 충남 논산,금산쪽이 바로 그것이다.바랑산은 그리높지 않은 산임에도 월성봉까지 이어지는 능선은 보기드문 절경을 자랑한다. 잘 닦인 등산로를 가지고 있으면서도 깨끗한 주변환경을 유지해 쾌적함속에 산행을 즐길 수 있는 곳이다.바랑산은 다리성 서쪽에 있고 모양이 바랑과 같이 생겼다 하여 붙여진 산명이며, 노승예불현의 명당이 있다.등산로 역시 양쪽 지형이 상반되는 것 만큼이나 특성이 뚜렷이 구분된다.", + "MNTN_HG_VL" : "555", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산시", + "MNTN_NM" : "바랑산" + }, + "longitude" : 127.27, + "latitude" : 36.130000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "지리산자락을 따라 북서쪽 능선 끝자락에 솟아 있는 바래봉은 매년 5월이면 철쭉제가 열리는 '천상화원'으로, 온 산이 연분홍빛 철쭉꽃으로 물들인다. 바래봉 철쭉은 다른 어느 산의 철쭉꽃보다 화려한 편이다. 그 이유는 바래봉 철쭉은 주능선에는 나무가 거의 없는 푸른 초원이 펼쳐진 능선 한가운데 피어나기 때문이다. 푸른 초원 위에 연분홍빛 철쭉이 더욱 화사하게 돋보이는 것이 바래봉 철쭉의 매력이다.바래봉이란 이름은 스님들의 밥그릇인 바리때를 엎어놓은 것 같다 하여 붙여졌다 한다. 이름의 유래와 같이 바래봉 주능선은 둥그스름하고 부드러운 능선을 펼치고 있어 산행은 마치 공원을 산책하는 듯 편안하다. 그러나 산위에 있는 이 천상의 화원을 즐기기 위해서는 산을 오르는 힘겨움을 감수해야만 한다. 세상의 모든 일에는 그 대가가 따르는 것처럼 바래봉의 철쭉도 그런 수고를 감수한 이후에야 맛볼 수 있다.이렇게 바래봉은 한라산,소백산 등과 더불어 대규모 철쭉군락지로 유명한 산일 뿐만 아니라, 운성(운봉) 10경의 하나로 바래봉 달빛 아래 몰려오는 독경시에 흔드는 작은 종소리 발악월경이 포함되어 있다.", + "MNTN_HG_VL" : "1165", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 운봉읍, 산내면", + "MNTN_NM" : "바래봉" + }, + "longitude" : 127.56, + "latitude" : 35.430000000000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "바위산은 사람들이 쉽게 접근하는 것을 막는 여염집 아낙처럼 찾아가기가 약간 번거롭다. 다른 산에 갈 때처럼 차나 기차를 이용해 근처까지 가도 소양댐 선착장에서 배를 타고 더 들어가야 하기 때문이다. 마치 그 물을 건너야 자신을 만날 자격이 있다는 것처럼 이 산은 저 멀리 서있다.춘천의 명물 중 하나인 소양호를 이용해서 산행을 즐길 수 있는 산과 호수의 낭만이 서려 있는 산이지만, 산 이름 자체는 널리 알려져 있지않아 일반인들은 그리 많지 않은 산악인들이 찾고 있는 편이며 능선으로 매봉이 바로 이웃하여 연결되어 있는 산이다. 소양호를 내려다 보면서 정상에 오르다 보면 노송이 우겨져 있고, 나자막한 돌탑이 있다.주머니 같이 둘러싸여 있는 능선 속으로 흐르는 중밭골 계곡에는 푸른 이끼가 끼어있고 군데군데 소와 작은 폭포가 있어 깨끗하기 이를데 없으며, 오솔길에는 풀이 무성해 융단을 딛는 것 같은 촉감의 정겨운 산길이다.", + "MNTN_HG_VL" : "858", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "바위산" + }, + "longitude" : -103.45906669999999, + "latitude" : 43.879102499999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봄과 여름 산행에서 빼놓을 수 없는 게 바로 계곡 산행이다. 박달봉은 백운골 계곡과 큰골 계곡이 특히 등산인들의 발길을 모으고 있다. 광덕재에서 광덕산 그리고 백운산에 이르는 능선은 암벽으로 이어져 스릴을 주며, 억새밭이 펼쳐져 있고 광덕재에서 바라보면 오른쪽은 백운산, 흥룡봉이 위치해 있고 왼쪽에는 광덕산, 박달봉이 대조를 이루고 있다.산행은 광덕재에서 시작하는 편이 쉽다. 광덕재에서 광덕산을 거쳐 박달봉을 지나 백운동 초입리와 광덕재 고개 중간 약간 아래쪽으로 하산하여 도로로 이동하는 편이 쉽지만, 도로 이동시 차량이 많아 사고 위험이 높아 특히 주의해야 한다.약 270년전에 이 산봉에는 박달나무가 밀집하여 통행을 하지 못할 정도였기 때문에 박달봉이라고 불리우고 있다.", + "MNTN_HG_VL" : "800", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", + "MNTN_NM" : "박달봉" + }, + "longitude" : 126.20277780000001, + "latitude" : 40.913611099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "박달산은 괴산군 감물면과 장연면의 경계에 자리하는 해발 825미터의 산이다. 대미산~포암산을 이어 서쪽으로 달려오던 백두대간의 주능선이 마패봉(922m)에서 직각으로 방향을 꺾어 정남쪽의 조령산을 향한다. 서쪽으로 계속 뻗어나간 산줄기는 보다 높은 신선봉(967m)을 솟구치고 괴산군에 이르러 박달산과 주월산(506m), 성불산(532m)을 일으킨 후 달천으로 내려든다. 박달산 동녘자락 장연면에는 송덕리와 추점리의 미선나무 군락지가, 오가리에는 느티나무 등 소중한 천연기념물도 품고있다.또 박달산은 독립된 봉우리로 어디에서 보나 그 덩치가 심상치 않다. 육산으로 산 안으로 들어가보면 아직 사람의 손길이 닿지 않아 원시림을 연상케 할 정도로 우거져 있는 곳이 많다.산불감시용 카메라가 설치된 철탑이 하늘을 찌를 듯 서 있는 정상에는 2002년에 세운 정상석과 1982년 복구한 삼각점이 있다. 그러나 무엇보다 이색적인 것은 정상석 옆에 자리한 ‘대한민국 국기게양대’다. 단기 4330년 음력 7월 6일(서기 1997년 8월 8일) 한국고대사연구회에서 세운 게양대와 빗돌은 박달산의 명물이 아닐 수 없다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 감물면ㆍ장연면", + "MNTN_NM" : "박달산" + }, + "longitude" : 127.923232, + "latitude" : 36.836640699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "896", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백", + "MNTN_NM" : "박월산" + }, + "longitude" : 128.53055560000001, + "latitude" : 35.574722199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "박지산은 강원도 평창에 위치한 산으로 오대산에서 발원하는 청정류 가운데 가장 때묻지 않은 계곡인 아차골을 품고 있다. 말복까지 얼음을 볼 수 있는 박지골과 경치가 수려한 아차골 등 박지산 골짜기는 등산인들의 발길이 뜸하여 오지의 신비함을 간직하고 있다.박지산은 두타산(頭陀山)이라고도 하는데 2007년 인쇄된 국토지리정보원 지형도상의 공식명칭으로 ‘우리 산 이름 바로 찾기 운동’에 따라 2002년 박지산에서 두타산으로 이름이 바뀌었다. 그러나 백두대간의 삼척 두타산(1352.7m)과 혼돈되기 때문에 여전히 박지산이라 일컫는 이들이 많다.정상에는 2미터 높이의 돌탑이 있는데 칠원성군(七元星君)을 모셨다하여 칠성대라 부르며, 칠원성군이란 불교에서 북두의 일곱 성군을 뜻한다. 칠원성군은 북두칠성을 인격화한 신(神)이며 농사와 생사(生死), 화복(禍福)을 맡아본다고 한다. 박지산은 이곳 주민들에겐 단순히 이끼가 많은 산이 아니라 북두칠성의 산이기도 하다.", + "MNTN_HG_VL" : "1391", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면", + "MNTN_NM" : "박지산(두타산)" + }, + "longitude" : 128.60083330000001, + "latitude" : 37.583888899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1084", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선", + "MNTN_NM" : "반론산" + }, + "longitude" : 128.7305556, + "latitude" : 37.4641667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운산과 무학봉의 능선과 이어져 있는 반암산은 강원도 화천군 사내면에 자리를 잡고 있다. 이 산은 `수색특공 훈련장' 이라는 안내판이 붙어 있어 많은 등산객들이 산행을 꺼리고 있어 훼손되지 않은 자연을 그대로 유지하고 있는 지역으로 백운산과 더불어 청정지구로 지정하자는 여론이 모아지고 있는 곳이다.백운산 능선과의 사이에는 덕골계곡이 있다. 짧은 능선에 있는 산이지만 때 묻지 않은 수림이 우거져 있다. 주변에는 광덕계곡, 반암계곡 등이 있다. 사철 수량이 풍부하고 주능선에는 이 산의 제일 명소인 거대한 구름다리바위와 사자바위 등 기암이 드문드문 있다.", + "MNTN_HG_VL" : "832", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면 광덕리", + "MNTN_NM" : "반암산" + }, + "longitude" : 127.4731841, + "latitude" : 38.076925699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남한의 산 중 최대면적을 가지고 있는 지리산의 산세는 세인을 압도하고도 남는다. 반야봉은 지리산 제2봉으로 산세가 웅장하고 계곡이 깊으며 수목이 울창하여 고산식물과 기암절벽이 장관을 이룬다. 이에 해마다 많은 산행인이 찾고 있다. 지리산의 모든 능선을 한눈에 볼 수 있는 지리산의 중심부로, 해질무렵 운무에 둘러쌓인 반야봉의 붉은 빛 낙조는 장엄하기 그지없어 산행인의 넋을 빼놓을 정도다. 특히 여름날 작열하던 태양이 지루한 하루를 보내고 저편 너머로 숨어들 무렵이면 반야의 하늘은 온통 진홍빛으로 물들어 보는 이들을 감동케 한다.지리산이 그토록 아름다울 수가 있는지를 끝없이 되뇌여도 반야봉의 낙조는 모자람이 없다. 화려한 불꽃잔치와 더불어 반야봉은 운해와 함께 우리에게 인식된다. 늘 발아래 운해를 거느리고 우뚝 솟아 있는 반야봉의 장관은 비경 그것이다.태산준령들 사이사이에 걸려 있는 지리산의 운해는 아마도 주봉인 천왕봉과 반야봉에 얽힌 마고할미와 반야의 애틋한 마음을 그대로 전해주려는 듯 심오함을 갖고 있다.반야봉 정상에서 동쪽으로 조금 내려가면 절벽 아래에 묘향대가 있는데 이곳은 옛부터 불도들이 수도하는 유서깊은 선암으로 유명하다.", + "MNTN_HG_VL" : "1732", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군, 전라북도 남원시, 경상남도 하동군", + "MNTN_NM" : "반야봉" + }, + "longitude" : 127.58, + "latitude" : 35.270000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "발교산은 강원도 홍천군 동면과 횡성군 청일면 사이에 남북으로 길게 드러누운 산이다. 발교산은 6·25의 전화도 피해갈 만큼 주위가 온통 산으로 둘러싸여 있는 오지의 한가운데 자리하고 있다. 그런 만큼 아직까지 자연 그대로의 모습을 유지하고 있다. 산행은 봉명2리에서 시작된다.봉명리는 구접이라는 이름으로도 불리는데 산이 아홉 겹이나 둘러싸고 있다 해서 그리 불렸다고 한다. 마을을 낀 계곡길을 따라 오르다 보면 소나무숲이 나오고 곧이어 가파른 오르막이 시작된다.정상까지는 오르막이 계속되어 오르는 발걸음을 무겁게 하지만 정상에 서면 공작산, 대화산이 지척에 보이고 멀리 치악산의 줄기가 시야에 와 닿는다. 철분이 많이 섞였다는 계곡의 물소리가 산행 내내 귀를 즐겁게 해준다.", + "MNTN_HG_VL" : "998", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 횡성군 청일면", + "MNTN_NM" : "발교산" + }, + "longitude" : 128.11388890000001, + "latitude" : 37.654722199999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "발왕산은 대관령 용평스키장으로 더욱 알려진 강원도 평창군 도암면과 진부면 그리고 강릉시 왕산면의 경계를 이루는 산이다. 즉 백두대간이 오대산, 황병산을 거쳐 대관령으로 이어질 무렵 황병산에서 남쪽으로 더욱 거대한 봉우리를 솟구치게 했으니 그 산이 바로 발왕산이다. 용평스키장으로 인해 다양한 등산코스가 개발되지는 못했으나 그만큼 교통이 좋은 장점이 있다.그 옛날 발이 컸던 발왕이와 그를 사랑한 옥녀의 슬픈 전설로 이름이 유래된 발왕산은 산세가 부드럽고 험한 길이 없으며 설원의 절경이 손꼽히는 산이다. 정상에 오르면 평창의 산을 조망하기 좋다. 정상에서 만나는 주목군락은 발왕산의 자랑거리며 아름다운 자연 그대로의 모습을 간직한 고장답게 1000여미터가 넘는 산들이 주변으로 즐비하다. 특히 북쪽으로 삼양대관령목장의 황병산을 시작으로 왼쪽으로 노인봉, 두로봉, 상왕봉, 비로봉, 계방산 등이 장대한 파노라마를 연출하며 펼쳐진다.", + "MNTN_HG_VL" : "1458", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 진부면ㆍ강릉시 왕산면", + "MNTN_NM" : "발왕산" + }, + "longitude" : 128.67283159999999, + "latitude" : 37.607200300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "발치봉은 충북 충주시에 자리한 야트막한 산으로 아직 일반인들에게는 잘 알려지지 않은 산이다. 발치봉의 이름에 대한 유래는 확실치 않다.남쪽 아래에 발치마을이 있고 발치고개가 있어 발치봉이란 이름을 붙이게 되었다는 이야기도 있으나 자세한 사실은 알 수 없다. 그리고 수안보 온천이 인근에 있어 그 분위기를 더한다.발치봉은 야산으로 버려져 있다시피 한 것을 최근에 등산로가 개척되면서 산악인들에게 알려지기 시작했을 뿐 아직까지는 많은 사람들이 찾지 않고 있는 미지의 산이다. 사람들의 발길이 뜸하다보니 숲이 우거지고 길이 희미하여 자칫하면 등산로를 잃을 수가 있으니 주의해야 한다.", + "MNTN_HG_VL" : "550", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 살미면", + "MNTN_NM" : "발치봉" + }, + "longitude" : -122.86777290000001, + "latitude" : 49.249334400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "밝얼산은 울주군 상북면 거리와 길천리에 걸쳐 있는 산으로 이 산을 따라 서쪽으로 넘어가면 배내봉을 지나 천화현(배내고개)에 이르게 되고 고개를 지나면 밀양으로 넘어가게 된다.또한 밝얼산은 신불산갈월산취서산과 한 지괴로 된 산으로 밝어리산, 밝얼제 등의 이름을 가졌으며 '광명'을 뜻하는 산이다. 그러므로 이 산은 광명하고 신성한 산이라는 의미를 가지고 있다.병풍같이 깎은 듯한 바위와 처녀 총각으로 풍자하는 바위가 있고, 배내와의 경계에는 참샘이 있어, 길손의 목을 축여 준다. 그리고 옛날에 이 우마차 길은 험하기로 이름이 있어, 이 산길을 다녀왔던 말이나 소는 삼천리 어디라도 다 갈 수 있다고 격찬했다.", + "MNTN_HG_VL" : "738", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 상북면", + "MNTN_NM" : "밝얼산" + }, + "longitude" : 129.0354055, + "latitude" : 35.576419700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "337", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 옥계면 천남리", + "MNTN_NM" : "밥봉" + }, + "longitude" : 129.04410139999999, + "latitude" : 37.604346700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "방가산(方可山)은 팔공지맥으로 해발 755.8m이며 군위군과 영천시의 접경구역이다. 방가산 정상에서 영천지역의 보현산천문대의 정상부를 조망이 가능하며 인근에 군위 장곡휴양림이 위치하고 있다. 방가산 등산로를 연계하여 고로면 양지리의 아미산 등산과 연계가 가능하며 총 7~8시간의 시간이소요될 것으로 예상된다.", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 고로면 인곡리, 영천시", + "MNTN_NM" : "방가산" + }, + "longitude" : 128.9064362, + "latitude" : 36.134187900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "방문산은 일반적으로 방장산이라고 하나 실은 고창고개를 가운데 두고, 동북쪽 장성갈재 옆에 솟아 있는 733봉을 방장산, 서남쪽네 솟아 있는 640봉을 방문산이라 구분된다.방문산은 그 남서 기슭에 미륵사, 상원사, 임공사 등의 사찰을 안고 있으며 주변에는 631년(무왕 32)에 승려 여환(如幻)이 창건한 백제 때 고찰 백양사(白羊寺), 사적 제384호로 지정된 장성 입암산성이 있다. 정상 서남쪽 아래로 고창읍 시가지를 한눈에 조망할 수 있고 북쪽으로 호남평야 일대와 동남쪽으로 장성호와 멀리 무등산까지 시야에 들어온다.산행은 미륵사나 임공사 도는 신림면 신평리 신기마을 등을 등산기점으로 할 수 있으되 하산은 석정온천과 연계시킨 코스가 좋다.", + "MNTN_HG_VL" : "640", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창읍, 신림면, 전라남도 장성 북이면", + "MNTN_NM" : "방문산" + }, + "longitude" : 126.73999999999999, + "latitude" : 35.450000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "방장산은 전북 정읍시와 고창, 전남 장성의 경계에 솟아 있다. 내장산의 서쪽 줄기를 따라 뻗친 능선 중 가장 높이 솟은 봉우리이다.지리산 무등산과 함께 호남의 삼신산으로 추앙받아 왔으며 주위의 이름난 내장산, 선운산, 백암산에 둘러싸여 있으면서도 기세가 눌리지 않는 당당함을 자랑하고 있다. 방장산 중턱에는 방장산 자연휴양림이 위치하고 있다.2000년 7월 1일 문을 연 것으로 서부지방 산림관리청(전북 남원 소재)에서 순창 회문산 자연휴양림, 무주 덕유산자연휴양림, 진안 운장산자연휴양림, 장흥 천관산자연휴양림, 함양 지리산자연휴양림, 남해 편백자연휴양림과 함께 방장산휴양림을 관리하고있다. 휴양림 내에는 참나무류와 소나무, 편백, 낙엽송, 리기다소나무 등이 많이 자라고 있으며, 고창 방면으로 난 임도를 따라가면 벽오봉(640m)과 고창 고개 중간의 능선에 닿는다. 이곳에서는 고창 읍내와 서해바다가 내려다보인다. 고창고개를 지나 장성갈재 방면으로 조금 더 가면 방장산 정상이다.방장산 정상에 오르면 신선지경에 이르며 고창읍을 비롯하여 광활한 야산개발지와 멀리는 서해바다가 보이며 동쪽으로는 광주 무등산까지 보인다.휴양림에서 정상까지는 왕복 3시간이 소요되며 석정온천으로 곧장 하산하는 산길도 나있다.주능선에 오르면 서해로부터 불어오는 시원한 바람을 맞이할 수 있는데 이 덕분에 패러글라이딩 동호인들이 종종 이곳을 찾기도 한다. 정상 서편 용추골에는 용추 폭포가 있으며 하산지에는 게르마늄 천으로 유명한 석정온천이 있어 피로회복에 더없이 좋고, 고창은 전통음식으로도 유명한 고장이다.", + "MNTN_HG_VL" : "734", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군, 전라북도 고창군 신림면ㆍ정읍시 입암면", + "MNTN_NM" : "방장산" + }, + "longitude" : 126.76000000000001, + "latitude" : 35.447778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국내 최대의 면적을 자랑하는 자연휴양림을 거느리고 있는 방태산은 강원도 인제군과 홍천군의 경계를 이루는 산으로, 교통이 불편한 관계로 아직도 오염되지 않은 깨끗한 계곡을 간직하고 있다.청정한 자연림에 들어서면 도심에서 불과 몇시간 거리밖에 떨어져 있지 않다는 사실이 믿어지지 않는다. 빽빽한 나무들 사이에 누워 하늘을 올려다보면 한줄기의 햇살도 허용하지 않는 수림의 깊이가 느껴진다.", + "MNTN_HG_VL" : "1446", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면, 상남면", + "MNTN_NM" : "방태산" + }, + "longitude" : 128.35604789999999, + "latitude" : 37.894853599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "배내봉은 가지산, 상운산, 천황산, 재약산, 능동산, 고헌산, 문복산, 간월산, 신불산 등 1000m급 봉우리 중앙부분에 위치하였으니 산 정기의 심장부인 곳이라 할 수 있다.배내봉 산행을 하려면 언양에서 석남사 행 버스로 궁평을 지나 양등 상북 주유소 앞에 내린다. 길 건너 주유소 100m 안으로 들어서면, 길가 콘테이너 밑에 푹 패인 찬물내기 즉 냉수정을 만날 수 있다. 계곡안쪽은 물이 많으며 바위와 어울어져 여름 피서지로는 좋아보이나 계곡물을 마을사람들 식수로 사용하므로 계곡이 깨끗하다.양등천을 지나 마을 당산나무 뒤 마을회관에 도착한다. 오른쪽으로 100m 가량 들어서면 마을이 끝나는 곳의 재실을 돌아 무덤 1구를 만난다. 산행들머리는 무덤에서 왼쪽으로 오르면 소나무 한 그루를 만난다. 해마다 당제를 지냈다는 국수목이다.정상은 탁 트인 초원 지대로 주변의 경관이 시원하게 펼쳐지며, 신불산(1,209m), 간월산, 수미봉, 사자봉 등의 산들이 한눈에 들어온다.", + "MNTN_HG_VL" : "965", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "배내봉" + }, + "longitude" : 129.0354055, + "latitude" : 35.576419700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "361", + "MNTN_LOCPLC_REGION_NM" : "충청남도 아산시 배방면", + "MNTN_NM" : "배방산" + }, + "longitude" : 127.052751, + "latitude" : 36.777539999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백덕산은 이름 그대로 하얀 눈이 쌓였을 때 절경을 이루는 산이다.겨울이면 무릎까지 빠지도록 많은 눈이 내린다. 1천m 이상의 주능선 봉오리마다 피어나는 설화(雪花)가 은백색의 세계로 빠져드는 환상을 느끼게 한다.", + "MNTN_HG_VL" : "1350", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 방림면, 횡성군 안흥면, 영월군 수주면", + "MNTN_NM" : "백덕산" + }, + "longitude" : 128.2934023, + "latitude" : 37.396552 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백련산은 높이 215.5m의 낮은 산이지만 서울시내 서대문구와 은평구의 경계에 자리하고 있어 주말이면 응암동,홍은동 일대의 주민들이 자주 찾는 산이며, 휴식공간으로 잘 활용되고 있다. 신라 경덕왕 때(서기747년) 진표율사가 창건, 무학대사가 중건한 백련사란 절이 있어 백련산이라 불리었다.", + "MNTN_HG_VL" : "216", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 은평구, 서대문구 홍은동", + "MNTN_NM" : "백련산" + }, + "longitude" : 126.9269444, + "latitude" : 37.589444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백련산은 진안군 팔공산에서 남서로 가지 친 능선이 성수산, 고덕산, 백이산을 거쳐 옥정호 동편 임실군 청운면에 솟아있는 산이다. 백련산은 일명 영취산이라고도 하며, 이산을 가운데 두고 북, 서, 남으로 옥정호와 섬진강 줄기가 휘어 감고 있어 마치 연못 한 가운데 피어 있는 연꽃 같다하여 백련산이라 한다. 정상에서 남쪽으로 강진면 갈담리까지 이어진 그곳에는 조선 8대 명당중의 하나인 잉어 명당이 있다. 옛날 이곳에 묘를 쓰려고 땅을 2~3척을 파내려가니 널빤지 같은 암반이 깔려 있어, 한쪽면을 들어 올려보니 암반 밑에서 놀던 잉어 두 마리 중 한 마리가 뛰어나오자 들어올리던 암반을 다시 놓고 묘를 썼다고 하며, 그후 명당바람으로 장자가 되었다고 한다.섬진강과 산 남서쪽에 있는 회문산의 유명세에 가려 있던 백련산은 정상 전체를 차지하고 있는 부처바위가 일품이다. 정상에는 높이 솟은 부처바위 외에도 쌍선대라는 두 개의 거대한 바위가 서있다. 정상에서 바라보이는 회문산과 필봉산이 섬진강을 끼고 솟은 모습도 장관이다.동으로는 청웅면 소재지와 임실 방면 성수산 줄기가 하늘금을 이루고, 더 멀리 진안 방면 선각산과 팔공산 줄기가 보인다. 남동으로는 백련암 계곡과 백련리 분지가 평화롭게 내려다 보이고, 멀리 지리산 연봉이 웅장한 자태로 하늘금을 이룬다.남으로는 부흥리 분지가 시원하게 내려다보아고, 순창 방면 원통산과 용골산, 무량산 줄기가 출렁이는 파도인 듯 겹겹하고, 남서쪽으로는 강진면 소재지와 필봉산 뒤로 회문산이 시원하게 펼쳐진다.", + "MNTN_HG_VL" : "754", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 청웅면, 강진면", + "MNTN_NM" : "백련산" + }, + "longitude" : 126.9269444, + "latitude" : 37.589444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백마산은 원남면 마송리, 주봉리와 괴산군 사리면 소매리에 걸쳐있는 명산으로 수석이 절기하고 경치가 아름다워 일명 음성의 소금강이라고 부른다.서기 1649년(인조 27년)에 큰 백마가 나타나서 이 산기슭 일대를 돌아다니며 살다 죽어 백마산이라 했다하며, 이 백마의 무덤은 지금까지도 남아 있다. 농사철에 가뭄이 심할 때면 이 말 무덤위에 맑은 물을 붓고 무덤을 약간 파헤치면서 농악을 울리면 단비가 쏟아진다는 전설이 있어 백마묘의 봉분은 옴푹하게 파헤쳐져 있다.산꼭대기 가까이에는 상독암, 관창암, 장사바위, 맹봉바위, 고깔바위, 상좌바위, 소두방바위, 범바위, 매바위, 쌍둥이바위 등이 있으며 남쪽에는 백운사가 있고 북쪽에는 주봉사가 있으며 백마산을 경계로 북쪽은 남한강 수계이고 남쪽은 금강수계의 분수령을 이루어 충북을 지형적으로 남북으로 둘로 구분하는 경계가 나뉘는 산이기도 하다.산에 올라 자세히 살펴보면 이 근방의 작은산을 모두 백마산을 보고 엎드려 절하는 것 같은 형상을 볼 수 있으며 주변에 백은사 암자가 있는데 암자에서 나오는 석가수가 산객을 맞아주고 있다.", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 사리면 노송리", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 밀양시 단장면의 백마산은 겉보기에 산꾼의 호기심을 끌어내지 못한다. 높지도 않을 뿐더러 정상석 하나없이 밋밋한 능선이 멧부리 구실을 하는 탓이다. 하지만 모든 산이 그렇듯 백마산도 나름의 맛을 지녔다.안부까지 이어지는 계곡과 정상에서의 조망은 분명 남다르다. 특히 주변의 풍광을 흡입하듯 담고 있는 밀양댐을 한 눈에 즐기는 것은 색다른 경험이다.백마산의 산행들머리는 선리 마을에서 계곡 따라 20여 분 언곡마을 (일명 담재, 다름재라 한다)에서 식수를 준비하고 계곡 따라 오른다. 25분 후 안붕에 오르면 능선에서 오른쪽으로 20여 분 지나면 갑자기 무덤이 나오고 고개 양 옆으로 갈림길이 나온다. 풍류동에서는 둥둥재라 하며, 선리 방면에서는 깐치목이라 하기도 하는데, 왼편은 풍류동으로 하여 평리마을로 가고, 오른쪽은 가산마을로 내려선다. 가고자 하는 길은 무덤 위에도 무덤 1구가 더 나타나며 능선을 따라 길이 열린다. 백마산성이 보이고 이내 정상인 백마산에 오른다. 밋밋한 구릉지를 이루고 있기에 어디가 정상인지 구분하기가 어렵다.", + "MNTN_HG_VL" : "464", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "286", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면 고례리\/ 양산시 상북면 대리", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진산과 금산을 잇는 도로에서 가깝다. 진산에서 복수면과 금산길이 갈라지는 곳에서 금산쪽 길에 들어서다 보면 길가의 부수바위마을(부암리)에 이른다. 이 마을 앞에서 남쪽을 바라보면 개울 건너에 백마산과 국사봉이 한 눈에 들어온다.부수바위마을 서쪽 끝머리쯤과 석막리로 가는 포장길이 금산길과 갈라져 남으로 뻗는다. 그 석막리 길을 따라가다 곧 다리를 건너고 국사봉 모퉁이를 돌면 길가에 삼가리 마을이 나타난다. 이 삼가리 마을이 산행의 기점이다. 마을 앞 길가에서 국사봉 고스락 아래 병풍바위가 올려다 보인다. 그 경관이 매우 아름다워 옛부터 많은 사람들의 사랑을 받아왔다. 그래서인지 옛날 원님들이 여기에 자주 놀러왔었다고 한다.백마산에 옛부터 다음과 같은 전설이 전해 내려오고 있다. 옛날 부수바위 마을에 겨드랑이에 날개가 달린 장수 아기가 태어났다. 그러자 백마산 국사봉 아래 용마굴에서 그 아기장수가 탈 백마도 나왔다. 그러나 아기의 어머니는 뒷일이 두려워 그만 아기의 날개를 베어내고 다듬이돌로 아기를 눌러 죽이고 말았다.", + "MNTN_HG_VL" : "460", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 진산면 삼가리, 엄정리", + "MNTN_NM" : "백마산" + }, + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백석봉은 백두대간상의 노인봉에서 남쪽으로 길게 뻗어 내린 산맥이 소황병산과 용산, 박지산을 크게 일으키고 오대천과 조양천의 합류지점인 북평면에 솟아 있는데, 정선 9대 명산 중의 하나이다.산정에 백색을 띈 큰 바위로 인해 백석봉이라 불리게 된 이 산은 숙암리와 나전 2리에 등산로를 새로 개설하여 등산하기 편해졌다. 산 정상에는 신기한 약효가 있는 샘이 있는데 이 물을 부정한 사람이 마시면 마른다는 전설이 있으며 이 웅봉이 검게 변하면 수일내에 비가 내린다는 전설이 전해내려 오고 있다.정상에 서면 철쭉이 군락지를 이루고 있는 숙암계곡이 아찔하게 내려다 보인다. 이 계곡 주변에는 맑고 깨끗한 숙암샘터가 있다. 등산 외에도 계곡길을 따라 드라이브를 즐기기에 좋은 코스다. 능선에는 진달래 군락지가 곳곳에 있고 참나무 군락지에는 겨우살이가 지천이다. 듬직한 능선길은 고산다운 풍경이여서 좋고, 등산로는 안내판이 잘 설치되어 있다.", + "MNTN_HG_VL" : "1170", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면", + "MNTN_NM" : "백석봉" + }, + "longitude" : 128.6408333, + "latitude" : 37.481944400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백석산은 이승복 생가터와 방아다리약수가 있는 계곡을 구분하는 능선이 속사리재를 지나 솟아오른 산 중의 하나로 계방산과 이웃해 있다. 이 산의 주능선은 넓은 초원지대를 이루고 있으며 주능선에서 사방으로 계곡이 펼쳐져 있어 자연 그대로의 계곡미를 간직한 산이다.산 정상에 흰 바위가 있어 백석산이라고 부르게 되었다고 전해지며, 백석산 정상 평지에는 깃대봉이 세워져 있고 서편은 기암 절벽이며 동쪽으로는 가리왕산이 손에 잡힐 듯 가깝게 보인다. 정상 남쪽 마랑치에서 서쪽으로 돌아 들어가면 암봉 밑에 영암사가 있는데 100여 년 전 산삼을 캐기 위해 지은 산막이 사찰로 변하게 된 것이라고 한다.", + "MNTN_HG_VL" : "1365", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", + "MNTN_NM" : "백석산" + }, + "longitude" : 128.51604320000001, + "latitude" : 37.539788799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백아산은 전라남도 화순군에서도 오지라고 할 수 있는 북면에 위치한다. 그렇기 때문에 그저 평범한 산으로 지나치기 쉬우나 이 산이 전남의 명산들을 조망하기에 매우 좋은 위치에 자리하고 있다는 것은 백아산에 오르는 순간 알게 된다. 한때 빨치산 활동지로도 유명한 백아산은 그들이 차지하고 활동할 만큼 사방 수십 리에 걸쳐 거침이 없다.석회석으로 된 산봉우리가 마치 흰 거위들이 모여 앉아 있는 것처럼 보여 백아산(白鵝山)이라는 이름이 붙여졌다고 한다. 산 북쪽으로 무등산(1187m)이, 남쪽으로 모후산(919m)이 있다. 날카로운 바위가 많고 산세가 험하나 등산로가 잘 정비되어 순탄한 산행을 즐길 수 있다. 산 중턱에는 화순 아천산 천연동굴이 있다. 석회암 동굴이며, 약 2억년 전에 생성된 것으로 추정하고 있다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 북면", + "MNTN_NM" : "백아산" + }, + "longitude" : 127.1639881, + "latitude" : 35.1661888 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백악산은 속리산 문장대에서 북쪽 화양동 계곡 방면으로 이어진 긴 능선위에 솟아있는 봉우리로 경북 상주와 충북 괴산의 도계를 이루고 있다. 규모는 작지만 화강암으로 된 여러 형상의 바위들이 산악미를 보여주는 옹골찬 산이다.속리산 국립공원의 중간지점에 위치하고 있는 이 산은 정상을 중심으로 좌우 편은 암봉과 암릉으로 연결되어 장관이고, 주능선 남쪽 면은 완만한 반면 북쪽은 절벽을 이루어 아찔하다.정상 북쪽 옥양골에는 유명한 옥양폭포가 있고, 폭포위 계곡 서편으로 조금 들어가면 암벽에 기이하게 생긴 석굴이 있는데 일명 보굴이라 불리기도 한다. 수양대군의 딸이 단종의 왕위를 차지하려는 아버지의 음모를 눈치채고 발설했다가#51922;겨나 숨어 지낸 곳이라고 전해지고 있다.", + "MNTN_HG_VL" : "857", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 괴산군 청천면", + "MNTN_NM" : "백악산" + }, + "longitude" : 127.85768899999999, + "latitude" : 36.614499700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백암산은 드넓은 호남평야를 마주하고 솟아오른 높이 741.2m의 산으로 내장산 국립공원에 속한다.옛부터 봄이면 백양, 가을이면 내장이라 했듯이 산하면 내장, 고적하면 백암이라 할 정도로 백암산의 절경은 내장산에 뒤지지 않는다. 백학봉과 상왕봉, 사자봉, 등의 기암괴석이 곳곳에 있으며, 산세가 험준한 편이다. 특히 비자나무숲과 회색 줄무늬 다람쥐가 유명한 이곳에는 대한 불교 조계종 18교구 본산인 대사찰 백양사도 있다.", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 복흥면, 전라남도 장성군 북하면", + "MNTN_NM" : "백암산" + }, + "longitude" : 126.85083299999999, + "latitude" : 35.462778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천", + "MNTN_NM" : "백암산" + }, + "longitude" : 126.85083299999999, + "latitude" : 35.462778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금남정맥에서 갈라진 작은 줄기가 금산으로 뻗어 내렸는데 그 산줄기의 주봉이 백암산이다. 아침 햇살을 받으면 바위 낭떠러지가 하얗게 보이기 때문에 백암이라고 하는 백암산은 600 고지로 널리 알려져 있다. 특히 백암산의 매부리봉은 다른 산에서 볼 수 없는 장관이다. 산의 원줄기 북쪽 끝봉을 서암산이라고 하는 바, 서암산에서 보면 매부리봉의 날카로운 바위가 마치 매의 부리처럼 서쪽 하늘로 내밀고 있어 신기하다. 이 매의 부리는 공중에 떠있는 셈이다.매부리봉 외에도 주릉 일대의 바위등성이는 주로 서쪽 휴양림 골짜기 쪽으로 천길 낭떠러지를 이루고 있으며 그곳에 노송이 어우러져 한 폭의 그림 같다. 봄에는 진달래가 많이 피어 경관을 이루고, 암봉이 많아 산행의 묘미를 맛볼 수 있다.백암산 줄기는 6.25 전쟁 당시 치열한 싸움이 벌어져 피로 물들었던 전적지이다. 충청남도과 전라북도의 경계를 이루며 운장산에서 대둔산으로 이어지는 큰 금남정맥 산줄기이기 때문에 이 백암산은 빨지산의 중요한 거점이며 요새였다. 빨치산 토벌을 위한 군경 합동작전으로 양측 모두 2천 5백명 이상의 귀중한 생명이 이 산에서 사라졌다. 이 작전을 기념하기 위하여 배티재 고갯마루에는 전승탑과 충혼비가 세워졌다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 남이면", + "MNTN_NM" : "백암산" + }, + "longitude" : 126.85083299999999, + "latitude" : 35.462778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백암산 하면 내장산국립공원에 속한 전남 장성 백암산(741.2m)과 경북 울진군 온정면에 자리한 백암산이 대표적이다. 장성 백암산은 백양사와 더불어 가을 단풍지로 각광받고 있지만 대체로 많은 이들이 울진 백암산을 먼저 떠올린다.산 정상부에 흰바위가 있어 백암산이라 이름 붙여진 1004미터 고봉은 국민관광지로 지정된 백암온천의 유명세 덕분에 많이 알려져 있다. 또한 신라시대 한 사냥꾼이 사슴을 쫓다가 발견했다는 백암산은 고려 공민왕이 난리를 피해 숨었던 산이라 전한다. 그러나 무엇보다도 백암산은 북쪽 검마산에서 이어져 남쪽 아랫삼승령으로 이어지는 낙동정맥의 한 산줄기로 험하지 않지만 위용있는 산세를 자랑한다.백암산의 대표적인 등산로는 크게 세 코스다. 숙박시설단지를 지나 능선을 타고 백암산을 오르거나 백암폭포를 지나 가파른 길을 따라 정상에 닿을 수 있다. 나머지 하나는 용소를 비롯한 12개의 소가 이어져 있다는 선시골계곡을 따라 오르는 길이다.백암산 꼭대기에 서면 동해바다가 한눈에 들어온다.바다에 차츰 붉은 기운이 감돌다가 불쑥 떠오르는 해돋이는 말 그대로 장관이다. 더욱이 맑은 날이면 멀리 울릉도까지도 눈에 들어온다.백암산 중턱에는 예부터 뛰어난 효험을 자랑하는 백암온천이 자리잡고 있다.", + "MNTN_HG_VL" : "1004", + "MNTN_LOCPLC_REGION_NM" : "경북 울진군 온정면, 영양군 수비면", + "MNTN_NM" : "백암산" + }, + "longitude" : 126.85083299999999, + "latitude" : 35.462778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백암산은 밀양군내 산내면산외면상동면의 경계를 이루는 괴곡마을 주산이다.이 산은 흙 색깔이 뿌옇다 하여 백암산 또는 흰덤산이라고도 한다. 백암산 정상은 헬기장으로 여름철에는 잡초가 무성한 관계로 산길방향을 잘 잡아야 한다.", + "MNTN_HG_VL" : "1004", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면, 산외면, 상동면", + "MNTN_NM" : "백암산" + }, + "longitude" : 126.85083299999999, + "latitude" : 35.462778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백양산은 부산의 등줄기를 이루는 낙동정맥의 주능선에 솟은 산이다. 부산을 가로지르는 낙동정맥은 금정산(801.5m), 상계봉(638m), 백양산(642m), 엄광산(503m), 구덕산(562m), 시약산(509m), 승학산(495m)을 거쳐 다대포 몰운대에 이르러 대한해협에 잠겨든다. 백양산은 이 정맥의 중심에 자리잡고 있어 부산의 심장부라 할 만하다. 지리적인 위치로는 부산진구와 북구, 사상구의 경계를 이룬다.산의 유래는 「동래부지」(1740년)에 백양사라는 절 이름이 나온다. 그러나 ‘백양산은 금용산에 있다’고 전한다. 금용산(149.6m)은 부산진구 초읍에서 연제구 거제동에 걸쳐있는 산이다. 전형적인 노년기 산지로 완만한 산세인데 서쪽 방향에서 백양산과 만난다. 기록으로 볼 때 백양산은 1740년 이후 금용산에서 분리된 듯하다.이후 이름을 가지지 못한 산은 절 이름으로 산 이름을 대신했던 것 같다. 동쪽 자락에 선암사가 있어 선암산이라 불리기도 하고 서쪽 자락에는 운수사가 있어 운수산이라고도 불렸다. 백양사에서 따온 백양산이란 이름도 함께 쓰이다가 점차 백양산으로 정착된 듯하다.", + "MNTN_HG_VL" : "642", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 부산진구, 북구, 사상구", + "MNTN_NM" : "백양산" + }, + "longitude" : 129.0264852, + "latitude" : 35.183268800000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백양산은 해발 642m로 부산의 등줄산맥인 금정산맥의 주능선에 솟은 산이다. 부산도심의 주요하천으로 우리나라 상수도의 시초가 된 성지곡수원지가 자리잡고 있으며, 동천의 발원지가 된다.백양산은 어린이 대공원 서쪽에 위치하고 있으며, 원래 금용산이라 불리어 왔다. 이산의 동편은 새미산인데 이 산은 사직동 사람들은 돌작동이라고 하며 산복에 배틀굴이라는 동굴이 있어, 임진왜란 때 연대주민이 피신하여 생명을 건진 곳으로 유명하다.들머리인 선암사는 신라 문무왕때 원효대사가 창건한 천년고찰이다. 창건 당시엔 낙동강이 보여 견강사(見江寺)로 불렸지만 경내에 화랑들이 수도를 했던 바위인 신선암이 널리 알려지면서 선암사(仙庵寺)로 명명됐다 한다.정상에서는 장쾌한 조망에 일순간 말문이 막힐 정도이다. 왼쪽엔 낙동강 물줄기와 황금빛 김해평야가, 오른쪽엔 서면시가지와 북항 등 부산전경이 한 눈에 잡힌다. 오른쪽 발밑엔 성지곡수원지와 하얀 사직주경기장이 눈에 들어온다. 시선이 자꾸 도심보다 낙동강과 김해평야 쪽으로 쏠린다. 부산 도심과 주변의 산들도 파노라마처럼 펼쳐진다.", + "MNTN_HG_VL" : "642", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 부산진구", + "MNTN_NM" : "백양산" + }, + "longitude" : 129.0264852, + "latitude" : 35.183268800000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "895", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 두촌면", + "MNTN_NM" : "백우산" + }, + "longitude" : 128.08235389999999, + "latitude" : 37.842965800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한마리의 새가 금방이라도 하늘을 향해 날아오르려 한껏 날개를 펼친 모습에 산새는 주변에 백암삼 가마봉 고적산 매봉산 송곳대산들이 서로의 자태를 뽐내고 있다.백우산은 높은산을 오를때와 같은 맛은 느낄수 없지만 올망졸망한 능선에 오르막 내리막이 재미있다.용소계곡에는 넓이 200여평의 작은 너래소,500여평큰 너래소를 비롯하여 자연경관이 절경이다.", + "MNTN_HG_VL" : "895", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면", + "MNTN_NM" : "백우산" + }, + "longitude" : 128.08235389999999, + "latitude" : 37.842965800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;새의 날개깃에 숨겨진 비경지대gt;홍천군 내촌면과 두촌면 경계에 있는 백우산은 한강기맥의 춘천지맥에 있는 백암산에서 서쪽으로 흘러나온 산이다. 겨울에 눈이 쌓이면 새가 하늘을 향해 날아오르려 날개를 펼친 것처럼 보여 백우산이라 부른다. 토질이 검고 부드러운 전형적인 육산이다. 인적이 드문 산이라 봄, 여름, 가을, 철따라 피는 여러 야생화를 볼 수 있다. 가족고개가 표고 550m 이므로 895m의 백우산 정상까지 힘들지 않게 올라간다. 하산은 홍천 9경의 하나이며 홍천강 발원지인 용소계곡(경수골)으로 하산하는 것이 좋다. 백우산 산행의 백미는 역시 용소계곡이다. 용소계곡은 남쪽의 백우산과 매봉, 북쪽의 가마봉과 소뿔산 사이로 굽이쳐 흐른다. 가족동에서 시작하여 천현리까지 봄철의 철쭉과 가을단풍 비경 30리가 이어지므로 계곡트레킹 자체만으로도 의미 있는 산행이다. 여름철 이곳에 오면 누가 권하지 않아도 다투어 옷 입은 채로 너래소에 뛰어든다. 가족고개 농가에서는 곰취, 곤드레, 야콘, 감자 등 친환경채소를 재배하면서 현지 판매도 한다. 내촌면 광암리 일원은 재래 토종벌 보호지역으로서 지역 내에 양봉 전사를 금지하고 있다.", + "MNTN_HG_VL" : "895", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 두촌면", + "MNTN_NM" : "백우산" + }, + "longitude" : 128.08235389999999, + "latitude" : 37.842965800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운봉은 양평읍에서 북동쪽으로 약 10km 떨어진 용문산 남쪽끝의 바위 봉우리이다. 높이가 940m로 주변의 용문산, 도일봉, 중원산 등과 함께 경기도 안에서는 비교적 높은 산으로 알려져 있으며 함왕봉과 능선으로 이어져 있다. 서쪽에는 함왕골, 동쪽에는 연수리계곡이 있으며 정상과 주능선에는 암봉이 많다. 함왕골에는 923년(경명왕 7)에 승려 대경이 창건한 사나사(舍那寺)가 있으며, 3층석탑, 대적광전, 원증국사비, 부도 등이 있다.능선은 골이 깊고 다향하여 매혹적이고 사적지가 많다. 잘 알려지지 않아 오염이 덜 되어 있고 호젓한 산행을 즐길 수 있다. 겨울철 하산길에 즐길 수 있는 자연 눈썰매코스가 매력적이다. 정상에서 남북으로 이은 주능선과 지능선마다 소나무와 암봉들이 조화를 이루고 있고 높은 암봉으로 이루어져 있으며, 앞이 탁 트이고 멀리 운악산, 용문산이 보이며 남쪽으로는 남한강 줄기가 보인다. 능선에는 철쭉, 단풍나무, 고목들이 우거져 있고 비좁고 험한 급경사길이 있다.", + "MNTN_HG_VL" : "936", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 양평읍, 옥천면, 용문면", + "MNTN_NM" : "백운봉" + }, + "longitude" : 127.52611109999999, + "latitude" : 37.533611100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "255", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우리나라의 산이름 중에 백운산 이라는 이름을 가진 산이 많다.그 중에서\"흰구름산\"이라는 이름값을 제대로 하는 산이 함양의 백운이다.높이도 1000 m 가넘는 준봉인데다 산정에서의 조망도 으뜸이라 할수있다. 남도의 명산이라 일컫는 산들이 동서남북 어떤 방향에서도 거칠것없이 한눈에 들어온다.노고단에서 천왕봉까지 남쪽 스카이라인의 지리산 파노라마는 그리움의 경지를 넘어 성스러움을 느끼게 한다. 반야봉의 자태는 너무 뚜렷해 민망스럽기까지 하다.북쪽 끄트머리에는 넉넉한 덕유산이 태평스레 앉아있고 그너머에는 황석, 거망, 월봉 산이 어깨를 맞대고 있다. 금원산 기백산도 지척으로 보이고 동북 방향으로는 가야산, 황매산도 가물거린다.백운산은 명산에 둘러싸여 명산과 어깨를 나란히 하는 이 지방 최고의 진산이다. 겹겹이 둘러싼 능파들 사이사이로 흰구름이 부리는 조화는 백운산만이 연출해 낼 수 있는 활동사진. 산세 또한 전형적인 육산이기에 사계절 내내 산행이 가능한 것이 이 산의 매력이다.", + "MNTN_HG_VL" : "1279", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 백전면", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운산(시흥)은 바라산, 광교산과 능선으로 연결되는 이웃한 산으로 능선은 매우 한적한 편이다. 경기도 의왕시의 백운저수지의 뒷산인 해발 567m의 산으로 서울특별시에서 가까워 찾기 쉬운 산이다. 백운 저수지에서 산행할 경우 임도를 이용한 한적한 산행이 가능하다. 주능선 길은 산행하기에 좋으며 소나무가 많다.", + "MNTN_HG_VL" : "567", + "MNTN_LOCPLC_REGION_NM" : "경기도 시흥시, 용인시, 수원시", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1218", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제천 백운산은 바로 옆 치악산의 그늘에 가려 등산인들에게 널리 알려지지 않았다. 그러나 그만큼 찾는 이가 드물어 등산로의 훼손이 적고 오염이 덜 되었으니 호젓하고 쾌적한 산행을 즐길 수 있다.서쪽에서부터 십자봉(984.8m), 조두봉(966.6m), 백운산(1,087.1m), 보름갈이봉(860m), 수리봉(909.9m), 벼락바위봉(937.6m)으로 이어지며 1000미터를 넘나드는 산줄기가 거대한 성곽처럼 도열해 제천시의 북쪽을 굳건히 지키고 선 모습은 가히 장관이다. 이 산들은 제천시계종주코스이기도 하다.백운산의 빼어난 점은 뭐니뭐니 해도 눈앞으로 펼쳐지는 일본잎갈나무(낙엽송) 조림지의 광대한 조망과 산길의 한적함이다. 북쪽인 원주 방면으로도 군데군데 보이지만, 남동쪽인 백운면 자락은 온 천지에 바늘을 꽂아둔 듯 빈틈없이 조림된 잘 자란 낙엽송 군락지가 시원하다. 백운산을 올라보면 당장 느낄 수 있지만 제천시민의 숲에 대한 보살핌과 정성, 자부심은 대단하다. 전국에서도 임도시설이 발달해 있기로 소문난 곳이기도 하다. 제천의 어느 산을 오르든지 잘 정비된 임도를 만나게 된다. 숲은 전체적으로 간벌이 잘 되어 있어 답답하지 않고 매우 건강하다.", + "MNTN_HG_VL" : "1087", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 백운면", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백운산은 가지산(실혜산)의 앞가슴에 해당되는 산으로 산 전채가 한 조각의 흰구름처럼 보이는 화강암으로 이루어져 있어 얻어진 이름이다. 주위의 큰 산에 가려져 이름이 나지 못했으나 정상 부근에는 온통 기암괴석으로 이루어져 경관이 빼어나며, 등산로는 아주 호젓하다. 바위봉으로 우뚝 솟은 정상을 보면 마치 중국에 있는 황산을 보는 듯한 느낌이 든다. 더구나 봄에 이곳을 다녀가면 진달래와 철쭉이 만발하여 더욱 운치를 느낄 수 있다 하여 백운산은 봄산이라는 말도 있다.산의 동편 하단부에 유명한 시례 호박소 가 있고, 동편 산허리에 구룡폭포가 있으며 서편에는 우리 나라 굴지의 산내 중석광이 있다. 남쪽 건폭은 일년 내내 산악인들의 암벽등반 훈련장이 되고 있다.", + "MNTN_HG_VL" : "885", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 울주군에 위치한 백운산은 열박산이라 부르기도 한다. 신라 김유신은 나이 17세 때 적군의 침공을 당하자 비장한 마음으로 혼자서 보검을 들고 열박산 깊은 골자기 속으로 들어가 향을 피우며 기를 모아 적을 물리칠수 있는 힘을 내려달라고 하늘에 빌었다는 이야기가 전해온다.산행 들머리는 언양에서 다개차리로 가는 버스를 타고 상차리에서 시작하면 된다. 백운산 정상은 대체로 칼등처럼 뾰족한 형상을 보이고 있다. 또한 바위군에 올라서서 바라보는 전망도 대단하다. 오른쪽은 옛날 기우제를 지냈던 아미산, 왼쪽에 문복산가지산, 남으로 고헌산, 북으로 삼강봉이 지척에 보인다.", + "MNTN_HG_VL" : "892", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "191", + "MNTN_LOCPLC_REGION_NM" : "경기도 평택시", + "MNTN_NM" : "백운산" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두산에서 시작되는 백두대간은 동해안 따라 뻗어 내리다 강원도 태백 피재에서 남서 향으로 방향을 틀어 한반도의 내륙을 따라 남해안으로 달려간다. 백운산은 백두대간에서 뻗어 나온 호남정맥이 남해바다로 잠들기전 마지막 힘을 다해 밀어 올린 산으로, 호남정맥의 최고봉이다.섬진강을 사이에 두고 지리산과 남북으로 마주보고 있는 백운산은 정상에서 서쪽으로 또아리봉(1127m),도솔봉(1153.2m)이, 동으로는 호남정맥으로 이어지는 매봉(866.9m)이, 남으로는 억불봉(1,007.5m)을 거느리고 있는 큰 산맥을 이루고 있다. 백운산 아래 옥룡면은 삼면이 산줄기로 둘러싸인 큰 골짜기로 남쪽만 열려 있는 자루 모양을 하고 있다. 이 골짜기를 불당골이라고 부를 만큼 불교 흔적이 많은 곳이다.지리도참설과 풍수사상의 원조라 할 수 있는 도선국사가 37세부터 35년 동안 옥룡사(지금은 남아 있지 않음)에서 주로 기거하다, 72세에 이 절에서 입적하였다. 백운산 산행기점인 동동 마을 왼쪽 옥룡사 터가 있는 백계산(505.8m)에 도선국사가 심었다는 동백 숲이 천연기념물로 지정되어 있다. 이 산에는 고로쇠나무가 많이 자라고 있는데, 예로부터 고로쇠나무에서 나온 수액이 만병통치약이라고 하여 경칩을 전후로 하여 많은 사람이 백운산을 찾아오고 있다.", + "MNTN_HG_VL" : "1222", + "MNTN_LOCPLC_REGION_NM" : "전라남도 광양시 봉강면ㆍ옥룡면ㆍ진상면ㆍ다압면, 구례군 간전면", + "MNTN_NM" : "백운산(광양)" + }, + "longitude" : 127.621944, + "latitude" : 35.107222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동강을 끼고 있는 백운산. '태고의 신비'와 '천혜의 비경'까지 갖춘 동강은 강원도 산 속 깊숙이 숨어서 말없이 흘러가고 있다. 그래서 일까. 백운산 산행은 마치 신선이 된 듯한 기분을 선사해준다.백운산 산행을 위해서는 동강을 건너야 한다. 그리고 산행을 마쳤을 때도강을 건너와야 한다. 하지만 물을 건너지 않고 아예 칠족령에서 문희 마을로내려선뒤 보트를 타고 섭새까지 내려오는 방법도 있다. 산과 강을 동시에즐기는 코스다. 하지만, 백운산 산행은 점재 마을에서 시작하는 것이 일반적이다.", + "MNTN_HG_VL" : "884", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 신동읍, 평창군 미탄면", + "MNTN_NM" : "백운산(정선)" + }, + "longitude" : 128.59615439999999, + "latitude" : 37.280543999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 포천군 이동면과 강원도 화천군 사내면의 경계를 이루는 백운산은 부드러운 산세와 해발 660m 인 광덕고개에서 산행이 시작되므로 가볍게 산행을 즐기려는 사람들이 많이 찾는다. 주말을 이용해 가족과 함께 등반을 하기에도 적격인 곳이다.광덕고개는 일명 '카라멜고개'라고 불리는데, 그렇게 불리는 데는 두 가지 설이 있다. 첫 번째 설은 도로가 비포장이었던 6.25때 이 지역을 관할하던 사단장이 광덕고개를 오를 때면 운전병의 졸음을 쫓기 위해 운전병에게 카라멜을 먹게 한 데에서 유래되었다는 것이다.두번째 설은 광덕고개의 꾸불꾸불한 모양이 낙타의 등을 연상케 한다고 해서, 카멜(Camel: 낙타)이 카라멜로 변하여 카라멜고개로 불리게 되었다는 것이다.백운산 정상 서쪽 아래로 4km에 이르는 백운계곡은 풍부한 수량과 빼어난 계곡미를 자랑한다. 계곡 곳곳에 넓적한 바위가 널려있어 아무데고 앉으면 쉼터가 될 정도로 등산인들이 쉬어가기 좋은 곳이다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", + "MNTN_NM" : "백운산(포천)" + }, + "longitude" : 127.4440759, + "latitude" : 38.0746477 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백원산은 육산으로 상주 안산의 하나이며 이 산의 조산은 갑장산이다. 일명 국사봉이라고도 한다. 서쪽 기슭에는 도곡서당과 도림사가 있고 동쪽 기슭에는 천연 기념물 제69호인 구상화강암이 분포되어 있다.거북돌이라고도 부르는데, 조선 후기에 처음 발견되었다. 화강암이고, 모양이 거북이 등처럼 생겼다. 세계에서도 100여 곳밖에 발견되지 않았으며, 특히 이곳의 구상화강암은 구조가 뚜렷하고 모양이 아름답다. 일부는 현재 상주시청에서 보관하고 있다. 서쪽 기슭에는 도곡서당과 도림사가 있다. 전해 내려오는 이야기로는 산 아래에서 나옹(혜근)이 태어났다고 하지만 확실한 위치는 알 수 없다.", + "MNTN_HG_VL" : "524", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 인평동, 거동동", + "MNTN_NM" : "백원산" + }, + "longitude" : 128.1886111, + "latitude" : 36.347222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백월산은 동서 2km, 남북 4km, 높이 약 394m의 도상구릉(島狀丘陵)을 형성하고 있다. 백월산의 정상부는 남북 20m, 동서 15m 규모의 평정봉(平頂峰)으로서 두꺼운 토양층으로 피복(被覆)되어, 암석 미지형은 전혀 나타나지 않고 있다. 그러나 정상 북측의 해발고도 300m~350m 높이 주변지역에는 화강암지역에서 찾아볼 수 있는 일반적인 암석 미지형들이 분포하고 있는데 이 미지형들은 주로 직경 2m 내외 원형의 집단적인 토르(tor)와 토르의 상층부에 형성된 30cm 내외의 폭의 그르부 및 4~5m 높이의 암주들로서 판상의 수직 및 수평절리들의 간격이 2m 규모로 발달하였기 때문에 나타난 현상이다. 암석 미지형이 집단적으로 분포하고 있는 곳의 해발고도 250m 지점의 산록에는 높이 10m, 폭 13m, 경사 60~65˚에 이르는 암석단애를 중심으로 암석의 급사면이 나타나고 있는데 이러한 현상은 수직에 가까운 사절리들이 발달하고 있기 때문이다. 한편 직경 3~5m 크기의 원형에 가까운 토르들이 3~5개 정도가 집단으로 기반암의 풍화충인 새프롤라이트와 토양층 위로 노출되어 토르를 덮고 있는 풍화층들이 장구한 세월동안 풍화와 침식으로 제거되었음을 나타내주고 있다.옛날에 홍성 지방의 용봉산과 백월산에 각각 장수가 살고 있었다. 이 장수들 사이에는 소향이라는아주 예쁜 처녀가 살았는데 장수들은 서로 이 소향이를 짝사랑하고 있었다. 장수들은 소향이를 차지하기 위해 서로 자기가 있는 산의 돌을 상대방 산에 던지기 시작하였다. 치열한 싸움이 계속되고 용봉산에 점점 돌이 쌓였다. 백월산 장수가 더 많은 돌을 던졌기 때문이다. 결국 백월산장수가 이겨서 소향이를 차지하게 되었고 홍성읍과 홍북면 사이에 있는 소향리는 백월산이 위치하는 홍성읍에 포함되게 되었다. 용봉산 장수는 싸움에서 지긴 했지만 백월산 장수가 던진 기암괴석들 덕분에 현재 전국에서 많은 관광객이 방문하고 있다.", + "MNTN_HG_VL" : "394", + "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군", + "MNTN_NM" : "백월산" + }, + "longitude" : 126.6222222, + "latitude" : 36.607777800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "394", + "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군 홍성읍 월산리, 구항면 오봉리, 홍북면 중계리", + "MNTN_NM" : "백월산" + }, + "longitude" : 126.6222222, + "latitude" : 36.607777800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "428", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시", + "MNTN_NM" : "백월산" + }, + "longitude" : 126.6222222, + "latitude" : 36.607777800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "백이산" + }, + "longitude" : 128.3497222, + "latitude" : 35.2347222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함안군", + "MNTN_NM" : "백이산" + }, + "longitude" : 128.3497222, + "latitude" : 35.2347222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "486", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시", + "MNTN_NM" : "백자산" + }, + "longitude" : 128.74805559999999, + "latitude" : 35.786666699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "석영과 석회석이 혼합된 흰색의 바위가 많이 쌓여 있어 백적산이라는 이름이 생겨났고, 흰적산이라고도 부른다. 바위들은 날씨가 궂으면 검게 보이고 날씨가 개이면 희게 보인다고 하며, 바위 틈에는 크고 작은 뱀들이 서식하고, 힘을 솟게 한다는 샘이 있다고 한다.강원도 평창군 대화면과 진부면의 경계에 있는 백적산은 사람들의 발길이 닿지않아 원시림이 울창한 산이다. 백두대간의 주맥인 오대산에서 지맥으로 갈래쳐 계방산 동쪽 2km지점에서 남하하여 영동고속도로를 건너 뛰어 백적산을 솟구치고 그 아래로 백석산(1365m), 가리왕산(1561m), 청옥산(1256m)을 일구어 놓았다.산 곳곳에 상여바위(수리바위),삼형제바위(통관바위)등 기암괴석이 있으며 백적산 정상은 사방천지의 산들이 모두 뚜렸하게 펼쳐지므로 그야말로 하늘에 오른 느낌이다. 사방의 산들이 맑은 하늘아래 모두다 선명하게 드러내니 백적산을 찾은 보람을 완전히 만끽하는 순간이다.", + "MNTN_HG_VL" : "1141", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", + "MNTN_NM" : "백적산" + }, + "longitude" : 128.4913889, + "latitude" : 37.591111099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;널찍하고 호젓한 주민들의 산책코스gt;조선 세조가 이곳을 지나다가 발(足)을 씻었는데 발이 희게 보였다하여 붙여진 이름이다. 자세한 연혁이나 사료가 없기 때문에 발을 씻은 장소가 정확히 어디인지는 분명치 않다. 산의 형상이 백가지 줄기로 뻗어나 마치 지네의 발과 같은 형상을 닮았다고 해서 지어진 이름 이라고도 알려져 있지만 경기도 이천의 백족산과 혼동해서 생긴 듯하다. 청주로 가는 32번 국도변에서 백족산의 둥그스름하고 펑퍼짐한 산세를 확인할 수 있는데 그 모습이 ‘순둥이’ 모양이라 지네의 모습과는 비슷하지 않다. 백족산은 널찍하고 평평한 능선, 울창한 소나무 숲으로 근교의 주민들에게 산책코스로 사랑받고 있다. 가파르지도 않거니와 정상부의 호젓한 산길이 하루 반나절, 운동 삼아 오르내리기에 부담 없기 때문이다. 백족산 정산 직전, 선두산으로 이어진 산길이 있다. 그 길을 따라가면 바로 금북정맥의 능선을 탈 수 있다. 산행이 심심하다면 선두산, 선도산을 거쳐 상당산성까지 종주산행도 가능하다.", + "MNTN_HG_VL" : "413", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 가덕면 한계리", + "MNTN_NM" : "백족산" + }, + "longitude" : 127.60416669999999, + "latitude" : 37.097222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백족산은 청원군 가덕면 상야리에 위치한 충청북도 자치연수원 뒤편에 우뚝솟은 산이 백족산이다.이산은 빼어나거나 절경을 이룬산은 아니지만 등산하기엔 좋은 편이라 산아래 교육원의 교육생들의 극기훈련장소로 많이 이용되고 있으며,가볍게 등산하기엔 좋은 산이다.", + "MNTN_HG_VL" : "402", + "MNTN_LOCPLC_REGION_NM" : "충북 청원군 낭성면 추정리", + "MNTN_NM" : "백족산" + }, + "longitude" : 127.60416669999999, + "latitude" : 37.097222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "412", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시", + "MNTN_NM" : "백족산" + }, + "longitude" : 127.60416669999999, + "latitude" : 37.097222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "413", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 가덕면 한계리", + "MNTN_NM" : "백족산" + }, + "longitude" : 127.60416669999999, + "latitude" : 37.097222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영동군 학산면과 무주읍에 걸쳐 있는 백하산은 하얀 노을, 하얀 이내라는 뜻으로 노을이 아름다운 산이다. 백하산 줄기는 영동에서 학산을 거쳐 무주로 이어지는 19번 국도와 나란히 뻗쳐있어 차를 타고 가며 계속 그 모습을 올려다 볼 수 있다.백하산은 북쪽에서 보면 그저 거하고 짙푸른 산이지만 산에 들어서면 곳곳에 까마득한 바위 낭떠러지가 많다.동쪽 끝 여의재 남쪽에는 여의 저수지가 있으며 서쪽 끝 압재 북쪽에는 봉황저수지가 있다. 19번 국도가 백하산 아래를 지나 돌아가기 때문에 백하산 산행을 위한 교통은 편리한 편이다.백하산 아래의 안삼마을은 큰 길가 삼정마을의 일부로 산골짜기 안에 있는 삼정이라 해서 안삼이라 한다. 마을 들머리에는 명절 때 풍년과 마을의 무고를 기원하는 도랑제를 모시는 반신 석상이 있다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동 학산면,전라북도 무주", + "MNTN_NM" : "백하산" + }, + "longitude" : 127.6891667, + "latitude" : 36.062777799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해제면 서쪽에 위치한 해발 126M되는 산으로 서해바다와 영광 낙월도,각이도 등이 보이는 곳이며 산 바로 아래가 서해안 바다여서 넓은바다가 한눈에 보인다. 과거 이 산은 동백나무가 많은 산으로 동백꽃이 필 때면 산 전체가 동백으로 만발하였다고 한다. 고려말에 고씨 성을 가진 스님이 발견했다는 동굴 2개가 마을에 있는데 동굴 하나는 물속에 용왕님에게 가는 굴이고, 다른 사나는 용왕의 아드링 육지와 바다를 드나들던 굴이었다 한다. 어느 해에 심한 가뭄이 들어 물속에 있는 용왕에게 불공을 드려 비가 오게 해달라고 빌자 갑자기 소나니가 쏟아져 가뭄을 해갈시켰다. 이때 소나기를 내린 물속의 대사는 용왕님 몰래 비를 내리게 했다하여 용왕의 노여움을 사서 학이 되어 흰구름을 타고 어디론가 사라졌다고 한다. 이 후 마을의 산에 흰 학이 많이 서식하여 산이름을 백학산이라 부른다 한다.", + "MNTN_HG_VL" : "126", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 해제면 대사리", + "MNTN_NM" : "백학산" + }, + "longitude" : 128.0318188, + "latitude" : 36.3465907 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화원읍 사무소에서 북쪽으로 긴 산이 보이는데 이를 뱀산이라 하고,서쪽으로 양반산, 그 중간에 고속도로때문에 일부만 남은 개구리산이 있다. 옛날에 뱀산의 뱀이 개구리산의 개구리를 잡아 먹으려고 고개를 내 뻗으니 뒤에 앉았던 양반산의 양반이\"예끼놈 그만 두어라\"고 무릎을 치며 호통을 쳤다. 호통에 놀란 뱀은 고개를 획하고 돌리고 있는 모양이다. 완만한 지형과 낮은 지세로 노약자분들에게도 쉽게 이용할 수 있는 산이다. 특별한 경관은 없지만 주변에 테니스장과 배수지 앞의 공원때문에 주변 주민들의 이용이 잦은 곳이다.", + "MNTN_HG_VL" : "91", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 구라리", + "MNTN_NM" : "뱀산" + }, + "longitude" : 127.6416667, + "latitude" : 37.026111100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "840", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", + "MNTN_NM" : "번암산" + }, + "longitude" : 127.4731841, + "latitude" : 38.076925699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 삼척시 가곡면 덕풍마을을 기점으로 부채살처럼 패어든 골짜기가 4개 있다. 이 중 계곡이 가장 길고 깊은 용소골 최상단부에 응봉산(998.5m)이 솟아 있는데 응봉산에서 북서쪽으로 용소골과 보리골 사이로 가지를 쳐 나가는 지능선에서 보리골이 덕풍계곡에 합수되는 지점에 솟아 있는 626m봉이 바로 범바위봉이다.이 용소골 문턱에 자리잡고 있어 오는 사람마다 쭈르르 용소골 골짜기로 무작정 올라가는 바람에 범바위봉은 올라가는 사람들을 구경하기도 바쁘다. 그래서인지 산길도 흐릿하여 잘못하면 길을 잃고 헤매는 수가 많다. 여팔곡은 계곡과 능선이 거미줄 혹은 나뭇잎 줄기 같아 능선 하나를 잘못 고르면 몇 십리를 돌아야 한다. 이 과정에서 사고를 당하기 십상이다.", + "MNTN_HG_VL" : "626", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "범바위봉" + }, + "longitude" : 128.0192103, + "latitude" : 37.244361699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "범암산은 강원도 화천군 사내면 광덕리에 위치한 산이다. 일반적으로는 번암산으로 더 알려져 있지만 이것은 잘멋 전해진 이름으로, 옛날 범이 바위에 자주 오르는 것을 보고 붙인 이름이라는 것이 광덕리 주민들의 의견이다.아직은 널리 소개되지 않은 편이라 훼손되지 않은 모습을 많이 간직하고 있다. 봄이면 연분홍 철쭉의 화사함이, 여름 이면 하얀 산목련의 청초함이 그 아름다움을 더해주기도 한 다. 산새가 험하거나 그다지 높지 않은 편이어서, 가족산행 을 하기에는 안성맞춤이다.뾰족 솟은 정상에 오르면 멀리 화악산과 석룡산이 보이고 명지산,국망봉,도마치봉이 파노라마처럼 펼쳐진다. 아주 널따란 바위가 누워있는 것도 다른 곳에서는 볼 수 없는 진풍경이다.", + "MNTN_HG_VL" : "832", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", + "MNTN_NM" : "범암산" + }, + "longitude" : 127.4731841, + "latitude" : 38.076925699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 구미시에 위치한 베틀산은 역암, 사암의 풍화 혹은 해식 작용으로 기이한 형태의 암석모양(큰상어굴, 작은 상어굴, 베틀굴)과 색상을 나타내고 있으며 해변가에서 느끼는 침식 현상을 여러 곳에서 볼 수 있다. 산은 그리 높지 않으나, 산세가 아기자기하고 암릉과 해식굴(海蝕窟) 등이 산재하여 산행이 재미있다.베틀산은 예전에 조계산이라고 불리었다. 문익점의 동생인 문영이 산의 모양과 해평면 오상리에 있는 공상다리의 모양을 따서 베틀을 만들어 문영베를 짜는 데 성공한 이후, 산이름이 조계산에서 베틀산으로 바뀌었다고 전해진다. 그밖에 어느 선비가 과거를 보러 한양으로 가는데 산 위에서 여인의 베짜는 소리가 들려왔다거나, 임진왜란 때 많은 사람들이 베틀굴에 피난하여 베를 짰다는 전설 등이 전해진다.", + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 금산리", + "MNTN_NM" : "베틀산" + }, + "longitude" : 128.4422836, + "latitude" : 36.206698400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제천시 백운면은 원주시에 둘러싸이다시피 에워싸여 있는 지역이다. 지형상 백운산이 날개를 펼친 듯한, 더 정확히 말하면 바가지를 엎어놓은 듯한 모양을 하고있기 때문이다. 그래서 바가지속의 백운면은 육지의 고도같은 느낌을 강하게 준다.서쪽은 구학산(971m)에서 벼락바위봉(939m), 백운산(1087m), 십자봉(985m),이 둥그렇게 원을 그리다시피 장벽을 그리고 있는 데다 동서 두 가닥의 맥은 각각 남으로 다시 뻗어 원을 완성하다 시피 한다. 북쪽 가파른 계곡에는 치악산 자연휴양림이 조성되어 있다.산세는 전체적으로 부드러운 편이지만, 정상부는 바위 절벽으로 이루어졌기 때문에 치악산쪽 전망이 좋고 비로봉 등도 관망할 수 있다. 자연휴양림에서 정상으로 오르는 길에 칠성바위, 거북바위 등 기암괴석을 볼 수 있고, 지름이 50cm 되는 삼각형의 좁은 바위구멍이 있는 구멍바위(산파바위)를 볼 수 있다.", + "MNTN_HG_VL" : "939", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", + "MNTN_NM" : "벼락바위봉" + }, + "longitude" : 128.0192103, + "latitude" : 37.244361699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통영 최고봉이라는 수식어와는 달리 멀리서 본 벽방산(碧芳山)은 눈에 잘 띄지 않는 산이다. 남해안에서 흔히 마주치는 평범한 산세이기 때문이다. 그러나 겉에서 본 산과 막상 들어갔을 때 감흥이 틀린 것이 벽방산이다. 의상대사의 자취가 남은 고찰과 아늑한 골짜기, 시원한 전망의 암봉 등 어디하나 빠지지 않는 산이다.벽방산은 벽발산(碧鉢山)이라고도 부른다. 석가의 십대 제자 중 한 사람인 가섭존자(迦葉尊者)가 벽발(碧鉢 바리때)을 받쳐 들고 있는 모습과 닮아서 생긴 이름이다.정상은 상봉(上峰) 또는 칠성봉(七星峰)이라고도 부른다. 정상 부근에는 진달래가 많아 4월 중순이면 절정을 이룬다. 정상 조망은 다도해를 비롯해 부산 앞바다가 보이며, 맑은 날에는 대마도까지도 볼 수 있다. 안정치로 내려오면 대나무 밭에 이른다. 이곳이 만리암터이며, 이 위에 솟아 있는 절벽이 만리창벽이다.벽방산에서 빼놓을 수 없는 것이 안정사다. 신라 태종무열왕 원년(서기 654)에 원효대사가 창건하여 현재까지 1400여년 동안 이어오고 있는 고찰로 대웅전은 도문화재로 지정되어 있다. 안정사 부근은 조선 영조 때 사찰 주변의 적송을 보호하라는 어송패가 내려질 만큼 소나무들이 운치 있다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "경남 통영시 광도면, 고성군 거류면ㆍ고성읍", + "MNTN_NM" : "벽방산" + }, + "longitude" : 128.3690746, + "latitude" : 34.959345499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "벽암산은 정선군 남면 별어곡과 신동읍 예미를 잇는 마차치고개가 산행 기점이다. 마차치고개 마루턱에서 서쪽으로 500미터쯤 내려간 곳에 마차치고개 식당이 있다. 북쪽 콘크리트길로 들어서 두 번째 삼거리인 광덕재에서 동쪽 능선으로 25분쯤 오르면 밭과 묘가 있는 안부에 이른다. 이 안부에서 15분쯤 올라서 840봉에 닿으면 능선이 둘로 갈라진다. 여기서 벽암산으로 가는 동쪽 능선은 보이질 않는다.벽암산으로 오르려면 눈에 잘 띄는 북릉으로 가지 말고 동쪽의 급경사를 내려서야 한다. 이내 능선이 나타나며 안부에 닿는다.정상에 오르니 작은 헬기장에는 삼각점과 작은 비닐코팅판이 걸려있고 나무들에 둘러싸여 조망은 막혀있다.하산은 정상에서 동남 쪽 능선을 따라간다. 능선 오른편으로 계곡이 세 개 갈라진다. 첫 번째 계곡이 통노구골, 두 번째가 금골, 세 번째가 절골이다. 세 번째 계곡인 절골로 내려서면 수광암에 닿는다.", + "MNTN_HG_VL" : "923", + "MNTN_LOCPLC_REGION_NM" : "강원 정선 남면", + "MNTN_NM" : "벽암산" + }, + "longitude" : 128.68777779999999, + "latitude" : 37.277777800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "522", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의령군", + "MNTN_NM" : "벽화산" + }, + "longitude" : 128.2276621, + "latitude" : 35.300024800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산세의 수려함은 덕유산을 닮고 골짜기와 기암의 조화는 뭍명산 못지 않으니 이 산이 바로 경남 거창군에 거창읍에 자리한 별유산이다. 이 산은 우두산, 의상봉이라고도 불린다. 우두산은 일본 개국신화와 관련된 전설의 산이며 의상봉은 신라 문무왕 때 의상대사가 과거세와 현세에서 참선한 곳이라는 뜻에서 의상대사 이름을 빌려 산 이름으로 삼았으며, 속세를 떠나 별유천지비인간이라 할 만큼 경치가 빼어 난 돌부리 산이다. 그 중에서 의상대사가 참선하던 곳으로 알려진 의상봉, 처녀봉, 장군봉, 바리봉, 비계산 등이 빼어난 산세를 자랑한다.이 산은 당일 산행이 가능하며 원점으로 되돌아 올 수 있도록 등산로가 이어져 있는 것이 특징이다. 산 곳곳에는 볼거리가 산재해 있는데 그 중 고견사와 가정산 폭포, 최치원 선생이 심었다는 은행나무, 의상대사가 쌀을 얻었다는 쌀굴등이 있다. 고견사는 견암사에 뿌리를 두고 있는 절로 덕유산 지봉의 해인터에 이어 거창의 두 번째 해인터이다. 절을 지을 때 쌓아 올렸던 신라 때의 석축이 눈에 들고 고운 선생이 심었다 하는 은행나무와 만든 때가 새겨진 범종과 석불 의상대사가 수도할 때 두 사람분의 쌀이 나왔다 하는 쌀굴과 십이지신상석이 있다.산행과 더불어 역사와 경관을 맛볼 수 있다. 별유산 정상 남쪽턱밑 억새밭께에서 만나는 별유샘도 꼭 들러가야 할 코스 중에 하나이다. 별유산 산행 후 가조 온천에서 온천으로 피로를 풀 수 있어서 주말이면 등산객의 발길이 이어진다.", + "MNTN_HG_VL" : "1046", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", + "MNTN_NM" : "별유산" + }, + "longitude" : 128.0437507, + "latitude" : 35.7519122 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "병무산(兵無山 920m)은 지난봄 찾았던 발교산(髮校山 998m)과 맥락을 같이 하는 산이다.즉 차령산맥중의 지맥에 속하는 산으로서 망고개를 경계로하여 발교산과 어깨를 나란히 하면서 남쪽으로 우뚝 솟아있는 것이다. 강원도 소재의 오지의 산답게 등산코스를 개발한지 얼마되지 않아 등산객들의 왕래가 적은 이 산은 한적한 산행지로 적합하다. 이름난 산속에서 볼 수 있는 고찰도, 잘 다듬어진 등산로도 찾아보기 힘들지만 수풀과 바위 사이를 헤짚고 가는 산행의 묘미가 일품이다.", + "MNTN_HG_VL" : "920", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면, 청일면", + "MNTN_NM" : "병무산" + }, + "longitude" : 128.0997222, + "latitude" : 37.641111100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 북실리", + "MNTN_NM" : "병방산" + }, + "longitude" : 128.6333333, + "latitude" : 37.348888899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "담양의 명산인 병풍산은 담양군의 산 가운데 가장 높은 산으로 일명 용구산이라고도 한다. 담양군 수북면 소재지에서 이 산을 바라보면 왜 병풍산이라 했는지 쉽게 짐작할 수 있다. 오른쪽 투구봉을 시작으로 우뚝 솟은 옥녀봉, 중봉, 천자봉을 거쳐 정상인 깃대봉과 신선대까지 고르게 뻗은 산줄기는 한눈에 보아도 틀림없는 병풍이다.정상에서의 조망은 장관을 이루어 ‘강동8경’이라 한다. 북으로 내장산, 백암산, 입암산이 보이고 추월산, 담양읍내는 물론 지리산도 시야에 들어온다. 북동에서 남서쪽으로 길게 뻗은 병풍산은 등줄기 양옆으로 무수히 많은 작은 능선이 있는데 이 능선 사이에 일궈진 골짜기가 99개에 달한다.특히 한재골은 기암괴석과 푸른 송림 등 갖가지 수목이 울창하게 우거져 천혜의 경관을 자랑하고, 가을 단풍과 겨울 설경은 기이한 아름다움을 지니고 있다. 광주와 가까운 이곳은 매년 관광객이 증가하고 있어 야영지, 체육시설, 풀장, 조경시설 등을 갖추어 가고 있다.", + "MNTN_HG_VL" : "826", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 수북면, 월산면ㆍ장성군 북하면", + "MNTN_NM" : "병풍산(용구산)" + }, + "longitude" : 126.90273070000001, + "latitude" : 35.338191600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보광산은 산세가 빼어나거나 경치가 좋고 기이한 바위가 있는 그런 산은 아니다. 그저 나즈막한 육산에 불과하다. 그러나 정상의 봉학사지에 얽힌 전설이 현실에서의 인간 욕심이 무상하다는 것을 일깨워 주는 곳이기도 하다. 또한 접근이 용이하고 험하지 않아 가족단위로 등산할 수 있는 좋은 산이다.원래 이름은 봉학산이었다가, 조선 중기부터 보광산이라고 부른다. 정상에는 봉학사 터가 있다. 사찰 건물은 남아 있지 않으나, 괴산봉학사지오층석탑(충북유형문화재 29)이 전해진다. 고려 때의 작품으로 추정되며, 일제강점기 때 무너졌던 것을 1967년 복원하였다. 산 아래에는 봉학사의 후신인 보광사가 자리잡고 있다.보광사는 없어진 봉학사의 후신으로 그 명성을 간직하여 오고 있으며 봉학사지 석조여래상을 대웅전에 주존불로 모시고 있다. 대웅전 처마끝에서 보면 끝없이 펼쳐지는 낮은 산들이 손에 잡힐 듯 친근해 보이고 마음까지도 시원해 지는 곳이다. 대웅전 오른쪽 바위 밑에선 석간수가 샘솟는데 아무리 가물어도 넘쳐 나는 샘물이 맛 또한 그만이다. 흔적도 없이 사라진 절터에 홀로 남은 봉학사지 5층석탑은 고려초기의 작품으로 추정되며 지방유형 문화재로 지정되었다는 안내판이 있다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 사리면", + "MNTN_NM" : "보광산" + }, + "longitude" : 127.6807002, + "latitude" : 36.821610300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "330", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "보납산" + }, + "longitude" : 127.4686111, + "latitude" : 37.694722200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보래봉은 강원도 평창군 봉평면 북쪽의 한 봉우리이다.\"\"메밀 꽃 필무렵\"\"의 이효석이 태어난 곳이고 이 소설의 무대가 바로 봉평면과 대화면이다. 진입로에 가로수가 없고 메밀을 심는다. 메밀꽃이 피는 여름에는 특히 물이 맑다.평창군은 해발 300-800미터 이상의 고랭지대로 이루어져 있는데 봉평면은 해발 600-800m의 고냉지대이다.이러한 봉평면 일원은 지대가 높고 추운 곳이어서 적설량이 풍부해 특히 겨울철산행을 즐기기에 좋은 산이다.부근에는 이효석의 동상과 소설에 관련된 곳들을 찾아볼 수 있다.", + "MNTN_HG_VL" : "1324", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면", + "MNTN_NM" : "보래봉" + }, + "longitude" : 128.3663889, + "latitude" : 37.686111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보련산은 백두대간의 줄기가 치악산과 백운산을 거쳐 충주시로 이어진 능선위에 자리해 있으며 충북 충주시 앙성면과 노은면의 경계를 이루고 있다.이 산은 인파가 많이 몰리지 않는 탓에 호젓한 산행을 즐기기에 적당하다. 정상에서 북쪽으로 눈을 돌리면 동암계곡 끝의 온천마을이 보이고 그 뒤로 남한강이 야트막한 산들 사이로 굽이쳐 흐른다. 서쪽으로는 국망산과 오갑산이 손짓한다. 이 산의 능선은 노송군락으로 이어져 있고 자연동굴, 수룡폭포 등이 있어 주변경치가 좋고 물이 맑다. 산 정상에는 보련산성이 있는데 능선을 따라 흙과 돌로 쌓은 성의 둘레는 약 1.8km이며 일명 봉황성 또는 천룡성이라고 한다.이 성과 동쪽 맞은 편의 장미산 정상에 있는 장미산성 간에는 아주 재미있는 전설이 전해 오고 있다. 삼국시대 때 이곳 보련산 서쪽 가마골 마을에 장미라는 사람과 보련이라는 누이가 살았는데 명산의 정기를 받은 이들은 둘 다 장수의 기질을 가지고 태어났다. 그러나 옛부터 한 집안에 두 장수가 태어나면 그 중 하나는 희생되어야 하기에 두 사람은 성쌓기 겨루기를 하기로 하였다. 이 사실을 안 어머니는 가슴을 저미는 고통을 느끼게 되는데 어머니가 보기에 보련이의 성 쌓는 솜씨가 아들인 장미보다 뛰어나 고민을 하게 되었다.마침내 결심을 한 어머니는 손수 떡을해서 보련이에게 떡을 보이고 다시 성을 쌓게 했는데 보련이가 마지막 돌을 하나 올리려는 순간 장미쪽에서 성을 다 쌓았음을 알리자 보련이는 어머니가 아들을 살리려 했음을 알고 집을 떠났다고 한다. 보련이가 떠난 다음 날 보련이의 집에 큰 별이 하나 떨어졌다고 하며 그후 그 지역 산과 산성을 보련산-보련산성, 장미산-장미산성이라고 부르게 되었다.", + "MNTN_HG_VL" : "765", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면, 노은면", + "MNTN_NM" : "보련산" + }, + "longitude" : 127.78390539999999, + "latitude" : 37.072415200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "627", + "MNTN_LOCPLC_REGION_NM" : "경기도가평군", + "MNTN_NM" : "보리산" + }, + "longitude" : 127.5373706, + "latitude" : 37.669107500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보문산은 대전시 남쪽 중심부에 근접해 있어 대전시민들에게는 매우 친근한 휴식처이다. 이 산에는 보문산성, 보문사지, 야외음악당, 전망대 유희시설, 케이블카가 있으며 시루봉길 등 10여개의 등산로와 20여개소의 약수터가 있다. 특히, 보문산성은 시 기념물 제 10호로 1991년 12월 백제산성중 최초로 복원되었다.정상에 있는 장대루에 오르면 광활한 대전 시가지의 발전상을 한 눈에 볼 수 있는 곳이다. 본래 이 산은 보물이 많다하여 보물산이라 부르다가 후에 보문산으로 고쳐 부르게 되었다거나, 나무꾼이 죽어가는 물고기를 살려줘서 얻은 '은혜를 갚는 보물주머니'에서 이름이 유래되었다는 전설도 전해진다. 보문산 녹음(綠陰)은 대전팔경의 하나로 꼽힌다.대전광역시의 대표적인 녹음공원이자 도시자연공원으로,사정공원지구에는 스포츠와 피크닉을 위한 넓은 잔디광장과 체육시설 등이 조성되어 있다. 평일 2천명, 성수기에는 1일 평균 2만여명이 즐겨 찾는 4계절 행락지이다.", + "MNTN_HG_VL" : "457", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 중구", + "MNTN_NM" : "보문산" + }, + "longitude" : 127.42154499999999, + "latitude" : 36.301724 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남쪽을 보면 무안읍과 남산이 보이고 서쪽을 보면 서해안의 바다가 한눈에 보이면서 우리 마음을 시원하게 해준다. 동쪽으로 보면 무안읍 용월리 학마을이 보인다. 왜가리 서식지로 보평산 정상에서 보면 작은산이 온통 하얗게 보일정도로 왜가리들이 옹기 종기 보여있어서 실로 눈이 내린듯 착각을 일으키게한다. 비록 큰 산은 자연만큼은 어디빠지지 않는다. 해마다 3~4월이면 동남아 지역에서 월동한 백로와 왜가리 4천여수가 이 곳을 찾아와 집단을 이루어 번식하고, 10월이면 다시 남하 이동해 가곤한다.보평산 줄기의 청용산 아래 조성된 작은 인공섬과 한가롭게 노는 백로.왜가리의 모습이 어우러져 더욱 신비를 자아낸다.", + "MNTN_HG_VL" : "225", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 무안읍 고절리, 용월리", + "MNTN_NM" : "보평산" + }, + "longitude" : 126.86602689999999, + "latitude" : 37.886687999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "온통 산으로 둘러싸인 거창에서 숨은 진주를 꼽으라면 보해산을 꼽을 수 있다. 칼날처럼 날카로운 바위 봉우리를 여럿 거느리고, 천길 낭떠러지 위에 우뚝 선 이 산을 누군가는 ‘거창의 용아장성’이라고 표현했을 정도로 풍광이 시원스럽다.능선에는 바늘을 꽂아둔 듯 빼곡히 자라는 소나무나 철쭉이 인상적이며, 시야가 트인 능선 너머로는 흰대미산과 수도산 등 여러 산들이 켜켜이 늘어서 멋진 산수화를 펼쳐 보인다. 산길은 동서남북 사방으로 나 있어 다양한 코스를 즐길 수 있으나 주능선 상에서는 식수를 구하기 어려운 것이 아쉬운 따름이다.일명 상대산이라고 부르는 보해산은 보해사라는 절과 여러 부속암자를 거느리고 있었는데, 현재 절은 없어지고 ‘보해’라는 이름을 가진 산과 여러 지명만 남아있을 뿐이라고 한다. 산 서쪽 기슭으로는 송이버섯이 많이 나는데, 모두 임자 있는 송이이니 산행 중에 손을 대지 않도록 주의한다.", + "MNTN_HG_VL" : "909", + "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가북면, 주상면", + "MNTN_NM" : "보해산" + }, + "longitude" : 127.96511940000001, + "latitude" : 35.745744799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "909", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "보해산" + }, + "longitude" : 127.96511940000001, + "latitude" : 35.745744799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보현산은 경북 영천시 화북면과 청송군 현서면, 포항시 죽장면의 경계를 이루며 솟은 육산이다. 정상 부근에는 국내 최대 규모의 보현산천문대가 있으며 천문대까지 차량으로 오를 수 있다. 참나무, 당단풍나무, 고로쇠나무 등이 숲을 이루고 있으며 야생화 천국이라 할 만큼 다양한 식물들이 자라고 있다.주능선은 이웃한 면봉산과 더불어 고산다운 산세를 지닌다. 시루봉(1124m)과 보현산(1126m), 두 봉우리가 나란히 정상군을 이루고 있다. 정상에서 동쪽 능선을 따라 3킬로미터 지점에는 826.5미터의 ‘작은 보현산’도 있다.보현산은 이 일대에서 가장 높은 산이기에 일출과 낙조를 잘 볼 수 있는 곳이다. 일출과 일몰의 아름다움이 알려지기 시작하면서 해마다 연말연시면 해돋이와 함께 새롭게 한 해를 시작하려는 이들로 인산인해를 이룬다. 이른 봄에는 고로쇠축제, 5월에는 산나물축제, 8월 중순에는 별빛축제가 열리는 들머리 정각리 별빛마을은 최근에 청정미나리로도 널리 알려져 찾는 이가 늘고 있다.", + "MNTN_HG_VL" : "1126", + "MNTN_LOCPLC_REGION_NM" : "경북 영천시 화북면, 청송군 현서면, 포항시 죽장면", + "MNTN_NM" : "보현산" + }, + "longitude" : 128.97476230000001, + "latitude" : 36.1616304 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "복계산은 대성산(1174.2m)에서 복주산(1151.9m)을 향해 뻗어나가던 한북정맥의 산줄기가 수피령을 막 지나온 지점의 마루금에서 오른쪽(북서쪽)으로 약 700미터 벗어난 거리에 빚어놓은 명산이다. 민통선 바로 아래 위치해 있어 산행의 감회가 남다르고 ‘신철원팔경’의 하나인 매월대(595m)와 매월대폭포, 1996년 SBS 특집드라마 ‘임꺽정’의 청석골세트장 등이 있어 찾는 사람들이 많다.복계산은 매월대로 더 잘 알려진 산행지다. 복계산 기슭에 위치한 높이 40미터의 절벽이 매월대로 전설에 따르면 아홉 선비가 매월대에서 바둑판을 새겨놓고 바둑을 두며 단종의 복위를 도모했다고 전해진다.복계산을 산행한 후 승리전망대를 견학하면 안보산행으로서 금상÷화다. 그러기 위해서는 승용차나 관광버스를 이용하는 것이 좋다. 매월대주차장을 기점으로 복주산 정상에 오르는 코스는 매월대코스와 매월대폭포코스, 청석골세트장코스 등이 있는데 이중에서 매월대폭포코스로 올랐다가 청석골세트장으로 하산하는 것이 가장 무난하다.", + "MNTN_HG_VL" : "1054", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면", + "MNTN_NM" : "복계산" + }, + "longitude" : 127.50101100000001, + "latitude" : 38.2016609 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "복두봉은 운장산(1,126m)에서 동쪽인 구봉산(980m)쪽으로 뻗어나간 능선의 중간지점에 솟구쳐 오른 산이다. 복두봉은 아직 사람들의 손길과 발길이 닿지 않은 천혜의 자연경관을 자랑하고 있으며, 진안의 북서쪽에 마치 울타리를 친 듯이, 운장산, 복두봉, 구봉산의 능선은 금강과 만경강의 분수령을 이루고 있다.계곡 안에는 아직 알려지지 않은 200여평에 달하는 마당바위, 해기소, 정밀폭포 등이 등산객들을 유혹하고, 갈거계곡의 최상류인 민듬분지에는 6.25동란 전까지 화전민이 살았던 농장 터가 있어, 이곳은 가을이면 수만평의 억새군락이 너울너울 춤을 추고, 산허리에는 만산홍엽 단풍물결이 어우러져 한 폭의 그림 같은 풍광을 연출한다.복두봉 북쪽 아래는 여름 피서지로 유명한 운일암, 반일암의 협곡이 자리잡고 있으며, 도 주능선에서 운일암, 반일암 방향으로 아직도 비경으로 남아 있는 늑막골과 물탕골이 있어 어느 방향에서 오르내리거나 산자수명한 계곡산행을 즐길 수 있다.", + "MNTN_HG_VL" : "1017", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안 정천면, 주천면", + "MNTN_NM" : "복두봉" + }, + "longitude" : 127.39638890000001, + "latitude" : 35.931111100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "소가 누워있는 형상의 산이라고 해서 이름지워진 복우산(伏牛山)은 낙동면 신오리와 구미시 옥성면 산초리와 옥관리에 걸쳐있는 하나의 육산이다.산행은 낙동면 신오리 아랫마을에서 시작하게 된다. 단점은 마을에 주차할 수 있는 공간이 없기 때문에 용포초등학교 주변에 차량을 주차시켜야 한다. 구미 지역에서는 태조산과 더불어 산행 코스로도 즐겨 이용되는데, 특히 대둔사를 거쳐 내려가는 하행길이 많이 알려져 있다. 이 대둔사가 자리한 복우산(伏牛山) 인근은 좋은 돌이 많아 채석이 많이 이루어진다고 하는데 이 때문에 환경파괴 논란이 일어나고 있다고 한다.", + "MNTN_HG_VL" : "509", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 옥성면 산촌리", + "MNTN_NM" : "복우산" + }, + "longitude" : 128.62463700000001, + "latitude" : 35.866298 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 철원군 근남면, 화천군 사내면 경계에 우뚝 솟은 한북정맥의 산이다. 복주산이란 산명은 그 옛날 세상이 물에 다 잠겼을 때, 이 산 꼭대기만 복주께(사발) 뚜껑만큼 남았다고 해서 이름 붙여졌다고 전한다. 대체로 산행은 SBS 청석골세트장이 있는 매월동마을 또는 한북정맥의 시작점인 수피령에서 시작한다. 산행 중에 만나는 ‘매월대’는 매월당 김시습이 바둑판을 그리고 바둑을 두었다고 하여 이름 붙여진 바위를 가리킨다. 높이 20미터의 매월대폭포는 겨울철이면 빙벽등반을 하는 이들이 즐겨 찾는 곳이다. 복주산은 복계산과 연계하여 산행이 이루어지는 것이 대부분이며, 군사지역의 최전방인 철원에 위치한 만큼 등산로 곳곳에 참호시설을 비롯한 군사시설물들로 가득 차 있어 적설량이 많은 겨울철 산행에는 조심해야 한다. 간간이 만나는 바위 구간에는 로프가 설치되어 있으며, 891.9봉과 실내고개 갈림길에 위치한 1014미터 봉우리는 주변 산록을 조망할 수 있는 훌륭한 전망대 역할을 한다.", + "MNTN_HG_VL" : "1152", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면·화천군 사내면", + "MNTN_NM" : "복주산" + }, + "longitude" : 127.5027778, + "latitude" : 38.203888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "195", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군", + "MNTN_NM" : "봉대산" + }, + "longitude" : 126.8475, + "latitude" : 37.605555600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉두산에 자리잡은 태안사 현판에는 이 산의 이름이 `동리산'으로 써 있다. 여기에는 다음과 같은 유래가 전해온다. 봉황이 서식하는 나무가 오동나무인데 태안사를 둘러싼 주변 형세가 그 오동나무 속처럼 아늑하다해서 동리산으로 불렸다고 한다. 그러나 그 이름이 언제 바뀌었는지는 알 수 없지만 두 이름에 연관이 아주 없는 것은 아니다.봉황이 서식하는 나무가 오동나무이고 태안사가 자리잡은 곳을 둘러싼 주변 산세가 오동나무 줄기 속처럼 아늑해서 동리산이라 불렀으며 둘러싼 주변산세의 최고점을 봉황의 머리 즉 봉두산 이라 부른다. 태안사는 신라 경덕왕 때 창건되었으며, 대안사 광자대사비(보물 275)·대안사 광자대사탑(보물 274) 등이 있다.봉두산 주변에는 곡성 특유의 내륙산지를 이루고 있어 정상에 올라서면 순천쪽 황학리의 작은 들판을 제외하고 주변 조망이 온통 산 뿐이다. 남서쪽으로 삼산과 희아산 능선 넘어로 모후산이 오똑하고 북서쪽으로는 통명산 넘어 무등산까지 시야가 트인다. 동쪽으로는 둥주리봉과 자라봉, 그리고 지리산이 장막을 치고 있다. 이러한 내륙산지 조망이 산행의 맛으로는 제일이지만 봉두산은 태안사 여행에 초점을 맞추어도 좋은 산이다.", + "MNTN_HG_VL" : "753", + "MNTN_LOCPLC_REGION_NM" : "전라남도 곡성군", + "MNTN_NM" : "봉두산" + }, + "longitude" : 127.3996327, + "latitude" : 35.159860199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 영월군의 진산인 봉래산은 영월읍내를 굽어보는 자리에 우뚝 솟아있다. 영월8경의 하나이기도 한 봉래산은 `봉래채운'이라는 예전의 명성 그대로 많은 관광명소를 끼고 있다.산행도 낙화암, 민충사 등 유명한 관광지를 안고 있는 체육공원에서부터 시작된다. 체육공원에서 절터를 지나 동북쪽 능선길을 따라 오르면 정상에 다다를 수 있다. 중간에 조망되는 남한강 물줄기와 영월읍내의 모습이 보는 이의 눈을 시원하게 해준다. 정상은 참나무가 빽빽이 들어서 있는 펑퍼짐한 둔덕으로 이루어져 있다.주위에 천연기념물인 고씨동굴과 어라연 등이 자리하고 있다. 또한 영월로 들어서는 길목인 소나기재 북쪽에 단종의 능이 위치해 있으며, 천문대와 동강등 주변 관광자원과 연계해 이제 영월은 새로운 산행과 관광을 겸할 수 있다.", + "MNTN_HG_VL" : "856", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "봉래산" + }, + "longitude" : 129.0552017, + "latitude" : 35.081954600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉래산의 가장 높은 봉우리를 조봉(祖峰)이라 하고, 그 다음의 봉우리를 자봉(子峰), 그 아래의 것을 손봉(孫峰)으로 부르고 있다. 가까이 보면 세 봉우리의 구별이 잘되지 않지만 멀리서 바라보면 굽이진 봉우리의 낮아진 모습이 확연하게 드러난다.산 전체가 원추형이며 산록의 사면은 가파른 편이다. 특히 남쪽 사면은 급경사로 바다에 거의 내리박듯 수직으로 돌입한다. 산기슭에는 기계적 풍화작용에 의해 쪼개진 바위가 점점이 흩어져 있다.봉래산은 원래 동쪽바다 한 가운데 있어서 신선이 살고 불로초와 불사약이 있다는 상상속의 영산이다. 봉황이 날아드는 산이라는 의미로 영도의 중심에 위치하고 있다.봉래산에는 두 가지 속설이 있다. 봉래산은 지세가 마치 아늑한 어머니의 품같은 형상을 하고 있어 자식들인 이곳 주민이 어머니 품을 떠나면 못 살게 된다는 설, 또 봉래산 산신령이 욕심이 많아 영도로 들어오는 것을 좋아하나 밖으로 떠나는 것을 싫어해 이 곳 주민들이 영도를 떠나면 좋지 않다는 설이다. 이런 것들은 속설에 지나지 않고 영도 사람들은 유달리 인정이 많아 이곳에서 한평생을 사는 사람이 많다는데서 유래된 듯하다.", + "MNTN_HG_VL" : "395", + "MNTN_LOCPLC_REGION_NM" : "부산광역시", + "MNTN_NM" : "봉래산" + }, + "longitude" : 129.0552017, + "latitude" : 35.081954600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉명산(697m)은 문경읍 마원리 우무실마을에 있는 문경읍의 앞산이어서 올라서면 문경읍이 한눈에 들어오고 주흘산, 조령산, 백화산, 성주봉이 문경읍을 빙둘러 서있는 모습을 볼 수 있는 곳이다.우리나라 산업발전의 원동력이 되었던과거 석탄과 흑연을 생산하던 봉명광업소가 있던 곳이며, 금학사라는 절도 있었으나 지금은 절터만 남았다. 과거에는 산 아래에 정기적으로 물이 솟는 조천이란 샘이 있었다고 전하나 지금은 찾을 길이 없다.정상에서 탁 트인 조망은 일품이다. 정상 부근에는 강대바위와 촛대바위가 있고, 산 앞으로는 조령천이 흐른다. 아래 등산로에 시루떡을 닮은 바위가 셋이 있는데 제일위의 시루떡 바위에 불상이 새겨져 있다.문경온천과 한눈에 조망되는 주흘산 모습이 좋아 등산객이 많이 찾고 있으며 매년 등산객이 늘어나고 있다.", + "MNTN_HG_VL" : "697", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "봉명산" + }, + "longitude" : 128.1427698, + "latitude" : 36.720131100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용문산(1157m) 북쪽 능선을 따라 10킬로미터 떨어진 곳에 솟은 봉미산은 경기도에서도 오지로 꼽히는 양평군 단월면 산음리에 있다. 산골마을의 정취가 물씬 풍기는 산음(山陰)리는 용문산의 그늘에 묻혀 음지가 된다고 이름 붙었다.정상 남쪽 능선에 작은 분지가 있어 ‘늪산’이라고 불리는 봉미산(856m)은 경기도 가평군 설악면과 단월면의 경계를 이루는 산이다.용문산을 비롯한 유명산(862m), 중미산(834m)으로 이어지는 산줄기가 한눈에 들어오고, 북으로는 홍천강에 발치를 담그는 장락산(627m) 줄기가 당차게 뻗어간다. 동으로도 매봉산(650m) 자락의 대명스키장이 훤히 보일만큼 조망이 좋다.", + "MNTN_HG_VL" : "856", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 단월면ㆍ설악면", + "MNTN_NM" : "봉미산" + }, + "longitude" : 127.5697222, + "latitude" : 37.6136111 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 횡성군 청일면과 홍천군 서석면의 경계를 이루는 봉복산은 남한강의 지류인 섬강의 발원지로 깨끗한 계곡과 풍부한 수량을 자랑하고 있다. 이 산은 산세가 봉황을 닮아서 '봉복산'이라고 불리우며, 산 뒤쪽에 봉복샘이 있는데 여기서 흐르는 물이 섬강을 이루는 근원이다. 산이 높은 만큼 골짜기가 깊지만 나무들이 많아 산세가 그렇게 험하지 않다. 맑고 깨끗한 물도 충분해서 좋은 산의 면모를 그대로 갖춘 산이다.봄에는 두릅, 산나물 등이 많이 나고, 여름철에는 소(沼)와 담(潭)이 많아서 시원함을 느낄 수 있다. 산이 높고 나무가 많아서 가을에는 낙엽이나 단풍도 가득하다. 단풍철만 되면 한꺼번에 몰리는 인파를 피해, 한적한 곳에서 여유롭게 단풍산행을 즐기기에 적합한 산이다. 호젓한 산길을 따라 흐르는 계곡이 너무나 맑고 깨끗하기에 기분이 무척 상쾌하기만 하다. 하얀 포말을 일으키며 쏟아지는 작은 폭포가 나타나는가 했더니 조금 더 오르면 시원한 숲그늘 속에 쉬어가기 좋은 반석을 이룬 곳들도 즐비하다. 꼭 신선놀음하는 분위기가 연이어지는 것이다.봉복산의 정상에서 내려다보는 경관은 그야말로 일품이다. 사방으로 막힘이 없이 시원하게 펼쳐져 있는 경치를 관망할 수 있다.", + "MNTN_HG_VL" : "1022", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", + "MNTN_NM" : "봉복산" + }, + "longitude" : 128.2163889, + "latitude" : 37.620277799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉수산은 아산시와 예산군의 경계에 위치하며 산세가 봉황의 머리를 닮아 봉수산이라 불리우고 있으며 경기 안성의 칠장산에서 태안반도 안흥진까지 연결되는 약 280km의 금북정맥의 줄기로 아산시는 광덕산을 거처 봉수산을 지나 예산의 천방산으로 진행되며 오서산과 가야산으로 이어진다.", + "MNTN_HG_VL" : "535", + "MNTN_LOCPLC_REGION_NM" : "충청남도 아산시 송악면 유곡리,송학리,강장리", + "MNTN_NM" : "봉수산" + }, + "longitude" : 126.7814735, + "latitude" : 36.597659499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충남 예산군 대술면과 공주시 유구면 및 아산시 송악면에 걸쳐 있다. 39번 도로를 사이에 두고 광덕산과 동서로 광덕산과 마주하고 있다.산세가 봉황의 머리를 닮아서 봉수산이라고 부른다고 하는데, 현재 산의 모습에서는 찾아볼 수 없다. 산도 높지 않고, 코스도 단순하여 나들이 겸 등산 코스로 좋다. 온천 산행지로도 더없이 좋은 산이다.산기슭에는 887년(진성여왕 1)에 도선국사가 창건한 봉곡사(鳳谷寺)가 있다. 임진왜란 때 소실된 것을 1647년(인조 24)에 중창하였다. 현재 대웅전, 향각전, 삼성각, 요사 등의 건물이 있으며, 대웅전과 그 옆에 있는 고방(庫房)이 함께 충청남도 문화재 자료 제323호로 지정되어 있고 대웅전 지장탱화는 충청남도 문화재 자료 제242호로 지정되어 있다. 봉곡사 진입로에는 수백년 된 노송 군락이 운치를 더하고 있다.이 산의 능선에는 명소 베틀바위가 있는데 족히 사오십명은 올라설 수 있을 정도로 크고, 전망이 뛰어나고 주변에도 바위들이 많아 가기에 좋은 곳이다.", + "MNTN_HG_VL" : "570", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 대술면, 아산송악", + "MNTN_NM" : "봉수산" + }, + "longitude" : 126.7814735, + "latitude" : 36.597659499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "봉수산" + }, + "longitude" : 126.7814735, + "latitude" : 36.597659499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "이 땅의 뼈대인 백두대간의 허리에서 갈린 금북정맥이 천안, 청양을 거치면서 대천 앞 서해에 그 발을 담그기 전에 솟구친 여러 봉우리 중 하나가 봉수산이다. 봉황의 머리를 닮았다고 해서 봉수산이라 이름 붙은 이 산을 대흥면 사람들은 ‘대흥산’이라 부른다. 정상부에 2.4킬로미터 길이의 성곽 ‘임존성’을 두른 봉수산은 백제 재건을 꿈꾸던 이들의 마지막 꿈이 영글던 산이다. 옛날 초등학교 교과서에 실렸던 ‘의 좋은 형제’ 이야기의 실화가 봉수산 자락의 대흥에 남아 있는 유서 깊은 곳으로, 산성 안의 산마루에는 억새가 많이 자라 가을 정취가 물씬 배어나는 곳이다. 임존성 안 넓은 억새밭에는 ‘백제 임존성 청수’라 적힌 비가 선 샘이 있다. 봄이면 성곽 주변으로 만발하는 진달래가 장관을 이룬다.", + "MNTN_HG_VL" : "483", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 대흥면, 광시면ㆍ홍성군 금마면", + "MNTN_NM" : "봉수산" + }, + "longitude" : 126.7814735, + "latitude" : 36.597659499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "예전 부터 봉화를 올릴수 있다고 봉수산이라 불리었다고한다.(다성 초이선사 탄생지로 유명하다) 산정상에 오르면 뒷편으로는 확트인 칠산바다와 앞으로는 싱싱달리는 새해안 고속도로의 시발점이 보인다. 앞으로는 시원하게 달리면 자동차와 뒤로는 뻥뚫린 바다가 보이는 전망이 아주 좋은 산이다.", + "MNTN_HG_VL" : "204", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 삼향면 왕산리", + "MNTN_NM" : "봉수산" + }, + "longitude" : 126.7814735, + "latitude" : 36.597659499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "음식의 양념으로 또는 한약제로도 쓰인 향취나 맛이 뛰어나 전국적으로 널리 알려진\"\"봉두생강\"\"의 주산지 봉동읍의 서북쪽에 우뚝 솟아 있는 산이 봉실산이다.이 산은 그리높지 않으나 봉동평야의 동북쪽으로 길게 뻗은 산맥으로 옥녀봉을 거느린 두 봉우리와 암봉으로 이루어진 산으로 정상에 서면 그 주위에 산이 없으므로 사방 거침없이 펼쳐진 들녘이 확 트여 시원스럽기 그지없는 전망이 일품이다.바둑판같이 잘 정리된 농경지이며 옹기종기 모여 있는 마을과 마을 동북에서 서남쪽으로 흘러내린 고산천의 물줄기가 푸른 농경지 사이로 아름답게 내려다보인다.", + "MNTN_HG_VL" : "372", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주 봉동읍, 비봉면", + "MNTN_NM" : "봉실산" + }, + "longitude" : 127.15235730000001, + "latitude" : 35.972536599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "301", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 소양동", + "MNTN_NM" : "봉의산" + }, + "longitude" : 127.73355309999999, + "latitude" : 37.888648099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "368", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시", + "MNTN_NM" : "봉화봉" + }, + "longitude" : 129.09805560000001, + "latitude" : 36.146666699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주로 군진지와 훈련용으로 많이 쓰이고 있는 구간이다. 경사는 있지만 대부분 완만하므로 일반 등산화로도 충분히 등산이 가능하다. 정상까지 헬기장 두곳이 있으며, 그곳에 올라서면 내설악과 외설악이 한눈에 들어와 장관을 이루어 한폭의 그림을 연상케 한다.", + "MNTN_HG_VL" : "590", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면 원통리", + "MNTN_NM" : "봉화봉" + }, + "longitude" : 129.09805560000001, + "latitude" : 36.146666699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "476", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "외지인들에게 구곡폭포로 더 잘 알려진 봉화산은 북한강에 둘러싸인 강원도 춘천시 남산면에 위치해 있다. 조선시대에 피웠던 봉수대가 정상에 있어 봉화산이라고 부른다.산의 규모면에서는 작으나 입구의 경관 및 편의시설이 좋아 주말 가족 야유회 장소로 더 없이 좋은 곳이다. 구곡폭포 일대에 수영장과 놀이터등 위락 시설이 있으며, 특히 강촌역 근방은 여름철이면 행락객 인파가 끊어지지 않고 모여든다. 통상 봉화산과 검봉을 한데 묶어 산행하는 경우가 더 많다. 검봉과 봉화산은 능선으로 바로 옆에 이어져 있다.경춘선 열차를 타고 가다 보면 북한강을 끼고 스쳐가는 산들이 여간 정겨운 게 아니다. 전국적인 교통난으로 주말 나들이가 고생길인 요즘, 연인끼리 또는 가족끼리 열차를 타고 다녀오는 산행은 한결 여유가 있어 좋다.특히 강과 더불어 빼어난 경관을 자랑하는 경춘선 부근의 산들은 그리 높지도 않아 당일 산행 코스로 적당하다. 경춘선을 즐겨 타는 이들에게 가장 인기있는 곳은 강촌이나 대성리 가평이다. 특히 강촌에는 해마다 겨울이면 신문과 TV에 단골로 나오는 폭포가 하나 있다. 얼음이 얼자마자 빙폭 등반을 하려는 산악인들이 줄을 서서 기다리는 곳, 바로 구곡폭포다. 그러나 정작 이 폭포를 품고 있는 봉화산은 사람들에게 그리 알려져 있지 않다. 강선사를 들머리로 하는 검봉과 더불어 봉화산 산행의 묘미는 능선길에 올라 굽어보는 북한강에 있다.구곡폭포는 아홉 굽이의 협곡을 돌아돌아 들어간다고 해서 붙여진 이름이라고도 하고 또, 옛날에 어떤 도사가 이곳에 오다가 아홉 개의 고개를 넘어 도착한 곳에 폭포가 있었다고 해서 붙여진 이름이라고도 한다. 최근에는 봉화산 진입로까지 자전거 도로가 개발되어 하이킹 코스로도 좋다.", + "MNTN_HG_VL" : "329", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉화산이란 이름에서 알수 있듯 이산은 연기나 불을 피워 통신을 하던 봉화대가 있는 산으로 사방이 트인 전망이 일품이다.장수군 천천면과 계남면을 가르고 있는 봉화산 정상에 서면 북동쪽으로 파도처럼 일렁이는 덕유산 능선이 보이고 12대 종산중의 하나인 장안산이 시야에 들어온다. 봉화산 산행의 맛을 음미하자면 정북 방향의 능선을 타고 방아재쪽으로 올라야 한다. 다른 봉우리에 비해 방아재는 여러 골짜기 물을 받아 흘러가는 천천의 물줄기를 한눈에 바라볼 수 있기 때문이다.평범하기 이를 데 없는 이 봉화산에 최근 남원을 기점으로 등산인들의 발길이 잦아지고 있다. 그 이유는 몰론 철쭉 군락이 발견되었기 때문이다. 철쭉 군락이 산사면 곳곳에 널려 있는 데다가 장수와 함양 땅으로 뻗은 암릉길이 온통 철쭉꽃길이다.", + "MNTN_HG_VL" : "338", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 천천면, 계남면", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "487", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천재산의 천제봉은 개도리 화산마을에 있는 정상이 해발 332(기존338)m로 화산마을과, 호령, 신흥마을을 지나서 정상에 오르면 다도해의 아름다운 장관을 한눈에 바라볼 수 있다.현 천제산(화개산)은 일명 천제봉(天祭峯)으로 불리고 있는데 돌산군지에는 일명 천조봉이라 적혀져 있으나 이는 오기이다. 삼월삼짓날 전야에 천조봉(天朝峯) 정상에 있는 제단에서 하늘의\"천제신\"에게 제를 올리는 산으로써 영산으로 알려지고 있으며, 옆으로는 봉화산이 솟아있어 두산의 봉우리가 마치 말의 귀와같이 쫑긋 솟아 있으며, 주위로는 높고 얕은 산들이 병풍을 펼쳐 둘러쌓은 것처럼 마을을 빙 둘러고 있다. 풍수지리설에 의하면 지맥을 통한 산세가 부락을 옹호하여 감싸고 덮어주는 정기가 있다해서 섬의 이름을 덮을 개(蓋)자를 붙여 개도(蓋島)라 이름지어 불렀다고 한다", + "MNTN_HG_VL" : "334", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 화정면 개도리", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "355", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 용당동,조례동", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "692", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 강서구 녹산동", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부용산(882m)에서 남쪽으로 능선이 뻗어 있는데, 이 능선상에서 가장 높은 봉우리이다. 부용산 외에 오봉산(779m)과도 능선이 이어져 있어, 종주 등반도 가능하다. 산의 북쪽을 제외하고는 소양호로 둘러싸여 있어, 정상에서의 조망이 시원하고 아름답다.청평사 선착장에서 서쪽길은 청평사로 이어지고 동쪽길 따라 작은 고개를 넘어가면 청평골 입구에 농막집이 있다. 농막에서 계곡 왼쪽 길을 따라 올라가서 계곡이 갈라지기 직전에 왼쪽길 따라 들어가면 동굴이 있는 기도터에 닿게 된다. 계곡을 건너서는 조금 가파른 길을 거쳐 하우고개에 이르게 된다. 하우고개 십자로에서 남쪽 길로 들어가면 봉화산에 오르게 되는데 이 길은 사람이 별로 다니지 않는 완만한 능선에 억새와 칡넝쿨이 무성하여 길바닥이 보이지 않는 상태이다.", + "MNTN_HG_VL" : "734", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "476", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", + "MNTN_NM" : "봉화산" + }, + "longitude" : 127.08694439999999, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부귀산은 전북 진안군 부귀면과 진압읍을 가로지르며 금남정맥과 호남정맥의 마루금을 긋고 있다. 등산 코스 가운데 특별히 시선을 끌만한 장소는 없으나 수풀이 우거져 있어 한적한 분위기를 만끽할 수 있으며 전체적으로 무난한 등산로를 갖추고 있다.부귀산의 북쪽인 부귀면 대곡마을이나 손실골에서 오르면 육산, 진안읍 원정곡 마을에서 오르면 암봉으로 이루어진 산이고, 이 두 방향에서 산의 조망이 잘된다. 부귀면 대곡마을은 원래 한실골(韓室谷)인데 일본인들이 고쳤으며, 마을 뒷산인 부귀산은 사지앙천(蛇之仰天) 즉 뱀이 하늘을 우러러보는 형상인 명당이 있고, 가뭄이 들면 진안지역의 사람들이 모여서 기우제를 지내는 곳이며, 산삼을 캔 적이 있는 곳이고 한다. 결국 부귀의 이름이 말해주듯이 이 지역은 산수(山水)가 좋아 천하명당자리에 터를 잡은 부귀한 곳이라는 의미이라고 한다.대곡마을 주민들은 부귀산을 '배택산'이라고도 하는데, 말세가 되면 이산에 올라서 배를 타고 나가야 살수 있다고 하는 속설을 간직한 산이다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍, 부귀면", + "MNTN_NM" : "부귀산" + }, + "longitude" : 127.3927778, + "latitude" : 35.809166699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;모유정 전설 깃든 은혜의 산gt;부모산은 청주시 비하동과 지동동에 걸쳐 있는 해발 232m의 작은 산이다. 주변 조망이 좋고, 리기다소나무, 상수리나무, 소나무 등으로 등산로가 잘 조성되어 있어 등산인들이 많이 찾는다. 본래 이산은 아양산, 악양산 등으로 불렸다. 임진왜란 때 박춘무가 복대에서 의병을 일으켜 청주성을 탈환하고 아양산 마저 탈환하여 그 곳에 머물고 있었다. 그러나 박춘무에게 패전했던 왜병이 아양산에는 물이 없다는 것을 알고 산 주위를 포위하고 보급로를 차단하자 굶어죽는 의병들이 속출하게 되었다. 때마침 의병장 박춘무의 꿈속에 지팡이를 짚은 백발 노인이 나타나 소나무를 가리키며 일어나라고 소리쳤다. 박춘무는 꿈에서 깨어나 군사들에게 소나무를 뽑게 했다. 그곳에서 식수는 물론 말에게 목욕을 시키고도 남을 만큼의 물이 솟아났다. 이것을 알게 된 왜병들이 물러났고, 이때부터 그 은혜가 부모와 같다하여 부모산이라 칭하게 되었으며, 이 우물을 모유정이라고 불렀다고 한다. 정상에는 충북기념물 제121호로 지정된 청주 부모산성(淸州父母山城)과 연화사(蓮花寺)가 있다.", + "MNTN_HG_VL" : "232", + "MNTN_LOCPLC_REGION_NM" : "", + "MNTN_NM" : "부모산" + }, + "longitude" : 127.410287, + "latitude" : 36.634100400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "232", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 흥덕구 비하동, 지동동", + "MNTN_NM" : "부모산" + }, + "longitude" : 127.410287, + "latitude" : 36.634100400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문경 북동쪽에 와서 수려한 산들을 떨궈놓은 백두대간이 속리산으로 내려가기 전, 문경의 진산 주흘산의 북서쪽에 바위벽으로 우뚝 솟게 한 산이 바로 부봉이다.비슷비슷한 암벽 봉우리로 모인 산인 부봉은 크고작은 나무와 아기자기한 암벽이 한데 어우러진 등산로로 인하여 많은 등산객들이 즐겨찾는 산이며 새재도립공원을 한눈에 내려다 볼 수 있는 조망이 아주 좋은 산으로 단풍이 가득한 가을산이 제일 아름다운 곳이다.", + "MNTN_HG_VL" : "913", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "부봉" + }, + "longitude" : 128.096397, + "latitude" : 36.768441000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부암산(傅岩山)은 스승 부(傅)자를 쓰며 일명 스승바위산이라고도 하는데 사실 부암산 자락은 너무 많은 역사를 간직한 산이다. 악(岳, 嶽)이나 암(岩)자가 들어가는 산은 거의 바위산인데 이 곳 역시 예외는 아니다. 부암산은 멀리서 쳐다보아도 암반 투성이고 정상에서 주위를 둘러보아도 역시나 북쪽 산들은 모두 바위산이다. 거대한 바위들이 누룩이 포개져 있는 것처럼 층층이 포개져 있다.한적한 마을 뒤에 있으면서도 그 산세가 빼어나다. 가까이 있으면서 소문이 자자한 황매산과 모산재에 조금도 뒤지지 않는 멋진 산이다. 산길로 들어서면 우람한 낙락장송이 산을 채우며 잔가지가 많은 소나무들이 마치 담 하나를 사이에 둔 이웃처럼 함께 어울려 골짜기를 메웠다. 특히 단계천 가운데 자리잡고 있는 기암이라는 바위는 그 풍채가 당당하면서도 멋스럽다. 바위에는 많은 구멍이 뚫려있는데 옛날에 일산을 꽂았던 자리이다. 단계현 시절에 놀이가 있을 때에 이곳에서 풍악을 울리고 기생을 불러서 놀이를 하던 곳으로 전한다.", + "MNTN_HG_VL" : "696", + "MNTN_LOCPLC_REGION_NM" : "경남 합천군 가회면, 산청군 차황면ㆍ산등면", + "MNTN_NM" : "부암산" + }, + "longitude" : 127.9902359, + "latitude" : 35.457224099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전남 장흥군 용산면 운주리를 부채모양으로 싸감고 있는 부용산은 동학운동의 최후 격적지로 봄이 되면 진달래 철쭉 등이 화사한 꽃빛으로 불태우는데 아직 등산로가 제대로 나 있지 않아 찾는 이가 드문 산이다. 또한 부채모양을 이루고 있기 때문에 다양한 원점회귀 산행이 가능하다.전란의 시달림에서 안전한 보호막이 돼 주었던 부용산의 덕성은 임진왜란까지 거슬러 오른다. 당시 이맹(李孟)이란 장수가 골목 어귀에 서 있다가 들어오는 왜적을 모조리 쏘아 죽여서 피란민들의 안전을 지켜주었던 곳이 있는데 이곳이 바로 지금의 장구목재다. 부용산은 부처가 솟은 산이라는 `불용산(佛聳山)', 산삼 등 약초가 많다고 해서 `약다산(藥多山), 돌이 많아 '석다산(石多山)등으로 불린다.곳곳에 튀어나온 바위에서 바라보는 도암만과 다도해 전경이 시원하며 바다에서 솟아오른 듯한 천관산을 바로 눈앞에서 감상할 수 있다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍 성산리", + "MNTN_NM" : "부용산" + }, + "longitude" : 127.0988696, + "latitude" : 37.733488800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "882", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "부용산" + }, + "longitude" : 127.0988696, + "latitude" : 37.733488800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충청북도 음성의 가섭산의 바로 옆에 있는 산으로 능선산행지로 최적인 곳이다. 음성에서 시작하여 약 8km정도 되는 주능선은 능선산행에 적합하다. 음성시내에서 부용산을 거쳐 금왕시내까지 도보로 이동할 경우 약 13-14km정도의 거리로 능선종주의 맛을 느낄 수 있는 산이다.산행 초입은 음성읍 용산리 저수지 좌측에 있는 궁도장인데, 이곳에는 50여대를 주차할 수 있는 주차장과 큰 산행안내판이 세워져 있다. 산행의 끝은 부용산 서쪽 금석저수지인데 댐 아래 도로변에 산행안내판이 세워져있다. 부용산은 산행안내판이 비교적 잘 세워져있고 등산로 상태도 걷기에 좋다. 정상에는 산행기록을 남기는 등산일지를 저장하는 철제박스가 놓여있어 이 산만의 특징으로 부각되고 있다.", + "MNTN_HG_VL" : "644", + "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 음성읍, 금왕읍", + "MNTN_NM" : "부용산" + }, + "longitude" : 127.0988696, + "latitude" : 37.733488800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "159", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시", + "MNTN_NM" : "부주산" + }, + "longitude" : 126.4434815, + "latitude" : 34.817745899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부흥산이란 이름은 나매기(나뫼기,난뫼기)로부터 범산까지 크게 부흥할 것이라하여 부흥산이라했다 한다.", + "MNTN_HG_VL" : "73", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 옥암동", + "MNTN_NM" : "부흥산" + }, + "longitude" : 126.4427778, + "latitude" : 34.806111100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북바위산은 월악산국립공원권내에 자리한 아기자기한 산으로, 행정구역상으로는 충북 충주시 상모면과 제천시 한수면의 경계를 이루고 있다, 산 이름이 북바위산인 까닭은 이 산 자락에 타악기인 북을 닮은 거대한 바위가 있어 붙여진 이름이다. 북바위산은 월악산 국립공원내에 월악산에서 남쪽 만수봉까지 이어지는 암릉서쪽에 송계계곡이 자리하고 있는데 송계계곡 중간쯤인 팔랑소에 비록 높지는 않으나 기암절벽을 거느리고 있어 아기자기한 스릴을 느끼면서 산행할 수 있는 산이다.이 산의 특징은 송계계곡으로 이어지는 능선남면이 온통 바위암반으로 슬랩을 형성하고 있으며 아름드리 적송들이 등산로를 에워싸고 있어 그 경관이 매우 아름답다. 송계계곡 중간쯤인 팔랑소와 와룡소에서 서쪽으로 솟아 있는 북바위산 암릉에서는 송계계곡을 사이에 두고 동쪽 방향 월악산(1,094m) 남릉이 마주보인다. 그리고 남릉에서 송계계곡 방면으로 가지쳐 나온 덕주봉(893m)과 용암봉(892m) 암릉미도 만끽할 수 있다. 여기에다 북쪽 동산계곡 건너인 말미봉(687.3m)과 남동쪽 사시리계곡 건너 박쥐봉(782.1m) 바위지대도 감상할 수 있는 천혜의 암릉코스로 사계절 인기 있다.", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면, 제천시 한수면", + "MNTN_NM" : "북바위산" + }, + "longitude" : 128.08618809999999, + "latitude" : 36.855391500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북배산은 고향집 바로 뒤에 솟아 있는 산처럼 향수를 자아내게 하는 산으로 크게 빼어나지도 웅장하지도 않지만 수수한 매무새의 시골 아낙 같은 자태를 하고 있다. 가덕산(858m)과 계관산(710m)으로 이어지는 능선에 위치하며 청정지역에 있는 산답게 깨끗하고 고즈넉한 산이다. 주능선은 산불을 대비해 폭 10미터 정도에 방화선이 형성되어 있으며, 이 방화산으로 능선 모두가 시원스레 조망되며 특히 눈 내린 후 가덕산에서 계관산까지 이어지는 경치는 이색적인 분위기를 느끼게 해준다.북배산은 수도권 등산인들에게 혼잡함을 피할 수 있는 당일치기 코스로 제격이다. 북배산 코스는 대개 목동2리 맴내~작은멱골을 경유하거나 또는 싸리재(마을)~싸리재고개를 경유해 정상을 다녀오는 것이다.정상에서 바라보는 조망은 막힘이 없다. 먼저 북서쪽으로는 북배산의 모산인 화악산이 하늘금을 이루고, 그 오른쪽으로는 북배산을 향해 세차게 흘러나오는 응봉, 촛대봉, 몽덕산, 가덕산 줄기가 연이어져 시야에 들어온다.동쪽으로는 병풍을 두른 듯한 대룡산 아래로 평화로운 춘천시내와 의암호가 펼쳐진다. 춘천남쪽으로 펼쳐지는 조망도 일품이다. 가장 멀리로 용문산이 하늘금을 이루고 그 아래 좌우로는 도명산, 대명스키장 슬로프, 장락산, 소리산 등이 넘실대는 파도처럼 광활하게 시야에 들어온다. 서쪽으로는 구나무산, 명지산, 월출산, 수덕산이 마주보이고, 구나무산 왼쪽 아래로 자리한 가평읍과 북한강이, 수덕산 아래로는 목동분지가 내려다보인다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "북배산" + }, + "longitude" : 127.6136111, + "latitude" : 37.920000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동부면 망골과 망치고개를 경계로 하여, 신현읍 삼거리에 주맥을 내려 뻗어 문동과 아주골 옥녀봉 줄기와 연결되어 있다. 망치고개에 고려시대에 축성했다는 성지가 산중간에서 마을까지 길게 뻗어 있다. 문동계곡 상류에는 문동폭포가 있고, 삼거리에는 신라시대에 있었다는 은적사 절터가 있다.장승포, 일운, 동부에서 고현으로 다니던 세갈래 길이 협곡에 있는 삼거리 마을은 교통의 중심지였다. 문동폭포가 있는 북병산은 그 높이가 465.4m로 고현을 병풍친 듯 둘렀다고 북병산이라 하며 북쪽을 막아 평풍을 두른 듯 하다고 북병산이라고 한다.북병산 고개를 넘어 동부 일운 거제 고현 등지로 통하는 세 갈래 길이 있어 삼거리로 통한다. 이 산에는 옛 신라시대 엄적사와 법률사란 큰절이 있었다고 하나 현재는 주춧돌만이 남아 있어 당시의 역사를 말해 주고 있다. 법률사는 그 경내가 방대하여 아주리까지 뻗어 있었다고 하며 그 절의 삼층 석탑비가 지금도 대우조선소 내에 남아 있다. 북병산 계곡에서 흐르는 물이 문동 폭포수가 되어 문동 저수지를 형성하여 그 모습이 장관이다.", + "MNTN_HG_VL" : "465", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제", + "MNTN_NM" : "북병산" + }, + "longitude" : 128.65655140000001, + "latitude" : 34.823366700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북성산은 거리가 그리 길지 않고 경사도 완만하여 가족과 함께 산책하기에 좋은 산으로많은 사람들이 찾고 있다. 농로의 끝에서 시작되는 작은 소로길을 따라 1㎞ 올라가다보면 마치 쉬어가라고 만들어 놓은 듯 약수터와 벤치가 놓여져 있다.이곳에서 조금 더 올라가면 정상이지만 실제 정상은 정상 바로 아래지점이다.실제 정상은 지뢰 밭으로 출입금지 하였기에 이곳에 정상을 만들어 놓은 듯 하다.", + "MNTN_HG_VL" : "259", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 여주읍", + "MNTN_NM" : "북성산" + }, + "longitude" : 127.5958333, + "latitude" : 37.286388899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "밀양시 산내면 등지의 산을 찾는 산악동호인들에겐 수리봉으로 더 잘 알려진 북암산은 지금까지 산길이 없어 산행이 불가능한 곳으로 생각해 왔었다. 능선길에 암벽이 버티고 있어 가파른 산행에 곳곳에 너덜이 자리해 자칫 잘못하다간 사고를 당하기 십상이다.북암산은 가인 3리 봉의저수지 아래 인골 산장에 도착하여 산장 우측 밭 오른편 길에서 산행이 시작된다. 정상으로 올라가는 길은 급경사지역이기 때문에 힘이 든다. 북암산 정상에는 정상 표지석 대신으로 누군가 돌탑을 쌓아 놓았다. 그리고 그 앞에 문바위가 우뚝 앞을 가로막고 있어 앞으로 다시 한번 더 고비를 넘겨야 한다.", + "MNTN_HG_VL" : "807", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "북암산" + }, + "longitude" : -118.3208913, + "latitude" : 34.054107500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울의 진산 북한산은 조선조 초기에는 삼각산(三角山)으로 불렀다. 삼각산이란 이름은 〈신증동국여지승람〉에 '삼각산은 양주의 경계에 있다. 일명 화산(華山)이라 하고, 신라시대에는 부아악(負兒岳)이라고 불렀다.이 산은 경성(京城)의 진산으로 동명왕의 아들 온조가 한산(漢山)에 이르러 부아악에 올라가서 살 만한 곳을 살폈다'는 기록이 있으며, '백운봉 (白雲峰, 지금의 백운대), 인수봉 (仁壽峰), 만경봉 (萬景峰,지금의 만경대)등 세 봉우리가 있으므로 그렇게 이름한 것이다'라고 유래를 기록하고 있다. 북한산성에 대해서는 〈신증동국여지승람〉과 〈북한지〉에 상세히 기록되어 있다. 북한산성은 백제 온조왕이 터를 잡았고 그후 개루왕 때 성터를 쌓았다는 기록이 있으며, 조선시대에 임진왜란, 병자호란을 치른 뒤 숙종 37년(1711년)에 시작하여, 6개월 만인 그해 10월에 완공하였다 한다.북한산성은 험한 산세를 이용하여 정상을 기점으로 서쪽 산자락부터 원효봉, 염초봉, 백운대, 만경대, 용암봉, 문수봉, 나한봉, 나월봉, 용출봉, 의상봉까지 연결하여 쌓은 산성으로 총 길이가 10km에 달한다. 당시 산성에는 14개의 성문을 냈는데, 산성의 정문 격인 대서문을 중심으로 북쪽으로 수문, 서암문(시구문), 북문, 백운대를 지나 위문, 용암문, 대동문, 보국문, 대성문, 대남문, 청수동암문, 대서문에서 북서쪽으로 이어지는 산성에는, 부황동암문, 가사동암문이 설치되었다.현재는 대부분 성문을 복원하였다. 북한산에 수많은 등산로 거미줄 같이 얽혀 있어 산행시 주의를 요하는 곳이다. 북한산의 산행 들머리는 대표적으로 여섯 군데를 꼽고 있다. 우이동 기점, 4.19탑 기점, 정릉 기점, 세검정 기점, 불광동 기점, 구파발 북한산성 기점으로 구분할 수 있다.", + "MNTN_HG_VL" : "836", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강북구ㆍ성북구ㆍ종로구ㆍ은평구, 경기도 고양시ㆍ양주시", + "MNTN_NM" : "북한산" + }, + "longitude" : 126.99333300000001, + "latitude" : 37.660832999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영광의 진산이라 내세울 수 있는 불갑산은 노령산맥의 정간에서 서남쪽으로 서해를 향해 힘차게 휘어 달리다가 우뚝 솟은 서지맥의 막내봉이다. 해발 516미터이며, 영광읍에서 약 10킬로미터 지점에 있다. 멀리서 보이는 산형은 마치 노서하전(老鼠下田)이라 하여 늙은 쥐가 밭을 향해 내려 오는 형세와도 같다고 한다.들길을 따라 참나무류와 싸리나무 등의 잡목 사이를 헤쳐 산 안으로 들어가다 보면 동백나무가 그 자태와 함께 빼곡하게 골짜기를 메우니 이곳이 바로 유명한 ‘불갑산 동백골’이다.정상 주변은 거대한 암봉으로 조망이 압권이며, 동쪽은 10여 미터의 깎아지른 절벽지대라 주의해야 한다.", + "MNTN_HG_VL" : "518", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 불갑면ㆍ함평군 해보면", + "MNTN_NM" : "불갑산" + }, + "longitude" : 126.5650998, + "latitude" : 35.190731300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 양주시 주내면에 위치한 불곡산(일명 불국산)은 작은 규모에 비해서 암릉이 많은, 아기자기하고 길게 이어지는 바위산이라 스릴 있으면서도 위험하지 않아서 산행의 묘미를 한껏 즐길 수 있는 산이다.의정부에서 시내버스로 10분이면 등산기점에 이를 수 있어 교통이 편리하고 서울 근교에 위치하여 당일 산행으로 제격이며 인적도 많지 않아 호젓한 산행지로 선택하기 좋다.산행은 유양리 백화암에서 출발, 부흥사로 하산할 수 있고 부흥사에서 산행을 시작해 백화암으로 하산하는 역코스도 있다. 불곡산은 옛날에 회양목이 많아서 겨울이 되면 빨갛게 물든다 하여 붙여진 이름이라한다. 산중턱에는 500여년쯤 된 우람한 느티나무와 신라시대 고찰인 백화암이 있다. 불곡산은 국립지리원에서 낸 지도에는 ‘불국산(佛國山)’으로 표기되어 있다. 그러나 「산경표」 한북정맥편에는 ‘불곡산’이라고 또렷이 적고 있다.불곡산은 갖가지 모양의 바위 전시장이다. 보는 이에 따라 온갖 모양이 연출된다. 너럭바위, 곰바위, 고양이바위, 투구바위, 상투바위, 산파바위, 시루떡바위 등 기묘한 바위를 찾으며 산행하는 것도 재미를 더한다. 불곡산 남쪽에 자리하고 있는 유양동에는 유양팔경이 전한다. 산성낙조, 기당폭포, 화암종성, 선동자화, 금화모연, 승학연루, 도봉제월, 수락귀운 등이다.", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 유양동", + "MNTN_NM" : "불곡산" + }, + "longitude" : 127.02581929999999, + "latitude" : 37.799757100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "불곡산은 경기도 성남시 분당구와 광주군 오포면의 경계를 이루는 해발 312.9m의 낮은 산으로 분당시민의 휴식처 역할을 톡톡히 하는 산이다. 산행은 수내동, 불정동, 정자동, 구미동에서 아무곳으로나 올랐다가 내려가면 된다.", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "경기도 성남시 분당구, 광주군 오포면", + "MNTN_NM" : "불곡산" + }, + "longitude" : 127.02581929999999, + "latitude" : 37.799757100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 성남시 분당구 정자동과 광주시 오포읍의 경계에 있는 산으로 자연 생태계가 잘보존 되어 있으며 혼효림이 무성하여 봄,여름,가을,겨울이 새롭게 보이는 산이다. 남서나 북서 방향의 행글라이딩 이륙장을 갖추고 있고, 특히 겨울에는 분당에서 생성된 열기류가 모이는 곳이므로 행글라이딩을 하기 좋은 곳으로 이름나 있다. 도심지역에 위치 하고 있어 지역주민들의 발길이 잦으며 초행길에도 그리 어렵지 않은 산행이 될것이다.", + "MNTN_HG_VL" : "465", + "MNTN_LOCPLC_REGION_NM" : "경기도 성남시, 광주시", + "MNTN_NM" : "불곡산" + }, + "longitude" : 127.02581929999999, + "latitude" : 37.799757100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "불금봉은 강원도 홍천군 북방면에 소재한 성치산의 봉우리이다. 성치산은 나지막한 산이지만, 남북으로 잇는 주능선이 의연하고 떡갈나무, 굴참나무 등 참나무류가 산초나무와 어울려 길을 가린다. 특히 등산 초입인 원골과 진골 일대는 장송이 하늘을 가려 마치 심산에 온 느낌을 준다. 불금봉에서 정상에 이르는 주능선 길 도중엔 몇 개의 무덤이 자리잡고 있어 그때마다 전망이 열리기도 한다.정상에는 괴이한 모양의 바위가 서있고 북동쪽으로 절벽을 이루면서 기암괴봉이 늘어서 있다. 또 그 아래 용담저수지가 아름답기 그지없다. 특히 강원도 홍천에 자리하고 있어 인적이 드물어 깨끗한 자연 그대로는 보존하고 있는 산중의 하나이다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면 성동리", + "MNTN_NM" : "불금봉" + }, + "longitude" : 127.84704670000001, + "latitude" : 37.733613599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "601", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "불기산" + }, + "longitude" : 127.4525, + "latitude" : 37.8030556 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "창원시와 진해시, 그리고 김해시 장유면의 경계점에 통신시설이 돋보이는 산봉이 있는데 그곳이 이 산의 정상이다. 창원시에서 보면 시역의 동쪽을 방책처럼 막아선 산릉의 끝머리에 다소곳 앉은 형세지만, 진해시에서 보면 험한 산세가 우선 눈에 띈다. 불모라는 특이한 이름처럼 아주 온화하고 포근한 산역이 대부분으로, 창원시 쪽의 산자락에 곰절이라고 불리는 성주사가 자리잡고 있어 불교와도 인연이 없는 것은 아니다.", + "MNTN_HG_VL" : "801", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시, 진해시. 김해시 장유면", + "MNTN_NM" : "불모산" + }, + "longitude" : 128.74147880000001, + "latitude" : 35.162522600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "다도해의 풍정이 물씬 나는 한려수도에 자리잡은 사량도 불모산은 사량섬을 동서로 가로지르는 능선 상에 솟아 있는 산이다. 가마봉이라고도 부른다. 사량도는 섬이 뱀처럼 생기고, 또 뱀이 많다고 해서 붙여진 이름이라고 한다.전하는 이야기에 따르면, 한 남자가 이룰 수 없는 사랑 때문에 괴로워하다가 상사병에 걸려 죽었는데 뱀이 되었다고 한다. 사량도는 모두 8개의 섬으로 이루어져 있다. 주섬은 윗섬과 아랫섬으로, 두 섬이 마주보고 있다. 이 중 불모산은 윗섬에 있다.이외에도 지리산(398m)·옥녀봉(261m) 등의 산들이 불모산과 능선이 이어져, 종주 등반하는 코스가 개발되어 있다. 서쪽에는 지리산(398)이, 동쪽에는 옥녀봉(261)을 좌우에 거느리고 있는 불모산의 정상은 거대한 바위덩이로 뭉쳐져 있다. 정상에서 조망은 사방이 탁 트여 푸른 바다에 섬들이 옹기종기 모여있는 모습이 발아래로 펼쳐지고, 그 사이로 떠다니는 배들이 한가롭다.", + "MNTN_HG_VL" : "399", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면 사량도", + "MNTN_NM" : "불모산" + }, + "longitude" : 128.74147880000001, + "latitude" : 35.162522600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "전라남도 광양시", + "MNTN_NM" : "불암산" + }, + "longitude" : 127.095, + "latitude" : 37.663333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울과 경기도 의정부시, 남양주시의 경계에 솟은 그리 높지 않은 산이다. 이 산은 덕릉고개를 사이에 두고 수락산(637.7m)과 마주하며 남북으로 우뚝한, 서울 동북쪽 공원녹지의 근간을 이룬다.불암산 주봉은 그 형상이 마치 송낙(소나무 겨우살이로 만든 여승이 쓰는 모자)을 쓴 부처의 모습과 같다 하여 불암산이라 불리게 되었으며 천보산(天寶山), 필암산(筆岩山) 이라는 이름도 가지고 있다.불암산은 사암으로 된 산이라 수목이 울창하지는 않으나 능선은 기암으로 이어지고 서울 근교의 수많은 등산학교들의 암벽교장으로 애용되기도 한다. 바위로 된 정상에서는 수락산, 도봉산, 북한산을 비롯한 서울과 남양주 쪽 조망이 아주 좋다.불암산 산행 코스 중 수락산과 북한산, 도봉산 능선을 잇는 종주코스가 최근 인기가 높다. 불암산 - 수락산 - 사패산 - 도봉산 - 북한산을 무박 2일로 이어 종주하는 ‘서울 5개산 종주산행’의 첫 출발지로 보통 불암산 자락의 불암동을 잡는다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 노원구 상계동, 중계동ㆍ경기도 남양주시 별내면", + "MNTN_NM" : "불암산" + }, + "longitude" : 127.095, + "latitude" : 37.663333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 지맥이 동쪽으로 뻗어 단지봉(1327m), 가양산(1430m), 미승봉(734m)으로 내려오다가 가야산에 이르기 전 남서쪽으로 별유산(1046m)을 지나 솟구친 것이 비계산이다.합천군과 거창군의 경계를 이루는 비계산은 인접한 별유산, 장군봉과 함께 닭이 금벼슬의 관을 쓰고 심장부에 고견사를 품고 있는 듯한 형상이다. 비계산은 닭머리 부분에 해당된다. 비계산은 돌, 너덜, 바람, 굴이 많은 산으로 유명하다. 능선상에는 암릉과 암봉들이 많아 산행시는 로프를 반드시 준비해야 한다.소요 시간 :6시간최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 갈림길에서 서쪽 능선을 따라 오른 비계산 정상은 잡목들로 어우러져 있고, 동서를 관통하는 88 고속도로 및 의상봉 상봉에서 서쪽으로 뻗은 암릉을 바라보는 경관이 좋다.도리나 거창휴게소에서 많이 올라간다. 비계산에서 시작하여 의상봉까지 종주하는 코스로 이용하기도 한다. 숲길로 활용하기 적당하나 정상부근은 안전장치가 좀더 필요할 듯하다. 휴게서외에는 식수를 구할 곳은 없다.", + "MNTN_HG_VL" : "1131", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 가야면", + "MNTN_NM" : "비계산" + }, + "longitude" : 128.06999999999999, + "latitude" : 35.7216667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "비룡산(240m)은 높이가 낮아서인지 그리 알려지지 않은 산이다. 그러나 제2의 어라연이라 할 수 있을 만큼 그림 같은 전경을 자랑하는 회룡포를 끼고 있는 산자락으로 산행길 내내 조망이 훌륭하며, 육지 속의 섬인 의성포(義城浦)를 감싸고 있는 산이다. 1998년에 세운 정자인 회룡대에 오르면 주변 경관이 한눈에 들어오는데, 특히 낙동강의 지류인 내성천(乃城川)이 휘감아 돌아 모래사장을 만든 곳에 자리한 의성포의 절경이 잘 내려다보인다. 의성포는 이웃하고 있는 회룡마을과 함께 하나의 관광지군으로 묶여 있어 회성포라고도 부르는데, 드라마 〈가을동화〉를 찍은 곳으로 유명해져서 사람들이 많이 찾고 있다.숲이 울창하며, 정상 바로 밑에 통일신라 때 의상대사의 제자인 운명선사가 세운 장안사가 있다. 1997년 11월 복원한 봉수대는 예전에 동쪽의 서암산 봉수, 서쪽의 소이산 봉수, 북쪽의 가불산 봉수와 연락을 담당하는 군사요충지였다고 한다. 정방형이며, 높이는 2.7m이다.또 마한시대에 축성된 원산성(圓山城:또는 따뷔성, 또아리성)이 있는데, 둘레가 약 920m, 높이가 1.5~3m인 토석혼축산성이다. 《군지》에는 '비룡산성'으로 기록되어 있으나 《삼국사기》에는 원형으로 쌓았다 하여 '원산성'이라고 표기되어 있다. 백제 시조 온조가 남하할 때 이 성에서 마한을 점령하고 백제를 세웠다거나, 고구려 온달 장군이 이 성을 점령하려고 내려오다 아차산성에서 전사했다는 이야기가 전해진다. 용궁향교, 무이서당(武夷書堂), 만파루, 황목근(천연기념물 400), 삼강 나루터가 가까이 있고 그밖에 용문사 대장전(보물 145) 외에 많은 문화재를 보유하고 있는 용문사와 예천 감천면의 석송령(천연기념물 294) 등 관광명소가 있다.", + "MNTN_HG_VL" : "240", + "MNTN_LOCPLC_REGION_NM" : "경상북도 예천군", + "MNTN_NM" : "비룡산" + }, + "longitude" : 129.04750000000001, + "latitude" : 36.996388899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "비봉산(飛鳳山)은 낙동 중의 낙동, 중동면 오상리의 강변에 지각변동으로 솟구쳐 생긴 산이다. 봉황이 하늘을 나는 형국이라서 이런 이름이 붙어졌겠는데, 실제 보아도 그런 것이 좌우로 펴진 능선이 비행기의 날개처럼 앞면은 두껍고 뒤쪽은 얇아지면서 깃털처럼 갈라져 영락없이 새가 날개를 펼친 모양이다. 그 가운데 정상이 머리처럼 우뚝해 강 건너편의 옥주봉을 바라보고 있다.주변이는 봉황과 관련된 지명인 죽암(竹岩). 오상리의 오동(梧桐) 마을 등이 있다.산세가 부드럽고 등산로에 소나무가 우거져 산보하는 기분으로 가족산행하기 좋은 곳이다. 솔잎을 밟고 솔향기에 취하여 강바람에 옷자락 나부끼며 음풍농월하는 데도 더할 나위 없이 좋다.정상에서 보는 낙동강은 한 폭의 그림같은 멋진 풍광을 자아낸다. 한마디로 무아지경이다. 시원스럽게 불어오는 강바람도 운치를 더해준다. 저멀리 상주의 삼악인 노악.갑장.천봉산과 속리산.청계산.작약산 등이 아련히 보이고 국민관광지인 경천대가 바로 눈앞에 다가선다. 정상 밑에는 숙종 원년(1672년)에 창건한 청용사가 자리를 잡고 있다. 사찰규모는 크지 않으나 낙동강과 어우러져 아름다움을 간직하고 종소리 은은하여 좋다.", + "MNTN_HG_VL" : "230", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 중동면 오상리", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제천에서 82번 도로를 따서 청풍으로 가다보면 오른쪽으로 호수 위에 솟은 산이 있다. 비봉산 가운데 솟은 봉우리는 봉황의 머리, 양쪽으로 뻗은 능선은 영락없는 날개니 이름 그대로 봉황이 날아갈 듯한 자태다. 금수산이나 월악산 등 명산의 그늘과 청풍문화재단지 등의 명성에 가려서 별로 알려지지 않았으나 여덟 명당 거느린 복스러운 산이다.비봉산은 산행 들머리인 연곡리부터 시작해서 사방으로 연곡리, 계산리, 양평리, 도곡리, 대류리, 신리 같은 마을들이 둘러싸고 있다. 청풍 쪽 마을은 물태리다. 이 마을들을 잇는 순환도로를 따르면 비봉산을 한 바퀴 돌게 된다. 도곡리나 양평리에서 더 들어가 길 끝자락 호숫가에 서면 흡사 섬에 온 것과도 같은 느낌이다.연곡리에서는 이백년이 훨씬 넘어 보이는 느티나무 한 그루가 길손을 반긴다. 산행은 이 느티나무가 있는 큰 길가에서 못안마을 축사 쪽으로 난 콘크리트 포장도로로 접어들면서 시작된다. 이 길에서 보면 비봉산이 거느린 여덟 개의 명당 중 하나로 짐작될 만한 곳이 눈에 띈다. 축사 뒤편으로는 흡사 봉황의 알처럼 솟은 나지막한 봉우리 두 개가 유난히 시선을 끈다. 원래 비봉산의 산세는 새가 알을 품고 있다가 먹이를 구하려고 비상하는 모습이라 했으니 두 봉우리 뒤편으로 솟은 비봉산이 더욱 범상치 않아 보인다.", + "MNTN_HG_VL" : "361", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "441", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면 문촌리", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진주시", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "비봉산은 낙동정맥 가사봉 분기점에서 뻗어나온 보현지맥을 따라 보현산을 지나고 석심산에 이르러 한 줄기는 남서쪽으로 팔공지맥, 또 한줄기는 북서쪽으로 보현지맥으로 나뉘어 구무산, 문암산을 지나 비봉산에 닿았다가 낙동강으로 흘러드는 위천을 만나면서 허리를 숙인다.비봉산은 글자 그대로 ‘봉황이 날아가는 형상’이라고 해 붙여진 이름이다. 고려시대 이전에는 태행산이라 불리다가 조선 말기에는 자미산이라 하였다고 전하나 지금은 비봉산으로 부르고 있다.경상북도 의성군 다인면, 안계면 일대는 분지형으로 사방이 산으로 둘러쳐져 있으나 모두 나지막한 산들로 이어져있다. 그 중에서 우뚝한 비봉산은 바라보는 위치에 따라 모습을 달리하는데, 동쪽에서는 봉황이 날개를 넓게 펼치고 앉아 있는 모습이고, 남쪽에서 올려다보면 봉황이 위엄 있는 자세로 날갯짓을 하는 듯하다. 서쪽 다인면 소재지에서 바라보면 장군이 투구를 쓰고 서 있는 형상을 하고 있다. 의성군에서는 손에 꼽을 정도로 아름다운 산이지만 아직 일반인에게 많이 알려지지 않은 산이다.", + "MNTN_HG_VL" : "256", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의성군 다인면", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "532", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 선산읍", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "138", + "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "125", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면", + "MNTN_NM" : "비봉산" + }, + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 청도군과 대구광역시 달성군의 경계에 있는산, 최고봉은 대건봉이며 남쪽으로는 조화봉, 관기봉과 이어지며 유가사쪽에서 올려다보면 정상을 떠받치고 있는 거대한 바위능선이 우뚝 솟아있다.정상에서 바라보는 낙동강의 경치가 아름답고 봄철에는 철쭉, 진달래 가을에는 억새군락이 볼만하다. 스님바위, 코끼리바위, 형제바위등의 이름난 바위와 달성군 옥포면의 용연사를 비롯하여 용문사, 유가사등의 사찰이 산재한다. 정상인 대견봉에서 남쪽 능선을 따라 988봉 - 조화봉으로 이어진다.조화봉 능선에서 서쪽으로 대견사 터 - 1034봉으로 이어지며 1034봉에 팔각정 전망대가 설치되어 있다. 정상에서 북으로 이어지는 능선은 앞산으로 가는 안내표시가 되어 있다.정상에서 조화봉 까지 약 4km에 걸친 능선은 988봉 주변에 바위가 있을 뿐 육산(흑산)으로 큰 나무들이 없는 시야가 탁 트이는 초원 같은 이 능선에 가을에는 억새가, 봄에는 군락을 이룬 진달래가 붉게 물들인다.진달래 군락사이에 싸리나무 등 잡목들이 섞여 있으나 진달래가 더 많다.비슬산 진달래는 정상부근, 988봉 부근 아래, 대견사 터 산자락 등 크게 3군데에 군락을 이루고 있다. 대견사터 북쪽 광활한 30여만평의 산자락이 대규모 진달래 군락지이며, 진달래가 가장 곱고 밀집되어 있는 곳은 988봉 부근 아래 산자락이다. 진달래는 4월 중순부터 물들기 시작해 4월 말에 절정에 달한다. 4월 하순경 참꽃(진달래)제가 열린다.", + "MNTN_HG_VL" : "1083", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 옥포면ㆍ유가면ㆍ가창면, 경상북도 청도군 각북면", + "MNTN_NM" : "비슬산" + }, + "longitude" : 128.52333329999999, + "latitude" : 35.715555600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산양면 부암리의 둣산이고 옛날 봉화를 올리던 곳으로 전하며 왕의산과 능선으로 이어져 있다. 현리 쪽으로 산라 때 고성인 근암성이 있는 근품산과 이어져 있다.봉우재를 거쳐 비조산(310m)에 올라가면, 전망이 시원하다. 부암, 형천, 과곡, 우본, 예천 용궁, 멀리 삼강까지 내려다 보인다. 비조산 밑으로 삼강까지는 거의 평야처럼 보인다.사람의 발길이 잦지 않아 비교적 깨끗함을 간직하고 있는 산이다.", + "MNTN_HG_VL" : "310", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 위만리", + "MNTN_NM" : "비조산" + }, + "longitude" : -73.945442299999996, + "latitude" : 40.750144800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "762", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", + "MNTN_NM" : "비학산" + }, + "longitude" : 129.2891482, + "latitude" : 36.196548900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "317", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산외면 남기리", + "MNTN_NM" : "비학산" + }, + "longitude" : 129.2891482, + "latitude" : 36.196548900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "뾰루봉은 청평호 옆에 솟아 있는 암릉이 많고 소나무가 암릉을 따라 숲을 이루고 있는 산이다. 이산은 화야산, 고동산으로 이어지면서 북한강을 따라 양수리까지 뻗은 산맥인데 이 연맥은 경춘가도의 북한강 경관을 결정하는 중요지형중의 하나이다.뾰루봉은 화야산을 주봉으로 볼 수 있는 이 능선에서 변방으로 밀려나온 듯한 느낌을 주지만 그 때문에 오히려 더 조망도 좋아 오르기가 무척 기분좋은 산이다. 높이는 화야산의 755미터에 못미치지만 청평댐을 내려다볼 수 있는 위치에 있고 암릉이 있다는 점에서 오히려 화야산보다 더 산행할 맛이 나는 산이라고 할 수 있다. 청평으로 가까워지면서 강건너 솟아있는 뾰루봉은 날카로운 인상을 준다. 청평댐은 이 뾰루봉때문에 축조될 수 있었다고 말할 수 있다. 북한강은 뾰루봉을 중간에 두고 청평댐부근에서 둥근 호를 그리며 돌아나가고 있다.호의 최원점에 댐이 있다. 이런 까닭으로 뾰루봉에서 청평댐과 북한강의 모습을 바라보기가 가장 적당하다. 암릉의 노송 가지 끝으로 바라다보이는 청평호가 그렇게 시원할 수가 없고 바람이라도 불면 귓가에 들리느니 송풍음 뿐이다.뽀루봉은 고동산과 이웃해 있는데 가평의 청평호를 건너 찾아가는 길이 아름답다. 구암리 나루터에서 배를 타고 동쪽으로 고동산을 보며 청평호를 건너면 삼회리라는 시내버스 종점이 나오는데 여기에서 고동산으로 올랐다가 뽀루봉으로 옮겨갈 수 있다. 또는 청평댐 건너편에 위치한 나이아가라 호텔 근처에서 산에 오를 수도 있다. 산에 오르면 청평호가 주위 산을 휘감아 도는 모습이 그림처럼 펼쳐진다.", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 외서면, 양평군 서종면", + "MNTN_NM" : "뽀루봉" + }, + "longitude" : 127.427809, + "latitude" : 37.721110000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", + "MNTN_NM" : "뾰루봉" + }, + "longitude" : 127.42475520000001, + "latitude" : 37.710080900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙동정맥이 백병산(1259m)을 빚고 육백산(1244m), 응봉산(1267m)을 지나 솟구친 산이 사금산이다. 이 산은 사금이 많이 난다고 해서 이름도 사금산이라 붙여졌다.고사목이 보이는 서쪽 무넹이골 사면을 지나면 1085m봉이 나타나는데 곧장 올라서지 않고 오른쪽 사면을 비켜나가면 그 아래 노송이 군락을 이루고 있어 쉬어가기 좋다. 산 정상에서는 북으로 응봉산 육백산이 펼쳐져 있고 그 너머로 낙동정맥이 기다랗게 도열해 있다.", + "MNTN_HG_VL" : "1092", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 원덕읍", + "MNTN_NM" : "사금산" + }, + "longitude" : 129.16611109999999, + "latitude" : 37.205833299999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "사달산은 노추산과 마주보고 있으며 산세는 동서로 6km에 걸쳐진 산이다. 노추산의 남쪽 봉우리가 바로 사달산(四達山)이다. 성현(聖賢) 네 분이 나신다는 산이다. 사통팔달 길이 사방으로 통한다는 이 사달산에서 공부를 하면 학문에 통달하게 되는데 지금까지 설총, 율곡, 인회 같은 이가 학문을 닦았다한다. 설총과 이율곡 선생이 동국십팔현(東國十八賢)의 반열에 올랐으니 앞으로 두 분의 성현(聖賢)이 더 나실 거라고 사람들은 믿고 있다.", + "MNTN_HG_VL" : "1187", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉, 정선", + "MNTN_NM" : "사달산" + }, + "longitude" : 128.77932329999999, + "latitude" : 37.543793399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 괴산군 청천면에 위치한 사랑산의 본 이름은 제당산이다. 사기막리의 제당골에 제당이 있어 ‘제당산’이라 불리던 것이 10년 전, ‘사랑의 영원성’을 상¡하는 연리목(連理木)이 발견되면서 괴산군청에서 산 이름을 ‘사랑산’이라 바꿔 부르게 되었다. 이 연리목은 산림청으로부터 천연보호수로 지정되었다.사랑산은 아기자기한 산이다. 초보 산행자를 위한 안성맞춤 대상지로 산길이 그리 비탈지지 않고 산행시간은 2~3시간이면 족하다. 등산로가 희미한 곳이 더러 있지만 바위와 흙길이 골고루 나 있어 산행이 지루하지 않다. 조망하기 좋은 전망바위도 곳곳에 나타나 산행의 심심함을 달래준다. 이름 그대로 코뿔소 한 마리가 서 있는 듯한 코뿔소바위, 뽀뽀를 하면 사랑이 이루어진다는 사랑바위 등이 산행의 재미를 더해준다. 사랑산을 상¡하는 연리지는 사기막리와 인접한 송면리에 있다. 그 아래에는 용추폭포가 있는데 더위를 식히기에 더없이 좋다.", + "MNTN_HG_VL" : "647", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "사랑산" + }, + "longitude" : 127.85463129999999, + "latitude" : 36.703488900000004 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : " 사룡산은 오봉산과 부산성으로 연결되는 군사적 요충지로서 신라시대 병사들이 이산을 거점으로적을 물리쳤다고 한다. 정상부근에는 음식을 날로 먹는 사람들이 모여 사는 곳이라고 하여 생식마을이 있고, 1300여년 전에 원효대사가 초창했다는 금정사가 있다. 한무당재에서 사룡산까지는 경주와 영천시의 경계지역이며, 낙동정맥 11구간으로 이구간에는관산과 만불산이 있으며, 대체로 오르 내림이 없는구간이나 형제지(형제목장고개)에서 사룡산까지는 계속 오르막길로 진땀을 빼는 구간이다. 전망대 바위에서 경주시 서면 소재지를 내려다 보면 아름다운 우리 강산임을 실감나게 하고,구간 구간에는 진달래 숲길과 산 벚꽃이 이어져 아름다움을 더 해준다.", + "MNTN_HG_VL" : "686", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 산내면, 영천시 북안면", + "MNTN_NM" : "사룡산" + }, + "longitude" : 129.0133333, + "latitude" : 35.846388900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "사명산은 정상에서 양구, 화천, 춘천과 멀리 인제군 등 네 곳의 고을을 조망할 수 있다고 해서 이름 붙었다. 춘천에서 배후령을 넘어 추곡약수를 지나면 사명산 산행들머리인 웅진리와 선정사가 보인다. 계곡의 등산로를 따라 두 시간 정도 오르면 파로호가 내려다보이는 주능선에 닿고 거기서 널찍한 평지를 이룬 정상까지는 멀지 않다.정상에 서면 화천댐으로 형성된 파로호가 화천과 양구에 걸쳐 넓게 펼쳐진 시원한 풍광이 눈맛을 시원하게 한다. 파로호 건너 우뚝한 화천 일산(1190.3m)이 육중한 산세를 자랑하며 솟았고, 멀리 설악산과 점봉산 등도 눈에 들어온다. 남쪽으로 소양호와 어울린 오봉산도 잘 보인다.봄이면 진달래가, 가을날엔 단풍이 아름답다. 설경 또한 장관을 이뤄 겨울산행지로도 인기 높다. 문바위, 첩바위 등 볼거리들이 걸음을 즐겁게 하는 사명산 남쪽 약수골에는 우리나라에서 손꼽히는 ‘추곡약수’가 있다.", + "MNTN_HG_VL" : "1198", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면, 양구군 양구읍", + "MNTN_NM" : "사명산" + }, + "longitude" : 127.9064195, + "latitude" : 38.077294899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장흥과 보성의 진산인 사자산은 곰재를 사이에 두고 제암산(779)과 마주보고 있다. 철쭉으로 유명한 '화산(花山)' 으로 해발은 낮으나 바닷가의 산이 다 그러하듯이 내륙의 산과 달리 웅장한 산세를 갖추고 있다. 사자산 정상 주변은 나무가 없이 억새와 바위로 완만한 능선을 이루고 있어 남쪽 발아래로 확 트인 남해바다의 풍경을 볼 수 있다.장흥벌을 향하여 울부짖는 사자형상으로 일컬어지는 사자산(獅子山 666m) 은 제암산, 억불산(518m)과 더불어 장흥의 삼산으로 꼽히는 명산이다 . 장흥읍쪽 봉이 사자머리 같다하여 사자두봉, 정상은 남릉과 더불어 꼬리같다고하여 사자미봉으로 불린다. 장흥벌에 솟구친 사자산은 철따라 다양한 모습을 보여준다.봄이면 파르한 기운이 스며 들면서 생명의 신비함을 느끼게 하고 여름이면 푸른 초원으로 변하고 가을이면 억새가 날리면서 강렬한 인상을 주는 산이다 사자두봉에서 사자미봉까지 이어지는 약 2km의 능선은 부드러움과 거친 자연미를 느낄 수 있다 .특히 남서면의 기암 절벽은 설악산의 어느 암릉에도 뒤지지않을 정도로 웅장하고 힘찬 자연미를 보여준다. 주능선 중간쯤의 안부와 능선 남쪽 사면은 전국에서도 유명한 활공장이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군, 보성군", + "MNTN_NM" : "사자산" + }, + "longitude" : 128.2825, + "latitude" : 37.406111099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 영월군 수주면과 횡성군 안흥면이 경계를 이루는 사자산은 지능인 연화봉 석굴에 많이 있었다는 꿀과 먹을 수 있는 흙인 전단포, 칠기의 도장 재료인 옻나무와 산삼등 네가지 재보가 많이 나기 때문에 일명 사재산(四財山)이라고 불리었다 한다. 일설에는 금.은.동이 많이 채굴되어 그렇게 부른다고도 한다.절골을 사이에 두고 백덕산(1,350m)과 마주한 이산은 남쪽 능선 끝자락으로 그림처럼 수려한 구봉대산(870)을 위시해 곳곳에 기암과 폭포를 가지고 있으며, 골이 깊어 많은 수량과 청정함을 유지하고 있어 고찰 법흥사와 조화를 이룬 산이다. 특히 겨울이면 많은 적설량에다 곳곳에 설화가 만발해 사자산을 찾는 등산객들에게 풍부한 아름다움을 선사한다.또한 등산로 경사가 완만해 가족단위 등산로로는 일품이다. 정상에 서면 가리왕산과 오대산의 산군이 물결치듯 보인다. 남쪽으로는 소백산의 고운 산줄기와 서쪽으로는 치악산맥이 한눈에 들어 온다.", + "MNTN_HG_VL" : "1181", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면, 횡성군 안흥면", + "MNTN_NM" : "사자산" + }, + "longitude" : 128.2825, + "latitude" : 37.406111099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간은 백두산을 시발로 남으로 내려오다 원산 아래 추가령지구대에서 하나의 정맥을 떨군다. 이것이 한북정맥이다. 한북정맥은 내려오면서 백암산, 적근산, 대성산, 광덕산, 백운산, 국망봉, 운악산을 이루고 도봉산에 이르기 전 사패산으로 솟아 올랐다. 사패산은 한북정맥이 운악산 끝에 이르러 기운이 명멸하듯 이어오다가 의정부에서 다시 힘차게 솟아오른 첫번째 봉우리로서 조선조 선조가 여섯째 딸 정휘옹주를 유정량에게 시집 보낼 때 마패와 함께 하사한 땅이라하여 '줄 사(賜), 호패 패(牌)' 라 이름 붙여졌다.이 산은 경기도 양주군 장흥면에 속해 있으며 안골, 회룡골, 송추계곡, 원각사계곡과 기암괴석의 범골 능선을 거느리고 있다. 정상은 커다란 암봉으로 되어있으며, 정상에 오르면 모두들 도봉, 북한산의 산줄기에 시선을 둔다. 이렇게 적은 땀을 흘리고도 이만한 경치를 즐길 수 있을까 싶을 정도로 조망이 일품이다. 거칠 것 없는 포대능선의 봉우리들이 자운봉, 만장봉, 선인봉을 에워싸고 오봉의 바윗덩어리들이 절묘하게 올라앉아 있다. 멀리 백운대와 인수봉 끝으로 상장능선이 병풍처럼 둘러져 있고 그 오른쪽으로는 노고산을 이어 한북정맥이 바다로 내쳐 달려간다.", + "MNTN_HG_VL" : "552", + "MNTN_LOCPLC_REGION_NM" : "경기도 의정부시, 양주시 장흥면", + "MNTN_NM" : "사패산" + }, + "longitude" : 127.010212, + "latitude" : 37.722460699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "사향산은 산정호수의 남쪽 5km 지점에 인접한 산이다. 또 관음산과 사향산은 산정리와 남유동을 잇는 도로를 가운데 두고 그 고개 마루턱인 낭유고개를 중심으로 동서로 마주보고 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면", + "MNTN_NM" : "사향산" + }, + "longitude" : 127.34282570000001, + "latitude" : 38.037779800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산방산은 둔덕면 산방리 뒷산으로 507.2m의 정상에는 큰 바위산 세 개가 하나의 산봉우리를 이루고 있으며, 삼봉이 우뚝 솟아 괴암괴석이 만물상을 이루고 가을 단풍이 곱게 물들면 천태만상의 대자연의 경관과 멀리 바라다 보이는 다도해의 한산섬과 서산 낙조, 멀리 보이는 작은 섬들이 점점이 떠 있어 거제의 봉산들이 다 그렇지만 정상에서 바라다보는 바다와 어우러진 경치는 필설로 표현하지 못할 만큼 절경이다.또한 거제도에 가뭄이 들면, 대대로 이곳에서 기우제를 지났다고 하는데, 지 금도 산정상에서 10M 아래에 무지개 터가 있고 주위로 기우제단이 마련되어 있다. 무지개 터라 부르는 그곳은 바위 틈새로 사시사철 물이 똑똑 떨어져 작은 우믈이 생긴곳이다. 특히 산방산 정상의 삼봉 분지 흙색깔이 다섯가지의 색을 띄고 있다 하여 오색토라 부르며, 산세가 다양하고 산중허리에 있는 석굴암이 있기도 하다.산이 높지 않아 가벼운 가을 산행지로 더없이 좋은 곳이다. 거제해금강과 외도 여행을 준비하였다면 한번쯤 들러 볼만한 곳이다.", + "MNTN_HG_VL" : "395", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 둔덕면 산방리", + "MNTN_NM" : "산방산" + }, + "longitude" : 126.3134467, + "latitude" : 33.241068200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제주도의 산중에서 가장 유명하고 경치가 빼어나며 신비스러운 분위기가 서린 곳으로, 반드시 찾아가봐야 하는 곳이 바로 산방산이다. 한라산 봉우리를 뽑아 옮겨 놓은 것이 산방산이고, 그 뽑힌 자리가 백록담이 되었다는 이야기가 있듯이 설화 속의 산방산은 수려한 용모가 단번에 찾는 이의 눈길을 빼앗을 정도로 아름답다. 매우 가파라서 오르기가 힘이드나 일단 오르고 나면 정상에서 바라보는 그 경치는 모든 피로감을 충분히 보상하고도 남으며 한번 오른 이는 다시 오르고 싶은 마음이 절로 나는산이다.또한 조면암질 안산암으로 구성되어 있으며 그 형태가 특이하다. 남서쪽 기슭, 해발고도 200m 지점에 산방굴(山房窟)이라는 자연 석굴이 있다. 그 안에 불상을 안치하였기 때문에 이 굴을 산방굴사(山房窟寺)라고도 한다. 굴 내부 천장 암벽에서 떨어지는 물방울은 산방산의 암벽을 지키는 여신 ‘산방덕(山房德)’이 흘리는 사랑의 눈물이라는 전설이 있다. 산의 남쪽 해안에는 성산포층(城山浦層)이 노출되어 있고 심한 해식(海蝕)으로 단애(斷崖)가 형성된 암석해안을 이룬다. 여기에 하멜 표류 기념탑(漂流記念塔)이 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 안덕면", + "MNTN_NM" : "산방산" + }, + "longitude" : 126.3134467, + "latitude" : 33.241068200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "산성산" + }, + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산성산은 별로 높지 않은 산으로 고적답사 차원에서 적합한 산이며, 특히 가족 동반으로 조용한 산행을 즐길 수 있다. 밀양역에서 택시로 (5,000원) 활성교 다리에 내려, 다리를 건너 상점 오른쪽길 따라 오르면 금시당에 도착한다. 버스는 구 시청 앞에서 2시간 마다 용활동 방면 버스가 있으나 매우 불편하다. 산행은 금시당 윗길을 올라 왼쪽으로 호젓한 산길에서 시작된다. 산성산의 정상에는 할머니 묘소가 있는데, 할미꽃이 무덤 위에 피어났다. 하산길은 내리막길의 연속이다.", + "MNTN_HG_VL" : "380", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 활성동", + "MNTN_NM" : "산성산" + }, + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "750", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의령", + "MNTN_NM" : "산성산" + }, + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "순창군과 담양군의 경계를 이루며 강천산(584m)과 형제처럼 솟아있는 산성산은 비록 그 높이는 낮지만 공룡등처럼 이어져있는 능선길을 따라 곳곳에 널린 유적과 절경을 감상하는 것만으로 산행의 즐거움을 충분히 챙겨갈 수 있는 그런 산이다. 이 산에 축조된 산성 때문에 산성산이라 이름 붙여졌다 하며, 일명 금성산이라고 불리는데 이는 금성면에 위치해 있기 때문이다.산성산은 해발 600m에 가까운 철마봉의 절벽에서 시작된, 연대봉, 운대봉, 시리봉 등 사방 계곡의 능선을 이용하여 축조한\"\"금성산성\"\"으로서 강천산 줄기가 서남으로 뻗어 담양군과 순창군의 경계를 이루고 각 봉우리마다 웅장한 암봉으로 이루어져 있다. 철마봉에서 서쪽으로 조망되는 담양호, 추워란의 위용 석양의 노을진 경관이 볼 만하다.", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군, 전라남도 담양군", + "MNTN_NM" : "산성산" + }, + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "달성군에서는 비슬산 정상을 제외한것 중 가장 높은 구역으로 지형과 지세가 험한 곳이 있으나 그만큼의 자연경관과 조망권을 자랑합니다. 초보들에겐 다시 힘겨운 곳이긴 하나 정상 부근에 올라가면 그 동안의 힘든 고통은 조망권 하나만으로 모든 것이 잊혀 질듯합니다. 하지만 주 등산로 외엔 혼자서의 산행은 위험하니 주의를 요한다.", + "MNTN_HG_VL" : "654", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 유가면", + "MNTN_NM" : "산성산" + }, + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "울주군 소호리와 내와리 사이 백운산 북쪽에 삼강봉이 있다. 삼강봉의 꼭대기에서 떨어지는 빗물이 3등분이 되어, 서쪽 방향은 소호리 동창천으로 해서 낙동강으로 흘러가고 동북 방향은 내와리 큰골로 해서 포항 형산강으로 흐르고, 동남 방향은 미호 저수지 그리고 미호천으로해서 울산 태화강으로 갈라져 흐르는 분수령을 이루고 있으므로 삼강봉이라고 한다.삼강봉 산행은 시간에 맞추어야 하는 고충이 있는데, 언양에서 8시 30분에 출발하는 내와 행 369번 버스를 타야 한다. 산행들머리는 지금 폐교된 두서초등학교 내와 분교 오른편 개천 따라 오르면 도 경계를 이루는 당고개에서 시작한다.", + "MNTN_HG_VL" : "851", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 소호리, 내와리", + "MNTN_NM" : "삼강봉" + }, + "longitude" : 129.18086769999999, + "latitude" : 35.681580400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "원래는 민주지산의 한 봉우리로 화전봉이었다. 삼도봉이라는 이름에 걸맞게 1989년부터 매년 10월 10일 이 삼도의 기관장과 주민들이 참석하여 삼도의 화합과 안녕을 비는 문화행사를 개최해오고 있다.삼도봉의 수목은 상수리나무가 특히 많으며, 김천 부항면 해인리 쪽으로는 호도나무가 많아 호도의 생산량이 연 70톤에 이른다.삼도봉은 소백산맥의 한 자락으로 사계절 변화무쌍한 그 절경은 가히 남한의 작은 백두산이라 칭할 만 하다.해발 1180미터인 삼도봉은 이웃한 석기봉, 민주지산과 함께 오래전부터 이름난 등산코스로 전국에 널리 알려져 있다.특히 가을 단풍이 절경이며, 산을 오르며 바닥에 밟히는 오래된 낙엽과 썩은 나무 둥치는 이 산이 아직은 때 묻지 않은 아름다운 산임을 말해주고 있고, 곳곳에 굴참나무를 비롯한 고산식물의 나무가지가 자라지 못하고 천태만상으로 구부러져 있어 신기함을 자아내고 있는데, 그리 높지 않은 산이면서도 희귀한 고산 식물이 많이 자생하고 있어, 생태학자들의 연구의 현장이기도 하다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 부항면, 전라북도 무주군 설천면, 충청북도 영동군 상촌면", + "MNTN_NM" : "삼도봉" + }, + "longitude" : 127.8761111, + "latitude" : 36.022500000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼문산(三門山)은 전남 완도군 약산면을 이루는 조약도 최고봉이다. 조약도로 가는 뱃길은 완도가 아닌 강진군 마량에서 배를 탄다. 조약도는 지형도에 표기되어 있는 행정지명이지만, 이곳 섬 주민들은 '약산도'로 부른다. 그래서 마량나루에 정박해 있는 조약도행 배에도 ‘약산’이라 붙어 있다.삼문산이라는 이름의 유래는 이렇다. 옛날 주능선 동쪽 분지인 삼개문(일명 삼감안)에서 땔감으로 쓰는 초나무나 풀을 베어 지게에 메고 서쪽 천동나루 방면으로 넘어올 때 망봉과 등거산 사이 움먹재나 망봉과 장룡산 사이 파래밭재와 큰새밭재를 넘어다녔다. 즉 세 고개를 세 문(門)으로 보았던 것이다.평범한 육산인 삼문산에 토끼바위, 쟁기바위, 부엉이바위 같은 특이한 모양의 바위들이 변화를 꽤한다. 그러나 삼문산의 매력은 사방으로 펼쳐지는 남해 바다와 여기에 떠 있는 다도해의 그림 같은 풍경에 있다. 삼문산 봉화대는 고금진의 망덕산, 신지진의 상봉, 가리포진(현재의 완도) 상황봉, 장흥 천관산으로 봉화를 하던 송신소 같은 곳이다.", + "MNTN_HG_VL" : "397", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 완도읍 약산면", + "MNTN_NM" : "삼문산" + }, + "longitude" : 126.9094444, + "latitude" : 34.381388899999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼방산은 남방산으로도 불리우며 강원도 평창군 평창읍 노론리와 미탄면 창리, 영월군 북면 공기리 사이에 있는 산이다. 푸른 숲을 간직하고 있는 산으로 옛부터 산과 나물의 고장으로 잘 알려진 강원도에 자리를 잡고 있어 산나물 산행지로 제격이다. 산행은 멧둔재를 중심으로 이루어지고 있으며 멧둔재는 삼방산의 동북능선을 형성하고 있다.평창읍 내에서 남동쪽 평창강 건너로 하늘금을 이루어 보이는 삼방산 이름의 의미는, 옛날 중요한 통로를 이루는 지역에는 대개 세 지점에 통행인을 검사하는 관방이 설치되어 있었던 데서 유래한다. 커다란 종 모습의 산으로, 평창읍을 자연성곽처럼 감싸고 있다.정상은 수림에 둘러싸여 동쪽을 빼고는 조망이 잘 되지 않으며, 대신 산을 내려오다 보면 900m봉을 지나 전망이 좋은 평야지대가 있다. 이곳에서는 평창 시가지 뒤로 옛날 숯가마가 있었다는 숯고개 너머로 장암산, 노성산이 보이고 멀리로는 배너미산, 무등산이 보이며 왼쪽으로는 종부리 마을을 휘감은 평창강과 수장산, 백덕산, 사재산 등이 바라보인다. 평창강변은 캠핑장소로 적합하며 부근에 이승복기념관, 오대산국립공원이 있다.", + "MNTN_HG_VL" : "980", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "삼방산" + }, + "longitude" : 128.4325, + "latitude" : 37.339444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼방산 산행은 태백시를 기점으로 한다. 시내버스를 타고 철암 방터골 입구 버스정차장에서 하차하여 동쪽으로 깊게 패인 방터골을 걸으면 넓은 길이 점점 좁아지며 계류도 맑아져 갑자기 깊은 산 속에 들은 기분이 든다. 실제 이곳은 태백시의 오지이다.징검다리 건너기를 여러번, 여유 있는 걸음으로 1시간 10여분 후면 원심이골 입구다. 입구에는 쌍소나무와 태백여성산악회 표지기가 있다. 원심이골에서 20분가면 합수점인데 합수점 사이 능선 대밭고리를 40분 올라 주능선 안부 전개목에 닿아 오른쪽으로 15분 능선을 따르면 늪지가 나타난다. 여기서 남쪽으로 방향을 꺾어 늪지를 내려서면 지르뫼어이 안부다. 지르뫼어이 바로 남쪽 둥그런 봉이 정상이다.하산 30분 후 돌탑에 이르러서부터는 독도에 신경을 써야 한다. 돌탑에서 육송정까지 약 2 시간 걸린다. 방터골에서 원심이골 정상을 거쳐 태백시계를 따라 육송정에 이르는 총산행 시간은 5시간 이상 소요된다.", + "MNTN_HG_VL" : "1175", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "삼방산" + }, + "longitude" : 128.4325, + "latitude" : 37.339444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "273", + "MNTN_LOCPLC_REGION_NM" : "충청북도 증평", + "MNTN_NM" : "삼보산" + }, + "longitude" : 127.5806831, + "latitude" : 36.783085399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "255", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시", + "MNTN_NM" : "삼봉산" + }, + "longitude" : 127.872652, + "latitude" : 35.892753399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼봉산(1,254m)은 고제면 봉계리에 정상을 둔 거창의 진산(鎭山)으로 산 고스락이 되는 봉우리는 세 개이며 그 중심 봉우리는 흡사 동구앞 돌무지 탑 같고 먼 데서 바라보면 흡사 피어나는 연꽃 모습 같다. 예로부터 소금강이라 부를 만큼 산 경치가 빼어났으며 가뭄이 들때면 삼봉산 금봉암에 있는 용머리 바위에서 기우제를 올리었다. 산기슭 좋은 터에 금봉암(金鳳庵)이라는 절이 있다. 절과 산 모두가 나한도량(羅漢道場)이라 하여 기도처로 이름나 있다. 이 산은 불심(佛心), 산심(産心), 무심(無心)의 삼심이 깃들고 금봉암을 둘러리한 바위무리들은 병풍처럼 둘려쳐 봉황의 산세를 이룬다. 칼바위, 장군바위, 석불바위, 부부봉, 문바위, 투구봉, 용바위, 노적봉, 칠성봉 들이 모두 셋씩 나란히 짝을 짓는다. 세 개의 영험스런 바위 샘물이 솟아나 목을 축일만한 데 모두 신령스럽고 영험스런 샘물이라고 하며 천지인(天地人)을 우러른 삼신사상(三神思想)과 인연이 깊다. 덕유산으로 달리는 큰 줄기에서 동쪽으로 내린 가지에는 시루봉이 솟아 있으며 남쪽 골짜기는 금(金)이 난다. 산행은 크게 두가지로 나뉘는데 갓파르고 낙석의 위험이 있는 칼바위쪽으로 올라 바위굴샘을 거쳐 억새능선을 타고 오르는 코스와 삼성각 오름길에서 북쪽 용바위용굴을 비켜 오르는 능선길 코스가 있는데 8㎞에 3시간정도 소요된다.소요 시간 : 1코스 : 4시간 30분 신풍령 → 4 km(3시간) → 삼봉산정상 → 3km(1시간30분) → 소사재 2코스 : 2시간 10분 금봉암 → 1.4km(40분) → 삼봉산정상 → 1.2km(20분) → 북능 → 3.8km(1시간 10분) → 봉계리 원기동최적 탐방 시기 :사계절볼거리 : 일봉산에서 본 조망 정상부가 세 개의 봉우리로 이루어져 있는데 멀리서 보면 그 모습이 마치 연꽃 봉우리 같이 보인다. 금봉암에서 시작되는 산행은 가파른 바윗길과 안부를 지나면 정상에 이를 수 있다. 정상은 폭이 좁지만 주변 경관은 확 트여 있어 시원한 느낌이 든다. 산행의 기점이기도 한 삼봉암은 1905년 창건된 사찰이다. 전해오는 이야기에 의하면 금봉안 창건주가 지관이 잡아둔 자리에서 가마솥 뚜껑이 덮인 샘물을 마셔가며 백일 단식기도를 드리고 회향하던 날 황금빛 새가 산봉우리와 기도처를 세 번이나 왕복한 후에 어디론가 날아가서 그 자리에 절을 지었다고 한다. 그리고 그 절의 이름을 금봉암이라 하였는데, 사찰의 요사채 뒤편엔 옛날 거창 부사가 기우제를 지내던 용머리 형상의 바위가 있다.숲길 명소 : 산행길에는 억새밭과 잣나무 숲이 펼쳐지고 정상에 서면 덕유산의 웅장한 모습이 펼쳐진다. 정상의 줄기에는 밑둥이 큰 떡갈나무들이 주종을 이루며 특히 겨울의 눈꽃이 볼 만하다.등산객은 거의 없으며, 인근 주민들이 운동삼아 오르는 정도의 작은 산. 비교적 등산로는 잘 되어 있으나, 삼봉산 정상이란 표식이 없어 정상인지 구분이 안감. 산내에 화장실, 음수대가 없어 다소 불편함.", + "MNTN_HG_VL" : "1254", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 고제면", + "MNTN_NM" : "삼봉산" + }, + "longitude" : 127.872652, + "latitude" : 35.892753399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", + "MNTN_NM" : "삼봉산" + }, + "longitude" : 127.872652, + "latitude" : 35.892753399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 제천시 백운면 화당리와 덕동리를 경계로 우뚝 솟아있는 삼봉산은 치악산 남대봉에서 서남쪽으로 갈라져 나온 백운산(1,078m)의 기세를 이어받은 산이다. 원주-봉양-박달재-산척-목계-귀래를 경유하여 백운산-구학산-주론산-시랑산-천등산-오청산-옥녀봉-십자봉 능선이 어깨를 맞대고 산 주변을 감싸고 있어 마치 그 가운데 푹 파묻혀 있는 듯한 느낌이 든다. 이렇듯 주변 산세에 둘러싸여 있는 까닭에 광복 전까지만 해도 호랑이가 종종 출몰했다고 전해진다. 실제로 호환을 당한 사람들의 시신을 돌무덤으로 쌓아놓은 호식장의 흔적이 남아있고, 대호지매점에서 1.5km 떨어진 지점에서는 호식총도 볼 수 있다. 원시림에 들어온 듯이 태고의 신비와 자연미가 살아있는 삼봉산은 그러나, 6.25의 아픔을 간직하고 있는 산이기도 하다. 산이 깊어 빨치산과 공비들이 숨어들자 삼봉산 아래에 비행장을 건설하려 공비를 토벌하려 했다는 이야기도 전해져 내려온다.정상에는 삼각점과 바위가 몇 개 있고, 시야를 막는 큰 나무가 없어 전망이 좋다.", + "MNTN_HG_VL" : "910", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면", + "MNTN_NM" : "삼봉산" + }, + "longitude" : 127.872652, + "latitude" : 35.892753399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우리나라 산 중에는 봉우리의 숫자에 의하여 이름지어진 산들이 많은데 삼봉산(三峰山)도 여기에 행당되는 산으로, 정상은 암봉으로 이루어진 세 개의 봉우리가 나란히 사이좋게 솟아있다.이 산의 특징은 낮으면서도 산세가 수려하여 한 때 신선이 내려와서 놀았다고 전하여져 내려오고 있으며, 산 정상부에 바둑판이 새겨진 바위가 있었다고 하나 세월의 풍화작용에 의하여 지금은 그 흔적을 찾아볼 수 없는 아쉬움이 있다.", + "MNTN_HG_VL" : "448", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 낙동면 유곡리, 상촌리", + "MNTN_NM" : "삼봉산" + }, + "longitude" : 127.872652, + "latitude" : 35.892753399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;세 성인 상징하는 경산의 대표 산gt;경북 경산은 흔히 삼성현(三聖賢)의 고장으로 불린다. 세 성인, 즉 원효대사와 설총, 삼국유사를 저술한 일연이 태어난 곳이기 때문이다. 이 삼성현을 상징하는 산이 바로 삼성산이다. 경산시 남산면에 위치한 삼성산 가는 길은 대구·경북 일원에서는 물 좋기로 정평이 난 상대온천 가는 길, 상대온천이 산행의 들머리이자 날머리이기 때문이다. 그래서 삼성산은 이곳을 기점으로 온천과 연계한 산행 대상지로 제법 알려져 있다. 산의 높이가 말해주듯 산세는 크지 않은데 정상에서는 남산면과 자인면 일대의 벌판이 보이는 정도다. 그러나 이 산자락에 삼성현의 얼이 서려있는 성지곡, 성제지, 성참사, 불당지 등이 자리하고 있다. 정상 언저리에는 원효가 창건한 성지암이라는 절간이 있었던 것으로 추정되며, 현재는 외면상 그 흔적은 없고 기왓장만 간혹 출토되고 있다고 전한다. 주능선은 북서쪽으로 백화산(486m), 남서쪽으로 청도군 학일산(693m)으로 이어진다. 한편, 경산시는 2012년 완공 목표로 삼성산 진입 길목인 인흥리에 수백억 원을 들여 이른바 ‘삼성현역사문화공원’을 조성 중에 있다. 삼성현의 업적과 정신문화를 계승, 발전시키기고 위한 것으로, 공원이 들어서고 나면 삼성산은 그야말로 경산의 진산으로 거듭날 것이다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", + "MNTN_NM" : "삼성산" + }, + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼성산은 경상북도 경산 읍내에서 남동쪽으로 약 10km 지점에 위치하고 표고는 554.2m의 나지막한 산이지만, 북쪽 산록에는 온천이 있어 가벼운 등산과 온천욕을 함께 즐길 수 있는 곳으로 인근에서는 자주 찾는 산중의 하나이다.상대 온천장 앞 버스 종점에서 서쪽 계곡을 따라 들어가면 저수지가 있고, 이 곳에서는 좌측 계곡을 따라 정상으로 바로 오르는 길과 우측길을 따라 고개를 거쳐 남동 능선을 경유, 정상으로 오르는 두 가지 길이 있다. 정상 서쪽 능선상에는 키를 넘는 억새 풀밭으로 되어 있다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", + "MNTN_NM" : "삼성산" + }, + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", + "MNTN_NM" : "삼성산" + }, + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울시 관악구와와 안양시를 경계로하는 삼성산은 관악산 주능선에서 서쪽으로 뻗어내린 팔봉능선을 타고 무너미고개로 내려 않다가 다시 솟구쳐 오른 산으로, 삼성산 아래 국기봉과 삼막사로 많이 알려져 있으며, 바위로 된 암산이다.관악산, 삼성산은 양쪽 봉우리가 서로 이어져 있어 일반 등산객들은 삼성산을 관악산의 한 작은 봉우리로 여겨 삼성산 정상에서도 관악산에 오른 것으로 생각하기도 하여 요즘은 특별하게 둘을 구분하지 않고 있다. 원효대사가 의상, 윤필과 함께 삼막사란 사찰을 짓고 수도하였다 하여, '삼성산' 이라는 이름이 붙여졌다고 한다. 이 산에는 신라 문무와 17년 (677)에 창건한 삼막사, 고려 태조때 창건한 염불암, 그리고 망월암등 절과 암자가 산자락에 자리잡고 있다.관악산 유원지로 들어서면 왼쪽이 관악산, 오른쪽 능선이 삼성산 능선이다. 삼성산의 등산로는 서울대, 시흥동, 관악역, 안양유원지 등을 기점으로 하는 코스가 있으며 삼막사, 남근석, 상불암, 망월암을 잇는 한적한 길도 있다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구, 금천구, 경기도 안양시", + "MNTN_NM" : "삼성산" + }, + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", + "MNTN_NM" : "삼성산" + }, + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼신봉은 어미의 품처럼 넓은 지리산 자락에 흩어진 수십개 봉우리 중의 하나로 영신봉(1652m)에서 남쪽으로 길게 뻗은 능선상의 최고봉이다. 또한 지리산 주능선의 전망대로서 참다운 가치를 가질 뿐만 아니라 악양으로 흘러내린 형제봉 능선과 멀리 남해 바다의 일망무제, 탁트인 전경을 선사해준다.특히 인적드문 비경의 남부능선 한가운데에 우뚝 솟아 동으로는 묵계 치를, 서쪽으로 생불재(상불재), 남으로는 청학동을, 북쪽으로는 수곡재와 세석 을 이어주는 사통팔달 요충지로서의 역할을 한다.지리산 하동지역은 쌍계사, 칠불사 등의 절을 비롯하여 불일폭포, 화계계곡, 청학동, 도인촌 등의 볼거리도 많다. 청학동 마을에서 삼신봉을 바라보면 왼쪽부터 쇠통바위, 가운데는 내삼신봉, 오른쪽이 외삼신봉으로 세 개의 봉우리가 눈에 들어온다.특히 삼신봉은 봄의 벚꽃 산행지로 이름 나 있다. 하동-쌍계사 십리 벚꽃길, 섬진강 60리 벚꽃길이 매년 4월 초순이면 장관을 이룬다. 수령 60년이 넘은 아름드리 벚나무가 구불구불한 계곡을 따라 활짝 필때 벚꽃산행지로 많은 사람들이 찾는다. 10리 벚꽃길은 젊은 남녀들이 걸으며 백년해로를 기약하는 경우가 많다고 해서\"\"혼례길목\"\"으로 불린다.섬진강 벚꽃길 60리는 섬진강 꽃길 따라 60리를 간다.구례에서부터 따라붙은 섬진강은 지리산에서 거친 숨결로 내려온 화개천과 만나 물줄기가 굵어진다. 이곳이 바로 화개장터로 불리는 탑리이다.", + "MNTN_HG_VL" : "1285", + "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군", + "MNTN_NM" : "삼신봉" + }, + "longitude" : 127.70404569999999, + "latitude" : 35.264464199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼악산(三岳山)은 한북정맥상의 포천 백운산 밑에서 동쪽으로 갈라진 지맥이 석룡산, 화악산, 계관산으로 이어지고 옛날 경춘 간 육로교통의 춘천관문이었던 석파령을 넘어 끄트머리에서 솟아 신연강 협곡을 이루어 놓은 명산이다.또한 협곡에 설치된 의암댐으로 호수가 생겨 물 속에 투영된 산을 볼 수 있어 더 한층 좋다. 매표소에서 계곡을 오르다 보면 등선폭포, 비선폭포, 승학폭포, 백련폭포등 크고 작은 폭포가 있으며, 용화봉, 청운봉, 등선봉을 비롯 3개의 봉우리에서 뻗어내린 능선이 암봉으로 이루어져 절경을 이룬다.기암괴석이 많고 소나무, 참나무등의 수림이 울창하며 계곡미가 빼어나다.삼악산의 산행기점은 세 군데 이다. 등선폭,상원사,강촌역에서 다리건너 바로 시작하는 세 기점이 있다. 대부분의 등산객들이 등선폭쪽에서 산행을 시작하나, 의암댐이 있는 상원사입구에서 시작하여 등선폭포로 내려오는 것이 좋다.", + "MNTN_HG_VL" : "656", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 서면", + "MNTN_NM" : "삼악산" + }, + "longitude" : 127.66031169999999, + "latitude" : 37.839902700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼암봉은 지도읍 읍내리에서 시작하여 광정리를 거쳐 감정리에 이르는 길이 10km가량으로 북서에서 동남방향으로 지도읍 중앙을 가로지르고 있다. 큰산, 깃대봉, 삼암봉으로 이어지는 3개의 봉우리가 있고주능선을 따라 등산로가 잘 정비되어있어 산행 중 섬 산행의 특성인 바다내음과 함께 다도해의 아름다운 풍광을 같이 즐길 수 있다. 옛날 삼암봉 봉우리에 작은 바위가 있는데 그바위에 조그만 웅덩이가 있었다. 일제강점기에 측량을 위해 그 웅덩이에 삼각점을 심어 현재는 웅덩이를 볼 수 없으나 옛날 삼암봉 정상부에 과일나무가 많아 삼암봉을 오르는 이들이 많았다고 한다 그러던 어느날 어떤 여인이 삼암봉에 올랐다가 웅덩이에 물을 마신후에 임신을 했고 출산을 했는데 뱃속에서 뱀들만 나왔다 하는 설화가전해진다.", + "MNTN_HG_VL" : "196", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군 지도읍", + "MNTN_NM" : "삼암봉" + }, + "longitude" : 126.17944439999999, + "latitude" : 35.090555600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼정산은 지리산 주능선 삼각고지에서 북쪽으로 뻗어 내린 능선에 우뚝 솟은 산으로, 지리산 산자락에 있는 봉우리이면서 '봉(峰)'이 아닌 '산(山)'으로 기록되어 있다. 천왕봉에서 노고단으로 이어지는 지리산 주능선상에 솟아 있는 봉우리를 통상적으로 '봉'이라 부르고 있으며 주능선을 기점으로 써레봉,삼신봉,왕시루봉 등 동, 남, 서쪽의 곁가지 봉우리들도 모두 봉으로 부르고 있다.부드러운 산세로 등산로에 위험한 곳은 없으나 군데군데 기암과 고사목, 노송 등이 어우러진 빼어난 경관이 산재하고, 단풍이 아름답고 붐비지 않는 한적한 산길이어서 더욱 좋다.능선의 동쪽면에는 도솔암, 영원사, 등 7개소의 사암이 남아있다. 옛날에는 군지사, 도마암, 정승절 등이 있었으나, 절터만 남아있고, 정승골 계곡 주변은 옛 모습을 간직한 채 풍경이 아름답다.", + "MNTN_HG_VL" : "1182", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 마천면, 전라북도 남원시 산내면", + "MNTN_NM" : "삼정산" + }, + "longitude" : 127.02396520000001, + "latitude" : 36.555352999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼태봉은 광주산맥의 한 갈래로서 가평군에 위치하고 있다. 광주산맥의 한 갈래로 좌우에는 중미산과 화야산이 있고, 산위에 오르면 서쪽으로는 북한강, 동쪽으로는 뇌암산이 손에 잡힐 듯 다가오며 북동쪽으로는 곡달산이 바라 보인다.좌우로 중미산(834), 화야산(755), 용문산(1,157), 통반산(650)이 자리하고 있어 같이 연계하여 등산하는 것이 좋다. 특히 통반산과 같이 산행하는 것이 일반적이다.정상은 암번으로 이뤄져 있어 쉼터로 좋고, 한강의 조망이 일품이다. 그리고 통방산까지 이어지는 산길은 완만해서 좋고, 주변은 수림이 울창하다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군\/양평군", + "MNTN_NM" : "삼태봉" + }, + "longitude" : 129.36437799999999, + "latitude" : 35.691971500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 단양군 어상천면과 영춘면 사이에 솟아있는 삼태산은 마치 삼태기 세 개를 엎어놓은 듯한 산세를 하고 있어 이와 같은 이름이 붙었다. 그러나 서쪽인 대전리나 남쪽인 임현리에서 바라보면 누에가 기어가고 있는 듯한 형상과 흡사하여 누에머리산이라고 불리기도 한다. 삼태산은 단양팔경과 인근 유명산들의 명성에 가려 산악인들에게 그리 잘 알려진 산은 아니다. 일반에게 잘 알려지지 않아 자연이 잘 보존되어 있다.어상천면과 영춘면 사이에 있는 농우재고개가 삼태산과 오기산을 이어주는데, 예로부터 주민들은 하늘 높이 솟아오른 삼태산을 남자산, 산세가 부드러운 오기산은 여자산으로 불러왔으며 두 산이 서로 바라보면서 항상 그리워한다고 여겼다.산허리의 단양팔경 중 2경인 일광굴의 신비한 풍광과, 산 구비구비 계곡 곳곳에 스며있는 애틋하고도 재미난 전설들은, 이 곳을 찾는 사람들의 발길을 즐겁게 해주고 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 어상천면", + "MNTN_NM" : "삼태산" + }, + "longitude" : 128.37006980000001, + "latitude" : 37.120670199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "714", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 주문진읍 삼교리 \/ 양양군 현남면", + "MNTN_NM" : "삼형제봉" + }, + "longitude" : 128.71777779999999, + "latitude" : 37.903888899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삿갓봉은 한북정맥을 주맥으로 하여 귀목봉(1,036m), 화악산(1,468m), 응봉(1,436m)을 거쳐 북배산(867m)의 지맥이 뻗어 내려오다 가덕산 동쪽에서 일으켜 세운 산이다. 주변의 천m급 산들이 위세당당하게 솟구쳐 있어 716m의 삿갓봉은 막내처럼 아기자기하게만 보인다. 일반에 잘 알려지지도 않아 오염되지 않았으며, 삼박골계곡은 수량이 풍부하고 매우 깨끗하게 유지되고 있으며 임도 끝에서 숲터널을 통과 계류를 건너면 와폭이 나타난다.주변은 가을 단풍이 좋고 우거진 숲 속의 오솔길이 정겹다.정상에서는 산과 강을 휘둘러보면 조망이 아름답다. 서편은 몽덕산과 북배산 쪽으로 뻗은 능선이 하늘금을 이루고, 북쪽 화천의 명산들이 파도처럼 일렁이고 춘천호와 춘천시까지 대룡산, 북한강 등 산수가 어우러진 풍경이 빼어나다.또한 정상에서 내려다 본 신매저수지가 유난히 돋보이고 하산 길은 큰 굴곡 없이 등산기점으로 회귀할 수 있도록 연결되어 있어 좋다.", + "MNTN_HG_VL" : "716", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 사북면", + "MNTN_NM" : "삿갓봉" + }, + "longitude" : 127.6993477, + "latitude" : 35.787457400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1134", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", + "MNTN_NM" : "삿갓봉" + }, + "longitude" : 127.6993477, + "latitude" : 35.787457400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삿갓봉은 강원도 횡성에 자리한 산이다. 삿갓봉이란 이름은 정상인 봉우리의 생김새가 삿갓을 쓴 모습과 너무나 닮아 있어서 붙여진 이름이다. 실제로 이 산을 찾은 사람들은 멀리서부터 삿갓봉의 생김새를 바라보며 이름과 똑같은 생김새에 감탄하기 일쑤다. 백두대간의 주맥인 오대산에서 갈래친 지맥이 계방산, 운두령을 지나 남하하면서 태기산을 솟구치고 영동고속도로를 뛰어 넘어 문치재에 이르러 잠시 떨어졌다가 안간힘을 다해 일군 산이 강원도 횡성군의 삿갓봉이다.정상은 헬기장으로 이루어져 있어 조망은 사방 막힘이 없다. 동으로는 사자산에서 달려오는 주능선이 지그재그로 삿갓봉으로 이루지고 , 사자산 능선 넘어 백덕산 정상이 M자 형태로 머리를 내밀고 있다. 남으로는 화채봉이 손에 잡힐 듯하고 구룡산 넘어 감악산 방면 산세가 시야에 겹겹이 들어오고 , 서남쪽으로는 하늘금을 그린 치악산 주능선과 비로봉이 압권이다.", + "MNTN_HG_VL" : "716", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군", + "MNTN_NM" : "삿갓봉" + }, + "longitude" : 127.6993477, + "latitude" : 35.787457400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삿갓봉은 백두대간의 주맥이 갈라져 나와 백적산을 세우고 청옥산을 일구며 강원도 평창 남서쪽으로 산세를 뻗쳐 솟아오른 산이다. 삿갓모양으로 우뚝 서 있어 삿갓봉이라 불리는데, 백운산, 응봉, 매봉 등과 마찬가지로 전국에 똑같은 이름의 산들이 곳곳에 산재해 있어 우리에게 친근하게 느껴지는 산이기도 하다.강원도 평창군의 삿갓봉은 강원도의 산들이 대개 그렇듯이 첩첩산중 오지 중에 오지로, 산세가 험하고 골이 깊기로 유명하다. 사람의 발길이 얼마 닿지 않아 울창한 산림이 그대로 보존되어 있고, 작은 벌레가 바스락거리는 소리까지 들릴 정도로 주변이 조용하여, 쾌적하고 여유로운 산행을 즐기기에는 안성맞춤인 산이다. 1천미터 이상의 기암괴석들이 봉우리를 이룬 정상에 오르면 북쪽으로 남병산, 남쪽으로 삼방산, 동쪽으로 청옥산, 그리고 서쪽으로는 장암산 등이 손에 잡힐 듯 조망되어 산행의 즐거움을 한껏 느낄 수 있는 산이다.", + "MNTN_HG_VL" : "400", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍, 미탄면", + "MNTN_NM" : "삿갓봉" + }, + "longitude" : 127.6993477, + "latitude" : 35.787457400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1055", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "삿갓봉" + }, + "longitude" : 127.6993477, + "latitude" : 35.787457400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 청원군 북일면과 낭성면 사이에 위치한 상당산은 서편으로 우암산(338m)과 마주하며 다소곳이 솟아있다. 일명 상령산(上嶺山)으로 불리우는 상당산에는 전적지로 유서 깊은 상당산성이 둥지를 틀고 있으며, 그 안쪽에는 30여채의 한옥이 모여있는 한옥마을이 조성되어 있다. 기록에 의하면 원래 성안에는 운주현, 관아사, 군기고, 군량고, 동창, 서창 등의 방어시설이 구축되어 있었으나, 지금은 모두 사라지고 한옥마을만이 자리를 지키고 있다. 그나마 민속음식을 파는 상점들로 변하여 옛날 격전지로서의 흔적은 찾아보기 힘들다.이 상당산성은 삼국시대때 처음 축조된 것으로 전해지고 있으며 이후 조선 숙종 때 오늘날의 모습으로 정비되었다고 한다. '상당'이라는 이름은 백제 때 청주목을 상당현으로 부른 것에 유래하고 있다. 상당산성은 사적 제 212호로 지정되었다. 기록에 의하면 원래 성안에는 운주현, 관아사, 군기고, 군량고, 동창, 서창 등의 방어시설이 구축되어 있었으나, 지금은 모두 사라지고 한옥마을만이 자리를 지키고 있다. 그나마 민속음식을 파는 상점들로 변하여 옛날 격전지로서의 흔적은 찾아보기 힘들다.", + "MNTN_HG_VL" : "491", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구", + "MNTN_NM" : "상당산성" + }, + "longitude" : 127.539913, + "latitude" : 36.661709999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "상산(서리산)은 축령산을 가운데 두고 능선으로 우측은 은두봉, 좌측은 상산이 2 - 3km 간격을 두고 이어져 있다. 상산은 축령산의 서북 능선과 이어진 산으로 마주보고 있다. 일명 서리산 이라고도 불리며 축령산과 더불어 서울특별시에서 가까운 곳에 있으면서도 사람이 덜 찾는 산이었다. 그러나 축령산 자연휴양림이 개장하면서 본격적으로 알려지고 주능선에 수천평의 철쭉 군락지가 발견되고 부터는 많은 인기를 끌고 있는 산이다.산세는 주능선 북쪽 사면이 바위 벼랑에 가까은 급경사로 이루어진 반면 남쪽은 완만한 경사로 이루어져 있다.따라서 등산로는 축령산 자연휴양림이 있는 남쪽 위주로 발달 되어있다.정상은 나무하나 없이 시야가 탁 트이며 축령산이 가깝게 보인다.정상에서 능선을 따라 축령산으로 오를 수 있는데 절고개 부근은 가을이면 억새가 가득하여 볼만 하다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평시", + "MNTN_NM" : "상산" + }, + "longitude" : 127.1186993, + "latitude" : 35.804417700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "함양 사람들에게 함양의 낮고 좋은 산이 어디냐고 물으면 서슴없이 서리산이라고 추천한다. 국립지리원의 지도에는 상산(霜山)이라고 표기되어 있지만 현지 주민들은 순수한 우리말인 서리산이라 부른다. 그런데 함양군청에서는 발행하는 행정지도에는 오봉산이라 표기되어 있고 현지 안내판 모두 오봉산이라 한다. 큰 암봉이 다섯 개여서 붙여진 이름이다.바위산인 서리산은 크고 까마득한 암벽과 낭떠러지가 곳곳에 있고 골짜기는 바위봉우리들로 협곡을 이루고 있어 경관이 빼어나다. 이 암봉들은 보통의 암봉과 달리 치악산 고스락의 석탑처럼 위가 둥글고 높게 쌓은 탑처럼 보이기도 하고 별천지로 들어가는 석문을 연상케 하기도 한다. 특히 아재원에서 오르는 도중 올려다보이는 거대한 쌍둥이 암봉은 참으로 멋있다.또 이 산은 낙락장송이 많아 기암괴봉들과 어우러져 더욱 아름답다. 단풍도 아름다워 가을의 경관이 일년 중 가장 좋기로 손꼽힌다. 함양 사람들이 가장 좋아하는 산으로도 꼽혀 경상남도 당국에서는 함양 사람들을 위해 이 산에 안내판을 비롯해 많은 시설들을 설치했을 뿐 아니라 산길도 잘 정비해 두었다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 함양읍, 남원시 아영면", + "MNTN_NM" : "상산" + }, + "longitude" : 127.1186993, + "latitude" : 35.804417700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1117", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면", + "MNTN_NM" : "상운산" + }, + "longitude" : 129.02408159999999, + "latitude" : 35.636000099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정선 아라리로 유명한 아우라지가 산의 아랫부분을 감아돌며 절경을 보여주는 산으로 철쭉 군락과 오래된 주목이 눈을 즐겁게 한다. 정상에서는 사방을 시원스럽게 조망할 수 있는데, 북쪽 멀리 백두대간도 보인다. 이곳에는 중국의 무릉도원에 비견되는 전설이 전해지는데, 이 산에서는 병도 안들고 늙지도 않는다는 것이다.또한 옥갑장군이 이 산에서 무예를 닦고 그가 입었던 갑옷을 산속에 숨겼다는 옥갑산봉도 남쪽에 있다. 상원산은 강원도 정선군의 최북단인 북평면과 북면 사이에 솟아있다.동쪽에는 평창군 도암면의 황병산 부근에서 발원하여 남쪽으로 흐르는 남한강의 지류인 송천이 심한 곡류를 이루고 있다. 부근에는 정선탄전에 속하는 탄광이 있으며, 석탄을 수송하기 위해 부설된 정선선의 기점이 된다. 북쪽에 두루봉, 서쪽에 갈미봉, 남쪽에 백석봉과 옥갑산봉, 북동쪽에 노추산 등이 솟아 있다.", + "MNTN_HG_VL" : "1421", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면, 북면", + "MNTN_NM" : "상원산" + }, + "longitude" : 128.67638890000001, + "latitude" : 37.508333299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "철따라 특징이 두드러지니까 명산이지만 이른 봄에 더욱 돋보이는 산이 충북 보은군 산외면과 경북 상주시 화북면에 걸쳐 있는 상학봉(上鶴峰,834m)이다. 뒤로는 묘봉, 앞으로는 미남봉과 마주보는 봉우리로 이름 그대로 정상 부근 암봉에 상급의 학들이 많이 모였었다.속리산 북서쪽에 숨어 있듯이 자리잡고 있는 상학봉은 산 전체가 아기자기한 바위산이어서 기암전시장을 방불케 한다. 공룡의 등허리인 양 기묘한 바위들이 울퉁불퉁 튀어나와 있는 공룡바위를 비롯, 돼지바위, 애기 업은 바위, 문바위 등이 연이어져 있어 지루한줄 모르고 산행을 할 수 있다.정상은 동남북 삼면이 천야만야한 수직절벽이다. 웬만큼 심장 강한 사람도 금세 현기증이 일고 오금이 저려온다. 손에 땀을 쥐고 엉금엉금 기다시피 자리를 옮기면서도 산 아래로 펼쳐지는 절경을 자꾸만 보게된다.", + "MNTN_HG_VL" : "834", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면", + "MNTN_NM" : "상학봉" + }, + "longitude" : 127.8344726, + "latitude" : 36.569043200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1024", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군", + "MNTN_NM" : "상해봉" + }, + "longitude" : 127.4307982, + "latitude" : 38.115392399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "완도군은 전남 해남군 땅끝 동쪽의 크고 작은 섬 202개로 이루어졌다. 이 가운데 완도가 가장 큰 섬으로 군소재지다. 상황봉은 완도에서 가장 큰 산이다. 완도 사람들은 오봉산이라고도 하는데 상황봉, 업진봉, 숙승봉, 백운봉, 쉼봉 등 다섯 개의 봉우리가 솟았기 때문이다. 고대 중국 남방에 살면서 주변을 오가며 무역하던 뱃사람들은 이 산에 부처님의 흔적이 있다 해서 ‘상왕(象王)’이라 불렀다고도 한다. 부처를 낳은 마야부인은 흰 코끼리가 배에 들어오는 태몽을 꾸었다. 그래서 코끼리의 왕이라고도 한다.옛날 어느 스님이 숙승봉의 토굴에 기거하며 수도하였고, 업진봉에 이르러 업을 다하였고, 백운대에 이르러 흰구름을 벗삼고, 쉼봉에 이르러 바다를 보며 잠시 숨을 고른 다음, 상황봉에 이르러 부처가 되었다는 유래도 있다. 관음사터와 중암사지는 흔적만 남아 있지만 상황봉이 예부터 불교의 산이었음을 뒷받침하고 있다.상황봉은 조망이 빼어난 산이다. 맑은 날이면 주변에 펼쳐진 오밀조밀한 다도해 풍경은 물론, 멀리 제주도 한라산까지 볼 수 있는 뛰어난 전망대다. 서쪽으로는 해남 달마산과 함께 두륜봉, 가련봉, 덕룡산, 주작산, 월출산 등이 펼쳐지고, 동쪽으로는 천관산이 보인다.난대성 상록활엽수림이 제공하는 독특한 풍치 또한 다른 곳에서 맛보기 힘든 이색적인 경험이다. 짙푸른 난대림으로 뒤덮인 완도 상황봉 일대는 거의 대부분 완도수목원에 편입되어 있다.", + "MNTN_HG_VL" : "646", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 군외면", + "MNTN_NM" : "상황봉" + }, + "longitude" : 126.6931914, + "latitude" : 34.348111099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "상황봉(644.1m)은 완도 최고봉답게 백운봉(600m), 숙승봉(435m) 등 거물급 봉우리를 거느리고 섬 중앙에 우뚝 솟았다.완도팔경의 하나인 백설홍춘(내린 눈속에 핀 동백꽃)은 수령 백년 이상의 동백나무가 많은 죽청리 동백림을 두고 이른 것인데, 상황봉은 이 동백나무와 돈나무 등의 상록활엽수와 단풍나무, 떡갈나무 등 낙엽활엽수가 어우러져 산 전체가 식물원으로 조성된 듯한 느낌을 준다. 또한 동백나무 자생지로는 국내에서 가장 넓은 동백나무 군락지가 삼두리 전남 청소년수련원 부근에 있다.상황봉에서 보는 조망 또한 일품이다. 봄이라 시야는 좋은 날이 드물긴 하지만, 맑은 날이면 주변에 펼쳐진 치밀한 다도해의 풍정이 볼 만하다. 멀리 한라산의 장엄한 모습도 볼 수 있다면 정말 운이 좋은 사람일 것이다. 서쪽으로는 해남 달마산과 함께 두륜봉, 가련봉, 강진의 덕룡산, 주작산, 월출산 등이 병풍처럼 둘러섰고, 동쪽 가까운 곳에 천관산이 솟았다. 전남 지역의 명산을 두루 조망할 수 있는 장소다.", + "MNTN_HG_VL" : "644", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 완도읍 군외면", + "MNTN_NM" : "상황봉" + }, + "longitude" : 126.6931914, + "latitude" : 34.348111099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "새득이봉은 강원도 춘천시 북산면 물노리와 홍천군 두촌면 천현리 경계선상의 가리산과 맥락을 같이하는 산이다. 워낙 산이 깊다보니 사람들의 접근이 쉽지않고 또 비교적 덜 알려져 있어 일반인들에게는 생소한 지명이다. 새득이봉은 원시청정림이 살아숨쉬는 곳으로 환경이 오염되지 않아 어디를 가나 빽빽한 나무에서 뿜어져 나오는 상쾌한 공기를 호흡할 수 있다. 심산유곡의 분위기를 한껏 자아내는 등산로를 오르다보면 땀이 송글송글 맺힌다.정상은 안타깝게도 나무들이 우거져있어 조망이 그리 좋은 편은 못되지만 나뭇가지 사이로나마 제법 웅장한 암골미를 드러낸 서남쪽 가리산 정상 풍광은 일품이다.", + "MNTN_HG_VL" : "935", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시, 홍천군", + "MNTN_NM" : "새득이봉" + }, + "longitude" : 127.97338240000001, + "latitude" : 37.882656799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어룡산에서 작약산으로 이어져 가는 산으로 안불정에서 바로 보이고 가은읍 저음리에 바로 보이는 산이다. 안불정에서 잘 닦인 임도를 따라가면 되고 가은읍 저음리에서는 능선을 타고 오르면 된다.", + "MNTN_HG_VL" : "617", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 신현리", + "MNTN_NM" : "새봉" + }, + "longitude" : 128.75209849999999, + "latitude" : 37.710744800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면", + "MNTN_NM" : "샘봉산" + }, + "longitude" : 127.54683439999999, + "latitude" : 36.455291099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화악산의 지붕. 기암괴석과 사철 맑은 물이 흐르는 비경을 간직하고 있다. 특히 원시림을 방불케하는 울창한 수림이 계곡을 따라 터널을 만들어놓아 연인과 가족끼리의 산행에 알맞으며 수량 또한 풍부하여 큰물안골,작은물안골이라는 지명이 생기게 되고, 이끼 낀 계곡은 와폭과 담소로 이어지고 아름다운 비경이 골골이 펼쳐 있는 것이 특색이다.정상은 아무런 표식이 없으며 작은바위봉이 움푹 파헤쳐져 있으나 남쪽 전망대는 노송과 암벽이 어우러져 이 능선에서는 경관이 으뜸이고 남쪽의 매봉산과 서쪽의 백운산, 북쪽의 두류산 주변의 산들이 펼쳐 보인다. 교통도 경기 포천에서 화천읍으로 진행하는 56번 국도변에 위치하고 있어 접근도 용이하다. 계곡내에 단풍나무가 집단 서식하고 있어 가을산행지로는 최고이다.", + "MNTN_HG_VL" : "885", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", + "MNTN_NM" : "샛등봉" + }, + "longitude" : 127.5537046, + "latitude" : 38.055818700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서대산의 높이는 904.1m이다. 충청남도 남동부의 금강분지를 둘러싸고 있는 금산고원에 속해 있으며, 노령산맥을 이루는 정수이자 충청남도의 최고봉이다. 충남에서는 높이 904.1m으로 가장 높은 산으로서 기암 절벽으로 이루어져 있다.화강암으로 이루어진 원추형 암산인 서대산은 기암절벽과 숲이 어우러지고 제법 험준해 산행의 묘미를 더한다. 정상에 올라서면 웅장하고 온화한 산세가 한눈에 들어오고 멀리 서북쪽으로 대전시내가 펼쳐진다.원흥사, 개덕사등 유명사찰과 정상 직전에 직녀 탄금대, 정상에서 북쪽 546봉으로 이어지는 능선 주변에는 장면대, 북두칠성 바위, 사자굴, 쌀바위 등이 산재해 있다.협곡을 가로 질러 높게 설치된 약 50m의 구름다리 주변은 신선바위, 벼슬바위등 기암 절벽들이 어울려 장관을 이루고 있다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 추부면ㆍ군북면, 충청북도 옥천군 군서면", + "MNTN_NM" : "서대산" + }, + "longitude" : 127.5357582, + "latitude" : 36.230901199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 남양주시 수동면과 가평군 상면 경계를 이루는 서리산(825m)은 한북정맥에서 가지를 쳐 나온 주금산(814m)을 모산으로 하는 산이다.서리산은 그동안 축령산 유명세에 가려져 있었다. 그러나 10여 년 전부터 축령산자연휴양림이 본격적으로 알려지고 주능선에 수천 평 규모의 철쭉군락이 인기를 얻으면서 축령산 못지않게 인기를 끌고있다.산세는 주능선 북쪽 사면이 바위벼랑에 가까운 급경사로 이뤄진 반면, 남쪽은 완만한 산세로 이뤄져 있다. 따라서 등산로는 축령산자연휴양림이 있는 남쪽 위주로만 발달되어있다. 들머리인 외방2리 종점가게에 이르면 북쪽으로 소 한 마리가 드러누운 듯 올려다보이는 산이 서리산이다.종점가게에서 계류 건너로 마주 보이는 능선은 서리산 남서릉이고, 그 끝에서 남서봉인 화채봉이 보인다. 정상은 보이지 않는다. 서리산 오른쪽에 우뚝 솟은 산이 축령산 정상이다. 정상에서 주능선은 855봉을 거쳐 남쪽 오독산으로 이어지는데, 855봉에서 종점가게 방향으로 가지를 치는 능선이 있다. 바로 이 능선 상에 유명한 남이바위, 수리바위, 박달고지가 있다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", + "MNTN_NM" : "서리산" + }, + "longitude" : 127.3156252, + "latitude" : 37.768321800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면", + "MNTN_NM" : "서방산" + }, + "longitude" : 127.2199081, + "latitude" : 35.908850999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서방산은 서방정토, 즉 아미타불의 부처님이 계시는 극락세계라는 뜻에서 유래됐다고 한다. 행정구역상 전라북도 완주군 용진면 간중리, 소양면 대흥리에 경계하고 있으며, 종남산에서 이어지는 연봉중 제일 높은 주봉이다.울창한 숲 속을 흘러내리는 봉서사 골짜기의 개울도 맑고 수려해 평야에 가까우면서도 깊은 산중의 맛이 느껴져 이 지역 산꾼들로부터 사랑받는 산이기도 하다. 숲이 울창하고 암벽과 암릉이 제법 발달해 있다.특히 뛰어난 것은 조망이 좋다는 것이다. 평야와 산지의 경계에 있어 넓은 김제 만경들을 넘어 서해 바다를 볼 수 있고 북에서 동을 거쳐 남으로도 수많은 산들을 조망할 수 있다.또한 송광사나 봉서사 등 유서깊은 사찰을 산행들머리로 하는 덕분에 산자락의 문화재를 감상하기도 좋다.", + "MNTN_HG_VL" : "612", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 용진면", + "MNTN_NM" : "서방산" + }, + "longitude" : 127.2199081, + "latitude" : 35.908850999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여항산에서 뻗어내린 남릉이 진북면과 진전면의 경계선을 따라 흘러내리면서 이룬 산봉이 서북산이다. 진동면의 서북쪽에 위치한 산이라 서북산이라는 이름이 붙은 이 산은 전형적인 내륙산으로 전체적으로 산세가 부드럽다.남쪽사면으로 산세를 열고 학동마을을 병풍처럼 둘러싸고 있는 이 산은 6.25동란의 격전지로 산정에는 근간에 세운 전몰자 위령비가 있다. 서릉은 진전면의 산역속으로 흐름을 파묻고 국도 건너편의 적석산과 마주하면서 대정골까지 산자락을 들이밀고 있다. 숨겨진 산이라 아직도 깨끗한 모습을 유지하고 있다.소요 시간 :5시간 30분최적 탐방 시기 : 10 ~ 11월 \/가을볼거리 : 진동 앞 바다 조망숲길 명소 : 숨겨진 산이라 아직도 깨끗한 모습을 유지하고 있는것이 특징이다.함안군에서 등산구간이 많이 나타나 있고 마산시는 임도를 중심으로 등산하는 곳이 많음", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시 합포구 진북면", + "MNTN_NM" : "서북산" + }, + "longitude" : 128.4194444, + "latitude" : 35.169166699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 안성시와 충청북도 진천의 경계에 선 서운산은 아담하고 바위가 거의 없는 유순한 산세를 지녔으며 봄이면 계곡과 능선에 진달래와 철쭉이 군락을 이루는 아름다운 산이다.서운산에 위치한 청룡사는 고려 원종 6년(1265)에 명본국사가 대장암이라는 이름으로 창건한 절로 공민왕 때 나옹화상이 중건하면서 청룡이 서운을 타고 내려오는 것을 보았다 하여 산 이름은 서운산, 절 이름은 청룡사로 하였다고 한다. 서운산 동북쪽 기슭에는 신라 문무왕 20년(680)에 창건한 석남사가 자리 잡고 있는데 염거국사와 혜거국사 등 이름 높은 스님들이 석남사를 거쳐 갔다.서운산에서 뻗은 서쪽 능선으로는 삼태기 모양으로 둘러싼 서운산성의 흔적을 찾을 수 있는데, 이 성은 임진왜란 당시 의병장이었던 홍계남과 이덕남이 안성을 방어하기 위해 쌓았던 군사요충지로 성 안에는 두 의병장의 대첩을 기념한 기념비와 석불이 있다.", + "MNTN_HG_VL" : "548", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 서운면ㆍ충청북도 진천군 백곡면", + "MNTN_NM" : "서운산" + }, + "longitude" : 127.2969842, + "latitude" : 36.929757000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "481", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군", + "MNTN_NM" : "서원산" + }, + "longitude" : 126.63341490000001, + "latitude" : 36.7292141 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼도봉(1,176m)을 시작으로 민주지산(1,241m), 각호산(1,176m)과 함께 웅장한 서북 능선을 이루는 산군(山群)에 속한다. 각호산·민주지산·삼도봉을 잇는 능선은 수림이 우거지고 바위들이 섞여 있으며 봄이면 능선을 따라 8㎞에 걸쳐 진달래가 만발한다.그 산들 사이에는 유명한 피서지인 물한계곡(勿閑溪谷)이 자리잡고 있다. 삼도봉에서 북서쪽으로 약 40분 거리에 우뚝 솟아 있는 석기봉은 민주지산의 주릉 중에서 가장 빼어나며, 주위 전망도 일품이다.황악산이 북동으로 바로 보이고 동남으로는 가야산이 손에 잡힐 듯 가까이 보인다. 서서남으로는 마이산의 뾰족한 두 귀가 선명하다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "석기봉" + }, + "longitude" : 127.8641667, + "latitude" : 36.025277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "535", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "석대산" + }, + "longitude" : 126.5970633, + "latitude" : 35.3414559 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "석두봉은 강원도 오지중에서도 손꼽히는 오지에 위치한 탓으로 산악인들 사이에서도 잘 알려지지 않아 등산인들의 발길이 뜸하다. 그러다보니 등산로가 수풀에 둘러싸여 원시림을 헤쳐나가는 산행의 묘미를 만끽할 수 있다. 석두봉은 산이 깊어 물이 맑고 수량 또한 풍부하다.기다리던 돌산, 석두봉 올라보면 하늘과 맞닿는 느낌이다. 석두봉 정상은 이름 그대로 두 쌍의 바위로 이루어져 있다. 동봉과 서봉으로 정상을 지키고 있는 바위에 올라서면 일대의 경관을 한눈에 조망할 수 있으며 바위 사이로 자라는 철쭉들이 신기롭다.또한 참나무 노령목들이 여기저기 자라는 모습은 장관이며, 서쪽으로는 안반데기 동쪽으로는 왕산면 목계리가 한눈에 들어온다. 정상 바로 옆에 큰바위가 있는데 이곳에 오르면 상쾌한 느낌이다. 용수골을 내려다보며 큰소리로 메아리를 만들어 보는 것도 일미이다.", + "MNTN_HG_VL" : "991", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "석두봉" + }, + "longitude" : 128.8230556, + "latitude" : 37.608333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한북정맥 지류에 있는 석룡산은 오른쪽으로 화악산, 중봉이 있고 왼쪽으로는 국망봉이 버티고 서 있다. 그 지류를 따라 서남쪽으로 내려서면 민둥산과 강씨봉이 있고 산 능선을 타고 남쪽으로 내려서면 명지산과 연인산으로 이어진다.능선코스와 계곡코스를 한번에 즐길 수 있는 석룡산은 웅장한 산세에 비해 등산로가 완만하고 산행 내내 폭포와 담소를 흐르는 시원한 물소리를 들으며 산행을 즐길 수 있어 여름산행 코스로는 이보다 좋을 순 없다.석룡산은 돌로 된 용이 있는 산이란 뜻이지만 실상, 산 어디를 가도 용을 닮은 돌은 보기가 어렵다. 그런데도 옛사람들이 이 산을 석룡산이라 했던 이유는 조무락계곡을 이루고 있는 계곡 전체가 하나의 바위로 이루어져 있고 물길에 잘 다듬어진 모습과 흰물결 굽이치며 떨어지는 계곡이 마치 용과 같다고 해서 석룡산이라 불러지고 있다.", + "MNTN_HG_VL" : "1153", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ강원도 화천군 사내면", + "MNTN_NM" : "석룡산" + }, + "longitude" : 127.4755749, + "latitude" : 38.005823399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충남 예산군 덕산면의 덕산도립공원 내에 위치한 해발 653m의 암산으로 가야산 주봉인 가야봉 북쪽 1.7km지점의 바위봉이다. 주봉인 가야봉에는 중계탑이 가득하게 들어서 있어 주봉의 의미를 퇴색시킨다. 석문봉은 이런 아쉬움을 달래기에 충분한 훌륭한 바위봉으로, 뛰어난 전망을 제공한다. 남쪽 주봉과 북동쪽 1.8km 지점의 옥양봉, 북서쪽으로 일락산이 내려다보이고, 서쪽 해미쪽으로는 서해바다가 시원스럽게 펼쳐진다.산행은 덕산시내에서 덕산초등학교 앞길로 들어선후 2차선의 포장도로를 따라 큰 저수지를 지나고 나오는 상가리 주차장에서부터 시작된다. 약 1km 떨어진 남연군묘앞 공터에 주차가 가능하지만 전체적으로 코스가 길지 않기 때문에 이곳에서부터 산행을 시작하는 편이 좋을 듯하다. 남연군묘 좌측길로 들어서서 시멘트길을 따라 저수지를 끼고 돌담집을 지나 쉼터를 거쳐 안부에 오른후 북쪽 암릉을 거쳐 석문봉 정상에 오른다. 하산은 북동쪽으로 잠시 내려가다 옥녀폭포로 내려서서 2km정도 내려서면 남연군묘에 도착하고, 1km를 더 내려가면 주차장에 도착한다. 산행시간은 총 3시간 30분 정도면 족하다.", + "MNTN_HG_VL" : "653", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", + "MNTN_NM" : "석문봉" + }, + "longitude" : 126.6033333, + "latitude" : 36.716666699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉", + "MNTN_NM" : "석병산" + }, + "longitude" : 128.89750000000001, + "latitude" : 37.586666699999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 강릉시 옥계면과 정선군 임계면 사이에 솟은 해발 1055미터의 석병산은 백두대간에 위치한 산이며 정상부 바로 아래 둥그런 구멍이 뚫린 일월문과 회양목 군락지, 철쭉 군락지 등 색다른 볼거리를 제공하는 웅장함과 아름다움을 겸비한 산이다.두리봉 동남쪽을 시작으로 산 전체가 돌로 쌓여있어 마치 바위가 병풍을 두른 것 같다고 해서 석병산이라 불린다. 옛날에는 산삼이 많이 자생하고 있어 약초꾼들이 많이 드나들던 곳이기도 하다.석병산은 석고암으로 형성되어 동굴이 많은 산이기 때문에 범바위골 계곡이 주류인데도 물이 흐르지 않아 특이하다. 정상이 두 개의 흰 암봉으로 이루어져 있으며, 정상 일대에는 백리향, 참바위취, 구름체꽃 같은 희귀식물들이 꽃을 피우고 있어 봄과 초여름 사이에 아름다운 꽃구경을 할 수 있으며, 두 개의 암봉 중 북봉에서 보는 경관이 일품이다. 북쪽 면은 깎아지른 절벽이고 이 암맥은 북동 능선으로 이어진다.", + "MNTN_HG_VL" : "1053", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 옥계면, 왕산면ㆍ정선군 임계면", + "MNTN_NM" : "석병산" + }, + "longitude" : 128.89750000000001, + "latitude" : 37.586666699999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "석화봉은 충북 단양의 수리봉과 황정산 사이에 동북 방향의 가지를 치고 그 지능선상에 솟아 있는 산이다. 석화봉을 가운데 두고 북으로 황정산, 동으로 올산(858m), 남서로 선미봉과 수리봉 암릉이 사방으로 에워싸고 있는 무풍지대다.형형색색의 기암괴석과 암봉 및 암벽, 암릉, 암굴 등으로 이루어진 신비로운 암산인 석화봉이란 이름은 시원스레 뻗은 암릉 위로 거대한 화강암 바위가 꽃처럼 피어 있는 형상에서 비롯된 것이다. 뿐만 아니라 정상 부근 낙타바위를 비롯해서 725봉 아래에 보는 이로 하여금 절로 웃음을 짓게하는 째진바위, 궁둥이 바위,백곰바위등이 산행을 즐겁게 하여준다. 산으로 오를수록 암릉길과 슬랩(경사),침니코스가 나온다 약간의 보조자일도 필요하다.정상에서의 조망은 시원하게 터진다.북동쪽으로 도솔봉과 흰봉산이 하늘금을 그리고 동쪽으로는 저수령 방면 백두대간과 그 아래 올산 마을이 아름답게 펼쳐진다.북서쪽으로는 암릉을 끌고 나가는 황정산이 우뚝하다.", + "MNTN_HG_VL" : "834", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "석화봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "인천에서 영종도 선착장이 있는 구읍배터 앞에 있는 아담한 석화산은 우리 역사의 개항과 더불어 열강의 수난을 겪은 산이다. 병인양요(1866)때는 우리 강화도에서 우리 원군에 패해 하여각종 문서와 유물을 훔쳐 달아나는 프랑스 함선으로부터 무차별 포격을 받았으며, 상인(商人)오페르트는(1868) 대원군의 아버지인 남인군묘를 도굴하고 이곳을 한동안 점령하면서 개항을요구하기도 했으며, 신미양요(1871)때는 초지진과 덕진진에 이어 광성보까지 무너졌던 아픈 상처를 같이 했던 곳이다. 3개의 봉우리로 구성된 석화산은 조림 사업이 잘 된 곳 중에 한곳이다. 소나무가 우거져 있으며숲길은 낙엽으로 된 방석을 딛고 걷는 듯한 착각이 들 정도로 감촉이 좋다. 특히 솔잎 낙엽 길은솔 향 내음이 더욱 좋은 산이다.", + "MNTN_HG_VL" : "143", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구 중산동", + "MNTN_NM" : "석화산" + }, + "longitude" : 127.88911090000001, + "latitude" : 37.699438999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1236", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면, 영주시 부석면. 강원도 영월군 하동면", + "MNTN_NM" : "선달산" + }, + "longitude" : 128.7094563, + "latitude" : 37.0390199 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;양백(兩白)지간에 솟은 내성천의 발원지gt;선달산은 경북 봉화군 물야면, 영주시 부석면과 강원 영월군 하동면에 걸쳐 있는 봉우리로 청정계곡과 우아한 산세를 자랑한다. 남으로 갈곶산(961m)과 봉황산(819m), 서로 회암령~어래산(1064m), 동으로 옥석산(옥돌봉)이 애워싸고 있다. 북쪽에는 일곱능선이 선달산으로 이어졌다는 뜻의 칠룡골이 있다. 또 이곳은 소백산과 태백산의 양백(兩白)지간에 있는 산으로 백두대간 구간에 속한다. 언뜻 봐서는 강원도의 영서 내륙지방 같은 분위기를 풍기는 선달산은 낙동강의 지류인 내성천(乃城川)의 발원지기도 하다. 전국에서도 손꼽히는 오전약수가 있어 약수산행지로도 잘 알려진 선달산의 산행코스는 크게 세 갈래. 봉화 쪽 물야저수지가 있는 오전2리 생달마을에서 용운사~늦은목이를 거쳐 정상에 오르거나 사기점마을의 왕바우골을 들머리로 원점회귀 산행하는 것이 일반적이다. 영주 쪽에선 남대리 상신기마을을 들머리로 선달산 북서능선 1136봉 사이 안부로 올라서거나 늦은목이을 거쳐 오른다. 영월 쪽은 내리 지동마을에서부터 내리천을 따라 늪다리에 이르러 칠용동계곡을 통해 오른다. 이 중 오전약수가 있는 봉화 쪽으로의 접근이 가장 수월하다.", + "MNTN_HG_VL" : "1236", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면#8228;영주시 부석면, 강원도 영월군 하동면", + "MNTN_NM" : "선달산" + }, + "longitude" : 128.7094563, + "latitude" : 37.0390199 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "선달산은 백두대간의 소백산과 태백산 사이에 솟아 있어 대간을 조망하기에 좋은 산이다. 정상에서는 동쪽으로 남대천과 어래산이 보이고 서쪽으로는 박달령이 보인다. 또한 남쪽의 갈곶산과 이어진 부드러운 구릉으로 산행하기 수월하다.선달산 부근의 문화 유적으로는 부석사 무량수전(국보 제18호)과 소수서원이 있다. 무량수전은 우리나라 최고의 목조 건물로 신라 문무왕 때 의상대사가 창건 하였다. 소수서원은 1532년 주세붕이 세운 우리나라 최초의 서원으로 창건 당시 백운동서원으로 불리다가 명종 때 풍기군수로 있던 이황의 건의로 소수서원이라 불렀다.경상북도 봉화군은 사방이 산으로 첩첩이 둘러싸여 있고 그 속에 오전, 두내, 다덕 등 전국에서 손꼽히는 약수가 여러 군데 있다. 그 중 으뜸인 오전약수는 서쪽으로 마구령과 동쪽으로 도래기재 사이의 선달산 아래 있으며, 물맛이 가장 좋기로 조선시대 최고의 약수로 뽑히기도 했다. 그리고 중종 때의 풍기 군수 주세붕은 오전약수를 마음의 병을 고치는 좋은 스승에 비길만하다고 극찬했다. 약수터 앞 음식점이 들어선 곳을 제외하고는 한가로운 농촌 마을이다. 그러나 오전약수터 주변은 주말과 단풍철이 되면 관광차와 사람들로 부산스럽다.또한 선달산은 아름다운 계곡을 품고 있으며 각종 나무가 아름답게 줄을 서 있어 산세도 우아하다. 영월군 하동면 내리 지동마을에서부터 시작되는 내리천 계곡은 초입에서부터 울창한 수림과 풍부한 수량이 마치 원시의 비경을 연상케 한다. 계곡을 거슬러 오를수록 점입가경의 계곡미가 펼쳐지는데 한가지 흠이라면 이곳의 상류가 석회암 지대인지라 계곡 바닥이 온통 석회석으로 덮혀 물을 마실 수가 없다. 그러나 늪다리에 이르러 칠룡동 계곡으로 들어서면 계곡물은 옥같이 맑고 폭포,소 등이 연이어 그야말로 심산유곡이 펼쳐진다.", + "MNTN_HG_VL" : "1236", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 경상북도 영주시, 봉화군", + "MNTN_NM" : "선달산" + }, + "longitude" : 128.7094563, + "latitude" : 37.0390199 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;한계저수지 품은 한남금북정맥의 산줄기gt;월오동 목련공원 남쪽 맞은편에 있는 선도산은 청주에서 제일 높은 산으로, 지리적으로는 한남금북정맥 줄기와 행정구역으로 청주시 경계선이 만나 함께 가는 유일한 지점이다. 선도산을 기점으로 북쪽으로는 상령산 줄기로 이어지며 동남으로 선두산 지역인 청원군 낭성면 가덕면이 펼쳐지고 남쪽으로는 말구리재 미테재 관봉으로 이어가며 한계저수지를 끌어안고 있다. 서쪽으로는 청주에서 가장 깊은 골짜기 동네인 월오동 서운말을 끼고 그 건너편에 낙가산과 것대산을 마주보며 상봉재와 보살사를 품에 안고 있다. 등산로에는 전국의 산악인들이 한남금북정맥을 종주하고 있는 표식기가 많이 보일 정도로 많은 사람들이 찾아오고 있다. 선도산은 개척 산행 맛이 나는 곳으로 참나무와 진달래가 자랄 대로 자란 수풀 사이로 한 사람이 겨우 다닐 정도로 한적하고 산림욕까지 곁들일 수 있다.", + "MNTN_HG_VL" : "547", + "MNTN_LOCPLC_REGION_NM" : "충청북도 낭성면 무성리, 지산리, 현암리", + "MNTN_NM" : "선도산" + }, + "longitude" : 129.1696369, + "latitude" : 35.827482500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "547", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 낭성면 무성리, 지산리, 현암리", + "MNTN_NM" : "선도산" + }, + "longitude" : 129.1696369, + "latitude" : 35.827482500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 단양군에 위치한 선미봉은 착한 산이라는 뜻의 착할 선자에다 산의 순수한 우리말인 `뫼'자를 붙여 선뫼봉으로 불리다가 오늘에 이르러서는 뫼가 아름다울 `미'로 변해 붙여진 이름이다.산이 착하다니 무슨 뜻일까. 착한산이라서 등산로마저도 편할 것 같지만 그동안 등산인들의 발길이 거의 미치지않아 등산로에는 잡목과 낙엽으로 원시림을 방불케한다. 정상에 오르면 서북쪽 풍광이 가장 먼저 시선을 끈다.선미봉과 맥락을 같이 하는 수리봉, 황정산, 도락산 정상이 시야에 와 닿고 동쪽으로는 멀리 도솔봉 부터 백두대간을 끌고온 시루봉과 촛대봉 그리고 저수령 아래로 거대한 분화구처럼 움푹패어든 목장지대가 그림처럼 펼쳐진다.", + "MNTN_HG_VL" : "1080", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 대강면", + "MNTN_NM" : "선미봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "선바위봉은 치악산 상원사 뒤편인 망경봉(1182m)에서 동남쪽 매봉(1095m) 방향으로 이어지는 능선 가운데에 솟아 있는 산이다. 원주시와 회성군, 영월군 경계상의 오지에 있어 등산인이 드문 한적한 때묻지 않은 산인 선바위봉은 정상 서편에 선바위가 있어 생긴 산명인 것 같다.평평한 정상에는 오래된 삼각점이 있고 수림으로 둘러싸여 조망은 좋지 않으나, 서편으로 근접한 선바위에 오르면 가슴이 트이고, 치악산, 만경봉으로 이어 오르는 능선이 아련하다.마치 피사의 사탑처럼 오른쪽으로 약간 기운 선바위는 조선시대 최고의 화가 중 한사람인 겸재 정선의 산수화 한 폭을 기분이다. 작은 분지를 이룬 거운리 앞을 유유히 흐르는 동강과 선바위가 아름답게 어우러진다. 전망바위에서 북동으로는 잣봉이 보이고, 잣봉 남릉 너머로는 능암덕산 줄기와 멀리 닭이봉과 곰봉도 시야에 와닿는다.평평한 정상에는 오래된 삼각점이 있고 수림으로 둘러싸여 조망은 좋지 않으나, 서편으로 근접한 선바위에 오르면 가슴이 트이고, 치악산, 만경봉으로 이어 오르는 능선이 아련하다.", + "MNTN_HG_VL" : "1001", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 영월군", + "MNTN_NM" : "선바위봉" + }, + "longitude" : 127.78638890000001, + "latitude" : 37.071944400000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "경상북도 산청군 생초면", + "MNTN_NM" : "선바위산" + }, + "longitude" : 128.81722049999999, + "latitude" : 37.148314300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "1\/5,000 지도에는 배나무산이라 나오며 동네에서는 선암산이라고도 한다. 호계면 선암리 상선암동네 뒷산이며 산북면 석봉리와 경계하며 호계면 부곡리 부운령에서 시작하여 배나무산을 지난 단산으로 이어지며 노송군락이 아주 좋다.", + "MNTN_HG_VL" : "814", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 석봉리", + "MNTN_NM" : "선암산" + }, + "longitude" : 128.9826621, + "latitude" : 35.387973100000004 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봄이면 동백꽃과 벚꽃으로 유명한 선운산은 '호남의 내금강'으로 불리는 산으로 79년 도립공원으로 지정된 명산이다. 본래 도솔산이었으나 백제 위덕왕 24년(577년)에 창건한 선운사(禪雲寺)가 있어 선운산이라 불리게 되었다.선운산은 이름 그대로 구름 속에 선(禪)을 닦는 산으로 선운사를 비롯해 참당암, 도솔암, 석상암, 동운암 등 유서 깊은 사찰과 암자가 산자락에 자리잡고 있다. 그 중 선운사는 백제 위덕왕 24년(577년)에 검단(黔丹)선사가 창건한 사찰로, 한때 89개 암자를 거느리기도 하였으나 현재는 4개의 암자만 남아있다. 선운사 대웅전 뒤에는 5천여 평의 동백나무숲(천연기념물 제184호)이 있는데 매년 4월 중순이면 붉게 피어나 보는 이의 탄성을 자아내게 한다. 김정호의 '대동여지도'에는 선운산이 표시돼 있지만 현재 각종 지도에는 선운산이라 표시되어 있지 않으며, 선운사 뒷산을 '도솔산' 또는 '수리봉' 으로 표시하고 있다. 선운사 창건 설화는 여러 가지가 있다.원래 선운사 자리는 용이 사는 용추로 검단선사가 용을 쫓아냈지만 용추를 메울 길이 없자, 용추에 꼭두각시 배를 띄우고 돌을 던져 꼭두각시 놀이를 하게 하였다 한다. 또 그 때 마을에 눈병이 퍼졌는데 숯 한 짐씩을 용추에 버린 뒤 눈을 씻으면 낫는다는 소문을 퍼뜨려 용추를 메워 선운사를 지었다는 전설이 있다.실제로는 검단선사가 그의 친구이자 신라 24대 진흥왕의 왕사인 의운(義雲)선사의 도움을 받아 진흥왕의 시주로 선운사를 창건하였다 한다. 진흥왕이 중생제도를 위해 왕위를 버리고 도솔왕비와 중애공주를 데리고 입산, 수도하였다는 진흥굴(眞興窟. 일명 좌변굴(左邊窟),열석굴(裂石窟))이 도솔암 아래에 남아있다. 낙조대에서 바라보는 서해바다의 조망과 하늘로 날아오를 듯한 모습을 한 천마봉 등 볼거리가 푸짐한 이 산은 암자와 바위, 굴마다 숱한 전설이 깃들어 있어 지루함 없이 산행을 즐길 수 있다.특히 선운산 마애불에는 재미난 전설이 전해지고 있다. 옛날부터 마애불 배꼽 속에 신기한 비결이 들어 있고 그 비결이 나오는 날 한양의 이씨가 망한다는 전설이 있었다. 전라도 감사 이서구(李書九)가 마애불의 배꼽을 열어 보려다가 뇌성벽력이 쳐, 실패한 일이 있었는데 동학혁명이 일어나기 전 동학의 간부 손화중(孫和中)이 배꼽을 열고 그 비결을 꺼내갔다고 한다.", + "MNTN_HG_VL" : "335", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 아산면ㆍ심원면ㆍ해리면", + "MNTN_NM" : "선운산" + }, + "longitude" : 126.571111, + "latitude" : 35.508056000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "427", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성", + "MNTN_NM" : "선유산" + }, + "longitude" : 128.27611110000001, + "latitude" : 35.1175 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "줄줄이 산릉과 산등이 융기되어 있는 선의산은 명당이 많다고 하여 지관들이 구석구석을 누비면서 지금도 찾아다니고 있다. 신라시대 사찰이 있었고 암자가 있다 하여 암자골이라 하며 그 위에 있는 선의산은 청도군과 경산시의 경계를 이루고 있다. 또한 말과 닮은 산의 형세라 하여 말안쪽산 즉 마암산이라고 부르기도 한다.", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "선의산" + }, + "longitude" : 128.77333329999999, + "latitude" : 35.726388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;남천면의 주산이자 경산의 진산gt;경산시 남천면과 청도군 매전면을 가르는 선의산은 남천면의 주산으로 쌍계산이라고도 하며 ‘선녀가 하강하여 춤을 추는 형상’이라 하여 선의산(仙義山)이라 이름 하였다. 그러나 ‘仙義’가 ‘춤추는 선녀’와 무슨 연관이 있는지는 도무지 알 수 없다. 정상석의 ‘풍수지리설에 의하면 이곳의 정기를 받으면 8정승이 태어난다는 설화가 있고 산 정상에는 용정(龍井)이라는 샘이 있어 가뭄이 심할 때는 이곳에서 기우제를 올리기도 했다’고 전하는데, 이를 확인할 길은 없다. 이밖에 정상석에는 ‘쇠말뚝 뽑은 곳’이라는 표식이 있는데 1990년에 쇠말뚝을 뽑고 ‘일제만행’이라고 적어놓았다.지난해 전망데크를 깐 정상에서는 비슬지맥이 남쪽으로 이어지는데 5킬로미터 거리의 용각산(龍角山#8228;697.4m)이 우뚝 솟아있다. 남서쪽으로는 청도 남산 등 청도군 일대가 어렴풋이 보인다. 최근에는 선의산과 용각산을 잇는 종주산행이 인기인데 경산과 청도쪽 들머리를 합쳐 대략 10군데에서 접근할 수 있다. 그 중 원점회귀가 가능하고 등산로 정비가 가장 잘 되어 있는 곳이 경산 남천면의 송백2리의 도성사 기점으로, 가장 많이 찾는 코스로 꼽힌다.", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "상북도 경산시 남천면, 청도군 매전면", + "MNTN_NM" : "선의산" + }, + "longitude" : 128.77333329999999, + "latitude" : 35.726388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남천면, 청도군 매전면", + "MNTN_NM" : "선의산" + }, + "longitude" : 128.77333329999999, + "latitude" : 35.726388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 강릉시 성산면과 평창군 도암면의 경계를 이루는 선자령은 백두대간의 주능선에 우뚝 솟아 있다. 산 이름을 '산'이나 '봉'이 아닌 선자령으로 부르게 된 유래는 알 수 없으나, 옛날 기록에 의하면 여러 가지 이름으로 표기하고 있다. 〈산경표(山經表)〉에는 '대관산(大關山)'이라 하고. 〈동국여지지도(東國輿地之圖)〉 와 〈사탑고적고(寺塔古蹟攷)〉에는 그 아래 보현사의 이름에 따라 '보현산(普賢山)'이라 표기되어 있다.그리고 보현사에 관한 기록을 전하는 〈태고사법(太古寺法)〉에는 '만월산(滿月山)'으로 적혀 있다. 보현사에서 보면 선자령이 떠오르는 달로 보이기 때문에 붙여진 이름인 것으로 추정된다. 선자령은 해발 840m인 대관령의 북쪽에 솟아 있는 산으로, 대관령에서 약 6km밖에 되지 않아 산행이 힘들지 않고 겨울철 적설 등반지로 적합하다. 대관령 고갯길은 옛날에는 오솔길이었으나, 이 고갯길을 조선조 중종때 이 지방 사람인 고형산이 사재를 털어 우마차가 다닐 수 있도록 넓혀 놓았다. 따라서 거의 평지길이나 다름없는 능선을 따라 오르게 되므로 산길은 매우 완만하다.이 능선길은 적설기와 신록기가 판이하게 달라진다. 적설기에는 많은 눈에 덮여 은세계를 이루어 황홀하고, 신록기에는 새로 자라난 연녹색의 초원에 야생화가 만발하여 화원을 이루고 있다.", + "MNTN_HG_VL" : "1157", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "선자령" + }, + "longitude" : 128.745, + "latitude" : 37.722222199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "계룡산 줄기 남쪽의 산으로 높이 507m로서 신현읍과 거제면의 경계에 위치하고 있으며 고현에서 구천계곡 쪽으로 들어가 수자원개발공사를 지나 삼거리 윗담마을에서 오르면 된다.가을에는 단풍나무가 아름답고 자작나무와 참나무가 무성하며 계곡 물이 맑고 깨끗하다. 이 계곡 물들이 굽이굽이 모여 구천댐 물을 이루고 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", + "MNTN_NM" : "선자산" + }, + "longitude" : 128.62948639999999, + "latitude" : 34.847562099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "설악산은 한라산(1,947.3m),지리산(1,915.4m)에 이어 남한에서 세 번째로 높은 산으로 강원도 속초시와 양양군,인제군에 걸쳐 있다.옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.백두산에서 남쪽으로 내리뻗어 이 땅의 기나긴 등뼈를 이루는 백두대간의 허리를 받들고 있는 설악산은 북의 금강산과 남의 오대산 사이에 솟아있는 천하의 명산으로 우리나라 관광명소 1호로 꼽힌다. 지난 1965년 11월 5일 천연기념물지구(163.4㎞), `69년 관광지(16.2㎞) 그리고 '70년에는 국립공원(174㎞)으로 각각 지정되었다. 그리고 1971년 9월에는 설악산 국립공원 관리사무소가 개설 되었고 `77년 '78년 두차례에 걸쳐 354.6㎞로 확장되었으며, 그 후 다시 374㎞로 넓이를 확대하였다. 울산암 등산로 초입에 있는 신흥사는 대한불교 조계종 제3교구 본사로 설악산의 대표적 사찰이다. 신라때 자장율사가 노루목근처에 향성사로 창건했다가 조선조때 현위치에 다시 세웠다고 한다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동, 인제군 북면ㆍ인제읍, 양양군 서면ㆍ강현면", + "MNTN_NM" : "설악산" + }, + "longitude" : 128.46555810000001, + "latitude" : 38.119550400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동", + "MNTN_NM" : "설악산 공룡능선" + }, + "longitude" : 128.46555810000001, + "latitude" : 38.119550400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남면 홍현마을에 있는 설흘산(488m)은 망산(406m)과 인접해 있다. 설흘산에서 내려다보면 깊숙하게 들어온 앵강만이 한눈에 들어오고 서포 김만중의 유배지인 노도가 아늑하게 내려다보인다. 인접하고 있는 전남 해안지역 뿐만 아니라 한려수도의 아기자기한 작은 섬들도 조망할 수 있는 곳이다.설흘산 정상 부근에는 봉수대의 흔적이 남아 있다. 원래 봉수대는 주위를 넓게 관측할 수 있는 곳에 정하는데 설흘산 역시 한려수도와 앵강만 그리고 망망한 남쪽 대해를 관측할 수 있는 곳이다.남면 구미 지역과 응봉산으로 오르는 등산로는 망망대해와 기암괴석 그리고 아래로 내려다보이는 다랭이마을의 풍경을 제대로 즐길 수 있다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경남 남해군 남면", + "MNTN_NM" : "설흘산" + }, + "longitude" : 127.8987633, + "latitude" : 34.737474499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "성미산" + }, + "longitude" : 126.908618, + "latitude" : 37.560164 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 임실과 진안을 사이에 두고 우뚝 솟은 성수산은 고려와 조선의 건국설화가 살아있는 유서 깊은 산이다. 그렇게 높은 산은 아니지만 정상의 조망이 빼어나고, 남쪽으로는 향나무와 낙엽송, 활엽수 등 수백만 그루의 잘 자란 나무들이 빼곡히 들어차 삼림욕을 하기에 좋다.성수산자연휴양림 입구에서 10여분 오르면 상이암을 만나는데 상이암은 875년 도선국사가 창건한 절로 초기에는 도선암으로 불렸다가, 조선시대 태조 이성계가 조선을 개국하기 전 이곳에 와 치성을 드리니 하늘에서 ‘왕이 될 것’이라는 소리가 들렸다 해서 상이암이라 고쳤다고 한다. 그래서인지 성수산 주변에는 이성계와 연관된 이야기가 많이 전해진다. 절 입구에는 이성계가 직접 썼다는 ‘삼청동’ 비가 세워져 있고, 왕방리는 이성계가 왜구를 물리치고 귀경하던 중 지나갔던 마을이라고 한다.한편 상이암은 의병대장 이석용이 항일운동의 근거지로 이용하던 곳인데 그 때문에 일제시대 일본군에 의해 강제로 소실되었다가 1958년 상이암재건위원들에 의해 다시 세워졌다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 성수면ㆍ진안군 백운면", + "MNTN_NM" : "성수산" + }, + "longitude" : 127.41567430000001, + "latitude" : 35.640969800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1060", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", + "MNTN_NM" : "성수산" + }, + "longitude" : 127.41567430000001, + "latitude" : 35.640969800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "471", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "성암산(감태봉)" + }, + "longitude" : 128.67776799999999, + "latitude" : 35.793171000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영남과 호남 사이를 흐르는 섬진강을 눈으로 좇으며 올라가는 성제봉(형제봉)은 암릉과 암봉이 이어지는 능선이 일품이다.고소성에서 봉수대,신선대,1052봉,성제봉,깃대봉으로 이어지는 성제봉 능선에는 노송지대와 온갖 기암과 반석,널찍한 억새밭, 조릿대 숲길, 넓은 철쭉 군락지 등으로 이어져 매우 아름답다. 5월 중순에는 철쭉제가 성대히 개최된다.또한 대하소설 `토지'의 무대로 유명한 평사리와 악양들을 만날 수 있다. 최근에는 소설의 배경을 그대로 재현해 놓은 최참판댁이 단장을 하고여행객들을 맞이하고 있고, 최참판댁 뒤로 고소성 군립공원이 있어섬진강의 굽이굽이를 내려다보기에 더없이 좋다 .평사리 일대에는 지리산 능선이 남으로 내달린 끝인 성제봉 아래 넓은 평야지대와 섬진강가의 동정호까지 펼쳐져 있다. 또한 고소산성을 비롯 통천문 신선바위 등 문화유적과 볼거리가 많아 힘들이지 않고 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "1115", + "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면, 화개면", + "MNTN_NM" : "성제봉" + }, + "longitude" : 127.6751435, + "latitude" : 35.193591599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "박경리의 소설 「토지」의 무대인 악양면 평사리. 악양은 남쪽으로 굽이쳐 흐르는 섬진강을 내어놓고, 삼면이 지리산 남부 능선 끝자락에 둘러싸여 있다. 멀리 지리산otilde;왕봉에서 제석봉, 촛대봉을 거쳐 남부능선을 따라 내려온 산줄기는 거사봉(1133m)에서 좌우로 갈래를 친다. 성제봉(1115.5m, 일명 형제봉)과 신선봉(586m), 칠성봉과 구재봉(767.6m)이 병풍oacute;럼 둘러싸며 악양의 너른 벌판에 젖줄이 된다. 악양은 중국의 악양과 닮았다 하여 지어진 이름이다. 악양을 둘러싼 산줄기는 어림잡아 도상거리 30여 킬로미터. 지리산 주능선이 25킬로미터 정도임에 비할 때 그 장대함을 알 수 있다. 이 코스를 종주하게 되면 북으로는 노고단에서 반야봉, 제석봉,otilde;왕봉 지리산 종주 코스가 한 눈에 들어오고, 남으로는 토지의 주무대인 악양면 평사리와 최참판댁, 동정호 그리고 굽이도는 섬진강과 백사장, 그 너머로 백운산이 겹겹이 펼쳐진다. 또한 거사봉에 서면 이상향으로 이름난ucirc;학동이 눈앞에 펼쳐진다.", + "MNTN_HG_VL" : "964", + "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면", + "MNTN_NM" : "성제봉(형제봉)" + }, + "longitude" : 127.27, + "latitude" : 37.207777800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "성주봉은 백두대간상의 대마산에서 남쪽으로 갈라진 지맥상의 운달산 서편에서 솟은 아름다운 암산이며 매우 깨끗하나 등산로가 험준하지만 운달산에서 문경읍쪽으로 붙어 있는 암벽이 보기 좋은 산이다.주능선은 대부분 암릉과 노송으로 어우러지고, 직벽을 따라 내려선 안부에서 다시 직벽을 기어오르는 협곡이 연속된다. 운달산 정상에서 능선을 타고 성주봉으로 종주할 수 있으나 자일과 암벽장비가 있어야 안전하다. 문경읍 당포리에서 성주봉만을 등산할 수 있다.서쪽 주흘산 연봉이 매력적으로 펼쳐 보이고, 북쪽 대미산과 남쪽 단산, 봉명산, 백화산 등의 조망이 좋다.당포리 마을은 약330년 전에 형성된 마을이라 전해오고 있으며 마을 가운데로 계곡변에는 수백년 된 느티나무 숲(휴식공원)이 있다. 성주봉은 기세 등등한 장군이 자리를 잡고 버티고 서 있는 형상을 하고 있어 이곳 당포리 일대 주민들은 성주봉을 흔히들 ‘장군봉’이라고 부르기도 한다.", + "MNTN_HG_VL" : "607", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 김룡리", + "MNTN_NM" : "성주봉" + }, + "longitude" : 128.04104889999999, + "latitude" : 36.534782100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "성주봉은 경상북도 문경시 문경읍 당포리와 용연리의 경계에 우뚝 솟아있는 바위산이다. 문경읍에서 5분 거리면 닿을 수 있는 산이지만 그리 알려지지 않은 탓에 때 묻지 않은 보석 같은 산이다.운달산(1097.2m)에서 서쪽으로 뻗어 내리다 당장이라도 포효하며 뛰어 오를 듯이 단단한 근육질의 몸으로 기세당당하게 자리 잡고 있다. 같은 산군이면서도 육산에 가까운 운달산과 달리 그림 같은 암봉미를 갖추고 있다.성주봉 산행은 당포리 입구에서 시작한다. 마을에 들어서면 정면으로 하얀 속살을 드러낸 성주봉 주능선 봉우리들이 치솟아 있다. 멀리서 보면 깎아지른 절벽 사이에 간혹 나무들이 보일 뿐 등산로가 있으리라고는 상상이 안 되는 산이다. 그 만큼 험악한 산으로 산행 시는 특히 조심해야 한다. 기본적인 암벽 장비와 보조 자일을 갖춰야 안전하게 암릉을 즐길 수 있다.", + "MNTN_HG_VL" : "961", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 당포리, 용연리", + "MNTN_NM" : "성주봉" + }, + "longitude" : 128.04104889999999, + "latitude" : 36.534782100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "성주봉은 도장산에서 그리 멀지 않은 남산 줄기의 한 봉우리다. 남산은 칠봉산 남쪽에 위치해 남산이라 이름 붙었으며 웬만한 지도에도 나오지만 상주 사람들은 남산보다는 노송과 암릉, 기암들의 경관이 뛰어난 성주봉을 좋아한다. 더구나 성주봉 아래에는 자연휴양림이 만들어져 교통도 편리하며 원점회귀를 할 수 있는 등산 코스라 승용차로 다녀오기 좋다.특히 크게 힘들지 않고 오를 수 있어 남녀노소 가리지 않고 좋아할 수 있는 산이다. 성주봉 정상의 암봉은 낙락장송과 어우러져 경관이 매우 뛰어나며 속리산, 대야산, 희양산, 주흘산과 소백산까지도 볼 수 있어 조망이 아주 좋다.또한 성주봉과 골짜기 건너 북쪽의 칠봉산에는 삼국지의 인물인 조자룡과 관련된 전설이 전해져 온다. 그래서 칠봉산 중턱 커다란 암벽 옆에는 조자룡 굴이 있다. 그리고 성주산자연휴양림 관리사무소에서 성주봉 정상으로 오르는 산등성이 암벽에 자리잡은 성주봉의 명소인 약수샘은 그 환경이 참으로 희한하며 물맛 또한 좋다.", + "MNTN_HG_VL" : "912", + "MNTN_LOCPLC_REGION_NM" : "경북 상주시 은척면", + "MNTN_NM" : "성주봉" + }, + "longitude" : 128.04104889999999, + "latitude" : 36.534782100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "성주산은 오서산과 함께 보령을 상징하는 명산으로 예로부터 성인, 선인이 많이 살았다 하여 성주산이라 부르고 있다. 성주산에는 질 좋은 소나무를 비롯, 느티나무, 굴참나무, 졸참나무, 때죽나무, 고로쇠나무 등이 자생하고 있는데 한낮에도 컴컴할 정도로 울창한 숲을 이루고 있다.또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다. 특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다.성주산 일대에 모란형의 명당8개소(성주8묘)가 있었는데 그중 하나가 이곳에 감추어져 있다하여 화장골이란 이름이 붙여졌다. 지금도 명당을 찾으려는 이들의 발길이 잦은 곳이기도 하다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.소요 시간 :150분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 심연동 계곡,삼림욕장,잔디광장, 전망대성주휴양림의 자랑거리가 되고 있는 숲속의 집 통나무 방갈로는 여름철뿐만 아니라 단풍이 짙어가는 가을철이나 흰눈에 싸인 겨울철에도 더할나위 없는 좋은 휴양시설로 각광받고 있다. 휴양림을 찾는 이들의 발길은 아무래도 여름철에 절정을 이룬다. 이때에는 이동도서관이 마련돼 이용자는 얼마든지 책을 대여해 시원한 계곡물에 발을 담그고, 혹은 삼림욕을 하면서 독서 삼매경에 빠질 수 있다.숲길 명소 : 휴양림 입구에서 정상 쪽으로 5백미터 오르면 휴양림을 만날 수 있고, 심연동 계곡쪽에도 휴양림 공간이 마련되어 있다. 또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다.특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.성주산 휴양림에서 정상까지 올라 산 뒤편으로 내려가도 심연동 계곡과 연결되어 있다. 예부터 깊은 골짜기가 있는 마을이라 하여 심연동이라 이름지어진 것처럼 골과 골 사이에 흘러내리는 계곡이 깊고 수려하다.휴양을 위한 각종 편의시설이 설치된 중앙의 코스 외에 외곽으로 따로 등산객을 위한 등산로가 성주산 정상까지 나 있다. 봄에는 만발한 온갖 꽃들의 안내를 받으며, 여름에는 신록의 축복 속에서 삼림욕을 하고, 가을엔 수려한 단풍에 취한 채, 겨울엔 통나무 방갈로에서 아름다운 설경을 음미할 수 있는 곳이 바로 성주산 자연휴양림이다.", + "MNTN_HG_VL" : "512", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "성주산" + }, + "longitude" : 128.09380289999999, + "latitude" : 36.699771499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "성주산은 마성면 정리에서 백화산 쪽으로 나와 보이는 산으로서 산 모양이 성군이 앉아 있는 모양이라 성주산이라 칭하였다. 백화산에서 내려온 큰 줄기가 성주산과 옥녀봉으로 갈라지며 그 중간 계곡이 대골이고 봉명 초등학교가 있는 곳이다. 오르는 길은 마성면 솥골에서 상내리로 넘어가는 나리재에서 백화산으로 오르다가 성주산으로 갈 수 있고 아니면 솥골에서 바로 올라가도 된다. 마성면 정리에서 보면 큰 돌서덜이 보인다.자그마한 봉우리인 정상에는 삼각점, 정상석, 팻말 등 이 전혀 보이지 않는 순결의 심산이다.", + "MNTN_HG_VL" : "712", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 상내리", + "MNTN_NM" : "성주산" + }, + "longitude" : 128.09380289999999, + "latitude" : 36.699771499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부천의 주산인 성주산은 시흥시와 인천시 경계에 위치하고 있다. 시흥의 주산인 소래산과 그 맥을 같이 하고 있으며, 성주산 정상의 높이는 해발 217m이고 도로로 단절되었던 하우고개 여우고갯길 은 현재 구름다리와 에코브릿지가 설치되어 아름다운 산으로 연결되었다. 성주산의 형세는 현재는 멀리 고층건물에서 관찰해야 볼 수 있지만 도시화가 되기 이전인 1960년 대 까지만 하여도 벌막쪽에서 보면 소가 앉아 있는 형세를 볼 수 있어 와우산(臥牛山)이라 불렀다. 성주산은 접근성이 좋아 시민들의 산책코스로 많이 이용되고 있다. 산주변부는 약수터공원 산새공 원 체육공원이 조성되어 더욱더 아름답고 깨끗하다. 산책로 주변에 편의시설물이 많아 이용에 불 편이 없으며 약수터 또한 많이 있는 산이다. 등산로는 깨끗이 정비되어 있지만 급경사 또한 맣아 등산화 준비가 필요한 곳이다.", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", + "MNTN_NM" : "성주산" + }, + "longitude" : 128.09380289999999, + "latitude" : 36.699771499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부천의 주산인 성주산은 시흥시와 인천시 경계에 위치하고 있다. 시흥의 주산인 소래산과 그 맥을 같이 하고 있으며, 성주산 정상의 높이는 해발 217m이고 도로로 단절되었던 하우고개 여우고갯길 은 현재 구름다리와 에코브릿지가 설치되어 아름다운 산으로 연결되었다. 성주산의 형세는 현재는 멀리 고층건물에서 관찰해야 볼 수 있지만 도시화가 되기 이전인 1960년 대 까지만 하여도 벌막쪽에서 보면 소가 앉아 있는 형세를 볼 수 있어 와우산(臥牛山)이라 불렀다. 성주산은 접근성이 좋아 시민들의 산책코스로 많이 이용되고 있다. 산주변부는 약수터공원 산새공 원 체육공원이 조성되어 더욱더 아름답고 깨끗하다. 산책로 주변에 편의시설물이 많아 이용에 불 편이 없으며 약수터 또한 많이 있는 산이다. 등산로는 깨끗이 정비되어 있지만 급경사 또한 맣아 등산화 준비가 필요한 곳이다.", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", + "MNTN_NM" : "성주산" + }, + "longitude" : 128.09380289999999, + "latitude" : 36.699771499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "219", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구 신탄진동", + "MNTN_NM" : "성치산" + }, + "longitude" : 127.4476619, + "latitude" : 35.992483900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도의 산이라 하면 일반적으로 높은 봉우리와 명산들을 손꼽기 마련인데 성치산은 불과 500m 남짓의 낮은 산인데다가 춘천에서 홍천으로 이어지는 국도변에 인접해 있어 그냥 지나치기 쉬운 평범한 봉우리이다.나지막한 산이지만, 남북으로 잇는 주능선이 의연하고 떡갈나무,굴참나무등 참나무류가 산초 나무와 어울려 길을 가린다. 싸리나무, 진달래등 잡초들도 많아 터널 길을 지나는 듯 구부리고 가야 할 때가 적지 않다. 특히 등산 초입인 원골과 진골 일대는 장송이 하늘을 가려 마치 심산에 온 느낌을 준다. 불금봉에서 정상에 이르는 주능선길 도중엔 몇 개의 무덤이 자리잡고 있어 그때마다 전망이 열리기도 한다.정상에는 괴이한 모양의 바위가 서 있고 북동쪽으로 절벽을 이루면서 기암괴봉이 늘어서 있다. 또 그 아래 용담저수지가 아름답기 그지없다. 샛성골로 가는 하산길은 처음엔 다소 긴장이 되지만, 잠시 후에는 수월하게 내려갈 수 있다. 특히 강원도 홍천에 자리하고 있어 인적이 드물어 깨끗한 자연 그대로는 보존하고 있는 산중의 하나이다. 그러나 이 근래에 사람들이 제멋대로 성치산 명함을 밖아놓았다하니 성치산도 사람의 발굽에서 시름할 날이 머지않다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면", + "MNTN_NM" : "성치산" + }, + "longitude" : 127.4476619, + "latitude" : 35.992483900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "189", + "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 장명동,수성동", + "MNTN_NM" : "성황산" + }, + "longitude" : 126.86145089999999, + "latitude" : 35.572579599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 양평군 옥천면과 가평군 설악면의 경계를 이루며 솟아있는 소구니산은 오대산 두로봉의 지맥이 뻗어내려 강원도 홍천과 횡성땅을 휘휘 돌아 경기도에 용문산과 유명산을 세워놓고 우뚝 솟아있다. 유명산과는 달리 바위가 어울린 산으로 유명산에 가려 잘 알려지진 않았지만 유명산과 연결해서 많이 찾는 곳이다.산행기점은 농다치고개와 북쪽의 서너치고개가 가장 일반적이나 교통편이 불편한 것이 흠이다. 정상에 서면 전망이 좋은데 유명산쪽으로는 고냉지 채소밭이 이색적이고 멀리 마터호른 같은 백운봉이 시야에 들어온다. 하산길은 정상 남쪽으로 뻗어내린 긴 능선을 따르거나 유명산을 거쳐 하산할 수도 있다.", + "MNTN_HG_VL" : "798", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "소구니산" + }, + "longitude" : 127.4729765, + "latitude" : 37.578820100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "296", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 용강동", + "MNTN_NM" : "소금강산" + }, + "longitude" : 129.23158000000001, + "latitude" : 35.861976599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "299", + "MNTN_LOCPLC_REGION_NM" : "경기도 시흥", + "MNTN_NM" : "소래산" + }, + "longitude" : 126.7789089, + "latitude" : 37.450962099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "양평군 단월면의 가장 북쪽에 위치한 소리산은 강원도 홍천군과 접경을 이루는 경기도의 오지이다. 소리산은 주변의 산에 비해 큰 산은 아니지만 깎아지른 듯한 바위절벽과 기암괴석, 맑은 계곡이 어울려 예로부터 산음리 소금강이라 일컬어질 만큼 빼어난 경관을 지니고 있다. 예부터 산 속에 바위벼랑에 수리가 서식했다고 하여 수리산으로 부르다가 소리산으로 바뀌었다는 이야기가 전해진다. 인근 봉미산과 종자산이 육산인 것과 달리 소리산 정상부는 바위로 이루어져 있다.특히 산음리와 석산리 사이에 있는 용소계곡은 기암절벽과 울창한 나무들이 어우러져 한폭의 풍경화를 연상케 한다. 산 전체가 오염되지 않은 신선함과 전형적인 시골 마을의 평화로운 정취로 인해 휴식공간으로 인기가 높다. 가파른 산길을 올라 수리봉에 서면 서쪽 낭떠러지 아래로 펼쳐지는 S라인 산음천의 모습이 가히 소금강다운 아름다움을 보여주고 있다. 매년 3월에는 소리산 고로쇠축제가 열린다.", + "MNTN_HG_VL" : "480", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 단월면", + "MNTN_NM" : "소리산" + }, + "longitude" : 127.61368330000001, + "latitude" : 37.637732100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도와 충청북도의 경계를 이루고 있는 소백산은 우리 나라 12대 명산 중의 하나로 '한국의 알프스' 라 불린다. 이 산은 총 면적이 320.5km에 달하는 거대한 산줄기로 정상인 비로봉을 비롯하여 연화봉(1,376.9m). 제 2 연화봉(1,357.3m). 국망봉(1,420.8m) 등 1천m 고봉이 줄지어 있어 웅장한 산세를 이루고 있다.", + "MNTN_HG_VL" : "1440", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 풍기읍, 충청북도 단양군 단양읍", + "MNTN_NM" : "소백산" + }, + "longitude" : 128.446123, + "latitude" : 36.951719900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오대산 두로봉에서 뻗어 나온 한강기맥은 청량봉(1052m)에서 춘천지맥으로 흘러나와 북한강을 따라 고개를 돌다가 경기도 가평 어귀에서 맥을 다한다. 응봉산(1097m)~백암산(1099m)~가마봉(1192)~소뿔산(1108m)으로 불거져 나오는 춘천지맥은 소양호에 막혀 남서방향으로 틀어 매봉(800m)~가리산(1051m)~연엽산(850m)으로 점차 고도를 낮추며 형세를 이루고 있다. 무엇보다도 이 지역의 백미는 가마봉에서의 조망이다. 북동으로 설악산(1708m)과 동으로 방태산(1435m), 오대산(1563m)의 자락들이 내려다보이며, 남으로는 수려한 공작산이 자리해 있다. 마치 등대에 올라 먼 바다를 꿈꿔보는, 양 시력이 허락하는 한 눈앞에 거슬리는 것이 없다. 소뿔산 정상에 서면 작은 암각도 발견할 수 없다. 하지만 소뿔산을 지나 백암산 자락에서 소뿔산을 바라보면 무명봉과 함께 이어진 소뿔산 산세 모양이 소의 뿔과 같이 생겼음을 알 수 있다.", + "MNTN_HG_VL" : "1108", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "소뿔산" + }, + "longitude" : 128.1408333, + "latitude" : 37.8938889 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울에서 44km, 동두천시청에서 동북쪽으로 약 5km의 거리에 있는 소요산은 경치가 뛰어나 경기도의 '소금강'이라 불린다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시, 포천시 신북면", + "MNTN_NM" : "소요산" + }, + "longitude" : 127.0878091, + "latitude" : 37.942629599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "475", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "소주봉" + }, + "longitude" : -79.433894899999999, + "latitude" : 43.795823200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한반도의 등줄기인 백두대간(白頭大幹)과 서해바다까지 뻗어 나간 한남금북정맥(漢南錦北正脈)의 분기점에 솟아 올라 조선팔경의 하나이자 소금강, 또는 제 2의 금강이라 불리는 속리산(1,058.4m)은 행정구역상으로는 충북 보은과 경북 상주에 걸쳐 있는 명산이다.", + "MNTN_HG_VL" : "1058", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 보은군 내속리면", + "MNTN_NM" : "속리산" + }, + "longitude" : 127.90000000000001, + "latitude" : 36.533332999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "231", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군", + "MNTN_NM" : "송공산" + }, + "longitude" : 126.254693, + "latitude" : 34.851599899999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북한 개성이나 제주도에 `송악' 이란 지명이 있는데 두 곳 모두 민족의 애환이 서려 있다. 경기도 가평군에 있는 송악산은 두 산과 별개로 백둔리 토박이 주민들이 지어낸 산이다.", + "MNTN_HG_VL" : "705", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "송악산" + }, + "longitude" : 126.29192190000001, + "latitude" : 33.1977951 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "송학산은 제천에서 영월로 뻗는 38번 국도에서 왼쪽으로 올려다 보이는 산으로, 산 전체가 거의 소나무 일색이며, 송학산 자락은 주변으로 채석장이 여러 곳 있어 질 좋은 화강암이 생산되던 곳이다.산 이름 그대로 아름드리 노송은 많지 않지만 산 전체가 거의 소나무 일색으로 산행 내내 코끝을 스치는 그윽한 솔향이 일품이며, 푹신한 솔잎을 밟으며 청산의 푸른 기운을 느낄 수 있다.정상 바로 아래에는 빼어난 조망을 가진 강천사가 있으며, 짧은 코스지만 정상에 올라서면 송학면 일대의 조망이 일품이다. 남쪽으로는 무등산, 왕박산, 갑산, 가창산이 첩첩으로 포개지며 서북쪽으로는 제천의 진산 용두산과 그 뒤에 석기암, 감악산이 한 눈에 들어온다.강천사에서 조금 내려오면 급하게 굽이도는 언덕 너머에 빈대로 망했다는 전설의 소악사지가 있으며 3층석탑만 외로이 남아 무상한 역사를 말해준다.", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면ㆍ강원도 영월군 주천면", + "MNTN_NM" : "송학산" + }, + "longitude" : 128.26791040000001, + "latitude" : 37.208268799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "276", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "송화산" + }, + "longitude" : 129.19061189999999, + "latitude" : 35.851393700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "794", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "수덕산" + }, + "longitude" : 127.5135183, + "latitude" : 37.915029699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", + "MNTN_NM" : "수도산" + }, + "longitude" : 127.98164250000001, + "latitude" : 35.859287100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수도산은 소백산맥 대덕산에서 초점산을 분기점으로 가야산으로 흘러드는 산줄기 들목에서 경남과 경북을 가르고 있는 육산이다. 경상북도 김천시 증산면 평촌리와 경상남도 거창군 가북면에 위치하는 이 산은 골짜기마다 맑은 물이 흘러넘쳐 소와 담을 이룬다.수도산이라는 이름은 정상에서 1.5킬로미터 아래 수도사가 위치하고 있는데서 유래한다. 수도사는 수도산 상부에 위치한 도량으로 옛날 도선국사가 이 도량을 보고 앞으로 무수한 수행인이 나올 것이라 하여 산과 도량 이름을 각각 수도산, 수도사라 정했다고 한다. 백 여 년 전부터는 부처님의 영험함과 이적이 많다하여 사람들이 불영산, 선령산이라고도 부른다.산 아래 수재(秀才)는 천재가 살았다는 전설에 따라 마을 이름이 되었다고 하며 심방소(尋芳所)는 고려 말 신방이란 사람이 은거한 곳이라는 뜻과 또는 땔나무가 많다는 뜻에서 신방(薪方)으로 하다가 아름다운 경치에 반해 찾는 사람들이 많다는 뜻의 심방(尋訪)으로 불렸다는 이야기가 전해진다.", + "MNTN_HG_VL" : "1317", + "MNTN_LOCPLC_REGION_NM" : "김천시 증산면, 대덕면·경상남도 거창군 가북면", + "MNTN_NM" : "수도산" + }, + "longitude" : 127.98164250000001, + "latitude" : 35.859287100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도봉산과 마주 보고 있는 수락산은 상계동에 대단위 아파트촌이 건립되면서 상계아파트 단지의 뒷산이 되었다. 도봉산에 비해 규모는 작지만 산 곳곳에 노출된 암벽으로 인해 경관이 뛰어나고 동쪽에는 신라 때 창건된 내원암과 흥국사가 있다.산 전체가 화강암과 모래로 이루어져 있고 기암괴석과 샘, 폭포가 많은 반면 나무는 매우 적다. 산의 분위기가 다소 삭막하기는 하나 바위의 경치가 뛰어나고 곳곳에 맑은 물이 흘러내린다. 수락 8경이라 불리는 금류폭, 은류폭, 옥류폭포와 동서 산록의 계곡에는 수락산유원지와 벽운동유원지가 있다.산세가 웅장할 뿐만 아니라 산 전체가 석벽과 암반으로 되어 있어 도처에 기암괴석이 즐비하다. 장암동에는 조선 숙종 때 형조판서를 지낸 서계 박세당의 정자인 6각형의 궤산정이 있다.", + "MNTN_HG_VL" : "641", + "MNTN_LOCPLC_REGION_NM" : "서울시 노원구 상계동", + "MNTN_NM" : "수락산" + }, + "longitude" : 127.08223340000001, + "latitude" : 37.696492999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수레의산은 충북 음성군에 위치한 아담한 산이다. 아직 사람의 발길과 개발의 손길이 미치지 않아서 천연의 순박함을 그대로 간직하고 있는데,이 산은 이름부터가 특이하다. 산 서쪽 계곡에는 청소년수련원과 차곡저수지가 있고 수량이 많으며 수리산에서부터 산서릉의 459번도로까지 임도가 잘 뚫려있다. 박쥐굴, 굴법당, 공기바위, 병풍바위, 상여바위, 전설의못등 볼거리가 많고, 산행시간이 짧고 등산로가 잘 닦여있어 가족산행지로 제격이다.수레의산은 신비의 산이며 숨어있는 산이다. 600m가 넘는 높은 등성이(주능선)에 25평이 넘는 연못이 있고, 거기에 꽤 많은 물이 고여 있다. 이른바 전설의 못이다. 잘 이해가 되지 않는 현상이다. 수레의산은 신비스러운 산답게 사람들의 눈에 잘 띄지 않는 곳에 조용히 숨어 있다. 큰 도로들이 거미줄처럼 얽혀 있는 지금의 상황에서는 웬만한 산은 큰 길에서 그 모습을 볼 수 있다.그러나 이 산은 근처를 지나는 3번 국도(이천 - 충주)나 38번 국도(평택 - 장호원 - 제천), 또는 중부내륙고속도로에서 잘 보이지 않는다. 심지어 산 북서에서 남동으로 가까이 지나는 520번 지방도에서도 가려내기 어렵다. 그 까닭은 큰 도로들이 이 산 근처에서 산 사이를 지나는 때문이기도 하고, 주위에 고만고만한 산들이 많기도 하기 때문이다. 수레의산 주변 산줄기는 남으로 가영산 - 부용산으로 이어지고, 북으로 수리산- 원통산- 오갑산으로 뻗쳐있다. 수레의산이 그처럼 비슷한 높이의 봉우리들로 이루어진 산줄기 가운데 자리잡고 있기 때문에 알아보기 쉽지 않은 것이다.그러나 이 산은 숲이 울창하고 산길이 좋은 데다 산허리를 임도가 지나고 있어 오르내리기에 편리하다. 어디서 올라도 점심시간을 포함해 3 - 4시간이면 어려움 없이 주봉은 물론 전설의 샘(못)까지 돌아 내려올 수 있어 가족산행에 알맞다. 내내 짙은 숲속을 걷기 때문에 산뜻한 기분이 끝까지 이어지고, 군데군데 상여바위 병풍바위 박쥐굴 공기돌 굴법당들도 볼 수 있어 심심찮다 특히 전설의 샘 위에 있는 상여바위는 푸른 숲에 둘러싸인 채 우뚝 솟아 특이하고, 그 위에 오르면 조망이 좋고 시원하다.전설의 샘이 말해주듯 산에는 물이 많다. 주름이 많아 골짜기가 많고 골짜기마다 개우에 맑은 물이 흐르고 있고, 매우 차가워 손을 오래 담그고 있기 어렵다.이 좋은 수질은 이미 근방에 널리 알려졌는데 농업용수로 사용하기 위해 저장해 놓은 차곡저수지의 물조차도 수영하기 어려울 정도로 차고 깨끗하다고 한다. 그래서 근처의 주민들도 아끼고 좋아하는 산인 듯 싶었다. 고스락에 오석 표석이 두 개가 있고, 화강암 표석도 하나 있다.가장 전망좋은곳은 상여바위 꼭대기이고, 전설의못은 능선상에 있는 연못으로 청학포란형의 권근 3대묘와 연루되어 묘를 쓸때 해발 505미터의 이곳에 물을 올렸다는 전설이 있다고 한다.", + "MNTN_HG_VL" : "679", + "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 생극면", + "MNTN_NM" : "수레의산" + }, + "longitude" : 127.6523238, + "latitude" : 37.034960099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 치악산국립공원내의 남대봉에서 중앙선 또아리굴이 지나가는 산자락에 연결되어 있는 지능선상에 솟아 있는 수리봉은 많이 알려지지 않은 산으로 때묻지 않은 자연을 간직한 곳이다.수리봉은 내원계곡을 끼고 있어 여름철 산행지로도 그만이다. 안으로 들어갈수록 수림이 울창하고 반석지대가 많아 물놀이를 즐기기 좋고 산행 후 땀을 씻기에도 안성맞춤이다.삼각점(442-76 재설)이 있는 정상은 남동쪽만 제외하고 서쪽과 북, 동쪽이 수림지대로 에워싸여 조망이 터지지 않는다. 남동쪽으로는 문막 건등산 뒤로 명봉산, 덕가산, 백운산 등이 조망된다.", + "MNTN_HG_VL" : "427", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수리봉은 수리가 긴 날개를 벌리고 내려앉은 형상의 품 넓은 산으로 정상에 서면 사방으로 첩첩이 둘러쌓은 능선의 바다를 만끽할 수 있는 오지의 산이기도 하다. 전반적으로 산세가 온화하지만 코스가 제법 길고, 무엇보다 지맥들이 수없이 갈려나가 독도에 각별한 주의를 요한다. 정상에서 여무재 쪽으로 10분쯤 떨어지면 수십km를 일망무제로 펼쳐진 숲과 능선의 바다가 펼쳐진 전망바위를 만날 수 있다.", + "MNTN_HG_VL" : "1019", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 횡성군", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수리봉의 등반로는 리지를 따라가게 되어있다. 수리봉 리지는 언제 누가 처음 등반을 했는지 알 수 없다. 그러나 연휴 때 줄을 서서 기다리는 기존의 리지 코스보다 한적한 등반을 즐길 수 있다. 또한 사람 손을 덜 타 새로운 루트를 등반한다는 기대감이 묘미를 더해 준다.산행 들머리는 생달국교와 약사정 마을 중간에 있는 다리다. 등반 도중에 물이 없으므로 낙엽 송숲을 지나 계곡에서 식수를 준비해 가야한다. 낙타바위 이외에는 설치된 확보물이 없으므로 선등자는 슬링과 크랙 등반에 필요한 프렌드를 넉넉하게 준비해야 한다.암벽등반 경험이 많은 사람들은 빨리 서두르면 4시간이면 등반을 마칠 수 있지만 초보자와 함께 한 등반이라면 암릉의 위험한 구간을 통과할 때마다 줄을 사용하는 것이 바람직하다. 바위를 손질해 놓지 않아 불확실한 확보물과 푸석바위가 많다. 낙석에 충분히 대비해야 한다. 기존 확보물이 없으므로 확보물에 각별히 신경을 써서 준비하는 것이 좋다. 계속 리지를 타고 올라가면 옛 성터 모습이 남아 있고 여기서 능선을 타고 올라가면 백두대간 능선인 황장재 헬기장 위에 도착된다.", + "MNTN_HG_VL" : "645", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 생달리", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 춘천시 동내면 사암리, 동내면 원창리에 위치한 해발 645미터의 수리봉은 대룡산, 연엽산, 금병산 사이에 위치한 육산이다. 원창고개 마루에서 산행이 시작되므로 300미터만 오르면 되니 가족 동반 산행이 가능하다. 정상 넘어 쉰동골에 있는 원창저수지 상류계곡은 인적이 드물어 호젓하게 산행을 즐길 수 있지만 현재는 등산로가 끊겨 저수지까지 산행은 불가능하다. 산행 후에는 따로 저수지에 들러 깨끗한 물에 탁족으로 산행의 피로를 푸는 즐거움도 있다.비록 높이도 규모도 작지만 능선의 마지막 부분에 우뚝 솟은 652미터 봉우리는 아름다운 직벽의 암봉이다. 특히 수리봉과 응봉의 사이의 협곡은 좌우로 막아선 암벽과 울창한 수림이 맑은 계류와 어울려 경관이 빼어나다.", + "MNTN_HG_VL" : "645", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동내면ㆍ동산면", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수리봉은 독수리가 서식하는 곳으로 수리등이라 하는 바위 층으로 된 산이다. 외부 세계와 단절된 심산유곡을 찾는 듯한 느낌을 줄 정도로 주변 경관이 수려하며 북암산과 억산의 중간에 위치한 독립된 산이다.운곡은 굼실이라 하여 산세가 웅장한 가운데 기암절벽을 이루고 폭포수가 떨어지고 있으며 그 산봉우리는 언제나 오색구름이 서려 있다고 하여 구름실(굼실)이라는 지명이 생겨났다. 조선조 숙종 때 숙종의 아들인 영조 임금을 낳은 숙빈 최씨의 고향이라는 기록도 남기고 있다. 산행들머리는 석골사 입구 부도군 아래 콘크리트 포장도로가 석골사와 주차장으로 나누어지는 왼쪽길이다.정상에는 봉화대인가 성터인가 돌무더기로 둘레를 만들어 놓아 쉴 곳이 마땅치가 못하다. 15분 정도 더 가서 있는 바위에 가서 쉬는 것이, 주변 경관과 조망이 좋아 나을 듯 싶다.", + "MNTN_HG_VL" : "767", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 단양군 대강면 방곡리에 위치한 수리봉은 빼어난 단양의 풍광을 그대로 이어받은 산이다. 인근의 소백산, 황정산, 도락산 등의 유명세에 가려 아직 일반에 잘 알려져 있지 않으나, 산행의 묘미만큼은 앞서의 산들과 비교할 때 전혀 손색이 없다.정상에서면 주흘산, 대미산, 황장산, 도솔봉, 소백산연봉, 문수봉, 하설산, 월악산, 도락산, 황정산 등이 보인다.대체로 바위산이나 동쪽 사면은 주로 신갈나무를 중심으로 한 숲으로 형성되어 있고. 암릉은 단속적이고 정상능선의 암릉은 300미터 될까 말까한 길이이지만 유의할 위험지대 있으며 바위아래 사면엔 진달래 철쭉류도 있다.또한 수리봉은 등산 뿐만이 아닌 단양팔경의 절경인 하선암, 중선암, 상선암 또는 사인암의 비경을 즐길 수 있어 주위의 경관과 함께 빛을 나타내는 산이다.산행기점인 방곡리는 도자기로 유명하다. 도자기를 생산하기 위해 만들어진 산이라고 불리울 정도로 도자기 생산에 필요한 재료가 모두 갖추어져 있다. 주로 서민층의 생활도기를 만들어 왔으며 일본으로 수출도 한다.그리고 이곳 방곡리는 속세와 떨어져 별천지에 온 것처럼 격리되어 있으며 옛날 도자기 장이 섰다는 장승마을에는 오래된 이곳 사람들의 옛사연을 머금은 채 장승한쌍이 자리를 지키고 있다.", + "MNTN_HG_VL" : "960", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면 방곡리", + "MNTN_NM" : "수리봉" + }, + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수리산은 안양, 군포, 안산시 경계에 자리한 산이다. 관악산, 삼성산, 모락산과 이웃하고 있으며 낮으면서도 암릉과 숲, 계곡의 경관이 좋아 조선시대에는 안산의 명산으로 불리기도 했다. 수리산 산세는 북쪽으로 터진 말발굽 모양을 하고 있다. 말발굽 북동쪽 끝줄기에 관모봉(426m)이 있으며 상봉인 태을봉(489m)은 관모봉 남서쪽에 있다. 태을봉에서 반 바퀴 돌아서면 서편 줄기 중간에 독수리바위인 수암봉(395m)이 있으며 산줄기가 휘돌아가는 슬기봉과 고깔봉 일대에 공공시설물이 있다.수리산 산행에서 가장 경관이 뛰어나고 산행의 맛이 좋은 곳은 태을봉에서 슬기봉까지 이어지는 암릉 구간과 수암봉이다. 산행은 안양 창박골 쪽에서 관모봉으로 올라 태을봉을 거쳐 병목안 골짜기를 끼고 반 바퀴 돌아 수암봉까지 가거나 거꾸로 수암봉에서 시작하여 관모봉으로 돌면 된다. 태을봉 바로 아래의 거대한 산본 아파트 단지에서도 등산로가 여럿 있다.", + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "경기도 안양시·군포시·안산시", + "MNTN_NM" : "수리산" + }, + "longitude" : 126.9027047, + "latitude" : 37.366196799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 밀양시 단장면 구천리에의 수미봉, 향로봉, 사자봉,필봉 정각봉이 바로 그 다섯 봉우리 중 가장 중심이 바로 수미봉이다. 수미산은 불교에서 말하는 세상의 중심에서 가장 높게 솟은 산. 그래서 수미봉이라 이름이 붙었다. 이 수미봉을 재약산이라고도 하는데 이는 사자평과 주암골 등지에서 약초재배가 많이 이루어졌기 때문이다.이 수미봉의 북쪽으로 더 높게 솟은 봉우리를 사자봉이라 부른다. 그 기상이 사자처럼 힘차고 늠름해서 붙여진 이름이다. 이를 일제의 개명으로 천황산이라 불리었고, 아직도 국립지리원 발행 5만분의 1 지형도에는 천황산이라 표기되고 있다.수미봉 정상에는 '재약산 수미봉(1,108m)', 사자봉 정상에는 '사자봉(1,189.2m)' 이라는 정상석이 세워져 있다.수미봉의 산행들머리는 표충사 500m 앞 주차장에서 사자평으로 가는 전술도로로 들어서는 입구에서 시작된다. 50여분 가다보면 흑룡폭포의 웅장함을 전망대에서 보게 된다. 이 길은 몇 차례 산비탈을 치고 오르는 코스가 있어, 초보자에게는 다소 무리가 따르나 계곡과 폭포 및 옥류동천의 비경을 감상하는 것으로, 그 만큼의 고통은 감수할 만하다. 수미봉 정상에서는 사자평의 억새밭이 태양과 바람에 은빛 파도가 되어 출렁이는 모습을 볼 수 있다.", + "MNTN_HG_VL" : "1116", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "수미봉" + }, + "longitude" : 128.96011490000001, + "latitude" : 35.532613699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "기양산과 수선산이 자리한 상주시는 예로부터 삼백(쌀, 누에고치, 곶감)의 고장으로 낙양으로도 불리었다.수선산은 상주시 청리면 청상리와 낙동면 수정에 솟아있는 육산으로 연산군 시절 연산군의 만행을 싫어하여 피신 은둔 수도한 서비가 많았다고 하여 이름지어진 산이다. 접근하는 방법에는 청리면 청상리 수선지 뒤 계곡길을 이용하거나 기양산에서 수선산을 거쳐 돌티로 하산하는 두 방법이 있으나 청상코스는 수선지 뒤 계곡이 끝나는 지점까지는 길이 잘 나 있으나 그 이후 길이 확실치 않고 잡목이 길을 막기 때문에 가급적 삼가고 기양산 코스를 이용하여 수선산으로 가는 방법을 택해야 한다.", + "MNTN_HG_VL" : "684", + "MNTN_LOCPLC_REGION_NM" : "상주시 청리면 청상리 \/ 낙동면 수정리", + "MNTN_NM" : "수선산" + }, + "longitude" : 128.1716667, + "latitude" : 36.299722199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "경기도 안산", + "MNTN_NM" : "수암봉" + }, + "longitude" : 126.8926501, + "latitude" : 37.367029899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수인산은 강진과 장흥의 경계를 이루고 있으며 그 높이와는 어울리지 않게 웅장하고 오묘한 산세를 이룬다. 산성으로 둘러싸인 정상부는 고려 말부터 조선말까지 전라 병영성의 전략 요충지로서 왜구가 침략할 때마다 주민들의 피난처로 이용되었고 병영면의 지명은 조선 태종 때 왜구를 막을 목적으로 병영을 설치한 데서 유래한 것이다. 실제 수인산은 병영면 소재지에서 바라보면 알을 품은 듯한 형상인 노적봉을 가운데로 주위가 온통 암벽으로 둘러 싸여 있어 천혜의 요새로 손색이 없는 철옹성 같은 산세를 보여준다.수인산은 억새로도 유명한데 정상부 천평 규모의 조릿대와 어우러져 황금벌판이 압권이다. 수인산의 대표적인 등산 코스는 강진 병영면의 수인사, 홈골에서 시작하는 것과 장흥 유치면 대리의 수덕목장에서 올라가는 길이다.무등산, 지리산, 두륜산, 천관산, 흑석산, 월출산에 둘러싸인 지점이 이곳으로 정상에서의 조망은 일품이다. 가까이는 장흥벌과 병영벌이 훤하게 내려다보인다. 장흥벌을 흐르는 탐진강이 길게 꼬리를 늘어뜨리며 다도해로 빠지고 있으며 병영면은 너른 평야를 감싸 안은 듯 산세가 이루어져 비옥한 곡창지대를 형성하고 있다.", + "MNTN_HG_VL" : "561", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 병영면·장흥군 유치면", + "MNTN_NM" : "수인산" + }, + "longitude" : 126.8516667, + "latitude" : 34.720555599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "『동국여지지』 죽산현 편에\"수정산은 현 북쪽 35리에 있고 건지산과 서로 연해 있다. 산 위에 돌로 된 굴이 있는데 그 안에 굴암(窟菴)이라 불리는 작은 암자가 있다.\"고 하여 관련 기록이 처음 등장한다. 『대동지지』에는\"북쪽 39리에 있는데 꼭대기에 석굴이 있고 그 안에 작은 암자가 있다. 수정이 나온다.\"라고 하여 예전에 이 산에서 자수정을 생산했던 관계로 그 이름이 유래한 것으로 짐작된다.", + "MNTN_HG_VL" : "348", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 처인구 백암면", + "MNTN_NM" : "수정산" + }, + "longitude" : 129.03749999999999, + "latitude" : 35.139444400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "345", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시", + "MNTN_NM" : "수정산" + }, + "longitude" : 129.03749999999999, + "latitude" : 35.139444400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충주시 살미면 향산리 남쪽에 자리잡고 있는 수주팔봉은 나즈막한 산세에 험준한 바위봉을 등에 업고 있는 작지만 커다란 산이다. 뾰족하게 서있는 바위봉들이 작은 산을 떠받치고 있어, 결코 만만히 볼 수 없는 위엄을 갖고 있다.달천강의 은빛 물결을 휘감고 있는 수주팔봉은 서쪽 이류면 문주리 팔봉마을에서 달천강 건너 동쪽의 산을 바라볼 때 정상에서 강안까지 달천강 위에 8개의 봉우리가 떠오른 것 같다 하여 붙여진 이름이다. 산 이름 그대로 산 주위에 물이 흐르고 8개의 봉우리가 있어 등산객들유혹하는 산임에는 틀림없다.또한 산 위에서의 조망이 마치 한폭의 동양화를 펼쳐 놓은 듯 절경을 이루고 송곳바위, 중바위, 칼바위 등 창검처럼 세워진 날카로운 바위들이 수직절벽을 이뤄 산행의 묘미를 더해준다. 주변에 수안보온천과 월악산국립공원이 있다.", + "MNTN_HG_VL" : "490", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 살미면 향산리", + "MNTN_NM" : "수주팔봉" + }, + "longitude" : 127.9196749, + "latitude" : 36.902216099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무이산역과 맞닿아 있는 이 산은 서릉을 학동재에서 향로봉의 주릉과 이음을 같이 하고 언뜻 보면 그저 거쳐가는 산봉에 불과한 것 같아서 산객들에게는 산정을 찾기가 어렵다. 그러나 보현사가 있는 남쪽사면에는 층석대가 포진하여 이 산에 아름다움을 더하고 있다.", + "MNTN_HG_VL" : "570", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 상리면", + "MNTN_NM" : "수태산" + }, + "longitude" : 128.20084900000001, + "latitude" : 34.976284999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수촌이라는 마을의 `자연숲' 뒤에 솟았다고 해서 숲뒤산이라 부르는 이 산은 고양이와 개에 관한 전설이 얽혀있는 광동굴, 층층나무와 잣나무가 그득한 숲, 하늘말나리와 더덕의 향기가 은은히 퍼지는 산길, 냉기가 솟는 샘물 때문에 오지를 찾는 사람들이 저절로 발길을 멈추게 된다.비라도 내리면 광동굴에 들어앉아 비오는 풍경도 감상할 수 있어 특히 여름 산행이 즐거운 산이다. 또한 숲뒤산은 강원도 삼척시 하장면 장전리에 있는 골로 마을이 있어 볼품없는 골짜기나 계곡 중간에 식수원으로 쓰는 광동굴 입구가 여름에 시원하고 멋지다. 골지천에서 휴식을 하고 한번쯤 둘러 보는 것도 좋다.", + "MNTN_HG_VL" : "1065", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", + "MNTN_NM" : "숲뒤산" + }, + "longitude" : 128.9251209, + "latitude" : 37.3435427 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "쉰움산은 삼ocirc;시 동쪽으로 15킬로미터 떨어진 두#376;산의 북동쪽 상에 솟은 작은 봉우리다. 명산이라 함은 대개 산정의 풍치와 계곡의 아름다움, 그리고 산기슭의 명찰까지도 거론하는데 쉰움산은 이 세 조건을 모두, 그것도 최상급으로 갖췄다.그럼에도 두#376;·ucirc;옥산 사이의 무릉계곡 경관이 워낙 빼어나 대개는 무릉계곡을 따라 두#376;~ucirc;옥간 능선만 밟고 돌아 내려가는 것이 일반적이었다. 무릉계곡의 한 지류로서 쉰움산 북쪽 바로 아래로 뻗은 비린내골 입구는 또 쌍용양회의auml;석장이라 통행이 되지 않았다. 이런 연유로 쉰움산을atilde;는 이는 극히 드물었던 것이다.쉰움산만 오르려면 삼ocirc;시 동쪽 미로면 내미로리의otilde;은사로 가면 된다.otilde;은사에서 정상까지는 1시간이면 충분히 오른다. 능선으로 올라 계곡으로 내려서는otilde;은사 원점회귀코스는 ª지만 쉰움산의 알yen;배기 비경을 둘러보며 산행할 수 있어 좋다.오십정산(五十井山)이라고도 불리는 이 산은 한자 그대로 오십 개의 우물이 있다고 해 붙여진 이름이다. 정상 부근은 거대한 암반에 쉰 개 보다 훨씬 많은 웅덩이가 곰보자국oacute;럼 박혔다. 정상석에는 쉰움산이라는 이름 대신 ‘五十井 683m’라 적혀있다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면, 동해시 삼화동", + "MNTN_NM" : "쉰움산" + }, + "longitude" : 129.0288889, + "latitude" : 37.447499999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오십개의 우물이 산 정상에 있다하여 오십정산(五十井山=쉰우물산)이다. 실제로 우물이 있는 것은 아니다. 정상의 바위표면이 흡사 달의 분화구 같기도 하고 천연두를 앓은 자국 비슷한 알터에는 가뭄에도 항상 물이 고여 있어 신비감을 더 한다.바위에 패인 자국을 누가 50개라 하였는지는 몰라도 작은 메추리 알에서 공룡알까지 또는 함지박에서 술잔 크기까지 크고 작은 것까지 따진다면 실제로 그 수를 헤아릴 수 없이 많아 이런 이름이 붙었다. 쉰움산은 강원도 삼척시 미로면과 동해시 삼화동의 경계에 위치하고 있으며 정상에서 남서쪽으로 3km지점에는 두타산이 위치해 있다.명산이라 함은 산정의 풍치와 계곡의 아르다움, 그리고 산기슭의 명찰까지도 거론하는데, 쉰움산은 이 세 조건을 그것도 최상급으로 갖추어 지녔다. 또한 이 산은 태백산과 마찬가지로 무속의 성지라 이를 만한 곳이다. 산 곳곳에 치성을 드리는 제단, 돌탑 등이 즐비하다. 어느 할머니가 이곳에 놀러왔다가 그만 신이 내려 무당이 되었다는 일화도 전한다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면, 동해시 삼화동", + "MNTN_NM" : "쉰움산" + }, + "longitude" : 129.0288889, + "latitude" : 37.447499999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무안군을 동서로 가르고 청계면과 몽탄면을 경계로 하는 해발 318m의승달산은 노령산맥 4대 명혈중의 하나이며 목포의 유달산과 쌍벽을 이루는 명산으로 총지사지, 목우암 등 불교사적이 많다. 3백미터가 조금 넘는 이 산이 명혈로 꼽히는 이유는 고승이 제자를 모아 놓고 불공을 드리는 형상이기 때문으로 예전에는 영축산이라 불렸다고 한다.고려 인종때 원나라 승원명이 제자 500명과 함께 도를 득달한 후 이 산을 승달산이라 명하셨고 산세가 수려하고 주변경관이 아름다워 휴일이면 가족단위 피크닉 장으로 널리 알려져 있다.현재는 이 혈아래에 목포대학교가 터를 잡고 있다. 승달산은 신안군과 서해를 내려다 볼 수 있으며 반나절이면 원점회귀가 가능해 평일에도 등반이 가능한 곳이다.들머리는 국립목포대학교 농과대 실습장이 있는 도림리 천지골과 월산리 수월동, 몽탄면 목우암인데, 교통이 편한 천지골이 자주 이용되고 있다. 특히 천지골 오름은 노승봉과 318봉으로 이어지는 능선 위 하루재까지 임도가 뚫려 쉽게 접근할 수 있으며 이 임도가 하루재 건너의 법천사나 목우암 아래까지 이어져 있다. 백제 성왕 때 덕이조사가 창건했다는 법천사는 조선시대 들어서 무수히 많은 고승이 수도하던 곳으로 우리나라 불교의 4대 성지중 하나로 불린다. 조선 후기에 폐사되었지만 퇴락한 요사채가 역사를 증명해 주고 있다. 법천사 맞은편에 위치한 목우암은 승달산 제일의 명당에 자리잡았다고 한다. 목우암에는 2미터가 넘는 목조불과 산신각이 있으며 새로지은 대웅전이 번듯하기만 하다.또한 남도의 바닷가에 위치하고 있어서 해발고도에 비해 월등히 뛰어난 조망을 즐길 수 있을 뿐 아니라 겨울에도 훈훈한 훈풍을 느낄 수 있는 명산이다. 그리고 토양이나 기후 조건이 야생난이 자라기에 최적의 조건을 지니고 있어 '난(蘭)'자생지로도 이름 난 곳이다.", + "MNTN_HG_VL" : "318", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 청계면, 몽탄면", + "MNTN_NM" : "승달산" + }, + "longitude" : 126.4569444, + "latitude" : 34.908888900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "승학산은 보라마을 뒷산으로, 산세가 마치 학이 나는 형상이라 하여 이름 붙여졌다. 승학산 봉우리 모양은 떡시루 같이 생겼다고 하며, 또 천지 개벽때에는 물에 잠기고 떡시루 하나 놓을 만큼 남아 있었다 하여 시루봉이라는 지명도 남아 있다. 승학산 기슭에 있는 보라마을은 승학산이 비단처럼 둘러싸여있다 하여 보라(甫羅)라고 했다.밀양의 승학산은 워킹과 계곡을 함께 즐길 수 있는 산행지로 적합한 산이다. 밀양시 단장면의 승학산-정각산-정승계곡 코스는 끝없이 이어지는 능선길을 달릴 수도 있고 하산길에 10여Km나 되는 계곡 물길을 거슬러 내려가는 계곡 산행을 같이 즐길 수 있는 멋진 곳이다. 특히 정승골 계곡은 산악인들에게 아직도 알려지지 않은 곳으로 깨끗함은 물론 비경이 이어지는 새로운 계곡 산행지이다. 정각산의 여러 코스를 올라 본 산악인이라면 정승골 계곡을 먼발치에서 내려다 본 경험은 있을 것이다. 그러나 비경이 이어지는 계곡의 참모습을 물길 산행을 하면서 느껴 본 사람은 그리 많지 않을 것이다.산행들머리는 회관에서 50m 과수원 초입에서, 왼쪽 위로 돌아 별장에서 오른쪽으로 오르면 본격적인 산행이 시작된다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "승학산" + }, + "longitude" : 128.98537350000001, + "latitude" : 35.1317807 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "승학산은 부산의 억새명산이다. 승학산은 부산에서 가장 서쪽에 있으며, 구덕산과 시약산의 서쪽, 엄광산의 남쪽으로 사하구 당리동의 뒷산이다. 승학산 동쪽 제석골 안부에 억새군락이 있는데, 이는 수만 평에 이르는 부산 제1의 억새밭이다. 바람 따라 일렁이는 대장관은 전국의 어느 억새명산 못지않다. 더불어 부산의 다양한 풍경을 한눈에 조망할 수 있다.승학산의 동쪽에는 영도, 감천, 송도 등의 항구와 바다가 펼쳐지며, 서쪽에는 서서히 강폭을 넓히는 낙동강과 드넓은 김해벌이 그 규모를 자랑하고 남쪽에는 연대봉이 우뚝 솟았고 북쪽에는 발아래 펼쳐진 억새밭이 눈길을 사로잡는다. 승학산은 높지 않으나 그 이름처럼, 도시 속의 고고한 학과도 같은 화려함으로 등산인들의 마음을 사로잡는 산이다. 고려말 무학대사가 전국을 두루 돌아다니며 산세를 살폈는데 이곳에 오니 산세가 준엄하고 기세가 높아 마치 학이 나는 듯 하여 승학산이란 이름을 붙였다는 전설이 전해 오며 흔히 동아대 뒷산이라고도 한다.", + "MNTN_HG_VL" : "497", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 사하구 당리동", + "MNTN_NM" : "승학산" + }, + "longitude" : 128.98537350000001, + "latitude" : 35.1317807 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "시랑산은 충북 제천시 백운면과 봉양읍의 경계를 이룬다. 백운산을 모산으로 하고 있는 시랑산은 높이는 나즈막하나 아기자기한 산행의 맛을 즐길 수 있다. 산을 오르면서 곳곳의 지명에 얽힌 뒷이야기들을 따라가다 보면 금새 정상에 다다른다. 정상에서 내려다보이는 산행들머리인 박달재에서는 금방이라도 `울고넘는 박달재'의 노랫소리가 들려올 것만 같다. 금봉이와 박달이의 애절한 사랑이야기와 거란족 10만 대군을 섬멸시킨 려의 명장 김취려장군의 승전을 상기하며 산행으로 인해 가빠진 호흡을 가다듬는다.눈꽃과 상고대가 곱게 피어난 정수리에서 북쪽으로 하산길을 이어간다. 조금 내려가면 쉬어가기에 적당한 널찍한 공터를 만나게 된다. 봄이나 가을이면 둘러앉아 간식을 권하며 산꾼들의 우정을 나누기에 안성맞춤인 명당이다. 조금 더 내려가면 바위지대를 만나게 된다. 눈이 쌓인 겨울에 미끄러지면 다치기가 쉽상이니 조시조심 지나가야 한다.조금 더 내려가면 아름드리 소나무와 참나무가 마주서서 정답게 이야기를 나누는 일주문을 지나게 되고, 북쪽 산길을 계속 이어가면 정상을 출발한 지 50분이면 단군비석에 도달한다. '국조단둔대황조성령(國祖檀君大皇祖聖靈), 삼선사령영사령(三仙四靈令司靈), 백운산성화신령(白雲山聖化神靈) 국사산왕산신지령(國祠山王山神之靈)' 이라고 쓰여진 세 개의 비석이 몇 그루의 노송 및 바위와 어우러져 신비로운 분위기를 연출한다. 이곳에서 조금 더 내려가면 그 유명한 박달재에 내려서게 된다.기나긴 세월동안 충주와 제천을 잇는 국도로서 숱한 애환이 서린 박달재이건만 이제는 고개 밑으로 시원스런 터널이 뚫려 인적이 드문 쓸쓸한 고갯길이 되고 말았으니 격세지감을 절로 느끼게 된다.", + "MNTN_HG_VL" : "691", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면, 봉양읍", + "MNTN_NM" : "시랑산" + }, + "longitude" : 128.05472219999999, + "latitude" : 37.126666700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "371", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군", + "MNTN_NM" : "시묘산" + }, + "longitude" : 129.25624719999999, + "latitude" : 35.762683299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "식산은 백원산과 같은 능선상에 있는 하나의 육산으로 정상 부근의 암석에 봉황대 세 글자가 새겨졌다고 전해져 내려오고 있으며 그 서쪽 기슭에는 동해사 (일명 한산사)가 자리를 잡고 있다.동해사는 무학대사가 상주의 지형이 행주형(行舟形)이라 풍수지리에 의하여 창건했다고 한다. 병자호란 이후에는 승정처사 이경남을 비롯한 그 후손들이 숭명사상을 고취한 곳으로도 유명하다.정상에서는 낙동강과 상주 시내가 잘 보이며, 부근에 있는 암석에는 ‘봉황대(鳳凰臺)’라는 글자가 새겨져 있었다고 전해진다.산행은 서곡동을 기점으로 하는데, 마을 안길로 접어들어 동해사를 거쳐 오르거나, 마을 안길을 따라 오르다가 마지막 민가 옆 갈림길에서 물탕골을 거쳐 오르는 방법이 있다. 등산로 상태가 좋은 편이며 경사가 완만하여 초행자도 쉽게 오를 수 있기 때문에 가족단위 산행에 좋다. 또는 굴티고개를 기점으로 채석강을 지나 백원산을 오른 다음 식산을 거쳐 동해사로 내려오는 코스가 있는데, 아카시아나무 군락이 많아 봄철에 꽃이 피면 산행하기가 즐겁다.", + "MNTN_HG_VL" : "503", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 서곡동 화개동 외담동, 낙동면 화산리", + "MNTN_NM" : "식산" + }, + "longitude" : 126.6853036, + "latitude" : 37.394303999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대전 동구 식장산은 높이 598미터로 대전에 있는 산 중 가장 높으며 우람하다. 또 무성한 숲과 높은 바위벼랑, 깨끗한 호수와 맑은 물이 흐르는 개울도 있다. 식장산 남북으로 양 날개를 펼친 산줄기는 대전의 동쪽 울타리를 이루고 있다. 대전 시민들은 식장산 위로 여명 해솟음을 보며 떠오르는 달을 본다.5월 하순 아카시아 꽃이 필 무렵이면 세천공원에서 철탑 사거리를 지나 구절사 길까지 온통 아카시아 꽃천지다. 온 산에 짙게 밴 꽃향기를 맡으며 하얀 아카시아꽃으로 뒤덮인 길을 걷노라면 하늘나라의 화원을 걷는 것 같다. 우리나라에서 식장산의 꽃길 10리가 아카시아꽃으로는 가장 훌륭한 곳으로 꼽힌다.식장산 세천공원 수원지 아래에는 벚꽃이 유명하다. 또 수원지 호수와 계곡이 아름답다. 숲으로 싸인 호수와 독수리봉에서 후주에 이르는 계곡은 어느 산의 계곡과 견주어도 빠지지 않는다. 숲 속에 묻혀 있는 계곡은 돌, 바위, 나무가 한데 어울려 깨끗하고 아름답다.식장산에는 오래된 절 세 개가 있다. 서쪽에는 고산사, 북쪽에 개심사, 동쪽 동수리봉 아래에는 구절사가 있다. 뿐만 아니라 숲이 짙으며 대전시가지가 내려다보이고 속리산, 백화산, 덕유산, 민주지산, 대둔산, 계룡산이 조망된다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 동구, 충북 옥천군", + "MNTN_NM" : "식장산" + }, + "longitude" : 127.4800673, + "latitude" : 36.2953647 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "333", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", + "MNTN_NM" : "신기산성" + }, + "longitude" : 129.0428896, + "latitude" : 35.359282700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산을 즐기면서 물을 벗할 수 있는 곳이 경기도에서는 그리 흔치 않다. 이 두 마리의 토끼를 함께 잡을 수 있는 곳이 신로봉이다. 가평군 북면과 포천군 경계에 솟아있는 신로봉은 국망봉으로 가는 길목에 있으므로 등산로가 모두 국망봉과 연결되어있다.산행기점은 역시 국망봉과 마찬가지로 이동면 장암리의 생수공장과 그 위의 장암 저수지이다. 신로봉이란 국망봉으로 가는 길목인 한북정맥상의 신로령(안부)옆의 두리뭉실한 봉우리를 말한다. 정상에서의 전망은 북쪽으로 백운산과 광덕산이 보이고, 동남쪽으로 석룡산과 화악산, 남쪽으로는 국망봉과 명지산, 서쪽으로 사향산과 관음산이 보인다. 지금은 장암리 저수지 쪽에 국망봉 자연휴양림이 생겨서 입장료를 내야함이 좀 아쉽다.", + "MNTN_HG_VL" : "999", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 가평 북면", + "MNTN_NM" : "신로봉" + }, + "longitude" : 127.4186675, + "latitude" : 38.013648500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 신불산 산자락에는 홍류폭포와 작천정이 유명하다.취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.", + "MNTN_HG_VL" : "1159", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 삼남면ㆍ상북면", + "MNTN_NM" : "신불산" + }, + "longitude" : 129.0561611, + "latitude" : 35.539955999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백덕산의 긴 주능선 자락은 주천강과 평창강이 합수하는 영월군까지 이어지는데 이 능선상의 첫번째 봉우리가 신선바위봉(1060m)이다. 산행길로 접어들면 과연 산의 이름대로 신선이 나올법한 기암과 오염되지 않은 경관을 갖추고 있다. 신선 바위에서 남릉으로 1.5km거리에는 각종 무공해 산나물이 그득 들어차 있어 산행의 또다른 재미를 맛볼 수 있다.신선바위는 20m가 넘는 수직절벽으로 꼭대기에서 내려다 보는 조망이 일품이다. 사방을 둘러봐도 막힘이 없다.. 정상에 서면 먼저 시선이 머무는 곳은 올라온 방향인 서쪽이다. 서쪽 아래로 법흥사 입구에서 관음사 방향으로 깊게 패인 협곡이 아찔하게 내려다 보이고 협곡위로는 법흥사 뒷산인 연화봉과 사자산이 ,그리고 치악산 비로봉이 시야에 들어온다.", + "MNTN_HG_VL" : "1068", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 주천면", + "MNTN_NM" : "신선바위봉" + }, + "longitude" : 128.0455943, + "latitude" : 36.7821456 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제otilde; 지역은 작성산과 동산(896.2m)을 지나 금수산(1015.8m)으로 이어지는 큰 산줄기가 단양군 적성면과 경계를 이루고 있다. 이 산줄기가 흐르는 금수산과 갑오고개 사이 900미터 봉에서 서쪽으로 향하는 산줄기의 최고봉이 신선봉(845.3m)이다.신선봉은 능선길 곳곳에 기암과 절벽을 이루고 있으며 노송들이 어울려 선경을 연출한다. 또한, 능선 좌우로 능강계곡과 학현계곡이 흘러 여름ouml;이면 많은 사람들의 피서지가 되기도 한다. 무엇보다 금수산 산악마라톤 대회 코스로도 유명하다.신선봉은 일명 ‘학바위봉’으로도 불린다. 학봉이라 불리는 774봉이 마치 날아오르려는 학을 닮았다는 데서 유래했다.신선봉 산행의 백미는 능강계곡을 뒤덮은 운해 너머의 금수산 풍경이다. 곳곳에 위치한 바위에 서면 남북으로 시원한 조망이 일품이다. 남쪽으로는 금수산에서 이어지는 망덕봉(926m), 가마봉(635m), 작은산밭봉(485m)을 연결하는 능선이 구름 위에서 솟아난다. 가득 피어오른 운해 사이로 기암절벽과 어우러진 노송의 모습은 그 이름oacute;럼 신선이 노닐만한 선경이다.", + "MNTN_HG_VL" : "891", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면, 수산면", + "MNTN_NM" : "신선봉" + }, + "longitude" : 128.43944440000001, + "latitude" : 38.241111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조령산 정상을 지나 조령관(제3관문) 쪽으로 40분정도 백두대간을 타고 가면 제일 높고 경치가 좋은 암봉이 나오는데 이곳이 신선봉이며 지도상에는 이름이 표시되어 있지 않다.충청북도 쪽으로는 신선암이 암벽등반지로서 이름이 높다. 정상 바로 밑 암릉에 서면 신선암에서 암벽등반하는 사람들이 보인다. 조령산 종주산행을 하면 지나가야 한다.", + "MNTN_HG_VL" : "845", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 각서리", + "MNTN_NM" : "신선봉" + }, + "longitude" : 128.43944440000001, + "latitude" : 38.241111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신선봉은 금수산(1.016m)과 동산(896m) 사이에서 서북쪽으로 뻗어 내린 능선상에 우뚝 솟은 산으로 충북 제천시 청풍면과 수산면의 경계를 이룬다.신선봉은 산자락에 비상하는 학을 닮은 바위가 있어 일명\"\"학봉바위\"\"로 불리며, 학현마을의 이름도 바로 학바위에서 유래되었다고 전해지고 있다.그러나, 신선봉의 학바위는 빙산의 일각에 불과하다고 말할 수 있다. 왜냐하면 온통 기암괴석으로 이루어진 산자락에 들어서면, 마치 조각가가 정성들여 빚어 놓은 듯한 기암괴석이 줄이어 나타나고 있으며, 바위 이름도 재미있어 킹콩바위ㆍ손바닥바위ㆍ못난이바위ㆍ물개바위ㆍ학바위ㆍ발바위 등이 그것이다.마을 북쪽인 동산에서 서남쪽으로 가지를 친 능선상의 모래재와 중고개 사이에는 옛 성터가 남아 있는데, 이곳을 마을 사람들은 작은 성안이라 부르고, 학현리의 거대한 분지를 큰 성안이라 부른다.등산을 위해 청풍도로에서 영아치고개를 넘어서면 산계곡 사이로 멋진 풍경이 연출된다.고개를 들어보면 동쪽 학현계곡이 펼쳐지고 움푹 패어내린 거대한 분지 왼쪽으로는 동산이 오른쪽으로는 저승봉, 그 너머로 신선봉이 바라보이는데, 이 일대의 모든 산 준령이 금강산을 옮겨 놓은 듯한 기암괴석과 노송 그리고 신록으로 어우러져 장관을 연출하고 있다.신선봉 정상은 계곡길과 와폭지대를 지난 다음 능선을 지나 자일을 이용해야 하는 세미클라이밍 지대와 바위지대를 지나야 오를 수 있다. 정상에는 정상임을 알리는 팻말과 돌탑이 쌓여 있고 참나무 등의 수림으로 덮여 있다. 따라서 조망은 그리 좋지 않다. 하지만 기암절경을 보았다는 것만으로도 산행의 기쁨을 느낄 수 있는 곳이 바로 신선봉이다.", + "MNTN_HG_VL" : "845", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 청풍면", + "MNTN_NM" : "신선봉" + }, + "longitude" : 128.43944440000001, + "latitude" : 38.241111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 충주시 상모면과 괴산군 연풍면에 걸쳐 뻗어있는 신선봉은 이름에서 느낄 수 있듯이 신비로움을 머금고 있는 산이다. 인근에 월악산, 주흘산, 조령산 같은 명산들이 둘러싸고 있어 그동안 잘 알려지지 않았는데, 신선봉 북쪽과 남쪽에는 각각 옛부터 이름난 두 줄기 길이 있다.북쪽의 길은 신라가 국력의 팽창에 따라 북진정책을 위해 이곳 백두대간에 처음으로 뚫은 하늘재(지릅재)요, 남쪽의 길은 조선시대에 영남의 선비들이 과거보러 서울로 올라가던 그 유명한 문경 새재 고갯길이다. 당시에\"\"황간의 추풍령을 넘으면 추풍낙엽처럼 과거에 떨어져버리고, 풍기의 죽령을 넘으면 대나무처럼 미끄러져 과거에 떨어져버리기 때문에 문경 새재를 넘는다.\"\"는 속말이 떠돌았다고 옛이야기는 전한다.한편 하늘재는 온달장군이 신라에게 빼앗겼던 계립현과 죽령 서쪽 땅을 되찾기 위해 출전했다가 단양군 영춘면 하리 소재의 아단성(근래들어 온달산성이라고 불리는 석성)에서 전사한 바 있는 바로 그 계립현으로서 충북 충주시 상모면 석문리와 경북 문경시 관음리를 잇는 해발 500m의 고갯길이다.", + "MNTN_HG_VL" : "486", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면, 괴산군 연풍면", + "MNTN_NM" : "신선봉" + }, + "longitude" : 128.43944440000001, + "latitude" : 38.241111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간이 장안산 근처의 영취산에서 금남호남정맥으로 분기되어 마이산 근처의 주화산까지 뻗어 가다가 다시 호남정맥으로 갈리어 만덕산, 오봉산, 갈재를 지나 내장산까지 이어진다.신성봉은 내장산의 주봉으로서 신선봉을 필두로 연자봉과 장군봉(696m), 서래봉(622m), 불출봉(610m) 등이 가치봉(717m)을 중심으로 대체로 동쪽으로 뻗어나가면서 입벌린 주머니(말발굽) 현상을 이루고 있다.그리고 그 사이에 개암사, 내소사 등 유서깊은 고찰이 있고 직소폭포, 봉래구곡, 낙조대 등의 승경이 곳곳에 산재하고 있다. 그뿐 아니라 주변에는 유천 도요지, 구암 지석묘군에다 호벌치와 우금산성 등 역사 유적지가 있다. 채석강, 적벽강에다 신석정 시비, 한국에서 최초로 조성된 금구원 조각공원, 변산해수욕장, 격포해수욕장 등을 갖춘 관광지다.", + "MNTN_HG_VL" : "967", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군", + "MNTN_NM" : "신선봉" + }, + "longitude" : 128.43944440000001, + "latitude" : 38.241111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신선암봉은 조령산 종주로의 중간에 위치한 암봉으로 조망이 좋고 오르고 내리는 코스도 다양하여 종주로 거쳐가기보다는 단독등산이 좋은 산이다. 오르는 코스로는 조령산의 등,하산로로 이용되는 절골에서 암벽훈련장 앞을 지나 오르는 코스와, 절골에서 중암절로 오르거나 용성골을 기점으로 오르는 코스 등 계절에 맞게 다양하게 준비되어있다.여기서는 용성골에서 북쪽능선을 타는 아기자기기하며, 전망 좋은 코스를 소개하겠다. 수옥폭포 아랫마을인 새터마을의 용성골 입구에 들어서면 벌써 별천지다. 매표소만 지나면 화강암 반석을 타고 흘러내리는 유리알처럼 맑은 계곡수와 노송이 어우러져 신선이 따로 없다는 생각이 들정도로 깨끗하다.정상에 올라서면 정상의 고즈넉함도 잠시 동, 서, 남, 북으로 뻗어오고, 뻗어나간 산줄기의 감동에 취하다보면 어느새 신선이 된다.", + "MNTN_HG_VL" : "937", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면 원풍리", + "MNTN_NM" : "신선암봉" + }, + "longitude" : 128.0455943, + "latitude" : 36.7821456 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 김해시 삼방동과 대동면, 상동면에 위치한 신어산은 동서로 뻗어 있는 산으로 북동쪽으로는 낙동강이 감돌아 흐르고 남쪽에는 광활한 김해평야가 펼쳐져 있는 낙남정맥의 한 줄기다. 가락국의 시조 김수로왕 탄강지로 전해오는 구지봉이 산맥의 서쪽 끝부분에 있다. 능선에서 김해시가지를 바라보며 산행할 수 있고 기암절벽 사이로는 구름다리가 있어 산행의 묘미를 더한다. 정상에서 서쪽 주능선을 따라 630봉까지 가는 도중에는 군데군데 암봉이 있고 580봉에서 남쪽 능선을 따라 460봉의 암봉에 올라서서 신어산을 바라보면 빼어난 경치에 감탄하게 된다. 460봉의 전망대 같은 바위에서 동쪽 계곡으로 내려가면 암벽 밑에 천진암이 있고 숲길과 대밭을 거쳐 은하사에 닿게 된다. 정상의 조망은 무척산, 토곡산, 매봉, 오봉산, 금정산의 고당봉 등이 선명하게 시야에 들어온다. 산림욕장이 문을 열어 가벼운 산책도 겸할 수 있어 가족산행으로도 제격이다.신어산이라는 이름은 ‘지모신이 깃들어 있는 산’을 뜻하는 ‘가모뫼’의 차차표기다.이렇듯 신어산은 예부터 신성한 산으로 인식되어져 왔다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 삼방동", + "MNTN_NM" : "신어산" + }, + "longitude" : 128.92087570000001, + "latitude" : 35.270207599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산행들머리는 쌍두봉 가든 입간판 사이로 난 샛길로 5분 정도 들어서 계곡을 건너면 왼쪽 사잇길이 산행의 진입로이다. 일단 산길에 오르면 쌍두봉까지 쉴 틈도 없이 계속 오르막이 계속된다.40여 분 후 조망이 탁 트이는 바위전망대에 올라서면 아래로 내려다보이는 삼계리는 정다운 마을 모습이 오순도순 그림 같고 그 위로 산세가 엄숙하게 둘러싸고 있다. 여기서 20여 분 후 쌍두봉 정상의 2개의 봉우리가 시야에 들어오고, 정상인 봉우리에는 험로로서 바위를 타고 오르며 보조 자일의 도움을 받아야 한다. 오른쪽으로 돌아가는 길이 있어 조금만 돌아서면 다시 쌍두봉 정상에 오를 수 있다.", + "MNTN_HG_VL" : "910", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 삼계리", + "MNTN_NM" : "쌍두봉" + }, + "longitude" : 129.00244050000001, + "latitude" : 35.663634700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전라북도 부안의 변산반도는 아름다운 해안선을 따라 수많은 절경이 이어지는데 이 일대가 국립공원으로 지정되어 있다. 변산은 바다를 끼고 도는 외변산과 남서부 산악지의 내변산으로 구분한다. 변산반도 국립공원의 내륙은 첩첩산중으로 이루어져 있다. 최고봉인 의상봉의 높이가 해발 509m에 불과하지만 400m급 준봉들이 겹겹이 이어진다. 내륙쪽 변산반도를 가리키는 내변산의 명소로는 최고봉인 의상봉(509m)을 비롯해 쌍선봉(459.1m), 옥녀봉, 관음봉(433m 일명 가인봉), 선인봉 등 기암봉들이 여럿 솟아 있고, 직소폭포, 분옥담, 선녀당, 가마소, 와룡소, 내소사, 개암사, 우금산성, 울금바위 등이 있다. 직소폭포 골짜기는 쌍선봉 자락에서 흘러내려 부안호로 흘러 내려간다.산에 얽힌 전설이 전해지는데, 이성계가 청년시절에 부안군 보안면 우반동 굴바위 옆 저수지 안쪽의 선계안(또는 성계골)에서 영험한 두 노인에게 각각 문(文)과 무(武)를 익혀 훌륭한 청년이 된 뒤 스승들과 헤어질 때가 되었다고 한다. 스승과 제자 모두 이를 서로 아쉬워하다가 선계안으로부터 북쪽으로 삼천보나 떨어진 이곳까지 왔고, 이성계가 두 스승에게 하직 인사를 하고 보니 두 스승은 사라지고 그 앞에 높은 봉우리 두 개만 우뚝 솟아 있었다고 한다.산중턱의 월명암에서 내려다보이는 안개 낀 아침 바다의 신비로움을 일컫는 월명무애와 직소폭포는 웅연조대, 소사모종, 채석범주, 지포신경, 개암고적, 서해낙조와 함께 변산팔경(邊山八景)으로 꼽힌다.", + "MNTN_HG_VL" : "459", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면", + "MNTN_NM" : "쌍선봉" + }, + "longitude" : 126.558978, + "latitude" : 35.643399299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평군 하면에 자리한 아기봉은 백두대간에서 갈라져 내려온 한북정맥이 운악산(936m)을 솟구쳐 웅장한 기세를 뽐내고 다시 내쳐 굴고개로 내려서기 직전 649m봉 어름에서 남쪽으로 살짝 앉혀놓은 봉우리다.이 아기봉은 운악산과 능선으로 바로 연결되어 정상에 나란히 봉우리가 솟아있다. 경기의 금강이라 부르는 일명 현등산의 운악산과 더불어 함께 산행을 하는 코스이기도 하다.운악산 정상에서 남능을 따라 5km 쯤 나간곳에 우뚝솟은 봉으로 현등산이 어머니의 산이라면 아기봉은 현등산에 안긴 아기에 비유되므로 아기봉으로 불리워왔다. 아기봉을 악귀봉이라고도 불리는데 이것은 잘못 전해진 이름이다.악귀봉(아기봉) 코스는 석장 위로 안부까지 가서 서남능선을 타고 정상을 거쳐 오른쪽 계곡으로 내려오는 코스인데, 암능 코스로 제법 시간이 걸리며 산행시 주의를 요한다.악귀봉의 모든 산악 관련 서류는 운악산과 일치하는 경우가 많아 운악산 자료를 살펴보면 자세한 정보를 알수 있다.", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면", + "MNTN_NM" : "아기봉" + }, + "longitude" : 127.32489889999999, + "latitude" : 37.878003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보령과 부여의 경계선에 있는 아미산은 호젓한 산행 코스가 자랑이지만 지금껏 알려지지 않은 산이다. 가을이면 산 전체가 불붙은 듯 단풍으로 가득한 곳, 예부터 산삼이 많이 나는 곳이며 부정한 사람이 출입하면 화를 입는다는 이야기가 전해져 오는 산이다. 높은 산은 아니지만 골이 깊고 산세가 자뭇 웅장하다. 만만히 보고 다가갔다 흠씬 비지땀을 흘려야 오를 수 있는 산이다.보령호가 담수를 시작하면서 산 끝자락이 잠겼고, 만산홍엽의 그림자가 비친 호수와 어울린 모습이 황홀경에 빠져들도록 아름답다. 미산면 용수리 동북쪽에 자리하고 있으며, 도화담에서부터 솟아오른 봉우리가 풍계리와 용수리에 걸쳐 있다. 북쪽은 부여군 외산면과 지경을 이룬다. 아미산에는 백제때 창건된 중대암이 있고 인근에는 영천이라는 약수가 있다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "충남 보령시 미산면, 부여군 외산면", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "아미산(402.4m)은 팔공산(1192m)에서 뻗은 팔공지맥의 끝자락에 있는 산이다. 높이는 낮지만 마치 설악산의 용아장성을 옮겨놓은 듯 아름다운 산이다. 팔공산 줄기는 시루봉을 지나 군위군 산성면 백학리를 지나며 끊어질 듯 야트막한 야산이 되었다가 조림산과 화산(華山middot;828m)이 만나는 갑령재에 이르러 다시 치솟는다. 화산을 넘으면서 탄력을 받은 줄기는 방가산(755.8m)을 지나 팔공지맥에서 가장 아름다운 절경을 만나게 되는데 바로 아미산이다. 여인의 아름다운 눈썹을 뜻하는 아미(蛾眉)에서 음을 빌려와 산이 높고 위엄이 있다는 뜻의 아미(峨嵋)로 했다.아미산은 높이로 말하는 산이 아니다. 산세가 수려하며 산이 작아 보여도 바위 형태가 만물상을 이룬 듯하다. 바위 틈 사이에서 자라ordf;게 뻗은 소나무 가지들은 분재 같은 모양으로 아름다움을 더해준다. 크게 다섯 개의 바위봉우리로 이루어졌는데, 그 모양들이 마치 촛대 같이 생겨ucirc;송 주왕산의 촛대바위를 연상케 한다. 뿐만 아니라 산의 모양은 다섯 개의 바위봉이 나란히 어깨를 맞댄 형국이고, 많은 병사들이 무기를 들고 마을을 지키는 듯한 모습이어서 예로부터 이곳은 전쟁의 피해가 거의 없었다고 한다.", + "MNTN_HG_VL" : "602", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 고로면", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "350", + "MNTN_LOCPLC_REGION_NM" : "충청남도 당진시", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "아미산은 홍천군 서석면에 자리한 해발 961미터의 산이다. 평창군 봉평면의 청량봉에서 한강기맥과 이별한 춘천지맥이 응봉산(1097m)을 눈앞에 둔 각근치에서 남서쪽으로 곁가지를 일으킨다. 이 산줄기는 무명봉(1009m)과 아미산, 고양산(675m)을 일으킨 후 홍천강으로 흘러드는 내촌천에 가라앉는다.우리나라에는 아미산이라 이름을 가진 산이 부산, 울산, 전남, 전북, 충남, 충북 등에 여럿 있으며 중국의 산동성에도 무협소설에 등장하는 같은 이름의 산이 있다. ‘아미’란 이름의 뜻은 우리가 흔히 생각하는 아미(蛾眉) 즉, 미인의 눈썹이 아니며 불교에서 아미타불(阿彌陀佛)의 약칭으로 말하는 아미도 아니다. 높을 아(峨)에 풍치가 아름다울 미(媚), 즉 ‘높고도 풍치가 아름다운 산’이 바로 홍천의 아미산이다. 아미산은 대중교통으로 접근하기에도 좋은 산이다. 서울에서 홍천, 홍천에서 서석으로 수시 운행하는 버스편을 이용하면 쉽게 다녀올 수 있는 산이다.아미산은 북으로는 가리산, 동으로는 계방산, 회령봉, 흥정산 줄기가 한눈에 들어오고 서쪽으로는 공작산을 조망할 수 있다. 아미산 끝자락에 있는 고양산은 사람들의 발길이 닿지 않은 곳으로 ª은 거리의 등산과 함께 깨끗한 내촌천에서 물놀이도 즐길 수 있다.", + "MNTN_HG_VL" : "961", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "아미산은 울주군 두서면 전읍리와 미호리에 걸쳐 있는 해발 601.5m의 산이다. 옛날 제정일치 시대의 군장을 천왕 또는 천군이라 하여 산의 수호신도 천왕이라 부르게 되었으며 그 수호신의 이름으로 산 이름을 부르게 되는 경우가 있다. 마찬가지로 두서면의 아미산은 노고신으로 말미암아 생긴 이름이다.", + "MNTN_HG_VL" : "402", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 두서면 전읍리, 미호리", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천마산의 연맥에 해당되는 아미산은 아미동 일대에 넓게 자리 잡고 있는 구릉성 산지로 아미동과 사하구(감천동)와 경계를 이룬다.산록이 완만하여 산정의 일부를 제외하면 도시화에 따른 주택지대로 변모하였다. 아미산이란 이름은 본래 이곳의 마을을 '아미골' 이라 부른데서 비롯되나 아미골의 정확한 어원은 알 수 없다. 속설에 의하면 아미골은 움막집이란 의미의 옛말인 애막이 바뀐 것으로 이를 한자식 峨眉로 표기한데서 비롯된다. 또, 이 산의 모습이 마치 미인의 아름다운 눈썹과 같다하여 아미산으로 표기된 것으로 전해지기도 한다. 아미산은 부산항 개항 이후 일본인들에 의해 설치된 공동묘지의 산으로도 잘 알려져 있다.아미산은 전부터 잘 알려져 있는 산이기는 하나 문헌에 기록된 바가 없는 작은 산이라서 한자로 어떻게 표기해야 할지몰라 峨媚山, 峨眉山 혹은 娥眉山, 娥媚山, 蛾眉山 등으로 혼기되어 왔는데, 요즈음은 峨嵋山으로 통일되어 사용되고있다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 서구 아미동, 사하구", + "MNTN_NM" : "아미산" + }, + "longitude" : 103.334737, + "latitude" : 29.516006999999991 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "너른 벌판 위를 달리던 한 줄기 바람이 갑작스럽게 숨을 몰아 쉬어야하는 곳, 우뚝 아차(蛾嵯)라고 이름 한 곳이 바로 아차산이다. 정상표고 200m되는 지점에서 시작하여 동남의 한강변 쪽으로 경사진 산허리의 윗 부분을 둘러싸고 있는 산성의 형태가 남아 있다.백제의 도읍이 한강 유역에 있을 때 우뚝 솟은 지형적 특성으로 인해 일찍부터 이 아차산에 흙을 깎고 다시 돌과 흙으로 쌓아 올려 산성을 축조함으로써 고구려의 남하를 막으려는 백제인의 노력이 있었다. 한강을 사이에 두고 맞은 편 남쪽에 있는 풍납동 토성과 함께 중요한 군사적 요지로서 백제의 운명을 좌우하던 곳이기도 하다.아단성(阿旦城), 아차성(蛾嵯城), 장하성, 광장성 등으로 불리우기도 하여 백제, 신라, 고구려가 한강을 중심으로 공방전을 장기간에 걸쳐 벌였던 것을 짐작할 수 있다.이 성의 흔적은 60년대까지만 해도 눈으로 알아 볼 수 있을 정도로 남아있었다. 아차산 분수령의 전부와 그 북쪽 기슭 면목동의 동쪽과 아차산의 서남쪽 기슭을 달리는 진맥의 분수령 및 그곳부터는 분명치 못하지만 모진동 밭에 이르는 사이에 이어져 있었던 길이 4km에 달하는 토성과 석성 자리는 신라가 쌓은 장한성으로 알려져 있다.1500여 년이라는 장구한 역사의 수레바퀴 속에서 여러 차례 그 운명을 달리해야 했던 아차산성은 아직도 그 자신의 운명을 나타내려는 듯 당시의 토기와 기와조각 등을 보여주고 있으며, 그 옛날 산성수비군의 역할을 다시 되새겨보려는 듯 많은 사람들이 오르는 시민공원이 되어 그 역사적 변신을 꾀하고 있다. (면적 103,375㎡, 1973.05.25지정 광장동 산 16-46, 구의동산 1-2)", + "MNTN_HG_VL" : "287", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 광진구", + "MNTN_NM" : "아차산" + }, + "longitude" : 127.1037627, + "latitude" : 37.571508700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 합천군 대병면에 자리하고 있는 악견산은 금성산, 허굴산과 더불어 합천의 삼산으로 불린다. 세 산은 합천호 부근에 옹기종기 모여 있다. 크고 작은 바위들이 들쭉날쭉 빚어내는 경관이 수려하고도 야무지다.악견산은 합천댐 설치로 더욱 돋보이게 되고 유명해졌다. 일반적으로 산의 정상은 암봉으로 되어 있거나 둥그스름한 봉우리로 되어 있는데 이 산의 정상은 집채만한 큰 바위들이 수없이 쌓이고 엉켜 정상부를 형성하고 있다. 이 산에서의 조망은 서쪽 능선따라 오르면서 뒤돌아 본 합천댐의 풍경이 매우 아름답다.악견산에는 임진왜란 때 왜적과 격전을 벌였던 악견산성이 남아있다. 이곳은 임진왜란 때 민중의 영웅으로 이름을 떨친 의병장 곽재우 장군의 전설이 담겨 있어 의구한 역사도 깃들어 있는 곳이다. 악견산성(경남 기념물 제218호)은 1439년(세종 21)에 축조된 테뫼식 산성으로 임진왜란 때(1594년) 유성룡의 지시를 받아 성주 목사로 있던 곽재우가 보수공사를 했다고 한다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", + "MNTN_NM" : "악견산" + }, + "longitude" : 128.0494783, + "latitude" : 35.531882899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "악휘봉은 충북 괴산군 연풍면과 칠성면의 경계를 이루는 산이다. 악휘봉의 정상 부근은 온통 기암괴석과 노송군락으로 어우러져 있어 보는 이로 하여금 자연의 신비감에 절로 고개를 숙이며 감탄을 자아내게 한다.천혜의 볼거리 외에도 악휘봉 산자락에는 역사의 흔적을 찾아볼 수 있는 곳이 많은데, 우선 등산로 초입 장바위 마을에 있는 유서깊은 반계정이 그것이다. 2층 누각으로 되어있는 반계정은 조선조 영조 1년(1725년) 좌의정을 거쳐 영의정을 지낸 장암 정호가 노후에 후손을 가르치며 여생을 보낸 곳이다.장바위라는 마을 이름은 정호의 호인 장암에서 유래되었다고 전해지며, 장바위 마을 주민들은 반계정을 장바위 정씨네 정자라 부르기도 한다. 3, 4봉 사이에 우뚝 솟아 산행기점이 되는 입석마을의 이름을 낳게 한 선바위가 정상 아래쪽에 당당히 서 있다.", + "MNTN_HG_VL" : "845", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면 적석리", + "MNTN_NM" : "악휘봉" + }, + "longitude" : 128.006, + "latitude" : 36.722000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", + "MNTN_NM" : "안락산" + }, + "longitude" : 126.88249999999999, + "latitude" : 36.694722200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "안마산" + }, + "longitude" : 127.7494444, + "latitude" : 37.842222199999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "완주군 동북부에 있는 요지인 고산은 고려시대에는 봉성형이었으며 조선시대에는 고산군이었다. 금남정맥에서 뻗쳐와 원등산 위봉산 되실봉을 거쳐 북쪽으로 달려가 안수산을 솟구친다. 북쪽으로 나아가던 500m대의 산세가 고산을 눈앞에 두고 갑자기 멈추며 산줄기는 동쪽으로 틀어진다.북쪽으로의 진행을 멈춘 산줄기는 자연스럽게 높은 턱을 이루고 그 끝에 크나큰 암봉을 빚어놓았다. 특히 이 암봉(일명 달걀봉)은 고산천이 휘돌아 흐르는 고산마을을 굽어보고 있다. 고산에서는 물론 봉동 삼레 일대 들녘에서도 눈에 잘 띄는 특이한 산세다. 달걀봉 아래 제법 널찍한 터에 안수암이 있고 수 백년 된 느티나무가 그 연륜을 자랑하고 있다. 느티나무로 미루어 볼 때 적어도 수 백년 전부터 있었으리라 믿어지는 안수암은 모악산 금산사의 말사로 지금은 젊은 범운스님이 홀로 다스리고 있다.안수산을 고산 사람들은 고산의 지킴이로 믿고 있다. 고산천을 중심으로 펼쳐진 고산 일대의 지형이 풍수지리적으로 '지네'의 형국이라 한다. 지내의 독기를 누릴 수 있는 것은 지네와 상극인 '닭'으로 알려져 있는데이 안수산이 닭벼슬을 닮아 일명 '계봉산'으로 불린다. 또 멀찍이서 바라보면 거대한 바위로 이뤄진 주봉이 듬직한 자태로 서 있어 오르기 전부터 보는 이의 마음이 한결 뿌듯해진다.안수산 정상에서 되실봉 정상까지 약 2시간 30분 소요되는 암릉코스가 산행의 재미를 더해준다. 산행기점은 주로 청동마을이나 성재동마을로 잡는 것이 일반적인데, 안수산 서쪽 계곡 저수지로 하산하거나 안수산에서 되실봉을 거쳐 오성리로 하산할 수 있다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", + "MNTN_NM" : "안수산" + }, + "longitude" : -118.29269170000001, + "latitude" : 34.0620324 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", + "MNTN_NM" : "안양산" + }, + "longitude" : 127.02019780000001, + "latitude" : 35.102527199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "안양산은 무등산을 잇는 가교로서 무등산, 만연산과 어우르며 화순의 알프스로 불린다. 호남정맥 종주대에 의해 알려지기 시작하면서 무등산에서 안양산까지 이어지는 능선길을 찾는 사람들이 늘고 있다. 안양산자연휴양림에서 오르는 길은 급경사 길이며 들국화마을에서 오르는 길은 목계단과 데크계단이 설치되어 있으며 약 1시간 정도 걸린다.능선부에 이르면 넓은 철쭉밭이 펼쳐져 있고 산세가 모나지 않고 둥그스름해 친근한 멋이 감도는 안양산은 5월 초에 오르면 널찍한 평지를 이룬 정상의 북쪽 완사면에 분홍 융단으로 펼쳐진 철쭉 꽃 밭이 감탄사가 절로 나오게 한다.‘안양산 키높이 철쭉놀이’라는 명칭으로 2005년부터 5월 초순이 되면 안양산 철쭉제가 열리고 있으며 그 기간에 산오름을 하면 어른 키보다 훨씬 큰 연분홍 철쭉꽃밭의 황홀함을 느낄 수 있다. 가을이면 억새 사이에 핀 야생화도 백마능선을 아름답게 장식하고 있어 봄, 가을에 서로 색다른 안양산의 풍모를 만끽할 수 있다.", + "MNTN_HG_VL" : "853", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 이서면", + "MNTN_NM" : "안양산" + }, + "longitude" : 127.02019780000001, + "latitude" : 35.102527199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "안전산 산행들머리는 배태고개 동편으로 나 있는 산길에서 시작된다.15분 후 558봉 산림초소에 올라서게 되는 데 그 아래 영포천 밑으로 탁트인 전망은 일품이고, 멀리 영포천이 반짝거리며 그 물은 원동천으로 하여 낙동강으로 흘러간다.몇 차례 봉우리를 오르내리면 안전산 정상에 오르게 된다. 정상에는 조그마한 표지석 하나가 정상임을 알려 주고 있으나, 주위 경관은 전혀 볼 수 없다. 이곳에서 15분 후에는 탁트인 시야가 전개되는데 삼원축산 농장이나. 초원은 영화 사운드 오브 뮤직에서 보았던 알프스 초원지대와 비슷하다.", + "MNTN_HG_VL" : "665", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", + "MNTN_NM" : "안전산" + }, + "longitude" : 127.035675, + "latitude" : 37.608305999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "148", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 부평구", + "MNTN_NM" : "앞산" + }, + "longitude" : 128.57638890000001, + "latitude" : 35.816944399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "583", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "앞산(앞산공원)" + }, + "longitude" : 128.57638890000001, + "latitude" : 35.816944399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "애기암봉은 장성봉에 딸려있고 희양산을 바라보며 서 있는데 1\/5,000 지도에는 높이가 746.6m로 표시되어 있다. 장성봉 정상에 오르기 바로 전에 연결된다.전형적인 육산(陸山)이며 갖가지 괴석과 노송, 활엽수들이 우거지며 능선길은 암릉이다. 불란치재에서 코끼리바위를 거쳐 수정광산터를 지나면 정상이 나온다. 옻나무골에서 오르는 길은 잣밭재를 경유 오를 수도 있고 정상부분으로 바로 오르는 산길도 있다.애기암봉에서 사방을 둘러보는 조망은 극치에 이른다고 할 수 있다. 장성봉서 올망졸망 애기암봉 타는 재미 “쏠쏠” 하다. 특히 애기암봉에는 큰 바위조망대가 있어 가장 가까이서 희양산과 구왕봉, 대야산, 둔덕산, 촛대봉, 곰넘이봉을 비롯한 주변의 산들이 건너다 보인다.", + "MNTN_HG_VL" : "731", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍 완장리", + "MNTN_NM" : "애기암봉" + }, + "longitude" : 127.9484282, + "latitude" : 36.706101400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 해룡면", + "MNTN_NM" : "앵무산" + }, + "longitude" : 126.92749999999999, + "latitude" : 37.7575 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "경상북도 거제시", + "MNTN_NM" : "앵산" + }, + "longitude" : 128.60173459999999, + "latitude" : 34.947230300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "아름다운 꾀꼬리가 알을 품고 있는 형상의 산세를 가진 앵자봉은 중부고속도로와 영동고속도로가 교차하는 곳에 산군을 이루고 있다. 앵자봉은 천주교인들에게 널리 알려진 산인데, 우리 나라 최초로 천주교가 전파되기 시작했고, 지금은 앵자봉 일원이 천주교성역 순례길로 지정이 되었기 때문이다.앵자봉은 그리 높지는 않으므로 산행에 특별한 어려움은 없지만, 초기에 천주교 교인들이 숨어 살았을 만큼 깊고 신비로운 산이므로 훼손된 등산로에 익숙한 사람들에게는 신선한 느낌을 줄 수 있다.북쪽만 수직암벽으로 이루어진 앵자봉 정상에 오르면 답답하던 가슴과 마음에 일시에 트이고 주변 경치가 시원하게 펼쳐진다. 산록은 산의 높이에 비해 숲이 울창하여 이산에 본격적인 단풍이 들면 볼만할 듯한 느낌이 든다.또한 억새지대와 진달래지대 등이 있고 특히 도토리가 많기로 유명하다.", + "MNTN_HG_VL" : "667", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면, 실촌면, 여주군 산북면, 양평군 강하면", + "MNTN_NM" : "앵자봉" + }, + "longitude" : 127.3977778, + "latitude" : 37.415277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구룡령은 옛부터 큰 고개인 원구룡령의 남동쪽 1㎞지점에 위치해 있다. 옛 구룡령은 현고개에서 서북쪽의 1100고지를 넘어가야 있는 것이다. 약수산이란 이름은 흔히 명개리 약수라 불리는 이 산 남쪽 골짜기의 약수에서 유래한 것이라고 한다.약수산은 백두대간이 오대산에 이르기 직전 산세를 일으키고 있는 산 들 중의 하나다. 구룡령 너머 서쪽엔 갈전곡봉이, 동남으로는 응복산(1360m), 만월봉(1279m)이 한 어깨로 나란히 솟아있다. 그래서 이 산들을 연결해서 종주하는 산악인들도 여럿 있다. 홍천군 내면 목맥동 일대는 수림이 울창하고 각종 희귀 동식물과 열대어 등 어류가 서식하고 있어 자연훼손을 최소화하는 산행을 해야 겠다.약수산 북쪽으로 이어진 암산 동북으로 깊고 길게 패여진 미천골은 아직 사람들이 많이 드나들지 않아 옛날 그대로의 숲과 자연경치를 간직 한 곳이다. 양옆으로 늘어선 나무들이 시원스럽고, 계곡 안의 물속에는 물고기들이 많다.울창한 숲, 맑은 물, 기암괴석, 야생동식물, 약수터, 신라고적, 토종꿀, 각종 산림부산물 등 휴양원이 풍부하고, 또한 이곳의 미천골 자연휴양림은 5,652천㎡의 시설 구역내에 평균수명 50년 이상의 활엽수 천연림으로 삼림욕을 즐길 수 있다. 미천골 초입에는 신라 법흥왕 때 창건했다가 고려 말에 폐사되었다는 선림원터가 있다. 석등, 3층석탑, 홍각선사탑비, 부도 등의 보물급 문화재가 남아 있다.공지(空地)로 된 정상에서는 남쪽의 백두대간길과 소황병산 및 오대산 구간이 잘 바라보인다.", + "MNTN_HG_VL" : "1306", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "약수산" + }, + "longitude" : 128.5261151, + "latitude" : 37.882913799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "양각산(兩角山)의 옛 이름은 금광산(金光山)이다, 북쪽 수도산 신선봉을 기점으로 남진하는 줄기의 4km 지점에 있다. 정상을 중심으로 동쪽에는 거창의 두메인 가북면 중촌리 수재 심방소가 자리하고 서쪽으로 웅양댐 위쪽에 자리한 금광(金光)마을을 품고 있다. 양각산의 양각(兩角)은 두 개의 소뿔을 의미한다. 따라서 소뿔산이라고 불러도 무방하다. 화강암지반을 갖고 높이 솟은 두 봉우리는 동서쪽으로 벼랑을 수반하고 소뿔형상의 암·수 자웅형태로 솟은 두 봉우리 가운데 복쪽 봉우리가 정상이다. 북봉의 정점이 되는 곳은 여러 형태의 바위들이 모여 있다. 그곳 중심 돌출된 바위 모양새는 남성을 상징하는 심벌처럼 생겼다. 남쪽에는 거북 모양새의 기이한 바위가 있는데 거북바위 뒷모습이 마치 여인 궁둥이처럼 생겼다. 거북바위 가까운 곳에는 바위구멍 한 개가 패여 있다. 언제 누가 양각산 정상 암반 위에 바위구멍을 파 놓았는지 알 수 없어도 성신신앙에서 비롯된 소산임을 알 수 있다. 바위구멍을 실측하여 보았더니 둘레 63cm에 길이가 15cm 된다. 이 바위구멍을 천정(天井)이라 부르는데 그 바위 구멍 속에 하늘물이 고여 있다. 북봉 주변에는 물고기 거북형상 등을 지닌 바위들이 많고 남봉에는 제단을 쌓았던 돌들로 여겨지는 막돌들을 이용하여 쌓아놓은 키 작은 돌무지탑(케언)들이 놓여 있다. 이 산의 특징은 양각이 소뿔의 의미를 담고 소와 관계된 것처럼 산이 갖는 재, 골짜기, 마을 이름들이 모두 소와 인연하여 이름이 지어졌다는 점이다. 양각산 서쪽 거창에서 김천시 대덕면으로 넘는 고개를 소머리고개 곧 우두령(牛頭嶺)이고 우두령 오르는 길에 놓은 마을은 소구시를 뜻하는 구수(口水)마을이고, 희대미산 아래 안긴 랑 우랑동(牛郞洞)이 소불알을 뜻한 마을이니 모두 소와 인연한 이름들이다. 소는 범어(梵語)로 가야(Gaya)를 뜻한다. 예날 이곳은 가야국에 속한 곳이어서 여기 ‘소’와 무관하지 만은 않다. 또한 수도산과 이어져 동쪽 가야산으로 드는 준령으로서 가야와 같은 맥락임을 알 수 있다. 양각산 예 이름인 금광산(金光山)은 고산자(古山子) 대동여지도 및「거창고읍지」에서 찾아 볼 수 있으나 금광(金光)이란 이름은 현재 양각산이 품고 있는 산아래 금광(金光)마을 이름으로 남아 있다. 금광(金光)이란 부처님을 뜻한다. 옛날 양각산 아래 금광사라 하는 절이 있었으며「거창향지」에서는 마을 근처 산에 금이 많이 묻혀 있었다는 전설에 의해 금광이라 한다고 하였다. 또 산의 반석에 항상 물이 번져 햇볕에 번쩍번쩍 금빛이 난다하여 이름 되었다고 한다. 양각산은 수도산에 인접하여 골이 깊고 옛날에는 산삼이 자생하였다고 전하며 현재에는 천마, 주치 등 한약재가 많이 자생한다. 양각산 아래 2km거리에 희대미산이 솟아 있으며 위족으로 수도산 신선봉과 연결 짓고 서쪽 거말흘산(巨末屹山, 902m)사이 우두령이 놓여 옛날에는 전략적 거점지로서 우두령은 임진왜란 때 김면(金沔)장군 지휘 아래 우척현 싸움이 있었던 곳으로 유명하다. 양각산이 품고 있는 웅양댐물은 어인동, 인삼동, 동북쪽 골짜기의 발원이다. 출처 : 「거창의 명산」 거창문화원(정태주·안수상 편저)", + "MNTN_HG_VL" : "1158", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 웅양면 산포리", + "MNTN_NM" : "양각산" + }, + "longitude" : 126.65746040000001, + "latitude" : 36.253848400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해발고도 1000미터를 훌½ 넘기며 우뚝 솟은 양각산은 경남 거acirc;군 웅양면과 가북면의 경계를 이룬다. 하얗게 반brvbar;이는 화강암릉과 푸르디 푸른 수풀이 조화를 이루며 빼어난 경치를 선사하는 이 산은 아기자기한 야생화가 곳곳에 피어 산행의 즐거움을 더한다.두 개의 소뿔을 닮았다고 하여 이름붙인 양각산은 그래서 재나 골yen;기, 마을이름 들이 소와 인연하여 만들어진 것들이 많다. 김otilde;시로 넘는 우두령을 비롯해 소의 물먹는 그릇을 뜻하는 구수마을, 생식기를 일컫는 우랑마을 등이 그렇다.양각산의 옛 이름은 금광산(金光山)인데 대동여지도와 거acirc;고읍지에서 그 흔적을 발견할 수 있다. 이를 뒷받침하듯 흰대미산과 양각산의 서쪽 용암저수지 일대에 금광마을이 위치해 있다. 금광이라는 이름이 붙여진 연유에 대해 금이 많이 나서였다고도 하고, 암릉이 빛에 반사되어 반brvbar;거리며 금빛이 난다고 하여 붙여졌다고도 한다.거acirc; 내에서도 오지에 속한 탓에 산행 코스내에 휴대폰 통화가 안되는 곳이 많지만, 흰대미산~양각산~수도산으로 이어진 능선은 오지답게 빼어난 수림을 자랑한다.", + "MNTN_HG_VL" : "467", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 웅천읍, 미산면", + "MNTN_NM" : "양각산" + }, + "longitude" : 126.65746040000001, + "latitude" : 36.253848400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "412", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "양각산" + }, + "longitude" : 126.65746040000001, + "latitude" : 36.253848400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "양성산은 문의면의 진산이다. 높지는 않으나 여러 가지 역사유적과 전설을 간직하고 있으며 문헌에 기록되어 있는 산이다. 산자락에 규모 큰 문화재단지가 있고 맞은편에는 대통령 별장이었던 청남대도 있다. 산 아래 푸른 대청호가 펼쳐져 있어 조망 또한 좋다.지도상 양성산으로 표기된 주봉은 297미터로 문의면사무소가 있는 미천리 마을 뒷봉우리다. 상봉은 378미터로 산행 들머리인 불당골로 오르는 가장 높은 봉우리다. 따라서 양성산은 주봉과 상봉으로 나누어 부를 필요가 있다. 산행은 상봉을 중심으로 이루어진다.양성산은 백제시대 일보산, 신라시대에는 연산이라 불렸다. 그 뒤에는 양승산, 양성산 등으로 불리며 지금에 이르렀다.삼국사기에 의하면 양성산 안의 일모산성은 474년에 쌓은 것으로 기록되어 있다. 신라시대 화랑 출신의 화은대사가 양성산을 보고 ‘저 산은 중이 바리를 들고 시주를 구하는 형세’라 했다. 중을 양성하기에 흠잡을 데가 없는 땅이라 감탄하고 승병 300명을 제자로 삼아 불경과 무예를 익히도록 했다.", + "MNTN_HG_VL" : "301", + "MNTN_LOCPLC_REGION_NM" : "충북 청원군 문의면", + "MNTN_NM" : "양성산" + }, + "longitude" : 127.48339439999999, + "latitude" : 36.512921899999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "151", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "양을산" + }, + "longitude" : 126.40777780000001, + "latitude" : 34.812500000000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 여주군 금사면과 양평군 강상면의 경계에 위치한 양자산은 앵자봉과 나란한 육산으로 부근에 이웃한 산중 가장 높은 산이다. 양평군 서남쪽 남한강 건너 강상면, 강하면과 여주군 산북면의 경계 정점을 이루는 양자산은 산세가 부드럽고 수도권에 근접해 있어 오래전부터 주말산행 코스로 잘 알려진 산이다.산행은 성덕리쪽에서 오르는 것이 일반적이나 코스가 짧다. 최근 양평군에서 개척한 능선종주 코스가 있는데 양자산 정상에서 북쪽으로 뻗어나간 10km의 장쾌한 능선길이다. 이 코스는 남한강변에서부터 올라가는데 4시간, 내려오는데 3시간 30분이 걸린다. 따라서 오를 때 보다는 남한강을 조망하며 내려가는 코스가 산행의 묘미를 더 즐길수 있다.능선 초입에는 소나무가 많고 올라갈수록 싸리나무와 참나무로 덮혀 있다. 가랑잎이 쌓일대로 쌓인 깨끗한 오솔길이 심산에 들어선 느낌을 준다. 정상일때는 한키가 넘는 싸리나무와 억새가 가득하여 온화한 분위기를 자아내고 있다.", + "MNTN_HG_VL" : "712", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 산북면, 양평군 강상면", + "MNTN_NM" : "양자산" + }, + "longitude" : 127.4262073, + "latitude" : 37.4377809 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "789", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", + "MNTN_NM" : "어답산" + }, + "longitude" : 128.0685852, + "latitude" : 37.584108200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어답산(御踏山)은 한강기맥이 북쪽으로 병풍을 이루고 있고, 태기산이 동쪽으로 손에 잡힐 듯 펼쳐진 곳에 횡성댐을 품고 있는 산이다. 진한(辰韓)의 마지막 왕, 태기왕(泰岐王)과 신라 박혁거세의 전설을 품고 있는 유서 깊은 산이기도 하다. 서기 937년 경, 삼한 중에서 가장 부강했던 진한 태기왕은 신라에 대패한 후 약간의 근위병을 데리고 덕고산으로 들어가던 중 이 산에 올랐다. 그래서 왕이 올랐다는 뜻으로 '어답산(御踏山)'이라는 이름이 붙었다. 설욕을 꿈꾸던 태기왕은 덕고산(지금의 태기산)에 성을 쌓고 화전을 개간, 부하를 훈련시켰다. 그러나 신라에 탐지되어 박혁거세가 지휘하는 신라군의 원정으로 끝내 한을 풀지 못하고 덕고산의 넋이 되었다. 원정군을 지휘하던 박혁거세가 이산에 올랐다고 해서 '어답산'이라 불린다는 설도 있다. 한 때는 '한국의 오지 다섯'에 꼽히던 병지방 계곡에 포장도로가 놓이고, 삼거리에 온천이 개발되고 삼거현(三巨峴)에서 갑천까지 도로가 확포장 되어 숨겨졌던 어답산이 널리 알려지게 됐다.", + "MNTN_HG_VL" : "789", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", + "MNTN_NM" : "어답산" + }, + "longitude" : 128.0685852, + "latitude" : 37.584108200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어답산은 삼거리저수지 동북쪽으로 병풍을 두른 듯 솟아 있으며 선바위, 어답산 장송, 약물탕 등의 볼거리와 정상에서의 끝간 데 없이 펼쳐지는 시야 아래로 잔잔한 횡성호와 삼거리저수지가 누워있는 경관을 감상할 수 있고, 어답산 정상에서 북쪽 200m 삼각점으로 향하는 곳에 낙수대에서는 정상과는 다르게 멋진 경관을 감상할 수 있다.", + "MNTN_HG_VL" : "789", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", + "MNTN_NM" : "어답산" + }, + "longitude" : 128.0685852, + "latitude" : 37.584108200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어등산은 광산구의 중심이 되는 송정의 진산으로 한말 때 의병과 왜병이 자주 싸웠던 전쟁터로 그 이름이 널리 알려져 있다.물고기가 비늘을 세우고 올라갔다는 이야기가 전해져 내려오는 어등산 자락에는 양씨삼강문, 광산김씨효열문, 선암사지 삼층석탑 등의 명소가 자리하고 있다.또한 이곳 어등산과 황룡강이 맞닿는 곳에 위치했던 선암장터는 옛날 어등산과 용진산을 근거로 활동했던 항일의병들이 이 시장을 통해 의류, 양고 등 군수물자를 공급 받았다고 전해진다.어등산 남쪽 골짜기 깊숙한 곳에 위치한 절골마을에는 연화약수라는 석간수가 있어 위장병과 성인병에 효험이 뛰어나다고 알려져 있다.남서 방향으로 뻗은 능선은 황룡강을 사이에 두고 복룡산과 마주보고 있으며 송산유원지로 내려서는 언덕에 패러글라이딩 활공장이 있어 이를 즐기려는 사람들의 발길이 끊이질 않는다.", + "MNTN_HG_VL" : "290", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 광산구 산정동ㆍ박호동ㆍ서봉동", + "MNTN_NM" : "어등산" + }, + "longitude" : 126.7431679, + "latitude" : 35.205953800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어래산이 있는 단양군 영춘면 의풍리는 남한강의 옥동천 지류인 남대천 상류에 자리해 있으며 `정감록'을 믿고 찾아 들어온 조상들의 후예들이 터전으로 한때 외진곳을 전전하는 도박꾼들의 집합장소로 악명 높았던 곳이다.분지를 이룬 의풍리를 두고 동쪽에는 어래산이, 서쪽으로는 형제봉이 솟아 있어 남쪽에서 흘러내려온 남대천이 북쪽의 옥동천으로 빠지고 있다. 그래서 물이 흘러나가는 북쪽을 제외하고는 모두 산으로 둘러싸여 있어 외지에서 이곳으로 들어서려면 고개를 넘어야 한다. 때문에 일단 어래산 산행에 앞서 마을 진입 자체가 문제인데다 산행코스 역시 만만치 않다.이처럼 접근이 어렵다는 것은 사람들의 손때를 타지 않았다는 반증이다. 산 곳곳에 혼을 빼앗길 만큼 청정한 계곡이 흐르고 광활한 낙엽송 조림지대가 있어 수월치 않은 산행의 피로를 씻어 줄 것이다.", + "MNTN_HG_VL" : "1064", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "어래산" + }, + "longitude" : 129.1800523, + "latitude" : 36.028150199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "어룡산은 경북 8경인 진남교반을 사이에 두고 오정산(805m)과 마주보고 있는 산이다. 오정산 쪽의 고모산성과 함께 이 산의 고부산성이 옛 길인 `토끼비리'를 지키고 있다.영강가에 솟은 미봉 어룡산은 작은 것이 아름답다는 것을 깨닫게 하는 산이다. 문경읍을 거쳐 20분 정도 달리면 강변을 따라 병풍을 둘러친 듯 기암괴석이 보이는 곳이 있는데 여기가 바로 유명한 경북팔경 중의 제1경으로 일컫는 진남교반이다. 경북 도민이 제 1경으로 꼽을 만큼 절경지인 영강 진남교 옆에 솟아있는 어룡산은 산속으로 들어서면 넋을 잃기 마련이다.울창한 숲과 영강과 어우러진 산세가 절경이기때문이다.이 진남교반을 끼고있는 어룡산은 많은 전설과 얘기가 전해오고 있으며, 고모산성과 돌고개, 성황당, 그리고 영남대로의 옛 모습을 그대로 잘 간직하고 있는 관갑천(토천,토끼비리)이 있고 진남유원지와 휴게소에는 지나는 사람들의 발길이 끊이질 않는다.작은 암봉이 있는 정상에 서면 보면 주흘산과 백화산이 눈앞에 있으며 멀리 산군들이 첩첩이 펼쳐 보인다. 어룡산은 주변의 풍광이 수려하고 볼거리와 즐길거리가 많으며 아래 영강에는 여름철 강수욕과 피서지로 이름나 있는 곳이다. 문경읍에는 보양천인 문경온천이 있다. 봄, 여름 산행지로 인기가 높은 곳이다. 또 황티기국, 부곡숫굴, 부곡암굴 등 동굴이 산 곳곳에 산재해 있다.", + "MNTN_HG_VL" : "617", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면", + "MNTN_NM" : "어룡산" + }, + "longitude" : 128.1147469, + "latitude" : 36.6442786 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "어림산" + }, + "longitude" : 129.16408229999999, + "latitude" : 35.8439938 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평군과 양평군의 경계를 이루고 있는 어비산은 유명산 계곡을 사이에 두고 유명산의 동쪽에 솟아 있는 산이다. 어비산이란 이름은 옛부터 홍수 때 물고기가 산을 뛰어 넘는다고 하여 붙여진 이름이라 하는데, 주민들은 건너편의 유명산과 더불어 설악면과 옥천면을 경계한 산이라하여 대부산이라고도 부른다 한다.용문산에서 서쪽으로 뻗어내린 능선이 어비산을 이루고, 어비산에서 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이룬 계곡이 어비계곡이다. 이 어비계곡 또한 유명계곡에 못지 않을 정도로 아름다운 계곡이다. 큰 바위와 이따금 나타는 청정한 푸른소는 어비계곡의 자랑거리라고 할 수 있다. 계곡까지 급사면을 이룬 산록은 울창한 숲으로 뒤덮이고 숲아래 바위들은 푸른이끼옷을 입고 있고 그 아래로 흐르는 계류는 때로는 비취빛으로 바뀐다.길을 버리고 계곡을 따라 내려가는 맛이 또한 시원하다. 그러나 유명계곡처럼 완연한 협곡을 이룬 것은 아니고 길이도 유명계곡 보다는 짧은 편이어서 아쉽기는 하지만 경기도내의 아름다운 계곡중의 하나임은 분명하다. 산행은 유명산 입구인 가일리에서 오르는 코스와 대일마을에서 시작하는 방법이 있다.", + "MNTN_HG_VL" : "726", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "어비산" + }, + "longitude" : 127.5186384, + "latitude" : 37.589764000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "엄광산은 높이 503.9m로 부산광역시진구에서 제법 높은 산에 속하며, 동남으로 구봉산에 이어져 있는 산이다. 이 산은 고원견산이라 불리기도 하는데 이 명칭은\"\"산이 높아 멀리까지 볼 수 있다.\"\"는 뜻으로 일제시대부터 불려진 이름이다. 엄광산은 얼마 전까지 고원견산으로 불리던 산인데\"\"부산광역시을 가꾸는 모임\"\"이 지난 95년 4월에 엄광산(嚴光山)이라는 이름을 찾아주고 정상표지석을 세웠다. 이 산의 정상조망 역시 뛰어나다. 동래부지 산천조에 보면 엄광산의 산봉이라는 기록으로 보아 엄광산으로 통해졌던 것이라 보아진다.이 산 정상에는 부산광역시 전체가 한눈에 들어온다. 동구, 서구, 사하구, 북구, 해운대구 일부도 한눈에 들어와 부산광역시의 숨소리가 그대로 느끼어진다. 안산암질의 암석으로 구성된 엄광산(고원견산)은 산정이 대체로 평탄하며, 산 정 부근에는 잔 자갈들로 된 애추가 발달한다. 산록은 비교적 가파른 편이다. 금정산맥의 말단부에 해당되며, 남서쪽으로 구덕산,나몽쪽으 로는 구봉산으로 연결된다. 엄광산은 부산광역시만의 전망이 좋기로 이름 나 있고 산록에는 산림이 울창하여 자연공원으로서 부산광역시민의 사랑을 받고 있다.", + "MNTN_HG_VL" : "504", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 서구 동대신동, 부산광역시 진구 개금동", + "MNTN_NM" : "엄광산(고원견산)" + }, + "longitude" : 129.02056450000001, + "latitude" : 35.137197399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "궐리사 부터 물향기 수목원을 거쳐 지곳동과 가장동까지 노선이이어진다. 고도가 낮으며 지세도 험하지 않다.", + "MNTN_HG_VL" : "86", + "MNTN_LOCPLC_REGION_NM" : "경기도 오산시 신장동", + "MNTN_NM" : "여계산" + }, + "longitude" : 127.0386111, + "latitude" : 37.173611100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "312", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 대구면 사당리", + "MNTN_NM" : "여계산" + }, + "longitude" : 127.0386111, + "latitude" : 37.173611100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진도읍에서 임회면 용호마을에 이르면 단정한 모습의 선녀를 닮은 산이 보인다. 여귀산은 마치 단정하게 차려입은 선녀가 가야금을 타는 형상이라 하여 풍수지리가들은 옥녀탄금형의 산이라고 한다. 여기서 옥녀는 가야금을 타는 선녀를 지칭하는데, 선녀는 곧 귀한 여자이므로 산 이름이 여귀산이 된 걸로 추정된다.여귀산은 두 얼굴을 가진 산이다. 정상은 제법 오르기가 험난한 바위지대로 이뤄진 반면 정상을 중심으로 좌우로 흘러내린 지능선들은 부드러운 산세를 이루고 있기 때문이다. 밖에서 바라본 여귀산은 어느 방향이든 쉽게 오를 수 있을 것으로 보이지만 막상 산에 들어서면 수림이 빽빽해 기존 등산로를 벗어나서는 산행이 어렵다.그러나 일단 주능선이나 정상에 오르면 남서쪽으로 시원하게 펼쳐진 다도해국립공원을 비롯해 바다 풍경이 황홀하게 펼쳐진다. 특히 바다를 주홍빛으로 물들이는 일출과 낙조가 일품이다.", + "MNTN_HG_VL" : "457", + "MNTN_LOCPLC_REGION_NM" : "전남 진도군", + "MNTN_NM" : "여귀산" + }, + "longitude" : 126.2297222, + "latitude" : 34.390555599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "귀한 여자란 뜻을 가진 여귀산은 북동쪽의 첨찰산과 직선거리로 약 12.5km거리를 두고 능선이 이어져 있으며, 등산로에 아기자기한 바위들이 늘어서 있어 약간의 스릴과 긴장감을 느끼게 한다.산명에 걸맞게 자태가 매우 예쁘고 아름다운 산이기도 하다. 주능선은 동서로 뻗어 있는데 319봉을 머리로 하고 370봉을 어깨, 작은여귀봉과 큰여귀봉은 풍만한 가슴으로, 국립남도국악원 뒤 안부는 허리로, 송월과 중만쪽에 다리를 뻗고 누워 있는 아름다운 여인같기도 한 산이다. 이 능선에는 솔밭지대,진달래지대,바위지대,억새지대,대밭지대 등으로 다양하게 이어나가며 시종 남해를 바라보면서 걸을 수 있는 능선길이 매우 낭만적이다. 정상에 오르면 사방은 남해와 황해의 망망대해로 수평선을 이루고 다도해 해상국립공원의 수많은 섬들이 별빛같이 반짝인다.", + "MNTN_HG_VL" : "457", + "MNTN_LOCPLC_REGION_NM" : "전라남도 진도군 임회면", + "MNTN_NM" : "여귀산" + }, + "longitude" : 126.2297222, + "latitude" : 34.390555599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여분산은 특징이 없는 그저 평범한 산이다. 그러나 정상에서의 조망은 사방이 툭트여서 막힘없이 아주 좋다. 남으로 호남정맥의 용추봉(龍秋峰)과 무등산, 동으로 지리산의 연봉들이 아스라히 마루금을 이룬다. 서로는 용추봉과 세자봉(世子峰)이 눈앞에 다가선다.때로 조용한 길을 걸으면서 주위의 생명들과 동화될 때 느껴지는 기쁨이 좋은 사람들과 만날 때의 그것보다 더 클 경우가 있다. 구림면에 위치한 여분산은 이런 기분을 최고조로 경험할 수 있게 해준다. 인적이 드물어 길이 희미한 곳도 간간이 있는 이 산은 떨어져 쌓였다가 점점 썩어가며 제 나무의 거름이 되는 잎사귀들과 그 사이를 자유롭게 오가는 산짐승들을 보며 오르는 산행을 통해 침착하고 한결 순해진 마음을 갖게 한다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 구림면", + "MNTN_NM" : "여분산" + }, + "longitude" : 127.0565735, + "latitude" : 35.483787999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여우봉은 명성산 남쪽에 위치한 620m의 독립봉으로서 변화 있는 암능코스를 자랑한다. 명성산 남쪽 산록에는 여우봉과 망우봉 등으로 둘러싸여 있는 산정호수가 있는데 물이 맑고 주변 경치가 훌륭하여 관광 명소가 되고 있다.남북으로 이어지는 능선에는 암봉과 절벽, 초원 등이 다양하게 전개되어 말잔등 같이 부드러운 곡선을 이루면서 흘러내리고 주변에는 삼부연 폭포등 크고 작은 폭포들이 있으며 삼각봉 동쪽 분지의 화전민터 일대는 억새풀이 가득한 초원 지대로 장관을 이루고 있다. 봄이면 여우봉능선은 진달래꽃과 철쭉꽃 터널을 이루고 능선 바윗길은 연인들이 손을 잡아주면서 서로의 사랑을 확인할 수 있는 멋진 산오름길이다.", + "MNTN_HG_VL" : "620", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영북면 이동면", + "MNTN_NM" : "여우봉" + }, + "longitude" : 127.34282570000001, + "latitude" : 38.037779800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여항산은 함안의 진산이다. 진산은 보통 삶터의 북쪽에 자리를 잡는데 여항산은 남쪽에 자리잡고 있다. 이에 그 허점을 풍수지리의 비보책으로 보완, 산 이름을 물과 관련있는 여항산으로 지었다고 한다. 이름을 지은이는 1583년(선조 16년) 함주도호부사로 함안에 부임한 정구(鄭逑)라는 인물이다. ‘여항’이란 산 이름에는 삶터의 균형을 잡아 평화롭게 살고자 하는 염원이 담겨 있다.여항산은 꽃이나 단풍으로 이름난 산은 아니다. 근처에 이름 난 관광지가 있어 덤으로 유명세를 타는 산도 아니다. 그저 산과 들판 사이에 솟았다. 그러나 산은 정상 부근의 옹골찬 기세와 능선의 부드러움이 어울려 여느 명산 못지않다. 마치 세상 명리를 뿌리치고 초야에 묻혀 사는 지조 높은 옛 선비 같은 산이다.여항산 능선을 타고 남쪽으로 1시간 40분 거리에 서북산이 있다. 낙남정맥 산줄기인 여항산과 서북산은 한국전쟁 당시 낙동강 방어선이었으며 북한군 6사단과 미 25사단이 사투를 벌였던 곳이다. 미군들은 ‘갓 뎀’이라며 치를 떨었는데 이후 여항산과 서북산 일대를 갓데미산으로도 부른다고 한다. 서북산 정상에는 6.25 전적비가 있으며 당시 전투에서 전사한 미군 중대장의 아들 리처드 티몬스가 1995년 주한 미군으로 부임해 와 세웠다고 한다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "경남 함안군 여항면, 마산시 진전면", + "MNTN_NM" : "여항산" + }, + "longitude" : 128.40670359999999, + "latitude" : 35.196818100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "339", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주", + "MNTN_NM" : "연미산" + }, + "longitude" : 127.10261819999999, + "latitude" : 36.473217099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "연석산은 전북 진안군과 완주군의 경계를 이루며 운장산과 이웃해 있는 산이다. 오지에 숨겨진 산으로 맑은 물과 울창한 숲이 자연 그대로 잘 보존되었다.산행은 정겨운 농촌 풍경이 물씬 풍기는 정수암마을에서 시작되는데 이곳에서 연석산 정상으로 가는 산길 초입은 완만한 묵밭사이로 억새가 군락을 이루고 있다. 연석산 정상은 민둥봉이나 북쪽으로 뻗어나간 능선에는 병풍바위를 비롯하여 빼어난 암봉이 우뚝우뚝 서 있다. 동쪽으로는 덕유능선이 다가오듯 어른거리고, 남쪽으로는 진안 마이산이 말귀처럼 쫑긋하게 솟아있다. 서편 사봉리로 흘러내린 연골계곡 단풍이 아름다운 지대이다.", + "MNTN_HG_VL" : "928", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군", + "MNTN_NM" : "연석산" + }, + "longitude" : 127.3316667, + "latitude" : 35.9072222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대야산 조항산을 지나온 백두대간이 청화산(984m)에 이르러 동녘으로 한줄기 곁가지를 뻗어 시루봉을 솟구치고, 다시 동녘으로 능선을 이어 아름다운 산세의 산을 일으키니 바로 연엽산이다. 연엽산은 북쪽 자락을 흘러온 궁기천과, 남녘 자락을 흘러온 농암천을 아울러 영강(潁江)으로 흐르게 하니 이 영강은 내성천과 합하여 낙동강에 들게 된다.화산리 앞에서 능선을 타고 오를 수 있으나 시루봉과 연이어 등산함이 좋고 정상은 소나무와 참나무숲이 있어서 아주 시원하다. 연엽산의 정상은 참으로 신비롭다. 멀리서 바라보았을 때 제법 뾰죽했던 정수리는 간 곳이 없고 이름 그대로 거대한 연잎을 하늘에 펼쳐놓은 듯 평평한 너른 밭과 같은 형상이었으니 말이다.이 산 정상에서는 전망이 없으나 동쪽으로 조금 내려선 헬기장에 서면 둔덕산 너머로 대야산 장성봉의 백두대간과 희양산 이만봉을 잇는 백두대간의 하늘 마루금이 초겨울 하늘 아래 눈부시다.", + "MNTN_HG_VL" : "850", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 화산리", + "MNTN_NM" : "연엽산" + }, + "longitude" : 127.8230556, + "latitude" : 37.798055599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "연엽산은 꼭대기에서부터 사방으로 능선이 길게 여러 갈래로 뻗어있는데, 산세도 그리 험하지 않고 찾는 이도 적어 원시림이 그대로 보존된 숲과 계곡이 비경을 이루고 있다. 계곡에는 울창한 숲 사이로 기암절벽이 이어지고 크고 작은 연못이 곳곳에 흩어져 있어 등산과 함께 계곡의 경치를 즐길 수 있는 산이다.강원대학교 연습림이기도 한 연엽산은 수백년 된 노송들이 빽빽하고 나무들이 우거져 있다. 정상은 무인대피소와 아름드리 잡목이 우거져 하늘만 보인며 능선에는 철쭉이 많다.※ 강원대학교 연습림지역으로 일반인의 출입을 통제하고 있으므로 입산이 절대로 안됩니다.", + "MNTN_HG_VL" : "775", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천시 북방면", + "MNTN_NM" : "연엽산" + }, + "longitude" : 127.8230556, + "latitude" : 37.798055599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "연인산은 경기도 제2의 고봉 명지산의 남녘 능선을 잇는 산이다. 가평군 제1의 휴양지인 용추계곡 최상류에 자리하고 있다.연인산은 우목봉과 월출산으로 불리어왔으나 가평군이 지명을 공모하여 1999년 3월 ‘사랑이 이루어지는 곳’이란 뜻에서 이 산 이름을 연인산으로 바꾸었다. 그리고 연인산 서남쪽의 전패봉(906봉)은 우정봉, 전패고개는 우정고개, 동남쪽의 879봉은 장수봉으로 고쳤다. 또한 연인산에서 뻗은 각 능선에 우정, 연인, 장수, 청풍 등의 이름을 붙였다.연인산은 수도권에서 승용차로 2시간 이내 거리이면서 아름다운 비경과 명소들이 많은 산이다. 그중 제일비경은 용추구곡으로 연인산의 발원지이다. 용추구곡은 연인산의 부드럽고 완만한 지능선을 ‘ㄷ자’ 형태로 감싸고 있다. 연인상 정상에 오르면 사방의 조망이 막힘 없이 시원하다.가평군은 1995년 연인산 능선에 철쭉이 자생하는 것이 확인한 후 이곳을 관광지로 보존하기 위하여 1999년 5월 철쭉제를 개최하고 해마다 열고 있다. 연인산 철쭉은 5월 중순경에 만개한다.", + "MNTN_HG_VL" : "1068", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍ㆍ북면ㆍ하면", + "MNTN_NM" : "연인산" + }, + "longitude" : 127.4186114, + "latitude" : 37.898696600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "868", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "연점산" + }, + "longitude" : 128.9556479, + "latitude" : 36.337886699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "459", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 강서구", + "MNTN_NM" : "연태봉" + }, + "longitude" : 128.83388890000001, + "latitude" : 35.0266667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "암천을 따라 고성읍 서북쪽 12km 거리에 있는 산으로 옥녀봉, 선도봉, 망선봉의 세 봉우리로 이루어져 있으며 산의 북쪽 기슭에는 유서깊은 옥천사와 백련암, 청연암, 연대암 등의 암자가 있으며 특산물로는 송이버섯과 산딸기 등이 유명하다.옥천사 대웅전 뒤에 위치한 옥천샘은 사시사철 마르지 않고 항상 수량과 수온이 일정하며 이 샘의 물은 위장병, 피부병에 효험이 있다. 1948년 샘 위에 옥천각을 세워 보존하고 있다.", + "MNTN_HG_VL" : "524", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 개천면ㆍ영현면", + "MNTN_NM" : "연화산" + }, + "longitude" : 128.26530349999999, + "latitude" : 35.073357899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "연화산으로 오르는 길은 3코스로 나누어진다.① 언양에서 365번 은칠행 버스로 은편하리 회관 앞에 내려 은편교회를 지나 태양가든 방향② 은편중리 매표소 옆 임도다라 내리재로 가는 길③ 은편중리에서 허고개 방향(남으로)15분 동신부엌가구에서 오르는 길이 열린다.산행들머리는 ③ 번째 코스로 간판 오른편 공장입구에서 왼편으로 오르는 산길이 열린다. 오른쪽에는 언양 반천일대를, 왼쪽에는 두동 은편리 일대를 끼고 능선을 걸어가노라면 고래등을 타고가는 기분이다. 발밑의 바싹 마른 낙엽은 푹신한 카페트처럼 부드럽다. 아무데나 앉아도 낙엽 자체가 방석이다.연화산 정상은 온통 나무를 베어 이곳에 집결시켜 놓고 잡목이 우거져 정상에는 들어갈 수 없을 만큼 어질러져 있다. 우거진 잡목 숲은 멧돼지의 서식지가 되고 있다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 언양면", + "MNTN_NM" : "연화산" + }, + "longitude" : 128.26530349999999, + "latitude" : 35.073357899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "연화산은 낙동정맥이 백두대간과 만나는 태백 한 가운데 불끈 솟아 있어 사방을 조망하는데 막힘이 없다. 태백시가 이 산을 중심으로 가락지처럼 형성되었다고 해도 과언이 아니다. 산속에 연화부수형의 명당 연당지가 있고 산의 형상이 연꽃처럼 생겨서 연화산이라 한다. 옛날엔 연화봉이라 불렀는데 최근에 와서 연화산이라 부르게 되었다. 연화산 주봉인 옥녀봉은 옛날 천지가 물바다로 되었을 때 옥녀봉에 옥녀가 피난을 왔고 통리의 유령산 갈미봉에 갈미를 쓴 남자가 피난을 왔는데 나중에 물이 다 빠진 다음 둘이 만나 세상에 사람을 퍼뜨렸다는 전설이 있다. 투구봉은 일명 비녀봉이라 한다. 봉우리가 바위 절벽으로 되어 있으며 그곳에 비녀바위가 있어 비녀봉이라 불렀다. 그런데 장군대좌형국의 뒷산 봉우리인 비녀봉의 바위 절벽을 장군의 투구로 보고 투구봉이라 부르게 되었다.", + "MNTN_HG_VL" : "1172", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 문곡동", + "MNTN_NM" : "연화산" + }, + "longitude" : 128.26530349999999, + "latitude" : 35.073357899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "663", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 청도면 구기리", + "MNTN_NM" : "열왕산" + }, + "longitude" : 128.5953988, + "latitude" : 35.541475000000013 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옛날 어느 도승이 여량을 지나다가 이곳 산세를 보고 저산이 화(火)자 모양을 닮아 마을에 불이 자주 일어나는 재앙이 있겠다고 하니, 마을 사람들이 어찌하면 그 재앙을 막을 수 있겠느냐며 그 비방을 알려달라 조르니,저 산봉우리에 간수를 묻으면 된다고 하여 그대로 이행하였으며, 그 후 지금까지 아무런 탈이 없었다고 한다. 그런데 1955년 초겨울에 난데없이 집 근처에 쌓아둔 짚가리나 불쏘시개로 쓰는 갈비(솔가리:말라 서 땅에 떨어진 솔잎)더미에 불이 나,사람들이 달려들어 불을 끄면 금새 꺼지며 또 여기저기 불이 붙었다. 그런데 이상하게도 그 불이 사람사는 가옥에는 전혀 피해를 주지 않고 짚가리나 갈비더미 에만 불이 일어났다. 마을 사람들이 산에 올라가 소금 단지를 열어보니 소금이 말라 있었다고 한다. 소금을 채워 넣었 더니 별일이 없었다. 그래서 소금을 감추는 산이라 하여 소금 염,감출 장,봉우리 봉 자를 써서 염장봉(鹽藏峰)이라 부른다.", + "MNTN_HG_VL" : "689", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북면 여량리", + "MNTN_NM" : "염장봉" + }, + "longitude" : 128.7305556, + "latitude" : 37.4641667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "203", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 동구", + "MNTN_NM" : "염포산" + }, + "longitude" : 129.40899999999999, + "latitude" : 35.521000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영대산은 장수군 산서면과 임실군 성수면의 경계에 자리한 산이다. 호남금남정맥의 팔공산이 서쪽으로 한줄기 곁가지를 일으킨다. 마령치를 지난 이 산줄기는 다시 둘로 나뉘어 북녘으로 성수산, 서녘으로 영대산과 오봉산을 일으킨 후 덕재산을 지나 오수면의 오수천에서 산줄기를 마감한다. 지형도에는 한문으로 영태산(靈台山)이라 표기되어 있으나 이곳 주민들은 모두 `영대산'이라 부른다.산형이 아담하고 수려하다. 또한 인자하고 후덕한 어머니가 자식을 품에 안고 젖을 주는 듯한 산이기도 하다 또 이 산은 장수 8경의 한 경치인 영산영월의 경관을 자랑한 산이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 산서면", + "MNTN_NM" : "영대산" + }, + "longitude" : 127.3986111, + "latitude" : 35.612499999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "277", + "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시", + "MNTN_NM" : "영천악" + }, + "longitude" : 128.95304709999999, + "latitude" : 35.982839299999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1081", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산 하북면, 원동면, 울산시 울주군 삼남면, 상북면", + "MNTN_NM" : "영축산" + }, + "longitude" : 129.05500000000001, + "latitude" : 35.517000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1081", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면, 하북면. 울산광역시 울주군 삼남면", + "MNTN_NM" : "영축산" + }, + "longitude" : 129.05500000000001, + "latitude" : 35.517000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화왕산역과 맞닿아 있는 관룡산역과 연결되고 있으며, 영축산으로도 불리는 이 산은 영산면 소재지를 북쪽에서 막아서면서 너덜지대가 확연하게 보이는 산경을 지니고 있다. 험한 산세를 지닌 남쪽사면의 급한 경사면에 산객들에게는 쉽게 접근을 허락하지 않지만, 구계리 쪽으로 흘러내리는 동릉에는 계곡과 유적이 산재하고 있다. 북쪽사면은 암릉과 암봉이 모여 있어 역시 산세가 험하고 그 기세로 화왕산을 견제하고 있다. 한옥과 향교가 있는 고리가 산자락에 마을을 이루고 있어 하산길에 잠시 머물면서 옛 향기를 맛보는 재미도 얻을 수 있다.", + "MNTN_HG_VL" : "737", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 영산면", + "MNTN_NM" : "영취산" + }, + "longitude" : 127.71361159999999, + "latitude" : 34.826988399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "여수시 북동쪽 여천 산업단지 부근에 솟은 영취산은 창녕 화왕산, 마산 무학산과 더불어 전국 3대 진달래군락지 중 한곳으로 꼽힌다. 진달래만 수만그루가 모여 군락을 이룬 15만평 규모의 넓은 진달래밭이 산 곳곳에 자리잡고 있어 봄이면 장관을 연출한다. 매년 4월 초순경에 절정을 이루는데 이때를 맞춰 진달래축제가 개최된다.영취산은 예로부터 신령스런 산으로 인식되어 기우제나 치성을 드렸던 곳이다. 영취산이란 그 이름도 석가모니가 최후로 설법했던 인도의 영취산에서 따온 것으로 추측된다. 또 산 기슭에는 전통기원 도량이었던 금성대가 있고 그 아래 기도도량인 도솔암이 지어져 오늘까지 이어지고 있다.해발 510미터의 산으로 정상에 서면 남해의 크고 작은 섬들과 동북쪽 광양의 백운산, 묘도가 선명하다. 서남쪽으로 흥국사도 또렷하게 보인다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 상암동, 중흥동", + "MNTN_NM" : "영취산" + }, + "longitude" : 127.71361159999999, + "latitude" : 34.826988399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "창녕군 영산면에 있는 영취산은 해발 682미터의 비교적 낮은 산이지만 지천에 위치한 함박산(작약산)과 더불어 영산면 소재지를 품은 형상을 하고 있다.영취산을 오르는 코스는 대략 두 가지로 나뉘는 데 영산여중·고를 지나 보덕암-632봉-정상으로 오르는 길과 영산향교-영명사-영축산성-정상길이 있다. 시간과 거리로 따지면 영산향교 코스로 오르는 것이 수월하다. 이 코스 초입에는 유명한 함박 약수터와 영산 석빙고(石氷庫)가 있다.함박 약수터는 함박산 등산이 시작되는 초입에 위치해 있고 석빙고는 더 아래에 있다. 창녕읍에 있는 석빙고보다 규모가 비교적 작은 영산 석빙고는 보존상태가 양호한 편이다. 석빙고에서 정상까지는 2시간이면 충분하다. 중간에 쉬운 암벽등반 구간도 나오는데 초보자도 별 어려움 없이 오를 수 있다.정상에서 병봉으로 내쳐 가면 보름고개와 종암산, 큰 고개를 거쳐 부곡온천까지 갈 수 있다. 시간은 줄잡아 6시간 이상 걸리는 만큼 첫 출발부터 준비를 철저히 해야하는 코스다.", + "MNTN_HG_VL" : "737", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 영산면, 계성면", + "MNTN_NM" : "영취산" + }, + "longitude" : 127.71361159999999, + "latitude" : 34.826988399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남양주군에 있는 예봉산은 경기도 하남시의 검단산을 바라보고 있는 산이다. 예봉산은 남북의 두 줄기가 팔당댐에서 합쳐졌다가 서울로 흘러드는 한강의 물결 파노라마를 지켜볼 수 있는 산으로 인접해 있는 예빈산(禮賓山 589m)을 거치는 것이 일반적이다.옛날에 배를 타고 영월, 정선, 충주, 단양, 춘천을 오가는 길손들이 한양을 떠나며 삼각산이 보이는 이곳에서 임금에게 예를 갖추었다 해서 예빈산이라 부르기도 했다. 그런 연유에서인지 이 산자락에서는 실학의 선구자 정약용, 건국 운동을 선동했던 몽양 여운형 선생, 가나안 농군학교를 설립해 농촌지도자를 양성하는 데 앞장섰던 김용기 장로 등 이름 있는 인물들이 많이 배출되었다.예봉산의 능선이나 정상에 올라가면 어디서나 북한강과 팔당댐이 산을 끼고 굽이쳐 흐르는 아름다운 모습을 볼 수 있다. 능선길의 단풍은 특히 좋다. 정상 주변은 옛 성터 같은 돌무더기가 있다. 예전에는 산령단이 있었다고 하나 지금은 헬기장으로 변했고, 삼각점(양수 26)과 예봉산악회가 세운 정상표지석이 있다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시", + "MNTN_NM" : "예봉산" + }, + "longitude" : 127.2611921, + "latitude" : 37.559263000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 남양주시 와부읍과 조안면 경계를 이루는 예봉산(683.2m)은 한북정맥에서 가지를 친 능선 끝머리에 해당되는 산이다. 이 산줄기는 다시 남동쪽으로 이어져 율리봉, 예빈산을 들어 올린 다음 북한강과 남한강이 합수되는 두물머리와 한강에서 모두 사그라진다.팔당역을 기점삼아 정상에 서면 한강을 가로지르는 팔당대교와 그 너머로 하남시와 강동구를 필두로 한 서울, 북한강과 양수대교, 그리고 북한강과 남한강이 만나는 두물머리와 팔당호가 한눈에 들어온다.옛날 길손들이 배를#376;고 강원도로 떠날 때 마지막으로 삼각산이 보이는 예봉산 아래 팔당에서 임금에게 예(禮)를 갖췄다고 해서 산이름을 예빈산으로 지었다는 설이 있다.예봉산은 수도권에서 손꼽히는 근교산행 코스로 중앙선 팔당역이 개통되면서 각광을 받고 있다.", + "MNTN_HG_VL" : "638", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 와부읍, 조안면", + "MNTN_NM" : "예봉산" + }, + "longitude" : 127.2611921, + "latitude" : 37.559263000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오갑산은 2개도(경기,충북), 3개군(음성,여주,충주)이 경계를 이루고 있는 명산으로 삼국시대 에는 오압산(梧壓山)이라 불리었다. 한때 오압사라는 거찰을 배치하고 있었으나 지금은 그 흔적을 찾아 볼 수 없으며 미륵좌불 하나만이 지방 사적으로 지정되어 보호되고 있다.삼국시대에 고구려와 신라의 국경지역이었던 오갑산은 한수지역의 거대한 농토를 확보하기 위한 양국의 크고 작은 싸움이 잦았던 곳으로 오갑산 정상에 진을 치고 군대를 주둔하면서부터 오갑산이라 불려지기 시작했다. 임진왜란 당시 명나라 장수 이여송이 왜군과 전투를 하기 위해 진을 쳤으나 왜군과의 전투는 없었던 것으로 전해지며 그 이후 오갑산 정상을 이진봉이라 하고 이진봉 북방 8부능선의 펑퍼짐한 갈대밭을 진터라고 부르고 있다.오갑산 앞의 삼태봉은 통신수단이었던 봉화터가 지리하고 있는데 맑은 날에는 사방 백리길이 훤히 보인다. 이름난 산인만큼 곳곳에 얽힌 사연들이 많이 전해져 내려오고 있다.오갑산은 바위가 거의 없는 흙산이면서 이상하리만큼 우뚝하다. 기름진 흙산이라서 숲이 울창하고 닭발처럼 사방으로 퍼져 나간 산줄기도 많다. 비탈도 산자락은 순하지만 머리 부분은 매우 가팔라서 고스락에 오를 때는 매우 힘이 들고 산행의 맛도 충분히 느낄 수 있다. 흙산인 데도 오랜 세월과 많은 비바람에 어떻게 그 우뚝함을 지키고 의연히 서있을 수 있는지 신기하다.오갑산은 2개도(경기,충북), 3개군(음성,여주,충주)이 경계를 이루고 있는 명산으로 삼국시대 에는 오압산(梧壓山)이라 불리었다. 한때 오압사라는 거찰을 배치하고 있었으나 지금은 그 흔적을 찾아 볼 수 없으며 미륵좌불 하나만이 지방 사적으로 지정되어 보호되고 있다. 삼국시대에 고구려와 신라의 국경지역이었던 오갑산은 한수지역의 거대한 농토를 확보하기 위한 양국의 크고 작은 싸움이 잦았던 곳으로 오갑산 정상에 진을 치고 군대를 주둔하면서부터 오갑산이라 불려지기 시작했다.임진왜란 당시 명나라 장수 이여송이 왜군과 전투를 하기 위해 진을 쳤으나 왜군과의 전투는 없었던 것으로 전해지며 그 이후 오갑산 정상을 이진봉이라 하고 이진봉 북방 8부능선의 펑퍼짐한 갈대밭을 진터라고 부르고 있다. 오갑산 앞의 삼태봉은 통신수단이었던 봉화터가 지리하고 있는데 맑은 날에는 사방 백리길이 훤히 보인다. 이름난 산인만큼 곳곳에 얽힌 사연들이 많이 전해져 내려오고 있다.오갑산은 바위가 거의 없는 흙산이면서 이상하리만큼 우뚝하다. 기름진 흙산이라서 숲이 울창하고 닭발처럼 사방으로 퍼져 나간 산줄기도 많다. 비탈도 산자락은 순하지만 머리 부분은 매우 가팔라서 고스락에 오를 때는 매우 힘이 들고 산행의 맛도 충분히 느낄 수 있다. 흙산인 데도 오랜 세월과 많은 비바람에 어떻게 그 우뚝함을 지키고 의연히 서있을 수 있는지 신기하다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 감곡면, 경기도 여주군 점동면", + "MNTN_NM" : "오갑산" + }, + "longitude" : 127.6958333, + "latitude" : 37.140000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "울창한 숲과 이름난 사찰, 약수, 유적지 등이 산재해 있어 관광객과 등산객으로 늘 붐비는 오대산은 강원도 평창군 진부면과 도암면, 홍천군 내면, 강릉시 연곡면의 오대산국립공원의 서부지구에 위치해 있다. 특히 짧은 산행이지만 유서깊은 사찰과 암자를 곳곳에서 볼 수 있는 상원사와 적멸보궁, 정상인 비로봉을 거쳐 미륵암으로 하산하는 코스가 가장 유명하다. 상원사는 6·25때 한암이라는 승려의 산화로 아군의 전략상 소실될 뻔 하였던 위기를 피해 현재까지 그 형태를 보존하고 있는 사찰이다. 국보 36호인 동종이 있으며 신라시대 자장법사에 의해 창건되었다.예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.높이로 본다면 비로봉은 오대산의 최고봉이자 이 산의 정상이라 할 수 있다. 백두대간의 주맥이 설악에서 이어져 두로봉과 동대산으로 연결되는 서쪽 일대에 자리하고 있는 오대산은 명산으로 이름이 난 만큼 유서깊은 사찰과 암자들이 많다. 또한 산에 관련된 신비로운 전설들이 많이 전해 내려오고 있어 오대산의 명성을 더하고 있다.오대산의 다섯 봉우리는 호령봉, 비로봉, 상왕봉, 두로봉, 동대산이다. 이 다섯 봉우리중 비로봉이 제일 높은 봉우리이고 그 다음이 호령봉이다.", + "MNTN_HG_VL" : "1565", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 홍천군 내면, 강릉시 연곡면", + "MNTN_NM" : "오대산" + }, + "longitude" : 128.5430327, + "latitude" : 37.798146699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.", + "MNTN_HG_VL" : "1434", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 강릉시 연곡면", + "MNTN_NM" : "오대산 동대산" + }, + "longitude" : 128.5430327, + "latitude" : 37.798146699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "높이로 본다면 비로봉은 오대산의 최고봉이자 이 산의 정상이라 할 수 있다. 백두대간의 주맥이 설악에서 이어져 두로봉과 동대산으로 연결되는 서쪽 일대에 자리하고 있는 오대산은 명산으로 이름이 난 만큼 유서깊은 사찰과 암자들이 많다. 또한 산에 관련된 신비로운 전설들이 많이 전해 내려오고 있어 오대산의 명성을 더하고 있다.", + "MNTN_HG_VL" : "1563", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 진부면, 강릉시 연곡면, 홍천군 내면", + "MNTN_NM" : "오대산 비로봉" + }, + "longitude" : 128.52443679999999, + "latitude" : 37.779378399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오대산의 다섯 봉우리는 호령봉, 비로봉, 상왕봉, 두로봉, 동대산이다. 이 다섯 봉우리중 비로봉이 제일 높은 봉우리이고 그 다음이 호령봉이다.", + "MNTN_HG_VL" : "1560", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 도암면, 홍천군 내면", + "MNTN_NM" : "오대산 호령봉" + }, + "longitude" : 128.53277779999999, + "latitude" : 37.779722199999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오도산은 도선국사가 깨달음을 얻었던 곳으로 숙성산 정상에서 이 산을 보면서 산의 기운과 형상에 도취되어 꼬박 일주일을 움직이지 않았다고 한다. 이를 본 주민들이 도선이 잠든 것으라 여겨 숙성산 정상을 성수단(聖睡壇)이 된 것이라고 전해진다.도선국사가 도취될 만큼 이 산에는 지실골, 한시골, 폭포골, 두오골 등 맑고 깊은 계곡이 포진해 있어 안으로 들어가면 갈수록 깊이를 더하는 산이다. 골짜기는 오도산,미녀산,숙성산에서 흘러내리는 물들을 모아 수량이 풍부하다. 다래나무가 계곡을 가릴 정도로 많고 그 열매가 계곡 암반에 떨어져 소복히 쌓여 있고 더러는 계곡의 와폭을 따라 흐르기도 한다.정상은 통신시설 때문에 일반인의 출입은 금지하고 있다. 정상 일대의 도로에서 사방을 조망하는 맛이 그만이다. 덕유산을 비롯해 수도산, 가야산 그리고 자굴산, 황매산,지리산, 백운산, 계관산, 황석산, 기백산이 병풍을 친 듯 장관이고 남으로 합천호도 보인다.", + "MNTN_HG_VL" : "1134", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 묘산면", + "MNTN_NM" : "오도산" + }, + "longitude" : 128.07499999999999, + "latitude" : 35.673888900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 양산시 원동면에 자리한 오룡산은 산봉우리가 5봉으로 용처럼 굽이굽이 생겼다 하여 오룡산이라는 설과 옛날 통도사 구룡지 못에서 살던 아홉 마리 용 중 다섯 마리 용이 통도사 남서쪽에 있는 산너머 골짜기로 달아난 오룡골이 있는데 그 골짜기 위에 있는 산이라 하여 오룡산이라 한다.골짜기들이 예전에 비해 오염되고 많이 훼손되었지만 통도골과 도터진골(도태정골)은 원시의 자연을 아직 간직하고 있다. 통도골은 원동면 선리 새들마을에서 통도사로 넘어가는 가장 빠른 길이고, 도터진골은 깨침을 받은 골짜기라는 뜻이다. 두 골짜기는 산 아래로 내려오면서 하나로 합쳐져 통도-도터진골이라고 부른다.통도사에서 스님들의 수도에 방해가 된다고 하여, 일반인 출입을 막고있는 관계로 지산마을까지 버스로 그리고 자장암까지 40여분 걸어야 한다. 오룡산은 다섯 봉우리가 북에서 2봉 1봉 5봉 4봉 3봉 높이 따라 연결되어 있고, 그 위를 암릉을 타고 가는 길도 매우 험하니 왼편으로 트레버스하여 칼바위 위에 있는 곳까지 돌아가는 것이 좋다.", + "MNTN_HG_VL" : "967", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", + "MNTN_NM" : "오룡산" + }, + "longitude" : 129.0172182, + "latitude" : 35.478224900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면과 화천군 간동면 사이에 있는 오봉산은 해발 779m이고 다섯개의 봉우리가 있다고 해서 오봉산이라고 한다. 기암절벽과 노송이 어울려 한폭의 동양화 같은 산으로 유서깊은 청평사가 있다.배후령에서 오르게 되는 첫번째 봉우리가 1봉(나한봉), 두번째 봉우리인 관음봉, 세번째 봉우리인 문수봉, 네번째 봉우리인 보현봉, 다섯번째 봉우리인 정상 비로봉이 있다. 이중 제5봉인 정상에서 청평사 방면으로 뻗어내린 암릉이 특히 빼어난 풍광을 지녔다. 이 암릉을 따라 소양호를 바라보며 내려가는 길이 오봉산행의 백미라 할 수 있다.", + "MNTN_HG_VL" : "778", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 평창군 방림면, 횡성군 안흥면 태백산맥에서 갈라져 나간 차령산맥의 원두에 있는 명산 백덕산(1,350m) 과 북쪽으로 연이은 능선 위에 솟아오른 산이다. 지도상에는 1,136봉이 무명으로 되어 있으나 주민들은 봉우리가 다섯개 있다고 하여 오봉산으로 부르고 있다. 소양댐 위에 있는 오봉산(779m)과 자칫 혼돈하기 쉬우니 이 점 착오없기 바란다. 문재를 가운데 두고 북쪽이오봉산, 남쪽이 백덕산인데 그래서 그런지 두 개의 산이 산세나 식물상도 매우 흡사하다.잡목이 무성한 산길을 따라가다 1126고지에 이르면 참나무 울창한 숲길을 만날 수 있다. 이곳에서 조금만 올라가면 정상이다. 사람의 흔적을 찾아보기 어려워 복잡한 도심속의 소음을 등지고 한적한 산행을 즐기기에 안성맞춤이다.", + "MNTN_HG_VL" : "1136", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 평창군", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 완주군 구이면과 임실군 운암면에 걸쳐있는 오봉산과 국사봉은 옥정호가 있어 그 존재가치를 인정받는 산이다. 임실군 강진면과 정읍시 산내면에 걸쳐있는 옥정호의 비경은 무엇보다도 외안날을 중심으로 피어오르는 아침 물안개다. 옥정호는 일제 강점기인 1925년 동진수리조합에서 시공에 들어간 관개용댐에서 비롯됐다. 당시 섬진강 상류인 정읍군 산외면에서 서남쪽으로 갈라져 나와 황해로 흘러들어가는 동진강 유역이 대부분 평야인데 가뭄이 심각했다. 그래서 수자원이 풍부한 섬진강 상류를 막아 반대편인 정읍군 치보로 넘겨 계화도와 호남평야에 농업용수를 제공하기 위해 1929년 운안댐이 준공됐다. 이 사업은 3공화국까지 이어졌고 1965년 섬진강 다목적댐이 완공되면서 운암댐은 수몰되고 전북에서 제일가는 인공호수가 탄생한 것이다. 옥정호란 이름은 당시 댐이 위치한 강진면 옥정리에서 유래한다.옥정호를 가장 쉽게 조망할 수 있는 방법은 국사봉전망대 휴게소로 가는 것이다. 그리고 사진 촬영을 위한 최적의 포인트는 휴게소에서 20분이면 오를 수 있는 옥정호전망대다. 외안날을 중심으로 펼쳐지는 옥정호를 조망하는 이곳은 주말에는 1시간 전에 올라야 자리를 차지할 수 있을 정도로 사진가들이 붐빈다. 정상에 오르면 옥정호 주변을 조망할 수 있을 뿐 아니라 멀리 마이산까지도 보인다.", + "MNTN_HG_VL" : "513", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 운암면", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보성군 득량면으로 들어서면 도로 왼쪽으로 너른 벌판이 펼쳐지고 그 끄트머리께 우뚝 솟은 산이 두 개 보인다. 예당벌과 오봉산이란 지명이 붙어 있는 산들이다. 이곳 사람들은 왼쪽은 오봉산, 오른쪽은 작은 오봉산(284.2m)이라 부른다. 다섯 개의 위성봉을 거느리고 있는 작은 오봉산은 가까이 가면 정상부 오른쪽에 바위가 삐죽 튀어나와 있는 것이 인상적이다.반면 봉우리가 다섯 개 모여 있는 오봉산은 산 아래 다가설 때까지도 그리 독특하지 못하다. 들녘에 솟은 그저 평범한 야산 정도일 따름이다. 하지만 파고들면 점입가경 신비스럽기 그지없다. 산행 초입 오봉산은 한때 구들장으로 애용되는 돌이 대량으로 추출되었다는 명성에 걸맞게 납작한 돌 천지다. 널찍하게 이어진 등산로를 따라 오르면 멋들어지게 쌓아둔 돌탑이 산 능선마다 쌓여있다.오봉산의 참 멋은 오봉산에 들어서야 알 수 있다. 그 중 오봉산의 으뜸은 칼바위다. 30여 미터 높이의 칼바위는 마치 손가락을 위로 세우고 손을 모아서 45도 각도로 굽힌 모양 같기도 하고, 선 채로 깊숙이 허리 굽혀 인사하는 모습 같기도 하다.웅장한 바위와 깊은 골짜기, 봄을 수놓은 진달래가 오봉산의 오른쪽 얼굴이라면 득량만이 내려다보이는 탁 트인 조망은 오봉산의 왼쪽 얼굴이다.", + "MNTN_HG_VL" : "513", + "MNTN_LOCPLC_REGION_NM" : "전남 보성군 득량면", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "영남알프스는 영축산 염수봉으로 솟구치며 남으로 내리닫다가 양산시 어곡동 어곡리의 매바위 못미쳐서 두 갈래로 나눠진다. 한가락은 남서로 뻗어 토곡산(855m)을 토한 뒤 낙동강에 첨벙 뛰어들었다. 나머지 한 능선은 동남으로 방향을 잡고는 매바위를 지난 뒤 남쪽을 향하다 화제고개에서 남서로 뒤틀어 오봉산 줄기를 이루고는 살며시 낙동강으로 기어들었다. 토곡산과 오봉산은 마주보고 있는데 북은 토곡산, 남은 오봉산이고 그 사이에 낙동강에 연한 화제들판이 펼쳐졌다.오봉산의 남쪽은 양산천을 낀 물금들이고 그 건너편에 금정산이 솟아있다. 물금읍과 원동면 경계를 이룬 오봉산은 말 그대로 5개의 봉우리로 이뤄진 능선이다. 530.8미터의 제1봉이 낙동강 바로 동쪽에 자리잡았고, 그 반대편 북동쪽 강서동 부근 화제고개 못미쳐 제5봉(449.9m)이 있어 산줄기의 흐름과는 반대로 낮은 봉우리에서 마지막에 높은 봉우리를 이룬 셈이다. 이 산 마루턱에는 고운 최치원의 유상지인 임경대 유적이 있다. 임경대는 오봉산 제1봉의 7부 능선에 있는 바위봉우리로 낙동강과 그 건너편의 산, 들과 어울려 수려한 산천을 확인할 수 있는 훌륭한 명소 중 하나다.특히 매바위 암릉은 설악산의 공룡릉에 버금가는 경치라고 이 지역 등산인들은 말한다. 산 자체의 경관보다는 이 산등성이에서 바라보는 낙동강 주변의 널찍한 풍광이 특히 손꼽아 줄만한 장관이라고 말하기도 한다.", + "MNTN_HG_VL" : "633", + "MNTN_LOCPLC_REGION_NM" : "경남 양산시 교동", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오봉산은 다섯 개의 낙타등 같은 봉우리가 솟았다 하여 유래한다. 경주 시내에서 서쪽 외곽인 건천읍과 서면 일대에 있으며 문헌을 보면 부산의 위성봉임을 알 수 있다. 일명 주사산이라 불리기도 하는데, 이는 정상의 주사암에서 따온 것이다.오봉산에서 가장 유명한 것은 여근곡이다. 건천읍 신평리에서 오봉산을 볼 때 산기슭에 불두덩처럼 도톰한 부분이 보이는데 희한하게 가운데 오목한 골홈이 패여 있다.산행은 여근곡쪽으로 올라 오봉산과 주사암, 고랭지채소밭을 지나 동문 쪽인 송선리로 하산하는 것이 일반적이며, 성암사를 기준으로 능선과 임도를 따라 도는 원점회귀산행도 가능하다. 오봉산 원점회귀산행의 도상거리를 7.6킬로미터, 가민 콜로라도 300GPS로 확인한 실주행거리는 11.4킬로미터다오봉산은 부산성과 주사암, 지맥석, 여근곡 등의 역사적 의미와 유래를 알아보고 산행한다면 더욱 재미없는 산행이 될 것이다. 더불어 정상과 지맥석에서의 시원한 경치는 땀방울을 식히기에 모자람이 없다. 평범한 산이지만 그 자락에는 신라 천 년의 사연과 설화가 배어있다.", + "MNTN_HG_VL" : "324", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 서면, 건천읍", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "101", + "MNTN_LOCPLC_REGION_NM" : "인천시 남동구 도림동", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "235", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오봉산(五峰山)은 이안천변의 야트막한 산이다. 옛부터 상당히 큰 고을이었던 함창의 정남방에 들판위로 다섯 봉우리가 섬처럼 떠있어 이름이 났다. 기우단이 있었고 남산고성과 성산봉수대 터가 남아있다. 산록 여기저기 고분이 산재하나 대부분 도굴된 상태라 관리의 소홀함과 세월의 야박함을 동시에 느끼게 해주는 역사의 현장이다. 1992년 등산로가 개설되어 함창읍 사람들이 즐겨 찾는다.정상에는 표석이 설치되어 있으나 잡목이 시야를 가리기 때문에 산행중 간간이 보이는 장소에서 주변을 감상하는 것이 좋다. 하산하는 길에 난간을 두른 바위에 이르게 되다. 이 곳은 주변이 탁트여 주변을 조망하기에 가장 좋은 장소의 하나이다. 함창.점촌시내가 한눈에 보이고 끝없이 펼쳐지는 벌판과 운달산.천주봉이 더 멋지게 솟아있다.", + "MNTN_HG_VL" : "235", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주 합창읍 신흥리, 공검면 역곡리", + "MNTN_NM" : "오봉산" + }, + "longitude" : 127.8060983, + "latitude" : 38.0007746 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;섬진강 굽어오는 자라의 형상gt;섬진강은 오산을 만들었다. 섬진강이 감고 도는 오산은 마치 자라(鼇 오)의 형상을 하고 있다 해서 자라산이라고도 불린다. 지리산 노고단에서 남쪽으로 뻗은 왕시리봉능선이 섬진강에 잠기는 곳에서 섬진강 바로 건너에 있다. 마치 자라가 섬진강 물을 마시며 지리산을 파고드는 형국이다. 산줄기로 보면 광양시의 백운산 형제봉에서 서북진한 능선이 둥주리봉을 지나 이곳 오산에서 섬진강으로 마무리되는 끝자락 산으로 530.8m밖에 안 된다. 그러면서도 어엿한 산 이름을 얻고 자래봉(523m)이라는 봉우리까지 거느리고 있다.의상, 원효, 도선, 진각 네 고승이 수도하였다는 사성암(四聖庵)이 있고 오산 주변에는 기이하게 생긴 돌이 많아 소금강이라고도 하며 바위 절벽에 마애여래입상이 조각되어 있다. 산신각 앞과 그 오르는 길에 있는 신선대에서 보는 산줄기와 물줄기의 조화는 가히 일품이다. 동쪽으로 계족산과 마주하고 있다. 빨치산 연대장급인 이명래가 마지막 지휘부와 은신처로 사용했던 장소로 10여명이 둘러앉을 정도의 인공 굴이 있다. 헛굴과 본굴로 나뉘어 있고 은폐와 엄폐가 잘 되어 있어서 안내자 없이는 발견할 수 없는 요새와 같다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", + "MNTN_NM" : "오산 (자라산)" + }, + "longitude" : 127.0687686, + "latitude" : 37.147824800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", + "MNTN_NM" : "오산(자라산)" + }, + "longitude" : 127.0687686, + "latitude" : 37.147824800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오서산은 금북정맥의 최고봉으로 까마귀가 많다하여 유래된 이름이다. 서해안에서 가장 높고 웅장하게 솟아 있는 산이어서 인근 바다를 지나가는 배들이 쉽게 알아보고 뱃길을 가늠한다고 해 ‘서해의 등대’라고 불리기도 한다. 국내 5대 억새산 중 하나로 손꼽힐 만큼 억새밭이 장관을 이루며 사방으로 탁 트여있는 조망까지 만끽할 수 있어 만추산행으로 제격이다.오서산은 정상까지 바위가 발달되어 있어 악산의 성격을 띠다가 하산코스에서는 완만한 곡선이 이어져 바위지대가 흔하지 않은 육산으로 되어 있다. 오르는 길에 기암괴석이 즐비하고 단풍길도 이어져 있다. 산의 능선이 용의 머리 같다고 해서 이름이 붙여진 용허리나 줌방바위, 대문바위, 은폭동 폭포, 신랑신부바위, 농바위가 눈길을 끈다. 산 정상에 오르면 석각으로 된 사각형의 우물 맛도 그만이다. 오서산이 위치한 광천은 감과 어리굴젖 등 해산물이 유명하다.", + "MNTN_HG_VL" : "790", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 청소면, 청라면·홍성군 광천읍", + "MNTN_NM" : "오서산" + }, + "longitude" : 126.6653237, + "latitude" : 36.449378000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "227", + "MNTN_LOCPLC_REGION_NM" : "전라북도 군산시", + "MNTN_NM" : "오성산" + }, + "longitude" : 126.78494689999999, + "latitude" : 36.013886399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대미산에서 뻗어나온 줄기가 운달산과 부운령을 지나 남쪽 끝에 마지막으로 일군 산이 경북 문경의 오정산이다. 조선조 학자 서거정의 팔경에 나오는 `오정종류'가 바로 이 산을 일컫는 말이다. 많은 양의 석탄을 품고 있는 이산은 그 기슭에 광산촌을 이루었다.삼국시대 초기에 축조된것으로 알려진 고모산성과 성황당을 지나 유명한 토끼비리를 따라 산행이 시작된다. 돌을 쪼아내 만든 토끼비리의 시작 지점에서 부터 희미한 길을 따라 능선을 타고 오르게 된다. 이곳에는 아직도 일부 산성이 남아 있다. 더 올라서서 623 봉에 오르면 이곳에서의 조망은 일품이다. 이 능선에 진달래 군락이 형성되어있다. 진남교반을 휘감아 도는 영강과 시원스런 3번 국도의 모습이 장관을 이룬다. 이곳에서 약 1시간 가량오르면 정상에 닿게된다.정상은 비슷한 높이의 3 개의 봉우리로 되어 있고 밑에서 보기보다 올라와서 보면 암벽이 의외로 많이 보이는 산이다. 여기헬기장에서 북쪽으로 정상이 있는데 헬기장에서의 전망이 제일 좋다. 정상에서 보면 멀리 영순면으로부터 북서쪽의 백두대간이 병풍처럼 둘러친 모습이 보인다. 정상의 조망 때문에 문경의 최고 일출 산행지로 이곳을 꼽는다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 호계면", + "MNTN_NM" : "오정산" + }, + "longitude" : 128.12652310000001, + "latitude" : 36.660165800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조양강이 활등처럼 휘어도는 강변가에 푸른 소나무숲이 산기슭을 장식하고 있는 옥갑산은 강원도 정선군 북면과 북평면 사이에 자리잡은 오지의 산이다. 산이름은 옥으로 만든 갑옷을 두른 것처럼 보인다 하여 지어졌다 하며 지도에도 안 나오는 산이다.이 산의 해발 약 1000미터 지점에 상옥갑사가 있는데 옥갑사에서 조양강을 내려다보면 옥갑산 산영을 머금은 맑은 물빛과 섬뜩하리만치 높은 산의 위엄에 새삼 놀라게 된다. 능선상에서도 발 아래 조양강의 푸른 물줄기가 굽이쳐 흐르고, 겨울철에는 소백산능선에서도 보지 못한 아름다운 설경을 바라보고 있으면, 무념 속으로 빠져들어 갈 것만 같은 산이다.정상에 오르면 조양강과 여량, 아우라지 나루터가 내려다 보이고 여량 뒤로 고암산, 상정바위 능선이 흐릿하게 보인다. 정상에서 앞으로 직진하면 상원산, 동쪽으로는 노추산, 서쪽으로는 가리왕산이 있다.", + "MNTN_HG_VL" : "1285", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북면, 북평면", + "MNTN_NM" : "옥갑산" + }, + "longitude" : 128.68083329999999, + "latitude" : 37.495555600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옥교산은 병풍바위 남쪽에 가마같이 생긴 봉우리라 하여 산 모양을 보고 산 이름을 지었다. 이 곳에 선녀가 옥교를 타고 와서 놀다가 갔다는 전설이 있다.밀양 옥교산을 동물에 비유하자면 꾀꼬리 정도가 적당할 것 같다. 산이 그만큼 덩치가 작고 정답게 느껴지기 때문이다. 밀양 도심에서 멀지 않은 이 산은 멀리서 보자면 `사철 발벗은' 아낙처럼 `예쁠 것도 없는' 평범한 모습 이다. 산꾼의 주목을 끌지 못하는 이런 수수한 외모가 옥교산의 매력을 더해줬다.낮게 달리는 능선길은 겨울답지 않게 폭신한 낙엽과 솔잎으로 가득 덮혀있다. 길지 않은 산행시간. 이번 산행은 가볍게 트래킹하는 기분으로 맑은 공기를 마음껏 마시고 올 수 있 는 산뜻한 코스다.산행은 교동 동사무소에 내려 포장도로를 따라 춘복타워 맨션으로 오른다. 그 맨션에서 아스팔트길로 150m 더 오르면 오른편에 교동 배수지가 보인다. 여기서부터 산행을 시작한다. 정상은 수림으로 둘러싸여 어느 쪽으로도 조망이 불가능하며, 그냥 정상임만을 짐작할 뿐이다.", + "MNTN_HG_VL" : "538", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 안인리", + "MNTN_NM" : "옥교산" + }, + "longitude" : 128.74241280000001, + "latitude" : 35.539616799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "\"보령 시가지를 동남쪽으로 둘러서 있는 산이 성주산과 옥마산이다. 성주터널이 생기기 전 성주와 부여 쪽으로 가려면 옥마산을 통과하는 구절양장을 고갯길을 넘어야 했다. 비포장도로인 옛길을 가쁜 숨을 몰아쉬고 오르다보면 보령시가지가 한눈에 내려다보이는 정자가 옥마정이다.옥마정에서 성주로 향하는 내리막길에서 다시 산을 타고 오르면 보령 행패러글라이딩 활공장과 만난다. 이곳은 항공 스포츠를 즐기는 이들에게 새로운 메카 구실을 하는 곳이다. 행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하여 자세한 안내를 받을 수 있다.소요 시간 :180분 (구간별, 코스별로 다름)최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 옥마정에서 보는 시내전망, 활공장(행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하면 자세한 안내를 받을 수 있다)", + "MNTN_HG_VL" : "602", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "옥마산" + }, + "longitude" : 126.6350923, + "latitude" : 36.317708400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "보령시내로 들어서면 병풍처럼 동남방으로 길게 뻗어 내린 해발 600m규모의 커다란 산줄기가 한눈에 들어온다. 이 산줄기는 차령산맥의 끝 부분으로 성태산, 문봉산, 성주산, 옥마산, 잔미산이 연결되어 보령시 웅천읍 대천리까지 이어지다가 화락산을 한 점으로 남기고 서해바다로 사라진다. 이 중 해발 601m의 옥마봉을 주봉으로 하는 옥마산은 보령시 명천동과 남포면을 호위하는 모습으로 우뚝 솟아있는데, 이곳에 중계탑이 설치되어 있어 누구든지 쉽게 찾을 수 있다.옥마산(봉)이라는 이름은 신라 비운의 마지막 임금인 경순왕과 화살 맞은 옥빛 말의 전설과 관련하여 전해지고 있다. 옥마봉에는 패러글라이더 이륙장이 있어 새처럼 날며 산과 바다의 조화된 아름다움을즐기려는 항공스포츠 동호인들이 전국에서 찾아오는 이름난 곳이기도 하다.", + "MNTN_HG_VL" : "601", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 성주면, 명천동", + "MNTN_NM" : "옥마산" + }, + "longitude" : 126.6350923, + "latitude" : 36.317708400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충청남도 예산군 덕산면에 위치한 옥양봉은 석문봉에서 약2km떨어진 곳에 있는 해발 621m의 봉우리로, 석문봉과 산행시점이 같기 때문에 옥양봉과 석문봉을 연결하여 산행하기가 쉽다. 석문봉이나 옥양봉 모두 암봉으로 이루어져 있으나, 분명히 다른 느낌을 주는데 , 석문봉의 경우는 오르고 내리는 등산로가 계곡코스이며, 옥양봉의 경우는 모두 능선으로 되어있기 때문에 분명한 차이를 느낄 수 있다.석문봉은 정상부만 암릉을 느낄 수 있지만, 옥양봉의 경우는 바위 전망대가 곳곳에 있고 석문봉에 비해 훨씬 아기자기하다. 하지만 계곡 코스가 없기 때문에 물이 없다는 점이 단점이다. 올라갈 때는 관음전코스로 올라가는 것이 산행의 재미를 높일 수 있다. 관음전으로 올라서는 길은 가을 냄새가 물씬 풍기는 숲속길로 되어있어 산책로 같은 느낌이 든다. 관음전 아래 삼거리부터는 능선이 시작되는데 많은 구간에 로프가 설치되어있고 바위 전망대가 몇 군데 있다. 이중에서도 옥양봉 정상부에 있는 암봉위에 올라서서 내려다보는 경치가 제일이다. 상가리가 내려다보이고 주변 경치가 한눈에 들어온다.", + "MNTN_HG_VL" : "621", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", + "MNTN_NM" : "옥양봉" + }, + "longitude" : 126.61058370000001, + "latitude" : 36.731824500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전남 화순군 동복면에 위치한 옹성산은 거대한 암봉군으로 이루어져 있다. 항아리를 엎어놓은 듯한 바위가 여러 개 있어 옹성산이라 불렀으며, 암질이나 솟은 모양새가 진안의 마이산과 비슷하지만, 마이산처럼 하늘을 향해 치솟아 오르지 못해 외면당해 왔다고 볼 수 있다.그러나 산행을 해보면 옹성산의 암봉들이 그 절경을 자랑하는데 독아지봉이나 쌍바위봉, 문바위, 옹성암터 등 다른 산에서는 쉽게 찾아볼 수 없는 비경들이 숨어 있어 자연조각공원이라 일컬어도 손색이 없다. 바위산이면서도 곳곳에 샘도 많고 쉴 곳도 많아 뜻밖에도 좋은 산행지임을 알 수 있다.이곳에는 산성이 있는데 철옹산성이라 부른다. 고려 말 왜구의 침입에 방비하려고 쌓았다고 전하며 입암산성, 금성산성과 함께 전남의 3대 산성으로 불리기도 한다. 임진왜란 시에는 이 고을 현감을 지내고 진주성에서 순국한 황진장군이 군사를 훈련시킨 곳이라 하며 동학이 활발한 때에는 오계련이 이곳을 증축하였다고 한다. 서울에 있는 몽촌토성보다 두 배 가량 큰 것으로 조사되었다.", + "MNTN_HG_VL" : "573", + "MNTN_LOCPLC_REGION_NM" : "전남 화순군 동복면", + "MNTN_NM" : "옹성산" + }, + "longitude" : 127.1329367, + "latitude" : 35.117416200000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "완택산은 연하리와 동강변인 삼옥리 사이에 위치하고 있다. 산세는 동고서저, 즉 주능선을 경계로 동쪽 연하리 방면은 급경사에 절벽이 많고, 서쪽 동강 방면은 완만한 산세를 이루고 있다. 산세가 이렇듯 그 옛날 완택산은 천혜의 요새였다는 전설이 전해지고 있다.주능선 동쪽은 수직절벽이 대부분이어서 자연성곽을 이루고 서쪽은 동강 물줄기가 자연적인 방어선을 이루고 있다. 그래서 완택산은 옛날 예맥의 땅이었다는 얘기가 전해지며, 퉁구스식 방법으로 축성한 산성흔적이 산자락 곳곳에 조금씩 남아있다.완택산 등산로는 급경사를 이룬 동쪽 연하리 방면에서 오르내리는 코스가 일반적이다. 그러나 요즘은 동강변 삼옥리에서 완만한 경사를 이룬 능선과 계곡 코스가 인기 있다.", + "MNTN_HG_VL" : "918", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "완택산" + }, + "longitude" : 128.55202180000001, + "latitude" : 37.2109405 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "왕모산은 안동에서 동북쪽으로 30여킬로미터 떨어진 곳에 있다. 낙동강이 굽어보이고 안동호와 가까운 산으로 산세가 수려하고 자연경관이 매우 아름답다. 주위에는 유적지가 많아 답사산행 하기에는 좋은 산이다. 안동댐을 내려다보며 우뚝 솟아 있는 왕모산은 1361년 고려 공민왕이 홍건적의 난을 피해 안동으로 왔을 때 왕의 어머니가 이 산으로 피난했다 해서 붙여진 이름이다. 전설에 의하면 홍건적이 이곳까지 진격하여 공민왕이 위태롭게 되자 백마를 탄 노장수가 번개처럼 나타나 왕을 구하고 지렁이로 변했다고 한다.이 산은 그리 높지는 않지만, 12개의 봉우리를 거쳐야만 산 정상에 오를 수 있고, 갈선대란 바위가 산 이름보다 더 유명하다. 수려한 경관 속에 펼쳐지는 왕모산성 등산로는 약 6.8킬로미터로 열두 봉우리 정상마다 특색 있는 암석들이 신비함을 더해 주고 있다.상수리나무와 굴참나무가 많은 정상에서는 수려한 낙동강이 조망되고 산 아래에는 유명한 도산서원을 품고 있으며, 고려 때 축성한 왕모산성의 흔적도 남아있다. 왕모산성 내에는 왕모당이라는 성황당이 있으며 매년 정월보름에 동산제를 지내고 있다.", + "MNTN_HG_VL" : "648", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 도산면, 예안면", + "MNTN_NM" : "왕모산" + }, + "longitude" : 128.9024215, + "latitude" : 36.731395700000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포천군의 진산으로 불리어 온 왕방산은 포천읍 서쪽에 우뚝 솟아 있는 산이다. 신라 헌강왕 3년(872년)경 도선국사가 이곳에 머무르고 있을 때, 국왕이 친히 행차하여 격려하였다 하여 왕방산이라 불리어졌고 도선국사가 기거했던 절을 왕방사라 했다는 말이 전해지고 있다. 왕방산은 광주산맥 서쪽의 지맥인 천보산맥의 북단에 자리잡고 있는 산이다.산들머리에는 유명한 문례현약수가 있고 완만한 육산의 능선길과 갈림길에는 안내판이 잘 정비되어 있다.정상은 초원이며 북쪽에서부터 종현산, 금주산, 문악산, 주금산, 죽엽산등이 바라보이고, 서울 근교에 위치한 산이라 교통이 편리하다. 능선과 게곡을 두루 거칠 수 있어서 좋다. 또한 눈내린 산길은 색다른 멋이 있다. 아담한 산세의 왕방산은 초겨울 가족 산행지로 알맞다. 완만한 등로와 키를 넘는 억새풀밭, 흰 눈이 깔린 왕방산은 초심자들도 큰 힘 들이지 않고 오를 수 있다.", + "MNTN_HG_VL" : "737", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 포천읍 신북면, 동두천시", + "MNTN_NM" : "왕방산" + }, + "longitude" : 127.155833, + "latitude" : 37.896667000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포천읍 바로 뒤에 솟은 왕방산(737.2m)은 덩치가 크고 품이 넉넉해 보이는 인자한 시골 아낙네 같은 산이다. 또한 포천읍의 진산으로 남북으로 길게 누운, 바위가 그리 많지 않은 육산이다. 신라 말(872년) 헌강왕이 지금의 보덕사(도선국사 창건설)를 친히 방문했다 하여 산 이름을 왕방산이라 하고 절 이름을 왕방사라 부르게 됐다고 전해온다.그러나 포천군읍지와 견성지 기록에 의하면 조선의 태조 이성계가 왕위에 오르기 전부터 이 산에서 무예를 익히고 사냥을 했으며, 왕위에 오른 후에도 단오와 추석에 강무(임금이 참관하는 무예시범)를 했다 하여 왕방산이라 부르게 됐다고 한다.태조 이성계가 왕위를 아들에게 물려주고 함흥에 살다가 한양으로 돌아오던 중 왕자의 난 소식을 듣고 비통한 마음을 달래고자 이 산을 찾았다는 다른 유래도 전해진다.왕방산 주변에 이와 연관된 지명으로 왕숙천, 팔야리(이성계가 한양에 들어가기 전에 여덟 밤을 지낸 마을) 등이 남아 있다. 이러한 유래를 갖고 있는 왕방산의 표기를 일제시대부터 왕자에 날 일(日)자를 붙여 旺자로 바꿔 표기했으나 최근에는 다시 ‘王’자로 바꿔 놓았다. 서울의 인왕산(仁王山)과 같은 경우다.", + "MNTN_HG_VL" : "737", + "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시, 포천시 포천읍", + "MNTN_NM" : "왕방산" + }, + "longitude" : 127.155833, + "latitude" : 37.896667000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "왕산은 필봉산과 더불어 산청군 금서면의 중심에 위치해 있으며 그 주변으로 마을들이 산재해 있다. 왕산은 산청군의 여타 산들처럼 지리산의 유명세에 가려져 있지만 정상에서의 조망과 필봉산으로 이어지는 날등의 철쭉과 억새밭의 조화는 가히 환상적이다. 지세는 지리산의 봉우리인 상봉, 중봉, 하봉과 왕등재 쌍재로 이어져 왕산까지 그 줄기가 이어진다. 왕산 주능선의 북동쪽은 절벽으로 되어 있으며 서쪽은 울창한 수림의 능선이 완만하게 흘러내린다. 평지 같은 정상에는 삼각점만 있으나 북쪽 주능선에는 전망이 좋은 암봉이 2개가 있고 정상이 아닌 895봉에 왕산이라 음각되 표석이 세워져 있어 정상으로 착각하기 쉽다. 정상 북쪽 절골 변에는 류의태 선생이 한약제조에 사용했다는 약수터가 있다. 또한 이 산의 자락에는 가락국 마지막 왕인 구형왕의 유물을 보존하기 위해 조선 정조 17년에 후손들이 지었다는 덕양전이 있다. 그곳에서 약 2킬로미터 위에는 사적 214호로 지정된 구형왕릉이 있다.", + "MNTN_HG_VL" : "926", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 금서면", + "MNTN_NM" : "왕산" + }, + "longitude" : 127.8126833, + "latitude" : 35.429355200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산양면에서 위만리로 가면 산양면과 용궁면 그리고 북쪽의 산북면의 경계가 되는 산이 왕의산(王衣山)인데 산양면 위만2리 뒷산으로 고려 공민왕이 몽고의 침입으로 안동에서 피난하고 돌아오는 길에 이곳에서 옷을 벗어 나무에 걸어 놓고 쉬었다 하여 왕의산이라 부르게 되었다고 한다. 높이 300m의 산봉우리가 왕의산에서 시작하여 산양면 현리 금천까지 이어져 있다. 높이에 비해 능선이 긴 것이 특징이다.산행들머리는 산양면 위만2리 상위마을을 지나자 바로 왕의산 쪽으로 나 있는 길로 접어들면 되는데 고가수 밑을 지나 길이 잘 나 있다. 올라가는데 약 40분이면 충분하고 소나무숲 길을 올라야 하며 오봉산, 비조산까지 능선을 타고 갈 수 있다.", + "MNTN_HG_VL" : "339", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 위만리", + "MNTN_NM" : "왕의산" + }, + "longitude" : -118.2912369, + "latitude" : 34.060234600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "왕치산은 등산로가 대부분 임도로 이뤄져 있어 길을 잃거나 할 염려가 없으면서도 사람의 발길이 거 의 닿지 않은 우거진 숲길을 거닐며 한적한 산행을 즐길 수 있다. 고사리 등 산나물과 자생 식물이 잘 보존돼 있고 산과 어우러진 월루마을의 풍광 또한 색다른 감흥을 불러일으킨다. 산행기점인 임계-여량리간 42번 국도상의 큰너그재는 해발760m의 고지대로 정상과의 고도 차가 200m을 조금 넘는 수준이어서 부담 없이 산을 오를 수 있다.큰너그재에서 산행을 시작한다. 넓지 않고 인적이 없어 등산로와 같은 임도를 타고 정상에 도달하거나 임도 옆 능선을 타고 정상에 오르는 방법이 있다. 여기서 왼쪽 임도를 따라가면 왕치산산행이 백미라 할 월루 마을의 아름다운 풍광을 감상할수 있다. 월루마을을 둘러보고 계곡을 따라 남하하는 임도를 타면 느라방죽이 나타나고 잠시후 골지천의 비경과 천 주변의 유적들을 만날 수 있다. 반천초등학교 옆의 구용소와 숙종때 공조참의를 지낸 이자선생이 노닐던 구미정, 그리고 고수당, 난포정, 장찬성지 등이 유명하다. 골지천은 여름철 물놀이를 즐기기에 제격인 곳이다.", + "MNTN_HG_VL" : "900", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 임계면", + "MNTN_NM" : "왕치산" + }, + "longitude" : 128.79443470000001, + "latitude" : 37.486439500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태백산맥에서 동남쪽으로 갈라져 나온 산줄기가 경주시 단석산(829m)을 지나 구룡산·반룡산으로 벋으며 솟은 산으로 청도 지방을 동과 서로 나누는 기준이 된다. 마을주민들이 흔히 마음산이라고 부르는 북쪽의 선의산(756.4m)과는 능선으로 이어진다. 비가 내려 산이 운무에 덮이는 광경이 아름다워 청도팔경의 하나로 꼽힌다.용각산은 용에 관한 유래가 많은 산으로 용이 물을 마셨다는 용샘, 용마가 태어나지 못하게 쇠말뚝을 박았다는 용맥, 용의 발자취가 있었다는 용바위 등 용에서 유래되어 심지어 바위샘까지도 용 자가 붙어 있다. 갖가지 용의 전설은 용을 숭배하는 토속 신앙의 표현이다. 또한 용맥은 용각산의 모습이 일본 후지산과 너무 흡사하여 임란 전에 일본에서 밀정을 파견하여 마을에 큰 인물이 나는 것을 미리 막기 위해 산정에다 쇠막뚝을 박았다는 이야기가 지금도 전해지고 있다.", + "MNTN_HG_VL" : "693", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군, 경산시 남천면", + "MNTN_NM" : "용각산" + }, + "longitude" : 128.7666667, + "latitude" : 35.6988889 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "모산동과 송학면 경계에 위치한 해발 871미터의 용두산은 삼한시대 축조된 의림지와 제2 의림지, 솔밭공원을 남녘 자락에 펼치고 있는 제천의 진산이다. 산기슭에서 흘러내린 물이 용두천을 이루며 의림지로 흘러든다. 북서쪽으로는 석기암산(906m)과 감악산(920m)이 이어진다. 제천 시내의 산이어서 교통이 편리하고 찾기가 수월해 주말이면 제천 시민들이 즐겨 찾는다.용두산 산행 코스는 크게 세 군데로 나눌 수 있다. 피재, 물안이골, 석기암봉 코스 중에서 사람들이 가장 많이 찾는 코스는 피재 방면이다. 산행은 솔밭공원 앞 주차장에서 시작한다. 수령 수백년을 헤아리는 노송 백여 그루가 숲을 이룬 솔향기 가득한 공원에는 여러 점의 조각이 놓여 있어 운치가 있다. 의림지 북쪽으로 약 5백미터 지점에 자리한 이 솔밭공원을 지나면 진초록 못물이 더욱 맑은 제2 의림지가 있다. 용두산 등산로는 그 위편에 위치한 청소년수련원 오른쪽으로 나 있다. 의림지와 용두산산림욕장 등을 연계해 산행하면 다양한 볼거리와 편안한 휴식을 즐길 수 있다.용두산 정상은 매우 널찍한 헬기장으로, 주위에 벤치가 10여개 설치돼 있다. 헬기장 한쪽 끄트머리에는 ‘용두산 해발 873m’라 새긴 아담한 정성석이 있다. 정상에서 바라보는 조망은남동쪽을 제외하고는 나무가 우거져 좋지 않다. 서북쪽으로 석기암(906m)과 감악산(920m) 산줄기가 이어진다.", + "MNTN_HG_VL" : "871", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면", + "MNTN_NM" : "용두산" + }, + "longitude" : 129.0326226, + "latitude" : 35.100653600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용두산은 태백산 끝자락에 위치하며 용머리 처럼 우뚝솟아올라 용두산이라고 하며 풍수지리를 연구하는 학자들은 소백산과 만나는 곳에 위치한 용두산을 와룡(누운용)이 여의주(용수사)를 물고 있는 형상이라고도 한다. 용두산은 안동시 녹전면과 도산면의 경계에 위치하고 있으며 유학의 대가인 농암과 퇴계선생 가문의 중요한 학문탐구의 장이었던 용수사를 품고 있으며, 남쪽으로는 퇴계선생의 조부이신 이계양공이 돌아가신 단종을 애도했던 장소로 유명한 국망봉을 거느리고 있다. 산행코스는 그다지 길지 않으므로 가족과 함께 가벼운 마음으로 용수사에 들렀다가 용두산 산행후 온천욕까지 즐길수 있다.", + "MNTN_HG_VL" : "661", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 도산면 운곡리, 매정리", + "MNTN_NM" : "용두산" + }, + "longitude" : 129.0326226, + "latitude" : 35.100653600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "529", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "용림산" + }, + "longitude" : 129.16408229999999, + "latitude" : 35.8439938 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 제천시 한수면에 자리한 용마봉은 소백산맥의 머리격인 소백산에서부터 죽령을 넘어 분수봉을 겨쳐 이화령에 이르기 전에 북쪽으로 내린 가지 위에 거대한 기암괴석으로 빚은 명산 월악산을 선보이고 그 주변에 600-1000m에 이르는 크고 작은 여러 산들을 거느리고 있다.그중 하나인 용마봉은 제천시 한수면 송계리에 위치한 월악산 국립공원의 숨겨진 보석이라 일컬을 정도로 정상을 이룬 거대한 바위 능선이며 . 송계계곡을 가운데 두고 월악산 덕주골과 마주보고 있는 서쪽에 솟아 있는 그리 높지 않은 산으로 바위 능선의 모양이 말안장을 닮았다고 해서 옛부터 말마봉 또는 말마산으로 불려왔다. 비록 높지는 않으나 다른 산에서 맛볼 수 있는 산행의 묘미를 골고루 체험할 수 있어 산악인들의 사랑을 받고 있다. 기암절벽으로 이루어진 산세는 아름다움을 자랑하고 암릉지대가 많아 스릴 또한 즐길 수 있으니 높이만 보고 얕잡아 볼일이 아니다.거기다 규모는 작지만 미륵사지와 송계계곡이 한눈에 내려다 보이는 조망은 참으로 아름답다.또 산행기점인 남문(월악루) 주변에 농암, 망폭대, 용추, 사자빈신사지석탑 등 볼거리가 많아 사계절 찾는 이들의 발길이 끊이지 않는다. 임진왜란 때 남쪽으로 마주보고 있는 북바위산에서 북을 치자 이 용마봉에서 용마가 하늘을 날며 포효했다는 전설이 전해진다.정상에서는 북으로는 송계리와 구례골이 샅샅이 내려다보이고, 시계바늘 방향으로는 월악산 정상이 장쾌하게 마주보인다. 월악산 정상에서 오른쪽으로는 V자로 패어든 덕주골이 남의 집 대문 안 들여다보듯 마주보이고, 톱날 같은 월악산 남릉이 덕주봉, 용암봉, 만수산과 함께 펼쳐진다. 남으로는 미륵리로 이어지는 송계계곡에 선을 그은 듯한 자동차 길이 실낱 같고, 용추, 팔랑소, 닷돈재 일원이 한눈에 들어온다. 그 오른쪽으로는 북바위산과 박쥐봉이 멀리 주흘산과 함께 시야에 와닿는다.", + "MNTN_HG_VL" : "687", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 송계리", + "MNTN_NM" : "용마봉" + }, + "longitude" : 127.0958467, + "latitude" : 37.571184899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용문산은 경기도에서 네 번째로 높은 산으로 기암괴석과 고산준령을 고루 갖추고 있는 산이다. 본디 미지산이라는 이름으로 불리었는데, 조선을 개국하고 이태조가 등극하면서 '용문산'이라 바꿔 부르게 되었다고 한다.정상은 입산통제 지역으로 우회하는 등산로가 이용되고 있다. 신라 선덕여왕때 창건한 용문사 사찰앞에는 높이 62m, 둘레 14m에 달하는 은행나무(천연기념울 제 30호)가 발걸음을 멈추게 한다.", + "MNTN_HG_VL" : "1157", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면ㆍ옥천면", + "MNTN_NM" : "용문산" + }, + "longitude" : 127.5518582, + "latitude" : 37.5622124 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "이 산 아래 가람을 연 용문사가 이 산 만큼이나 유명하다. 고려 건국후에 태조가 이곳을 방문했을 때 용이 나타나 환영했고, 이를 기뻐한 태조가 산 이름을 용문산으로, 절 이름을 용문사로 각각 명명했다.용문사하면 많은 사람들이 양평 용문사를 떠올린다. 양평 용문사는 서울에서 가깝고 큰 은행나무가 있어 사람들이 많이 찾기 때문이다. 그러나 경북 예천에는 훨씬 역사가 오래된 보물인 용문사가 있다.또한 소나무가 대부분이며, 삼국시대에 축성된 것으로 추정되는 어림성이 용문면 선리 산 45와 하리면 금곡리 산 450에 소재해 있다.", + "MNTN_HG_VL" : "782", + "MNTN_LOCPLC_REGION_NM" : "경상북도 예천군 용문면, 하리면, 상리면", + "MNTN_NM" : "용문산" + }, + "longitude" : 127.5518582, + "latitude" : 37.5622124 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용바위봉은 충북 제천시 청풍면과 단양군 적성면 경계를 이루는 금수산 주능선에 솟아있는 산이다. 용바위봉이란 지명은 단양군 소야리와 각기리에서 서쪽으로 치솟은 산을 올려다보면 대소 5개의 골짜기들이 패어져 있는데 이중 가운데 것인 큰 용바위골이 마치 승천하는 용이 올라가면서 파낸 자국처럼 보이기 때문에 두 용바위골 끝머리가 만나는 꼭대기라서 붙여진 이름이다.용바위봉 정상에는 큰 용바위골과 작은 용바위골에 걸쳐 얹힌 용머리를 닮은 커다가 바위가 두 개 있다. 용바위봉은 이름에서도 알 수 있듯이 제법 험준한 산이지만 알려지지 않은 비경이 많아 산을 찾는 이들을 즐겁게 한다.", + "MNTN_HG_VL" : "750", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 단양군", + "MNTN_NM" : "용바위봉" + }, + "longitude" : 129.0219444, + "latitude" : 37.050277800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신선봉에서 북진하는 능선에서 서북쪽으로 갈라져 나간 지능선에 마지막으로 솟아오른 용산봉은 단양군 남한강변인 가곡면 사평리, 보발리, 대대리 사이에 서있다. 용산봉은 어머니산인 신선봉과 비슷하다. 신선봉을 멀리서 또는 산 아래에서 보면 산세가 육산 같지만 정상이 쇠뿔 돋아난 듯 바위로 되어 있는 것처럼 용산봉도 주능선에 올라보면 바위지대가 노송 사이에 펼쳐지기 때문이다. 또한 진달래군락이 어우러져 아름답다.산행 초반부터 깔딱고개를 만나 힘을 쏟는가 하면 암릉지대를 미끄러지며 올라 정상에 서면 조망이 장관이다. 4평 정도의 공터에 국유지 표지석이 있는 정상에서 동서남북으로 이어지는 파노라마를 만나게 되는데 소백산 주능선, 국망천계곡, 제2연화봉, 도솔봉, 황장봉산, 문수산, 대미산, 충주호, 남한강, 도담삼봉, 삼태산, 태화산 등이 도열한 모습이 숨을 멈추게 한다.", + "MNTN_HG_VL" : "944", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "용산봉" + }, + "longitude" : 128.4241667, + "latitude" : 37.024999999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "용소봉" + }, + "longitude" : 127.6578615, + "latitude" : 36.089642599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "686", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "용암봉" + }, + "longitude" : 126.9810445, + "latitude" : 37.653481499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용암봉은 충북 제천시 한수면 송계리에 솟아있는 봉우리로 월악산국립공원내의 만수봉(983m)에서 서북쪽 방면으로 이어지는 바위 능선상의 최고봉이다. 만수봉 부근의 산들이 모두 그렇듯 용암봉도 한폭 그림처럼 아름답다. 해묵은 노송들이 치마를 펼친 듯한 회백색 바위 사이에 군락을 이뤄 산행의 즐거움을 더해준다.용암봉(892m)은 '송계8경' 중 제1경인 팔랑소 동쪽에 병풍을 두른 듯 솟은 산이다. 또한 이 산을 중심으로 북쪽에 고무서리계곡, 남쪽에 만수골이 패어져내려 주능선에 올라 내려다보는 조망이 더욱 깊이가 있다.산 이름은 892m봉 남쪽 단애를 이루는 계곡에 높이 50m나 되는 용암폭포가 있어 붙여진 이름이다. 이 폭포는 평상시 건기에는 물이 말라 버리기 때문에 이 지역 산악인들은 물줄기가 실처럼 가늘다해서 '실폭' 이라 부르기도 한다.정상은 참나무 수림 때문에 시원한 조망이 터지지 않는다. 그러나 서쪽 팔랑소를 향하여 서서히 가라앉는 암릉인 북서릉을 타면서 부터 진수가 나타나기 시작한다. 북서릉에서는 시종 박쥐봉, 북바위산, 용마봉을 마주보며 걷게 되고, 오른쪽으로는 월악산 정상이 압도하듯 올려다 보인다. 또한 덕주봉 암릉도 거대한 아름다운 수석인 듯 느껴진다. 여기에다 덕주봉 뒤로 충주호가 내려다보이고, 송계계곡이 골골샅샅 이내려다보여 이곳 저곳 구경하느라고 누구든지 산행시간은 길어지고 만다. 북서릉은 다섯 개의 암봉으로 이어진다. 아기자기한 노송 아래 바윗길을 따라 2시간 남짓 내려서면 시원한 폭포수가 바위를 차고 내리는 팔랑소가 반긴다. 하늘 나라에서 여덟공주가 내려와 목욕을 했다는 전설이 있는 팔랑소 주변에는 200 여 평이 넘는 너럭바위가 있어 휴식을 즐기기에 그만이다.", + "MNTN_HG_VL" : "892", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 송계리", + "MNTN_NM" : "용암봉" + }, + "longitude" : 126.9810445, + "latitude" : 37.653481499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화순 한천면과 춘양면의 경계에 우뚝 솟아 있는 용암산은 화순 일대의 유순한 산세와 달리 마치 용암이 분출해 솟아 오른 듯 날카롭고 거칠며 하늘을 찌를 듯 솟은 바위봉우리와 연이은 낭떠러지로 이루어진 독특한 산이다.예전에는 금오산이라 불렀는데 산 위에 있는 샘에서 하늘로 올라가려던 금자라가 나왔다고 해 이름 붙여졌다고 한다. 하지만 실제로는 금자라가 아닌 쇠처럼 생긴 바위벼랑이 있는 모습으로 보고 금오산이라 불렀다고 하니, 예부터 용암산의 산세가 험준했다는 것을 말해준다. 하지만 언제부턴가 금오산보다 ‘바위가 솟았다’는 의미의 용암산으로 불리게 되었다.용암산이 위치한 한천면은 예로부터 물 좋기로 이름난 고장이다. 어떤 곳을 파든 맑고 시원한 샘물이 솟는 천혜의 지역으로 알려졌다.용암산 산행은 용암사를 경유해 능선으로 오르는 것과 용암산장 뒤쪽의 계곡을 통해 정상으로 오르는 두 가지 방법이 있다. 길이 뚜렷한 능선길로 오르려면 먼저 용암사 경내로 들어서야 한다.", + "MNTN_HG_VL" : "547", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 한천면ㆍ춘양면", + "MNTN_NM" : "용암산" + }, + "longitude" : 127.0052778, + "latitude" : 34.957500000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", + "MNTN_NM" : "용암산" + }, + "longitude" : 127.0052778, + "latitude" : 34.957500000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용인등봉은 강원도 삼척시 가곡면 풍곡리 덕풍마을에서 볼 때 문지골과 괭이골 사이에 솟아 오른 산릉의 최고봉으로 착한(어진)용이란 뜻을 담고 있다. 용인등봉의 시발점인 산봉우리는 515m봉으로 마을 주민들 사이에서는 개족발봉으로 통한다. 산세가 마치 수캐의 생식기처럼 보여 개족발봉이라 부르는데 한자로 구신암(拘腎岩)이라고도 한다.개족발봉 동쪽 아래에서 문지골과 용소골의 물이 합수되는데 이곳에 패어든 용소골안 제 1용소는 옛부터 제를 지내는 신성한 구역이었다. 개족발봉 동쪽 아래에서 문지골과 용소골의 물이 합수되는데 이곳에 패어든 용소골안 제 1용소는 옛부터 제를 지내는 신성한 구역이었다.제를 올릴때는 여느제처럼 돼지를 올리지 않고 개를 제물 삼아 개의 피를 용소에 뿌렸다는 것이 특이하다. 제 1용소까지 돼지를 끌고 들어가기가 어려워서 재물로 개를 사용했다고 전해진다.산에 밑둥이 두 아름이나 되는 굴참나무가 있다. 제당으로 불리는 이 나무는 심마니들이 제사를 지내는 신목(神木)이라 하니 눈여겨 볼 만 하다.", + "MNTN_HG_VL" : "1124", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "용인등봉" + }, + "longitude" : 129.165651, + "latitude" : 37.067689999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "담양군 용면 용연리 소재 용추산(해발 523m)을 중심으로 사방 4km 주변을 가마골이라고 부르 는데, 여러 개의 깊은 계곡과 폭포, 기암괴석이 수려한 경관을 이루고 있어 사시사철 관광객 의 발길이 끊이지 않는 곳이다. 영산강의 시원으로 유명한 용소가 있고 1986년부터 관광지로 지정,개발되어 관광객을 위한 각종 볼거리, 편의시설, 운동시설, 등산로 등이 잘 갖추어져 있다. 가마골은 깊은 계곡 사이로 쏟아지는 용연폭포와갖가지 기암괴석들이 즐비해 경관이 수려 하다. 또한 약 900명이 야영할수있는 야영장을 비롯해 각족 편의시설이 개발되어 많은 관광객 이 찾고 있다. 용소 윗부분에 있는 출렁다리 또한 빼놓을 수 없는 볼거리를 제공한다.출렁거 리는 다리에서 아슬아슬한 스릴감과 함께 시원한 용소를 바라볼 수 있어 찾는 이가 많다.", + "MNTN_HG_VL" : "523", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 용면 용연리", + "MNTN_NM" : "용추산" + }, + "longitude" : 127.0321063, + "latitude" : 35.436277699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해발 878m의 용화산은 간동면 유촌리, 하남면 삼화리와 거레리, 춘천시 사북면 고탄리에 걸쳐있다. 북쪽으로는 파로호를, 서쪽으로는 춘천호를, 남쪽으로는 소양호의 중심에 위치한 산이다.용화산 준령과 오봉산 사이에 성불령이라는 고개가 있고 여기에 성불사 터가 있다. 옛부터 성불사 저녁 종소리와 용화산 안개와 구름, 기괴한 돌, 원천리 계곡의 맑은 물, 부용산의 밝은 달, 죽엽산의 단풍, 구운소의 물고기 등을 옛부터 팔경이라 불렀다. 산에는 광바위, 심바위, 꼭지바위, 주전자바위, 마귀할미바위, 바둑바위 등 실물을 방불케하는 기암괴석이 있다.", + "MNTN_HG_VL" : "878", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 간동면ㆍ하남면, 춘천시 사북면", + "MNTN_NM" : "용화산" + }, + "longitude" : 127.74382540000001, + "latitude" : 38.039407599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "용화산" + }, + "longitude" : 127.74382540000001, + "latitude" : 38.039407599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문수산(일명 천호산)의 한 지맥이 서쪽으로 뻗어 형성된 해발 342m의 높지 않은 산이다.미륵산 동쪽의 왕궁면,여산면에 걸쳐있는 네 봉우리(옥녀봉,선인봉,노승봉,성태봉)를 통틀어 봉화산이라 말한다.서동공원에서 시작해 용화산의 정상부에 오르면 서쪽으로 익산의 진산인 미륵산이 보이고 여산 방면으로 가다가 우측으로 내려가면 서동요의 전설로 잘 알려진 선화공주사가가 나온다.미륵산과 용화산을 합하며모두 용화산이라 불러왔으나 지금은 미륵사가 있는곳이 미륵산이고 나머지를 용화산이라 한다. 일명 군입산(軍入山)이라고 하는데 고려 태조가 후백제를 정벌할때 군대를 주둔시켰던 곳이기 때문에 붙여진 이름이라고 신증동국여지승람은 기록하고 있다.", + "MNTN_HG_VL" : "342", + "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", + "MNTN_NM" : "용화산" + }, + "longitude" : 127.74382540000001, + "latitude" : 38.039407599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "435", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 둔덕면 거림리", + "MNTN_NM" : "우두봉" + }, + "longitude" : 128.12028240000001, + "latitude" : 35.823721599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북으로 두리봉을 거쳐 가야산국립공원으로 연결되고, 남으로 비계산과 이어지면서 거창군의 동벽 역할을 하고 있는 우두산은 가야산을 모산으로 삼고 있다. 별유산이라고도 불리는 이산의 백미는 정상 서쪽 의상봉과 장군봉을 거쳐 병산으로 뻗어내린 능선이다.거창은 산이 많기로 이름난 곳이라 알려진 산들이 많은데 우두산은 최근에 그 진가가 알려져 산을 좋아하는 동호인들 사이에서 산행인구가 꾸준히 늘고 있다. 빼어난 암릉미로 널리 알려져 있으면서 산 남쪽에 자리잡은 가조온천 덕분에 온천산행지로 이름난 산이다. 힘들게 산행을 마치고 온천에 몸을 풀면 일상의 피로까지도 개운하게 가실 것이다.소요 시간 :1코스 : 4시간 50분고견사 주차장 → 4km(1시간20분) → 마장재 → 3.6km(2시간) → 정상 → 0.8km(20분) → 의상봉 → 0.3km(10분) → 서능 → 2.5km(30분) → 고견사 → 2.2km(30분) → 주차장2코스 : 8시간가조휴게소 → 자인봉 → 마장재 → 정상 → 장군봉 → 가조면 병산마을최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 고견사, 견암폭포숲길 명소 : 은행나무(수령 700년), 쌀굴절을 지을 때 쌓아 올렸던 신라 때의 석축이 눈에 들고 고운 선생이 심었다 하는 은행나무와 만든 때가 새겨진 범종과 석불 의상대사가 수도할 때 두 사람분의 쌀이 나왔다 하는 쌀굴과 십이지신상석이 있다.산행과 더불어 역사와 경관을 맛볼 수 있다.우두산 의상봉은 외부에서 많이 찾아오는 곳이다. 관광버스로 고견사주차장에 내려서 고견사를 거쳐 의상봉에 오르거나 우두산까지 가기도 하고 마장재로 돌아오르거나 더러는 비계산부터 종주를 하기도 한다.의상봉아래에서 장군봉으로 이어지기도 한다. 의상봉은 가파르기 때문에 철계단으로 제법 올라가야하는데 철계단이 그다지 안전해보이지 않는다. 위험요소가 없는지 확인할 필요가 있다. 마장재에서 우두산 오르는 길은 바위지역을 지나가야 한다.", + "MNTN_HG_VL" : "1054", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "우두산" + }, + "longitude" : 128.03433459999999, + "latitude" : 35.760938699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우두산은 고래산과 능선으로 이어져 있으며 신라때 대사찰 이었던 곳에 최근에 지은 고달사가 있다. 고달사는 764년(신라 경덕왕 23)에 창건되었다고 하며, 신라 이래의 유명한 삼원(三院), 즉 도봉원(道峰院)·희양원(曦陽院)·고달원(高達院) 중 하나로 고려시대에는 국가가 관장하는 대찰이었다. 고달사지부도(국보 4)를 비롯하여 고달사원종대사혜진탑비 귀부 및 이수(보물 6), 고달사지석불좌(보물 8), 고달사원종대사혜진탑(보물 7) 등의 문화재가 남아 있다. 불교유적도 찾아볼 수 있어 문화유적 탐방코스로도 인기가 높은 산이다.산행 기점은 곡수리이다. 고래산의 등산로는 동쪽의 쪽다리나 금동 마을에서 오르는 길과 서쪽의 곡수리를 기점으로 하는 코스가 있다. 구둔역에서 남쪽 도로를 따라가다 쪽다리에서 440봉에 올라 정상까지는 육산의 완만한 길이며 정상에는 큰바위로 구성되어 있다.", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평, 여주", + "MNTN_NM" : "우두산" + }, + "longitude" : 128.03433459999999, + "latitude" : 35.760938699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우두산은 9개의 봉우리로 이루어져있는데, 산의 형세가 소머리를 닮았다고 해서 불리는 이름이다. 우두산을 의상봉이라 부르는 이도 있다. 하지만 의상봉은 신라 문무왕 때 의상 대사가 참선하던 곳으로 주변 경관이 빼어나고 아름답긴 하지만 우두산 9개 봉우리 중 2봉일 뿐이다.<>마장재에서 의상봉 구간은 저마다 빼어난 풍광과 수려한 자태를 자랑하며 불쑥불쑥 솟은 바위들이 수도 없이 나타나는데, 산 정상에서는 바라보면 단지봉과 남산제일봉, 매화산, 깃대봉, 두리봉, 가야산 등 수많은 수려한 봉우리들이 사방팔방으로 솟아있다.<>1094봉에서 마장재 사이 넓고 완만한 안부 노른재엔 산철쭉이 군락을 이루며 자라는데, 점차 넓어지는 철쭉 군락 덕분에 매년 5월이면 온통 붉은 꽃밭을 감상할 수 있다.<>산자락에는 신라 애장왕 때 순응과 이정이 창건한 고견사가 있고, 주변으로 숙종이 원효대사를 기려 내린 강생원을 비롯 의상대사가 수도할 때 매일 2인분의 쌀이 나왔다는 쌀굴 등이 있다.", + "MNTN_HG_VL" : "1046", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가북면", + "MNTN_NM" : "우두산" + }, + "longitude" : 128.03433459999999, + "latitude" : 35.760938699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "우암산(338m)은 청주시를 지켜온 산으로서 그 모양이 소가 누워있는 형상과 비슷하다고 하여 일명 와우산이라고도 부른다. 청주시 명암동·내덕동·우암동·수동·대성동·문화동·용암동에 걸쳐 있다.침엽수림과 낙엽수림이 섞인 숲이 우거지고, 약수터와 순환도로·등산로 등이 잘 정비되어 있어 시민들의 휴식처로 널리 이용되고 있다. 높이에 비해 산세가 깊은 탓에 용암사, 목암사, 보현사, 관음사, 광덕사, 문수사, 용화사, 대한불교수도원 등 사찰이 여럿 들어서 있고, 그와 함께 통일신라 말 작품으로 보이는 용암사의 석조비로자나불상, 목암사의 나한입상 등 유적들이 산기슭 곳곳에 산재해 있는 명산이다. 또 정상 부근에 삼국시대 것으로 보이는 와우산성(臥牛山城)이 있다. 와우산성은 《동국여지승람》에는 둘레가 1.587km로 되어 있으나 실제로는 내성 2km, 외성 1,800km로 총 3.8km에 이른다. 지금은 성 주변으로 민가와 농경지가 늘어나 크게 훼손된 상태이다.산 초입부분에는 1919년 3·1운동 당시 독립선언서에 서명한 민족대표 33인 중 충청북도 출신 6명의 동상을 모신 삼일공원이 있다. 또한 산자락에 많은 약수터와 운동시설 등이 있고 정상에서 조망되는 청주시 전체의 모습이 아름다우며 드라이브 코스로 적당한 우암산 순회도로를 갖고 있는 등 시민의 등산지 및 기타 여가활동공간으로서 큰 역할을 하고 있다.", + "MNTN_HG_VL" : "338", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 내덕동, 우암동, 수동, 대성동", + "MNTN_NM" : "우암산" + }, + "longitude" : 127.5038053, + "latitude" : 36.649905699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "운계봉" + }, + "longitude" : 128.78583330000001, + "latitude" : 37.805277799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구름을 다리 삼아 다녀야 하는 절벽산인 운교산은 아래로 옥동천이 구비치는 모습을 내려다 보고 위로 높은 하늘을 우러르는 형상이다. 옥동천에 발을 담그려 다리를 뻗은 채 구름다리를 건너 하늘로 오르고 싶어하는 산의 마음이 전해진다. 산과 산이 연이어지고 그 산들 또한 키를 다투는 영월에서도 오지에 속하는 이 산은 암벽으로 이루어진 능선이 절경이다. 바위마다 석이버섯이 많아 주민들은 석이산으로 부르기도 한다.산행은 중동면사무소에서 시작하며 4봉·3봉·2봉으로 이어지는 암릉길이 등산의 묘미를 더해 준다. 오르막과 내리막이 모두 무척 가파르며 정상에서 동남쪽으로 옥동천을 굽어보는 조망이 아름답다.주변에 청령포와 고씨동굴 등의 명승지가 있다. 이 중 청령포는 단종이 귀양살이를 하던 곳으로, 삼면으로 깊은 강물이 흐르고 한쪽은 깎아지른 절벽으로 되어 있는 천혜의 유형지이다. 고씨동굴은 수억년 전에 생긴 전형적인 석회동굴인데, 길이가 6.3km에 이르며 굴 내부에 호수를 비롯하여 3개의 폭포와 6개의 광장이 있다. 임진왜란 때 고씨 일가가 이 동굴에 숨어 살았다 해서 고씨동굴이라 부르게 되었다는 전설이 전한다. 천연기념물 219호로 지정되었다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 중동면", + "MNTN_NM" : "운교산" + }, + "longitude" : 128.65333330000001, + "latitude" : 37.137500000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운길산(610m)은 경기도 남양주시 조안면 송촌리 북한강변에 위치한다. 이 산은lsquo;구름이 산에 걸려서 멈춘다rsquo; 또는lsquo;길상한 구름에 뒤덮인 산rsquo;이라는 뜻을 함축하고 있다. 수종사에서 조망되는 북한강과 남한강이 합수되는 두물머리의 서정적 풍광이 일품이다. 양수리 풍경은 어디서 봐도 아름답지만 이곳이 진yen;다. 조선 초 판서를 지낸 서거정이 수종사를lsquo;동방에서 제일의 전망을 가진 사찰rsquo;이라고 하여 남긴 시가 있을 정도다. 그러다보니 운길산에 오른다는 건 수종사를 보러 가자는 것과 마찬가지다.검단산을 좌측 배경으로 양수리가 훤히 보이면서 예봉산 아래 정약용 생가 유적지도 눈에 들어온다. 규모는 작지만, 긴 역사와 경관이 기가 막힌 곳에 자리 잡아 꼭 들러야 하는 사찰이다. 송촌리나 진중리에서 올라 수종사만 보고 가도 아쉽지 않다. 정상에서 두물머리쪽은 수림에 가려 전혀 조망이 안 된다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 와부읍", + "MNTN_NM" : "운길산" + }, + "longitude" : 127.2951884, + "latitude" : 37.5720399 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운길산은 서울에서 동쪽으로 40㎞, 북한강과 남한강이 합류되는 양수리에서 서북쪽으로 4㎞ 거리에 솟아 있는 산이다. 산 아래까지 시내버스가 연결되고 있어 교통이 편리하고, 산세가 부드럽고 등산로가 순탄하여 가족산행이나 가벼운 주말산행에 적합한 곳이다.주변에 정다산마을·팔당호·서울종합영화촬영소·금남유원지 등의 관광지가 있고 산중턱에 수종사(水鐘寺)가 있어 볼거리도 많은 편이다. 특히 수종사에서 바라보는 팔당호의 모습은 일찍이 서거정이 동방의 사찰 중 전망이 제일이라고 격찬했을 정도이다. 서쪽의 적갑산(561m)과 예봉산(683m)을 함께 종주할 때 기준점이 되는 산이기도 하다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 조안면 송촌리", + "MNTN_NM" : "운길산" + }, + "longitude" : 127.2951884, + "latitude" : 37.5720399 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 등허리 태백에서 분기한 산줄기가 내륙을 향해 달리다 수려한 봉우리를 만들었으니 그 이름 운달산이라하여 계곡에 흐르는 물이 맑고 차갑기가 얼음같아 일명 '냉골'이라 불리워진다. 용암산(龍岩山)이라고 부르기도 하는 이 산은 문경읍 동북쪽 8km 지점에 위치한다. 산 능선은 길게 동서로 10여km에 걸쳐 뻗었으며, 그 사이의 마전령(馬轉嶺:627m)· 조항령(鳥項嶺:673m) 등 안부(鞍部)가 예로부터 문경과 다른 지방을 연결하는 교통의 요지였다. 산에는 금선대(金仙臺)를 비롯하여 많은 기암괴석으로 덮여 경치가 아름다우며, 남동사면 일대에 화장암(華藏庵)·양진암(養眞庵)·대성암(大成庵)·금룡사(金龍寺) 등 고찰이 있어 많은 관광객이 찾아든다.특히 수령 300년 이상 수고 30여미터의 전나무 숲속에 고목이 조각품마냥 운치를 더해주고 겨울철 눈꽃은 내방객의 넋을 잃게 하고 여름철에는 조용한 곳을 찾는 피서객들이 찾아 온다.또한 운달산은 김룡사를 품고 있다. 김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다. 다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다. 그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", + "MNTN_HG_VL" : "1097", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 용연리", + "MNTN_NM" : "운달산" + }, + "longitude" : 128.19868009999999, + "latitude" : 36.7564888 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운무산은 강원도 횡성군 청일면과 홍천군 서석면 경계에 있는, 규모는 작으나 아름다운 암봉을 갖춘 산이다. 횡성군에는 이렇다 할 산이 없을 것으로 생각되지만 그렇지 않다. 그것은 횡성군이 영동방면으로 가는 길목 이상의 역할을 하지 못했기 때문이다. 그래서 잘 알려지지 않은 아름다운 산이 적지 않다. 발교산, 덕고산, 봉복산, 운무산 등이 그런 산에 속한다. 그 중에서도 운무산은 독특한 암봉미와 아기자기한 능선을 갖추고 있어 아름답다.항상 구름과 안개가 낀 듯하다는 데서 이름이 유래한 운무산은 자연 그대로의 모습이 오롯이 남아 있는 멋스러운 산이다. 아지랑이 하롱하롱 밀려드는 봄날이 오면 야생 벚나무의 향연이 수채화 물감처럼 번져 오른다. 특히 사람의 측면 얼굴을 닮은 듯한 수리봉은 운무산 가운데 가장 전망이 뛰어난 곳으로, 이곳에 서면 운무산 전경과 청량1리의 삼근암과 새대기, 횡성의 산줄기들이 잘 조망된다.", + "MNTN_HG_VL" : "979", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", + "MNTN_NM" : "운무산" + }, + "longitude" : 128.2016667, + "latitude" : 37.650277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동으로 가지산과 이어져 있는 운문산은 산세가 웅장하며 나무들이 울창하여 등산객이 많이 찾는 산이다. 이 곳에는 운문사를 비롯한 크고 작은 절과 암자가 있고, 주변 경치가 매우 아름답다.", + "MNTN_HG_VL" : "1195", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면, 경상남도 밀양시 산내면", + "MNTN_NM" : "운문산" + }, + "longitude" : 129.034167, + "latitude" : 35.676389 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운문산은 가지산에서 서쪽으로 다시 갈라진 능선 상에 솟아 있는 명산이다. 산세가 웅장하며 나무들이 울창하여 산악인이 많이 찾는 산이다. 정상에서의 전망은 남쪽 건너편으로 천황산의 억새밭이 황금빛으로 물결치고 동쪽으로는 가지산으로 이어지는 능선이 용틀임하는 듯 보인다.이 일대는 가지산을 필두로 신불산,운문산,재약산,간월산,취서산,고헌산,문복산등 1,000m가 넘는 대 산군을 이루고 있는 일대를 '영남의 알프스'로 불리어진다. 이중 최고봉은 가지산이며 운문산과는 동서로 약 4km의 거리이며 경상 남북도의 도계를 이루고 있다. 이곳에는 운문사를 비롯한 크고 작은 절과 암자가 있고 주변 경치가 매우 아름다우며 특히 가을철의 억새는 장관을 이룬다. 밀양시 산내면과 청도군 운문면의 경계에 솟아 있는 산으로 주봉 가지산 능선에 잇대어져 있어 가지산까지 능선을 이어 종주 산행을 많이 한다.운문산은 예로부터 호거산이라 부르며 명산으로서 조건을 모두 갖추어진 산이다. 천문지골, 심심이골, 복숭아 골, 상운암 계곡등 깊은 골짜기를 품고 대 사찰 운문사와 천상에 걸린 상운안 및 부속 암자를 두고 있고 동의 보감의 허준이 반위에 걸린 스승의 시신을 해부 한곳이 운문산의 얼음굴이라는 설이 전해 온다.심산 유곡의 깊은 골짜기에는 약초와 나물이 천지이고 기암과 산세가 어우러져 한폭의 동양화를 보는 것 같은 착각에 빠진다.운문산의 산행들머리는 석골사를 지나 상운암 계곡에 들어선다. 계곡마다 계곡수가 넘쳐흘러 계곡을 건널 때는, 그대로 발을 담가야만 한다. 운문산 정상에는 탁 트인 남명리의 벌판이 전개되고, 왼편으로 아랫재가지산 가는 길이며 오른편에 함화산 가는 길이 열려 있다.", + "MNTN_HG_VL" : "1196", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "운문산" + }, + "longitude" : 129.034167, + "latitude" : 35.676389 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "47", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 토성면 운봉리", + "MNTN_NM" : "운봉산" + }, + "longitude" : 128.507882, + "latitude" : 38.2876695 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청평에서 북동쪽으로 약 20km 떨어진 운악산은 일명 경기 소금강이라고 불리울 만큼 뛰어난 모습을 지니고 있다. 주봉인 망경대를 둘러싸고 커다란 바위들이 봉우리마다 구름을 뚫고 솟아 있으며, 오래된 절 현등사와 물 맑은 조종천은 매력을 한층 더해준다.", + "MNTN_HG_VL" : "935", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 포천시 화현면", + "MNTN_NM" : "운악산" + }, + "longitude" : 127.32489889999999, + "latitude" : 37.878003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전라북도 경계선이내에는 1000m 가 넘는 5대 고산이 있다. 그 중 높이가 네 번째인 운장산에서 북쪽으로 뻗어나간 대능선이 칠백이고지를 만들고 여기서 남서쪽으로 갈라진 지맥의 끄트머리에서 아름다운 대아저수지에 그림자를 드리우고 우뚝 솟아 숨어 지내온 수려한 명산이다.구름위에 솟아 있는 바위산이라고 하여 이름도 운암산이라 지었다. 이름에서부터 운치있는 산의 풍광을 떠올리게 되는데 산 정상에서의 조망은 그 기대를 저버리지 않는다. 새만금간척지로 흘러가는 대아댐이 굽어보이며 정상에서 봉화대로 이어지는 수려한 암벽능선이 인상적이다. 정상인 관봉은 옛날 봉수대자리로 그 때의 석축이 지금도 뚜렷하게 남아있다. 서쪽으로 뻗은 능선은 기암괴석으로 이어져 있고, 능선의 남쪽면은 거대한 절벽지대를 이루고 있다. 이 절벽지대는 군부대의 산악훈련장으로 이용하고 있어 입산이 통제되어 있으나 능선 등산에는 지장이 없다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 고산면", + "MNTN_NM" : "운암산" + }, + "longitude" : 127.28103900000001, + "latitude" : 35.988175900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "487", + "MNTN_LOCPLC_REGION_NM" : "고흥군", + "MNTN_NM" : "운암산" + }, + "longitude" : 127.28103900000001, + "latitude" : 35.988175900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산이 높아 구름 같은 기운이 산을 감싸고있다 하여 운암산이라 부르는 고흥의 명산이며, 모악산 이라 부르기도 한다. 운암산은 포두쪽에서 바라보면 두 봉우리가 우뚝 솟아있다. 제일 높은 봉우리가 깃대봉이요, 또 한 앞 봉우리는 마치 부채를 펼쳐놓은듯한 부채봉이다. 운암산 부채봉으로 오르는 길은 세 군대가있다. 사람들의 발길이 거의 닿지 않는 자연의 모습을 그대로 간직하고 있고, 골짜기에는 많은 전설들이 있다. 정상 부근의 빼어난 봉우리들이 줄지어 서 있는 모습과 산길옆 저수지의 에메랄드 빛 초록색의 향연, 깊은 계곡들 그리고 수목들이 가슴 벅찬 아름다움을 느끼게 한다. 산꼭대기에서는 기우제를 지내기도 하였다. 조선말기 총리대신을 지낸 김홍집이 흥양현감으로 재임시 이곳 운암산에 올라 기우제를 올린 사실이 이우제문과 함께 전한다.동산동마을 축사가 있는 하산길로 내려오다보면 유난히 파란색에 빛나는 용은제가 보인다. 용이하늘로 승천하기 위해 때를 기다리며 은거하고 있는 곳이라는\"용은제\"이다.", + "MNTN_HG_VL" : "487", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", + "MNTN_NM" : "운암산" + }, + "longitude" : 127.28103900000001, + "latitude" : 35.988175900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운장산은 전라북도 진안군 주천면, 정천면, 부귀면, 완주군 동상면에 걸쳐 있으며 남쪽과 북쪽으로 흐르는 물은 금강으로 유입되고, 서쪽 계곡으로 흐르는 물은 완주군 동상면을 지나 만경강으로 흘러 금강과 만경강의 발원지 구실도 하고 있다. 북두칠성의 전설이 담겨 있는 칠성대를 지나 한참 더 올라가면 오성대가 있는데 조선조 중종 때의 서출 성리학자 송익필이 은거하였던 곳으로 전해지고 있다.주요 등산코스는 부귀면 궁항리나 황금리로 오르는 코스와 완주군 동상면 신월리로 오르는 코스가 있고 주천면 중사, 외처사동 마을에서 시작하여 동봉으로 오르는 코스도 있다.", + "MNTN_HG_VL" : "1126", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 주천면ㆍ부귀면ㆍ정천면, 완주군 동상면", + "MNTN_NM" : "운장산" + }, + "longitude" : 127.3572838, + "latitude" : 35.910964300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", + "MNTN_NM" : "운제산" + }, + "longitude" : 129.35138889999999, + "latitude" : 35.934444399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구름을 받치고 있는 기둥같다’는 운주산(806.2m)은 팔공산 보현산과 함께 영천의 삼산으로 불린다. 운주산은 높지 않으나 그 품이 넓고 깊어 민초들이 살아온 고된 삶의 흔적이 많이 배여있다. 임진왜란 때는 김백암장군이 이 산에 성을 쌓아 항전했고, 구한말에는 영남지방의 의병조직인 산남의진(山南義陣)이 이곳을 근거지 삼아 포항·영일 일대서 거센 항쟁을 펼쳤다. 또 한국전쟁 때는 많은 피난민들이 이 산에 은신하기도 했다.정상에서는 사방이 훤히 트인 멧부리에서는 굽이치는 낙동정맥의 자태가 한눈에 들어온다. 서쪽으로는 얼어붙은 조양호가, 북서쪽으로는 눈고깔을 하얗게 덮어쓴 보현산이 머리를 내민다. 동쪽으로는 비학산 도음산이 포항시를 감싸고 남쪽으로 도덕산 자옥산이 이어지며 영천시를 보듬고 있다.산 중턱 쯤에 안국사가 있다.안국사는 신라 때 국태민안과 왕실의 번영을 기원하기 위해 기림사와 함께 세워진 유서 깊은 고찰이다. 한때 이 골짜기에 열두 암자를 거느리며 신라 불교의 전성기를 이끌기도 했다. 그러나 구한말 의병 활동의 근거지였던 까닭에 일제에 의해 대부분 불태워졌다. 암자에서 만난 노스님은 지금도 운주산 일대에 당시 승려들이 만든 저수지와 절터가 곳곳에서 발견된다고 말했다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영천시 임고면, 자양면, 포항시 기계면", + "MNTN_NM" : "운주산" + }, + "longitude" : 127.228914, + "latitude" : 36.676924999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조치원읍에서 국도 1호선을 따라 천안방면으로 가다보면 개미고개를 지나 전의면 경계에 이르러 운주산 입구 푯말을 만나 진입로를 따라 올라가면 주차장을 만난다. 등산을 하기 위해서는 주차장에 차를 놓고 등산로(약 1km)를 따라 30여분 올라가면 운주산성 입구에 다다른다. 운주산성은 서기 660년 백제가 멸망하고 풍왕과 복신, 도침장군을 선두로 일어났던 백제부흥운동의 최후 구국항쟁지로 평가되는 역사적으로 중요한 산성이다. 운주산성은 충청남도 지정문화재 기념물 제 79호로 지정, 관리되고 있다.운주산 정상에 오르면 “백제의 얼 상징탑”이 운주산을 찾는 탐방객을 반가이 맞이한다. 운주산에서는 독립기념관, 천안시, 청주시와 맑은 날에는 아산만까지 관망된다. 어린이나 노약자를 동반한 관람객은 운주산 중턱까지 임도가 개설되어 있어 승용차를 이용하여 올라가면 광장을 만나게 된다. 광장부근에서 정상까지는 도보로 약 10여분이 소요된다.정자도 세 곳에 있고 피숫골 주계곡은 수량이 풍부한 편이라 삼천굴,고산사 등 명소도 있다.", + "MNTN_HG_VL" : "460", + "MNTN_LOCPLC_REGION_NM" : "충청남도 연기군 전동면, 전의면", + "MNTN_NM" : "운주산" + }, + "longitude" : 127.228914, + "latitude" : 36.676924999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "939", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", + "MNTN_NM" : "울련산" + }, + "longitude" : 129.23611109999999, + "latitude" : 36.771388899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "울련산은 대동여지도에 울연산(蔚然山)이라 표기되어 있으며 이외에 울람산, 우련산, 우렁산이라고도 불린다.서쪽으로는 즉 수비에 이르는 보잘것없는 능선을 가진것 같지만 동쪽으로는 금장산(848.7m)까지 무릇 8km의 능선이 이어지며 자못 우람한 산세를 이룬다.이 산은 낙동정맥의 동쪽에 놓여있는 산이다. 따라서 금장산과 백암산(1003.7m) 사이의 구슬령에서 동쪽이나 서쪽으로 발원한 물은 신기하게도 모두 동해로 흘러든다.서쪽으로 내린 물은 곧바로 동해로 가지 않고 수비를 경유 울련산 서쪽을 한바퀴 돈 다음 장수포천, 욍피천을 거쳐 동해로 흘러든다.이 때문에 낙동정맥의 마루금을 그을 때 주의해야 하는 지역이기도 하다. 정상은 뾰족하고 좁은 편이나 조망은 매우 좋다. 서쪽으로는 낙동정맥의 능선이 물결치고 남쪽 멀리에는 백암사 능선이 꿈틀거린다. 남쪽 신원천 건너편으로는 남이장군이 칼을 갈았다는 검마산(918.2m)이 보이며 서북쪽으로는 장수포천 너머로 일월산 정상에 서 있는 송신탑과 중계소가 한눈에 들어온다.", + "MNTN_HG_VL" : "939", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 수비면", + "MNTN_NM" : "울련산" + }, + "longitude" : 129.23611109999999, + "latitude" : 36.771388899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "1983년 11월 23일 군립공원으로 지정된 웅석봉은 지리산에서 흘러온 산이면서도 지리산을 가장 잘 볼 수 있는 산이다. 천왕봉에서 시작된 산줄기가 중봉과 하봉으로 이어져 쑥밭재∼새재∼외고개∼왕등재∼깃대봉을 거쳐 밤머리재에 이르러 다시 한 번 치솟는데 이 산이 웅석봉이다.경남 산청의 웅석봉은 이름 그대로 ‘곰바위산’ 으로 불린다. 정상부에서 놀던 곰이 가파른 북사면으로 떨어져 죽었다는 전설에서 유래된 지명이다. 실제로 웅석봉 정상에서 보면 북쪽에 깎아지른 낭떠러지가 있어 곰이 떨어져 죽었다는 이야기가 설득력 있게 들린다.산세가 웅장한 만큼 수려한 계곡도 많다. 정상을 중심으로 뻗어 내린 곰골과 어천계곡, 청계계곡, 딱바실골 외에도 남릉에서 발원하는 백운동과 실골 같은 골짜기는 경관이 뛰어나고 물이 맑기로 유명하다.웅석봉 산행은 산청읍에서 접근해 지곡사쪽에서 오르는 것이 일반적이었다. 하지만 산청읍과 시천면을 잇는 59번 국도가 포장되면서부터 변화가 생기기 시작했다. 산청읍 쪽에서 접근할 경우 1000미터 고도차의 가파른 산길을 치고 올라야 하기 때문에 힘들 수밖에 없다. 하지만 해발 570미터의 밤머리재에서 산행을 시작하면 운치있는 능선길을 따라 쉽게 정상에 오를 수 있다. 능선에서 보는 천왕봉 동쪽 사면의 조망도 뛰어나 인기 있다.", + "MNTN_HG_VL" : "1099", + "MNTN_LOCPLC_REGION_NM" : "경남 산청군 단성면", + "MNTN_NM" : "웅석봉" + }, + "longitude" : 127.8772768, + "latitude" : 35.364010999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문수산(일명 천호산)의 한 지맥이 서쪽으로 뻗어 형성된 해발 342m의 높지 않은 산이다.미륵산 동쪽의 왕궁면,여산면에 걸쳐있는 네 봉우리(옥녀봉,선인봉,노승봉,성태봉)를 통틀어 봉화산이라 말한다.서동공원에서 시작해 용화산의 정상부에 오르면 서쪽으로 익산의 진산인 미륵산이 보이고 여산 방면으로 가다가 우측으로 내려가면 서동요의 전설로 잘 알려진 선화공주사가가 나온다.미륵산과 용화산을 합하며모두 용화산이라 불러왔으나 지금은 미륵사가 있는곳이 미륵산이고 나머지를 용화산이라 한다. 일명 군입산(軍入山)이라고 하는데 고려 태조가 후백제를 정벌할때 군대를 주둔시켰던 곳이기 때문에 붙여진 이름이라고 신증동국여지승람은 기록하고 있다.", + "MNTN_HG_VL" : "342", + "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", + "MNTN_NM" : "원대봉" + }, + "longitude" : 126.94916670000001, + "latitude" : 35.186111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금남정맥상의 운장산(1126m)이 조산인 원등산은 전북 완주군 소양면과 동상면 경계를 이루며 위봉산(524m) 서방산(612m) 안수산(554m) 동성산(550m)과 맥을 같이 하고 있다. 이 산을 중심으로 북으로는 위봉산성과 송광사, 드라이브코스로 제격인 대아저수지와 동상 저수지 호안도로가 이어져 있는데 이렇게 이름난 주변 명소에 밀려 원등산은 손타지 않은 자연을 제법 잘 보존하고 있다.원등산의 옛이름은 청량산이거니와 남녘 자락에 오랜 고찰 원등사가 자리하여 세월이 흐르는 동안 원등산으로 이름이 바뀌었다. 해발 500m에 자리한 원등사에 서면 전주 시내가 한눈에 들어온다. 정상에서는 운장산과 연석산이 보이고 연석사와 연석폭포가 있는 사봉리 협곡까지 손금처럼 훤히 내려다 보인다. 기암절벽이 산줄기 곳곳에 솟아있어 산세가 아름답고 가족이 함께 산행하기에도 좋은 곳이다.해발 500m 지점에 위치한 원등사는 1200년된 고찰로 신라 문성왕 2년 보조선사가 세웠다고 전한다. 보조선사가 사찰을 세우기 위해 그곳에서 멀리 떨어진 무주 향악 난야에서 나무로 만든 오리를 날려보냈는데 오리가 앉은 곳이 원등사였다고 한다. 이곳은 또한 도승 진묵대사가 많은 기행을 남긴 곳으로도 유명한 곳이다. 동란 때 소실된 법당은 아직도 증축하지 못한 채 터만 남아 있다. 바위를 뚫어 만든 굴속에 오백나한을 모셔 놓았는데 지금은 너와집 같은 건물에 법당을 마련하고 나한을 모시고 있다.", + "MNTN_HG_VL" : "713", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군", + "MNTN_NM" : "원등산" + }, + "longitude" : 127.2937072, + "latitude" : 35.8874104 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "168", + "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", + "MNTN_NM" : "원미산" + }, + "longitude" : 126.8024796, + "latitude" : 37.5001526 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한남정맥과 갈라진 산줄기가 북쪽으로 태화산(645m) 백마산(530m) 줄기를 떨구고 동북진하여 광주와 이천을 잇는 넓고개를 건너 솟구친 산이 바로 원적산이다. 무적산(無寂山)이라고도 한다. 동쪽 원적봉(563.5m) 기슭에 638년(선덕여왕 7년)에 창건했다는 영원사(靈源寺)라는 사찰이 있으며, 주봉인 천덕봉 기슭에는 율수폭이라는 폭포가 있다. 고려말 공민왕이 난을 피해 이곳에 머물렀다는 전설이 전한다. 신둔면 장동리 쪽에는 군사훈련장이 있어 입산이 제한되므로 산행은 백사면 경사리 쪽에서 시작한다.전체적인 능선이 부드럽고 완만해 보이지만 산 천덕봉 안쪽으로 암벽이 있으며 이 산의 최고봉인 천덕봉은 높이 635m로 이천군내에서 제일 높다. 산행기점인 송곡마을은 전국 제일의 산수유 산지로 봄이면 농가울타리와 논밭두렁이 산수유의 노란 물결로 일렁이고 가을이 되면 들 곳곳에서 열매를 따는 풍요로운 풍경이 등반객들의 마음을 넉넉하게 채워준다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.", + "MNTN_HG_VL" : "564", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 백사면, 광주군 실촌면", + "MNTN_NM" : "원적산" + }, + "longitude" : 127.4489854, + "latitude" : 37.351347400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "원통산" + }, + "longitude" : 127.68361109999999, + "latitude" : 37.078055599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "원효산은 낙동정맥이 혼신의 힘을 다해 일구어 영남 알프스의 최고봉인 가지산(1240m)의 남쪽 끝에 있는 신불산, 취서산에서 동남쪽으로 흘러내린 지맥에 위치해 있다. 통도 인터체인지에서 5km쯤 남으로 내려오다 보면 왼쪽으로 나란히 서 있는 원효산은 규모로나 높이로나 만만찮은 산이지만 일반인들에게는 그리 널리 알려져 있지 않아 다소 한적한 산행을 즐길 수 있다.현재 원효산은 정상부근이 입산통제구역으로 되어 있어 정상에 오르는 기쁨은 맛 볼 수 없다. 하지만 신라 선덕여왕 때 창건된 흥룡사와 흥룡폭포를 보는 것만으로 산행의 기쁨을 어느 정도 느낄 수 있다. 또한 암벽을 끼고 있는 원효암과 의상대의 모습이 특히 볼만하다.", + "MNTN_HG_VL" : "922", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 상북면, 하북면, 웅상읍, 동면", + "MNTN_NM" : "원효산" + }, + "longitude" : 129.1058333, + "latitude" : 35.400833300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다.", + "MNTN_HG_VL" : "456", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군, 강진군", + "MNTN_NM" : "월각산" + }, + "longitude" : 126.6819335, + "latitude" : 34.721094600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "두산동과 입압동 경계지역에 있는 강릉시내에서 가장 해발고가 높은 산으로 꼭대기에 옛날 봉화를 올렸던 봉수대가 있었다. 지금은 강릉 봉수대비가 있어 유적의 자취를 찾아 볼수 있다. 월대산은 강릉 사주산의 하나이며 봉 서쪽 낙맥에 일제시대에 일본인들이 한국인의 기를 말살시키기 위해 철주 (쇠말뚝)을 박았던 바위가 있다. 월대산 동쪽 마을은 뻗어내린 산줄기가 곡식을 담는 말처럼 생겼다 하여 말산이라 한다. 남쪽면은 경사가 완만하고 북쪽면은 경사가 급한 편으로 거리가 짧은 편이어서 힘든 코스는 아니다. 정상에 오르는 코스가 여러갈래로 갈라져 있어 모든 코스를 등산하면 운동량이 꽤 많은 코스이다. 조망점에서 강릉시내가 한눈에 들어오는 조망권이 좋은 특징이 있다.", + "MNTN_HG_VL" : "75", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 성덕동", + "MNTN_NM" : "월대산" + }, + "longitude" : 128.9252778, + "latitude" : 37.756111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월류봉은 충청북도 영동군 황간면에 솟아 있는 해발 400.7미터의 봉우리다. 이름 뜻 그대로 달이 머문다는 이 봉우리는 달이 머물러 갈만큼 아름답다. 하물며 이곳에선 달이 서쪽으로 그냥 넘어 가는 것이 아니라 능선 모양을 따라 서쪽으로 흐르는 듯 달이 머물다 사라진다고 한다.그리 높지 않지만 빼어난 비경을 지닌 월류봉. 영동 한천팔경이라는 것이 이 월류봉의 곳곳을 세분화하여 일컫는다는 말이 빈말은 아닌 모양이다. 한천팔경 중에서도 산세가 빼어나고 준수한 면모를 지녀 첫손에 꼽히는 월류봉이 당연지사 1경이라면, 3경인 용연동은 월류봉 아래의 깊이를 가늠할 수 없는 깊은 소를 지칭한다. 4경 산양벽은 단애 이룬 월류봉의 기암절벽을 8경은 우암 송시열(1607~1689)이 즐겨 찾던 명승지 월류봉을 감상하며 머물렀다는 한천정사를 말한다.월류봉은 들머리에서 바라보면 토산으로 보이지만 반대편 강가에서 바라보면 기암괴석이 보인다. 봄에는 신록이 우거지고 가을에는 단풍이 아름다워 관광객이 끊이지 않고 있는 산이다. 또 월류봉에 오르면 총강천 건너로 원촌리 구릉성산맥이 한반도의 모양과 똑 닮은 모습으로 자리하고 있는 것을 볼 수 있다.", + "MNTN_HG_VL" : "401", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면", + "MNTN_NM" : "월류봉" + }, + "longitude" : 127.89136310000001, + "latitude" : 36.234184999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "133", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "월봉산" + }, + "longitude" : 127.72486480000001, + "latitude" : 35.729298100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 거창군 북상면(北上面)과 함양군 서상면(西上面)의 경계에 있는 산. 덕유산국립공원 남쪽에 위치한다. 북쪽 능선을 따라 덕유산(1,614m)에 이르고, 남쪽으로는 거망산擧網山:1,184m)에 이른다.동쪽 비탈면은 남강(南江)의 상류인 지우천(智雨川)의 수원이 되고, 동쪽에 위치한 기백산(箕白山:1,331m)과의 사이에 계곡을 이룬다.서쪽 비탈면은 완만하고 남강의 상류 하곡(河谷)을 이룬다. 서쪽의 장수군 장계면(長溪面)과의 사이에 육십령(六十嶺)이 있는데, 영남과 호남지방의 중요한 통로이다. 남강 하곡분지를 둘러싸고 있으며 덕유산에 이어져서 자연경관이 아름답다. 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나다.소요 시간 :1코스 (3시간정도)서상 - 영각사 - 남녕재(기점) - 능선 - 정상2코스 (4시간정도)안의 - 용추계곡 - 수망령 - 큰목재 - 정상 - 남녕재최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나며 남릉과 서북릉의 중턱위로 진달래가 군락을 이루어 천상의 화원을 걷는 기분이 든다.숲길 명소 : 남릉과 서북릉의 중턱위로 진달래 군락월봉산은 덕유산의 명성에 가려 많이 알려지지 않았다가 최근 들어 찾는 이가 늘고있는 산이다. 단독코스로도 다녀올 수 있고 금원산과 연계하여 종주하기도 하고 거망산과 연계하여 종주하기도 한다.함양군에서 안내판과 이정표를 적절히 설치해놓았다. 내계에서 가는 길은 임도길을 많이 걸어야해 산길오르기전에 지치기 쉽다. 남령 안내판에는 식수대가 그려져있지만 찾아보니 없다. 식수대가 있으면 좋을 듯하다.", + "MNTN_HG_VL" : "1294", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 서상면, 거창군 북상면", + "MNTN_NM" : "월봉산" + }, + "longitude" : 127.72486480000001, + "latitude" : 35.729298100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1279", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양", + "MNTN_NM" : "월봉산" + }, + "longitude" : 127.72486480000001, + "latitude" : 35.729298100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월아산은 해맞이, 달맞이가 아름다운 산으로 봉긋한 두 봉우리 사이로 수줍게 떠오르는 해와 달은 한 폭의 그림이다. 달을 토해내듯하다는 월아산은 산이 구릉을 이루고 있지만 숲이 아름답고 아담해 가족 단위 등산인들이 주말을 이용해 즐겨 찾는 산이다. 월아산은 장군대산과 이어지는데 장군대산 높이도 482.4미터밖에 되지 않아 한나절 산행으로 알맞다.진주 동쪽에 있는 월아산은 나라에 한발이 계속되면 나라에서 기우제를 지내던 곳으로 일명 ‘무제등’이라고도 한다. 1950년대까지도 기우제를 지냈다는 기록이 남아있다.산행 들머리는 갈전리의 청곡사와 용아리의 금호지 또는 질매재에서 시작한다. 갈전리 청곡사에서 할 경우 장군대산과 월아산 국사봉을 무리하지 않고 종주할 수 있어 좋다. 표식기가 많이 붙어있으며 등산로 중간에 땀을 식힐 수 있는 편의시설이 갖추어져 있다. 날머리 금호지는 커다란 자연 호수로 물이 맑고 푸르며 깊이가 깊어 명주실 3꾸리가 들어갔다는 전설이 있다. 그러나 지금은 제방둑을 쌓아 농업용 저수지로 만들어놓았다.산행 들머리에 있는 청곡사는 신라 헌강왕 5년에 도선국사가 창건한 절로 남강의 청학이 월아산으로 날아드니 사기가 충만함을 보고 정해진 절터라 전해온다. 절 입구에 있는 방학교와 ‘학을 불러들인다’는 뜻의 환학루가 이 전설을 뒷받침하고 있다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "경남 진주시 금산면ㆍ진성면", + "MNTN_NM" : "월아산" + }, + "longitude" : 128.1900574, + "latitude" : 35.191648100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "달이 떠오르는 모양을 한 산이라는 월아산은 1986년 도시자연공원으로 지정되었으며 북쪽의 봉우리는 달임산 남쪽 봉우리를 장군대라 부르는데, 장군대산 또는 달음산이라고 부르기도 한다. 두 봉우리 사이에 떠오르는 보름달이 인근 금호지에 비치는 모습을 아산토월(牙山吐月)이라 해서 진주 12경 중 하나로 꼽는다.정상은 예부터 기우제를 지내던 곳으로 임진왜란 때 김덕령 장군이 목aring;성을 쌓고 왜적을 무찌르던 곳이다. 시내에서 10분 거리로 가깝고 숲이 아름다워 가족단위의 등산객이 주말마다 즐겨atilde;는 산이다.사찰로는 산 서쪽에 있는ucirc;곡사가 많이 알려졌다.ucirc;곡사(靑谷寺)는 879년(신라 헌강왕 5)에 도선이acirc;건하고 고려말 우왕 때 실상사 장로 상총대사가 중건한 바 있으며, 임진왜란 때 불에 탄 것을 선조와 광해군 대에 걸쳐 복원한 고찰이다.ucirc;곡사 입구의 다리 방학교(訪鶴橋)에는 남강변에서 노닐던ucirc;학이 이곳으로 날아온 것을 보고 도선이 절터로 정했다는 이야기가 전한다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경남 진주시", + "MNTN_NM" : "월아산(장군대봉)" + }, + "longitude" : 128.1900574, + "latitude" : 35.191648100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월악산 국립공원은 충북 제천시 한수면과 덕산면의 경계를 이루는 산으로 백두대간이 이화령을 지나 조령산, 조령, 마패봉, 부봉, 월항삼봉, 하늘재, 포암산을 거쳐 대미산으로 이어지는 중간선 북쪽에 솟아있는 봉우리이다. 넓이 373㎢에 걸쳐 있는 월악산 능선은 백두대간보다 높고 무엇보다도 바위와 암릉으로 형성되어 있어 대간에 비해 능선이 훨씬 두드러져 있다.제천시 한수면과 충주시 살미면의 경계를 이루는 지점에 자리한 월악수리봉은 일반인들에게는 생소한 이름이지만 알고보면 숨겨진 비경들이 많은 명산이다. 산행을 나선 후 곳곳에서 펼쳐지는 기암절벽의 변화무쌍함은 산악인들의 탄성을 자아낸다. 숨은 절경들은 둘러보며 정상에 오르면 어느새 월악수리봉에 대한 애정이 듬뿍 생겨 다시한번 이 곳을 찾고 싶은 마음이 절로 든다.월악산(月岳山 1095.3m) 뒤안길에는 용하구곡이 30리나 늘어서 있는데 월악시루봉은 용하구곡의 서쪽에 병풍처럼 자리한 산이다. 시루봉을 가려면 일단 덕산면을 거쳐야 한다. 덕산(德山)은 이름 그대로 산의 덕을 본다는 뜻으로 덕산면은 예부터 인삼재배 적격지로 유명하다. 산 곳곳에 빼어난 경관이 산재해 있는데 특히 전망대 바위에서의 조망이 일품이다. 전망대 바위에 오르면 서북쪽의 월악산 정상이 울부짖는 호랑이 형상을 하고 있어 보는 이의 마음을 압도하며 동쪽에는 용하구곡 건너로 하설산, 매두산, 문수봉 산릉이 아름다운 풍광을 연출하고 있다.", + "MNTN_HG_VL" : "1095", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면, 덕산면", + "MNTN_NM" : "월악산" + }, + "longitude" : 128.09096439999999, + "latitude" : 36.889304099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월악산(月岳山 1093m) 뒤안길에는 용하구곡이 30리나 늘어서 있는데 월악시루봉은 용하구곡의 서쪽에 병풍처럼 자리한 산이다. 시루봉을 가려면 일단 덕산면을 거쳐야 한다. 덕산(德山)은 이름 그대로 산의 덕을 본다는 뜻으로 덕산면은 예부터 인삼재배 적격지로 유명하다. 산 곳곳에 빼어난 경관이 산재해 있는데 특히 전망대 바위에서의 조망이 일품이다. 전망대 바위에 오르면 서북쪽의 월악산 정상이 울부짖는 호랑이 형상을 하고 있어 보는 이의 마음을 압도하며 동쪽에는 용하구곡 건너로 하설산, 매두산, 문수봉 산릉이 아름다운 풍광을 연출하고 있다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", + "MNTN_NM" : "월악시루봉" + }, + "longitude" : 127.9338889, + "latitude" : 37.163888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월여산은 경남 거창군 남쪽 지맥에 우뚝 솟아 있다. 인근 사람들은 3개의 봉우리로 이루어졌다해서 삼봉산으로도 부른다. 이 산은 산세가 좋아 무학대사가 금계포란형이라 지목하여 유명한 풍수가들이 즐겨 찾았던 곳이다.거창의 지형으로 보아 거창지역의 모든 물줄기는 거창읍을 거쳐 남하면에서 합수하여 합천호에 이르지만 월여산이 위치한 신원천만은 그 아래쪽으로 독립되어 흐르고 있다. 산이 높으면 골 또한 깊어 수량이 풍부하다. 그 물이 맑아 월여산을 찾는 이들을 반긴다. 정상 서쪽면은 층암절벽이 관목과 어우러져 가을 단풍이 특히 아름답다.", + "MNTN_HG_VL" : "862", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "월여산" + }, + "longitude" : 127.9480152, + "latitude" : 35.549462400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옥천군 이원면에 위치한 월이산은 말그대로 `달이 떠오르는 산'이라는 뜻이다. 순우리말로 달이산이라고도 부른다. 산세가 달처럼 둥근 모양이다. 북쪽으로 금강이 흐르며, 기암괴석으로 이루어진 정상 서쪽에 투구처럼 생긴 투구봉과 서봉(507m)이 있고 남쪽 산등성이 아래에는 높이 20m의 옥계폭포가 있다. 달이산 최고의 명소이기도 하며 달이산 줄기와 앞의 국사봉 줄기가 마주칠 듯 맞보고 서있는 사이에 한줄기 시원한 옥계폭포에는 많은 사람들이 찾는다.정상에 오르면 산을 병풍삼아 S자로 휘어져 흐르는 금강이 보이고 멀리 서쪽으로 금강철교·서대산 등이 한눈에 들어온다. 정상에서 서봉(507m)으로 넘어가는 산등성이에 있는 투구봉에서는 밧줄을 잡고 암봉을 오르는 산행의 묘미를 느낄 수 있다. 조선시대에 영동의 박달산과 대전의 계족산 봉수대를 중계하던 봉수대 터가 정상에 남아 있다.", + "MNTN_HG_VL" : "551", + "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 이원면 원동리", + "MNTN_NM" : "월이산" + }, + "longitude" : 127.6561111, + "latitude" : 36.228888900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월출산은 국내에서 규모가 제일 작은 국립공원으로 천태만상의 기암괴석이 수석 전시장을 연상케한다. 남성적인 웅장함을 갖춘 북쪽의 가파른 돌산과 여성적인 섬세함을 갖춘 완만한 남쪽산이 조화를 이뤄 지리산, 변산, 천관산, 내장산과 함께 호남의 5대 명산으로 꼽히고 있다. 신라시대에는 월나산(月奈山), 고려시대에는 월생산(月生山) 그리고 조선시대부터 월출산이라고 불리어졌다.", + "MNTN_HG_VL" : "811", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 영암읍ㆍ군서면ㆍ학산면, 강진군 성전면", + "MNTN_NM" : "월출산" + }, + "longitude" : 126.7104573, + "latitude" : 34.774338800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충주시 상모면에 위치한 월항삼봉은 뽀족한 봉우리 세 개가 나란히 서 있어 삼봉으로 부르기도 하고 산삼이 많이 나는 산이라서 삼봉(蔘峰)으로 부르기도 한다. 산의 형세는 웅장하지 않으나 암봉과 아름드리 장송으로 이루어져 있어 아기자기한 산행의 맛을 즐길 수 있다.월악산국립공원 내에 속하며 가까이에 미륵사지와 수안보온천 등의 관광지가 있어 봄철 산행지로 각광받는 산이다.산 북쪽에 있는 미륵사지는 고려 초기에 조성된 절터이다. 1977∼1978년에 발굴작업이 이루어졌으며 괴산미륵리오층석탑(보물 95)과 괴산미륵리석불입상(보물 96)이 남아 있다. 특히 석불입상에는 신라의 마지막 태자인 마의태자가 동생 덕주공주와 함께 금강산에 입산하는 길에 이곳에 머물러 절을 세운 뒤 석불에 자신의 자화상을 새겨 놓았다는 전설이 서려 있다.", + "MNTN_HG_VL" : "851", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면 미륵리, 경상북도 문경시", + "MNTN_NM" : "월항삼봉" + }, + "longitude" : 128.10508999999999, + "latitude" : 36.806125000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 제천시 한수면 탄지리와 덕산면 신현리 사이에 솟은 월형산은 정상에서 바라다보이는 충주호의 경치와 월악산을 올려다보는 풍광을 만끽할 수 있어 좋은 산이다. 충주에서 단양을 잇는 국도변에서 바로 등산을 할 수 있고 등산거리가 짧아 겨울산행 코스로 제격인 산이다.보기에는 작은 산이지만 월악산은 속이 꽉 찬 만두처럼 다양한 비경들이 펼쳐져있어 산을 오르는 이들을 즐겁게 한다. 월형산 동쪽 송계팔경의 하나인 팔랑소의 시원한 물과 바위들은 여름철 피서지를 찾는 이들로 인해 인산인해를 이룬다. 흐르는 계곡물 옆으로 노송이 하늘을 찌르는 절경은 보기만 해도 마음까지 시원해진다.", + "MNTN_HG_VL" : "526", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 탄지리", + "MNTN_NM" : "월형산" + }, + "longitude" : 127.59622779999999, + "latitude" : 36.1135831 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "523", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "위례산" + }, + "longitude" : 127.2547119, + "latitude" : 36.880067799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "위봉산은 별로 높지 않고 많이 알려져 있지도 않은 산이다. 추줄산이라고도 한다. 삼국시대 백제와 신라의 국경지대를 이루었고 조선시대에는 성리학의 영남학파와 기호학파를 구분짓는 학풍적 경계를 이루었던 곳이다. 하지만 분지에 위봉산성과 위봉사를 품고 있고, 전주의 8경 중 하나라 일컬어지는 2단 위봉폭포도 거느리고 있어 이름만 알려지지 않았을 뿐이지 실세라 할 수 있다. 또한 이 명물들을 구경하면서 오르는 산길은 부드럽게 이어져 마치 공원에 나온 듯한 착각이 들 정도로 편한 산이다.정상에 서면 북으로 동상저수지, 동으로 연석산, 운장산, 남으로 원등산, 마이산, 만덕산, 서로는 종남산, 서방산 등을 조망할 수 있다.위봉사는 604년(백제 무왕 5) 창건된 것인데 한국 불교사찰 31본산의 하나로서 경내에는 보광명전(普光明殿;보물 608) 등이 있다. 위봉산성은 송광사에서 위봉사로 넘어가는 고개 위에 그 터가 남아 있는데 성내에는 행궁과 진전의 터도 있다. 송광사에서 더 깊이 골짜기를 타고 4㎞쯤 위봉산 고개길을 오르면 위봉산성 서문이 나온다. 이 위봉산성 서문을 지나 300m쯤 내려가면 위봉사가 나온다.위봉산성은 이태조의 영정을 봉안하기 위해 축성했던 성이다. 성의 규모는 길이 16㎞, 높이 4~5m, 폭 3m의 홍예석문이 지방기념물로 보존되고 있다. 이 산성은 1675년 (숙종 원년) 7년의 세월과 인근 7개 군민을 동원하여 쌓은 것을 임진왜란, 정유재란, 병자호란을 겪으면서 전주 경기전의 영정과 왕조실록을 묘향산까지 피난시켰고, 무주 적상산성에 설치한 사고도 어려움이 많아 전주에서 가까운 험한 지형을 골라 새로 성을 쌓아서 이태조 영정을 피난시키는데 목적이 있었다. 사찰 앞에서 1백여미터 아래에 있는 위봉폭포가 장관이다. 절벽사이로 비류직하 하는 60여미터의 폭포와 빼어난 경관은 그 아래로 펼쳐진 골짜기, 그리고 동상댐 호반의 절경 등이 어우러져 주말뿐 아니라 평일에도 이곳을 찾는 차량의 행렬이 줄을 잇고 있다.", + "MNTN_HG_VL" : "524", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 소양면, 동상면", + "MNTN_NM" : "위봉산" + }, + "longitude" : 127.2619316, + "latitude" : 35.918517299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "목포시와 다도해를 한눈에 굽어볼 수 있는 높이 228m의 목포 뒷산으로, 기암절벽이 첩첩하여 '호남의 개골'이라고도 한다. 산은 비록 해발고도가 낮으나 산정은 매우 날카롭고 층층기암과 절벽이 많아 경치가 수려하다. 이엉으로 바위 전체를 덮어서 마치 아군의 군량미처럼 꾸며 왜군이 감히 넘보지 못하게 하였다는 설화가 전해오는 노적봉을 비롯하여 해발 228m의 일등바위와 이등바위로 나뉘어져 있다.산정에서는 목포시와 다도해를 한눈에 바라볼 수 있고 그 사이를 오고 가는 크고 작은 선박들의 모습이 마치 한포그이 동양화를 연상케 한다. 동쪽 산꼬리에는 기상관측소 ·시청 ·법원 등 관공서가 있고, 산 중턱에는 유달사 ·수도사(修道寺) ·관음사(觀音寺) 등 사찰이 많다. 서쪽 산록은 바다에 임하며 해수욕장으로 유명하다. 또한 이 산에는 대학루, 달성각, 유선각 등 5개의 정자가 있으며, 산 주변에는 2.7km의 유달산 일주도로가 개통되어 있다. 산 아래에는 4. 19 기념탑, 충혼탑, 가수 이난영이 부른 '목포의 눈물' 기념비 등과 조각작품 65점이 전시된 조각공원과 난공원이 있다.", + "MNTN_HG_VL" : "228", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 죽교동", + "MNTN_NM" : "유달산" + }, + "longitude" : 126.37257219999999, + "latitude" : 34.791997799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국립지리원 발행 지형도에도 마유산으로 표기하다가, 1973년 국토자오선 종주대가 이 산을 통과하면서 당시 대원 중 홍일점이었던 진유명씨의 이름을 따서 유명산으로 부르게 되었다.이 산은 정상에 이르는 능선이 완만하고 부드러우며, 산 전체에 갖가지 나무가 울창하여 봄부터 여름까지 하늘을 가릴 정도이고 여름이면 기암괴석과 우거진 숲이 조화를 이룬 계곡은 수량이 풍부해 절경을 이루고 있다.", + "MNTN_HG_VL" : "864", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "유명산" + }, + "longitude" : 127.48761399999999, + "latitude" : 37.576265100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "98", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "유방산" + }, + "longitude" : 128.46611110000001, + "latitude" : 34.889722200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "유학산은 높다란 바위벽이 병풍처럼 둘러처져 있고 낙락장송이 어우러진 수려한 경치를 자랑하는 산이다. 하지만 6·25전쟁 때는 치열한 격전지였다. 이런 역사적 아픔 때문에 이곳에는 다부리와 왜관지구 두 곳에 전적기념관이 있다. 경치가 빼어나 학이 놀다간 산이라는 이름을 가졌지만, 잊어서는 안될 우리의 가슴 아픈 역사를 간직하고 있기에 문화답사 산행지로 적격이다.유학산은 동봉과 서봉 능선이 동서로 길게 뻗은 산으로 팔공산에서 서쪽으로 이어지는 산줄기의 서쪽 끝에 위치한다. 유학산의 서쪽면은 중턱에서부터 고스락까지 깎아지른 거대한 바위가 병풍처럼 솟아 있다.바위 벼랑이 까마득하게 높아 쉰길이나 된다는 쉰길바위가 있고 학이 놀았다는 학바위, 조망 좋고 시원한 신선대가 있다.", + "MNTN_HG_VL" : "839", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 석적면", + "MNTN_NM" : "유학산" + }, + "longitude" : 128.51033670000001, + "latitude" : 36.064411100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황조리에서 올라가는 코스는 산 중턱 까지 경사가 심하고 임도구간을 만나면 그길로 임도를 따라 등산로 길이 있다. 마교리에서 올라가는 코스도 산중턱까지는 경사가 심하고 첫번째 봉우리를 지나면 완만한 등산로길이 나온다. 숲길주변을 정비해서 인지 깔끔히 되어 있고 가는길 중간중간 마다 이정표가 설치 되어 있다. 삼척시 도계읍 신리와 항조리 사이에 위치하고 있으며 태백산맥에 속한다. 산정에는 육백산면 이라는 고위 평탄면이 있어 한국의 지형발달을 연구하는데 중요한 지표가 된다.둘레에는 해발 1000m가 넘는 봉우리 십여개가 이 산을 호위하고 있으며 이 산줄기는 근산,응봉산으로 이어져 낙동정맥과 만나 부산 금정산까지 뻗어간다.", + "MNTN_HG_VL" : "1251", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍 황조리", + "MNTN_NM" : "육백산" + }, + "longitude" : 129.1083333, + "latitude" : 37.2233333 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "육화산은 북으로 청도군 매전면과 밀양군 산내면 경계 지점이 있다. 육화산은 큰 산, 작은 산, 청계수, 폭포, 적석, 흑석의 6가지를 갖추어 있는 산이라 붙여진 이름이다. 산행은 상동역 앞 슈퍼마켓에서 동곡행 버스를 타고 지전리 중남 초등학교에 내려 내동교를 지나 안내동 마을가지 30여 분 걸어야 한다.마을 입구 고목을 지나 다리를 건너 바로 왼쪽 계곡 따라 포장길을 오르는 길이 있는데 육화에서 구만 종주 코스로 많이 이용되고 있다. 육화산 정상은 한쪽 방향으로 시야가 확 트여 있어 전망만큼은 뛰어나다. 구만산과 그 뒤편으로 이어지는 억산이 파노라마처럼 보인다. 정상 주위에 진달래 터널과 진달래 군락지가 있어 봄이면 장관을 이룬다.", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 매전면 장연리", + "MNTN_NM" : "육화산" + }, + "longitude" : 128.85859429999999, + "latitude" : 35.613249099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주금산에서 남쪽으로 뻗어온 산줄기가 서리산, 축령산을 지나 북한강으로 빠지기 직전에 만들어 놓은 것이 바로 은두봉이다. 은두봉은 북쪽에 위치한 축령산(897m)에 딸린 한봉우리만 사람들에게 인식되어 왔다. 그러다 이 봉우리 서북쪽에 있는 운두목현의 이름을 따서 은두봉이라 불려졌다. 따라서 은두봉은 하나의 독립된 산이 아니라 축령산에 딸린 한 봉우리로 보는 것이 더 타당하다. 그런 의미로 보면 은두봉의 서북쪽 1.5km거리에 있는 오독산(621m)도 축령산에 속한 봉우리라 할 수 있다.예전 마석에서 청평으로 넘나들던 은두목현을 거쳐 동남쪽 능선길을 따라가다 보면 정상에 이르게 된다. 정상에서는 청평댐과 북한강이 한눈에 들어오며 강을 따라 이어지는 연봉의 모습도 눈을 떼지 못하게 한다. 교통이 편한데다 산세가 제법이어서 많은 산악인들의 각광을 받고 있다.", + "MNTN_HG_VL" : "678", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", + "MNTN_NM" : "은두봉" + }, + "longitude" : 127.41861110000001, + "latitude" : 37.841388899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "은석산은 천안시 북면과 병천면에 경계해 있는 높이 455미터 산이다. 산 남쪽엔 신라 문무왕 때 원효대사가 세웠다는 은석사가 있어 예로부터 시인묵객들이 많이 찾았다 한다. 또 사찰 입구엔 백여명이 앉아 쉴 수 있는 반석이 있다.남동쪽 계곡에는 도동서원이 있었던 서원마을이 자리하고 있다. 마을 이름이 ‘서원’인 것은 그 마을에 서원으로는 유일하게 도동서원이 자리하면서 마을 이름까지 서원으로 붙였다고 한다. 이 서원에선 김일손과 목천현 출신 유학자 황종배가 배출되었다고 한다.은석사를 지나면 어사로 유명한 영성군(靈城君) 박문수(1691~1756)의 묘가 있다. 암행어사 박문수는 1727년 정미환국으로 소론이 득세하자 사서에 등용되어 영남 암행어사로 나가 부정관리들을 적발했다. 이듬해 이인좌의 난 때는 종사관으로 출전, 전공을 세워 경상도 관찰사에 발탁되고, 분무공신 2등에 책록되어 영성군에 봉해졌다. 군정과 세정에 밝았으며, 암행어사 때의 많은 일화가 전해지고있다.또 은석산은 불개미로 유명한데 송충이의 천적으로 숲을 보호하는 역할을 한다. 은석산 남쪽에는 병천암이라는 커다란 바위가 있는데 천안시알파인클럽에서 이 바위에 등반길을 개척했다. 코스는 좌벽, 우벽, 중앙벽 등 3면으로 나뉘며 난이도는 5.8급에서 5.12급까지 다양하게 있다.", + "MNTN_HG_VL" : "455", + "MNTN_LOCPLC_REGION_NM" : "충남 천안시 북면ㆍ병천면", + "MNTN_NM" : "은석산" + }, + "longitude" : 127.28273969999999, + "latitude" : 36.781580200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "206", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군", + "MNTN_NM" : "은적산" + }, + "longitude" : 126.5812478, + "latitude" : 34.7552278 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "응복산은 설악산과 오대산을 잇는 백두대간의 중간에 서있는 산으로 오대산으로 들어가는 들머리에 해당하기도 한다. 실제로 응복산에서 오대산 두로봉까지는 10km도 안 떨어져 있어 응복산∼두로봉이나 응복산∼약수산∼구룡령을 잇는 구간을 장기산행 할 수도 있다. 원당초교명개리 계곡은 명개분교에서 북대사 길로 접어들면 얼마간 걷다보면 약수골과 바랑골이 만나는 곳에 닿는데 이곳까지는 임도가 나있다.진달래군락지를 지나 오르게 되는 정상은 주목 한 그루가 자리를 지키고 있는데 시야가 탁 트여있다. 주변에 708년(신라 성덕왕 7)에 원효대사가 창건한 수타사(水墮寺)와 철분을 비롯한 유리탄산·불소·칼슘 등이 들어 있어 만성위장병과 고혈압·빈혈·당뇨 등에 효과가 있다는 삼봉약수터가 있다. 울창한 수림과 맑은 물이 흐르는 계곡을 안고 있는 응복산에는 희귀 동식물과 어류들이 많이 서식하고 있어 훼손 안된 자연의 모습이 어떠한지를 잘 말해주고 있다.산행이 시작되는 서울에서 청도까지는 약5시간이 소요되는 등 교통이 불편하므로 미리 청도에 가서 민박을 알아두거나 통바람계곡에서 야영을 해야 하는 불편을 감수해야 한다. 또한 계곡이 넓어 장마철에는 계곡물이 불어나기 쉬우므로 이 기간에는 산행을 피하는 것이 좋다.", + "MNTN_HG_VL" : "1156", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "응복산" + }, + "longitude" : 128.56705579999999, + "latitude" : 37.875693300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "응봉산은 강원도 삼척군과 경북 울진군의 경계를 이루며 산 주변에 전인미답의 여러 계곡들을 끼고 계곡탐험코스로 적합한 산이다. 응봉산을 중심으로 북쪽의 기곡천과 재랑박골, 서쪽의 용소골, 문지골, 갱이골, 보리골 등이 있으며 남쪽 울진군내에 대광천과 동해안쪽 폭포골, 성우골등이 즐비하게 들어서 있다. 호산에서 버스종점을 지나 1km쯤 들어서면 폐광터가 나오는데 여기서 조금 더 올라가면 연이어진 2개의 폭포가 힘차게 흐른다. 조금 더 올라가면 오른쪽 깊은 계곡 아래로 헤아릴 수 없는 폭포지대를 만날 수 있다. 금강산의 축소판을 연상케 하는 이곳은 3단까지는 시야에 들어오나 그 아래로는 워낙 협곡이어서 몇단까지 폭포가 꺽어져 내리는지 셀 수 없을 정도다. 용소골을 탐험할 경우에는 암벽등반 경험자가 동행해야 하며 20m자일 두동쯤은 있어야 위험지대를 통과할 수 있다.", + "MNTN_HG_VL" : "1000", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면ㆍ원덕읍, 경상북도 울진군 북면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 127.02982609999999, + "latitude" : 37.548176900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", + "MNTN_HG_VL" : "1268", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 127.02982609999999, + "latitude" : 37.548176900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", + "MNTN_HG_VL" : "1268", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 127.02982609999999, + "latitude" : 37.548176900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", + "MNTN_HG_VL" : "1268", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 127.02982609999999, + "latitude" : 37.548176900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우 리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", + "MNTN_HG_VL" : "1268", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍,노곡면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 127.02982609999999, + "latitude" : 37.548176900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 합천호 남쪽 황강(黃江)가에 솟아 있는 의룡산은 `소월출산'이라 불릴만큼 절경이 아름답고 기암괴석이 많은 곳이다. 특히 황강을 막아 만들어 놓은 북쪽 기슭의 조정지와 어울려 한 폭의 산수화 같은 멋진 풍경을 연출한다. 하산길에 본 서릉은 설악산 공룡릉의 축소판 같다. 의룡산 북쪽 황강가에 있는 용문정 쪽에서 이 산을 남쪽으로 바라보면 매우 가파른 바위산이 강기슭에서부터 표고 400여m나 치솟아 있어 어디 한군데 마땅히 발붙일 곳이 없을 것처럼 보인다.이 산은 악견산과 능선이 연결되어 있어서 3.5km 정도만 더 걸으면 의룡산 정상에 오를 수 있다. 정상에서 서쪽 악견산, 황매산 줄기, 북쪽으로 용문정, 북동쪽으로는 황강에 만든 조정지댐과 그 댐 안에 담겨있는 짙푸른 호수물이 발아래 내려다보인다.", + "MNTN_HG_VL" : "453", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", + "MNTN_NM" : "의룡산" + }, + "longitude" : 128.07158609999999, + "latitude" : 35.532140499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 거창 주변에는 험한 산들이 많이 포진해 있다. 그 중 의상봉은 암봉과 골짜기가 조화를 이루어 옛날부터 등산인들의 사랑을 받아 온 곳이다. 의상봉(이상봉 1046.2m)은 가야산 국립공원 남서단에 위치한 바위산이다. 가야산 국립공원은 의상봉 남쪽 고견사 일원과, 의상봉에서 남동쪽 비계산으로 이어지는 능선 일원도 공원지역에 포함시키려 하고 있으나, 거창군의 반대로 2001년 2월 현재 의상봉 동쪽 일원만 국립공원으로 지정해 놓고 있다.또한 억새밭이 유명한 마장재와 쌀굴,견암폭포를 볼 수 있는 곳으로 근래 개발된 가조온천으로 인해 온천산행을 겸할 수 있는 곳으로 각광을 받고 있다.", + "MNTN_HG_VL" : "1046", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "의상봉(이상봉)" + }, + "longitude" : 128.04416670000001, + "latitude" : 35.752222199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 근간을 이루는 백화산(1063m)과 희양산(998m)사이에 우뚝 솟은 이만봉은 충북 괴산군 연풍면과 경북 문경시 가은읍의 경계에 위치해 있다. 이만봉이라는 산 이름은 임진왜란때 이곳 산골짜기로 2만여 가구가 피난을 들어와 이만봉이라 불리었다는 전설과, 옛날 이만호라는 이름을 가진 형제가 이 산에 들어와 살기 시작하면서 생긴 이름이라는 두가지 전설을 간직하고 있다.이만봉은 아직까지 많은 사람들에게 알려지지 않아 자연미가 살아 숨쉬고 있다. 배너미평전, 곰봉, 굴바위 등 환상적인 경관이 산 곳곳에 자리하고 있어 한번 찾은 등산객들을 다시 찾게 하고 있다. 정상에 오르는 도중에 만나는 능선길에는 기암절벽이 자리하고 있어 빼어난 경관을 볼 수 있다. 또 산행 도중 이화령, 월악산, 주흘산 등을 시야에 담을 수 있어 전혀 지루하지 않게 정상에 오를 수 있다.", + "MNTN_HG_VL" : "990", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면", + "MNTN_NM" : "이만봉" + }, + "longitude" : 128.02609659999999, + "latitude" : 36.719266099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "이명산은 경남 사천시와 하동군의 경계에 위치해 있다. 인근의 봉명산과 계명산과 함께 삼명산으로 불리기도 한다.또한 이맹산(理盲山)·전야산(轉也山)·해양전산(海陽轉山)·화전산(花田山)·윤산(輪山)·봉명산이라고도 한다. 군립공원으로 지정되었으며, 산기슭의 다솔사 입구 입석에는 '봉명산'이라 적혀 있다. 삼국시대에는 신라의 남서부 지역 요충지로서 북쪽 산정 부근에 사찰을 세우고 석굴과 마애불상 등을 만들어 적의 침입에 대비하였다.옛 이름 이맹산에 얽힌 전설이 《동경지(東京誌)》에 전한다. 옛날 산 정상에 용지(龍池)가 있었는데 이 용지 때문에 동경(지금의 경주)에서 맹인이 많이 태어난다는 소문이 돌았다. 이에 동경 사람들이 불에 달군 쇠와 모래와 돌을 용지에 집어 넣자 이를 견디지 못한 용이 진교(辰橋) 아래 깊은 호수로 도망갔고 이후 동경에서 맹인이 사라졌다고 한다. 지금도 산 정상 부근에는 구운 돌과 못의 흔적이 남아 있다.등산로는 다솔사 입구에서 시작된다. 다솔사에는 경상남도유형문화재 29호로 지정된 고려시대 석조불상을 비롯하여 극락전(경상남도문화재자료 148), 응진전(경상남도문화재자료 149), 대양루(경상남도유형문화재 83), 보안암석굴(경상남도유형문화재 39) 등의 문화재가 있다.다솔사에서 보안암으로 빠지는 고개를 지나 20분을 더 가면 정상이다. 정상에 오르면 남쪽으로 금오산(849m)과 다도해, 서쪽으로 백운산(1,215m), 서북쪽으로 지리산 능선, 웅석봉(1,099m) 등이 한눈에 들어온다. 정상 아래 등산로에 시루떡을 닮은 바위가 셋 있는데 제일 위의 시루떡 바위에는 불상이 새겨져 있다.", + "MNTN_HG_VL" : "570", + "MNTN_LOCPLC_REGION_NM" : "경남 산청시 곤양면", + "MNTN_NM" : "이명산" + }, + "longitude" : 127.89100500000001, + "latitude" : 35.087016300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "716", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "이방산" + }, + "longitude" : 127.8411984, + "latitude" : 35.304295199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "257", + "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군", + "MNTN_NM" : "이성산" + }, + "longitude" : 127.1822222, + "latitude" : 37.5266667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "인내산" + }, + "longitude" : 129.1022293, + "latitude" : 35.921467 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 충주시에 위치해 있는 인등산은 천등산, 지등산과 함께 삼등산으로 불리기도 한다. 땅 위에 사람이 있고 사람 위에 하늘이 있듯이 천등산, 인등산, 지등산이 북에서 남으로 나란히 위치하고 있다. 그래서 차례로 천(天)ㆍ지(地)ㆍ인(人)의 3재(三才)를 이루는 특이한 이름을 갖고 있다.7부 능선까지 임도가 나 있으며, 정상에 오르면 남쪽으로 지등산과 월악산이 충주호와 함께 보이고 북쪽으로는 천등산과 그 산자락에 있는 서대마을터가 보인다. 충북선 동량역에서 산행을 시작하여 삼탄역에서 산행을 끝내는 철도 산행지로 유명하다.인등산 자락에 위치한 소모천마을에는 돌무더기 가운데 사람 키만한 높이로 장승처럼 세워진 조똘바위가 자리잡고 있는데, 전설에 의하면 옛날 소모천마을의 남자들이 변고로 죽어가자 노승이 이곳의 산세가 요녀의 허리모양을 하고 있으니 요녀 형국의 요부에 혈을 찔러서 음기를 눌러야 한다 하여 큰 돌을 운반해 혈을 누른 곳이 바로 조똘바위라고 한다.정상에서는 남서쪽으로 남한강을, 북동쪽으는 충주호의 지류인 주포천을 끼고 있어 산수가 수려한 편이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "충북 충주시 동량면ㆍ산척면", + "MNTN_NM" : "인등산" + }, + "longitude" : 128.0067454, + "latitude" : 37.057504399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "나라 안팎으로 이름난 산, 북한산이 남쪽으로 보현봉을 솟구치고 다시 북악에서 한 줄기는 동쪽 낙산으로 또 한 줄기는 서쪽으로 뻗어 인왕산을 빚어 놓았다. 풍수상으로 보면 조산인 북한산에서 주산인 북악산에 연결되고 낙산이 좌청룡이면 인왕산은 우백호가 된다.인왕산은 서울 어느 방향에서 오르든지 한 시간이면 오를 수 있고 오르면 조망이 뛰어나다.서울의 중심에 솟아있으며 높지는 않지만 산세는 웅장하다. 특히 동쪽 기슭이 아늑하고 풍치가 빼어나 장안 제일의 명승지라 할 수 있다. 북쪽 자락에 있는 부암동은 무계동이라 불리던 곳으로 중국의 무릉도원에 버금갈 정도의 아름다운 경치를 자랑하던 곳이다.인왕산이란 명칭은 산자락에 인왕사라는 절이 있어 붙여진 이름이다. 조선 중종 때는 필운산이라 불리기도 해, 지금도 사직공원 근처엔 동네 이름으로 남아있다.인왕산하면 떠오르는 이야기가 몇 가지 있다. 그중 첫 번째가 호랑이다. 조선시대 인왕산은 호랑이의 출몰로 호환이 끊이지 않았다. 민가는 물론이요 경복궁이나 창덕궁에까지 들어와 소란을 피웠다. 피해가 커지자 조정에서 군대를 동원해 호랑이를 잡을 정도였다. 불과 100년 전인 1901년에도 경복궁에 호랑이가 출몰한 기록이 있다.수려한 경치 덕분에 인왕산을 배경으로 한 산수화가 많다. 겸재 정선의 ‘인왕제색도’가 널리 알려져있다. 국보 216호인 이 작품은 비온 뒤 안개가 피어오르는 인왕산의 모습을 잘 표현한 걸작이다.또 한 가지 인왕산에 대한 일화는 무장공비사건이다. 1968년 북한의 김신조 일당이 청와대를 습격하기 위해 인왕산 옆 산길로 질러왔다. 그 사건 뒤로 인왕산은 일반인 출입이 통제되었다가 1993년 2월 24일부터 오를 수 있게 됐다.", + "MNTN_HG_VL" : "340", + "MNTN_LOCPLC_REGION_NM" : "서울시 종로구, 서대문구", + "MNTN_NM" : "인왕산" + }, + "longitude" : 126.95930420000001, + "latitude" : 37.584948900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "388", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "일광산" + }, + "longitude" : 129.20754350000001, + "latitude" : 35.2667134 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충청남도 예산에서 서해안으로 나가면 덕산온천과 수덕사를 감싸안고 큰산들이 무리를 이루고 있는 가야산의 장관을 만난다. 가야산은 예산군과 당진군 서산군등 3개군에 걸쳐 들판에 우뚝 솟아 산세가 당당하고 곳곳에 사찰이 자리하고 있어 은은한 풍경을 자아낸다.일락산은 가야봉(677.6m), 원효봉(677m), 석문봉(653m), 옥양봉(621.4m), 수정봉(453m), 상왕산(307.2m)등의 봉우리와 더불어 가야산에 오밀조밀하게 자리잡고 있으며, 가야산은 온통 산을 뒤덮은 철쭉과 진달래가 산행의 즐거움을 더해주고 깨끗한 계곡은 많은 산악인과 관광객의 발길이 끊이지 않는 곳이다.예로부터 많은 문화유적을 간직한 명산으로 상왕산 기슭에 백제의 미소로 불리는 서산마애산존불상을 비롯하여 보원사지, 백암사지, 명종대왕태실 등 유서깊은 문화유적과 개심사, 일락사, 문수사, 송덕암 등의 명사찰이 있으며, 21.06km2의 거대산 산지를 개발하여 산악축산의 요람으로 성장한 한우목장이 있다.", + "MNTN_HG_VL" : "521", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시", + "MNTN_NM" : "일락산" + }, + "longitude" : 126.5948908, + "latitude" : 36.730963199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "664", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", + "MNTN_NM" : "일림산" + }, + "longitude" : 127.0262077, + "latitude" : 34.679327499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "일림산은 전남 보성군 웅치면 용반리, 대산리, 회otilde;면 봉강리와 장흥군 안양면 학송리와 경계에 위치한 호남정맥 중 가장 남녘에서 기운차게 우뚝 솟아 백두 기운을 다시 북으로 돌리는 산이다.제암산이 산릉의ouml;쭉 화원을 대표한다면, 호남정맥 줄기로 한나절 거리인 보성 일림산과 장흥 삼비산의ouml;쭉밭은 2000년부터 개발된 100ha 이상 전국 최대의ouml;쭉군락지를 자랑하며, 제암산과 사자산으로 연결되는ouml;쭉군락지의 길이는 12.4㎞에 달하여 가히 세계적이라 추켜 세울만하다.일림산 정상에 서면 제암산(807m), 무등산(1,186.8m), 월출산(809m),otilde;관산(723m), 팔영산(609m) 등 전남의 명산들이 한눈에 들어온다.등산인들에게 인기 있는 코스는 주차장에서 완경사 계곡 길을 따라 호남정맥 골재에 올라선 다음 골치산~삼비산~일림산을 거쳐 능선을#376;고 용추폭으로 내려서는 코스(3시간30분)로, 삼비산~일림산 사이 안부에서 보성강 발원지로 빠지는 코스도 많이 따른다(2시간30분). 호남정맥 구간인 한치~아미봉(418m)~일림산~삼비산~골치~용추폭 코스는 4시간 정도 걸린다.", + "MNTN_HG_VL" : "664", + "MNTN_LOCPLC_REGION_NM" : "전남 보성군 웅치면ㆍ화천면", + "MNTN_NM" : "일림산" + }, + "longitude" : 127.0262077, + "latitude" : 34.679327499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "178", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", + "MNTN_NM" : "임호산" + }, + "longitude" : 128.86982140000001, + "latitude" : 35.226345799999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "목포시 동쪽에 상동과 용해동에 걸쳐있는 해발 110m 산이다.산중턱에는 체육시설이 있으며 정상에서 바라보면 목포 구도심과 하당신도심 그리고남악신도심을 한눈에 볼 수 있다. 입암산 동남쪽 바닷가에 갓을 쓰고 있는 듯한 바위가 있어 이를 갓바위라 하는데갓바위가 있는 산이라 하여 갓바위산, 입암산이라 하였다 한다.목포팔경 중 입암반조(笠岩返照)라 하여 저녁노을에 물든 바닷가의 갓바위와바위절벽으로 된 입암산에 반사되는 저녁노을의 아름다움을 노래하고 있다.", + "MNTN_HG_VL" : "110", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 상동", + "MNTN_NM" : "입암산" + }, + "longitude" : 126.82715090000001, + "latitude" : 35.4843118 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "내장산국립공원 하면 일반적으로 내장산과 백암산 두 개 산으로 알려져 있지만, 공원 서쪽으로 입암산(687m) 또한 큰 면적을 차지하고 있다. 입암산은 중부 이북의 등산인들에게는 낯설지만 호남 등산인들에게는 오래 전부터 명성이 자자한 산이다. 특히 가을철이면 내장산 못지않게 고운 단풍으로 인기를 끄는 산이다.전북 정읍시 입암면, 전남 장성군 북하면에 위치한 입암산(626.1m)은 정상의 바위가 사람이 갓을 쓴 것 같다는 말과 능선위에 바위가 우뚝 솟아 입암이라 했다는 설이 있다.전라남도와 전라북도의 경계인 이 산은 정읍시 입암면을 가로질러 해발 260m의 노령을 넘다보면 좌측으로 보이는 산이 입암산(해발 626m)이다. 정읍벌의 평야지대와 대조를 이루며 우뚝 솟아 있기에 그 모습은 더욱 인상적이다. 또한 골짜기 깊숙한 곳이 분지를 이루고 있어 군사적 요충지로 지목되기도 했다. 특히 정상부에 위치한 입암산성은 조선 효종때 개축한 것으로 사적 384호다. 입암산은 옛부터 왜적의 침입을 막던 항쟁의 장소였다. 고려시대는 송고비장군이 몽고의 6차 침입을 맞아 이곳에서 몽고군을 물리쳤다고 하며 임진왜란 때는 윤진이 소서행장과 싸우다 전사하기도 했다.", + "MNTN_HG_VL" : "626", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군 북이면, 죽하면, 전라북도 정읍시", + "MNTN_NM" : "입암산" + }, + "longitude" : 126.82715090000001, + "latitude" : 35.4843118 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "157", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 중구 다운동", + "MNTN_NM" : "입화산" + }, + "longitude" : 129.2814722, + "latitude" : 35.580594300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제otilde;시 금성면과 단양군 적성면의 경계를 이르는 작성산(鵲城山)은 북으로 가acirc;산(819.5m), 갑산(776.7m), 호명산(475.3m), 마당재산(661.2m) 산줄기를 이어받고, 남으로 내려뻗어 동산(896.2m), 금수산(1,015.8m)을 빚는다.ucirc;풍호를 서쪽에 낀 작성산은 이웃한 동산과 더불어 제otilde;의 이름난 산이다. 원래 이 산은 현지 사람들이 부르고 있는 ‘까치성산’ 이었는데, 일제시대에 일본인들이 지형도를 만들면서 한문표기인 ‘鵲’자를 사용하면서 작성산(鵲城山)으로 더 알려졌다. 까치성산이란 이름에 얽힌 전설이 있다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명했다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.", + "MNTN_HG_VL" : "840", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면 성내리", + "MNTN_NM" : "작성산" + }, + "longitude" : 128.21611110000001, + "latitude" : 37.036944400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "옛 목천현의 지산으로 개목고개가 있는데 이 고개에는 주인을 구하고 죽은 의구의 전설이 있고 동남쪽에는 병천 활석광산이 있고 산상의 성지는 임진왜란 때 의병장 이복장 장군의 의병을 이끌고 침략해 온 왜병에게 항전하며 지킨 곳이라고 한다.", + "MNTN_HG_VL" : "771", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 병천면 매성리 북면 매송리", + "MNTN_NM" : "작성산" + }, + "longitude" : 128.21611110000001, + "latitude" : 37.036944400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금수산에서 뻗어내린 능선 계곡의 금성면 성내리 무암계곡, 왼쪽이 작성산, 오른쪽이 동산이다. 능선 위에 사람 모습을 한 암봉이 줄지어 있는 모습이 인상적이다. 특히 북한산 인수봉의 축소판이라고 하는 배바위는 암벽훈련장으로도 이용되고 있다. 흔히 금수산에 배바위가 있는 것으로 알려져 있지만 실제로는 작성산에 소재하며, 원래 이름은 까치성산이나, 일제강점기에 일본인들이 지형도를 만들면서 한자 '鵲'자로 표기한 뒤부터 문헌에는 까치성산보다는 작성이라는 이름이 더 많이 쓰이게 되었다.까치성산이라는 이름에 얽힌 전설이 전한다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명하였다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.작성산은 산, 호수(충주호), 계곡, 바위 등을 골고루 갖추고 있는 실속 산행지이다. 그리 높지 않으면서도 아담하고 긴 능선위로 사람형상의 암봉들이 연이어 있다. 그래서 계곡산행을 즐기는 등산객 뿐 아니라 북한산 인수봉의 축소판 배바위는 클라이머 들이 자주 찾으며 암벽훈련장으로도 이용되고 있다.작성산은 정상부근까지 흙이 많은 육산이고 정상 부근에만 기암괴석이 발달한 것이 특징이다. 등산로는 톱날같은 형상의 바위능선 사이로 나 있는데 가을이면 좌우 양편으로 샛노란 은행나무와 붉은 단풍나무가 화려한 색의 대비를 이루며 늘어서 마치 내장산의 단풍터널을 빠져나가는 기분이 든다. 정상에 서면 충주호가 저 멀리 시야에 들어온다.", + "MNTN_HG_VL" : "771", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 금성면, 단양군 적성면", + "MNTN_NM" : "작성산" + }, + "longitude" : 128.21611110000001, + "latitude" : 37.036944400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 괴산에는 군자산이 두 개가 있다. 지도상에는 칠성면에 있는 군자산(948)과 남쪽 능선으로 약 4.5km에 작은 군자산이 있다. 이 지역 주민들은 작은군자산을 '남군자산'이라고도 부른다. 군자산은 옛부터\"\"충북의 소금강\"\"이라 불려왔을 정도로 산세가 빼어나다.속리산 국립공원에 속해 있는 군자산은 온 산이 기암석벽과 암릉을 이뤄 산세가 험준하다. 작은군자산은 바위가 많은 산으로, 산부인과바위, 삼형제바위, 낙타바위 등 기암괴석의 전시장을 연상케 한다.조선시대 당시 수많은 유학자와 문인들이 쌍곡의 산수 경치를 사랑하여 이곳에 소요하였고 수많은 전설을 간직하고 있는 곳으로 전해진다. 구곡은 호롱소, 소금강, 병암, 문수암, 용초, 쌍벽, 선녀탕, 쌍곡폭포, 마당바위 등이다. 산 아래를 흐르는 쌍곡계곡은 물이 맑고 깨끗해서 보는 사람들의 눈을 시원스럽게 할 뿐 아니라 물놀이를 즐기기에도 제격이다. 쌍곡계곡에서 시원스런 나무숲사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2m 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다.정상에서 북동쪽으로 내려서는 주능선에는 설악산의 '용아장성'을 연상케 하는 '용아릉'란 암릉이 산행 재미를 한층 더해준다. 이 산의 남쪽 산자락에는 1981년 재단법인 오운문화재단에서 설립한 '수련마을 보람원'이 자리잡고 있다. 군자산을 더욱 돋보이게하는 것은 쌍곡계곡이다. 쌍곡계곡은 퇴계 이황과 송강 정철의 사랑을 받았던 괴산8경의 하나로 쌍계라 부르기도 한다.계곡의 길이는 쌍곡리 쌍곡교에서 선유동으로 넘어가는 제수리치까지 약 12㎞에 달한다.가을이면 굴참나무, 다래나무, 단풍나무 등이 어울려 단풍숲 터널을 이룬다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단양읍, 대강면", + "MNTN_NM" : "작은군자산" + }, + "longitude" : 127.87860019999999, + "latitude" : 36.737540799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "작은 동산은 제otilde;시와 단양군 경계를 이루는 동산(896m)에서 서쪽으로 길게 뻗은 산줄기가 성봉(825.7m)에서 가지쳐 남서방향으로 뻗어 내리다 모래고개에서 주춤한 다음 솟아 오른 봉우리다. 산의 형세가 작고 아름다울 뿐만 아니라 산줄기를ucirc;풍호에 담그고 있어 작은 동산이라 불린다.작은동산 산행은ucirc;풍면 교리 마을과ucirc;풍랜드 사이의 계곡에서 시작한다. 서너 대의 주차공간이 있다.ucirc;풍랜드 번지점프장 바로 뒤편 도로변이다. 교리마을 주차장에서 시작해도 능선에서 만난다.외솔봉 전후, 모래고개 지점에서 우회하는 길이 많아 등산 시간과 코스를 맘 내키는 대로 조정할 수 있고, 푸른 소나무와 완만한 암릉길,ucirc;풍호반과 주변 산들의 조망이 좋아 남녀노소 편안하게 즐길 만한 산이다.", + "MNTN_HG_VL" : "545", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면 교리", + "MNTN_NM" : "작은동산" + }, + "longitude" : 128.19855190000001, + "latitude" : 37.011857900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "작은 동산은 충북 제천시 청풍면 교리와 학현리 사이에 위치한 산으로 체구는 작지만 경관이 수려하고 아기자기함이 살아있다. 산행곳곳에서 마주치는 산세의 수려함은 산행의 즐거움에 흠뻑 빠지게 한다. 동산으로 이어지는 능선과 작은동산의 정상에서 바라다보이는 전망은 가슴을 푸근하게 할만큼 정겹다. 고향집 뒷산처럼 아늑하고 그러면서도 산세가 뛰어난 작은동산의 산행길은 크게 힘든 지형이 없어 아이들을 동반한 산행길로도 그만이다, 산행길에 만나는 학현폭포와 약물탕계곡은 보기만해도 가슴이 시릴만큼 청량감을 내뿜는다.노송군락으로 에워싸인 길이 8m, 높이 6m, 폭 1m 가량 되는 입석바위가 작은동산 정상이다. 입석바위 아래에는 사과상자 두 배 크기의 자연석 제단이 있다. 예전부터 주민들이 치성을 드리던 장소라 전해진다. 그래서인지 요즘도 제천의 여러 단위산악회들이 여기서 시산제를 지내고 있다.정상에서는 에워싸인 노송군락으로 시야가 막혀 시원한 조망이 터지지 않는 것이 흠이다. 그러나 정상에서 만끽하지 못한 조망은 서릉을 타면서부터 시원하게 터지기 시작한다. 정상에서 서릉으로 10분 거리에 이르면 '추락주의' 안내판이 있는 암릉 위 너럭바위 전망장소(제1전망장소)에 닿는다. 남쪽 아래가 수십 길 절벽인 이곳에서는 학현리가 골골샅샅이 내려다보인다. 학현리 위로는 저승벽, 촛대바위, 궁뎅이바위가 선명하게 드러나 보이는 미인봉 ( 저승봉)이 병풍을 두른 듯 마주보인다. 미인봉 위로는 신선봉과 망덕봉이 살짝 고개를 내민 모습도 보이고, 남동쪽으로는 충주호반 위로 월악산 정상도 시야에 와닿는다.", + "MNTN_HG_VL" : "545", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", + "MNTN_NM" : "작은동산" + }, + "longitude" : 128.19855190000001, + "latitude" : 37.011857900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 주맥인 오대산(1563m)에서 뻗어나온 줄기가 계방산에서 남으로 내려와 백적산을 일구고 그 아래에 힘껏 솟구쳐 일군 봉우리가 잠두산이다. 바로 옆에 백석산이 이웃해 있고 주변에는 오대산, 계방산, 가리왕산, 청옥산, 남병산 등 평창군 일대의 고봉들이 운집해 있다. 잠두산은 산의 형상이 누에벌레를 닮았다 하여 붙여진 이름이다.잠두산 정상은 산죽으로 덮여있고, 백석산 쪽으로 내려가는 넓은 능선엔 억새밭과 콩제비꽃 지대가 있어 아름답다. 산행으로는 맑은 오대천이 흐르는 동쪽이 산세가 완만해서 가족산행으로 좋다. 들머리는 마평리, 수항리, 화의리 어디를 선택해도 좋다.", + "MNTN_HG_VL" : "1243", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "잠두산" + }, + "longitude" : 128.5097222, + "latitude" : 37.5586111 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "완주군 동상면과 진안군 주천면 경계에 자리한 장군봉은 등산객의 발길이 드물어 등산로가 희미하고 표지기도 거의 없는 산이다. 이 산은 슬랩 등반, 침니 등반, 줄타기 등의 교육장으로 활용할 수 있을 정도로 다양하고, 숲도 좋고 계곡이 짧은 거리에서 험하기는 하나 진입로에는 우리나라에서 네 번째로 크고 아름다운 대야저수지와 동산저수지가 있으며, 산길에는 쇠사다리 하나 설치되어 있지 않아서 더더욱 좋다.등산지로는 전북 어느 산과 견주어도 손색이 없는 이 산이 옛 모습대로 깨끗하게 유지되고 있는 것은 눈에 잘 뜨이지 않는 오지에 있기 때문이며, 산 정상에서 내려다보는 암석의 아름다움은 누구나보아도 매료당할 정도이다.", + "MNTN_HG_VL" : "735", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 진안군 주천면", + "MNTN_NM" : "장군봉" + }, + "longitude" : 127.34527780000001, + "latitude" : 35.9697222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 봉화군에 위치하고 있으며 인근 일월산과 마주하고 있다. 풍수지리설에 의하면 장군대작(將軍大爵)의 모기(墓基)가 있다고 하여 장군봉(將軍峰)이란 이름이 명명되어 전하여 오고 있고 동서남북으로 임산도로가 개설되어 있어 접근이 용이하다.장군봉은 그 이름처럼 일월산을 지켜주는 남성산이다. 토산인 일월산이 여성산이라 그 산과 나란히 하면서 일월산을 주켜주기 위해 태동했다는 일설이 전한다. 또 봄철 두릅, 산나물 등이 많아 채취하는 사람들의 발길이 끊이지 않고 있다. 그래도 봉화에서도 가장 험악한 산악지대로 알려진 곳에 있고 찾는 이가 드물어 아직까지는 호젓한 산행을 할 수 있는 곳이다. 그러나 임도가 정상부까지 나있어 산행시간이 많이 걸리지 않는다.북쪽으로는 태백산(1,560.6m)과 청옥산(1,276.5m)을 두고 있고, 남쪽으로는 일월산(1,218m)을, 동쪽으로는 통고산(1,066.5m)을 끼고 있다. 또 서남쪽으로는 도립공원인 청량산(970.4m)을 가까이 하고 있다. 장군봉을 둘러싸고 있는 산들은 모두 사람이 많이 찾는 곳이다. 어쩌면 장군봉은 그들의 위세에 밀려 알려지지 않은 산인지도 모른다.", + "MNTN_HG_VL" : "1039", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 소천면", + "MNTN_NM" : "장군봉" + }, + "longitude" : 127.34527780000001, + "latitude" : 35.9697222 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : " 도시 생활권내의 자연휴양지로 경사가 완만하고 토질은 자갈썩인 점질토이며, 주변에는주로 소나무와 잣나무가 생육하며, 도시근교의 야산으로 부녀자와 젊은 사람이 많이 찾는곳이다. 전문 등산객은 능선을 따라 개설된 주등산로을 따라 대구시 경계까지 등산하는코스를 이용하고 있고, 정상부에서는 전망이 좋아 하양읍과 진량읍 관내을 볼수 있으며운동시설도 잘 되어 있어 많은 사람이 찾는 곳이다.", + "MNTN_HG_VL" : "314", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 하양읍 부호리", + "MNTN_NM" : "장군산" + }, + "longitude" : 127.1994444, + "latitude" : 36.4658333 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "325", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "장군산" + }, + "longitude" : 127.1994444, + "latitude" : 36.4658333 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용문산 북쪽의 992m봉에서 북으로 분기하여 늪산(봉미산)을 빚고 홍천강으로 빠져들기 직전에 장락산을 만들었다.능선 주변에는 기암이 도처에 산재하고 노송이 어우러져 아름다운데다 굽이굽이 흐르는 홍천강을 시종 바라보면서 걸을 수 있는 능선길이 더욱 운치 있다. 능선의 좋은 경치는 전망이 뛰어난 615봉에서부터 시작되는데 깃대봉과 화채봉에서 절정을 이룬다.계곡은 장락골이 제일 좋고, 마곡리 일대 강변의 넓은 모래밭은 모곡 유원지로서 유명하고 형제봉에는 유명한 약수터가 있고, 깃대봉과 화채봉 사이 서편 농바위골 주변에는 강씨굴과 약수터가 또 있다.", + "MNTN_HG_VL" : "627", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 강원도 홍천군 서면", + "MNTN_NM" : "장락산" + }, + "longitude" : 127.5486609, + "latitude" : 37.670588000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼천포의 사람들이 아침등산을 각산으로 간다면 사천의 사람들이 많이 이용하는 아침 등산로이다. 많은 사람들이 이용을 하고있고 가볍게 등산하는 코스로 근처 아파트 단지 주민들이 많이 이용하고 있다.뜸북산이라고도 부른다.", + "MNTN_HG_VL" : "250", + "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시 정동면", + "MNTN_NM" : "장령산" + }, + "longitude" : 127.5553671, + "latitude" : 36.243483400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "978", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창 방림면, 대화면", + "MNTN_NM" : "장미산" + }, + "longitude" : 127.85416669999999, + "latitude" : 37.049999999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장미산은 차령산맥의 줄기로 산 아래로는 남한강 최상류인 평찬강이 흐르고 청태산, 금강산이 위용을 자랑하며 휘둘러있다. 산 이름은 산 모습이 노루꼬리처럼 생겼다 하여 생겨났다. 웬만한 지도책에는 나오지 않고 겉보기에도 밋밋한 산이지만 실제 올라보면 갖가지 기암괴석과 울창한 산림을 보유하여 아기자기한 맛이 있다.정상에서는 북으로 덕수산·등용산, 동으로는 백적산에서 청옥산까지 이르는 능선, 서쪽으로는 오봉산·솔이봉·청태산 등이 어렴풋이 보인다. 자연이 잘 보존되어 노랑괴불꽃, 고추냉이꽃, 줄딸기 등 희귀 식물이 많고 취나물·더덕·곰취·두릅·고사리·씀바귀 등 산나물도 흔하게 난다.봉우리 중에서 6·25전쟁 때 최악의 격전지로 유명한 중대갈봉은 민둥산이었을 때 붙은 이름이며 지금은 수림이 울창하고 거북바위와 표대봉이 있다. 장미산에서 덕수산 사이로 흐르는 금당계곡은 유동마을을 거쳐 개수교, 봉황대로 흐른다. 봉황대는 봉황이 놀았다고 하여 부근 마을에서 길조바위로 숭배하고 있다. 산행은 덕수산(913㎙)을 넘어 남쪽 능선을 따라 이어진 장미산까지 4시간 남짓의 코스. 온통 숲으로 뒤덮여 산 중턱과 정상을 가름하기 조차 힘들다.", + "MNTN_HG_VL" : "980", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 방림면 대화면", + "MNTN_NM" : "장미산" + }, + "longitude" : 127.85416669999999, + "latitude" : 37.049999999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장복산은 진해시와 창원시를 경계로 진해시를 병풍처럼 둘러싸고 있는 높이 582미터 산이다. 장복산은 「세종실록지리지」나 「경상도지리지」에lsquo;長卜山rsquo;으로 나온다. 장복이라는 사람이 무술을 닦은 곳이라는 설과 풍수설에서 이곳에 자리를 정하여 산다면lsquo;오래도록(長) 살만한 좋은 곳(卜居middot;卜地)이 될 것이라rsquo;는 설에서 이름이 유래되었다.해마다 봄이면 화사한 벚꽃이 장복산 기슭을 온통 뒤덮어 찾는 이들의 시선을 사로잡는다. 또한 송림과 편백 등 오래된 나무들이 울창하여 산림욕을 즐길 수 있는 산이다. 장복산 기슭에는 88만 여평의 넓은 녹지대에 장복산공원이 조성되어 있다. 울창한 송림과 만여 그루의 벚꽃이 조화를 이루고 있어 장관을 이룬다. 4월 초에 총 10일간에 걸쳐 군항제가 펼쳐진다. 산 일대에 대광사, 진흥사 등의 사찰이 있다.", + "MNTN_HG_VL" : "582", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 여좌동", + "MNTN_NM" : "장복산" + }, + "longitude" : 128.65882300000001, + "latitude" : 35.172026099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장산은 태백시를 나와 화방재를 넘은 뒤 조금 내려오면 옥동천이 시작되면서 오른쪽으로 보이는 화려한 암봉과 능선으로 이루어진 멋진 산이다. 서울특별시에서 태백산으로 가는 길은 특히 영월을 지난 뒤 고개와 강, 숲과 협곡, 고봉과 단애가 연이어 나타나 어느 지역의 경관이 좋고 어떤 산이 높고 아름다우며, 어떤 강물이 맑으니하고 말하기가 어렵다. 하나같이 높고 아름다운 산이 연이어져 보임에서 그렇다.이산의 장점이라면 남쪽과 서쪽은 바위로만 이루어져서 경관이 수려하고 북쪽과 동쪽은 완사면으로 되어있어 올라가기가 좋다. 경사가 완만하며 바위벽이 가로막고 숲길로 이어지는 반복적인 등산로 이기에 지루함을 못느끼고 너덜지대 끝에 올라서면 시야가 확 트인다 .정상에는 조그마한 삼각점이 있고 두위봉이 시야에 들어오고 백운산,함백산 정상의 중계탑이 선명하고 태백산의 장군봉,천제단,문수봉의 너덜지대와 구룡산으로 이어지는 백두대간의 웅장한 흐름을 볼 수 있다.문자 그대로 장(壯)한 산이다. 암릉도 암릉이거니와 산행의 시작을 맑은 계류가 굽이쳐 흐르는 옥동천에서 시작한다는 것이 장산을 처음 오르는 사람도 탄성을 지르게 한다.", + "MNTN_HG_VL" : "1409", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 상동읍", + "MNTN_NM" : "장산" + }, + "longitude" : 129.14469020000001, + "latitude" : 35.194415200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "많은 사람들이 해운대는 알아도 장산(634m)은 모른다. 장산은 그리 높지 않으나 우람하고 아름다운 산이다. 여기 저기 넓은 억새밭이 있어 가을엔 하얀 억새가 넘실거린다. 장산 능선 자락 여러 곳에 크고 작은 너덜이 있다. 특히 6부 능선길과 8부 능선길 사이에 있는 큰 너덜은 500~600미터대에서 폭 40~50미터 규모로 형성돼 있어 장쾌하고 특이한 광경을 연출한다.무엇보다 장산이 좋은 것은 바다 조망이 있다는 것이다. 끝없이 펼쳐지는 바다는 가슴을 후련하게 해준다. 오륙도가 보이고 멋진 광안대교가 한눈에 내려다보인다. 신증동국여지승람이 밝힌 바와 같이 장산은 일본 대마도를 가장 가까이 볼 수 있는 곳이다. 장산은 억새와 너덜, 그리고 조망 외에도 숲이 울창하며 계곡과 폭포도 아름답다. 대천공원으로 흘러내리는 계곡은 물론 폭포사 위 양운폭포(일명 장산폭포)는 어느 폭포와 견주어도 손색이 없을 정도로 훌륭하다. 장산폭포는 해운8경의 제3경이다.장산 들머리인 대천공원도 볼거리다. 공원에는 상징조형물과 야외무대, 놀이터, 저수지, 체육시설 등이 갖추어져 있다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "부산시 해운대구 좌동", + "MNTN_NM" : "장산" + }, + "longitude" : 129.14469020000001, + "latitude" : 35.194415200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 문경시 가은읍 서쪽에 위치한 장성봉은 예전에는 수정을 캐던 수정광산으로 알려지기도 했지만 그마져도 그 분야에 상관이 있는 사람들이나 알 수 있었을 만큼 알려지지 않은 산이다. 산을 찾는 사람들이 많아지다 보니 요즘은 이름이 덜 알려진 산들이 자꾸만 개발이 되고 장성봉 역시 그런 산들 중 하나이다.장성봉(915m)은 경북 문경시 가은읍 서쪽에서 백두대간의 허리를 떠받치고 있는 숨은 명산이다. 1\/5,000지도에는 높이가 907.8m로 표시되어 있고 산이름이 그렇듯 마치 거대한 만리장성의 일부를 보는 듯한 장성봉은 북쪽으로부터 남진하는 백두대간이 희양산(999m)에서 서쪽으로 꺾였다가 악희봉(843m)을 솟구친 후, 다시 직각으로 꺾여 남족의 대야산(931m)으로 치닫다가 악희봉과 대야산 중간쯤에 이르러 우뚝 솟아 있다.이 때문에 장성봉을 중심으로 12시 방향인 북쪽 악희봉에서 시계바는 방향으로 구왕봉(898m), 희양산(999m), 애기암봉(731m), 둔덕산(970m), 대야산(930.7m), 군자산(910m) 등이 원을 그린 듯 에워싸고 있어 제법 심산유곡에 들어선 것처럼 느껴지는 산이다. 또, 북쪽의 깊고 긴 계곡이 봉암사 계곡인 봉암용곡임을 아는 사람은 많지 않다. 아뭏튼 장성봉은 경북 문경시와 충북 괴산군 경계를 이루는 백두대간 일원의 주말산행코스로 이용되는 여러 산들 중에서 아직까지는 가장 조용하고 오염이 안된 산으로 남아있는 것이 자랑거리이다.등산로가 확실하지 않고, 산 속에 들어서면 이따금 사람을 보고도 놀라는 기색없이 발길을 옮기는 노루와 토끼, 그리고 희귀식물인 솜다리(에델바이스)가 눈에 보이는 것만으로도 장성봉이 얼마나 오염이 안된 산인가를 입증하고 있다.", + "MNTN_HG_VL" : "915", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍", + "MNTN_NM" : "장성봉" + }, + "longitude" : 127.9552778, + "latitude" : 36.701944400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장안산은 장수군과 함양군의 경계선에 있는 백두대간상의 영취산에서 서쪽으로 갈라진 호남정맥의 첫머리에 솟아 있는 기봉이다. 기봉인 장안산에서 섬진강과 금강을 경계로 호남지방과 호서지방까지 뻣어 국토의 약 25%를 점유하고 풍요로운 강산을 이루고 있는 조산, 영산이기에 더욱 아름답게 가꾸어 나가야 한다. 장안산은 이 산맥에 솟아 있는 산중에서도 제일 높고 호남,지방에서는 지리산 덕유산 남덕유산에 이어 4번째로 높은 산이다.이 산은 1986년에 군립공원으로 지정되었다. 기암괴석과 울창한 원시수림을 자랑하는 장안산은 덕산용소와 방화동, 지지계곡 지구로 나뉘어져 아름다운 절경을 이루는 관광지다.", + "MNTN_HG_VL" : "1237", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 장수읍, 계남면", + "MNTN_NM" : "장안산" + }, + "longitude" : 127.5959075, + "latitude" : 35.629946500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장암산이란 이름은 산 정상에 자리잡은 너럭바위에서 비롯되었다. 장암산은 산이름이 그렇듯이 펑퍼짐한 초원을 이룬 정상에 너럭바위가 있는데, 그 모습이 옆에서 보면 마치 물위를 떠가는 조각배를 닮아 신기하기만 하다. 더욱 기이한 것은 이웃하고 있는 태청산은 이따금 눈에 띄는 단단한 바위들이 모가나 날카로운데 비해 장암산 정상에 덩그러니 올려 놓은 듯한 바위는 조각작품처럼 매끄럽게 다듬어 놓은 것 같아 맨발로 올라 앉아도 괜찮을 정도이다.장암산은 전남 영광군 묘량면, 장성군 삼서면에 위치한 나즈막한 산이다. 굴비의 고장 영광군은 서쪽으로는 서해바다를 끼고 있다. 북쪽으로는 전북 고창군과 경계를 이루지만 거의 평야를 이루고 있다. 그러나 장성군과 경계를 이루는 동쪽과 함평군과 경계를 이루는 남쪽은 400m?600m 높이로 솟은 산들이 성곽처럼 에워싸고 있다.장암산에서 남서쪽으로 활시위처럼 휘어지는 산릉은 남쪽 함평군과 경계를 이루며 불갑산(516m), 모악산(348m), 군유산(403m), 월암산(338m)을 연속적으로 들어올린 다음 그 여맥을 서해바다에 가라앉힌다.장암산은 훌륭한 등산코스일 뿐만 아니라 행글라이더들에게도 인기가 대단하다. 그만큼 정상에 오르면 마치 비행기를 타고 하늘 위에 떠있는 기분에 휩싸일 만큼 시원한 파노라마가 펼쳐진다. 행글라이더들이 뛰어내리는 방향인 서쪽 아래로는 묘량면 곡창지대 들판이 시원하게 터지며 멀리 영광읍 너머인 백수 방면 서해바다가 가물거린다.북으로는 대마면 들판 너머로 고창군 곡창지대가 시원해게 펼쳐진다. 대마면에서 오른쪽으로 하늘금을 이루는 태청산과 얼랑산 풍광도 일품이며 남으로 불갑산으로 내다르는 산릉이 첩첩산중을 이루어 장암산에 오른 보람을 만끽하고도 남는다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 묘량면, 삼서면", + "MNTN_NM" : "장암산" + }, + "longitude" : 128.4221124, + "latitude" : 37.3872778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 평창군에는 유난히 전인미답의 1000m급 고봉들이 모여 있다. 장암산은 주변에 남병산(1149m)을 비롯하여 가리왕산(1560m), 청옥산(1256m), 백덕산(1350m)등이 인접해 있어 그 유명한 산들의 위세에 눌려 이름조차 생소한 산이다.첩첩 산중의 미답지인만큼 원시림에 가까운 수림이 주를 이룬다. 이 산 서쪽으로는 오대산 산자락에서 발원한 물줄기가 속사천을 거쳐 평창강과 남한강으로 흘러들면서 장암산을 끼고 돌아 주위경관이 더욱 수려하다. 특히, 이곳의 명물인 국내 최대의 송어 양식장이 자리하고 있어 산행 후 회나 매운탕을 별미로 맛볼 수도 있다. 장암산은 남병산을 베게 삼아 남북으로 길게 누웠는데 반으로 갈라 북쪽은 장암산이라고 하고 남쪽은 송계산이라고 한다 .송계산이라 부르는 연유는 옛부터 그 자락에 살아온 송씨들의 계모임에서 그렇게 불렀다고 한다. 최근 들어서는 페러글라이딩 동호회 회원들이 최고로 꼽는 활공장으로소의 역할을 톡톡히 하고 있다.", + "MNTN_HG_VL" : "833", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "장암산" + }, + "longitude" : 128.4221124, + "latitude" : 37.3872778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 옥천군에 자리한 장용산은 정상 봉우리의 모양새가 멀리서도 눈에 띨 만큼 이채롭다. 기암괴봉들이 엉켜 절경을 연출하고 있어 산을 찾는 사람들에게 기쁨을 준다.장룡산 마성산 사이의 고개를 사목재라고 하는데 장룡산에서 사목재쪽의 암릉은 왕관바위 등 기암괴봉이 이어진다. 이 암릉 동쪽(옥천쪽)비탈에는 절 용암사가 있으며 서쪽 사면은 포옹바위, 병풍바위 등 기암괴봉과 암벽으로 이루어져 있다. 이 경관 좋은 서쪽 비탈 아래 옥천군에서 조성한 장룡산휴양림 시설의 하나로 장룡산 중봉 아래 정자까지 지어 놓았다.용암사는 서기 552년 신라 진흥왕 13년에 의신조사가 속리산에 법주사를 창건하기 전에 이곳의 산세를 보고 신비로움에 감탄한 나머지 절을 세웠다고 한다. 이 절 왼편 언덕에는 충청북도 유형문화재 제3호인 쌍석탑이 있고 절 뒤에는 역시 충청북도 유형문화재 제8호인 여래입상을 양각한 마애불이 있다.", + "MNTN_HG_VL" : "656", + "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 군서면 금산리", + "MNTN_NM" : "장용산" + }, + "longitude" : 127.5663661, + "latitude" : 36.242428199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "안평산은 금남정맥의 산줄기가 대둔산 태고사 앞산인 오대산을 타고 내려와 대전광역시 남서쪽 끝에 와서 불끈 힘을 모아 솟아올린 산이다. 안평산 은 덩치가 우람하고 수림이 매우 울창하며, 아직 때가 묻지 않은 산으로 산 언저리에는 두메산골의 풍경이 그대로 간직되어 있기도 하다.안평산의 이름은 산 속에 만인이 피난을 와서 살 곳이 있다고 해서 안평산이라 부르게 되었다고 하며, 이 산 위에 있는 장태산 휴양림은 대전광역시8경의 하나로서 관광명소로 자리잡아 가고 있다.또한 수양,압점.안평의 세 봉우리로 이루어진 안평산은 옛날부터 시인 묵객들이 자주 찾았던 곳이며,임진왜란 때는 의병활동의 본거지 역할을 했을 것으로 짐작된다.장안동 주민들이 애착심을 갖고 관리하고 있는 산으로 코스와 등산로가 잘 정비되어 있다.울창한 수림,오지를 걷는 듯한 사면길,안평산 정상의 가슴 확트이는 조망봉에서 바라보는 용태울 저수지 방향의 그림같은 풍경,신앙 굿당지들의 이색볼거리 등 대전에서는 잘 알려지는 않은 산이다. 마을 주민들이 등로를 정비 개발하고 주황색 물호스를 잘라 리본을 만들어 코스코스 마다 매달아 놓아 리본을 따라 진행하면 어려움이 전혀 없다.안평산 정상에서의 조망은 사방으로 뛰어나며, 특히 구불거리며 흐르는 유등천이 인상적이다.", + "MNTN_HG_VL" : "471", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구", + "MNTN_NM" : "장태산" + }, + "longitude" : 127.8977778, + "latitude" : 37.068055600000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "재래봉" + }, + "longitude" : 129.19864290000001, + "latitude" : 35.713271400000004 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "재약산은 영남 알프스 산군중의 하나로 영남 밀양 청도 일대에 위치해 있다. 해발 1,000미터 이상의 준봉들로 이루어진 재약산(사자봉)은 산세가 부드러우면서도 정상 일대에는 거대한 암벽을 갖추고 있다.125만평에 이르는 재약산 동쪽의 사자평 고원은 광할한 분지가 온통 억새풀로 뒤덮혀 있다. 우리나라에서 가장 넓은 억새벌판이다. 억새풀이 밀집해 자라는 곳만도 5만평에 이른다. 재약산은 해발 1,108m의 수미봉과 1,189m의 사자봉으로 이루어져 있다. 사자평고원은 두 봉우리 사이의 해발 800m 지점부터 완만한 타원형의 언덕들로 이어진다.사자평 억새는 어른 가슴정도 밖에 안 올 정도로 키가 작다.산아래 밭둑이나 길가의 억새에 비하면 절반밖에 되지 않는다. 잎새도 가늘고 투박하다. 꽃이삭은 거친 산정의 바람에 닳아서인지 뭉툭하고 짧다. 그래서 가는 바람에는 이삭 끝의 낭창거림을 보기 어렵다.", + "MNTN_HG_VL" : "1119", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면ㆍ산내면, 울산광역시 울주군 상북면", + "MNTN_NM" : "재약산" + }, + "longitude" : 128.9793348, + "latitude" : 35.547564700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고흥군 금산면 거금도에 솟아있는 적대봉은 마치 바다에 떠 있는 고래등 같은 모습을 하고 있다. 녹동에서 여객선으로 20여분 정도 걸리는 거리로, 뭍과 그리 멀리 떨어지지 않은 거금도는 섬 자체가 하나의 면을 이룰 정도로 커다란 섬이면서도 멀리서 바라보면 둥그스름한 하나의 산처럼 보이기도 하다.섬 안에 큰 금맥이 뻗어 있어 거금도라 불린다는 이 섬의 한가운데 솟아 있는 적대봉은 북쪽으로 천등산, 마복산이 서쪽으로 장흥 천관산과 마주보고 있다. 섬 산이면서도 고흥군에서는 팔영산 다음으로 높아 펑퍼짐한 산세와 달리 전망이 매우 뛰어나다. 이러한 지형적 특성 때문에 조선시대에 축조된 둘레 34미터, 지름 7미터의 큰 봉수대가 정상에 있다.정상에 서면 서쪽으로 완도, 남쪽으로 거문도, 동쪽으로 여수 일원의 바다와 섬들이 한눈에 들어올 뿐만 아니라 날씨가 좋으면 멀리 제주도가 바라보일 정도로 전망이 좋다.산행은 적대봉 서쪽 능선을 가로질러 거금도 남북을 잇는 임도의 북단에 위치한 성치마을에서 시작, 파상재를 거쳐 정상에 올라 파상재로 내려선 다음 송광암을 거쳐 면소재지로 내려서는 코스가 가장 즐겨 찾는 코스다.산기슭에는 조선시대에 목장성이 있었던 것으로 알려져 있다. 거금도는 이웃한 소록도, 절제도, 시산도, 나로도와 함께 도양 목장에 속한 속장의 하나였으며 이 산을 중심으로 성을 쌓아 말 116마리를 키웠던 세납 목장이 있었다. 거금도 남북을 가로질러 석정리와 어전리를 잇는 임도 곳곳에는 아직도 목장성 흔적이 남아 있다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 금산면", + "MNTN_NM" : "적대봉" + }, + "longitude" : 127.1802778, + "latitude" : 34.462222199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "적상산은 사방이 깎아지른 듯한 암벽으로 이루어져 있으며, 그 절벽 주변에 유난히도 빨간 단풍나무가 많이 서식하여 가을철이면 마치 온 산이 빨간 치마를 입은 여인네의 모습과 같다 하여 붙어진 이름이다. 이 산에는 장도바위, 장군바위 등 자연 명소와 함께 최영 장군이 건의하여 축조했다는 적상산성(사적 제 146호)이 있다.이는 고려 공민왕 23년(1374) 최영 장군이 탐라를 토벌한 후 귀경길에 이 곳을 지나다가 산의 형세가 요새로서 적지임을 알고 왕에게 축성을 건의하여 건설된 것이라 한다. 현재의 성은 조선 인조6년(1628년)에 다시 쌓은 것으로서 둘레가 8.143㎞에 이른다. 적상산성 안에는 고찰 안국사 등 유서깊은 문화유적이 있어 이 곳을 찾아온 사람들에게 운치를 더해 준다.한편 고려 충렬왕 3년(1227년) 월인화상이 창건했다고 전해지는 안국사 및 조선시대 인조 21년(1643년)에 창건한 호국사도 있다.", + "MNTN_HG_VL" : "1031", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군 적상면", + "MNTN_NM" : "적상산" + }, + "longitude" : 127.6897512, + "latitude" : 35.947660200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "적석산은 바닷가의 산으로 산 아래 양촌에 온천이 있어 산행 뒤 온천욕을 즐길 수 있으며 다도해를 바라보며 맛있는 회를 저렴한 가격으로 맛볼 수 있는 곳이다. 또한 주변의 명소와 유적을 돌아볼 수도 있는, 실로 1석 3조의 산행지다.적석산 정상은 넓은 반석으로 남북이 바위로 까마득하게 낭떠러지를 이루고 있다. 적석산은 이름 그대로 납작바위를 차곡차곡 쌓아 올린 것처럼 보이는 산이다. 그래서 쌓을 적(積)자를 써서 적산이라고도 한다. 온 산이 바위로 되어 있다 하여도 과언이 아닐 정도로 기이하고 괴상한 바위와 돌들이 널려 있다. 적석산의 고스락은 깎아지른 바위 낭떠러지여서 조망이 좋다. 마산 앞바다와 북쪽에 오봉산, 동북쪽으로 여항산, 서북산이 보이고 동쪽으로 광려산이, 머리를 살짝 내밀고 있는 마산의 무학산도 볼 수 있다.", + "MNTN_HG_VL" : "492", + "MNTN_LOCPLC_REGION_NM" : "경남 마산시 진전면·고성군 회화면·창원시", + "MNTN_NM" : "적석산" + }, + "longitude" : 128.36944439999999, + "latitude" : 35.109444400000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 평창군과 영월군에 걸쳐 있는 절개산은 아직 일반인들에게는 덜 알려진 곳으로 산행의 발걸음이 잦지않다. 에머랄드빛 평창강이 휘감아도는 청정지역으로 산세 또한 깨끗함을 자랑한다. 정상에 노송한그루가 자리하고 있어 절개산의 최고지임을 증명한다. 동남쪽으로 영월 봉래산과 태화산등이 조망되고 날씨가 좋은 날은 멀리 소백산까지도 시야에 들어온다. 호젖한 오르막길과 갖가지 산나물이 지천으로 생명력을 자랑하는 능선길을 걷다보면 시원한 강바람이 내내 산행길을 함께 했음을 느낄 수 있다.절개산은 이름 그대로 신념이나 신의를 굽힘이 없고 변하지 않는 절개를 대표하는 산이다. 이 산 서쪽 평창강이 에돌아 깎아 세운 뼝대 위에 관굴과 민굴이라 하는 응암동굴이 있다. 임진왜란 때 여기에 배수진을 치고, 권두문 군수는 휘하 장졸, 백성들과 함께 단기 3925년, 서기 1592년 8월7일부터 5일간 응암동굴을 본부로 삼아 왜적과 혈전을 벌였던 유적지다. 또한 군수의 부인 강소사는 왜병의 포로가 될 때 절벽에서 투신, 초개와 같이 목숨을 버려 절개를 지켰다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군, 영월군", + "MNTN_NM" : "절개산" + }, + "longitude" : 128.40283840000001, + "latitude" : 37.324562800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "334", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천", + "MNTN_NM" : "절산" + }, + "longitude" : 127.471637, + "latitude" : 34.976263000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한계령 오른쪽으로 보이는 점봉산은 설악산 대청봉과 남북으로 마주보며 설악산 국립공원의 일부를 이루고 있다.주요 관광명소로는 12담 구곡으로 불리는 주전골이 있는데, 좌우로 갖가지 모양의 바위봉우리, 원시림, 맑은 계곡물이 어우러져 절경을 이루며, 특히 주전골 입구의 오색약수터는 빼놓을 수 없는 관광지다. 군사지역으로 출입이 통제되고 있는 것이 안타까울 뿐이다. 지소 조금 아래쪽 안국사로 오르는 길은 돌비탈을 지나야 하고 길도 애매하므로 산행기점은 일반적으로 서창리지소를 택한다.", + "MNTN_HG_VL" : "1426", + "MNTN_LOCPLC_REGION_NM" : "강원도 양양군 서면, 인제군 기린면ㆍ인제읍", + "MNTN_NM" : "점봉산" + }, + "longitude" : 128.4252587, + "latitude" : 38.049280499999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "평창 청옥산(1256m)을 모산으로 해 동강을 품은 산으로 자생식물이 많고 하늘을 가리는 잡목이 우거져 있는 등 천연의 모습이 잘 간직돼있다. 심마니들을 심심찮게 볼 수 있는 것도 이 때문이다.돌리네 현상으로 땅이 꺼지면서 산줄기가 겹쳐진 형상을 하고있어 근동에서는 겹산이라 부르며, 정상은 봉분처럼 생겼다하여 묘봉, 요봉이라 한다. 산행을 마치고 동강변의 비경속에서 피서를 즐기기에 적당하다. 실제 산행을 하다보면 심밭굼이라 하는 움푹 꺼진 곳은 숲이 무성한 긴 계곡으로 나타난 난해한 지형이다.", + "MNTN_HG_VL" : "823", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "접산" + }, + "longitude" : 128.4891374, + "latitude" : 37.265738200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "374", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 고아읍 이례리,원호리,봉한1리,대망2리,예강1리,예강리,항곡리,", + "MNTN_NM" : "접성산" + }, + "longitude" : 128.32762840000001, + "latitude" : 36.186809699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정각산은 경남 밀양시 단장면 한적한 곳에 자리 잡고 있다. 삼각산(887m)과 인접해 있으며 말발굽형상으로 연결되어 있는 이 산에는 유독 묘(墓)들이 눈에 띄게 많다. 그만큼 풍수지리상 좋은 자리를 차지하고 있다는 설이 있다. 대신 등산객들은 찾아 보기 어렵고 발길 닿지 않은 자연림의 형태를 잘 보존하고 있는 곳이다.정상 가까이에 묘(墓)가 많이 있으며, 이웃한 삼각산(887m)과 말발굽 모양으로 이어져 있다. 산행은 표충사에서 4Km 떨어진 범도리 아불마을에서 시작하여 정상에서 능선을 따라 삼각산을 마주보고 내려가다가 송백리로 빠져 내려온다. 산 아래로 남천이 남서쪽으로 흐르며, 산 동쪽 재약산(1108m) 자락에는 신라 진덕여왕 8년 원효대사가 창건한 표충사가 있다. 표충사에는 청동함은향완(국보 75), 삼층석탑(보물 467), 석등(경남유형문화재 14), 표충서원(경남유형문화재 52) 등의 유물이 남아 있다.", + "MNTN_HG_VL" : "860", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면", + "MNTN_NM" : "정각산" + }, + "longitude" : 128.90484180000001, + "latitude" : 35.547757799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "상림2리 다리 앞에서 차도 따라 서쪽으로 나가다 계곡 갈림길과 만나면 오른쪽 계곡길로 들어 교회 앞을 지나 15분쯤 올라간 갈림길에서 왼쪽 계곡기로 급경사를 올라가게 된다. 차츰 왼쪽 지능선으로 붙어 올라가게 되고 능선 따라 노고봉에 이른다.왼쪽(남)능선길로 들어 잠시 내려갔다가 올라가면 정광산 정상이고 남릉 따라 3개의 봉우리를 넘어선 안부에서 왼쪽(동)계곡길로 들어선다. 계곡 아래 내려서면 시어골이고 차도 따라 상림2리 다리 앞이다.", + "MNTN_HG_VL" : "563", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 모현면", + "MNTN_NM" : "정광산" + }, + "longitude" : 127.2812524, + "latitude" : 37.323208899999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정승골은 신라때 어느 왕이 병을 고치기 위해 재약산 표충사에 머물고 있을 때 수행한 정승이 이곳에 머물며 대기했다고 전해져와 붙여진 이름이다.산행 들머리는 밀양 산내면 남명리 남명초등학교 앞이다. 이곳은 하양마을이나 삼양마을을 거쳐 바로 운문산으로 갈 수 있고, 천황산이나 백운산 정족산 구천산 억산 등 영남알프스의 웬만한 봉우리로 손쉽게 접근 가능해 산꾼들은 흔히 이곳을 영남알프스의 '베이스 캠프'라 부른다. 정승봉에 오르면 시원한 바람에 마음의 문까지 활짝 열린다. 성장에는 표지도 없고 좁아서 몇몇 사람이 서 있기에도 마땅치 못하나, 조망은 뛰어나다.", + "MNTN_HG_VL" : "803", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면", + "MNTN_NM" : "정승봉" + }, + "longitude" : 128.87570880000001, + "latitude" : 35.440996499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남한강과 남한강의지류인 경안천 사이에 솟아있는 산으로 팔당댐을 기준으로 하면 왼쪽인 북쪽의 양수리에서 북한강과 남한강이 합류하고 남쪽인 광주쪽에서 남한강의 경안천이 흘러드는 광주군 초월면 방향으로 팔당댐이 깊숙이 파고 든다.4백미터 남짓한 나지막한 산으로 별로 눈에 띄지 않는데다 교통도 그리 좋은 편이 아니라 찾는 이들은 그리 많지 않다. 하지만 막상 산을 찾아가면 주변 일대에 풍기는 강촌의 향취와 정상에서 내려다 보는 한강의 풍경에 감탄한다. 남북한강이 어우러지는 양수리 부근에 빼꼼히 솟아 오른 정암산은 한강을 발아래 두고 오르는 산행의 묘미가 일품이다.주변에 신라 문무왕(文武王) 때 쌓은 주장성(晝長城)의 옛터를 활용하여 1624년(인조 2)에 축성한 남한산성(사적 57)이 있다.", + "MNTN_HG_VL" : "403", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 남종면", + "MNTN_NM" : "정암산" + }, + "longitude" : 127.34154669999999, + "latitude" : 37.514297800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "700", + "MNTN_LOCPLC_REGION_NM" : "경상북도 양산시", + "MNTN_NM" : "정족산" + }, + "longitude" : 126.487099, + "latitude" : 37.632629100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정족산은 산의 생김새가 마치 세 발 달린 가마솥과 같다고 해서 이름 붙여진 산이다. 정족산에는 단군이 세 아들을 시켜 쌓았다는 삼랑성이 있다. 일명 정족산성이라고도 하는 삼랑성은 사적 제130호의 돌성이다. 성의 시설물로는 남문루와 동문, 서문, 북문지가 있고 성 안에는 13개의 우물이 있었다고 전하며 고구려시대에 창건된 전등사가 있다.전등사는 이 삼랑성안에 있는 사찰이다. 고구려 소수림왕 11년(372) 아도화상이 진종사(眞宗寺)라 이름한데서 시작되었다.\"\"신증동국여지승람\"\"에 의하면 충렬왕 8년(1282) 왕의 원비인 정화궁주 왕씨가 승려 인기(印奇)에게 송나라에 들어가 대장경을 가져오게 하여 이 절에 보관했다고 한다. 전등사라는 이름은 정화궁주가 불전에 옥으로 된 등잔을 올린 뒤 붙여진 이름이다. 특히 정족산에는 `조선왕조실록'을 보관했던 사고터가 남아 있어 유적답사 및 가족산행을 하기에 가장 적합한 곳이다.산행은 전등사에서 시작된다. 전등사의 요사채 뒤로 난 길을 곧바로 올라가면 정상에 닿을 수 있다. 정상에서는 나무에 둘러싸인 전등사의 고풍스러운 모습과 마니산과 서해바다의 모습을 한눈에 바라 볼 수 있다.", + "MNTN_HG_VL" : "200", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 길상면", + "MNTN_NM" : "정족산" + }, + "longitude" : 126.487099, + "latitude" : 37.632629100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제비봉은 충북 단양군 단양읍에서 서쪽인 충주호 방면으로 약 8km 거리인 장회리에 위치한 산으로, 단양팔경의 절정인 구담봉과 옥순봉에서 서남쪽 머리위로 올려다 보이는 바위산이다.유람선을 타고 구담봉 쪽에서 이 산을 바라보면 충주호를 향해 부챗살처럼 드리워진 기암괴봉과 바위능선이 마치 제비가 날개를 활짝 펴고 나는 듯한 형상을 갖추고 있다하여 제비봉이라 이름 붙여졌다 한다. 충주호 건너편 금수산도 단풍이 빼어나지만 바위산과 어우러진 제비봉의 단풍은 더욱 장관인데, 특히 정상에서 조망은 북쪽 발 아래로 충주호의 그림같이 시원한 경치가 보이고 그 뒤로 금수산이 우뚝 솟아 있으며 동쪽 멀리 소백산 연능이 스카리라인을 이루고, 서북쪽 아래로 단양팔경중 으뜸인 구담봉과 옥순봉이 인접해 있어 손에 잡힐 듯 하다. 이들 경치를 구경하며 산행의 묘미를 실컷 만끽할 수 있음은 물론이다.", + "MNTN_HG_VL" : "721", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", + "MNTN_NM" : "제비봉" + }, + "longitude" : 128.25608639999999, + "latitude" : 36.926274999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "순천의 제석산은 호남정맥에서 갈려져 남쪽으로 흘러내린 금전산과 오봉산 줄기의 끝자락에 위치한 산이다. 행정구역상 순천에 속해있긴 하지만 벌교 사람들은 벌교의 제석산이라고 부른다. 그럴만한 것이 벌교 어디서든 고개만 들면 보이는 곳이 제석산이기 때문이다. 능선에 올라서면 넓은 낙안벌과 순천만으로 이어지는 벌교 앞바다가 훤히 내려다보이는 전망이 특히 뛰어난데, ‘제석’은 하늘에 있는 33개의 하늘 중 가장 마지막에 있는 하늘인 도리천에 있으면서 모든 하늘을 다스리는 제석천왕을 뜻하는 불경에 나오는 이름이다.한편 벌교란 지명은 뗏목으로 잇달아 만들어 놓은 다리를 뜻하는 말로, 예전 이곳에는 벌교천을 가로지르는 뗏목다리가 있어서 벌교란 지명이 생겼다고 한다. 하지만 이 다리가 무너지고 이후 보물 304호로 지정된 홍교가 건설되었다고 한다.제석산과 벌교는 조정래의 대하소설 「태백산맥」의 주무대가 되는 곳으로 곳곳에 그 자취를 발견할 수 있어 산행뿐 아니라 문학탐방으로도 그 가치가 높다고 할 수 있다.정상에는 1995년 벌교의 제석산악회에서 세운 표지석이 있다. 이곳 행정구역이 벌교가 아닌 순천임에도 벌교에서 표지석을 세운 이유는 그만큼 벌교 사람들이 이곳을 많이 찾는다는 것이다.", + "MNTN_HG_VL" : "560", + "MNTN_LOCPLC_REGION_NM" : "전남 순천시 별량면, 보성군 벌교읍", + "MNTN_NM" : "제석산" + }, + "longitude" : 127.36750000000001, + "latitude" : 34.869166700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남도 끝자락 전남 장흥에 있는 제암산은 철쭉이 전국에서 제일 먼저 피는 곳 중의 한 곳으로 철쭉명산이다. 해발 807미터의 산으로 호남정맥의 한 줄기를 이루고 있다. ‘제암’이란 이름은 정상에 우뚝 솟구친 ‘임금바위’에서 생겨났다. 이 산은 5월 초면 곰재를 사이에 두고 솟은 곰재산의 철쭉 산상화원이 연출된다. 곰재산은 기암괴석의 험준한 제암산과 달리 평원을 이룬 듯이 나지막하게 솟아 있다. 그 능선에 전국 제일의 철쭉 군락이 있다.제암산의 지형도 상 높이는 779미터이지만 정상의 높이는 807미터이다. 그 차이는 임금 제(帝)자 모양의 임금바위가 있고 없음의 차이인 듯 하다. 임금바위는 수십명이 앉을 수 있을 정도로 편편한데 제암단이라 하여 예부터 기우제를 지내던 곳이 있다.", + "MNTN_HG_VL" : "807", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥 안양면·보성 웅치면", + "MNTN_NM" : "제암산" + }, + "longitude" : 126.97551730000001, + "latitude" : 34.709934199999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "평창군 도암면, 성산면 어흘리와 왕산면 왕산리 사이에 있는 높이 841m의 산이다. (구)대관령 휴게소에서 1시간가량 오르면 정상에 오를 수 있다. 정상에서 상제민원(옛길 주막터)방향은 내리막길의 연속으로 지세는 급,완경사지로 이루어져 있고 지형적으로는 능선을 따라 이동하면서 자연스럽게 계곡으로 이동하게 되고 대관령박물관 옛길 코스에서도 오를 수 있다.대관령 능선의 어디에서나 강릉 시가지를 볼 수 있지만 제왕산성에서 내려다 보는 강릉 시가지는 특별하다. 시야에 막힘이 없어 시원하고도심의 모습과 바다로 흐르는 남대천의 흐름까지를 전부 조망할 수 있다.소요 시간 :2시간정도최적 탐방 시기 :매년 음력 5월 5일에는 단오제가 열리고, 10월에는 율곡제·무천제가 열린다. 하지만 4계절 모두 경치가 좋음명소 : 국사성황당 및 산신각, 신재생에너지전시관, 양떼목장, 대관령박물관볼거리 : 산세가 완만하며 상제민원의 계곡이 뛰어나고, 참나무숲과 낙엽송이 우거진 수풀이 곳곳에 있다.평창군 도암면과 강릉시 성산면 경계에는 선자령이 있고, 북쪽으로 영동고속도로를 사이에 두고 대관령 및 오대산국립공원과 마주본다.숲길 명소 : 강릉영림서의 임간학교가 제왕산 계곡에 있어 삼림욕을 즐길 수 있고, 어흘리에 대관령 박물관이 있어 옛 얼을 느껴 볼 수 있다.백두대간의 한구간으로서 능경봉과 선자령구간을 탐방할 수도 있으며 뛰어난 조망점을 자랑하고 있다.", + "MNTN_HG_VL" : "841", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 성산면", + "MNTN_NM" : "제왕산" + }, + "longitude" : 128.78527779999999, + "latitude" : 37.687777799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "높이 887m의 비교적 낮은 산인 조계산은 1979년 12월 도립공원으로 지정되었는데, 산세가 부드럽고 아늑한 것이 특징이다. 산 속 깊은 계곡에는 젖줄과 같은 맑은 물이 흐르며, 만수봉과 모후산이 송광사 일대를 병풍처럼 둘러싸고 있어 마치 어머니 품처럼 포근함을 느낄 수 있다. 전국 3대사찰의 하나인 송광사와 고찰인 선암사가 주능선을 중심으로 동서에 자리하고 선암사 계곡을 흐르는 동부계곡은 이사천으로 남부계곡은 보성강으로 흘러들게 된다.선암사 둘레에는 월출봉, 장군봉, 깃대봉, 일월석 등이 줄지어 솟아있어 장관을 연출한다. 조계산 산행은 송광사나 선암사 어느 쪽에서 시작해도 비슷한 시간대에 다양한 코스를 즐길 수 있으며, 산세가 험하지 않고 평탄한 길이 많아 연인끼리 또는 가족단위 소풍코스로도 알맞다. 송광사 3대 명물중의 하나인 800년이 넘은 천연기념물 쌍향수도 이곳을 찾아오는 사람들의 눈길을 끌고 있다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 승주읍ㆍ송광면", + "MNTN_NM" : "조계산" + }, + "longitude" : 127.31361099999999, + "latitude" : 35.002499999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조계산으로 이름하기 이전에 이 산에 나무하러 간 농부가 넘어져 죽어 원통하다 하여 원통산이라고도 하였고 산이 조개처럼 생겼다하여 음차(音借)하여 조계산이라 한다. 문화 유적으로 불대사터, 무애암 등이 있다.", + "MNTN_HG_VL" : "473", + "MNTN_LOCPLC_REGION_NM" : "", + "MNTN_NM" : "조계산" + }, + "longitude" : 127.31361099999999, + "latitude" : 35.002499999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1189", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면 대기리", + "MNTN_NM" : "조고봉" + }, + "longitude" : 128.7668238, + "latitude" : 37.564401699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조령산은 경북 문경시와 충북 괴산군을 나누는 백두대간 마루능선을 이루는 산의 하나다. 충북과 경북에 걸쳐 있는 이화령과 조령3관문 사이에 위치하고, 산림이 울창하며 대암벽지대가 많아 기암괴봉이 노송과 어울려 한폭의 그림을 보는 것과도 같이 아름답다. 문경새재를 허리춤에 안고 있는 조령산은 산보다 재가 더 유명하다.이화령(큰세재)에는 휴게소와 대형 주차장이 있고, 북쪽 구새재는 조령 제 3관문(조령관)이 있으며 관문 서편에는 조령산 자연 휴양림이 조성되어 있어 여러사람이 찾아와도 부담이 없다. 주능선 상에는 정상 북쪽으로 신선봉과 치마바위봉을 비롯 대소 암봉과 암벽 지대가 많아 산의 웅장한 면모를 느낄 수 있고, 능선 서편으로는 수옥 폭포와 용송골, 절골, 심기골등 아름다운 계곡이 있어 여름철 산행으로 그만이다.", + "MNTN_HG_VL" : "1025", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 경상북도 문경시 문경읍", + "MNTN_NM" : "조령산" + }, + "longitude" : 128.04363900000001, + "latitude" : 36.770401 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙영산과 이웃해 있는 조봉산은 충북 괴산군 청천면에 뿌리를 내리고 있으며 각종 기암괴석으로 조각된 듯한 바위만물상들이 마치 새의 입부리처럼 뾰족한 형태를 이루고 있다하여 산 이름을 조봉산이라 지었다.산 자락에는 신비스러운 자연석굴인 굴바위를 비롯하여 거대한 벽돌처럼 보이는 마당바위, 행상바위, 맷돌바위, 베틀바위, 코뿔소바위, 구멍바위, 북바위 등 바위 군락지가 있어 산행인들의 눈을 쉬지 않게 해 준다. 자연석굴을 지나면 급경사 내리막길이 시작되며 이곳 중턱에 이르면 산부인과 바위라 부르는 구멍바위가 나타난다.구멍바위를 통과해도 계속 내리막길이 이어지는데 겨울철 적설기에는 반드시 보조자일이 필요하다. 이 산 남쪽으로는 용대천 계곡이 흐르고 있어 여름철 피서지로도 그만이다.", + "MNTN_HG_VL" : "687", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "조봉산" + }, + "longitude" : 126.6750438, + "latitude" : 35.7556273 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조비산은 처인구 백암면 용천리,석천리,장평리에 접해 있는조그마한 돌산이다. 새가 날아가는 형상같다하여 조비산이라 부른다하며 산향이 한양도(漢陽都)를 등지고 있다하여 역적산 즉 적비산이라 부른다. 용인팔경의 하나인 조비산은 동국여지지 죽산현편에 보면현 북쪽 십오리에 한 봉우리가 돌연 우뚝 솟아 돌을 이고있는데 산이 높고 가파라서 빼어난 모양이 기이 하게 보인다.", + "MNTN_HG_VL" : "260", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 백암면", + "MNTN_NM" : "조비산" + }, + "longitude" : 127.3672222, + "latitude" : 37.118888900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "857", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 재산면 동면리", + "MNTN_NM" : "조산봉" + }, + "longitude" : 129.01527780000001, + "latitude" : 36.8313889 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "800", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군", + "MNTN_NM" : "조항산" + }, + "longitude" : 129.37995799999999, + "latitude" : 35.756602999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조항산은 청화산과 이웃해 있는 산으로 해발이 제법 높은데 비하여 많이 알려지지 않아 인적이 드문 산이다. 조항산에 오르기전에 삼송리라는 마을을 거치게 되는데 이곳에는 천연기념물 제 290호로 지정된 `용송'이 볼만하다. 수령 약 600여년이 된 소나무로 밑둥둘레가 약 5m에 높이가 15미터나 되며 용의 형상으로 가지를 드리운 폭이 20미터가 넘는다. 주변에는 아름드리 노송 20여그루를 거느리고 있어 일명 왕소나무라 불리기도 한다.정상에 오르면 북쪽으로는 대야산과 둔덕산 줄기너머로 군자산 장성봉, 희양산이 보이고 남으로는 청화산이 서쪽으로는 백악산 정상이 한눈에 들어온다.갓바위재와의 중간지점에 있는 병풍 같은 암릉지대가 이 산에서는 제일 절경이며, 정상 서편 770봉 주변 암릉지대에 있는 거암군 또한 일품이다.", + "MNTN_HG_VL" : "951", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면, 충청북도 괴산군 청천면", + "MNTN_NM" : "조항산" + }, + "longitude" : 129.37995799999999, + "latitude" : 35.756602999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "종암산은 산세가 온순한데다 산악동호인들의 발길이 뜸했던 산 답지 않게 길이 또렷하고 잡목과 수풀의 훼방도 거의 없다. 눈 아래로 펼쳐지는 부곡하와이의 전경과 손 에 잡힐 듯한 창녕의 진산 영축산 조망도 그림 같다.특히 등산로 입구에서 만나는 함박산약수터(향토문화경승지 제19호)는 1천2백 여년의 역사를 지닌 영산의 명소로 당뇨와 위장병에 특별한 효험이 있는 것으로 알려져 있다. 신라시대 한 효자나무꾼에 얽힌 전설을 간직한 이 곳에는 사시사철 사람의 발길이 끊이지 않는다.", + "MNTN_HG_VL" : "546", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군", + "MNTN_NM" : "종암산" + }, + "longitude" : 124.83666669999999, + "latitude" : 40.0341667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 포천군 관인면에 있는 종자산(643m)은 그 모양새부터 범상치 않다. 한탄강을 굽어보며 마치 병풍처럼 솟은 산으로 절벽으로 이루어졌다 해도 과언이 아니다. 하얀 물줄기와 수직으로 솟은 절벽은 서로에게 조금치의 양보도 없이 한껏 자신의 아름다움을 자랑한다. 그 모습이 눈이 부셔 이곳을 찾는 이들의 산행을 더디게 하며 진달래와 단풍 또한 좋다.정상 남동편 들머리에는 굴바위가 있는데 전설에 의하면 옛날 3대 독자의 부부가 아이를 못 낳아 고심하던 중이 굴에서 백일기도를 올린 뒤 아들을 낳았다고 하며 종자산(씨앗산) 명도 여기에서 유래되었다고 한다.정상에 다다르면 오른쪽 깎아지른 듯한 낭떠러지 아래로 고남산과 은장산 사이에서 흘러 내려오는 한탄강이 보인다. 동북쪽으로는 철원평야가 아련하고 북쪽으로는 향로봉을 지나 지장봉, 고대산으로 이어지는 능선이 가물가물하다.", + "MNTN_HG_VL" : "643", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 관인면", + "MNTN_NM" : "종자산" + }, + "longitude" : 127.1907673, + "latitude" : 38.077864900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "추가령곡에서 발원한 한탄강이 철원평야를 지난 뒤 임진강과 합류하기 전에 만나는 것이 종자산이다. 우리말로 씨앗산이라 하는 종자산은 주위의 보장산이나 불무산, 은장산과는 다른 모습의 암산으로 보는 이를 압도한다.지릉에만 올라서도 산을 휘돌아 가는 한탄강의 푸른 물결이 내려다보인다. 산중 곳곳에 암릉이 버티고 있으며, 수십 명의 등산인들이 쉬었다 갈 수 있을 정도의 커다란 굴도 있다.잡목이 섞인 암릉을 통해 정상에 다다르면 오른쪽 깎아지른 듯한 낭떠러지 아래로 고남산과 은장산 사이에서 흘러 내려오는 한탄강의 물줄기가 구절양장이다. 동북쪽으로는 철원평야가 아련하고 북쪽으로는 향로봉을 지나 지장봉, 고대산으로 이어지는 능선이 가물가물하다.정상에서 가장 가까운 산행의 들머리는 포천군 관인면 중리의 늘거리다. 산행 중에는 물을 구할 수 없으므로 근처 민가에서 미리 식수를 충분히 준비해야 한다.", + "MNTN_HG_VL" : "643", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 관인면", + "MNTN_NM" : "종자산" + }, + "longitude" : 127.1907673, + "latitude" : 38.077864900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "종현산은 신북면 덕둔리 북쪽에 우뚝 솟아 있으며 경기 포천 산악지역의 상징적 존재이기도 하다. 그러나 경기도의 소금강이라 불리는 소요산(532m) 북쪽에 인접한 산으로 유명한 산과 이웃해 있고 교통이 불편하다는 이유로 사람들 사이에 많이 알려지지 않은 산이다.높이 600미터도 못 미치는 낮은 산이지만 기암괴봉과 아기자기한 계곡미가 일품이며 온 산을 뒤덮은 활엽수림과 덩굴숲이 아늑한 분위기를 자아내 조용한 산행을 즐기기 좋다. 능선에서 내려다 보는 경치는 여느 산 못지 않게 아름답다.종현산 기슭에 삼정골이라는 취락이 있는데 조선 초기 난을 피하여 세 정승이 이 곳에 와 은거하면서 외부와의 접촉을 일체 끊고 산수를 벗삼아 일생을 살았다 하여 삼정골이라 부르게 되었다는 전설이 전해지고 있다. 병풍처럼 둘러싸여 있는 계곡에는 산내천이 서류하여 한탄강으로 흘러 내려간다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 청산면", + "MNTN_NM" : "종현산" + }, + "longitude" : 127.1233601, + "latitude" : 37.980375600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "좌구산은 미원면 대덕리와 증평군 증평읍 율리의 경계를 이루는 산으로 청원군에서 가장 높은 산이다. 계곡을 따라 이어진 숲길에는 사람이 다닌 자취는 거의 없고 멧돼지가 헤집은 흔적만이 곳곳에 있다.잘 뻗은 낙엽송 군락을 비록하여 다양한 활엽수가 산행을 즐기게 한다. 풀숲에는 으아리 참취가 곳곳에 군락을 이루고 대표적인 독초로 꼽히는 천남성과 부자도 자주 눈에 띄이며, 이산은 한남금북정맥 종주 구간에 포함되어 있는 산이다.", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군, 청원군", + "MNTN_NM" : "좌구산" + }, + "longitude" : 127.6513729, + "latitude" : 36.708345700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "658", + "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", + "MNTN_NM" : "좌구산" + }, + "longitude" : 127.6513729, + "latitude" : 36.708345700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;거북이가 앉아 있는 형상gt;청원군 미원면 대덕리(大德里)와 괴산군 청천면(靑川面) 사이에 자리하고 있다. 한남금북정맥의 줄기이면서 가장 높으나 날카롭지 않고 둥글둥글한 모양새를 지니고 있다. 조선 광해군 때 벼슬을 지냈던 김치(金緻)는 임금의 폭정에 시달리다 신변의 위협을 느껴 관직을 그만두고 좌구산 아래 율리에서 은둔생활을 했다. 어느 날 심기원(沈器#28306;)이 찾아와 능양군(인조)을 임금으로 추대하려는 반정을 꾀하던 중 좌구산에서 개 짖는 소리에 염탐꾼이 와 있다는 것을 깨닫고는 황급히 자리를 떠 목숨도 구하고 반정에도 성공할 수 있었다. 그 후로 산 이름이 앉을 ‘좌(座)’자, 개 ‘구(拘)’자를 써 좌구산이라고 불렸다. 지금은 두타산에서 보이는 좌구산의 모습이 거북이가 앉아 있는 형상과 비슷하다 하여 거북이 ‘구(龜)’자로 바꾸어 쓰고 있다. 이름과 얽힌 이야기 외에도 화원리의 새로운 왕을 기다린다는 새왕이 마을, 한국전쟁 중 미원지구 전투에서 톱밥만으로 적군의 탱크를 폭파시켰다는 13인의 특공대 이야기 등 좌구산을 둘러싼 많은 이야기가 전해진다.", + "MNTN_HG_VL" : "658", + "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", + "MNTN_NM" : "좌구산" + }, + "longitude" : 127.6513729, + "latitude" : 36.708345700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "435", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남면 발산리", + "MNTN_NM" : "좌방산" + }, + "longitude" : 127.6088889, + "latitude" : 37.720277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "415", + "MNTN_LOCPLC_REGION_NM" : "경남 고성군", + "MNTN_NM" : "좌이산" + }, + "longitude" : 128.18729250000001, + "latitude" : 34.923567599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주걱봉은 설악산 국립공원의 남서부에 위치해 있는 가리봉 줄기에 자리잡고 있다. 최고봉인 가리봉을 위시하여 가리봉 북쪽 지릉의 십이연봉, 주걱처럼 생긴 주걱봉, 삼형제봉 등이 한데 어우러져 있는데 모두 바위봉으로 이뤄져 산세가 급하고 험준하다. 북쪽으로 자양천·계천이 흐르고 이 두 하천을 사이에 두고 맞은 편에 대승령(1210m)·안산(1430m)이 있다. 북쪽 산 아래에 하늘벽·장수대가 있다.주걱봉을 비롯한 가리봉 줄기를 오를때는 사전에 정확한 정보를 준비해야 한다. 점봉산처럼 원시림이 울창하고 암봉이 이어져 있으며 양쪽에 낭떠러지가 있어 능선 중앙부에 있는 가리봉으로 접근하는 일이 쉽지 않기 때문이다.", + "MNTN_HG_VL" : "1401", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면, 인제읍", + "MNTN_NM" : "주걱봉" + }, + "longitude" : 128.3327778, + "latitude" : 38.096944399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산이 부드럽고 아름다워 일명 비단산이라고도 불리는 주금산은 운악산과 천마산의 중간지점에 가장 높이 솟아있는 산이다. 남쪽의 아름다운 비금계곡은 도심 근교의 대표적 피서지 중 하나다. 남쪽 약 1.3킬로미터 지점에는 독을 엎어놓은 것 같아 ‘독바위’라 불리는 암봉이 있으며 능선에는 바위지대와 억새밭이 심심치 않게 있고 수림도 울창하다.특히 수동천 상류의 비금계곡은 자연 그대로의 모습을 잘 간직하고 있다. 이 계곡은 옛날 풍류를 즐기던 선비들이 거문고를 숨겨놓고 다녔다하여 붙은 이름이다.정상 부근의 기암과 수려한 비금계곡이 어우러져 마치 비단결 같은 산세가 이어지며, 서북쪽 산자락에는 베어스타운 스키장이 자리잡고 있다.등산 코스로는 내촌에서 오르는 길과 비금계곡에서 오르는 길, 두 가지가 있다. 두 길 모두 산세가 뛰어나 아기자기한 산행을 맛볼 수 있다. 산행 시간은 4시간 남짓으로 서울에서 당일 산행지로 적합하다.", + "MNTN_HG_VL" : "814", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 포천시 내촌면, 가평군 상면", + "MNTN_NM" : "주금산" + }, + "longitude" : 127.2691293, + "latitude" : 37.784374499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 제천시 백운면과 봉양읍에 걸쳐 위치한 주론산은 구학산과 박달재사이에 솟아있는 산이다. 주론산이란 이름은 정상에서 동쪽 아래로 패어내려간 조백석골에서 학곡리 배론마을까지 이어지는 골짜기가 마치 배(船)밑바닥을 닮았다해서 붙여진 이름이다.일반이들에게 아직 알려지지 않은 산으로 이름조차 생소하지만 주론산은 한국 천주교사에서 빼놓을 수 없는 유서깊은 배론 성지가 있는 역사교육장이기도 하다. 이름이 널리 알려진 박달재와 탁사정이 인접하고 있어 등산을 겸한 가족나들이 코스로도 각광 받고 있다. 또 산행기점인 박달재는 고려 고종3년(1216년) 거란족의 10만대군을 김취려 장군이 섬멸시킨 전승지이기도 하다.산행보다는 역사현장을 둘러본다는 것이 더 적합할 듯하나 900m가 넘는 주론산의 산행은 결코 만만치 않으므로 단단히 채비를 하고 나서야 낭패를 당하는 일이 없다. 주론산은 부드러운 능선으로 이어져 적설기 등산지로 좋고 때묻지 않은 오지 농촌의 풍경을 간직하고 있어 더욱 좋다.", + "MNTN_HG_VL" : "903", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 봉양읍, 백운면", + "MNTN_NM" : "주론산" + }, + "longitude" : 128.04396890000001, + "latitude" : 37.161651999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "주발봉" + }, + "longitude" : 127.4947222, + "latitude" : 37.776111100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주봉산은 충주시 동량면 지동리와 서운리 사이에 솟은 봉우리로 산세가 완만하고 순탄해서 누구나 별무리 없이 등산할 수 있는 산이다. 특히 이 산을 중심으로 해서 충주호가 삼면으로 둘러싸고 있어 정상에 올라서면 마치 섬안에 떠있는 듯한 느낌을 받는다. 이 산의 남쪽자락에는 서운리 마을이 자리잡고 있다. 충주호 선착장에서 충주호반을 따라 꾸불꾸불한 길을 따라 한참을 들어가면 길이 끝나는 지점에 아담한 마을이 나타나는데 이 마을 을 지키고 서 있는 산이 바로 주봉산이다.주봉산 정상에서 바라보면 남서쪽으로는 계명산이 서쪽으로는 부대산, 지등산이 옹기종기 둘러앉아 잇는 모습이다.", + "MNTN_HG_VL" : "643", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면", + "MNTN_NM" : "주봉산" + }, + "longitude" : 128.54221570000001, + "latitude" : 38.172462099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "338", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시", + "MNTN_NM" : "주봉산" + }, + "longitude" : 128.54221570000001, + "latitude" : 38.172462099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주산은 대가야의 고분이 남아있고 순장묘 등 고분군이 발견된 산으로 역사적 가치가 높다. 남동쪽 구릉의 동남쪽 사면에 위치한 대가야시대의 무덤들은 현재와 고대를 연결하는 시간의 문을 연상케 한다. 또한 고령군민과 외지인들이 많이#52287;는 고령의 명산이다.고령의 진산인 주산정상(3백11M)에 오르면 북서쪽으로 가야산과 미숭산이 멀찌감치서 절묘한 자태를 드러낸다. 동쪽 산아래로는 고령읍이 한눈에 들어 오고 산능선을 넘나드는 한줄기 바람과 봄철에만 피어나는 철쭉꽃이 만발해 보는이로 하여금 가슴을 져미게 만든다.주산정상에서 고분군으로 내려오는 길 옆에는 명상의 숲을 꾸며 놓았다. 나무벤치 앞마다 주옥같은 명시를 기록해 나그네를 잠시 쉬어가게도 한다. 대가야 시대에 축조된 지산동고분군은 주산의 남동쪽 능선을 따라 내려 가면서 낙타등 처럼 이어지는데 언뜻 보면 거대한 봉분들만 눈에 띄지만 능선 아래로 크고 작은 무덤들이 마치 잊혀진 역사처럼 풀숲에 수도 없이 묻혀 있다고 해고 과언이 아닐듯 하다.높이 6m 지름 25~27m 규모인 제51호 고분을 비롯, 32호 고분까지 규모가 큰 고분이 이어지는데 특히 지난 78년 발굴. 조사결과 우리나라에서 첫 확인된 순장묘로 밝혀진 제44호 고분이 눈길을 끈다. 고분 주위를 걷다가 잠시 무덤가에 앉아 낙동강을 타고 오르는 바람결에 땀을 식히노라면 여기서도 고령읍내가 훤하게 보인다. 능선을 따라 줄곳 내려가면 44호분의 실물 크기로 순장묘 전시관이 나타난다.16대 도설지왕 때인 서기 562년에 신라에 멸망한 후기 가야연맹의 맹주국이던 대가야, 대가야의 5백년 역사는 삼국사기나 삼국유사에서도 어렴풋이 기록되어 있을뿐 정복당한 왕조의 애달픈 사연을 고분안에 묻은 채 빛바랜 대가야의 찬란했던 문화는 아직도 우리 역사에서 전설로 남아 있다.", + "MNTN_HG_VL" : "310", + "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군", + "MNTN_NM" : "주산" + }, + "longitude" : -74.005592699999994, + "latitude" : 40.8404071 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "831", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "주산" + }, + "longitude" : -74.005592699999994, + "latitude" : 40.8404071 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주암산은 앞산과 비슬산으로 대표되는 대구 남쪽 산군의 동쪽 부분을 차지한다. 가창댐이 있는 용계천과 냉천이 산자락의 북동쪽을 감싸며 흐르고, 정상에서 남서로 뻗은 산줄기는 최정산을 지나 비슬산, 청룡산 앞산으로 이어지며 거대한 산지를 이룬다. 주암산 산행은 허브힐즈 오른쪽 안양사나 광덕사 뒤 능선을 따라 오른다. 동쪽 자락의 주암산수양관, 또는 동남쪽 원장마을에서 원티골을 따라 오르는 길이 일반적이다. 어느 곳을 들머리로 삼든지 산행은 3~4시간이면 충분하다. 주암산은 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 정상 일대와 능선에는 억새풀이 무성하고, 봄에는 진달래 천국을 이루고, 가을에는 단풍이 온 산을 물들여 대구 근교지방의 주민들에게는 매우 친근한 산이다. 최정산과 주암산은 능선상으로 바로 이웃하여 있어 두 산을 종주하는 것도 좋다.", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", + "MNTN_NM" : "주암산" + }, + "longitude" : 128.61694439999999, + "latitude" : 35.773888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "국립공원 주왕산은 병풍처럼 펼쳐진 기암절벽이 장관.", + "MNTN_HG_VL" : "722", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군 청송읍ㆍ부동면, 영덕군 지품면ㆍ달산면", + "MNTN_NM" : "주왕산" + }, + "longitude" : 129.16659859999999, + "latitude" : 36.388218100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주월산은 괴산의 명산 중 가장 짧은 코스이다. 산행에 필요한 시간은 불과 1시간 정도면 충분하기 때문이다. 그렇다고 볼거리가 없다거나 시시한 산은 절대 아니다. 느릅재 정상에서 충주 쪽으로 19번 국도를 따라 가면서 가까이 보이는 까닭에 누구든 빼어난 산의 모습에 취하면 쉽게 내려오지 못하는 산이기도 하다.바위능선이 병풍처럼 둘러쳐져 있어 산세가 빼어나고 정상에 오르면 남쪽으로 박달산을 비롯한 여러 산이 보인다. 주변에 공림사와 망개나무자생지·수안보온천 등의 명소가 있다.산행은 감나무골에서 시작한다. 능선을 타고 5분 오르면 작은 봉우리가 나오는데 이곳에서 서쪽으로 이담저수지와 마을이 보인다. 동쪽으로 10분 정도 올라가 첫번째 바위봉우리를 지나면 정상이다. 두 봉우리 주위는 마치 성곽처럼 평평한 바위로 둘러싸여 있고 그 모습이 절구의 확돌처럼 보인다 하여 산 아랫마을을 화학골이라 부르기도 한다.", + "MNTN_HG_VL" : "470", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 장연면", + "MNTN_NM" : "주월산" + }, + "longitude" : 127.9037335, + "latitude" : 36.849944299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주읍산은 양평과 용문 중간에 위치한 산으로 추읍산, 혹은 칠읍산이라 불렀다한다. 이는 주변의 일곱개 읍, 즉 양평, 용문, 개군, 지제, 강상, 옥천, 청운등이 한눈에 보인데서 유래한 것이다.용문산 동쪽 싸리재와 횡성과의 경계에 있는 성지봉에서 발원되는 신내개울이 산 기슭을 굽이 돌고 서쪽으로는 오대산과 태백산 어름에서 흘러내려온 남한강이 산 밑둥을 감싸 흐르며 산그늘을 담아내는 모습이 숭엄해 보인다.중성마을 뒤 밤나무가 많은 능선을 타고 질마재에서 소나무숲 터널을 거쳐 정상에 오르면 신내천과 남한강이 한눈에 내려다보인다. 주읍산 정상에는 1975년에 설치한 삼각점 외에 아담한 정상비가 있다. 여름철에는 신내천의 초원지대에서 마음껏 뛰어 놀수 있어 가족 단위 산행으로 제격이다.", + "MNTN_HG_VL" : "583", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 양평읍, 개군면, 지제면", + "MNTN_NM" : "주읍산" + }, + "longitude" : 127.5729425, + "latitude" : 37.456420199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉황이 날개를 활짝 펴고 하늘을 날고 있다해서 이 산의 이름은 주작산이다. 해남과 강진의 경계를 이룬 주작산(약 475m) 능선은 전형적인 암릉길이다. 그동안 지척에 있는 두륜산에 가려 빛을 보지 못했지만 특유의 거칠고 까탈스런 바윗길 덕분에 이제 남도의 대표적인 암릉산행지로 주목받고 있다.주작산은 두륜산에서 동쪽으로 뻗어내린 산맥이 오소치에서 멈춘 뒤, 거친 기세로 솟아 오른 바위능선 한 귀퉁이에 솟아 있다. 그것도 주능선이 아닌 동쪽으로 조금 삐져나온 지능선 상에 위치한다. 그래서 주작산 산행은 이 주봉을 오르기보다 오소재 - 작천소령으로 연결되는 산줄기 전체를 타는 것이 일반적이다.주작산 줄기는 북으로 덕룡산(432.9m)과 석문산(272m) - 만덕산(408.6m)까지 이어진 긴 능선의 일부 구간이다. 이 산자락의 대부분 구간은 바위 봉우리와 벼랑으로 형성되어 보는 맛이 탁월하다. 특히 주작산 구간은 톱날 같은 암릉이 길게 이어져 아기자기한 산행의 묘미가 뛰어나다.주작산 산행은 접근이 편리한 오소재에서 시작해 작천소령으로 답사하는 것이 일반적이다. 초창기에는 산이 거칠고 길도 없어 10시간 이상 걸렸지만, 이제는 우회로가 많이 생겨 시간이 많이 단축됐다. 건각들은 주작 - 덕룡산 줄기를 하루에 답파하기도 한다. 위험한 구간에는 어김없이 로프를 매어 놓았지만, 아직도 아찔한 구간이 많으니 초심자가 낀 팀은 주의해야 한다.", + "MNTN_HG_VL" : "475", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", + "MNTN_NM" : "주작산" + }, + "longitude" : 126.6956041, + "latitude" : 34.5063703 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "김otilde;쪽에서 추풍령을 넘어 황간 가까이 내려오면 1시 방향으로 하나의 커다란 배가 하늘을 떠가는 모양을 볼 수 있다. 바로 주행봉이다. 떠가는 배의 모양을 그대로 이름으로 한 것이다.속리산에서 백두대간과 헤어진 산줄기 하나가 구병산을 거쳐 팔음산(762m, 옥otilde;ucirc;산면)으로 나아가고 이 산줄기는 한껏 낮아졌다가 백화산으로 다시 일어나 933미터의 포성봉과 874미터의 주행봉을 빚어놓았다. 이 백화산은 상주의 모동면 모서면, 옥otilde;의ucirc;산면 일대의 분지 가운데 자리잡고 있기 때문에 더욱 우뚝하고 커 보인다.국토지리정보원의 지도에는 포성봉, 주행봉으로 표기되어 있다. 포성봉이라 부르는 연유는 알 수 없으나 「신증동국여지승람」과 모든 기록에 백화산으로 되어 있고 상주쪽에서는 한성봉이라 부르기도 한다. 주행봉을 현지 주민들은 “쌀개봉”이라 부른다. 주행봉의 머리를 이루는 바위 봉우리 두 개가 옛날 디딜방아의 쌀개oacute;럼 되어있기 때문이다.", + "MNTN_HG_VL" : "874", + "MNTN_LOCPLC_REGION_NM" : "충북 영동군 황간면", + "MNTN_NM" : "주행봉" + }, + "longitude" : 127.8877233, + "latitude" : 36.278346300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경부고속도로를 따라 추풍령을 지날 때 영동 근처에 이르면 서북쪽으로 솟아오른 백화산(933m)이 보인다. 주행봉은 백화산이 껴안은 봉우리로 황간쪽에서 올려다 보면 물위를 떠가는 배와 같은 형상을 하고 있다. 산 아랫마을 사람들은 이 산을 쌀개봉이라고도 한다. V자로 갈라진 봉오리가 방아허리를 받치는 쌀개 같다하여 붙여진 이름이다.주행봉은 산 주름이 거의 없는 판판한 북서 사면이 장관이다. 높이 8백여 미터 내외의 산줄기가 거의 주름이 없고 4킬로미터 정도 뻗어 있다. 비탈이 대부분 가파른 너덜로 되어 있어 더욱 장관이다.", + "MNTN_HG_VL" : "874", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 모서면, 충청북도 영동군 황간면", + "MNTN_NM" : "주행봉" + }, + "longitude" : 127.8877233, + "latitude" : 36.278346300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울의 진산 자리를 놓고 삼각산과 다투다가 휘적휘적 내려와 버렸다는 전설이 있을 만큼 빼어난 산이다. 정상에서 남봉으로 뻗어내린 1000m를 넘나드는 능선이 특히 준걸해 흡사 삼각산 백운대에서 보현봉에 이르는 장쾌한 능선을 빼다 놓은 듯하다. 일반등산로는 정상으로 알려진 1075봉을 중심으로 6방으로 나있는데 이 중 상봉인 주흘영봉과 부봉을 지나 동화원로 이어지는 줄기의 능선미가 일품이다. 월항삼봉으로 해서 하늘재로 내려서는 코스도 좋은데 월악산에서는 이 둘의 하늘금이 리듬체조의 리본처럼 역동적으로 보인다. 산이 솟음이 우세한 형국이라 썩 발달한 계곡은 없다. 대신 곡충골의 여궁폭포와 파랑소, 조곡골의 꽃밭서덜이 이채롭다. 너덜 사이를 듬성듬성 뚫고 올라온 진달래가 꽃을 피운 모습은 어디서도 찾아보기 힘들다. 도립공원으로 지정돼있는 문경새재는 주흘관, 조곡관, 조령관의 관문과 아울러 자연보도로도 유명하다. 근래에는 여기에 드라마왕건 세트장과 산악영화제가 보태졌다.", + "MNTN_HG_VL" : "1108", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "주흘산" + }, + "longitude" : 128.10060530000001, + "latitude" : 36.788566500000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "명지산(1,267m)과 운악산(936m)을 빚은 백두대간의 줄기가 의정부에 이르러 나즈막하게 솟구쳐 오른 산이 죽엽산이다. 국수봉(605m)과 소리봉(536m)을 이웃하고 있으며 굴곡 없는 육산이다. 언뜻 보기엔 밋밋하고 신통치 않게 보이는 산이지만 이산의 특징은 울창한 수림에 있다.도봉산의 사패능선이나 포대능선처럼 경치를 볼 수 있는 탁 트인 곳은 없지만, 주능선상의 쭉쭉 뻗은 울창한 수림사이를 시원한 바람을 맞으며 걷노라면 이 산의 매력이 충분히 느껴질 것이다. 산행은 큰넓고개나 직동에서 시작한다.", + "MNTN_HG_VL" : "601", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 소흘읍, 내촌면", + "MNTN_NM" : "죽엽산" + }, + "longitude" : 127.1855556, + "latitude" : 37.7916667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "859", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", + "MNTN_NM" : "죽엽산" + }, + "longitude" : 127.1855556, + "latitude" : 37.7916667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 괴산군 청천면에는 아름다운 경관을 갖춘 산들이 많이 있는데 그 중 중대봉은 아직 타지 사람들의 귀에 생소한 산이다. 백두대간상의 대야산(931m) 정상인 상대봉에서 서쪽으로 분기하는 지릉산의 최고봉이 중대봉인데 이 산은 우리나라에서 몇 안되는 `전인미답'의 경지를 보존하고 있다.중대봉은 바로 이웃인 상대봉의 상대적인 개념으로 붙여진 이름이며, 산 전체가 하나의 화강암으로 이루어져 있으며, 2∼3년 전까지만해도 워킹코스가 없어 전인 미답의 산으로 남아있었지만 최근 암벽을 이용한 코스가 개발되고 위험한 곳에는 로프를 매놓아 완벽한 등산로를 만들어 놓았다.중대봉을 가기 위하여는 청천면 소재지, 화양동, 송면 소재지를 지나 상주시 화북면으로 가는 592번 지방도를 따라 삼송 3구 마을까지 가야하는데, 이 마을은 농바위 마을이라 불리워 진다. 농바위 마을의 마지막집 담장에는 500여년이나 되는 느티나무가 노쇠한 모습으로 서 있다. 이 마을은 손꼽히는 장수마을이다. 마을 지반 전체가 신비의 돌이라는 맥반석이 깔려있고 여기서 솟는 물을 먹고 장수한다고 믿고 있다.정상에서의 조망은 동쪽과 남쪽은 확 트였지만 북쪽과 서쪽은 참나무에 가려 잘 보이지 않는다 하지만 동족은 대야산이 꽉 채우고 있으며 그 왼쪽아래 주흘산이, 조금 떨어진 동북쪽으로 희양산 하얀 바위봉우리가 우뚝하며, 남쪽으로 서서히 둔덕산과 마귀할멈 통시바위, 조항산의 백두대간이 도도히 흐르고 있다.", + "MNTN_HG_VL" : "830", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군", + "MNTN_NM" : "중대봉" + }, + "longitude" : 128.39222219999999, + "latitude" : 40.191666699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "중봉은 가지산의 전위봉으로 해발 1168.8m 이며, 영남알프스 내에서도 몇째가는 봉우리다. 산행은 언양을 출발한지 30여 분 석남사 주차장에서 밀양행 버스로 갈아타고, 석남터널을 지나 30여 분 후 삼양교 다리에 내리면, 호박소구룡소폭포 입구이다.안으로 들어서면 제일관광가든이 나오는데 이 건물 뒷편 안내문 간판이 있다. 여기서부터 시작이다. 하산길에는 선녀탕과 성제소를 만날 수 있다. 선녀탕은 특히 겨울에 암반에 걸린 물줄기가 얼어붙어 요란한 고드름이 병풍을 형성하고 그 아래 계곡수는 얼음 밑으로 유유히 흐르고 있다. 성제소는 형제소라 하는데 옛날에 어느 선비 형제가 이곳에서 공부를 하다 형이 빠뜨린 붓 대롱을 건지려다 물속에 빠져 허우적거리는 형을 동생이 구하려다 같이 죽었다는 전설이 있어 형제소라는 지명이 생겨났다.", + "MNTN_HG_VL" : "1169", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산내면", + "MNTN_NM" : "중봉" + }, + "longitude" : 126.7067349, + "latitude" : 37.625689899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평군에 있는 중봉은 화악산과 남서쪽으로 이웃해 있는 산으로 화악산 정상부가 군사 통제 구역으로 묶여 있기 때문에 등산인들이 오를 수 있는 경기도내의 가장 높은 산이다. 대부분 중봉 산행은 관청리 큰골 계곡으로 올랐다가 다시 큰골로 하산하는 경우가 많은데 산행경력이 있다면 가림에서 출발하여 가파른 능선을 타고 오른 후 큰골로 하산하는 것도 괜찮다.가림마을에서 시작하는 산행은 돌집수련원 입구에서 시작되는데 초입부가 오솔길처럼 평탄하다고 해서 만만하게 보아서는 안된다. 750m 고지를 오르면서부터 산길이 급격하게 가팔라지고 험준한 길이 이어진다. 그러나 이 구간쯤에 이르면 명지산에서부터 국망봉, 백운산까지 이어지는 능선이 한눈에 들어와 피로를 잊게 해 준다.", + "MNTN_HG_VL" : "1424", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "중봉" + }, + "longitude" : 126.7067349, + "latitude" : 37.625689899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가곡면 풍곡리 덕풍계곡에 자리잡은 중봉산은 사람들에게 덜 알려진 만큼 훼손도 덜 된 곳이다. 그래서 호젓한 주말산행을 원하는 사람 몇 명이 뜻을 모아 함께 찾아가기에 좋다. 태백에서도 한참을 더 가서야 만날 수 있는 이 산은 시원한 덕풍계곡의 물소리가 능선길을 오르는 동안 내내 따라올 만큼 한적하다. 또한 나이를 짐작하기 어려울 정도로 밑둥이 굵은 아름드리 노송도 몇 그루 만날 수 있다.그리고 참나무와 물푸레나무 등이 울창하게 늘어선 산에서 새소리와 물소리를 들으며 함께 간 사람들과 두런두런 얘기를 나누다 보면 세속의 가면을 벗어 던진 자신을 발견할 수 있을 것이다. 한편 정상에서는 남동쪽을 조망할 수 있는데, 이곳에 한국 전쟁 당시 참호로 사용되었을 웅덩이가 남아 있어 민족의 비극을 떠올리게 한다.", + "MNTN_HG_VL" : "740", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "중봉산" + }, + "longitude" : 128.9277778, + "latitude" : 37.448611100000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동상면 대아리 저수지의 우암교에서 은천리 계곡을 따라 2.1Km 지점에 이르면 거대한 암벽과 숲과 계곡과 반석 그리고 소(沼)로 선경을 이룬 곳이 있으니 고종황제도 이곳의 경치가 너무나 황홀하여 머물러갔다는 데서 그 이름 '왕재'라고 하는 곳이다.중수봉은 높지 않으며 바로 옆에 붙은 삼정봉의 바위들을 빼면 험한 길도 없고 능선이 완만해서 산책 삼아 오르기에 알맞은 곳이다. 삼정봉으로 이어지는 능선길과 3개의 봉우리를 잇는 암릉지대가 등산의 진수를 느끼게 해주는 산이기도하다. 은천리 계곡의 왕재에서 동쪽 중수골 계곡을 타며 산세를 조망할 수 있다.이 산의 계곡과 은천리 계곡 일대는 감나무골로 가을 단풍과 함께 주렁주렁 매달린 감나무들로 더 한층 가을의 정취를 물씬 풍겨주고 있으며 특히 이 고을 감은 씨가 없고 그 맛이 꿀과 같아 한 때는 임금님께 바치는 진상품으로서의 역사를 간직하고 있다고 한다.또한 인근에 대아자연휴양림이 있어 휴양림에 텐트를 친 후 이 산에 올랐다 내려오는 식으로 두 곳을 연결해 산행하는 것이 좋다. 그래서인지 조용하게 오붓한 시간을 보내려는 가족들이 많이 찾는다. 이곳을 찾는 사람들은 편안함과 화려함을 떠나 가장 기본적인 것만을 갖춘 채 함께 지내는 동안 가족간의 애정이 더 돈독해지는 것을 느끼게 된다고 한다.", + "MNTN_HG_VL" : "548", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면", + "MNTN_NM" : "중수봉" + }, + "longitude" : 126.92749999999999, + "latitude" : 37.7575 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "중왕산은 해발 1376미터로 정선읍 북서쪽으로 평창군과 경계를 이루며 우측 해발 1560미터의 가리왕산과 함께 고산의 면모를 충분히 보여주는 산이다. 주왕산이라고도 한다.태백산맥의 지붕 역할을 하는 높은 산으로 주변에는 백석산(1,365m)·청옥산(1,256m)·가리왕산(1,561m)·중봉(1,433m)·하봉(1,380m) 등의 높은 산을 비롯하여 정선 소금강, 화암약수, 정선 아우라지, 화암종유굴 등의 명승지와 가리왕산 자연휴양림이 있다. 가리왕산(1,561m)과는 능선으로 이어져 있어 같은 산으로 보기도 한다.능선이 끝없이 펼쳐진 초원지대로 육중하고 당당하며 자작나무와 주목이 군락을 이루고 있다. 5월 하순께에는 산기슭 곳곳에 취나물, 두릅 등 수십 종의 산나물이 돋아나 산행의 즐거움을 더해준다.", + "MNTN_HG_VL" : "1376", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 정선군", + "MNTN_NM" : "중왕산" + }, + "longitude" : 128.52379479999999, + "latitude" : 37.463714899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "용문산, 백운봉, 도일봉과 더불어 웅장한 절경을 이루어 경기의 금강산이라 불리기도 하는 중원산은 경기 양평 용문면과 단월면의 경계에 있는 산이다.주능선의 왼쪽에 용계계곡과 오른쪽에 중원폭포, 중원계곡을 끼고 있는데, 중원폭포 계곡은 머루와 달래밭으로 유명하며, 봄이면 철쭉·금낭화가 피고, 가을이면 약초와 야생과일이 많이 난다. 계곡사이로는 기암이 늘어서있고 울창한 숲 사이로 맑은물이 흘러내려온다. 계곡, 암봉과 함께 중원산에서 빼놓을 수 없는 것은 머루, 다래밭이다.산행은 중원리에 있는 주차장에서부터 시작한다. 계곡을 따라 중원폭포와 치마폭포를 지나 갈림길에서 왼쪽길로 작은 계곡을 지난다. 너들고개가 나오면 왼쪽 능선으로 정상에 오른다. 정상에 서면 동쪽으로 도일봉, 서쪽으로 용문산이 가깝게 보인다.", + "MNTN_HG_VL" : "800", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", + "MNTN_NM" : "중원산" + }, + "longitude" : 127.60196449999999, + "latitude" : 37.559491399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "일명 `찌걱산'이라 불리는 지각산은 삼척시 하장면에 있는 오지의 산이다. 부근에 광동댐이 들어서면서 일부 훼손된 부분이 있으나 광동호와 인접해 있는 이 산의 경관은 지나가는 사람들의 발길을 붙잡기에 충분하다. 특히 광동댐 관리사무소가 들어선 능선부근은 남녀가 마주치면 그냥 지나치지 못하고 꼭 일이 생긴다는 말이 전해질 만큼 계곡 경관이 수려하다.지각산 동쪽 깎아지른 절벽에는 설패바위, 촛대바위,금강문 등 수많은 기암이 하늘을 찌를 듯이 솟아 선경을 이루는 별유천지이다. 건너편 미륵봉 밑에는 천연기념물 178호로 지정된 환선동굴이 있으며 황금색 종유석, 석순 폭포 등 기묘한 현상으로 감탄을 금치 못한다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", + "MNTN_NM" : "지각산" + }, + "longitude" : 128.96111110000001, + "latitude" : 37.333055600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "108", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 지곡동", + "MNTN_NM" : "지곡산" + }, + "longitude" : 129.29416670000001, + "latitude" : 36.008611100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "지등산은 충북 충주시 동량면에 위치한 산으로 천등산, 인등산과 함께 3등산의 하나이다. 정상 부근은 뾰족하고 높아 이름과는 어울리지 않는 형세를 하고 있다. 산세가 특별히 아름답거나 비경을 감추고 있지만 않지만 흙으로 된 육산으로 숲이 우거져 있어 나름대로의 매력을 지닌 산이다.그러나 산세가 특별히 내세울 것이 없다보니 사람들의 관심에서 잊혀진 산이었다. 그로인해 사람들의 발길이 뜸하다보니 지등산은 깨끗한 자연환경을 간직할 수 있었고 원시림과 같은 참신한 맛을 느낄 수 있다. 우거진 숲 사이로 불어오는 청량한 바람은 건강에도 많은 도움이 되어 산행의 값을 한층 높여준다. 산 아래에는 충주호와 충주댐이 있다.정상에 서면 북쪽으로 인등산, 남동쪽으로 충주호·계명산이 보이고, 동쪽으로 관모봉(641m)이 능선을 따라 이어져 있다.", + "MNTN_HG_VL" : "535", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면 조동리", + "MNTN_NM" : "지등산" + }, + "longitude" : 127.9875262, + "latitude" : 37.017703300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 청도군 운문면에 자리한 지룡산은 영남 알프스에 속하는 운문산과 바로 인접해 있는 산으로 운문산 운문사의 부속암자들이 배치된 곳이다. 청신암과 내원암, 북대암 등 사찰 규모는 크지 않지만 옛 정취를 느끼고 쉬어가기에는 충분한 공간이며 주변 경관과 더해져 한층 멋스러움을 자아낸다.낮은 산이지만 산행길은 그리 만만치 않다. 곳곳에 칼날 같은 바위능선이 있고 가파른 너덜지대와 폭 넓은 고사목이 산재해 있다. 또한 견훤이 신라 침공 때 축조한 지룡 산성이 있다.산행은 운문사에서 북쪽으로 차도를 따라 나가다 오른쪽 계곡길로 들어서 청신암,내원암을 거쳐 북대암으로 올라가면 정상이 멀지 않다.", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면", + "MNTN_NM" : "지룡산" + }, + "longitude" : 127.3383333, + "latitude" : 34.680555599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "\"환상의 섬\"사량도 그 중간에 우뚝솟은 또 다른\"지리산\"(399.3m) 힘겹게 오른 옥녀봉서 바라보는 한려수도와 하산후의 싱싱한 회맛 눈과 입이 즐겁다 환상의 섬! 사량도가 더욱 아름답게 새로이 태어났다.감추어졌던 사량도의 비경들이 이제 수많은 산꾼들과 여행자들에게 흐뭇하게 그 매혹적인 자태를 드러내게 된 것이다. 통영시에서 펼친 관광개발로 대항해수욕장이 조성되고 여객선 터미널이 새롭게 단장되고 위험했던 등산로가 야무지게 정비되는 등 찾는 이들의 안전과 편의를 개선하여 사량도는 수많은 관광객들로 붐비고 있다.사량도는 통영시 사량면에 해당하는 섬으로 우리나라 남단 다도해 한려해상공원에 둘러싸인 아름다운 섬이다. 사량도는 섬 자체가 뱀 모양으로 생겼고 뱀이 많다고 해서 붙인 이름이라 하는데, 한 남자가 이룰 수 없는 사랑에 괴로워하다 상사병으로 죽어뱀이 되었다는 이야기도 전해온다.삼천포시 앞바다의 잔잔한 물결을 가르고 사량도 상도에 도착하면 섬 가운데 우뚝 솟은 지리산을 볼 수 있다.본래는 우리에게 잘 알려져 있는 전라도와 경상도에 걸친 장대한 지리산이 바라다보여 「지이망산」이라 불리다가 그 말이 줄어 「지리산」이 된 것이다. 높이는 얼마되지 않지만 한려수도의 빼어난 경관과 어우러져 그 어느 명산 못지 않게 절묘한 경관을 간직하고 있다.산에 오르는 길은 여럿 있으나 돈지포구를 시발점으로 지리산 옥녀봉을 거치는 능선을 타고 진촌으로 빠지는 코스를 택하는 것이 이 산의 진면목을 가장 잘 즐길 수 있는 방법이다.돈지는 수려한 경관의 바위산과 푸른 물살이 넘실대는 바다를 배경으로한 한폭의 그림같은 순박한 섬마을이다. 마을을 빠져나와 산을 오르기 시작하면 돌밭길이 나오는데 시야에 들어오는 바다 풍경 덕에 돌길이 지루하지 않고 아기자기하기만 하다. 행여 주위 경관에 시선을 빼앗겨 발이라도 헛디딜까 걱정이 될 정도다.", + "MNTN_HG_VL" : "399", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면", + "MNTN_NM" : "지리산(통영)" + }, + "longitude" : 128.18587239999999, + "latitude" : 34.8472443 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정선의 지억산은 민둥산에 가려진 산이다. 민둥산이 가을 억새로 워낙 유명하다 보니 지척의 지억산은 민둥산 산행 중 지나치는 산 정도로 알려져 있다. 산 족보로 따지면 지억산은 백두대간 금대봉에서 뻗어 나온 산줄기다. 이 산줄기를 산꾼들은 소위 ‘정선지맥’이라 부르며 지맥 주능선상에 지억산이 있다. 민둥산은 지억산에서 갈래 쳐진 산이니 지억산이 모산이다.지억산에서 민둥산은 2.6킬로미터 거리로, 1시간 10분 정도 밖에 걸리지 않아 당일 코스로 연결해도 무리가 없다. 높이는 거의 비슷한 편이며 민둥산이 1117.8미터로 1.1미터 높다. 그러나 지억산 정상에는 억새지대가 없으며 등산인들의 발길도 뜸한 편이다. 정상에는 철망에 둘러쳐진 태양열 전지가 있으며 표지석에는 ‘몰운산’이라 적혀있다. 인근 몰운대와 몰운리라는 지명에서 온 산 이름인 듯하다. 국토지리정보원 지형도를 보면 유명한 민둥산조차 이름이 없지만 지억산만큼은 선명히 표기되어 있다. 지억산의 한문 표기를 해석해 보면 영지와 같은 평평한 버섯으로 추정되는데 산행길 역시 평탄하고 정상부의 모양새도 봉긋하다.", + "MNTN_HG_VL" : "1117", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면ㆍ남면", + "MNTN_NM" : "지억산" + }, + "longitude" : 128.78374719999999, + "latitude" : 37.290074300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "773", + "MNTN_LOCPLC_REGION_NM" : "경북 상주시 모동면 신흥리", + "MNTN_NM" : "지장산" + }, + "longitude" : 127.20718170000001, + "latitude" : 38.101389999999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "\"지장산은 경기도 포천군과 연천군의 경계를 이룬다. 주능선에는 울창한 수림과 바위봉이 어우러져 있으며, 특히 더덕, 취나물 등 산나물이 많이 서식하고 있어 때마다 바구니를 들고 찾아오는 사람들의 발길이 끊이지 않는다. 또한 지장산은 계곡미가 뛰어난 곳이다. 숲 터널을 사이로 흐르는 계류가 곳곳에 웅덩이를 이루고 있는 5km에 달하는 지장계곡은 여름철 피서지로 손꼽히는 곳이다.산행은 대중교통을 이용하면 중리초등학교에서 약 4km에 달하는 도로를 걸어가야 하는 불편함이 있다. 승용차나 버스는 중리에서 약 4km 거리인 화전민터까지 접근할 수 있다. 이곳부터 지장산 산행의 묘미를 만끽할 수 있다. 능선까지 1시간정도의 거리는 좌우로 다래나무가 빽빽이 늘어서 있고 능선에서 정상까지는 30분정도 걸린다. 정상에 올라서면 바로 북쪽으로 민간인 통제구역인 금학산(947m)과 고대산(832m)이 우뚝 솟아있고, 동서로는 철원 평야 및 연천일대가 손에 잡힐듯 시야에 들어온다.", + "MNTN_HG_VL" : "877", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 관인면, 연천군 신서면, 강원도 철원군", + "MNTN_NM" : "지장산 (보개산)" + }, + "longitude" : 127.1466479, + "latitude" : 38.156833200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "189", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "지적산" + }, + "longitude" : 126.8896191, + "latitude" : 37.4949309 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금산읍 시내에서 남서쪽을 가로 막고 솟아 있다. 서대산, 계룡산에 이어 충청남도에서 세번째로 높은 산으로 주능선에 기암괴봉이 많고 숲이 무성하다.산자락에는 고찰 영천암과 영천약수·보석사·선공암·원효암·봉화대·관음암·관음굴·원효폭포 등 명소가 많고, 보석사 입구에는 전나무 숲과 수령 약 1000년의 은행나무(천연기념물 365)가 있다. 남이면에는 인삼시장이 서고, 금성면에서는 임진왜란 당시 왜적과 싸우다 옥쇄한 7백인의 충혼이 깃들인\"\"칠백의총(사적 제105호)을 찾아 선열들의 깊은 뜻을 새겨볼 수 있어 가족동반 코스로도 적당하다.산행은 금산읍 계진리 마을회관 앞에서 시작한다.계곡길을 따라 선공암과 빈대바위 옆을 지나 능선길을 오르면 정상이 나온다.정상에서 동쪽을 내려다 보면 수십길 깎아지른 절벽이 아찔하다. 서북쪽으로는 대둔산이 하얀 구름띠를 허리에 감고 다가오고 서대산의 기암절벽도 위용을 자랑하며 자태를 뽐낸다. 남쪽으로는 운장산과 구봉산이 마치 형제인양 맞붙은 모습으로 시야에 들어온다.", + "MNTN_HG_VL" : "732", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 금산읍", + "MNTN_NM" : "진락산" + }, + "longitude" : 127.45882520000001, + "latitude" : 36.077696000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "진악산은 해발 737미터로 충남에서 네 번째로 높은 산이다. 주릉에 펼쳐지는 기암괴석의 경관이 아름다우며 금산 쪽으로 깎아지른 듯한 낭떠러지는 장엄하기까지 하다. 진악산을 감싸고 있는 숲도 무성하며 영천암과 원효암 골짜기의 개울도 좋다. 특히 진악산 북편 관음봉 일대의 암애와 암봉들, 원효암 일대의 기암괴석과 폭포는 일품이다. 명물, 명소로는 보석사 입구에 전나무숲과 천연기념물 365호인 1100년 수령의 은행나무가 있고, 천년사찰 보석사와 영천암, 원효암이 있으며 이밖에 영천암의 영천약수, 도구통바위, 봉화대, 관음암과 관음굴, 원효폭포, 물골의 바위굴은 명소로써 훌륭한 가치를 지니고 있다.진악사 정상에서는 속리산과 서대산, 천태산, 민주지산, 덕유산의 장쾌한 산줄기를 모두 볼 수 있으며, 운장산의 특이한 모습도 보이고 계룡산도 눈에 띈다. 옛날부터 나라의 안위를 봉화로 알리는 봉화대가 있었으며, 조선시대 임진년 8월(1592년) 금산벌 싸움에서 중봉 조헌 선생과 함께 싸우다 순국하신 기허당 영규대사는 진악산 남쪽 기슭에 있는 보석사에서 수도를 했고 그 인연으로 보석사내의 의선각에 영규대사의 영정이 모셔져 있으며 보석사 들머리에 영규대사의 충혼을 기리는 위병 승장비가 세워져 있다.", + "MNTN_HG_VL" : "732", + "MNTN_LOCPLC_REGION_NM" : "충남 금산군 금산읍", + "MNTN_NM" : "진악산" + }, + "longitude" : 127.45882520000001, + "latitude" : 36.077696000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "질운산 산행은 대체적으로 힘들지 않다. 직동리 큰 터 삼거리, 직동만물슈퍼와 담배집이 산행들머리이다. 한밭골 자동차 길을 따라 40분에 효자각에 이르고, 오른쪽으로 효자각이 있는 골로 들어, 계속 광산길로 천천히 1시간 40분쯤에 새비재가 있다. 중간중간 샛길이 있으나 자동차 바퀴자국을 유심히 살피고 따르면 실수없을 것이다.새비재 고랭지 밭에는 10비터 높이의 전주만 있는데 정상으로 가는 주능선 앞에 20미터 높이의 전주가 있다. 정상은 40분 소요. 하산은 동쪽 주능으로 30분에 넓은 자운동 안부이다. 이곳에서 남쪽 광산길로 15분에 삼거리 왼쪽 길로 계속 구불구불 광산터, 붉은절벽, 폐광굴(폐쇄)를 지나며 오른쪽을 유심히 살피면 삼지창 같은 소나무를 발견할 수 있다. 여기서 오른쪽 상막골로 내려선다. 자운동 안부에서 삼지창 소나무까지 약 1시간 20분 걸린다. 총 산행시간은 6시간 30분에서 7시간 소요된다.", + "MNTN_HG_VL" : "1172", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 중동면, 정선군 신동읍", + "MNTN_NM" : "질운산" + }, + "longitude" : 128.71722220000001, + "latitude" : 37.196111100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진주시", + "MNTN_NM" : "집현산" + }, + "longitude" : 128.03420779999999, + "latitude" : 35.3133531 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "쫓비산은 광양 다압면 매화마을을 둘러싸고 있는 산이다. 이름이 특이한 쫓비산은 인근 주민들에게 그 뜻을 물어도 명확한 답을 아는 이가 없다. 다만 형태가 뾰족해 사투리 ‘쪼삣’에서 유래했다는 설도 있고 섬진강의 푸른 물줄기에 빗대어 맑은 하늘이란 뜻의 ‘쪽빛’에서 유래된 이름이라는 설도 있다.쫓비산은 광양 매화마을을 둘러싸고 있는 산으로, 호남정맥 백운산에서 갈래 쳐진 산이며 섬진강을 끼고 앉은 산이다. 섬진강 550리 유장한 먼 굽이를 돌아나와 전라도와 경상도의 경계를 지으며 남해로 흘러드는 곳, 호남정맥이 끝나는 백운산 동편 산줄기에 솟은 것이 갈미봉 쫓비산 자락이다.쫓비산 하면 단연 매화꽃이 유명하다. 산 입구의 청매실농원은 매화꽃 만발해 축제가 열리는 봄이면 관광객들과 등산객으로 메워진다. 매화꽃이 유명하지만 능선으로 들면 진달래와 철쭉이 지천이다. 꽃의 개화 시기는 차이가 있어 산기슭의 매화꽃이 지면 바통을 이어받아 산등성이의 진달래와 철쭉이 핀다.", + "MNTN_HG_VL" : "537", + "MNTN_LOCPLC_REGION_NM" : "전남 광양시 진상면", + "MNTN_NM" : "쫓비산" + }, + "longitude" : 127.6977778, + "latitude" : 35.07 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "542", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천", + "MNTN_NM" : "창안산" + }, + "longitude" : 126.84514729999999, + "latitude" : 37.303596499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "채계산은 여러 이름으로 불리우기도 한다. [동국여지지]에서는 화산(華山)으로, 옥천지에는 차계 산(次戒山)으로 적혀 있고 또 책과 같이 돌이 쌓여 있다하여 책여산(冊如山)이라고도 불리운다. 또한 옛부터 아미산, 광덕산(일명 강천산)과 더불어 순창의 3대명산으로 꼽고 있으며 명산답게 산 과 관련된 전설이 많이 내려오는 곳이기도 하다. 산중턱에 큰 바위가 툭 튀어나와 잇으며 그 바위밑에는 큰 굴이 잇는데 이 굴이 바로 전설에서 전 하는 세칭 금돼지굴이고, 채계산 밑 적성강변에 천재지변에 따라 색깔을 달리하는 거대한 흰바위 가 있는데 높이가 6자가 실히 된데다가 그 형상이 마치 백발노인이 우뚝 서 있는 모습과 같아 사 람들은 이 바위를 ‘화산옹’ 이라 불러오고 있다. 얼핏보면 늙은 사람과 같다 하여 이름도 사람 에 비유하여 ‘화산늙은이’라고 한 것 같다.그런데 이 화산옹은 이상한 능력을 가지고 있다고 전 한다. 그것은 그해 풍년이 들려면 색깔이 희고 아름답게 보이지만 반대로 흉년이 들려면 색깔이 검은색을 띄게 된다. 또 큰불이 난다거나 전염병이 퍼져 인명의 피해가 많은 해는 바위 색깔이 파 란색을 띄게 된다. 그리고 전쟁이 일어나거나 천재지변이 있을 때는 붉은 색깔을 띄게 된다는 전 설이 전해져 내려오고 있다. 읍의 동쪽 약 10km쯤 떨어져 있는 이산은 멀리 장수 팔공산에서부터 뻗어난 줄기가 이산을 이루는 데 정상에서 내려다보면 적성강 물줄기가 보여 그 경치를 더해준다. 산중턱부터 정상부까지 암반 으로 이루어져 있어 그 경치가 빼어나다.", + "MNTN_HG_VL" : "348", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 적성면", + "MNTN_NM" : "채계산" + }, + "longitude" : 127.226091, + "latitude" : 35.401224399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "341", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군", + "MNTN_NM" : "채계산" + }, + "longitude" : 127.226091, + "latitude" : 35.401224399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "죽산현감(竹山縣監)을 지낸 채씨(蔡氏)의 묘가 있는 산이라는 데서 유래하였다. 채죽산의 서쪽으로는 유구천이 흐르고 있는 넓은 충적 평야인 우성농조들이 위치해 있다.남쪽의 산등성이가 끝나는 곳에 부엉산이 있으며, 바로 금강으로 이어진다.", + "MNTN_HG_VL" : "177", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", + "MNTN_NM" : "채죽산" + }, + "longitude" : 127.0961111, + "latitude" : 36.474444400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산이 바위로 이루어져 봉우리마다 하늘을 찌를 듯 솟아있는 천관산은 지리산, 월출산, 내장산, 내변산과 함께 호남의 5대 명산중 하나다.아기바위, 사자바위, 종봉, 천주봉, 관음봉, 선재봉, 대세봉, 석선봉, 돛대봉, 구룡, 갈대봉, 독성암, 아육탑 등을 비롯 수십개의 기암괴석과 기봉이 꼭대기 부분에 비죽비죽 솟아 있는데, 그 모습이 주옥으로 장식된 천자의 면류관 같다하여 천관산이라 불렀다고 한다.", + "MNTN_HG_VL" : "724", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍, 대덕읍", + "MNTN_NM" : "천관산" + }, + "longitude" : 126.91597160000001, + "latitude" : 34.532343099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 이천군 실촌면과 신둔면을 가르고 선 천덕봉은 마을 뒷산처럼 큰 특징이 없는 평범한 산이다. 남서쪽의 오르막길을 향하다보면 드넓은 이천평야가 시야에 들어오는데 가을녁에 보면 황금색 벌판이 장관을 이룬다.고려말 공민왕이 홍건적의 난을 피해 이곳에 왔다고 하여 공민왕봉이라고도 한다. 원적산에서 가장 높은 봉우리이며 항상 구름과 안개에 싸여 있다. 산속에 신라 선덕여왕 때 혜법선사가 세운 영원사가 있고, 계곡에는 산간 오지마을인 실촌면의 외선리·내선리가 있다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.산행길은 대체로 완만한 편이나 천덕봉 정상에서 원적봉까지 육군 사격장지대기 때문에 산행을 하려면 다시 돌아서 남서쪽의 오르막길을 올라야 한다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 실촌면, 신둔면", + "MNTN_NM" : "천덕봉" + }, + "longitude" : 127.4425, + "latitude" : 37.358333299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면, 북후면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "안동의 진산인 학가산(870m)과 마주보고 있는 천등산은 산세가 부드럽고 풍수지리상 곳곳에 명당이 포진해 있으며 천년 고찰 봉정사(鳳停寺)를 품고 있다.봉정사는 신라 문무와 12년(672년) 의상대사가 명찰을 지을 명당을 찾기 위해 소백산 부석사에서 종이학을 만들어 보냈는데 그 학이 지금의 안동 제 1의 명찰인 봉정사에 떨어졌다고 한다. 이 사찰 극락전에서 발견된 상량문에 의하면, 의상대사의 제자인 능인대덕이 창건한 이래 조선시대까지 여러 차례 중수한 기록이 있어 국내에서 가장 오래된 목조 건물로 확인됐다. 이밖에도 조선시대의 대웅전을 비롯해 고금당, 화엄강당 등은 우리나라 건축연구에 중요한 자료가 된다.", + "MNTN_HG_VL" : "707", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고흥반도 최남단에 솟아 있는 천등산은 겉에서 보면 그냥 커다란 바위산 같지만 오르면서 보면 암릉들이 골고루 세밀하게 나뉜 것이 산행의 재미를 더해준다. 능선에는 상여바위, 암릉지대, 염소바위, 뭉치바위 등이 있고, 능선 곳곳에는 억새 밭이 장관을 이루고 정상 서편 천동마을 위쪽에는 철꾹동산이 잘 조성되어 있다.정상에는 조선조 때의 봉수대 축성이 흐트러져 있고 기우단으로서도 유명한 곳이며, 고흥 반도에서 팔영산에 이어 두 번째로 높은 산이라 남해의 조망이 특히 뛰어나다.정상 동쪽 금사에는 전남 유형 문화재로 지정된 고찰 금탑사의 극락전이 있다. 이 극락전은 삼국시대에 창건된 후로 여러 번 중수되었으나, 조선시대 말기적인 건축 모습을 잘 보여주는 건물로 알려 있다. 절 주변에는 천연기념물 제 2399호로 지정된 비자나무 숲이 유명하고, 이 나무는 신라 선덕여왕 6년에 처음 심어진 것이라 전해오고 있으며 동백나무 거목 군락지도 있다.", + "MNTN_HG_VL" : "550", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 풍양면, 포두면, 도화면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고흥반도 최남단에 솟은 천등산은 봉우리가 하늘에 닿는다고 해서 천등이라고도 하고, 스님들이 정상에 올라 천개의 등불을 켜놓아 천등이라고 불렀다는 이야기가 전해진다.해발 554미터의 낮은 산이지만 바다 근처에 있어 어느 곳에 올라도 다도해의 아름다운 모습을 볼 수 있고, 사방으로 등산로가 나 있어 골라 오르는 재미가 있다. 정상에는 봉수대가 있었는데, 동쪽으로 마복산 서쪽으로 장기산 봉수와 서로 응했다고 한다. 정상 맞은편으로 월각산(딸각산)이 위치하는데, 바위를 밟고 오르노라면 “딸각딸각”하는 소리가 난다고 해서 그렇게 부른다고 한다.천등산 중턱에는 철쭉공원이 조성되어 있어 5월 초순 꽃이 만개하면 등산객을 비롯해 가족단위 관광객이 많이 찾고 있으며, 동쪽 능선 아래에는 신라시대 원효대사가 창건했다는 금탑사와 이 사찰을 중심으로 형성된 비자나무 숲(천연기념물 239호)이 자리하고 있다.", + "MNTN_HG_VL" : "550", + "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 풍양면, 도화면, 포두면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 완주군 운주면에 위치한 천등산은 대둔산의 명성에 가려져 있었다. 그러나 천등산은 금남정맥의 주맥인 대둔산(878m)과 함께 도립공원으로 지정되면서 주말이면 대전과 전주에서 산을 찾는 사람들로 붐빈다.능선은 암릉지대가 많고 곳곳에 기암이 산재하며 절벽은 층층을 이루면서 노송과 어우러져 절경이다. 특히 521봉에서 감투봉으로 오르는 등선에는 거북등 같은 모양의 바위가 넓게 깔려 이색적이며 암봉도 빼어나다.빈덕바위 남쪽 절벽 밑에 있는 신망 터에는 동굴 속에 샘과 제단이 설치된 명소가 있는데 식수는 이곳에서 준비하는 것이 좋다. 정상 서편 골짜기에는 돌탑이 많고 무당의 기도 터인 움막과 석굴이 있다. 정상 북쪽 갈림능선에서 북동으로 꼬부라져 내려가는 구간은 암벽지대의 험로이므로 노약자는 서쪽 지능선길을 택하는 게 안전할 것이다.", + "MNTN_HG_VL" : "707", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 운주면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "대중가요 `울고 넘는 박달재'의 배경인 박달재로부터 6km 떨어진 곳에 위치한 천등산은 수도권과 가까운데다 교통편이 좋아 등산인 들의 발길이 끊이지 않은 산이다. 천등산의 남쪽으로 5km거리에 인등산이 있고, 다시 남쪽으로 지등산이 나란히 있어, 천지조화설을 담고 있는 「천부경」의 천지인을 뜻하는 것으로도 본다.지등산, 인등산, 천등산을 옛 사람들은 삼등산이라 불렀으며, 임진왜란 때는 정감록의 예언에 따라 많은 사람들이 이 산으로 피난을 했다고 한다. 천등산에는 조선조 세조 때 황규라는 지사가 명당을 찾아 전국을 돌아다니다가 이 곳 천등산에서 신선을 보고 명당을 찾아 산세도를 그렸다는 전설이 전해지고 있다. 산행들머리는 해발 453m인 다리재 고개마루턱으로 산행이 힘들지 않은 편이다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 산척면, 제천시 백운면", + "MNTN_NM" : "천등산" + }, + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "마석에서 서북쪽으로 4.5km 떨어져 있는 산으로 1983년 군립공원으로 지정되어 휴일이면 많은 사람이 몰리고 있다.특히 이 곳은 스키장과 청소년 심신수련장 등이 있으며, 산의 형세가 험하지 않고 나무가 울창하여 당일 등산코스로 알맞다. 1990년 11월 1일부터 야영장외 지역에서는 취사가 금지됐다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 오남읍, 화도읍", + "MNTN_NM" : "천마산" + }, + "longitude" : 127.272778, + "latitude" : 37.680556000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "170", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 인천", + "MNTN_NM" : "천마산" + }, + "longitude" : 127.272778, + "latitude" : 37.680556000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문경시 동로면에서 내려오는 금천이 산북면 산양면을 지나고 영순면에 와서 예천군에서 내려오는 내성천과 합쳐지고 다시 내성천이 낙동강과 합해지면서 영순면 달지리 삼강이 된다. 이곳에서 낙동강변을 따라 영순면이 있으며, 문경시의 젖줄기인 영강이 낙동강과 다시 만나는 곳 영순면 말응리 영풍교반까지 문경시의 제일 남쪽을 막고 있는 산이 천마산이다. 이 산이 영순면 달지리에서 영순면 이목리와 말응리까지 이어져 있어 낮지만 낙동강을 바라보며 지키고 있는 산이다.옛날 낙동강이 주요물품의 이동통로였을 당시에는 이 천마산 기슭 나룻가에 많은 배들이 드나들었다고 하며 아직도 금포 백포라는 이름이 불리어지고 있다. 그리고 옛날 산에 평령암(平岺庵)이 있다고 하나 지금은 없고 해장골에 해장사(海張寺)라는 작은 암자가 있다.천마산의 산행은 무엇보다도 낙동강을 굽어보는 모습이 아주 좋다. 귀파재에서 오르는 길 외에는 잡목과 덤불로 덮여 있다.", + "MNTN_HG_VL" : "278", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 영순면 이목리", + "MNTN_NM" : "천마산" + }, + "longitude" : 127.272778, + "latitude" : 37.680556000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천마산은 내와리와 복안리에 걸쳐 있는 산으로 천(天)은 높음을 뜻하고 마(馬)는 뫼(山)을 뜻하니 결국은 높은 산이라는 뜻을 지닌 해발 610.5m의 산이다. 산행을 하려면 언양에서 봉계행 버스(30분 간격)로 25분 후 미호에 하차한다. 고속도로 굴다리를 지나 30여 분 농로길을 따르면 두서 초등학교가 나오는데 상동(마리골)이다.상동상회에서 오른쪽 아스팔트 길을 따라 오르면 고개 언덕에 올라선다. 음지 마을로 내려서는 오작골이며 그 아래 오작골못이 보이고 언덕 밑에는 큰 노송이 버티고 있다. 본격적인 산행은 고개를 넘어서면서 시작된다. 정상에서는 주변 시야를 볼 수 없다.", + "MNTN_HG_VL" : "611", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 두서면 내화리", + "MNTN_NM" : "천마산" + }, + "longitude" : 127.272778, + "latitude" : 37.680556000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "324", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서천군 판교면, 문산면", + "MNTN_NM" : "천방산" + }, + "longitude" : 127.1466667, + "latitude" : 34.714444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서천", + "MNTN_NM" : "천방산" + }, + "longitude" : 127.1466667, + "latitude" : 34.714444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "485", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군", + "MNTN_NM" : "천방산" + }, + "longitude" : 127.1466667, + "latitude" : 34.714444399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "의정부과 동두천 중간쯤에 양주시 덕정리 철로변 마을에서 동쪽으로 나 있는 길을 따라가다 보면 남북으로 뻗은 산줄기가 보인다. 양주와 포천 땅을 가르는 산줄기인데 이 산줄기의 중앙부에 우뚝 솟은 산이 천보산이다. 연이은 바위봉과 소나무 군락이 어울려 산 전체가 수려한 경치를 뽐내고 있다. 능선은 바위봉우리로 되어 있고 소나무 군락이 많다.산자락에는 고려 때 3대 사찰이었던 회암사지(사적 128)와 회암사지선각왕사비(보물 387), 회암사지부도(보물 88), 회암사지쌍사자석등(보물 389) 등이 있고, 회암사지 왼편길을 오르면 1828년(순조 28)에 창건한 회암사가 있다. 주변에 불곡산·백화암·장흥국민관광지·권율장군묘 등이 있다. 정상에서는 북쪽으로 소요산이 손에 잡힐 듯 가까이 보이고 남쪽으로는 천길 절벽을 이루고 있다", + "MNTN_HG_VL" : "337", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 회천읍", + "MNTN_NM" : "천보산" + }, + "longitude" : 127.0667052, + "latitude" : 37.763901099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천봉산은 상주 삼악의 하나인 석악으로 상주의 명산이다. 천년에 한 번 봉황이 나타난다고 해서 천봉산(千峰山)이라는 설과 정상에 서면 주변의 천개의 산봉우리를 볼 수 있다고 하여 천봉산(千峰山)이라는 주장하는 사람도 있다. 산경표는 천봉산(天峰山)으로 표기되어 있다.천봉산에는 일찍부터 민속 문화가 발생하여, 성황사를 비롯해 산신제단이 현재도 남아 있고, 암석 신앙에서 비롯된 영암각이 있다. 성황사는 만민이 평안하고 풍요하며 신공으로 우순풍조하여 풍년이 들 것을 기원하던 자리다. 조선 후기까지도 고지기를 두어 지키게 하고 매년 제사를 지냈다 한다. 한마디로 천봉산은 민속 문화의 보고라 일컬을 만하다.정상은 황악산, 속리산, 주흘산 그리고 굽이쳐 흐르는 낙동강 등 산이 낮으면서도 주변 경치를 한 눈에 볼 수 있는 천연전망대다.최근 신년 일출산행지로 각광받고 있다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 만산동, 부원동", + "MNTN_NM" : "천봉산" + }, + "longitude" : 128.1429444, + "latitude" : 36.442608999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천봉산은 전라남도 보성군의 문덕면과 복내면의 경계에 자리한 해발 609m의 아담한 산이다. 무등산을 지나 남으로 달려가던 호남정맥이 화순군의 두봉산(631m)을 지나며 북동쪽으로 한 줄기 곁가지를 일으킨다. 이 곁가지는 장재봉과 알아리재를 지나 보성군과의 경계를 이루는 말봉산(584m)에 이르러 왼쪽으로는 까치봉을, 오른쪽으로는 천봉산을 지나 드넓은 주암호 푸른물에 스르르 내려앉게 된다.또한 이 산은 보성군을 비롯해 화순과 순천에까지 걸쳐 있는 주암호변에서 그 물기운으로 솟구쳐오른 듯한 형상이며 산세가 깊으면서도 전망이 빼어나며 깊은 계곡도 거느리고 있다. 또한 천봉산은 말봉산, 까치봉과 힘을 모아 대원사 계곡을 보호하고 있으며, 봉황에 관한 전설을 가지고 있다.들머리에 자리한 대원사는 1550년 전 백제 무령왕 3년, 아도화상에 의해 창건되었다고 전하며 6.25 동란으로 극락전만 남기고 소실되었으나 십여 년 전부터 중창불사가 시작된 규모있는 사찰이다. 문화유산으로는 지방유형문화재 제 35호인 자진원오국사 부도와 제87호인 극락전이 있다. 연못에 놓인 돌다리를 지나 경내에 들러 극락전과 부모공덕불, 500년 고목 등을 둘러보고 일주문을 나서 위쪽에 자리한 티벳박물관 앞을 지나 산행을 시작한다.", + "MNTN_HG_VL" : "436", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군 문덕면", + "MNTN_NM" : "천봉산" + }, + "longitude" : 128.1429444, + "latitude" : 36.442608999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천비산은 만인산에서 산줄기가 북서쪽으로 달리다 어남산(464.5m)을 거쳐 유등천에서 떨어지기 직전에 정생동에서 힘을 모아 솟구친 산이다.천비산의 정기를 이어온 이 산 언저리는 옛날부더 오늘에 이르기까지 민족사의 중요한 역할을 담당해 온 한편, 민족정기를 크게 불러 일으킨 곳이다.", + "MNTN_HG_VL" : "466", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 중구 침산동, 서구 정생동", + "MNTN_NM" : "천비산" + }, + "longitude" : 127.3910219, + "latitude" : 36.2360647 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천삼산은 치악산(1288m)의 남대봉에서 뻗어 내려 온 능선이 감악봉을 조금 못미쳐 남서쪽으로 흘러내리는 곳에 위치한 산이다. 옛부터 약초가 많고 위장병에 효험 있는 천수암 약수터가 있어 영험한 산으로 알려진 이 산에는 사찰이 세 개나 있으며 한때 새마을 운동의 일환으로 많은 사람들이 교육받았던 가나안농군학교가 터를 잡고 있다.또한 20여리에 달하는 능선 자락에 시루봉, 상봉, 중봉, 동굴, 천수암터, 흔들바위등 기기묘묘한 바위의 천국이다. 용암 3리 선터골 상단부에 철철바위가 있는데 늦가을철 비가 내리면 이 바위 위로 산삼씨앗이 흘러내려와서 하늘에서 산삼씨앗을 준다는 전설이 있는 산이다. 그래서 하늘이 산삼을 내리는 산, 천삼산으로 부르게 되었다고한다.", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", + "MNTN_NM" : "천삼산" + }, + "longitude" : 128.1018985, + "latitude" : 37.209571099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "\"김새 때문에 여러 가지 이름으로 불린다. 동쪽에서 보면 하늘 천(天)자로 보이고 정상이 일자봉으로 생김새가 특이하여 하늘이 내놓은 산이라 해서 천생산이라고도 하고, 함지박을 엎어 놓은 것 같다 하여 방티산, 한일자로 보인다 해서 일자봉, 병풍을 둘러친 것 같다 해서 병풍바위라고도 부르며, 장천면 일대에서는 천생산성을 박혁거세가 처음 쌓았다는 전설 때문에 혁거산이라고 부른다.천생산성은 경상북도 기념물 제12호로 지정되었다. 그런가하면 금오산성과 낙동강을 동서로 끼고 있어 오히려 전략적 가치가 높은 산이다. 선조 29년(1596년) 임진왜란 때 홍의장군 곽재우가 이 산에 의지하여 왜적을 대파한 것도 산이 위치하고 있는 전략적 가치를 말해준다. 그가 활약했던 천생산성이 있고, 군기를 굽던 자리가 지금도 남아있다. 구미시를 내려다보고 있다.산행은 무지개 마을에서 시작해 천룡사와 미득암을 지나 정상에 오른 뒤 통신 바위를 지나 신장리의 자골로 내려온다.", + "MNTN_HG_VL" : "407", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 산동, 장천면", + "MNTN_NM" : "천생산" + }, + "longitude" : 128.458507, + "latitude" : 36.1107935 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 구미시 신동, 인의동, 금전동과 장천면 경계에 솟은 천생산은 많은 이름을 가졌다. 동쪽에서 볼 때 생김새가 ‘하늘 천’자를 닮아 하늘이 빚은 산 천생산, 함지박을 엎어놓은 것 같아 함지박의 경상도 사투리 ‘방티’를 붙인 방티산, 능선이 ‘한 일’자로 보인다고 해서 일자봉이라고도 한다. 장천면 일대에서는 정상에 있는 산성을 박혁거세가 처음 쌓았다는 전설 때문에 혁거산으로 통한다.이처럼 다양한 이름을 가진 천생산은 썩 높지 않으며 산마루가 길고 평탄해 산행하는 데 힘들지 않다. 숲도 울창한데 구미시에서 삼림욕장을 조성해 시민들이 쉽게 자연을 접할 수 있도록 했다.정상 서쪽에는 불쑥 튀어나온 큰 바위 미득암(米得岩)이 있다. 사자가 하늘을 우러러 포효하는 형상이다. 천생산을 앙천산(仰天山)이라고도 부르는 이유는 바로 이것 때문.임진왜란 당시 난공불락이던 천생산성을 공략하기 위해 왜군이 산기슭에 큰 연못을 파 성 안의 물을 마르게 했다. 이에 의병장 곽재우는 미득암 바위에 말을 세워두고 쌀을 주르르 부어 말을 씻는 시늉을 했다. 이를 본 왜군은 산성에 물이 많은 것으로 생각하고 물러갔다고 한다. 그래서 쌀의 덕을 보았다고 하여 ‘미덕암(米德岩)’으로도 부른다.", + "MNTN_HG_VL" : "407", + "MNTN_LOCPLC_REGION_NM" : "경북 구미시 신동ㆍ인의동ㆍ황상동ㆍ금전동, 장천면", + "MNTN_NM" : "천생산" + }, + "longitude" : 128.458507, + "latitude" : 36.1107935 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통도사 인터체인지에서 부산쪽으로 7km 떨어진 곳에 있는 산으로, 경부고속도로 위로 가설된 용연 육교를 지나 3km쯤 가면 내원사로 가는 골짜기에 다다르게 된다. 여기서부터 기암괴석과 울창한 숲이 우거져 금강산의 계곡을 방불케하는 천성산이 시작된다.", + "MNTN_HG_VL" : "920", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 하북면, 상북면, 웅상읍", + "MNTN_NM" : "천성산" + }, + "longitude" : 129.11215920000001, + "latitude" : 35.420248999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", + "MNTN_NM" : "천왕산" + }, + "longitude" : 128.28416669999999, + "latitude" : 34.990833299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;화왕산과 관룡산 조망이 일품gt;천왕산(619m)은 낙동정맥 사룡산에서 비슬산을 지나 밀양 종남산 오우진나루까지 146킬로미터의 산줄기로 뻗은 비슬지맥의 한 봉우리다. 묘봉산(514m)에서 배바위산(608m)으로 이어지는 비슬지맥에서 약간 벗어나 있지만 비슬지맥을 종주하는 등산인들이 꼭 들리는 곳이다. 남쪽 밀양시 청도면의 소태리에서 죽바위산-호암산을 거쳐 건티재로 갔다가 배바위산-천왕산에 오른 후 천왕재로 내려오는 긴 코스의 산행을 할 수 있다. 또 북동쪽의 풍각면 덕양리(가양)에서 임도를 따라 대산사까지 가거나 각남면 상옥산에서 대산사에 오른 후 족금당-천왕산-배바위산으로 산행을 이어갈 수도 있다. 비슬지맥이 지나는 천왕산-배바위산-건티재 능선은 길이 뚜렷하지만 족금당과 대산사로 이어지는 능선은 길이 다소 희미하다. 능선에 툭 튀어나온 큰 바위인 배바위에 오르면 화왕산과 관룡산 조망이 일품이다. 능선에 샘이 없어서 식수는 미리 준비한다.", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", + "MNTN_NM" : "천왕산" + }, + "longitude" : 128.28416669999999, + "latitude" : 34.990833299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "156", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 수성구 고산동", + "MNTN_NM" : "천을산" + }, + "longitude" : 128.70492100000001, + "latitude" : 35.845638899999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "시루봉(웅산)줄기가 남으로 뻗어 이룬 줄기에 있는 천자봉은 기반암이 노출하는 큰 암괴로 되어 있으며 성채처럼 보인다. 산록은 가파르고 곳에 따라 산정과 산능에서 떨어져 나온 자갈들이 즐비하여 산 전체가 돌산처럼 보이기도 한다.웅장한 산세 때문에 조선 태조(이성계), 명나라 태조(주원장), 주(朱)씨, 이(李)씨, 천자(天子) 등과 관련된 전설이 여럿 전한다.옛날 천자봉 연못의 이무기가 용이 못 되자 마을 사람을 못살게 굴었다. 이에 염라대왕이 이무기에게 용대신 천자가 되라고 권하여 연못 아래 백일마을의 주(朱)씨 가문 아기로 태어났다. 이 아기가 뒷날 중국으로 건너가 명나라 태조인 주원장이 되었다고 한다. 다른 전설도 전한다. 함경도 사람 이씨가 하인인 주씨를 데리고 명당을 찾으러 천자봉에 올랐더니 바다에서 반인반어(半人半漁)의 괴물이 나타나 바닷속에 굴이 둘 있는데 오른쪽 굴이 천자가 태어날 명당이라고 점지해 주었다. 하인 주씨가 욕심이 나서 자기 선친은 오른쪽에 묻고 주인 이씨의 유골은 왼쪽에 묻었다. 그래서 주씨 가문에서는 명나라 태조 주원장이 태어났고, 이씨 가문에서는 조선 태조 이성계가 태어났다고 한다.천자봉 정상에서 바라다 보이는 남해바다의 크고 작은 섬들이 이뤄내는 한 폭의 수채화 같은 정취를 자아내게 하는 조망은 가히 절경이다.", + "MNTN_HG_VL" : "502", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 자은동, 웅천 1동", + "MNTN_NM" : "천자봉" + }, + "longitude" : 128.72499999999999, + "latitude" : 35.126666700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해발 158m의 비교적 낮은 지역인 전주대 뒷산으로 일반 등산객들은 아주 드물게 이동하는 지역이며 주로 전주대 학생들이 즐겨 찾는 지역임", + "MNTN_HG_VL" : "158", + "MNTN_LOCPLC_REGION_NM" : "전라북도 전주시 상림동", + "MNTN_NM" : "천장봉" + }, + "longitude" : 127.8280278, + "latitude" : 36.755976400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "332", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", + "MNTN_NM" : "천재산" + }, + "longitude" : 128.91524039999999, + "latitude" : 37.095739199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천주산은 자체로도 녹록치 않은 높이를 자랑하지만 주변에 버금갈 만한 산이 없어서 더욱 뛰어난 상승감을 준다. 분지로 둘러싸인 창원을 굽어보는 진달래 명산으로, 지리산 영신봉(1652m)에서 김해 신어산(631m)을 지나 낙동강 하구에 그 꼬리를 담그는 232킬로미터의 낙남정맥에 솟은 수많은 산 가운데서도 단연 돋보이는 명산이다.천주산의 주봉은 용지봉으로 주변 일대에 진달래가 군락을 이루어 있다. 조망이 시원한 정상에서는 무학산에서 정병산 지나 비음산, 용지봉까지 이어지는 낙남정맥이 마산과 창원을 감싸며 꿈틀거리듯 뻗어가는 장쾌한 모습을 감상할 수 있으며, 웅장한 산세에 둘러싸인 아름다운 도시 마산과 창원, 진해도 한눈에 볼 수 있다. 무학산과 마산 앞바다, 북쪽으로 철새들의 낙원인 주남저수지와 그 일대 들판도 그림처럼 펼쳐진다.", + "MNTN_HG_VL" : "640", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 마산회원구 구암동, 의창구 북면", + "MNTN_NM" : "천주산" + }, + "longitude" : 128.59073989999999, + "latitude" : 35.271812500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산 남동쪽의 산행 출발점으로는 간송1리인 천주마을과 천주에서 975번 도로를 따라 북쪽으로 약 1km 더 올라가면 만나는 천주사 입구가 있다. 산의 북쪽에서는 동로면 소재지에서 노래이(동로면 노은1리 지형도에는 노루이라고 표기됨)로 접근한 다음 산행을 시작할 수 있다. 다만 어느 코스로 오르든 암벽지대를 오르게 되므로 주의를 요한다. 천주마을에서 산행을 시작하려면 이 마을 포장도로길을 따라 올라가면\"천산정\"이 나오는데 이곳에서 물을 준비해야 한다.계곡을 따라 20분 정도 오르면 능선으로 이어진 길이 나타나는데 이 능선길로 접어들면 된다. 능선길을 따라 40분정도 오르면 큼직한 돌로 형성된 너덜지대를 지나게 되고 이곳에서는 천주마을과 지나온 길을 모두 돌아볼 수 있어 전망이 좋다이 너덜지대를 지나면 절벽이 나타나서 길이 없어진 것처럼 보인다. 하지만 오른쪽으로 자세히 찾아보면 절벽사이로 난 길을 발견할 수 있다. 이곳을 지나 조금 더 오르면 정상이 보이고 다시 오른쪽으로 틀면 노송이 한 그루 나타난다.소요 시간 : 2시간최적 탐방 시기 : 4~10월 \/ 봄, 여름, 가을볼거리 : 경천호 경천댐,큰봉 정상에 서면 운달산, 대미산, 문수봉, 황장산이 한눈에 보여 백두대간의 웅장함을 실감할 수 있다.숲길 명소 : 돌탑, 암벽", + "MNTN_HG_VL" : "836", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 노은리", + "MNTN_NM" : "천주산" + }, + "longitude" : 128.59073989999999, + "latitude" : 35.271812500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 원주시 소초면과 횡성군 안흥면의 경계를 이루는 천지봉은 치악산과 매화산 중간에 우뚝 솟은 봉으로 치악산 정상인 비로봉의 유명도에 밀려 아직도 깨끗함을 간직하고 있다.남쪽 능선길은 부드럽고 많은 산악인으로 붐비는 구간인 반면, 북쪽 천지봉으로 이어지는 능선은 굴곡이 심하고 전망 좋은 암봉이 곳곳에 있으며 섬뜩한 기운이 감돌기조차 하는 한적한 산길이라 대조적이다.영말골과 세렴골계곡은 울창한 수림이 하늘을 가리고 군데군데의 폭포와 옥 같은 계류가 어우러져 매우 아름답고 산길은 원시림을 방불케 해서 더욱 좋다. 정상에는 삼각점이 있고 밋밋하기는 하나 비로봉,백덕산,매화산,삼봉 등 사방을 바라보는 전망이 일품이다.", + "MNTN_HG_VL" : "1087", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면, 횡성군 안흥면", + "MNTN_NM" : "천지봉" + }, + "longitude" : 127.2261958, + "latitude" : 36.2128242 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천제봉은 용암산 아래 제전마을 위에 있으며 천제봉이 있는 무수등에는 지형이 소의 등처럼 생겼다 하여 무소등에서 유래됐다.가뭄이 들 때면 이곳 바위에서 상녀들이 춤을 추며 기우제를 지냈다. 이곳에서 기우제를 지내는 이유는 비를 내리게 하는 용이 북쪽 용암산에 숨어 있다고 믿었기 때문이다. 무수등에서 천제봉으로 가는 길은 바위로 구성되어 아슬아슬한 암벽을 타고 내려야 한다.", + "MNTN_HG_VL" : "685", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면", + "MNTN_NM" : "천지봉(천제봉)" + }, + "longitude" : 128.72499999999999, + "latitude" : 35.126666700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 영동군 양산면과 충남 금산군 제원면의 경계를 이루는 천태산은 기암절벽과 수림이 조화를 이루고 있어 일명 '충북의 설악'이라 불리고 있는 산이다. 등산로는 바위지대에다 안내표지와 로프가 설치되어 있어 아기자기한 바위산행을 만끽할 수 있는 묘미가 있는 산이며 뛰어난 자연경관을 자랑하는 산이기도 하다.이름난 명소가 산재해 있어 가족동반 등산지로도 좋다. 계곡은 비록 짧으나 시원하게 쏟아지는 용추폭포와 진주폭포가 있고, 봄에는 진달래, 벚꽂이 온 산을 뒤덮고 가을에는 단풍 또한 좋다.천태산에는 양산 8경 중 제1경인 영국사가 있으며, 10km 떨어진 곳에 여의정, 강선대, 용암 등이 있어 볼거리가 많은 곳이다. 영국사 앞 등산로 입구에는 천연기념물 제233호로 지정된 수령 천년이 넘는 은행나무가 서 있다.이 나무는 높이 18m, 둘레가 6m에 달하는 거목이다. 나라를 평안하게 하는 뜻을 가진 영국사는 고려 31대 공민왕이 홍건적의 난을 피해 이 근처에 와서 천일기도를 드린 끝에 난을 평정한 것을 기념하여 절을 짓고 이름을 영국사라 붙였다고 전해지고 있다.", + "MNTN_HG_VL" : "715", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 양산면, 충청남도 금산면 제원면", + "MNTN_NM" : "천태산" + }, + "longitude" : 127.6135306, + "latitude" : 36.157161500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "392", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시", + "MNTN_NM" : "천태산" + }, + "longitude" : 127.6135306, + "latitude" : 36.157161500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천태산은 천성산, 영축산과 함께 양산의 3대 명산으로 예부터 경치가 빼어나기로 유명할뿐 아니라 남서쪽으로 낙동강, 북서쪽으로 삼랑진 양수발전소댐, 그리고 동북쪽으로 여름철 피서지로 유명한 배내골이 연계되어 부산, 울산, 마산 등에서 산행지로 유명세를 떨치고 있다.특히 정상에서 바라본 낙동강의 낙조는 탄성을 자아내도 모자랄 만큼 아름답고 신비하다.남쪽에 위치한 천태각(천태정사)에서 용연폭포에 이르는 30여리의 긴 계곡은 태고의 신비를 그대로 간직한 맑고 깨끗한 자연경관을 자랑하고 있다.또 하나 볼거리로 산 정상 이르기 전에 조그마한 암자가 있는데 그곳을 따라 골짜기를 오르면 기암절벽을 이룬 절경을 만날 수 있으며 정상에 오르면 넓은 바위가 평지처럼 놓여있어 마치 하늘 밑 구름에 떠 있는 느낌을 받는다. 물소리를 들으며 주위경관에 취해 산행을 하다보면 도원경(桃源境)에서 신선들과 장기나 바둑을 두면서 현세의 시름을 잊을 것 같은 착각에 빠져들기도 한다.임진왜란 때 박진 밀양부사가 작원관을 최후의 교두보로 하고 왜적에 대항했으나 이기지 못하고 눈물을 머금고 후퇴했던 곳이다. 이곳은 관(국경이나 중요한 지역에 두어 지나는 사람과 물건 등을 조사하게 하던곳)이기 때문에 서울로 가는 행객들이 여기서 검문을 받기도 하고 쉬어가는 곳이기도 했다.", + "MNTN_HG_VL" : "631", + "MNTN_LOCPLC_REGION_NM" : "경남 양산시 원동면", + "MNTN_NM" : "천태산" + }, + "longitude" : 127.6135306, + "latitude" : 36.157161500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "289", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진", + "MNTN_NM" : "천태산" + }, + "longitude" : 127.6135306, + "latitude" : 36.157161500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천택산(川擇山)은 화남 임곡에 솟아있는 육산으로 이 산 밑에는 지금도 우복길지의 비결을 믿고 사는 사람들이 있다. 조선 후기의 술사 이량박이 임실 즉 임곡 안골을 우복동(牛腹洞)이라 칭하였기 때문이다. 일대에는 우복동과 관련된 태조산, 대모산, 용굴, 시루봉, 적(赤)바위 등이 있다. 태조산은 안골에서 보는 구병산을 가리킨다. 남자의 얼굴 모양이라는 것이다. 안골 바로 앞산은 또 여인이 누워있는 형상이라며 대모산(大母山)이라고 부른다. 적바위는 대모산에 있는데 임곡리 옆동네 이름 적암리가 여기서 유래했다. 시루봉은 적암리의 25번 국도변에 있다.또한 일대는 석회암지대로 석회를 채굴하고 있으며 석탄을 캔 흔적도 남아 있는 특이한 지형이다. 동학농민운동 때 지도부의 은신처로 사용되던 석회암 동굴인 용굴이 있다. 정상에서는 봉황산에서 국수봉으로 이어지는 백두대간과 구병산·팔음산·백화산이 보인다. 하산은 올라왔던 길로 되돌아 내려간다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화남면 임곡리, 화서면 사산리", + "MNTN_NM" : "천택산" + }, + "longitude" : 139.76481200000001, + "latitude" : 35.708142000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "401", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", + "MNTN_NM" : "천호봉" + }, + "longitude" : 126.79073750000001, + "latitude" : 37.445665300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "만행산 천황봉은 백두대간 장수 영취산에서 금남호남정맥으로 분기되어 남서쪽으로 뻗어가다가, 팔공산을 솟구쳐 놓았다. 이곳에서 섬진 2지맥으로 갈리어, 묘목산(846m), 상서산(627.4), 만행산, 약산, 묘적봉(567.7m), 풍악산(620m), 응봉(579m), 주생터널, 문덕봉(598.1m), 삿갓봉(629.1), 고리봉(708m), 상귀티 730번 도로, 섬진강까지 이어지는 산줄기의 중간지점의 만행산 줄기 가운데서 우뚝 솟아 오른 봉우리이다.천황봉은 유난히 뾰족하게 우뚝 솟은 삼각봉이어서 지리산같은 큰산에서 작은 산을 찾기는 어렵지만, 이 산은 매우 특이해서 많은 산 가운데서 쉽게 눈에 띈다.", + "MNTN_HG_VL" : "910", + "MNTN_LOCPLC_REGION_NM" : "전북 남원시", + "MNTN_NM" : "천황봉" + }, + "longitude" : 127.20583329999999, + "latitude" : 36.342500000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상남도 밀양시 단장면·산내면과 울산광역시 울주군 상북면(上北面)의 경계에 있는 산이다. 주봉(主峰)은 사자봉이다. 남쪽 5km 부근에 솟아 있는 재약산(載藥山:주봉은 수미봉 1,018m)과 맥이 이어져, 천황산을 재약산으로 일컫기도 하는데, 이러한 혼동은 천황산이 일제강점기 때 붙은 이름이라 하여 '우리 이름 되찾기' 운동의 일환으로 사자봉을 재약산 주봉으로, 재약산을 수미봉으로 부르면서 생겨났다.산세가 수려하여 삼남금강(三南金剛)이라 부르며, 인근 일대의 해발고도 1,000m 이상의 준봉들로 이루어진 영남알프스 산군(山郡)에 속하는 산이다. 산세는 부드러운 편이나 정상 일대에는 거대한 암벽을 갖추고 있다. 수미봉·사자봉·능동산·신불산·취서산으로 이어지는 능선은 드넓은 억새평원으로서 사자평 고원지대라고 부르는데, 일대는 해발고도가 800m에 달해 목장으로 개발되어 있다.서쪽 산기슭에 있는 유명한 대찰(大刹)인 표충사(表忠寺)를 비롯하여 부근에 내원암(內院庵)·서상암(西上庵) 등의 절과, 높이 20m의 폭포 2개가 연이어 있는 칭칭폭포[層層瀑布:毘盧瀑布], 무지개가 걸리는 높이 25m의 금강폭포 등 명소가 있다. 천황산의 북쪽 사면에는 가마볼·호박소[臼淵] 등의 명소 외에 단열냉각에 의한 물리적 현상으로 여름에도 골짜기에 얼음이 어는 얼음골(천연기념물 224)이 있다.", + "MNTN_HG_VL" : "1189", + "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상남도 밀양시", + "MNTN_NM" : "천황산" + }, + "longitude" : 128.97150189999999, + "latitude" : 35.557452300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "철마산은 쇠말산, 샛말, 소멀미 등 비슷한 속명이 있다. 옛날 이곳은 큰홍수와 해일로 인하여 오랫동안 물속에 잠겨 있었는데, 미역바위의 용굴에서 동해 용왕의 명을 받은 용마가 나와서 물을 다스리고 나서부터는 물이 없어 용마는 환궁하지 못한 채 햇볕에 말려져 점차 굳어져서 작은 쇠말이 되어 최근까지도 그 흔적이 남아 있었기 때문에 쇠로 된 말이 있는 산이라 하여 쇠(鐵), 말(馬), 뫼(山)로 철마산이라 하였다고 한다.쇠는 소, 새와 같은 말로 샛바람이라 하는동쪽을 뜻이고, 말은 마라, 말, 머리와 동계어로서 마루라는 말로서 산마루 로 산등성이를 뜻하는 말이다.", + "MNTN_HG_VL" : "605", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면", + "MNTN_NM" : "철마산" + }, + "longitude" : 127.24682780000001, + "latitude" : 37.720437500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "음지 마을의 주산으로 옛날에 장군이 암굴에서 철마를 타고 나왔다는 전설이 있어 불려진 산으로 화악산 줄기의 대표적인 명산이다. 정상에는 아직도 성터(철마산성)가 남아 있고 주위에는 높고 험한 산줄기가 이어져 천혜의 요새를 이루고 있다.남북으로 뻗은 산줄기를 기준으로 서쪽은 산세가 급경사를 이루어 이렇다 할 계곡도 없지만, 상대적으로 경사가 완만한 동쪽 일원에는 비금계곡이라는 남양주시 최고의 계곡과 지계곡들이 여럿 있어 여름 피서철 산행지로 이름 높다.또한 동남서 방향에 돌을 쌓았으며 불암이라는 절벽에는 장군이 나왔다는 바위굴이 있다. 그 바위굴은 장군이 말을 매어 두고 사육했던 곳으로 암반의 곳곳에 장군의 흔적이 역력히 남아 잇다. 또한 전설에 의하면 바위굴은 신라의 선인 옥단춘의 출생지로서 고려 초 보조국사가 그 자리에 한선사를 건립했다는 기록이 남아 있다.", + "MNTN_HG_VL" : "627", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "철마산" + }, + "longitude" : 127.24682780000001, + "latitude" : 37.720437500000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "첨찰산은 등산로 주변에 인공보조물이 전무해 태고적 자연미가 그대로 살아 있다. 또한 산길이 천연기념물 107호로 지정된 상록수림 터널로 이어지고 있어 신선미가 넘친다. 상록수림에는 동백, 후박, 참가시, 감탕, 종가시, 생달, 모새, 참식, 차, 자금우, 광나무, 붉가시나무, 메밀잣밤 등 상록성을 띈 나무는 물론, 졸참, 자귀, 느릅, 말오줌때, 쥐똥, 실거리, 조록, 소사나무 등 50여종에 달하는 낙엽성을 띄고 있는 나무들이 섞여 쌍계사 주변에 숲을 이루고 있다.이런 다양한 수림 덕분에 사계절 산과일을 맛보며 산행을 즐길 수 있다. 봄에는 보리똥, 꼬지딸, 보리딸을, 여름에는 먹딸, 수릿딸, 박딸(산딸), 신금열매가 있고 가을에는 넝쿨식물인 산능금, 으름, 잣밤, 윤노리, 산감, 돌배, 머루, 다래, 갈매나무 열매 등이 군침을 돌게 한다.첨찰산 산행을 하며 쌍계사를 둘러보지 않을 수 없다. 신라 때 도선국사가 창건한 이 사찰은 사찰 양편으로 하천이 흐른다 하여 절 이름이 쌍계사로 지어졌다. 건립 연대는 숙종 23년 (1697년)으로 약 1미터 높이의 자연석 기단에 주춧돌을 놓고 그 위에 원주를 세운 대웅전이 볼만하다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "전남 진도군 고군면ㆍ의신면", + "MNTN_NM" : "첨찰산" + }, + "longitude" : 126.304923, + "latitude" : 34.465848000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "첩푸산은 시어골을 가운데에 두고 대미산과 마주서서 두상에서 풍부하게 흘러내리는 물줄기로 중산저수지를 만들어 놓았다. 첩푸산은 옛날 이 산자락에 금광이 있었다는 데서 적보산이라 불렀고, 아홉 개의 지능선이 마치 머리빗같은 형상으로 뻗어내린 데서 구봉산이라 불렀는데 옛날 어느 마을에 마음씨 착한 총각이 살았다. 그가 아름다운 처녀와 결혼해 가정을 꾸렸는데 그녀가 색을 지나치게 탐하는 바람에 남편은 견딜 수가 없었다. 그래 궁리 끝에 이 산으로 도망해 와 숨어 살았고 그 후 이 산을 첩푸산이라 부르기 시작했다고 한다.남쪽자락 상모면 소재지에 수안보 온천이 자리잡고 있어 산오름한 뒤 온천욕을 즐길 수 있다.", + "MNTN_HG_VL" : "699", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면 중산리, 온천리", + "MNTN_NM" : "첩푸산" + }, + "longitude" : 127.986448, + "latitude" : 36.844752000000007 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청계산이란 이름을 가진 산이 경기도에만 세 곳이 있다. 양평군 양서면의 청계산(658m)과 과천시와 성남시의 경계를 이루는 청계산(618m), 그리고 포천군 일동면과 가평군 하면의 경계를 이루는 청계산(849m)으로 이 중에서 포천 청계산이 가장 높고, 산세가 커 산행코스도 다양하다.수도권 지역에서 등산인들이 즐겨찾는 산들 중 하나인 청계산은, 관악산과 마주한 과천의 청계산(618m)과 양평군 양서면에 있는 청계산(658m)보다 그 규모나 아름다움에 있어 으뜸으로 꼽힐 만한 곳이다.이 청계산(849.1n)의 일반적으로 잘 알려진 등산 코스는 청계저수지를 기점으로 해서 길매고개를 거쳐 정상에 오른 뒤 동북쪽으로 뻗은 계곡을 통해 다시 청계저수지로 하산하는 것이다. 상판리 방면에서 갈매재로 올라가는 길은 1990년부터 입산금지 구역으로 지정되어 있다.실제 정상은 서북쪽에 솟은 육산의 모습을 지닌 봉우리다.정상에서 북쪽으로 내려설 때 바위지대를 지나야 하므로 안전에 유의하도록 한다.", + "MNTN_HG_VL" : "618", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", + "MNTN_NM" : "청계산" + }, + "longitude" : 127.0415787, + "latitude" : 37.414165699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서울시 서초구 양재동과 경기도 과천, 의왕, 성남시에 걸치고 있으며 서울 주변에서 숲과 계곡, 절, 공원 등을 한꺼번에 만날 수 있는 청계산은 청룡이 승천했던 곳이라 과거에는 청룡산으로도 불렸다. 남북으로 흐르는 능선을 중심으로 펼쳐진 산세가 수려하며 숲 또한 울창하고 계곡이 깊고 아늑하다.과천의 서울대공원에서 바라보면 대공원 뒤에 병풍처럼 둘러있으며 바위로 되어 있는 정상인 망경대가 우뚝 솟아 보인다. 정상에 서면 북서쪽으로 펼쳐진 계곡 아래 과천시와 동물원, 식물원이 있는 서울대공원, 각종 놀이기구가 있는 서울랜드, 국립현대미술관, 과천 경마장이 한눈에 내려다보인다.청계사에는 갖가지 명물이 많은데 그중 대표되는 것이 계단길이다. 시민의 손으로 산을 꾸미겠다는 취지로 얼마의 돈을 지불하면 계단 한 칸 마다 사연을 적어 꾸밀 수 있게 했다. 자신들의 소망, 기업이나 가게 홍보, 성경 구절 등으로 계단을 빼곡이 채우고 있어, 계단을 오를 때마다 읽어 가는 재미가 쏠쏠하다. 또 청계산은 역사적으로도 절의 곧은 선비들이 난세를 피해 은거한 충절의 산이라 할 수 있다. 대표적인 인물은 고려의 충신 이색과 조윤, 조선 중기의 김종직의 문하로 활동하던 일두 정여창이다. 망경대, 금수샘, 이수봉 등은 모두 그들과 관계되어 있다.", + "MNTN_HG_VL" : "873", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 신원동, 경기도 과천시 막계동, 의왕시 청계동, 성남시 수정구", + "MNTN_NM" : "청계산" + }, + "longitude" : 127.0415787, + "latitude" : 37.414165699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "동쪽으로 용문산과 북쪽으로 중미산을 건너다보고 있으며 남서쪽으로는 남한강이 유유히 흘러나가고 있다. 교통이 그렇게 나쁜편은 않은데도 그냥 지나쳐 버리기 쉬운 산중 하나이다. 목왕리 못 미쳐에는 조선중엽의 문신인 한음 이덕형 선생의 묘와 신도비가 있어 산행길에 들러봄직 하고 정상에 서면 북한강과 발아래 펼쳐지고 두물머리인 양수리 일대가 잡힐 듯 내려다 보인다.양평에 위치한 이 청계산은 수도권 일대의 세 개의 청계산 중 가장 알려지지 않은 산이다. 호젓한 산행을 즐기고 싶다면 한 번쯤 찾아 볼 만하다.", + "MNTN_HG_VL" : "849", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평 서종면, 양서면", + "MNTN_NM" : "청계산" + }, + "longitude" : 127.0415787, + "latitude" : 37.414165699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산이 두리뭉실하다고 하여 두루봉이라고 했던가. 유래는 알 수 없지만 인근 마을에서 두루봉이라고 부른다. 대궐터산이라고 부르는 사람들도 있는데 이는 후백제를 건국한 견훤이 이 산에 성을 쌓고 대궐을 지었다고 청계마을 사람들이 말하는 것을 보고 누군가가 대궐터산이라는 이름을 붙인 것으로 추측된다.그러나 상주의 역사책 상산지에 이 산이 청계산(淸溪山)이라고 나와 있으니 청계산 두루봉이라고 부르는 것이 맞다. 대궐터산 명칭을 꼭 붙이려면 극락정사 뒤 삼각점이 있는 곳에만 한정해야 한다.", + "MNTN_HG_VL" : "658", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화서면 화송리, 화남면 동관리", + "MNTN_NM" : "청계산" + }, + "longitude" : 127.0415787, + "latitude" : 37.414165699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "230", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초", + "MNTN_NM" : "청대산" + }, + "longitude" : 128.56960169999999, + "latitude" : 38.1778786 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청도읍에서 남서쪽으로, 밀양시에서는 북서쪽으로 솟은 화악산은 이 일대에서는 가장 높은 산이다. 이 산은 화악산의 북쪽, 같은 능선에서 솟은 산으로 산 북쪽에는 신둔사가 있고 동쪽에는 적천사가 있다.먼 옛날 청도에는 이서국(伊西國)이란 부족국가의 도읍지가 있었다고 한다. 그래서 한 나라의 수도였던 곳에만 있는 남산이 이곳 청도에도 있다.삼국사기와삼국유사에서 전하는 이서국은 한때 신라를 공격해 위기에 빠뜨릴 정도의 강국이었으나 결국 신라에 합병되었다. 그래서 남산에는 신라군사에 쫓긴 이서국의 왕이 숨어들었다는 전설을 갖고 있는 은왕봉이 있다. 서울과 경주, 개성의 남산이 300m 정도인데 비해 청도 남산은 800m 대의 높이를 자랑하는데 등산로가 여럿 있어 그 위용을 알 만하다. 산 곳곳에 뛰어난 암릉 전망대를 품고 있으며 정상 북쪽에는 비구니 사찰인 죽림사가 자리잡고 있다. 이곳 명소 가운데 하나인 약수폭포는 상부의 저수지에 물을 저장하고 있다가 여름에 풀어내 절경의 극치를 보여준다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "청도남산" + }, + "longitude" : 128.70460869999999, + "latitude" : 35.614273900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉화읍에서 동남쪽으로 26km 떨어진 청량산(869.7m)에는 금탑봉을 비롯하여 아름다운 봉우리 12개와 8개의 동굴이 있다.자연경관이 수려하여 옛부터 소금강이라 전하여지는 명산으로써 태백산에서부터 시작되는 낙동강 줄기가 절벽을 감아돌아 절경을 빚어내고 있으며, 신선이 내려와 바둑을 두었다는 신선대와 선녀가 가무유희를 즐겼다는 선녀봉을 비롯하여 12봉의 기암괴석으로 이루어져 있고, 신라때부터 근세에 이르기까지 김생, 퇴계이황등 선현들이 수도를 하던 유불선교 발상지로 널리 알려져 있을뿐만 아니라 고려 공민왕 10년에 제2차 홍건적의 난을 피하여 왕이 이곳에 와 마지막요새로써 산성을 축조하였고, 난이 끝난후 왕이 이곳을 떠나자 주민들이 왕을 추모하기 위하여 공민왕당을 세우고 봄, 가을로 공을 드리자 대란이 있을때 마다 소리가 울려 재난을 피할수 있었다는 전설이 있으며, 이곳 공민왕당을 오르는 등산로는 말 다섯 마리가 한꺼번에 지나다녔다는 五馬道가 있다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 명호면", + "MNTN_NM" : "청량산" + }, + "longitude" : 128.90838890000001, + "latitude" : 36.7964974 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 인천", + "MNTN_NM" : "청량산" + }, + "longitude" : 128.90838890000001, + "latitude" : 36.7964974 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "796", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "청룡산" + }, + "longitude" : 126.9470587, + "latitude" : 37.474794199999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "155", + "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", + "MNTN_NM" : "청명산" + }, + "longitude" : 127.08305559999999, + "latitude" : 37.258888900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청우산(해발 619.3m)은 46번 경춘국도를 따라 가평 춘천 방면으로 진행하다가 청평 건문소에서 현리 포천방면 37번국도로 옮겨 오다보면 가평 사계절 썰매장을 막지나 광성교회수련원앞에광진교를 건너면서 산행이 시작된다.청우산은 명지산에서 시작하여 매봉, 대봉, 대금산이 가평을 동서로 가루는 산줄기의 끝 지점에 위치해 있다. 그리 높지 않은 산임에도 정상에 경치가 매우 아름답다 동쪽으로 경춘국도를 사이에 두고 호명산과 주발봉으로 이어지는 산맥이 옆으로 길게 누운 모습이 한눈에 들어온다.#65517;소요 시간 : 정상까지 2시간#65517;볼거리 : 아침고요수목원#65517;최적 탐방 시기 :4월 \/봄 잣나무숲을 끼고 청오사를 지나 능선마루에 오르면 봄이면 능선마다 진달래와 철쭉이 만발하고 참나무숲이 우거져 있다.#65517;숲길 명소 : 정상에서 조망#65517;문화재 : 경기 가평군 하면 대보리 산176-1번지 기념물 제28호 조종암(朝宗巖)이 바위는 조선(朝鮮) 숙종(肅宗) 10년(1684)에 가평군수(加平郡守) 이제두(李齊杜)와 허격(許格) 백해명(白海明) 등이 명(明)나라가 임진왜란(壬辰倭亂) 때 베푼 은혜와 청(淸)나라로부터 당한 굴욕을 잊지 말자는 뜻을 새긴 숭명배청사상(崇明排淸思想)의 기념물이다.#65517;산이 험하지 않아 청우산만 오른다면 하루거리로 적당한 산행이 될수 있고 주변 산장국민관광지는 가족과 즐길수 있는 야영캠프장과 어린이 놀이터, 다목적운동시설 등이 있다.", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 상면, 외서면", + "MNTN_NM" : "청우산" + }, + "longitude" : 127.4138889, + "latitude" : 37.780833299999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "둔내면 두원리에 위치한 청태산은 두원리와 평창군 방림면 계촌리의 경계를 이루고 있으며, 영동고속도로가 태기산을 잇는 능선을 가로 지르고 있다. 산마루에는 잣나무, 소나무, 참나무, 싸리나무 등 각종 수목이 울창할 뿐 아니라 도라지, 더덕, 삽주삭 등 많은 약초가 자생하고 있다.91년 산림청에서 조성한 청태산 자연 휴양림은 영동 고속도로에 위치해 교통편이 좋으며 삼림욕장, 산책로, 야영장, 전망대, 산막, 잔디 광장, 주차장, 자연관찰원 등 각종 편의 시설과 체육시설이 구비되어 있어 하계 수련대회장으로 활용하기에 적합하다. 또한 겨울철에는 춥고 눈이 많이 오는 곳이다. 특히 둔내 일대의 산야가 온통 하얗게 뒤덮인 풍경은 한 폭의 동양화가 같다. 겨울 등산 장비를 갖추었다면 청태산 정상에 오르는 것도 좋다.", + "MNTN_HG_VL" : "1200", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 둔내면, 평창군 봉평면, 방림면", + "MNTN_NM" : "청태산" + }, + "longitude" : 128.30148149999999, + "latitude" : 37.511260399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간 마루금상의 청화산(984m)은 정상은 경상북도 상주와 문경시, 충청북도의 괴산군과 경계를 이루고 있다. 북쪽 대야산에서 남진하여 조항산을 지나온 백두대간이 청화산에 이르면 방향을 남서쪽으로 틀어 눌재로 떨어진 다음 속리산으로 이어져 나간다.lt;택리지gt;에서 이중환은 “청화산은 뒤에 내외의 선유동을 두고 앞에는 용유동에 임해 있어 경치가 지극히 좋음은 속리산보다 낫다”고 표현할 만큼 이름다운 산이다. 육산의 웅장함과 바위산의 아기자기한 맛을 함께 맛볼 수 있을 뿐만 아니라 백악산, 군자산 등 속리산국립공원 일원의 산봉들을 조망할 수 있다. 청화산 오름길은 크게 세 코스다. 오래전부터 많이 이용돼온 입석1리나 심송2리에서 송면지~갓바위재를 경유하는 코스와 사계절 인기 있는 백두대간상의 눌재 기점, 그리고 쌍룡계곡 병천에서 화산마을로 들어가 정상 접근이 가장 ª은 원적사를 경유하는 코스가 있다.", + "MNTN_HG_VL" : "984", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 상주시, 충청북도 괴산군", + "MNTN_NM" : "청화산" + }, + "longitude" : 127.91937729999999, + "latitude" : 36.624444099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북과 경북의 경계인 청화산은 멀리 소백산으로부터 조령산, 주흘산, 대야산 등과 함께 속리산을 솟구치게 하는 교두보 역할을 한다. 청화산은 울창한 숲과 험준한 바위가 잘 어우러져 산행의 재미를 두배로 맛볼 수 있는 산이다.의상저수지에서 누런 문양처럼 보이는 갓바위재까지 가는 길은 송림이 무성하며 산죽도 군락을 이루고 서 있다. 겨울철에도 푸르름을 간직하고 있는 비경과 그 드넓은 산죽군락은 보는 사람의 가슴을 깨끗이 정화 해 줄 듯 하다. 갓바위재에서 871봉을 거쳐 정상에 오르는 길에는 수많은 기암이 대기하고 서 있는데 특히 871봉에서 정상까지는 중간에 세미클라이밍을 해야 할만큼 험준하다.한편 등산 기점인 옥양동에서 의상저수지로 가다보면 둘레가 5미터, 폭이 20미터, 높이가 15미터인 소나무가 서 있는데 이는 천연기념물 제 290호로 지정되어 있는 용송이다.", + "MNTN_HG_VL" : "984", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 문경시 농암면, 충청북도 괴산군 청천면", + "MNTN_NM" : "청화산" + }, + "longitude" : 127.91937729999999, + "latitude" : 36.624444099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "701", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 도개면 다곡리", + "MNTN_NM" : "청화산" + }, + "longitude" : 127.91937729999999, + "latitude" : 36.624444099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "초록봉은 백두대간의 연봉 청옥산의 한 봉우리로 수목이 울창하고 계곡과 자연경관이 아름다운 등산로이며 정상에서 동해시 전체가 바로 보여 동해 8경 중 제8경으로 선정되었다. 최근들어 시민들의 휴식공간 및 소원을 빌기 위한 장소로도 많은 사람들이 찾고 있다.초록봉에는 ‘칠성바위’라고 불리는 바위가 있다. 이 바위에는 전설이 전해져 오는데, 옛날 인간세상이 너무 어지러워 하느님이 세상을 바로잡기 위해 한 장수를 보냈다. 이 장수는 세상을 바로잡고 자기 일을 다 한 후 승천하기 위해 힘차게 바위를 밟고 지나갔는데 그 장수의 오른쪽 발자국은 초록봉 벼락바위에, 왼쪽 발자국은 초록봉 아래 바위에 길이 15미터, 높이 3미터의 큰 흔적으로 남았다. 후세 사람들은 그 바위에 소원을 빌면 소원성취 있다해 칠성바위라 불렀다.옛적에는 초로의 산, 비나리의 산으로 명성이 있었으나 대형 산불로 잿더미가 되는 바람에 현재는 오히려 조망 좋은 일출, 일몰 산행지로 각광받고 있다. 초록봉은 산세가 부드럽고 키 큰 나무가 적어 산행 내내 바다를 볼 수 있으며 등산로도 유추하기 쉬워 길을 잃을 염려가 없다. 중식시간을 포함하더라도 느긋하게 5시간이면 충분히 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "529", + "MNTN_LOCPLC_REGION_NM" : "강원도 동해시", + "MNTN_NM" : "초록봉" + }, + "longitude" : 129.0714347, + "latitude" : 37.522134999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "152", + "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", + "MNTN_NM" : "초록산" + }, + "longitude" : 126.956596, + "latitude" : 37.092230999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전남 보성은 차 다음으로 철쭉이 유명한 고장이다. 이에 제암산과 일림산은 5월이면 사람들이 줄 지어 찾아 오른다. 반면 같은 보성임에도 불구하고 여유롭게 철쭉을 즐길 수 있는 산이 있으니 바로 겸백면에 위치한 초암산이다.제암산, 일림산이 산 정상에 오르면 푸른 바다와 어우러진 철쭉을 볼 수 있다는 장점이 있는 반면 초암산은 철쭉 하나로 승부한다. 단출하게 느껴지지만 그만큼 색이 분산되지 않는 단정한 미학이 살아 있는 산이다. 또한 초암산은 철쭉이라는 핵심만을 즐기고 내려올 수도 있다는 간편함이 두드러진다. 최근 너무 힘든 산행보다는 간편하게 즐기면서 오를 수 있는 산을 찾는 사람들이 증가한 만큼 초암산은 앞으로 많은 사람들이 찾기에 매력적이다. 북쪽 임도를 이용해 철쭉밭 바로 아래까지 차량으로 올라간 다음 정상 철쭉밭을 구경한 후 되내려오는 거의 관광에 가까운 탐방이 가능하다.너무 간단하게 느껴진다면 호남정맥 일부를 이루고 있는 광대코재~주월산~방장산~오도재 능선을 포함한 원점회귀형의 사뭇 긴 당일산행 코스를 잡을 수도 있다. 겸백면은 이 원점회귀형 등산로의 출발지인 수암리에 널쩍한 주차장도 새로 만들었다.더불어 보성군은 ‘녹차와 철쭉이 어우러진 보성’이라는 모토로 작년부터는 초암산에서도 철쭉제를 열고 있다.", + "MNTN_HG_VL" : "576", + "MNTN_LOCPLC_REGION_NM" : "전남 보성군 겸백면", + "MNTN_NM" : "초암산" + }, + "longitude" : 127.1822171, + "latitude" : 34.828257000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평에는 한북정맥의 주를 이루는 1000미터급 고봉이 밀집되어 있다. 촉대봉은 경기도에서 제일 높은 화악산에서 동쪽으로 뻗어 내린 능선이 응봉(1436m)에서 동남쪽 홍적이고개로 이어지는 능선에 솟아 있는 산이다. 이름은 정상 부분이 봉우리 세 개로 되어 있고 끝이 뾰족한 데서 유래하였으며 촉대봉(燭臺峰)이라 한다. 화악산이 북쪽에서 남쪽을 바라보며 버티고 서 있는 형상이라면 촉대봉은 왼쪽 어깨에 해당하는 것으로 거대한 바위와 나무가 우거진 능선이 웅장하고 정상에서의 경치가 장관이다. 특히 겨울 설경과 가을 단풍이 아름답다.강원도 춘천시 사북면과 경기도 가평군 북면의 경계를 이루고 있는 촉대봉에는 동쪽 산자락인 강원도 춘천시 사북면 지암리에 집다리골자연휴양림이 조성되어 있다. 능선 끝의 멱골, 싸리재마을은 의병운동와 독립만세운동의 중심지였다.", + "MNTN_HG_VL" : "1125", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면·강원도 춘천시 사북면", + "MNTN_NM" : "촉대봉" + }, + "longitude" : 127.7001509, + "latitude" : 35.314562500000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "촛대봉도 대야산에서 불란치재 사이 백두대간에 있으며 1\/5,000 지도에는 높이가 671.2m로 표시되어 있다.산행은 대야산 돌마당 식당을 지나 20분 정도 올라가면 용추가 나오는데 용추의 오른쪽 능선을 타면 촛대봉으로 바로 오를 수 있고 정상에서 대야산이나 불란치재로 내려갈 수 있다. 정상에 무덤이 있다. 능선길은 소나무와 바위가 잘 조화되어 있는 아름다운 산이다.", + "MNTN_HG_VL" : "661", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 화산리", + "MNTN_NM" : "촛대봉" + }, + "longitude" : 127.7001509, + "latitude" : 35.314562500000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "비슬산의 주봉에서 동쪽으로 이어지는 능선이 북으로 방향을 바꾸어 올라가다 솟구쳐서 이루어진 산(900m)이다. 비슬산 주봉우리의 동쪽 능선이 북쪽으로 이어져 솟은 산이다. 비슬산과 산세가 비슷하며, 700m 부근부터는 경사가 완만한 고위평탄면 지형을 이룬다. 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 봄에는 진달래 천국을 이루고 가을에는 단풍이 온산을 물들여 대구 근교 지방의 주민들에게는 매우 친근한 산이다.정상 일대 능선에는 억새풀과 진달래가 군락을 이루어 자란다. 주암산과는 능선으로 이어져 있으며 두 산을 연결하여 산행하면 좋다.", + "MNTN_HG_VL" : "905", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", + "MNTN_NM" : "최정산" + }, + "longitude" : 128.60083330000001, + "latitude" : 35.763888899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "담양읍에서 13km 정도 떨어진 높이 731.2m의 추월산은 전라남도 기념물 4호이자 전라남도 5대 명산중의 하나로 손꼽힌다.담양군의 최북단인 용면 월계리와 전라북도 순창 북흥면과 도경계를 이룬다. 많은 수림과 기암괴석, 깎아세운 듯한 석벽이 마치 성을 쌓은 듯이 둘러있고 서쪽에 겨우 사람 하나 통행 할 정도의 길이 트여 있다.", + "MNTN_HG_VL" : "731", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 용면, 전라북도 순창군 복흥면", + "MNTN_NM" : "추월산" + }, + "longitude" : 126.9756112, + "latitude" : 35.3992133 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "243", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "추화산" + }, + "longitude" : -121.95104910000001, + "latitude" : 37.318331800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화도읍(마석)에서 북동쪽으로 12km 거리에 있는 축령산(887.1m)은 조종천과 수동천의 사이에 솟아 있다. 이 산에는 일명 '남이바위'라고 하는 바위가 있는데, 이는 조선시대 때 남이장이 이 곳에서 심신을 수련하였다 하여 붙여진 이름이라고 한다.축령산의 울창한 수림과 계곡을 이용하여 자연 휴양림을 조성, 삼림욕장, 휴계소, 체육시설, 놀이시설, 야영장 등 편의 시설이 두루 갖추어 진 곳이다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", + "MNTN_NM" : "축령산" + }, + "longitude" : 127.3330406, + "latitude" : 37.752879499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "축령산은 전남 장성과 전북 고창의 경계를 이루는 산으로 노령 지맥 위에 솟아 있다. 장성에서는 편박나무숲 기슭을 축령산이라 부르고 문수사에서는 청량산이라고도 부른다. 축령산은 6.25 전쟁 등 민족적 수난기에 깊은 상처를 받기도 한 산이지만 현재 축령산 남서쪽 산록은 유럽풍의 잘 조림된 침엽수림 지대를 연상케 한다.삼나무, 편백, 낙엽송, 리기다소나무 등 수령 5~50년생의 숲이 널찍하게 바다를 이루고 있으며 주변엔 천연림인 상수리, 졸참나무, 떡갈나무 등이 둘러싸고 있다.이렇듯 축령산이 세상에 알려진 것은 산을 두르고 있는 숲 덕분이다. 숲을 배경으로 영화 ‘태백산맥’, ‘내마음의 풍금’과 드라마 ‘왕초’도 촬영됐다. 하지만 축령산의 숲은 사람에 의해 인공적으로 만들어졌다. 일제시대를 겪으면서 완전히 헐벗었던 산이 지금의 모습이 되기까지 애쓴 분은 춘원 임종국 선생이다. 1956년부터 시작된 육림의지는 선생이 세상을 떠난 1987년까지 계속됐다.편백과 삼나무가 주를 이루는 축령산휴양림은 오후 1시부터 3시 사이에 산책하는 것이 좋다. 나무별로 피톤치드가 활발히 생성되는 시간이 다른데 편백과 삼나무의 피톤치드 활성 시간이 오후 1~3시 사이다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "전북 고창군 고수면, 전남 장성군 서삼면", + "MNTN_NM" : "축령산" + }, + "longitude" : 127.3330406, + "latitude" : 37.752879499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 산 아래 뻗어있는 계곡은 통도사 주변 암자와 연결되어 있어 산책하기 좋은 코스이기도 하다. 취서산 (영축산)통도사는 양산8경의 제 1경이다. 그밖의 8경으로는 천성산, 내원사계곡, 홍룡폭포, 배내골, 천태산, 오봉산 임경대, 대운산 탑골휴양림 등이 있다.", + "MNTN_HG_VL" : "1059", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 하북면, 원동면, 울산광역시 울주군 삼남면, 상북면", + "MNTN_NM" : "취서산" + }, + "longitude" : 129.05500000000001, + "latitude" : 35.517000000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "321", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "취암산" + }, + "longitude" : 127.18480460000001, + "latitude" : 36.782106200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "치마산은 구이면과 신덕면의 경계선상에 완만하게 솟아있는 육산으로 구이저수지 동쪽의 경각산을 바라보고 있다.이 산은 산세가 말이 달려나가는 형상이라 하여 달릴 치(馳) 자와 말 마(馬) 자를 붙여 이름을 지었다고 한다. 망산 마을이름은 마을 뒷산(치마산 북릉)이 옥토망월형이라 하여 생긴 이름이라는 설과, 모악산을 마주보는 형국이라 지어진 것이라는 설이 전해진다. 이 마을은 실와우와 돔바우 2개 마을로 이뤄져 있다.이 산을 가운데 두고 주변에 높고 너른 산과 들이 시원스럽게 펼쳐져 있어 전망이 뛰어나며 겨울이 되면 정상 헬기장 부근에 눈이 많이 쌓여 눈 등산하기에 좋다. 치마산은 겉으로 보기에는 펑퍼짐한 육산 정도로 보인다. 평범하게 보이는 이 산 속에 진안 마이산 석탑을 보는 듯한 석탑군이 형성돼 있는 용광사를 비롯해서 장군바위, 장군굴, 마애불상 등 볼거리가 적지 않아 앞으로 근교산행 대상코스로 자리매김할 수 있는 내용이 알찬 산이다.", + "MNTN_HG_VL" : "567", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 구이면, 임실군 신덕면", + "MNTN_NM" : "치마산" + }, + "longitude" : 127.1461111, + "latitude" : 35.695833299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 삼척시 가곡면에 자리한 치바위산은 사금산에서 남향으로 뻗어나간 지능선상의 최고봉이다. 산을 올려다보면 산꼭대기의 바위들이 `키'처럼 보이는데 `키'의 방언이 `치'이기 때문에 치바위산이라 불리게 되었다. 서쪽으로 낙동정맥 마루금에 솟아 있는 백병산(1259m)과 복두산(978m)을 마주보고 있어 신리에서 풍곡으로 이어진 도화천협곡의 장관을 감상할 수 있다. 남서쪽으로 토산과 면산자락에 가곡자연휴양림이 조성되어 있고, 남쪽으로는 유명한 용소골이 길게 패여있으며 주위로 벼락바위봉과 범바위봉, 중봉산이 자리잡고 있다.치바위산은 크게 두 개의 봉우리로 나누어진다. 하나는 동활리쪽 835m봉으로 `동활 치바위'라 부르고 이곳에서 동쪽 오저리 방면으로 분기한 780m봉을 `오저 치바위'라 부른다.", + "MNTN_HG_VL" : "835", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "치바위산" + }, + "longitude" : 129.17500000000001, + "latitude" : 37.154166699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경주와 울산의 경계를 이루고 있는 산이 치술령이다.치술령은 조망도 특별하다. 남북으로 뻗은 능선의 좌우로 아름다운 산하가 펼쳐지는데다 정상주변에서는 삼태봉 너머로 손에 잡힐 듯 들어오는 잿빛 동해바다의 싱그러움이 닫힌 마음을 열어주기 때문이다.치술령에는 신라 충신 박제상과 그의 부인에 관한 애절한 전설이 있어,「삼국사기」와 「삼국유사」에 전해 내려오고 있다. 박제상은 눌지왕 즉위 후 고구려와 일본에 볼모로 잡혀 있던 두 왕제를 구출코자, 먼저 고구려에 가 있는 복호를 구출해 귀국시킨 후, 일본으로 건너가 미사흔을 구출해 내었다. 그러나 정작 자신은 일본에 잡혀 심한 고문 끝에 소사 당했다. 이때 박제상의 김씨부인은 두 딸을 데리고 치술령에 올라 일본에 간 남편을 기다리다 죽으니 그 몸은 돌로 변하여 망부석이 되고, 그 영혼은 날아가 숨었는데 그 곳을 은을암이라 한다. 그 후 왕은 박제상의 딸을 미해공의 부인으로 삼고 박제상에게 대아찬으로 관위를 높혀주고, 김씨부인은 국대부인에 추봉하였으며, 사당을 짓고 그 뜻을 기리는 제를 봉행토록 한 곳을 치산서원이라 한다.", + "MNTN_HG_VL" : "765", + "MNTN_LOCPLC_REGION_NM" : "울산시 울주군 두동면, 경북 경주시 외동읍", + "MNTN_NM" : "치술령" + }, + "longitude" : 129.27522060000001, + "latitude" : 35.657918299999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "치악산은 강원도 원주시와 횡성군의 경계를 이루는 산으로, 산세가 뛰어난 데다 영동고속국도와 중앙고속국도에 인접해 있어 교통이 편리해 중부권 산행지로 인기가 높다.", + "MNTN_HG_VL" : "1282", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 횡성군, 영월군", + "MNTN_NM" : "치악산" + }, + "longitude" : 128.05050990000001, + "latitude" : 37.3716893 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "칠갑산은 해발 561m의 낮은 산이기는 하나 산세가 거칠고 가파르다. 아직은 널리 알려지지 않아서 자연 그대로의 울창한 숲을 이루고 있다. 산위에 오르면 서해가 바라다 보이고 골짜기마다 흐르는 물이 모여 지천과 사천을 이룬다.", + "MNTN_HG_VL" : "560", + "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군 대치면, 정산면, 장평면", + "MNTN_NM" : "칠갑산" + }, + "longitude" : 126.884288, + "latitude" : 36.413367800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한국전쟁을 전후해 이 산에 본부를 두고 있던 빨치산과 전투하던 국군이 작전지도에 편의상 붙인 것이 그대로 이름이 된 칠백육고지는 산의 높이도 이름처럼 706m다.이곳을 중심으로 볼 때 서, 남, 북쪽을 섬진강이 감싸고 있고, 동쪽으로는 등재에서 시작하는 능선이 둘러쳐져 있어 요새로서 적합한 곳이기 때문에 빨치산이 본부를 두었다고 한다. 멀리서 보았을 때 정상에 초원이 부드럽게 펼쳐져 있어 얼핏 보기에는 예사로운 산처럼 느껴지니 그야말로 천연의 요새라 할 만하다. 산의 능선에 초원이 드넓고 억새가 무리지어 서있는 이곳은 아직까지 사람의 발길이 많이 닿지 않은 곳이어서 멧돼지나 노루같은 산짐승도 간간이 만날 수 있다.또한 바위의 중간에 패인 부분들이 광대가 쓰는 가면을 닮았다는 광대바위와 불을 밝히는 호롱처럼 생겼다는 호롱바위 등 특색 있는 바위들이 산행하는 발걸음을 더 들뜨게 한다. 그리고 정상에서는 지리산과 회문산, 원통산, 오봉산, 모악산, 성수산 등을 조망할 수 있다.", + "MNTN_HG_VL" : "706", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 강진면", + "MNTN_NM" : "칠백육고지" + }, + "longitude" : 127.1113728, + "latitude" : 37.347777800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "칠백이고지는 편안하면서도 숨이 차는 숲길과 원형이 잘 보존된 숯가마터, 깨끗한 계곡이 자랑거리다. 숲길은 동네 뒷산을 걸을 때처럼 부담이 없다가도 계곡이 끝나면서 가파르게 전개되어 그 재미가 독특하며, 옛날 사람들이 연료와 생활용품으로 사용한 숯을 만들었던 숯가마터에서는 숲이 우리에게 베푸는 혜택을 새삼 느끼게 된다.더하여 비가 아무리 많이 내려도 물이 무릎까지밖에 안차고 바위도 깔끔한데다가 3㎞쯤 완만하게 누운 계곡은 그 물에 발을 담그고 옆에 누워도 좋을 만큼 여유롭다. 산의 높이는 701m인데도 이름을 칠백이고지라 한 이유를 인근 지역 사람들에게 알아보는 것도 산행의 재미를 더한다.", + "MNTN_HG_VL" : "701", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", + "MNTN_NM" : "칠백이고지" + }, + "longitude" : 127.3305556, + "latitude" : 36.016111100000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "칠보산은 충북 괴산군 칠성면과 장연면의 경계를 이루는 산으로, 쌍곡계곡을 사이에 두고 군자산과 마주보고 있다. 칠보는 불교의 무량수경이나 법화경에 나오는 일곱가지 보배인 금, 은, 파리, 마노, 기거, 유리, 산호를 뜻한다고 한다.산의 규모는 작지만 기암괴석이 곳곳에 널려 있고, 고사목과 노송이 암봉과 조화를 이루어 한폭의 동양화를 보는 듯 하다. 이 산은 송이버섯 산지로 유명하며, 또한 칠보산에 오르는 길목에는 신라시대에 창건하였다는 고찰 각연사가 자리잡고 있다. 이 사찰에는 보물 제 433호인 석조비로 사나불좌상, 통일대사탑비 등이 있어 관광 코스로도 손색이 없는 곳이다. 정상에 서면 북쪽 아래로 각연사와 청석골 계곡이 보이고, 동북쪽으로는 덕가산과 희양산이, 서북쪽으로는 쌍곡계곡과 군자산이 가깝게 보인다.", + "MNTN_HG_VL" : "778", + "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 청안면", + "MNTN_NM" : "칠보산" + }, + "longitude" : 126.9333333, + "latitude" : 37.25 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "수원시의 서쪽에 있는 산으로 수원시와 화성군의 경계지점을 이루고 있으며 예로부터 일곱 가지 보물 (산삼, 맷돌, 잣나무, 황계수닭, 절, 장사, 금)이 많았다고 하여 칠보산이라 한다. 해발 234m로 2개의 등산코스는 완만하고 수림이 울창하여 노약자와 주부들의 산행으로 매우 적당하다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "경기도 수원, 화성", + "MNTN_NM" : "칠보산" + }, + "longitude" : 126.9333333, + "latitude" : 37.25 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 영덕군 창수면, 울진군 온정면에 자리한 칠보산 (七寶山 810m ) 은 더덕, 황기, 산삼, 돌옷, 멧돼지, 철, 구리 등 동식물과 광물질 등 7가지가 풍부하다해서 붙여진 이름이다.1993년에 개장된 칠보산자연휴양림은 칠보산(810m)과 등운산(767m)을 잇는 능선 아래 자리하고 있다. 동해바다가 지척인 이곳에서는 고래불해수욕장이 한눈에 내려다보이고 아르드리 소나무 숲은 휴양림 입구부터 산 정상부까지 계속 이어진다. 고래불해수욕장은 병풍처럼 둘러친 송림을 끼고 타원으로 펼쳐지는 명사 20리 백사장과 송림을 가지고 있다. '고래불' 이란 고려말 목은 이색 선생이 시를 읊으며 유년시절에 상대산에 올라가 바다를 바라보니 고래가 하얀 분수를 뿜으며 놀고 있는 모습과 같아 고래불이란 명칭을 사용하게 되어 지금가지 전해져 내려오고 있다.어린 소나무 한 그루가 지키고 섰는 정상에는 오래 전부터 자리한 돌탑 무더기와 영해 산사랑산악회에서 세운 정상표지석이 세워져 있다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영덕군 창수면, 울진군 온정면", + "MNTN_NM" : "칠보산" + }, + "longitude" : 126.9333333, + "latitude" : 37.25 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉우리가 7개인 데서 칠봉산이라 유래되었다. 동쪽으로 임천고개를 넘어 선바위산과 운암산으로 이어지고, 서쪽에 십리산, 남쪽에 평안산, 북쪽에는 백운산이 있다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 대학리", + "MNTN_NM" : "칠봉산" + }, + "longitude" : 127.093144, + "latitude" : 37.871221800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 양주시 회천읍에 자리한 칠봉산은 그리 높지않은 산이지만 유서깊은 사찰을 거느리고 있어 주변에 알려진 산이다. 칠봉산은 500m급 밖에 되지 않는 산이지만 암릉이 많고 시선을 끄는 경치들이 많아 산행의 아기자기함으로 등산인들을 즐겁게 한다. 발치봉·응봉·석봉·기대봉·투구봉·솔치봉·돌봉 등 7개 봉우리가 솟아 있어 칠봉이라는 이름이 붙었다. 주변에 삼봉산·오봉산·구봉산 등 홀수로 된 이름을 가진 산들이 많다.조선시대 세조가 말년에 과거의 잘못을 뉘우치며 이곳에 올랐다 하여 어등산(御登山)이라고도 하고, 가을단풍이 아름다워 비단병풍에 비유하여 금병산(錦屛山)이라고도 한다.산행을 하려면 송내동에서 대도사를 지나 능선을 따라 정상에 오른 뒤 송전탑을 지나 천보산을 거쳐 회암사를 지나 회암동으로 하산한다. 대도사와 회암사 뒷편에는 괴이하게 생긴 바위들이 있으며, 회암사지 주변에는 많은 사적이 남아 있어 가족을 동반한 가벼운 산행지로도 좋다.", + "MNTN_HG_VL" : "506", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 회천읍", + "MNTN_NM" : "칠봉산" + }, + "longitude" : 127.093144, + "latitude" : 37.871221800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "높이 506m로천보산 지맥이 북쪽으로 이어져 솟은 산이다. 발치봉,응봉,석봉,기대봉,투구봉,솔치봉,돌봉 등 7개 봉우리가 솟아 있어 칠봉이라는 이름이 붙었다. 주변에 삼봉산,오봉산,구봉산 등 홀수로 된 이름을 가진 산들이 많다. 조선시대 세조가 말년에 과거의 잘못을 뉘우치며 이곳에 올랐다 하여 어등산(御登山) 이라고도 하고,가을 단풍이 아름다워 비단 병풍에 비유하여 금병산(錦屛山)이라고도 한다. 인근에 목행선 선생 선묘와 탑동석불이 자리잡고 있다.", + "MNTN_HG_VL" : "506", + "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시 송내동, 불현동", + "MNTN_NM" : "칠봉산" + }, + "longitude" : 127.093144, + "latitude" : 37.871221800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "일곱 봉우리로 이루어진 칠봉산은 경북 문경 농암면과 상주시 은척면에 걸쳐 있는 산으로 높이는 낮지만 유명한 전설속에 명소를 감추고 있는 곳이다. 산 높이는 그리 높은 편은 아니지만 유명한 전설속에 명소를 감추고 있는 곳이다. 산 중턱에 조자룡 굴이 있는데 이곳 칠봉산의 전설에 따르면 이곳은 옛날 중국 삼국지에 나오는 조자룡이 태어난 곳이며 무술을 연마했던 곳이라고 한다. 현재는 토속신앙의 기도처로 이용되고 있다.중국의 유명한 삼국지의 주인공이 어찌하여 한국 경북의 문경에서 태어 났겠는가?전설이니 전설이려니 하는편이 나을듯 싶다. 산이 있으면 고개가 있고 이 칠봉산에도 옛 고개인 황령을 비롯하여 절 이름이 예사롭지 않은 황령사라는 절도 있다.산행시작은 농암면 갈동리로 가면 되지 않고 농암면 지동리나 선곡리로 가야 된다. 아니면 상주 은척면 남곡리로 가도 된다. 칠봉산은 상주시와 문경시 경계에 있는 산이므로 경계선을 타고 산행을 계속하여도 되지만 남곡 용추에서 능선을 타고 산행하는게 가장 추천할만한 코스이다.", + "MNTN_HG_VL" : "595", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 갈동리", + "MNTN_NM" : "칠봉산" + }, + "longitude" : 127.093144, + "latitude" : 37.871221800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "330", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "칠봉산" + }, + "longitude" : 127.093144, + "latitude" : 37.871221800000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "981", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 구정면, 옥계면", + "MNTN_NM" : "칠성산" + }, + "longitude" : 128.87542120000001, + "latitude" : 37.669779900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "981", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉", + "MNTN_NM" : "칠성산" + }, + "longitude" : 128.87542120000001, + "latitude" : 37.669779900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "lt;땅 위에 드리운 북두칠성gt;칠성산(981m)은 백두대간상의 석병산(1055m)과 삽당령(680m) 사이에 위치한 두리봉(1033m)에서 강릉을 바라보며 북으로 뻗은 지맥 상의 약 9km쯤에 솟은 봉우리다. 이 산은 머리에 바위를 이고 길게 드리운 품새가 하늘의 북두칠성과 흡사하다. 칠성산은 옛 고을 원님이 기거하던 칠사당자리(강릉의료원)에서 올려다보면 여러개의 바위 봉들이 별과 같은 형상으로 빛을 토하고 있어 칠성산이라 불렀다고 한다. 또한 활활 타오르는 불꽃 모양의 칠성산 때문에 강릉시에 화재가 자주 일어난다는 설도 있다. 국립지리원 발행 지형도에는 칠성산이란 지명은 없다. 다만 주봉(981m) 남쪽에 칠성대(954m)라 표기되어 있을 뿐이다. 「대동여지도」에는 ‘담정산’ 이라 하였지만 언제 이름을 잃었는지 모르며 다만 산자락 아래 담산동이란 마을 이름이 남아 있다. 칠성산은 도심에 인접한 산이면서도 강릉 사람들이 바다를 좋아하는 탓인지 원시림의 모습을 간직하고 있다. 이 칠성산은 1996년 강릉 앞바다에 난데없이 나타난 북한 잠수함으로 인해 전국의 이목을 집중시켰다.", + "MNTN_HG_VL" : "981", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 구정면, 옥계면", + "MNTN_NM" : "칠성산" + }, + "longitude" : 128.87542120000001, + "latitude" : 37.669779900000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 안성군 삼죽면, 죽산면, 금광면에 위치한\"\"칠장산군\"\"(덕성산-칠현산-칠장산)은 백두대간 중 속리산에서 가지쳐 나온 정맥인 금북정맥에 속한 산이다. 높이는 높지 않지만 산의 폭이 크고 숲이 울창하여 그 일부는 안성시와 진천군의 경계를 이루고 있으며, 산 기슭에 칠장사란 고찰이 있어 유명해진 산이다.636년(신라 선덕여왕 5) 자장율사가 창건한 칠장사는 조선 명종 때 임꺽정이 승려인 병해와 함께 10여 년 머물던 사찰이다. 칠장사오불회괘불탱(국보 296), 칠장사혜소국사비(보물 488), 봉업사석불입상(보물 983), 조선 후기에 진흙으로 빚은 사천왕상(경기유형문화재 11)을 비롯하여 대웅전(경기유형문화재 114), 인목대비친필족자(경기유형문화재 34), 철당간(경기유형문화재 39) 등 많은 문화재를 보유하고 있다.국보와 보물이 있는 한적한 고찰 칠장사를 둘러 보고, 숲이 울창한 칠장산에 올라 시원한 공기를 마시고 내려와 칠장사 혜소국사비 아래쪽 골짜기 약수터를 둘러보면 칠장산과 칠장산 순례는 끝난다.", + "MNTN_HG_VL" : "492", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 죽산면, 금광면, 삼죽면", + "MNTN_NM" : "칠장산" + }, + "longitude" : 127.3912223, + "latitude" : 37.030774200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통영시 사량면 아랫섬(하도)에 위치한 해발 349m의 산으로서 남쪽으로 뻗은 산줄기를 따라 7개의 봉우리가 솟아 있어 칠현봉(七絃峰)이라 하는데 이 가운데 망산(공수산, 해발 310m)에는 옛 사량진의 봉수지(烽燧址)가 있다. 칠현봉에는 등산로와 안내판이 잘 정비되어 있고 일곱 봉우리를 오르내리는 능선길이 재미있을 뿐아니라 사방으로 탁 트인 전망 또한 좋아 근래 가장 각광받는 등산코스이다.산기슭에 칠장사가 있다. 고려 때 혜소국사가 일곱 도적을 제도하여 도를 깨치게 했다 하여 칠현산이라 불리게 되었다. 칠장산과 붙어 있어 함께 산행할 수도 있다. 산행은 걸미고개에서 시작하여 극락마을을 통해 정상에 오른 뒤 다시 극락마을로 내려와 걸미고개로 하산한다. 칠장산과 이어서 등반하려면 걸미삼거리에서 신대마을로 들어가 원효암을 지나 정상에 오른 뒤 갈림길에서 칠장사를 거쳐 칠장산에 올랐다가 사거리 갈림길에서 신미창교로 내려와 미장리 정류장으로 하산한다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량도", + "MNTN_NM" : "칠현산" + }, + "longitude" : 127.3977778, + "latitude" : 37.0113889 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도초는 신라시대 당나라에 교역시 기항지였는데 당나라 사람들이 지형을 볼때 꼭 자기나라 수도와 같은 형태이며, 지역마다 초목이 무성하여 목마지로도 활용하였기에 '도초(도초)'라 칭하였다.도초도에 남쪽끝에 자리하고 있는 큰산은 좌측은 도초에 자랑 시목해수욕장을 끼고 있으며반대편은 다도해의 수많은 섬들을 내려다 보는 형세이다.", + "MNTN_HG_VL" : "202", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군 도초면 엄목리", + "MNTN_NM" : "큰산" + }, + "longitude" : 126.9398793, + "latitude" : 37.548087600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "탄항산(월항삼봉)은 백두대간이 북쪽으로 향하여 부봉을 지나 오른쪽 능선을 뻗어 주흘산을 만들어 놓으며 가고 다시 평천재를 지나 하늘재 사이에 있는 산으로서 지도에는 산이름이 표시되어 있지 않다.옛날에는 봉화를 올리던 곳으로 산 남쪽 월항마을 사람들은 봉화봉이라고 부르기도 한 산이다. 정상은 노송과 절벽,괴석 등으로 어우러지고 정남으로 주흘산과 마주보고 있으며, 백두대간상의 하늘재 직전에서 남쪽으로 들어간 계곡이 아름답고, 정상 서편에서 북쪽으로 뻗은 칼바위등길은 너럭바위, 홈바위, 칼바위 등으로 어우러져 스릴 있는 하산 길이다.", + "MNTN_HG_VL" : "857", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "탄항산" + }, + "longitude" : 128.10508999999999, + "latitude" : 36.806125000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태기산은 횡성군의 최고봉으로 치악산과 인접해 있다. 일명 덕고산(또는 대기산)이라고도 불리는 태기산은 삼한시대 말기 진한의 마지막 왕인 태기왕이 신라군에게 쫓기어 이곳에 성을 쌓고 군사를 길러 신라와 싸웠다는 전설이 전해지고 있어 태기산이라 이름붙었다 한다.산 정상에는 삼한시대의 진한의 마지막 왕인 태기왕이 신라에 대항하던 태기산성(약1km)이 있다. 태기산성은 삼한시대, 진한의 마지막 왕인 태기왕이 신라에 대항하던 곳으로 그 안에 태기산성비가 세워져 있다.주변에는 신라 선덕여왕 16년에 자장율사가 창건한 봉복사라는 절과 심산유곡의 약수터가 있다. 양구두미재 정상에서 비포장 도로를 따라 정상에 오르던가 봉복사 계곡을 따라 잡목이 우거진 능선길을 헤치고 올라가면 정상에 이른다. 정상은 한국방송공사 송신소가 있어 입산 통제 구역이다.", + "MNTN_HG_VL" : "1261", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 둔내면, 청일면, 평창군 봉평면, 홍춘군 서석면", + "MNTN_NM" : "태기산" + }, + "longitude" : 128.28561920000001, + "latitude" : 37.601998999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간 오대산에서 서쪽으로 가지를 뻗어 내린 유장한 산줄기 가운데 가장 깊숙한 곳, 신대리를 중심으로 봉복, 덕고, 태기산 줄기가 부챗살을 펼치며 솟아있다. 아직 시로 승격되지 못한 홍천, 평창, 횡성의 3개 군의 경계를 이루는 오지다. 높이 1261미터로 횡성군에서 가장 높다. 본래는 덕고산(德高山)이었는데 삼한시대 진한의 마지막 왕인 태기왕이 산성을 쌓고 신라에 대항하던 곳이라 하여 이름을 고쳐 부르게 되었다.정상아래 1000미터 고원에는 1970년대 초만 해도 이 산에 150여 호, 근 천여 명이나 살던 마을 태기리가 있었다. 화전민과 고랭지 채소밭, 초등학교까지 거느릴 정도로 품이 너른 산이다. 현재는 돌담과 잡목만 무성한 집터들뿐이다.이 산 아래 주변에는 볼거리가 많다. 신대리 초입에 있는 신라시대 창건한 봉복사와 삼층석탑을 비롯해서, 동쪽에는 효석문화마을, 동남쪽에는 휘닉스 파크, 또 청태산으로 이어지는 남쪽 산줄기 아래는 청태산자연휴양림이 자리하고 있다.", + "MNTN_HG_VL" : "1261", + "MNTN_LOCPLC_REGION_NM" : "횡성군 둔내면, 평창군 봉평면, 홍천군 서석면", + "MNTN_NM" : "태기산" + }, + "longitude" : 128.28561920000001, + "latitude" : 37.601998999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태백산은 경상북도 봉화군 석포면 대현리와 태백시 문곡소도동 그리고 강원도 영월군 상동면 천평리와 접경을 이루며 동경 128。56\"북위 37。05\"에 자리잡은 해발 1,566.7m의 명산이다. 이 산에서 발원하는 물이 영남평야의 젖줄인 낙동강과 우리민족의 역사와 함께한 한강, 삼척의 오십천을 이루니 국토의 종산이자 반도 이남의 모든 산의 모태가 되는 뿌리산이다.태백산은 천제단이 있는 영봉을 중심으로 북쪽에 장군봉(1567m) 동쪽에 문수봉(1,514.9m), 영봉과 문수봉사이의 부쇠봉(1,549.4m)로 이루어져 있다. 암벽이 적고 경사가 완만하여 남녀노소 누구나 쉽게 오를 수 있는 산으로 정상에는 고산식물이 자생하고 봄이면 산철쭉, 진달래의 군락지가 등산객을 맞이하고 여름에는 울창한 수목과 차고 깨끗한 계곡물이 한여름 더위를 잊기에 충분하며 가을은 형형색색의 단풍으로 수놓으며 겨울은 흰 눈으로 뒤덮인 주목군락의 설경을 보여 주는 곳으로 남성다운 중후한 웅장함과 포용력을 지닌 육산으로 이루어져 있다.또한 정상에서 바라보는 일출과 낙조는 장엄하여 세속을 떠난 천상계를 연상케 하고 맑은 날 멀리 동해 바다를 볼 수 있는 것도 태백산이 가지고있는 자랑거리이다. 이 밖에도 최고높은 곳에 위치한 한국명수중 으뜸수 용정, 용담이 있다.1989년 5월 13일 17.44㎢의 면적이 도립공원으로 지정되었으며 소도집단시설지구에 콘도형인 태백산 민박촌을 비롯하여 숙박시설,음식점,야영장 등이 마련되어 있으며 석탄의 역사를 한 눈에 볼 수 있는 석탄박물관이 있고, 겨울철에는 대규모의 눈썰매장이 개장된다.", + "MNTN_HG_VL" : "1567", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "태백산" + }, + "longitude" : 128.91524039999999, + "latitude" : 37.095739199999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "숙종의 태를 묻었던 곳으로, 태봉동이라 하였다. 비석 중 하나는 1661년(현종 2)에 고종의 태(胎)를 처음 이곳에 안치할 때 세운 것이며, 다른 하나는 숙종이 임금에 즉위한 후 9년 후인 1683년에 건립한 것이다. 1869년(고종 2) 태와 태실은 경기도 양주로 옮겨가고 지금은 비석만 남아 있다. 관리가 잘 되어있어 남녀노소 누구나 건강증진에 좋다.", + "MNTN_HG_VL" : "133", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 태봉동", + "MNTN_NM" : "태수산" + }, + "longitude" : -77.004718999999994, + "latitude" : 38.888683999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "692", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 일선리,도문리", + "MNTN_NM" : "태조산(냉산)" + }, + "longitude" : 128.4007306, + "latitude" : 36.258746899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태청산은 전남 영광군 대마면과 장성군 삼계면ㆍ삼서면의 경계를 이루며 솟은 영광군 최고봉이다. 큰 바위가 있다고 해서 석태산(石太山)으로도 불린다. 새재에서 호남정맥을 벗어난 산줄기를 영산북기맥이라 부르는데, 영산북기맥은 길고 긴 능선을 이어 태청산을 일으키고 다시 장암산(481.5m)과 불갑산(516m)으로 흘러간다.태청산은 영광군 내 최고봉답게 정상에서의 조망이 빼어나다. 세 개의 바위로 된 정상부에 서면 북서쪽 월랑산과 고성산, 방장산을 지나 내장산까지 거침없고, 동남쪽 광주 무등산과 남쪽의 장암산과 불갑산이 멋진 산너울을 이루며 그림처럼 펼쳐진다. 서쪽으로는 영광시가지 너머 서해바다가 아스라하다.", + "MNTN_HG_VL" : "593", + "MNTN_LOCPLC_REGION_NM" : "전남 영광군 대마면, 장성군 삼계면ㆍ삼서면", + "MNTN_NM" : "태청산" + }, + "longitude" : 126.5835598, + "latitude" : 35.273987499999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신증동국여지승람에 대화산이라 지칭한 태화산은 강원 영월군 영월읍 남쪽에 자리해 있다. 정상에서 북서쪽으로 뻗은 능선 끝에는 남한강이 굽이쳐 흐르고 정상으로 향하는 길에 영월읍을 두루 굽어볼 수 있는 태화산성터가 남아 있다.고구려 시대에 쌓았던 토성, 태화산성에서는 간혹 당시의 기와 파편이 발견되기도 한다. 태화산 정상에서는 멀리 남으로 소백산과 백두대간 줄기가 조망된다.", + "MNTN_HG_VL" : "1028", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍, 충청북도 단양군 영춘면", + "MNTN_NM" : "태화산" + }, + "longitude" : 127.2886111, + "latitude" : 37.291944399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 광주시 남쪽 끝에 자리한 도척면은 백제 온조왕이 한강유역에 도읍을 정하려고 이곳을 탐사할 때 자로 재고 또 쟀다고 해서 도척(都尺)이란 이름이 붙었다고 한다. 이러한 도척면 북서쪽을 병풍처럼 에워싸고 있는 산이 바로 태화산이다. 조선 영조 때의 고지도와 광주부읍지에는 대해산(大海山), 해동지도에는 대화산(大華山)으로 기록되어 있다.경기 남부에서 아름답기로 이름 난 태화산은 관바위, 수리바위, 병풍바위, 상사바위, 조춤바위 등 멋진 다섯 개의 바위들이 늘어선 바우산골과 조망 좋은 정상 그리고 그 바로 아래쪽의 백련암, 김병기 대감이 대화약수를 마시고 병이 나은 기념으로 썼다는 ‘大華水石’ 암각 등 볼거리 또한 풍성하다.태화산은 봄이 다 가도록 흐드러지게 피어나는 진달래와 철쭉이 특징이다. 내세울 만한 높이는 아니지만 전망 좋은 바위가 곳곳에 자리하고, 울창하게 우거진 숲은 산림욕을 즐기기에 그만이다.", + "MNTN_HG_VL" : "641", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 도척면", + "MNTN_NM" : "태화산" + }, + "longitude" : 127.2886111, + "latitude" : 37.291944399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", + "MNTN_NM" : "토곡산" + }, + "longitude" : 128.95459579999999, + "latitude" : 35.371205400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "토곡산은 달음산과 더불어 부산 근교의 3대 악산(惡山)으로 꼽힌다. 계곡능선으로 연결되는 산행로의 경사도 만만치 않은데다 곳곳에 암릉이 많아 험준한 산길이 이어져 있기 때문이다. 그러나 토곡산은 곳곳에 설악산의 `용아릉' 못지 않은 아름다운 암릉군을 감추고 있어 산 타는 재미와 함께 보는 것만으로도 충만한 자연미를 안겨다 준다.경부선 원동역에 접해 있어 열차를 이용한 등산대상지로 안성맞춤이다. 정상에 오르면 남서편으로는 낙동강이 유유히 흐르고 강 건너 무척산과 신어산을 바라보는 조망이 좋고, 동쪽은 천성산에서 금정산으로 뻗어 내린 낙동정맥의 산군이 장쾌하다. 정상에서 서쪽으로 뻗은 능선의 남쪽면은 암벽지대이고 능선 곳곳에 바위지대가 있으며, 북쪽 산록에는 자연휴양림이 조성되어 있고, 앞으로는 선장천이 흘러 가족단위로 조용히 휴식을 취하기에도 더 없이 좋다.", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", + "MNTN_NM" : "토곡산" + }, + "longitude" : 128.95459579999999, + "latitude" : 35.371205400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "토함산은 호국의 진산으로 예로부터 신성시 되어온 산이다. 신라의 영산으로 일명 동악이라 불리었으며, 서악 선도산, 남악 금오산, 북악 금강산, 중악 남산과 더불어 신라 5악이다. 신라의 4대 임금인 석탈해왕이 죽은 후 동악의 산이 되었다고 한다. 석탈해왕은 토해왕이라고도 했는데 토함산의 이름은 동악의 산이 된 데에서 유래된 듯하다.경주에서 가장 큰 산으로서 울산광역시와 경계를 이루며 동쪽으로는 추령재를 지나 기림사와 죽어서 동해의 큰 용이 되어 왜적으로부터 동해를 지키겠다는 문무대왕의 수중릉이 있는 동해바로 이어진다. 서쪽으로는 대덕산과 노천박물관으로 불리는 남산과 마주하고 있다. 북쪽으로는 만호봉을 지나 보문관광단지에 이른다.토함산 기슭에 위치한 불국사와 석굴암 이외에도 무덤에 물이 괴어 널을 걸어 묻었다는 전설로 유명한 괘능, 아사달과 아사녀의 애절한 전설이 담긴 영지못 등 주변에는 많은 문화재가 있다. 일출이 일품인 정상은 신년일출산행지로 손꼽히는 곳이다.", + "MNTN_HG_VL" : "746", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 불국동", + "MNTN_NM" : "토함산" + }, + "longitude" : 129.37361100000001, + "latitude" : 35.756667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한국의 계곡을 대표하는 불영계곡과 인적이 끊긴 내천인 와피천을 가슴에 품고 있는 산이다. 낙동정맥의 주맥으로 울창한 원시림과 맑은 물은 가히 선경(仙境)을 방불케한다. 단지 교통이 불편해서 찾기 어렵다는 단점이 있지만, 마음먹고 찾아간 사람들에게는 자연이 줄 수 있는 최상의 선물을 분명 안겨주는 곳이다.이 산은 왕피천과 한국토종 소나무 자생군락지로 유명한 불영계곡을 품은 낙동정맥의 산이다 주위에 왕궁목재로 이용되던 황장목 보호구역이었던 곳도 있으며 울창한 산림을 이용개발한 통고산 자연휴양림이 있는 곳이다. 각종 나무마다 팻말이 붙어있는 등 가족단위로 나들이 하기엔 안성맞춤이고 산장들은 통나무로 지어져 있고 이름도\"\"머루랑\"\",\"\"다래랑\"\"등 자연그대로의 분위기를 살린 곳이며 삼림욕장 개장과 동시 임산 도로의 개설로 접근이 쉬워진 산이기도 하다. 또한 신라 진덕여왕 5년에 의상대사가 창건한 불영사가 자리잡고 있다.정상에 서면 50평 남짓한 헬기장으로 울진 원자력 발전소에서 세운 둥근 정상 표지판이 반긴다. 시야가 탁 트이면서 조망도 매우 좋다 . 동해 바다의 넘실대는 파도가 손에 잡힐듯 하며 불영계곡과 왕피천계곡이 펼쳐진다. 북쪽으로는 낙동정맥이 굽이 굽이 물결치는 가운데 응봉산이 올려다 보이고 남으로는 저 멀리 아련히 일월산 장군봉이 눈에 들어온다.", + "MNTN_HG_VL" : "1067", + "MNTN_LOCPLC_REGION_NM" : "경상북도 울진군 서면", + "MNTN_NM" : "통고산" + }, + "longitude" : 129.19194440000001, + "latitude" : 36.898611099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "통내산은 경북 청도의 주 하천인 동창천이 매전면쪽으로 흐르다 북서쪽으로 갈라져 나온 관하천을 끼고 있는 산으로 청도군 금천면 금곡리에 자리잡고 있다. 소나무숲과 바위능선 지대가 어우러져 있으며 주변에 동창천이 흐른다.산행은 수무동 버스정류장에서 시작한다. 마을을 지나 능선에 오르면 오른쪽으로 낙타등처럼 보인다 해서 낙타봉이라 이름 붙인 두 개의 봉우리가 보이는데, 뒤로 보이는 것이 정상이다. 앞의 봉우리를 지나 정상에 오르면 무덤이 있고 숲이 앞을 가려 전망은 좋지 않다. 정상에서 두 개의 봉우리를 지나 동창마을로 내려온다.", + "MNTN_HG_VL" : "674", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 매전면", + "MNTN_NM" : "통내산" + }, + "longitude" : 127.0308757, + "latitude" : 37.494464200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "섬진강과 보성강을 가르고 있는 통명산은 그리 높은 산은 아니지만 지리상으로 중요한 위치를 점하고 있다. 통명산을 주산으로 주부산과 곤명산 산줄기가 섬진강과 보성강을 가르고 있기 때문이다. 일반적으로 곡성하면 동악산을 생각하지만 최고봉은 분명 통명산이다. 4개 면의 경계가 되는 지리적인 요충지 외에도 이름조차도 하늘의 옥황상제가 기거한다는 통명전을 뜻하니 말이다. 또한 곡성이 배출한 명장 신숭겸과 마천목은 각각 고려초와 조선초기에 주군을 도와 나라의 기초를 다지는데 기여한 인물들인데 바로 통명산 자락에서 태어났다.제단을 쌓은 듯 평평한 정수리의 조망은 시원하기 이를 데 없다. 북쪽으로 동악산과 곡성읍이, 동쪽으로는 주부산과 지리산의 위용이, 남쪽으로는 조계산을 이어 달리는 호남정맥과 주암호를 지나온 보성강 물줄기가 섬진강을 향하여 굽어드는 절경이 펼쳐진다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "전남 곡성군 죽곡면", + "MNTN_NM" : "통명산" + }, + "longitude" : 127.2616723, + "latitude" : 35.208018799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 양평군 서종면과 가평군 설악면이 경계를 이루는 지점에 위치한 통방산은 북동쪽으로는 청다락골이 있고, 서쪽으로는 사기막천이, 서남쪽으로는 소(沼)와 탕(湯)이 즐비한 삼각골이 있어 띠를 두른 듯 세 방면으로 큰 계곡이 흐르고 있어 여름철 산행지로 적당한 곳이다.지형적으로 남쪽으로만 시계가 트여 남한강이 조망되며, 좌우로 중미산(834), 화야산(755), 용문산(1,157)이 자리하고 있어 첩첩산중에 들어선 느낌을 주는 산이다. 산행기점이 계곡을 건너게 되어 있으므로 수량이 늘어나는 장마철에는 각별한 주의를 해야한다. 수입리쪽에 자리한 사기막천은 계곡미가 수려하여 벽계구곡으로 불리어 왔다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면, 가평군 설악면", + "MNTN_NM" : "통방산" + }, + "longitude" : 127.4560599, + "latitude" : 37.633368599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "팔각산은 계곡을 끼고 뾰족한 암봉 8개가 이어져 있는 데에서 유래했으며 ‘옥계팔봉’이라고도 부른다. 높은 산은 아니지만 각종 기암괴석과 급경사, 암벽 등으로 인해 산세가 험한 편이다. 산 중턱에는 200여 명이 앉을 수 있을 만큼 넓고 편평한 푸른색 암반이 있다.2000년 이전엔 등산로 4.5킬러미터만 개방되었으나 이후 6.1킬로미터 등산로가 추가로 정비되었으며, 곳곳에 로프와 철봉이 설치되었다. 8개의 연이은 봉우리에 다다를 때마다 동해와 삼사해상공원, 주왕산 줄기, 옥계계곡의 물줄기가 차례로 내려다보인다. 산 북쪽에 있는 산성계곡 일대에는 삼림욕장이 조성되어 있으며, 운동시설과 삼림욕 의자, 야외탁자, 평상 등 편의시설과 음수대, 간이화장실, 안내소, 종합안내소가 있다.팔각산과 동대산에서 흘러내린 물이 합류해 이루어진 옥계계곡도 팔각산에서 빼놓을 수 없다. 1607년 손성을이 광해군의 학정을 피해 은거하며 지은 침수정(枕漱亭)이 있으며 이 계곡 일원은 경상북도기념물 45호로 지정되어 있다. 손성을은 계곡 가운데 꽃봉오리 모양으로 앉은 진주암(眞珠岩) 외에 병풍바위, 향로봉, 촛대바위 등 주변의 아름다운 곳을 골라 ‘팔각산 37경’이라는 이름을 붙였다.", + "MNTN_HG_VL" : "633", + "MNTN_LOCPLC_REGION_NM" : "경북 영덕군 달산면 주응리", + "MNTN_NM" : "팔각산" + }, + "longitude" : 129.2583333, + "latitude" : 36.344999999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "팔강산은 중랑구 신내동과 구리시 갈매동 경계에 있는 구릉산 북쪽에 위치한 조그만 봉우리로 서울시 자료에는 표시가 안되어 있으며, 일부 지도 및 구리시 지도에 표시된 산이다. 북쪽으론 불암산을 바라보고 있으며 남서쪽으론 봉화산이 보인다. 정상은 능선으로 되어 있으며, 그 능선을 따라 중랑구와 구리시의 경계가 갈린다.", + "MNTN_HG_VL" : "150", + "MNTN_LOCPLC_REGION_NM" : "경기도 구리시 갈매동", + "MNTN_NM" : "팔강산" + }, + "longitude" : 128.69499999999999, + "latitude" : 36.016944000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경북 경산시의 북쪽에 위치한 해발1,192.3m 산이고. 관봉은 852m 봉우리로써 아주 험준한 산은 아니고 보통인은 등산하기에 알맞고 능선부위에 암반이 많은 곳으며, 자연경관이 좋고 관봉에서는 전망도 좋으며. 일년내내 불자신도와 등산객이 가장많은 장소이다.", + "MNTN_HG_VL" : "1192", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 부계면, 영천시 신녕면, 대구광역시 동구", + "MNTN_NM" : "팔공산" + }, + "longitude" : 128.69499999999999, + "latitude" : 36.016944000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "팔공산하면 대구의 팔공산을 떠올리지만 이 산은 전북 진안과 장수에 걸쳐있는 팔공산으로 제법 높은 산인데도 인적이 드문 산이다. 무진장,무주,진안,장수는 오지중에서도 오지로 꼽혀 사람들의 접근이 쉽지 않았으나 최근에는 깨끗한 산천을 찾는 이들이 늘어가면서 하나씩 이름이 알려져가고 있다.팔공산 역시 사람들의 발길이 닿지 않아 원시림과 같은 청정함을 느낄 수 있는 곳이다. 이 산만이 갖는 뚜렷한 특징은 없으나 정상에서 북으로 내려가는 능선에 키를 넘는 억새군락이 인상적이다.정상에는 송신탑이 있고 사방으로 끝없이 펼쳐지는 산의 파노라마가 장관이며, 동쪽 장안산과의 사이에는 논개의 충절이 소리 없이 깔려 군민과 함께 숨쉬고 친절한 도시 장수가 내려다 보인다. 정상에서 북쪽으로 이어진 능선에는 억새가 장관이며 와룡자연휴양림이 조성되어 더더욱 좋다.", + "MNTN_HG_VL" : "1151", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군", + "MNTN_NM" : "팔공산" + }, + "longitude" : 128.69499999999999, + "latitude" : 36.016944000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주능선이 마치 병풍을 펼친 듯한 산세로, 예부터 '소금강' 이라 불리어질 만큼 아름답다. 게다가 주능선 좌우로 홍천강이 흐르고 있어 정상에 올라서 바라보는 전망이 더 없이 좋으며, 물놀이도 겸할 수 있는 곳이다.팔봉산은 흔히 두 번 놀라게 하는 산으로 알려져 있다. 낮은 산이지만, 산세가 아름다워 놀라고 일단 산에 올라 보면 암릉이 줄지어 있어 산행이 만만치 않아 놀란다는 것이다.", + "MNTN_HG_VL" : "328", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서면 팔봉리", + "MNTN_NM" : "팔봉산" + }, + "longitude" : 127.753889, + "latitude" : 37.702778000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "서산 팔봉산(361.5m)은 금북정맥의 금강산(361.1m)에서 분기한 지능선의 한 줄기로 금강산 서북쪽 바로 건너편에 천혜의 절경을 자랑하며 8개의 봉우리로 솟아있다. 400미터도 되지 않는 낮은 산이지만 아기자기한 암릉과 조망이 일품이다. 능선에 오르면 북쪽으로 오밀조밀한 해변이 한눈에 들어오고 차분하게 가라앉은 주변의 정취가 한 폭의 멋들어진 수채화 같다. 서해안에 접한 이곳은 특히 바위에 노을이 물드는 저녁 시간의 풍경이 장관이다.산의 위치도 바다를 조망하기 좋은 위치이며, 아담한 암릉이 주는 고즈넉한 산세는 백제인의 미소처럼 소탈하다.팔봉산 산행 가운데는 제1봉에서 제3봉 사이에 펼쳐진 암릉 구간이 백미다. 암릉을 오르내리며 걷다보면 수석처럼 현란한 바위의 조화에 절로 탄성이 터져 나온다. 예전에는 아슬아슬한 바위타기가 재미를 더했지만, 지금은 서산시에서 위험한 곳에 철계단을 설치하여 가족산행을 하기에 무리없다. 남녀노소 누구나 안전하게 팔봉산의 바위 능선을 감상할 수 있다.팔봉산만 돌아보고 내려오는데는 3시간 정도면 충분하다. 산행이ordf;다고 느껴지는 사람들은 제8봉에서 산이고개를 거쳐 금강산과 장군산으로 산행을 이어가며 구간을 늘일 수도 있다.", + "MNTN_HG_VL" : "362", + "MNTN_LOCPLC_REGION_NM" : "충남 서산시 팔봉면", + "MNTN_NM" : "팔봉산" + }, + "longitude" : 127.753889, + "latitude" : 37.702778000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "395", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군", + "MNTN_NM" : "팔암산" + }, + "longitude" : 127.1822171, + "latitude" : 34.828257000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고흥읍에서 동쪽으로 25km 떨어진 소백산맥의 맨 끝부분에 위치한 산으로 8개의 봉우리가 남쪽을 향해 일직선으로 솟아 있다.", + "MNTN_HG_VL" : "607", + "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 영남면 우천리", + "MNTN_NM" : "팔영산" + }, + "longitude" : 127.4341153, + "latitude" : 34.618202699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도심에 자리잡은 산자락에는 일제 강점기에 만들어져 오랫동안 마산시민의 식수를 공급했고 수원지에 이르는 길은 침엽수가 울창하여 경관이 뛰어남 서쪽 먼등골에는 한시민이 1993년 산사태가 난후에 계곡을 정비하면서 돌탑을 쌓기 시작하여 지금까지 700여개가 넘는 돌탑군을 쌓아 많은 사람들이 즐긴다.소요 시간 :3시간 30분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 봉암저수지 둘레일반등산객이 정상까지 등반 할 수 있게 안내판, 이정표, 목계단, 안전가드레인이 잘정비 되어 있다.", + "MNTN_HG_VL" : "328", + "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시, 창원시", + "MNTN_NM" : "팔용산" + }, + "longitude" : 128.59123829999999, + "latitude" : 35.226665799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "등산을 즐기는 사람이라도 경기도 양평에 편전산이 있다는 것을 아는 사람은 그다지 많지 않다. 널리 알려지지 않은 산들이 그렇듯이 편전산은 호젓한 산행을 즐기기 좋으며 수풀이 우거져 덮수룩한 산길을 걷는 묘미가 있는 산행지이다. 이 산에는 특히 소나무와 참나무가 많으며 곳곳에 억새풀 수풀림이 형성되어 있다. 정상에 서면 북쪽 건너편에 동그마니 들어앉은 마유산이 보이고 동쪽으로 용문산 주봉과 그 연릉이 남으로 길게 뻗어 나가다 솟구친 백운봉이 가깝게 눈에 든다.정상에 오르면 북쪽 건너편에 커다란 무덤처럼 둥근 산세를 지닌 마유산이 보이고 동쪽으로는 용문산의 주봉과 그 연릉이 남으로 길게 뻗어가다가 솟은 백운봉이 가깝게 조망된다.", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군", + "MNTN_NM" : "편전산" + }, + "longitude" : 127.4802778, + "latitude" : 37.541111099999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포성봉은 충북 영동과 경북 상주시에 걸쳐 있으며 맑은 물과 아름다운 경치로 인해 산을 타는 사람들의 사랑을 받고 있는 곳이다. 여름철이면 풍부한 수량과 짙은 녹음을 찾는 이들로 인해 붐빈다. 산행 길목 어디서든지 들을 수 있는 시원한 물소리는 한여름의 더위마져도 무색케 한다.", + "MNTN_HG_VL" : "933", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시, 충청북도 영동군", + "MNTN_NM" : "포성봉" + }, + "longitude" : 127.8877233, + "latitude" : 36.278346300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "포암산은 반듯한 암벽이 키대로 우뚝 서, 산 모습이 마치 거대한 피륙을 펼쳐 놓은 것처럼 바라보여, '베바우산'으로 불리기도 한다. 또한 희고 우뚝 솟은 바위가 삼대 즉, 지릅같이 보여서 마골산이라고 불렸다는 기록도 전해오고 있다. 만수계곡에서 들어가면 쌍봉의 육산처럼 보이지만 문경시 쪽에서 보면 암봉으로 보인다.백두대간의 중심부에 자리잡고 있고 산세가 험하여 삼국시대부터 군사적 요충지였다. 이 산 밑 고개인 하늘재는 신라시대부터 사용한 옛고개로 북방의 문화를 영남지방에 전해주던 관문이었고 지금도 성벽이 남아 있다.하늘재 밑의 미륵사지는 고려 초기에 조성된 약 4천 평의 대사찰로 주흘산을 진산으로 하며 좌우로는 신선봉과 이 산을 끼고 멀리 월악산을 조산으로 하는 중심혈에 자리잡고 있다. 이곳에는 보물 제95호인 5층석탑과 보물 제96호인 미륵석불이 있다. 미륵석불은 우리나라에서는 보기 힘든 '북향석불'이다. 이 석불은 마의태자가 금강산으로 들어가는 길에 이곳에 머물렀다는 전설을 담고 있어 마의태자 자화상으로도 불린다. 산행은 문경읍 관음리 하늘재에서 시작한다.", + "MNTN_HG_VL" : "962", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍, 충청북도 충주시 상모면", + "MNTN_NM" : "포암산" + }, + "longitude" : 128.11840900000001, + "latitude" : 36.821261999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "풍악산은 남원시 대산면과 순창군 동계면의 경계에 자리한 해발 600미터의 아담한 산이다. 산은 높지 않지만lsquo;단풍나무산rsquo;이라는 이름만큼이나 아름다운 경관을 지니고 있다. 섬진강 옆의 평지에 우뚝 솟아올라 산행할 때 조망이 좋으며, 해발 230미터 중턱에 돌을 쌓아 올린 축대 위로 올려다보이는 마애불은 열반길에 접어든 고목과 어우러지며 범상치 않은 분위기를 연출한다.특히 시원한 조망을 갖춘 정상부는 온갖 기암괴석과 울창한 송림이 어울린 경관이 빼어나다. 전일상호신용금고에서 세운 팻말이 자리한 정상 동쪽으로는 참으로 아름다운 산세와 묘한 이름을 가진 교룡산이 손닿을 듯 다가오고, 그 너머로 지리산의 웅장한 산세가 눈부신 하늘 아래 산평선을 그으며 동쪽으로 달려간다. 남쪽으로는 올림픽고속국도 너머로 곡성의 명산 동악산과 통명산이, 북쪽으로는 장수군의 명산 팔공산이 우뚝한 위용을 자랑한다.풍악산 정상에는 묘한 형상의 바위가 놓여 있다. 어찌보면 조물주가 큼직한 붓으로 일필휘지한 듯한 뫼 산(山) 형상의 바위는 자그마한 연못까지 갖추고 있다.", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "전북 남원시 대산면, 전남 순창군 동계면", + "MNTN_NM" : "풍악산" + }, + "longitude" : 128.10495800000001, + "latitude" : 38.6566951 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "754", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "피래산" + }, + "longitude" : 128.9761111, + "latitude" : 37.646111099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "하설산은 충북 제천에 자리잡은 산이다. 백두대간이 대미산 부근에서 북으로 갈라져 솟은 봉우리가 문수봉이고 이곳에서 북서로 뻗어 우뚝 솟은 봉우리가 바로 하설산이다. 이 산은 대미산에서 갈린 산줄기이며 문수봉과 매두막에서 이어지며 월악산국립공원 안에 있다. 여름에도 눈이 온다는 뜻을 지닌 산 이름은 실제로 눈이 오지는 않지만 그만큼 시원하다는 의미를 담고 있다. 특히 산 아래 자리잡은 용하구곡은 경치가 아름답고 계곡물이 차기로 이름 나 있다. 계곡의 물은 대미산에서 발원한 광천에서 흘러들어온다.정상에서의 조망은 월악산국립공원 일대가 한눈에 들어오고 북쪽으로 충주호와 금수산이, 동쪽으로는 도락산 줄기 너머로 소백산 연화봉과 죽령이 보인다. 정상 주변에는 참나무 수림이 빽빽하고 산딸기나무 군락이 1천 평 남짓 형성되어 있다.", + "MNTN_HG_VL" : "1028", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면", + "MNTN_NM" : "하설산" + }, + "longitude" : 128.1758734, + "latitude" : 36.874696399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "학가산은 경북 안동시 서후면과 북후면, 예천군 보문면의 경계를 이루고 있으며 주변에 막힘없이 우뚝 솟아 있는 산으로 학이 날아가는 형상이라 해서 붙여진 이름이다. 백두대간 선달산에서 옥돌봉을 지나 남쪽 지맥으로 내달리다 청량산과 이나리강을 사이에 두고 남쪽으로 내려서면 봉정사를 품은 천등산을 지나 학가산에 이르러 주변에서 가장 높이 솟아 있다. 정상은 거대한 바위로 이루어져 있는데 국사봉이다. 산의 남쪽에는 고려 공민왕 때 축성된 학가산성이 있고, 북쪽 산등성이에는 자연적으로 쌓여진 자연석탑이 산재해 있다.주변에는 곳곳에 서원과 고택이 많으며 사찰이 골골이 들어차 있고 옛 문인들의 흔적이 고스란히 남아 있다. 학가산을 중심으로 안동은 북서풍을 막아주고, 예천은 일출을 맞이하는 해가 뜨는 동산, 영주에서는 앞산이 되어 풍수지리적으로 안산의 역할을 하고 있어 어느 곳에서나 진산의 면모를 갖추고 있다. 신라시대 능인대사, 학조대사, 학가산 사랑이 남달랐던 송암 권호문 선생 등 역사적 인물과 관계가 깊은 산이다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면, 북후면ㆍ예천군 보문면", + "MNTN_NM" : "학가산" + }, + "longitude" : 128.64811270000001, + "latitude" : 36.589284300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "118", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구", + "MNTN_NM" : "학산" + }, + "longitude" : -118.3204549, + "latitude" : 33.819496399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한석산(1,103)은 내설악 인근의 삼형제봉,가리봉,으로 연결되는 산으로 등산객에게는 많이 알려지지 않은 미지의 산이다. 삼형제봉,가리봉은 험준한 바위들로 이루어져 일반등산객들이 사전지식없이 산행하기에는 무리가 있어 조심해야 하며 주변에 내린천이 있어 래프팅등 모험관광을 동시에 즐길수 있으며 대부분의 코스가 당일 산행이 가능하다.인제군은 오래전부터 이곳에 스키장등 대단위 관광지로 개발하려고 하고 있으나 아직까지 가시적 성과없이 지지부진한 상태이다.한석산의 한모퉁이 내린천 변에는 6.25당시 이땅을 지키기 위한 우리 국군 용사들의 넋을 기리기위해 1990년 11월 매봉 한석산 전적비가 세워졌다.당시 한석산에서는 국군들이 치열한 전투끝에 8백95명의 적군을 사살하고 42명의 포로를 생포하였으며 3일간의 치열한 전투끝에 매봉과 한석산을 탈환하는 전과를 얻었으나 이과정에서 국군 72명이 전사하고 3백19명이 전사하여 이를 기리기위해 8백여평의 부지에 높이 8.1m의 화강암 석탑으로 6.25당시 참전부대인 9사단 30연대를 상징하기 위하여 탑을 9단으로 쌓았으며 탑의 원형도 30각도로 조성한 것이 특징이다", + "MNTN_HG_VL" : "1103", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", + "MNTN_NM" : "한석산" + }, + "longitude" : 128.25588619999999, + "latitude" : 38.051582499999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "원래 차가운 비가 내리는 산이란 뜻의 찰비산이라 불리다가 나중에 찰 한(寒), 비 우(雨) 자를 쓴 한우산으로 이름이 바뀐 이 산은 의령의 명산인 자굴산과 이어져 있다.비록 지리산이나 자굴산에 비해 알려지지는 않았지만, 한우산에서 산성산까지 연결하여 산행을 하다보면 풀밭이 널찍하게 자리잡은 곳이 있어 신나게 달리다가도 수직의 빳빳한 암벽이 늘어선 암봉지대를 만나면 힘겹게 오르는 맛이 있어 숨겨진 산의 보물을 찾아내는 기분이다.산 정상에서 내려다보는 마을은 포근한 느낌이 드는 전형적인 산간마을이어서 그곳에서 하룻밤을 지내면 노곤한 몸이 생기를 되찾을 것이다. 또한 한우산은 철쭉군락지로 유명하고 아름다운 찰비골 계곡에는 민속촌이 조성되어 있다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군", + "MNTN_NM" : "한우산" + }, + "longitude" : 128.20174539999999, + "latitude" : 35.393346600000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "신라와 백제의 격전지로 알려진 한우산은 봄이면 철쭉제가 열리는 철쭉 명산이다. 한자로 찰 한(寒)자와 비 우(雨)자를 쓰는 이 산은 한여름에 내리는 비도 한겨울에 내리는 비처럼 차다고 해서 붙여진 이름이다. 산자락에는 망대실골, 찰비골, 백학계곡이 흐르고 있고 골짜기마다 사시사철 맑은 물이 흐르고 곳곳에 폭포와 소를 만들어 장관을 이룬다.산길은 모나지 않고 완만하고 부드럽다. 한우산은 패러글라이딩 활공장으로도 유명하며 766미터봉 주변으로는 철쭉이 군락을 이루고 있어 봄이면 철쭉을 만끽할 수 있다. 찰비골을 따라 자굴산(897.1m)으로 이어지는 임도를 따르면 산행을 굳이 하지 않아도 차량으로 정상에 다다를 수 있다. 이 임도는 안성기 주연의 영화 ‘아름다운 시절’을 촬영한 곳이기도 하다.국토지리정보원 지형도에는 한우산 정상을 766미터봉으로 표기하고 있으나 의령군청 정보와 실제 산행을 해보면 835미터 봉우리가 정상에 걸맞다는 것을 알 수 있다. 정상석 역시 835봉에 세워져 있지만 높이가 764미터로 표기되어 있으므로 수정이 필요하다.", + "MNTN_HG_VL" : "835", + "MNTN_LOCPLC_REGION_NM" : "경남 의령군 가례면", + "MNTN_NM" : "한우산" + }, + "longitude" : 128.20174539999999, + "latitude" : 35.393346600000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "315", + "MNTN_LOCPLC_REGION_NM" : "대전 동구 효평동,마산동", + "MNTN_NM" : "함각산" + }, + "longitude" : 127.47583330000001, + "latitude" : 36.395555600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "함박산은 최악의 조건을 갖추고 있는 악산이다. 암릉은 대단히 험난하고, 식수는 처음부터 하산 지점까지 전혀 구할 수 없고, 경사도는 매우 심하고 자갈 너덜지대로 되어 있다.암릉식수경사도의 3대 최악의 조건을 구비한 산이라 하겠다. 일부 공룡능선만큼이나 험난한 암릉 코스로 중간중간 위험이 도사리는 만큼, 눈비가 오는 날이나 단독 산행은 절대 금물이다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", + "MNTN_NM" : "함박산" + }, + "longitude" : 127.18888889999999, + "latitude" : 37.2141667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "산경표에서는 ‘크고 밝은 뫼’의 뜻으로 대박산(大朴山), 삼국유사에서는 묘범산(妙梵山)이라 불린 함백산(1572.9m)은 5대 적멸보궁인 정암사를 품고 있으며 지하에는 무진장의 석탄을 간직한 남한 제6위의 산이다. 함백산이 품고 있는 정암사는 1300여년 전 자장율사가 문수보살의 계시에 따라 갈반지(葛盤地)를 찾아 큰 구렁이를 찾은 후 그 자리에 적멸보궁과 수마노탑을 짓고 석가모니의 진신사리를 모셨다고 한다. 적멸보궁 옆 주목은 자장율사가 꽂아둔 지팡이가 살아난 것이라 해 ‘선장단’이라 부른다.함백산 정상 부근은 주목이 군락을 이루며, 두문동재에서 만항재까지의 고원 지역에는 참나물, 누리대, 취나물 등 산나물이 많다. 특히 겨울산행을 하다보면 주목과 고사목에 핀 눈꽃이나 상고대가 추위조차 잊게 해 줄 만큼 아름답다. 함백산의 대표 등산로 중 하나인 만항재는 해발 1330미터로 남한에서 가장 높은 도로며 두문동재는 1268미터로 만항재와 버금가는 높이다.", + "MNTN_HG_VL" : "1573", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 영월군 상동읍, 정선군 고한읍", + "MNTN_NM" : "함백산" + }, + "longitude" : 128.9176271, + "latitude" : 37.1615368 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 양평군 옥천면과 용문면 경계에 있는 함왕봉(947m)은 용문산과 2km거리를 두고 인접해 있는 산으로 용문산의 유명세에 눌려 호젓한 산행을 즐길 수 있는 곳이다. 명찰 용문사가 있는 용문산은 주말이면 행락객들로 만원을 이루는 곳이다.서쪽에 함왕골,동쪽에 연수천 계곡이 흐르고 있어 정상까지 오르면 고봉에 오른듯한 느낌을 주며 산 남쪽으로 남한강이 있어 조망 또한 일품이다.함왕봉에 있는 사나사는 신라 경명왕 7년(923년) 대경대사가 창건한 고찰로 경내에는 석종,3층석탑, 원증국사비, 부도, 함씨각 등이 있고 분지 형태의 함왕성터에는 한겨울에도 얼지 않는 고산샘터가 있다. 양평군 옥천면과 용문면 경계에 있는 함왕봉(947m)은 호젓한 산행을 즐기기에 좋은 산이다. 고찰 사나사를 끼고 있으며 고즈넉한 분위기를 자아낸다.정상에서는 북쪽으로 함왕봉의 모산(母山)인 용문산과 그 옆으로 유명산이 아름다운 자태로 시야에 들어온다. 남쪽으로는 백운봉과 남한강 물줄기가 시원하게 펼쳐져 보인다.", + "MNTN_HG_VL" : "947", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군", + "MNTN_NM" : "함왕봉" + }, + "longitude" : 127.551089, + "latitude" : 37.544308899999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장수군 장계면과 함양군 서상면으 경계로 육십령고개 바로 북쪽에 솟아 있는 암봉이 할미봉이다. 북으로 남덕유산의 우람한 두 봉우리를 올려다 보게 되고, 동으로 월봉산 금원산 황석산을 볼 수 있으며, 남으로 백운산 장안산 왕산 지리산 줄기가 조망된다. 서쪽으로는 팔공산 덕태산이 보이며 운장산도 보인다.", + "MNTN_HG_VL" : "1024", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 장계면 명덕리", + "MNTN_NM" : "합미봉" + }, + "longitude" : 127.6611111, + "latitude" : 35.735277799999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해남 금강산은 한반도 서남쪽 끝머리에 자리잡은 해남읍을 병풍처럼 두르고 있다. 한양과 멀다는 이유로 이곳은 귀양지로 이름을 날린 고장이다. 그러나 귀양 온 양반들이 심어놓은 문화와 유적은 오랫동안 이어져 유배문화의 본산이 된다.그 때문일까. 해남의 산들에는 독특한 정서가 스며있어 산을 찾는 이들마저 시 한 수 읊지 않고는 견딜 수 없게 만든다. 비록 작은 산이지만 기암과 괴석으로 된 암장들이 포진해 있는 금강산 정상에서는 해남읍내와 인근의 목포, 강진, 진도, 완도, 장흥, 영암일대를 조망할 수 있다.", + "MNTN_HG_VL" : "481", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군", + "MNTN_NM" : "해남 금강산" + }, + "longitude" : 126.5997222, + "latitude" : 34.591666699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "해명산은 인천시 삼산면 석모도에 위치한 산으로 서해에서 불어오는 해풍을 받으며 산과 바다의 정취를 동시에 즐길 수 있는 곳이다. 서해에서 불어오는 해풍을 듬뿍 받으며 산행을 할 수 있는 해명산의 정상에서면 낙가산과 상봉산의 모습이 한눈에 들어오고 서쪽바다에는 이름모를 섬들이 아른거리고, 정상을 떠나 주변 바다를 보면서 군데군데 피어있는 진달래 능선을 따라 낙가산으로 갈 때면 마치 바다 위를 걷는 기분이 든다.산세가 아기자기해 가족동반 산행지로 적합하며 산행이 수월하므로 인접한 낙가산 산행을 곁들이는 것이 좋다.", + "MNTN_HG_VL" : "309", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", + "MNTN_NM" : "해명산" + }, + "longitude" : 126.3494724, + "latitude" : 37.676399099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면과 남종면의 경계에 솟은 해협산은 북으로 정암산(403m)과 한강을 끼고, 남쪽의 관산(555m), 양자산(704m)과 함께 나지막한 산이다. 비록 산은 작으나 산세가 험하지 않고 강과 연접해 있어 가족단위 산행과 물놀이를 즐기기 적당한 곳이다.천지개벽 당시에 온 천지가 물바다가 되어 많은 사람들이 배를 타고 피난을 하던 중 정상에 있는\"군두바위\"에 말뚝을 박고 배를 잡아매었다 하며 바위가 있는 곳이 골짜기라 하여 해협산이라 불렀다 한다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면, 남종면", + "MNTN_NM" : "해협산" + }, + "longitude" : 127.3559904, + "latitude" : 37.491495200000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "향로산의 산행들머리는 원동에서 장선행 버스편으로 선리 마을에서 내려, 마을 상점 옆 계곡을 따라 언곡(담재)에 도착한다. 마을에서 식수를 준비하고 왼편길을 따라 나서면, 이 마을의 수호목으로 언제나 해송 4그루가 마중 나와 반기고 있다.바위봉우리인 향로산(香爐山) 정상은 시야가 좋고 사방이 트였다. 뒤로 돌아보면 쌍봉이 의좋게 나란히 서 있는 모습이 정겨워 보인다. 오른 편으로 향로봉이 가까이 보이고 멀리 김해 무척산 신어산까지 뚜렷하다. 산들이 겹겹이 둘러쳐진 그림같은 모습은 근교에선 보기 힘든 빼어난 광경으로 손꼽힌다. 향로산의 본 모습은 염수봉에서 보아야 제맛이다.", + "MNTN_HG_VL" : "976", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "향로산" + }, + "longitude" : 127.66742739999999, + "latitude" : 36.020660100000008 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "574", + "MNTN_LOCPLC_REGION_NM" : "충청남도 계룡시 향한리, 논산시 상월면", + "MNTN_NM" : "향적산" + }, + "longitude" : 127.20184399999999, + "latitude" : 36.292887800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남북으로 길게 누워 계룡산 천왕봉을 올려다보고 있는 향적산은 동서 양편이 높은 바위벼랑으로 되어 있어 아름답다.백두대간에서 금남호남정맥이 갈라져 나와 계룡산 어림에 다다른 금남정맥이 산태극을 이루며 금강을 따라 서남향으로 돌아 나아간다. 여기서 계룡산은 손가락으로 남쪽을 가리키듯 한 가닥 산줄기를 남으로 뻗친다. 계룡산에서 거의 일직선으로 연산까지 뻗은 이 산줄기의 중간쯤에 향적산이 자리 잡고 있다.이 향적산 줄기의 동서 비탈은 지도의 등고선이 보여주는 것처럼 거의 절벽에 가까운 급경사를 이루고 있다. 이 가운데 향적산 주봉 일대의 서면과 농바위 일대의 동서 양면은 깎아지른 바위벼랑으로 장관을 이루어 경관이 좋다.향적산에서는 계룡산을 바로 턱 밑에서 올려다 볼 수 있고 산줄기 너머로 대전시가지가 보인다. 뿐만 아니라 서대산, 진악산, 대둔산, 덕유산, 운장산, 오서산 등이 보인다.", + "MNTN_HG_VL" : "574", + "MNTN_LOCPLC_REGION_NM" : "충청남도 계룡시 향한리, 논산시 상월면", + "MNTN_NM" : "향적산" + }, + "longitude" : 127.20184399999999, + "latitude" : 36.292887800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "허굴산은 인접한 봉화산(금성산), 악견산과 더불어 암릉이 험준하기로 이름난 삼산으로 알려져 있다. 전체적으로 산의 속이 비어 있다고 해서 허굴산이라 이름 붙였다고 하는데 이 산과 관련한 전설과 일화과 있다.하나는 마고할미와 관련한 이야기다. 마고할미 박랑이 가려움증에 시달려 고생하고 있을 때 꿈에서 황매산 자락에 사는 허굴산 신령이 자신의 배꼽 부분에 박힌 돌멩이를 뽑아주면 가려움증이 사라질 것이라 귀띔해 주었다. 박랑 할멈은 곧장 황매산 협곡의 중간에 있는 배꼽바위로 가서 끼인 돌을 뽑아내었다. 그러자 허굴산 속에 가득 찼던 더운 김이 왈칵 빠져나오면서 박랑의 가려움증이 씻은 듯이 나았다고 한다.또 하나는 임진왜란 때 허굴산 정상 아래 고리바위와 남쪽의 여산봉(494m) 정상에 줄을 걸어놓고 허수아비를 만들어 마치 장수가 하늘을 날아 다니는 것처럼 꾸며 쳐들어 오던 왜군들이 겁을 먹고 달아났다는 실화가 그것이다.허굴산 북쪽 허리쪽에는 백년 전에 건립한 청강사가 있다. 산신각, 대웅전, 종루, 요사채, 동굴방이 있는데 양쪽에 놓인 두 개의 큰 바위와의 조화가 눈길을 끈다. 또한 등산로를 따라 가다보변 위장병과 피부병을 고쳤다는 약샘이 있고 허굴산 최고의 전망대인 용바위가 나온다. 수십길 깊이의 바위틈을 건너야 하는 어려움이 따르기 때문에 용바위를 다녀 온 사람은 10년을 더 산다는 말이 전해 내려오고 있다.", + "MNTN_HG_VL" : "681", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", + "MNTN_NM" : "허굴산" + }, + "longitude" : 128.04514599999999, + "latitude" : 35.508830099999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강화군 내가면 고천리에 위치한 해발 466m의 혈구산은 강화도의 중심에 위치한 산이다. 고려산과 고비고개를 사이에 두고 남북으로 이어져있으나 혈구산이 더 높고 산세도 부드러운 고려산에 비해 뾰족하면서 굴곡이 있어 힘이 넘친다. 고비고개에서 정상에 이르는 능선길은 4개의 봉우리로 이루어져있으며 첫 번째 봉우리를 지나면서 방향이 우측으로 심하게 휘면서 2봉을 만나고 남쪽으로 진행하다 3봉이 된 후 다시 왼쪽으로 휘어지며 4봉인 혈구산 정상부를 만들어 낸다.각 봉우리 오름길은 매우 가파라서 숨이 가쁘지만 봉우리에 올라서면 시원한 조망을 제공해주며 다음 봉우리 사이 안부까지 내리막길이 있어 강약이 조화를 이루는 코스라 할 수 있다. 그러면서도 쉬는 시간을 포함해 2시간밖에 걸리지 않는 짧은 거리여서 가족산행지로도 적격이다. 정상부에 올라서면 사방으로 전망이 트이며 강화도의 전모가 드러난다.", + "MNTN_HG_VL" : "466", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 내가면 고천리", + "MNTN_NM" : "혈구산" + }, + "longitude" : 126.4405556, + "latitude" : 37.720277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "912", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 마산면 황전리", + "MNTN_NM" : "형제봉" + }, + "longitude" : 127.0388889, + "latitude" : 37.328888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충청북도 단양군 영춘면과 경상북도 영주시 단산면에 걸쳐 있는 형제봉은 동·북 비탈면에서 남한강 지류 남대천이 발원한다. 소백의 남서쪽 끝자락에 이름 그대로 두 봉우리가 우뜩 솟은 형제봉(1,177.5m)은 소벡산 중에서도 찾는 이가 거의 없는 곳이다. 소백산의 주능선과 이어져 있지만 거의 독립된 봉우리라 해도 과언이 아니다.소백산 끝자락에 온화하게 솟은 산. 비로봉에서 북동쪽으로 직선거리 11.5Km 지점에 솟은 형제봉은 이름 그대로 두 봉우리가 사이좋게 솟아 소백의 남서쪽 끝자락에 자리잡고 있다. 죽령에서 시작하여 비로봉을 지나 국망봉에서 내려오면 형제봉을 바로 앞두고 칼바위에서 서쪽으로 백두대간이 갈려나가고 형제봉을 지나 의풍리로 빠져 나오면 총 39km로 소백산의 가장 긴 종주코스에 해당한다.", + "MNTN_HG_VL" : "1115", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영춘면", + "MNTN_NM" : "형제봉" + }, + "longitude" : 127.0388889, + "latitude" : 37.328888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "한강, 낙동강, 금강의 분수령인 삼파수 속리산 천황봉(1058m)을 지나는 백두대간의 동남쪽 6km 지점에 바위봉을 우뚝 세운 형제봉(828m)은 서쪽 골짜기속에 십승지 중의 하나인 만수동을 감싸고 있다.형제봉의 비경을 빛내는 명소로 금란정과 장각폭포를 꼽을 수 있는데 천황봉에서 동쪽으로 흘러내린 계곡이 상오리에 이르러 높이 6m의 폭포와 소를 이룬 모습이 주변의 경관과 어우러져 선경을 연출한다.", + "MNTN_HG_VL" : "1178", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시, 충청북도 보은군", + "MNTN_NM" : "형제봉" + }, + "longitude" : 127.0388889, + "latitude" : 37.328888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "낙남정맥이 삼신봉에 이르러 섬진강 쪽으로 지맥을 흘러 강 언저리에 솟구쳐 만든 산봉이 형제봉이다. 하동군민이\"\"형\"\"을\"\"성\"\"이라 부르는 언행에서 형제봉을 성제봉으로도 부르는데, 어찌된 셈인지 정상에는 어진 임금이라는 성제봉이라고 표기된 표지석이 산객을 어리둥절하게 한다.악양면소재지 서쪽편으로 막아서서 남쪽으로 길게 뻗어내린 이 산역은 동쪽사면으로 산세를 열어 박경리의 소설 「토지」에 나오는 평사리를 비롯한 마을을 산자락에 포용하고 있다.", + "MNTN_HG_VL" : "1115", + "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면", + "MNTN_NM" : "형제봉" + }, + "longitude" : 127.0388889, + "latitude" : 37.328888900000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "호구산은 지형도에는 이름이 표기되어 있지 않지만, 남해군에서는 송등산, 괴음산 등 산군을 엮어 호구산으로 대표되는 호구산군립공원으로 지정하고 있다. 남해군의 군립공원으로 지정된 것은 그만큼 자연경관이 뛰어나고 보존가치가 있는 곳이라는 뜻이다.남해읍 이동면에 솟은 호구산은 남해 산꾼들이 외부에 알리기를 꺼릴 만큼 아름다운 산으로 소나무, 벚나무, 단풍나무 등 수림이 울창하다.신라 애장왕 때 개창한 남해에서 가장 오래된 절인 용문사에는 대웅전을 비롯해 석불좌상, 천왕각, 명부전, 촌은선생의 집책판, 삼혈포와 수국사 금패 등 많은 문화재가 있으며 부속암자로 백련암, 염불암을 품고 있다.또 암봉으로 된 정상에서 바라보는 앵강만의 풍경은 놓칠 수 없는 볼거리다. 물을 베고 누워 있는 다도해 섬들 사이로 서포 김만중이 유배생활을 하며 「사씨남정기」를 집필했던 노도도 내려다보인다.호구산은 원산 또는 납산으로도 불린다. 호구산(虎丘山)은 정상에서 용문사 쪽으로 뻗어내린 산줄기의 형상이 호랑이가 누워있는 것과 같다해 얻은 이름이다. 원산(猿山)은 이 산을 북쪽에서 보았을 때 원숭이가 웅크리고 있는 것처럼 보인다해 부르는 이름이다. 납산의lsquo;납rsquo;은 원숭이의 옛말이다.", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경남 남해군 이동면 용소리", + "MNTN_NM" : "호구산" + }, + "longitude" : 127.905485, + "latitude" : 34.790899799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "490", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", + "MNTN_NM" : "호랑산" + }, + "longitude" : 127.7008915, + "latitude" : 34.791603500000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "245", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "호룡곡산" + }, + "longitude" : 126.4214736, + "latitude" : 37.378381300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "인otilde;시 중구 무의도에 있는 호룡곡산은 사계절 바다의 정취를 즐기며 산행을 즐길 수 있는 산이다. 수도권에서 1~2시간이면 닿을 수 있고, 섬 산행과 낙조산행을 즐기기에 제격이다.무의동~호랑바위~신선약수~정상~마당바위~부oacute;바위~환상의길~하나개해수욕장으로 이어지는 등산코스는 2시간이면 누구나 완주할 수 있다. 약 6킬로미터에 달하는 등산코스에는 옹달샘, 약수터, 나무계단 등이 잘 정비되어 있다.정상에서는 용유도, 팔미도, 자월도, 영흥도 등 섬과 바다가 어우러진 풍광이 일품이다. 산행 후 들리게 되는 무의도 서쪽 하나개 해변에서는 동죽, 바지락 등 조개도 잡을 수 있다. 이 해변은 영화 공포의 외인구단 촬영장소였다.호룡곡산 산행의 또 다른 매력은 산릉에 있는 고려바위, 마당바위, 부oacute;바위 등 기암괴석을 감상하는 것이다. ‘서해의 알프스’ 라 불릴 만큼 산세가 수려하다. 생태관찰로, 산림uuml;험로(4km), 전망대 등을 갖춘 삼림욕장도 있다.", + "MNTN_HG_VL" : "245", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "호룡곡산" + }, + "longitude" : 126.4214736, + "latitude" : 37.378381300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "북한강변에 자리 잡은 호명산은 한북정맥상의 귀목봉에서 남으로 뻗은 산줄기 끝자락에 있는 산으로 청평댐 뒤로 병풍처럼 솟아 있다. 이 산은 지난 79년 산 위에 양수발전용 저수지인 호명 저수지가 생긴 다음부터 등산객들의 발길이 잦아지는 산이다.‘호랑이가 우는 산’이란 뜻의 호명산은 옛날 산림이 우거지고 사람들의 왕래가 적었을 때 호랑이 울음소리가 많이 들려오곤 했다는 데서 유래되었다. 때문에 범이 우는 마을의 호명리와 범이 입을 벌리고 있는 모습과 흡사하다는 아갈바위봉, 아갈바위골 등 호랑이와 관련된 지명이 산 곳곳에 남아있다. 남쪽으로는 청평호반과 조종천이 지척이며, 북쪽으로는 북한강과 함께 인공댐인 청평 양수발전소가 있는 천지연이 자리 잡고 있다.정상에서는 남으로 화야산 뽀루봉과 용문산이 줄지어 서있고 서북으로는 깃대봉과 축령산, 서리산 등이 조망된다. 북으로 청우산과 대금산 매봉이 뚜렷하게 보이고 명지산, 화악산, 국망봉 등이 파노라마의 장관을 연출하며 산 아래로는 청평호와 북한강, 조종천, 천지연의 물줄기가 반짝인다.", + "MNTN_HG_VL" : "632", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 청평면", + "MNTN_NM" : "호명산" + }, + "longitude" : 127.4460303, + "latitude" : 37.729328899999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "호음산" + }, + "longitude" : 127.83861109999999, + "latitude" : 35.797499999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "물을 받는 통처럼 골이 깊고 물이 많다는 뜻의 이름을 지닌 홀통골산은 충북 단양군 영춘면남천리 남천계곡 동쪽에 자리한 형제봉(1178m)과 맥을 같이하고 있다.정상의 남쪽 멀리로 소백산의 신선봉이 조망되고 그 아래로 범놀이골, 새삼박골, 활골, 너래골, 석골 등 도원경을 연상케 하는 남천계곡이 보인다.수림지대로 뒤덮여 길을 찾기 어려우므로 지형도와 개념도, 나침반을 준비하고 장마기간에는 남천계곡을 건널 20m이상의 보조자일을 준비해 가야 한다", + "MNTN_HG_VL" : "1029", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영천면", + "MNTN_NM" : "홀통골산" + }, + "longitude" : 126.3372732, + "latitude" : 35.0612329 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "섬 산행은 언제나 가슴 설레게 만든다. 사면이 바다이고 공기가 맑고 깨끗하며, 특히강화군은 많은 유적지와 역사적 의미가 곳곳에 어우러져 있어 더욱 좋다. 화개산은 누구나 등반하기 좋으며, 산세가 아름답고 숲이 잘 가꾸어져 있다. 토사와 암반이 적당하게 조화를 이루고있으며 정상부에 있는 약수터는 과거 산성으로서의 가치가 매우 우수했으리라 짐작된다. 정상부는 산성으로 이용하기 좋은 구조이며, 과거에도 큰 역할을 했으리라 생각된다. 남한산성이나 행주산성 처럼 용수 시설을 포함하고 있는 포곡식 산성인 화개산은 동쪽으로는 절벽의 지형을 잘 이용하고 있으며, 북과 남으로 길게 늘어져 있는 형태이다. 봉수대는 동쪽으로 봉천산 봉수대와 연락을 했고, 남으로는 덕산봉수와 대응했다고 신동국여지승람에 전한다.", + "MNTN_HG_VL" : "262", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 교동면 대룡리", + "MNTN_NM" : "화개산" + }, + "longitude" : 126.29608589999999, + "latitude" : 37.779330000000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화란봉은 이름 그대로 꽃모양을 하고 있는 산으로 부채살처럼 펼쳐진 화관이 화란봉을 중심으로 겹겹이 에워싼 형상이다.산행기점인 벌마을에는 용수골이 있는데 이곳은 옛날에 이무기가 하늘로 오르다 힘이 부쳐 떨어진 곳이라 한다. 지금도 그때 자국이 용수골 너럭바위에 남아있다.화란봉에선 닭목재가 한눈에 들어온다.화란봉 주위에는 기암괴석과 몇 아름 되는 노송들이 바위 틈새에서 우람하게 자라는 모습을 보면 마치 한 폭의 동양화를 연상하게 된다.", + "MNTN_HG_VL" : "1069", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면", + "MNTN_NM" : "화란봉" + }, + "longitude" : 128.78916670000001, + "latitude" : 37.626388899999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화악산은 경북 청도군 경남 밀양시의 도경계를 이루고 있다. 비슬산에서 남쪽으로 이어져 한 줄기는 창녕 화왕산으로 갈라지고, 화악산을 지나 철마산으로 뻗어내려 물길을 만나면서 멈춘다.화악산은 부드러운 육산과 곳곳에 바윗길을 드러낸 골산이 합쳐진 형태의 산으로 청도에서 손꼽을 만큼 아름다운 산이다. 정상은 세 봉우리가 주봉을 중심으로 나란히 솟아 있고 그 등성이가 황소의 등을 방불케 하며, 두 봉우리의 중간쯤에서 남쪽으로 또 한 봉우리가 솟아 있는데 이를 속칭 작은 화악산이라고 한다.화악이란 이름은 정상의 세개 봉우리 형상이 중국 오악의 하나인 서악, 즉 화악의 삼봉과 비슷하다고 하여 붙여진 것이다. 또 산의 생김새가 덕성스러워 덕기에 둔취되어 있다는 뜻에서 둔덕산이라고도 한다. 화악산은 영남알프스까지 이어지는 만만찮은 높이에 시원스런 조망과 아기자기한 암릉 그리고 봄철에는 철쭉이 피어 가족산행지로 적합하다.", + "MNTN_HG_VL" : "932", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 청도읍ㆍ경상남도 밀양시 청도면", + "MNTN_NM" : "화악산" + }, + "longitude" : 127.5031003, + "latitude" : 37.9950197 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "높이 755m의 화야산은 북한강이 북에서 서쪽으로 감싸고 흘러내리는 가운데 위치해 있다. 산위에서의 전망이 좋고 강물을 내려다보며 산을 오르는 이색적인 기분을 맛 볼 수 있다. 화야산은 가평군 외서면과 양평군 서정면에 걸쳐 있는 해발755m의 산으로 북한강이 산 북쪽으로 청평호를 이루면서 감싸고 돌아 남쪽으로 행해 나란히 흘러나가는 가운데 있으므로 산행중에 내려다 보이는 경치가 아름답다.청평에서 멀지않은곳에 있으므로 접근이 용이하고 정상 북쪽끝에 위치한 뾰루봉(709m)과 서쪽능선위에 일구어진 고동산(600m)이 모두 화야산에 딸린 봉우리라 할수 있다. 동서로 갈라져 내려간 능선에는 수림이 울창하고 계곡이깊어서 어느때 찾아도 만족한 산행을 할수 있다. 산행에 있어서 어느코스를 택하건 4시간 이상 소요되므로 만만히 보아서는 않된다.또 겨울철에는 적설량이 많아 겨울산행의 맛을 제 대로 느껴 볼수 있는 산이기도 하다. 북쪽의 청평 호반과 서쪽 큰골 또한 대성리 유원지와 함께 여름철 피서지로서 유명하다. 주능성에 올라서면 강물을 끼고 산행하는 기분이 좋다.", + "MNTN_HG_VL" : "755", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 외서면", + "MNTN_NM" : "화야산" + }, + "longitude" : 127.4279782, + "latitude" : 37.671530099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경남 창녕에 자리한 화왕산은 험준한 산이다.특히 봄이면 진달래와 철쭉, 여름에는 녹음과 계곡물, 가을에는 억새, 겨울에는 설경이 유명하다. 봄철 진달래 경치와 가을철 억새가 유명한데, 봄철이면 진달래 군락지를 이루고 있는 화왕산성 주위의 비탈과 관룡산으로 이어지는 능선 일대는 마치 분홍물감을 쏟아부은 듯하다. 매년 4월 하순에서 5월 초순까지 그야말로 산 전체가 불타오르듯 만발한 진달래의 붉은 기운으로 뒤덮인다.화왕산 최대의 명물이라면 정상 주변의 넓고 평평한 억새밭인 '십리억새밭'이다.그 십리 억새밭이 평지에서 급경사 벽으로 뚝 떨어지는 경계선인 능선을 따라 화왕산 성벽이 쌓여 있으며, 그 바깥 경사면 거의 모두가 진달래밭을 이루고 있다. 매년 10월이면 이곳에서 화왕산 억새제가 개최된다. 화왕산은 선사시대 화산으로 추정되며, 3개의 못(龍池)가 있으며, 창녕조(曺)씨가 득성하였다는 득성비가 화왕산성(사적제64호)가 있다. 또 서쪽 능선으로는 사적 65호인 목마산성이 보인다. 능선의 동쪽 5km 거리에 관룡사가 있다.", + "MNTN_HG_VL" : "758", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍 옥천리 일대", + "MNTN_NM" : "화왕산" + }, + "longitude" : 128.56055559999999, + "latitude" : 35.537222200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 연천군 신서면과 포천군 관인면에 걸친 지장산(877m)은 일반인의 등산이 허용된 산중 최북단이다. 화인봉은 삼형제봉쪽으로 뻗은 남쪽길을 버리고 북릉을 타고 고도를 높여가면 나타난다.바위봉우리인 화인봉에서는 김일성이 휴전 후 눈물을 흘리며 아까워했다는 철원평야가 한눈에 들어온다. 화인봉을 한자로 쓰면 어떤지 모르지만 자꾸 fine봉이라는 영어가 떠오른다. 그처럼 그림 같은 봉우리이기 때문이다.", + "MNTN_HG_VL" : "805", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 관인면 중리", + "MNTN_NM" : "화인봉" + }, + "longitude" : 127.17340609999999, + "latitude" : 38.1419122 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장흥과 가깝고 험한 능선이 있어 전란의 소용돌이에 끊임없이 휘말려들었던 화학산은 오르다보면 실제로는 그리 험하지 않다. 나무도 거의 잡목이고 육산인데다가 주능선도 바위지대가 없이 길게 남북으로 늘어져 있다.정상은 좁은 데다가 꺽다리 억새들이 무성해서 주위경관을 감상하기는 쉽지 않다. 하지만 남쪽으로 조금 내려와 헬기장에 서면 천태산과 금성산, 용암산과 국사봉을 모두 볼 수 있다.", + "MNTN_HG_VL" : "614", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 청풍면, 도암면", + "MNTN_NM" : "화학산" + }, + "longitude" : 127.5031003, + "latitude" : 37.9950197 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "환성산은 팔공산과 무학산이 서로 연결되는 중앙산록으로 예부터 이 산의 생김새가 서로 고리를 걸어 당기는 형상이라 해 환성산이라 불렀다. 하양 명산으로 산 아래에는 신라 헌덕왕의 왕자인 심지왕사가 창건했다는 환성사가 있다.안심에서 산행을 시작해 뾰족한 봉우리를 오르면 초래봉이다. 태조 왕건 촬영지로 알려져 많은 등산인들이 찾고 있다. 뒤로는 대구시가지와 금호강 줄기가, 동쪽으로는 카톨릭대학과 하양읍내가 보인다. 초래봉은 바위로 이루어져있는데 정상표석은 대안산악회에서 설치했다. 이 산은 고려 태조 왕건이 후백제 견훤이 패하여 이곳에 이르렀다가 후에 여기서 제를 올렸다는 이야기가 전한다.정상을 지나면 불굴사에 닿는다. 경내에는 갓바위약사여래불과 동시대 것으로 추정되는 약사여래입상과 보물 429호인 불굴사 삼층석탑이 있다. 불굴사 주방 뒤로 가면 절벽 위에 자연석굴이 있는데 지금은 홍주암이라는 암자로 쓰인다. ‘불굴’, ‘원효굴’, ‘관음굴’로도 불리며 굴 속에 ‘아동제일약수(我東第一藥水)’가 있다. 원효굴은 김유신 장군이 이 물을 마시면서 삼국통일의 염원을 기도했던 장소로도 알려져 있다.", + "MNTN_HG_VL" : "811", + "MNTN_LOCPLC_REGION_NM" : "대구시 동구, 경북 경산시 하양읍ㆍ와촌읍", + "MNTN_NM" : "환성산" + }, + "longitude" : 128.74083329999999, + "latitude" : 35.936944400000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "환희산은 진천군 문백면과 충청남도 천안군 동면을 경계로 위치해 있다. 환희산이란 이름은 말그대로 기쁨을 안겨주는 산이라는 뜻에서 그렇게 불려진다.야트막한 산을 산책 삼아 오르내리며 환희산이 안겨주는 기쁨으로 몸도 마음도 건강해질 수 있을 것이다. 환희산은 등산시간이 짧아 등산으로 인한 피로감은 전혀 느껴지지 않는다. 삼림욕을 하듯 천천히 산을 즐긴다면 맑은 공기가 가슴을 탁 트이게 한다.", + "MNTN_HG_VL" : "402", + "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면 봉죽리", + "MNTN_NM" : "환희산" + }, + "longitude" : 127.402422, + "latitude" : 36.800996699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "합천호 푸른물속에 산자락을 담그고 하봉, 중봉, 상봉 등 세 봉우리로 정상을 이루어 수중매로 불리는 황매산(1,108m)은 합천읍에서 서남쪽으로 20km 지점에 위치해 있다.산아래의 황매 평전은 목장 지대와 고산 철쭉 자생지가 있으며, 통일 신라시대의 고찰인 염암사지(사적 131호)가 있다. 황매산은 군리 공원으로 1983년 지정되어, 가회면 둔내리에서 영암사지에 이르는 등산로를 개설하였다. 대병면 하금리 하금천에는 야영장을 개설하여 합천호와 이 지역을 찾는 관광객의 편의를 도모하고 있다.", + "MNTN_HG_VL" : "1113", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면, 가회면, 산청군 차황면.", + "MNTN_NM" : "황매산" + }, + "longitude" : 127.9744444, + "latitude" : 35.495833300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "103", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 중구 장현동", + "MNTN_NM" : "황방산" + }, + "longitude" : 127.098922, + "latitude" : 35.834747 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황병산은 높이 1,407m의 명산으로 청학동 소금강의 절경을 끼고 구룡폭포, 만물상, 금강사, 십자소 등 수많은 명승 고적을 품고 있다.75년 오대산이 국립공원으로 지정되면서 황병산 또한 국립공원으로 편입됐지만, 사람들 사이에서는 잘 알려지지 않은 편이다. 잘 알려지지 않은 까닭에 황병산은 자연 그대로의 아름다움을 간직할 수 있었다. 골골이 깊은 산중의 계곡 하며, 희귀식물, 원시림 등은 황병산의 또 다른 자랑이다.육산이라 산행도 수월한 편이며 부드러운 흙을 밟으며 산행 할 수 있어 좋다. 특히 여름이면 계곡을 끼고 가는 코스가 인기다. 정상은 입산금지 구역이다.", + "MNTN_HG_VL" : "1407", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면 병내리", + "MNTN_NM" : "황병산" + }, + "longitude" : 128.66333330000001, + "latitude" : 37.7577778 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황석산이 위치해 있는 함양은 '썩은 갈치가 다 모이는 곳' 이라 할만큼 상대적으로 교통이 불편한 곳으로 사람의 발길을 덜 타는 오지이다. 그래서 이 산은 손때 묻지 않은 자연미를 그대로 보존하고 있는 곳이다.황석산 정상부로 가는 길은 억새능선이 장관을 이루고 정상부에 이르면 쌍립한 암봉의 멋스러움이 등산의 피로를 어루만져준다. 인접한 거망산 종주길도 경관이 일품인데 그 사이사이에 위험한 암릉길이 있으므로 20m정도의 보조자일을 준비하는 것이 안전하다.", + "MNTN_HG_VL" : "1193", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", + "MNTN_NM" : "황석산" + }, + "longitude" : 127.7574192, + "latitude" : 35.656779499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황악산은 김천시에서 서쪽으로 12km 떨어진 곳에 위치한 산이다.옛부터 학이 많이 찾아와 황학산이라 불리었으나, 직지사의 현판 및 택리지에 황악산으로 되어있다. 울창한 소나무 숲과 깊은 계곡에 옥같이 맑은 물, 가을의 단풍과 겨울의 설화가 아름답다. 일대는 국민관광지로 지정되어 더욱 개발되고 있다.전체적인 산세는 특징없이 완만한 편이나 온 산에 수림이 울창하고 산 동쪽으로 흘러내리는 계곡은 곳곳에 폭포와 소를 이뤄 그윽한 계곡미를 이루고 있다. 특히 직지사 서쪽200m 지점에 있는 천룡대에서부터 펼쳐지는 능여계곡은 이산의 대표적인 계곡으로 봄철에는 진달래, 벚꽃, 산목련이 볼만하고 가을철 단풍 또한 절경을 이룬다.황악산 정상에서 직지사를 내려다 보면 무수한 지능선이 하나씩 계곡안에서 소멸된 뒤 마지막 남은 두가닥 능선이 좌우에서 직지사를 크게 싸안으면서 산과 절의 화합은 완성된다. 1111m에 이르는 황악산의 높은 봉우리와 그 아래 학의 날개처럼 펼쳐지는 계곡이 좁은 수로를 통하여 동으로 빠져나가고 그 길목에 직지사는 자리잡고 있는 것이다.직지사는 어떻게 보면 황악산 정기가 맺은 전혀 다른 종류의 꽃봉오리 같아 보인다. 직지사는 새로 세운 대형 일주문에 동국제일가람이라는 커다란 편액을 붙여놓은 대로 국중의 사찰 가운데서도 열손가락에 들만한 거찰이다.", + "MNTN_HG_VL" : "1111", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대항면 운수리", + "MNTN_NM" : "황악산" + }, + "longitude" : 127.966111, + "latitude" : 36.119166999999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "백두대간의 한 뼈대를 이루며 높이 솟아있는 이 산은 이름이 여럿 있다. 황정산(黃庭山)이라고도 하고 작성산(鵲城山), 또는 황장봉산 등으로 표기되고 있으나 황장목이 많아 황장산으로 통칭되고 있다.소나무의 한 종류인 황장목은 균열이 적고 단단해 임금의 관(棺)이나 대궐을 만드는데 많이 쓰인 귀한 나무이다. 이 때문에 조선조 숙종 때인 1680년에 이 산에서의 벌목과 개간을 금지하는 봉산(封山) 표석이 동로면 명전리 벌천계곡 하류에 세워졌다. 또 산 깊숙한 문안골 계곡에는 우람한 석문이 있는 작성산성이 있는데 축조방식으로 보아 고구려 시대 것으로 추정된다. 산 아래 금천에는 버들치 등 1급수 어류가 살고 있다.", + "MNTN_HG_VL" : "1079", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면", + "MNTN_NM" : "황장산" + }, + "longitude" : 128.27611099999999, + "latitude" : 36.813056000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1069", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면 활기리,화장면 번천리", + "MNTN_NM" : "황장산" + }, + "longitude" : 128.27611099999999, + "latitude" : 36.813056000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황적봉은 계룡산의 봉우리중 하나이다. 계룡산은 충청남도 공주군과 논산군에 걸쳐있으며 주봉인 천왕봉(845m)아래로 쌀개봉(828m), 황적봉(664m),수창봉(662m) 도덕봉(524m)등 거대한 산혼을 횡성하고 산세는 대체로 경사가 완만한 편이며 정상 부근은 경사가 급하다. 이들 봉우리 사이에는 7개의 계곡과 3개의 폭포가 있어 운치를 더해주며, 골짜기에는 동학사갑사신원사 그리고 구룡사의 대가람을 배치한 불교의 명지이며, 다양한 식, 생물분포의 학술적 자원이 풍부하며 자연경관이 빼어난 국립공원으로 이름이 높다.출입이 금지되어 있는 황적봉-쌀개봉 능선은 계룡산 산행의 또 하나의 모험이자, 신선한 충격이다. 황적봉-쌀개봉능선을 잇는 산행은 때로는 한가할 정도로 평탄한 산행길이지만 변화 많은 봉우리로 점철 돼 있어 잔재미가 많으며 때로는 위험한 바윗길이 숨어있는 호방한 산행의 기분도 만끽할 수 있는 아름다운 코스이다. 특히 쌀개능선의 호방한 바위암릉위에서 바라보는 연천봉에서 관음봉을 거쳐 자연성능, 삼불봉으로 이어지는 이 산의 이른바\"\"주코스\"\"의 능선과 봉우리들을 바라보는 경관은 전혀 다른 매력으로 다가온다.", + "MNTN_HG_VL" : "664", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 반포면, 논산시 두마", + "MNTN_NM" : "황적봉" + }, + "longitude" : 127.2319444, + "latitude" : 36.348611099999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "황정산은 충북 단양군 대강면에 위치한 산으로, 도로를 사이에 두고 유명한 도락산과 마주보고 있다. 백두대간이 소백산을 지나 죽령에서 가라앉았다가 남쪽으로 다시 치솟으며 도솔봉(1,314m)과 묘적봉(1,148m)을 빚어낸다.백두대간이 묘적봉에서 서쪽으로 방향을 틀어 황장봉산(1,077m)으로 뻗어나가기 직전인 저수재와 벌재 사이 1,076m봉에서 북으로 가지를 쳐 나간 지능선은 1,080m봉과 수리봉(1,019m)을 일으키고 이어서 빚어 놓은 것이 황정산이다. 황정산을 일으킨 능선은 서북쪽으로 방향을 틀어 직치에서 가라앉았다가 다시 고도를 높이며 도락산(964m)을 빚어 놓고 북으로 금수산을 향하여 뻗어 나간 능선이 덕절산(780m)과 두악산(732m)을 마지막으로 빚어놓고 그 여맥을 충주호에 가라앉힌다.이 산에는 천년고찰인 원통암(圓通庵)을 비롯해서 기암괴석으로 이루어진 신단양8경의 하나인 칠성암,남근석,모자(母子)바위, 손가락바위, 누에바위 등 볼거리가 산 곳곳에 널려있다. 황정산 북동쪽 산자락에 자리잡은 원통암은 고려 공민왕(1351-1374)때 나옹화상이 개창했다고 전해진다. 원통암 옆에는 대석 높이 7m 위에 높이 15m의 7개 암석이 있다. 4개의 수직 균열이 있어 부처님 손바닥을 닮았다는 칠성암(七星巖)이 있는 꼭대기에는 수령이 3백년은 됨직한 노송이 한 그루 서 있다.", + "MNTN_HG_VL" : "959", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "황정산" + }, + "longitude" : 128.33677549999999, + "latitude" : 36.845008499999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "회령봉은 강원도 평창군 봉평면에 위치한 준봉으로써, 육산이며 숲이 울창하고 산록엔 더덕이 많다. 멀지 않은 곳에 솟아 있는 흥정산과 산세와 규모가 비슷한 산이다.산길은 대체로 또렷하나 숲이 짙으므로 길 찾기가 쉽지 않다. 능선엔 진달래와 철쭉나무가 군락을 이룬다.사람들이 거의 찾지 않는 강원도의 오지 산 중의 하나이다.", + "MNTN_HG_VL" : "1309", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면", + "MNTN_NM" : "회령봉" + }, + "longitude" : 128.3663889, + "latitude" : 37.686111099999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 순창에 있는 회문산은 북에서 동으로 섬진강 줄기가 꺾여 흐르며 남으로 구림천이 섬진강으로 휘돌아 빠지는 지점에 둔중한 줄기로 솟아 있다. 우리나라 5대 명당 중 하나로 옛부터 영산으로 이름난 회문산은 홍문대사(홍성문)가 이 산에서 도통하여, 회문산가 24혈의 명당 책자를 만들었다고 해서 유래되었다. 이 책에는 회문산 정상에 24명당과 오선위기가 있는데, 이곳에 묘를 쓰면 당대부터 발복하여 59대까지 갈 것이라 했다.회문산은 순창군과 임실군을 가르는 산으로서 봉우리와 골짜기가 많아 첩첩산중을 이루고 있는데다 서쪽을 제외한 삼면이 강으로 둘러싸여 있어 예로부터 천혜의 요새로 알려져 있다. 이러한 지형적인 특성 때문에 역사적으로 많은 사연을 품고 있다.소설남부군의 배경이 되기도 했으며 한말에 임병찬 최익현 양윤숙 선생이 의병을 일으켜 일제에 항거했고, 6·25때는 북한의 남부군총사령부가 있었던 곳이다. 그러나 지금은 회문산자연휴양림이 조성되어 지난날의 흔적을 찾아보기가 어렵다.", + "MNTN_HG_VL" : "837", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 덕치면", + "MNTN_NM" : "회문산" + }, + "longitude" : 127.10604069999999, + "latitude" : 35.499814700000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "효양산은 삼족당 기대유 공이 마을에 부임해 와서, 마을 뒷산의 엄청난 위용과 험준함을 보고, 마을에 무슨 피해라도 있을까봐 공이 산을 받든다는 뜻에서 이 산을 효양산이라고 이름을 지었다. 그 이후 마을에는 효자, 효부가 많이 났다고 한다.산행들머리는 나무 왼편 골목길에서 파란 기와집 오른쪽으로 오르면 산자락에 접어드는데 식수는 반드시 이 마을에서 준비해야 한다. 정상은 5,6 명이 겨우 설 수 있을 정도로 좁다.", + "MNTN_HG_VL" : "580", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "효양산" + }, + "longitude" : 127.4807519, + "latitude" : 37.272978999999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "후봉" + }, + "longitude" : 127.8288889, + "latitude" : 37.923333300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "흑성산" + }, + "longitude" : 127.208302, + "latitude" : 36.796827100000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "오대산에서 시작되는 백두대간의 줄기가 운두령을 넘어 서진하다가 1212m봉에서 남서쪽으로 가지를 친 능선위에 솟아 있는 산이 흥정산이다. 흥정산의 전체 산새는 육산이고, 능선길은 산죽이 깔려 있으며 숲이 앞을 가려 조망은 좋지 않은 편이다.흥정산 골짜기 계곡주변은 이름모를 잡목, 단풍나무, 물푸레나무, 싸리나무, 두릅나무 등 울창한 수림지대를 이루고 냉수성어류 인 열목어와 송어 등이 다량 서식하고 있으며, 기암괴석과 울창한 숲속으로 조화롭게 이루어진 게곡이다.", + "MNTN_HG_VL" : "1279", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면 흥정리", + "MNTN_NM" : "흥정산" + }, + "longitude" : 128.31444440000001, + "latitude" : 37.676944399999996 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "희리산은 해발 327미터로 그리 높지 않아 어린 자녀와 함께 삼림욕을 즐기기에 안성맞춤이다. 최고봉인 문수봉에 올라서면 사방이 탁 트여 조망 또한 훌륭하다. 산 전체는 사계절 내내 푸른 해송으로 둘러싸여 있어 언제든지 녹색의 신선함을 느낄 수 있다.희리산은 자연휴양림으로 유명하다. 휴양림의 휴양관은 총 15개실로 대회의실과 소회의실을 갖추고 있어 단체 이용객이 사용하기에 적합하고 숲속의 집은 7개 수종(소나무, 잣나무, 낙엽송, 삼나무, 해송, 층층나무, 참나무)의 판재로 내부 인테리어를 꾸며 특유의 향기를 느낄 수 있다.휴양림의 북서쪽에는 네명의 장사가 놀던 자리라는 사인대가 있고 사인대 밑에는 이 장사들이 턱걸이한 장소라 하여 턱걸이장이라 불리고 있는 140미터 정도의 절벽도 있다.문수봉 밑으로는 이 장사들이 살았다는 큰 산봉우리 4개가 있고 그 아래로 이 장사들의 졸병들이 살았다 하여 이름 붙여진 여러 모양의 작은 졸병바위가 100여 개 정도 있으며 빈대가 너무 많아 절을 헐었다는 문수사 절터도 있어 희리산을 오르는 동안 많은 볼거리를 제공하고 있다.", + "MNTN_HG_VL" : "327", + "MNTN_LOCPLC_REGION_NM" : "충남 서천군 종천면", + "MNTN_NM" : "희리산" + }, + "longitude" : 126.66426149999999, + "latitude" : 36.112400299999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "희양산은 충북의 괴산과 경북의 문경에 걸쳐 거대한 하나의 바위덩이로 이루어진 듯 당당한 위세를 뽐내고 있는 산이다. 정상에서 북쪽은 시루봉, 서쪽으로는 구왕봉으로 이어져 나가며 기세를 진정시키지만, 동남서쪽으로 노출된 암장능 곡클라이밍 코스로 다시 없이 좋아 이미 여러개의 코스가 개발되어 있다.병풍처럼 둘러쌓인 거대한 화강암벽은 설악산 울산바위에 필적할 만 하며, 암벽 하단부인 2백여m의 슬랩과 암벽은 위압감을 느끼기에 충분하다. 정상 남쪽 아래 유서깊은 봉암사가 있고, 옥석대와 그 주변 일대에 펼쳐진 옥석계곡의 뛰어난 정경은 등산의 또 다른 맛을 준다.", + "MNTN_HG_VL" : "996", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면,", + "MNTN_NM" : "희양산" + }, + "longitude" : 128.0027001, + "latitude" : 36.715962300000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "본래 이름은흰돌더미산이다. 흰덤이가 흰대미로 불리기도 하고 희대미로 불리기도 한다. 산 정상에 높이 약 1.5m 둘레 6m 쯤되는 흰 화강암이 놓여있는데 산이름은 여기서 유래되었다고 본다. 정상에서 북쪽으로 2km 거리에 양각산이 있고 더가면 수도산이 있다. 남쪽으로는 회남령과 이어져 보해산과 금귀봉이 자리하고 있고 서쪽으로는 웅양댐이 안겨있고거말산에서 국사봉으로 이어지는 길이 된다.", + "MNTN_HG_VL" : "1018", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가북면, 웅양면", + "MNTN_NM" : "흰대미산" + }, + "longitude" : 127.9561111, + "latitude" : 35.825277799999988 + } +] \ No newline at end of file From 83f33841a8d0cca5fb46582f735a396a22977413 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 18:02:37 +0900 Subject: [PATCH 024/465] [Feat] AddTarget Pause Button Action --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index f63e72c..5fc60de 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -87,6 +87,7 @@ class RecordingViewController: UIViewController { self.configureConstraints() self.configureButton() self.configureBindings() + self.configureTarget() } private func configureBindings() { @@ -122,4 +123,12 @@ class RecordingViewController: UIViewController { }) .store(in: &subscriptions) } + + private func configureTarget() { + self.pauseButton.addTarget(self, action: #selector(pauseButtonAction), for: .touchUpInside) + } + + @objc func pauseButtonAction(_ sender: UIResponder) { + + } } From 425dedf4c3690b4387edb7bc7dc1da4b31404403 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 19:21:58 +0900 Subject: [PATCH 025/465] [Fix] Remove receiveCompletion --- .../RecordingScene/RecordingViewController.swift | 12 ++++-------- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 5fc60de..4d5e4c1 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -93,32 +93,28 @@ class RecordingViewController: UIViewController { private func configureBindings() { recordingViewModel.$currentTime .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] time in + .sink (receiveValue: { [weak self] time in self?.timeLabel.text = time }) .store(in: &subscriptions) recordingViewModel.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] kilometer in + .sink (receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer }) .store(in: &subscriptions) recordingViewModel.$altitude .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] altitude in + .sink (receiveValue: { [weak self] altitude in self?.altitudeLabel.text = altitude }) .store(in: &subscriptions) recordingViewModel.$walk .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] walk in + .sink (receiveValue: { [weak self] walk in self?.walkLabel.text = walk }) .store(in: &subscriptions) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 3ba0c2e..54659c7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -24,32 +24,28 @@ class RecordingViewModel: ObservableObject { private func configureBindings() { recording.$time .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] time in + .sink (receiveValue: { [weak self] time in self?.currentTime = time }) .store(in: &subscriptions) recording.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] kilometer in + .sink (receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) .store(in: &subscriptions) recording.$altitude .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] altitude in + .sink (receiveValue: { [weak self] altitude in self?.altitude = altitude }) .store(in: &subscriptions) recording.$walk .receive(on: DispatchQueue.main) - .sink (receiveCompletion: { print ("completion: \($0)") }, - receiveValue: { [weak self] walk in + .sink (receiveValue: { [weak self] walk in self?.walk = walk }) .store(in: &subscriptions) From 7f45d99f1f0aa147c64a567fb30b8958ee0e9e67 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 19:27:58 +0900 Subject: [PATCH 026/465] [Feat] AddTarget Stop Button Action --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 4d5e4c1..1aed1bc 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -122,9 +122,14 @@ class RecordingViewController: UIViewController { private func configureTarget() { self.pauseButton.addTarget(self, action: #selector(pauseButtonAction), for: .touchUpInside) + self.stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside) } - @objc func pauseButtonAction(_ sender: UIResponder) { + @objc private func pauseButtonAction(_ sender: UIResponder) { + + } + + @objc private func stopButtonAction(_ sender: UIResponder) { } } From a27bf24f52fee1f98e4509d90e8bc651715f27cf Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 19:35:19 +0900 Subject: [PATCH 027/465] =?UTF-8?q?[Feat]=20Stop=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=8B=9C=20Present=20StopAlert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingViewController.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 1aed1bc..e75d070 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -130,6 +130,15 @@ class RecordingViewController: UIViewController { } @objc private func stopButtonAction(_ sender: UIResponder) { - + let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) + let noneAction = UIAlertAction(title: "아니요", style: .default) { (action) in + g + } + let terminationAction = UIAlertAction(title: "종료", style: .default) { (action) in + + } + stopAlert.addAction(noneAction) + stopAlert.addAction(terminationAction) + present(stopAlert, animated: true, completion: nil) } } From 2b5177afb19ad8271bf214829ebb250dbaa35163 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 19:42:24 +0900 Subject: [PATCH 028/465] =?UTF-8?q?[Fix]=20RecordingViewController,=20Reco?= =?UTF-8?q?rdingViewModel=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20self=20?= =?UTF-8?q?=EB=B6=99=EC=9D=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController.swift | 24 +++++++++---------- .../RecordingScene/RecordingViewModel.swift | 19 ++++++++------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index e75d070..fca97b6 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -91,33 +91,33 @@ class RecordingViewController: UIViewController { } private func configureBindings() { - recordingViewModel.$currentTime + self.recordingViewModel.$currentTime .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.timeLabel.text = time }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recordingViewModel.$kilometer + self.recordingViewModel.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recordingViewModel.$altitude + self.recordingViewModel.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitudeLabel.text = altitude }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recordingViewModel.$walk + self.recordingViewModel.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walkLabel.text = walk }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) } private func configureTarget() { @@ -131,11 +131,9 @@ class RecordingViewController: UIViewController { @objc private func stopButtonAction(_ sender: UIResponder) { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) - let noneAction = UIAlertAction(title: "아니요", style: .default) { (action) in - g - } - let terminationAction = UIAlertAction(title: "종료", style: .default) { (action) in - + let noneAction = UIAlertAction(title: "아니요", style: .default) + let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in + self?.recordingViewModel.stopRecording() } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 54659c7..63828e7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -22,33 +22,36 @@ class RecordingViewModel: ObservableObject { } private func configureBindings() { - recording.$time + self.recording.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.currentTime = time }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recording.$kilometer + self.recording.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recording.$altitude + self.recording.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitude = altitude }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) - recording.$walk + self.recording.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walk = walk }) - .store(in: &subscriptions) + .store(in: &self.subscriptions) } + func stopRecording() { + self.recording.cancel() + } } From 23518aa0445b39046ae5594087e040a6541bc87c Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 19:51:07 +0900 Subject: [PATCH 029/465] =?UTF-8?q?[Feat]=20RecordingModel=EC=97=90=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=EB=90=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=B0=9B=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingModel.swift | 10 +++++++++- .../SanTa/RecordingScene/RecordingViewController.swift | 3 ++- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index c1ba006..85df0a2 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -9,8 +9,8 @@ import Foundation struct Record { let time: String - let step: Int - let distance: Double? + let step: String + let distance: String? let locations: [Location] } diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index c7ec800..a6d0950 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -85,9 +85,17 @@ class RecordingModel: NSObject, ObservableObject { timer?.resume() } - func cancel() { + func cancel() -> Record { + let timeString = time.split(separator: " ") + + let resultRecord = Record(time: String(timeString[0]), + step: walk, + distance: kilometer, + locations: location) timer?.cancel() timer = nil + + return resultRecord } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index fca97b6..19f2198 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -133,7 +133,8 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in - self?.recordingViewModel.stopRecording() + let resultRecord = self?.recordingViewModel.stopRecording() + print(resultRecord) } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 63828e7..3954df6 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -51,7 +51,7 @@ class RecordingViewModel: ObservableObject { .store(in: &self.subscriptions) } - func stopRecording() { - self.recording.cancel() + func stopRecording() -> Record { + return self.recording.cancel() } } From ab78e37c00ce771c7c37081bf8d2661d8c39b953 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 3 Nov 2021 13:58:02 +0900 Subject: [PATCH 030/465] =?UTF-8?q?[Feat]=20=EC=8B=9C=EC=9E=91=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=B8=A1=EC=A0=95=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 6 ++++++ SanTa/SanTa/MapScene/MapViewCoordinator.swift | 17 ++++++++++++++--- .../RecordingViewController.swift | 4 ++++ .../RecordingViewCoordinator.swift | 19 +++++++++++++------ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 319039d..9ee48f0 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -51,6 +51,8 @@ class MapViewController: UIViewController { ] NSLayoutConstraint.activate(startButtonConstraints) + self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchUpInside) + self.userTrackingButton = .init(mapView: mapView) self.view.addSubview(self.userTrackingButton) self.userTrackingButton.isHidden = true @@ -111,6 +113,10 @@ class MapViewController: UIViewController { self.mapView.addAnnotation(mountainAnnotaion) } } + + @objc private func presentRecordingViewController() { + coordinator?.presentRecordingViewController() + } } extension MapViewController: MKMapViewDelegate { diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index acb6006..f17f29f 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -9,15 +9,26 @@ import UIKit class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController = UINavigationController() var childCoordinator: [Coordinator] = [] - + func start() { } - func startPush() -> MapViewController { + func startPush() -> UINavigationController { let mapViewController = MapViewController() mapViewController.coordinator = self + self.navigationController.setViewControllers([mapViewController], animated: false) + + return navigationController + } +} - return mapViewController +extension MapViewCoordinator { + func presentRecordingViewController() { + let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + recordingViewCoordinator.parentCoordinator = self + self.childCoordinator.append(recordingViewCoordinator) + recordingViewCoordinator.start() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b8900f2..1fb8b8c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -90,4 +90,8 @@ class RecordingViewController: UIViewController { private func configure() { timer = RecordingViewModel() } + +// override func viewDidAppear(_ animated: Bool) { +// self.coordinator?.dismiss() +// } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 3b1fcb0..1044aac 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -10,16 +10,23 @@ import UIKit class RecordingViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController var childCoordinator: [Coordinator] = [] + var recordingViewController: RecordingViewController + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + self.recordingViewController = RecordingViewController() + self.recordingViewController.coordinator = self + } func start() { + recordingViewController.modalPresentationStyle = .fullScreen + self.navigationController.present(recordingViewController, animated: true) } - - func startPush() -> RecordingViewController { - let recordingViewController = RecordingViewController() - recordingViewController.coordinator = self - - return recordingViewController + + func dismiss() { + self.navigationController.dismiss(animated: true) } } From 5c0b3be83432eb593c3fcc82e1265730020fc072 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 3 Nov 2021 21:33:09 +0900 Subject: [PATCH 031/465] =?UTF-8?q?[Fix]=20Record=20Model=20Data=20Type=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/SceneDelegate.swift | 8 +++----- SanTa/SanTa/RecordingScene/Record.swift | 6 +++--- .../SanTa/RecordingScene/RecordingModel.swift | 20 ++++++++++++------- .../RecordingScene/RecordingViewModel.swift | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index da4d56c..18e4a5e 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -14,11 +14,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) -// self.appCoordinator = AppCoordinator(window) -// -// appCoordinator?.start() - self.window?.rootViewController = RecordingViewController() - self.window?.makeKeyAndVisible() + self.appCoordinator = AppCoordinator(window) + + appCoordinator?.start() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 85df0a2..4fe1662 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,9 +8,9 @@ import Foundation struct Record { - let time: String - let step: String - let distance: String? + let time: Int + let step: Int + let distance: Double let locations: [Location] } diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index a6d0950..2589bc2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -10,7 +10,7 @@ import CoreLocation import CoreMotion import Combine -class RecordingModel: NSObject, ObservableObject { +final class RecordingModel: NSObject, ObservableObject { @Published private(set) var time = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @@ -20,6 +20,8 @@ class RecordingModel: NSObject, ObservableObject { private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? private var date: Date? + private var currentWalk = 0 + private var currentKilo: Double = 0 private var location = [Location]() private var currentTime = 0 { @@ -69,8 +71,14 @@ class RecordingModel: NSObject, ObservableObject { self?.walk = "\(activityData.numberOfSteps)" + guard let walk = self?.walk, + let walkNumber = Int(walk) else { return } + + self?.currentWalk = walkNumber + guard let distance = activityData.distance else { return } let transformatKilometer = Double(truncating: distance) / 1000 + self?.currentKilo = transformatKilometer let distanceString = String(format: "%.2f", transformatKilometer) self?.kilometer = "\(distanceString)" @@ -86,12 +94,10 @@ class RecordingModel: NSObject, ObservableObject { } func cancel() -> Record { - let timeString = time.split(separator: " ") - - let resultRecord = Record(time: String(timeString[0]), - step: walk, - distance: kilometer, - locations: location) + let resultRecord = Record(time: self.currentTime, + step: self.currentWalk, + distance: self.currentKilo, + locations: self.location) timer?.cancel() timer = nil diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 3954df6..8c3f576 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -8,7 +8,7 @@ import Foundation import Combine -class RecordingViewModel: ObservableObject { +final class RecordingViewModel: ObservableObject { @Published private(set) var currentTime = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" From 94e92f48d0e6f6146d1757e93ddaadd14932999d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 3 Nov 2021 22:43:31 +0900 Subject: [PATCH 032/465] =?UTF-8?q?[Feat]=20CoreDataStorage=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/Persistences/CoreDataStorage.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 SanTa/SanTa/Persistences/CoreDataStorage.swift diff --git a/SanTa/SanTa/Persistences/CoreDataStorage.swift b/SanTa/SanTa/Persistences/CoreDataStorage.swift new file mode 100644 index 0000000..7eb519f --- /dev/null +++ b/SanTa/SanTa/Persistences/CoreDataStorage.swift @@ -0,0 +1,36 @@ +// +// CoreDataStorage.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// 참고: https://github.com/kudoleh/iOS-Clean-Architecture-MVVM/blob/master/ExampleMVVM/Data/PersistentStorages/CoreDataStorage/CoreDataStorage.swift + +import CoreData + +final class CoreDataStorage { + + private lazy var persistentContainer: NSPersistentContainer = { + let container = NSPersistentContainer(name: "SanTa") + container.loadPersistentStores { _, error in + if let error = error as NSError? { + assertionFailure("CoreDataStorage Unresolved error \(error), \(error.userInfo)") + } + } + return container + }() + + func saveContext() { + let context = self.persistentContainer.viewContext + if context.hasChanges { + do { + try context.save() + } catch { + assertionFailure("CoreDataStorage Unresolved error \(error), \((error as NSError).userInfo)") + } + } + } + + func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) { + self.persistentContainer.performBackgroundTask(block) + } +} From 94c46e0c38ee9424b72da23154de558f0646426e Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 3 Nov 2021 22:44:43 +0900 Subject: [PATCH 033/465] =?UTF-8?q?[Feat]=20CoreDataRecordStorage=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoreDataRecordStorage.swift | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift new file mode 100644 index 0000000..b5e1c76 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -0,0 +1,53 @@ +// +// CoreDataRecordsStorage.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// + +import Foundation +import CoreData + +protocol RecordsStorage { + func save(record: Record, + completion: @escaping (Result) -> Void) +} + +final class CoreDataRecordStorage: RecordsStorage { + + private let coreDataStorage: CoreDataStorage + + init(coreDataStorage: CoreDataStorage) { + self.coreDataStorage = coreDataStorage + } + + func save(record: Record, completion: @escaping (Result) -> Void) { + self.coreDataStorage.performBackgroundTask { context in + let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", + into: context) + recordObject.setValue(record.time, forKey: "time") + recordObject.setValue(record.distance, forKey: "distance") + recordObject.setValue(record.step, forKey: "step") + + record.locations.forEach { + let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", + into: context) as? LocationEntityMO + locationObject?.altitude = $0.altitude + locationObject?.latitude = $0.latitude + locationObject?.longitude = $0.longitude + + guard let locationObject = locationObject else { return } + (recordObject as? RecordEntityMO)?.addToLocations(locationObject) + } + + do { + try context.save() + completion(.success(record)) + } catch { + completion(.failure(error)) + } + } + } + + +} From 1590b581f7bac92cc772bc69cca8e010aed95117 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 3 Nov 2021 22:45:50 +0900 Subject: [PATCH 034/465] =?UTF-8?q?[Feat]=20RecordRepository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordRepository.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SanTa/SanTa/RecordingScene/RecordRepository.swift diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift new file mode 100644 index 0000000..f6024a4 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -0,0 +1,26 @@ +// +// DefaultRecordsRepository.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// + +import Foundation + +protocol RecordRepository { + func save(record: Record, + completion: @escaping (Result) -> Void) +} + +final class DefaultRecordRepository: RecordRepository { + + private let recordStorage: CoreDataRecordStorage + + init(recordStorage: CoreDataRecordStorage) { + self.recordStorage = recordStorage + } + + func save(record: Record, completion: @escaping (Result) -> Void) { + self.recordStorage.save(record: record, completion: completion) + } +} From 8f64ccb154762f9e9977d5ec97bb6c1a2841276e Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 3 Nov 2021 22:47:01 +0900 Subject: [PATCH 035/465] =?UTF-8?q?[Feat]=20CoreData=20Entity=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98=20=EB=B0=8F=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa.xcdatamodel/contents | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 73ca9d6..a6cf650 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,4 +1,19 @@ - - + + + + + + + + + + + + + + + + + \ No newline at end of file From 7c923b70c0c871a01a6bc5f0bd191cc951de8b95 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 3 Nov 2021 22:48:09 +0900 Subject: [PATCH 036/465] =?UTF-8?q?RecordingUseCase=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=A0=80=EC=9E=A5=20=EC=9A=94=EC=B2=AD=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 28 +++++++++++++++---- SanTa/SanTa/RecordingScene/Record.swift | 22 +++++++++++++++ .../RecordingScene/RecordingUseCase.swift | 26 +++++++++++++++++ 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 SanTa/SanTa/RecordingScene/Record.swift create mode 100644 SanTa/SanTa/RecordingScene/RecordingUseCase.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 900765e..387d38a 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -29,14 +29,17 @@ 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; + 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; + 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; + 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */; }; + 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */; }; 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; - DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - 985EEF65273010BD002413D9 /* SettingsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* SettingsCell.swift */; }; 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; + DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; - /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -64,14 +67,17 @@ 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + 984DDEC027325D67003BE56B /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; + 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCase.swift; sourceTree = ""; }; + 984DDEC427325FB9003BE56B /* RecordRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordRepository.swift; sourceTree = ""; }; + 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataRecordStorage.swift; sourceTree = ""; }; + 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CoreDataStorage.swift; path = SanTa/Persistences/CoreDataStorage.swift; sourceTree = SOURCE_ROOT; }; 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; - DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - 985EEF64273010BD002413D9 /* SettingsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = ""; }; 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; - /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -92,6 +98,10 @@ DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, + 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */, + 984DDEC427325FB9003BE56B /* RecordRepository.swift */, + 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */, + 984DDEC027325D67003BE56B /* Record.swift */, ); path = RecordingScene; sourceTree = ""; @@ -151,6 +161,7 @@ 54296943272FB8410070B362 /* Persistences */ = { isa = PBXGroup; children = ( + 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */, ); path = Persistences; sourceTree = ""; @@ -299,7 +310,9 @@ 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */, + 984DDEC127325D67003BE56B /* Record.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, + 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, @@ -311,6 +324,9 @@ 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, + 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, + 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, + 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift new file mode 100644 index 0000000..487f807 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -0,0 +1,22 @@ +// +// Recording.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// + +import Foundation + +struct Record { + let time: Int + let step: Int + let distance: Double + + let locations: [Location] +} + +struct Location { + let latitude: Double + let longitude: Double + let altitude: Double +} diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift new file mode 100644 index 0000000..22a4e11 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -0,0 +1,26 @@ +// +// DefaultSaveRecordUseCase.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// + +import Foundation + +protocol RecordingUseCase { + func save(record: Record, + completion: @escaping (Result) -> Void) +} + +final class DefaultRecordingUseCase: RecordingUseCase { + + private let recordRepository: RecordRepository + + init(recordRepository: RecordRepository) { + self.recordRepository = recordRepository + } + + func save(record: Record, completion: @escaping (Result) -> Void) { + self.recordRepository.save(record: record, completion: completion) + } +} From fb1ec9d3dd9cce796a7ac90f9cf6bd2e65373c92 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 4 Nov 2021 10:29:33 +0900 Subject: [PATCH 037/465] =?UTF-8?q?[Fix]=20Merge=20=EC=9D=B4=ED=9B=84=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EB=B6=88=EA=B0=80=ED=95=9C=20Xcode?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- .../Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index a702027..4bb75dd 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -15,7 +15,7 @@ class MapViewCoordinator: Coordinator { func start() { } - func startPush() -> MapViewController { + func startPush() -> UINavigationController { let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self self.navigationController.setViewControllers([mapViewController], animated: false) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index a6cf650..3be75cc 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -13,7 +13,7 @@ - + \ No newline at end of file From 74c2bab8d6179693ed78f8a4837c692d4e737e21 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:08:07 +0900 Subject: [PATCH 038/465] =?UTF-8?q?[Docs]=20=EB=A6=AC=ED=8E=99=ED=86=A0?= =?UTF-8?q?=EB=A7=81=20=EC=9D=B4=EC=8A=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refactor-request-template.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/refactor-request-template.md diff --git a/.github/ISSUE_TEMPLATE/refactor-request-template.md b/.github/ISSUE_TEMPLATE/refactor-request-template.md new file mode 100644 index 0000000..4f2c772 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/refactor-request-template.md @@ -0,0 +1,23 @@ +--- +name: Refactor Request Template +about: Refactor 작업 필요시 사용하는 기본 템플릿 +title: '' +labels: Refactor +assignees: '' + +--- + +## 구조 설명 +> 팀원이 이해할 수 있도록 자세하게 구체적으로 작성합니다. 담당자도 함께 할당해주세요. + +- 현재 구조 + 1. MVC 입니다 + +- 개선될 구조 + 2. MVVM 입니다 + +## 기대하는 결과 +> 구체적으로 어떤 결과가 나오게 수정해야 하는지 작성합니다. + +## 참고자료 +> 보여지는 뷰의 경우 스크린샷도 함께 첨부합니다. From 0dec495637efb3ea7cb55326c30c448812545f09 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 4 Nov 2021 11:24:06 +0900 Subject: [PATCH 039/465] =?UTF-8?q?[Fix]=20Core=20Data=20Entity=20Inverse?= =?UTF-8?q?=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 1 + .../SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 210a1b2..2427922 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -6,6 +6,7 @@ // import UIKit +import MapKit protocol Coordinator: AnyObject { var childCoordinator: [Coordinator] { get set } diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 3be75cc..51d819d 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,19 +1,19 @@ - + - + - + - - + + \ No newline at end of file From 5a6900f53e032c03c7b78fb42b131600110befd4 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 4 Nov 2021 11:34:04 +0900 Subject: [PATCH 040/465] =?UTF-8?q?[Refactor]=20MapViewController=20?= =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MapView를 재할당 하는 구문, if let 구문 수정 --- SanTa/SanTa/MapScene/MapViewController.swift | 33 +++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index c66b701..1ddf579 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -8,7 +8,7 @@ import MapKit class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? - private var mapView = MKMapView() + private var mapView: MKMapView? private var startButton = UIButton() private var manager = CLLocationManager() private var userTrackingButton = MKUserTrackingButton() @@ -40,19 +40,20 @@ class MapViewController: UIViewController { latitude: mountainEntity.latitude, longitude: mountainEntity.longitude ) - self.mapView.addAnnotation(mountainAnnotation) + mapView?.addAnnotation(mountainAnnotation) } } private func configureViews() { self.mapView = MKMapView(frame: view.bounds) - self.mapView.showsUserLocation = true - self.mapView.delegate = self - self.view.addSubview(self.mapView) - self.mapView.showsUserLocation = true - self.mapView.showsScale = true - self.mapView.showsCompass = true - self.mapView.delegate = self + guard let mapView = mapView else { return } + mapView.showsUserLocation = true + mapView.delegate = self + self.view.addSubview(mapView) + mapView.showsUserLocation = true + mapView.showsScale = true + mapView.showsCompass = true + mapView.delegate = self self.view.addSubview(self.startButton) self.startButton.backgroundColor = .blue @@ -69,7 +70,7 @@ class MapViewController: UIViewController { let startButtonConstraints = [ self.startButton.widthAnchor.constraint(equalToConstant: 100), self.startButton.heightAnchor.constraint(equalToConstant: 100), - self.startButton.bottomAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: -150), + self.startButton.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -150), self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) ] NSLayoutConstraint.activate(startButtonConstraints) @@ -87,7 +88,7 @@ class MapViewController: UIViewController { self.userTrackingButton.widthAnchor.constraint(equalToConstant: 50), self.userTrackingButton.heightAnchor.constraint(equalToConstant: 50), self.userTrackingButton.leftAnchor.constraint( - equalTo: self.mapView.rightAnchor, + equalTo: mapView.rightAnchor, constant: -100 ), self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) @@ -96,11 +97,12 @@ class MapViewController: UIViewController { } private func registerAnnotationView() { - self.mapView.register( + guard let mapView = mapView else { return } + mapView.register( MountainAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier ) - self.mapView.register( + mapView.register( ClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier ) @@ -115,6 +117,7 @@ class MapViewController: UIViewController { } private func render(_ location: CLLocation) { + guard let mapView = mapView else { return } let coordinate = CLLocationCoordinate2D( latitude: location.coordinate.latitude, longitude: location.coordinate.longitude @@ -124,7 +127,7 @@ class MapViewController: UIViewController { longitudeDelta: 0.01 ) let region = MKCoordinateRegion(center: coordinate, span: span) - self.mapView.setRegion(region, animated: true) + mapView.setRegion(region, animated: true) } @objc private func presentRecordingViewController() { @@ -134,7 +137,7 @@ class MapViewController: UIViewController { extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - if let _ = annotation as? MountainAnnotation { + if annotation is MountainAnnotation { return MountainAnnotationView( annotation: annotation, reuseIdentifier: MountainAnnotationView.ReuseID From 9827d0618a7f6c9651901399244dc60e9003ea8c Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 4 Nov 2021 11:44:36 +0900 Subject: [PATCH 041/465] =?UTF-8?q?[Feat]=20=EB=A7=88=EC=BB=A4=20=ED=84=B0?= =?UTF-8?q?=EC=B9=98=EC=8B=9C=20=EB=A7=90=ED=92=8D=EC=84=A0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20mapView()=20=EB=8D=B8=EB=A6=AC=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20MountainAnnotationView=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 12 ++++++------ SanTa/SanTa/MapScene/MountainAnnotationView.swift | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index c66b701..835f435 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -134,13 +134,13 @@ class MapViewController: UIViewController { extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - if let _ = annotation as? MountainAnnotation { - return MountainAnnotationView( - annotation: annotation, - reuseIdentifier: MountainAnnotationView.ReuseID - ) + guard let annotation = annotation as? MountainAnnotation else { return nil } + + guard let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: MountainAnnotationView.ReuseID) as? MountainAnnotationView else { + return MountainAnnotationView(annotation: annotation, reuseIdentifier: MountainAnnotationView.ReuseID) } - return nil + dequeuedView.annotation = annotation + return dequeuedView } } diff --git a/SanTa/SanTa/MapScene/MountainAnnotationView.swift b/SanTa/SanTa/MapScene/MountainAnnotationView.swift index 84b8a56..90e16ce 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotationView.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotationView.swift @@ -13,7 +13,10 @@ class MountainAnnotationView: MKMarkerAnnotationView { override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) - clusteringIdentifier = "mountain" + self.clusteringIdentifier = "mountain" + self.canShowCallout = true + self.calloutOffset = CGPoint(x: 0, y: 5) + self.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) } required init?(coder aDecoder: NSCoder) { From 21f1a42d82ca4e3f6b387aea346e9acb5a04e668 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 4 Nov 2021 12:01:16 +0900 Subject: [PATCH 042/465] =?UTF-8?q?[Refactor]=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 ----- .../SanTa/Application/TabBarController.swift | 34 ------------------- 2 files changed, 42 deletions(-) delete mode 100644 SanTa/SanTa/Application/TabBarController.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 4aaa6fc..12aefee 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -31,7 +31,6 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; - 54851299272A6D0900407F28 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851298272A6D0900407F28 /* TabBarController.swift */; }; 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; @@ -44,7 +43,6 @@ DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; - /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -74,7 +72,6 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 54851298272A6D0900407F28 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 984DDEC027325D67003BE56B /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCase.swift; sourceTree = ""; }; 984DDEC427325FB9003BE56B /* RecordRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordRepository.swift; sourceTree = ""; }; @@ -87,7 +84,6 @@ DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; - /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -113,7 +109,6 @@ 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */, 984DDEC027325D67003BE56B /* Record.swift */, DAB37D4F273256B900EC523F /* RecordingModel.swift */, - ); path = RecordingScene; sourceTree = ""; @@ -200,7 +195,6 @@ children = ( 54851281272A6AD500407F28 /* AppDelegate.swift */, 54851283272A6AD500407F28 /* SceneDelegate.swift */, - 54851298272A6D0900407F28 /* TabBarController.swift */, 54296944272FBC6E0070B362 /* AppCoordinator.swift */, ); path = Application; @@ -334,11 +328,9 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, - DAB37D4E2732557100EC523F /* Record.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, - 54851299272A6D0900407F28 /* TabBarController.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, diff --git a/SanTa/SanTa/Application/TabBarController.swift b/SanTa/SanTa/Application/TabBarController.swift deleted file mode 100644 index b0facf2..0000000 --- a/SanTa/SanTa/Application/TabBarController.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// TabBarController.swift -// SanTa -// -// Created by shin jae ung on 2021/10/28. -// -// 삭제 대상 - - -import UIKit - -class TabBarController: UITabBarController { - - override func viewDidLoad() { - super.viewDidLoad() - tabBar.tintColor = .blue - tabBar.unselectedItemTintColor = .label - tabBar.backgroundColor = .systemBackground - setUpTabBar() - } - - private func setUpTabBar() { - let homeViewController = UINavigationController(rootViewController: MapViewController()) - homeViewController.tabBarItem.image = .init(systemName: "play.fill") - homeViewController.title = "시작" - - let homeViewController2 = UINavigationController(rootViewController: MapViewController()) - homeViewController2.tabBarItem.image = .init(systemName: "play.fill") - homeViewController2.title = "시작" - - viewControllers = [homeViewController, homeViewController2] - } - -} From 50d5634b615f7959c25e0dcd216d25d615de770a Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 13:03:40 +0900 Subject: [PATCH 043/465] [Feat] Dismiss RecordingViewController --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 28a8a22..a54e7ec 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -135,13 +135,10 @@ class RecordingViewController: UIViewController { let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in let resultRecord = self?.recordingViewModel.stopRecording() print(resultRecord) + self.coordinator?.dismiss() } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) present(stopAlert, animated: true, completion: nil) } - -// override func viewDidAppear(_ animated: Bool) { -// self.coordinator?.dismiss() -// } } From b353024bc10179d426417f9c694976b78b90378c Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 4 Nov 2021 14:15:30 +0900 Subject: [PATCH 044/465] =?UTF-8?q?[Fix]=20=EC=A2=85=EC=9D=B4=20=EB=B9=84?= =?UTF-8?q?=ED=96=89=EA=B8=B0=20=EB=B2=84=ED=8A=BC=EC=9D=B4=20=EB=82=98?= =?UTF-8?q?=ED=83=80=EB=82=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index c66b701..ec4355d 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -27,6 +27,15 @@ class MapViewController: UIViewController { self.configureViewModel() } + override func viewWillAppear(_ animated: Bool) { + if manager.authorizationStatus == .authorizedAlways || + manager.authorizationStatus == .authorizedWhenInUse { + userTrackingButton.isHidden = false + } else { + userTrackingButton.isHidden = true + } + } + private func configureViewModel() { self.viewModel?.markersShouldUpdate = { self.configureMarkers() } self.viewModel?.viewDidLoad() From b51a7c95bd61395978ea28dd9673ad063fa06314 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 14:26:21 +0900 Subject: [PATCH 045/465] =?UTF-8?q?[Feat]=20Recording=20Model=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingUseCase.swift | 28 ++++++++++++++----- .../RecordingViewController.swift | 7 ++--- .../RecordingScene/RecordingViewModel.swift | 17 +++++------ 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 22a4e11..eba78c3 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -6,21 +6,35 @@ // import Foundation +import Combine protocol RecordingUseCase { - func save(record: Record, - completion: @escaping (Result) -> Void) + var currentTime: String { get set } + var kilometer: String { get set } + var altitude: String { get set } + var walk: String { get set } + var recording: RecordingModel { get set } + + func save(completion: @escaping (Result) -> Void) } -final class DefaultRecordingUseCase: RecordingUseCase { +final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { + @Published var currentTime = "" + @Published var kilometer = "" + @Published var altitude = "" + @Published var walk = "" + + var recording: RecordingModel - private let recordRepository: RecordRepository + private let recgordRepository: RecordRepository + private var subscriptions = Set() - init(recordRepository: RecordRepository) { + init(recordRepository: RecordRepository, recordingModel: RecordingModel) { self.recordRepository = recordRepository + self.recording = recordingModel } - func save(record: Record, completion: @escaping (Result) -> Void) { - self.recordRepository.save(record: record, completion: completion) + func save(completion: @escaping (Result) -> Void) { + self.recordRepository.save(record: recording.cancel(), completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index a54e7ec..9485b01 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -76,7 +76,7 @@ class RecordingViewController: UIViewController { let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() - private var recordingViewModel = RecordingViewModel() + private var recordingViewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) private var subscriptions = Set() override func viewDidLoad() { @@ -133,9 +133,8 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in - let resultRecord = self?.recordingViewModel.stopRecording() - print(resultRecord) - self.coordinator?.dismiss() + self?.recordingViewModel.save() + self?.coordinator?.dismiss() } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 8c3f576..c630694 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -14,36 +14,37 @@ final class RecordingViewModel: ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" - private var recording = RecordingModel() + private let recordingUseCase: RecordingUseCase private var subscriptions = Set() - init() { + init(recordingUseCase: RecordingUseCase) { + self.recordingUseCase = recordingUseCase configureBindings() } private func configureBindings() { - self.recording.$time + self.recordingUseCase.recording.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.currentTime = time }) .store(in: &self.subscriptions) - self.recording.$kilometer + self.recordingUseCase.recording.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) .store(in: &self.subscriptions) - self.recording.$altitude + self.recordingUseCase.recording.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitude = altitude }) .store(in: &self.subscriptions) - self.recording.$walk + self.recordingUseCase.recording.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walk = walk @@ -51,7 +52,7 @@ final class RecordingViewModel: ObservableObject { .store(in: &self.subscriptions) } - func stopRecording() -> Record { - return self.recording.cancel() + func save() { + self.recordingUseCase.save(completion: { _ in }) } } From f371aaf0fcab1ee75bb0380367a23f8684d26c7b Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 14:33:07 +0900 Subject: [PATCH 046/465] =?UTF-8?q?[Feat]=20RecordingViewController=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingUseCase.swift | 2 +- .../RecordingViewController.swift | 17 +++++++++++------ .../RecordingViewCoordinator.swift | 3 ++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index eba78c3..95e8231 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -26,7 +26,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { var recording: RecordingModel - private let recgordRepository: RecordRepository + private let recordRepository: RecordRepository private var subscriptions = Set() init(recordRepository: RecordRepository, recordingModel: RecordingModel) { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 9485b01..1d79258 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -76,9 +76,14 @@ class RecordingViewController: UIViewController { let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() - private var recordingViewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) + private var recordingViewModel: RecordingViewModel? private var subscriptions = Set() + convenience init(viewModel: RecordingViewModel) { + self.init() + self.recordingViewModel = viewModel + } + override func viewDidLoad() { super.viewDidLoad() @@ -91,28 +96,28 @@ class RecordingViewController: UIViewController { } private func configureBindings() { - self.recordingViewModel.$currentTime + self.recordingViewModel?.$currentTime .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.timeLabel.text = time }) .store(in: &self.subscriptions) - self.recordingViewModel.$kilometer + self.recordingViewModel?.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer }) .store(in: &self.subscriptions) - self.recordingViewModel.$altitude + self.recordingViewModel?.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitudeLabel.text = altitude }) .store(in: &self.subscriptions) - self.recordingViewModel.$walk + self.recordingViewModel?.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walkLabel.text = walk @@ -133,7 +138,7 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in - self?.recordingViewModel.save() + self?.recordingViewModel?.save() self?.coordinator?.dismiss() } stopAlert.addAction(noneAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 1044aac..533de95 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -16,7 +16,8 @@ class RecordingViewCoordinator: Coordinator { init(navigationController: UINavigationController) { self.navigationController = navigationController - self.recordingViewController = RecordingViewController() + let viewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) + self.recordingViewController = RecordingViewController(viewModel: viewModel) self.recordingViewController.coordinator = self } From c99f32cc3155449e8afa3988627df795e672c03e Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 14:34:25 +0900 Subject: [PATCH 047/465] =?UTF-8?q?[Fix]=20RecordingViewModel=20UseCase=20?= =?UTF-8?q?=EC=98=B5=EC=85=94=EB=84=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index c630694..b1e0243 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -14,7 +14,7 @@ final class RecordingViewModel: ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" - private let recordingUseCase: RecordingUseCase + private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() init(recordingUseCase: RecordingUseCase) { @@ -23,28 +23,28 @@ final class RecordingViewModel: ObservableObject { } private func configureBindings() { - self.recordingUseCase.recording.$time + self.recordingUseCase?.recording.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.currentTime = time }) .store(in: &self.subscriptions) - self.recordingUseCase.recording.$kilometer + self.recordingUseCase?.recording.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) .store(in: &self.subscriptions) - self.recordingUseCase.recording.$altitude + self.recordingUseCase?.recording.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitude = altitude }) .store(in: &self.subscriptions) - self.recordingUseCase.recording.$walk + self.recordingUseCase?.recording.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walk = walk @@ -53,6 +53,6 @@ final class RecordingViewModel: ObservableObject { } func save() { - self.recordingUseCase.save(completion: { _ in }) + self.recordingUseCase?.save(completion: { _ in }) } } From d8518af397a00500434a7744fd3959a3b2710153 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 14:48:04 +0900 Subject: [PATCH 048/465] =?UTF-8?q?[Feat]=20Stop=20Completion=20Handler=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 8 ++++++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 1d79258..3206a61 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -138,8 +138,12 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in - self?.recordingViewModel?.save() - self?.coordinator?.dismiss() + self?.recordingViewModel?.save() { [weak self] completion in + print(completion) + DispatchQueue.main.async { + self?.coordinator?.dismiss() + } + } } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index b1e0243..d36f51c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -52,7 +52,7 @@ final class RecordingViewModel: ObservableObject { .store(in: &self.subscriptions) } - func save() { - self.recordingUseCase?.save(completion: { _ in }) + func save(completion: @escaping (Result) -> Void) { + self.recordingUseCase?.save(completion: completion) } } From 639897d75cfc7cd6b08ff65b808a17233c4f6503 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 14:51:28 +0900 Subject: [PATCH 049/465] =?UTF-8?q?[Feat]=20LocationButtonAction=20Target?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 3206a61..b0b6ca2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -128,6 +128,7 @@ class RecordingViewController: UIViewController { private func configureTarget() { self.pauseButton.addTarget(self, action: #selector(pauseButtonAction), for: .touchUpInside) self.stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside) + self.locationButton.addTarget(self, action: #selector(locationButtonAction), for: .touchUpInside) } @objc private func pauseButtonAction(_ sender: UIResponder) { @@ -139,14 +140,17 @@ class RecordingViewController: UIViewController { let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in self?.recordingViewModel?.save() { [weak self] completion in - print(completion) DispatchQueue.main.async { self?.coordinator?.dismiss() - } + } } } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) present(stopAlert, animated: true, completion: nil) } + + @objc private func locationButtonAction(_ sender: UIResponder) { + + } } From 0b153b9c26a8bbebabb577af11af2fd41e833e33 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 15:03:23 +0900 Subject: [PATCH 050/465] =?UTF-8?q?[Fix]=20MapViewCoordinator=20recordingV?= =?UTF-8?q?iewCoordinator=20=EC=A4=91=EB=B3=B5=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 9 +++++++-- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 4bb75dd..54bb8c7 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -11,6 +11,12 @@ class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController = UINavigationController() var childCoordinator: [Coordinator] = [] + var recordingViewCoordinator: RecordingViewCoordinator? + + init() { + self.recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + self.recordingViewCoordinator?.parentCoordinator = self + } func start() { } @@ -26,8 +32,7 @@ class MapViewCoordinator: Coordinator { extension MapViewCoordinator { func presentRecordingViewController() { - let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) - recordingViewCoordinator.parentCoordinator = self + guard let recordingViewCoordinator = self.recordingViewCoordinator else { return } self.childCoordinator.append(recordingViewCoordinator) recordingViewCoordinator.start() } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b0b6ca2..492b71b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -151,6 +151,6 @@ class RecordingViewController: UIViewController { } @objc private func locationButtonAction(_ sender: UIResponder) { - + self.coordinator?.dismiss() } } From 76034a0d11f85760575e1b7b0605a8df656579db Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 4 Nov 2021 15:07:42 +0900 Subject: [PATCH 051/465] =?UTF-8?q?[Refactor]=20JSON=20=EC=A0=95=ED=99=95?= =?UTF-8?q?=EB=8F=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contents.json | 2 +- ...ation.json => MountainsWithLocation2.json} | 6456 +++++------------ 2 files changed, 1844 insertions(+), 4614 deletions(-) rename SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/{MountainsWithLocation.json => MountainsWithLocation2.json} (65%) diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json index d107816..5f17223 100644 --- a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json @@ -1,7 +1,7 @@ { "data" : [ { - "filename" : "MountainsWithLocation.json", + "filename" : "MountainsWithLocation2.json", "idiom" : "universal" } ], diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json similarity index 65% rename from SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json rename to SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json index 42eace2..db51b43 100644 --- a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation.json +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json @@ -11,23 +11,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제주도 다음으로 큰 섬인 거제도에는 해발 500m가 넘는 산이 7개가 있다. 그 중에서도 가라산은 도토리 키재기에서 1등을 차지해 `거제도 제1봉'이란 이름을 얻고 있는 산이다. 그래서인지 높이는 얼마 안되지만, 산행하기가 쉽지 않다.경상남도 남단 거제시의 최고봉으로 주봉은 가래봉이다. 산길에 서면 해안선이 가장 긴 한국 제2의 섬 거제도와 주변의 여러 섬은 물론 북쪽으로 진해시·마산시ㆍ고성군, 서쪽으로 통영시를 마주하고, 남·동쪽으로 남해를 굽어볼 수 있다. 부산 영도가 지척이고 갠 날은 쓰시마섬[對馬島]이 가물거릴 만큼 조망이 뛰어나다.가라산 곁에 계룡산(鷄龍山:566m)·노자산(老子山: 565m)·앵산(鶯山:507m)·산방산(山芳山:507m)·선자산(扇子山:507m)·옥녀봉(玉女 峰:555m) 등 500m대 비탈산이 많아 농지가 적지만 바다로 둘려 수산물이 풍부하다. 계룡산∼가라산 종주(약 25㎞)보다 노자산∼가라산 쪽이 인기다. 두 산은 1cm 사이라는 거제 유머가 있다.봄이면 고로쇠 약수 채취로 붐비고 해양성기후에 잘 자라는 아열대식물인 동백나무·팔손이나무·소철·종려나무 등 600여 종이 우거졌다. 노자산의 천연기념물인 학동의 동백림(233)은 세계적인 팔색조(八色鳥:204) 번식지이며, 서불의 불로초 신화에 얽힌 신선산의 산삼 또한 손꼽는다. 거제 해금강이 보 이는 학동고개에서 오르면 벼늘[露積]바위ㆍ선녀바위가 있는 주능선 삼거리에 닿고, 다도해의 수묵화가 펼쳐진다.거제 10대 명산의 수봉(首峰)까지는 젖봉바위·매바위 등에서 암벽등반도 즐기며 들맞이재와 안부를 지나면 잡목 울창한 정상 못미처 봉화대와 기우단이 있고 견암봉(見岩峰) 밑에 신라시대의 견암사지가 있다. 하산은 다대산성(多大山城)을 거치는 다대포구 쪽과 산정 밑 전망대바위-속가심바구 또는 원추리바위-에서 해금강 배타는 데로 가는 두 길이 있다.육로는 통영과 마산·진주·부산 등이 국도로 연결된 1일권으로 편리하다. 뱃길은 정기 여객선과 쾌속선이 옥포·고현·성포항에서 부산·통영·진해로 가며, 부산까지 40분으로 육상보다 낫다. 항공편은 수시로 헬리콥터가 김해와 연결된다. 근처의 명사·여차(몽돌)·덕원·함목·학동(몽돌)해수욕장 등도 가볼 만하다.", - "MNTN_HG_VL" : "580", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 남부면 다대리", - "MNTN_NM" : "가라산" + "DETAIL_INFO_DTCONT" : "백악산(百岳山,858m)에서 북쪽으로 뻗어 내린 능선이 배골재를 지나 740m봉을 일으키고 북쪽은 산자락에 흐르는 화양계곡에 막혀 좌우로 부챗살처럼 능선을 늘어뜨리며, 오른쪽 동북쪽으로 가지를 친 능선에 솟아 있는 산이 가령 산이다.왼쪽 서북쪽으로 이어진 능선에는 낙영산(681m)과 화양계곡으로 유명한 도명산(道明山,642m)이 서북쪽으로 갈미봉(560m)을 빚어 놓고 화양계곡입구인 화양리에서 꼬리를 내린다.북쪽 산 아래로 흐르는 화양계곡에는 경관이 뛰어난 화양구곡이 줄지어 있다. 제1곡은 경천벽, 운영담(제2곡), 읍궁암(제3곡), 금사담(제4곡), 첨성대(제5곡), 능운대(제6곡), 와룡담(제7곡), 학소대(제8곡), 파천(제9곡)이 저마다 자태를 뽐내고 있다.가령산은 등산로 곳곳에 시루바위, 거북바위 등 암봉이 널려있어 아기자기한 산행 재미를 느낄 수 있는 산이다.", + "MNTN_HG_VL" : "642", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군", + "MNTN_NM" : "가령산" }, - "longitude" : 128.62708369999999, - "latitude" : 34.753540999999998 + "longitude" : 127.84999999999999, + "latitude" : 36.649999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 춘천시와 홍천군의 경계를 이루는 산으로, 산 정상에 서면 탁 트인 시야와 발 아래로 펼쳐진 소양호의 풍경이 등산객들의 발걸음을 멈추게 하는 곳이다. 산자락을 감싸 흐르는 조그마한 폭포의 물소리가 사람들의 마음을 시원하게 해주는 가리산은 우거진 숲과 노송들이 어루러져 비경을 이루고 있다.소양호 쪽으로 하산하여 물노리 선착장에서 유람선을 타고 소양댐 선착장까지 나올 수 있어, 산행도 하고 배를 타는 재미가 있다.산이름인 가리는 '단으로 묶은 곡식이나 땔나무 따위를 차곡차곡 쌓아둔 큰 더미'를 뜻하는 순우리말로서, 산봉우리가 노적가리처럼 고깔 모양으로 생긴 데서 유래한다. 태백산맥 중 내지(內地) 산맥의 일부를 이룬다. 제1봉 남쪽에서 홍천강이 발원하여 북한강의 지류인 소양강의 수원(水源)을 이룬다.능선은 완만한 편이나, 정상 일대는 좁은 협곡을 사이에 둔 3개의 암봉으로 이루어져 있으며 강원 제1의 전망대라고 할 만큼 조망이 뛰어나, 소양호를 비롯하여 북쪽으로 향로봉에서 설악산을 거쳐 오대산으로 힘차게 뻗어나간 백두대간 등 강원 내륙의 고산준령이 한눈에 보인다. 정상 부근에서는 소양호로 갈 수 있는 가삽고개가 있는데, 그 형태가 계단식 분지형으로 이루어져 있다.북쪽 산록은 소양호에 미치고 동쪽 산록에 홍천광산이 있다. 산기슭에는 숲이 우거져 있고 갖가지 기암괴석이 즐비하며, 산 정상과 계곡에는 향토 수종인 참나무가 주종을 이루며 자라고 있다. 아래쪽에는 두릅나무·철쭉·싸리나무·산초나무 등 관목류와 약용으로 사용되는 피나물·애기똥풀·양지꽃 등 야생화가 서식하고 있다. 강원도에서 진달래가 가장 많이 피는 산으로도 유명하다.1998년 가리산 자연휴영림으로 개장되어 통나무집·야영장·체육시설 등 편의시설이 있다. 휴양림 입구에는 높이 8m의 용소폭포가 있고, 주변에 스키장·온천·수타사·팔봉산 등의 관광지가 있다.", - "MNTN_HG_VL" : "1051", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면ㆍ동면, 홍천군 두촌면ㆍ화촌면", - "MNTN_NM" : "가리산" + "DETAIL_INFO_DTCONT" : "가리봉은 설악산국립공원에 속하는 산으로 설악산 귀때기청봉(1,580m)과 대승령을 잇는 설악산 서북 주능선과 마주보고 있어 독립된 산처럼 보인다. 멀리서 보면 봉우리가 둥글둥글 완만해 보이지만 험준한 암봉들이 많은 산이다.산행 들머리는 옥녀탕앞이나 한계령에서 시작하는데 오르다 보면 산의 남서쪽에 이 산의 명물 팔례 약수가 있다.가리봉 주능선은 등산인들의 왕래가 거의 없는 관계로 등산로가 뚜렷하지 않으므로 산행시 주의해야 하는 곳이다.", + "MNTN_HG_VL" : "1519", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", + "MNTN_NM" : "가리봉" }, - "longitude" : 127.9609203, - "latitude" : 37.873404200000003 + "longitude" : 128.34222220000001, + "latitude" : 38.093611099999997 }, { "mountain" : { @@ -36,24 +36,14 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면 장암리", "MNTN_NM" : "가리산" }, - "longitude" : 127.9609203, - "latitude" : 37.873404200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "가리왕산은 태백산의 지붕역활을 하고 있으며 경사도가 완만한 등산로로 유명하다. 산 능선에는 고산식물인 주목, 잣나무, 단풍나무등 각종 수목이 울창하며 산삼등 많은 산약초가 자라고 있다.회동리 입구에는 자연휴양림이 조성되어 각종 편의시설이 설치되어 있고 등산로 산행시간은 총 6시간 정도 소요된다. 군립공원으로 지정, 개발계획에 있으며 숙암방면 입구는 약 4km 구간에 철쭉이 밀집 자생하고 있다.", - "MNTN_HG_VL" : "1562", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 회동리ㆍ북평면, 평창군 진부면", - "MNTN_NM" : "가리왕산" - }, - "longitude" : 128.56326319999999, - "latitude" : 37.462132500000003 + "longitude" : 127.403469, + "latitude" : 38.037748999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "공주시 반포면 상신리는 계룡산 자락이 감싸고 있는 마을로, 뒷산을 ‘솥봉’ 또는 ‘가마봉’이라 부르는데 지명에 얽힌 슬픈 전설이 전해진다. 아주 오랜 옛날 산 아랫마을에 석공 부부와 두 딸이 단란하게 살고 있었다. 어느 날 석공이 독이 있는 음식을 잘못 먹고 급사하게 되자, 그의 아내와 두 딸은 산속에서 나물을 캐고 나무를 해서 먹고 살아야 했다. 그러던 어느 날 석공의 아내가 산나물을 뜯고 있다가 마침 사냥을 나온 인근 고을의 원님과 마주치게 되었다.원님은 한눈에 이 여인에게 반하여 억지로 끌고 가서 자신의 시중을 들라고 명령하였다. 석공의 아내는 완강하게 거부하였고, 원님은 만약 끝까지 싫다고 한다면 가마솥의 끓는 물에 집어넣어 죽이겠노라고 협박하였다. 그래도 여인이 끝내 싫다 하니 원님은 처음 만났던 그 산속으로 여인을 다시 데리고 가 부하들로 하여금 가마솥을 걸게 하고 물을 끓인 후 사공의 아내를 빠뜨려 죽이고 말았다. 그 후 석공의 두 딸이 어머니의 처참한 시신을 발견하고, 통곡을 하며 복수를 다짐한 끝에 10여 년의 시간이 흐른 후 사냥 나온 원님을 향해 화살을 쏘아 죽였다.죽은 여인의 혼은 이승을 맴돌며 지금도 비오는 밤이나 안개가 낀 날에 큰 울음소리를 낸다고 한다. 산중턱에 솥을 걸었던 자리는 사람 형상의 바위가 생겨나 ‘사람바위’ 혹은 ‘아내바위’라 불렀고, 그 산은 솥봉 또는 가마봉이라 불리게 되었다고 한다.", - "MNTN_HG_VL" : "416", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 반포면", + "DETAIL_INFO_DTCONT" : "강원도 홍천군 내천면과 인제군 상남면의 경계에 걸쳐 있는 가마봉은 산을 즐겨 타는 등반객들에게도 잘 알려지지 않아 자연 그대로의 정경을 간직한 산이다.산행기점인 김부리는 신라의 마지막 왕인 김부(金傅)에서 유래한 지명인데 세월이 흐르면서 현재 `金富'로 변했다고 한다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 인제군 남면", "MNTN_NM" : "가마봉" }, "longitude" : 128.1766667, @@ -61,13 +51,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 홍천군 내천면과 인제군 상남면의 경계에 걸쳐 있는 가마봉은 산을 즐겨 타는 등반객들에게도 잘 알려지지 않아 자연 그대로의 정경을 간직한 산이다.산행기점인 김부리는 신라의 마지막 왕인 김부(金傅)에서 유래한 지명인데 세월이 흐르면서 현재 `金富'로 변했다고 한다.", - "MNTN_HG_VL" : "925", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 인제군 남면", - "MNTN_NM" : "가마봉" + "DETAIL_INFO_DTCONT" : "대구의 명산 팔공산 정상에서 서쪽으로 약 10킬로미터 떨어진 가산은 일명 칠봉산이라고도 불리며 칠곡군 내 최고봉으로 가산면 가산리에 있다. 7개의 봉이 7개의 골짜기를 이루어 칠곡(七谷)이라 한 것이 오늘의 칠곡(漆谷)이 되었다. 1640년(인조 18)에 가산성을 쌓고 칠곡도호부의 치소가 약 180년간 산성 내에 있었다.<>한국전쟁 때의 격전지로서 선조의 호국의지가 깃들어 있는 가산산성과 가산바위 등 명소가 많으며 울창한 수림, 계곡의 석간수는 한여름에도 서늘함을 느낄 만큼 시원하여 가족 단위의 등산객이 많이 찾고 있다.<>가산바위는 산성 서쪽에 있는 80여평의 넓은 바위로, 신라시대의 고승 도선(道詵, 827∼898년)이 산천을 편력하면서 가산바위에 쇠로 만든 소와 말의 형상을 묻어 지기를 눌렀다고 전한다. 용의 모습을 닮은 용바위, 신선이 노닐었다는 유선대는 가산 정상에 우뚝 솟아 있다.", + "MNTN_HG_VL" : "902", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 동명면", + "MNTN_NM" : "가산" }, - "longitude" : 128.1766667, - "latitude" : 37.886111100000001 + "longitude" : 128.58266399999999, + "latitude" : 36.037387899999999 }, { "mountain" : { @@ -86,8 +76,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 운산면·예산군 덕산면", "MNTN_NM" : "가야산" }, - "longitude" : 128.1179362, - "latitude" : 35.822099600000001 + "longitude" : 126.6117509, + "latitude" : 36.707605200000003 }, { "mountain" : { @@ -96,28 +86,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", "MNTN_NM" : "가야산" }, - "longitude" : 128.1179362, - "latitude" : 35.822099600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "가야산은 진안 장안산에서 시작해 광양 백운산에서 끝을 맺는 듯하던 호남정맥이 남으로 국사봉과 봉화산으로 뻗어 내리다가 동쪽으로 다시 한번 여세를 몰아 일으킨 산이다. 정상에 오르면 광양 백운산과 백두대간에서 시작하는 지리산 천왕봉은 물론 주릉의 모습까지 한 눈에 조망되는 작지만 알찬 산이다.광양만을 바라보며 우뚝 솟아있어 시내 어디에서나 보이며 또 쉽게 오를 수 있어 광양시민들에게 사랑받는 산이다. 산에서 내려다보이는 광양만은 예부터 전남과 경남을 잇는 해상교역의 요충지이자 수산물의 보고이기도 하다.불과 500미터에 가까운 낮은 산이지만 이곳에는 암장이 있다. 병풍암, 동굴바위, 전망대바위, 처마바위, 적벽 등은 1989년 강신복, 김병석씨가 처음 개척한 이래 현재 70여개 루트가 열려 있고, 도로에서 암장까지는 약 30분이면 갈 수 있어 이곳 바위꾼들의 암벽 훈련 장소로 제격이다. 산행 시간은 어느 코스를 잡아 올라서든 4시간이면 충분하다.", - "MNTN_HG_VL" : "497", - "MNTN_LOCPLC_REGION_NM" : "전남 광양시 옥곡면", - "MNTN_NM" : "가야산" - }, - "longitude" : 128.1179362, - "latitude" : 35.822099600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "가야산은 나주시 가야동 영산강변에 피라미드 형상으로 아름답게 솟은 산이다.나지막한 산세지만 발아래 바로 영산강을 끼고 있어 나주 평야 전체를 바라볼 수 있다. 특히 북쪽 기슭에 위태롭게 매달려 있는 앙암은 강과함께 어우러져 뛰어난 경관을 자랑한다.", - "MNTN_HG_VL" : "189", - "MNTN_LOCPLC_REGION_NM" : "전라남도 나주시 남평읍 수원리", - "MNTN_NM" : "가야산" - }, - "longitude" : 128.1179362, - "latitude" : 35.822099600000001 + "longitude" : 126.6117509, + "latitude" : 36.707605200000003 }, { "mountain" : { @@ -146,8 +116,18 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 장평면 우산리", "MNTN_NM" : "가지산" }, - "longitude" : 129.00305599999999, - "latitude" : 35.621110999999999 + "longitude" : 126.9025627, + "latitude" : 34.820325599999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "삼봉약수에 있는 가칠봉(1,240m)에서 직선거리로 약 14km 북쪽에 위치한 가칠봉은 곰배령으로 더 유명하다. 곰배령 일대의 넓은 초원지대는 봄부터 가을까지 온갖 야생화가 피어나 지나는 이의 눈길을 끌고 놓지 않는다.<><>가칠봉 산자락에 사는 주민들은 일년 내내 산골 곳곳을 누비며 약초와 나물을 캐러 다니고 있다. 그래서 99년 5월부터 곰배령,가칠봉 일대를 입산 금지하고 있어, 입산코자 할 경우 인제 군청에 미리 확인해 봐야 한다.<><>가칠봉에서 북쪽으로 이어지는 주능선을 따라가면 곰배령을 지나 작은 점봉산(1,295m)으로 이어지고 이어서 점봉산(1,424m)으로 연결되어 한계령으로 능선이 뻗어 나가면서 설악의 품으로 들어간다. 가칠봉 일대는 교통이 불편한 관계로 접근이 어려워 아직도 깨끗한 계곡과 경관을 유지하고 있다.", + "MNTN_HG_VL" : "1242", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면 진동리", + "MNTN_NM" : "가칠봉" + }, + "longitude" : 128.42111109999999, + "latitude" : 38.0038889 }, { "mountain" : { @@ -169,26 +149,6 @@ "longitude" : 126.6497777, "latitude" : 37.626327199999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "398", - "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시", - "MNTN_NM" : "각산" - }, - "longitude" : 128.0564378, - "latitude" : 34.937731300000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "각호산은 백두대간상의 삼도봉에서 상촌면을 사이에 두고 백두대간과 상당부분 나란히 북으로 뻗어내리며 석기봉-민주지산-각호산-삼봉산 등을 솟구치게 한 뒤 황간부근을 흐르는 초경천에서 끝나는 길다란 능선의 한 봉우리이다.건각들일 경우 삼도봉-석기봉-민주지산-각호산을 잇는 코스로 종주하기도 하여 민주지산 범주안에 넣어버리는 예도 있으나 독자코스로 오르는 예가 많다.정상은 두 개의 암봉으로 이루어져 있으며 멀리 동쪽과 서쪽면에서 이산을 바라보면 m자형을 이루고 있는 산이다.", - "MNTN_HG_VL" : "1176", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 상촌면 물한리", - "MNTN_NM" : "각호산" - }, - "longitude" : 127.8456499, - "latitude" : 36.0625936 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "각화산은 태백산 남쪽 15Km 지점 경북 봉화군 춘양면 석현리에 위칙하고 있으며, 가을에는 정상을 오르는 등산로에 단풍이 곱게 물들어 많은 사람들이 찾는다.각화산이란 명칭은 시라 문무왕 16년 (676년)원효대사가 춘양면 서동리에 있던 람화사(覽華寺)를 이 산자락 밑으로 이전한 뒤 생각\"각\"자로 바꿔 부른데서 기인한다. 이 람화사에는 보물 52호로 지정된 3층 석탑이 있으며, 각화사에서 2Km 떨어진 곳에는 조선왕조실록을 보관하던 조선 5대사고 가운데 하나인 태백산고지지(사적348호)가 위치하고 있으며 산림이 무성하여 찾기가 힘들고 오전에 등반해야 하산을 할 수 있다.", @@ -216,8 +176,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면 신기리", "MNTN_NM" : "간대산" }, - "longitude" : 126.5258333, - "latitude" : 36.826666699999997 + "longitude" : 129.09671549999999, + "latitude" : 37.343407200000001 }, { "mountain" : { @@ -231,53 +191,33 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 원주시 지정면에 위치한 간현봉은 1985년 국민관광지로 지정되었다. 국민관광지로 지정이 되면서 주차장과 위락시설등이 들어섰고 사람들의 발길이 더욱 부산해졌다.간현봉은 강원도 원주시 지정면 간현유원지에 있는 386m의 나즈막한 산이다. 낮은 산이지만 산행의 값어치는 대단하다.북쪽으로 이어지는 능선은 소나무암릉으로 수십미터의 절벽과 굽이치며 흐르는 강물이 잘 조화되어 다른곳에서 느낄 수 없는 아름다움을 느끼게 한다. 산행 초입에는 매우 아름다운 두몽폭포가 자리잡고 있어 산행을 더욱 뜻깊게 한다. 별 볼일 없을 것같은 산에 이처럼 아름다운 폭포와 뛰어난 암릉지대가 있다", - "MNTN_HG_VL" : "386", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 지정면", - "MNTN_NM" : "간현봉" - }, - "longitude" : 127.8095197, - "latitude" : 37.357180800000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "갈두산이 위치한 해남군은 한반도 육지부에서 최남단에 위치한 군이다.그것을 증명이라도 하듯 갈두리에 '땅끝비'가 있기도 하다.해남은 우리나라최남단이라는 지리적 특성으로 인하여 조선시대에는 유배지로 지정됐다. 유배자의 35%가 전라도로 보내졌는데, 그중 50%가 해남으로 유배되었다고 한다.갈두산은 해남군에서도 최남단에 위치한 산으로 예부터 산자락에 칡이 많았다는데서 산 이름이 유래됐다. 일명 사자봉으로도 불리는 갈두산의 모산은 해남군 최고봉인 두륜산(703m)이다.정상에 있는 봉화대는 옛날 이곳에서 불을 지퍼 뱃길을 유도했다고 한다. 봉화대에서 남쪽 아래 500m 거리가 우리나라 육지부의 최남단, 북위 34도 17분 38초, 동경 126도 6분 01초 지점으로 조국의 무궁함과 땅끝임을 알리는 높이 10m에 바닥면적 3.6m인 땅끝탑이 세워져 있다.", - "MNTN_HG_VL" : "155", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남 송지면", - "MNTN_NM" : "갈두산" - }, - "longitude" : 126.4638211, - "latitude" : 34.475259000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "갈모봉은 작은군자산에서 옥녀봉으로 이어지는 능선상의 675m 봉에서 남쪽으로 뻗어 내린 지능선상 최고봉이다.갈모봉 동남쪽 아래는 장성봉에서 발원한 계류가 흐르는 선유동계곡이 유명하다. 일명 선유구곡(仙遊九曲)으로 불리는 이 계곡은 절경을 이루는 아홉 개의 명소들이 하나같이 희고 반들반들한 화강암으로 되어 있어 경치가 더욱 돋보인다.갈모봉은 온 산이 온통 기암괴석으로 이루어져 있어, 산행 코스마다 산의 경관이 새롭게 다가오며 그런 새로움에 취해 힘든 줄 모르고 산행 할 수 있는 곳이다. 갈모봉 산행 코스를 따라 만나게 되는 기암을 순서별로 보면 칠형제바위, 공기돌, 폭포바위, 두부바위, 우주선바위, 찐빵바위, 도마뱀바위, 벌통바위, 모녀바위, 치마바위, 비행기바위 등 10여개가 넘는다. 선유동계곡은 경관이 빼어나 신선이 노닐었다는 전설이 깃든 곳으로, 이곳의 아름다움에 반하여 조선 유학의 대학자인 퇴계(退溪) 이황(李滉)선생과 우암(尤唵) 송시열(宋時烈)선생이 말년을 보냈다고 한다.선유동계곡의 절경을 9곡으로 나누어 부르고 있는데, 제1경은 석굴형 바위인 선유동문(仙遊洞門)을 말하며, 제2곡은 마치 하늘을 떠받치는 형상을 하였다 하여 경천벽(擎天壁)을 말한다. 제3곡은 층암절벽으로 학이 둥지를 트는 형상인 학소대(鶴巢臺,일명 학소암)이고, 제4곡은 옛날 도사들이 바위로 금단을 끓였다는 연단로(鍊丹爐)를 말한다.제5곡은 연단로 상류 폭포지대인 와룡폭(臥龍瀑)을 말하며, 제6곡은 난가대(爛柯臺)로, 옛날 어느 나무꾼이 신선이 바둑 두는 것을 구경하다가 도끼자루 썩는 줄 몰랐다는 전설이 깃든 곳이다.난가대와 마주보고 있는 제7곡은 바위 바닥이 바둑판 형상으로 되어 있어 기국암(碁局巖)이라 부르며, 제8곡은 거북이 모습을 닮은 바위인 구암(龜巖)을 말한다. 제9곡은 옛날 신선이 숨어 살았다는 은선암(隱仙巖)을 말한다.", - "MNTN_HG_VL" : "582", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시, 충청북도 괴산군", - "MNTN_NM" : "갈모봉" + "DETAIL_INFO_DTCONT" : "기암괴봉과 깍아지른 바위벼랑이 한 폭의 동양화처럼 아름답고 능선이 반원형으로 가운데가 깊숙한 골을 이루며 암벽들이 산기슭을 감돌아 흐르는 금강줄기와 어울러져 경관을 자랑한다.또한 천태산, 서대산등 주변의 산 군을 바라볼 수 있는 조망이 좋은 산이다.", + "MNTN_HG_VL" : "585", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "갈기산" }, - "longitude" : 128.26813920000001, - "latitude" : 34.973953000000002 + "longitude" : 127.6280556, + "latitude" : 36.116666700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "img alt=\"\"style=\"width: 684px; height: 424px\"src=\"\/fckeditor\/data\/image\/%EA%B0%88%EB%AF%B8%EB%B4%89(%EC%86%8C%EB%A3%A1%EB%B4%89)-%EA%B4%91%EC%A3%BC%EA%B4%91%EC%97%AD%EC%8B%9C.jpg\"\/", - "MNTN_HG_VL" : "372", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구 선교동, 내남동", - "MNTN_NM" : "갈미봉" + "DETAIL_INFO_DTCONT" : "갈기산(585m)의 갈기는 말이나 사자의 갈기를 의미하는 것으로, 산행 중 만나는 울퉁불퉁한 바위능선길이 마치 갈기를 닮았다고 해서 붙여진 이름이다. 산 이름 속에 산세가 내포된 특이한 케이스다.이름 그대로 바위가 많은 갈기산은 산기슭을 휘감은 금강 줄기와 어우러져 흔치 않은 경관을 이룬다. 바위 낭떠러지라는 의미의 영동 일대 사투리인 '덜게기'는 금강 쪽으로 수 백길의 절벽을 이루고 있고 강 주변의 들녘은 한폭의 한국화를 연상시킨다. 주능선 좌우의 절벽은 남성적인 모습을 보인다. 암릉산행의 묘미를 느끼게 하면서도 정상에서는 그림 같이 흐르는 금강을 보여주며 부드러운 조망을 선물한다.금강을 중심으로 천태산과 마주보고 있는 갈기산은 천태산 때문에 상대적으로 관심을 덜 받아 왔지만 지금은 산꾼들의 입소문을 타면서 찾는 이가 많다. 등산코스는 크게 세 가지다. 주차장에서 정상을 밟고 관광농원으로 하산하거나 주차장에서 정상을 밟고 570봉과 560봉을 차례로 밟으며 소골재에서 소골로 길을 잡아 하산하는 길. 그리고 소골재에서 월영봉을 밟고 485봉을 지나 소골로 하산하는 길이 있다.", + "MNTN_HG_VL" : "585", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 양산면", + "MNTN_NM" : "갈기산" }, - "longitude" : 128.60611109999999, - "latitude" : 37.516666700000002 + "longitude" : 127.6280556, + "latitude" : 36.116666700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "548", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "갈미봉" + "DETAIL_INFO_DTCONT" : "용두리에서 홍천 방향으로 이어지는 44번 국도 동쪽 옆에 솟아 있는 갈기산은 산 높이는 낮으나 능선 곳곳에 바위가 돌출 되어 전망이 좋은 산이다. 봄이면 바위들과 진달래, 철쭉이 어우러져 고운 빛깔로 물들이고, 가을이면 형형색색의 단풍으로 자태를 뽐내는 산으로, 유명 산에 비해 한적하고 쾌적한 산행을 하기에 안성맞춤인 산이다.국토지리정보원 발행 지형도상 갈기산의 한자 표기는 칡 '갈' 자에 터 '기' 자를 쓴 '葛基山'이지만 과거에는 일어날 기(起)자를 썼다고 한다. 구한말 기록에는 부동산(不動産), 그 이전에는 감물악(甘勿岳)이라고 불렀다고 한다.정상 주변은 온통 암릉으로 되어 있어 전망이 좋으나 주의를 요하는 곳이다. 계곡이 깨끗하고 물이 차가워 송어 양식에 적합한 장소로 산자락에는 송어회집이 여러 곳 있다.", + "MNTN_HG_VL" : "685", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 홍천군", + "MNTN_NM" : "갈기산" }, - "longitude" : 128.60611109999999, - "latitude" : 37.516666700000002 + "longitude" : 127.7844462, + "latitude" : 37.578187 }, { "mountain" : { @@ -286,8 +226,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 충주시", "MNTN_NM" : "갈미봉" }, - "longitude" : 128.60611109999999, - "latitude" : 37.516666700000002 + "longitude" : 127.9080556, + "latitude" : 37.167222199999998 }, { "mountain" : { @@ -309,16 +249,6 @@ "longitude" : 126.9689597, "latitude" : 37.941738699999988 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "감악산은 치악산 동쪽에 있는 높이 945m의 바위산으로, 정상까지의 산행거리가 짧고 경사도 급하지 않아 초보자도 쉽게 찾을 수 있는 산이다.원주시 신림면. 충북 제천시 봉양읍 경계에 소재, 원주시의 남동단에 위치하고 있으며 치악산과 이웃하고 있어 빛을 보지 못하고 있으나 정상에는 석기암을 잇는 암봉과 암릉이 치악산 못지않는 절경을 지니고 있다.여름철 황둔리에서 황치리로 이어지는 시원한 계곡과 해발 945m의 바위산으로 정상까지의 산행거리가 짧고 경사도 급하지 않아 초보자도 쉽게 오를 수 있어 많은 등반객의 사랑을 받고 있다.정상 밑에는 백련사라는 절이 있으며 이곳까지 길이 잘 뚫려 있어 자동차 통행이 가능하다. 주능선에 우뚝 솟은 암봉들은 올라서기에 다소 위험하지만 굳이 바위에 올라가지 않아도 되므로 무리하게 올라서려하지 않는게 좋다.", - "MNTN_HG_VL" : "945", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면", - "MNTN_NM" : "감악산" - }, - "longitude" : 126.9689597, - "latitude" : 37.941738699999988 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -326,8 +256,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", "MNTN_NM" : "감악산" }, - "longitude" : 126.9689597, - "latitude" : 37.941738699999988 + "longitude" : 127.92212739999999, + "latitude" : 35.596956200000001 }, { "mountain" : { @@ -336,8 +266,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 시천면 사리", "MNTN_NM" : "감투봉" }, - "longitude" : 126.92702130000001, - "latitude" : 37.3404472 + "longitude" : 127.8411984, + "latitude" : 35.304295199999999 }, { "mountain" : { @@ -361,23 +291,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "대구 팔공산 능선에 있는 관봉을 말한다.높이 5.6m의 자연석에 부조한 4.15m의 석조여래좌상을 가리킨다. 부처가 갓을 쓰고있다고 해서 갓바위부처로 불린다. 이 부처의 소속사찰인 선본사 사적기에 따르면 신라 선덕여왕 7년(638년) 원광법사의 수제자인 의현대사가 돌아가신 어머니를 기리기 위해 만든 것이라 한다.", - "MNTN_HG_VL" : "852", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 와촌면", - "MNTN_NM" : "갓바위" - }, - "longitude" : 128.73777670000001, - "latitude" : 35.980165100000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "운달산과 마주한 높은 계곡이 냉곡이다. 운달산에서 한줄기 내려와 산북면 전두리와 구별하였으며, 산밑에 김룡사가 있다. 김룡사 경내를 통과하여 계곡을 올라서면 정상까지 갈 수 있고 삼각점이 있다. 정상에서 전망이 아주 좋다.김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다.다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다.그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", - "MNTN_HG_VL" : "673", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 김용리", - "MNTN_NM" : "갓산" + "DETAIL_INFO_DTCONT" : "경기도 포천군과 가평군의 경계를 이루는 강씨봉은 옛날 이 곳에 강씨가 모여 살았다 하여 붙여진 이름이라 한다. 강씨봉에서 동남쪽으로 뻗어 내리는 능선 길에 강씨봉고개가 있으며, 고갯마루에서 동쪽 아래에 강씨봉 마을터가 남아있다.전체 산세가 완만하고 부드러워 산행이 힘들지 않으며, 한나무골 계곡은 아직도 맑고 깨끗함을 간직하고 있다. 강씨봉은 포천시과 가평군을 경계로하는 아기자기한 등산코스를 지니고 있지만 주위에 유명한 산들이 많아, 등산객이 많지 않은 조용한 산행을 즐길 수 있어 가족산행지로 가볼만 하다.특히 겨울설경이 아름다우며 산꼭대기 좌우로 매우 아름다운 경관을 가진 산으로 한나무골의 계곡은 맑고 깨끗하다. 마지막 능선의 억새밭과 싸리나무, 봄철의 진달래와 철쭉이 어우러진 모습이 볼 만하다.", + "MNTN_HG_VL" : "830", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시, 가평군", + "MNTN_NM" : "강씨봉" }, - "longitude" : 140.02699709999999, - "latitude" : 38.549490599999999 + "longitude" : 127.38239059999999, + "latitude" : 37.969131699999998 }, { "mountain" : { @@ -399,6 +319,16 @@ "longitude" : 127.4697881, "latitude" : 36.387103499999988 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "개이빨산은 경기도 포천군 이동면과 가평군 북면의 경계를 이루는 산으로 국망봉(國望峰.1,168m)과 강씨봉(姜氏峰.830m) 사이에 위치해 있다.멀리서 이 산 정상부를 바라보면 정상 일원의 능선 10여개가 톱니처럼 돌출돼 있어 마치 개이빨을 연상케해 이 산의 이름을 개이빨산이라 부르게 된 것이다. 때문에 산자락에 사는 주민들은 이 산을 일명 견치산(犬齒山), 또는 견아산(犬牙山)이라 불러 왔다고 한다.", + "MNTN_HG_VL" : "1110", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 포천군", + "MNTN_NM" : "개이빨산" + }, + "longitude" : 127.32489889999999, + "latitude" : 37.878003 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "오대산을 지나 설악산으로 달리던 백두대간이 갈전곡봉에 이르러 서쪽으로 가지를 뻗은 산이 개인산이다.<>개인산은 개인, 삼봉, 방동약수로 유명하며 이 약수 섞인 물은 개인산의 북면을 흐르는 방대천과 서남면을 돌아가 방대천을 합하는 20킬로미터의 내린천으로 흘러들어 차례로 소양강, 북한강, 한강이 된다. 계곡은 수려하나 보이지 않고 산날은 치솟았지만 바위를 드러내지 않는다. 공기 좋고 물이 맑아 전염병이 들지 않고 먹거리가 많다. 입구는 좁고 안은 너른 형세다.<>이런 곳은 여덟 군데 살둔, 달둔, 월둔, 아침가리, 명지가리, 적가리, 곁가리, 연가리의 ‘삼둔오갈’을 두었는데 물, 불, 바람 즉 흉년, 전염병, 전쟁을 피할 수 있는 곳으로 내우외환이 끊이지 않았던 불행한 시대에 개인산은 많은 민추들을 보듬어 주었음을 역사는 전한다. 그리하여 개인산은 지리산과 금강산처럼 장엄하거나 빼어나진 않지만 그 어느 것보다 한국적인 산이다.", @@ -419,16 +349,6 @@ "longitude" : 129.14583329999999, "latitude" : 35.250555599999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "497", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", - "MNTN_NM" : "개천산" - }, - "longitude" : 126.91560149999999, - "latitude" : 34.9044934 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -449,16 +369,6 @@ "longitude" : 128.37976710000001, "latitude" : 34.995313600000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "인천대공원 정문을 나와 부평방향으로 가다가 서울외곽순환고속국도를 타기 위해 장수 IC로 들어가면 점점 진입로가 높아지면서 오른쪽으로 군부대유격장이 들어온다. 유격장의 남쪽으로 우뚝 솟아 있는 봉우리가 거마산이다. 유격장이 있는 골짜기를 경계로 남쪽 봉우리를 중심으로 거마산, 북쪽 봉우리가 부천시에 속하는 성주산이다.", - "MNTN_HG_VL" : "214", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 남동구 장수동", - "MNTN_NM" : "거마산" - }, - "longitude" : 126.76766720000001, - "latitude" : 37.471848100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -469,16 +379,6 @@ "longitude" : 127.7369444, "latitude" : 35.683055600000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산곡 버스정류장에서 산곡초등학교 앞을 지나 동쪽 계곡길을 곧바로 올려다 보이는 능선 안부를 향해 올라가면 주능선 안부에 이른다. 여기서 오른쪽(남) 능선을 따라 545봉을 지나 정상에 오르고 서남능선으로 내려간 안부에서 왼쪽 (동남) 계곡길을 따라 과학동에 이른다.", - "MNTN_HG_VL" : "596", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 중부면, 퇴촌면", - "MNTN_NM" : "거문봉" - }, - "longitude" : 126.96611110000001, - "latitude" : 38.702222200000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강원도 평창군 용평면과 대화면 사이에 솟아 있는 거문산은 오대산에서 서쪽으로 뻗어 내린 산줄기가 계방산에 이르러 남쪽으로 이어지면서 백적산(1,141m)에서 서쪽으로 가지를 친 능선이 금당산(1,173m)을 빚어 놓고 그 여력으로 우뚝 솟은 산이다. 이 산을 일으키고 남쪽으로 뻗어 내린 지맥은 평창강과 대화천을 가라앉힌다.금당산(錦塘山)·백적산(白積山)·형제봉(兄弟峰) 등과 함께 한국의 척량부(脊梁部)를 이루는 태백산맥(太白山脈)의 일부를 구성한다. 중부지방을 북서쪽으로 흐르는 한강(漢江)의 지류인 평창강(平昌江)의 발원지를 이룬다.", @@ -486,8 +386,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", "MNTN_NM" : "거문산" }, - "longitude" : 129.1552418, - "latitude" : 35.301902699999999 + "longitude" : 128.42388890000001, + "latitude" : 37.527500000000003 }, { "mountain" : { @@ -501,23 +401,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", - "MNTN_NM" : "거열산" - }, - "longitude" : 127.87636500000001, - "latitude" : 35.715445299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "건흥산(乾興山, 572m)과 취우령(驟雨嶺, 792m. 일명 아홉산)은 거창군 거창읍과 마리면의 경계에 자리한 산이다. 거창읍을 한 눈에 굽어보는 산에는 백제 부흥군이 신라에 대항해 싸운 거열산성이 자리하며, 673년에는 신라의 아진함(阿珍含)이 당군과의 싸움에서 장렬하게 전사한 역사의 현장이기도 하다.또 이 산의 서녘자락으로는 위천(渭川)이 흘러간다. 위천은 백두대간 덕유산 주능선의 동녘에서 비롯되는 소정천, 분계천, 산수천, 월성천, 창선천 등 여러 골물이 어우러져 흐른 넉넉한 물길이며 거창을 지나 합천호에 모였다가 다시 황강, 낙동강을 거쳐 남해에 이른다.약수터와 거열산성이 있어 거창군민들의 산책로로 인기 높은 건흥산 정상에 서면 거창군의 첩첩 산들이 이루는 파노라마가 장관이다. 또 멀리 수도-가야산과 지리산, 덕유산 능선도 볼 수 있다.", - "MNTN_HG_VL" : "792", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍, 마리면", - "MNTN_NM" : "건흥산(거열산)" + "DETAIL_INFO_DTCONT" : "봉각산이라 불리기도 하는 검각산은 그 이름에 걸맞게 산봉우리가 창을 맞대어 세워놓은 듯한 풍모를 가지고 있다.영월의 팔경 가운데 하나인 `검각창송'이란 평창강과 주천강이 합해져 서강이 되어 단종의 슬픈 역사를 담은 청령포를 지나 남한강으로 흘러가는 어귀에서 그 강물과 어우러지는 이 산의 빼어난 자태를 칭송한 것이다. 이 산에는 소의 뿔에서 땀이 날 정도로 험하고 넘기 힘들다는 각한치가 있는데, 억새가 빼곡이 서있는 풍경에 홀려 힘든 것도 모르고 가게 된다.", + "MNTN_HG_VL" : "505", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 남면", + "MNTN_NM" : "검각산" }, - "longitude" : 127.87636500000001, - "latitude" : 35.715445299999999 + "longitude" : 128.4233333, + "latitude" : 37.184166699999999 }, { "mountain" : { @@ -529,16 +419,6 @@ "longitude" : 127.2472779, "latitude" : 37.521461799999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1017", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", - "MNTN_NM" : "검마산" - }, - "longitude" : 129.233304, - "latitude" : 36.745343099999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "검봉은 춘천시 남산면 강촌리 북한강변에 솟아 있으며 구곡폭포로 유명한 봉화산(487m)과 산줄기를 잇고 있다. 봉화산과 이웃해 있어 구곡폭포 방향을 산행 기점으로 삼을 수도 있으나 구곡폭포에서 문배마을에 이르는 널따란 길이 나 있어 산행 첫머리로는 어울리지 않아 강촌리 강선사를 들머리로 하는 것이 보통이다.검봉은 칼을 세워 놓은 것처럼 생겼다고 해서 칼봉으로도 불린다. 또 주위 경관이 아름다워 사계절 내내 많은 관광객이 찾고 있으며 특히 겨울철에는 빙벽 교육 장소로도 인기 있다.강촌역 뒤 강선사로 오르면 첫 번째 봉우리에서 오른쪽으로는 의암호가 보이며 왼쪽으로는 경기도와 경계 지점인 도계휴게소 및 강촌휴게소가 보인다. 아득하게 보이는 발아래 경치를 감상 한 뒤 능선을 따라 2~3시간 정도 오르면 아홉 구비 계곡을 돌아 볼 수 있는 구곡정이 나타나며 50여 미터 높이의 구곡폭포에서물안개를 일으키며 떨어지는 물줄기가 보인다.", @@ -559,36 +439,6 @@ "longitude" : 127.5986521, "latitude" : 37.805322400000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "804", - "MNTN_LOCPLC_REGION_NM" : "", - "MNTN_NM" : "견두산" - }, - "longitude" : 127.4004582, - "latitude" : 35.347366200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "804", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시, 전라남도 구례군", - "MNTN_NM" : "견두산" - }, - "longitude" : 127.4004582, - "latitude" : 35.347366200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 포천군과 가평군의 경계를 이루는 지점에 위치한 산으로 경기도내에서 아주 드물게 1000미터급 산이 즐비한 곳이기도 하다. 명지산, 귀목봉, 민둥산, 개이빨산(견치봉), 국망봉, 광덕산등의 1000미터급 산과 청계산, 강씨봉, 신로봉, 가리산, 백운산등 8-900미터급의 산들이 뒤를 잇는다.", - "MNTN_HG_VL" : "1120", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면\/가평군", - "MNTN_NM" : "견치봉" - }, - "longitude" : 127.4186675, - "latitude" : 38.013648500000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "호남정맥의 마루금에 위치한 경각산은 구이저수지 서쪽에서 모악산을 마주보며 우뚝 솟아있다. 경각산(鯨角山)의 한자 그대로 고래등에 난 뿔처럼 생긴 두 개의 바위가 정상부에 솟아, 산 아래에서 바라보면 모악산 방향으로 머리를 둔 고래의 모습과 흡사하다. 이 때문에 어머니를 상징하는 모악산과 달리 경각산은 남성을 상징한다.산 정상에서는 전주와 익산 시내, 미륵산, 고덕산, 마이산, 오봉산이 선명하게 보인다. 특히 가을 단풍과 겨울 선경으로 이름 높지만, 모악산에 비해 상대적으로 덜 알려져 있어 주말에도 호젓한 산행을 할 수 있다. 패러글라이딩 활공장이 있어 날씨가 좋은 날에는 하늘 높이 날아가는 패러글라이딩의 모습도 볼 수 있다.경각산 아래 정각사는 고려말기에acirc;건된 태고종 사찰로 많은 고승들의 수도oacute;가 되었다고 전해진다.", @@ -609,16 +459,6 @@ "longitude" : 127.15733539999999, "latitude" : 35.728343799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경운산(慶雲山)은 남으로 주촌 고개에서 북으로 삼계로타리(14번 국도)까지 4.9Km로주촌면, 내외동, 삼계동을 포함한 전형적인 시내 근교 산으로 많은 시민들이 체육공원겸 당일 산행지로 애용하고 있는 산이다. 산 정상은 해발 378m로 크게 높지 않으나 김해 시내와 주촌, 칠산, 장유면과 멀리부산시까지 한 눈에 발라볼 수 있어 전망이 확 트인 시원한 산이다. 동으로는 수인사, 경원사등 사찰과 유치원, 초.중학교가 있으며 서로는 선지사, 태안사등 많은 사찰과 자연 부락을 안고 있다. 이 산은 2002년 국립지리원에서 발행한(1:50,000 지형도)에는 競雲山으로 표기되어있으며\"신동국여지승람\"에서는 운참산(雲站山)으로 불리었다. 조선 전기까지 운참사(雲站寺)가 있었다는 기록이 있으나 지금은 사찰터를 찾지 못하고 있다.", - "MNTN_HG_VL" : "378", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", - "MNTN_NM" : "경운산" - }, - "longitude" : 128.85577259999999, - "latitude" : 35.250136099999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "몽덕산(680m)에서 뻗어 내린 능선이 가덕산(858m),북배산(867m)을 일으키고 싸리재를 지나 서남쪽으로 이어지는 능선에 우뚝 솟아 있는 계관산은 강원도 춘천시 서면과 경기도 가평군 북면의 경계를 이루는 산이다.몽덕산에서 계관산으로 이어지는 주능선 마루에는 폭 20여 미터에 방화선이 만들어져 있는데 이곳에 억새풀이 빼곡이 들어 서 있다. 가을이면 황금빛으로 물들어 산행 재미를 더해 준다. 정상에 서면 북으로는 북배산, 그 뒤로 가덕산과 몽덕산이 가까이 보이고, 그 오른쪽으로 용화산과 오봉산이 한눈에 들어오며, 동쪽 발 아래로는 물위에 떠 있는 듯한 춘천시내와 의암호가 거울처럼 보인다.서북쪽으로는 구나무산, 월출봉, 백둔봉, 명지산, 수덕산, 화악산 등의 산맥이 줄지어 솟아 있다.", @@ -646,8 +486,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", "MNTN_NM" : "계룡산" }, - "longitude" : 127.20583329999999, - "latitude" : 36.342500000000001 + "longitude" : 128.608, + "latitude" : 34.871299999999998 }, { "mountain" : { @@ -656,8 +496,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 신현읍, 거제면", "MNTN_NM" : "계룡산" }, - "longitude" : 127.20583329999999, - "latitude" : 36.342500000000001 + "longitude" : 128.608, + "latitude" : 34.871299999999998 }, { "mountain" : { @@ -666,8 +506,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", "MNTN_NM" : "계명산" }, - "longitude" : 127.977, - "latitude" : 36.989999999999988 + "longitude" : 128.93972220000001, + "latitude" : 36.420833299999998 }, { "mountain" : { @@ -676,8 +516,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 석현면", "MNTN_NM" : "계명산" }, - "longitude" : 127.977, - "latitude" : 36.989999999999988 + "longitude" : 126.9333333, + "latitude" : 37.745555600000003 }, { "mountain" : { @@ -689,6 +529,36 @@ "longitude" : 127.977, "latitude" : 36.989999999999988 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "남한에서 한라산(1947.3m) 지리산(1915.4m) 설악산(1708.1m) 덕유산(1614.2m)에 이어 다섯 번째로 높은 계방산은 겨울철 적설등반 산행지로 유명한 산이다.강원도 홍천군 내면과 평창군 진부면에 걸쳐 있는 광대한 산맥을 거느리고 있으나, 북동쪽으로 연결되어 있는 오대산의 명성에 가려 빛을 보지 못했던 명산이다. 높은 산이면서도 유순한 산세와 능선을 가지고 있으며 가을이면 온 산을 단풍으로 물들이고 겨울철에서 무릎이상 빠질정도의 적설량으로 등산인들의 사랑을 듬뿍 받고 있는 산이다. 산기슭에 있는 방아다리 약수는 위장병, 피부병에 효험이 있는데 메밀꽃 필 무렵 마시면 특효가 있다고 한다.", + "MNTN_HG_VL" : "1579", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면, 평창군 용편면ㆍ진부면", + "MNTN_NM" : "계방산" + }, + "longitude" : 128.4448506, + "latitude" : 37.707517000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "계족산은 말 그대로 닭의 발처럼 산줄기가 사방으로 뻗어있다. 대전시 동북쪽에 울타리를 이룬 시민의 산인지라 온 산이 공원화 되어 있다. 등산로만 해도 입구가 20여 군데에 달할 정도다. 산 남서쪽에는 경부고속도로가 시내와 경계를 지으며 산줄기와 나란히 달리고, 그 맞은편인 동쪽 산자락에는 푸른 대청호가 넘실거린다.산 자락에는 각종 유적과 문화재 등이 즐비하다. 들머리인 용화사에는 석불입상, 날머리인 비래사에는 동춘당이 지은 정자인 옥류각, 그 아랫마을인 송촌동에는 동춘당이 있다. 우암 송시열 선생이 학문을 닦고 제자를 가르쳤던 곳에는 우암사적 공원이 들어섰다. 과거와 현재, 미래가 공존하는 도시인 대전답게 계족산 역시 그 모습을 고스란히 반영하고 있다.계족산에는 계족산성이 북에서 남으로 길게 산정을 형성하고 있다. 삼국시대 백제 부흥군이 활동했던 옹산성으로 추정되는 이 성은 둘레만 해도 1037미터로 이 고장 최대의 산성이다. 성벽은 안쪽의 흙을 깎아내고 바깥쪽에만 돌을 쌓는 수법으로 만들어졌다.", + "MNTN_HG_VL" : "424", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구, 동구", + "MNTN_NM" : "계족산" + }, + "longitude" : 127.43934659999999, + "latitude" : 36.385547600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "890", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "계족산" + }, + "longitude" : 128.5200261, + "latitude" : 37.169667099999998 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "고고산은 강원도 영월군 영월읍 문산리와 중동면 연하리, 정선군 신동읍 고성리와 경계를 이루며 동강변에 솟아 있는 산이다.설악산 용아름의 축소판인 암릉은 이 산의 백미로 구들장 같은 바위들이 층층이 쌓여 있고 암릉 위에는 분재와 같은 노송들이 뿌리를 내려 거대한 한 폭의 동양화를 연상하게 한다. 북릉을 타고 전망바위 정상에서 북으로 보면 신병산과 능암덕산이 마주 보이고 오른쪽으로는 백운산과 곰봉 사이를 가로 지르는 동강이 조망된다.", @@ -699,6 +569,26 @@ "longitude" : 128.57913009999999, "latitude" : 37.220578799999998 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "396", + "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 서호동", + "MNTN_NM" : "고근산" + }, + "longitude" : 126.51384419999999, + "latitude" : 33.266262900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "175", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 애월읍 고내리", + "MNTN_NM" : "고내봉" + }, + "longitude" : 126.3418004, + "latitude" : 33.459126500000004 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경원선 철도가 휴전선에 막혀 더 이상 달리지 못하고 멈추는 곳에 고대산이 솟아 있다. 고대산은 등산객들이 자유롭게 산행을 할 수 있는 산 중에서 휴전선에 가장 가깝게 위치해 있는 산이다. 경기도 최북단인 연천군 신서면 신탄리와 강원도 철원군 사이에 있는 고대산 정상에서는 북녘의 철원평야와 6·25 때 격전지인 백마고지, 금학산과 지장봉, 북대산, 향로봉은 물론 한탄강 기슭의 종자산까지 한눈에 들어온다. 분단의 한, 망향의 한이 굽이쳐 북녘이 그리울 때, 멀리서나마 북녘땅을 바라볼 수 있는 3대 명산으로 고대산, 복계산, 지장봉을 꼽는데 해마다 6월이면 분단 상황을 체험해 보려는 많은 등산인들이 고대산을 찾는다. 수려한 전망과 적당한 코스 등 최적의 산행코스를 갖췄음에도 전략적 요충지라는 이유로 웬만한 지도에는 감춰진 산이다. 휴전선과 가장 가까운 곳에 있기 때문에 여태껏 사람들에게 잘 알려지지 않았다는 것이 이 산이 간직한 매력이기도 하다.", @@ -716,8 +606,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", "MNTN_NM" : "고덕산" }, - "longitude" : 127.1788889, - "latitude" : 35.772222200000002 + "longitude" : 127.3434029, + "latitude" : 35.659716299999999 }, { "mountain" : { @@ -729,16 +619,6 @@ "longitude" : 127.1788889, "latitude" : 35.772222200000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "고두산은 더덕이 많고 사람들에게 잘 알려지지 않은 전형적인 강원지방 산이다. 이 산은 특히 산더덕이 풍부한데 정상방면 능선은 온통 더덕 향이다. 곳곳에 수북히 쌓인 멧돼지 배설물도 이 산이 인적이 드문 깊은 산임을 알게 한다.산이 깊은 탓에 고두산은 조망이 그리 좋지는 않다. 특히 정상은 굴참나무가 빽빽이 들어서 있어 주위를 둘러보기 힘들다. 대신 약수봉 전망바위가 정상의 조망을 대신한다. 북으로 보이는 금당산과 금당산 아래로 흐르는 평창강과 아찔하게 펼쳐진 금당계곡이 시원함으로 다가온다.", - "MNTN_HG_VL" : "1030", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면", - "MNTN_NM" : "고두산" - }, - "longitude" : -72.60738649999999, - "latitude" : 41.833431300000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "계방서정맥(桂芳西正脈)이라 불리는 산줄기 도미(掉尾)를 장식하며, 경기의 곡창지대인 여주 들녁에 우뚝 서 한 바다에 고래 등처럼 떠 있는 이산은 '고달산(高達山)'으로 불리기도 하며, 예로부터 고려장을 하던 '고려산'으로 불리었다.서남쪽으로 위치한 우두산(牛頭山) 남쪽에 사적 제382호로 지정된 '고달사지(高達寺址)'라는 사적지를 가지고 있으며, 금동마을 뒤쪽으로는 고려장 굴이 있어 옛 고려장 관습에 흔적을 가지고 있는 산이다.산세는 육산으로 가파른 경사를 이루고 있으며, 지제면 대평리쪽은 골프장 개발공사로 자연이 훼손되고 등산로가 없어졌으므로 여주 북내면쪽으로만 산행이 가능하다. 고달사지는 국보 제4호로 지정된 고달사부도를 위시해, 보물 3점, 향토유적지등이 있어, 산행과 문화재 탐방을 함께 할 수 있는 산이다.", @@ -759,16 +639,6 @@ "longitude" : 126.4372675, "latitude" : 37.744586699999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "예로부터 신령스런 산으로 여겨왔던 고령산은 숲이 울창하지는 않지만 봄과 가을이면 능선 따라 꽃과 단풍이 고와 분위기 있는 등산을 즐기기 좋다. 파주시 광탄면 기산리와 영장리, 장흥면 석현리, 양주시 장흥계곡에 걸쳐 있으며, 숲이 울창하게 우거져 있다. 높이가 별로 높지 않으나, 경기도 북서지역에서는 감악산(675m)과 더불어 가장 높은 산으로 꼽힌다. 북쪽으로 양주시가, 남쪽으로 북한산 백운대가, 동쪽으로 불국산, 사패산, 도봉산 등의 봉우리가 있다.산 아래에 있는 보광사는 894년(진성여왕 8) 도선국사가 왕명으로 창건하였고 임진왜란 때 소실되었다가 여러 차례 중수하였다. 1634년(인조 9년)에 주조된 범종이 크기는 작지만 화려한 모습을 띄고있어 조선조 시대의 범종 양식을 잘 보여준다. 산기슭에는 도솔암이 있는데, 말 그대로 소나무로 둘러싸인 암자이다. 도솔암에서 조금 더 오르면 정상이다. 정상은 평탄한 공터이며, 북쪽으로 감악산이 보인다. 정상 남쪽의 봉우리는 군사지역으로 산행할 수 없다.고령산은 1634년에 주조한 보광사 범종과 조선 후기에 편찬된 《양주목읍지》에 각각 고령산(高嶺山)과 고령산(高靈山)으로 기록되어 있어 높고 신령스러운 산으로 여겼음을 알 수 있다. 산정에서 북서편으로 능촌교를 지나면 영조대왕의 생모인 숙빈 최씨의 묘소인 소령원(昭岺園)이 있다.", - "MNTN_HG_VL" : "622", - "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 장흥계곡", - "MNTN_NM" : "고령산" - }, - "longitude" : 126.92749999999999, - "latitude" : 37.7575 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "고루포기산은 강원도 강릉시 왕산면과 평창군 도암면의 경계를 이루는 산으로, 주변의 발왕산, 제왕산, 능경봉의 명성에 가려 찾는 이들이 많지 않았던 산이다.태백산맥의 지맥인 해안 산맥에 딸린 산으로, 북서쪽의 빗면은 한때 대관령 스키장이 있었던 곳이다. 부근의 횡계리(橫溪里) 일대는 평탄면을 이룬다.서쪽에는 남한강의 지류인 송천(松川)이 감입곡류를 이루면서 남쪽으로 흘러 하안단구를 이룬다. 북동쪽 빗면으로 흐르는 수계는 왕산면 왕산리(旺山里)에서 강릉 남대천(南大川)의 지류로 흘러든다.", @@ -779,26 +649,6 @@ "longitude" : 128.73346340000001, "latitude" : 37.647446599999988 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "고리봉은 전북 남원시 주생면ㆍ금지면ㆍ대강면에 자리잡고 있는 호남정맥의 줄기다. 지리산을 지척에 두고 맥을 달리하는 바위산으로 곡성에서 남원 방향으로 향하다보면 금지들이라 불리는 평원에서 옹골차게 솟은 산이다.골산(骨山)의 전형을 보여주는 고리봉의 이름은 소금배를 묶어두었던 ‘고리(還)’에서 유래한다. 지금 남원 시내를 관통하며 흘러내리는 요천은 남원 관광단지 앞 물줄기만 둑을 쌓아 뱃놀이가 가능하지만, 100여 년 전까지만 해도 하동을 출발한 소금배가 섬진강에 이어 요천 물줄기를 거슬러 남원성 동쪽 오수정(참나무정)까지 올라와 닻을 내렸다고 한다.당시 소금배가 중간 정박지로 금지평원에 머물기 위해 배 끈을 묶어두었던 쇠고리를 바로 고리봉 동쪽 절벽에 박아 놓았다는 것이다. 이렇게 소금배와 얽힌 전설이 전하는 고리봉은 조망도 좋지만 산세가 뛰어난 산이다. 동서 양쪽 사면은 거대한 바위 병풍을 연상케 할 만큼 웅장한 산세를 과시하고, 능선은 소나무가 울창한 가운데 부드러운 육산과 아기자기한 암릉이 번갈아 이어져 산행의 즐거움까지 더해진다.", - "MNTN_HG_VL" : "710", - "MNTN_LOCPLC_REGION_NM" : "전북 남원시 주생면ㆍ금지면ㆍ대강면", - "MNTN_NM" : "고리봉(두리봉)" - }, - "longitude" : 127.5351143, - "latitude" : 35.377140400000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "153", - "MNTN_LOCPLC_REGION_NM" : "전라북도 군산시", - "MNTN_NM" : "고봉산" - }, - "longitude" : 126.79034540000001, - "latitude" : 37.692349399999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "크게 화려하거나 요란하지 않지만 그런 대로 쏠쏠하게 볼거리가 있고 전망도 좋은 산이다.해발 500여 미터정도의 나지막한 산이지만 정상에 오르면 멀리 영광쪽 바다에 배가 떠다니는 모습이 보이고 무등산을 물론 광주시내까지도 조명할 수 있는 산이다. 광주에서 거리도 그리 멀지 않아 당일치기로 다녀와도 무리가 없다. 작은 규모에 비해 등산로는 꽤 가파른 편이며 아기자기한 암벽미도 그만이다.", @@ -806,8 +656,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 성송면\/전라남도 장성군 삼계면 부성리", "MNTN_NM" : "고성산" }, - "longitude" : 127.17472220000001, - "latitude" : 37.048333300000003 + "longitude" : 126.6333333, + "latitude" : 35.299999999999997 }, { "mountain" : { @@ -816,8 +666,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 고성군간성읍 금수리", "MNTN_NM" : "고성산" }, - "longitude" : 127.17472220000001, - "latitude" : 37.048333300000003 + "longitude" : 128.45110779999999, + "latitude" : 38.352438200000002 }, { "mountain" : { @@ -826,8 +676,28 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", "MNTN_NM" : "고성산" }, - "longitude" : 127.17472220000001, - "latitude" : 37.048333300000003 + "longitude" : 128.45110779999999, + "latitude" : 38.352438200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 정선군에서도 가장 오지 마을이라 할 수 있는 임계면 고양리에 위치한 산이다. 그리고 반론산(1068)은 고양산에서 북쪽 여량 방면으로 뻗은 능선상 최고봉으로 고양산과는 약 4km 정도 거리를 두고 있는 산이다.이 두 산의 주체는 베낭족의 낙원이라 불리던 골지천(骨只川)이 된다. 즉 골지천에서도 가장 하이라이트라 할 수 있는 구미동, 어전동, 성북동, 봉정리 등이 이 두 산을 감싸면서 휘돌고 있다.골지천(骨只川)에 솟아 있는 어머니 같이 넉넉하고 편안한 품을 펼치고 있는 고양산은 정선의 오지 중에 오지인 임계면에 자리잡고 있다.", + "MNTN_HG_VL" : "1151", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "고양산" + }, + "longitude" : 128.77055559999999, + "latitude" : 37.416944399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", + "MNTN_NM" : "고양산" + }, + "longitude" : 128.17715340000001, + "latitude" : 37.736119500000001 }, { "mountain" : { @@ -879,16 +749,6 @@ "longitude" : 127.4664193, "latitude" : 37.657477 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "715", - "MNTN_LOCPLC_REGION_NM" : "전라남도 곡성군 오곡면", - "MNTN_NM" : "곤방산" - }, - "longitude" : 128.99863020000001, - "latitude" : 37.713526999999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강원도 영월군 하동면 와석리 곡골 동쪽에 우뚝 솟은 곰봉은 산자락 곳곳에 산나물이 즐비하게 자생할 정도로 오염되지 않은 청정지역이다. 곰봉 정상에는 돌을 고여놓고 가마솥을 얹어 놓은 듯한 형상인 자동차 크기의 바위가 세 개 놓여 있다. 정상에 곰 모양의 바위가 있어 곰봉이라 부른다.국립지리원에서 발행한 지형도에 마대산은 표기되어 있으나 곰봉은 이름도 없이 산을 의미하는 기호에 산 높이만 적혀 있다. 이 산은 마대산보다 암릉이 잘 발달되어 있어 전망이 좋다. 암릉에는 소나무가 우거져 있으며, 그 뒤로는 산들이 첩첩하게 서 있어 매우 아름답다.산행은 희귀한 민화를 전시하고 있는 조선민화박물관을 출발하여 암릉을 타고 올라 855m 봉우리에서 시루봉을 지나 정상에 오른다.", @@ -929,16 +789,6 @@ "longitude" : 128.0100592, "latitude" : 37.715563299999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 창념읍과 고암면 사이에 자리잡은 화왕산과 이 화왕산 꼭대기에서 동남쪽 능선으로 뻗어내린 관룡산은 경상남도 창녕군에서 한 번쯤 곡 가봐야 할 진산이다.높지는 않지만 경관이 수려하고 낙동강 하류지대에 솟아올라 있어 산세가 제법 크게 느껴진다. 두 산은 마치 ㄷ자를 오른쪽으로 90도 가량 돌려놓은 듯한 지형이다.가을에는 억새풀이 봄에는 진달래가 유명한 산이다. 또한 사적이나 문화재가 많아 ‘제2의 경주’라고 불리기도 한다. 그러므로 아이들과 함께 하는 가벼운 산행지로 매우 좋다. 그러나 시간은 한정되고 둘러 볼 것은 많으므로 볼거리를 미리 정해 두어야 한다.", - "MNTN_HG_VL" : "740", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 고암면", - "MNTN_NM" : "관룡산" - }, - "longitude" : 128.5534586, - "latitude" : 35.531947600000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -946,8 +796,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", "MNTN_NM" : "관모산" }, - "longitude" : 126.7655213, - "latitude" : 37.451878399999998 + "longitude" : 126.8583333, + "latitude" : 36.6969444 }, { "mountain" : { @@ -956,8 +806,18 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍", "MNTN_NM" : "관모산" }, - "longitude" : 126.7655213, - "latitude" : 37.451878399999998 + "longitude" : 126.8583333, + "latitude" : 36.6969444 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "관산은 천진암 성지가 있는 앵자봉의 주능선이 좌측으로 이어지다 북쪽으로 이어진 산이다. 서쪽으로 무갑리 계곡과 무갑산이 지척이고, 천진암 성지도 가까워 성지 순례와 겸한 산행도 가능하다.양자산, 앵자봉, 관산이 북에서부터 남으로 능선으로 이어져 통상 이 세 산을 연결하여 종주 하는 경우도 많으며 서울시에서 별로 멀지않아 휴일이면 산악회에서 단체로 산행하는 경우가 많다.", + "MNTN_HG_VL" : "501", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면", + "MNTN_NM" : "관산" + }, + "longitude" : 127.3583333, + "latitude" : 37.4186111 }, { "mountain" : { @@ -969,26 +829,6 @@ "longitude" : 126.9610024, "latitude" : 37.442938499999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "변산은 호남의 5대 명산 중에 하나로 서해에 접한 반도를 형성한 산 군을 말하며, 행정구역상으로는 전북 부안군 하서면, 상서면, 변산면, 진서면, 보안면에 접해 있는 산이다.의상봉(509m), 삼예봉(355m), 덕성봉(328m), 상여봉(398m), 옥녀봉(433m), 쌍선봉(459m), 신산봉(486m), 삼신산(486m), 갑남산 등을 통칭하여 변산이라 부르고 있다. 변산 반도는 산군이 형성된 내륙 쪽을 내변산, 해안 쪽을 외변산으로 구분하여 부르고 있다. 관음봉이 솟아 있는 변산반도에는 직소폭포, 분옥담, 선녀탕, 와룡소와 낙조대, 망포대 등 널리 알려진 명승지들이 산재해 있으며 관음봉 등산로에는 낙조대 아래에 월명암과 관음봉 아래 내소사 등 유서 깊은 사찰들이 자리해 있다.백제 무왕 34년(633년)에 혜구스님이 창건한 내소사는 `다시 태어나서 온다'는 뜻으로 소래사(蘇來寺)로 불러 오다가, 조선 인조 11년(1633년)에 청민선사가 중건한 뒤부터 내소사로 이름이 바뀌었다고 한다. 이 지방에서는 `춘변산 추내장(春邊山 秋內臟)이란 말이 전해지는데 이는 봄에는 변산반도, 가을엔 내장산의 경치가 최고라는 것을 한마디로 표현한 것이다. 관음봉은 일명 세봉(細峰), 가는봉이라 불리고 있으며, 거대한 바위절벽을 두르고 있어 보는 이로 하여금 감탄을 자아내게 한다.관음봉 산행은 남여치에서 시작하여 쌍선봉, 낙조대, 월명암, 봉래구곡, 직소폭포, 재백이재를 거쳐 관음봉을 오른 뒤 내소사로 하산하는 코스가 많이 이용되고 있다. 이 중 낙조대는 서해의 해지는 풍경을 보러 오는 사람들로 늦은 시간에도 사람들의 발길이 끊이지 않는 곳이며, 30여미터의 높이에서 떨어지는 직소폭포는 부안 3절(扶安三絶)의 하나로 채석강과 더불어 변산을 상징하는 명소다.", - "MNTN_HG_VL" : "433", - "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군", - "MNTN_NM" : "관음봉" - }, - "longitude" : 127.20027779999999, - "latitude" : 36.351944400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "관음산은 북동쪽으로 명성산과 주능선이 이어져있다. 정상에서 북쪽 산자락에는 관광명소인 산정호수가 자리잡고 있으며, 남쪽으로는 드라이브코스인 영평천이 흐르고 있어 볼거리가 많은 곳이다.관음산에서 동쪽으로 이어지는 사향산은 군사시설로 입산이 통제되어 있는 곳이다.주위의 명성산 국망봉, 백운산 그늘에 가려 별로 알려지지 않은 산이지만 그만큼 호젓한 산행을 즐기기에 좋다.관음산의 특징은 바위가 별로 없는 '육산'이라는 점이다. 정상에 서 북쪽 사자락에는 관광명소인 산정호수가 자리잡고 있으며, 남쪽으로는 드라이브 코스인 영평천이 흐르고 있어, 볼거리가 많다. 산행 들머리는 영중면 파주골, 영북면 산정리와 쇠골, 낭유고개 등이다.이 중 파주골은 후고구려를 건국한 궁예가 명성산에서 왕건에게 패한 후 도주했던 곳이라 해서 패주동으로 불리다가 훗날 파주골로 되었다. 파주골 식당을 지나 계곡 초입에는 폐광터가 있다. 남쪽으로는 바위에서 바람이 솟아난다는 풍혈산, 북쪽으로는 낭유 고개 너머 사향산과 명성산이 솟아있다.", - "MNTN_HG_VL" : "733", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영북면", - "MNTN_NM" : "관음산" - }, - "longitude" : 127.310757, - "latitude" : 38.028650900000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "관인봉은 정상에서 남봉으로 뻗어내린 능선과 평행선을 이루고 주능선은 대부분 암릉과 암벽지대로 이루어져 있고, 이러한 천혜의 지형을 이용행 보가산성을 축조한 석축이 남아있다. 지장봉계곡을 사이에 두고 서로 마주보고 있는 삼형제봉과 지장봉은 일직선으로 연결되어있고 관인봉은 관인북봉 위쪽에서 예각으로 좌회전하여 서진하면 지장봉과 만난다.경기도 포천군 관인면 서북단에 위치한 관인봉 일원은 예로부터 전략적 요충지로 삼국시대 때 고구려, 백제, 신라가 영토 분쟁을 하였던 곳이다. 삼국시대 초기에는 백제 땅이었다가 고구려 광개토왕 6년(396년)에는 고구려령이 되었고, 신라 진흥왕 12년(551년)에는 신라의 국토에 편입되어 경덕왕 16년(757년)에는 칠성군에 속해 있었다는 기록이 있다. 신라 말에는 궁예가 태봉국을 건국하여 철원에 도읍을 정하였을 때 태봉국의 영역에 속하게 되었다한다. 태봉국왕인 궁예의 폭정에 못 견딘 어진(仁) 관리(官)들이 관직을 버리고 이 지역에 모여 살았다는 유래로 이 지역이 관인으로 불리게 되었다 한다.정상에서 조망은 북으로는 철원군의 고대산(高臺山.832m)과 금학산(金鶴山.947m)이, 동쪽으로는 고남산(古南山.644m)이, 남쪽으로는 종자산(種子山.643m), 서쪽으로는 지장봉(地藏峰.877m)이 관인봉을 감싸고 있다. 울창한 수림으로 수량이 많은 큰골은 계곡 피서지로서 유명하고 가을 단풍도 좋다.", @@ -996,8 +836,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 포천시", "MNTN_NM" : "관인봉" }, - "longitude" : 126.2227778, - "latitude" : 40.032499999999999 + "longitude" : 127.17340609999999, + "latitude" : 38.1419122 }, { "mountain" : { @@ -1021,19 +861,19 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 아산시 송악면과 천안시 광덕면의 경계를 이룬 광덕산은 높이에 비해 산세와 조망이 뛰어난 산으로 정평이 나 있다. 온양온천을 지척에 두고 있어 온천산행지로도 널리 알려진 광덕산은 천안, 아산, 공주의 분기점이자 금북정맥 상의 각흘고개와 갈재고개 사이의 무명봉에서 북쪽으로 갈래 쳐 천안시와 아산시를 가르며 뻗은 산줄기의 최고봉으로서, 흔히 내포지방이라 일컫는 아산, 당진, 서산뿐 아니라 평택, 천안, 대전 등 충남북 일원을 한눈에 조망할 수 있는 산이다. 크고 풍후(豊厚)하여 옛날부터 덕이 있다고 하는 광덕산은 난리가 나거나 불길한 큰 일이 있으면 산이 운다는 전설이 있으며 계곡에는 언제나 맑은 물이 흘러 곡교천의 상류가 되며 남록인 공주시 사곡면 운암리에는 유서 깊은 마곡사가 자리하고 있다.또한 호두나무가 풍성한 광덕사 주변은 갑신정변을 일으켰던 풍운아 김옥균, 임시정부 주석 김구 선생 등 역사적인 인물들이 은신했던 곳으로도 알려져 있다.", + "DETAIL_INFO_DTCONT" : "한북정맥에 들머리가 되는 광덕산은 경기도에서는 가장 북쪽에 위치한 산이며, 강원도 화천군과 철원군의 경계를 이루고 있으며, 거의 정상 부위까지 군사 비상도로가 개설되어 있고 산자락 곳곳에 군사시설이 있어 지형적으로 군사 요충지임을 말해주는 산이다.가을이면 오색단풍의 물경이 겨울이면 설경이 아름다운 곳이다. 이 산은 교통편이 좋아 쉽게 찾을 수 있고, 또 주위에 백암산, 적근산, 복주산 등 여러 산과 백운계곡이 유원지화되어 있어 올때마다 새로움을 느낄 수 있다.", "MNTN_HG_VL" : "699", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 광덕면, 아산시 송악면", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 철원군 서면, 화천군 사내면", "MNTN_NM" : "광덕산" }, - "longitude" : 127.034266, - "latitude" : 36.693891999999998 + "longitude" : 127.4307982, + "latitude" : 38.115392399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한북정맥에 들머리가 되는 광덕산은 경기도에서는 가장 북쪽에 위치한 산이며, 강원도 화천군과 철원군의 경계를 이루고 있으며, 거의 정상 부위까지 군사 비상도로가 개설되어 있고 산자락 곳곳에 군사시설이 있어 지형적으로 군사 요충지임을 말해주는 산이다.가을이면 오색단풍의 물경이 겨울이면 설경이 아름다운 곳이다. 이 산은 교통편이 좋아 쉽게 찾을 수 있고, 또 주위에 백암산, 적근산, 복주산 등 여러 산과 백운계곡이 유원지화되어 있어 올때마다 새로움을 느낄 수 있다.", + "DETAIL_INFO_DTCONT" : "충남 아산시 송악면과 천안시 광덕면의 경계를 이룬 광덕산은 높이에 비해 산세와 조망이 뛰어난 산으로 정평이 나 있다. 온양온천을 지척에 두고 있어 온천산행지로도 널리 알려진 광덕산은 천안, 아산, 공주의 분기점이자 금북정맥 상의 각흘고개와 갈재고개 사이의 무명봉에서 북쪽으로 갈래 쳐 천안시와 아산시를 가르며 뻗은 산줄기의 최고봉으로서, 흔히 내포지방이라 일컫는 아산, 당진, 서산뿐 아니라 평택, 천안, 대전 등 충남북 일원을 한눈에 조망할 수 있는 산이다. 크고 풍후(豊厚)하여 옛날부터 덕이 있다고 하는 광덕산은 난리가 나거나 불길한 큰 일이 있으면 산이 운다는 전설이 있으며 계곡에는 언제나 맑은 물이 흘러 곡교천의 상류가 되며 남록인 공주시 사곡면 운암리에는 유서 깊은 마곡사가 자리하고 있다.또한 호두나무가 풍성한 광덕사 주변은 갑신정변을 일으켰던 풍운아 김옥균, 임시정부 주석 김구 선생 등 역사적인 인물들이 은신했던 곳으로도 알려져 있다.", "MNTN_HG_VL" : "699", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 철원군 서면, 화천군 사내면", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 광덕면, 아산시 송악면", "MNTN_NM" : "광덕산" }, "longitude" : 127.034266, @@ -1046,28 +886,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 안산", "MNTN_NM" : "광덕산" }, - "longitude" : 127.034266, - "latitude" : 36.693891999999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "마산의 진산 무학산과 마주하고 있으며 여항산과 무학산을 이어주는 낙남정맥의 종주길이기도 하다. 무학산의 유명세에 눌리고 광려천 깊숙이 숨어 있어 그동안 알려지지 않았다. 최근 들어 내서읍이 개발되어 접근이 쉬워지고 낙남정맥을 종주하는 산꾼들에 의해 조금씩 알려지면서 찾는 사람들이 늘고 있다. 봄이면 광려산과 대산 사이 능선의 진달래와 얼레지 군락은 어느 유명산 못지않은 장관을 연출한다.내서읍 삼계마을 뒤쪽에 솟은 상투봉은 이 산의 주릉에 변화를 주고 있지만 산세는 부드럽다. 남릉은 쌀재에서 무학산의 산릉을 이어받아 길게 북으로 치달려 올라 감천마을을 포용하면서 옥수골을 만들어 놓는다. 동릉은 함안군으로 흘러나가고, 북쪽 사면은 산세를 열어 여항산으로 산기운을 보내고 있다.", - "MNTN_HG_VL" : "752", - "MNTN_LOCPLC_REGION_NM" : "경남 마산시 내서읍", - "MNTN_NM" : "광려산" - }, - "longitude" : 128.49108480000001, - "latitude" : 35.189903700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "괘관산은 함양군 서하면과 병곡면의 경계에 자리한 해발 1252미터의 듬직한 산이다. 덕유산과 남덕유산을 지나 전라남도와 경상남도의 경계를 이루며 남하하던 백두대간인 백운산에 이르러 동쪽으로 곁가지를 일으킨다. 이 산줄기는 다시 남과 북의 두 줄기로 나누어지고, 그중 남녘으로 내린 산줄기는 함양땅의 원통재(일명 빼빼재)를 내려 37번 도로에 이른다. 원통재에서 숨을 고른 산줄기는 서하면과 병곡면의 경계를 이루며 동북으로 힘차게 달려 괘관산과 도성산(1044m)을 일으킨 후 남간 상류에 이르러 끝을 맺는다.괘관산이란 이름은 북쪽의 서하면에서 바라보면 뾰족한 정수리가 ‘갓 걸이 산’으로 생각하기 십상이다. 그러나 괘관이란 이름에는 깊은 뜻이 숨어 있었으니 괘관이란 관에서 제정한 관을 쓰지 않고 걸어둔다는 뜻으로 벼슬을 내놓고 물러남을 이르는 말이다. 또한 경기도 개성의 경덕궁 북쪽에 괘관현이란 고개가 있었는데 조선 초 태조 이성계의 등극 때 고려의 유신들이 이 고개에서 관을 벗어 던지고 갔다 전한다.", - "MNTN_HG_VL" : "1252", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 서하면ㆍ병곡면", - "MNTN_NM" : "괘관산" - }, - "longitude" : 127.6988889, - "latitude" : 35.605277800000003 + "longitude" : 127.51833329999999, + "latitude" : 37.082222199999997 }, { "mountain" : { @@ -1076,8 +896,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 진주, 함안", "MNTN_NM" : "괘방산" }, - "longitude" : 128.99863020000001, - "latitude" : 37.713526999999999 + "longitude" : 128.30583329999999, + "latitude" : 35.225277800000001 }, { "mountain" : { @@ -1089,16 +909,6 @@ "longitude" : 128.99863020000001, "latitude" : 37.713526999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "괘일산(掛日山)은 해질녘 해가 산에 걸려있다고 해서 괘일이라는 이름을 썼다고 한다. 또한 그다지 높지 않은 산이지만 산세가 범상치 않아 예전부터 명산의 대열에 끼였으며, 호남정맥마루금에 솟아 담양 산성산에서 맥을 받아 광주 무등산으로 맥을 넘겨주는 이산은 멀리서 보면눈이 쌓인 것처럼 정상부 바위 벼랑이 하얗게 빛나 그런 이름을 얻었다고 한다.", - "MNTN_HG_VL" : "455", - "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 무정면", - "MNTN_NM" : "괘일산" - }, - "longitude" : 127.6522222, - "latitude" : 37.538611099999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -1111,33 +921,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구나무산 서남쪽 산자락에는 일명 물안골로 불리는 용추계곡이 자리잡고 있으며 이 계곡에는 용추폭포, 미륵바위, 소바위, 곰바위 등 볼거리가 널려 있다. 이름 그대로 구나무가 많아 구나무산이라 불린다.구나무는 참나무와 모양이 비슷한데 나무껍질이 두터워 병마게 재료로 많이 사용된다. 1930-40년대에는 구나무로 숯을 구웠다고 하는데 산행 중에 더러 숯가마를 볼 수도 있다. 구나무산은 아기자기한 면은 없으나 바위하나 없는 육산이라 험로가 없고 산행시간도 비교적 짧아 간편한 산행을 즐기는 이에게는 적격인 산이다.서울에서 가까운 거리에 있으면서도 주변의 명산들에 가려 빛을 보지 못하다가 최근에 등산객들이 많이 찾고있는 산이다. 주변에 청평자연휴양림, 아침고요수목원 등 도시나 복잡한 유원지를 피해 호젓히 자연속에서 여유로운 시간을 보내기에 좋은 곳이 많다.", - "MNTN_HG_VL" : "859", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", - "MNTN_NM" : "구나무산" - }, - "longitude" : 127.4788889, - "latitude" : 37.880833299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "구담봉은 충주호에 솟아 있는 높이 335미터의 작은 산으로 단양 8경의 하나이다. 물속에 비친 바위가 거북 무늬를 띠고 있어 구담봉으로 불리고 있다.이 산은 아담한 규모의 산으로 옥순봉과 함께 충주호 수상관광의 백미를 이루며 호수에서 보는 절경 못지않게 산행코스 또한 아기자기하다. 또한 제비봉과 금수산, 멀리는 월악산이 감싸고 있다. 퇴계 이황은 이 같은 구담봉의 장관을 보고 “중국의 소상팔경이 이보다 나을 수는 없을 것”이라고 극찬했다고 한다.조선 인종 때 백의재상 이지번이 벼슬을 버리고 이곳에 은거, 푸른 소를 타고 강산을 청유하며 칡넝쿨을 구담의 양안에 매고 비학을 만들어 타고 왕래하니 사람들이 이를 보고 신선이라 불렀다는 이야기도 전해져 온다.구담봉 산행은 제천시 수산면 경계선에 위치한 계란재에서 시작한다. 이 고개 오른쪽으로 제천시 구역임을 알리는 환영구조물이 있고 작은 주차장이 있다. 월악산국립공원 관리공단측에서 이 길만을 정규등산로로 개방하고 있다.", - "MNTN_HG_VL" : "373", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면 괴곡리, 계란리", - "MNTN_NM" : "구담봉" - }, - "longitude" : 128.24787660000001, - "latitude" : 36.941200700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "구담보은 물속에 비친 바위가 거북 무늬를 띠고 있어 붙여진 이름이다. 퇴계이항은 구밤보의 장관을 보고\"중국의 소상팔경이 이보다 나을 수는 없을것\"이라고 극찬했다고 한다.구담봉은 서북쪽으로 가까이 이어져 있는 옥순봉(玉荀峰.290m)과 함께 단양 8경 중의 하나로 손꼽히는 경관을 자랑하고 있다. 충북 제천시 수산면과 단양군 단양읍의 경계를 이루는 계란재에서 북동쪽으로 충주호 방향으로 뻗어 내린 능선에 솟아 있는 구담봉을 올라보면 주변 풍광에 누구나 탄성을 자아내게 한다.", - "MNTN_HG_VL" : "373", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 단양군", - "MNTN_NM" : "구담봉" + "DETAIL_INFO_DTCONT" : "구곡산 산행 기점은 진주서 중산리 가는길에 위치한 산청군 덕산리 덕산서원(조선시대 대유학자 남명 조식선생 사적지로 사적305호)이다. 약간 불투명한 하산길 말고는 험로는 없지만 무성한 산죽군락이 가을이면 누렇게 변해 황금능선이란 이름이 붙은 산행후반부는 산행 재미가 꽤 빼어나다.지리산 남부능선에 솟아 있는 산으로 대원사 길과 중산리 길이 갈라지는 덕산마을 서쪽에 있다. 이 산에서부터 국사봉을 거쳐 써리봉까지 이어지는 20여 ㎞에 이르는 능선을 일명 '황금능선'이라 하는데 이는 가을이면 산죽군락이 누렇게 변해서 붙여진 이름이다.황금능선의 가장 긴 코스는 구곡산 남쪽 마을인 외공마을에서 시작, 산청군의 4대 사찰 중 하나인 도솔암 직전의 왼쪽 계곡을 타면서 본격적인 산행에 나서게 되는데 산중턱에 있는 도솔암까지는 대개 차량으로 오른다.정상에는 정상석이 세워져 있으며, 천왕봉, 칠선봉, 삼신봉, 촛대봉, 장터목, 제석봉 등 이른바 남부능선의 봉우리들이 시원하게 펼쳐진다. 글자 그대로 아홉계곡이 있다고하여 구곡산이다. 구곡산은 황금능선의 들머리로서 능선에 서면 지리산 천황봉이 손에 잡힐듯이 가까워 보이며, 구곡산 정상에 서면 장괘한 지리산 주능이 가장 가까이 조망되고 봄이면 철쭉, 가을이면 단풍등 후회없는 산행이 된다.", + "MNTN_HG_VL" : "961", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청", + "MNTN_NM" : "구곡산" }, - "longitude" : 128.24787660000001, - "latitude" : 36.941200700000003 + "longitude" : 127.79553679999999, + "latitude" : 35.277158700000001 }, { "mountain" : { @@ -1149,16 +939,6 @@ "longitude" : 128.99967799999999, "latitude" : 35.122726499999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "구두산은 설천면사무소가 있는 남양마을 조금 못미쳐 있는 문의마을 산길을 따라 오른다. 문의마을에서 걸어 올라가면 1시간, 차량으로는 약10분 정도 걸린다.구두산 정상에서 바라보면 삼면은 바다요 남쪽은 연봉이다. 크고 작은 섬은 여기저기 떠 있고 그 사이를 떠가는 일엽편주, 물위를 날듯 하얀 물줄기를 가르며 경쾌하게 달리는 한려수도의 쾌속선 엔젤호, 바다 건너 넓은 들녘과 높고 낮은 산, 그리고 촌락이 군데군데 떼지어 모여 앉아 있다.동으로 삼천포, 사천, 북으로 바다건너 금오산의 성급한 산줄기가 내리 뻗고 서쪽으로 섬진강 하류, 광양, 모두가 고요 속에 잠겨 한 편의 시를 읊고 있는 기분이다. 산정에서 북쪽으로 조금 내려가면 남해대교가 굽어보인다.", - "MNTN_HG_VL" : "618", - "MNTN_LOCPLC_REGION_NM" : "경상남도 남해군 설천면 덕신리", - "MNTN_NM" : "구두산" - }, - "longitude" : 128.60313009999999, - "latitude" : 35.179795800000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "구룡산(九龍山) 정상은 해발307.7m의 서울특별시 서초구 염곡동, 내곡동, 양재동과 강남구 개포동 일대에 위치한 산이다. 구룡산은 열 마리의 용이 승천하는 것을 인근을 지나가던 임신한 여성이 보고 크게 놀라 소리를 질러 용 한마리가 떨어져 죽고, 아홉 마리만 하늘로 승천하였다고 한다. 아홉 마리의 용이 승천하면서 남긴 흔적이 구룡산이라 불리게 되었으며, 하늘에 승천하지 못하고 죽은 용이 있던 자리가 물이 되어 양재천(良才川)이 되었다는 전설이 있다. 실제로 산을 자세히 보면 9개의 계곡으로 이루어져 있다.정상보다 낮은 이 산의 주봉(主峰)은 국수봉(國守峰)이라고 하는데, 조선시대 전부터 정상에 봉수대(烽燧臺)가 있어 국가를 지킨다고 해서 붙여진 것으로 이 곳에는 바위굴 국수방(國守房)이 있어 봉수군(烽燧軍)이 기거했다고 한다. 『여지도서』 광주목에\"관아의 남쪽 30리에 있다. 봉수대가 설치되어 있다\"고 기록되어 있다.내곡동에 있는 헌인릉과 함께 구룡산 기슭에 세종대왕이 묻힌 영릉(英陵)이 있었으나, 1469년(예종 1년)에 여주로 천장(遷葬)하였다. 초장지(初葬地)였던 구룡산 내곡동에 국가정보원이 들어서 있다.구룡산 제2봉인 국수봉전망대는 서울 강남.강북과 경기도 한강하류와 상류지역까지를 관망할 수 있는 최적지로 주.야경 조망명소이다.약 300m의 산으로 산높이나 길이 험하지 않아 가족과의 산행코드로는 제격이며, 접근성도 용이하여 부담없이 즐길 수 있다.구룡산에는 능인선원과 자룡사가 있다. 2015년 9월 13일 능인선원에 세계 최대 약사여래좌불을 점안하여 이름을\"서울약사대불\"이라 하였다.이 산에는 자작나무과인 수피가 얇은 종잇장처럼 벗겨지는 물박달나무 군락지가 산재해 있으며, 그 외에 신갈나무, 리기다소나무, 아까시나무 등이 있다. 관악산, 청계산, 우면산 등과 산자락이 이어진다.", @@ -1169,16 +949,6 @@ "longitude" : 127.0572222, "latitude" : 37.469166700000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;대청호 전망대라 불리는 조망 명산gt;1980년 대청댐의 완공으로 문의면 4075세대가 물에 잠겼다. 댐 건설로 주변지역은 잦은 홍수와 가뭄으로부터 벗어났지만 고향을 잃은 이들에겐 그 무엇으로도 위로가 되지 않았다. 물끄러미 물속만 들여다 볼 수밖에. 대청댐 서쪽 바로 옆으로 솟은 구룡산. 정상에서 대청호 조망은 물론, 대청댐 주변 풍광이 한눈에 들어온다. 이 때문에 구룡산은 실향민들에게 조금이나마 위로가 될 수 있는 곳이기도 하다. 또한 이곳은 군사정권 시절 군인들이 보초를 서던 곳이기도 했다. 건너편으로 훤하게 들여다보이는 ‘청남대’ 때문. 당시에는 대통령 전용 별장이었지만 지금은 시민들에게 개방되어 있다. 이처럼 구룡산은 대청호 인근에서 전망대 역할을 하고 있다고 해도 과언이 아니다. 하지만 이 외에도 정상 바로 아래의 장승공원과 현암사가 있어 등산객들은 물론 대청호를 찾은 많은 관광객들을 불러 모으고 있다. 장승공원 입구까지는 승용차로도 갈 수 있으니 부담 없이 산을 오를 수 있다.", - "MNTN_HG_VL" : "373", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면 덕유리, 현도면 하석리", - "MNTN_NM" : "구룡산" - }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "구룡산은 강원도 영월군 수주면을 감싸 흐르는 서만이 강변에서 북쪽으로 솟아 있는 산이다. 구룡산 남쪽 산자락 끝에 위치한 '섬안'이라는 마을을 동, 남, 서쪽으로 감싸 흐르는 강줄기 이름이 서만이강인데 옛날 명칭은 '섬안이강'이라고 전해지고 있다.정상에 오르면 치악산과 매화산이 스카이라인을 이루고, 산갓봉, 화채봉, 백덕산, 사자산, 돼지봉, 배거리산 등 숲겨지 명산들이 주변에 있고, 선달산과 소백산, 금수산까지 보인다. 때묻지 않고 수수하며 능선과 깨끗한 계곡이 좋고, 사철 등산하기에도 그만이다.", @@ -1186,38 +956,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", "MNTN_NM" : "구룡산" }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "370", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 현도면, 문의면", - "MNTN_NM" : "구룡산" - }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "373", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면 덕유리, 현도면 하석리", - "MNTN_NM" : "구룡산" - }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "여름철 등산지는 열차를 이용하는 편이 보다 편리하다. 중앙선 판대역에 내려 철길을 따라 원주쪽으로 조금 이동한 후 통운판대 출장소가 있으며, 이집 뒤쪽으로 돌아서 연화정사에 이르게 된다.연화정사는 일요일에 학생들을 모아 포교하는 아담한 사찰이다. 절에서 나와 동쪽 길을 따라 고개를 넘으면 하구재 마을에 당도한다. 지리내미골을 통해 400봉에 올라 정상으로 가는 도중에 암봉이 있는데, 이곳에서는 구룡골 일대를 한눈에 조망할 수 있다.", - "MNTN_HG_VL" : "479", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 지정면", - "MNTN_NM" : "구룡산" - }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 + "longitude" : 128.21341229999999, + "latitude" : 37.3214763 }, { "mountain" : { @@ -1279,6 +1019,66 @@ "longitude" : 128.25140740000001, "latitude" : 37.362444199999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 용인의 구봉산은 속리산에서 뻗어 나온 한남금북정맥 선상에 위치하고 있다. 산명에서도 알 수 있듯이 많은 봉우리로 이루어진 구봉산에는 재미있는 전설이 전해오고 있다.예전 구봉산 자락인 용인군 원삼면 일대가 도읍지가 될 자리였는데 당시 1백개의 봉우리로 이루어진 구봉산이 어느날 큰 홍수로 끝봉우리가 떨어져 나갔고 이로 인해 이곳이 도읍지가 되지 못했다고 한다.구봉산 산행은 산의 동북쪽 끝인 외사면 근창리 창동에서 시작된다. 등산로는 인적이 적은 만큼 호젓한 산행의 재미를 느낄 수 있다. 이러한 소로길을 따라가다 보면 만나는 뾰족한 봉우리는 414봉이다. 정상은 여기에서 건너편 산줄기를 1시간 30분 정도를 더 걸어야 만날 수 있다. 정상에서는 고삼저수지와 주변의 너른 평야가 한눈에 들어온다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 원삼면, 외사면", + "MNTN_NM" : "구봉산" + }, + "longitude" : 127.3269444, + "latitude" : 37.120555600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "440", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "구봉산" + }, + "longitude" : 127.7820761, + "latitude" : 37.891676400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전북 진안군 주천면과 정천면 경계에 우뚝 솟은 구봉산(九峰山)은 아홉 개의 봉우리가 시원한 조망을 보여주는 전망 좋은 산이다. 주봉인 천황봉(장군봉)과 8개의 봉우리는 설악산의 공룡능선처럼 험준하게 솟아 있는데, 각각의 봉우리에 오를 때 마다 서쪽으로는 복두봉과 운장산, 남쪽으로는 부귀산과 마이산의 두 봉우리가 선명하며, 동쪽으로는 덕유산을 위시한 백두대간 능선이 한눈에 펼쳐진다.<>구봉산은 연꽃산이라고도 불리는데, 천황봉을 제외한 8개의 봉우리가 막 피어오르는 연꽃을 닮았다고 해서 붙여진 이름이다. 훌륭한 조망과 함께 북쪽으로 운일암 반일암계곡과 남쪽의 갈거리계곡 등 크고 아름다운 계곡을 끼고 있고, 용담댐과 메타쉐콰이어 길 등 볼거리가 많아 사람들의 발길이 계속 이어지고 있다.<>구봉산 남동쪽으로는 875년 창건한 천황사가 자리하고 있는데, 천황사 앞 전나무는 국내에서 가장 규모가 크고 아름답기로 정평이 나 있다.", + "MNTN_HG_VL" : "1002", + "MNTN_LOCPLC_REGION_NM" : "전북 진안군 주천면ㆍ정천면", + "MNTN_NM" : "구봉산" + }, + "longitude" : 127.4168889, + "latitude" : 35.924352599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "178", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", + "MNTN_NM" : "구봉산" + }, + "longitude" : 126.4441667, + "latitude" : 37.525833300000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "호남고속도로를 지나면 차창으로 아름다운 구봉산을 볼 수 있다. 아홉 봉우리의 산이라는 뜻의 구봉산은 높이가 264미터로 낮은 산이지만 바위봉우리가 늘어서 있는 경관이 매우 아름다워 신선이 내려와 노닌다는 전설이 전해지고 있다. 또 다른 이야기로는 구봉산이 아홉 마리의 봉황새 모양이어서 새 봉(鳳)자를 쓴 구봉산(九鳳山)이라 부른다는 이야기도 있고 구봉산의 아홉 개 봉우리가 마치 대신들이 한 줄로 늘어서서 허리를 굽히고 계룡산 신도 안으로 들어가는 형국의 산세라 하여 ‘군신입조형(君臣入朝形-신하들이 임금을 뵈려고 조정에 들어가는 형국)’의 명산이라고 한다. 재미있는 것은 아홉 바위 봉우리 가운데 맨 동쪽, 대전 중심부 가까이 있는 봉우리만이 계룡산을 외면하고 있어 아홉 신하 가운데 한 사람은 반역을 꾀한다는 이야기도 있다.", + "MNTN_HG_VL" : "264", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구 가수원동", + "MNTN_NM" : "구봉산" + }, + "longitude" : 127.3343871, + "latitude" : 36.2865854 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구봉산은 남,여 등산객들의 발길이 끊이지 않아 사방에서 등산할 수 있도록 등산로가 잘 정비되어 있으며, 정상에서는 시내를 한눈에 바라볼 수 있고,특히 여수항과, 오동도, 돌산대교를 먼저 볼 수 있다. 국동, 봉산동에서 오르는 길중턱 한산사 아래의 약수는 질이 좋아 여수시민들이 많이이용하며 체육시설도 잘 가꾸어져 있다. 한산사는 여수 8경중 3경으로 한산사에서 내려다 보면여수앞바다의 전경이 매우 아름답다.구봉산은 밑에 서당이 있었다 하여 서당산 이라고도 하며, 하홉마리 봉황이살다가 이 곳에서 승천했다는 전설에 따라 산 이름이 붙여다고 하는데, 정상에거암이 솟은 잔구가 있어 산악의 미가 돋보인다.", + "MNTN_HG_VL" : "388", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "구봉산" + }, + "longitude" : 127.70833330000001, + "latitude" : 34.737777800000003 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "전북 김제시 금구면과 금산면의 경계를 이루는 구성산은 모악산이 서북쪽으로 가지를 친 지맥선상에 위치해 있다.모악산과 마주한 형태로 서있는 구성산은 그리 높지는 않지만 정상에 서면 만경강과 동진강이 빚어놓은 김제 평야의 광활함이 한눈에 들어온다. 모악산의 명성에 눌려 찾는 등산객들이 별로 많지는 않지만 그만큼 훼손 안된 자연의 상태를 유지하고 있다.이 산과 모악산에서 모아진 수자원으로 이루어진 금평저수지 주변에는 각종 신흥종교가 번창했던 곳으로 산 남쪽 기슭에 자리잡은 학선암과 전주-금산간 도로변의 유서 깊은 국신사를 비롯, 도처에 기도처가 남아 있어 신흥종교 신봉자들이 적지 않게 찾아온다.", @@ -1291,23 +1091,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "바다와 인접한 구수산은 짭짤한 바다내음을 맡으며 산을 오를 수 있다. 그리 높지않은 산으로 일반인들에게 잘 알려지지 않은 탓인지 등산객들의 발길은 뜸하다.원불교 창시자인 소태산 박중빈(1891-1943)이 태어나 득도한 영산성지 북서쪽에 자리한 산이다. 바다와 인접한 산인 만큼 정상이나 주능선에서 휘둘러 보는 조망이 일품이다. 북쪽으로는 계마리 금정산(264m)의 왼쪽, 서해바다에 떠 있는 위도가 가물거린다. 금정산 오른쪽 아래로는 옛날 우리나라로 불교가 처음 들어왔다는 법성포가 뚜렷하게 보인다.산자락 끄트머리에는 원불교의 상징인 동그란 원이 산꼭대기 바위벽에 그려져 있는 옥녀봉(152m)이 솟아 있다.", - "MNTN_HG_VL" : "351", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군", - "MNTN_NM" : "구수산" - }, - "longitude" : 128.552392, - "latitude" : 35.938760000000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "갓봉은 북동쪽에 위치한 구수산의 하위 봉우리지만 갓봉에서 봉화령을 거쳐 뱀골봉으로 이어지는 남북으로 길게 뻗은 능선은 총 8.6킬로미터에 이르러 구수산 정상을 거치지 않는 하루 산행으로 능히 만족스러운 산이다. 특히 봉화령을 지나면서 뱀골봉까지 펼쳐진 능선길은 아름다운 서해바다를 바라보며 산행할 수 있어 일품이다.원불교 창시자인 소태산 박중빈이 태어나 득도한 영산성지 북서쪽에 자리하고 있으며, 북쪽으로 금정산이, 서쪽으로는 위도가 보인다. 우리나라 불교가 처음 들어왔다는 법성포도 뚜렷하다.갓봉 직전 갈림길에서 수리봉으로 향하는 등산로가 나 있으나 정비가 되지 않아 길이 험해 대부분은 갓봉에서 뱀골봉까지 이어진 등산로를 이용한다.모재봉에서 내려서는 길은 가라프고, 봉화령에서 오르는 암릉구간은 미끄럽기 때문에 겨울철에는 조심해야 한다.능선상에 샘이 없으므로 산행시 물을 충분히 준비하는 것이 좋다.", - "MNTN_HG_VL" : "344", - "MNTN_LOCPLC_REGION_NM" : "전라북도 영광군 백수읍", - "MNTN_NM" : "구수산 갓봉" + "DETAIL_INFO_DTCONT" : "구왕봉은 백두대간의 주봉인 희양산(998m)의 서쪽에 위치한 산이다. 바위로 이루어진 구왕봉은 바로 이웃한 희양산의 명성에 눌려 찾는 등산객의 수가 그리 많지 않아 깨끗한 자연 그대로의 모습을 유지하고 있는 산이다.구왕봉은 깨끗한 등산로와 아기자기한 능선길이 등산하는 즐거움을 느낄 수 있는 산이지만 급경사 암릉지대도 있으므로 보조자일을 준비하는 것이 좋다. 구왕봉 자락에는 신라 헌강왕 5년 지증대사에 의해 창건된 유서깊은 사찰인 봉암사가 자리하고 있다. 또한 지름티재의 가을 정취는 아름답기 그지없다.충분한 습도와 풍부한 영양으로 단풍의 색깔이 다른 지역보다 곱고 색도 가지가지여서 산행을 하는 이들의 마음까지도 온통 울긋불긋하게 물들고 만다.", + "MNTN_HG_VL" : "877", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면", + "MNTN_NM" : "구왕봉" }, - "longitude" : 126.4066955, - "latitude" : 35.300632200000003 + "longitude" : 127.9833333, + "latitude" : 36.716666699999998 }, { "mountain" : { @@ -1326,8 +1116,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 신풍면", "MNTN_NM" : "구절산" }, - "longitude" : 128.42027780000001, - "latitude" : 35.024722199999999 + "longitude" : 126.97027780000001, + "latitude" : 36.487777800000003 }, { "mountain" : { @@ -1336,28 +1126,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천군 북방면", "MNTN_NM" : "구절산" }, - "longitude" : 128.42027780000001, - "latitude" : 35.024722199999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "구천산의 정상 아래에는 망바위가 있고 망바위에 올라서면 남쪽으로 원동의 토곡산과 천태산, 금오산이 동북쪽으로 가지산, 천황산, 운문산 등 영남 알프스의 준봉들이 눈에 쏙 들어온다. 망바위에서 조금 더 가면 구천산 정상(620m). 누군가 정상 바위 위에 정성스럽게 돌탑을 쌓아 놓았다. 정상 가는 길은 제법 길이 험하기 때문에 조심해야 한다.만어산의 옛 이름은 마야사산이다. 마야사는 고기를 일컫는 옛말이다. 사기에는 만어산에 나찰녀 다섯이 있어서 동해의 독용과 왕래하면서 사귀었다. 그런 이유로 때때로 번개가 치고 비가 내려 4년 동안 오곡이 익지 못했다. 왕은 주술로써 이것을 금하려 했으나 금하지 못하고 부처에 청하여 설법했더니 그제야 나찰녀는 오계를 받아 그 후로는 재해가 없어지고 동해의 물고기와 용이 산 중에 가득찬 돌이 되어서 각각 종과 경쇠의 소리가 난다고 전한다.이러한 전설을 뒷받침하듯 산복부에는 만어군이라 일컫는 너덜겅이 넓고 길게 이어져 장관이다. 돌부리가 한결같이 동해를 향해 누운 듯한 바위군들은 두드리면 맑은 쇳소리가 나 신비감을 자아낸다. 밀양강이 활처럼 휘어져 흐르고 밀양의 큰 들인 상남벌이 너르게 펼쳐져 있는 모습을 보면서 산행하면 즐거움이 한층 더할 것이다.", - "MNTN_HG_VL" : "620", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진", - "MNTN_NM" : "구천산" - }, - "longitude" : 128.87570880000001, - "latitude" : 35.440996499999997 + "longitude" : 127.831547, + "latitude" : 37.772691899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "579", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 장마면, 계성면", - "MNTN_NM" : "구현산" + "DETAIL_INFO_DTCONT" : "구학산은 충북 제천시 백운면,봉양면과 강원도 원주시 신림면의 경계를 이루는 산이다. 남쪽 끝머리에 자리한 남대봉(1,187m)에서 서남쪽 백운산(1,087m)으로 뻗어 내리던 능선이 백운산 정상을 약 2km 남겨둔 981m봉에서 동남쪽으로 뻗어 내린 능선이 구력재를 지나 첫 번째로 높이 솟아 있는 산이다.구학산을 일으킨 능선은 남쪽으로 흘러내리며 주론산을 빚어 놓은 뒤, 남쪽으로 이어지다 박달재에서 맥을 낮추어 박달재를 이루고, 다시 고도를 높이며 시랑산(691), 면위산(780), 마미산(601)을 빚어 놓고 그 여맥을 충주호에 가라앉힌다. 산 이름에는 유래가 있듯이, 구학산에는 옛날 이 산에서 살던 아홉 마리의 학이 사방으로 날아가 아홉 군데의 '학'자가 들어가는 지명이 생겨났다는 전설이 전해 내려오고 있다.구학산에서 살던 아홉 마리의 학이, 신림 방면의 황학동, 상학동, 선학동과, 봉양 방면의 학산리와 구학리, 백운면 방면의 방학리와 운학리, 송학면의 송학산과 충북 영동의 황학산으로 한 마리씩 날아가 마을 이름이 생겨났다고 한다.구학산은 부드러운 능선으로 이어져 적설기 등산지로 좋고, 때묻지 않은 오지 농촌의 순박한 풍경을 볼 수 있어 더욱 좋다. 구학산은 산 전체가 육산으로 울창한 수림으로 덮여 있으나 정상은 바위로 돌출 되어 있어 전망이 좋은 편이다. 북으로는 백운산이 가깝게 보이고, 동으로는 감악산, 석기암산, 용두산과 제천시가 아스라히 보인다. 남으로는 주론산과 시랑산 사이로 박달재 고갯길이 보이고, 서쪽으로는 촉새봉(십자봉)과 삼봉산이 한눈에 들어온다.", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", + "MNTN_NM" : "구학산" }, - "longitude" : 128.53222220000001, - "latitude" : 35.513055600000001 + "longitude" : 128.04027780000001, + "latitude" : 37.188888899999988 }, { "mountain" : { @@ -1369,16 +1149,6 @@ "longitude" : 128.53222220000001, "latitude" : 35.513055600000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;송이 향 진동하는 화왕산 전망대gt;창녕의 진산인 화왕산(757m)에서 곧장 남쪽으로 뻗어 내린 산줄기 끝에 뿔처럼 솟은 산이 구현산(579m)이다. 산꾼들 사이에서는 이 산줄기가 화왕지맥으로 통한다. 구현산 산행은 보통 남쪽의 삼성암에서 올라 돌탑봉, 556봉을 지나 구현산, 쌍교산을 거쳐 여초리로 내려서거나 여초저수지에서 석대산으로 올랐다가 구현산, 쌍교산을 거쳐 법성불원으로 내려서는 코스를 택한다. 또 구현산에서 비들재 지나 화왕산, 관룡산까지 이어가는 능선산행도 인기다. 법성불원에서 쌍교산으로 오르는 길이 꽤 가파르다. 이후 능선은 걷기 좋은 산길이다. 쌍교산을 지나면서 조망이 트이는 바위들이 곳곳에 나타나고 화왕산과 관룡산 방면의 조망이 빼어나다. 특히 삼성암으로 갈리는 556봉과 석대산에서의 조망은 그야말로 압권이다. 남쪽으로 옥천저수지 건너 우뚝 솟아 오른 병봉(674m)과 영취산(681m)이 가슴 시원한 풍광으로 펼쳐진다. 구현산 일대는 온통 소나무로 가득하다. 송이 생산지로도 유명해 일대 마을마다 가을이면 송이채취로 온 마을이 떠들썩하다.", - "MNTN_HG_VL" : "579", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍, 장마면, 계성면", - "MNTN_NM" : "구현산" - }, - "longitude" : 128.53222220000001, - "latitude" : 35.513055600000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "충주시 앙성면에 위치한 국망산의 옛이름은 금방산이었다.국망산으로 불리워지게 된 세월은 그리 길지않다. 임오군란 당시 명성황후가 이곳으로 피난을 오게 됐다. 피난을 와서 한양소식이 궁금한 황후는 매일 이 산마루에 올라가 한양을 바라보며 초조해 했었다는데서 국망산이라 불려지게 된 것이다.당시 황후는 충주목사인 민옹식의 집으로 피난을 가기로 하였으나 피난지가 알려지면 신변이 위험할 것 같아 이곳으로 피한 것이다. 황후가 피신한 집은 가난한 초가집이었는데 그 집에는 이도령이라는 총각이 홀어머니를 모시고 나무장사를 하면서 살고 있었다. 이도령은 가난하였으나 황후를 극진히 대접하였다.황후가 피난생활을 마치고 환도한 후 이 도령을 불러 사례하고자 하였으나 사양하여 황후는 이 도령에게 음성군수를 시켰다. 이도령은 군수 재직중 선정을 베풀어 주민들로부터 칭송을 받았으며 그 후 5개 마을의 군수를 지냈다. 마을에서는 이 도령의 집을 이음성집이라 부르고 그의 집터를 대궐터라고 부르고 있다.", @@ -1391,23 +1161,33 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "국봉은 충북 단양군 적성면과 제천시 청풍면의 경계를 이루는 산으로, 금수산에서 북서쪽으로 이어지는 능선이 갑오고개에서 맥을 낮추었다가 북서쪽 동산(東山.896m)으로 이어지는 능선상 700m봉에서 동쪽으로 뻗어 내린 지능선에 솟아 있는 산이다.국봉에 이르는 등산로에는 약 100여 미터 높이의 만경대를 비롯해 촛대바위 등 암릉이 곳곳에 널려 있어 산행시 주의를 요하는 곳이다. 국봉 정상은 굴참나무로 둘러 싸여 전망이 시원치 않으나 능선 곳곳의 암릉이 주변의 경관을 보여 주어 산행 재미를 더해준다.", - "MNTN_HG_VL" : "628", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군, 제천시", - "MNTN_NM" : "국봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "399", + "MNTN_LOCPLC_REGION_NM" : "충청남도공주", + "MNTN_NM" : "국사봉" }, - "longitude" : 126.41918939999999, - "latitude" : 34.803756900000003 + "longitude" : 127.22861109999999, + "latitude" : 36.410277800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경주 주변에 있는 모든 산들의 산세가 왕도에 대하여 경의를 표하는 자세인데, 유독 국수봉만은 그 자세가 나라에 반역하는 것처럼 등을 돌리고 앉았다 하여, 나라國자와 원수讐자의 이름을 붙여 국수봉으로 불리워 왔다. 또한 구전에 의하면 신라 때에 형을 받은 죄인들은 이곳에 유배시켰다 한다.지금의 은을암 주지 스님은 讐자를 守자로 바꾸어 재치있게 國守峰으로 표기하고 있다. 스님 말씀에 讐자를 守자로 표기한 것은, 서라벌을 등지고 일본을 향하고 있는 것은 신란 경주에 등 돌렸다기보다는 일본으로부터 나라를 지킨다고 보아야 한다는 것이다.높거나 험하지 않아 부담없는 산행이나 아침운동을 즐기기에 적당한 산이다.", - "MNTN_HG_VL" : "603", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "국수봉" + "DETAIL_INFO_DTCONT" : "미타산에서 남으로 뻗어 내린 산릉의 끝머리에 암봉이 불쑥 고개를 내밀고, 산릉을 좌우로 마치 날아가는 독수리가 나래를 편 형세로 자리잡고 있는 산이 의령군민들에게 사랑을 받고 있는 국사봉이다.합천군 대양면, 의령군 봉수면에 걸쳐 산역을 펼치고 있는 이 산은 인근 주민들 이외는 별로 알려진 산은 아니지만 아기자기한 암릉과 깨끗한 산의 모습이 산객들에게 호감을 주고 있다.국사라는 이름을 가진 산에는 옛날 나라일에 관해 행사를 치렀다는 기록이 남아 있다.", + "MNTN_HG_VL" : "613", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 봉수면", + "MNTN_NM" : "국사봉" + }, + "longitude" : 128.2488889, + "latitude" : 35.492777800000013 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "239", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "국사봉" }, - "longitude" : 127.27972219999999, - "latitude" : 37.4091667 + "longitude" : 126.41622390000001, + "latitude" : 37.383214000000002 }, { "mountain" : { @@ -1419,26 +1199,6 @@ "longitude" : 128.6382653, "latitude" : 36.198841799999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "403", - "MNTN_LOCPLC_REGION_NM" : "전라남도 함평군,영광군", - "MNTN_NM" : "군유산" - }, - "longitude" : 126.41355950000001, - "latitude" : 35.156066299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "199", - "MNTN_LOCPLC_REGION_NM" : "경기도 시흥", - "MNTN_NM" : "군자봉" - }, - "longitude" : 126.805131, - "latitude" : 37.358890000000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "산행은 쌍곡리에서 시작한다. 쌍곡계곡에서 시원스런 나무숲 사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2미터 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다. 원효굴에서 조금 더 가면 첫 봉우리에 이른다. 다시 고개 하나를 지나면정상이다. 하산은 서남쪽 고개를 돌아 계곡을 타고 내려온다. 큰군자산 종주 코스는 비지정등산로이며 현재 국립공원 지정등산로는 소금강 - 큰군자산 - 도마골 정도니 그 외 등산로는 허가를 받아야 한다.", @@ -1449,36 +1209,6 @@ "longitude" : 127.87860019999999, "latitude" : 36.737540799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "굴암산은 경남 김해시와 진해시를 북남으로 가르고, 부산광역시마저 능선으로 금을 그은 요충의 산이다. 지리산에서 비롯되어 김해의 동신어산(459.6m)까지 산줄기를 이어간 낙남정맥의 주능선은 창원시와 김해시의 경계를 이룬 용지봉(723m)에서 한줄기 곁가지를 남쪽으로 뻗어 내린다. 이 산줄기는 성주사로 유명한 불모산(802m)을 일으킨 후 다시 두 줄기로 나누어진다. 남쪽으로 내리는 한 줄기는 웅산(703m), 장복산(582.2m), 천자봉(503m) 등을 일으키고, 동녘으로 달리는 또 다른 한 줄기는 화산(798m)과 굴암산, 보배산(479m)을 일으킨 후 남해바다에 스르르 잠기게 된다. 3월말 정상에서면 벚꽃이 만개해 인산인해를 이루는 진해시와 낙동강 하구둑, 가덕도, 안골포, 거제도 등이 푸른 남해와 어울린 멋진 풍광을 볼 수 있다.인근 주민들이 팔판천이라 부르는 계곡이 있어 팔판산이라고도 한다. 능선 남쪽 자락 끝부분에는 용추폭포가 있다. 사람들의 발길이 없어 호젓한 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "663", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 웅동, 김해시 장유면, 부산광역시 강서구 지사동", - "MNTN_NM" : "굴암산" - }, - "longitude" : 128.78995459999999, - "latitude" : 35.157104699999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "궁산은 궁산이란 이름 외에 파산, 성산, 진산, 관산등의 이름을 가지고 있다. 백제의 옛날 고성지가 있었으며, 조선조 화가인 겸재 정선이 양천 현령으로 재임하면서 그림을그렸던 소악루가 있고 오랜 세월동안 인물을 배출한 양천 향교가 있다. 임진 왜란때 의병의 집결장소였으며, 조선시대에는 우리고장의 행정 중심지 였다. 한강과 마주하고 있으며 북쪽으론 경사가 가파르며 남쪽으로는 완만하다. 정상 부근엔 평지가 있고 한강 전경을 볼수 있는 조망소도 위치하고있다.", - "MNTN_HG_VL" : "74", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 강서구 가양동", - "MNTN_NM" : "궁산" - }, - "longitude" : 128.4833333, - "latitude" : 35.868333300000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "금정면 세류리의 기동 마을에서 북서쪽으로 조금 떨어진 곳에 있는 이 산은 산 정상부에 산성이 있었다 하여 궁성산이라 이름 붙었다. 현재는 대부분 도괴된 상태로 그 흔적만이 일부 남아 있다.이 궁성산성은 그 유래에 대한 기록이 전혀 없어 정확한 축성연대와 용도 등은 알 길이 없다. 하지만 주민들은 임진왜란 당시 이곳에서 군사와 말을 훈련시키고 화살을 쏘는 연습장으로 활용되어 '활터'라 불렀다고 전한다.지형상으로는 장흥 유치나 금정 청룡리를 경유해 쳐들어오는 왜구를 방어하기 위한 산성으로 판단된다.또한 일부에서는 월출산과 활성산에서 전달된 신호를 전하는 봉화대였을 것이라는 주장도 있다.또한 역사적으로 임진왜란과 한국전쟁을 온몸으로 겪으면서 아파했던 곳이기도 하다. 등산로가 잘 닦여있지 않으며, 가시덤불이 너무 많아 힘든 면이 있지만 겨울에는 나름대로의 묘미를 주기도 한다.궁성산은 산의 높이가 484.2m로 규모가 큰 것도 아니고 산세가 수려하지도 않다. 그러나 역사적으로 임진왜란이나 6.25동란을 거치며 전쟁의 소용돌이가 끊이지 않았던 곳으로 아픈 역사의 단면을 간직한 곳이다.", - "MNTN_HG_VL" : "484", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 금정면, 나주시 봉황면", - "MNTN_NM" : "궁성산" - }, - "longitude" : 128.19955880000001, - "latitude" : 37.106391000000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "동쪽과 북쪽은 지세가 험하여 일반등산화 이상을 싣고 등반하여야 하는 곳이다.자연 경관은 산불피해를 입어서 앙상한 나뭇가지들이 있어 경관을 헤치고 있다.강원도 삼척시 미로면에 위치한 근산은 삼척에서 자랑하는 미로 8경중의 하나이다. 강을 건너는 나무다리가 오십개나 있었다 해서 이름 지어진 오십천에 물을 보태는 근산은 삼척에서 바라보면 마치 우산을 펼쳐 세워 놓은 것처럼 보인다.원시림을 그대로 간직하고 있고 동해바다를 끼고 오르는 산과 바다를 즐길 수 있는 산행을 즐길 수 있다", @@ -1489,16 +1219,6 @@ "longitude" : 129.1358333, "latitude" : 37.407777799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "505", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면 내미로리", - "MNTN_NM" : "근산" - }, - "longitude" : 129.1358333, - "latitude" : 37.407777799999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강과 바다 들녘이 어우러진 서남쪽 끝머리에 자리 잡은 해남에는 먼 이북의 아름다운 금강산과 토시 하나 틀리지 않는 똑같은 이름을 가지고 있는 금강산이 자리하고 있다. 기암괴석으로 된 암장과 아열대 수림으로 덮여 있고, 봄이면 춘란이 무리지어 갈잎 속에 꽃대를 올려 개화를 시작한다.lsquo;옥녀탄금rsquo;의 형상이라는 해남읍의 지형에서 가야금을 타는 선녀에 해당하는 금강산은 병풍처럼 해남읍을 두르고 있고 정상에는 금강산성이 성곽을 이루고 있으며 아래로는 은적사, 금강폭포, 미암 등이 자리하고 있다. 해남에 이름 있는 많은 산들의 유명세에 가려서 사람들이 많이 찾는 곳은 아니지만 비교적 산을 오르기 쉬우며 사람의 발길이 닿지 않는 야생의 모습을 그대로 간직하고 있는 산이다. 크고 작은 돌무더기와 암벽들을 산길 곳곳에서 접하게 되고, 인적이 드물어 사람의 흔적이 묻어나지 않은 억새풀 숲과 수목들로 가득 차 있어 조바심을 내지 않고 트레킹 하는 기분으로 천천히 오르기에 알맞은 산행을 즐길 수 있다.", @@ -1506,18 +1226,18 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 마산면", "MNTN_NM" : "금강산" }, - "longitude" : 128.10495800000001, - "latitude" : 38.6566951 + "longitude" : 126.5997222, + "latitude" : 34.591666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "진도의 금강이라 불리고 있는 金骨山. 군내면 둔전리에 위치한 금골산은 200미터도 채 안 되는 낮은 산이지만 개골산이라는 다른 이름이 말해주듯 산 전체가 기암괴석으로 형성된아름다운 산으로 석굴 세 개와 더불어 금성초등학교의 교정에 있는 고려말에 세워진 5층석탑(보물 제 529호)과 산 중턱의 굴에 마애여래좌상(전남 문화재자료 제 110호)이 음각되어 있으며 해언사라는 절이 있었는데 최근에 복원되었다.1498년 정언벼 슬을 지낸 이주(李胄)가 무오사화때 이곳에 유배되어 금골산의 아름 다움에 감탄,『금골산록』을 지어 서거정의 동문선에 실려 오늘에 전 해오고 있다.석수가 수만 년에 걸쳐 예술품을 조각해 놓은 듯 층층인가 하면 구멍이고, 구멍인가 하면 기둥이고, 사람인가 하면 짐승인 모습을 보여주며 기암의 색깔 또한 황색, 백색, 흑색, 회색 등으로 다양하다.산 아래 자리한 아담한 학교에 있는 보물 제 529호 금골산 오층 석탑은 진도의 기나긴 연륜을 대변한다. 산 중턱에는 욕심을 내서는 안 된다는 전설을 안고 있는 굴암이 있다.산 위에는 세 개의 석굴이 있는데, 맨 왼쪽 굴 북쪽 벽에는 1470년 정후에 조성한 것으로 알려진 좌우 3.5m 크기의 미륵불이 있다. 이 미륵불 배꼽에서 쌀이 나와 석굴에서 깨우침을 얻으려는 수도자들의 양식이 되어 왔으나 그 중 한사람이 욕심을 부려 더 이상 나오지 않게 되었다는 전설이 전해진다.또 서거정의 동문선 금골산록편에는\"\"영험이 많은 금골산이 매년 빛을 발해 유행병 등 재앙을 막았으나 미륵불이 조성된 후 빛을 발한 적이 없다\"\"라고 해 민간신앙의 변천 모습을 보여준다.", - "MNTN_HG_VL" : "196", - "MNTN_LOCPLC_REGION_NM" : "전라남도 진도군 군내면", - "MNTN_NM" : "금골산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군", + "MNTN_NM" : "금계산" }, - "longitude" : 126.29486300000001, - "latitude" : 34.539684000000001 + "longitude" : 128.44862860000001, + "latitude" : 35.7696118 }, { "mountain" : { @@ -1529,16 +1249,6 @@ "longitude" : 127.9513889, "latitude" : 35.729999999999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 괴산군의 최남단에 위치한 금단산은 주위의 도명산이나 낙영산 등의 유명세에 밀려 잘 알려지지 않은 산이다. 그러나 안으로 들어가보면 우거진 송림과 바위지대가 잘 어우러져 있고 용대천 계곡 남쪽에 위치하고 있어 정상에서의 조망이 좋고 아직까지 때묻지 않은 자연경관을 자랑하고 있어 색다른 곳을 찾는 등산객들에게 권하고 싶은 산이다.샘이 없어 사담마을에서 반드시 식수를 준비해야 한다. 높은 절벽과 노송이 군락을 이루고 있으며 계류가 맑아 여름철 피서객들이 많이 찾고 있다.", - "MNTN_HG_VL" : "767", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", - "MNTN_NM" : "금단산" - }, - "longitude" : 127.2472779, - "latitude" : 37.521461799999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "금당산은 광주 풍암지구를 병풍처럼 둘러싸고 있는 산으로 북쪽으로는 옥녀봉, 서쪽으로는 황새봉을 거느리고 있다.옥녀봉에서 황새봉에 이르는 능선을 따라 걷다보면 무등산 정상인 천황봉을 비롯해 동화사터와 장불재, 광주 월드컵 경기장이 한눈에 바라보이고, 광주 시가지와 멀리 어등산이 어렴풋이 눈에 들어온다. 서쪽으로는 함평 들녘으로 떨어지는 아름다운 일몰을 감상할 수도 있다.광주시 서구청에서 8.2킬로미터에 이르는 산책로를 정비해 노약자나 어린이들도 쉽게 접근이 가능하다. 등산로 곳곳에는 쉼터와 체육시설 등을 설치하고 나무 이름표를 달아놓아 어린이들의 자연학습장으로도 좋다. 주변의 아파트 단지를 따라 많은 등산로가 개설되어 있어 작은 산이지만 다양한 코스를 즐길 수 있는 것이 장점이다.", @@ -1556,18 +1266,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 용평면", "MNTN_NM" : "금당산" }, - "longitude" : 126.88861110000001, - "latitude" : 35.117777799999999 + "longitude" : 128.41599729999999, + "latitude" : 37.540842300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "191", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 남동구, 부평구", - "MNTN_NM" : "금마산" + "DETAIL_INFO_DTCONT" : "강원도 태백시 창죽동에 위치한 금대봉은 지형도상에는 이름 없이 높이만 표기되어 있는 무명산으로 그리 많이 알려지지 않은 산이다.백두대간의 주맥에 솟아 동쪽의 매봉 줄기를 받아 남쪽의 함백산, 태백산으로 맥을 이어주는 역할을 한다. 이 봉우리 북사면 골짜기에는 한강의 발원지 역할을 하는 고목나무샘, 검용소 등이 있고 낙동강 천리 물길이 시작되는 용수골이 자리하고 있다.뿐만 아니라 매봉산 동쪽 가지인 1145m봉에서 낙동강 동쪽 산세를 형성하는 낙동정맥이 뻗어 있으니 금대봉이 갖는 의미는 각별하다.함백산에서 금대봉구간은 1993년 환경부가 생태계 보전지역으로 지정해 등산이 일부구간만 허용되는 곳이다.봄부터 가을까지 만흥 식물들이 자생하면서 ‘산상의 화원’이란 이름으로 알려진 곳으로 곳곳에 ‘백두대간 나무심기’ 라는 팻말을 품고 있는 수목들이 쉽게 눈에 띄는 것도 식물자원 보호구역으로 지정되면서 자연을 지키려는 노력의 결실이기도 하다.이 때문에 금대봉은 산행뿐 아니라 다양한 꽃과 자생식물을 촬영하려는 생태 탐방객들이 즐겨찾는 곳이다. 금대봉에서 두메기름나물, 바이칼바람꽃, 등 백두산에서 백두대간을 타고 내려온 북방계 식물을 비롯해 한국 특산식물이 15종, 희귀식물은 16종 이상을 조사한 바 있는 현진오 박사는 해발1,200m를 넘는 고산 정상부에서 다양한 초본 식물상을 한꺼번에 관찰할 수 있는 곳은 금대봉 일대가 우리나라에서 거의 유일하다고 밝힌바 있다.금대봉에는 높고 추운 산꼭대기에서 자라는 만병초도 자생하는 것으로 알려져 있다. 『정선총쇄록』에도 “이 약은 이 고을의 갈래사(葛來寺) 동편 골짜기에서만 나는데 만병통치로 즉효를 보지 못한 건시 없다고 하나 아직 시험해 보지 못했는데 각처 사람들이 많이 와서 잎을 뜯어간다”고 나와 있다.금대봉 정상에 오르면 두문동재 넘어 천의봉과 함백산이 웅장하게 다가온다. 금대봉을 오른 사람들은 주로 38번 국도상의 두문동재(1,268m)에 정상까지 가는 동안 두개의 헬기장을 지나며 방화선을 따라 이어지는 산길 주변으로는 봄이면 얼레지, 노루귀, 꿩의바람 등 산상의 화원에 펼쳐진 야생화에 빠져들다 보면 예상 등산시간보다 훨씬 더 소요된다.", + "MNTN_HG_VL" : "1418", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", + "MNTN_NM" : "금대봉" }, - "longitude" : 127.0982281, - "latitude" : 36.838459 + "longitude" : 128.91526469999999, + "latitude" : 37.212530600000008 }, { "mountain" : { @@ -1581,9 +1291,9 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "390", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성구", + "DETAIL_INFO_DTCONT" : "춘천시에서 남쪽으로 8킬로미터 지점에 자리 잡은 산으로 일명 진병산(陳兵山)으로 불리며, 춘천시를 에워싼 산들 중 최고봉이라고 할 수 있는 대룡산(899m)에서 남서쪽으로 뻗어내린 능선이 수리봉(645m)을 솟구친 후 그 맥이 원창고개에서 잠시 가라앉았다가 마지막으로 솟은 산이다. 사계절 중 겨울에 오르기 가장 좋은 산으로 가을이면 낙엽이 무릎까지 빠질 정도로 수목이 울창하다. 김유정의 고향 실례마을을 품고 있는 산이며, 춘천의 문인들이 그의 소설 제목을 따서 만부방길, 동백꽃길, 봄봄길 등의 이름을 붙인 정겨운 등산길이 눈길을 끈다. 본래 금병산 정상은 참나무숲으로 에워싸여 조망이 어려웠지만, 최근 춘천시에서 100여 평 정도 깨끗하게 베어내 이제는 사방으로 막힘없는 조망을 즐길 수 있다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신동면, 동산면", "MNTN_NM" : "금병산" }, "longitude" : 127.7452778, @@ -1591,13 +1301,53 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "춘천시에서 남쪽으로 8킬로미터 지점에 자리 잡은 산으로 일명 진병산(陳兵山)으로 불리며, 춘천시를 에워싼 산들 중 최고봉이라고 할 수 있는 대룡산(899m)에서 남서쪽으로 뻗어내린 능선이 수리봉(645m)을 솟구친 후 그 맥이 원창고개에서 잠시 가라앉았다가 마지막으로 솟은 산이다. 사계절 중 겨울에 오르기 가장 좋은 산으로 가을이면 낙엽이 무릎까지 빠질 정도로 수목이 울창하다. 김유정의 고향 실례마을을 품고 있는 산이며, 춘천의 문인들이 그의 소설 제목을 따서 만부방길, 동백꽃길, 봄봄길 등의 이름을 붙인 정겨운 등산길이 눈길을 끈다. 본래 금병산 정상은 참나무숲으로 에워싸여 조망이 어려웠지만, 최근 춘천시에서 100여 평 정도 깨끗하게 베어내 이제는 사방으로 막힘없는 조망을 즐길 수 있다.", - "MNTN_HG_VL" : "652", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신동면, 동산면", - "MNTN_NM" : "금병산" + "DETAIL_INFO_DTCONT" : "남해 금산은 남해섬을 대표하는 산으로, 한려해상국립공원이 말 그대로 거의 다 바다로 지정되어 있는데 유일하게 산이 해상 공원에 포함된 것이 금산이다.금산은 비단을 두를 뻔한 산으로 유명하다. 금산의 본래 이름은 보광산(普光山)이다. 이성계가 왕이 되고자 보리암 아래 있는 '이태조기단'에서 백일기도를 드리면서 자신이 왕이 되면 이 산을 비단으로 덮겠다는 약속을 했다. 이성계가 조선을 개국한 뒤, 약속을 지킬 일을 생각하니 난감했다.이때 사려 깊은 신하가 산 이름을 하사하면 비단보다 오래 갈 것이라고 제안해 이름을 비단 '금(錦)'자를 써 이전의 산 이름을 금산으로 바꿈으로 이성계는 자신의 약속을 절묘하게 지킬 수 있었다고 전해지고 있다.매표소에서 보리암으로 이어지는 등산로 왼편으로 사선대가 올려다 보인다. 사선대는 먼 옛날 동서남북의 네 신선이 조그만 암봉에서 놀았다는 곳이다. 사선대 맞은편에는 절벽을 이룬 웅장한 바위는 만장대이다.", + "MNTN_HG_VL" : "705", + "MNTN_LOCPLC_REGION_NM" : "경상남도 남해군 상주면ㆍ이동면ㆍ삼동면", + "MNTN_NM" : "금산" }, - "longitude" : 127.7452778, - "latitude" : 37.8125 + "longitude" : 127.9774498, + "latitude" : 34.7561125 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "비봉산(672m)과 금성산(550m)은 경북 의성군 금성면, 가음면, 춘산면, 사곡면에 걸쳐 있는 비교적 알려지지 않은 산이다. 금성산 서녘자락인 금성면 탑리에는 국보 77호 의성탑리오층석탑이 있다. 또한 28번 국도와 927번 지방도가 만나는 초전리에는 문익점선생기념비와 삼한시대 부족국가인 조문국의 경덕왕릉이 있어 문화유적답사를 겸하여 한 번은 올라야 할 산이다.몇 년 전만 해도 의성 부근은 교통이 불편하여 당일산행은 언감생심이었다. 그러나 최근 중앙고속국도의 개통으로 군위, 의성에 있는 오지 산도 당일산행이 가능해졌다.의성군 금성면의 탑리 시가지를 벗어나 산운리의 68번 지방도에서 북쪽으로 올려다보면 금성산 비봉산의 산세는 참으로 눈부시다. 겨울 햇볕에 빛나는 산세는 한번 우러르기만 하면 도저히 참을 수 없는 산행에의 정열이 저절로 솟구친다.산행 종점 인근에는 신라시대 의상조사가 창건한 유서깊은 고찰인 수정사가 있고 탑리 오층석탑, 관덕리 삼층석탑, 빙산사지 오층석탑 등 우리나라 석탑 양식을 살펴볼 수 있는 석탑과 제오리 공룡발자국 화석지 등의 유적지가 금성산 일원을 따라 자리잡고 있다. 이중 빙산사지 오층석탑이 있는 빙계계곡은 여름철 피서지로서 빙혈과 풍혈로 유명하다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "경북 의성군 금성면ㆍ가음면ㆍ춘산면ㆍ사곡면", + "MNTN_NM" : "금성산" + }, + "longitude" : 128.7093678, + "latitude" : 36.262196699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "672", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군", + "MNTN_NM" : "금성산" + }, + "longitude" : 128.03661880000001, + "latitude" : 35.516717800000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "부여읍내에서 아주 가까운 동쪽에 위치, 청마산과 연결되어 도심형등산코스이며, 청마산은 금남정맥의 끝부분임", + "MNTN_HG_VL" : "121", + "MNTN_LOCPLC_REGION_NM" : "충청남도 부여군 부여읍", + "MNTN_NM" : "금성산" + }, + "longitude" : 126.92388889999999, + "latitude" : 36.277500000000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "전국 8대 명산의 하나로 알려진 나주의 금성산은 동쪽의 노적봉(露積峰), 서쪽의 오도봉(悟道峰), 남쪽의 다복봉(多福峰), 북쪽의 정녕봉(定寧峰) 등 4개의 봉우리로 이루어져 있다. 금성산은 예부터 군사요충지였으며 현재도 군사보호지역으로 묶여있다. 금성산에는 1011년 고려 현종이 거란족의 침입을 피해 10여일 머물렀던 금성산성의 흔적이 남아있다.또한 고려시대부터 국가에서 산신제를 지냈던 영산으로 매년 봄, 가을이면 나주뿐만 아니라 전국 각지에서 사람들이 모여들어 한 해의 풍년과 태평함을 기원하였던 곳이기도 하다. 특히 금성산에는 5개의 사당이 있었는데, 산 정상에는 상실사(上室祠), 중턱에는 중실사(中室祠), 산 기슭에는 하실사(下室祠)와 국제사(國際祠)가 있었으며, 금성산성 안에는 이조당(爾朝堂)이 있었지만 현재는 모두 소실되었다. 금성산 주변은 요즘도 도처에서 치성을 드리기 위해 찾아온다.현재 정상부는 군사보호지역으로 산행이 불가능하지만, 1월 1일에는 해맞이 행사를 개최하고 일반인들이 올라갈 수 있다.", + "MNTN_HG_VL" : "451", + "MNTN_LOCPLC_REGION_NM" : "전남 나주시 경현동 대호동", + "MNTN_NM" : "금성산" + }, + "longitude" : 126.6972222, + "latitude" : 35.055 }, { "mountain" : { @@ -1629,26 +1379,6 @@ "longitude" : 128.30529999999999, "latitude" : 36.088487800000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "예산의 주산 금오산은 높지는 않지만 산세가 수려하고 주변 경관이 아름답다. 백제 말엽 의각대사가 석달 동안 기도하던 중에 금빛 까마귀 한 쌍이 나는 것을 보고 따라갔더니 맑고 향기로운 샘물이 있더라는 것이다. 그래서 그 자리에 향천사를 세우고 이 산의 이름을 금오산이라 불렀다고 전한다.산정에 오르면 예산의 전경이 한눈에 내려다보이며 청명한 날이면 동남쪽 저 멀리 계룡산이 손바닥만큼 아물거리며, 서쪽으로는 드넓은 예당평야와 삽교천 무한천을 배경으로 도립공원 가야산의 준봉들이 아름다운 저녁 노을 속에 잠겨든다. 남으로는 백제의 최후 항전지인 임존성의 아름다운 산세가 예당호에 얼비치고, 북쪽의 광대한 ‘소들’의 기름진 들녘에 아산호와 삼교천호와 더불어 곡창을 이룬다.산중턱에 있는 용바위는 옛날에 원님이 이곳에서 기우제를 올리면 비를 내리게 해주었다는 전설이 전해져 내려오는 곳으로, 많은 군민의 심신을 단련하는 등산로로 손색이 없어 각광받고 있다. 또한 금오산 동쪽의 유서 깊은 향천사와 북쪽의 탈해사에는 약수가 샘솟는 샘터가 있어 등산 후 지친 심신을 식혀줌에 부족함이 없다.", - "MNTN_HG_VL" : "234", - "MNTN_LOCPLC_REGION_NM" : "충남 예산군 예산읍", - "MNTN_NM" : "금오산" - }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", - "MNTN_NM" : "금오산" - }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "지리산 왕시리봉에서 섬진강을 내려다보면 굽이쳐 가던 섬진강 끝자락에 삼각형 실루엣으로 우뚝 솟은 산이 눈길을 사로잡는데, 하동의 진산인 금오산(849m)이다. 금오산 정상은 남해 조망이 일품이다. 오른쪽으로 광양제철소와 화력발전소, 정면으로 다도해의 수많은 섬들이 점점이 떠 있고, 왼쪽 사천만 뒤로 우뚝한 와룡산의 멋진 자태 또한 일품이다. 정상에 선 중계탑으로 인해 실제로 오를 수 있는 정상부가 한쪽으로 밀려나 있는 게 아쉽다.남해를 비추며 떠오르는 달맞이와 해맞이, 아름다움을 간직한 해넘이는 금오산이 자랑하는 최고의 볼거리다. 달맞이 전망대로는 금오산 남쪽의 너덜지대에 위치한 석굴암이 최고로 꼽힌다. 달이 없는 밤이라도 불야성을 이룬 광양제철소의 야경 또한 황홀한 볼거리를 제공한다.석굴암과 봉수대, 비구니도량 금성암 등 산행하면서 둘러볼 수 있는 볼거리 외에도 1973년 완공된 남해대교와 충무공의 얼을 기리는 충렬사, 그 앞 노량 앞바다에 떠 있는 거북선 등 많은 명소가 있다.", @@ -1656,8 +1386,8 @@ "MNTN_LOCPLC_REGION_NM" : "경남 하동군 금남면ㆍ진교면", "MNTN_NM" : "금오산" }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 + "longitude" : 127.8692594, + "latitude" : 34.993499200000002 }, { "mountain" : { @@ -1666,18 +1396,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 돌산읍", "MNTN_NM" : "금오산" }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;고운 물빛 굽어보는 낙동강변 명산gt;금오산은 낙동정맥 영축산에서 남서로 갈라진 영축지맥에 있는 산으로 경남 밀양시와 양산시를 가르고 있다. 남쪽으로 천태산(630.9m), 북쪽으로는 만어산(670.4m)을 거느리고 이 일대 6~7백미터 산들의 형님 노릇을 하는 산이다. 정상에 서면 멀리 영남알프스와 남쪽의 낙동강 조망이 시원하다. 삼랑진을 중심으로 밀양강과 낙동강이 만나는 멋진 풍경을 볼 수 있고, 낙동철교 아래 고운 물빛과 어울린 은빛 모래톱이 장관이다. 금오산 높이는 정상석에 760.5미터(2003년 지형도와 동일), 경남관광 길잡이의 안내도에는 765미터, 2008년 지형도에는 766미터로 각각 다르게 나와 있다. 정상 주변에 펼쳐진 500미터 정도의 암릉 구간은 바위 자체로도 멋있지만 아무데나 주저앉아도 그대로 조망명소가 된다. 금오산을 중심으로 밀양호, 천태호, 안태호, 감물저수지, 국전저수지 등이 펼쳐지는 게 특징이다. 산행은 주변의 만어산, 천태산과 연계가 가능하다.", - "MNTN_HG_VL" : "766", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍·단장면, 양산시 원동면", - "MNTN_NM" : "금오산" - }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 + "longitude" : 127.7908326, + "latitude" : 34.593600700000003 }, { "mountain" : { @@ -1686,18 +1406,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼량진읍, 양산 원동", "MNTN_NM" : "금오산" }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "766", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍·단장면, 양산시 원동면", - "MNTN_NM" : "금오산" - }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 + "longitude" : 128.90615080000001, + "latitude" : 35.416717800000001 }, { "mountain" : { @@ -1719,16 +1429,6 @@ "longitude" : 127.3497222, "latitude" : 34.924722199999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "부산시의 동래온천 북쪽 4km되는 곳에 있으며, 일부는 경남 양산군에 속해 있다.무한의 보고인 바다와 더불어 산자락은 풍요로운 삶의 터전이 되고 있는 부산의 모산이기도 하다.산세는 능선이 완만하게 뻗어내려 요란스러움이 없고, 고담봉을 비롯하여 부채바위,나비바위,대륙봉 등 암장이 있으며, 능선 언저리에는 곳곳에 억새 밭이 있고 날등 어디서 보나 낙동강과 부산시내를 내려다 볼 수 있어 가슴이 후련하다.고당봉,의상봉,상계봉,서문을 연결한 날등에는 외침을 대비한 조선 숙종 29년에 쌓은 국내 최대규모의 금정산성이 자연석으로 축조되어 있고, 동쪽 산록에는 대찰 범어서와 많은 암자가 있다.범어사는 합천 해인사, 양산 통도사, 순천 송광사, 구례 화엄사와 더불어 우리나라 5대 사찰 중의 하나로 많은 불교 역사유적을 간직한 유명한 사찰이며 인근에금강공원과 동래온천이 있다.산정에는 높이 3장(丈:1장은 10자) 정도의 돌이 있고 샘은 둘레가 10여 자[尺]이고 깊이가 7치[寸]로서 늘 물이 차 있으며 가뭄에도 마르지 않고 금빛이 났는데, 금색 물고기가 5가지 색의 구름을 타고 하늘에서 내려와 그 샘에서 놀았다는 전설에서 산이름이 유래되었다고 전해진다.", - "MNTN_HG_VL" : "801", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 금정구ㆍ북구, 경상남도 양산시", - "MNTN_NM" : "금정산" - }, - "longitude" : 129.05547390000001, - "latitude" : 35.283041900000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "포천읍에서 북쪽으로 약 10km 떨어진 나즈막한 산으로 교통이 편리하고 산길이 짧아 산을 처음 오르는 사람이나 여성들에게 인기가 있다. 산중턱에 금룡사라는 절과 커다란 미륵불상이 자리하고 있어 문화적 가치도 높은 산이다.정상에는 삼각점이 있고, 백운산,국망봉,청계산 등 조망이 뛰어나다.봄의 진달래, 늦가을의 낙엽, 겨울의 설경 또한 좋으며 계곡은 능선 북쪽편이 좋다.산록에는 사시사철 철철 넘치는 석간수가 있고, 일동에는 유황,하와이,사이판온천 등이 있다.", @@ -1739,6 +1439,36 @@ "longitude" : 127.272735, "latitude" : 37.957242299999997 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "947", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "금학산" + }, + "longitude" : 128.91777780000001, + "latitude" : 36.377499999999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "정상은 947m 이며, 산전체가 철원군에 속해있다. 계산상 걷는 거리는 약 2km 정도여서 짧은편이나 코스의 굴곡이 있는 편이므로 2 시간 이상은 잡아야 한다.구불구불하게 이어진 산행은 아기자기하고 재미있는 편이며,부엽토길이 많아서 푹신함을 느낄수 있다.넓은 철원평야의 서쪽에 위치하므로 능선에서 철원 시내를 훤히 내려다 볼 수 있으며 등산로 곳곳에 벙커나 참호,전선등 군사시설을 볼 수 있다.", + "MNTN_HG_VL" : "576", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 동송읍", + "MNTN_NM" : "금학산" + }, + "longitude" : 127.201291, + "latitude" : 38.184018700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 홍천군 북방면과 남면의 경계에 솟은 금확산은 655미터의 아담한 산이다. 하지만 정상에서 바라보는 전경은 1000미터가 넘는 산들과 비교해 결코 뒤지지 않는다. 그 배경이 되는 홍천강은 금확산을 더욱 아름답게 해주는 역할 중 으뜸이다.들머리는 북방면 노일리에 있는 노일분교다. 이곳에서 서쪽으로 300미터쯤 있는 버스종점의 콘크리트 포장길을 따라 북쪽으로 6분쯤 가면 간판 없는 작은 목장이 나온다. 등산로는 축사 뒤 계곡으로 뚜렷하게 나 있다.초입에서 40분쯤 걸리는 전망대바위에서 내려다보는 산태극 수태극을 그리며 흐르는 홍천강의 경치가 산행의 하이라이트다. 다시 산길을 30여분 오르면 정상이다. 용문산의 북녘 줄기인 봉미산에서 나산을 거쳐 장락산으로 이어지는 산세는 마치 봉황의 꼬리를 보는 듯하다.하산은 올라온 길을 다시 내려가 큰 소나무가 있는 삼거리에서 오른쪽 능선길로 빠지는 길, 홍천강이 지척으로 보이는 동남쪽 능선의 두 코스로 할 수 있다.", + "MNTN_HG_VL" : "655", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면, 남면", + "MNTN_NM" : "금확산" + }, + "longitude" : 127.7519444, + "latitude" : 37.694166699999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "자연경관이 좋고 등산로가 원만하여 누구나 쉽게 오를수 있고, 산림욕 하기 좋다. 산을 오르면서 동식물들을 접할수 있어 자연학습에 도움이 많이 된다. 정상에 올라가면 비봉산과 인제읍 시가지가 한눈에 내려다 보이며 경관이 좋다.", @@ -1746,8 +1476,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 인제읍 상동리", "MNTN_NM" : "기룡산" }, - "longitude" : 129.0124543, - "latitude" : 36.120247200000001 + "longitude" : 128.1527778, + "latitude" : 38.0816667 }, { "mountain" : { @@ -1769,16 +1499,6 @@ "longitude" : 127.1736111, "latitude" : 35.809722200000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "383", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "기마봉" - }, - "longitude" : 129.02803879999999, - "latitude" : 37.651583500000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "기백산은 1983년 함양군이 군립공원으로 지정했으며, 옛 이름은 지우산(知雨山)이다. 기백산 자락의 거창, 안의 지역은 기백산의 날씨 변화에 따라 비가 내릴 것을 미리 알 수 있었다고 한다. 백두대간인 덕유산 능선이 무룡산, 삿갓봉, 장수 덕유산으로 구비쳐오다 남덕유에서 갈라져 남동 방향으로 꺾어진 뒤 월봉산, 금원산을 일으킨 다음 거창 쪽으로 깊숙이 들어와 솟았다. 산 고스락 남쪽에 원추리와 싸리나무군락으로 이루는 기백평전이 펼쳐져 있으며 지우샘이 솟아 맞은편 황석산과 수망령에서 시작한 물줄기와 합하여 안의 지우천을 이룬다. 지우천이 흐르는 장수동은 옛 안의 삼동 가운데 하나인 심진동으로 지금은 용추사 계곡으로 더 알려져 장수사 조계문, 용추폭포, 용추사들의 명소가 널려있다. 또 기백산 안봉에서 솟기 시작한 물줄기는 고학천 용폭을 이루고 쌀다리와 용원정 명소를 간직하고 있다.", @@ -1811,23 +1531,53 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "까치산은 경상북도 청도군 운문면 방음리 말음 마을에 있다.말음 마울의 말음의 뜻은 계곡의 경관이 빼어나고 산중유곡이라 하여, 옛날에 신선과 선녀들이 모여 놀던 곳으로, 선녀들이 노닐 때마다 부르는 노래 소리가 언제나 끝 후렴만 들려오고 주된 부분은 들리지 않아 끝소리를 다서 말음이라 한 것이 마을 이름으로 되었다.산행들머리는 방음리에 내려 포장길안으로 100m 쯤 마을로 들어서면 ‘원두막’이라는 간판이 보이고 그 위에 2채의 빨간 벽돌집이 보인다.", - "MNTN_HG_VL" : "571", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면 방음리", - "MNTN_NM" : "까치산" + "DETAIL_INFO_DTCONT" : "경기도 포천군 일동면과 가평군 하면에 경계를 이루는 갈매봉은 갈매고개를 사이에 두고 청계산(849)과 마주 보고 있는 산이다. 시원한 계곡과 울창한 수림으로 휴식처가 많아 여름철 피서 산행지로 안성맞춤이다.주능선은 바위로 되어 있어 아기자기한 암릉산행에 묘미를 느낄 수 있으며, 아찔한 바위능선을 지나는 스릴도 만끽 할 수 있다.산행기점에는 청계 저수지가 자리하고 있어서 등산과 낚시를 함께 즐길 수 있는 가족 산행지로 적합하다. 갈매재를 기준으로 동쪽(하판리 방향)은 군 사격장으로 출입이 통제되는 지역임으로 주의를 해야 한다.길매봉은 청계산(849m)과 운악산 사이에 위치한 산으로 주능선과 지능선 상에 암릉지대가 많고 주능선 북사면 하단부 높이 10m, 중단부 10m, 상단부 20m나 되는 복계폭포가 있다.길매재, 바위능선을 거쳐 정상에 이른다. 정상 조망은 시원하다. 우선 청계산 방면으로는 청계산 뒤로 국망봉으로부터 흘러오는 한북정맥이 넘실거린다. 청계산 오른쪽으로는 명지산이 하늘금을 이루고, 명지산에서 시계바늘 방향으로는 아재비고개, 월출산, 전패봉, 매봉 등이 한줄로 이어져 시야에 들어온다.남으로는 하판리를 가래질한 듯 패어져 나간 조종천 계곡과 그 오른쪽으로 운악산이 피라밋처럼 우뚝 솟아 있다.북서쪽 아래로는 청계저수지로 패어져 내린 계곡이 한눈에 내려다보인다.", + "MNTN_HG_VL" : "735", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", + "MNTN_NM" : "길매봉" }, - "longitude" : 126.8467055, - "latitude" : 37.531767500000001 + "longitude" : 127.4158333, + "latitude" : 37.856666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "295", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군", - "MNTN_NM" : "까치절산" + "DETAIL_INFO_DTCONT" : "전라남도 신안군 흑산면 홍도리에 위치하고 있는 홍도는 대흑산 본섬의 부속 도서로서 다도해 해상 국립공원으로 매가도라고도 한다. 홍도는 본 섬을 비롯한 20여 개의 부속 섬이 절정을 이루어 남해의 소금강으로 불린다. 그 중에서 녹섬의 해돋이는 가히 장관이 아닐 수 없다. 파도와 바닷물이 출렁거리는 가운데 2개의 바위 사이로 해가 떠오른 광경은 말로 표현할 수 없을 정도로 아름답다. 여기에 덧붙여 홍도의 낙조 또한 놓칠 수 없는 비경이다.어미섬의 주봉인 깃대봉(해발 367m)과 남쪽의 깃대봉 주변에는 아름드리 동백나무 숲, 후박나무, 식나무 등 휘귀식물 5백여종이 있으며 2백여 종의 동물과 곤충이 함께 서식하고 있다.깃대봉 산행은 가파르기 그지 없고 철쭉,동백등 이름모를 나무들이 온통 빽빽이 자라고, 주봉에 닿으면 뾰족한 모양이 마치 바늘같다.남서로 양상봉의 연봉이 한 폭의 동양화를 펼쳐 놓은 듯하고 동쪽으로는 설풍서전의 울창한 숲이 장관이다.", + "MNTN_HG_VL" : "382", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안 흑산면 홍도", + "MNTN_NM" : "깃대봉" + }, + "longitude" : 125.201944, + "latitude" : 34.695 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "깃대봉은 경기도 가평군 하면과 가평읍의 경계를 이루고 있다. 가평군 내에는 깃대봉이 두곳에 있는데, 또 다른 깃대봉은 청평리 북쪽에 솟아 있는 해발 624m인 산으로 대성리 뒷산인 은두봉(銀頭峰.678m)과 같은 능선으로 이어져 있다.깃대봉은 가평의 명지산에서 남쪽으로 가지를 친 능선상의 매봉(929m)과 약수봉(850m) 사이에 솟은 산이다. 정상에 서면 매봉, 명지산, 칼봉산, 화악산, 구나무산, 불기산, 대금산, 축령산, 서리산, 주금산 등이 시원하게 펼쳐저 보인다.산행 들머리는 대금산과 같은 두밀리에서 시작하고 깃대봉 정상에 오르면 10여평의 공터를 만날 수 있다. 북으로는 매봉과 칼봉산 넘어 전패봉, 명지산, 화악산 등이 펼쳐져 있고, 가평읍 넘어 멀리 삼악산이 보이며, 남으로는 대금산이 손에 잡힐 듯 가깝게 보인다. 서남쪽으로 축령산과 주금산이, 서북쪽으로는 운악산이 한눈에 들어온다.", + "MNTN_HG_VL" : "835", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 가평읍", + "MNTN_NM" : "깃대봉" + }, + "longitude" : 127.41861110000001, + "latitude" : 37.841388899999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가평에 깃대봉이 2개 있다. 청평휴게소 뒷산인 깃대봉(644m)과 대금산 뒤의 가평군 두밀리의 깃대봉(910m)이다. 청평휴게소 뒷산인 깃대봉(644m)봉은 북한강을 한눈에 볼 수 있는 조망을 갖춘 산으로 청평역에 인근하고 있다.두 산 모두 경춘선으로 다녀올 수 있는데, 가평읍 경계의 깃대봉은 가평역에서 산행 들목까지 버스나 택시로 이동해야 하지만, 청평 깃대봉은 청평역에서 곧바로 산행을 시작할 수 있다. 또한 두 산은 이름은 같지만 족보가 차이가 난다. 물론 근원은 한북정맥이지만 가평 깃대봉은 명지산(1,267m)에 뿌리를 두었고, 청평 깃대봉은 축령산(879m)에 두고 있다.이웃에 대금산, 불기산, 청우산이 있어 깃대봉 정상에 서면 능선이 한눈에 들어오고 시간이 날 경우 완전히 하산하여 다시 조종천을 끼고 이웃한 산들을 접할 수도 있다. 깃대봉은 청평 휴게소와 대갈교에서 오르는 길이 있으나, 대갈교쪽 교통이 편리하다.", + "MNTN_HG_VL" : "520", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍 상면", + "MNTN_NM" : "깃대봉" + }, + "longitude" : 127.39388889999999, + "latitude" : 37.744444399999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "까치산은 경상북도 청도군 운문면 방음리 말음 마을에 있다.말음 마울의 말음의 뜻은 계곡의 경관이 빼어나고 산중유곡이라 하여, 옛날에 신선과 선녀들이 모여 놀던 곳으로, 선녀들이 노닐 때마다 부르는 노래 소리가 언제나 끝 후렴만 들려오고 주된 부분은 들리지 않아 끝소리를 다서 말음이라 한 것이 마을 이름으로 되었다.산행들머리는 방음리에 내려 포장길안으로 100m 쯤 마을로 들어서면 ‘원두막’이라는 간판이 보이고 그 위에 2채의 빨간 벽돌집이 보인다.", + "MNTN_HG_VL" : "571", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면 방음리", + "MNTN_NM" : "까치산" }, - "longitude" : 126.8746556, - "latitude" : 37.471224599999999 + "longitude" : 128.94111179999999, + "latitude" : 35.702323399999997 }, { "mountain" : { @@ -1836,8 +1586,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면 월악리", "MNTN_NM" : "꾀꼬리봉" }, - "longitude" : 127.3522222, - "latitude" : 36.486944399999999 + "longitude" : 127.86333329999999, + "latitude" : 37.100833299999998 }, { "mountain" : { @@ -1869,16 +1619,6 @@ "longitude" : 128.60795680000001, "latitude" : 37.346452900000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "475", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 용정동, 용암동", - "MNTN_NM" : "낙가산" - }, - "longitude" : 126.3276408, - "latitude" : 37.691369100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "낙가산의 산명은 신라 선덕여왕 4년 금강산 보덕암에서 수도하던 회정스님이 이곳 봉황이 날아와 집을 짓는 형국의 명당에 자리잡고 절을 세울 때, 관세음보살이 계신다는 인도 남해의 보타 낙가산의 이름을 따라 뒷산을 낙가산이라 불리게 되었다고 하며, 해명산, 상봉산보다 낮으나 주변 경관이 좋다.강화도의 끝, 외포리 항구에서 배를 타고 들어가다 보면 누에고치처럼 나지막히 자리잡은 석모도(席毛島)라는 섬이 있다. 이곳에는 300m 남짓한 산들이 섬 가운데에 길게 누워있는데 그 많은 봉우리안에 낙가산이 자리잡고 있다. 석모도의 주봉은 해명산이지만, 낙가산과 줄기를 같이하는 해명산(327m)과 상봉산(316m)에 비해 더 잘 알려진 까닭은 유명 사찰인 보문사가 있기 때문이다.산은 야트막하고 작지만 맵시 있고 적당한 다리품을 팔기에 그만이다. 보문사는 절 위에 모신 눈썹바위의 불상이 영험하다고 하여 불자들의 발길이 끊이지 않는데 눈썹바위에서 내려다보는 서해의 절경이 장관이다. 점점이 흩어져 있는 자그마한 암초들과 무인도는 절로 경탄을 자아낸다. 이 광경은 일찍이 강화 8경으로 알려졌을 정도로 뛰어나다.", @@ -1889,16 +1629,6 @@ "longitude" : 126.3276408, "latitude" : 37.691369100000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "483", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 용정동, 용암동", - "MNTN_NM" : "낙가산" - }, - "longitude" : 126.3276408, - "latitude" : 37.691369100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "낙영산은 속리산(1,058)을 조산(祖山)으로 백악산(858)과 도명산(642)사이에 기암절벽을 이룬 산이다. 남과 북으로 용대천과 화양구곡을 안고 있으며 암골미(岩骨美)가 뛰어나 괴산의 명산으로 불리고 있다.낙영산은 속리산국립공원권에 속한 산답게 산자락 곳곳에 두꺼비바위,코끼리바위등 기암을 가지고 있으며, 암릉이 산재해 있어 아기자기한 암릉산행 묘미와 시원스런 조망을 동시에 즐길 수 있는 곳이다. 또 이 산자락에 위치한 공림사(公林寺)도 볼 만 하다. 공림사는 법주사의 말사로 신라 경문왕(861-874)때 자정선사가 창건한 천년 고찰이다.정상에 서면 백두대간 주능선에 장쾌한 모습과 속리산 연봉들에 아름다운 모습을 볼 수 있고 산행 후에는 용대천과 화양구곡에서 깨끗한 자연을 만끽 할 수 있다. 하지만 암벽지대가 많아 다소 위험한 곳이 있으므로 주의해야 한다.", @@ -1911,13 +1641,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남군자산은 북쪽에 위치한 군자산(948m)에 비해 덜 유명한 곳이지만 기암절벽이 만들어내는 경치와 산에서 흘러나오는 깨끗한 물은 군자산 못지 않은 곳이다. 또한 남쪽에 약 2km에 걸쳐 있는 선유계곡은 보기만 해도 남군자산 등반에서 흘린 땀을 씻어준다. 그래서 이곳은 등산과 피서를 함께 할 수 있는 장점을 가지고 있다.산행을 시작하면 누구라도 압도당할 수 밖에 없는 집채만한 바위 덩어리들이 하늘을 가리운다. 이것이 삼형제바위, 수천톤이 됨직한 바위 세 개가 조각품을 전시해 놓은 듯 하다.관평 사람들은 이산을 소군자산,혹은 남봉이라 부른다. 북으로 보이는 군자산의 웅장한 산세가 보이며 북동쪽으로는 칠보산, 남동쪽으로는 대야산이 대야산 너머로는 속리산 문장대로 이어지는 능선이 그림같이 펼쳐진다. 한편 선유계곡은 조선시대 학자 이황이 이곳 경치가 좋아 아홉달을 돌아다니며 구경하고 선유동(仙遊洞)이라 이름 붙인 곳이다.", - "MNTN_HG_VL" : "827", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면 관평리", - "MNTN_NM" : "남군자산" + "DETAIL_INFO_DTCONT" : "임란이 일어나 왜군이 이곳까지 들어오자 가곡마을에 살던 밀양 박씨의 부녀자인 여흥 민씨(박희량의 처)는 다른 부녀자와 함께 이 산 바위굴에 피난했다. 그러나 왜군에게 발각되어 화를 면할 수 없게 되자 이 사 바위 절벽에서 몸을 던져 스스로 목숨을 끊었다. 임란이 평정되자 민씨의 정절을 표창하였고, 그 이후 그 절벽은 민씨가 꽃처럼 깨끗하게 떨어져 죽은 바위라 하여 낙화암이라고 부르고, 또 산의 형세가 꽃이 지는 것 같다 하여 낙화산이라 했다. 낙화산 정상에는 표지가 없으나 이리저리 산악회에서 달아놓은 리본들로 어지럽다.밀양시 산외면 소재 낙화산(落花山)은 정상으로 가는 도중 봉우리가 열댓개 되는 산으로 이 봉우리들을 그다지 힘들지 않게 넘을 수 있어 그 재미가 상당하다. 따라서 많은 산행인들이 이 산을 밟으려고 생각을 하고 있으나 코스를 어떻게 잡아야 할지 몰라 섣불리 발을 내딛지 못하는 형편이다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 도곡리", + "MNTN_NM" : "낙화산" }, - "longitude" : 127.8718618, - "latitude" : 36.691155799999997 + "longitude" : 128.8251827, + "latitude" : 35.544978800000003 }, { "mountain" : { @@ -1946,8 +1676,8 @@ "MNTN_LOCPLC_REGION_NM" : "전남 진도군 의신면", "MNTN_NM" : "남망산" }, - "longitude" : 128.4297943, - "latitude" : 34.841193799999999 + "longitude" : 126.29203390000001, + "latitude" : 34.381267399999999 }, { "mountain" : { @@ -1961,53 +1691,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남암산은 문수산 남쪽 산으로 김신기 산이라고도 한다. 그 유래는 경순왕이 나라가 어려워지자 영축산을 찾아 문수보살의 계시르 받고자 삼호까지 왔을 때, 한 동자가 앞을 인도하다가 무거에서 자취를 감추자, 경순왕은 문수보살이 자기를 저버렸음을 깨닫고, 고려에 나라르 바치니, 그의 장남 마이태자는 개골산으로 들어가 인생을 마감하고 둘째 차남 범공은 불가에 의지하다가 결국은 남암산에 김신암을 짓고 여기서 생을 마감했다.조망이 탁월해 울산과 주변의 산이란 산은 모두 볼 수 있다. 북쪽 정면으로 삼태봉, 파헤친 곳 국수봉, 그 뒤 치술령, 그 왼쪽으로 무학산 연화산 백운산 고헌산 문복산 운문령 상운산 가지산 배내봉 간월산 신불산 영축산 투구봉 시살등 오룡산 염수봉 채바우골만당 천마산 토곡산, 그 앞 능선엔 정족산 천선상이 그야말로 파노라마처럼 펼쳐진다. 울산 시가지와 온산공단 그리고 탁 트인 동해바다도 볼 수 있다.", - "MNTN_HG_VL" : "543", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", - "MNTN_NM" : "남암산" - }, - "longitude" : 129.21700000000001, - "latitude" : 35.512999999999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "진안고원의 남부 백운면과 성수면, 마령면의 경계에 남쪽 고덕산과 더불어 암봉, 암릉으로 이루어진 내동산이 솟아 있다. 진안읍 마이산에서 암릉 줄기가 서남쪽 진안 성수면과 임실 성수면 방향으로 길게 뻗어 내리면서 나웅대(545m), 광대봉(609m)을 일구어 놓고 널따란 마령평야를 지난 남쪽에 고덕산과 함께 빚어 놓은 산이다. 동남쪽 덕현리 산기슭에 안겨 있는 약수암과 내동폭포 주변 일대의 사철 변화무쌍한 풍경은 오가는 길손들의 발목을 붙잡는다. 약수암은 보잘 것 없는 초라한 암자이지만 이 산과 약수암은 일명 ‘백마산 백마사’라고도 불리고 있다. 남북으로 길게 뻗어있는 이 산은 지금까지 오지로 알려진 백운면에 속해 있었기 때문에 사람들이 찾는 기회는 많지 않은 편이었다. 그러나 암릉선을 타고 남북을 종주하는 등산 코스가 등산인들에게 사랑을 받기 시작했다. 남릉에서 북릉을 타면서 조망되는 경치가 일품이기 때문이다. 북으로 마이산의 두 말귀와 운장산, 그리고 동쪽으로 덕태산, 선각산과 성수산, 팔공산이 하늘과 맞닿아 늘어서 있는 가운데 산들과 산 사이로 펼쳐진 백운평야는 한국의 전형적인 농촌 풍경이다.", - "MNTN_HG_VL" : "887", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 백운면, 마령면, 성수면", - "MNTN_NM" : "내동산" - }, - "longitude" : 127.36805560000001, - "latitude" : 35.690277799999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "전라북도 부안군 변산면, 전서면, 보안면, 상서면, 하서면의 5개면에 걸쳐 산악과 해안 일대를 포괄하고 있는 변산반도는 아름다운 해안선을 다라 수많은 절경이 이어지는 우리나라 유일의 반도공원이다.호남정맥에서 나뉘어 온 하나의 산줄기가 서해로 튕겨 나온 듯한 변산반도 내변산에는 의상봉(509m), 신선봉(486m), 쌍선봉(459m) 등 기암 괴석으로 이루어진 산봉우리와 그 사이 직소폭포, 봉래구곡, 낙조대 등 승경이 곳곳에 산재하고 있다.그 주변에는 유천도요지, 구암 지석묘군, 호벌치와 우금산성 등의 역사 유적지와 '내소사'와 '월명암' 이라는 역사깊은 사찰이 있다대부분의 봉우리들이 바위로 이루어져 기묘함을 더하고 그 사이의 계곡에는 폭포와 소, 담 과 여울이 어울려 아름다움을 보태준다.1995년 내변산에 부안댐이 완공되어 물이 차면서 중계계곡이 호수로 변해, 천연적인 단애를 이룬 기암괴석과 어울려 절경을 이룬다.내변산의 직소폭포는 30m 높이에서 힘찬 물줄기가 쏟아지고 폭포 아래에는 푸르른 옥녀담이 출렁대며 여러 개의 크고 작은 폭포를 이루고 있는데 이를 봉래구곡이라 부른다. 곳곳의 계곡에서 내려오는 물줄기들은 백천내로 변산댐에 이르면서 곳곳에 시원한 경치를 만들어 내기도 한다.", - "MNTN_HG_VL" : "459", - "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면 진서면", - "MNTN_NM" : "내변산" - }, - "longitude" : 126.5713382, - "latitude" : 35.631484299999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "보경사와 청하골 계곡으로 유명한 내연산은 상생폭포, 관음폭포, 연산폭포 등 12개의 폭포를 거느리고 있는 산으로 산 전체가 거의 육산으로 완만한 능선으로 이어져 있다.내연산 산행 들머리는 유서 깊은 보경사로 이 절은 신라 진평왕 25년에 지명법사가 창건하였다고 한다.지명법사가 진나라에서 유학하고 돌아올 때 신비한 팔면경을 가져와 진평왕에게 진언, 내연산 아래 큰 연못에 거울을 묻고 그 위에 금당을 세운 뒤 사찰을 세워 보경사라 이름을 지었다고 한다.", - "MNTN_HG_VL" : "711", - "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 송라면ㆍ청하면ㆍ죽장면, 영덕군 남정면", - "MNTN_NM" : "내연산" + "DETAIL_INFO_DTCONT" : "경주 남산은 곧 신라라해도 과언이 아니다. 그만큼 신라 건국에서부터 멸망에 이르는 동안의 수많은 유적과 신라를 지탱해 온 불교유적의 보고이다.신라의 건국설화에 나오는 나정(羅井)에서부터 종말기의 포석정이 남산 기슭에 자리잡았다. 그 사이의 시간 간격이 900년이다.", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 남산동ㆍ내남면", + "MNTN_NM" : "남산" }, - "longitude" : 129.28364629999999, - "latitude" : 36.278844499999998 + "longitude" : 129.22555600000001, + "latitude" : 35.768056000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "그 산 밖에서 볼 수 없는 천하의 명승을 그 산의 내부에 숨기고 있다' 는 뜻의 이름을 지닌 내장산. 기암절벽, 계곡, 폭포와 단풍 등 산이 갖춰야 할 품세를 빠짐없이 갖춘 천혜의 가을산이다.내장산은 전북 정읍시와 순창군의 경계를 이루는 산으로 천하 제일의 단풍 명소로 손꼽히고 있다. 내장사 경내에 있는 정혜루기에 의하면 내장산은 구례의 지리산, 영암의 월출산, 장흥의 천관산, 부안의 능가산(변산)과 더불어 호남의 5대 명산의 하나로 기록돼 있다.말발굽 형태로 이루어진 능선에 기기묘묘하게 솟은 기암절벽과 울창한 단풍숲이 어우러져 가을철이면 단풍 산행지로 각광을 받고 있다.", - "MNTN_HG_VL" : "764", - "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 내장동, 순창군 복흥면ㆍ쌍치면", - "MNTN_NM" : "내장산" + "DETAIL_INFO_DTCONT" : "남산은 충주시 직동과 살미면의 경계선상에 자리하고 있는 산으로 일명 금봉산이라고도 한다. 예전에 봉황이 살았던 상서로운 산이라고 한다.마즈막재를 사이에 두고 북쪽에 위치한 계명산과 마치 형제처럼 마주하고 있으며 이 산 남쪽 기슭에는 신라 시대 때 창건하였다는 창룡사를 비롯하여 시내 쪽 기슭에는 각종 체육시설 및 약수터가 있어 충주 시민의 발길이 끊이지 않는 산이다. 또한 이 산 정상에는 삼국 시대에 축성된 것으로 보여지는 산성이 자리잡고 있는데 이 성이 충주산성이다. 이 산성은 삼한시대 마고선녀가 축성했다는 전설을 간직하고 있어 마고성이라고도 알려져 있다.이 산 남쪽 기슭에는 약 1300년 전 신라 원효대사가 창건하였다는 창룡사가 있고 이곳 북방 3km 지점의 탑대라는 곳에는 3층석탑이 지금도 있을 뿐 아니라 부근의 지명이 윗절골, 아래절골 등으로 불리어 지는 것으로 보아 창룡사를 중심으로 한 직동일대가 대사찰지였던 것으로 보인다.", + "MNTN_HG_VL" : "636", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 직동, 살미면", + "MNTN_NM" : "남산" }, - "longitude" : 126.8879786, - "latitude" : 35.479702199999998 + "longitude" : 127.9743071, + "latitude" : 36.954960700000001 }, { "mountain" : { @@ -2029,36 +1729,6 @@ "longitude" : 126.94474719999999, "latitude" : 37.6841309 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "노목산은 백두대간의 금대봉(1,418m)에서 서북으로 뻗은 지맥선상에 위치해 있다. 산세가 부드러운 노목산은 노나무산이라고도 불리는데 정상 북동쪽 아래에 있는 백전 2리 노나무마을에서 유래되었다.노목산 산행은 정선과 사북읍을 잇는 노나무재에서 시작된다. 이곳에서 15분 정도 오르면 주릉선에 오르게 되고 정상은 능선길을 따라 1시간 30분여 더 오르면 당도할 수 있다. 삼각점이 있는 정상에서는 이름을 알 수 없는 연봉과 백두대간의 장중하게 앉아 있는 모습을 한눈에 볼 수 있다. 정상 부근에는 이름도 모를 꽃들이 지천에 널려 있다. 노목산은 산세가 부드러워 산행에 별 어려움은 없다.", - "MNTN_HG_VL" : "1150", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍, 동면", - "MNTN_NM" : "노목산" - }, - "longitude" : 128.84527779999999, - "latitude" : 37.254444399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;원시림 간직한 오지의 산gt;백두대간의 금대봉(1418m)에서 서북쪽으로 뻗은 지맥이 민둥산(1119m)과 지억산(1117m)으로 가는 중간지점에 자리잡고 있는 산으로 아직 원시림을 간직하고 있는 오지의 산이다. 일명 노나무산이라고도 불린다. 노나무, 즉 개오동나무와는 관련이 없다. 그 유래는 산 정상 북동쪽 아래 백전2리 노나무 마을에서 유래한 것이다. 옛날 매년 음력 정월 보름에 솟대를 세우고 마을의 안녕을 빌었는데 이 풍습을 ‘노대를 지낸다’ 하여 노나무골이라 불렀다. 또한 마을을 감싸고 있는 산을 노목산이라 칭했다. 삼각점이 있는 정상에 오르면 북쪽은 이름을 알 수 없는 연봉들이 중첩하고 동쪽은 아련히 백두대간이 마루금을 긋고 있다. 남쪽은 백운산(1426m), 두리봉(1466m)이 날개 죽지를 펴고 있다. 민둥산과 지억산이 서쪽으로 가깝다. 조망도 일품이지만 넓은 헬기장의 가을꽃이 노목산의 자랑이다. 각시취, 절굿대, 노란색을 뽐내는 마타리, 빨간 모자를 쓴 산비장이, 수리취, 그늘취, 참취, 어수리, 산솜방망이, 산오이풀, 엉겅퀴, 싸리나무꽃, 억새꽃이 지천에 피어난다.", - "MNTN_HG_VL" : "1150", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍·동면", - "MNTN_NM" : "노목산" - }, - "longitude" : 128.84527779999999, - "latitude" : 37.254444399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1150", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 사북읍, 동면", - "MNTN_NM" : "노목산" - }, - "longitude" : 128.84527779999999, - "latitude" : 37.254444399999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "노성산은 논산8경 중 제8경인 노성산성이 있는 산이다. 이 산성은 백제시대에 축성된 것으로 자연적인 지세를 교묘하게 이용하여 둘레 약 1킬로미터를 석축으로 거의 완벽하게 쌓은 성지이다. 동면, 북면, 서면을 활석을 다듬어 네모지게 하여 쌓았고, 봉우리 정상에는 장대지로 추정되는 곳과 동벽으로 약간 내려온 곳에 봉수대로 보이는 곳이 남아있다. 성내에는 우물지가 4개소 있고, 건물지로 보이는 여러 개의 유지가 있으며 백제시대의 기와편과 토기편 그리고 고려, 조선시대에 이르기까지 다양한 유물들이 산재해 있다.동쪽으로 계룡산이 막아서고 남쪽으로는 논산평야가 바라다 보이며 북쪽으로는 공주, 서쪽으로는 부여 방면이 한눈에 조망되는 요지로, 연산 황산성과 함께 백제와 신라가 대치했던 방어선에 위치한 산성이다. 그 중요성 때문에 노성산성은 삼국시대부터 조선시대에 이르기까지 계속해서 사용했던 것으로 전해진다.노성산에는 논산시민들이 해맞이를 즐기는 넓은 공터가 있다. 이곳에 오르면 우리나라 3대 곡창지대 중 하나인 논산평야가 황금빛으로 물들어 풍요롭게 보인다. 더 멀리 기운찬 계룡산의 향적봉, 국사봉, 천황봉, 그리고 관음봉으로 이어지는 마루금이 인상적이다.", @@ -2066,8 +1736,8 @@ "MNTN_LOCPLC_REGION_NM" : "충남 논산시 노성면", "MNTN_NM" : "노성산" }, - "longitude" : 127.5040697, - "latitude" : 37.127014500000001 + "longitude" : 127.12361110000001, + "latitude" : 36.2955556 }, { "mountain" : { @@ -2079,26 +1749,6 @@ "longitude" : 127.5040697, "latitude" : 37.127014500000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "노악산은 갑장산, 천봉산과 더불어 상주 3악을 이루며 상주 서북을 병풍처럼 둘러막고 있는 상주의 진산이다. 노악산에는 국사봉, 옥녀봉, 정상인 상상봉과 큰골, 작은골, 물골, 능암뒷골, 홰나무골, 절골 등이 있다. 등산로는 종주 코스, 중궁암 코스, 홰나무골 코스, 북장사 코스 등 다양하게 개발되어 있고 산세 또한 빼어나서 ‘영남 8경’의 하나로 알려진 산이다. 서쪽 기슭에 북장사, 남동쪽 기슭에 남장사를 품고 있는데 두 사찰 모두 신라 때 창건된 유서 깊은 절이다. 특히 남장사 일대는 늦가을 정취가 인상 깊은 명승지로서 ‘경북 8경’의 하나로 손꼽히기도 하다. 늦가을이면 남장마을의 집집마다 곶감을 널어 말리는 풍경이 정겹다. 이 남장마을은 곶감의 명산지다. 또 남장사 입구의 옛 상주초등학교 남장분교에 전국 유일의 장승공원이 들어서 있다.한편 산경표와 국립지리정보원 발행 지형도에 노악산은 노음산이라 하는데 예전부터 산 아래 주민들은 노음산, 또는 논산으로 불러왔다. 그러나 남장사 일주문에는 ‘노악산 남장사(露嶽山 南長寺)’라는 현판이 걸려 있다. 상주초교 교가에는 노악산으로 되어 있다.", - "MNTN_HG_VL" : "726", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 남장동, 외서면, 내서면", - "MNTN_NM" : "노악산(노음산)" - }, - "longitude" : 128.09666669999999, - "latitude" : 36.438888899999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "일명 노악산이라고도 하는 노음산의 산행 기점은 남장사 입구에 있는 제실저수지이며, 산행코스가 쉽다. 산 아래에는 여러가지 자생식물과 잡목이 섞여 자라며 위로갈수록 참나무, 단풍나무등의 관목들이 많이 있고, 특히 동쪽산 아래에 울창한 숲 속에 있는 남장사는 이름난 명승지이며 서쪽 아래로는 북장사가 있다.", - "MNTN_HG_VL" : "725", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 외서면, 내서면", - "MNTN_NM" : "노음산" - }, - "longitude" : 128.09666669999999, - "latitude" : 36.438888899999988 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "오대산국립공원권에 속해 있는 노인봉은, 강원도 강릉시와 평창군의 경계를 이루고 있는 산으로, 유명한 소금강계곡을 산자락에 거느리고 있다. 금강산의 축소판이라 일컫는 '소금강'이라는 이름은 율곡선생이 청학동을 탐방하고 쓴 〈청학산기〉에서 유래되었으며 무릉계옆 바위에 아직 '소금강'이라는 글씨가 남아 있다.산의 정상에는 기묘하게 생긴 화강암 봉우리가 우뚝 솟아 있으며, 그 모습을 멀리서 바라보면 백발노인과 같이 보인다 하여 노인봉이라 붙여졌다 한다.정상에서 소금강계곡으로 내려서면 낙영폭포가 나타난다. 낙영폭포에서 무릉계까지 7km 가량 이어지는 소금강계곡은 30여개의 다리를 건너야 하는 아기자기한 산행길이다. 낙영폭포를 지나면,광폭포,삼폭포,백운대를 지나 만물상으로 이어진다.", @@ -2109,75 +1759,35 @@ "longitude" : 128.6394444, "latitude" : 37.782499999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "노추산은 강릉시 왕산면 대기리와 정선군 북면 구절리 사이의 경계를 이루는 산으로 해발 1322미터며 북쪽에는 조고봉, 서쪽에는 상원산 남동쪽에는 덕우산, 동쪽에는 사달산을 거느리고 있다. 강릉시에서의 등산로는 왕산면 대기리 늑막골 코스와 왕산면 고단2리 새목재에서 사달산으로 오르는 코스가 나 있지만 경관이 별로 좋지 않아서 등산객들은 거의 정선 쪽 코스를 이용한다. 노추산에는 이성대가 있는데 이곳은 강릉과 정선의 유림들이 힘을 합쳐 설총과 율곡 이이를 기리기 위하여 세운 누각으로 겨울철이나 갑자기 눈·비가 올 때는 대피소 역할도 하고 있다. 중국 노나라의 공자와 추나라 맹자의 기상이 서려 있다 하여 노추산이라 불린다. 신라시대 설총과 조선시대 율곡 이이 선생이 입산, 수학한 곳으로 등산로가 잘 개설되어 있다. 동북쪽으로는 완만한 구릉이지만, 남쪽 정선 방면의 경사면은 심한 굴곡을 이루고 있다. 이름의 유래나 전설로도 명산이요, 산수의 경치로도 명산이다.", - "MNTN_HG_VL" : "1322", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면·정선군 북면", - "MNTN_NM" : "노추산" - }, - "longitude" : 128.74063749999999, - "latitude" : 37.570945199999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "뇌암산은 삼척시 각곡면에 자리해 있으며 국립지리원 발행 5만분의 1지형도에는 벼락바위로 표기되어 있으나 근동에서는 뇌암산이라 부른다.사람들의 발길이 잘 닿지 않아 표지기는 물론 등산로도 제대로 나 있지 않지만 경치가 빼어나고 맑은 물이 곳곳에 연이어 있다. 이 산 초입에 있는 덕풍계곡은 자연경관이 빼어나고 마을과 멀리 떨어져 있어 조용하며 여러 개의 폭포가 산재하고 있을 뿐만 아니라 병풍처럼 둘러싸인 산세가 수려하여 등산을 겸한 가족단위 피서지로 적합한 곳이다. 한여름에도 살을 에는 듯한 계류가 흐르고 있다.교통이 조금 불편한 것이 흠이지만 불편을 무릅쓰고 찾아가 볼 만한 곳이다. 오지여행 전문가들이 마지막 남은 오지로 꼽는 곳이기도 하다.", - "MNTN_HG_VL" : "812", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "뇌암산" - }, - "longitude" : 126.987933, - "latitude" : 34.699324500000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 문경에 위치한 뇌정산은 백두대간이 속리산을 일구기 전에 백화산에서 동남쪽으로 뻗친 능선위로 투박하게 빚어놓은 산이다.산 이름 탓인지 이 산에는 벼락이 잘 치고 물 난리도 많이 나서 인근 마을에서는 `뇌정산'이라고 부르는 것을 금기시하고 있다. 현재는 안에서 스스로 다스린다는 뜻을 지닌 내정산이라 부르고 있으나 여전히 인적이 드물어 지도에는 초입만 겨우 표시되어 있는 정도다. 때문에 사전에 산행 지도를 준비해야 하며 산행시 각별히 방향 설정에 주의해야 한다.활엽수가 많은 산인데 특히 895봉에서 서쪽 세능 따라 내력는 구간은 곱게 물들은 낙엽이 발이 빠질 만큼 두껍게 깔려 가을의 정취를 한층 느끼게 한다. 또 중간의 바위 언덕에서 빼어난 희양산의 거대한 암봉과 신라 선문구산으로서 지금도 비구니의 수도도량으로 유명한 봉암사를 내려다보는 경관이 빼어나다.", - "MNTN_HG_VL" : "991", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 마성면", - "MNTN_NM" : "뇌정산" - }, - "longitude" : 127.4956402, - "latitude" : 36.6244364 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;꽃대궐 차린 백두대간의 산gt;눌의산은 경상북도 김천시, 충청북도 영동군 경계에 있는 백두대간의 산으로 '눌의'는 눌하다 혹은 더디다의 의미로 김천과 영동 인정의 교류가 뜸했다는 뜻을 가지며 이에 따라 이 산을 찾는 이들이 적어 호젓한 산행을 할 수 있는 곳으로 알려졌다. 하지만 백두대간을 종주하는 사람들을 통해 입소문이 나기 시작해 점차 자연의 순수함과 사람의 손길이 공존하는 곳이 되어가고 있다. 추풍령에서 눌의산까지는 고도차가 500m가 넘는다. 200m대의 추풍령에서 743m의 눌의산까지 오르기 위해서는 깔딱 일어선 능선을 따라 한참 올라야 한다. 등산로 초입부터 곳곳에 오른쪽과 왼쪽 방향으로 등산로가 나뉘지만 왼쪽으로 방향을 잡아서 오르면 된다. 표지기가 자주 눈에 띄지만 야간산행을 하며 길을 헤맸다는 등산인들이 많기에 초입 부분에서 독도에 주의하는 것이 좋다. 추풍령~눌의산~괘방령은 백두대간 구간이라 등산로가 뚜렷하고 아무래도 사람의 발길이 자주 닿다보니 단단하게 다져진 흙길 덕분에 길이 좋다.", - "MNTN_HG_VL" : "743", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", - "MNTN_NM" : "눌의산" - }, - "longitude" : 127.9811368, - "latitude" : 36.196130199999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "743", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", - "MNTN_NM" : "눌의산" + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평", + "MNTN_NM" : "노적봉" }, - "longitude" : 127.9811368, - "latitude" : 36.196130199999999 + "longitude" : 127.4788889, + "latitude" : 37.880833299999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "눌의산은 추풍령 뒤쪽에 자리잡은 산으로 등산인들의 발길이 뜸하여 호젓한 산행을 즐길 수 있는 곳이다. 이 산의 이름인 `눌의'는 한자어로 정의가 눌하다 혹은 더디다는 뜻이니 추풍령 영마루를 사이하는 충청도와 경상도의 양쪽 인정의 교류가 뜸하다는 것을 뜻한다.정상에 봉수대가 있는 것으로도 알 수 있듯이 주변 조망이 뛰어나다. 또한 옛날에는 요긴한 거점구실을 했을 것이라는 것을 짐작할 수 있다. 나라에 긴급을 다투거나 외적이 침범했을 때 활활 타는 봉화를 피워올려 제몫의 역할을 다했을 눌의산의 늠름함이 살아 있다. 추풍령에서 시작하는 산행길은 사람들의 발길이 뜸하다보니 깨끗함을 자랑하고 산새들의 울음소리가 한적한 산행길을 함께 한다.", - "MNTN_HG_VL" : "743", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시, 충청북도 영동군", - "MNTN_NM" : "눌의산" + "DETAIL_INFO_DTCONT" : "lt;아홉 굽이 절경 펼쳐지는 가평의 명산gt;노적봉은 한북정맥 강씨봉과 청계산 사이에서 흘러나온 명지지맥이 연인산에서 동쪽으로 흐르면서 가평군 가평읍과 북면을 가르는 능선 상에 있다. 노적봉은 육산으로 험로가 없고 전 구간 나무 그늘이 잘 되어 있으며, 여름 장마철을 제외한다면 사계절 산행지로 좋다. 구나무가 많이 자라고 있어 구나무산으로도 불린다. 구나무란 너도밤나무과 참나무속 굴참나무의 방언으로 수피에 콜크가 많은 낙엽 교목이다. 노적봉 남쪽은 여름철 피서지로 유명한 가평 제3경 용추구곡이고 북쪽은 백둔계곡이다. 등산기점 또한 용추구곡이 있는 승안리나, 백둔계곡이 있는 백둔리를 선택한다. 원점회기 산행의 경우 들머리를 백둔계곡보다 용추구곡으로 잡는 것이 좋다. 산행거리도 적당하고 용추구곡을 빠트릴 수 없기 때문이다. 산행 코스를 길게 잡고 싶다면 노적봉-연인산 연결 종주산행을 하면 된다. 하산은 둘레길, 능선, 계곡을 다양하게 선택할 수 있다. 이 일대는 2005년 도립공원으로 지정되면서 변화의 바람이 불고 있다. 최근 가평군에서 옛 임도를 이용한 걷기산행 코스와 MTB코스를 개발, 각광받고 있다.", + "MNTN_HG_VL" : "859", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", + "MNTN_NM" : "노적봉 (구나무산)" }, - "longitude" : 127.9811368, - "latitude" : 36.196130199999999 + "longitude" : 127.4788889, + "latitude" : 37.880833299999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "능걸산은 걷기 편하고 숲이 좋은 오솔길과 기차바위 부근의 경관이 빼어난 암릉, 영남 알프스의 걸출한 산들을 한 눈에 볼 수 있는 시야까지, 삼박자를 두루 갖춘 산이다. 벌판처럼 시야가 툭 트인 정상에서는 사방이 산으로, 남쪽에는 금정산과 양산이 펼쳐져 있고, 서쪽에는 어곡산, 매봉, 토곡산이 우뚝하다. 동쪽에는 천성산과 화엄벌 억새밭이 유명하다. 능걸산 남동 날등에 펼처진 암릉 구간에는 수십은 넉넉히 앉을 만한 마당바위전망대 뒤 한 칸 높은 곳에 더 탐스런 너럭바위전망대가 숨어있고 울퉁불퉁한 바위능선길을 온몸으로 기어오르는 암릉 구간이 도사리고 있다. 암릉 구간 아래로는 빽빽한 철쭉이 군락을 이루고 있는 반면 매봉산이 있는 구간은 외제가 아닌 순수 국산 융단을 깔아 놓았다. 많은 이들이 천마산이라 부르기도 하지만 산림청에는 능걸산이라는 이름으로 등록되어 있다. 흔한 이정표도 하나 없지만 먼저 다녀간 이들이 남겨놓은 탄탄한 길이 곧 이정표가 되어 많은 등산인들이 즐겨 찾고 있다.", - "MNTN_HG_VL" : "783", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 상북면", - "MNTN_NM" : "능걸산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "859", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", + "MNTN_NM" : "노적봉(구나무산)" }, - "longitude" : 129.00995800000001, - "latitude" : 35.420667199999997 + "longitude" : 127.4788889, + "latitude" : 37.880833299999999 }, { "mountain" : { @@ -2189,6 +1799,16 @@ "longitude" : 128.7647929, "latitude" : 37.672805199999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "능곡산은 백화산 줄기가 구랑리에 와서 맺힌 산으로서 마성면 정리 솥골에서 상내리로 넘어가는 나리재에서 능선을 타고 백화산 반대 방향으로 올라가면 되고, 아니면 마성면 상내리에서 오르는 길이 있고 정상에는 삼각점이 있다.능곡산(571.6m)은 마성면 정리에 위치해 있으며 상내리와 접해 있다. 능곡산을 오르기 위해 찾는 산행객은 드물다. 백화산에서 남으로 뻗어온 산줄기로 인접해 전국에서 워낙 이름난 백두대간상의 명산인 백화산이 버티고 있기 때문이다.백화산에서 여러 방향으로 뻗어나간 한 줄기에 자리잡고 있고 해발도 그리 높지도 못하다.정상은 잡목이 있어서 조망이 되질 않고 정상 전 헬기장에서 백화산과 이만봉쪽으로 펼쳐진 풍경이 들어온다. 동으로 정리와 주지봉 방향은 나뭇가지 사이로 보일뿐 역시 잡목 때문에 조망이 희미하다.정리쪽에서 보는 능곡산은 산세가 아주 순하게 생겼지만, 상내리 질마재골 쪽에서 보면 하늘로 봉이 치솟아 경사도가 심한 삼각형 모양을 하고 있어 위협적으로 느껴진다.", + "MNTN_HG_VL" : "572", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 상내리", + "MNTN_NM" : "능곡산" + }, + "longitude" : 128.08266570000001, + "latitude" : 36.679440399999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "능동산은 영남알프스의 산군 중에 하나이며 가지산과 천황산, 재약산의 유명세에 가려 그 이름이 묻혀 버렸다. 석남재에서 천황산에 뻗은 산줄기의 중간지점에 우뚝 솟아 있는 산이며, 언양에서 얼음골로 넘어가는 도로가 개통되기 전에는 주변의 산세속에서 아주 깊이 뭍혀 있었던 산이였다.그러나 언양과 밀양을 잇는 도로가 개통되면서 지금은 석남터널에서 가까이 보이고, 또 천황산에 가는 길목의 능선에 위치하고 있어서 많은 등산객들이 지나는 산이다. 특히 이 산에서 천황산과 배내봉 방향의 능선이 갈라지고 있으므로 영남알프스 종주길에 반드시 거치게 되는 지점에 위치하고 있다.능동산 산행은 석남사 주차장 안쪽에서 시작된다. 포근한 산길에 경쾌한 걸음으로 40여 분 후 전망대에 오르는데 여기서 영남 알프스 1000m 고지들이 시야에 전개되고 시원한 바람까지 불어온다. 능동산은 영남 알프스 중앙에 위치해있기 때문에 정상에 오르면 전망을 두루두루 관망할 수 있다. 정상에는 돌무더기를 쌓아 두었는데 아마도 등산객들이 소원성취와 안전을 기원하면서 돌을 하나 둘 올리다보니 돌무더기로 변한 듯 싶다. 하산은 반대쪽으로 하면 된다.", @@ -2216,18 +1836,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선 북면", "MNTN_NM" : "다락산" }, - "longitude" : 128.7215238, - "latitude" : 37.5263499 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "388", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 봉곡동,부곡동", - "MNTN_NM" : "다봉산" - }, - "longitude" : 128.30615879999999, - "latitude" : 36.167700500000002 + "longitude" : 128.7613806, + "latitude" : 37.5412933 }, { "mountain" : { @@ -2239,6 +1849,16 @@ "longitude" : 128.2624572, "latitude" : 35.567715799999988 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "문경시는 백두대간을 병풍처럼 두른 후에 남쪽방향으로 길게 뻗은 여러 개의 산줄기를 두고 평야지대와 산 구릉지대가 조화롭게 이룬 사람 살기 좋은 고장이다. 특히 지하자원이 풍부하여 조선시대 철의 생산지로 기록되어 있으며 일제시대와 현재까지 석탄 생산지로 유명하였다. 탄전지대는 단산을 중심으로 발전하였는데 운달산과 단산, 오정산을 중심으로 탄전이 모여 있다.단산은 오정산과 운달산 사이에 있는데 길게 뻗은 정상부는 깊은 산 속에 있는 산봉우리 같은 느낌을 준다.정상에서는 주흘산과 운달산이 눈앞에 들어오고 문경읍과 산북면 모습이 보인다.이 산은 능선을 타는 것이 가장 좋으며 잡목을 많이 헤치고 길을 찾으며 가야 한다. 광산 채굴 때문에 생긴 함몰지대를 조심하고 우회를 많이 해야 한다. 산에는 패러글라이딩의 활공장이 있다.", + "MNTN_HG_VL" : "956", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면", + "MNTN_NM" : "단산" + }, + "longitude" : 128.18333329999999, + "latitude" : 36.716666699999998 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경부고속도로 건천나들목에서 남쪽으로 바라다 보이는 산이다. 산은 건천읍 송선리 우중골에 있으며, 산 7-8부 능선에는 4개의 바위가 둘러싸인 천연굴이 있는데 옛날에는 상인암(上人巖, 일명 탱바위)이라고 불리었다고 한다. 화랑들은 이 바위굴 속에 불상을 새기고 그 위에 지붕을 덮어 석굴사원을 만들었다. 이 절을 신선사(神仙寺) 또는 단석사(斷石寺)라고 부른다. 내부의 마애불상은 국보 제199호로 지정되었다. 단석산은 경주에서 가장 높은 산으로 백제에 대한 신라의 국방의 요충지였다.이 지역은 진달래 군락지로 봄철 산악 애호가들의 사랑을 받고 있으며, 인근 조래봉(657m)과 더불어 등산 코스로 각광을 받고 있다. 단석산으로 올라가려면 방내리에서 큰골로 가는 숲길이 있는데 화랑도량의 표시인 화랑바위가 있고, 화랑들을 불러 면회하던 급제바위가 있으며 정상 가까이에 올라가면 김유신이 칼 쓰기 연습을 하다가 남았다는 기둥바위가 있으니 사람들이 고단석이라 부른다.", @@ -2249,6 +1869,16 @@ "longitude" : 129.09134510000001, "latitude" : 35.793620900000001 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "달마산은 옛날 영암의 송양현에 속했을 정도로 월출산과 가깝다. 달마산은 바위들이 갖가지 형상을 하고 있어 마치 금강산을 길게 펼쳐 놓은 듯하다 하여 ‘호남의 소금강’이라 불러왔다. 또 하나의 자랑은 산자락에 있는 미황사다. 미황사는 한반도 최남단에 위치한 사찰로서 바닷길 불교 전래를 추측케 하는 신비로운 전설을 간직한 천년 고찰이다. 사람들은 바위의 누런 이끼, 금빛 나는 금샘, 달마전 낙조를 미황사의 3황으로 꼽는다. 달마산 종주산행을 하면 이 산자락에 숨겨져 있는 보물과 다도해를 운행 중 시종일관 볼 수 있다. 운이 좋으면 보길도 격자산 쪽으로 제주 한라산의 원경도 볼 수 있다.북으로 두륜산이 접해 있고 삼면은 모두 바다와 닿아있는 산, 송호리에는 소나무와 참나무가 무성하여 모두 백여 척이나 되는 것들이 치마를 두른 듯 서 있다. 그 위에 마주한 기암괴석들은 우뚝 솟은 깃발과 같다. 혹 사자가 찡그리고 하품하는 것 같고 또는 용과 범이 발톱과 이빨을 벌리고 있는 것 같기도 하며 멀리서 바라보면 하얗게 쌓인 눈이 공중에 한 발짝 다가서 서 있는 듯하다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 송지면, 북평면", + "MNTN_NM" : "달마산" + }, + "longitude" : 126.5852778, + "latitude" : 34.3825 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -2256,8 +1886,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 봉화읍", "MNTN_NM" : "달봉산" }, - "longitude" : 128.11477009999999, - "latitude" : 36.141345600000001 + "longitude" : 128.69057369999999, + "latitude" : 36.885565799999988 }, { "mountain" : { @@ -2279,16 +1909,6 @@ "longitude" : 127.6561111, "latitude" : 36.228888900000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "당산은 경기도 양평과 여주, 강원도 원주에 접해 있는 산으로 서울에서 가깝고 높이도 그리 부담스럽지 않아 주말 가족산행지로 적지이다. 이 산에는 험준한 바위지대가 없는 대신 넓은 계곡이 환히 트여 있어 산행 코스로는 손색이 없다.산에는 다래나무 군락과 호랑이, 산신령 석고상이 모셔져 있는 자연석굴이 있고 정상은 참나무 수림으로 덮여 있어 시야가 그리 넓지는 못하지만 동쪽으로 수리봉 줄기 너머 구룡산이 보인다.또한 철도산행을 할 수 있는 산으로 중앙선 열차를 이용 판대역에서 하차한다. 판대역에서 이천교를 건너 아래 배내마을을 지나 서남쪽으로 차도를 따라 나가면 포장도로와 만나고 길 건너가 솔치마을이다.솔치 마을을 지나 물탕골을 통해 당산으로 오르게 된다. 물탕골은 숲이 우거져 있고 절터가 있는 지점에서 계류를 건너 왼쪽 능선으로 오르게 되는데 도중 묘지에서 우측 계곡으로 내려가면 석간수가 나온다.정상은 넝쿨로 덮혀있고, 남쪽 능선에 바위를 감고 있는 특이한 소나무가 있다.", - "MNTN_HG_VL" : "541", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 여주군, 강원도 원주시", - "MNTN_NM" : "당산" - }, - "longitude" : 126.90199010000001, - "latitude" : 37.534027799999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -2306,8 +1926,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", "MNTN_NM" : "대금산" }, - "longitude" : 128.69916670000001, - "latitude" : 34.949444399999997 + "longitude" : 127.4210301, + "latitude" : 37.818873099999998 }, { "mountain" : { @@ -2326,8 +1946,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", "MNTN_NM" : "대덕산" }, - "longitude" : 128.56, - "latitude" : 37.131943999999997 + "longitude" : 128.92944439999999, + "latitude" : 37.240833299999998 }, { "mountain" : { @@ -2336,8 +1956,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대덕면, 전라북도 무주군 무풍면", "MNTN_NM" : "대덕산" }, - "longitude" : 128.56, - "latitude" : 37.131943999999997 + "longitude" : 127.8805948, + "latitude" : 35.9249163 }, { "mountain" : { @@ -2346,8 +1966,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍", "MNTN_NM" : "대덕산" }, - "longitude" : 128.56, - "latitude" : 37.131943999999997 + "longitude" : 128.92944439999999, + "latitude" : 37.240833299999998 }, { "mountain" : { @@ -2356,18 +1976,8 @@ "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구 송현동", "MNTN_NM" : "대덕산" }, - "longitude" : 128.56, - "latitude" : 37.131943999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "큰 두메의 산'을 뜻하는 대둔산은 전북과 충남 두 도에 걸쳐있는 도립공원이다. 특이하게도 대둔산은 두 얼굴을 지니고 있다.주능선을 경계로 완주군 방향인 남쪽은 바위 얼굴이고, 북쪽은 순후한 시골 아낙네의 얼굴을 한 금산군과 논산시의 얼굴이다. 남면의 전북 지역은 가파른 비탈에 기암괴봉이 숲처럼 솟아 있어 아기자기하고 멋스러운데 비해 북면의 충남 지역은 울창한 숲이 우거져 장중해 보인다.경관이 뛰어나서 소금강이라 불리기도 하는데, 멀리서 바라보면 늘어 선 암벽이 마치 한 폭의 병풍을 연상케 한다. 그리 높지 않은 산이지만 정상인 마천대를 기점으로 충남 논산시,금산군 그리고 전북 완주군에 산자락을 펼치고 있다. 이 산은 임금바위,장군봉,동심바위,신선바위등 온통 바위로 이루어져 있으며, 이 중에서도 임금바위와 입석대를 잇는 높이 70m, 길이 50m, 폭 50cm인 금강구름다리와 삼선구름다리는 대둔산의 상징이기도 하다.", - "MNTN_HG_VL" : "879", - "MNTN_LOCPLC_REGION_NM" : "충청남도 논산시 벌곡면ㆍ금산군 진산면, 전라북도 완주군 온주면", - "MNTN_NM" : "대둔산" - }, - "longitude" : 127.32330930000001, - "latitude" : 36.120049700000003 + "longitude" : 128.56388889999999, + "latitude" : 35.816666699999999 }, { "mountain" : { @@ -2379,16 +1989,6 @@ "longitude" : 127.8202778, "latitude" : 37.844999999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "206", - "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", - "MNTN_NM" : "대명산" - }, - "longitude" : 127.5283333, - "latitude" : 37.205277799999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "산이라고 하기에는 염치가 없을 정도로 나즈막한 높이의 대모산은 서울시 강남구에 위치해 있다. 예전에는 국수봉이라고도 불리웠는데 언제부터 대모산으로 부르게 되었는지 확실치 않다.서울 변두리에 위치해 있어 잊혀지다시피한 산이었으나 인근에 아파트가 들어선 후로는 시민들의 휴식처로서의 역할을 톡톡히 하고 있다. 이른 아침 가벼운 산책을 하려는 시민들의 발길이 끊이지 않고 주말이면 많은 사람들이 이곳에 나와 도심의 찌든 때를 씻는다.이 산의 남쪽 기슭에는 헌인릉이 있어 둘러볼 만한데 헌인릉이란 조선 3대 태종과 그 왕비의 능침인 헌릉과 제23대 순조와 그 왕비의 능침인 인릉을 합쳐서 부르는 이름이다.", @@ -2401,13 +2001,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "창선섬에서 가장 높은 산, 대방산은 오르는 길이 세 갈래다. 길이 편해 등산객들이 제일 많이 오르는 코스는 옥천마을에 있는 운대암 사찰 앞을 지나서 창선저수지 위로 난 길을 따라 오르는 동쪽길이다.이 외에도 사포에서 오르는 서쪽길과 상신에서 오르는 북쪽길도 있다. 대방산(臺芳山) 산길을 굽이굽이 돌아 산마루에 오르면, 깊은 계곡 아래 저수지 물빛은 내리쬐는 햇빛이 반사되어 은하수를 만든다. 반짝이는 은하수를 돌아가면 구름에 떠 있다 하여 이름 지어진 운대암이 있다. 옥천마을 동쪽길을 따라 오르다보면 8부능선쯤 경사면에 석축을 쌓은 건물지로 보이는 평탄지가 여러 곳에 보인다.이 곳이 봉수대에 근무하는 병사들의 거주지였던 곳으로 추정하고 있다. 200m정도 더 올라가게 되면 대방산의 정상에 도달하게 된다. 여기에서 동쪽을 바라보면 넓은 강진 바다가 펼쳐지고 서쪽으로 눈을 돌려 바라보면 남해의 진산인 망운산이 보인다. 그리고 남쪽으로 보면 금산이 있고 북쪽으로는 사천 각산이 보인다.아래로 펼쳐진 앵강만은 남해안의 황금어장이다.섬 속의 섬 창선의 아름다움을 가장 가까이서 조망할 수 있는 곳이다. 가을에 대방산에서 내려다보는 단풍으로 물든 경치 또한 일품이다. 대방산 역시 중요한 군사적 요충지였던 관계로 봉수대가 설치되어 있다. 대방산 봉수대는 남해 해안에서 발생한 모든 상황을 육지로 전달하는 중간봉수로서 최남단에 위치한 금산봉수대와 사천 각산에 있는 봉수대의 교량역할을 한 중요한 지역이다.봉수대가 있는 대방산 정상은 장방형의 평탄한 자연암반으로 형성되어 있는데, 이 자연 암반 위에 직접 봉화를 올린 것으로 보인다. 축성법은 토석혼축으로 되어 있고, 현재에는 상당히 양호하게 보존되어 있는 상태이다.소요 시간 :2시간최적 탐방시기 :10월 \/가을볼거리 : 운대암, 봉수대숲길 명소 : 정상에서의 조망, 창선저수지", - "MNTN_HG_VL" : "468", - "MNTN_LOCPLC_REGION_NM" : "경상남도 남해 창선면", - "MNTN_NM" : "대방산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "대미산" }, - "longitude" : 127.98564090000001, - "latitude" : 34.858767200000003 + "longitude" : 127.77444439999999, + "latitude" : 34.674166700000001 }, { "mountain" : { @@ -2426,8 +2026,8 @@ "MNTN_LOCPLC_REGION_NM" : "충북 옥천군 이원면, 충남 금산군 군북면", "MNTN_NM" : "대성산" }, - "longitude" : 127.5427778, - "latitude" : 38.2308333 + "longitude" : 127.6154454, + "latitude" : 36.217931999999998 }, { "mountain" : { @@ -2449,6 +2049,16 @@ "longitude" : 127.9324859, "latitude" : 36.670577600000001 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "장백산령이 나려오면서 남으로 많은 산군을 융기시켰다. 청도군과 경산시의 경계를 이루는 선의산, 용각산이 융기되고 이현 복고개에서 힘을 다하는 것 같았으나 다시 마지막 힘을 뻗어 대왕산을 이루었다.학일산은 일제가 우리나라를 강제로 점령하자 학일산의 영험을 빌어 나라를 지키고자 마을 이름을 내촌에서 학일이라 고쳐 불렀다. 이와 마찬가지로 항일 죽창 의거사건과 관련이 깊은 대왕산 또한 민족혼이 어린 명산이라 하겠다. 근래 마을에는 수질, 수온, 수량 등 조건이 양호한 온천수가 발견되었다.", + "MNTN_HG_VL" : "605", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "대왕산" + }, + "longitude" : 128.83631489999999, + "latitude" : 35.746121799999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "대운산은 울산광역시와 부산광역시, 경남 양산시의 경계에 있는 산이다. 금정산에서 원효산, 천성산을 이어가는 낙동정맥이 그 중간에서 동쪽으로 곁가지를 내려 백운산(520m), 철마산(604m), 거문산(543m), 달음산(588m), 용천산(545m) 등을 차례로 일으킨다. 그 중 최고봉인 대운산은 2개 광역시와 경상남도의 경계선을 긋는 중요한 곳에 자리하고 있으며, 장안사, 척판암, 내원암 등 역사의 향기가 가득한 명찰을 자락에 품고 있는 남녘의 명산이다.대운산을 오르는 산길은 다양하나 겨레의 영원한 스승 원효대사의 발자취를 찾아 기장군 장안읍에 자리한 장안사를 거쳐 오를 수 있다. 장안사는 신라 문무왕 13년(서기 673년) 원효대사가 창건한, 오랜 역사를 자랑하는 고찰이다.‘불광산(대운산의 다른 이름) 대운사’라고 쓰인 문을 지나 들어선 장안사 뜨락에는 동백꽃이 뚝뚝 지고 고목들이 연륜을 알려주는 경내에는 불향이 그득 넘친다. 장안사 절문을 나서면 오른쪽에 참으로 특이한 해우소(변소)가 보인다. 굵은 왕대를 엮어 울타리를 두른 멋진 해우소. 볼 일이 급하지 않더라도 잠시 들러 왕대나무 화장실의 멋을 엿보아야 한다.", @@ -2459,6 +2069,26 @@ "longitude" : 129.21184489999999, "latitude" : 35.402419600000002 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 홍천군 동면과 서석면의 경계에 자리한 대학산은 양옆으로 공작산(887m)과 발교산(998m)을 끼고 있으며 수림이 울창하여 첩첩산중이라는 말이 실감나는 오지의 산이다.이 산에 있는 물골은 본래 `수동'이라 불리었으며 계곡이 크다 해서 예로부터 주민들 사이에는 큰골로 통했다. 물골에서 시작하는 이 산행은 교통이 불편한 게 흠이지만 일단 산에 들어서면 속세와 완전히 격리된 듯한 분위기를 만끽할 수 있는 곳이다.숲과 단애, 낙엽송 수림, 노송이 있는 6월의 대학산은 자연의 생기찬 모습이 그대로 전달되어 오는 자연에 푹 빠진 산행으로 코스를 마칠 수 있는 깨끗한 산이다.정상에서의 조망은 서북쪽으로 공작산이 가깝게 보이고 동쪽으로는 수리봉에서 병무산으로 이어지는 능선이 시야를 막고 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 서석면", + "MNTN_NM" : "대학산" + }, + "longitude" : 128.085553, + "latitude" : 37.674847499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "괴산군 연풍면과 장연면의 경계를 이루고 있는 덕가산은 충북의 유명산 악휘봉(940m)과 이웃해 있다. 악휘봉이란 명산에 가려져 빛을 보지 못한 산이기도 하다.덕가산은 악희봉과 반대로 육산이며, 정상에는 삼각점과 깃대봉이 있다. 주능선에는 상수리나무가 주종을 이루고 등산화를 파묻히게 하는 낙엽의 아삭아삭하는 소리가 홀로 걷는 이의 빈 마음을 채워주어서 좋다.주위에 여러산들이 기암절벽으로 산을 감싸고 있는 반면 산세가 부드럽고 장송들이 많아 여성적인 자태를 지니고 있다.", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면", + "MNTN_NM" : "덕가산" + }, + "longitude" : 127.95, + "latitude" : 36.75 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "덕갈산은 산청,거창,함양군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳에서 양분 되어 한줄기는 갈전, 철마, 소룡, 바랑산을 거쳐 황매산으로 뻗어있고 또하나가 바로 덕갈산 줄 기를 이루며 그 끝은 태봉산까지 길게 이어져 있다. 마치 떡가래처럼 널어져 있는 형세를 하고 있으며 그 줄기위에서는 지리산을 정면으로 바라볼수 있어 주변의 1000m 내외의 산들과 구별되어 산중에 제왕임을 한눈에 알 수 있게한다. 또한 덕유산에서 지리산으로 흐르다 출렁이면서 솟아 오 른 고봉들도 조망이 가능하여 덕갈산을 방문한 등산객에게만 산행의 참맛을 선사한다. 덕갈산은 가슴을 확트이게하고 눈을 즐겁게 하는 산으로 자신을 자랑하기보다는 주변 산들의 기상 과 기세를 칭찬하는 겸손한 산이다.", @@ -2479,26 +2109,6 @@ "longitude" : 128.16441259999999, "latitude" : 37.471818200000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "종남산에서 남릉을 따라 4Km 지점에 종남산과 같은 형태의 산봉이 솟아있는데 이 산이 덕대산이다. 산 아래에 있는 초동면에 이 산의 정기를 받아 인물이 많이 난다는 뜻에서 붙여진 이름으로 산의 전체적인 형세는 종남산과 더불어 내륙산의 모습을 하고 있다. 북릉은 종남산에 중봉을 거쳐 연결되고 동릉은 남산마을 쪽으로 급하게 쏟아지고 있다. 서릉은 무안면 쪽으로 길게 뻗어나가면서 완만한 산세를 펼치고 있지만 산세를 열고 있는 쪽은 남쪽사면으로 초동면을 품고 있다.", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 하남읍 남전리", - "MNTN_NM" : "덕대산" - }, - "longitude" : 128.0386111, - "latitude" : 36.087499999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕두산은 남원 운봉고원(해발 500m)의 동쪽에 철쭉군락지 바래봉과 함께 지리산국립공원의 서부지역의 북단 가장자리에 솟아 있다. 이 산은 험준한 산악지대요 울창한 산림에다 봄의 철쭉, 약초 등이 많이 자라고 있어 등산객보다는 봄나물, 약초캐는 아낙네들의 발길이 더 잦은 곳이다. 산행은 중군리 중군마을이나 인월리 용계마을에서 시작할 수 있으나 중군마을에서 시작하여 신인월로 하산하는 것이 좋다.", - "MNTN_HG_VL" : "1150", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원 운봉읍, 동면, 산내면", - "MNTN_NM" : "덕두산" - }, - "longitude" : 127.5807889, - "latitude" : 35.427014999999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "덕룡산과 주작산은 높이에 따라 산세가 좌우되지 않는다는 사실을 깨닫게 하는 산이다. 해남 두륜산과 이어져 있고 높이라야 고작 400미터를 조금 넘지만 산세만 놓고 보면 1000미터 높이의 산에 뒤지지 않는다. 이 산은 웅장하면서도 창끝처럼 날카롭게 솟구친 암릉과 암릉 사이의 초원능선 등 능선이 표현할 수 있는 아름다움과 힘의 진수를 보여준다. 두륜산과 경계를 이루는 오소재에서 주작산, 덕룡산, 소석문까지 이어지는 11킬로미터 암릉은 마치 봉황이 날개를 펴고 하늘로 비상하는 형상이다. 봄이면 산꾼의 가슴을 태워버릴 듯 암릉에 흐드러지게 핀 진달래가 탄성을 자아내게 하고, 여름이면 은빛으로 빛나는 다도해와 누렇게 익은 보리밭의 조망, 가을이면 억새와 단풍 그리고 사시사철 신이 빚어 놓은 만물상이 연이어지는 스릴 넘치는 암릉이 산행의 백미다. 주작산은 강진군 신전면, 도암면, 해남군 옥천면, 북일면을 경계하고, 덕룡산은 강진군 도암면과 신전면을 경계한다. 덕룡산 정상에서 조망은 북으로 흑석산과 만의산, 만덕산과 월출산, 북동으로 궁성산과 국사봉, 수인산과 제암산, 동으로 천관산과 일림산, 남으로 두륜산과 상황봉, 서쪽은 두륜산과 첨찰산이 보인다.", @@ -2516,18 +2126,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍 수철리 449", "MNTN_NM" : "덕봉산" }, - "longitude" : 129.23928380000001, - "latitude" : 37.388126799999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕성산은 경기도 안성에 위치한 산으로 칠현산, 칠장산의 세 산이 능선상으로 바로 이웃하여 연결되어 있어 세산을 이어 종주 할 수도 있는 산이다. 칠현산, 칠장산은 걸미 삼거리에서 신대 마을로 들어가는 도중에 우측으로 지름길이 있어 이용할 수 있으며, 신대마을에서 칠장사까지는 약 40분이 소요된다.칠장사는 신라 때 창건 되었으며, 해소 국사비(보물 488호)와 인목대비의 친필족자(지방 문화재)가 있다.또한 덕성산은 정상에서 서쪽 능선으로 하산하는 길은 수림이 매우 우거져 있어 심마니들이 이용하는 길 같기도 하다.", - "MNTN_HG_VL" : "519", - "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 금광면", - "MNTN_NM" : "덕성산" - }, - "longitude" : 126.96856200000001, - "latitude" : 37.318686999999997 + "longitude" : 126.8822222, + "latitude" : 36.713611100000001 }, { "mountain" : { @@ -2556,18 +2156,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선군 임계면", "MNTN_NM" : "덕우산" }, - "longitude" : 127.74638899999999, - "latitude" : 35.860556000000003 + "longitude" : 128.83387450000001, + "latitude" : 37.512631599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "단양팔경에 속하는 하선암과 사인암 사이에 솟아있는 덕절산은 미개의 산으로 태고의 자연미를 그대로 보존하고 있다.겉으로 보기엔 평범한 육산의 형태를 많이 보여주지만 실지 산행시엔 암릉을 타고 올라가는 재미가 쏠쏠한 산이다.덕을 마디마디 산으로 만든다는 의미인지 덕을 끊어 버리고 산으로 남겠다는 것인지 모르겠지만 덕절산은 그 이름이 들려주는 느낌으로는 아주 후덕한 단양의 인심을 떠올리는 산이다. 후덕함속의 날카로운 비수를 간직한 산답게 숨겨놓은 비경이 많은 것이 특징이다. 특히 암릉에 온갓 풍상을 꿋꿋하게 버티며 자라고 있는 노송들의 자태가 청년의 기상에 노년의 완숙미가 함께 풍기는 모양새로 소나무의 미학을 보여주고 있었다.정상에서의 조망은 일품이다. 동으로는 소백산의 각 연봉, 남으로는 황정산과 도락산의 절경들이 웅장함을 더한다. 북으로는 충주호가 은빛물결을 출렁이며 산사람들을 유혹하고 있다.", - "MNTN_HG_VL" : "780", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", - "MNTN_NM" : "덕절산" + "DETAIL_INFO_DTCONT" : "덕유산은 전북 무주군과 장수군, 경남 거창군과 함양군의 경계를 이루며, 2도 4군 8개면에 걸쳐있다. 한라산.지리산.설악산에 이어 남한에서 4번째로 높고 1000미터 이상의 봉우리가 20개도 넘는 거대한 산이다.덕유라는 이름은 덕이 있고 크며 넉넉한 산의 모습을 나타낸 말이다. 무학대사가 골치아픈 정권에서 벗어나 첩첩산중 경치 아름다운 산을 물색하다가 발견했다는 산이 바로 덕유산이다.", + "MNTN_HG_VL" : "1614", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군ㆍ장수군, 경상남도 거창군ㆍ함양군", + "MNTN_NM" : "덕유산(향적봉)" }, - "longitude" : 128.3307547, - "latitude" : 36.897567299999999 + "longitude" : 127.7468314, + "latitude" : 35.860032799999999 }, { "mountain" : { @@ -2589,16 +2189,6 @@ "longitude" : 127.4473366, "latitude" : 35.6892979 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "환선굴'로 유명해진 덕항산은 강원도 삼척시 신기면에 자리해 있다.이 산은 동남으로 펼쳐진 병풍암을 비롯하여 깎아놓은 듯 반듯한 암석과 거대한 암벽들이 수려한 산세를 이루며 동으로는 오십천으로 합류하는 12km길이의 무릉천이 흐르고 있어 산행하기 적합한 곳이다.", - "MNTN_HG_VL" : "1073", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면ㆍ태백시 하사미동", - "MNTN_NM" : "덕항산" - }, - "longitude" : 129.01166670000001, - "latitude" : 37.308888899999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다. 또한 기슭에는 고찰 도갑사(道岬寺)가 있고 이곳에는 국보로 지정된 해탈문, 보물로 지정된 석조여래좌상 등이 있다. 특히, 도갑산을 포함한 월출산이 국립공원으로 지정된 후 관광지로서 각광을 받고 있다.", @@ -2629,6 +2219,36 @@ "longitude" : 127.2780556, "latitude" : 36.348888899999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "두덕산(斗德山)이라 불리기도 했던 이 산은 산세야 그리 빼어나다고 할 수 없지만, 아담하고 조망이 시원한 정겨운 산이다. 낙동정맥 마루금이 지나면서 경북 경주시 안강읍과 영천시 고경면을 가르는 배티재 옆에 비켜 앉은 도덕산은 결국 그 지맥이 북쪽, 낙동정맥으로 이어진다. 아직까지 널리 알려져 있지 않은 관계로 이 지역 등산객들과 정맥 종주꾼들이 간간이 찾을 정도다. 남쪽의 자옥산(紫玉山, 569.9m)과는 능선을 맞대고 이웃해 있으며, 산기슭에는 볼 만한 문화유적도 많다. 동쪽 산자락을 따라 흐르는 옥산천(玉山川)의 자연과 어우러진 독락당, 옥산서원을 비롯해 주변에 산재한 문화유적을 둘러볼 수 있다.", + "MNTN_HG_VL" : "703", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 안강읍·영천시 고경면", + "MNTN_NM" : "도덕산" + }, + "longitude" : 129.1391667, + "latitude" : 36.025277799999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 이천의 도드람산은 높이도 보잘 것 없고 코스도 짧다. 하지만 능선 전체가 암석으로 이뤄져 바위타는 재미에 있어서는 수도권 산 가운데 으뜸이다. 등산 동호인들의 말을 빌리자면 '바위맛'이 좋은 산이라고 한다. '바위맛'이란 발뿐 아니라 손을 이용해 바위 뿌리 등을 잡고 가는 등산로의 아기자기함을 뜻하는 은어이다.'이천의 소금강'이라 불리는 도드람산은 일명 저명산(猪鳴山)이라고도 부른다. 저명산의 한문 표기의 '돗 저''울 명'의 돗울음산이 변하여 도드람산으로 부르게 된 것으로 전해지고 있다산 중턱에 있는 영보사 뒷편 절벽 아래서 샘솟는 차고 시원한 석관수의 맛이 일품이며,능선을 따라 바위를 오르는 등산객의 아기자기함이 산행의 묘미를 만끽하게 해준다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 마장면", + "MNTN_NM" : "도드람산" + }, + "longitude" : 127.39193779999999, + "latitude" : 37.266356700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "‘이otilde;의 소금강’으로 불리는 도드람산은 남북으로 이어진 작고 낮은 산줄기에 불뚝불뚝 솟아오른 암봉의 아기자기한 모양새가 가시가 돋아 난 공룡 등brvbar;과도 같다. 저명산(돼지울음산, 猪鳴山)이라는 독특한 이름으로도 불리는 이 산은 높이는 낮지만 기암괴석의 봉우리들로 이어진 산세가 절경을 이루고 있어 이otilde; 제일의 명산으로 불린다. 또한 산과 관련된 여러 전설이 깃든 곳이고, 바위를#376;고 넘는 등산로가 일품이어서 주말이면 많은 등산인들이atilde;는 이름난 명승지이기도 하다.산은 그다지 높지 않아도 평지에 솟아 있어 조망이 좋고 힘들지 않게 암릉산행을 즐길 수 있는 이점이 있다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 마장면", + "MNTN_NM" : "도드람산" + }, + "longitude" : 127.39193779999999, + "latitude" : 37.266356700000003 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "우암 송시열 선생이\"도를 깨닫고 스스로 즐길 만한 곳이다\"해서 도락산이라 명명한 이 산은 경북과 충북의 도경계선에 근접해 있다.월악산국립공원권에 속해 있는 산으로, 충북 단양군 단양읍과 대강면의 경계를 이루고 있으며 도락산 산자락에는 단양 8경 중 4경인 사인암,상선암,중선암,하선암 등이 있어 관광의 보고이기도 하다.", @@ -2639,16 +2259,6 @@ "longitude" : 128.31169420000001, "latitude" : 36.856228899999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "한북정맥 분기점에 위치해 있으며, 경기 제1의 비경지대 도마치계곡을 안고 있는 도마치봉은 백운계곡, 도마치계곡, 반암계곡이 모아지는 삼각지점에 자리해 수려한 산세와 사방으로 거칠 것 없는 시원한 시야를 갖추고 있는 산이다.궁예가 왕건에게 쫓기면서 도망친 산이라는 설과, 사람과 말이 모두 걸어서 넘었다는 전설로 '도마치'가 되었다는 이 산은 비경지대인 도마치계곡이 민간인 출입금지구역으로 되어 있어 아쉬움이 남는다.자연보존상태가 좋으나 정상 접급이 길고 험준하다. 정상 일대에서는 시야를 가릴 큰 나무는 없다. 도마치봉에서는 국망봉과 국망봉에서 가리산으로 이어지는 능선이 눈 앞에 보이고, 신로령에서 국망봉으로 이어지는 밋밋한 능선이 시야에 들어 온다.", - "MNTN_HG_VL" : "937", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", - "MNTN_NM" : "도마치봉" - }, - "longitude" : 127.39564439999999, - "latitude" : 38.038512799999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "뛰어난 풍광으로 우암 송시열이 낙향하여 머물던 화양구곡 중앙부에 위치한 도명산은 국립공원 속리산에 속하여 있으며 태고의 신비와 자연의 오묘한 섭리를 안고 있는 산이다. 첨성대 바위, 흔들바위 등 자연이 빚어낸 기묘한 형태에 기암과 암릉(岩陵)이 곳곳에 산재해 있으며 특히 정상부를 차지하고 있는 기암 덩어리인 정상 바위는 가히 일품이라 할 수 있다.정상은 크고 작은 바위 다섯 개가 하나로 정상을 이루고 있다. 정상에서의 조망은 북쪽 아래로는 화양동 계곡과 군자산, 칠보산이 펼쳐지고, 동쪽으로는 대하산, 남쪽으로는 낙영산, 주봉산, 멀리 속리산 능선과 문장대가 들어온다. 주변에는 분재처럼 자란 소나무가 정취를 더한다. 화양동계곡은 기암괴석으로 이뤄진 절경이 아홉 곳이나 된다고 해서 '화양구곡'(華陽九曲) 또는 '화양동 소금강'으로 불린다. 이곳은 경치가 너무 아름답고 물이 맑아 조선시대의 조선조 대유학자였던 우암 송시열 선생이 조정을 물러나와 은거하던 곳으로도 유명하다.이곳에 반한 조선 후기의 유학자 우암 송시열은 화양동주(洞主)로서 은거하며 이곳이 중국의 무이구곡을 닮았다 하여 9곡의 이름을 짓고 경천벽·금사담\\·첨성대 등의 바위에 글씨를 새겼다.제1곡 경천벽은 깎아지른 층암절벽이 하늘을 떠받치고 있으며, 화양2교 옆의 2곡 운영담은 구름이 비치는 담 주변에 넓은 모래사장이 있다. 3곡은 우암이 새벽에 올라 효종의 승하를 통곡했다는 읍궁암으로 민박집과 식당이 많다. 서원철폐의 빌미가 된 화양서원을 거쳐 하마소와 채운사 등의 명소가 있다.제일 수려한 4곡 금사담은 금모래가 반짝이며 넓은 암반 위에 우암의 암서재가 노송 사이에 있다. 화양3교 직전 바른쪽 낙영산 정상의 기암절벽인 5곡 첨성대는 별을 관측하던 곳이다. 더 가면 심곡에 큰 2층바위인 6곡 능운대가 나오며 7곡 와룡암, 8곡 학소대, 9곡 파천이 있다.", @@ -2671,23 +2281,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "소백산 국립공원에 속하는 도솔봉은 충북 단양과 경북 영주의 경계를 이루는 산으로 형제봉과 더불어 가장 한적한 육산으로 꼽히고 있다. 도솔봉은 소백산의 축소판이라 불릴만큼 한 키나 되는 철쭉과 진달래가 화원을 이루며 각종 고산식물이 많다. 또한 숲길 가득 수목이 울창하고 계곡마다 꽃피는 초본류가 무성하여 발길 닿는 곳마다 풍치가 그만이다.정상 도솔봉을 주축으로 삼형제봉과 묘적봉을 거느리고 우뚝 솟아 있으며, 능선에는 바위지대와 억새등이 있다.정상 암봉에 서면 중령에서 장엄하게 뻗어 오른 소백산의 장릉을 끝까지 바라볼 수 있어 황홀하고, 남쪽으로는 활같이 구부러지면서 황정산으로 이어내린 백두대간이 아련하기만 하고, 단양팔경으로 유명한 산야가 펼쳐 보인다.", - "MNTN_HG_VL" : "1314", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시, 충청북도 단양군", - "MNTN_NM" : "도솔봉" - }, - "longitude" : 128.42567840000001, - "latitude" : 36.876253699999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백운산과 도솔봉은 동서로 나란히 능선상으로 이웃하고 있다. 동쪽 봉우리가 백운산, 서쪽 봉우리가 도솔봉으로 둘 다 1,100미터가 넘는 고산으로 그 위용이 당당하다. 백운산 서쪽의 도솔봉(1123.4m)에서 광양만으로 이어진 도솔봉 능선은 사람의 발길이 닿지않은 원시의 그리움이 그대로 보존된 곳이다. 산짐승이나 다녔음직한 그 호젓한 능선길은 진달래 철쭉이 군락을 이루고 있어 봄에는 황홀한 경관을 연출한다.도솔봉 자락은 조선의 학자이자 우국지사인 매천(梅泉) 황현의 고향답게 백운란·백운원추리·고로쇠나무·철쭉 등이 백운산에 못지 않다. 특히 봄철이면 백운산의 고로쇠나무 수액을 마시기 위해 전국에서 많은 산꾼들이 모여드는 곳으로도 유명하다.전라남도에서 지리산 다음으로 높은 산이 백운산이며, 조계산, 무등산과 같이 남해안을 따라 산맥을 형성한다. 또 광양읍에서 북쪽 약 12km지점에 위치하며 주봉은 동주리봉, 형제봉, 도솔봉, 백운산 매봉을 잇고 있다. 4개의 지능은 남쪽으로 뻗어 바다로 빠진다.", - "MNTN_HG_VL" : "1125", - "MNTN_LOCPLC_REGION_NM" : "전라남도 광양", - "MNTN_NM" : "도솔봉" + "DETAIL_INFO_DTCONT" : "도비산은 서산시에서 연암산(441m)과 팔봉산(362m)에 이어 3번째로 높다. 정상에 올라서면 서해 조망이 뛰어나다. 주변에는 안면도 간월암 수덕사 등 관광명소가 산재해 있어 여름철 가족 산행지로 적격이다.산행 들머리는 추평리 부석사 입구에서 시작된다. 이곳서 시멘트로 포장된 농로를 따라 30여분을 올라가면 부석사에 닿는다. 급경사길을 20여분 오르면 능선에 닿는다. 능선길을 따라 15분 정도 걸으면 바로 정상. 그만큼 산행을 하기에 어려움이 없다. 정상에 오르면 천수만 간척지를 비롯해 너른 들판과 그 너머로 서해바다가 손짓한다. 도심에서는 느낄 수 없는 포근함이 다가온다. 또 겨울이면 간월호와 부남호의 철새를 볼 수 있다.일설에 의하면 산 대부분이 나무로 덮여 있어 봄이면 복숭아꽃으로 산을 장식하고, 주위에 낙화가 소복이 쌓이는 데서 연유되어 [복숭아 도]자 와 [살찔 비]자를 써서 도비산이라 이름 붙였다고 한다.", + "MNTN_HG_VL" : "352", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 인지면", + "MNTN_NM" : "도비산" }, - "longitude" : 128.42567840000001, - "latitude" : 36.876253699999999 + "longitude" : 126.41607550000001, + "latitude" : 36.702880200000003 }, { "mountain" : { @@ -2701,9 +2301,9 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "상주시 화북면과 문경시 농암면 경계에 솟은 도장산은 계곡미가 빼어난 경북의 숨은 명산이다. 용추에서ucirc;룡, 황룡이 살았다하여 쌍용계곡이라 불리는 골yen;기를 따라 선녀들이 내려와 목욕을 하였다는 선녀탕, 암반 아래에 명주실 한#376;래가 들어간다는 깊은 용추(용소) 등 오랜 세월 풍화를 겪은 기암괴석과 맑고 깊은 물이 어우러져 시원한 절경을 자아낸다.도장산이 걸쳐있는 상주시 화북면은 십승지 중 하나인 우복동otilde;(牛腹洞川)의 명당터로 알려져 있다. 그리하여 예부터 ‘삼산삼수(三山三水)의 고장’으로 불리어왔는데 도장산이 속리산(1057.7m),ucirc;화산(984m)과 함께 삼산에 속해 경치 좋고 사람 살기 좋은 곳으로 꼽혀왔다. 상주시에서는 이 삼산을 하나로 엮어 2007년 ‘우복동otilde;’ 산행 코스를 정비하였다. 이 중 도장산은 5.2킬로미터 구간이 조성되어 있다.도장산 정상은 밋밋한 편이다. 그러나 속리산을 조망하기에는 더 없이 좋다. 정상에 서면 속리산otilde;황봉으로부터 뻗어지는 문장대까지 한눈에 볼 수 있다. 산자락에 위치한 심원사는 원효대사가acirc;건한 고찰로서 고즈넉하고 소박한 암자의 모습을 간직하고 있다.", + "DETAIL_INFO_DTCONT" : "", "MNTN_HG_VL" : "828", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면 용유리, 문경시 농암면", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시", "MNTN_NM" : "도장산" }, "longitude" : 127.94232150000001, @@ -2711,9 +2311,9 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", + "DETAIL_INFO_DTCONT" : "상주시 화북면과 문경시 농암면 경계에 솟은 도장산은 계곡미가 빼어난 경북의 숨은 명산이다. 용추에서ucirc;룡, 황룡이 살았다하여 쌍용계곡이라 불리는 골yen;기를 따라 선녀들이 내려와 목욕을 하였다는 선녀탕, 암반 아래에 명주실 한#376;래가 들어간다는 깊은 용추(용소) 등 오랜 세월 풍화를 겪은 기암괴석과 맑고 깊은 물이 어우러져 시원한 절경을 자아낸다.도장산이 걸쳐있는 상주시 화북면은 십승지 중 하나인 우복동otilde;(牛腹洞川)의 명당터로 알려져 있다. 그리하여 예부터 ‘삼산삼수(三山三水)의 고장’으로 불리어왔는데 도장산이 속리산(1057.7m),ucirc;화산(984m)과 함께 삼산에 속해 경치 좋고 사람 살기 좋은 곳으로 꼽혀왔다. 상주시에서는 이 삼산을 하나로 엮어 2007년 ‘우복동otilde;’ 산행 코스를 정비하였다. 이 중 도장산은 5.2킬로미터 구간이 조성되어 있다.도장산 정상은 밋밋한 편이다. 그러나 속리산을 조망하기에는 더 없이 좋다. 정상에 서면 속리산otilde;황봉으로부터 뻗어지는 문장대까지 한눈에 볼 수 있다. 산자락에 위치한 심원사는 원효대사가acirc;건한 고찰로서 고즈넉하고 소박한 암자의 모습을 간직하고 있다.", "MNTN_HG_VL" : "828", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면 용유리, 문경시 농암면", "MNTN_NM" : "도장산" }, "longitude" : 127.94232150000001, @@ -2731,13 +2331,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "최고봉인 비로봉을 비롯하여 호령봉, 상왕봉, 두로봉, 동대봉의 5개 대를 합쳐 오대산이라 부른다.오대산은 주봉인 비로봉을 비롯해서 다섯 개의 연봉이 주축을 이루면서 마치 연꽃처럼 피어올라 있으며, 이들 연봉의 사이사이에도 노인봉, 계방산, 복용산 등 그만그만한 준봉들이 숱하게 솟아있고 오대산 일대의 주요 산마루는 거의 대부분이 평정봉으로 그 풍치는 마치 우아한 여성의 성격을 띠고 있는 것이 특징이다.태백산맥의 중추를 이루며 산세가 만만치 않아 주요 코스 이외에는 아직도 개발이 안된 부분이 많은 산이다. 월정사 일대의 전나무들과 단풍이 유명하고 상원사 적멸보궁 등의 명소가 많아 관광객이 끊이지 않는다. 75. 2. 1 일 11번째 국립 공원으로 지정됨 태백산맥에서 남서 방향으로 뻗어 충청북도와 남도를 거쳐 태안 반도에 이르는 차령산맥의 분기점이 되는 오대산은 한강 발원지의 하나인 오대천 상류를 둘러싸고 수려한 계곡을 조성하고 있다.연꽃 같은 산세의 화심의 명당에는 적멸보궁이 있고, 동대산록에는 고찰 월정사가 있으며, 상원사에서 적멸보궁까지는 완만한 길을 지그재그로 오르게 된다.", - "MNTN_HG_VL" : "1434", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면", - "MNTN_NM" : "동대산" + "DETAIL_INFO_DTCONT" : "충북 제천시 금성면, 청풍면 교리·단양군 적성면 경계에 솟은 동산(東山)은 남근석으로 유명하다. 이 남근석이 동산을 대표한다 해도 과언이 아니다. 어른 두 세 명이 팔로 에둘러야 할 정도의 굵기와 약 3미터 높이의 크기를 자랑하는 남근석은 동산의 생명력과 원천의 상징이기도 하다. 대체로 산세가 가파르나 수려하며 동산을 지키는 수많은 기암괴석은 노송과 어우러져 운치를 더한다. 동산의 정상은 원래 세 개의 봉우리를 형성하고 있어 삼봉(三峰)이라 불렸다고 한다. 북으로는 작성산(848m), 마당재산(661.2m), 호조산(475.3m)의 산줄기를 이어받아 솟은 동산은 남으로는 금수산(1015.8m)을 빚는다.", + "MNTN_HG_VL" : "896", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면, 청풍면·단양군 적성면", + "MNTN_NM" : "동산" }, - "longitude" : 129.28397870000001, - "latitude" : 36.310201900000003 + "longitude" : 128.22666670000001, + "latitude" : 37.024722200000006 }, { "mountain" : { @@ -2751,23 +2351,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 평창군 방림면과 영월군 수주면 경계를 이루는 백선산 남쪽 능선 가운데쯤 되는 곳에서 남서쪽으로 갈라지는 또 다른 능선이 있다.돼지봉은 이 남서릉의 최고봉으로 산세가 빼어나고 알려지지 않은 비경이 많은 산이다. 낙화함을 연상케하는 수십길 바위절벽, 그 바위절벽 위에 4평 남짓한 요선정이라는 정자가 서 있다. 요선정은 수백년정 무릉마을에 살았던 이(李), 원(元), 곽(郭)씨등 세 문중에서 뜻을 모아 세운 것으로 전해지고 있는데 요선정의 뜻을 신선을 맞이한다는 것이다. 정자 옆으로는 15척 높이의 마애석불이 서 있다. 이 정자 및 무릉계곡에는 억겁 세월의 물결에 깎인 화강암이 기묘한 형상을 한 채 깔려 한 폭의 동양화를 연상케 하는데, 이 곳을 요선암이라 부르게 된 이유는 조선 중기의 풍류가이며 강릉부사를 지낸 양사연이 이곳 경치에 반하여 선녀탕 위 바위에 요선암이라는 글자를 생긴데서 연유한다.이 산에 들어서면 첫째 공가와 초목의 향기가 예사롭지 않음을 직감하게 되고 티 없이 깨끗하게 유지되고 있는 산이다. 정상에는 삼각점이 매설되어 있으며 깃발이 세워져 있다. 정상에서 조망은 동쪽으로 굽이굽이 돌아 흐르는 평창강과 주천강이 무릉도원을 이루면서 흘러 특히 아름답고 북의 백덕산 서편의 치악산 장릉이 아련하다.", - "MNTN_HG_VL" : "818", + "DETAIL_INFO_DTCONT" : "강원도 영월에 화채봉과 구룡산 사이에 솟아 있는 된불데기산은 위험지대가 없고 묵밭지대 초원이 산재해 있어 가족산행지로 안성맞춤이다.된불이란 말은 사냥꾼들이 쓰는 용어로 급소를 맞힌 총알을 일컫는데 전에 이 산에 멧돼지가 많아 마을 주민들이 멧돼지 사냥을 하면서 된불데기 산이라 불렀던 것이 산 이름의 유래가 되었다. 사람들 발길이 뜸하여 기름진 땅에서 자란 약초들은 유난히 향이 진하다.정상에 서면 북으로 화채봉과 삿갓봉 오봉산이 펼쳐져 있고 동으로는 백덕산이, 남으로는 구룡산이 시야에 들어온다.서쪽으로는 운학천 계곡 건너로 배향산이 멀리의 치악산 비로봉과 매화산 등과 함께 조망된다.", + "MNTN_HG_VL" : "910", "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", - "MNTN_NM" : "돼지봉" + "MNTN_NM" : "된불데기산" }, - "longitude" : 126.9708945, - "latitude" : 37.530080300000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "250", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", - "MNTN_NM" : "두개비산" - }, - "longitude" : 127.88284899999999, - "latitude" : 37.727337299999988 + "longitude" : 128.2186111, + "latitude" : 37.347499999999997 }, { "mountain" : { @@ -2776,18 +2366,38 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", "MNTN_NM" : "두루봉" }, - "longitude" : 127.53547759999999, - "latitude" : 36.507948900000002 + "longitude" : 128.64944439999999, + "latitude" : 37.572222199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한반도의 최남단에 위치한 두륜산(700m)은 백두대간에서 뻗은 호남정맥이 바다에 이르면서 마지막으로 솟아 오른 산이다.전남 해남군 삼산면과 현산면의 경계를 이루는 산으로 일명 대둔산(大芚山)이라고도 불린다. 임진왜란 당시 전국의 산야를 누비며 왜적을 몰아낸 서산대사는 이곳 두륜산을 '만고에 깨지지 않고 삼재가 미치지 않는 산' 이라 했다. 삼재가 들지 않는다는 것은 홍수나 재해에서 안전하다는 뜻이다.실제로 두륜산은 북으로는 월출산이 하늘을 받쳐주고 남으로는 달마산이 지축을 맺어 주고 있어 옛 조상들로부터 풍수지리적으로 인정받은 산이다. 상상의 산이며 산의 조종으로 알려진 곤륜산과 백두산에서 연유했다는 뜻에서 두 산의 한자씩을 따 두륜산이라 이름 지었다고 한다.", - "MNTN_HG_VL" : "700", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 삼산면ㆍ북일면ㆍ북평면ㆍ현산면", - "MNTN_NM" : "두륜산" + "DETAIL_INFO_DTCONT" : "두류산은 강원도 화천군 사내면과 하남면 사이에 위치한 산으로 위도상 38도선 북방 12km거리에 자리하고 있어 민간인들의 출입이 뜸한 곳이다. 그래서 백마계곡의 수려한 계곡미와 울창한 수림, 기암절벽이 이룬 아름다운 조화를 그대로 간직하고 있다.백마계곡에는 대명사와 신선바위 등이 있고, 청정지대로 유지되고 있다. 계곡 물이 맑고 숲이 울창해 여름산행에는 제격인 산이다.정상은 운모가 섞인 광석토양이라 나무 한그루 풀 한 포기 없지만, 사방으로 펼쳐진 두류산의 주름진 자락을 한눈에 볼 수 있다.금강산을 찾아가던 신선들이 이 산 경관에 반해 잠시 머물다 갔다는 전설이 전해질 정도니 이 산을 직접 가보지 못한 사람들도 그 절경은 가히 짐작할 만 하다.마치 명월이가 누워 있는 옆모습 같다 하여 두류산이라 불리며, 마을 이름도 명월리이다.", + "MNTN_HG_VL" : "993", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면 하남면", + "MNTN_NM" : "두류산" }, - "longitude" : 126.6193897, - "latitude" : 34.4792889 + "longitude" : 127.5457596, + "latitude" : 38.103257200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "993", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천", + "MNTN_NM" : "두류산" + }, + "longitude" : 127.5457596, + "latitude" : 38.103257200000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "993", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면, 하남면", + "MNTN_NM" : "두류산" + }, + "longitude" : 127.5457596, + "latitude" : 38.103257200000002 }, { "mountain" : { @@ -2809,16 +2419,6 @@ "longitude" : 128.7534191, "latitude" : 37.212416400000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "두타산은 부처가 누워있는 형상으로 박달령을 사이에 두고 청옥산과 마주하고 서 있다. 울창한 수림과 기암절벽에 노송이 뿌리를 내려 산세가 수려한 두타산은 강원도 국민관광지 1호로 지정돼 있다.두타산의 '두타(頭陀)'란 '속세의 번뇌를 버리고 불도를 닦는 수행'을 말한다. 이는 두타산이 불교와 인연이 깊은 불교의 도량임을 미루어 짐작할 수 있다. 지금은 삼화사,관음암,천은사가 남아 있지만 10여개의 사찰이 있다는 옛기록으로 보아 무릉계는 불교가 크게 번성했던 두타의 도량이었던 같다.", - "MNTN_HG_VL" : "1357", - "MNTN_LOCPLC_REGION_NM" : "강원도 동해시 삼화동, 삼척시 미로면ㆍ하장면", - "MNTN_NM" : "두타산" - }, - "longitude" : 129.09999999999999, - "latitude" : 37.259999999999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "두타산은 진천군 초평면, 괴산군 도안면과 증평읍의 경계를 이루고 있으며, 능선이 마치 부처가 누워있는 모습을 하고 있다. 진천의 상산8경 중 하나인 고찰 영수사를 산자락에 품고 있으며 은은한 종소리와 함께 아름다움을 간직한 명산으로 손꼽힌다.두타산 정상엔 삼국시대에 축조된 것으로 추정되는 석성이 자리하고 있는데, 길이 1킬로미터, 높이 1.2미터의 규모로 성내에는 두 개의 우물터가 있으며, 이따금 통일신라시대의 토기편과 기와 조각 등이 발견 되고 있으며 고려 시대의 유물도 출토된 적이 있다.두타산이란 산 지명은 단군이 팽우에게 높은 산과 냇물 등 산천을 다스리게 했는데, 그때 하루도 빠짐없이 비가 내려 온 산천이 모두 물에 잠기게 되자 사람들이 높은 곳으로 피난을 가야했다. 이때 팽우는 이 산에 머물게 되었고 산꼭대기가 섬처럼 조금 남아 있었다고 하여 두타산이라 이름 지었다고 한다.두타산의 산행기점은 진천 쪽 초평저수지에서 영수사를 거쳐 오르는 길과 대평주유소 전 동잠교에서 계곡을 따라 큰재로 오른 후 북동쪽 능선을 타고 정상에 오르는 길이 자주 이용된다. 이외에 증평읍 자양마을에서 오르는 길이 있지만 접근이 어렵고 능선을 넘어 다시 계곡으로 떨어져야하므로 거의 이용되지 않고 있다.", @@ -2826,8 +2426,8 @@ "MNTN_LOCPLC_REGION_NM" : "충북 진천군 초평면, 괴산군 도안면, 증평읍", "MNTN_NM" : "두타산" }, - "longitude" : 129.09999999999999, - "latitude" : 37.259999999999998 + "longitude" : 127.5661554, + "latitude" : 36.830412799999998 }, { "mountain" : { @@ -2859,46 +2459,6 @@ "longitude" : 127.9456586, "latitude" : 35.387092799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "둥지봉은 국립공원 소백산의 주맥인 형제봉과 신선봉 사이에서 서북쪽으로 뻗어나온 지맥으로 등반객의 발길이 거의 닿지 않은 천연의 코스이다.그 안쪽으로 형제봉과 만나는 산면을 따라 6~7km에 이르는 대산골 계곡이 이어진다. 대산골은 소백산 일대에서 가장 풍부한 수량과 비경을 자랑하지만 일반에 잘 알려져 있지 않아 천연의 비경을 그대로 간직한 곳이다.암릉구간이 길고 굴곡이 심해 다소 힘든 코스이긴 하지만 하산하면서 대산골의 맑은 물에 몸을 눕힐 수 있어 더 이상의 여름철 피서산행코스도 없을 것이다.", - "MNTN_HG_VL" : "822", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "둥지봉" - }, - "longitude" : 128.2316715, - "latitude" : 36.946938699999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "368", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", - "MNTN_NM" : "드름산" - }, - "longitude" : 127.70006979999999, - "latitude" : 37.839205199999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "등선봉은 넓은 의미의 삼악산에 속하지만 독자적인 산행이 가능하다는 점에서 독립봉으로 보아야 한다. 대체로 암릉과 암봉으로 이루어져서 산행한 후 높은 성취감을 느낄 수 있다.삼악산이 정상을 중심으로 산괴가 몰려있는 형세인 반면 등선봉은 능선을 이루며 길게 뻗어있는 것이 삼악산과 다른 점이다. 이 산은 삼악산의 한 봉우리로 주봉인 용화봉(645m)과 청운봉(546m)의 능선과 이어져 있으며 일명 성봉이라 불리기도 한다. 궁예와 왕건이 싸웠다는 이 산에는 성터의 흔적이 남아 있다. 산행기점은 강촌교 북단에서 가평쪽으로 10m지점이다.등선봉은 강원도 춘천과 강촌사이에 있어 낭만의 열차, 경춘선을 이용해서 가는 열차산행지이다. 강촌역에 내리면 수많은 청춘남녀들이 낭만을 찾아 열차여행을 하는 코스다.", - "MNTN_HG_VL" : "632", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 강촌", - "MNTN_NM" : "등선봉" - }, - "longitude" : 127.6465845, - "latitude" : 37.831663900000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "춘천 소양댐 선착장에 닿으면 동쪽으로 두 산이 보이는데 정면으로 물고기 머리처럼 솟아 오른 산이 가리산(1051m)이고 그 옆에 병풍처럼 서 있는 산이 두루봉(545m)이다. 등잔봉은 가리산에 가려 보이지 않는 산으로 가리산맥 중간지점인 홍천고개에서 남쪽으로 펑퍼짐하게 버티고 서 있는 산이다. 등잔봉 사이에는 새득이봉(935m)봉이 솟아있다정상은 펑퍼짐한 초원지대로 인접해 있는 새득이봉이나 가리산이 뾰족한데 비해 둥그스름해서 넉넉해 보여 작은 들판으로 생각이 드는 곳이다. 하산은 밤가시 마을로 하는데 예부터 밤나무가 많아 밤가시 마을이라 불렸다는 이름의 유래가 흥미롭다.", - "MNTN_HG_VL" : "834", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "등잔봉" - }, - "longitude" : 127.8280278, - "latitude" : 36.755976400000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "고흥읍에서 율리치를 지나 고개를 넘어 송정리로 들어서면 천등산과 벼락산이 한눈에 든다. 천등산 정상부와 함께 겹쳐 보이는 바위산이 그 앞에 보이는데, 이 산 이름은 딸각산이다.바위를 밟고 오르노라면\"딸각딸각\"소리가 난다 해서 그곳 주민들은 그렇게 부른다고 한다. 그러나 옛 기록에는 월각산(月角山)이라 기록하고 있다.\"딸각\"이\"달각\"으로, 달각이 월각으로 변한 것이다. 산행은 산 중턱을 가로 넘는 임도가 세 가닥이 나 있어 어떤면에서는 쉽게 오를 수 있는 산이지만 임도 때문에 오히려 산행의 맛이 덜할 수도 있다.", @@ -2906,28 +2466,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", "MNTN_NM" : "딸각산" }, - "longitude" : 127.25388890000001, - "latitude" : 34.548055599999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "떡갈봉은 충주호를 사이에 두고 월악산과 마주보며 수석처럼 솟아 오른 산으로 월악산에 비해 덩치는 작지만 정상에서의 조망은 큰 산 못지 않다. 정상에 올라 내려보는 아름다운 충주호와 월악산 북사면을 샅샅이 훑어보는 독특한 조망이 있어 관심을 끄는 산이다.본래 이 산자락에는 4개의 마을이 있었는데 충주호가 생기면서 마을이 수장되고 주민들은 이주하게 되었다. 그러나 가을이 되면 예전 주민들을 이 산에서 쉽게 만나 볼 수 있다.", - "MNTN_HG_VL" : "544", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", - "MNTN_NM" : "떡갈봉" - }, - "longitude" : 127.43776750000001, - "latitude" : 36.235260099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "용인시내에서 동북쪽으로 보이는 길고 높은 산릉이 광주산맥이다.그 중에서 중절모같이 생긴 산이 광주의 태화산인데 태화산 북쪽에 뾰족한 삼각형산을 아는 사람은 별로 없다. 높이는 품은 태화산에 손색이 없는 이 산이용인시 제1봉인 말아가리산(마구산)이다.말아가리산은 정상의 바위가 퉁점에서 보면 말이 입을 벌린 모습에서말아가리라 이름 붙여진 산으로, 포곡읍 유운리에서 보면 말머리 모습으로 보이는 말과 인연이있는 산이다.", - "MNTN_HG_VL" : "595", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 처인구 포곡읍 금어리", - "MNTN_NM" : "마구산" - }, - "longitude" : 127.2254866, - "latitude" : 37.264675199999999 + "longitude" : 127.2780763, + "latitude" : 34.541848000000002 }, { "mountain" : { @@ -2946,8 +2486,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군, 옥천군", "MNTN_NM" : "마니산" }, - "longitude" : 126.434827, - "latitude" : 37.611603000000002 + "longitude" : 127.6519444, + "latitude" : 36.171666700000003 }, { "mountain" : { @@ -2959,16 +2499,6 @@ "longitude" : 128.573329, "latitude" : 37.087678099999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "162", - "MNTN_LOCPLC_REGION_NM" : "경기도 오산", - "MNTN_NM" : "마등산" - }, - "longitude" : 127.10383539999999, - "latitude" : 37.144254599999996 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -2979,16 +2509,6 @@ "longitude" : 127.7422222, "latitude" : 34.763611099999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강릉대학교의 뒷산으로 숲길 이용이 많은 산이다. 주로 여성들과 노약자들의 등산로로 애용되는 곳이며 위험지역은 없으며 경사도도 무난한 편이다. 많은 이들이 이용하는등산로라서 이정표와 운동기구등 시설물 설치가 꼭 필요한 곳이다. 해발이 낮고 나무로 인하여 조망권은 별로 좋지 못하다.", - "MNTN_HG_VL" : "113", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "마명산" - }, - "longitude" : 127.4127778, - "latitude" : 37.4791667 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "전라남도 고흥군은 보성에서 끝날듯하던 한반도 남단이 벌교를 지나 계속 남쪽으로 내달으면서 형성된 반도를 이룬 군이다. 때문에 고흥 하면 바다만 보일 것만 같은 선입견을 갖기 마련이다.하지만 실제 고흥땅을 밟으면 해발 500~600m대 높이의 산들이 수없이 많다는 사실을 깨닫게 된다. 말이 엎드려 있는 형상이라는 이름을 갖고 있듯 마복산은 해창벌에서 바라보면 그저 동서로 길 게 뻗은 동네 뒷산처럼 평범하게 느껴진다. 하지만 파고들면 생각지도 못했던 모습에 마음을 빼앗기고 만다. 산등성이에는 수많은 지릉이 흘러내리고 그 지릉마다 바위꽃이 활짝 피어 있어 마치 금강산이나 설악산의 축소판을 보는 듯하다. 이러한 경관 때문에 마복산은 소개골산(少皆骨山)이라 불리기도 한다.마복산이 지닌 또 하나의 자랑거리는 다도해 전경이다.산 남쪽 바다는 다도해 해상국립공원으로 지정되어 있을 만큼 아름다운 곳이다. 산 등성이에 올라 푸른 바다 위를 떠다니는 듯한 올망졸망한 섬들 부드러운 선으로 이어지는 해안선과 그 사이사이 들어앉은 포구를 바라 보노라면 보는 이마저도 바다에 떠 있는 듯한 느낌에 사로잡히고 만다.", @@ -3001,13 +2521,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "마분봉과 구왕봉, 희양산은 모두 백두대간 충청북도쪽 산자락에 있는 은터에서 올라간다. 마분봉은 백두대간에서 갈라져 나온 암릉으로 이루어진 능선이며 이 능선을 통과하면 악휘봉 근처에서 백두대간에 올라설 수 있다. 백두대간 능선에 이르면 진행방향으로 보아 악휘봉이 뒤쪽에 있고 구왕봉과 희양산은 멀리 떨어져 있다.마분봉을 연풍사람들은『말똥바우』라 부르며『말똥바우』에 비가 묻어 오면 바쁘게 비설겆이를 한다. 연풍지역의 비는 늘 이곳부터 시작되기 때문이다. 마분봉의 유난히 뾰족한 봉우리가 말똥을 연상케도 하지만 실제로 정상 가까이 가보면 화강암 덩어리들이 말똥처럼 보인다. 특히 정상에는 또 하나의 말똥이 사발을 엎어놓은 듯이 보여 어느 모로 보나 말똥바우가 틀림없는 듯 하다.등산로에는 곳곳에 밧줄이 설치되어 있으며, 세미 클라이밍 지대는 있으나 특히 위험한 곳은 없다.", - "MNTN_HG_VL" : "776", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면", - "MNTN_NM" : "마분봉" + "DETAIL_INFO_DTCONT" : "마산은 백두대간의 남한쪽 분단이다. 강원도 고성군 간성읍과 토성면의 경계에 위치하고 있는데 북으로 더 이상 나가지 못하고 있어 아쉬운 마음이 든다.현재는 대단위 종합레져타운을 기슭에 품고 있는 화려한 산이 되었지만, 예전에는 고원의 넉넉한 평원을 굽어보는 수수한 산이었다. 동쪽으로 끝없이 펼쳐진 바다와 함께 호수의 조망이 일품이다. 날씨가 좋을 경우 진부령에서 향로봉, 비로봉을 비롯한 금강산 연봉까지 아슴푸레하게 볼 수 있다.마산과 신선봉은 능선으로 바로 연결이 되있으며 알프스 스키장이 산행 초입리가 되어 겨울철에는 알프스 스키장까지 이동하는 차편이 무궁무진하여 교통은 어렵지 않다. 신선봉은 백두대간 종주 등산로에서 약간 동쪽으로 벗어나 있는 봉우리다. 너덜이 깔린 신선동 정상에 서면 동해와 신평벌, 설악산이 한눈에 들어온다. 두 산을 종주 하거나 거꾸로 미시령에서 시작해서 알프스 스키장으로 하산할 수 있다.", + "MNTN_HG_VL" : "1052", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 간성읍", + "MNTN_NM" : "마산" }, - "longitude" : 128.00587999999999, - "latitude" : 36.722050899999999 + "longitude" : 128.47333330000001, + "latitude" : 38.403611099999999 }, { "mountain" : { @@ -3016,8 +2536,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 충주시 상모면", "MNTN_NM" : "마역봉" }, - "longitude" : 128.07108489999999, - "latitude" : 36.828661099999998 + "longitude" : 128.03113740000001, + "latitude" : 36.753807299999998 }, { "mountain" : { @@ -3049,16 +2569,6 @@ "longitude" : 127.79229549999999, "latitude" : 37.952335800000007 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : " 마정산은 해발 402M의 산으로 군위읍내에 위치하고 있어 주민의 발걸음이 빈번한 지역이다. 따라서 지자체에서 순환등산로 및 생활체육시설을 설치하여 주민의 복지증진을 꾀하였다. 마정산은 북서방향으로 길게 늘어진 능선으로 동쪽으로 선암산, 국통산이 관측되며 북쪽으로 선방산이 관측된다. 서쪽으로는 읍내와 위천, 중앙고속도로 등이 조망된다. 연말 군민의 해돋이 장소로 이용되는 구간이다.", - "MNTN_HG_VL" : "402", - "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 군위읍 용대리", - "MNTN_NM" : "마정산" - }, - "longitude" : 129.11215920000001, - "latitude" : 35.420248999999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -3066,8 +2576,8 @@ "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구", "MNTN_NM" : "마집봉" }, - "longitude" : 126.9887555, - "latitude" : 35.134134000000003 + "longitude" : 126.9480556, + "latitude" : 35.109999999999999 }, { "mountain" : { @@ -3079,26 +2589,6 @@ "longitude" : 128.46111110000001, "latitude" : 35.899722200000006 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "조령산 (제3관문)을 사이에 두고 깃대봉과 마주하며 충청북도 쪽으로는 신선봉과 맞닿아 있다. 백두대간이 지나는 산으로 지도에는 마역봉이라 기록되어 있으나 이 지방에서는 마폐봉이라 부르고 있다. 오르는 길은 조령관(제3관문) 못미처 충청북도 쪽에서 오르는 길이 잘 나 있으나 조령관(제3관문) 군막터를 지나 성벽을 따라 오르는 길도 있다. 오르는 시간은 1시간이면 충분하며 내려가는 길은 여러 곳이 있다.", - "MNTN_HG_VL" : "925", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 각서리", - "MNTN_NM" : "마폐봉" - }, - "longitude" : 128.07108489999999, - "latitude" : 36.828661099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "광산의 갱도 막바지를 뜻하는 막장을 닮은 계곡의 끝에 서 있다하여 이름 붙은 막장봉은 기암괴봉과 낙랑장송이 어우러져 장관을 이룬 산이다. 달팽이 바위, 이빨바위, 삼형제바위 등 이름도 독특한 기암과 비탈 곳곳을 장식한 소나무가 만들어 내는 한 폭의 수묵화는 탄성을 절로 나게 한다. 이 산은 서쪽의 장성봉과 한 줄기로 이어져 있으며 북으로는 칠보산을, 남으로는 대야산을 마주보고 있다.작은 금강산이라는 불리워지는 쌍곡계곡은 괴산에서 연풍방면으로 12km정도에 위치하며 괴산팔경의 하나로 계곡의 경치가 아름답고 물이 맑아 사철 관광객이 끊이지 않는다. 쌍곡계곡을 흐르고 있는 냇물을 쌍천이라고하는데, 도수리고개에서 시작한 맑은 물이 군자산, 비학산, 보가산의 계곡사이로 구비치며 내곡천, 외곡천의 두줄기로 흘러 쌍계라 하였으며 이로 말미암아 골짜기 이름도 쌍곡이라 하였다.조선시대 이름 난 학자 퇴계 이황, 송강 정철등 수많은 학자와 문인들이 쌍계의 산수경치를 사랑하여 이곳에 머물렀다고 하는 쌍곡계곡은 호롱소, 소금강, 떡바위, 문수암, 고쌍벽, 곡용소, 쌍곡폭포, 선녀탕, 곡장암등 구곡을 이루며 푸른숲과 기암절벽 사이사이로 맑은 계곡물이 흐르고 있어 화양동, 선유동과함께 명승으로 알려져 있다.", - "MNTN_HG_VL" : "868", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군", - "MNTN_NM" : "막장봉" - }, - "longitude" : 127.9484282, - "latitude" : 36.706101400000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "만덕산은 완주군 소양면 화심에서 진안으로 가는 구 도로에 우뚝 솟아 있다. 그리고 임진왜란 당시 왜군을 맞아 치열한 전투를 벌였던 역사적 전적지이며 6·25 때 공비 출몰이 심했던 곳 중 하나로 곰티재를 지키고 있는 수문장과 같은 곳이다. 만덕산은 한자로 일만 만(萬)과 큰 덕(德)을 써서 만인에게 덕을 베푸는 산이라는 뜻이다. 그 이름 덕분인지 주민들의 말에 따르면 수많은 전란을 겪으면서도 지역 주민들은 큰 화를 입지 않았다고 한다. 암봉과 육산으로 조화를 이루어 가을 단풍, 겨울 설경의 풍치가 한 폭의 그림과도 같다. 특히 이 산의 동남쪽 기슭에 자리 잡고 있는 미륵사 일대의 경관은 일품이며 바로 아래 높이 50미터의 만덕폭포와 그 주변의 풍광은 등산객들의 발길을 사로잡는데 부족함이 없다. 겨울철의 빙폭은 젊은 산악인들의 빙벽 훈련장으로 사랑을 받고 있다. 전주에서 가깝고 교통이 편리한데다 등산 코스가 다양하여 모악산 다음으로 전주시민이 즐겨 찾는 곳이다.", @@ -3106,8 +2596,8 @@ "MNTN_LOCPLC_REGION_NM" : "전북 완주군 상관면, 소양면", "MNTN_NM" : "만덕산" }, - "longitude" : 126.7438889, - "latitude" : 34.592222200000002 + "longitude" : 127.2724339, + "latitude" : 35.791643800000003 }, { "mountain" : { @@ -3119,66 +2609,6 @@ "longitude" : 126.7438889, "latitude" : 34.592222200000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만복대는 지리산의 많은 봉우리들 중 하나이다. 만복대라는 이름은 지리산의 많은 복을 차지하고 있다고 해서 붙여진 이름으로 조망이 뛰어난 곳이다. 또한 만복대 능선은 경사가 완만해 나이든 산악인들도 무난하게 정상에 오를 수 있다. 펑퍼짐한 시골 아낙의 엉덩이처럼 풍만하고 넉넉해 보이는 만복대는 산을 찾는 이들을 심성 좋게 품어준다.만복대는 북풍한설에 피어난 설화가 아름답기로도 유명하지만, 뭐니 뭐니 해도 지리산 최고의 억새능선이라는 수식어가 가장 어울린다. 가을철이면 금빛으로 출렁이는 억새의 군무가 저 멀리 병풍처럼 둘러친 지리산 주능선의 웅장함과 어우러져 장쾌한 풍경을 연출한다. 잡목이 많이 자라 예전만 못하다며 아쉬워하는 사람들도 있지만, 그래도 여전히 만복대 억세군락은 특유의 아름다움을 간직하고 있다. 봄철 산수유꽃이 필 때면 산동면 위안리의 상위, 하위 등 산수유마을에서 노란 산수유꽃을 감상하고 만복대에 올라도 좋다.", - "MNTN_HG_VL" : "1433", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 산내면 덕동리", - "MNTN_NM" : "만복대" - }, - "longitude" : 127.3930556, - "latitude" : 35.412222200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만수산은 부여를 대표하는 고찰 무량사로 널리 알려진 산이다. 무량사는 신라 문무왕때 창건된 사찰로 경내에 보물 제 356호인 극락전과 삼존불, 정림사지 5층 석탑, 석등등 고려시대부터 조선조에 이르는 문화재를 많이 보존하고 있다.또한 생육신의 하나인 매월당 김시습의 혼이 깃든 곳이기도 하다. 수양대군(세조)이 단종을 몰아내고 왕이 되자 전국 각지의 절을 돌아다니며 승려 생활을 하던 김시습이 입적했던 이 사찰 입구에는 8각 원당형으로 된 그의 부도가 서 있다. 정상 서편에 근접해 있는 휴양림에는 편의시설도 갖추어져 있다.비록 산은 낮지만 수림에 덮인 능선이 병풍을 두른 듯 사찰 일대를 감싸고 있으면서 만만찮은 산세를 이루고 있어 등산할 만한 산이다.", - "MNTN_HG_VL" : "575", - "MNTN_LOCPLC_REGION_NM" : "충청남도 부여군 외산면, 보령시 미산면", - "MNTN_NM" : "만수산" - }, - "longitude" : 126.7113622, - "latitude" : 36.338012800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "미양역에서 시내 쪽으로 600m 가다가 오른쪽에 역전시장으로 들어서면 팔각정 휴게소에 오른다.(택시 2,000원) 왼쪽 휴게소 정자 안으로 길 따라 나서면 청룡사 절이 나오고 용두산 용두연이 나온다.만어산 기슭에 자리잡고 있는 만어사 절앞 너른 계곡에는 온통 크고작은 바위들이 지천으로 널려있다. 절앞 바위들은 1만마리의 고기들이 부처님을 찾아와 설법을 듣고 바로 성불한뒤 모두 바위로 변했다고 한다.산행들머리는 되돌아 나와 휴게소 전면 헬기장을 지나 산길 따라 오르면 산행이 시작된다. 중계탑을 지나 체육공원으로 이어지고 주위에 갈림길이 많이 나와 있는 산행로이지만 반드시 능선을 탄다는 생각으로 오르면 무난하다.만어산 정상은 지금가지 지나온 코스를 눈여겨 보면 구비구비 아득하다. 서편에 우뚝 선 봉우리가 대마도를 보았다는 대마도 만댕이다. 만어마을 뒤에 우뚝 서 있고, 또한 정상에는 마치 통시간(뒷간)처럼 생긴 통시바위가 있다.", - "MNTN_HG_VL" : "670", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼랑진읍 우곡리", - "MNTN_NM" : "만어산" - }, - "longitude" : 128.84601649999999, - "latitude" : 35.454823300000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만연산은 화순읍 쪽에서 바라보면 바위군들이 날카로운 바위무리가 솟아있고 곳곳에 너덜이 있어 험하게 보인다.만연산 골짜기에 만연사가 있다. 이 절집은 고려시대인 1208년 만연선사에 의하여 창건되었다고 전하는데 만연선사가 무등산 원효사에서 수도를 마치고 조계산 송광사로 돌아가는 도중에 무등의 주봉을 넘어 남으로 내려오다가 만연사 중턱에 이르러 피곤한 몸을 잠시 쉬어가고자 앉은 사이 언뜻 잠이 들어 꿈을 꾸었는데 16나한이 석가모니불을 모실 역사를 하고 있는 꿈이었다.잠을 깨 사방을 둘러보니 어느새 눈이 내려 주위가 온통 백색인데 신기하게도 선사가 누운 자리 주변만 녹아 김이 모락모락 올라오고 있었다. 그 길로 이곳에 토굴을 짓고 수도를 하다가 만연사를 세웠다는 것이다.", - "MNTN_HG_VL" : "609", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 화순읍", - "MNTN_NM" : "만연산" - }, - "longitude" : 126.9923874, - "latitude" : 35.091793699999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 주맥인 영취산에서 나누어진 금남호남정맥이 팔공산에서 지맥을 분기해 솟구친 산이 바로 만행산이다. 이 산의 이름은 불가에서 스님들이 탐욕을 없애기 위해 걸식하며 산야을 돌아다니면서 수행을 닦는 두타행과 같은 뜻을 담고 있다.남쪽 산자락에 가람을 배치한 귀정사의 옛 이름은 만행사인데 백제때 한 고승의 설법에 취해 왕이 3일동안 이곳에 머물렀다고 하여 귀정사로 이름을 바꾸었다고 전해지며 현재는 비구니사찰이다. 지도상에는 주봉의 이름을 본따 천황산으로 표기되어 있으나 본래는 `만행산'이 올바른 표기라 하겠다.봄철에 철쭉이 한창일 때의 이산은 춘심을 억제하기 힘들만큼 온통 붉은 빛으로 가득차게 된다. 보현사와 귀정사등 천년고찰이 들어서 있고 상사바위로 올라서 정상까지 이르는 능선길은 산행의 묘미를 만끽하기에 충분하다. 비교적 잘 다듬어진 등산로와 중간 중간의 안내 표지판은 등산을 보다 수월하게 하는데 큰 도움이 되고 있으며, 정상까지 오를 수 있는 지름길도 있어 비교적 가볍게 다녀올 수 있는 산이다.", - "MNTN_HG_VL" : "909", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시", - "MNTN_NM" : "만행산" - }, - "longitude" : 127.450621, - "latitude" : 35.525928700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "말목산은 충주호가 내려다보이는 충북 단양군 적성면에 위치한 산이다. 많은 암봉으로 이루어진 말목산은 마항산(馬項山)이라고도 부르는데 산의 형세가 말의 목처럼 생겼다하여 붙여진 이름이다. 또한 마항산 자락에 있는 하진리에는 옛날 장군감이 태어나자 그와 걸맞는 말도 함께 태어났지만 장군감과 말이 모두 하진의 뒷산에서 죽어 이 산을 말목산이라 하였다는 전설도 전해오고 있다.말목산의 산행은 충주호와 맞닿은 하진리 마을회관에서 시작한다. 마을회관에서 북서로 난 길을 따라 20여분 정도 오르면 송전철탑이 나오는데 여기서부터는 급경사로 된 숲터널이 이어진다. 이곳을 지나면 너덜지대가 나타나고 또다시 급경사 사면이 시작된다. 여기에서 30분 정도 가쁜 숨을 몰아쉬면 도착하는 곳이 690m봉이다. 정상은 남쪽으로 난 능선길을 40분 정도 더 가야 도달할 수 있다. 정상까지의 능선길은 충주호가 바로 내려다보여 전망이 매우 좋다.말목산은 구담봉과 옥순봉을 비롯하여 설마동계곡과 장회탄,이호대등 조화신공의 자연경관과 유람선이 주유하는 풍경까지 곁들인 수려한 절경을 내려다 볼 수 있는 망루같은 산이며, 4개소의 큰 전망대에서 내려다 보면 감탄을 금치 못한다.", - "MNTN_HG_VL" : "710", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 적성면 하진리", - "MNTN_NM" : "말목산" - }, - "longitude" : 128.27165919999999, - "latitude" : 36.941253699999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "망경대산은 백둣대간의 상의 함백산을 모산으로 두위봉을 지나 질운산과 예미산을 지나 수라리재에서 잠시 능선을 가라앉았다가 다시 솟구친 산이다. 강원도 영월군 중동면과 하동면 경계를 이루고 있는 망경대산은 등반 경력을 가진 산악 동호인에게 조차 생소한 산이다. 10여년 전까지만해도 탄광이 들어서 있어서 산행지와 거리가 멀었다. 탄광이 빠져나가면서 이 산 인근의 산꾼들이 오르내리기 시작하여 지금은 등산로를 찾기가 수월해 졌다. 정상에 서면 남쪽으로 와석리 무릉계곡과 마대산 줄기가 장쾌한 파노라마로 펼쳐져 있고 멀리 선달산에서 소백산으로 이어지는 백두대간이 광활하게 펼쳐진다.망경대산의 산이름은 어린 단종이 숙부인 수양대군에게 왕위를 찬탈당하였다는 소식을 들은 충신 추익환이 산위에 올라 한양을 바라보며 눈물을 흘렸다는 데에서 유래되었다고 전해지며 영월 영모전에는 추익환이 단종에게 산머루를 진상하는 그림이 보관되어 있다.정상은 헬기장으로 이루어져 사방 막힘이 없이 좋은 조망을 보여준다. 북으로는 가리왕산 능선이 하늘금을 그리고 북동쪽으로는 예미산, 질운산, 두위봉으로 이어지는 능선이 보이고 동으로는 단풍산과 매봉산, 장산이 시야에 들어오고 그너머 태백산에서 선달산으로 이어지는 백두대간의 주능선이 한눈에 들어온다.남서쪽으로는 하동면 옥동리 마을이 분지처럼 보이고 산자락을 굽이치며 흐르는 옥동천이 그림같고 서쪽으로는 응봉산 방면으로 부드럽게 뻗은 능선이 시야에 들어온다.", @@ -3189,55 +2619,15 @@ "longitude" : 128.61972220000001, "latitude" : 37.161388900000013 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충주호를 끼고 비단같은 풍광으로 우뚝 솟은 금수산 서쪽에 자리잡은 망덕봉은 금수산과 줄기를 같이하는 봉우리다. 금수산 정상에서 직선거리 1.5km지점에 솟아 있으니 금수산의 일부분이라 할 수 있다.정상에서 서쪽 고사리 봉으로 이어지는 암릉길이 너무 좋다. 낙타등 처럼 튀어나온 암봉을 그 지역에서는 용아장성이라고 부른다. 바위 안부에서 용아장성으로 오르는 길은 약 40m 에 이르는 절벽이다. 발디딤과 손잡이가 양호하여 전문인은 쉽게 오를 수 있은나 초보자는 주의를 기울여야 한다.암봉 꼭대기에 오르면 노송군락과 충주호를 끼고 앉은 월악산의 자태가 빼어나다. 북쪽 아래로는 바위절벽 아래에 숨은 듯이 보이는 천년고찰 정방사가 보이고 능강계곡이 매우 아름답게 보인다. 용아릉에서 고사리봉 못미쳐서 안부 사거리에서 우측길 능강천으로 내려오면 계곡에 물이 많고 능강교 아래는 맑은 물이 흐르는 정비된 넓은 계곡이 유원지처럼 물놀이 하기에 좋다.안부 사거리에서 좌측길로 내려서면 수천평의 억새밭이 있고 내려서면 술모기 등산 기점으로 내려설 수 있다.", - "MNTN_HG_VL" : "926", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", - "MNTN_NM" : "망덕봉" - }, - "longitude" : 128.22201559999999, - "latitude" : 36.989854299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "망산(397m)은 거제도 최남단에 위치한다. 덕분에 가는 길이 즐겁다. 신거제대교로 견내랑을 지나 어느 방향으로 달리더라도 탁 트인 해안가 절경과 쪽빛바다가 이어진다. 산 정상에 오르면 지금까지 봐왔던 단편적인 절경이 다도해라는 한폭의 초대형 풍경화로 다가온다. 망산은 조선 말기 국운이 기울면서 왜구의 침범이 잦자 주민들이 자발적으로 산 정상에 올라 왜구 선박의 감시를 위해 망을 보았다 해서 명명됐다. 그래서 망산은 울창한 숲으로 인한 산 자체의 빼어난 아름다움보다는 조망이 뛰어나다는 점이 우선 부각된다. 그런 점에서 오늘날의 ‘망’은 한려해상국립공원의 비경을 관찰하는 조망처로 해석하면 될 듯하다. 날씨가 청명하면 대마도와 부산도 볼 수 있다. 등산로는 크게 네 가닥인데 깎아지른 듯한 해안을 끼고 마을을 형성하고 있다. 망산 앞바다에 작은 섬들을 거느린 대·소병대도가 점점이 떠있어 이 섬들을 바라보고 지키는 곳이라 하여 여차(汝次)라 한다.", - "MNTN_HG_VL" : "375", - "MNTN_LOCPLC_REGION_NM" : "경남 거제시 일운면", - "MNTN_NM" : "망산" - }, - "longitude" : 128.60480910000001, - "latitude" : 34.711878899999988 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "686", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", - "MNTN_NM" : "망실봉" - }, - "longitude" : 127.90437300000001, - "latitude" : 35.708252100000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "망우산(망우리공원)은 중랑구의 동남측과 구리시와 경계에 걸쳐있으며, 행정구역상 서울시 중랑구 망우동, 면목동, 경기도 구리시에 남북으로 길게 위치하고 있다. 망우산(망우리공원)을 중심으로 서남쪽으로 용마산과 동남쪽으로 아차산과 경계를 이루고 있으며,지형은 남북으로 형성된 주 능선축을 중심으로 동서방향의 부능선이 수지형으로 발달되어 계곡을 형성하고있다. 표고는 최고 287.71m, 최저 40.2m로 표고차는 약 247m로 다소 높은편이며 표고별 면적 구성비는 50~250m 사이에 고르게 분포 되어 있다. 경사는 면적분포를 보면10~20% 경사지가 전체의 62.0%로 완경사지가 가장 많은면적을 차지하고 있으나, 시설입지가 가능한 완경사지가 가장 많은 면적을 차지하고 있으나, 시설 입지가 가능한 완경사지의 대부분이 묘지가 분포 되어 있어 시설부지 조성이 어려운 실정이다. 식생은 망우로를 중심으로 부지의 북측은 참나무류(16.02%), 아까시나무(14.53%), 잣나무(6.93%)등이 우점하고있으며, 전체적으로 양호한 수림대를 형성하고 있다. 단, 망우로 남측은 전반적으로 묘지가 분포되어 있어초지(34.99%)로 나타나고 있다. 경관은 남북방향의 능선축을 따라 멀리 북서측의 망우동 전경과 남동측의 구리시 전경이 파노라믹한 경관을 형성하고 있어 탁월한 조망효과를 연출하고 있다. 망우산(망우리공원)에서는 우리나라 어린이운동의 효시인 방정환, 3.1운동의 민족대표 33인중 한 분인 오세창, 한용운, 우두보급의 선구자로 의학자이며, 국어학자인 지석영, 임시정부 내무부서기를 역임한 문병훤, 동아일보 주필과 한국민주당 창당을 주도했던 장덕수, 제헌국회의원이며 진보당 당수였던 조봉암 등의 묘소가 있으며, 이들 일곱 분의 애국지사 및 유명인사 연보비가 공원 내 산책로 조성과 함께 지난 1997년 2월에 설치되었으며, 이어서 1998년 2월에 시인 박인환, 문일평, 서병호, 서동일, 오재영, 서광조, 유상규, 교육가 오긍선 등여덟 분의 연보기가 추가로 설치되어 역사의 교육장으로 이용되고 있다. 또한 , 망우동 산57-1번지 일대 망우산(망우리공원) 내의 내부순환도로 5.2km 를 아스콘으로 포장하여 산책로로 만들었으며, 산책로의 이름을 공모하여 1998년 5월 사색의 길로 정하고, 도시환경과 자연관찰로, 종합안내판, 나무정자, 약수터 등이 설치되어 구민과 이용자의 휴식 및 자연공원으로 많은 시민들이 찾고 있다.", - "MNTN_HG_VL" : "282", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 중랑구 망우동, 면목동, 구리시", - "MNTN_NM" : "망우산" - }, - "longitude" : -69.771065399999998, - "latitude" : 44.229377100000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "남해에서 최고 높이를 자랑하는 망운산, 그러나 남해 명산인 금산에 가려 그 진가가 꼭꼭 숨겨진 곳이다. 또한 망운산을 오르는 사람은 이곳이 알려지는 것을 싫어한다. 깨끗한 풍모, 드넓은 기상을 많은 사람들과 공유하기 싫은 탓이겠다. 금산이 남해를 찾는 손님들의 산이라면, 망운산은 남해인들이 가장 아끼는 늠름한 기상이다.고현면 대곡마을에 있는 화방사에서 조용한 산사의 정적을 뒤로 하며 산길을 올라 정상에 오를 수 있다. 정상에서 보는 주변 바다 위에 점점이 떠있는 자그마한 섬들과 강진만, 연죽저수지, 청정해역의 서상 앞바다, 멀리는 지리산, 여천공단, 여수, 삼천포까지 한눈에 들어온다. 정상에는 기우제를 지냈던 흔적인 듯, 평평하게 북쪽을 향하도록 되어 있고, 옆에는 제관이 앉을 수 있도록 돌로 된 의자가 놓여있다. 남해에 비가 오지 않을 경우 제일 먼저 이곳에서 기우제를 지내고, 그래도 비가 오지 않을 경우 상주리 앞바다 세존도에서 기우제를 지냈다고 한다. 정상 반대편에 있는 연대봉에는 봉수대의 흔적이 남아 있다.5월에는 철쭉군락지의 꽃들이 만개해 많은 사람들이 찾는다. 정상까지는 1시간 30분 정도 걸린다.", - "MNTN_HG_VL" : "785", - "MNTN_LOCPLC_REGION_NM" : "경남 남해군 서면 노구리, 남해읍 아산리 일원", - "MNTN_NM" : "망운산" + "MNTN_HG_VL" : "140", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "망마산" }, - "longitude" : 127.8446545, - "latitude" : 34.844905300000001 + "longitude" : 127.6708675, + "latitude" : 34.754024100000002 }, { "mountain" : { @@ -3246,38 +2636,18 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면", "MNTN_NM" : "매곡산" }, - "longitude" : 126.8894794, - "latitude" : 35.198389200000008 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상북도 양산", - "MNTN_NM" : "매봉산" - }, - "longitude" : 127.0088236, - "latitude" : 37.544227499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "삼랑진과 원동에 걸쳐 있는 매봉산, 금오산, 천태산은 낙동강을 끼고 있어 주위 경관이 수려할 뿐 아니라 경부선열차를 이용할 수 있어 교통도 편리하다. 금오산만 오를 경우 4시간, 금오산- 천태산 코스는 6시간30분, 금오산-매봉산 코스는 6시간 정도 소요된다.산행기점은 삼량진역에서 안태행버스를 타고 종점에 내리면 상점이 눈에 들어온다. 이 상점 옆으로 계류가 흐르는 냇가가 있는데 이 길로 오르면 포장도와 만난다. 포장도를 건너 노란색 물탱크옆 작은길로 접어들면 본격적인 산행이 시작된다.", - "MNTN_HG_VL" : "755", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양 삼량진", - "MNTN_NM" : "매봉산" - }, - "longitude" : 127.0088236, - "latitude" : 37.544227499999998 + "longitude" : 127.39749999999999, + "latitude" : 37.6211111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "220", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 고아읍 괴평리", - "MNTN_NM" : "매봉산" + "DETAIL_INFO_DTCONT" : "백두산에서 남하하는 백두대간이 금강산 북쪽 분수령부근에서 서남쪽으로 한북정맥을 내주었는데 이 정맥은 휴전선을 넘어 대성산과 백운산을 솟구치고 서울의 진산인 삼각산으로 달려가다가 동남쪽으로 갈래친 줄기위로 이 매봉을 빚어놓았다. 매봉의 북쪽으로는 전패봉과 명지산이 있고 남으로 깃대봉(910m) 대금산(704m)이 보이며 동쪽에는 칼봉산(900m)이 나란히 앉아 있다.매봉은 바위지대가 많아 험준한 산으로 사전에 코스 선택에 신중을 기해야 한다. 특히 6.5km에 달하는 회목고개에서 승안리에 이르는 코스는 초행자가 오르기에는 다소 힘든 거리다. 하산은 회목고개로 내려오는 것보다 정상에서 서쪽능선 길을 따라 마일리로 내려오거나 깃대봉쪽 갈림길에서 마일리로 내려가야 힘이 덜 든다. 하지만 힘들게 오른다 해도 정상에서 만나는 시원한 조망 앞에서 누구나 산행의 피로를 잊게 된다.", + "MNTN_HG_VL" : "865", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 가평읍", + "MNTN_NM" : "매봉" }, - "longitude" : 127.0088236, - "latitude" : 37.544227499999998 + "longitude" : 127.4158333, + "latitude" : 37.856666699999998 }, { "mountain" : { @@ -3286,8 +2656,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면, 영월군 수주면", "MNTN_NM" : "매봉산" }, - "longitude" : 127.0088236, - "latitude" : 37.544227499999998 + "longitude" : 128.12416669999999, + "latitude" : 37.274999999999999 }, { "mountain" : { @@ -3296,18 +2666,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원 영월 상동읍. 중동면", "MNTN_NM" : "매봉산" }, - "longitude" : 127.0088236, - "latitude" : 37.544227499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "매악산 하면 산이 험하고 힘든 산으로 생각하기 쉬우나 사벌면 일대에 솟아 있는 산들이 대부분 200m미만의 낮은 구릉과 평야지대로써 이 산 주변에는 이만한 높이의 산이 없기 때문에 주변 사람들이 산에 오르기가 힘이 든다고 해서 유래되었다고 한다.시원스럽게 펼쳐치는 넓은 평야와 굽이쳐 흐르는 낙동강, 상주 유일의 억새숲으로 뒤덮인 덕암산과 낙동강 1300리 물길중 제일 아름답다는 경천대. 그리고 낙동강변에 솟은 비봉산, 쉰등, 나각산 상주의 삼악인 노악산, 갑장산, 천봉산이 그림처럼 조망되는 곳이다.", - "MNTN_HG_VL" : "335", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 사벌면 매호리", - "MNTN_NM" : "매악산" - }, - "longitude" : 127.0843701, - "latitude" : 35.729759000000008 + "longitude" : 128.7738889, + "latitude" : 37.1438889 }, { "mountain" : { @@ -3316,8 +2676,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면", "MNTN_NM" : "매화산" }, - "longitude" : 128.09546739999999, - "latitude" : 35.773327199999997 + "longitude" : 128.09777779999999, + "latitude" : 37.405833299999998 }, { "mountain" : { @@ -3339,26 +2699,6 @@ "longitude" : 128.3197222, "latitude" : 37.830833299999988 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "월악산 국립공원권에 속하는 만수봉(萬壽峰)과 하설산(1028) 사이에 자리한 용하구곡(用夏九曲)을 굽어보며 기암 절벽으로 솟아 있는 메밀봉은 월악산 국립공원권에서는 산 높이가 비교적 낮은 산에 속하나 경관면에서는 여느 명산 못지 않게 경치가 뛰어 난 곳이다.남북으로 대판골과 용초골이라는 때묻지 않은 비경을 간직한 계곡이 흐르며 산행 기점 모두가 용하구곡에 있어 여름철 산행지로는 최상의 조건을 가지고 있는 산이다. 암릉 능선은 시원한 조망과 아기자기한 산행 묘미를 주며, 용초골 계곡 산행의 비경은 신비로움을 더해주며, 옛날 용이 승천하였다는 용초폭포는 깊이가 두 길이 넘는 소(沼)를 거느리고 있어 보는 이의 가슴속까지 시원하게 해준다.", - "MNTN_HG_VL" : "839", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면, 한수면", - "MNTN_NM" : "메밀봉" - }, - "longitude" : 127.0053193, - "latitude" : 37.482602999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "포항시와 청송군의 경계에 솟은 면봉산은 포항시에서가장 높은 산으로 남동쪽으로 보현산, 북동쪽으로 베틀봉과 이어진다. 낙동강의 길안천이 북사면에서, 금호강의 자호천이 동사면에서 발원한다. 교통이 불편해 찾는 이가 많지 않지만, 그 때문에 아직도 청정 계곡과 숨은 비경을 간직하고 있다.정상에서 건너편 보현산 천문대가 손에 잡힐 듯 가까이 있고, 주변으로 나무가 없고, 넓은 초지를 형성하고 있어 지역 사람들은 ‘민봉산’으로 부르기도 한다. 산 정상에는 청송군과 포항시에서 각각 정상석을 세워놓았는데, 청송군에서는 1205미터 포항시에서는 1113미터라고 정상 높이를 표기하고 있다. 교통이 불편한 탓에 산행은 원점회귀 코스를 택하게 되는데, 주로 두마리 마을회관을 들머리와 날머리로 이용하고 있는데, 10년 전 폐교된 두마분교를 주차장으로 이용한다.2004년 설립된 면봉상 기상레이더 관측소가 있으며, 이에 따른 임도가 산 정상까지 나 있다.", - "MNTN_HG_VL" : "1113", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군 현동면 ·현서면, 경상북도 포항시 북구 죽장면", - "MNTN_NM" : "면봉산" - }, - "longitude" : 129.02324719999999, - "latitude" : 36.170616500000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "면산은 창말의 앞에 있다 해서 마을 사람들이 붙인 이름이다. 이 산은 사람들이 많이 찾지 않아 처녀림의 신비함을 간직하고 있으며 정상에서는 노루와 같은 야생동물들의 흔적을 쉽게 발견할 수 있다. 이 산 부근의 다른 산들도 여전히 사람들의 시선에서 벗어나 있어 훼손되지 않은 곳이 많다.정상에 오르면 대덕산, 매봉산이 뾰족하다. 금대봉, 함백산 중계탑 사이로 장산, 그 뒤로도 끝없는 산이 이어진다. 서쪽에 강원탄광이 위치하고 영동선(嶺東線)이 통리(桶里)를 넘어 동해시에 이른다. 낙동강 상류의 작은 지류가 발원한다.", @@ -3366,8 +2706,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", "MNTN_NM" : "면산" }, - "longitude" : 129.09562510000001, - "latitude" : 37.100704499999999 + "longitude" : 129.09555560000001, + "latitude" : 37.100277800000008 }, { "mountain" : { @@ -3399,6 +2739,16 @@ "longitude" : 127.8568085, "latitude" : 37.297361400000007 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "명성산은 서울에서 동북으로 84Km, 운천에서 약 4Km 거리에 위치해 있다. 산자락에 산정호수를 끼고 있어 등산과 호수의 정취를 만끽 할 수 있는 산이다.일명 '울음산'이라 불리기도 하는데 거기에는 안타까운 전설이 전해 내려오고 있다. 신라의 마지막 왕자인 마의태자가 망국의 슬픔으로 이 산에서 통곡을 하자 산도 따라 울었다 한다. 나라를 잃은 슬픔을 산도 알았을까. 그런 연유로 '울 명' '소리 성'자를 붙여 명성산으로 불리게 되었다는 것이다.산전체가 암벽으로 이루어져 산세가 당당하고 가파르며 가을이면 억새풀이 장관을 이룬다. 암릉과 암벽이 같이 형성된 산이라서 사시사철 다양한 풍경을 연출해 등산객들로 하여금 철따라 다른 느낌을 느끼게 해 준다. 정상은 민등봉이나 전망이 매우 좋으며, 남쪽으로 이어진 12봉 능선의 모습이 장쾌하다. 능선에서 우거진 억새풀밭을 오르락내리락 하는 사이에 지루한 줄 모르고 걷게 된다.", + "MNTN_HG_VL" : "922", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 갈말읍, 경기도 포천시 영북면ㆍ이동면", + "MNTN_NM" : "명성산" + }, + "longitude" : 127.3377243, + "latitude" : 38.1069751 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경기도에서 화악산(1,468.3m)에 이어 두 번째로 높은 명지산은 정상을 오를 수 있는 산으로는 최고봉이다. 거대한 산맥을 이룬 명지산은 산 크기만큼이나 등산로도 많이 있으나 어느 길이나 정상까지 3시간 이상 소요된다. 서울에서 가까운 곳에 있으면서도 아직 오염되지 않은 깨끗한 계곡과 울창한 수림을 간직하고 있다.가평천을 사이에 두고 화악산과 마주보고 있는 명지산은 정상을 기점으로 사방으로 산자락을 펼치며, 귀목봉, 사향봉, 백둔봉 등을 거느리고 있는 웅장한 산이다. 명지산의 울창한 수림은 일상에 지쳐 산을 찾는 이들을 포근히 감싸안는데 그 깊이를 가늠할 수 없다.사계절이 다 아름다운 명지산은 특히 봄에는 진달래와 쩔쭉이 온산에 흐드러져 봄날의 산행을 즐기는 이들을 황홀경에 젖게 만든다. 가을 단풍은 가평 팔경 중 제 4경으로 지정 되었다. 우리나라 가을 산은 어디나 아름답지만 명지산의 단풍은 수십년 묵은 고목과 기암괴석들과 조화를 이루어 더욱 더 깊이를 더 한다. 또한 겨울에는 적설량이 많아 설화가 장관을 이뤄 겨울산행을 나선 이들을 반긴다.명지산 입구인 익근리에서 약 1Km가량 올라가면 규모가 작은 사찰인 승천사가 나타나고, 이어서 2Km가량 더 가면 등산로 왼쪽으로 높이 6m에서 시원한 물줄기가 쏟아 내리는 명지폭포를 만나게 된다. 한여름 불볕더위도 식혀 버리는 명지폭포 아래 깊은 웅덩이는 옛날에 명주실 한타레가 다 들어갈 정도로 깊어 명지폭포로 이름이 붙여졌다 한다.", @@ -3439,16 +2789,6 @@ "longitude" : 127.0843701, "latitude" : 35.729759000000008 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "함평군 해보면 광암리 북쪽을 병풍처럼 에워싸고 있는 산이 모악산이다. 이 산은 아늑한 분위기인 남쪽 산자락에 마치 어머니가 아기를 품안에 안듯이 서해안 최고 고찰 용천사를 숨기고 있는 산이다. 모악산은 단풍나무가 많아 특히 가을 단풍이 천하절경을 이루고 산자락에 일명 꽃무릇이라 불리는 상사화(相思花)가 군락을 이루어 개화기인 9월에는 온 산을 붉게 물들여 보는 이의 가슴마저 불타게 하고 있으며 이는 한국백경 중 일경에 속한다.모악산을 본격적으로 오르고 내리는 등산 기점은 용천사, 그래서 용천사를 둘러보지 않을 수 없습니다. 명산마다 명찰이 있듯이 모악산을 더욱 빛나게 해주고 있는 명찰 용천사는 모악산의 핵(劾)에 해당됩니다.", - "MNTN_HG_VL" : "348", - "MNTN_LOCPLC_REGION_NM" : "전라남도 함평, 영광", - "MNTN_NM" : "모악산" - }, - "longitude" : 127.0843701, - "latitude" : 35.729759000000008 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "모후산은 섬진7지맥의 한 봉우리로 백아산의 산줄기를 타고 내려와 동복천을 앞에 두고 멈춰선 곳이다. 이 산은 광주 무등산과 순천시 조계산의 그늘에 가려 잘 알려지지 않았으나 유마사, 주암호, 사평폭포 등의 명소가 곳곳에 있고, 항상 푸른 계곡물이 넘쳐 있어 관광객과 등산객에게 각광을 받고 있다. 또한 우리나라 최초의 고려인삼 시배지이기도 하다.모후산은 고려 공민왕 10년(1361) 홍건적이 쳐들어왔을 때 왕과 왕비가 태후를 모시고 이곳까지 피난을 왔던 산이다. 공민왕은 수려한 산세에 반해 가궁을 짓고 환궁할 때까지 1여년 남짓 머물렀다고 한다. 그 뒤 나복산을 어머니의 품속 같은 산이라 하여 모후산으로 바꾸었다.또한 임진왜란 때 이곳 동복현감인 서하당 김성원이 노모를 구하기 위하여 필사적으로 싸우다가 순절하였다고 하여 모후산을 모호산(母護山)이라 부르고 마을 이름도 모호촌이라 하였다.", @@ -3469,16 +2809,6 @@ "longitude" : 127.4357262, "latitude" : 36.735338599999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "목우산은 강원도 영월군 하동면 내리와 녹전리의 경계를 이루는 산이다. 이 산을 녹전리쪽에서 올려다 보면 마치 황소가 엎드려 있는 것처럼 보여 목우산이라 부르는데 내리쪽에서 보면 정상을 이룬 바위가 상여처럼 보인다고 해서 내리 주민들은 이 산을 생애봉(상여봉의 방언)이라 부르기도 한다.정상은 멋진 기암과 노송들이 그림처럼 조화를 이루고 있다. 정상 바위에 걸터앉아 사위를 휘둘러보는 조망은 가히일품이다. 서쪽 영월 방면으로 패어져 나간 옥동천이 마대산과 운교산 산모퉁이를 감싸며 자취를 감추고, 멀리로는 태화산이 하늘금을 이룬다. 태화산 오른쪽인 북서쪽 운교산 너머로는 망경대산, 예미산, 질운산 산릉이 펼쳐진다. 운교산 아래로는 분지 속 평화로운 녹전리와 함께 녹색 비단을 펼친 듯S자로 굽도는 옥동천이 내려다보인다. 북으로는 단풍산과 매봉산이 멀리 함백산과 함께 시야에 들어온다.동으로는 상동읍 내덕리 방면 깊고 길게 패어진 옥동천 상류 멀리로 태백산 정상이 마주 보인다. 태백산은 영월 청령포에서 죽은 단종의 넋이 어려있는 곳. 그래서 목우산 정상 바위는 옛날 주민들이 태백산을 향해 제사를 올릴 때 제단으로 사용하기도 했다. 남쪽 조망은 등골이 섬뜩해져 허리부터 젖혀진다. 수십 길 절벽 건너 선달산과 어래산이 멀리 백두대간과 함께 마주 보이고, 그 아래로는 내리천의 수십 개 지계곡들이 마치 주름치마처럼 패여 있다.", - "MNTN_HG_VL" : "1066", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면", - "MNTN_NM" : "목우산" - }, - "longitude" : 128.75353079999999, - "latitude" : 37.078150299999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "가평군청에서 북쪽으로 20km 떨어진 산으로 경기도 가평군과 강원도 춘천시의 경계를 이루고 있다.즐겨 찾는 이가 많지 않아 호젓한 산행으로 그만이다. 능선에는 싸리, 억새숲을 이루고 있어, 전망도 매우 좋다.정상에는 나무하나 없이 밋밋한 좁은 부위의 마루턱을 이루고 있는데 어떤 시설물이라도 있었던 것인지 여기저기 나무기둥 같은게 보인다. 여기서의 전망은 좋아서 북으로 가덕산과 그위로 몽덕산을 잇는 연릉이 일직선으로 뻗어 나간 모습을 볼수 있는가 하면 남으로 계관산을 잇는 역시 한일자로 굽이굽이 이어지는 억새수풀 능선이 그림처럼 아스라이 전개되는 모습이 장관이다.", @@ -3489,26 +2819,6 @@ "longitude" : 127.60406380000001, "latitude" : 37.9545265 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "추풍령 방향으로 향하던 백두대간이 속리산에서 서북 방향으로 가지를 친 지능선에 솟아 있는 묘봉은 문장대(887)와 상학봉(834) 사이에 수려한 암골미를 자랑하는 산이다.속리산(1,087)을 모산(母山)으로 하는 산답게 기암괴석이 많으며, 절골을 비롯한 깨끗한 계곡을 남북으로 가지고 있다. 절골에 자리한 미타사는 용화분지를 안고 있는 사찰로 사담리 공림사와 법주사를 양분하는 자리에 있으며, 일설에는 법주사의 전신인 용화사가 있던 터라고 추정하고 있다.묘봉의 거대한 평암봉은 물론 능선에서도 백악산, 낙영산 등 조망이 뛰어나다. 이 산은 절벽지대가 있는 산으로 산행시 주의를 요하며, 정상에서 서북 방향 능선(상학봉봉쪽)은 등산로가 험하므로 출입을 삼가 하는 것이 좋다.", - "MNTN_HG_VL" : "874", - "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 산외면 신정리, 경상북도 봉화군 석포면", - "MNTN_NM" : "묘봉" - }, - "longitude" : 127.8344726, - "latitude" : 36.569043200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "묘적봉은 충북 단양군과 경북 영풍군의 경계를 이루는 소백산국립공원 최남단에 위치한 산이다. 이 산은 일반적으로 소백산국립공원과 동떨어진 산으로 생각하나 죽령 남쪽 약 10km거리인 묘적봉 일원까지가 소백산 국립공원에 속한다.도솔봉을 포함한 묘적봉 일대에는 취나물군락과 철쭉군락이 주능선에 형성되어 있다. 대부분의 등산객들이 죽령 북쪽의 소백산맥을 주로 이용하기 때문에 아직까지 묘적봉은 잘 알려지지 않은 산이므로 도솔봉과 함께 종주하기도 한다. 정상은 암봉으로 되어 있고 동쪽에는 광장이 있으며 바라보는 죽령과 소백산의 자태는 가희 장관이다.", - "MNTN_HG_VL" : "1148", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군, 경상북도 영주시", - "MNTN_NM" : "묘적봉" - }, - "longitude" : 128.42409409999999, - "latitude" : 36.876874999999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -3517,167 +2827,67 @@ "MNTN_NM" : "무갑산" }, "longitude" : 127.3337173, - "latitude" : 37.404533200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;갑옷을 두른 무사의 형상gt;서울에서 가까운 경기도 광주시 초월면에 있는 무갑산은 600m가 채 안되는 산으로 숲이 울창한 흙산이다. 또 관산, 검은골 등 아름답고 깊은 골짜기에 맑은 물이 시원하다. 정상 일대 외에는 바위도 그리 없고 대부분 편안한 흙길이며 가끔 산행의 맛을 잃지 않을 만큼 적당히 가파른 산길이 나서기도 하며 곳곳에 암벽도 볼 수 있다. 능선으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다. '무갑산' 이란 이름의 유래에 관하여 두 가지 설이 있다. '임진왜란 때에 왜병들에게 항복하기를 거부한 무인들이 은둔한 데서 무갑산이라 했다'는 이야기와 '산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다' 는 이야기다. 무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다. 마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다고 한다.", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", - "MNTN_NM" : "무갑산" - }, - "longitude" : 127.3337173, - "latitude" : 37.404533200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면에 솟아있는 무갑산은 정상으로 오르는 계곡길이 아름답기로 소문난 산이다. 또한 서울 근교에 있으면서도 오지에 온 듯한 느낌이 들게 하는 곳이다. 무갑산은 능선상으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다.숲이 울창하며 골자기의 개울이 아름답고 물이 맑으며 시원한 산, 볕이 내리쬐는암릉과 기암괴봉보다 숲속 그늘의 흙길이 편안하고 가끔 알맞게 가파른 산, 거기다가 산을 내려와 시원한 개울 가에서 물을 퍼다가 등멱이라도 할 수 있는 산이다.'무갑산' 이란 이름은 산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다.마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다. 광주는 자기의 명산지로 조선시대에는 훌륭한 백자를 생산했다. 이처럼 광주고을이 도자기로 유명했던 것도 무갑산에서 많은 땔감을 쉽게 댈 수 있었기 때문이었다 한다.", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월읍", - "MNTN_NM" : "무갑산" - }, - "longitude" : 127.3337173, - "latitude" : 37.404533200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "광주시가지에서 동쪽으로 불과 10km 거리에 자리하고 있는 무등산은 도립공원으로 지정되어 있다.산의 형세가 험하지 않고 대부분이 흙으로 이루어져 있어 누구나 쉽게 오를 수 있으며, 곳곳에 맑은 물이 흐르고 있다. 특히 산위에는 서석대, 규봉, 입석대등의 웅장한 바위들이 있으며 산기슭과 중턱에는 약사암, 증심사, 원효사 등의 이름난 절들이 자리잡고 있다. 1972년 도립공원으로 지정되었으며 산 아래에는 각종 놀이 및 편의시설이 들어서 있다.", - "MNTN_HG_VL" : "1187", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구, 전라남도 담양군 남면ㆍ화순군 이서면", - "MNTN_NM" : "무등산" - }, - "longitude" : 126.9887555, - "latitude" : 35.134134000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "바다와 접한 고성군의 산역이 그렇듯이 해발 600m 미만의 산들이 부드러운 산줄기를 서로 이어가면서 나름대로의 산역을 만들고 잇다. 무량산은 고성읍 북서쪽에 위치하면서 대가면의 중심을 이루는 산으로 양화마을을 병풍처럼 둘러싸는 형세로 동서로 길게 뻗어 있다. 산세는 그저 평범한 내륙산의 전형이지만 주릉을 따라 드문드문 자리잡은 암봉이 그런대로 변화를 주고 있다. 남릉에 봉화대가 아직도 있고, 특히 주릉에 올라서면서 숨어있는 정상을 찾는 재미도 있다. 헤아릴 수 없다는 뜻의 산명도 아마 쉽게 정상을 가름할 수 없는 데서 온 것이 아닌가 싶다.", - "MNTN_HG_VL" : "579", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 고성읍 무량리", - "MNTN_NM" : "무량산" - }, - "longitude" : 128.26166670000001, - "latitude" : 35.021666699999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 김해시 진례면과 한림면 위치한 무릉 산은 남북으로 뻗어있는 산으로 낙남정맥의 한 줄길인 황새봉과 이어져 있다. 비교적 덜 알려져 있어 식생과 등산로의 상태는 좋은 편이나 탐방객이 적은 관계로 관목이 우겨져 있고 등로도 희미해 탐방시 주의를 요한다.", - "MNTN_HG_VL" : "313", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 한림면, 진례면", - "MNTN_NM" : "무릉산" - }, - "longitude" : 128.56579629999999, - "latitude" : 35.328721999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "무릉산은 칠북면의 중심산역으로 작대산의 북쪽에 위치하면서 둥그스럼한 산릉에 부드러움을 더하고 있다. 낙동강에 산자락을 내밀고 있는 북릉은 북면 온천이 있는 마금산역에 손을 내밀면서 느긋하게 산세를 일으키고 있다.", - "MNTN_HG_VL" : "556", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 북면, 함안군 칠북면", - "MNTN_NM" : "무릉산" - }, - "longitude" : 128.56579629999999, - "latitude" : 35.328721999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "무성산(614m)은 충남 공주시 사곡면 정안면, 우성면 경계를 이루는 산이다. 공주시에서 북서쪽으로 마치 한 마리 누에가 기어가는 듯이 보이는 산이다. 속리산에서 북서쪽으로 갈라진 한남금북정맥은 경기도 안성 동쪽 칠현산에서 두 가닥으로 갈라진다.무성산은 서쪽 명가천을 사이에 두고 마곡사를 내려다보고 있다. 그러나 마곡사 명성이 대단했던 까닭에 아직까지 무성산에 훌륭한 등산코스가 숨어 있다는 것을 아는 이는 많지 않다.홍길동이 쌓았다는 전설을 간직하고 있는 성터 석탑지대에서 휘둘러보는 파노라마는 막힘이 없다. 북쪽으로는 국사봉에서 차령을 지나 광덕산 방면으로 이어지는 금북정맥이 하늘금을 이룬다. 동쪽으로는 정안천이 흐르는 화봉리 분지 너머로 북쪽 멀리 금북정맥 국사봉으로부터 가지쳐 나온 높고 낮은 산릉들이 일렁이는 파도인 듯 시야에 와닿는다.남동쪽으로는 공주시 뒤로 계룡산이 가물거리고 백마강이 흘러가는 방향인 남소쪽 멀리로는 청양 칠갑산이 넘실대는 산릉 위로 고개를 내밀고 있다. 서쪽 조망도 일품이다. 예부터 전해지는 십승지의 한 곳인 유구를 감싸고 칠갑산으로 달아나는 금북정맥이 하늘금을 이루고, 금북정맥 아래로는 운암리 마곡사를 감싸고 있는 태화산(614m)이 아늑한 분위기로 시야에 들어온다.", - "MNTN_HG_VL" : "614", - "MNTN_LOCPLC_REGION_NM" : "충남 공주시 우성면 한천리", - "MNTN_NM" : "무성산" - }, - "longitude" : 127.07295019999999, - "latitude" : 36.562825400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "고성읍에서 사천으로 가는 국도상에서 왼쪽으로 바라보면 KBS 송신용 안테나가 서있는 산봉이 눈에 띈다. 이 산이 마을 사람들은 청량산으로 부르기도 하는 무이산으로 주봉이 국도에 인접해 있다. 언뜻 보기에는 흔히 볼 수 있는 산으로 생각되나 산으로 접근하면 분위기가 달라진다.", - "MNTN_HG_VL" : "549", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 상리면", - "MNTN_NM" : "무이산" - }, - "longitude" : 128.2110145, - "latitude" : 34.979779600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "무제봉은 충북 진천군 이월면과 백곡면의 경계를 이루는 곳에 위치하고 있다. 무제봉은 산세는 험해 보이지만 등산로가 잘돼있어 오르기가 수월하다. 무제봉의 남동쪽으로는 옥녀봉이 능선으로 연결되어 있다.능선에 오르면 소나무가 우거져 있는 육산이다. 이 옥녀봉 동쪽 아래로는 노원리의 궁동마을이 있는데 이 마을은 중국의 원나라 홀필열 황제의 황후 기씨가 탄생한 곳이다. 지금도 동리 뒤에는 황제가 기씨 황후를 위하여 지어주었다는 궁동이라는 궁궐터가 남아있다. 이곳 무제봉 인근은 어댕이,신계리 아래세월 등 듣기에도 생소한 단어들의 지명 이름이 특이하다.", - "MNTN_HG_VL" : "573", - "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 이월면 선계리", - "MNTN_NM" : "무제봉" - }, - "longitude" : 127.68741199999999, - "latitude" : 37.166568599999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "무척산은 신어산, 불모산과 더불어 김해의 3대 명산으로 꼽힌다. 그다지 높지 않고 산줄기가 시원스럽지도 않지만 산천으로 둘러싸인 경치 좋은 뜻의 생림동천(生林洞天)이란 말을 만들어 낼 정도로 아름다운 산이다. 또한 기묘한 바위들이 자리 잡고 있어 그 멋스러움이 더욱 특출나 보인다. 특히 낙동강과 이어져 있어 굽이쳐 흐르는 낙동강의 조망이 탁월하며 산허리 부분에 괴상하게 생긴 암봉이 많아 경치가 수려하다.무척산은 산 이름도 다양하다. 무척산 외에도 무착산, 무쌍산, 식산으로도 불린다. 식산은 북풍을 막아주고 낙동강 물줄기를 끌어들여 들을 기름지게 해 김해 고을을 먹여 살리는 산이라 하여 부르는 이름이다. 또 산의 형세가 밥상을 받는 모양과 같다고 해 식산, 식산 대신 밥상이라고도 부른다.다양하게 불려지는 이름뿐만 아니라 무척산은 많은 설화를 간직하고 있는 산이다. 이 산의 정상 바로 밑에 천지못이 있는데, 이 연못은 김수로 왕릉의 물줄기를 잡기 위해 설치됐다는 전설을 갖고 있다. 또한 고찰 모은암은 김수로왕이 어머니의 은혜를 갚기 위해 지었다고 전해진다. 가락국의 불교를 중흥시키기 위해 창건되었다는 백운암도 유명하다.하늘벽, 가야벽, 탕건바위, 장군봉 등 개척된 암장이 여럿 있으며 부산, 경남 클라이머에게 인기가 높다.", - "MNTN_HG_VL" : "702", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 생림면, 상동면", - "MNTN_NM" : "무척산" - }, - "longitude" : 128.87060070000001, - "latitude" : 35.340642799999998 + "latitude" : 37.404533200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "학이 춤을 추는 듯한 형상의 바위를 정상에 가지고 있어 무학봉이라 불리는 이 산은 한북정맥 주능선의 위치한 백운산(904)에서 동남 방향으로 가지를 친 지능선에 자리잡고 있으며, 수려한 산세와 백옥 같은 바위 위에 맑은 계류가 흘러 여름철 산행지로 적합하다. 백운산 유명세에 가려 찾는 이가 많치 않은 만큼 자연 그대로의 모습을 가지고 있어 상큼함을 느낄수 있는 산이다.겨울철 설경으로 유명한 산은 아무래도 설악산, 한라산, 치악산, 소백산 등을 으뜸으로 치는 것이 상례다. 그러나 수도권에서 그리 멀지 않은 경기도 포천군 이동면 도평리에 위치한 백운산은 38선 이북으로 10km 나 더 북쪽에 위치하며 위도상으로는 설악산과 거의 같아 겨울철 설경이 뛰어나고 산세도 아기자기하다.", - "MNTN_HG_VL" : "832", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면, 경기도 포천시", - "MNTN_NM" : "무학봉" + "DETAIL_INFO_DTCONT" : "lt;갑옷을 두른 무사의 형상gt;서울에서 가까운 경기도 광주시 초월면에 있는 무갑산은 600m가 채 안되는 산으로 숲이 울창한 흙산이다. 또 관산, 검은골 등 아름답고 깊은 골짜기에 맑은 물이 시원하다. 정상 일대 외에는 바위도 그리 없고 대부분 편안한 흙길이며 가끔 산행의 맛을 잃지 않을 만큼 적당히 가파른 산길이 나서기도 하며 곳곳에 암벽도 볼 수 있다. 능선으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다. '무갑산' 이란 이름의 유래에 관하여 두 가지 설이 있다. '임진왜란 때에 왜병들에게 항복하기를 거부한 무인들이 은둔한 데서 무갑산이라 했다'는 이야기와 '산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다' 는 이야기다. 무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다. 마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다고 한다.", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", + "MNTN_NM" : "무갑산" }, - "longitude" : 127.0250484, - "latitude" : 37.5628417 + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 끝자락인 지리산 삼신봉에서 시작되는 낙남정맥의 상좌격인 무학봉은 마산의 진산(鎭山)으로 마산만과 진해만을 굽어보며 바다를 향해 학이 날개를 펼친 듯 아름다운 형상을 하고 있다.명산이 갖추어야 할 면모를 두루 갖추고 있는 이 산은 바닷가에 위치한 산답게 시원한 조망을 만끽할 수 있으며 주능선 등로엔 억새밭과 암봉 전망대가 있어 편안한 느낌을 준다.대곡산 아래쪽에는 `만날고개'가 있는데 이곳은 가정형편이 어려워 댓가를 받고 시집 보낸 딸을 그리워하던 어미와 그 딸이 그리움을 참지 못해 고갯마루에 올랐다가 우연히 만났다는 애틋한 전설이 전해지는 고개다. 무학산의 옛이름은 풍장산이었는데 신라말 최치원이 이곳에 머물면서 산세를 보니 학이 나는 형세같다하여 무학산이라 불리우게 되었다한다.", - "MNTN_HG_VL" : "761", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 교방동", - "MNTN_NM" : "무학산" + "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면에 솟아있는 무갑산은 정상으로 오르는 계곡길이 아름답기로 소문난 산이다. 또한 서울 근교에 있으면서도 오지에 온 듯한 느낌이 들게 하는 곳이다. 무갑산은 능선상으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다.숲이 울창하며 골자기의 개울이 아름답고 물이 맑으며 시원한 산, 볕이 내리쬐는암릉과 기암괴봉보다 숲속 그늘의 흙길이 편안하고 가끔 알맞게 가파른 산, 거기다가 산을 내려와 시원한 개울 가에서 물을 퍼다가 등멱이라도 할 수 있는 산이다.'무갑산' 이란 이름은 산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다.마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다. 광주는 자기의 명산지로 조선시대에는 훌륭한 백자를 생산했다. 이처럼 광주고을이 도자기로 유명했던 것도 무갑산에서 많은 땔감을 쉽게 댈 수 있었기 때문이었다 한다.", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월읍", + "MNTN_NM" : "무갑산" }, - "longitude" : 128.5357745, - "latitude" : 35.211068699999998 + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수성구(壽城區)는 신라시대에 위화군(#21919;火郡, 上村昌郡이라고도함)인데 경덕왕이 수창군(壽昌郡)이라하였다.고려초에 수성군(壽城郡)으로 바뀌어 현종 9년(1018)에 수성군사(壽城郡司)로 경주에 속했다가 공양왕 2년(1390)에 해안현(解顔縣, 慶州任內에 속했는데 그 시대는 미상이다)을 겸하여 감무(監務)를 두었다.조선 태조3년(1394)에 대구겸관으로 삼았다가 태종 14년(1414)에 대구에 합속(合屬)시켰으며, 1419년에 수성현사(壽城縣司)로수성구 전체 면적의 76.6%가 녹지지역 전지역 공원화로 숲에 덮힌 아름다운 도시경관 창출(녹지지역 76.6%)공항, 역, 터미널 근접으로 교통 편리함 수성구지형]비슬산 주봉에서 동쪽 경산쪽으로 이어지는 屛風山있는데 좌측은 法伊山 우측은 聖岩山이다대구광역시 범물동 욱수동 대흥동 삼덕동 행정구역 大德마을 위치한 大德山(600)으로 이름붙여저 부르고 있다大德山 맞은편 案에 있다고 하여 봉우리가 案山(470.5)이다.기암으로 이루어지고 안산 정상에는 거북상이#52287;는이에게 속삭임의 경관은알려주고 있다.침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고 수백종의 자생식물이자라며 사계 꽃과 단풍들이 수성구 두리봉유래]만촌동 태초에 세상이 전부 물에 잠기었을 때 봉우리에 두루미 한 마리가 앉을 정도만 남았다 하여 두리봉이라 불리다가 두봉골로 바꿔 불렀다 한다. 하지만 이 지명은 상당히 윤색된 설화를 지닌 것으로 보여진다. 그리고 처음에 그러한 설화를 지녔더라도 두봉골로 이름이 바뀌고 부터는 그 설화를 잃어버리고 단순히 두개의 봉우리 사이에 있는 골짜기란 의미로 전락해 버렸다. 현재 오성고등학교가 위치한 지점에서부터 대구산업정보대 서편을 가리키는데, 두봉골(무학산유래]지산동 현재 학산재(鶴山齋)가 있는 곳의 뒷산을 가리키며 학이 날아오는 기세와 같이 생겼다는 설이 있고, 학이 날아와 즐겨 앉았던 산이라 그렇게 부른다는 설이 있다.조일골유래]지산동 골짜기가 동남쪽으로 틔여 있어 아침에 해가 뜨면 가장 먼저 따뜻하게 비치는 곳이라 하여 조일골 이라고 부른다.", - "MNTN_HG_VL" : "200", - "MNTN_LOCPLC_REGION_NM" : "대구 수성구 황금동", - "MNTN_NM" : "무학산" + "DETAIL_INFO_DTCONT" : "광주시가지에서 동쪽으로 불과 10km 거리에 자리하고 있는 무등산은 도립공원으로 지정되어 있다.산의 형세가 험하지 않고 대부분이 흙으로 이루어져 있어 누구나 쉽게 오를 수 있으며, 곳곳에 맑은 물이 흐르고 있다. 특히 산위에는 서석대, 규봉, 입석대등의 웅장한 바위들이 있으며 산기슭과 중턱에는 약사암, 증심사, 원효사 등의 이름난 절들이 자리잡고 있다. 1972년 도립공원으로 지정되었으며 산 아래에는 각종 놀이 및 편의시설이 들어서 있다.", + "MNTN_HG_VL" : "1187", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구, 전라남도 담양군 남면ㆍ화순군 이서면", + "MNTN_NM" : "무등산" }, - "longitude" : 128.5357745, - "latitude" : 35.211068699999998 + "longitude" : 126.9887555, + "latitude" : 35.134134000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "설악산 용아능선의 축소판 형상이라 하여 `작은 용아릉' 이라 불리는 문덕봉은 다섯 개에 암봉을 가진 남원의 화산 (火山)이다. 전북에서는 암릉 산행코스로 단연 돋보이는 산이며, 인위적으로 설치한 안전시설이 없어 자연 그대로에 암릉 산행을 즐길 수 있는 산이다.험난한 코스가 있는 산으로 암벽등반에 경험이 없거나, 담력이 약한 사람은 경험자를 동행(同行) 하는 것이 필요하며, 우천시는 산행을 피하는 것이 좋다. 문덕봉은 아기자기한 산행 묘미가 있는 산으로, 산행 내내 지리산 산줄기와 섬진강 강줄기를 바라보며 걷는 재미는 다른 산에서 느낄 수 없는 독특한 즐거움이다. 또한 명당 자리로 알려져 있어 기우제를 지내는 곳으로도 유명하다.정상에 서면 동북쪽으로 남원시가지는 한눈에 내려다 보이고 섬진강으로 합류되는 남원 요천이 광활한 금지평야의 젖줄이 되고 있음을 보여 주고 있다. 석양의 햇살에 눈이 부신 서쪽의 옥정호와 운암댐에서 흘러내리는 섬진강 물줄기 너머로 저 멀리 순창의 광덕산과 담양의 추월산이 어렴풋하게 보인다.", - "MNTN_HG_VL" : "598", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 금지면, 대강면, 주생면", - "MNTN_NM" : "문덕봉" + "DETAIL_INFO_DTCONT" : "무릉산은 칠북면의 중심산역으로 작대산의 북쪽에 위치하면서 둥그스럼한 산릉에 부드러움을 더하고 있다. 낙동강에 산자락을 내밀고 있는 북릉은 북면 온천이 있는 마금산역에 손을 내밀면서 느긋하게 산세를 일으키고 있다.", + "MNTN_HG_VL" : "556", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 북면, 함안군 칠북면", + "MNTN_NM" : "무릉산" }, - "longitude" : 127.5351143, - "latitude" : 35.377140400000002 + "longitude" : 128.56579629999999, + "latitude" : 35.328721999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "인천 앞 바다가 조망되는 경기의 명산 용문산(1157) 정상에서 동북쪽으로 3km 거리에 위치한 문례봉은 용문봉(947)과 용조봉(635), 중원산(800) 사이로 용계골과 조계골을 거느리고 있는 산이다.다른 산에 비해 정상으로의 접근 거리가 길어 잘 알려지지 않은 산이다. 용계골과 조계골은 용문산 주변 계곡 중에서 뛰어난 계곡미로 인해 `용계조계(龍溪鳥溪)'로 오래 전부터 많이 알려진 곳이며, 용계골은 군사시설이 자리하고 있어 출입이 통제된 지역이다. 전반적인 산세는 지능선 쪽으로 암릉과 절벽이 있고, 정상부는 육산 형태를 이루고 있으므로 산행시 주의를 해야 한다.폭산 또는 천사봉이라고도 한다.", - "MNTN_HG_VL" : "992", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", - "MNTN_NM" : "문례봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "무선산" }, - "longitude" : 127.603212, - "latitude" : 37.6410093 + "longitude" : 127.6480638, + "latitude" : 34.7671888 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "문복대는 경북 예천군과 문경시, 충북 단양군의 경계지점에 위치한 저수재와 벌재사이에 있는 백두대간상의 산이다. 문복대는 이 산에서 한줄기가 북으로 뻗어 수리봉.신선봉과 단양팔경 중 유명한 상.중.하선암이 있는 도락산을 두고 있다. 이 산 밑에 배나무골,호박골,세작골,성골을 두고 있으며, 이 골짜기들이 모두 동로면 석항리를 이루고 있다. 석항리를 돌목이라고도 하는데 아직까지 남아있는 아름다운 우리의 이름이다.백두대간이 죽령, 도솔봉, 향적봉, 저수령을 지나서 문경시 관내로 들어오면서 처음으로 큰산을 두고 있는데 바로 운봉산이다. 석항리 사람들은 ‘문복대’라고 부르고 있으나 산이름에 ‘대’가 붙어 있어 이상하게 생각하고 알아본 결과 옛 이름이 운봉산, 운봉재라 하였다 한다. 운봉재라고 부르는 것은 문복대의 벌재 방향으로 잘록이 부분을 통해 석항리 주민들이 산 너머의 마을로 오가던 길이 있다는 데서 그렇게 불렀다고 한다.정상에서 바라보는 경천호 주변의 붕어입을 한 천주산과 공덕산이 장관이다. 조망지로서 최적의 장소다.", - "MNTN_HG_VL" : "1074", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 석항리", - "MNTN_NM" : "문복대" + "DETAIL_INFO_DTCONT" : "무척산은 신어산, 불모산과 더불어 김해의 3대 명산으로 꼽힌다. 그다지 높지 않고 산줄기가 시원스럽지도 않지만 산천으로 둘러싸인 경치 좋은 뜻의 생림동천(生林洞天)이란 말을 만들어 낼 정도로 아름다운 산이다. 또한 기묘한 바위들이 자리 잡고 있어 그 멋스러움이 더욱 특출나 보인다. 특히 낙동강과 이어져 있어 굽이쳐 흐르는 낙동강의 조망이 탁월하며 산허리 부분에 괴상하게 생긴 암봉이 많아 경치가 수려하다.무척산은 산 이름도 다양하다. 무척산 외에도 무착산, 무쌍산, 식산으로도 불린다. 식산은 북풍을 막아주고 낙동강 물줄기를 끌어들여 들을 기름지게 해 김해 고을을 먹여 살리는 산이라 하여 부르는 이름이다. 또 산의 형세가 밥상을 받는 모양과 같다고 해 식산, 식산 대신 밥상이라고도 부른다.다양하게 불려지는 이름뿐만 아니라 무척산은 많은 설화를 간직하고 있는 산이다. 이 산의 정상 바로 밑에 천지못이 있는데, 이 연못은 김수로 왕릉의 물줄기를 잡기 위해 설치됐다는 전설을 갖고 있다. 또한 고찰 모은암은 김수로왕이 어머니의 은혜를 갚기 위해 지었다고 전해진다. 가락국의 불교를 중흥시키기 위해 창건되었다는 백운암도 유명하다.하늘벽, 가야벽, 탕건바위, 장군봉 등 개척된 암장이 여럿 있으며 부산, 경남 클라이머에게 인기가 높다.", + "MNTN_HG_VL" : "702", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 생림면, 상동면", + "MNTN_NM" : "무척산" }, - "longitude" : 128.34853440000001, - "latitude" : 36.804896200000002 + "longitude" : 128.87060070000001, + "latitude" : 35.340642799999998 }, { "mountain" : { @@ -3689,16 +2899,6 @@ "longitude" : 129.03833330000001, "latitude" : 35.679166700000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 문경 동로면에 위치한 운봉산은 백두대간이 죽령, 도솔봉, 향적봉, 저수령을 지나서 문경시 관내로 들어오면서 솟구친 산이다. `문봉재'라고 많이 알려져 있으나 옛이름은 운봉산이다. 1\/5,000지도에는 문봉재라고 되어 있다. 이 문봉재는 저수령과 벌재 사이에 있는데 이 산에서 한줄기가 북으로 뻗어 수리봉·신선봉과 유명한 단양팔경 중 상·중·하 선암이 있는 도락산을 두고 있다.산새가 아름답고 골짜기 마다 운치가 있어 산행의 즐거움을 더한다. 이 산 밑에 배나무골, 호박골, 세작골, 성골을 두고 있으며 이 골짜기들이 모두 동로면 석항리를 이루고 있다. 석항을 돌목이라고 하는데 아직까지 남아있는 예쁜 우리마을 이름이다. 오늘도 돌목 뒷산인 운봉산은 봄, 여름, 가을 돌목사람들을 지키며 묵묵히 있다.", - "MNTN_HG_VL" : "1074", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면", - "MNTN_NM" : "문봉재 (운봉산)" - }, - "longitude" : 128.507882, - "latitude" : 38.2876695 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "백두대간이 동로면 벌재를 지나 대미산을 빚어놓고 대미산 정상에 못 미친 1,045m고지에서 북으로 한줄기 뻗어 문수봉을 솟아 놓았다. 충북 제천시 덕산면과 경북 문경시 동로면의 경계를 이룬 문수봉은 월악산 국립공원에 속해 있으며 육산으로 이루어져 있어 등반하기 수월한 산이다. 폭포, 탕, 소 등이 사방 곳곳에 흩어져 있어 여름철 가족 피서지로 적합한 이 산의 자랑은 단연 용하구곡이다. 용하구곡이란 이름 자체가 `여름을 갖고 논다'는 뜻에서 비롯된만큼 더위를 씻어내는 야영지로서의 조건을 다 갖추고 있다.옛날 시인 묵객들이 시문을 겨뤘던 청벽대에서부터 선미대, 가학정, 석운대, 수룡대, 우화굴,세심폭, 활래담 마지막 9경인 강서대에 이르기까지 편편한 반석과 깨끗한 물줄기가 절경을 이룬다. 능선 안부에서 곰취, 취나물, 신선초 등 무공해 산나물을 채취하는 재미도 솔솔하며 봄에는 능선안부께에 철쭉나무 군락이 터널을 이루어 산행의 묘미를 더해준다.", @@ -3706,8 +2906,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 경상북도 문경시", "MNTN_NM" : "문수봉" }, - "longitude" : 126.9717141, - "latitude" : 37.632514 + "longitude" : 128.21333329999999, + "latitude" : 36.850277800000001 }, { "mountain" : { @@ -3716,8 +2916,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", "MNTN_NM" : "문수봉" }, - "longitude" : 126.9717141, - "latitude" : 37.632514 + "longitude" : 128.94, + "latitude" : 37.0944444 }, { "mountain" : { @@ -3726,38 +2926,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", "MNTN_NM" : "문수산" }, - "longitude" : 126.53889650000001, - "latitude" : 37.739061399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "341", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 산동면 인덕리", - "MNTN_NM" : "문수산" - }, - "longitude" : 126.53889650000001, - "latitude" : 37.739061399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산 좋고 물 좋기로 소문난 봉화에는 청량산, 청옥산, 문수산 등 명산이 여럿이다. 또 산마다 명수로 알려진 약수터가 있어 찾는 발걸음이 끊이질 않는다. 선달산 아래 오전약수와 옥돌봉 아래 주실령 남동쪽의 문수산 두내약수, 그리고 문수산 자락 끄트머리의 다덕약수 등이 유명하다.문수산 산행들머리로는 개단1리 월계마을이 애용된다. 봉화에서 버스가 다녀 접근성이 좋고 울창한 춘양목 숲에 둘러싸인 축서사가 있기 때문이다. 봉화를 대표할 만한 절집인 축서사에는 신라시대의 작품인 석불좌상(보물 995호)과 고려시대의 석등이 있다.축서사 북쪽의 잣나무 군락지를 따라 오르면 1시간 30분쯤 걸리고 좀 더 강도 높은 산행을 하려면 동쪽의 계곡을 따라 오르면 된다.정상인 서봉에 서면 산 천지인 봉화의 멋진 하늘금을 제대로 조망할 수 있다.", - "MNTN_HG_VL" : "1205", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 춘양면, 봉성면, 물야면", - "MNTN_NM" : "문수산" - }, - "longitude" : 126.53889650000001, - "latitude" : 37.739061399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "600", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 청량면 삼동면, 범서읍", - "MNTN_NM" : "문수산" - }, - "longitude" : 126.53889650000001, - "latitude" : 37.739061399999997 + "longitude" : 129.21639630000001, + "latitude" : 35.534487400000003 }, { "mountain" : { @@ -3769,16 +2939,6 @@ "longitude" : 126.53889650000001, "latitude" : 37.739061399999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "봉화는 산 좋고 물 좋기로 소문난 곳이다. 청량산, 청옥산, 문수산이 대표적인 봉화의 산이며 선달산 아래 오전약수, 옥돌봉 아래 주실령 남동쪽 문수산 두내약수 그리고 문수산 자락 끄트머리의 다덕약수가 봉화의 약수들이다. 깊은 산, 깊은 골 천혜의 자연 속 깊숙한 곳에 자리했다.정상부에는 참나무 군락지가 형성되어 있고 발길이 뜸한 산으로 늦가을 낙옆에 빠지는 만추산행의 멋을 만끽할수 있으며 축서사에서 오르는 등산로는 경사가 급하며 주실령에서 진입할 경우 능선을 따라서 산행을 즐길수 있다. 정상은 삼각점과 철제구조물이 있어 그 모습이 초라하지만 봉화군의 중심에 위치하고 있으며 앞을 가로막을 산들이 없어 조망은 좋다.문수산은 시선이 닿는 저끝 어디하나 트인곳 없이 산마루 금으로 둘러싸여 커다란 바루속에 우뚝 솟은 형세다. 정상에서 맑은날에는 태백산, 소백산, 청량산, 일월산이 멀리보이며 특히, 두내 약수탕에서 오르는 등산로 입구의 서벽임도에는 하늘을 찌를 듯 곧게 자란 붉은 줄기의 춘양목 군락지가 임도를 따라 형성되어 있어 가족나들이 산책로로 인기가 있다.", - "MNTN_HG_VL" : "1205", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면, 춘양면, 봉성면", - "MNTN_NM" : "문수산" - }, - "longitude" : 126.53889650000001, - "latitude" : 37.739061399999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "백두대간에서 갈라진 산줄기가 경기도에 이르러 화악산과 명지산 등 고산을 일구고, 운악산과 천마산으로 이어져 북한강가에 이르러 빚어놓은 산이 문안산이다.산은 낮으나 북한강가에 자리잡고 있어 경치가 뛰어나고 험한 곳이 없어 어린아이를 동반한 가족 산행지로 적합한 곳이다. 봄에는 능선길의 진달래가 볼만하고 하산길엔 북한강이 한눈에 들어온다 .문안산이라는 이름의 유래는 날씨가 좋은 날 정상에 오르면 서울의 문안까지 환히 보여서 붙은 이름이라고 한다.", @@ -3829,16 +2989,6 @@ "longitude" : 126.9933333, "latitude" : 36.440833300000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "미남봉은 산 형상이 잘생긴 남자의 옆얼굴처럼 생겼다고 해서 붙여진 이름이며, 속리산국립공원권에 속하는 산으로 상학봉(834)과 금단산(767)을 마주하고 있는 산이다. 속리산국립공원은 다른 곳에 비해 계곡의 규모가 크고 수량이 많은 것이 특징이다.묘봉(874)과 상학봉은 돌출 된 기암괴석으로 산세가 이루어져 있는데 반해 이산은 정상부만 100m 정도에 거암(巨岩)이 돌출해 있는 것을 제외하고는 거의 육산으로 느낄 만큼 돌출바위가 없이 감추어진 산세를 가지고 있고 수려한 비경을 연출해 말 그대로 속세를 떠난 산 (俗離山) 의 모습을 보여준다.정상이 돌출바위 지대로 조망이 시원스레 열려 있으며, 백두대간의 연봉과 문장대, 상학봉 일대가 그림처럼 아름답게 보이는 산이다. 곳곳에 숨겨진 바위지대가 있으므로 산행시 방심해서는 안 되는 산이다.", - "MNTN_HG_VL" : "610", - "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 산외면, 경상북도 상주시 화북면", - "MNTN_NM" : "미남봉" - }, - "longitude" : 129.07159820000001, - "latitude" : 35.206026399999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "미녀봉의 본 이름은 문재산(文載山)이다. 그러나 미인이 머리를 풀고 누워있는 형상이라 하여 미녀봉(美女峰)으로 널리 불린다. 미녀봉에는 두 가지 전설이 전한다. 옛날 바다였던 이곳에 장군이 탄 나룻배가 표류하자 옥황상제가 딸을 지상으로 보내 구하고자 했다. 장군은 딸과 사랑하게 되었고 그런 딸을 보고 노한 옥황상제는 너희 둘은 영원히 산으로 누워 있으라는 형벌을 내렸다고 한다. 또 다른 전설은 예쁜oacute;녀가 어머니 병을 고치기 위해 미녀봉에만 있는 약초를 캐려 했는데 뱀에 물려 죽자 불쌍히 여긴 산신이 죽은oacute;녀의 모습대로 만든 산이 미녀봉이라 한다. 88고속도로 인터uuml;인지에서 바라보는 미녀봉은 참으로 감탄스럽기 그지없다. 잘 다듬어진 이마, 세련된 화장술로 그려낸 듯한 눈썹, 오똑한 코, 힘겨워 헤 벌리고 있는 입, 봉긋 달덩이oacute;럼 솟아오른 젖가슴, 아이를 잉태한 듯한 볼록한 배 등 산봉우리들이 모여 하나의 아름답고 고운 여인 형상을 빚고 있다. 미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀봉을 눈부시게 만든다.", @@ -3876,8 +3026,8 @@ "MNTN_LOCPLC_REGION_NM" : "전북 익산시 금마면ㆍ낭산면ㆍ삼기면", "MNTN_NM" : "미륵산" }, - "longitude" : 128.4163241, - "latitude" : 34.810502800000002 + "longitude" : 127.03903339999999, + "latitude" : 36.0250561 }, { "mountain" : { @@ -3886,48 +3036,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면", "MNTN_NM" : "미륵산" }, - "longitude" : 128.4163241, - "latitude" : 34.810502800000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "168", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 금호리,해평리,낙성리", - "MNTN_NM" : "미석산" - }, - "longitude" : 128.3761111, - "latitude" : 36.205277799999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "미타산은 경남 의령군 부림면과 합천군 적중면의 경계에 자리한 해발 662미터의 아담한 산이다. 또 서쪽으로 능선길을 이어가면 천황산(655m), 국사봉(688m) 등 여럿의 청산이 솟구쳐 산행의 묘미를 더해준다. 봄날 진달래 군락지가 장관을 이루며, 9부 능선에는 약 2킬로미터에 이르는 토석 혼축으로 된 도지정기념물인 삼국시대 축성된 미타산성이 있다. 미타산 중턱에는 옛 묵방초등학교를 절로 개조한 불관사가 있다.그리고 미타산 기슭에는 지금부터 약 1300여년 전 통일신라시대 때에 창건되었다는 고찰 유학사가 있다. 유학사는 원래 미타산의 8부 능선에 자라잡고 있었으나 조선초기 태조 이성계의 왕사를 지낸 무학대사가 유학사에 들러 사찰이 앉은 위치가 풍수지리에 맞지 않다고 하여 지금의 위치에 절을 옮겨왔다고 구전으로 전해지고 있다. 현재 미타산의 8부 능선 예전의 사지에는 지금도 절터의 흔적이 완연히 남아있다.", - "MNTN_HG_VL" : "662", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 부림면ㆍ합천군 적중면", - "MNTN_NM" : "미타산" - }, - "longitude" : 128.28888889999999, - "latitude" : 35.5152778 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상북도 의령", - "MNTN_NM" : "미타산" - }, - "longitude" : 128.28888889999999, - "latitude" : 35.5152778 + "longitude" : 127.8530556, + "latitude" : 37.186111099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "민둥산은 1,023m의 제법 높은 산으로 주변에는 국망봉, 강씨봉, 청계산,귀목봉 등 산세가 아름다운 산들이 모여있다.민둥산은 민드기봉, 민덕산이라고도 하며 적목리 서쪽 한북정맥에 솟아있는 산이다. 주능선을 경계로 서쪽은 경기도 포천군 이동면 연곡리로, 조금 더 지역을 좁혀 설명하면 개이빨산(1,110m)과 강씨봉(830m) 사이 능선에서 가장 높은 산이다. 현지 사람들은 민덕산이라고도 부른다.이 민둥산은 제비울 분지와 억새밭을 가지고 있는 가을철 풍광이 좋은 산이다. 가평군 용수동쪽으로는 수량이 많고 깨끗한 가평천을 산행기점으로 하고 있어 여름철 피서 산행지로도 적합한 곳이다. 주능선 좌우로 시원한 조망을 즐길 수 있으며, 강씨봉이나 개이빨산으로 연계 산행이 가능하다. 민드기재에서부터 정상으로 이어지는 능선에는 키를 넘는 억새 밭이 펼쳐져 있어 늦가을이면 하얀 억새꽃을 머리에 인 산의 정취가 일품이다. 또한 적설량이 많은 산으로 알려져 겨울에 능선을 종주하는 산행이 인상적이다.", - "MNTN_HG_VL" : "1023", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 가평군 북면", - "MNTN_NM" : "민둥산" + "DETAIL_INFO_DTCONT" : "미숭산은 비운의 역사를 품고 있는 산이다. 고려의 장군이었던 이미숭이란 사람이 조선을 건국한 이성계에 대항해 군사를 모으고 이 산에 성을 쌓아 고려를 회복하는 싸움을 벌였던 곳이다. 그러나 이미 대세는 조선과 이씨 왕조쪽으로 기운 상태였기 때문에 장군은 결국 고려 회복의 뜻을 이루지 못하고 순절했다고 전해진다. 산에 장군과 관련된 유적이 아직 남아 있어 대세와 명분 사이의 긴장감 넘치는 대결을 떠올리게 한다. 정상 주변에 미숭산성의 성터와 성문의 잔해가 있고, 성문터 옆에 샘물도 있다. 이 산성은 삼국시대에 축조된 후 조선시대까지 계속 이용되었다고 한다.원래 이름은 상원산이었으나 후세 사람들이 이미숭 장군의 이름을 따서 미숭산이라 부르게 되었다.미숭산을 오르다보면 사방으로 운무에 가린 산, 산, 산이 겹겹으로 늘어서 있다. 그 사이로 들녘에 반짝 빛나는 것은 낙동강이다. 한 페이지의 역사도 남기지 않고 사라진 가야의 유물과 사적지를 둘러보면서 주산과 미숭산을 오르내리다 보면 봉긋하게 솟아난 언덕만 봐도 고분으로 보이고 등산길에 맞닥뜨리는 바위마다에는 원시 암각화가 그려 있는 것 같아 유심히 살펴보게 된다. 자신도 모르게 이처럼 신비에 쌓인 가야의 역사 속으로 빨려 들어간다.", + "MNTN_HG_VL" : "757", + "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군 고령읍", + "MNTN_NM" : "미숭산" }, - "longitude" : 128.77488750000001, - "latitude" : 37.270854200000002 + "longitude" : 128.19232030000001, + "latitude" : 35.738110900000002 }, { "mountain" : { @@ -3939,36 +3059,6 @@ "longitude" : 128.77488750000001, "latitude" : 37.270854200000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "민주지산(1,241.7m)은 추풍령 남서쪽 약 25km 지점에 있으며 산행의 기점은 정상의 동북쪽 방향인 한천마을과 남쪽 아래의 대불리로 크게 나눌 수 있다. 삼도봉, 석기봉이 명소이며, 석기봉 동쪽에는 원시숲과 화전민터가 있어 옛 주민들의 생활상을 엿볼 수 있고, 물한리에서 멀지 않은 곳에는 1972년에 지은 황룡사가 있다.석기봉과 삼도봉으로 이어지는 주능선은 봄이면 온통 산죽과 진달래가 군락을 이뤄 꽃산행을 즐기게 된다. 다른 산의 진달래가 무리지어 군락을 이루는데 반해 이 곳 진달래는 능선을 따라 도열해 있는 것이 특징이다.물한계곡을 끼고있어 심산유곡으로 아직도 때묻지않은 계곡이 돋보이며, 각종 잡목과 진달래 철쭉 등이 꽉 들어차 장관을 이루고 있다. 옥소(玉沼) 응주암 의용곡폭포 등이 절경을 이루며, 삼도봉에는 충북, 경북, 전북 등 3도인이 모여 세운 3도봉 대화합탑이 있다.", - "MNTN_HG_VL" : "1242", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 상촌면ㆍ용화면, 전라북도 무주군 설천면, 경상북도 김천시 부항면", - "MNTN_NM" : "민주지산" - }, - "longitude" : 127.8490946, - "latitude" : 36.040040900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "바라산은 백운산, 광교산과 능선으로 연결되는 이웃한 산으로 이들 산은 경부고속도로와 서울특별시, 수원간의 옛 도로 사이에 약 10여km에 걸쳐 수원까지 뻗어 있다.동서로 흘러내린 계곡에는 동막천과 백운(의왕) 저수지 및 광교저수지 등 유원지화 되어 가는 곳도 있으나 능선은 매우 한적하고, 완만하며 수목이 우거져 있어 오붓하게 산행을 할 수 있는 당일 산행이며, 주위에 일왕저수지, 광교저수지, 파장저수지, 하광교 소류지, 백운저수지, 운중저수지 등이 산재해 있어 특히 주말이면 낚시 인파로 항상 붐비는 곳이기도 하다.", - "MNTN_HG_VL" : "428", - "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시, 성남시", - "MNTN_NM" : "바라산" - }, - "longitude" : 127.0196199, - "latitude" : 37.372872800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "바랑산은 화순 너릿재에서 광주로 넘어오는 국도변에 들어앉은 쓰레기 매립장을 곁에 두고 있다.매립장이 들어선 것은 2000년도, 동구지역에서 발생하는 쓰레기는 이 곳에서 처리되고 있다. 정상으로 바로 이어지는 등산로는 가파라서, 등산하기에는 힘들고 동구환경관리사업소 사무실 옆 우회로가 등산에 적합하다. 숲길은 비교적 깔끔하게 잘 정비되었으며, 등산로 주변에는 소나무가 빽빽하게 식생하고 있다. 30분 정도 올라가면 헬기장이 있으며, 그 곳을 지나 왼쪽으로 바랑산 정상으로 가는 등산로가 나있다.참나무, 벚나무, 갈참나무 등 국립공원 못지 않은 다양한 식생을 갖추고 있으며, 그 변화도 다양하다. 정상(320m)에서는 무등산의 여러 봉우리들이 한 눈에 들어와 무등산의 장엄함을 감상하기에 충분하다.", - "MNTN_HG_VL" : "602", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구 소태동,용산동", - "MNTN_NM" : "바랑산" - }, - "longitude" : 127.27, - "latitude" : 36.130000000000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "호남의 금강이라 부르기에 손색이 없는 대둔산은 충남 논산시와 금산군, 전북 완주군 등 3개군에 걸쳐 있다. 최고봉인 마천대를 중심으로 기암괴석들이 제각기 위용을 자랑하며 늘어서 있다. 대둔산은 두 얼굴을 가지고 있다. 기경의 절벽을 이루는 전북 완주쪽과 순후한 시골아낙 같은 충남 논산,금산쪽이 바로 그것이다.바랑산은 그리높지 않은 산임에도 월성봉까지 이어지는 능선은 보기드문 절경을 자랑한다. 잘 닦인 등산로를 가지고 있으면서도 깨끗한 주변환경을 유지해 쾌적함속에 산행을 즐길 수 있는 곳이다.바랑산은 다리성 서쪽에 있고 모양이 바랑과 같이 생겼다 하여 붙여진 산명이며, 노승예불현의 명당이 있다.등산로 역시 양쪽 지형이 상반되는 것 만큼이나 특성이 뚜렷이 구분된다.", @@ -3996,18 +3086,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", "MNTN_NM" : "바위산" }, - "longitude" : -103.45906669999999, - "latitude" : 43.879102499999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "봄과 여름 산행에서 빼놓을 수 없는 게 바로 계곡 산행이다. 박달봉은 백운골 계곡과 큰골 계곡이 특히 등산인들의 발길을 모으고 있다. 광덕재에서 광덕산 그리고 백운산에 이르는 능선은 암벽으로 이어져 스릴을 주며, 억새밭이 펼쳐져 있고 광덕재에서 바라보면 오른쪽은 백운산, 흥룡봉이 위치해 있고 왼쪽에는 광덕산, 박달봉이 대조를 이루고 있다.산행은 광덕재에서 시작하는 편이 쉽다. 광덕재에서 광덕산을 거쳐 박달봉을 지나 백운동 초입리와 광덕재 고개 중간 약간 아래쪽으로 하산하여 도로로 이동하는 편이 쉽지만, 도로 이동시 차량이 많아 사고 위험이 높아 특히 주의해야 한다.약 270년전에 이 산봉에는 박달나무가 밀집하여 통행을 하지 못할 정도였기 때문에 박달봉이라고 불리우고 있다.", - "MNTN_HG_VL" : "800", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", - "MNTN_NM" : "박달봉" - }, - "longitude" : 126.20277780000001, - "latitude" : 40.913611099999997 + "longitude" : 127.96777779999999, + "latitude" : 37.9566667 }, { "mountain" : { @@ -4019,16 +3099,6 @@ "longitude" : 127.923232, "latitude" : 36.836640699999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "896", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백", - "MNTN_NM" : "박월산" - }, - "longitude" : 128.53055560000001, - "latitude" : 35.574722199999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "박지산은 강원도 평창에 위치한 산으로 오대산에서 발원하는 청정류 가운데 가장 때묻지 않은 계곡인 아차골을 품고 있다. 말복까지 얼음을 볼 수 있는 박지골과 경치가 수려한 아차골 등 박지산 골짜기는 등산인들의 발길이 뜸하여 오지의 신비함을 간직하고 있다.박지산은 두타산(頭陀山)이라고도 하는데 2007년 인쇄된 국토지리정보원 지형도상의 공식명칭으로 ‘우리 산 이름 바로 찾기 운동’에 따라 2002년 박지산에서 두타산으로 이름이 바뀌었다. 그러나 백두대간의 삼척 두타산(1352.7m)과 혼돈되기 때문에 여전히 박지산이라 일컫는 이들이 많다.정상에는 2미터 높이의 돌탑이 있는데 칠원성군(七元星君)을 모셨다하여 칠성대라 부르며, 칠원성군이란 불교에서 북두의 일곱 성군을 뜻한다. 칠원성군은 북두칠성을 인격화한 신(神)이며 농사와 생사(生死), 화복(禍福)을 맡아본다고 한다. 박지산은 이곳 주민들에겐 단순히 이끼가 많은 산이 아니라 북두칠성의 산이기도 하다.", @@ -4049,16 +3119,6 @@ "longitude" : 128.7305556, "latitude" : 37.4641667 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백운산과 무학봉의 능선과 이어져 있는 반암산은 강원도 화천군 사내면에 자리를 잡고 있다. 이 산은 `수색특공 훈련장' 이라는 안내판이 붙어 있어 많은 등산객들이 산행을 꺼리고 있어 훼손되지 않은 자연을 그대로 유지하고 있는 지역으로 백운산과 더불어 청정지구로 지정하자는 여론이 모아지고 있는 곳이다.백운산 능선과의 사이에는 덕골계곡이 있다. 짧은 능선에 있는 산이지만 때 묻지 않은 수림이 우거져 있다. 주변에는 광덕계곡, 반암계곡 등이 있다. 사철 수량이 풍부하고 주능선에는 이 산의 제일 명소인 거대한 구름다리바위와 사자바위 등 기암이 드문드문 있다.", - "MNTN_HG_VL" : "832", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면 광덕리", - "MNTN_NM" : "반암산" - }, - "longitude" : 127.4731841, - "latitude" : 38.076925699999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "남한의 산 중 최대면적을 가지고 있는 지리산의 산세는 세인을 압도하고도 남는다. 반야봉은 지리산 제2봉으로 산세가 웅장하고 계곡이 깊으며 수목이 울창하여 고산식물과 기암절벽이 장관을 이룬다. 이에 해마다 많은 산행인이 찾고 있다. 지리산의 모든 능선을 한눈에 볼 수 있는 지리산의 중심부로, 해질무렵 운무에 둘러쌓인 반야봉의 붉은 빛 낙조는 장엄하기 그지없어 산행인의 넋을 빼놓을 정도다. 특히 여름날 작열하던 태양이 지루한 하루를 보내고 저편 너머로 숨어들 무렵이면 반야의 하늘은 온통 진홍빛으로 물들어 보는 이들을 감동케 한다.지리산이 그토록 아름다울 수가 있는지를 끝없이 되뇌여도 반야봉의 낙조는 모자람이 없다. 화려한 불꽃잔치와 더불어 반야봉은 운해와 함께 우리에게 인식된다. 늘 발아래 운해를 거느리고 우뚝 솟아 있는 반야봉의 장관은 비경 그것이다.태산준령들 사이사이에 걸려 있는 지리산의 운해는 아마도 주봉인 천왕봉과 반야봉에 얽힌 마고할미와 반야의 애틋한 마음을 그대로 전해주려는 듯 심오함을 갖고 있다.반야봉 정상에서 동쪽으로 조금 내려가면 절벽 아래에 묘향대가 있는데 이곳은 옛부터 불도들이 수도하는 유서깊은 선암으로 유명하다.", @@ -4079,36 +3139,6 @@ "longitude" : 128.11388890000001, "latitude" : 37.654722199999988 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "발왕산은 대관령 용평스키장으로 더욱 알려진 강원도 평창군 도암면과 진부면 그리고 강릉시 왕산면의 경계를 이루는 산이다. 즉 백두대간이 오대산, 황병산을 거쳐 대관령으로 이어질 무렵 황병산에서 남쪽으로 더욱 거대한 봉우리를 솟구치게 했으니 그 산이 바로 발왕산이다. 용평스키장으로 인해 다양한 등산코스가 개발되지는 못했으나 그만큼 교통이 좋은 장점이 있다.그 옛날 발이 컸던 발왕이와 그를 사랑한 옥녀의 슬픈 전설로 이름이 유래된 발왕산은 산세가 부드럽고 험한 길이 없으며 설원의 절경이 손꼽히는 산이다. 정상에 오르면 평창의 산을 조망하기 좋다. 정상에서 만나는 주목군락은 발왕산의 자랑거리며 아름다운 자연 그대로의 모습을 간직한 고장답게 1000여미터가 넘는 산들이 주변으로 즐비하다. 특히 북쪽으로 삼양대관령목장의 황병산을 시작으로 왼쪽으로 노인봉, 두로봉, 상왕봉, 비로봉, 계방산 등이 장대한 파노라마를 연출하며 펼쳐진다.", - "MNTN_HG_VL" : "1458", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 진부면ㆍ강릉시 왕산면", - "MNTN_NM" : "발왕산" - }, - "longitude" : 128.67283159999999, - "latitude" : 37.607200300000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "발치봉은 충북 충주시에 자리한 야트막한 산으로 아직 일반인들에게는 잘 알려지지 않은 산이다. 발치봉의 이름에 대한 유래는 확실치 않다.남쪽 아래에 발치마을이 있고 발치고개가 있어 발치봉이란 이름을 붙이게 되었다는 이야기도 있으나 자세한 사실은 알 수 없다. 그리고 수안보 온천이 인근에 있어 그 분위기를 더한다.발치봉은 야산으로 버려져 있다시피 한 것을 최근에 등산로가 개척되면서 산악인들에게 알려지기 시작했을 뿐 아직까지는 많은 사람들이 찾지 않고 있는 미지의 산이다. 사람들의 발길이 뜸하다보니 숲이 우거지고 길이 희미하여 자칫하면 등산로를 잃을 수가 있으니 주의해야 한다.", - "MNTN_HG_VL" : "550", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 살미면", - "MNTN_NM" : "발치봉" - }, - "longitude" : -122.86777290000001, - "latitude" : 49.249334400000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "밝얼산은 울주군 상북면 거리와 길천리에 걸쳐 있는 산으로 이 산을 따라 서쪽으로 넘어가면 배내봉을 지나 천화현(배내고개)에 이르게 되고 고개를 지나면 밀양으로 넘어가게 된다.또한 밝얼산은 신불산갈월산취서산과 한 지괴로 된 산으로 밝어리산, 밝얼제 등의 이름을 가졌으며 '광명'을 뜻하는 산이다. 그러므로 이 산은 광명하고 신성한 산이라는 의미를 가지고 있다.병풍같이 깎은 듯한 바위와 처녀 총각으로 풍자하는 바위가 있고, 배내와의 경계에는 참샘이 있어, 길손의 목을 축여 준다. 그리고 옛날에 이 우마차 길은 험하기로 이름이 있어, 이 산길을 다녀왔던 말이나 소는 삼천리 어디라도 다 갈 수 있다고 격찬했다.", - "MNTN_HG_VL" : "738", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 상북면", - "MNTN_NM" : "밝얼산" - }, - "longitude" : 129.0354055, - "latitude" : 35.576419700000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -4139,16 +3169,6 @@ "longitude" : 126.73999999999999, "latitude" : 35.450000000000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "방장산은 전북 정읍시와 고창, 전남 장성의 경계에 솟아 있다. 내장산의 서쪽 줄기를 따라 뻗친 능선 중 가장 높이 솟은 봉우리이다.지리산 무등산과 함께 호남의 삼신산으로 추앙받아 왔으며 주위의 이름난 내장산, 선운산, 백암산에 둘러싸여 있으면서도 기세가 눌리지 않는 당당함을 자랑하고 있다. 방장산 중턱에는 방장산 자연휴양림이 위치하고 있다.2000년 7월 1일 문을 연 것으로 서부지방 산림관리청(전북 남원 소재)에서 순창 회문산 자연휴양림, 무주 덕유산자연휴양림, 진안 운장산자연휴양림, 장흥 천관산자연휴양림, 함양 지리산자연휴양림, 남해 편백자연휴양림과 함께 방장산휴양림을 관리하고있다. 휴양림 내에는 참나무류와 소나무, 편백, 낙엽송, 리기다소나무 등이 많이 자라고 있으며, 고창 방면으로 난 임도를 따라가면 벽오봉(640m)과 고창 고개 중간의 능선에 닿는다. 이곳에서는 고창 읍내와 서해바다가 내려다보인다. 고창고개를 지나 장성갈재 방면으로 조금 더 가면 방장산 정상이다.방장산 정상에 오르면 신선지경에 이르며 고창읍을 비롯하여 광활한 야산개발지와 멀리는 서해바다가 보이며 동쪽으로는 광주 무등산까지 보인다.휴양림에서 정상까지는 왕복 3시간이 소요되며 석정온천으로 곧장 하산하는 산길도 나있다.주능선에 오르면 서해로부터 불어오는 시원한 바람을 맞이할 수 있는데 이 덕분에 패러글라이딩 동호인들이 종종 이곳을 찾기도 한다. 정상 서편 용추골에는 용추 폭포가 있으며 하산지에는 게르마늄 천으로 유명한 석정온천이 있어 피로회복에 더없이 좋고, 고창은 전통음식으로도 유명한 고장이다.", - "MNTN_HG_VL" : "734", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군, 전라북도 고창군 신림면ㆍ정읍시 입암면", - "MNTN_NM" : "방장산" - }, - "longitude" : 126.76000000000001, - "latitude" : 35.447778 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "국내 최대의 면적을 자랑하는 자연휴양림을 거느리고 있는 방태산은 강원도 인제군과 홍천군의 경계를 이루는 산으로, 교통이 불편한 관계로 아직도 오염되지 않은 깨끗한 계곡을 간직하고 있다.청정한 자연림에 들어서면 도심에서 불과 몇시간 거리밖에 떨어져 있지 않다는 사실이 믿어지지 않는다. 빽빽한 나무들 사이에 누워 하늘을 올려다보면 한줄기의 햇살도 허용하지 않는 수림의 깊이가 느껴진다.", @@ -4159,35 +3179,25 @@ "longitude" : 128.35604789999999, "latitude" : 37.894853599999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "배내봉은 가지산, 상운산, 천황산, 재약산, 능동산, 고헌산, 문복산, 간월산, 신불산 등 1000m급 봉우리 중앙부분에 위치하였으니 산 정기의 심장부인 곳이라 할 수 있다.배내봉 산행을 하려면 언양에서 석남사 행 버스로 궁평을 지나 양등 상북 주유소 앞에 내린다. 길 건너 주유소 100m 안으로 들어서면, 길가 콘테이너 밑에 푹 패인 찬물내기 즉 냉수정을 만날 수 있다. 계곡안쪽은 물이 많으며 바위와 어울어져 여름 피서지로는 좋아보이나 계곡물을 마을사람들 식수로 사용하므로 계곡이 깨끗하다.양등천을 지나 마을 당산나무 뒤 마을회관에 도착한다. 오른쪽으로 100m 가량 들어서면 마을이 끝나는 곳의 재실을 돌아 무덤 1구를 만난다. 산행들머리는 무덤에서 왼쪽으로 오르면 소나무 한 그루를 만난다. 해마다 당제를 지냈다는 국수목이다.정상은 탁 트인 초원 지대로 주변의 경관이 시원하게 펼쳐지며, 신불산(1,209m), 간월산, 수미봉, 사자봉 등의 산들이 한눈에 들어온다.", - "MNTN_HG_VL" : "965", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "배내봉" - }, - "longitude" : 129.0354055, - "latitude" : 35.576419700000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "361", - "MNTN_LOCPLC_REGION_NM" : "충청남도 아산시 배방면", - "MNTN_NM" : "배방산" + "MNTN_HG_VL" : "225", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 연제구, 수영구", + "MNTN_NM" : "배산" }, - "longitude" : 127.052751, - "latitude" : 36.777539999999988 + "longitude" : 129.09638889999999, + "latitude" : 35.18 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백덕산은 이름 그대로 하얀 눈이 쌓였을 때 절경을 이루는 산이다.겨울이면 무릎까지 빠지도록 많은 눈이 내린다. 1천m 이상의 주능선 봉오리마다 피어나는 설화(雪花)가 은백색의 세계로 빠져드는 환상을 느끼게 한다.", - "MNTN_HG_VL" : "1350", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 방림면, 횡성군 안흥면, 영월군 수주면", - "MNTN_NM" : "백덕산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "353", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", + "MNTN_NM" : "백두산" }, - "longitude" : 128.2934023, - "latitude" : 37.396552 + "longitude" : 128.96777779999999, + "latitude" : 35.254444399999997 }, { "mountain" : { @@ -4206,18 +3216,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 청웅면, 강진면", "MNTN_NM" : "백련산" }, - "longitude" : 126.9269444, - "latitude" : 37.589444399999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백마산은 원남면 마송리, 주봉리와 괴산군 사리면 소매리에 걸쳐있는 명산으로 수석이 절기하고 경치가 아름다워 일명 음성의 소금강이라고 부른다.서기 1649년(인조 27년)에 큰 백마가 나타나서 이 산기슭 일대를 돌아다니며 살다 죽어 백마산이라 했다하며, 이 백마의 무덤은 지금까지도 남아 있다. 농사철에 가뭄이 심할 때면 이 말 무덤위에 맑은 물을 붓고 무덤을 약간 파헤치면서 농악을 울리면 단비가 쏟아진다는 전설이 있어 백마묘의 봉분은 옴푹하게 파헤쳐져 있다.산꼭대기 가까이에는 상독암, 관창암, 장사바위, 맹봉바위, 고깔바위, 상좌바위, 소두방바위, 범바위, 매바위, 쌍둥이바위 등이 있으며 남쪽에는 백운사가 있고 북쪽에는 주봉사가 있으며 백마산을 경계로 북쪽은 남한강 수계이고 남쪽은 금강수계의 분수령을 이루어 충북을 지형적으로 남북으로 둘로 구분하는 경계가 나뉘는 산이기도 하다.산에 올라 자세히 살펴보면 이 근방의 작은산을 모두 백마산을 보고 엎드려 절하는 것 같은 형상을 볼 수 있으며 주변에 백은사 암자가 있는데 암자에서 나오는 석가수가 산객을 맞아주고 있다.", - "MNTN_HG_VL" : "772", - "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 사리면 노송리", - "MNTN_NM" : "백마산" - }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 127.168783, + "latitude" : 35.567224400000001 }, { "mountain" : { @@ -4226,8 +3226,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", "MNTN_NM" : "백마산" }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 128.94467259999999, + "latitude" : 35.502180600000003 }, { "mountain" : { @@ -4236,8 +3236,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", "MNTN_NM" : "백마산" }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 127.96885260000001, + "latitude" : 35.322628600000002 }, { "mountain" : { @@ -4251,23 +3251,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "772", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면 고례리\/ 양산시 상북면 대리", - "MNTN_NM" : "백마산" + "DETAIL_INFO_DTCONT" : "태백시 동쪽 경계에 있으며, 태백시계의 연봉 중 하나다. 해발 1259미터로 백두대간에서 갈라져 나온 낙동정맥의 산들 중 가장 높기도 하다. 낙동정맥은 백두대간 천의봉(매봉산, 1303m) 동쪽 능선에 있는 1145봉에서 부산 몰운대에 이르는 350여 킬로미터의 산줄기이다.백병산은 금대봉 같은 육산과 달리 정상부가 마치 바위병풍을 둘러놓은 듯하다고 해서 백병산이라 이름 붙었다. 전해오는 이야기에 따르면 병풍바위가 가뭄 때는 흰빛을, 비가 올 때는 검은 빛을 띠므로 바위 색깔만을 보고 가뭄이 올 것인지 홍수가 날 것인지를 판단했다고 한다.", + "MNTN_HG_VL" : "1259", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 황연동", + "MNTN_NM" : "백병산" }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 129.06833330000001, + "latitude" : 37.158333300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "진산과 금산을 잇는 도로에서 가깝다. 진산에서 복수면과 금산길이 갈라지는 곳에서 금산쪽 길에 들어서다 보면 길가의 부수바위마을(부암리)에 이른다. 이 마을 앞에서 남쪽을 바라보면 개울 건너에 백마산과 국사봉이 한 눈에 들어온다.부수바위마을 서쪽 끝머리쯤과 석막리로 가는 포장길이 금산길과 갈라져 남으로 뻗는다. 그 석막리 길을 따라가다 곧 다리를 건너고 국사봉 모퉁이를 돌면 길가에 삼가리 마을이 나타난다. 이 삼가리 마을이 산행의 기점이다. 마을 앞 길가에서 국사봉 고스락 아래 병풍바위가 올려다 보인다. 그 경관이 매우 아름다워 옛부터 많은 사람들의 사랑을 받아왔다. 그래서인지 옛날 원님들이 여기에 자주 놀러왔었다고 한다.백마산에 옛부터 다음과 같은 전설이 전해 내려오고 있다. 옛날 부수바위 마을에 겨드랑이에 날개가 달린 장수 아기가 태어났다. 그러자 백마산 국사봉 아래 용마굴에서 그 아기장수가 탈 백마도 나왔다. 그러나 아기의 어머니는 뒷일이 두려워 그만 아기의 날개를 베어내고 다듬이돌로 아기를 눌러 죽이고 말았다.", - "MNTN_HG_VL" : "460", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 진산면 삼가리, 엄정리", - "MNTN_NM" : "백마산" + "DETAIL_INFO_DTCONT" : "백봉은 평범한 산이라 별다른 재미가 없다고 말할지 모른다. 그러나 숲속의 산길이 유난히 편안하고 단풍나무가 많아 화사한 것이, 평범하지만 잔잔한 재미가 있는 산이다. 백봉 산행을 뜻깊게 하는 것 중 하나는 묘적사와 홍릉 등의 유적이다.묘적사는 백봉 남쪽 골짜기에 있다. 묘적사계곡을 중심으로 백봉의 산등성이가 말발굽모양으로 둘러싼 산세이기에 묘적사는 산행 들머리 혹은 날머리 기점이 된다. 그래서 묘적사 골짜기에 들어서면 협곡의 개울을 따라 꼬불꼬불 휘돌아 들어가는 것이 마치 별천지에 들어온 느낌이 든다.지형도에는 백봉의 이름은 흰 ‘백’ 자를 쓴 백봉(白峰)으로 되어 있으나 본래 이름은 잣봉산 혹은 묘적산이다. 남양주 시지에 의하면 평내동과 화도읍 쪽에서는 백봉을 잣봉산이라 부르며 와부읍에서는 묘적산이라 부른다고 밝히고 있다.백봉은 수도권에서 멀지 않고 인구 밀집지역인 남양주 도심에서 가까이 있는 산이어서 많은 사람들이 오르내린다. 따라서 길도 좋고 갈래도 많다. 그러나 백봉의 참맛을 보려면 홍유릉과 묘적사를 잇는 산길이 가장 좋다. 이 코스가 좀 길어도 산길이 험하지 않고 편안해 4시간 정도면 산행을 마칠 수 있다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 평내동, 와부읍, 화도읍", + "MNTN_NM" : "백봉산(백봉)" }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 127.2577778, + "latitude" : 37.638888899999998 }, { "mountain" : { @@ -4326,18 +3326,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 홍천", "MNTN_NM" : "백암산" }, - "longitude" : 126.85083299999999, - "latitude" : 35.462778 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "금남정맥에서 갈라진 작은 줄기가 금산으로 뻗어 내렸는데 그 산줄기의 주봉이 백암산이다. 아침 햇살을 받으면 바위 낭떠러지가 하얗게 보이기 때문에 백암이라고 하는 백암산은 600 고지로 널리 알려져 있다. 특히 백암산의 매부리봉은 다른 산에서 볼 수 없는 장관이다. 산의 원줄기 북쪽 끝봉을 서암산이라고 하는 바, 서암산에서 보면 매부리봉의 날카로운 바위가 마치 매의 부리처럼 서쪽 하늘로 내밀고 있어 신기하다. 이 매의 부리는 공중에 떠있는 셈이다.매부리봉 외에도 주릉 일대의 바위등성이는 주로 서쪽 휴양림 골짜기 쪽으로 천길 낭떠러지를 이루고 있으며 그곳에 노송이 어우러져 한 폭의 그림 같다. 봄에는 진달래가 많이 피어 경관을 이루고, 암봉이 많아 산행의 묘미를 맛볼 수 있다.백암산 줄기는 6.25 전쟁 당시 치열한 싸움이 벌어져 피로 물들었던 전적지이다. 충청남도과 전라북도의 경계를 이루며 운장산에서 대둔산으로 이어지는 큰 금남정맥 산줄기이기 때문에 이 백암산은 빨지산의 중요한 거점이며 요새였다. 빨치산 토벌을 위한 군경 합동작전으로 양측 모두 2천 5백명 이상의 귀중한 생명이 이 산에서 사라졌다. 이 작전을 기념하기 위하여 배티재 고갯마루에는 전승탑과 충혼비가 세워졌다.", - "MNTN_HG_VL" : "650", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 남이면", - "MNTN_NM" : "백암산" - }, - "longitude" : 126.85083299999999, - "latitude" : 35.462778 + "longitude" : 128.16748430000001, + "latitude" : 37.848827800000002 }, { "mountain" : { @@ -4346,38 +3336,8 @@ "MNTN_LOCPLC_REGION_NM" : "경북 울진군 온정면, 영양군 수비면", "MNTN_NM" : "백암산" }, - "longitude" : 126.85083299999999, - "latitude" : 35.462778 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백암산은 밀양군내 산내면산외면상동면의 경계를 이루는 괴곡마을 주산이다.이 산은 흙 색깔이 뿌옇다 하여 백암산 또는 흰덤산이라고도 한다. 백암산 정상은 헬기장으로 여름철에는 잡초가 무성한 관계로 산길방향을 잘 잡아야 한다.", - "MNTN_HG_VL" : "1004", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면, 산외면, 상동면", - "MNTN_NM" : "백암산" - }, - "longitude" : 126.85083299999999, - "latitude" : 35.462778 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백양산은 부산의 등줄기를 이루는 낙동정맥의 주능선에 솟은 산이다. 부산을 가로지르는 낙동정맥은 금정산(801.5m), 상계봉(638m), 백양산(642m), 엄광산(503m), 구덕산(562m), 시약산(509m), 승학산(495m)을 거쳐 다대포 몰운대에 이르러 대한해협에 잠겨든다. 백양산은 이 정맥의 중심에 자리잡고 있어 부산의 심장부라 할 만하다. 지리적인 위치로는 부산진구와 북구, 사상구의 경계를 이룬다.산의 유래는 「동래부지」(1740년)에 백양사라는 절 이름이 나온다. 그러나 ‘백양산은 금용산에 있다’고 전한다. 금용산(149.6m)은 부산진구 초읍에서 연제구 거제동에 걸쳐있는 산이다. 전형적인 노년기 산지로 완만한 산세인데 서쪽 방향에서 백양산과 만난다. 기록으로 볼 때 백양산은 1740년 이후 금용산에서 분리된 듯하다.이후 이름을 가지지 못한 산은 절 이름으로 산 이름을 대신했던 것 같다. 동쪽 자락에 선암사가 있어 선암산이라 불리기도 하고 서쪽 자락에는 운수사가 있어 운수산이라고도 불렸다. 백양사에서 따온 백양산이란 이름도 함께 쓰이다가 점차 백양산으로 정착된 듯하다.", - "MNTN_HG_VL" : "642", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 부산진구, 북구, 사상구", - "MNTN_NM" : "백양산" - }, - "longitude" : 129.0264852, - "latitude" : 35.183268800000008 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백양산은 해발 642m로 부산의 등줄산맥인 금정산맥의 주능선에 솟은 산이다. 부산도심의 주요하천으로 우리나라 상수도의 시초가 된 성지곡수원지가 자리잡고 있으며, 동천의 발원지가 된다.백양산은 어린이 대공원 서쪽에 위치하고 있으며, 원래 금용산이라 불리어 왔다. 이산의 동편은 새미산인데 이 산은 사직동 사람들은 돌작동이라고 하며 산복에 배틀굴이라는 동굴이 있어, 임진왜란 때 연대주민이 피신하여 생명을 건진 곳으로 유명하다.들머리인 선암사는 신라 문무왕때 원효대사가 창건한 천년고찰이다. 창건 당시엔 낙동강이 보여 견강사(見江寺)로 불렸지만 경내에 화랑들이 수도를 했던 바위인 신선암이 널리 알려지면서 선암사(仙庵寺)로 명명됐다 한다.정상에서는 장쾌한 조망에 일순간 말문이 막힐 정도이다. 왼쪽엔 낙동강 물줄기와 황금빛 김해평야가, 오른쪽엔 서면시가지와 북항 등 부산전경이 한 눈에 잡힌다. 오른쪽 발밑엔 성지곡수원지와 하얀 사직주경기장이 눈에 들어온다. 시선이 자꾸 도심보다 낙동강과 김해평야 쪽으로 쏠린다. 부산 도심과 주변의 산들도 파노라마처럼 펼쳐진다.", - "MNTN_HG_VL" : "642", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 부산진구", - "MNTN_NM" : "백양산" - }, - "longitude" : 129.0264852, - "latitude" : 35.183268800000008 + "longitude" : 129.29821530000001, + "latitude" : 36.717375500000003 }, { "mountain" : { @@ -4426,8 +3386,8 @@ "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 126.5169444, + "latitude" : 37.493888900000002 }, { "mountain" : { @@ -4436,8 +3396,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 백전면", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 127.63534850000001, + "latitude" : 35.616948800000003 }, { "mountain" : { @@ -4446,18 +3406,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 시흥시, 용인시, 수원시", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1218", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", - "MNTN_NM" : "백운산" - }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 127.0175, + "latitude" : 37.353055599999998 }, { "mountain" : { @@ -4466,8 +3416,8 @@ "MNTN_LOCPLC_REGION_NM" : "충북 제천시 백운면", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 127.9627778, + "latitude" : 37.25 }, { "mountain" : { @@ -4476,28 +3426,18 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 울주군에 위치한 백운산은 열박산이라 부르기도 한다. 신라 김유신은 나이 17세 때 적군의 침공을 당하자 비장한 마음으로 혼자서 보검을 들고 열박산 깊은 골자기 속으로 들어가 향을 피우며 기를 모아 적을 물리칠수 있는 힘을 내려달라고 하늘에 빌었다는 이야기가 전해온다.산행 들머리는 언양에서 다개차리로 가는 버스를 타고 상차리에서 시작하면 된다. 백운산 정상은 대체로 칼등처럼 뾰족한 형상을 보이고 있다. 또한 바위군에 올라서서 바라보는 전망도 대단하다. 오른쪽은 옛날 기우제를 지냈던 아미산, 왼쪽에 문복산가지산, 남으로 고헌산, 북으로 삼강봉이 지척에 보인다.", - "MNTN_HG_VL" : "892", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "백운산" - }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 128.98400000000001, + "latitude" : 35.594999999999999 }, { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "191", - "MNTN_LOCPLC_REGION_NM" : "경기도 평택시", + "mountain" : { + "DETAIL_INFO_DTCONT" : "경상북도 울주군에 위치한 백운산은 열박산이라 부르기도 한다. 신라 김유신은 나이 17세 때 적군의 침공을 당하자 비장한 마음으로 혼자서 보검을 들고 열박산 깊은 골자기 속으로 들어가 향을 피우며 기를 모아 적을 물리칠수 있는 힘을 내려달라고 하늘에 빌었다는 이야기가 전해온다.산행 들머리는 언양에서 다개차리로 가는 버스를 타고 상차리에서 시작하면 된다. 백운산 정상은 대체로 칼등처럼 뾰족한 형상을 보이고 있다. 또한 바위군에 올라서서 바라보는 전망도 대단하다. 오른쪽은 옛날 기우제를 지냈던 아미산, 왼쪽에 문복산가지산, 남으로 고헌산, 북으로 삼강봉이 지척에 보인다.", + "MNTN_HG_VL" : "892", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", "MNTN_NM" : "백운산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 128.98400000000001, + "latitude" : 35.594999999999999 }, { "mountain" : { @@ -4559,16 +3499,6 @@ "longitude" : 126.6222222, "latitude" : 36.607777800000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "428", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시", - "MNTN_NM" : "백월산" - }, - "longitude" : 126.6222222, - "latitude" : 36.607777800000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -4576,8 +3506,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", "MNTN_NM" : "백이산" }, - "longitude" : 128.3497222, - "latitude" : 35.2347222 + "longitude" : 128.7102778, + "latitude" : 37.3011111 }, { "mountain" : { @@ -4609,26 +3539,6 @@ "longitude" : 128.4913889, "latitude" : 37.591111099999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;널찍하고 호젓한 주민들의 산책코스gt;조선 세조가 이곳을 지나다가 발(足)을 씻었는데 발이 희게 보였다하여 붙여진 이름이다. 자세한 연혁이나 사료가 없기 때문에 발을 씻은 장소가 정확히 어디인지는 분명치 않다. 산의 형상이 백가지 줄기로 뻗어나 마치 지네의 발과 같은 형상을 닮았다고 해서 지어진 이름 이라고도 알려져 있지만 경기도 이천의 백족산과 혼동해서 생긴 듯하다. 청주로 가는 32번 국도변에서 백족산의 둥그스름하고 펑퍼짐한 산세를 확인할 수 있는데 그 모습이 ‘순둥이’ 모양이라 지네의 모습과는 비슷하지 않다. 백족산은 널찍하고 평평한 능선, 울창한 소나무 숲으로 근교의 주민들에게 산책코스로 사랑받고 있다. 가파르지도 않거니와 정상부의 호젓한 산길이 하루 반나절, 운동 삼아 오르내리기에 부담 없기 때문이다. 백족산 정산 직전, 선두산으로 이어진 산길이 있다. 그 길을 따라가면 바로 금북정맥의 능선을 탈 수 있다. 산행이 심심하다면 선두산, 선도산을 거쳐 상당산성까지 종주산행도 가능하다.", - "MNTN_HG_VL" : "413", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 가덕면 한계리", - "MNTN_NM" : "백족산" - }, - "longitude" : 127.60416669999999, - "latitude" : 37.097222199999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백족산은 청원군 가덕면 상야리에 위치한 충청북도 자치연수원 뒤편에 우뚝솟은 산이 백족산이다.이산은 빼어나거나 절경을 이룬산은 아니지만 등산하기엔 좋은 편이라 산아래 교육원의 교육생들의 극기훈련장소로 많이 이용되고 있으며,가볍게 등산하기엔 좋은 산이다.", - "MNTN_HG_VL" : "402", - "MNTN_LOCPLC_REGION_NM" : "충북 청원군 낭성면 추정리", - "MNTN_NM" : "백족산" - }, - "longitude" : 127.60416669999999, - "latitude" : 37.097222199999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -4639,16 +3549,6 @@ "longitude" : 127.60416669999999, "latitude" : 37.097222199999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "413", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 가덕면 한계리", - "MNTN_NM" : "백족산" - }, - "longitude" : 127.60416669999999, - "latitude" : 37.097222199999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "영동군 학산면과 무주읍에 걸쳐 있는 백하산은 하얀 노을, 하얀 이내라는 뜻으로 노을이 아름다운 산이다. 백하산 줄기는 영동에서 학산을 거쳐 무주로 이어지는 19번 국도와 나란히 뻗쳐있어 차를 타고 가며 계속 그 모습을 올려다 볼 수 있다.백하산은 북쪽에서 보면 그저 거하고 짙푸른 산이지만 산에 들어서면 곳곳에 까마득한 바위 낭떠러지가 많다.동쪽 끝 여의재 남쪽에는 여의 저수지가 있으며 서쪽 끝 압재 북쪽에는 봉황저수지가 있다. 19번 국도가 백하산 아래를 지나 돌아가기 때문에 백하산 산행을 위한 교통은 편리한 편이다.백하산 아래의 안삼마을은 큰 길가 삼정마을의 일부로 산골짜기 안에 있는 삼정이라 해서 안삼이라 한다. 마을 들머리에는 명절 때 풍년과 마을의 무고를 기원하는 도랑제를 모시는 반신 석상이 있다.", @@ -4666,48 +3566,38 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 해제면 대사리", "MNTN_NM" : "백학산" }, - "longitude" : 128.0318188, - "latitude" : 36.3465907 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "화원읍 사무소에서 북쪽으로 긴 산이 보이는데 이를 뱀산이라 하고,서쪽으로 양반산, 그 중간에 고속도로때문에 일부만 남은 개구리산이 있다. 옛날에 뱀산의 뱀이 개구리산의 개구리를 잡아 먹으려고 고개를 내 뻗으니 뒤에 앉았던 양반산의 양반이\"예끼놈 그만 두어라\"고 무릎을 치며 호통을 쳤다. 호통에 놀란 뱀은 고개를 획하고 돌리고 있는 모양이다. 완만한 지형과 낮은 지세로 노약자분들에게도 쉽게 이용할 수 있는 산이다. 특별한 경관은 없지만 주변에 테니스장과 배수지 앞의 공원때문에 주변 주민들의 이용이 잦은 곳이다.", - "MNTN_HG_VL" : "91", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 구라리", - "MNTN_NM" : "뱀산" - }, - "longitude" : 127.6416667, - "latitude" : 37.026111100000001 + "longitude" : 126.26312969999999, + "latitude" : 35.1397324 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "840", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", - "MNTN_NM" : "번암산" + "DETAIL_INFO_DTCONT" : "포성봉(933m)은 충북 영동과 경북 상주의 경계에 위치하고 있는 산으로 바위가 많고 한폭의 그림과도 같은 빼어난 자연경관을 자랑하고 있는 산이다. 지도상에는 포성봉으로 되어있으나 인근지역주민들은 이 산을 백화산으로 부르고 있다.봄이면 철쭉이 능선마다 꽃띠를 두르고 있어 꽃산행도 겸할 수 있고, 여름에는 수풀과 옥류가, 가을에는 단풍이 정상에서 능선을 타고 석천골 반야사를 온통 붉게 물들인다. 정상에서는 쉴 만한 공터와 무덤이 한쪽에 있고 남쪽으로 석천을 내려다 보면 은빛 물결을 이루고 있으며 남서쪽으로는 주행봉이,주행봉 동편에는 분묘가 어림된다. 북으로는 속리산과 구병산이 남으로는 석천너머로 황악산과 덕유산이 그리고 서쪽으로는 서대산이 펼쳐진다.", + "MNTN_HG_VL" : "1063", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면, 경상북도 상주군 모동면", + "MNTN_NM" : "백화산" }, - "longitude" : 127.4731841, - "latitude" : 38.076925699999997 + "longitude" : 127.90472219999999, + "latitude" : 36.302222200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 삼척시 가곡면 덕풍마을을 기점으로 부채살처럼 패어든 골짜기가 4개 있다. 이 중 계곡이 가장 길고 깊은 용소골 최상단부에 응봉산(998.5m)이 솟아 있는데 응봉산에서 북서쪽으로 용소골과 보리골 사이로 가지를 쳐 나가는 지능선에서 보리골이 덕풍계곡에 합수되는 지점에 솟아 있는 626m봉이 바로 범바위봉이다.이 용소골 문턱에 자리잡고 있어 오는 사람마다 쭈르르 용소골 골짜기로 무작정 올라가는 바람에 범바위봉은 올라가는 사람들을 구경하기도 바쁘다. 그래서인지 산길도 흐릿하여 잘못하면 길을 잃고 헤매는 수가 많다. 여팔곡은 계곡과 능선이 거미줄 혹은 나뭇잎 줄기 같아 능선 하나를 잘못 고르면 몇 십리를 돌아야 한다. 이 과정에서 사고를 당하기 십상이다.", - "MNTN_HG_VL" : "626", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "범바위봉" + "DETAIL_INFO_DTCONT" : "태안읍 사무소 뒤에 우뚝 솟아있는 백화산은 전설에 많은 명산으로서 주민들의 사랑을 받고 있는 아름다운 산이다. 팔봉산(362m)에서 서쪽으로 가지를 내려 태안 읍내를 품에 안은 백화산은 284미터의 작고 아담한 산이다. 그러나 서해안 인근의 산들이 대부분 단순한 육산인 반면 백화산은 온갖 수석을 모아놓은 듯 기기묘묘한 바위가 서해 바다를 배경으로 펼쳐져 아름다운 풍광을 선사한다. 산에는 기암괴석들이 많고, 바위들과 소나무가 어우러져 있고, 특히 산 정상에서 바라보는 일몰은 최고의 경관이다.백화산에는 서해 낙조를 즐기기 안성맞춤인 전망대가 있다. 시야가 트여 서해 경치가 한눈에 들어와 산행의 피로를 말끔히 가시게 해주는 이곳은 이름도 낙조봉. 정상 남쪽에 자리한 낙조봉은 변산 낙조대의 일몰에 뒤지지 않을 아름다운 조망을 제공한다.태안읍 백화산 태을암 동편 30m지점의 거암에 부조된 삼존불상(1좌3신)으로 좌우여래 입상과 중앙에 보살입상을 배치 조각했는데 크기는 중앙보살입신상이 223cm이며, 좌우여래상은 306cm, 296cm 좌우를 크게 배치한 점이 특이하다. 굳게 다문 입술가는 오히려 미소를 머금고 두 어깨에 걸친 옷자락은 양팔에 걸쳐 평행곡선으로 길게 주름진 첨단이 삼각형으로 변형된 것은 고대에 즐겨 사용된 중국 육조시대양식과 흡사하다.이같은 조각 양식으로 보아 6세기초(백제시대)작품으로 추정되는 우리나라 마애삼존불의시초이며 백제 마애석불 미술의 발상지임을 말해주는 작품이다.", + "MNTN_HG_VL" : "284", + "MNTN_LOCPLC_REGION_NM" : "충청남도 태안군 태안읍", + "MNTN_NM" : "백화산" }, - "longitude" : 128.0192103, - "latitude" : 37.244361699999999 + "longitude" : 126.30255699999999, + "latitude" : 36.767481500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "범암산은 강원도 화천군 사내면 광덕리에 위치한 산이다. 일반적으로는 번암산으로 더 알려져 있지만 이것은 잘멋 전해진 이름으로, 옛날 범이 바위에 자주 오르는 것을 보고 붙인 이름이라는 것이 광덕리 주민들의 의견이다.아직은 널리 소개되지 않은 편이라 훼손되지 않은 모습을 많이 간직하고 있다. 봄이면 연분홍 철쭉의 화사함이, 여름 이면 하얀 산목련의 청초함이 그 아름다움을 더해주기도 한 다. 산새가 험하거나 그다지 높지 않은 편이어서, 가족산행 을 하기에는 안성맞춤이다.뾰족 솟은 정상에 오르면 멀리 화악산과 석룡산이 보이고 명지산,국망봉,도마치봉이 파노라마처럼 펼쳐진다. 아주 널따란 바위가 누워있는 것도 다른 곳에서는 볼 수 없는 진풍경이다.", - "MNTN_HG_VL" : "832", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", - "MNTN_NM" : "범암산" + "DETAIL_INFO_DTCONT" : "상주 백화산은 내륙 깊은 곳에 자리한 산답게 사계절 아무 때나 찾아도 산의 멋과 향과 느낌과 기운 그리고 깊은 적막감을 맘껏 누릴 수 있는 산 중 의 산이다. 맑은 물이 풍부하고, 산자락을 남동으로 휘감고 굽이치며 흐르는 석천(石川) 또한 아름답다.백화산이란 이름은 산 전체가 티없이 맑고 밝다는 뜻으로 봄이면 철쭉이 능선마다 꽃띠를 두르고 있어 꽃산행도 겸할 수 있다. 여름에는 수풀과 옥류가, 가을에는 단풍이 정상에서 능선을 타고 석천골 반야사를 온통 붉게 물들인다. 지도상에는 포성봉(捕城峰)으로 표기되어 있는데 한성봉(漢城峰)이 제 이름이다.산행들머리에 해당하는 두 곳에 보현사와 반야사라는 아담한 절집이 자리하고, 보현사 건너편 수봉리에는 조선 사학의 자존심 옥동서원(경북 기념물 제52호)과 더없이 아름다운 곳에 학처럼 자리한 정자 백옥정이 있어 볼거리 또한 풍성하다. 또 대궐터, 보문사터, 금돌산성 등 옛 호국의 유적들을 만나볼 수 있다.", + "MNTN_HG_VL" : "933", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 모서면, 모동면ㆍ충청북도 영동군 황간면", + "MNTN_NM" : "백화산(한성봉)" }, - "longitude" : 127.4731841, - "latitude" : 38.076925699999997 + "longitude" : 127.90472219999999, + "latitude" : 36.302222200000003 }, { "mountain" : { @@ -4719,16 +3609,6 @@ "longitude" : 128.4422836, "latitude" : 36.206698400000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "제천시 백운면은 원주시에 둘러싸이다시피 에워싸여 있는 지역이다. 지형상 백운산이 날개를 펼친 듯한, 더 정확히 말하면 바가지를 엎어놓은 듯한 모양을 하고있기 때문이다. 그래서 바가지속의 백운면은 육지의 고도같은 느낌을 강하게 준다.서쪽은 구학산(971m)에서 벼락바위봉(939m), 백운산(1087m), 십자봉(985m),이 둥그렇게 원을 그리다시피 장벽을 그리고 있는 데다 동서 두 가닥의 맥은 각각 남으로 다시 뻗어 원을 완성하다 시피 한다. 북쪽 가파른 계곡에는 치악산 자연휴양림이 조성되어 있다.산세는 전체적으로 부드러운 편이지만, 정상부는 바위 절벽으로 이루어졌기 때문에 치악산쪽 전망이 좋고 비로봉 등도 관망할 수 있다. 자연휴양림에서 정상으로 오르는 길에 칠성바위, 거북바위 등 기암괴석을 볼 수 있고, 지름이 50cm 되는 삼각형의 좁은 바위구멍이 있는 구멍바위(산파바위)를 볼 수 있다.", - "MNTN_HG_VL" : "939", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", - "MNTN_NM" : "벼락바위봉" - }, - "longitude" : 128.0192103, - "latitude" : 37.244361699999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "통영 최고봉이라는 수식어와는 달리 멀리서 본 벽방산(碧芳山)은 눈에 잘 띄지 않는 산이다. 남해안에서 흔히 마주치는 평범한 산세이기 때문이다. 그러나 겉에서 본 산과 막상 들어갔을 때 감흥이 틀린 것이 벽방산이다. 의상대사의 자취가 남은 고찰과 아늑한 골짜기, 시원한 전망의 암봉 등 어디하나 빠지지 않는 산이다.벽방산은 벽발산(碧鉢山)이라고도 부른다. 석가의 십대 제자 중 한 사람인 가섭존자(迦葉尊者)가 벽발(碧鉢 바리때)을 받쳐 들고 있는 모습과 닮아서 생긴 이름이다.정상은 상봉(上峰) 또는 칠성봉(七星峰)이라고도 부른다. 정상 부근에는 진달래가 많아 4월 중순이면 절정을 이룬다. 정상 조망은 다도해를 비롯해 부산 앞바다가 보이며, 맑은 날에는 대마도까지도 볼 수 있다. 안정치로 내려오면 대나무 밭에 이른다. 이곳이 만리암터이며, 이 위에 솟아 있는 절벽이 만리창벽이다.벽방산에서 빼놓을 수 없는 것이 안정사다. 신라 태종무열왕 원년(서기 654)에 원효대사가 창건하여 현재까지 1400여년 동안 이어오고 있는 고찰로 대웅전은 도문화재로 지정되어 있다. 안정사 부근은 조선 영조 때 사찰 주변의 적송을 보호하라는 어송패가 내려질 만큼 소나무들이 운치 있다.", @@ -4761,13 +3641,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산세의 수려함은 덕유산을 닮고 골짜기와 기암의 조화는 뭍명산 못지 않으니 이 산이 바로 경남 거창군에 거창읍에 자리한 별유산이다. 이 산은 우두산, 의상봉이라고도 불린다. 우두산은 일본 개국신화와 관련된 전설의 산이며 의상봉은 신라 문무왕 때 의상대사가 과거세와 현세에서 참선한 곳이라는 뜻에서 의상대사 이름을 빌려 산 이름으로 삼았으며, 속세를 떠나 별유천지비인간이라 할 만큼 경치가 빼어 난 돌부리 산이다. 그 중에서 의상대사가 참선하던 곳으로 알려진 의상봉, 처녀봉, 장군봉, 바리봉, 비계산 등이 빼어난 산세를 자랑한다.이 산은 당일 산행이 가능하며 원점으로 되돌아 올 수 있도록 등산로가 이어져 있는 것이 특징이다. 산 곳곳에는 볼거리가 산재해 있는데 그 중 고견사와 가정산 폭포, 최치원 선생이 심었다는 은행나무, 의상대사가 쌀을 얻었다는 쌀굴등이 있다. 고견사는 견암사에 뿌리를 두고 있는 절로 덕유산 지봉의 해인터에 이어 거창의 두 번째 해인터이다. 절을 지을 때 쌓아 올렸던 신라 때의 석축이 눈에 들고 고운 선생이 심었다 하는 은행나무와 만든 때가 새겨진 범종과 석불 의상대사가 수도할 때 두 사람분의 쌀이 나왔다 하는 쌀굴과 십이지신상석이 있다.산행과 더불어 역사와 경관을 맛볼 수 있다. 별유산 정상 남쪽턱밑 억새밭께에서 만나는 별유샘도 꼭 들러가야 할 코스 중에 하나이다. 별유산 산행 후 가조 온천에서 온천으로 피로를 풀 수 있어서 주말이면 등산객의 발길이 이어진다.", - "MNTN_HG_VL" : "1046", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", - "MNTN_NM" : "별유산" + "DETAIL_INFO_DTCONT" : "서해바다와 인접해 있는 변산은 호남평야를 사이에 두고 호남정맥줄기에서 떨어져 독립된 산군을 형성하고 있다. 이 산은 예로부터 능가산, 영주산, 봉래산이라 불리며 호남의 5대 명산중의 하나로 꼽혀왔다.1971년 도립공원으로 지정된 변산에는 기상봉, 망포대, 신선대, 쌍성봉, 옥녀봉, 세봉 등 400m 이상의 산이 6개 있고 계곡에는 와룡소, 가마소, 직소폭포, 성계폭포 등 장엄한 절경을 자랑하는 명소들이 산재해 있다. 이 밖에도 서해안 해식단애(海蝕斷崖)의 절경을 이루는 채석장을 비롯하여 우금바위와 산성, 굴바위, 빙봉 낙조대, 내소사, 월명암, 개암사 등 천태만상의 명소들이 진을 치고 있어 볼거리가 많은 곳이다.", + "MNTN_HG_VL" : "508", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면, 상서면, 진서면", + "MNTN_NM" : "변산" }, - "longitude" : 128.0437507, - "latitude" : 35.7519122 + "longitude" : 126.531389, + "latitude" : 35.680833 }, { "mountain" : { @@ -4789,6 +3669,26 @@ "longitude" : 128.6333333, "latitude" : 37.348888899999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "병풍산하면 병풍을 펼쳐 놓은 것처럼 산세가 빼어난 산이 아닌지 한번쯤 생각을 하게 된다. 병성산이라고도 불리운다. 그러나 이 산이 병풍산으로 이름 붙여진 것은 산 정상에 올라서면 시야가 탁트여 마치 병풍을 펼쳐 놓은 것처럼 주변을 감상할 수 있어서 그런 듯 하다.정상부에는 삼한시대 사벌국(沙伐國)이나 그 후계 세력인 상주 지역의 실체 파악에 주요한 단서가 되는 토석 혼축의 병풍산성(또는 아자개성)이 축조되어 있고, 산 곳곳에는 삼한시대 사벌국의 고분군(古墳群:경북기념물 125)이 널려 있다. 또한 넓은 들판과 상주 시내, 낙동강과 함께 국수봉·속리산·대야산·백화산·주흘산 등이 병풍처럼 펼쳐져 있다.", + "MNTN_HG_VL" : "366", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 동문동", + "MNTN_NM" : "병풍산" + }, + "longitude" : 128.22188180000001, + "latitude" : 36.423279399999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "796", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", + "MNTN_NM" : "병풍산" + }, + "longitude" : 127.81778920000001, + "latitude" : 38.079237399999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "담양의 명산인 병풍산은 담양군의 산 가운데 가장 높은 산으로 일명 용구산이라고도 한다. 담양군 수북면 소재지에서 이 산을 바라보면 왜 병풍산이라 했는지 쉽게 짐작할 수 있다. 오른쪽 투구봉을 시작으로 우뚝 솟은 옥녀봉, 중봉, 천자봉을 거쳐 정상인 깃대봉과 신선대까지 고르게 뻗은 산줄기는 한눈에 보아도 틀림없는 병풍이다.정상에서의 조망은 장관을 이루어 ‘강동8경’이라 한다. 북으로 내장산, 백암산, 입암산이 보이고 추월산, 담양읍내는 물론 지리산도 시야에 들어온다. 북동에서 남서쪽으로 길게 뻗은 병풍산은 등줄기 양옆으로 무수히 많은 작은 능선이 있는데 이 능선 사이에 일궈진 골짜기가 99개에 달한다.특히 한재골은 기암괴석과 푸른 송림 등 갖가지 수목이 울창하게 우거져 천혜의 경관을 자랑하고, 가을 단풍과 겨울 설경은 기이한 아름다움을 지니고 있다. 광주와 가까운 이곳은 매년 관광객이 증가하고 있어 야영지, 체육시설, 풀장, 조경시설 등을 갖추어 가고 있다.", @@ -4796,8 +3696,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 수북면, 월산면ㆍ장성군 북하면", "MNTN_NM" : "병풍산(용구산)" }, - "longitude" : 126.90273070000001, - "latitude" : 35.338191600000002 + "longitude" : 126.88611109999999, + "latitude" : 35.325000000000003 }, { "mountain" : { @@ -4809,6 +3709,16 @@ "longitude" : 127.6807002, "latitude" : 36.821610300000003 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 여주군 강천면, 남한강이 휘감아 도는 자리에 보금산이 솟아 있다. 그러나 이 산은 솟아 있다는 말 자체가 무색하리 만치 낮은 산으로 해발 400미터가 채 안되는 봉우리이다.섬강과 남한강이 산을 둘러싸고 흘러 경치가 아름답다. 높지는 않지만, 등산로 곳곳에 암릉이 많다. 보금산에서 가장 뛰어난 풍경은 정상 부근에 있는 기암이다. 가파른 절벽 위에 있는 기암으로, 마귀할멈 측간바위라고 부른다. 마치 치마 입은 여인이 턱을 두 손에 괴고 앉아 있는 모습처럼 보여 눈길을 끈다산행은 당고개에서 시작한다. 이 고개는 삿갓재라고도 부르는데, 옛날에는 산적이 많았다고 전한다. 그래서 50명이 모여서야 겨우 이 고개를 넘었다고 하여, 오십명고개라고 부르기도 한다. 주변에는 1993년 불교목공예가 박찬수가 설립한 목아불교박물관이 있다. 또, 북내면에는 남한강변에 자리한 신륵사가 있다. 신라 진평왕 때 원효대사가 창건하였다고 전하며, 보물로 지정된 문화재가 다수 있다.", + "MNTN_HG_VL" : "364", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면", + "MNTN_NM" : "보금산" + }, + "longitude" : 127.7236111, + "latitude" : 37.315277799999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -4819,6 +3729,16 @@ "longitude" : 127.4686111, "latitude" : 37.694722200000001 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "밀양군 상동면과 산외면의 경게에 있는 보두산은 비암골 동북쪽으로 솟아 있는 산봉우리로 옛날에 보담 노장이라는 천문지리에 능통한 감여가의 전설이 담긴 곳이다. 보담 노장은 옛날 중국 왕족이었는데, 나라에 죄를 지어 이곳 보두산에서 귀양살이를 하였다. 이 산에 산성을 쌓고 암자를 지어 평생을 고독하게 지내다가 생을 마감한 산이 바로 이 보두산이다. 보담산이라고도 한다.산은 높지 않지만 암벽타기와 산을 4개나 넘어면서 밀양들을 바라보는 재미가 있는 산이다.", + "MNTN_HG_VL" : "562", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 상동면", + "MNTN_NM" : "보두산" + }, + "longitude" : 128.8251827, + "latitude" : 35.544978800000003 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "보래봉은 강원도 평창군 봉평면 북쪽의 한 봉우리이다.\"\"메밀 꽃 필무렵\"\"의 이효석이 태어난 곳이고 이 소설의 무대가 바로 봉평면과 대화면이다. 진입로에 가로수가 없고 메밀을 심는다. 메밀꽃이 피는 여름에는 특히 물이 맑다.평창군은 해발 300-800미터 이상의 고랭지대로 이루어져 있는데 봉평면은 해발 600-800m의 고냉지대이다.이러한 봉평면 일원은 지대가 높고 추운 곳이어서 적설량이 풍부해 특히 겨울철산행을 즐기기에 좋은 산이다.부근에는 이효석의 동상과 소설에 관련된 곳들을 찾아볼 수 있다.", @@ -4839,16 +3759,6 @@ "longitude" : 127.78390539999999, "latitude" : 37.072415200000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "627", - "MNTN_LOCPLC_REGION_NM" : "경기도가평군", - "MNTN_NM" : "보리산" - }, - "longitude" : 127.5373706, - "latitude" : 37.669107500000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "보문산은 대전시 남쪽 중심부에 근접해 있어 대전시민들에게는 매우 친근한 휴식처이다. 이 산에는 보문산성, 보문사지, 야외음악당, 전망대 유희시설, 케이블카가 있으며 시루봉길 등 10여개의 등산로와 20여개소의 약수터가 있다. 특히, 보문산성은 시 기념물 제 10호로 1991년 12월 백제산성중 최초로 복원되었다.정상에 있는 장대루에 오르면 광활한 대전 시가지의 발전상을 한 눈에 볼 수 있는 곳이다. 본래 이 산은 보물이 많다하여 보물산이라 부르다가 후에 보문산으로 고쳐 부르게 되었다거나, 나무꾼이 죽어가는 물고기를 살려줘서 얻은 '은혜를 갚는 보물주머니'에서 이름이 유래되었다는 전설도 전해진다. 보문산 녹음(綠陰)은 대전팔경의 하나로 꼽힌다.대전광역시의 대표적인 녹음공원이자 도시자연공원으로,사정공원지구에는 스포츠와 피크닉을 위한 넓은 잔디광장과 체육시설 등이 조성되어 있다. 평일 2천명, 성수기에는 1일 평균 2만여명이 즐겨 찾는 4계절 행락지이다.", @@ -4861,13 +3771,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남쪽을 보면 무안읍과 남산이 보이고 서쪽을 보면 서해안의 바다가 한눈에 보이면서 우리 마음을 시원하게 해준다. 동쪽으로 보면 무안읍 용월리 학마을이 보인다. 왜가리 서식지로 보평산 정상에서 보면 작은산이 온통 하얗게 보일정도로 왜가리들이 옹기 종기 보여있어서 실로 눈이 내린듯 착각을 일으키게한다. 비록 큰 산은 자연만큼은 어디빠지지 않는다. 해마다 3~4월이면 동남아 지역에서 월동한 백로와 왜가리 4천여수가 이 곳을 찾아와 집단을 이루어 번식하고, 10월이면 다시 남하 이동해 가곤한다.보평산 줄기의 청용산 아래 조성된 작은 인공섬과 한가롭게 노는 백로.왜가리의 모습이 어우러져 더욱 신비를 자아낸다.", - "MNTN_HG_VL" : "225", - "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 무안읍 고절리, 용월리", - "MNTN_NM" : "보평산" + "DETAIL_INFO_DTCONT" : "충북 괴산군에 위치한 보배산은 사람들의 발길이 닿지 않는 산으로 자연의 청정함이 그대로 살아 있다. 특히 쌍곡계곡은 소금강이라 불릴 만큼 경치가 아름다워 한폭의 동양화를 연상케 한다. 계곡을 따라 군데군데 펼쳐지는 바위와 암릉의 조화, 그 위를 흐르는 맑은 물, 단풍이라도 든다면 그야말로 가을의 운치가 물씬 묻어나는 곳이다.보배산 청석골 골짜기에는 충청북도에서 가장 오래된 사찰 각연사가 있다. 각연사는 신라 법흥왕(514~539) 때 유일대사가 창건했다. 경내에는 석조비로자나불좌상(보물 제433호), 통일대사탑비(유형문화재 제2호), 비로전(유형문화재 제123호), 대웅전(유형문화재 제126호), 그리고 대웅전 앞마당을 뒤덮은 밑둥 둘레가 두 아름이 넘는 보리수나무 등 볼거리가 많다.", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면 태성리", + "MNTN_NM" : "보배산" }, - "longitude" : 126.86602689999999, - "latitude" : 37.886687999999999 + "longitude" : 127.91666669999999, + "latitude" : 36.75 }, { "mountain" : { @@ -4921,13 +3831,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "소가 누워있는 형상의 산이라고 해서 이름지워진 복우산(伏牛山)은 낙동면 신오리와 구미시 옥성면 산초리와 옥관리에 걸쳐있는 하나의 육산이다.산행은 낙동면 신오리 아랫마을에서 시작하게 된다. 단점은 마을에 주차할 수 있는 공간이 없기 때문에 용포초등학교 주변에 차량을 주차시켜야 한다. 구미 지역에서는 태조산과 더불어 산행 코스로도 즐겨 이용되는데, 특히 대둔사를 거쳐 내려가는 하행길이 많이 알려져 있다. 이 대둔사가 자리한 복우산(伏牛山) 인근은 좋은 돌이 많아 채석이 많이 이루어진다고 하는데 이 때문에 환경파괴 논란이 일어나고 있다고 한다.", - "MNTN_HG_VL" : "509", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 옥성면 산촌리", - "MNTN_NM" : "복우산" + "DETAIL_INFO_DTCONT" : "복두산은 강원도 삼척시 가곡면에 숨어 있는 오지의 산이다. 이 산은 북으로 육백산과 매봉산, 동쪽으로 치바위산, 남쪽으로 면산, 서쪽으로 백병산이 둥그렇게 에워싸고 있는 곳으로 열매로 치면 두터운 껍질에 쌓인 알맹이 부위라 할 수 있다.그래서 옛날 이 마을 사람들은 이 산을 복동아리산이라 하였다. 산 아랫마을 이름은 동활리인데 이것은 복두산에서 기인한 것으로 본래 `복동아리' 또는 `도화리(桃花里)라 불리던 곳이 와전된 것이다.촛대처럼 뾰족한 기이한 바위 등 군데군데 암봉이 많다. 등산로는 다소 험하며, 복두천은 여름철 피서지로 각광받고 있는 곳으로 휴가철에는 마을에서 입장료를 받고 계곡을 관리하고 있다.", + "MNTN_HG_VL" : "978", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "복두산" }, - "longitude" : 128.62463700000001, - "latitude" : 35.866298 + "longitude" : 129.1268848, + "latitude" : 37.162401899999999 }, { "mountain" : { @@ -4946,18 +3856,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군", "MNTN_NM" : "봉대산" }, - "longitude" : 126.8475, - "latitude" : 37.605555600000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "봉두산에 자리잡은 태안사 현판에는 이 산의 이름이 `동리산'으로 써 있다. 여기에는 다음과 같은 유래가 전해온다. 봉황이 서식하는 나무가 오동나무인데 태안사를 둘러싼 주변 형세가 그 오동나무 속처럼 아늑하다해서 동리산으로 불렸다고 한다. 그러나 그 이름이 언제 바뀌었는지는 알 수 없지만 두 이름에 연관이 아주 없는 것은 아니다.봉황이 서식하는 나무가 오동나무이고 태안사가 자리잡은 곳을 둘러싼 주변 산세가 오동나무 줄기 속처럼 아늑해서 동리산이라 불렀으며 둘러싼 주변산세의 최고점을 봉황의 머리 즉 봉두산 이라 부른다. 태안사는 신라 경덕왕 때 창건되었으며, 대안사 광자대사비(보물 275)·대안사 광자대사탑(보물 274) 등이 있다.봉두산 주변에는 곡성 특유의 내륙산지를 이루고 있어 정상에 올라서면 순천쪽 황학리의 작은 들판을 제외하고 주변 조망이 온통 산 뿐이다. 남서쪽으로 삼산과 희아산 능선 넘어로 모후산이 오똑하고 북서쪽으로는 통명산 넘어 무등산까지 시야가 트인다. 동쪽으로는 둥주리봉과 자라봉, 그리고 지리산이 장막을 치고 있다. 이러한 내륙산지 조망이 산행의 맛으로는 제일이지만 봉두산은 태안사 여행에 초점을 맞추어도 좋은 산이다.", - "MNTN_HG_VL" : "753", - "MNTN_LOCPLC_REGION_NM" : "전라남도 곡성군", - "MNTN_NM" : "봉두산" - }, - "longitude" : 127.3996327, - "latitude" : 35.159860199999997 + "longitude" : 126.2736111, + "latitude" : 35.119166700000001 }, { "mountain" : { @@ -4966,8 +3866,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", "MNTN_NM" : "봉래산" }, - "longitude" : 129.0552017, - "latitude" : 35.081954600000003 + "longitude" : 128.4858619, + "latitude" : 37.197774199999998 }, { "mountain" : { @@ -4989,16 +3889,6 @@ "longitude" : 128.1427698, "latitude" : 36.720131100000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "용문산(1157m) 북쪽 능선을 따라 10킬로미터 떨어진 곳에 솟은 봉미산은 경기도에서도 오지로 꼽히는 양평군 단월면 산음리에 있다. 산골마을의 정취가 물씬 풍기는 산음(山陰)리는 용문산의 그늘에 묻혀 음지가 된다고 이름 붙었다.정상 남쪽 능선에 작은 분지가 있어 ‘늪산’이라고 불리는 봉미산(856m)은 경기도 가평군 설악면과 단월면의 경계를 이루는 산이다.용문산을 비롯한 유명산(862m), 중미산(834m)으로 이어지는 산줄기가 한눈에 들어오고, 북으로는 홍천강에 발치를 담그는 장락산(627m) 줄기가 당차게 뻗어간다. 동으로도 매봉산(650m) 자락의 대명스키장이 훤히 보일만큼 조망이 좋다.", - "MNTN_HG_VL" : "856", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 단월면ㆍ설악면", - "MNTN_NM" : "봉미산" - }, - "longitude" : 127.5697222, - "latitude" : 37.6136111 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강원도 횡성군 청일면과 홍천군 서석면의 경계를 이루는 봉복산은 남한강의 지류인 섬강의 발원지로 깨끗한 계곡과 풍부한 수량을 자랑하고 있다. 이 산은 산세가 봉황을 닮아서 '봉복산'이라고 불리우며, 산 뒤쪽에 봉복샘이 있는데 여기서 흐르는 물이 섬강을 이루는 근원이다. 산이 높은 만큼 골짜기가 깊지만 나무들이 많아 산세가 그렇게 험하지 않다. 맑고 깨끗한 물도 충분해서 좋은 산의 면모를 그대로 갖춘 산이다.봄에는 두릅, 산나물 등이 많이 나고, 여름철에는 소(沼)와 담(潭)이 많아서 시원함을 느낄 수 있다. 산이 높고 나무가 많아서 가을에는 낙엽이나 단풍도 가득하다. 단풍철만 되면 한꺼번에 몰리는 인파를 피해, 한적한 곳에서 여유롭게 단풍산행을 즐기기에 적합한 산이다. 호젓한 산길을 따라 흐르는 계곡이 너무나 맑고 깨끗하기에 기분이 무척 상쾌하기만 하다. 하얀 포말을 일으키며 쏟아지는 작은 폭포가 나타나는가 했더니 조금 더 오르면 시원한 숲그늘 속에 쉬어가기 좋은 반석을 이룬 곳들도 즐비하다. 꼭 신선놀음하는 분위기가 연이어지는 것이다.봉복산의 정상에서 내려다보는 경관은 그야말로 일품이다. 사방으로 막힘이 없이 시원하게 펼쳐져 있는 경치를 관망할 수 있다.", @@ -5009,26 +3899,6 @@ "longitude" : 128.2163889, "latitude" : 37.620277799999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "봉수산은 아산시와 예산군의 경계에 위치하며 산세가 봉황의 머리를 닮아 봉수산이라 불리우고 있으며 경기 안성의 칠장산에서 태안반도 안흥진까지 연결되는 약 280km의 금북정맥의 줄기로 아산시는 광덕산을 거처 봉수산을 지나 예산의 천방산으로 진행되며 오서산과 가야산으로 이어진다.", - "MNTN_HG_VL" : "535", - "MNTN_LOCPLC_REGION_NM" : "충청남도 아산시 송악면 유곡리,송학리,강장리", - "MNTN_NM" : "봉수산" - }, - "longitude" : 126.7814735, - "latitude" : 36.597659499999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 예산군 대술면과 공주시 유구면 및 아산시 송악면에 걸쳐 있다. 39번 도로를 사이에 두고 광덕산과 동서로 광덕산과 마주하고 있다.산세가 봉황의 머리를 닮아서 봉수산이라고 부른다고 하는데, 현재 산의 모습에서는 찾아볼 수 없다. 산도 높지 않고, 코스도 단순하여 나들이 겸 등산 코스로 좋다. 온천 산행지로도 더없이 좋은 산이다.산기슭에는 887년(진성여왕 1)에 도선국사가 창건한 봉곡사(鳳谷寺)가 있다. 임진왜란 때 소실된 것을 1647년(인조 24)에 중창하였다. 현재 대웅전, 향각전, 삼성각, 요사 등의 건물이 있으며, 대웅전과 그 옆에 있는 고방(庫房)이 함께 충청남도 문화재 자료 제323호로 지정되어 있고 대웅전 지장탱화는 충청남도 문화재 자료 제242호로 지정되어 있다. 봉곡사 진입로에는 수백년 된 노송 군락이 운치를 더하고 있다.이 산의 능선에는 명소 베틀바위가 있는데 족히 사오십명은 올라설 수 있을 정도로 크고, 전망이 뛰어나고 주변에도 바위들이 많아 가기에 좋은 곳이다.", - "MNTN_HG_VL" : "570", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 대술면, 아산송악", - "MNTN_NM" : "봉수산" - }, - "longitude" : 126.7814735, - "latitude" : 36.597659499999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -5036,18 +3906,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", "MNTN_NM" : "봉수산" }, - "longitude" : 126.7814735, - "latitude" : 36.597659499999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "이 땅의 뼈대인 백두대간의 허리에서 갈린 금북정맥이 천안, 청양을 거치면서 대천 앞 서해에 그 발을 담그기 전에 솟구친 여러 봉우리 중 하나가 봉수산이다. 봉황의 머리를 닮았다고 해서 봉수산이라 이름 붙은 이 산을 대흥면 사람들은 ‘대흥산’이라 부른다. 정상부에 2.4킬로미터 길이의 성곽 ‘임존성’을 두른 봉수산은 백제 재건을 꿈꾸던 이들의 마지막 꿈이 영글던 산이다. 옛날 초등학교 교과서에 실렸던 ‘의 좋은 형제’ 이야기의 실화가 봉수산 자락의 대흥에 남아 있는 유서 깊은 곳으로, 산성 안의 산마루에는 억새가 많이 자라 가을 정취가 물씬 배어나는 곳이다. 임존성 안 넓은 억새밭에는 ‘백제 임존성 청수’라 적힌 비가 선 샘이 있다. 봄이면 성곽 주변으로 만발하는 진달래가 장관을 이룬다.", - "MNTN_HG_VL" : "483", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 대흥면, 광시면ㆍ홍성군 금마면", - "MNTN_NM" : "봉수산" - }, - "longitude" : 126.7814735, - "latitude" : 36.597659499999999 + "longitude" : 128.7333333, + "latitude" : 36.733333299999998 }, { "mountain" : { @@ -5056,8 +3916,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 삼향면 왕산리", "MNTN_NM" : "봉수산" }, - "longitude" : 126.7814735, - "latitude" : 36.597659499999999 + "longitude" : 126.4154277, + "latitude" : 34.856907499999998 }, { "mountain" : { @@ -5096,8 +3956,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면 원통리", "MNTN_NM" : "봉화봉" }, - "longitude" : 129.09805560000001, - "latitude" : 36.146666699999997 + "longitude" : 128.22194440000001, + "latitude" : 38.138055600000001 }, { "mountain" : { @@ -5106,8 +3966,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.6119444, + "latitude" : 34.652500000000003 }, { "mountain" : { @@ -5116,8 +3976,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.6084018, + "latitude" : 37.7829087 }, { "mountain" : { @@ -5126,8 +3986,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 천천면, 계남면", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.5485212, + "latitude" : 35.701548299999999 }, { "mountain" : { @@ -5136,58 +3996,78 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.8758333, + "latitude" : 37.708888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천재산의 천제봉은 개도리 화산마을에 있는 정상이 해발 332(기존338)m로 화산마을과, 호령, 신흥마을을 지나서 정상에 오르면 다도해의 아름다운 장관을 한눈에 바라볼 수 있다.현 천제산(화개산)은 일명 천제봉(天祭峯)으로 불리고 있는데 돌산군지에는 일명 천조봉이라 적혀져 있으나 이는 오기이다. 삼월삼짓날 전야에 천조봉(天朝峯) 정상에 있는 제단에서 하늘의\"천제신\"에게 제를 올리는 산으로써 영산으로 알려지고 있으며, 옆으로는 봉화산이 솟아있어 두산의 봉우리가 마치 말의 귀와같이 쫑긋 솟아 있으며, 주위로는 높고 얕은 산들이 병풍을 펼쳐 둘러쌓은 것처럼 마을을 빙 둘러고 있다. 풍수지리설에 의하면 지맥을 통한 산세가 부락을 옹호하여 감싸고 덮어주는 정기가 있다해서 섬의 이름을 덮을 개(蓋)자를 붙여 개도(蓋島)라 이름지어 불렀다고 한다", - "MNTN_HG_VL" : "334", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 화정면 개도리", + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "355", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 용당동,조례동", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.5166667, + "latitude" : 34.966666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "355", - "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 용당동,조례동", + "DETAIL_INFO_DTCONT" : "부용산(882m)에서 남쪽으로 능선이 뻗어 있는데, 이 능선상에서 가장 높은 봉우리이다. 부용산 외에 오봉산(779m)과도 능선이 이어져 있어, 종주 등반도 가능하다. 산의 북쪽을 제외하고는 소양호로 둘러싸여 있어, 정상에서의 조망이 시원하고 아름답다.청평사 선착장에서 서쪽길은 청평사로 이어지고 동쪽길 따라 작은 고개를 넘어가면 청평골 입구에 농막집이 있다. 농막에서 계곡 왼쪽 길을 따라 올라가서 계곡이 갈라지기 직전에 왼쪽길 따라 들어가면 동굴이 있는 기도터에 닿게 된다. 계곡을 건너서는 조금 가파른 길을 거쳐 하우고개에 이르게 된다. 하우고개 십자로에서 남쪽 길로 들어가면 봉화산에 오르게 되는데 이 길은 사람이 별로 다니지 않는 완만한 능선에 억새와 칡넝쿨이 무성하여 길바닥이 보이지 않는 상태이다.", + "MNTN_HG_VL" : "734", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.8413889, + "latitude" : 37.967222199999988 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "692", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 강서구 녹산동", + "MNTN_HG_VL" : "476", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", "MNTN_NM" : "봉화산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.1086111, + "latitude" : 34.732777800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부용산(882m)에서 남쪽으로 능선이 뻗어 있는데, 이 능선상에서 가장 높은 봉우리이다. 부용산 외에 오봉산(779m)과도 능선이 이어져 있어, 종주 등반도 가능하다. 산의 북쪽을 제외하고는 소양호로 둘러싸여 있어, 정상에서의 조망이 시원하고 아름답다.청평사 선착장에서 서쪽길은 청평사로 이어지고 동쪽길 따라 작은 고개를 넘어가면 청평골 입구에 농막집이 있다. 농막에서 계곡 왼쪽 길을 따라 올라가서 계곡이 갈라지기 직전에 왼쪽길 따라 들어가면 동굴이 있는 기도터에 닿게 된다. 계곡을 건너서는 조금 가파른 길을 거쳐 하우고개에 이르게 된다. 하우고개 십자로에서 남쪽 길로 들어가면 봉화산에 오르게 되는데 이 길은 사람이 별로 다니지 않는 완만한 능선에 억새와 칡넝쿨이 무성하여 길바닥이 보이지 않는 상태이다.", - "MNTN_HG_VL" : "734", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "예부터 흥양골에 군자가 많이 나서 봉황새가 날아와 보금자리를 잡았다 하여 봉황산이라 부르며선인들은 봉황을 군자의 새라 하였다. 일제 말기에 송탄유를 만들기 위해 많은 충송을 베어내어지금은 얼마 남지않았다.산세가 완만하고 코스가 적당(50분)하며 고흥읍 유민의 아침, 저녁 주 산책로이며 정상에서고흥 시가지가 한 눈에 보이며,숲의 주요 수종은 수령 50~60년생의 소나무로 천연보육림 상태로 숲이 잘 발달 되어 있다.", + "MNTN_HG_VL" : "199", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 고흥읍 남계리", + "MNTN_NM" : "봉황산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 127.2850741, + "latitude" : 34.603868599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉황산(鳳凰山)은 중화지구 화령(化寧) 북쪽에 우뚝 솟아있는 대간상의 산이다. 1300여년 전 봉황새가 이 산에 날아들어 30여년 정도 살았다는 전설에서 유래했다 한다.인근에서는 “정상을 봉황머리처럼 원만하게 빼어 올리고 좌우 양 날개를 길게 펼친 형국이 봉황새 같아서” 라고도 한다. 화령은 행정구역상 화서면이라 부르지만 지역 사람들에게는 화령으로 더 알려져 있다. 옛날 화령현 소재지였던 까닭이다. 그 당시 무사들이 살았다는 무동(武洞), 현감이 살았다는 상현(上縣), 관곡(官穀)을 보관했던 창고가 있었던 창안 등의 지명이 지금도 남아있다.", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "상주시 화서면 신봉리 상현리, 상곡리 화송리\/화남면 동관리", + "MNTN_NM" : "봉황산" + }, + "longitude" : 127.9403798, + "latitude" : 36.463463900000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "봉황산은 경북 영주와 봉화군의 경계를 이루는 산이다. 산의 모양이 봉황을 닮았다고 해서 봉황산이라 불리는 이 산은 태백산(1567m)을 거친 백두대간이 소백산(1439m)으로 뻗어 내리다가 중간에 위치한 선달산에서 남쪽으로 가지친 지맥 선상에 자리하고 있다.사람들에게는 별로 알려지지 못한 산이지만 산자락에 자리잡은 부석사는 매우 유명하다. 부석사 무량수전은 한국에서 가장 오래된 목조건물이며, 국보 제18호로 지정되어 있다. 이 외에도 석탑, 석종 등 보물이 많고, 규모가 웅장해서 이 절을 찾는 관광객이 많다 부석사만 둘러보고 가는 관광객이 많아 한적한 산행을 즐길 수 있다. 특히 소백산 도립공원에 속해 있으면서도 주변의 영봉들에 가려 그 진가가 제대로 알려지지 않았지만 그만큼 사람들의 발길을 덜타 깨끗하고 아름다운 자연미를 그대로 간직하고 있다.부석사 무량수전 뒤편의 오솔길을 따라 능선에 오르면 정상까지 이를 수 있다. 정상까지의 길은 울창한 소나무 숲과 진달래가 군락을 이룬 숲길이 등산의 피곤함을 잊게 해준다.", + "MNTN_HG_VL" : "259", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 부석면, 봉화군 물야면", + "MNTN_NM" : "봉황산" + }, + "longitude" : 128.6937088, + "latitude" : 37.004579300000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "476", - "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", - "MNTN_NM" : "봉화산" + "MNTN_HG_VL" : "149", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "봉황산" }, - "longitude" : 127.08694439999999, - "latitude" : 37.608333299999998 + "longitude" : 126.6080556, + "latitude" : 36.376666700000001 }, { "mountain" : { @@ -5219,16 +4099,6 @@ "longitude" : 127.410287, "latitude" : 36.634100400000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "문경 북동쪽에 와서 수려한 산들을 떨궈놓은 백두대간이 속리산으로 내려가기 전, 문경의 진산 주흘산의 북서쪽에 바위벽으로 우뚝 솟게 한 산이 바로 부봉이다.비슷비슷한 암벽 봉우리로 모인 산인 부봉은 크고작은 나무와 아기자기한 암벽이 한데 어우러진 등산로로 인하여 많은 등산객들이 즐겨찾는 산이며 새재도립공원을 한눈에 내려다 볼 수 있는 조망이 아주 좋은 산으로 단풍이 가득한 가을산이 제일 아름다운 곳이다.", - "MNTN_HG_VL" : "913", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", - "MNTN_NM" : "부봉" - }, - "longitude" : 128.096397, - "latitude" : 36.768441000000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "부암산(傅岩山)은 스승 부(傅)자를 쓰며 일명 스승바위산이라고도 하는데 사실 부암산 자락은 너무 많은 역사를 간직한 산이다. 악(岳, 嶽)이나 암(岩)자가 들어가는 산은 거의 바위산인데 이 곳 역시 예외는 아니다. 부암산은 멀리서 쳐다보아도 암반 투성이고 정상에서 주위를 둘러보아도 역시나 북쪽 산들은 모두 바위산이다. 거대한 바위들이 누룩이 포개져 있는 것처럼 층층이 포개져 있다.한적한 마을 뒤에 있으면서도 그 산세가 빼어나다. 가까이 있으면서 소문이 자자한 황매산과 모산재에 조금도 뒤지지 않는 멋진 산이다. 산길로 들어서면 우람한 낙락장송이 산을 채우며 잔가지가 많은 소나무들이 마치 담 하나를 사이에 둔 이웃처럼 함께 어울려 골짜기를 메웠다. 특히 단계천 가운데 자리잡고 있는 기암이라는 바위는 그 풍채가 당당하면서도 멋스럽다. 바위에는 많은 구멍이 뚫려있는데 옛날에 일산을 꽂았던 자리이다. 단계현 시절에 놀이가 있을 때에 이곳에서 풍악을 울리고 기생을 불러서 놀이를 하던 곳으로 전한다.", @@ -5246,8 +4116,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍 성산리", "MNTN_NM" : "부용산" }, - "longitude" : 127.0988696, - "latitude" : 37.733488800000003 + "longitude" : 126.8758333, + "latitude" : 34.593333299999998 }, { "mountain" : { @@ -5256,28 +4126,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", "MNTN_NM" : "부용산" }, - "longitude" : 127.0988696, - "latitude" : 37.733488800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충청북도 음성의 가섭산의 바로 옆에 있는 산으로 능선산행지로 최적인 곳이다. 음성에서 시작하여 약 8km정도 되는 주능선은 능선산행에 적합하다. 음성시내에서 부용산을 거쳐 금왕시내까지 도보로 이동할 경우 약 13-14km정도의 거리로 능선종주의 맛을 느낄 수 있는 산이다.산행 초입은 음성읍 용산리 저수지 좌측에 있는 궁도장인데, 이곳에는 50여대를 주차할 수 있는 주차장과 큰 산행안내판이 세워져 있다. 산행의 끝은 부용산 서쪽 금석저수지인데 댐 아래 도로변에 산행안내판이 세워져있다. 부용산은 산행안내판이 비교적 잘 세워져있고 등산로 상태도 걷기에 좋다. 정상에는 산행기록을 남기는 등산일지를 저장하는 철제박스가 놓여있어 이 산만의 특징으로 부각되고 있다.", - "MNTN_HG_VL" : "644", - "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 음성읍, 금왕읍", - "MNTN_NM" : "부용산" - }, - "longitude" : 127.0988696, - "latitude" : 37.733488800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "159", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시", - "MNTN_NM" : "부주산" - }, - "longitude" : 126.4434815, - "latitude" : 34.817745899999998 + "longitude" : 127.82734619999999, + "latitude" : 38.000608399999997 }, { "mountain" : { @@ -5289,16 +4139,6 @@ "longitude" : 126.4427778, "latitude" : 34.806111100000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "북바위산은 월악산국립공원권내에 자리한 아기자기한 산으로, 행정구역상으로는 충북 충주시 상모면과 제천시 한수면의 경계를 이루고 있다, 산 이름이 북바위산인 까닭은 이 산 자락에 타악기인 북을 닮은 거대한 바위가 있어 붙여진 이름이다. 북바위산은 월악산 국립공원내에 월악산에서 남쪽 만수봉까지 이어지는 암릉서쪽에 송계계곡이 자리하고 있는데 송계계곡 중간쯤인 팔랑소에 비록 높지는 않으나 기암절벽을 거느리고 있어 아기자기한 스릴을 느끼면서 산행할 수 있는 산이다.이 산의 특징은 송계계곡으로 이어지는 능선남면이 온통 바위암반으로 슬랩을 형성하고 있으며 아름드리 적송들이 등산로를 에워싸고 있어 그 경관이 매우 아름답다. 송계계곡 중간쯤인 팔랑소와 와룡소에서 서쪽으로 솟아 있는 북바위산 암릉에서는 송계계곡을 사이에 두고 동쪽 방향 월악산(1,094m) 남릉이 마주보인다. 그리고 남릉에서 송계계곡 방면으로 가지쳐 나온 덕주봉(893m)과 용암봉(892m) 암릉미도 만끽할 수 있다. 여기에다 북쪽 동산계곡 건너인 말미봉(687.3m)과 남동쪽 사시리계곡 건너 박쥐봉(782.1m) 바위지대도 감상할 수 있는 천혜의 암릉코스로 사계절 인기 있다.", - "MNTN_HG_VL" : "772", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면, 제천시 한수면", - "MNTN_NM" : "북바위산" - }, - "longitude" : 128.08618809999999, - "latitude" : 36.855391500000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "북배산은 고향집 바로 뒤에 솟아 있는 산처럼 향수를 자아내게 하는 산으로 크게 빼어나지도 웅장하지도 않지만 수수한 매무새의 시골 아낙 같은 자태를 하고 있다. 가덕산(858m)과 계관산(710m)으로 이어지는 능선에 위치하며 청정지역에 있는 산답게 깨끗하고 고즈넉한 산이다. 주능선은 산불을 대비해 폭 10미터 정도에 방화선이 형성되어 있으며, 이 방화산으로 능선 모두가 시원스레 조망되며 특히 눈 내린 후 가덕산에서 계관산까지 이어지는 경치는 이색적인 분위기를 느끼게 해준다.북배산은 수도권 등산인들에게 혼잡함을 피할 수 있는 당일치기 코스로 제격이다. 북배산 코스는 대개 목동2리 맴내~작은멱골을 경유하거나 또는 싸리재(마을)~싸리재고개를 경유해 정상을 다녀오는 것이다.정상에서 바라보는 조망은 막힘이 없다. 먼저 북서쪽으로는 북배산의 모산인 화악산이 하늘금을 이루고, 그 오른쪽으로는 북배산을 향해 세차게 흘러나오는 응봉, 촛대봉, 몽덕산, 가덕산 줄기가 연이어져 시야에 들어온다.동쪽으로는 병풍을 두른 듯한 대룡산 아래로 평화로운 춘천시내와 의암호가 펼쳐진다. 춘천남쪽으로 펼쳐지는 조망도 일품이다. 가장 멀리로 용문산이 하늘금을 이루고 그 아래 좌우로는 도명산, 대명스키장 슬로프, 장락산, 소리산 등이 넘실대는 파도처럼 광활하게 시야에 들어온다. 서쪽으로는 구나무산, 명지산, 월출산, 수덕산이 마주보이고, 구나무산 왼쪽 아래로 자리한 가평읍과 북한강이, 수덕산 아래로는 목동분지가 내려다보인다.", @@ -5321,23 +4161,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "북성산은 거리가 그리 길지 않고 경사도 완만하여 가족과 함께 산책하기에 좋은 산으로많은 사람들이 찾고 있다. 농로의 끝에서 시작되는 작은 소로길을 따라 1㎞ 올라가다보면 마치 쉬어가라고 만들어 놓은 듯 약수터와 벤치가 놓여져 있다.이곳에서 조금 더 올라가면 정상이지만 실제 정상은 정상 바로 아래지점이다.실제 정상은 지뢰 밭으로 출입금지 하였기에 이곳에 정상을 만들어 놓은 듯 하다.", - "MNTN_HG_VL" : "259", - "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 여주읍", - "MNTN_NM" : "북성산" - }, - "longitude" : 127.5958333, - "latitude" : 37.286388899999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "밀양시 산내면 등지의 산을 찾는 산악동호인들에겐 수리봉으로 더 잘 알려진 북암산은 지금까지 산길이 없어 산행이 불가능한 곳으로 생각해 왔었다. 능선길에 암벽이 버티고 있어 가파른 산행에 곳곳에 너덜이 자리해 자칫 잘못하다간 사고를 당하기 십상이다.북암산은 가인 3리 봉의저수지 아래 인골 산장에 도착하여 산장 우측 밭 오른편 길에서 산행이 시작된다. 정상으로 올라가는 길은 급경사지역이기 때문에 힘이 든다. 북암산 정상에는 정상 표지석 대신으로 누군가 돌탑을 쌓아 놓았다. 그리고 그 앞에 문바위가 우뚝 앞을 가로막고 있어 앞으로 다시 한번 더 고비를 넘겨야 한다.", - "MNTN_HG_VL" : "807", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", - "MNTN_NM" : "북암산" + "DETAIL_INFO_DTCONT" : "북악산은 서울의 주산으로 경복궁 뒤쪽에 위치하고 남산과 대칭하여 북쪽에 있다하여 북악이며 일명 백악, 면악, 공극산으로도 불리고 있다.북악산길이 시작되는acirc;의문 일대의 부암동은 서울에서는 보기 드문 산촌 같은 마을이다. 백석동otilde;으로 이어지는 산길, 백사실계곡 등 때 묻지 않은 자연을 그대로 간직하고 있다. 곳곳에 문화유적과 미술관, 독특한 인테리어의 음식점 등 볼거리도 널려 있어 출사지로 꼭 한 번씩은atilde;는 명소다.부암동에서 출발하는 북악산 산aring;길은acirc;의문에서 시작해 산 뒤를 휘감아 도는 북악 스카이웨이를 따라 성북구 정릉까지 6.2km 이어진다. 지금은 등산로가 나 있지만 조선시대에는 도성을 지키는 순라꾼들이 오르내리던 길이었고 일반인에게 개방되기 전까지만 해도ucirc;와대를 경비하는 군인들만 오르내리던 길이었다. 산aring;길을 쉬엄쉬엄 걷다 보면 한쪽에는 북한산 보현봉 자락이, 가을이면 한쪽으로 노을oacute;럼#376;오르는 북악산 단풍의 모습이 일품이다.서울에 남은 유일한 생태축인 서울 성곽은 옛 한양의 문화와 역사를 느낄 수 있는 공간이다. 인왕산 성곽길에 이어 2007년 북악산 숙정문~acirc;의문 구간이 개방되면서 서울 성곽 전uuml;를 연결해서 걸을 수 있게 되었다. 18.2km의 성곽길 중에서도 북악산 능선을 따라 이어지는 성벽 길이 인기 코스다. 오랫동안 통행이 금지되어서 성곽의 모습이 잘 보존되어 있고 전망도 빼어나다.", + "MNTN_HG_VL" : "342", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 종로구 부암동", + "MNTN_NM" : "북악산" }, - "longitude" : -118.3208913, - "latitude" : 34.054107500000001 + "longitude" : 126.97333329999999, + "latitude" : 37.5930556 }, { "mountain" : { @@ -5376,8 +4206,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 성남시 분당구, 광주군 오포면", "MNTN_NM" : "불곡산" }, - "longitude" : 127.02581929999999, - "latitude" : 37.799757100000001 + "longitude" : 127.1352778, + "latitude" : 37.346111100000002 }, { "mountain" : { @@ -5386,8 +4216,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 성남시, 광주시", "MNTN_NM" : "불곡산" }, - "longitude" : 127.02581929999999, - "latitude" : 37.799757100000001 + "longitude" : 127.1352778, + "latitude" : 37.346111100000002 }, { "mountain" : { @@ -5409,26 +4239,6 @@ "longitude" : 127.4525, "latitude" : 37.8030556 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "창원시와 진해시, 그리고 김해시 장유면의 경계점에 통신시설이 돋보이는 산봉이 있는데 그곳이 이 산의 정상이다. 창원시에서 보면 시역의 동쪽을 방책처럼 막아선 산릉의 끝머리에 다소곳 앉은 형세지만, 진해시에서 보면 험한 산세가 우선 눈에 띈다. 불모라는 특이한 이름처럼 아주 온화하고 포근한 산역이 대부분으로, 창원시 쪽의 산자락에 곰절이라고 불리는 성주사가 자리잡고 있어 불교와도 인연이 없는 것은 아니다.", - "MNTN_HG_VL" : "801", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시, 진해시. 김해시 장유면", - "MNTN_NM" : "불모산" - }, - "longitude" : 128.74147880000001, - "latitude" : 35.162522600000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "다도해의 풍정이 물씬 나는 한려수도에 자리잡은 사량도 불모산은 사량섬을 동서로 가로지르는 능선 상에 솟아 있는 산이다. 가마봉이라고도 부른다. 사량도는 섬이 뱀처럼 생기고, 또 뱀이 많다고 해서 붙여진 이름이라고 한다.전하는 이야기에 따르면, 한 남자가 이룰 수 없는 사랑 때문에 괴로워하다가 상사병에 걸려 죽었는데 뱀이 되었다고 한다. 사량도는 모두 8개의 섬으로 이루어져 있다. 주섬은 윗섬과 아랫섬으로, 두 섬이 마주보고 있다. 이 중 불모산은 윗섬에 있다.이외에도 지리산(398m)·옥녀봉(261m) 등의 산들이 불모산과 능선이 이어져, 종주 등반하는 코스가 개발되어 있다. 서쪽에는 지리산(398)이, 동쪽에는 옥녀봉(261)을 좌우에 거느리고 있는 불모산의 정상은 거대한 바위덩이로 뭉쳐져 있다. 정상에서 조망은 사방이 탁 트여 푸른 바다에 섬들이 옹기종기 모여있는 모습이 발아래로 펼쳐지고, 그 사이로 떠다니는 배들이 한가롭다.", - "MNTN_HG_VL" : "399", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면 사량도", - "MNTN_NM" : "불모산" - }, - "longitude" : 128.74147880000001, - "latitude" : 35.162522600000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -5436,8 +4246,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 광양시", "MNTN_NM" : "불암산" }, - "longitude" : 127.095, - "latitude" : 37.663333299999998 + "longitude" : 127.7266667, + "latitude" : 35.050555600000003 }, { "mountain" : { @@ -5449,6 +4259,16 @@ "longitude" : 127.095, "latitude" : 37.663333299999998 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "불태산은 담양 대전면 대치리에서 장성 백양사로 넘어가는 한재(대치)를 경계로 왼쪽에 솟아있는 해발 720미터의 봉우리다. 그동안 오른쪽의 병풍산의 그늘에 가려져 많이 알려지지 않았으나 최근 남쪽 산자락에 위치한 군사 훈련소 때문에 민간인 출입이 통제되어오던 것이 최근 완화되면서 남도 등산인들로부터 당일 산행지로 사랑받고 있다.불태산은 장성 진원면과 담양 대전면에서 바라보면 마치 거대한 부처를 연상케 한다. 이를 증명하듯 장성군에서 발간한lt;문화유적gt;에 따르면 불태산을 ‘불대산(佛大山)’으로 표기하고 있고, 또 산자락에 80개의 사찰이 있었다는 이야기가 전해지고 있다.국토지리정보원 지형도에는 636미터 봉우리를 ‘불태산(佛台山)’으로 표기하고 있으나 지역주민과 과거의 자료를 살펴보면 ‘불태봉 720m’라 적힌 정상석이 세워진 봉우리가 불태산 정상이라 하겠다. 해발 685.2미터의 ‘병장산’도 지형도에는 ‘병봉산(屛鳳山)’이라 표기되어 있다. 산세는 동쪽 사면은 가파른 절벽이고 서쪽 사면은 완만하다. 대치~천봉 구간은 육산이지만 주능선 곳곳을 이루는 암릉구간은 암릉산행의 재미를 선사한다.", + "MNTN_HG_VL" : "720", + "MNTN_LOCPLC_REGION_NM" : "전남 장성군 장성읍·진원면, 담양군 대전면", + "MNTN_NM" : "불태산" + }, + "longitude" : 126.8666667, + "latitude" : 35.299999999999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "백두대간의 지맥이 동쪽으로 뻗어 단지봉(1327m), 가양산(1430m), 미승봉(734m)으로 내려오다가 가야산에 이르기 전 남서쪽으로 별유산(1046m)을 지나 솟구친 것이 비계산이다.합천군과 거창군의 경계를 이루는 비계산은 인접한 별유산, 장군봉과 함께 닭이 금벼슬의 관을 쓰고 심장부에 고견사를 품고 있는 듯한 형상이다. 비계산은 닭머리 부분에 해당된다. 비계산은 돌, 너덜, 바람, 굴이 많은 산으로 유명하다. 능선상에는 암릉과 암봉들이 많아 산행시는 로프를 반드시 준비해야 한다.소요 시간 :6시간최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 갈림길에서 서쪽 능선을 따라 오른 비계산 정상은 잡목들로 어우러져 있고, 동서를 관통하는 88 고속도로 및 의상봉 상봉에서 서쪽으로 뻗은 암릉을 바라보는 경관이 좋다.도리나 거창휴게소에서 많이 올라간다. 비계산에서 시작하여 의상봉까지 종주하는 코스로 이용하기도 한다. 숲길로 활용하기 적당하나 정상부근은 안전장치가 좀더 필요할 듯하다. 휴게서외에는 식수를 구할 곳은 없다.", @@ -5476,8 +4296,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 중동면 오상리", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 128.26611109999999, + "latitude" : 36.436388899999997 }, { "mountain" : { @@ -5496,18 +4316,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면 문촌리", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진주시", - "MNTN_NM" : "비봉산" - }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 128.79523180000001, + "latitude" : 36.839934399999997 }, { "mountain" : { @@ -5516,8 +4326,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 의성군 다인면", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 128.3608667, + "latitude" : 36.488524099999999 }, { "mountain" : { @@ -5526,8 +4336,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 126.95, + "latitude" : 34.983333299999998 }, { "mountain" : { @@ -5536,8 +4346,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 선산읍", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 128.2994444, + "latitude" : 36.247222200000003 }, { "mountain" : { @@ -5546,8 +4356,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 126.79972220000001, + "latitude" : 36.501111100000003 }, { "mountain" : { @@ -5556,8 +4366,18 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면", "MNTN_NM" : "비봉산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 128.79523180000001, + "latitude" : 36.839934399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "5만분의 1 지형도에는 날 비(飛)자로 표기되어 있으나 이 지역 주민들 말에 의하면 옛부터 이 산위에 구름이 걸려 있으면 꼭 비가 왔다고 해서 우리말 `비'를 붙여 비산이라 부른다고 한다. 또 일설에 의하면 서만이강이 범람했을 때 이 산 꼭대기에 배가 걸려 들어 배거리산이라 불리기도 했다. 이 서만이강은 이름도 묘하거니와, 강의 상류도 주천강이요 하류도 주천강이어서 사람들을 어리둥절하게 만들곤 한다.굽이구비돌아올라가는 솔치고개도 옛모습을 보기는 어렵다. 솔치고개밑으로 터널을 뚫어놓았기 때문에 자동차들이 솔치고개를 넘지를 않기때문이다. 이 솔치고개는 이름 그대로 송림이 울창하게 숲을 이루고 있어 지어진 이름이다. 한아름 두아름되는 노송이 늘어서있고 비산으로 가는 길은 소나무숲 길이다. 이길은 사람에게 그리도 좋다는 피톤치드를 온몸으로 느끼는 삼림욕 숲속길이다.봄이면 진달래, 복숭아, 산벚꽃이 지천으로 피어난다는 버들치 마을은 이름 그대로 아름다운 풍광에 고운 인심을 자랑하는 전형적인 산마을이다.정상에 올라 하산길로 들어서면 북으로 펼쳐지는 구룡산을 비롯하여 멀리 백덕산까지도 조망된다.", + "MNTN_HG_VL" : "694", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 영월군", + "MNTN_NM" : "비산" + }, + "longitude" : 128.21735760000001, + "latitude" : 37.278231599999998 }, { "mountain" : { @@ -5571,13 +4391,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산양면 부암리의 둣산이고 옛날 봉화를 올리던 곳으로 전하며 왕의산과 능선으로 이어져 있다. 현리 쪽으로 산라 때 고성인 근암성이 있는 근품산과 이어져 있다.봉우재를 거쳐 비조산(310m)에 올라가면, 전망이 시원하다. 부암, 형천, 과곡, 우본, 예천 용궁, 멀리 삼강까지 내려다 보인다. 비조산 밑으로 삼강까지는 거의 평야처럼 보인다.사람의 발길이 잦지 않아 비교적 깨끗함을 간직하고 있는 산이다.", - "MNTN_HG_VL" : "310", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 위만리", - "MNTN_NM" : "비조산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "231", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", + "MNTN_NM" : "비조봉" }, - "longitude" : -73.945442299999996, - "latitude" : 40.750144800000001 + "longitude" : 126.1304785, + "latitude" : 37.219784599999997 }, { "mountain" : { @@ -5589,26 +4409,6 @@ "longitude" : 129.2891482, "latitude" : 36.196548900000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "317", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산외면 남기리", - "MNTN_NM" : "비학산" - }, - "longitude" : 129.2891482, - "latitude" : 36.196548900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "뾰루봉은 청평호 옆에 솟아 있는 암릉이 많고 소나무가 암릉을 따라 숲을 이루고 있는 산이다. 이산은 화야산, 고동산으로 이어지면서 북한강을 따라 양수리까지 뻗은 산맥인데 이 연맥은 경춘가도의 북한강 경관을 결정하는 중요지형중의 하나이다.뾰루봉은 화야산을 주봉으로 볼 수 있는 이 능선에서 변방으로 밀려나온 듯한 느낌을 주지만 그 때문에 오히려 더 조망도 좋아 오르기가 무척 기분좋은 산이다. 높이는 화야산의 755미터에 못미치지만 청평댐을 내려다볼 수 있는 위치에 있고 암릉이 있다는 점에서 오히려 화야산보다 더 산행할 맛이 나는 산이라고 할 수 있다. 청평으로 가까워지면서 강건너 솟아있는 뾰루봉은 날카로운 인상을 준다. 청평댐은 이 뾰루봉때문에 축조될 수 있었다고 말할 수 있다. 북한강은 뾰루봉을 중간에 두고 청평댐부근에서 둥근 호를 그리며 돌아나가고 있다.호의 최원점에 댐이 있다. 이런 까닭으로 뾰루봉에서 청평댐과 북한강의 모습을 바라보기가 가장 적당하다. 암릉의 노송 가지 끝으로 바라다보이는 청평호가 그렇게 시원할 수가 없고 바람이라도 불면 귓가에 들리느니 송풍음 뿐이다.뽀루봉은 고동산과 이웃해 있는데 가평의 청평호를 건너 찾아가는 길이 아름답다. 구암리 나루터에서 배를 타고 동쪽으로 고동산을 보며 청평호를 건너면 삼회리라는 시내버스 종점이 나오는데 여기에서 고동산으로 올랐다가 뽀루봉으로 옮겨갈 수 있다. 또는 청평댐 건너편에 위치한 나이아가라 호텔 근처에서 산에 오를 수도 있다. 산에 오르면 청평호가 주위 산을 휘감아 도는 모습이 그림처럼 펼쳐진다.", - "MNTN_HG_VL" : "710", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 외서면, 양평군 서종면", - "MNTN_NM" : "뽀루봉" - }, - "longitude" : 127.427809, - "latitude" : 37.721110000000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -5669,6 +4469,16 @@ "longitude" : 127.9064195, "latitude" : 38.077294899999998 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "충북 단양군 단성면 회산리와 장회리의 경계를 이루고 있는 사봉은 금수산, 소백산, 도락산 등 주변의 명산들과 함께 단양의 풍광을 연출하는 아름다운 산이다. 그러나 단양팔경의 절경과 다른 산들의 유명세에 가려 일반인들은 물론 산악인들에게도 잘 알려지지 않은 편이다. 물론 이 때문에 한결 여유롭고 아늑하게 산행을 즐길 수 있다는 이점도 있다.사봉은 일명 물레봉이라고도 하는데 옛날 홍수 때 물레만큼 남았었다하여 부르게 된 산명이라 전해오고 있다.특히 이 산 정상에는 일본인들이 한반도의 혈맥을 막기 위해 박아 놓은 쇠말뚝이 있어 역사의 기구함을 느끼게 하고 있다. 사봉 주위에는 단양팔경 중 4경의 절경들이 펼쳐져 있어 산행 후의 주변 관광을 빼 놓을수 없다.", + "MNTN_HG_VL" : "879", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", + "MNTN_NM" : "사봉" + }, + "longitude" : 128.28194439999999, + "latitude" : 36.907499999999999 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "장흥과 보성의 진산인 사자산은 곰재를 사이에 두고 제암산(779)과 마주보고 있다. 철쭉으로 유명한 '화산(花山)' 으로 해발은 낮으나 바닷가의 산이 다 그러하듯이 내륙의 산과 달리 웅장한 산세를 갖추고 있다. 사자산 정상 주변은 나무가 없이 억새와 바위로 완만한 능선을 이루고 있어 남쪽 발아래로 확 트인 남해바다의 풍경을 볼 수 있다.장흥벌을 향하여 울부짖는 사자형상으로 일컬어지는 사자산(獅子山 666m) 은 제암산, 억불산(518m)과 더불어 장흥의 삼산으로 꼽히는 명산이다 . 장흥읍쪽 봉이 사자머리 같다하여 사자두봉, 정상은 남릉과 더불어 꼬리같다고하여 사자미봉으로 불린다. 장흥벌에 솟구친 사자산은 철따라 다양한 모습을 보여준다.봄이면 파르한 기운이 스며 들면서 생명의 신비함을 느끼게 하고 여름이면 푸른 초원으로 변하고 가을이면 억새가 날리면서 강렬한 인상을 주는 산이다 사자두봉에서 사자미봉까지 이어지는 약 2km의 능선은 부드러움과 거친 자연미를 느낄 수 있다 .특히 남서면의 기암 절벽은 설악산의 어느 암릉에도 뒤지지않을 정도로 웅장하고 힘찬 자연미를 보여준다. 주능선 중간쯤의 안부와 능선 남쪽 사면은 전국에서도 유명한 활공장이다.", @@ -5676,8 +4486,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군, 보성군", "MNTN_NM" : "사자산" }, - "longitude" : 128.2825, - "latitude" : 37.406111099999997 + "longitude" : 126.9809063, + "latitude" : 34.683520700000003 }, { "mountain" : { @@ -5689,36 +4499,6 @@ "longitude" : 128.2825, "latitude" : 37.406111099999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간은 백두산을 시발로 남으로 내려오다 원산 아래 추가령지구대에서 하나의 정맥을 떨군다. 이것이 한북정맥이다. 한북정맥은 내려오면서 백암산, 적근산, 대성산, 광덕산, 백운산, 국망봉, 운악산을 이루고 도봉산에 이르기 전 사패산으로 솟아 올랐다. 사패산은 한북정맥이 운악산 끝에 이르러 기운이 명멸하듯 이어오다가 의정부에서 다시 힘차게 솟아오른 첫번째 봉우리로서 조선조 선조가 여섯째 딸 정휘옹주를 유정량에게 시집 보낼 때 마패와 함께 하사한 땅이라하여 '줄 사(賜), 호패 패(牌)' 라 이름 붙여졌다.이 산은 경기도 양주군 장흥면에 속해 있으며 안골, 회룡골, 송추계곡, 원각사계곡과 기암괴석의 범골 능선을 거느리고 있다. 정상은 커다란 암봉으로 되어있으며, 정상에 오르면 모두들 도봉, 북한산의 산줄기에 시선을 둔다. 이렇게 적은 땀을 흘리고도 이만한 경치를 즐길 수 있을까 싶을 정도로 조망이 일품이다. 거칠 것 없는 포대능선의 봉우리들이 자운봉, 만장봉, 선인봉을 에워싸고 오봉의 바윗덩어리들이 절묘하게 올라앉아 있다. 멀리 백운대와 인수봉 끝으로 상장능선이 병풍처럼 둘러져 있고 그 오른쪽으로는 노고산을 이어 한북정맥이 바다로 내쳐 달려간다.", - "MNTN_HG_VL" : "552", - "MNTN_LOCPLC_REGION_NM" : "경기도 의정부시, 양주시 장흥면", - "MNTN_NM" : "사패산" - }, - "longitude" : 127.010212, - "latitude" : 37.722460699999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "사향산은 산정호수의 남쪽 5km 지점에 인접한 산이다. 또 관음산과 사향산은 산정리와 남유동을 잇는 도로를 가운데 두고 그 고개 마루턱인 낭유고개를 중심으로 동서로 마주보고 있다.", - "MNTN_HG_VL" : "507", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면", - "MNTN_NM" : "사향산" - }, - "longitude" : 127.34282570000001, - "latitude" : 38.037779800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산방산은 둔덕면 산방리 뒷산으로 507.2m의 정상에는 큰 바위산 세 개가 하나의 산봉우리를 이루고 있으며, 삼봉이 우뚝 솟아 괴암괴석이 만물상을 이루고 가을 단풍이 곱게 물들면 천태만상의 대자연의 경관과 멀리 바라다 보이는 다도해의 한산섬과 서산 낙조, 멀리 보이는 작은 섬들이 점점이 떠 있어 거제의 봉산들이 다 그렇지만 정상에서 바라다보는 바다와 어우러진 경치는 필설로 표현하지 못할 만큼 절경이다.또한 거제도에 가뭄이 들면, 대대로 이곳에서 기우제를 지났다고 하는데, 지 금도 산정상에서 10M 아래에 무지개 터가 있고 주위로 기우제단이 마련되어 있다. 무지개 터라 부르는 그곳은 바위 틈새로 사시사철 물이 똑똑 떨어져 작은 우믈이 생긴곳이다. 특히 산방산 정상의 삼봉 분지 흙색깔이 다섯가지의 색을 띄고 있다 하여 오색토라 부르며, 산세가 다양하고 산중허리에 있는 석굴암이 있기도 하다.산이 높지 않아 가벼운 가을 산행지로 더없이 좋은 곳이다. 거제해금강과 외도 여행을 준비하였다면 한번쯤 들러 볼만한 곳이다.", - "MNTN_HG_VL" : "395", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 둔덕면 산방리", - "MNTN_NM" : "산방산" - }, - "longitude" : 126.3134467, - "latitude" : 33.241068200000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "제주도의 산중에서 가장 유명하고 경치가 빼어나며 신비스러운 분위기가 서린 곳으로, 반드시 찾아가봐야 하는 곳이 바로 산방산이다. 한라산 봉우리를 뽑아 옮겨 놓은 것이 산방산이고, 그 뽑힌 자리가 백록담이 되었다는 이야기가 있듯이 설화 속의 산방산은 수려한 용모가 단번에 찾는 이의 눈길을 빼앗을 정도로 아름답다. 매우 가파라서 오르기가 힘이드나 일단 오르고 나면 정상에서 바라보는 그 경치는 모든 피로감을 충분히 보상하고도 남으며 한번 오른 이는 다시 오르고 싶은 마음이 절로 나는산이다.또한 조면암질 안산암으로 구성되어 있으며 그 형태가 특이하다. 남서쪽 기슭, 해발고도 200m 지점에 산방굴(山房窟)이라는 자연 석굴이 있다. 그 안에 불상을 안치하였기 때문에 이 굴을 산방굴사(山房窟寺)라고도 한다. 굴 내부 천장 암벽에서 떨어지는 물방울은 산방산의 암벽을 지키는 여신 ‘산방덕(山房德)’이 흘리는 사랑의 눈물이라는 전설이 있다. 산의 남쪽 해안에는 성산포층(城山浦層)이 노출되어 있고 심한 해식(海蝕)으로 단애(斷崖)가 형성된 암석해안을 이룬다. 여기에 하멜 표류 기념탑(漂流記念塔)이 있다.", @@ -5739,26 +4519,6 @@ "longitude" : 128.59083330000001, "latitude" : 35.810000000000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산성산은 별로 높지 않은 산으로 고적답사 차원에서 적합한 산이며, 특히 가족 동반으로 조용한 산행을 즐길 수 있다. 밀양역에서 택시로 (5,000원) 활성교 다리에 내려, 다리를 건너 상점 오른쪽길 따라 오르면 금시당에 도착한다. 버스는 구 시청 앞에서 2시간 마다 용활동 방면 버스가 있으나 매우 불편하다. 산행은 금시당 윗길을 올라 왼쪽으로 호젓한 산길에서 시작된다. 산성산의 정상에는 할머니 묘소가 있는데, 할미꽃이 무덤 위에 피어났다. 하산길은 내리막길의 연속이다.", - "MNTN_HG_VL" : "380", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 활성동", - "MNTN_NM" : "산성산" - }, - "longitude" : 128.59083330000001, - "latitude" : 35.810000000000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "750", - "MNTN_LOCPLC_REGION_NM" : "경상북도 의령", - "MNTN_NM" : "산성산" - }, - "longitude" : 128.59083330000001, - "latitude" : 35.810000000000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "순창군과 담양군의 경계를 이루며 강천산(584m)과 형제처럼 솟아있는 산성산은 비록 그 높이는 낮지만 공룡등처럼 이어져있는 능선길을 따라 곳곳에 널린 유적과 절경을 감상하는 것만으로 산행의 즐거움을 충분히 챙겨갈 수 있는 그런 산이다. 이 산에 축조된 산성 때문에 산성산이라 이름 붙여졌다 하며, 일명 금성산이라고 불리는데 이는 금성면에 위치해 있기 때문이다.산성산은 해발 600m에 가까운 철마봉의 절벽에서 시작된, 연대봉, 운대봉, 시리봉 등 사방 계곡의 능선을 이용하여 축조한\"\"금성산성\"\"으로서 강천산 줄기가 서남으로 뻗어 담양군과 순창군의 경계를 이루고 각 봉우리마다 웅장한 암봉으로 이루어져 있다. 철마봉에서 서쪽으로 조망되는 담양호, 추워란의 위용 석양의 노을진 경관이 볼 만하다.", @@ -5766,8 +4526,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군, 전라남도 담양군", "MNTN_NM" : "산성산" }, - "longitude" : 128.59083330000001, - "latitude" : 35.810000000000002 + "longitude" : 127.0391056, + "latitude" : 35.379716700000003 }, { "mountain" : { @@ -5779,26 +4539,6 @@ "longitude" : 128.59083330000001, "latitude" : 35.810000000000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "울주군 소호리와 내와리 사이 백운산 북쪽에 삼강봉이 있다. 삼강봉의 꼭대기에서 떨어지는 빗물이 3등분이 되어, 서쪽 방향은 소호리 동창천으로 해서 낙동강으로 흘러가고 동북 방향은 내와리 큰골로 해서 포항 형산강으로 흐르고, 동남 방향은 미호 저수지 그리고 미호천으로해서 울산 태화강으로 갈라져 흐르는 분수령을 이루고 있으므로 삼강봉이라고 한다.삼강봉 산행은 시간에 맞추어야 하는 고충이 있는데, 언양에서 8시 30분에 출발하는 내와 행 369번 버스를 타야 한다. 산행들머리는 지금 폐교된 두서초등학교 내와 분교 오른편 개천 따라 오르면 도 경계를 이루는 당고개에서 시작한다.", - "MNTN_HG_VL" : "851", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 소호리, 내와리", - "MNTN_NM" : "삼강봉" - }, - "longitude" : 129.18086769999999, - "latitude" : 35.681580400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "원래는 민주지산의 한 봉우리로 화전봉이었다. 삼도봉이라는 이름에 걸맞게 1989년부터 매년 10월 10일 이 삼도의 기관장과 주민들이 참석하여 삼도의 화합과 안녕을 비는 문화행사를 개최해오고 있다.삼도봉의 수목은 상수리나무가 특히 많으며, 김천 부항면 해인리 쪽으로는 호도나무가 많아 호도의 생산량이 연 70톤에 이른다.삼도봉은 소백산맥의 한 자락으로 사계절 변화무쌍한 그 절경은 가히 남한의 작은 백두산이라 칭할 만 하다.해발 1180미터인 삼도봉은 이웃한 석기봉, 민주지산과 함께 오래전부터 이름난 등산코스로 전국에 널리 알려져 있다.특히 가을 단풍이 절경이며, 산을 오르며 바닥에 밟히는 오래된 낙엽과 썩은 나무 둥치는 이 산이 아직은 때 묻지 않은 아름다운 산임을 말해주고 있고, 곳곳에 굴참나무를 비롯한 고산식물의 나무가지가 자라지 못하고 천태만상으로 구부러져 있어 신기함을 자아내고 있는데, 그리 높지 않은 산이면서도 희귀한 고산 식물이 많이 자생하고 있어, 생태학자들의 연구의 현장이기도 하다.", - "MNTN_HG_VL" : "1176", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 부항면, 전라북도 무주군 설천면, 충청북도 영동군 상촌면", - "MNTN_NM" : "삼도봉" - }, - "longitude" : 127.8761111, - "latitude" : 36.022500000000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "삼문산(三門山)은 전남 완도군 약산면을 이루는 조약도 최고봉이다. 조약도로 가는 뱃길은 완도가 아닌 강진군 마량에서 배를 탄다. 조약도는 지형도에 표기되어 있는 행정지명이지만, 이곳 섬 주민들은 '약산도'로 부른다. 그래서 마량나루에 정박해 있는 조약도행 배에도 ‘약산’이라 붙어 있다.삼문산이라는 이름의 유래는 이렇다. 옛날 주능선 동쪽 분지인 삼개문(일명 삼감안)에서 땔감으로 쓰는 초나무나 풀을 베어 지게에 메고 서쪽 천동나루 방면으로 넘어올 때 망봉과 등거산 사이 움먹재나 망봉과 장룡산 사이 파래밭재와 큰새밭재를 넘어다녔다. 즉 세 고개를 세 문(門)으로 보았던 것이다.평범한 육산인 삼문산에 토끼바위, 쟁기바위, 부엉이바위 같은 특이한 모양의 바위들이 변화를 꽤한다. 그러나 삼문산의 매력은 사방으로 펼쳐지는 남해 바다와 여기에 떠 있는 다도해의 그림 같은 풍경에 있다. 삼문산 봉화대는 고금진의 망덕산, 신지진의 상봉, 가리포진(현재의 완도) 상황봉, 장흥 천관산으로 봉화를 하던 송신소 같은 곳이다.", @@ -5826,18 +4566,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", "MNTN_NM" : "삼방산" }, - "longitude" : 128.4325, - "latitude" : 37.339444399999998 + "longitude" : 129.07030929999999, + "latitude" : 37.084382499999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "273", - "MNTN_LOCPLC_REGION_NM" : "충청북도 증평", - "MNTN_NM" : "삼보산" + "DETAIL_INFO_DTCONT" : "치악산국립공원에 속하는 삼봉은 치악산 정상인 비로봉(1288)에서 서북쪽으로 이어지는 능선 상에 솟아 있는 산이다. 삼봉을 지나면서부터 1km 간격으로 투구봉(1,002m), 토끼봉(887m)이 이어져 있다.삼봉에서 짜릿한 묘미를 즐기려는 이들은 낚시봉 코스를 선호한다. 삼거리에서 지능선으로 20분 오르면 약수터가 반기는 절터에 닿는다. 이 절터에서는 거리 100m를 두고 두 개의 샘이 있다. 그러나 관리가 되지 않아 늦가을이나 겨울에는 물에 낙엽이나 이물질들이 담기거나 얼어붙어 크게 기대할 것은 못된다. 두번째 샘터에서 숲속으로 15분 가량 올라가면 동쪽으로 이어지는 능선길을 밟는다. 이 능선길을 오르다가 참나무숲을 벗어나면 바윗길이 나타나기 시작한다. 바윗길은 급경사 바위를 피하느라 능선 좌우로 횡단하며 이어진다.삼각점(89년 재설)이 박혀있는 정상에서 휘둘러보는 조망은 막힘이 없다. 먼저 동으로는 도실암골 건너로 석탑 3기가 마치 쇠머리에 돋아난 뿔처럼 보이는 치악산 정상 비로봉이 천지봉과 함께 시야에 들어온다. 비로봉 정상에 오른 등산인들의 움직임도 뚜렷하다. 남쪽으로는 향로봉 능선이 꿈틀거린다. 향로봉에서 오른쪽 멀리로는 남대봉과 백운산이 하늘금을 이루고, 백운산 방향에서 오른쪽 아래로는 원주시내가 한눈에 내려다보인다.서쪽 조망도 일품이다. 흥양리 분지로 패어내린 범골, 밤나무골, 삼장골, 되미골 협곡이 아찔하게 내려다보이고 흥양리 오른쪽으로는 새말로 이어지는 영동고속도로가 실낱같다. 멀리로는 양평 용문산 정상이 가물거린다.", + "MNTN_HG_VL" : "1073", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", + "MNTN_NM" : "삼봉" }, - "longitude" : 127.5806831, - "latitude" : 36.783085399999997 + "longitude" : 128.03805560000001, + "latitude" : 37.370555600000003 }, { "mountain" : { @@ -5846,8 +4586,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시", "MNTN_NM" : "삼봉산" }, - "longitude" : 127.872652, - "latitude" : 35.892753399999997 + "longitude" : 128.4447222, + "latitude" : 34.878611100000001 }, { "mountain" : { @@ -5876,18 +4616,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면", "MNTN_NM" : "삼봉산" }, - "longitude" : 127.872652, - "latitude" : 35.892753399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "우리나라 산 중에는 봉우리의 숫자에 의하여 이름지어진 산들이 많은데 삼봉산(三峰山)도 여기에 행당되는 산으로, 정상은 암봉으로 이루어진 세 개의 봉우리가 나란히 사이좋게 솟아있다.이 산의 특징은 낮으면서도 산세가 수려하여 한 때 신선이 내려와서 놀았다고 전하여져 내려오고 있으며, 산 정상부에 바둑판이 새겨진 바위가 있었다고 하나 세월의 풍화작용에 의하여 지금은 그 흔적을 찾아볼 수 없는 아쉬움이 있다.", - "MNTN_HG_VL" : "448", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 낙동면 유곡리, 상촌리", - "MNTN_NM" : "삼봉산" - }, - "longitude" : 127.872652, - "latitude" : 35.892753399999997 + "longitude" : 127.96055560000001, + "latitude" : 37.190277799999997 }, { "mountain" : { @@ -5896,8 +4626,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", "MNTN_NM" : "삼성산" }, - "longitude" : 126.9391667, - "latitude" : 37.436111099999998 + "longitude" : 128.7943459, + "latitude" : 35.771673499999999 }, { "mountain" : { @@ -5906,8 +4636,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", "MNTN_NM" : "삼성산" }, - "longitude" : 126.9391667, - "latitude" : 37.436111099999998 + "longitude" : 128.7943459, + "latitude" : 35.771673499999999 }, { "mountain" : { @@ -5916,8 +4646,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", "MNTN_NM" : "삼성산" }, - "longitude" : 126.9391667, - "latitude" : 37.436111099999998 + "longitude" : 128.7943459, + "latitude" : 35.771673499999999 }, { "mountain" : { @@ -5936,8 +4666,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", "MNTN_NM" : "삼성산" }, - "longitude" : 126.9391667, - "latitude" : 37.436111099999998 + "longitude" : 128.7943459, + "latitude" : 35.771673499999999 }, { "mountain" : { @@ -5969,16 +4699,6 @@ "longitude" : 126.17944439999999, "latitude" : 35.090555600000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "삼정산은 지리산 주능선 삼각고지에서 북쪽으로 뻗어 내린 능선에 우뚝 솟은 산으로, 지리산 산자락에 있는 봉우리이면서 '봉(峰)'이 아닌 '산(山)'으로 기록되어 있다. 천왕봉에서 노고단으로 이어지는 지리산 주능선상에 솟아 있는 봉우리를 통상적으로 '봉'이라 부르고 있으며 주능선을 기점으로 써레봉,삼신봉,왕시루봉 등 동, 남, 서쪽의 곁가지 봉우리들도 모두 봉으로 부르고 있다.부드러운 산세로 등산로에 위험한 곳은 없으나 군데군데 기암과 고사목, 노송 등이 어우러진 빼어난 경관이 산재하고, 단풍이 아름답고 붐비지 않는 한적한 산길이어서 더욱 좋다.능선의 동쪽면에는 도솔암, 영원사, 등 7개소의 사암이 남아있다. 옛날에는 군지사, 도마암, 정승절 등이 있었으나, 절터만 남아있고, 정승골 계곡 주변은 옛 모습을 간직한 채 풍경이 아름답다.", - "MNTN_HG_VL" : "1182", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 마천면, 전라북도 남원시 산내면", - "MNTN_NM" : "삼정산" - }, - "longitude" : 127.02396520000001, - "latitude" : 36.555352999999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "삼태봉은 광주산맥의 한 갈래로서 가평군에 위치하고 있다. 광주산맥의 한 갈래로 좌우에는 중미산과 화야산이 있고, 산위에 오르면 서쪽으로는 북한강, 동쪽으로는 뇌암산이 손에 잡힐 듯 다가오며 북동쪽으로는 곡달산이 바라 보인다.좌우로 중미산(834), 화야산(755), 용문산(1,157), 통반산(650)이 자리하고 있어 같이 연계하여 등산하는 것이 좋다. 특히 통반산과 같이 산행하는 것이 일반적이다.정상은 암번으로 이뤄져 있어 쉼터로 좋고, 한강의 조망이 일품이다. 그리고 통방산까지 이어지는 산길은 완만해서 좋고, 주변은 수림이 울창하다.", @@ -5986,8 +4706,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 가평군\/양평군", "MNTN_NM" : "삼태봉" }, - "longitude" : 129.36437799999999, - "latitude" : 35.691971500000001 + "longitude" : 127.46194439999999, + "latitude" : 37.624166700000004 }, { "mountain" : { @@ -5999,6 +4719,16 @@ "longitude" : 128.37006980000001, "latitude" : 37.120670199999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "73", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "삼학도" + }, + "longitude" : 126.3914317, + "latitude" : 34.782971400000001 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -6011,13 +4741,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삿갓봉은 한북정맥을 주맥으로 하여 귀목봉(1,036m), 화악산(1,468m), 응봉(1,436m)을 거쳐 북배산(867m)의 지맥이 뻗어 내려오다 가덕산 동쪽에서 일으켜 세운 산이다. 주변의 천m급 산들이 위세당당하게 솟구쳐 있어 716m의 삿갓봉은 막내처럼 아기자기하게만 보인다. 일반에 잘 알려지지도 않아 오염되지 않았으며, 삼박골계곡은 수량이 풍부하고 매우 깨끗하게 유지되고 있으며 임도 끝에서 숲터널을 통과 계류를 건너면 와폭이 나타난다.주변은 가을 단풍이 좋고 우거진 숲 속의 오솔길이 정겹다.정상에서는 산과 강을 휘둘러보면 조망이 아름답다. 서편은 몽덕산과 북배산 쪽으로 뻗은 능선이 하늘금을 이루고, 북쪽 화천의 명산들이 파도처럼 일렁이고 춘천호와 춘천시까지 대룡산, 북한강 등 산수가 어우러진 풍경이 빼어나다.또한 정상에서 내려다 본 신매저수지가 유난히 돋보이고 하산 길은 큰 굴곡 없이 등산기점으로 회귀할 수 있도록 연결되어 있어 좋다.", - "MNTN_HG_VL" : "716", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 사북면", - "MNTN_NM" : "삿갓봉" + "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면에 소재한 삽디리봉은 소양호 건너편에 있다는 불편 때문에 찾는 이들의 발길이 그리 흔치 않은 산이다. 자연히 천혜의 경관을 그대로 간직하고 있으며 물빛과 어우러진 자연경관 역시 일품이다.산속은 대체로 평이한 형세를 하고 있어 산행 코스로 짚어 줄 만한 특징적인 장소는 없으나 삽다리골 초입에서부터 정상까지 살아있는 자연의 숨결을 한껏 만끽할 수 있다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "삽다리봉" }, - "longitude" : 127.6993477, - "latitude" : 35.787457400000001 + "longitude" : 127.93611110000001, + "latitude" : 37.926666699999998 }, { "mountain" : { @@ -6026,8 +4756,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", "MNTN_NM" : "삿갓봉" }, - "longitude" : 127.6993477, - "latitude" : 35.787457400000001 + "longitude" : 127.6388889, + "latitude" : 35.7858333 }, { "mountain" : { @@ -6036,8 +4766,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군", "MNTN_NM" : "삿갓봉" }, - "longitude" : 127.6993477, - "latitude" : 35.787457400000001 + "longitude" : 128.21361110000001, + "latitude" : 37.392777799999998 }, { "mountain" : { @@ -6046,8 +4776,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍, 미탄면", "MNTN_NM" : "삿갓봉" }, - "longitude" : 127.6993477, - "latitude" : 35.787457400000001 + "longitude" : 128.53, + "latitude" : 37.343333299999998 }, { "mountain" : { @@ -6056,48 +4786,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", "MNTN_NM" : "삿갓봉" }, - "longitude" : 127.6993477, - "latitude" : 35.787457400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 청원군 북일면과 낭성면 사이에 위치한 상당산은 서편으로 우암산(338m)과 마주하며 다소곳이 솟아있다. 일명 상령산(上嶺山)으로 불리우는 상당산에는 전적지로 유서 깊은 상당산성이 둥지를 틀고 있으며, 그 안쪽에는 30여채의 한옥이 모여있는 한옥마을이 조성되어 있다. 기록에 의하면 원래 성안에는 운주현, 관아사, 군기고, 군량고, 동창, 서창 등의 방어시설이 구축되어 있었으나, 지금은 모두 사라지고 한옥마을만이 자리를 지키고 있다. 그나마 민속음식을 파는 상점들로 변하여 옛날 격전지로서의 흔적은 찾아보기 힘들다.이 상당산성은 삼국시대때 처음 축조된 것으로 전해지고 있으며 이후 조선 숙종 때 오늘날의 모습으로 정비되었다고 한다. '상당'이라는 이름은 백제 때 청주목을 상당현으로 부른 것에 유래하고 있다. 상당산성은 사적 제 212호로 지정되었다. 기록에 의하면 원래 성안에는 운주현, 관아사, 군기고, 군량고, 동창, 서창 등의 방어시설이 구축되어 있었으나, 지금은 모두 사라지고 한옥마을만이 자리를 지키고 있다. 그나마 민속음식을 파는 상점들로 변하여 옛날 격전지로서의 흔적은 찾아보기 힘들다.", - "MNTN_HG_VL" : "491", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구", - "MNTN_NM" : "상당산성" - }, - "longitude" : 127.539913, - "latitude" : 36.661709999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "상산(서리산)은 축령산을 가운데 두고 능선으로 우측은 은두봉, 좌측은 상산이 2 - 3km 간격을 두고 이어져 있다. 상산은 축령산의 서북 능선과 이어진 산으로 마주보고 있다. 일명 서리산 이라고도 불리며 축령산과 더불어 서울특별시에서 가까운 곳에 있으면서도 사람이 덜 찾는 산이었다. 그러나 축령산 자연휴양림이 개장하면서 본격적으로 알려지고 주능선에 수천평의 철쭉 군락지가 발견되고 부터는 많은 인기를 끌고 있는 산이다.산세는 주능선 북쪽 사면이 바위 벼랑에 가까은 급경사로 이루어진 반면 남쪽은 완만한 경사로 이루어져 있다.따라서 등산로는 축령산 자연휴양림이 있는 남쪽 위주로 발달 되어있다.정상은 나무하나 없이 시야가 탁 트이며 축령산이 가깝게 보인다.정상에서 능선을 따라 축령산으로 오를 수 있는데 절고개 부근은 가을이면 억새가 가득하여 볼만 하다.", - "MNTN_HG_VL" : "825", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평시", - "MNTN_NM" : "상산" - }, - "longitude" : 127.1186993, - "latitude" : 35.804417700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "함양 사람들에게 함양의 낮고 좋은 산이 어디냐고 물으면 서슴없이 서리산이라고 추천한다. 국립지리원의 지도에는 상산(霜山)이라고 표기되어 있지만 현지 주민들은 순수한 우리말인 서리산이라 부른다. 그런데 함양군청에서는 발행하는 행정지도에는 오봉산이라 표기되어 있고 현지 안내판 모두 오봉산이라 한다. 큰 암봉이 다섯 개여서 붙여진 이름이다.바위산인 서리산은 크고 까마득한 암벽과 낭떠러지가 곳곳에 있고 골짜기는 바위봉우리들로 협곡을 이루고 있어 경관이 빼어나다. 이 암봉들은 보통의 암봉과 달리 치악산 고스락의 석탑처럼 위가 둥글고 높게 쌓은 탑처럼 보이기도 하고 별천지로 들어가는 석문을 연상케 하기도 한다. 특히 아재원에서 오르는 도중 올려다보이는 거대한 쌍둥이 암봉은 참으로 멋있다.또 이 산은 낙락장송이 많아 기암괴봉들과 어우러져 더욱 아름답다. 단풍도 아름다워 가을의 경관이 일년 중 가장 좋기로 손꼽힌다. 함양 사람들이 가장 좋아하는 산으로도 꼽혀 경상남도 당국에서는 함양 사람들을 위해 이 산에 안내판을 비롯해 많은 시설들을 설치했을 뿐 아니라 산길도 잘 정비해 두었다.", - "MNTN_HG_VL" : "825", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 함양읍, 남원시 아영면", - "MNTN_NM" : "상산" - }, - "longitude" : 127.1186993, - "latitude" : 35.804417700000002 + "longitude" : 128.95833329999999, + "latitude" : 37.601388900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1117", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면", - "MNTN_NM" : "상운산" + "DETAIL_INFO_DTCONT" : "강화도의 서남단 외포리 선착장에서 4km정도 떨어진 석모도에는 상봉산을 중심으로 동쪽에 해명산(327m)과 북쪽에 상주산(264m)이 있다. 3개의 산이 있다해서 삼산면으로 이중 상봉산이 가장 높다. 석모도는 위의 세 산과 상봉산 북쪽으로 펼쳐진 광활한 방죽논지대, 이렇게 네 부분이 합쳐져 섬을 이루고 있다. 상봉산 동남쪽 아래 세워진 보문사는 규모도 크지만 바다를 향해 전망 좋은 곳에 위치한 관광명소로 찾는 이들이 많다. 관광을 겸할 경우 봄과 가을이 좋다.산행하면서 서해바다의 아름다운 모습을 구경할 수 있고 특히 상봉산 정상에서 서남쪽 볼음도 방향으로 바라보는 노을과 올망졸망한 섬들의 모습이 널리 알려져 있다. 정상은 암봉으로 되어 있으며, 남쪽으로 해안선과 바다, 북쪽으로 넓은 평야지대를 볼 수 있고 동쪽으로 해명산에 이르는 주능선이 잘 바라보인다. 능선 곳곳에 암벽이 자리잡고 있고 해명산에서 낙가산으로 가는 구간에는 억새풀 군락이 멋지다.", + "MNTN_HG_VL" : "316", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 삼산면 석모도", + "MNTN_NM" : "상봉산" }, - "longitude" : 129.02408159999999, - "latitude" : 35.636000099999997 + "longitude" : 126.3088889, + "latitude" : 37.694166699999997 }, { "mountain" : { @@ -6111,13 +4811,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "철따라 특징이 두드러지니까 명산이지만 이른 봄에 더욱 돋보이는 산이 충북 보은군 산외면과 경북 상주시 화북면에 걸쳐 있는 상학봉(上鶴峰,834m)이다. 뒤로는 묘봉, 앞으로는 미남봉과 마주보는 봉우리로 이름 그대로 정상 부근 암봉에 상급의 학들이 많이 모였었다.속리산 북서쪽에 숨어 있듯이 자리잡고 있는 상학봉은 산 전체가 아기자기한 바위산이어서 기암전시장을 방불케 한다. 공룡의 등허리인 양 기묘한 바위들이 울퉁불퉁 튀어나와 있는 공룡바위를 비롯, 돼지바위, 애기 업은 바위, 문바위 등이 연이어져 있어 지루한줄 모르고 산행을 할 수 있다.정상은 동남북 삼면이 천야만야한 수직절벽이다. 웬만큼 심장 강한 사람도 금세 현기증이 일고 오금이 저려온다. 손에 땀을 쥐고 엉금엉금 기다시피 자리를 옮기면서도 산 아래로 펼쳐지는 절경을 자꾸만 보게된다.", - "MNTN_HG_VL" : "834", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면", - "MNTN_NM" : "상학봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1006", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "상정바위" }, - "longitude" : 127.8344726, - "latitude" : 36.569043200000003 + "longitude" : 128.71916669999999, + "latitude" : 37.423611100000002 }, { "mountain" : { @@ -6149,26 +4849,6 @@ "longitude" : 126.6931914, "latitude" : 34.348111099999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "새득이봉은 강원도 춘천시 북산면 물노리와 홍천군 두촌면 천현리 경계선상의 가리산과 맥락을 같이하는 산이다. 워낙 산이 깊다보니 사람들의 접근이 쉽지않고 또 비교적 덜 알려져 있어 일반인들에게는 생소한 지명이다. 새득이봉은 원시청정림이 살아숨쉬는 곳으로 환경이 오염되지 않아 어디를 가나 빽빽한 나무에서 뿜어져 나오는 상쾌한 공기를 호흡할 수 있다. 심산유곡의 분위기를 한껏 자아내는 등산로를 오르다보면 땀이 송글송글 맺힌다.정상은 안타깝게도 나무들이 우거져있어 조망이 그리 좋은 편은 못되지만 나뭇가지 사이로나마 제법 웅장한 암골미를 드러낸 서남쪽 가리산 정상 풍광은 일품이다.", - "MNTN_HG_VL" : "935", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시, 홍천군", - "MNTN_NM" : "새득이봉" - }, - "longitude" : 127.97338240000001, - "latitude" : 37.882656799999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "어룡산에서 작약산으로 이어져 가는 산으로 안불정에서 바로 보이고 가은읍 저음리에 바로 보이는 산이다. 안불정에서 잘 닦인 임도를 따라가면 되고 가은읍 저음리에서는 능선을 타고 오르면 된다.", - "MNTN_HG_VL" : "617", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 신현리", - "MNTN_NM" : "새봉" - }, - "longitude" : 128.75209849999999, - "latitude" : 37.710744800000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -6179,16 +4859,6 @@ "longitude" : 127.54683439999999, "latitude" : 36.455291099999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "화악산의 지붕. 기암괴석과 사철 맑은 물이 흐르는 비경을 간직하고 있다. 특히 원시림을 방불케하는 울창한 수림이 계곡을 따라 터널을 만들어놓아 연인과 가족끼리의 산행에 알맞으며 수량 또한 풍부하여 큰물안골,작은물안골이라는 지명이 생기게 되고, 이끼 낀 계곡은 와폭과 담소로 이어지고 아름다운 비경이 골골이 펼쳐 있는 것이 특색이다.정상은 아무런 표식이 없으며 작은바위봉이 움푹 파헤쳐져 있으나 남쪽 전망대는 노송과 암벽이 어우러져 이 능선에서는 경관이 으뜸이고 남쪽의 매봉산과 서쪽의 백운산, 북쪽의 두류산 주변의 산들이 펼쳐 보인다. 교통도 경기 포천에서 화천읍으로 진행하는 56번 국도변에 위치하고 있어 접근도 용이하다. 계곡내에 단풍나무가 집단 서식하고 있어 가을산행지로는 최고이다.", - "MNTN_HG_VL" : "885", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면", - "MNTN_NM" : "샛등봉" - }, - "longitude" : 127.5537046, - "latitude" : 38.055818700000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "서대산의 높이는 904.1m이다. 충청남도 남동부의 금강분지를 둘러싸고 있는 금산고원에 속해 있으며, 노령산맥을 이루는 정수이자 충청남도의 최고봉이다. 충남에서는 높이 904.1m으로 가장 높은 산으로서 기암 절벽으로 이루어져 있다.화강암으로 이루어진 원추형 암산인 서대산은 기암절벽과 숲이 어우러지고 제법 험준해 산행의 묘미를 더한다. 정상에 올라서면 웅장하고 온화한 산세가 한눈에 들어오고 멀리 서북쪽으로 대전시내가 펼쳐진다.원흥사, 개덕사등 유명사찰과 정상 직전에 직녀 탄금대, 정상에서 북쪽 546봉으로 이어지는 능선 주변에는 장면대, 북두칠성 바위, 사자굴, 쌀바위 등이 산재해 있다.협곡을 가로 질러 높게 설치된 약 50m의 구름다리 주변은 신선바위, 벼슬바위등 기암 절벽들이 어울려 장관을 이루고 있다.", @@ -6209,36 +4879,6 @@ "longitude" : 127.3156252, "latitude" : 37.768321800000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "462", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면", - "MNTN_NM" : "서방산" - }, - "longitude" : 127.2199081, - "latitude" : 35.908850999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "서방산은 서방정토, 즉 아미타불의 부처님이 계시는 극락세계라는 뜻에서 유래됐다고 한다. 행정구역상 전라북도 완주군 용진면 간중리, 소양면 대흥리에 경계하고 있으며, 종남산에서 이어지는 연봉중 제일 높은 주봉이다.울창한 숲 속을 흘러내리는 봉서사 골짜기의 개울도 맑고 수려해 평야에 가까우면서도 깊은 산중의 맛이 느껴져 이 지역 산꾼들로부터 사랑받는 산이기도 하다. 숲이 울창하고 암벽과 암릉이 제법 발달해 있다.특히 뛰어난 것은 조망이 좋다는 것이다. 평야와 산지의 경계에 있어 넓은 김제 만경들을 넘어 서해 바다를 볼 수 있고 북에서 동을 거쳐 남으로도 수많은 산들을 조망할 수 있다.또한 송광사나 봉서사 등 유서깊은 사찰을 산행들머리로 하는 덕분에 산자락의 문화재를 감상하기도 좋다.", - "MNTN_HG_VL" : "612", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 용진면", - "MNTN_NM" : "서방산" - }, - "longitude" : 127.2199081, - "latitude" : 35.908850999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "여항산에서 뻗어내린 남릉이 진북면과 진전면의 경계선을 따라 흘러내리면서 이룬 산봉이 서북산이다. 진동면의 서북쪽에 위치한 산이라 서북산이라는 이름이 붙은 이 산은 전형적인 내륙산으로 전체적으로 산세가 부드럽다.남쪽사면으로 산세를 열고 학동마을을 병풍처럼 둘러싸고 있는 이 산은 6.25동란의 격전지로 산정에는 근간에 세운 전몰자 위령비가 있다. 서릉은 진전면의 산역속으로 흐름을 파묻고 국도 건너편의 적석산과 마주하면서 대정골까지 산자락을 들이밀고 있다. 숨겨진 산이라 아직도 깨끗한 모습을 유지하고 있다.소요 시간 :5시간 30분최적 탐방 시기 : 10 ~ 11월 \/가을볼거리 : 진동 앞 바다 조망숲길 명소 : 숨겨진 산이라 아직도 깨끗한 모습을 유지하고 있는것이 특징이다.함안군에서 등산구간이 많이 나타나 있고 마산시는 임도를 중심으로 등산하는 곳이 많음", - "MNTN_HG_VL" : "741", - "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시 합포구 진북면", - "MNTN_NM" : "서북산" - }, - "longitude" : 128.4194444, - "latitude" : 35.169166699999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경기도 안성시와 충청북도 진천의 경계에 선 서운산은 아담하고 바위가 거의 없는 유순한 산세를 지녔으며 봄이면 계곡과 능선에 진달래와 철쭉이 군락을 이루는 아름다운 산이다.서운산에 위치한 청룡사는 고려 원종 6년(1265)에 명본국사가 대장암이라는 이름으로 창건한 절로 공민왕 때 나옹화상이 중건하면서 청룡이 서운을 타고 내려오는 것을 보았다 하여 산 이름은 서운산, 절 이름은 청룡사로 하였다고 한다. 서운산 동북쪽 기슭에는 신라 문무왕 20년(680)에 창건한 석남사가 자리 잡고 있는데 염거국사와 혜거국사 등 이름 높은 스님들이 석남사를 거쳐 갔다.서운산에서 뻗은 서쪽 능선으로는 삼태기 모양으로 둘러싼 서운산성의 흔적을 찾을 수 있는데, 이 성은 임진왜란 당시 의병장이었던 홍계남과 이덕남이 안성을 방어하기 위해 쌓았던 군사요충지로 성 안에는 두 의병장의 대첩을 기념한 기념비와 석불이 있다.", @@ -6269,16 +4909,6 @@ "longitude" : 127.8641667, "latitude" : 36.025277799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "535", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", - "MNTN_NM" : "석대산" - }, - "longitude" : 126.5970633, - "latitude" : 35.3414559 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "석두봉은 강원도 오지중에서도 손꼽히는 오지에 위치한 탓으로 산악인들 사이에서도 잘 알려지지 않아 등산인들의 발길이 뜸하다. 그러다보니 등산로가 수풀에 둘러싸여 원시림을 헤쳐나가는 산행의 묘미를 만끽할 수 있다. 석두봉은 산이 깊어 물이 맑고 수량 또한 풍부하다.기다리던 돌산, 석두봉 올라보면 하늘과 맞닿는 느낌이다. 석두봉 정상은 이름 그대로 두 쌍의 바위로 이루어져 있다. 동봉과 서봉으로 정상을 지키고 있는 바위에 올라서면 일대의 경관을 한눈에 조망할 수 있으며 바위 사이로 자라는 철쭉들이 신기롭다.또한 참나무 노령목들이 여기저기 자라는 모습은 장관이며, 서쪽으로는 안반데기 동쪽으로는 왕산면 목계리가 한눈에 들어온다. 정상 바로 옆에 큰바위가 있는데 이곳에 오르면 상쾌한 느낌이다. 용수골을 내려다보며 큰소리로 메아리를 만들어 보는 것도 일미이다.", @@ -6346,8 +4976,8 @@ "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구 중산동", "MNTN_NM" : "석화산" }, - "longitude" : 127.88911090000001, - "latitude" : 37.699438999999998 + "longitude" : 126.5508463, + "latitude" : 37.5047292 }, { "mountain" : { @@ -6359,16 +4989,6 @@ "longitude" : 128.7094563, "latitude" : 37.0390199 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;양백(兩白)지간에 솟은 내성천의 발원지gt;선달산은 경북 봉화군 물야면, 영주시 부석면과 강원 영월군 하동면에 걸쳐 있는 봉우리로 청정계곡과 우아한 산세를 자랑한다. 남으로 갈곶산(961m)과 봉황산(819m), 서로 회암령~어래산(1064m), 동으로 옥석산(옥돌봉)이 애워싸고 있다. 북쪽에는 일곱능선이 선달산으로 이어졌다는 뜻의 칠룡골이 있다. 또 이곳은 소백산과 태백산의 양백(兩白)지간에 있는 산으로 백두대간 구간에 속한다. 언뜻 봐서는 강원도의 영서 내륙지방 같은 분위기를 풍기는 선달산은 낙동강의 지류인 내성천(乃城川)의 발원지기도 하다. 전국에서도 손꼽히는 오전약수가 있어 약수산행지로도 잘 알려진 선달산의 산행코스는 크게 세 갈래. 봉화 쪽 물야저수지가 있는 오전2리 생달마을에서 용운사~늦은목이를 거쳐 정상에 오르거나 사기점마을의 왕바우골을 들머리로 원점회귀 산행하는 것이 일반적이다. 영주 쪽에선 남대리 상신기마을을 들머리로 선달산 북서능선 1136봉 사이 안부로 올라서거나 늦은목이을 거쳐 오른다. 영월 쪽은 내리 지동마을에서부터 내리천을 따라 늪다리에 이르러 칠용동계곡을 통해 오른다. 이 중 오전약수가 있는 봉화 쪽으로의 접근이 가장 수월하다.", - "MNTN_HG_VL" : "1236", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면#8228;영주시 부석면, 강원도 영월군 하동면", - "MNTN_NM" : "선달산" - }, - "longitude" : 128.7094563, - "latitude" : 37.0390199 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "선달산은 백두대간의 소백산과 태백산 사이에 솟아 있어 대간을 조망하기에 좋은 산이다. 정상에서는 동쪽으로 남대천과 어래산이 보이고 서쪽으로는 박달령이 보인다. 또한 남쪽의 갈곶산과 이어진 부드러운 구릉으로 산행하기 수월하다.선달산 부근의 문화 유적으로는 부석사 무량수전(국보 제18호)과 소수서원이 있다. 무량수전은 우리나라 최고의 목조 건물로 신라 문무왕 때 의상대사가 창건 하였다. 소수서원은 1532년 주세붕이 세운 우리나라 최초의 서원으로 창건 당시 백운동서원으로 불리다가 명종 때 풍기군수로 있던 이황의 건의로 소수서원이라 불렀다.경상북도 봉화군은 사방이 산으로 첩첩이 둘러싸여 있고 그 속에 오전, 두내, 다덕 등 전국에서 손꼽히는 약수가 여러 군데 있다. 그 중 으뜸인 오전약수는 서쪽으로 마구령과 동쪽으로 도래기재 사이의 선달산 아래 있으며, 물맛이 가장 좋기로 조선시대 최고의 약수로 뽑히기도 했다. 그리고 중종 때의 풍기 군수 주세붕은 오전약수를 마음의 병을 고치는 좋은 스승에 비길만하다고 극찬했다. 약수터 앞 음식점이 들어선 곳을 제외하고는 한가로운 농촌 마을이다. 그러나 오전약수터 주변은 주말과 단풍철이 되면 관광차와 사람들로 부산스럽다.또한 선달산은 아름다운 계곡을 품고 있으며 각종 나무가 아름답게 줄을 서 있어 산세도 우아하다. 영월군 하동면 내리 지동마을에서부터 시작되는 내리천 계곡은 초입에서부터 울창한 수림과 풍부한 수량이 마치 원시의 비경을 연상케 한다. 계곡을 거슬러 오를수록 점입가경의 계곡미가 펼쳐지는데 한가지 흠이라면 이곳의 상류가 석회암 지대인지라 계곡 바닥이 온통 석회석으로 덮혀 물을 마실 수가 없다. 그러나 늪다리에 이르러 칠룡동 계곡으로 들어서면 계곡물은 옥같이 맑고 폭포,소 등이 연이어 그야말로 심산유곡이 펼쳐진다.", @@ -6379,26 +4999,6 @@ "longitude" : 128.7094563, "latitude" : 37.0390199 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;한계저수지 품은 한남금북정맥의 산줄기gt;월오동 목련공원 남쪽 맞은편에 있는 선도산은 청주에서 제일 높은 산으로, 지리적으로는 한남금북정맥 줄기와 행정구역으로 청주시 경계선이 만나 함께 가는 유일한 지점이다. 선도산을 기점으로 북쪽으로는 상령산 줄기로 이어지며 동남으로 선두산 지역인 청원군 낭성면 가덕면이 펼쳐지고 남쪽으로는 말구리재 미테재 관봉으로 이어가며 한계저수지를 끌어안고 있다. 서쪽으로는 청주에서 가장 깊은 골짜기 동네인 월오동 서운말을 끼고 그 건너편에 낙가산과 것대산을 마주보며 상봉재와 보살사를 품에 안고 있다. 등산로에는 전국의 산악인들이 한남금북정맥을 종주하고 있는 표식기가 많이 보일 정도로 많은 사람들이 찾아오고 있다. 선도산은 개척 산행 맛이 나는 곳으로 참나무와 진달래가 자랄 대로 자란 수풀 사이로 한 사람이 겨우 다닐 정도로 한적하고 산림욕까지 곁들일 수 있다.", - "MNTN_HG_VL" : "547", - "MNTN_LOCPLC_REGION_NM" : "충청북도 낭성면 무성리, 지산리, 현암리", - "MNTN_NM" : "선도산" - }, - "longitude" : 129.1696369, - "latitude" : 35.827482500000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "547", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 낭성면 무성리, 지산리, 현암리", - "MNTN_NM" : "선도산" - }, - "longitude" : 129.1696369, - "latitude" : 35.827482500000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "충북 단양군에 위치한 선미봉은 착한 산이라는 뜻의 착할 선자에다 산의 순수한 우리말인 `뫼'자를 붙여 선뫼봉으로 불리다가 오늘에 이르러서는 뫼가 아름다울 `미'로 변해 붙여진 이름이다.산이 착하다니 무슨 뜻일까. 착한산이라서 등산로마저도 편할 것 같지만 그동안 등산인들의 발길이 거의 미치지않아 등산로에는 잡목과 낙엽으로 원시림을 방불케한다. 정상에 오르면 서북쪽 풍광이 가장 먼저 시선을 끈다.선미봉과 맥락을 같이 하는 수리봉, 황정산, 도락산 정상이 시야에 와 닿고 동쪽으로는 멀리 도솔봉 부터 백두대간을 끌고온 시루봉과 촛대봉 그리고 저수령 아래로 거대한 분화구처럼 움푹패어든 목장지대가 그림처럼 펼쳐진다.", @@ -6406,38 +5006,38 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 대강면", "MNTN_NM" : "선미봉" }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 + "longitude" : 128.33677549999999, + "latitude" : 36.845008499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "선바위봉은 치악산 상원사 뒤편인 망경봉(1182m)에서 동남쪽 매봉(1095m) 방향으로 이어지는 능선 가운데에 솟아 있는 산이다. 원주시와 회성군, 영월군 경계상의 오지에 있어 등산인이 드문 한적한 때묻지 않은 산인 선바위봉은 정상 서편에 선바위가 있어 생긴 산명인 것 같다.평평한 정상에는 오래된 삼각점이 있고 수림으로 둘러싸여 조망은 좋지 않으나, 서편으로 근접한 선바위에 오르면 가슴이 트이고, 치악산, 만경봉으로 이어 오르는 능선이 아련하다.마치 피사의 사탑처럼 오른쪽으로 약간 기운 선바위는 조선시대 최고의 화가 중 한사람인 겸재 정선의 산수화 한 폭을 기분이다. 작은 분지를 이룬 거운리 앞을 유유히 흐르는 동강과 선바위가 아름답게 어우러진다. 전망바위에서 북동으로는 잣봉이 보이고, 잣봉 남릉 너머로는 능암덕산 줄기와 멀리 닭이봉과 곰봉도 시야에 와닿는다.평평한 정상에는 오래된 삼각점이 있고 수림으로 둘러싸여 조망은 좋지 않으나, 서편으로 근접한 선바위에 오르면 가슴이 트이고, 치악산, 만경봉으로 이어 오르는 능선이 아련하다.", - "MNTN_HG_VL" : "1001", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 영월군", - "MNTN_NM" : "선바위봉" + "DETAIL_INFO_DTCONT" : "1\/5,000 지도에는 배나무산이라 나오며 동네에서는 선암산이라고도 한다. 호계면 선암리 상선암동네 뒷산이며 산북면 석봉리와 경계하며 호계면 부곡리 부운령에서 시작하여 배나무산을 지난 단산으로 이어지며 노송군락이 아주 좋다.", + "MNTN_HG_VL" : "814", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 석봉리", + "MNTN_NM" : "선암산" }, - "longitude" : 127.78638890000001, - "latitude" : 37.071944400000007 + "longitude" : 128.18333329999999, + "latitude" : 36.716666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "376", - "MNTN_LOCPLC_REGION_NM" : "경상북도 산청군 생초면", - "MNTN_NM" : "선바위산" + "DETAIL_INFO_DTCONT" : "충남 금산과 전북 완주 사이에 우뚝 솟은 선야봉은 숲이 울창하고 신선풀무대 그리고 암봉과 암릉, 바위낭떠러지, 폭포 등을 고루 갖춘 산이다. 남북으로 뻗은 크고 높은 산줄기와 그 사이로 나란히 뻗은 경관 좋은 느티골과 피묵이골이 산 아래로 흐르고 있다. 그 중 금산쪽에 위치한 느티골은 아름다운 계곡이 이어져 있고 숲이 울창한데다 자연휴양림을 조성하고 있어 훌륭한 휴식처로 개발되어 있다.느티골 안쪽에 높이 25미터의 쉰길폭포가 장관을 이룬다. 새로 개설한 선야봉 등산로는 폭포를 지나며 아기자기한 암릉을 거쳐 기암괴봉을 조망할 수 있는 능선으로 이어져 있어 많은 등산객과 휴양객들이 자연을 편하게 즐길 수 있는 곳이다.정상 능선에서 서쪽으로는 대둔산, 천등산, 서대산이 있고 동쪽으로는 전적지로 유명하며 경관이 뛰어난 백암산이 있다.", + "MNTN_HG_VL" : "759", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 남이면ㆍ전라북도 완주군 운주면", + "MNTN_NM" : "선야봉" }, - "longitude" : 128.81722049999999, - "latitude" : 37.148314300000003 + "longitude" : 127.3666667, + "latitude" : 36.048333300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "1\/5,000 지도에는 배나무산이라 나오며 동네에서는 선암산이라고도 한다. 호계면 선암리 상선암동네 뒷산이며 산북면 석봉리와 경계하며 호계면 부곡리 부운령에서 시작하여 배나무산을 지난 단산으로 이어지며 노송군락이 아주 좋다.", - "MNTN_HG_VL" : "814", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 석봉리", - "MNTN_NM" : "선암산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산", + "MNTN_NM" : "선야봉" }, - "longitude" : 128.9826621, - "latitude" : 35.387973100000004 + "longitude" : 127.3666667, + "latitude" : 36.048333300000003 }, { "mountain" : { @@ -6466,18 +5066,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", "MNTN_NM" : "선의산" }, - "longitude" : 128.77333329999999, - "latitude" : 35.726388900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;남천면의 주산이자 경산의 진산gt;경산시 남천면과 청도군 매전면을 가르는 선의산은 남천면의 주산으로 쌍계산이라고도 하며 ‘선녀가 하강하여 춤을 추는 형상’이라 하여 선의산(仙義山)이라 이름 하였다. 그러나 ‘仙義’가 ‘춤추는 선녀’와 무슨 연관이 있는지는 도무지 알 수 없다. 정상석의 ‘풍수지리설에 의하면 이곳의 정기를 받으면 8정승이 태어난다는 설화가 있고 산 정상에는 용정(龍井)이라는 샘이 있어 가뭄이 심할 때는 이곳에서 기우제를 올리기도 했다’고 전하는데, 이를 확인할 길은 없다. 이밖에 정상석에는 ‘쇠말뚝 뽑은 곳’이라는 표식이 있는데 1990년에 쇠말뚝을 뽑고 ‘일제만행’이라고 적어놓았다.지난해 전망데크를 깐 정상에서는 비슬지맥이 남쪽으로 이어지는데 5킬로미터 거리의 용각산(龍角山#8228;697.4m)이 우뚝 솟아있다. 남서쪽으로는 청도 남산 등 청도군 일대가 어렴풋이 보인다. 최근에는 선의산과 용각산을 잇는 종주산행이 인기인데 경산과 청도쪽 들머리를 합쳐 대략 10군데에서 접근할 수 있다. 그 중 원점회귀가 가능하고 등산로 정비가 가장 잘 되어 있는 곳이 경산 남천면의 송백2리의 도성사 기점으로, 가장 많이 찾는 코스로 꼽힌다.", - "MNTN_HG_VL" : "756", - "MNTN_LOCPLC_REGION_NM" : "상북도 경산시 남천면, 청도군 매전면", - "MNTN_NM" : "선의산" - }, - "longitude" : 128.77333329999999, - "latitude" : 35.726388900000003 + "longitude" : 128.77348799999999, + "latitude" : 35.727622799999999 }, { "mountain" : { @@ -6500,174 +5090,104 @@ "latitude" : 37.722222199999997 }, { - "mountain" : { - "DETAIL_INFO_DTCONT" : "계룡산 줄기 남쪽의 산으로 높이 507m로서 신현읍과 거제면의 경계에 위치하고 있으며 고현에서 구천계곡 쪽으로 들어가 수자원개발공사를 지나 삼거리 윗담마을에서 오르면 된다.가을에는 단풍나무가 아름답고 자작나무와 참나무가 무성하며 계곡 물이 맑고 깨끗하다. 이 계곡 물들이 굽이굽이 모여 구천댐 물을 이루고 있다.", - "MNTN_HG_VL" : "507", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", - "MNTN_NM" : "선자산" - }, - "longitude" : 128.62948639999999, - "latitude" : 34.847562099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "설악산은 한라산(1,947.3m),지리산(1,915.4m)에 이어 남한에서 세 번째로 높은 산으로 강원도 속초시와 양양군,인제군에 걸쳐 있다.옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.백두산에서 남쪽으로 내리뻗어 이 땅의 기나긴 등뼈를 이루는 백두대간의 허리를 받들고 있는 설악산은 북의 금강산과 남의 오대산 사이에 솟아있는 천하의 명산으로 우리나라 관광명소 1호로 꼽힌다. 지난 1965년 11월 5일 천연기념물지구(163.4㎞), `69년 관광지(16.2㎞) 그리고 '70년에는 국립공원(174㎞)으로 각각 지정되었다. 그리고 1971년 9월에는 설악산 국립공원 관리사무소가 개설 되었고 `77년 '78년 두차례에 걸쳐 354.6㎞로 확장되었으며, 그 후 다시 374㎞로 넓이를 확대하였다. 울산암 등산로 초입에 있는 신흥사는 대한불교 조계종 제3교구 본사로 설악산의 대표적 사찰이다. 신라때 자장율사가 노루목근처에 향성사로 창건했다가 조선조때 현위치에 다시 세웠다고 한다.", - "MNTN_HG_VL" : "1708", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동, 인제군 북면ㆍ인제읍, 양양군 서면ㆍ강현면", - "MNTN_NM" : "설악산" - }, - "longitude" : 128.46555810000001, - "latitude" : 38.119550400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.", - "MNTN_HG_VL" : "1708", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동", - "MNTN_NM" : "설악산 공룡능선" - }, - "longitude" : 128.46555810000001, - "latitude" : 38.119550400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "남면 홍현마을에 있는 설흘산(488m)은 망산(406m)과 인접해 있다. 설흘산에서 내려다보면 깊숙하게 들어온 앵강만이 한눈에 들어오고 서포 김만중의 유배지인 노도가 아늑하게 내려다보인다. 인접하고 있는 전남 해안지역 뿐만 아니라 한려수도의 아기자기한 작은 섬들도 조망할 수 있는 곳이다.설흘산 정상 부근에는 봉수대의 흔적이 남아 있다. 원래 봉수대는 주위를 넓게 관측할 수 있는 곳에 정하는데 설흘산 역시 한려수도와 앵강만 그리고 망망한 남쪽 대해를 관측할 수 있는 곳이다.남면 구미 지역과 응봉산으로 오르는 등산로는 망망대해와 기암괴석 그리고 아래로 내려다보이는 다랭이마을의 풍경을 제대로 즐길 수 있다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "경남 남해군 남면", - "MNTN_NM" : "설흘산" - }, - "longitude" : 127.8987633, - "latitude" : 34.737474499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "431", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", - "MNTN_NM" : "성미산" - }, - "longitude" : 126.908618, - "latitude" : 37.560164 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 임실과 진안을 사이에 두고 우뚝 솟은 성수산은 고려와 조선의 건국설화가 살아있는 유서 깊은 산이다. 그렇게 높은 산은 아니지만 정상의 조망이 빼어나고, 남쪽으로는 향나무와 낙엽송, 활엽수 등 수백만 그루의 잘 자란 나무들이 빼곡히 들어차 삼림욕을 하기에 좋다.성수산자연휴양림 입구에서 10여분 오르면 상이암을 만나는데 상이암은 875년 도선국사가 창건한 절로 초기에는 도선암으로 불렸다가, 조선시대 태조 이성계가 조선을 개국하기 전 이곳에 와 치성을 드리니 하늘에서 ‘왕이 될 것’이라는 소리가 들렸다 해서 상이암이라 고쳤다고 한다. 그래서인지 성수산 주변에는 이성계와 연관된 이야기가 많이 전해진다. 절 입구에는 이성계가 직접 썼다는 ‘삼청동’ 비가 세워져 있고, 왕방리는 이성계가 왜구를 물리치고 귀경하던 중 지나갔던 마을이라고 한다.한편 상이암은 의병대장 이석용이 항일운동의 근거지로 이용하던 곳인데 그 때문에 일제시대 일본군에 의해 강제로 소실되었다가 1958년 상이암재건위원들에 의해 다시 세워졌다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 성수면ㆍ진안군 백운면", - "MNTN_NM" : "성수산" - }, - "longitude" : 127.41567430000001, - "latitude" : 35.640969800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1060", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", - "MNTN_NM" : "성수산" - }, - "longitude" : 127.41567430000001, - "latitude" : 35.640969800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "471", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "성암산(감태봉)" + "mountain" : { + "DETAIL_INFO_DTCONT" : "설악산은 한라산(1,947.3m),지리산(1,915.4m)에 이어 남한에서 세 번째로 높은 산으로 강원도 속초시와 양양군,인제군에 걸쳐 있다.옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.백두산에서 남쪽으로 내리뻗어 이 땅의 기나긴 등뼈를 이루는 백두대간의 허리를 받들고 있는 설악산은 북의 금강산과 남의 오대산 사이에 솟아있는 천하의 명산으로 우리나라 관광명소 1호로 꼽힌다. 지난 1965년 11월 5일 천연기념물지구(163.4㎞), `69년 관광지(16.2㎞) 그리고 '70년에는 국립공원(174㎞)으로 각각 지정되었다. 그리고 1971년 9월에는 설악산 국립공원 관리사무소가 개설 되었고 `77년 '78년 두차례에 걸쳐 354.6㎞로 확장되었으며, 그 후 다시 374㎞로 넓이를 확대하였다. 울산암 등산로 초입에 있는 신흥사는 대한불교 조계종 제3교구 본사로 설악산의 대표적 사찰이다. 신라때 자장율사가 노루목근처에 향성사로 창건했다가 조선조때 현위치에 다시 세웠다고 한다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동, 인제군 북면ㆍ인제읍, 양양군 서면ㆍ강현면", + "MNTN_NM" : "설악산" }, - "longitude" : 128.67776799999999, - "latitude" : 35.793171000000001 + "longitude" : 128.46555810000001, + "latitude" : 38.119550400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "영남과 호남 사이를 흐르는 섬진강을 눈으로 좇으며 올라가는 성제봉(형제봉)은 암릉과 암봉이 이어지는 능선이 일품이다.고소성에서 봉수대,신선대,1052봉,성제봉,깃대봉으로 이어지는 성제봉 능선에는 노송지대와 온갖 기암과 반석,널찍한 억새밭, 조릿대 숲길, 넓은 철쭉 군락지 등으로 이어져 매우 아름답다. 5월 중순에는 철쭉제가 성대히 개최된다.또한 대하소설 `토지'의 무대로 유명한 평사리와 악양들을 만날 수 있다. 최근에는 소설의 배경을 그대로 재현해 놓은 최참판댁이 단장을 하고여행객들을 맞이하고 있고, 최참판댁 뒤로 고소성 군립공원이 있어섬진강의 굽이굽이를 내려다보기에 더없이 좋다 .평사리 일대에는 지리산 능선이 남으로 내달린 끝인 성제봉 아래 넓은 평야지대와 섬진강가의 동정호까지 펼쳐져 있다. 또한 고소산성을 비롯 통천문 신선바위 등 문화유적과 볼거리가 많아 힘들이지 않고 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "1115", - "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면, 화개면", - "MNTN_NM" : "성제봉" + "DETAIL_INFO_DTCONT" : "옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동", + "MNTN_NM" : "설악산 공룡능선" }, - "longitude" : 127.6751435, - "latitude" : 35.193591599999998 + "longitude" : 128.4504379, + "latitude" : 38.145543600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "박경리의 소설 「토지」의 무대인 악양면 평사리. 악양은 남쪽으로 굽이쳐 흐르는 섬진강을 내어놓고, 삼면이 지리산 남부 능선 끝자락에 둘러싸여 있다. 멀리 지리산otilde;왕봉에서 제석봉, 촛대봉을 거쳐 남부능선을 따라 내려온 산줄기는 거사봉(1133m)에서 좌우로 갈래를 친다. 성제봉(1115.5m, 일명 형제봉)과 신선봉(586m), 칠성봉과 구재봉(767.6m)이 병풍oacute;럼 둘러싸며 악양의 너른 벌판에 젖줄이 된다. 악양은 중국의 악양과 닮았다 하여 지어진 이름이다. 악양을 둘러싼 산줄기는 어림잡아 도상거리 30여 킬로미터. 지리산 주능선이 25킬로미터 정도임에 비할 때 그 장대함을 알 수 있다. 이 코스를 종주하게 되면 북으로는 노고단에서 반야봉, 제석봉,otilde;왕봉 지리산 종주 코스가 한 눈에 들어오고, 남으로는 토지의 주무대인 악양면 평사리와 최참판댁, 동정호 그리고 굽이도는 섬진강과 백사장, 그 너머로 백운산이 겹겹이 펼쳐진다. 또한 거사봉에 서면 이상향으로 이름난ucirc;학동이 눈앞에 펼쳐진다.", - "MNTN_HG_VL" : "964", - "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면", - "MNTN_NM" : "성제봉(형제봉)" + "DETAIL_INFO_DTCONT" : "남면 홍현마을에 있는 설흘산(488m)은 망산(406m)과 인접해 있다. 설흘산에서 내려다보면 깊숙하게 들어온 앵강만이 한눈에 들어오고 서포 김만중의 유배지인 노도가 아늑하게 내려다보인다. 인접하고 있는 전남 해안지역 뿐만 아니라 한려수도의 아기자기한 작은 섬들도 조망할 수 있는 곳이다.설흘산 정상 부근에는 봉수대의 흔적이 남아 있다. 원래 봉수대는 주위를 넓게 관측할 수 있는 곳에 정하는데 설흘산 역시 한려수도와 앵강만 그리고 망망한 남쪽 대해를 관측할 수 있는 곳이다.남면 구미 지역과 응봉산으로 오르는 등산로는 망망대해와 기암괴석 그리고 아래로 내려다보이는 다랭이마을의 풍경을 제대로 즐길 수 있다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경남 남해군 남면", + "MNTN_NM" : "설흘산" }, - "longitude" : 127.27, - "latitude" : 37.207777800000002 + "longitude" : 127.8987633, + "latitude" : 34.737474499999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주봉은 백두대간상의 대마산에서 남쪽으로 갈라진 지맥상의 운달산 서편에서 솟은 아름다운 암산이며 매우 깨끗하나 등산로가 험준하지만 운달산에서 문경읍쪽으로 붙어 있는 암벽이 보기 좋은 산이다.주능선은 대부분 암릉과 노송으로 어우러지고, 직벽을 따라 내려선 안부에서 다시 직벽을 기어오르는 협곡이 연속된다. 운달산 정상에서 능선을 타고 성주봉으로 종주할 수 있으나 자일과 암벽장비가 있어야 안전하다. 문경읍 당포리에서 성주봉만을 등산할 수 있다.서쪽 주흘산 연봉이 매력적으로 펼쳐 보이고, 북쪽 대미산과 남쪽 단산, 봉명산, 백화산 등의 조망이 좋다.당포리 마을은 약330년 전에 형성된 마을이라 전해오고 있으며 마을 가운데로 계곡변에는 수백년 된 느티나무 숲(휴식공원)이 있다. 성주봉은 기세 등등한 장군이 자리를 잡고 버티고 서 있는 형상을 하고 있어 이곳 당포리 일대 주민들은 성주봉을 흔히들 ‘장군봉’이라고 부르기도 한다.", - "MNTN_HG_VL" : "607", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 김룡리", - "MNTN_NM" : "성주봉" + "DETAIL_INFO_DTCONT" : "산정에 부처님을 닮은 불상이 있다하여 이름 붙여졌다는 성불산은 충북 괴산군 감물면에 울창한 삼림을 등에 지고 아담히 솟아있는 산이다. 충북 괴산군에는 아직까지 사람의 발길이 많이 닿지않아 천연의 자연상태를 보존하고 있는 산들이 다수 있는데, 성불산도 그 중 하나다.소백산의 지맥으로 갈라져 나와 다소곳이 앉아있는 성불산은 산 규모도 작고 외진 곳에 위치하여 산악인들에게 별로 알려지지 않은 산이다. 가벼이 산책하듯 오르내릴 수 있는 산이라 생각하기 십상이나, 작은 산등성엔 험준한 암봉들이 십여개가 늘어서 있고, 그 사이마다에는 노송들이 하늘을 가리우고 있어, 풍광면에서나 산행 난이도 면에서나 결코 만만히 봐서는 안된다.정상에서는 모산인 박달봉이 동쪽으로 근접해있고, 남동쪽으로는 덕가산, 치로산, 보배산 등이 둘러싸고, 서쪽 편에는 고산구경을 품고 있는 달천이 감돌아 흐른다. 강 건너 괴산 시내를 한눈으로 내려다 볼 수 있는 위치에 있는 명산이다.", + "MNTN_HG_VL" : "532", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 감물면 매전리", + "MNTN_NM" : "성불산" }, - "longitude" : 128.04104889999999, - "latitude" : 36.534782100000001 + "longitude" : 127.8619885, + "latitude" : 36.814836700000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주봉은 경상북도 문경시 문경읍 당포리와 용연리의 경계에 우뚝 솟아있는 바위산이다. 문경읍에서 5분 거리면 닿을 수 있는 산이지만 그리 알려지지 않은 탓에 때 묻지 않은 보석 같은 산이다.운달산(1097.2m)에서 서쪽으로 뻗어 내리다 당장이라도 포효하며 뛰어 오를 듯이 단단한 근육질의 몸으로 기세당당하게 자리 잡고 있다. 같은 산군이면서도 육산에 가까운 운달산과 달리 그림 같은 암봉미를 갖추고 있다.성주봉 산행은 당포리 입구에서 시작한다. 마을에 들어서면 정면으로 하얀 속살을 드러낸 성주봉 주능선 봉우리들이 치솟아 있다. 멀리서 보면 깎아지른 절벽 사이에 간혹 나무들이 보일 뿐 등산로가 있으리라고는 상상이 안 되는 산이다. 그 만큼 험악한 산으로 산행 시는 특히 조심해야 한다. 기본적인 암벽 장비와 보조 자일을 갖춰야 안전하게 암릉을 즐길 수 있다.", - "MNTN_HG_VL" : "961", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 당포리, 용연리", - "MNTN_NM" : "성주봉" + "DETAIL_INFO_DTCONT" : "제주시에서 동쪽으로 48km 떨어져 있는 성산포 바닷가에는 삼면이 바다로 둘러싸인 성산반도의 위쪽에 분화구로 이루어진 돌산이 있다.이곳이 바로 아름다운 성산일출봉인데, 한덩이의 왕관같은 99개 기암 봉우리와 짙푸른 바다 위를 솟아 오르는 아침 햇살이 장관을 이룬다.", + "MNTN_HG_VL" : "182", + "MNTN_LOCPLC_REGION_NM" : "제주도 남제주군 성산읍 성산리 114", + "MNTN_NM" : "성산 일출봉" }, - "longitude" : 128.04104889999999, - "latitude" : 36.534782100000001 + "longitude" : 126.9425, + "latitude" : 33.458056000000013 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주봉은 도장산에서 그리 멀지 않은 남산 줄기의 한 봉우리다. 남산은 칠봉산 남쪽에 위치해 남산이라 이름 붙었으며 웬만한 지도에도 나오지만 상주 사람들은 남산보다는 노송과 암릉, 기암들의 경관이 뛰어난 성주봉을 좋아한다. 더구나 성주봉 아래에는 자연휴양림이 만들어져 교통도 편리하며 원점회귀를 할 수 있는 등산 코스라 승용차로 다녀오기 좋다.특히 크게 힘들지 않고 오를 수 있어 남녀노소 가리지 않고 좋아할 수 있는 산이다. 성주봉 정상의 암봉은 낙락장송과 어우러져 경관이 매우 뛰어나며 속리산, 대야산, 희양산, 주흘산과 소백산까지도 볼 수 있어 조망이 아주 좋다.또한 성주봉과 골짜기 건너 북쪽의 칠봉산에는 삼국지의 인물인 조자룡과 관련된 전설이 전해져 온다. 그래서 칠봉산 중턱 커다란 암벽 옆에는 조자룡 굴이 있다. 그리고 성주산자연휴양림 관리사무소에서 성주봉 정상으로 오르는 산등성이 암벽에 자리잡은 성주봉의 명소인 약수샘은 그 환경이 참으로 희한하며 물맛 또한 좋다.", - "MNTN_HG_VL" : "912", - "MNTN_LOCPLC_REGION_NM" : "경북 상주시 은척면", - "MNTN_NM" : "성주봉" + "DETAIL_INFO_DTCONT" : "전북 임실과 진안을 사이에 두고 우뚝 솟은 성수산은 고려와 조선의 건국설화가 살아있는 유서 깊은 산이다. 그렇게 높은 산은 아니지만 정상의 조망이 빼어나고, 남쪽으로는 향나무와 낙엽송, 활엽수 등 수백만 그루의 잘 자란 나무들이 빼곡히 들어차 삼림욕을 하기에 좋다.성수산자연휴양림 입구에서 10여분 오르면 상이암을 만나는데 상이암은 875년 도선국사가 창건한 절로 초기에는 도선암으로 불렸다가, 조선시대 태조 이성계가 조선을 개국하기 전 이곳에 와 치성을 드리니 하늘에서 ‘왕이 될 것’이라는 소리가 들렸다 해서 상이암이라 고쳤다고 한다. 그래서인지 성수산 주변에는 이성계와 연관된 이야기가 많이 전해진다. 절 입구에는 이성계가 직접 썼다는 ‘삼청동’ 비가 세워져 있고, 왕방리는 이성계가 왜구를 물리치고 귀경하던 중 지나갔던 마을이라고 한다.한편 상이암은 의병대장 이석용이 항일운동의 근거지로 이용하던 곳인데 그 때문에 일제시대 일본군에 의해 강제로 소실되었다가 1958년 상이암재건위원들에 의해 다시 세워졌다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 성수면ㆍ진안군 백운면", + "MNTN_NM" : "성수산" }, - "longitude" : 128.04104889999999, - "latitude" : 36.534782100000001 + "longitude" : 127.41567430000001, + "latitude" : 35.640969800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주산은 오서산과 함께 보령을 상징하는 명산으로 예로부터 성인, 선인이 많이 살았다 하여 성주산이라 부르고 있다. 성주산에는 질 좋은 소나무를 비롯, 느티나무, 굴참나무, 졸참나무, 때죽나무, 고로쇠나무 등이 자생하고 있는데 한낮에도 컴컴할 정도로 울창한 숲을 이루고 있다.또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다. 특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다.성주산 일대에 모란형의 명당8개소(성주8묘)가 있었는데 그중 하나가 이곳에 감추어져 있다하여 화장골이란 이름이 붙여졌다. 지금도 명당을 찾으려는 이들의 발길이 잦은 곳이기도 하다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.소요 시간 :150분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 심연동 계곡,삼림욕장,잔디광장, 전망대성주휴양림의 자랑거리가 되고 있는 숲속의 집 통나무 방갈로는 여름철뿐만 아니라 단풍이 짙어가는 가을철이나 흰눈에 싸인 겨울철에도 더할나위 없는 좋은 휴양시설로 각광받고 있다. 휴양림을 찾는 이들의 발길은 아무래도 여름철에 절정을 이룬다. 이때에는 이동도서관이 마련돼 이용자는 얼마든지 책을 대여해 시원한 계곡물에 발을 담그고, 혹은 삼림욕을 하면서 독서 삼매경에 빠질 수 있다.숲길 명소 : 휴양림 입구에서 정상 쪽으로 5백미터 오르면 휴양림을 만날 수 있고, 심연동 계곡쪽에도 휴양림 공간이 마련되어 있다. 또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다.특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.성주산 휴양림에서 정상까지 올라 산 뒤편으로 내려가도 심연동 계곡과 연결되어 있다. 예부터 깊은 골짜기가 있는 마을이라 하여 심연동이라 이름지어진 것처럼 골과 골 사이에 흘러내리는 계곡이 깊고 수려하다.휴양을 위한 각종 편의시설이 설치된 중앙의 코스 외에 외곽으로 따로 등산객을 위한 등산로가 성주산 정상까지 나 있다. 봄에는 만발한 온갖 꽃들의 안내를 받으며, 여름에는 신록의 축복 속에서 삼림욕을 하고, 가을엔 수려한 단풍에 취한 채, 겨울엔 통나무 방갈로에서 아름다운 설경을 음미할 수 있는 곳이 바로 성주산 자연휴양림이다.", - "MNTN_HG_VL" : "512", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", - "MNTN_NM" : "성주산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1060", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", + "MNTN_NM" : "성수산" }, - "longitude" : 128.09380289999999, - "latitude" : 36.699771499999997 + "longitude" : 127.4813889, + "latitude" : 35.721388900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주산은 마성면 정리에서 백화산 쪽으로 나와 보이는 산으로서 산 모양이 성군이 앉아 있는 모양이라 성주산이라 칭하였다. 백화산에서 내려온 큰 줄기가 성주산과 옥녀봉으로 갈라지며 그 중간 계곡이 대골이고 봉명 초등학교가 있는 곳이다. 오르는 길은 마성면 솥골에서 상내리로 넘어가는 나리재에서 백화산으로 오르다가 성주산으로 갈 수 있고 아니면 솥골에서 바로 올라가도 된다. 마성면 정리에서 보면 큰 돌서덜이 보인다.자그마한 봉우리인 정상에는 삼각점, 정상석, 팻말 등 이 전혀 보이지 않는 순결의 심산이다.", - "MNTN_HG_VL" : "712", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 상내리", - "MNTN_NM" : "성주산" + "DETAIL_INFO_DTCONT" : "면적 72평방 킬로미터에 둘레가 44.12킬로미터인 울릉도는 포항에서 뱃길로 188킬로미터 떨어진 섬으로 독도를 포함해서 본토에서 가장 멀리 있는 섬이다. 섬 주변은 대부분 화산암의 해안절벽으로 되어 있는데 바로 이 섬 중심부에 성인봉이 자리해 있다.작은 땅, 울릉도 위에 하나의 봉우리가 솟아 있으니 성인봉이 곧 울릉도인 셈이다. 울릉도는 오래전부터 왕조들의 정책에 의해 백성들을 살 수 없게 하였던 곳이나 백성들이 몰래 숨어 들어 끝끝내 우리 땅으로 지켜낸 우리 민족의 기상이라고 할 수 있다. 울릉도에 관한 기록은 신라시대로 거슬러 올라간다.〈삼국사기〉와 〈삼국유사〉에 신라 22대 지증왕 때 울릉도에 관한 기록이 있다. 〈삼국사기〉에는 지증왕 13년에 우산국(于山國)이 항복했고, 하실라 군주 이사부(異斯夫)가 나무로 만든 사자를 싣고 가서 항복을 받았다고 기록되어 있는데 〈삼국유사〉의 기록은 조금 다르다. 〈삼국 유사〉에 따르면 아슬라주 동쪽 바다에서 순풍으로 이틀 걸리는 곳에 우릉도(于陵島)가 있고 이 섬에 사는 오랑캐들은 교만하게 바닷물이 깊은 것을 믿고 조공을 바치지 않아 이창 박이종(朴伊宗)이 나무사자로 위협해 항복시켰다고 한다.울릉도는 겨울에는 따뜻하고 여름에는 시원해서 누구라도 살기 좋고 모든 것이 풍요롭다. 특히 '3무'라고 해서 도둑,거지,뱀이 없고 '5다'라고 하여 향(香),풍(風),미(美),수(水),석(石))이 많기로 이름나 있다. 해안가로 나가면 구멍바위(공암), 거북바위, 사자바위, 곰바위, 말바위, 국수를 널어놓은 듯한 국수바위 등 기암괴석을 쉽게 볼 수 있다. 성인봉 북쪽 하산 길에 있는 이십 여만 평의 나리분지에는 억새 밭과 나리꽃 군락이 서쪽으로 솟아 있는 알봉(538)과 어우러져 비경을 자아낸다.울릉도 서쪽 끝 태화동에는 울릉도의 대표적 사당인 성하신당이 자리잡고 있다. 이곳 주민들은 매년 음력 2월에 농사와 어업의 풍년,풍어를 빌고 있다.전설에 의하면 성하신당은 조선 태종 때 안무사로 왔던 김인우가 세웠다고 한다. 안무사 김인우가 심한 풍랑으로 본토에 돌아가지 못하고 있을 때 신의 지시를 받고 젊은 남녀 한 쌍 태하동에 억지로 떼어놓고 본토로 돌아갈 수 있었는데 몇 년 뒤 울릉도에 다시 와 보니 두 사람이 껴안은 채 백골이 되어 있어 그들의 원혼을 달래기 위해 세운 사당이라 한다. 저동에서 봉래폭포로 이어지는 등산로에는 바위틈에서 찬바람이 나오는 〈천연에어컨〉이 땀을 시켜 준다.천연에어컨에서 정상으로 이어지는 등산로를 따라 약 40분 오르면 세 갈래 물줄기가 원시림을 뚫고 쏟아지는 봉래폭포를 만나게 된다. 나리분지에서 산행이 끝나는 지점인 천부선착장을 따라 서쪽으로 2백미터정도 걷다보면 바위굴 속에서 찬바람이 나오는 풍혈(風穴)이 있다. 봉래폭포쪽 천연에어컨보다 못하지만 여름 땀을 씻어내기에는 충분하다.", + "MNTN_HG_VL" : "987", + "MNTN_LOCPLC_REGION_NM" : "경상북도 울릉군 울릉읍 서면ㆍ북면", + "MNTN_NM" : "성인봉" }, - "longitude" : 128.09380289999999, - "latitude" : 36.699771499999997 + "longitude" : 130.86615280000001, + "latitude" : 37.503257099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부천의 주산인 성주산은 시흥시와 인천시 경계에 위치하고 있다. 시흥의 주산인 소래산과 그 맥을 같이 하고 있으며, 성주산 정상의 높이는 해발 217m이고 도로로 단절되었던 하우고개 여우고갯길 은 현재 구름다리와 에코브릿지가 설치되어 아름다운 산으로 연결되었다. 성주산의 형세는 현재는 멀리 고층건물에서 관찰해야 볼 수 있지만 도시화가 되기 이전인 1960년 대 까지만 하여도 벌막쪽에서 보면 소가 앉아 있는 형세를 볼 수 있어 와우산(臥牛山)이라 불렀다. 성주산은 접근성이 좋아 시민들의 산책코스로 많이 이용되고 있다. 산주변부는 약수터공원 산새공 원 체육공원이 조성되어 더욱더 아름답고 깨끗하다. 산책로 주변에 편의시설물이 많아 이용에 불 편이 없으며 약수터 또한 많이 있는 산이다. 등산로는 깨끗이 정비되어 있지만 급경사 또한 맣아 등산화 준비가 필요한 곳이다.", - "MNTN_HG_VL" : "217", - "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", + "DETAIL_INFO_DTCONT" : "성주산은 오서산과 함께 보령을 상징하는 명산으로 예로부터 성인, 선인이 많이 살았다 하여 성주산이라 부르고 있다. 성주산에는 질 좋은 소나무를 비롯, 느티나무, 굴참나무, 졸참나무, 때죽나무, 고로쇠나무 등이 자생하고 있는데 한낮에도 컴컴할 정도로 울창한 숲을 이루고 있다.또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다. 특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다.성주산 일대에 모란형의 명당8개소(성주8묘)가 있었는데 그중 하나가 이곳에 감추어져 있다하여 화장골이란 이름이 붙여졌다. 지금도 명당을 찾으려는 이들의 발길이 잦은 곳이기도 하다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.소요 시간 :150분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 심연동 계곡,삼림욕장,잔디광장, 전망대성주휴양림의 자랑거리가 되고 있는 숲속의 집 통나무 방갈로는 여름철뿐만 아니라 단풍이 짙어가는 가을철이나 흰눈에 싸인 겨울철에도 더할나위 없는 좋은 휴양시설로 각광받고 있다. 휴양림을 찾는 이들의 발길은 아무래도 여름철에 절정을 이룬다. 이때에는 이동도서관이 마련돼 이용자는 얼마든지 책을 대여해 시원한 계곡물에 발을 담그고, 혹은 삼림욕을 하면서 독서 삼매경에 빠질 수 있다.숲길 명소 : 휴양림 입구에서 정상 쪽으로 5백미터 오르면 휴양림을 만날 수 있고, 심연동 계곡쪽에도 휴양림 공간이 마련되어 있다. 또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다.특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.성주산 휴양림에서 정상까지 올라 산 뒤편으로 내려가도 심연동 계곡과 연결되어 있다. 예부터 깊은 골짜기가 있는 마을이라 하여 심연동이라 이름지어진 것처럼 골과 골 사이에 흘러내리는 계곡이 깊고 수려하다.휴양을 위한 각종 편의시설이 설치된 중앙의 코스 외에 외곽으로 따로 등산객을 위한 등산로가 성주산 정상까지 나 있다. 봄에는 만발한 온갖 꽃들의 안내를 받으며, 여름에는 신록의 축복 속에서 삼림욕을 하고, 가을엔 수려한 단풍에 취한 채, 겨울엔 통나무 방갈로에서 아름다운 설경을 음미할 수 있는 곳이 바로 성주산 자연휴양림이다.", + "MNTN_HG_VL" : "512", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", "MNTN_NM" : "성주산" }, - "longitude" : 128.09380289999999, - "latitude" : 36.699771499999997 + "longitude" : 126.6788646, + "latitude" : 36.365286699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부천의 주산인 성주산은 시흥시와 인천시 경계에 위치하고 있다. 시흥의 주산인 소래산과 그 맥을 같이 하고 있으며, 성주산 정상의 높이는 해발 217m이고 도로로 단절되었던 하우고개 여우고갯길 은 현재 구름다리와 에코브릿지가 설치되어 아름다운 산으로 연결되었다. 성주산의 형세는 현재는 멀리 고층건물에서 관찰해야 볼 수 있지만 도시화가 되기 이전인 1960년 대 까지만 하여도 벌막쪽에서 보면 소가 앉아 있는 형세를 볼 수 있어 와우산(臥牛山)이라 불렀다. 성주산은 접근성이 좋아 시민들의 산책코스로 많이 이용되고 있다. 산주변부는 약수터공원 산새공 원 체육공원이 조성되어 더욱더 아름답고 깨끗하다. 산책로 주변에 편의시설물이 많아 이용에 불 편이 없으며 약수터 또한 많이 있는 산이다. 등산로는 깨끗이 정비되어 있지만 급경사 또한 맣아 등산화 준비가 필요한 곳이다.", - "MNTN_HG_VL" : "217", - "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", - "MNTN_NM" : "성주산" + "DETAIL_INFO_DTCONT" : "성지봉은 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑다. 금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서남으로 뻗어나가고 있다.경기도 양평군 청운면과 강원도 횡성군 서원면의 경계를 이루는 성지봉 (791m)은 산 이름에서 나타나듯이 천주교와 관계가 깊은 곳이다. 조선 순조 원년(1801년)의 신유 박해와 고종 3년 (1866년) 병인양요, 고종 8년 (1871년) 신미양요 등으로 극심하게 탄압 받았던 천주교 신도들이 이곳 성지봉으로 숨어 들었다고 한다.직행버스는 성지봉 입구에 정차하지 않으므로 청운에서 횡성 방향으로 1.5km 못 미친 풍수원에 하차 하여야 한다. 풍수원 마을 가장 윗쪽에 강원도 유형문화재 제 69호로 지정된 풍수원 천주교회가 자리잡고 있다. 이 교회가 옛날 천주교인들의 피난처였던 것이다. 천주교회는 고종 27년 (1888년) 프랑스인 르메르이신부가 초가집 사랑방에서 초대 신부로 부임해 한국에서 네 번째 천주교회로 출발한 곳으로 유명하다.", + "MNTN_HG_VL" : "791", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 청운면, 강원도 횡성군 서원면", + "MNTN_NM" : "성지봉" }, - "longitude" : 128.09380289999999, - "latitude" : 36.699771499999997 + "longitude" : 127.84222219999999, + "latitude" : 37.5416667 }, { "mountain" : { @@ -6676,18 +5196,18 @@ "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구 신탄진동", "MNTN_NM" : "성치산" }, - "longitude" : 127.4476619, - "latitude" : 35.992483900000003 + "longitude" : 127.48277779999999, + "latitude" : 36.432499999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도의 산이라 하면 일반적으로 높은 봉우리와 명산들을 손꼽기 마련인데 성치산은 불과 500m 남짓의 낮은 산인데다가 춘천에서 홍천으로 이어지는 국도변에 인접해 있어 그냥 지나치기 쉬운 평범한 봉우리이다.나지막한 산이지만, 남북으로 잇는 주능선이 의연하고 떡갈나무,굴참나무등 참나무류가 산초 나무와 어울려 길을 가린다. 싸리나무, 진달래등 잡초들도 많아 터널 길을 지나는 듯 구부리고 가야 할 때가 적지 않다. 특히 등산 초입인 원골과 진골 일대는 장송이 하늘을 가려 마치 심산에 온 느낌을 준다. 불금봉에서 정상에 이르는 주능선길 도중엔 몇 개의 무덤이 자리잡고 있어 그때마다 전망이 열리기도 한다.정상에는 괴이한 모양의 바위가 서 있고 북동쪽으로 절벽을 이루면서 기암괴봉이 늘어서 있다. 또 그 아래 용담저수지가 아름답기 그지없다. 샛성골로 가는 하산길은 처음엔 다소 긴장이 되지만, 잠시 후에는 수월하게 내려갈 수 있다. 특히 강원도 홍천에 자리하고 있어 인적이 드물어 깨끗한 자연 그대로는 보존하고 있는 산중의 하나이다. 그러나 이 근래에 사람들이 제멋대로 성치산 명함을 밖아놓았다하니 성치산도 사람의 발굽에서 시름할 날이 머지않다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면", - "MNTN_NM" : "성치산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "631", + "MNTN_LOCPLC_REGION_NM" : "충청남도 부여", + "MNTN_NM" : "성태산" }, - "longitude" : 127.4476619, - "latitude" : 35.992483900000003 + "longitude" : 126.7236111, + "latitude" : 36.373333299999999 }, { "mountain" : { @@ -6739,6 +5259,16 @@ "longitude" : 127.61368330000001, "latitude" : 37.637732100000001 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "무술목 남쪽 크고 아름다운 산이란 뜻을 가진 대미산(大美山)이 있는데 이에 비해 작다고 하여 소미산(小美山)이란 명칭을 붙였다고 한다. 돌산도(突山島)에는 대미산,소미산,수죽산,천마산,봉황산,두산(斗山),천왕산,금오산의 8대 명산이 있는데 소미산이 그 중 하나이다.대미산 북쪽 해발 210m에 위치하고 있으며, 무술목에서 오르는 코스와 소굴전마을에서 오르는 코스가 있다. 산의 높이가 낮고 또 인근에 높은 산이 없어서 관망하기에 좋은 산이다. 인근에 무술목유원지와 해수욕장, 해양수산과학관이 있어 가족 관광지로서도 아주 좋은 곳이다.", + "MNTN_HG_VL" : "210", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 돌산", + "MNTN_NM" : "소미산" + }, + "longitude" : 127.7763889, + "latitude" : 34.688611100000003 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경상북도와 충청북도의 경계를 이루고 있는 소백산은 우리 나라 12대 명산 중의 하나로 '한국의 알프스' 라 불린다. 이 산은 총 면적이 320.5km에 달하는 거대한 산줄기로 정상인 비로봉을 비롯하여 연화봉(1,376.9m). 제 2 연화봉(1,357.3m). 국망봉(1,420.8m) 등 1천m 고봉이 줄지어 있어 웅장한 산세를 이루고 있다.", @@ -6749,16 +5279,6 @@ "longitude" : 128.446123, "latitude" : 36.951719900000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "오대산 두로봉에서 뻗어 나온 한강기맥은 청량봉(1052m)에서 춘천지맥으로 흘러나와 북한강을 따라 고개를 돌다가 경기도 가평 어귀에서 맥을 다한다. 응봉산(1097m)~백암산(1099m)~가마봉(1192)~소뿔산(1108m)으로 불거져 나오는 춘천지맥은 소양호에 막혀 남서방향으로 틀어 매봉(800m)~가리산(1051m)~연엽산(850m)으로 점차 고도를 낮추며 형세를 이루고 있다. 무엇보다도 이 지역의 백미는 가마봉에서의 조망이다. 북동으로 설악산(1708m)과 동으로 방태산(1435m), 오대산(1563m)의 자락들이 내려다보이며, 남으로는 수려한 공작산이 자리해 있다. 마치 등대에 올라 먼 바다를 꿈꿔보는, 양 시력이 허락하는 한 눈앞에 거슬리는 것이 없다. 소뿔산 정상에 서면 작은 암각도 발견할 수 없다. 하지만 소뿔산을 지나 백암산 자락에서 소뿔산을 바라보면 무명봉과 함께 이어진 소뿔산 산세 모양이 소의 뿔과 같이 생겼음을 알 수 있다.", - "MNTN_HG_VL" : "1108", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", - "MNTN_NM" : "소뿔산" - }, - "longitude" : 128.1408333, - "latitude" : 37.8938889 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "서울에서 44km, 동두천시청에서 동북쪽으로 약 5km의 거리에 있는 소요산은 경치가 뛰어나 경기도의 '소금강'이라 불린다.", @@ -6776,18 +5296,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", "MNTN_NM" : "소주봉" }, - "longitude" : -79.433894899999999, - "latitude" : 43.795823200000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "한반도의 등줄기인 백두대간(白頭大幹)과 서해바다까지 뻗어 나간 한남금북정맥(漢南錦北正脈)의 분기점에 솟아 올라 조선팔경의 하나이자 소금강, 또는 제 2의 금강이라 불리는 속리산(1,058.4m)은 행정구역상으로는 충북 보은과 경북 상주에 걸쳐 있는 명산이다.", - "MNTN_HG_VL" : "1058", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 보은군 내속리면", - "MNTN_NM" : "속리산" - }, - "longitude" : 127.90000000000001, - "latitude" : 36.533332999999999 + "longitude" : 127.66861110000001, + "latitude" : 37.762500000000003 }, { "mountain" : { @@ -6799,16 +5309,6 @@ "longitude" : 126.254693, "latitude" : 34.851599899999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "북한 개성이나 제주도에 `송악' 이란 지명이 있는데 두 곳 모두 민족의 애환이 서려 있다. 경기도 가평군에 있는 송악산은 두 산과 별개로 백둔리 토박이 주민들이 지어낸 산이다.", - "MNTN_HG_VL" : "705", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "송악산" - }, - "longitude" : 126.29192190000001, - "latitude" : 33.1977951 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "송학산은 제천에서 영월로 뻗는 38번 국도에서 왼쪽으로 올려다 보이는 산으로, 산 전체가 거의 소나무 일색이며, 송학산 자락은 주변으로 채석장이 여러 곳 있어 질 좋은 화강암이 생산되던 곳이다.산 이름 그대로 아름드리 노송은 많지 않지만 산 전체가 거의 소나무 일색으로 산행 내내 코끝을 스치는 그윽한 솔향이 일품이며, 푹신한 솔잎을 밟으며 청산의 푸른 기운을 느낄 수 있다.정상 바로 아래에는 빼어난 조망을 가진 강천사가 있으며, 짧은 코스지만 정상에 올라서면 송학면 일대의 조망이 일품이다. 남쪽으로는 무등산, 왕박산, 갑산, 가창산이 첩첩으로 포개지며 서북쪽으로는 제천의 진산 용두산과 그 뒤에 석기암, 감악산이 한 눈에 들어온다.강천사에서 조금 내려오면 급하게 굽이도는 언덕 너머에 빈대로 망했다는 전설의 소악사지가 있으며 3층석탑만 외로이 남아 무상한 역사를 말해준다.", @@ -6859,16 +5359,6 @@ "longitude" : 127.98164250000001, "latitude" : 35.859287100000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도봉산과 마주 보고 있는 수락산은 상계동에 대단위 아파트촌이 건립되면서 상계아파트 단지의 뒷산이 되었다. 도봉산에 비해 규모는 작지만 산 곳곳에 노출된 암벽으로 인해 경관이 뛰어나고 동쪽에는 신라 때 창건된 내원암과 흥국사가 있다.산 전체가 화강암과 모래로 이루어져 있고 기암괴석과 샘, 폭포가 많은 반면 나무는 매우 적다. 산의 분위기가 다소 삭막하기는 하나 바위의 경치가 뛰어나고 곳곳에 맑은 물이 흘러내린다. 수락 8경이라 불리는 금류폭, 은류폭, 옥류폭포와 동서 산록의 계곡에는 수락산유원지와 벽운동유원지가 있다.산세가 웅장할 뿐만 아니라 산 전체가 석벽과 암반으로 되어 있어 도처에 기암괴석이 즐비하다. 장암동에는 조선 숙종 때 형조판서를 지낸 서계 박세당의 정자인 6각형의 궤산정이 있다.", - "MNTN_HG_VL" : "641", - "MNTN_LOCPLC_REGION_NM" : "서울시 노원구 상계동", - "MNTN_NM" : "수락산" - }, - "longitude" : 127.08223340000001, - "latitude" : 37.696492999999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "수레의산은 충북 음성군에 위치한 아담한 산이다. 아직 사람의 발길과 개발의 손길이 미치지 않아서 천연의 순박함을 그대로 간직하고 있는데,이 산은 이름부터가 특이하다. 산 서쪽 계곡에는 청소년수련원과 차곡저수지가 있고 수량이 많으며 수리산에서부터 산서릉의 459번도로까지 임도가 잘 뚫려있다. 박쥐굴, 굴법당, 공기바위, 병풍바위, 상여바위, 전설의못등 볼거리가 많고, 산행시간이 짧고 등산로가 잘 닦여있어 가족산행지로 제격이다.수레의산은 신비의 산이며 숨어있는 산이다. 600m가 넘는 높은 등성이(주능선)에 25평이 넘는 연못이 있고, 거기에 꽤 많은 물이 고여 있다. 이른바 전설의 못이다. 잘 이해가 되지 않는 현상이다. 수레의산은 신비스러운 산답게 사람들의 눈에 잘 띄지 않는 곳에 조용히 숨어 있다. 큰 도로들이 거미줄처럼 얽혀 있는 지금의 상황에서는 웬만한 산은 큰 길에서 그 모습을 볼 수 있다.그러나 이 산은 근처를 지나는 3번 국도(이천 - 충주)나 38번 국도(평택 - 장호원 - 제천), 또는 중부내륙고속도로에서 잘 보이지 않는다. 심지어 산 북서에서 남동으로 가까이 지나는 520번 지방도에서도 가려내기 어렵다. 그 까닭은 큰 도로들이 이 산 근처에서 산 사이를 지나는 때문이기도 하고, 주위에 고만고만한 산들이 많기도 하기 때문이다. 수레의산 주변 산줄기는 남으로 가영산 - 부용산으로 이어지고, 북으로 수리산- 원통산- 오갑산으로 뻗쳐있다. 수레의산이 그처럼 비슷한 높이의 봉우리들로 이루어진 산줄기 가운데 자리잡고 있기 때문에 알아보기 쉽지 않은 것이다.그러나 이 산은 숲이 울창하고 산길이 좋은 데다 산허리를 임도가 지나고 있어 오르내리기에 편리하다. 어디서 올라도 점심시간을 포함해 3 - 4시간이면 어려움 없이 주봉은 물론 전설의 샘(못)까지 돌아 내려올 수 있어 가족산행에 알맞다. 내내 짙은 숲속을 걷기 때문에 산뜻한 기분이 끝까지 이어지고, 군데군데 상여바위 병풍바위 박쥐굴 공기돌 굴법당들도 볼 수 있어 심심찮다 특히 전설의 샘 위에 있는 상여바위는 푸른 숲에 둘러싸인 채 우뚝 솟아 특이하고, 그 위에 오르면 조망이 좋고 시원하다.전설의 샘이 말해주듯 산에는 물이 많다. 주름이 많아 골짜기가 많고 골짜기마다 개우에 맑은 물이 흐르고 있고, 매우 차가워 손을 오래 담그고 있기 어렵다.이 좋은 수질은 이미 근방에 널리 알려졌는데 농업용수로 사용하기 위해 저장해 놓은 차곡저수지의 물조차도 수영하기 어려울 정도로 차고 깨끗하다고 한다. 그래서 근처의 주민들도 아끼고 좋아하는 산인 듯 싶었다. 고스락에 오석 표석이 두 개가 있고, 화강암 표석도 하나 있다.가장 전망좋은곳은 상여바위 꼭대기이고, 전설의못은 능선상에 있는 연못으로 청학포란형의 권근 3대묘와 연루되어 묘를 쓸때 해발 505미터의 이곳에 물을 올렸다는 전설이 있다고 한다.", @@ -6876,18 +5366,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 생극면", "MNTN_NM" : "수레의산" }, - "longitude" : 127.6523238, - "latitude" : 37.034960099999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 치악산국립공원내의 남대봉에서 중앙선 또아리굴이 지나가는 산자락에 연결되어 있는 지능선상에 솟아 있는 수리봉은 많이 알려지지 않은 산으로 때묻지 않은 자연을 간직한 곳이다.수리봉은 내원계곡을 끼고 있어 여름철 산행지로도 그만이다. 안으로 들어갈수록 수림이 울창하고 반석지대가 많아 물놀이를 즐기기 좋고 산행 후 땀을 씻기에도 안성맞춤이다.삼각점(442-76 재설)이 있는 정상은 남동쪽만 제외하고 서쪽과 북, 동쪽이 수림지대로 에워싸여 조망이 터지지 않는다. 남동쪽으로는 문막 건등산 뒤로 명봉산, 덕가산, 백운산 등이 조망된다.", - "MNTN_HG_VL" : "427", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", - "MNTN_NM" : "수리봉" - }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 + "longitude" : 127.6635849, + "latitude" : 37.030279200000003 }, { "mountain" : { @@ -6896,18 +5376,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 횡성군", "MNTN_NM" : "수리봉" }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "수리봉의 등반로는 리지를 따라가게 되어있다. 수리봉 리지는 언제 누가 처음 등반을 했는지 알 수 없다. 그러나 연휴 때 줄을 서서 기다리는 기존의 리지 코스보다 한적한 등반을 즐길 수 있다. 또한 사람 손을 덜 타 새로운 루트를 등반한다는 기대감이 묘미를 더해 준다.산행 들머리는 생달국교와 약사정 마을 중간에 있는 다리다. 등반 도중에 물이 없으므로 낙엽 송숲을 지나 계곡에서 식수를 준비해 가야한다. 낙타바위 이외에는 설치된 확보물이 없으므로 선등자는 슬링과 크랙 등반에 필요한 프렌드를 넉넉하게 준비해야 한다.암벽등반 경험이 많은 사람들은 빨리 서두르면 4시간이면 등반을 마칠 수 있지만 초보자와 함께 한 등반이라면 암릉의 위험한 구간을 통과할 때마다 줄을 사용하는 것이 바람직하다. 바위를 손질해 놓지 않아 불확실한 확보물과 푸석바위가 많다. 낙석에 충분히 대비해야 한다. 기존 확보물이 없으므로 확보물에 각별히 신경을 써서 준비하는 것이 좋다. 계속 리지를 타고 올라가면 옛 성터 모습이 남아 있고 여기서 능선을 타고 올라가면 백두대간 능선인 황장재 헬기장 위에 도착된다.", - "MNTN_HG_VL" : "645", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 생달리", - "MNTN_NM" : "수리봉" - }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 + "longitude" : 128.24333329999999, + "latitude" : 37.479722199999998 }, { "mountain" : { @@ -6916,28 +5386,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동내면ㆍ동산면", "MNTN_NM" : "수리봉" }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "수리봉은 독수리가 서식하는 곳으로 수리등이라 하는 바위 층으로 된 산이다. 외부 세계와 단절된 심산유곡을 찾는 듯한 느낌을 줄 정도로 주변 경관이 수려하며 북암산과 억산의 중간에 위치한 독립된 산이다.운곡은 굼실이라 하여 산세가 웅장한 가운데 기암절벽을 이루고 폭포수가 떨어지고 있으며 그 산봉우리는 언제나 오색구름이 서려 있다고 하여 구름실(굼실)이라는 지명이 생겨났다. 조선조 숙종 때 숙종의 아들인 영조 임금을 낳은 숙빈 최씨의 고향이라는 기록도 남기고 있다. 산행들머리는 석골사 입구 부도군 아래 콘크리트 포장도로가 석골사와 주차장으로 나누어지는 왼쪽길이다.정상에는 봉화대인가 성터인가 돌무더기로 둘레를 만들어 놓아 쉴 곳이 마땅치가 못하다. 15분 정도 더 가서 있는 바위에 가서 쉬는 것이, 주변 경관과 조망이 좋아 나을 듯 싶다.", - "MNTN_HG_VL" : "767", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", - "MNTN_NM" : "수리봉" - }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 단양군 대강면 방곡리에 위치한 수리봉은 빼어난 단양의 풍광을 그대로 이어받은 산이다. 인근의 소백산, 황정산, 도락산 등의 유명세에 가려 아직 일반에 잘 알려져 있지 않으나, 산행의 묘미만큼은 앞서의 산들과 비교할 때 전혀 손색이 없다.정상에서면 주흘산, 대미산, 황장산, 도솔봉, 소백산연봉, 문수봉, 하설산, 월악산, 도락산, 황정산 등이 보인다.대체로 바위산이나 동쪽 사면은 주로 신갈나무를 중심으로 한 숲으로 형성되어 있고. 암릉은 단속적이고 정상능선의 암릉은 300미터 될까 말까한 길이이지만 유의할 위험지대 있으며 바위아래 사면엔 진달래 철쭉류도 있다.또한 수리봉은 등산 뿐만이 아닌 단양팔경의 절경인 하선암, 중선암, 상선암 또는 사인암의 비경을 즐길 수 있어 주위의 경관과 함께 빛을 나타내는 산이다.산행기점인 방곡리는 도자기로 유명하다. 도자기를 생산하기 위해 만들어진 산이라고 불리울 정도로 도자기 생산에 필요한 재료가 모두 갖추어져 있다. 주로 서민층의 생활도기를 만들어 왔으며 일본으로 수출도 한다.그리고 이곳 방곡리는 속세와 떨어져 별천지에 온 것처럼 격리되어 있으며 옛날 도자기 장이 섰다는 장승마을에는 오래된 이곳 사람들의 옛사연을 머금은 채 장승한쌍이 자리를 지키고 있다.", - "MNTN_HG_VL" : "960", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면 방곡리", - "MNTN_NM" : "수리봉" - }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 + "longitude" : 127.8202778, + "latitude" : 37.844999999999999 }, { "mountain" : { @@ -6949,16 +5399,6 @@ "longitude" : 126.9027047, "latitude" : 37.366196799999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 밀양시 단장면 구천리에의 수미봉, 향로봉, 사자봉,필봉 정각봉이 바로 그 다섯 봉우리 중 가장 중심이 바로 수미봉이다. 수미산은 불교에서 말하는 세상의 중심에서 가장 높게 솟은 산. 그래서 수미봉이라 이름이 붙었다. 이 수미봉을 재약산이라고도 하는데 이는 사자평과 주암골 등지에서 약초재배가 많이 이루어졌기 때문이다.이 수미봉의 북쪽으로 더 높게 솟은 봉우리를 사자봉이라 부른다. 그 기상이 사자처럼 힘차고 늠름해서 붙여진 이름이다. 이를 일제의 개명으로 천황산이라 불리었고, 아직도 국립지리원 발행 5만분의 1 지형도에는 천황산이라 표기되고 있다.수미봉 정상에는 '재약산 수미봉(1,108m)', 사자봉 정상에는 '사자봉(1,189.2m)' 이라는 정상석이 세워져 있다.수미봉의 산행들머리는 표충사 500m 앞 주차장에서 사자평으로 가는 전술도로로 들어서는 입구에서 시작된다. 50여분 가다보면 흑룡폭포의 웅장함을 전망대에서 보게 된다. 이 길은 몇 차례 산비탈을 치고 오르는 코스가 있어, 초보자에게는 다소 무리가 따르나 계곡과 폭포 및 옥류동천의 비경을 감상하는 것으로, 그 만큼의 고통은 감수할 만하다. 수미봉 정상에서는 사자평의 억새밭이 태양과 바람에 은빛 파도가 되어 출렁이는 모습을 볼 수 있다.", - "MNTN_HG_VL" : "1116", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "수미봉" - }, - "longitude" : 128.96011490000001, - "latitude" : 35.532613699999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "기양산과 수선산이 자리한 상주시는 예로부터 삼백(쌀, 누에고치, 곶감)의 고장으로 낙양으로도 불리었다.수선산은 상주시 청리면 청상리와 낙동면 수정에 솟아있는 육산으로 연산군 시절 연산군의 만행을 싫어하여 피신 은둔 수도한 서비가 많았다고 하여 이름지어진 산이다. 접근하는 방법에는 청리면 청상리 수선지 뒤 계곡길을 이용하거나 기양산에서 수선산을 거쳐 돌티로 하산하는 두 방법이 있으나 청상코스는 수선지 뒤 계곡이 끝나는 지점까지는 길이 잘 나 있으나 그 이후 길이 확실치 않고 잡목이 길을 막기 때문에 가급적 삼가고 기양산 코스를 이용하여 수선산으로 가는 방법을 택해야 한다.", @@ -6969,16 +5409,6 @@ "longitude" : 128.1716667, "latitude" : 36.299722199999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "431", - "MNTN_LOCPLC_REGION_NM" : "경기도 안산", - "MNTN_NM" : "수암봉" - }, - "longitude" : 126.8926501, - "latitude" : 37.367029899999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "수인산은 강진과 장흥의 경계를 이루고 있으며 그 높이와는 어울리지 않게 웅장하고 오묘한 산세를 이룬다. 산성으로 둘러싸인 정상부는 고려 말부터 조선말까지 전라 병영성의 전략 요충지로서 왜구가 침략할 때마다 주민들의 피난처로 이용되었고 병영면의 지명은 조선 태종 때 왜구를 막을 목적으로 병영을 설치한 데서 유래한 것이다. 실제 수인산은 병영면 소재지에서 바라보면 알을 품은 듯한 형상인 노적봉을 가운데로 주위가 온통 암벽으로 둘러 싸여 있어 천혜의 요새로 손색이 없는 철옹성 같은 산세를 보여준다.수인산은 억새로도 유명한데 정상부 천평 규모의 조릿대와 어우러져 황금벌판이 압권이다. 수인산의 대표적인 등산 코스는 강진 병영면의 수인사, 홈골에서 시작하는 것과 장흥 유치면 대리의 수덕목장에서 올라가는 길이다.무등산, 지리산, 두륜산, 천관산, 흑석산, 월출산에 둘러싸인 지점이 이곳으로 정상에서의 조망은 일품이다. 가까이는 장흥벌과 병영벌이 훤하게 내려다보인다. 장흥벌을 흐르는 탐진강이 길게 꼬리를 늘어뜨리며 다도해로 빠지고 있으며 병영면은 너른 평야를 감싸 안은 듯 산세가 이루어져 비옥한 곡창지대를 형성하고 있다.", @@ -6989,26 +5419,6 @@ "longitude" : 126.8516667, "latitude" : 34.720555599999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "『동국여지지』 죽산현 편에\"수정산은 현 북쪽 35리에 있고 건지산과 서로 연해 있다. 산 위에 돌로 된 굴이 있는데 그 안에 굴암(窟菴)이라 불리는 작은 암자가 있다.\"고 하여 관련 기록이 처음 등장한다. 『대동지지』에는\"북쪽 39리에 있는데 꼭대기에 석굴이 있고 그 안에 작은 암자가 있다. 수정이 나온다.\"라고 하여 예전에 이 산에서 자수정을 생산했던 관계로 그 이름이 유래한 것으로 짐작된다.", - "MNTN_HG_VL" : "348", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 처인구 백암면", - "MNTN_NM" : "수정산" - }, - "longitude" : 129.03749999999999, - "latitude" : 35.139444400000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "345", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시", - "MNTN_NM" : "수정산" - }, - "longitude" : 129.03749999999999, - "latitude" : 35.139444400000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "충주시 살미면 향산리 남쪽에 자리잡고 있는 수주팔봉은 나즈막한 산세에 험준한 바위봉을 등에 업고 있는 작지만 커다란 산이다. 뾰족하게 서있는 바위봉들이 작은 산을 떠받치고 있어, 결코 만만히 볼 수 없는 위엄을 갖고 있다.달천강의 은빛 물결을 휘감고 있는 수주팔봉은 서쪽 이류면 문주리 팔봉마을에서 달천강 건너 동쪽의 산을 바라볼 때 정상에서 강안까지 달천강 위에 8개의 봉우리가 떠오른 것 같다 하여 붙여진 이름이다. 산 이름 그대로 산 주위에 물이 흐르고 8개의 봉우리가 있어 등산객들유혹하는 산임에는 틀림없다.또한 산 위에서의 조망이 마치 한폭의 동양화를 펼쳐 놓은 듯 절경을 이루고 송곳바위, 중바위, 칼바위 등 창검처럼 세워진 날카로운 바위들이 수직절벽을 이뤄 산행의 묘미를 더해준다. 주변에 수안보온천과 월악산국립공원이 있다.", @@ -7019,16 +5429,6 @@ "longitude" : 127.9196749, "latitude" : 36.902216099999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "무이산역과 맞닿아 있는 이 산은 서릉을 학동재에서 향로봉의 주릉과 이음을 같이 하고 언뜻 보면 그저 거쳐가는 산봉에 불과한 것 같아서 산객들에게는 산정을 찾기가 어렵다. 그러나 보현사가 있는 남쪽사면에는 층석대가 포진하여 이 산에 아름다움을 더하고 있다.", - "MNTN_HG_VL" : "570", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 상리면", - "MNTN_NM" : "수태산" - }, - "longitude" : 128.20084900000001, - "latitude" : 34.976284999999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "수촌이라는 마을의 `자연숲' 뒤에 솟았다고 해서 숲뒤산이라 부르는 이 산은 고양이와 개에 관한 전설이 얽혀있는 광동굴, 층층나무와 잣나무가 그득한 숲, 하늘말나리와 더덕의 향기가 은은히 퍼지는 산길, 냉기가 솟는 샘물 때문에 오지를 찾는 사람들이 저절로 발길을 멈추게 된다.비라도 내리면 광동굴에 들어앉아 비오는 풍경도 감상할 수 있어 특히 여름 산행이 즐거운 산이다. 또한 숲뒤산은 강원도 삼척시 하장면 장전리에 있는 골로 마을이 있어 볼품없는 골짜기나 계곡 중간에 식수원으로 쓰는 광동굴 입구가 여름에 시원하고 멋지다. 골지천에서 휴식을 하고 한번쯤 둘러 보는 것도 좋다.", @@ -7076,8 +5476,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", "MNTN_NM" : "승학산" }, - "longitude" : 128.98537350000001, - "latitude" : 35.1317807 + "longitude" : 128.86506800000001, + "latitude" : 35.537758199999999 }, { "mountain" : { @@ -7086,8 +5486,8 @@ "MNTN_LOCPLC_REGION_NM" : "부산광역시 사하구 당리동", "MNTN_NM" : "승학산" }, - "longitude" : 128.98537350000001, - "latitude" : 35.1317807 + "longitude" : 128.97999999999999, + "latitude" : 35.116666700000003 }, { "mountain" : { @@ -7106,18 +5506,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군", "MNTN_NM" : "시묘산" }, - "longitude" : 129.25624719999999, - "latitude" : 35.762683299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "식산은 백원산과 같은 능선상에 있는 하나의 육산으로 정상 부근의 암석에 봉황대 세 글자가 새겨졌다고 전해져 내려오고 있으며 그 서쪽 기슭에는 동해사 (일명 한산사)가 자리를 잡고 있다.동해사는 무학대사가 상주의 지형이 행주형(行舟形)이라 풍수지리에 의하여 창건했다고 한다. 병자호란 이후에는 승정처사 이경남을 비롯한 그 후손들이 숭명사상을 고취한 곳으로도 유명하다.정상에서는 낙동강과 상주 시내가 잘 보이며, 부근에 있는 암석에는 ‘봉황대(鳳凰臺)’라는 글자가 새겨져 있었다고 전해진다.산행은 서곡동을 기점으로 하는데, 마을 안길로 접어들어 동해사를 거쳐 오르거나, 마을 안길을 따라 오르다가 마지막 민가 옆 갈림길에서 물탕골을 거쳐 오르는 방법이 있다. 등산로 상태가 좋은 편이며 경사가 완만하여 초행자도 쉽게 오를 수 있기 때문에 가족단위 산행에 좋다. 또는 굴티고개를 기점으로 채석강을 지나 백원산을 오른 다음 식산을 거쳐 동해사로 내려오는 코스가 있는데, 아카시아나무 군락이 많아 봄철에 꽃이 피면 산행하기가 즐겁다.", - "MNTN_HG_VL" : "503", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 서곡동 화개동 외담동, 낙동면 화산리", - "MNTN_NM" : "식산" - }, - "longitude" : 126.6853036, - "latitude" : 37.394303999999998 + "longitude" : 128.31055559999999, + "latitude" : 36.028055600000002 }, { "mountain" : { @@ -7129,26 +5519,6 @@ "longitude" : 127.4800673, "latitude" : 36.2953647 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "333", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", - "MNTN_NM" : "신기산성" - }, - "longitude" : 129.0428896, - "latitude" : 35.359282700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산을 즐기면서 물을 벗할 수 있는 곳이 경기도에서는 그리 흔치 않다. 이 두 마리의 토끼를 함께 잡을 수 있는 곳이 신로봉이다. 가평군 북면과 포천군 경계에 솟아있는 신로봉은 국망봉으로 가는 길목에 있으므로 등산로가 모두 국망봉과 연결되어있다.산행기점은 역시 국망봉과 마찬가지로 이동면 장암리의 생수공장과 그 위의 장암 저수지이다. 신로봉이란 국망봉으로 가는 길목인 한북정맥상의 신로령(안부)옆의 두리뭉실한 봉우리를 말한다. 정상에서의 전망은 북쪽으로 백운산과 광덕산이 보이고, 동남쪽으로 석룡산과 화악산, 남쪽으로는 국망봉과 명지산, 서쪽으로 사향산과 관음산이 보인다. 지금은 장암리 저수지 쪽에 국망봉 자연휴양림이 생겨서 입장료를 내야함이 좀 아쉽다.", - "MNTN_HG_VL" : "999", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 가평 북면", - "MNTN_NM" : "신로봉" - }, - "longitude" : 127.4186675, - "latitude" : 38.013648500000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 신불산 산자락에는 홍류폭포와 작천정이 유명하다.취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.", @@ -7159,76 +5529,6 @@ "longitude" : 129.0561611, "latitude" : 35.539955999999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백덕산의 긴 주능선 자락은 주천강과 평창강이 합수하는 영월군까지 이어지는데 이 능선상의 첫번째 봉우리가 신선바위봉(1060m)이다. 산행길로 접어들면 과연 산의 이름대로 신선이 나올법한 기암과 오염되지 않은 경관을 갖추고 있다. 신선 바위에서 남릉으로 1.5km거리에는 각종 무공해 산나물이 그득 들어차 있어 산행의 또다른 재미를 맛볼 수 있다.신선바위는 20m가 넘는 수직절벽으로 꼭대기에서 내려다 보는 조망이 일품이다. 사방을 둘러봐도 막힘이 없다.. 정상에 서면 먼저 시선이 머무는 곳은 올라온 방향인 서쪽이다. 서쪽 아래로 법흥사 입구에서 관음사 방향으로 깊게 패인 협곡이 아찔하게 내려다 보이고 협곡위로는 법흥사 뒷산인 연화봉과 사자산이 ,그리고 치악산 비로봉이 시야에 들어온다.", - "MNTN_HG_VL" : "1068", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 주천면", - "MNTN_NM" : "신선바위봉" - }, - "longitude" : 128.0455943, - "latitude" : 36.7821456 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "제otilde; 지역은 작성산과 동산(896.2m)을 지나 금수산(1015.8m)으로 이어지는 큰 산줄기가 단양군 적성면과 경계를 이루고 있다. 이 산줄기가 흐르는 금수산과 갑오고개 사이 900미터 봉에서 서쪽으로 향하는 산줄기의 최고봉이 신선봉(845.3m)이다.신선봉은 능선길 곳곳에 기암과 절벽을 이루고 있으며 노송들이 어울려 선경을 연출한다. 또한, 능선 좌우로 능강계곡과 학현계곡이 흘러 여름ouml;이면 많은 사람들의 피서지가 되기도 한다. 무엇보다 금수산 산악마라톤 대회 코스로도 유명하다.신선봉은 일명 ‘학바위봉’으로도 불린다. 학봉이라 불리는 774봉이 마치 날아오르려는 학을 닮았다는 데서 유래했다.신선봉 산행의 백미는 능강계곡을 뒤덮은 운해 너머의 금수산 풍경이다. 곳곳에 위치한 바위에 서면 남북으로 시원한 조망이 일품이다. 남쪽으로는 금수산에서 이어지는 망덕봉(926m), 가마봉(635m), 작은산밭봉(485m)을 연결하는 능선이 구름 위에서 솟아난다. 가득 피어오른 운해 사이로 기암절벽과 어우러진 노송의 모습은 그 이름oacute;럼 신선이 노닐만한 선경이다.", - "MNTN_HG_VL" : "891", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면, 수산면", - "MNTN_NM" : "신선봉" - }, - "longitude" : 128.43944440000001, - "latitude" : 38.241111099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "조령산 정상을 지나 조령관(제3관문) 쪽으로 40분정도 백두대간을 타고 가면 제일 높고 경치가 좋은 암봉이 나오는데 이곳이 신선봉이며 지도상에는 이름이 표시되어 있지 않다.충청북도 쪽으로는 신선암이 암벽등반지로서 이름이 높다. 정상 바로 밑 암릉에 서면 신선암에서 암벽등반하는 사람들이 보인다. 조령산 종주산행을 하면 지나가야 한다.", - "MNTN_HG_VL" : "845", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 각서리", - "MNTN_NM" : "신선봉" - }, - "longitude" : 128.43944440000001, - "latitude" : 38.241111099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "신선봉은 금수산(1.016m)과 동산(896m) 사이에서 서북쪽으로 뻗어 내린 능선상에 우뚝 솟은 산으로 충북 제천시 청풍면과 수산면의 경계를 이룬다.신선봉은 산자락에 비상하는 학을 닮은 바위가 있어 일명\"\"학봉바위\"\"로 불리며, 학현마을의 이름도 바로 학바위에서 유래되었다고 전해지고 있다.그러나, 신선봉의 학바위는 빙산의 일각에 불과하다고 말할 수 있다. 왜냐하면 온통 기암괴석으로 이루어진 산자락에 들어서면, 마치 조각가가 정성들여 빚어 놓은 듯한 기암괴석이 줄이어 나타나고 있으며, 바위 이름도 재미있어 킹콩바위ㆍ손바닥바위ㆍ못난이바위ㆍ물개바위ㆍ학바위ㆍ발바위 등이 그것이다.마을 북쪽인 동산에서 서남쪽으로 가지를 친 능선상의 모래재와 중고개 사이에는 옛 성터가 남아 있는데, 이곳을 마을 사람들은 작은 성안이라 부르고, 학현리의 거대한 분지를 큰 성안이라 부른다.등산을 위해 청풍도로에서 영아치고개를 넘어서면 산계곡 사이로 멋진 풍경이 연출된다.고개를 들어보면 동쪽 학현계곡이 펼쳐지고 움푹 패어내린 거대한 분지 왼쪽으로는 동산이 오른쪽으로는 저승봉, 그 너머로 신선봉이 바라보이는데, 이 일대의 모든 산 준령이 금강산을 옮겨 놓은 듯한 기암괴석과 노송 그리고 신록으로 어우러져 장관을 연출하고 있다.신선봉 정상은 계곡길과 와폭지대를 지난 다음 능선을 지나 자일을 이용해야 하는 세미클라이밍 지대와 바위지대를 지나야 오를 수 있다. 정상에는 정상임을 알리는 팻말과 돌탑이 쌓여 있고 참나무 등의 수림으로 덮여 있다. 따라서 조망은 그리 좋지 않다. 하지만 기암절경을 보았다는 것만으로도 산행의 기쁨을 느낄 수 있는 곳이 바로 신선봉이다.", - "MNTN_HG_VL" : "845", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 청풍면", - "MNTN_NM" : "신선봉" - }, - "longitude" : 128.43944440000001, - "latitude" : 38.241111099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 충주시 상모면과 괴산군 연풍면에 걸쳐 뻗어있는 신선봉은 이름에서 느낄 수 있듯이 신비로움을 머금고 있는 산이다. 인근에 월악산, 주흘산, 조령산 같은 명산들이 둘러싸고 있어 그동안 잘 알려지지 않았는데, 신선봉 북쪽과 남쪽에는 각각 옛부터 이름난 두 줄기 길이 있다.북쪽의 길은 신라가 국력의 팽창에 따라 북진정책을 위해 이곳 백두대간에 처음으로 뚫은 하늘재(지릅재)요, 남쪽의 길은 조선시대에 영남의 선비들이 과거보러 서울로 올라가던 그 유명한 문경 새재 고갯길이다. 당시에\"\"황간의 추풍령을 넘으면 추풍낙엽처럼 과거에 떨어져버리고, 풍기의 죽령을 넘으면 대나무처럼 미끄러져 과거에 떨어져버리기 때문에 문경 새재를 넘는다.\"\"는 속말이 떠돌았다고 옛이야기는 전한다.한편 하늘재는 온달장군이 신라에게 빼앗겼던 계립현과 죽령 서쪽 땅을 되찾기 위해 출전했다가 단양군 영춘면 하리 소재의 아단성(근래들어 온달산성이라고 불리는 석성)에서 전사한 바 있는 바로 그 계립현으로서 충북 충주시 상모면 석문리와 경북 문경시 관음리를 잇는 해발 500m의 고갯길이다.", - "MNTN_HG_VL" : "486", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면, 괴산군 연풍면", - "MNTN_NM" : "신선봉" - }, - "longitude" : 128.43944440000001, - "latitude" : 38.241111099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간이 장안산 근처의 영취산에서 금남호남정맥으로 분기되어 마이산 근처의 주화산까지 뻗어 가다가 다시 호남정맥으로 갈리어 만덕산, 오봉산, 갈재를 지나 내장산까지 이어진다.신성봉은 내장산의 주봉으로서 신선봉을 필두로 연자봉과 장군봉(696m), 서래봉(622m), 불출봉(610m) 등이 가치봉(717m)을 중심으로 대체로 동쪽으로 뻗어나가면서 입벌린 주머니(말발굽) 현상을 이루고 있다.그리고 그 사이에 개암사, 내소사 등 유서깊은 고찰이 있고 직소폭포, 봉래구곡, 낙조대 등의 승경이 곳곳에 산재하고 있다. 그뿐 아니라 주변에는 유천 도요지, 구암 지석묘군에다 호벌치와 우금산성 등 역사 유적지가 있다. 채석강, 적벽강에다 신석정 시비, 한국에서 최초로 조성된 금구원 조각공원, 변산해수욕장, 격포해수욕장 등을 갖춘 관광지다.", - "MNTN_HG_VL" : "967", - "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군", - "MNTN_NM" : "신선봉" - }, - "longitude" : 128.43944440000001, - "latitude" : 38.241111099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "신선암봉은 조령산 종주로의 중간에 위치한 암봉으로 조망이 좋고 오르고 내리는 코스도 다양하여 종주로 거쳐가기보다는 단독등산이 좋은 산이다. 오르는 코스로는 조령산의 등,하산로로 이용되는 절골에서 암벽훈련장 앞을 지나 오르는 코스와, 절골에서 중암절로 오르거나 용성골을 기점으로 오르는 코스 등 계절에 맞게 다양하게 준비되어있다.여기서는 용성골에서 북쪽능선을 타는 아기자기기하며, 전망 좋은 코스를 소개하겠다. 수옥폭포 아랫마을인 새터마을의 용성골 입구에 들어서면 벌써 별천지다. 매표소만 지나면 화강암 반석을 타고 흘러내리는 유리알처럼 맑은 계곡수와 노송이 어우러져 신선이 따로 없다는 생각이 들정도로 깨끗하다.정상에 올라서면 정상의 고즈넉함도 잠시 동, 서, 남, 북으로 뻗어오고, 뻗어나간 산줄기의 감동에 취하다보면 어느새 신선이 된다.", - "MNTN_HG_VL" : "937", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면 원풍리", - "MNTN_NM" : "신선암봉" - }, - "longitude" : 128.0455943, - "latitude" : 36.7821456 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경상남도 김해시 삼방동과 대동면, 상동면에 위치한 신어산은 동서로 뻗어 있는 산으로 북동쪽으로는 낙동강이 감돌아 흐르고 남쪽에는 광활한 김해평야가 펼쳐져 있는 낙남정맥의 한 줄기다. 가락국의 시조 김수로왕 탄강지로 전해오는 구지봉이 산맥의 서쪽 끝부분에 있다. 능선에서 김해시가지를 바라보며 산행할 수 있고 기암절벽 사이로는 구름다리가 있어 산행의 묘미를 더한다. 정상에서 서쪽 주능선을 따라 630봉까지 가는 도중에는 군데군데 암봉이 있고 580봉에서 남쪽 능선을 따라 460봉의 암봉에 올라서서 신어산을 바라보면 빼어난 경치에 감탄하게 된다. 460봉의 전망대 같은 바위에서 동쪽 계곡으로 내려가면 암벽 밑에 천진암이 있고 숲길과 대밭을 거쳐 은하사에 닿게 된다. 정상의 조망은 무척산, 토곡산, 매봉, 오봉산, 금정산의 고당봉 등이 선명하게 시야에 들어온다. 산림욕장이 문을 열어 가벼운 산책도 겸할 수 있어 가족산행으로도 제격이다.신어산이라는 이름은 ‘지모신이 깃들어 있는 산’을 뜻하는 ‘가모뫼’의 차차표기다.이렇듯 신어산은 예부터 신성한 산으로 인식되어져 왔다.", @@ -7241,13 +5541,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산행들머리는 쌍두봉 가든 입간판 사이로 난 샛길로 5분 정도 들어서 계곡을 건너면 왼쪽 사잇길이 산행의 진입로이다. 일단 산길에 오르면 쌍두봉까지 쉴 틈도 없이 계속 오르막이 계속된다.40여 분 후 조망이 탁 트이는 바위전망대에 올라서면 아래로 내려다보이는 삼계리는 정다운 마을 모습이 오순도순 그림 같고 그 위로 산세가 엄숙하게 둘러싸고 있다. 여기서 20여 분 후 쌍두봉 정상의 2개의 봉우리가 시야에 들어오고, 정상인 봉우리에는 험로로서 바위를 타고 오르며 보조 자일의 도움을 받아야 한다. 오른쪽으로 돌아가는 길이 있어 조금만 돌아서면 다시 쌍두봉 정상에 오를 수 있다.", - "MNTN_HG_VL" : "910", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 삼계리", - "MNTN_NM" : "쌍두봉" + "DETAIL_INFO_DTCONT" : "강원도 원주시 귀래면과 충북 제천시 백운면의 경계를 이루는 십자봉은 원주에서 남쪽으로 15㎞ 지점에 숨어있는 명산이다.겨울에는 설경, 가을에는 단풍과 낙엽, 그리고 여름에는 시원한 계곡으로 사시사철 산행지로 각광을 받고 있는데, 특히 산으로 들어서면 등산로마다 잡목수림이 터널을 이루고 있어, 여름철에 더위를 피하기 위한 장소로 그만이다. 빽빽히 들어찬 나무사이로 4㎞ 길이의 천은계곡이 쭉 뻗어 있으며 곳곳에 소와 담, 암반이 펼쳐져 계곡미가 뛰어나다. 계곡입구에서 10분 거리에 천은사라는 아담한 절이 있다.십자봉이라는 산이름은 일제가 붙인 이름이고, 덕동리 주민들은 촉새봉이라 부른다. 산 서쪽 자락인 귀래리에 있는 천은사 절이름도 '십자봉 천은사'가 아닌 '백운산 천은사'로 부르고 있다. 촉새봉이라는 산 이름은 이곳 주민들이 예전부터 조상 대대로 불러온 이름이다.", + "MNTN_HG_VL" : "985", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면, 충청북도 제천시 백운면", + "MNTN_NM" : "십자봉" }, - "longitude" : 129.00244050000001, - "latitude" : 35.663634700000003 + "longitude" : 127.93055560000001, + "latitude" : 37.211111099999997 }, { "mountain" : { @@ -7271,23 +5571,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보령과 부여의 경계선에 있는 아미산은 호젓한 산행 코스가 자랑이지만 지금껏 알려지지 않은 산이다. 가을이면 산 전체가 불붙은 듯 단풍으로 가득한 곳, 예부터 산삼이 많이 나는 곳이며 부정한 사람이 출입하면 화를 입는다는 이야기가 전해져 오는 산이다. 높은 산은 아니지만 골이 깊고 산세가 자뭇 웅장하다. 만만히 보고 다가갔다 흠씬 비지땀을 흘려야 오를 수 있는 산이다.보령호가 담수를 시작하면서 산 끝자락이 잠겼고, 만산홍엽의 그림자가 비친 호수와 어울린 모습이 황홀경에 빠져들도록 아름답다. 미산면 용수리 동북쪽에 자리하고 있으며, 도화담에서부터 솟아오른 봉우리가 풍계리와 용수리에 걸쳐 있다. 북쪽은 부여군 외산면과 지경을 이룬다. 아미산에는 백제때 창건된 중대암이 있고 인근에는 영천이라는 약수가 있다.", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "충남 보령시 미산면, 부여군 외산면", - "MNTN_NM" : "아미산" + "DETAIL_INFO_DTCONT" : "봉황새가 높이 나는 형상이라 하여 아기산 또는 봉황산이라고도 하는데, 조선조 이조참판 류복기 선생은 이 산과 연관해 호를 기봉이라 했으며 후손들은 이곳을 당산으로 모시고 정월 보름날 아기당에서 고사를 올린다.아기산은 한발이 심할 때 이곳에서 기우제를 올리면 영험이 많아 반드시 비를 내렸다고 전하는 임동면의 진산이다.아기산의 북쪽 자락에는 신라시대의 고찰인 봉황사가 있고 전주 류씨의 집성촌인 무실마을이 있다.산 정상에서 바라보면 웅장한 임동교, 수곡교와 중평단지가 한폭의 병풍 같으며, 임하호의 맑은 물이 한눈에 보인다. 또 정상에서 서쪽으로는 안동 최고봉인 학가산과 안동시가지인 용상이 보이고 동쪽으로는 일월산이, 북쪽으로는 와룡산이 시야에 들어온다. 아기산 남쪽에는 지례예술촌이 있다. 1993년 12월 임하댐이 완공되면서 섬 아닌 섬이 되어 드넓은 임하호에 두둥실 떠다니는 형국이 되었다.", + "MNTN_HG_VL" : "589", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 임동면", + "MNTN_NM" : "아기산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 128.93333329999999, + "latitude" : 36.533333300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "아미산(402.4m)은 팔공산(1192m)에서 뻗은 팔공지맥의 끝자락에 있는 산이다. 높이는 낮지만 마치 설악산의 용아장성을 옮겨놓은 듯 아름다운 산이다. 팔공산 줄기는 시루봉을 지나 군위군 산성면 백학리를 지나며 끊어질 듯 야트막한 야산이 되었다가 조림산과 화산(華山middot;828m)이 만나는 갑령재에 이르러 다시 치솟는다. 화산을 넘으면서 탄력을 받은 줄기는 방가산(755.8m)을 지나 팔공지맥에서 가장 아름다운 절경을 만나게 되는데 바로 아미산이다. 여인의 아름다운 눈썹을 뜻하는 아미(蛾眉)에서 음을 빌려와 산이 높고 위엄이 있다는 뜻의 아미(峨嵋)로 했다.아미산은 높이로 말하는 산이 아니다. 산세가 수려하며 산이 작아 보여도 바위 형태가 만물상을 이룬 듯하다. 바위 틈 사이에서 자라ordf;게 뻗은 소나무 가지들은 분재 같은 모양으로 아름다움을 더해준다. 크게 다섯 개의 바위봉우리로 이루어졌는데, 그 모양들이 마치 촛대 같이 생겨ucirc;송 주왕산의 촛대바위를 연상케 한다. 뿐만 아니라 산의 모양은 다섯 개의 바위봉이 나란히 어깨를 맞댄 형국이고, 많은 병사들이 무기를 들고 마을을 지키는 듯한 모습이어서 예로부터 이곳은 전쟁의 피해가 거의 없었다고 한다.", - "MNTN_HG_VL" : "602", - "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 고로면", + "DETAIL_INFO_DTCONT" : "보령과 부여의 경계선에 있는 아미산은 호젓한 산행 코스가 자랑이지만 지금껏 알려지지 않은 산이다. 가을이면 산 전체가 불붙은 듯 단풍으로 가득한 곳, 예부터 산삼이 많이 나는 곳이며 부정한 사람이 출입하면 화를 입는다는 이야기가 전해져 오는 산이다. 높은 산은 아니지만 골이 깊고 산세가 자뭇 웅장하다. 만만히 보고 다가갔다 흠씬 비지땀을 흘려야 오를 수 있는 산이다.보령호가 담수를 시작하면서 산 끝자락이 잠겼고, 만산홍엽의 그림자가 비친 호수와 어울린 모습이 황홀경에 빠져들도록 아름답다. 미산면 용수리 동북쪽에 자리하고 있으며, 도화담에서부터 솟아오른 봉우리가 풍계리와 용수리에 걸쳐 있다. 북쪽은 부여군 외산면과 지경을 이룬다. 아미산에는 백제때 창건된 중대암이 있고 인근에는 영천이라는 약수가 있다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "충남 보령시 미산면, 부여군 외산면", "MNTN_NM" : "아미산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 126.6911111, + "latitude" : 36.279444400000003 }, { "mountain" : { @@ -7296,8 +5596,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 당진시", "MNTN_NM" : "아미산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 126.6648254, + "latitude" : 36.845756000000002 }, { "mountain" : { @@ -7306,8 +5606,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", "MNTN_NM" : "아미산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 128.209, + "latitude" : 37.738999999999997 }, { "mountain" : { @@ -7316,38 +5616,28 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 인제", "MNTN_NM" : "아미산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "아미산은 울주군 두서면 전읍리와 미호리에 걸쳐 있는 해발 601.5m의 산이다. 옛날 제정일치 시대의 군장을 천왕 또는 천군이라 하여 산의 수호신도 천왕이라 부르게 되었으며 그 수호신의 이름으로 산 이름을 부르게 되는 경우가 있다. 마찬가지로 두서면의 아미산은 노고신으로 말미암아 생긴 이름이다.", - "MNTN_HG_VL" : "402", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 두서면 전읍리, 미호리", - "MNTN_NM" : "아미산" - }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 128.20861110000001, + "latitude" : 37.7386111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천마산의 연맥에 해당되는 아미산은 아미동 일대에 넓게 자리 잡고 있는 구릉성 산지로 아미동과 사하구(감천동)와 경계를 이룬다.산록이 완만하여 산정의 일부를 제외하면 도시화에 따른 주택지대로 변모하였다. 아미산이란 이름은 본래 이곳의 마을을 '아미골' 이라 부른데서 비롯되나 아미골의 정확한 어원은 알 수 없다. 속설에 의하면 아미골은 움막집이란 의미의 옛말인 애막이 바뀐 것으로 이를 한자식 峨眉로 표기한데서 비롯된다. 또, 이 산의 모습이 마치 미인의 아름다운 눈썹과 같다하여 아미산으로 표기된 것으로 전해지기도 한다. 아미산은 부산항 개항 이후 일본인들에 의해 설치된 공동묘지의 산으로도 잘 알려져 있다.아미산은 전부터 잘 알려져 있는 산이기는 하나 문헌에 기록된 바가 없는 작은 산이라서 한자로 어떻게 표기해야 할지몰라 峨媚山, 峨眉山 혹은 娥眉山, 娥媚山, 蛾眉山 등으로 혼기되어 왔는데, 요즈음은 峨嵋山으로 통일되어 사용되고있다.", - "MNTN_HG_VL" : "234", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 서구 아미동, 사하구", - "MNTN_NM" : "아미산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "353", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "아홉산" }, - "longitude" : 103.334737, - "latitude" : 29.516006999999991 + "longitude" : 129.18416669999999, + "latitude" : 35.285277800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "너른 벌판 위를 달리던 한 줄기 바람이 갑작스럽게 숨을 몰아 쉬어야하는 곳, 우뚝 아차(蛾嵯)라고 이름 한 곳이 바로 아차산이다. 정상표고 200m되는 지점에서 시작하여 동남의 한강변 쪽으로 경사진 산허리의 윗 부분을 둘러싸고 있는 산성의 형태가 남아 있다.백제의 도읍이 한강 유역에 있을 때 우뚝 솟은 지형적 특성으로 인해 일찍부터 이 아차산에 흙을 깎고 다시 돌과 흙으로 쌓아 올려 산성을 축조함으로써 고구려의 남하를 막으려는 백제인의 노력이 있었다. 한강을 사이에 두고 맞은 편 남쪽에 있는 풍납동 토성과 함께 중요한 군사적 요지로서 백제의 운명을 좌우하던 곳이기도 하다.아단성(阿旦城), 아차성(蛾嵯城), 장하성, 광장성 등으로 불리우기도 하여 백제, 신라, 고구려가 한강을 중심으로 공방전을 장기간에 걸쳐 벌였던 것을 짐작할 수 있다.이 성의 흔적은 60년대까지만 해도 눈으로 알아 볼 수 있을 정도로 남아있었다. 아차산 분수령의 전부와 그 북쪽 기슭 면목동의 동쪽과 아차산의 서남쪽 기슭을 달리는 진맥의 분수령 및 그곳부터는 분명치 못하지만 모진동 밭에 이르는 사이에 이어져 있었던 길이 4km에 달하는 토성과 석성 자리는 신라가 쌓은 장한성으로 알려져 있다.1500여 년이라는 장구한 역사의 수레바퀴 속에서 여러 차례 그 운명을 달리해야 했던 아차산성은 아직도 그 자신의 운명을 나타내려는 듯 당시의 토기와 기와조각 등을 보여주고 있으며, 그 옛날 산성수비군의 역할을 다시 되새겨보려는 듯 많은 사람들이 오르는 시민공원이 되어 그 역사적 변신을 꾀하고 있다. (면적 103,375㎡, 1973.05.25지정 광장동 산 16-46, 구의동산 1-2)", - "MNTN_HG_VL" : "287", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 광진구", - "MNTN_NM" : "아차산" + "DETAIL_INFO_DTCONT" : "부산의 진산 금정산 주능선을 내달리다 잠시 산성 끄트머리에 걸터앉아 동쪽인 오른편 저 멀리 회동수원지를 바라보면 바로 뒤에 올망졸망한 봉우리가 시야에 들어온다. 아홉산이다. 부산에는 원래 또 다른 아홉산이 있는데 기장군ouml;마면 웅otilde;리 미동마을 뒷산인 아홉산이 그것. 최근 숲uuml;험장으로 각광받고 있다고 하면 고개를 끄떡일 사람들이 제법 있을듯하다. 그러나 금정구 회동동의 아홉산은 회동수원지에서 기장군ouml;마면 장전리에 걸쳐 뻗은 산이다. 기장의 산으로 비교적 알려진 운봉산과 개좌산과 이웃해 능선으로 이어진다. 아홉산은 이름 그대로 아홉개의 봉우리로 된 회동수원지 뒷산이다. 덩치는 작지만 아홉개의 작은 봉우리를 오르내리는 재미가 쏠쏠하다. 높이가 300미터 대에 불과해 가볍게 몸풀기에 적당하다. 그렇기 때문에 산꾼들은 아홉산 하나를 오르면 왠지 허전해 바로 옆의 운봉산이나 개좌산을 함께#376;는 경우가 많다. 무엇보다 아홉산의 자랑은 시원한 조망. 금정산 주능선과 출렁거리는 동해바다는 '부산에도 이런 곳이 있었나'라는 생각이 들 정도다.", + "MNTN_HG_VL" : "353", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 금정구 기장군", + "MNTN_NM" : "아홉산" }, - "longitude" : 127.1037627, - "latitude" : 37.571508700000003 + "longitude" : 129.18416669999999, + "latitude" : 35.285277800000003 }, { "mountain" : { @@ -7359,16 +5649,6 @@ "longitude" : 128.0494783, "latitude" : 35.531882899999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "악휘봉은 충북 괴산군 연풍면과 칠성면의 경계를 이루는 산이다. 악휘봉의 정상 부근은 온통 기암괴석과 노송군락으로 어우러져 있어 보는 이로 하여금 자연의 신비감에 절로 고개를 숙이며 감탄을 자아내게 한다.천혜의 볼거리 외에도 악휘봉 산자락에는 역사의 흔적을 찾아볼 수 있는 곳이 많은데, 우선 등산로 초입 장바위 마을에 있는 유서깊은 반계정이 그것이다. 2층 누각으로 되어있는 반계정은 조선조 영조 1년(1725년) 좌의정을 거쳐 영의정을 지낸 장암 정호가 노후에 후손을 가르치며 여생을 보낸 곳이다.장바위라는 마을 이름은 정호의 호인 장암에서 유래되었다고 전해지며, 장바위 마을 주민들은 반계정을 장바위 정씨네 정자라 부르기도 한다. 3, 4봉 사이에 우뚝 솟아 산행기점이 되는 입석마을의 이름을 낳게 한 선바위가 정상 아래쪽에 당당히 서 있다.", - "MNTN_HG_VL" : "845", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면 적석리", - "MNTN_NM" : "악휘봉" - }, - "longitude" : 128.006, - "latitude" : 36.722000000000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -7389,6 +5669,26 @@ "longitude" : 127.7494444, "latitude" : 37.842222199999988 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "안산의 지세는 대체로 급경사로 이루어져 있으나 높이가 297M로 낮은 편이어서 주민들의 산책로로 이용되고 있다. 면적은 약 209만제곱미터이며 여러개의 등산로가 조성되어 있고, 다양한 종류의 야생화와 함께 숲길 옆으로 소나무, 잣나무, 독일가문비, 메타세쿼이어, 벗나무, 단풍나무, 복자기나무가 울창해 도심 속에서 삼림욕을 즐길수 있는 서울 서대문구의 대표적인 명소이다. 정상에는 안산봉수대가 있으며 북한강과 인왕산, 행주산성과 한강을 조망할수 있다.", + "MNTN_HG_VL" : "297", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서대문구 홍제동", + "MNTN_NM" : "안산" + }, + "longitude" : 126.94499999999999, + "latitude" : 37.576666699999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "설악산 대청봉에서 서북능선을 따라 10km쯤 달리면 한계령으로 빠지는 갈림길이 나온다. 이곳에서 계속 전진하는 길에 귀때기청봉(1,578m)을 거쳐 10km여를 더 오르락내리락 하다보면 대승령 안부에 이른다. 여기서도 방향을 계속 서쪽으로 잡아 4km쯤 가다보면 마치 말안장을 연상시키듯 두 개의 암봉 사이가 잘룩하게 들어간 모습을 접하게 된다. 여기가 바로 안산의 정상부위로서 일명 길마산이라고도 한다.안산은 외진 위치 때문에 찾는 사람이 많지 않다. 남쪽의 장수대에서 산행을 시작하는 사람들은 대승령에서 십이선녀탕계곡으로 하산길을 잡아 이 산을 스쳐 지나는 것이 보통이다. 그래서 설악을 수십번 다닌 사람들 중에도 안산을 다녀온 사람이 드물 정도로 한적한 봉우리로 남아 있다.안산은 멀리 원통쪽에서 바라보아도 말안장을 닮은 모습이 시선을 끌고 있고, 막상 올라가보아도 처음부터 암벽으로 이루어진 협곡이 만만찮은 험산임을 느끼게해 준다. 이 산을 중심으로 옥녀탕 계곡과 12선녀탕계곡이 좌우로 펼쳐져 있고, 정상 주변에는 화강암 기암이 도처에 산재하고 조망하는 전망이 일품이어서 등산의 가치가 높은 산이다. 정상 옆에는 무악동 봉수대가 있다.", + "MNTN_HG_VL" : "1430", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면", + "MNTN_NM" : "안산" + }, + "longitude" : 128.33000000000001, + "latitude" : 38.140000000000001 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "완주군 동북부에 있는 요지인 고산은 고려시대에는 봉성형이었으며 조선시대에는 고산군이었다. 금남정맥에서 뻗쳐와 원등산 위봉산 되실봉을 거쳐 북쪽으로 달려가 안수산을 솟구친다. 북쪽으로 나아가던 500m대의 산세가 고산을 눈앞에 두고 갑자기 멈추며 산줄기는 동쪽으로 틀어진다.북쪽으로의 진행을 멈춘 산줄기는 자연스럽게 높은 턱을 이루고 그 끝에 크나큰 암봉을 빚어놓았다. 특히 이 암봉(일명 달걀봉)은 고산천이 휘돌아 흐르는 고산마을을 굽어보고 있다. 고산에서는 물론 봉동 삼레 일대 들녘에서도 눈에 잘 띄는 특이한 산세다. 달걀봉 아래 제법 널찍한 터에 안수암이 있고 수 백년 된 느티나무가 그 연륜을 자랑하고 있다. 느티나무로 미루어 볼 때 적어도 수 백년 전부터 있었으리라 믿어지는 안수암은 모악산 금산사의 말사로 지금은 젊은 범운스님이 홀로 다스리고 있다.안수산을 고산 사람들은 고산의 지킴이로 믿고 있다. 고산천을 중심으로 펼쳐진 고산 일대의 지형이 풍수지리적으로 '지네'의 형국이라 한다. 지내의 독기를 누릴 수 있는 것은 지네와 상극인 '닭'으로 알려져 있는데이 안수산이 닭벼슬을 닮아 일명 '계봉산'으로 불린다. 또 멀찍이서 바라보면 거대한 바위로 이뤄진 주봉이 듬직한 자태로 서 있어 오르기 전부터 보는 이의 마음이 한결 뿌듯해진다.안수산 정상에서 되실봉 정상까지 약 2시간 30분 소요되는 암릉코스가 산행의 재미를 더해준다. 산행기점은 주로 청동마을이나 성재동마을로 잡는 것이 일반적인데, 안수산 서쪽 계곡 저수지로 하산하거나 안수산에서 되실봉을 거쳐 오성리로 하산할 수 있다.", @@ -7396,8 +5696,18 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", "MNTN_NM" : "안수산" }, - "longitude" : -118.29269170000001, - "latitude" : 34.0620324 + "longitude" : 127.22648959999999, + "latitude" : 35.954262300000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "347", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "안심산" + }, + "longitude" : 127.65000000000001, + "latitude" : 34.733333299999998 }, { "mountain" : { @@ -7417,77 +5727,27 @@ "MNTN_NM" : "안양산" }, "longitude" : 127.02019780000001, - "latitude" : 35.102527199999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "안전산 산행들머리는 배태고개 동편으로 나 있는 산길에서 시작된다.15분 후 558봉 산림초소에 올라서게 되는 데 그 아래 영포천 밑으로 탁트인 전망은 일품이고, 멀리 영포천이 반짝거리며 그 물은 원동천으로 하여 낙동강으로 흘러간다.몇 차례 봉우리를 오르내리면 안전산 정상에 오르게 된다. 정상에는 조그마한 표지석 하나가 정상임을 알려 주고 있으나, 주위 경관은 전혀 볼 수 없다. 이곳에서 15분 후에는 탁트인 시야가 전개되는데 삼원축산 농장이나. 초원은 영화 사운드 오브 뮤직에서 보았던 알프스 초원지대와 비슷하다.", - "MNTN_HG_VL" : "665", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", - "MNTN_NM" : "안전산" - }, - "longitude" : 127.035675, - "latitude" : 37.608305999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "148", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 부평구", - "MNTN_NM" : "앞산" - }, - "longitude" : 128.57638890000001, - "latitude" : 35.816944399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "583", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "앞산(앞산공원)" - }, - "longitude" : 128.57638890000001, - "latitude" : 35.816944399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "애기암봉은 장성봉에 딸려있고 희양산을 바라보며 서 있는데 1\/5,000 지도에는 높이가 746.6m로 표시되어 있다. 장성봉 정상에 오르기 바로 전에 연결된다.전형적인 육산(陸山)이며 갖가지 괴석과 노송, 활엽수들이 우거지며 능선길은 암릉이다. 불란치재에서 코끼리바위를 거쳐 수정광산터를 지나면 정상이 나온다. 옻나무골에서 오르는 길은 잣밭재를 경유 오를 수도 있고 정상부분으로 바로 오르는 산길도 있다.애기암봉에서 사방을 둘러보는 조망은 극치에 이른다고 할 수 있다. 장성봉서 올망졸망 애기암봉 타는 재미 “쏠쏠” 하다. 특히 애기암봉에는 큰 바위조망대가 있어 가장 가까이서 희양산과 구왕봉, 대야산, 둔덕산, 촛대봉, 곰넘이봉을 비롯한 주변의 산들이 건너다 보인다.", - "MNTN_HG_VL" : "731", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍 완장리", - "MNTN_NM" : "애기암봉" - }, - "longitude" : 127.9484282, - "latitude" : 36.706101400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "385", - "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 해룡면", - "MNTN_NM" : "앵무산" - }, - "longitude" : 126.92749999999999, - "latitude" : 37.7575 + "latitude" : 35.102527199999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "507", - "MNTN_LOCPLC_REGION_NM" : "경상북도 거제시", - "MNTN_NM" : "앵산" + "MNTN_HG_VL" : "583", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "앞산(앞산공원)" }, - "longitude" : 128.60173459999999, - "latitude" : 34.947230300000001 + "longitude" : 128.57638890000001, + "latitude" : 35.816944399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "아름다운 꾀꼬리가 알을 품고 있는 형상의 산세를 가진 앵자봉은 중부고속도로와 영동고속도로가 교차하는 곳에 산군을 이루고 있다. 앵자봉은 천주교인들에게 널리 알려진 산인데, 우리 나라 최초로 천주교가 전파되기 시작했고, 지금은 앵자봉 일원이 천주교성역 순례길로 지정이 되었기 때문이다.앵자봉은 그리 높지는 않으므로 산행에 특별한 어려움은 없지만, 초기에 천주교 교인들이 숨어 살았을 만큼 깊고 신비로운 산이므로 훼손된 등산로에 익숙한 사람들에게는 신선한 느낌을 줄 수 있다.북쪽만 수직암벽으로 이루어진 앵자봉 정상에 오르면 답답하던 가슴과 마음에 일시에 트이고 주변 경치가 시원하게 펼쳐진다. 산록은 산의 높이에 비해 숲이 울창하여 이산에 본격적인 단풍이 들면 볼만할 듯한 느낌이 든다.또한 억새지대와 진달래지대 등이 있고 특히 도토리가 많기로 유명하다.", - "MNTN_HG_VL" : "667", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면, 실촌면, 여주군 산북면, 양평군 강하면", - "MNTN_NM" : "앵자봉" + "DETAIL_INFO_DTCONT" : "충청남도 공주시 사곡면 화월리와 우성면 방문리의 경계를 이루는 산", + "MNTN_HG_VL" : "280", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", + "MNTN_NM" : "약산" }, - "longitude" : 127.3977778, - "latitude" : 37.415277799999998 + "longitude" : 127.05457490000001, + "latitude" : 36.497249500000002 }, { "mountain" : { @@ -7506,28 +5766,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 웅양면 산포리", "MNTN_NM" : "양각산" }, - "longitude" : 126.65746040000001, - "latitude" : 36.253848400000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "해발고도 1000미터를 훌½ 넘기며 우뚝 솟은 양각산은 경남 거acirc;군 웅양면과 가북면의 경계를 이룬다. 하얗게 반brvbar;이는 화강암릉과 푸르디 푸른 수풀이 조화를 이루며 빼어난 경치를 선사하는 이 산은 아기자기한 야생화가 곳곳에 피어 산행의 즐거움을 더한다.두 개의 소뿔을 닮았다고 하여 이름붙인 양각산은 그래서 재나 골yen;기, 마을이름 들이 소와 인연하여 만들어진 것들이 많다. 김otilde;시로 넘는 우두령을 비롯해 소의 물먹는 그릇을 뜻하는 구수마을, 생식기를 일컫는 우랑마을 등이 그렇다.양각산의 옛 이름은 금광산(金光山)인데 대동여지도와 거acirc;고읍지에서 그 흔적을 발견할 수 있다. 이를 뒷받침하듯 흰대미산과 양각산의 서쪽 용암저수지 일대에 금광마을이 위치해 있다. 금광이라는 이름이 붙여진 연유에 대해 금이 많이 나서였다고도 하고, 암릉이 빛에 반사되어 반brvbar;거리며 금빛이 난다고 하여 붙여졌다고도 한다.거acirc; 내에서도 오지에 속한 탓에 산행 코스내에 휴대폰 통화가 안되는 곳이 많지만, 흰대미산~양각산~수도산으로 이어진 능선은 오지답게 빼어난 수림을 자랑한다.", - "MNTN_HG_VL" : "467", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 웅천읍, 미산면", - "MNTN_NM" : "양각산" - }, - "longitude" : 126.65746040000001, - "latitude" : 36.253848400000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "412", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", - "MNTN_NM" : "양각산" - }, - "longitude" : 126.65746040000001, - "latitude" : 36.253848400000003 + "longitude" : 127.9610339, + "latitude" : 35.838789200000001 }, { "mountain" : { @@ -7559,6 +5799,16 @@ "longitude" : 127.4262073, "latitude" : 37.4377809 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "양천산은 진천군 문백면 평산리, 은티리, 사양리에 걸쳐 있는 산으로 말이 달리고 있는 분마형(奔馬形)을 하고 있다. 봉우리가 평원하여 반석과 같고 산중턱에는 석지(石池)가 있어 찬물이 그치지 않는 산이라 하여 냉천산(冷川山)이라 불리기도 한다.옥성교에서 그럭재마을을 지나 정상에 오르면 사양저수지가 내려다 보인다. 사미마을 쪽으로 내려오는 하산길은 경사가 급해 조심해야 한다. 임진왜란 때 주민들을 피신시킨 양천산성이 있다.", + "MNTN_HG_VL" : "350", + "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면", + "MNTN_NM" : "양천산" + }, + "longitude" : 127.4608339, + "latitude" : 36.770334800000001 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -7589,16 +5839,6 @@ "longitude" : 128.0685852, "latitude" : 37.584108200000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "어등산은 광산구의 중심이 되는 송정의 진산으로 한말 때 의병과 왜병이 자주 싸웠던 전쟁터로 그 이름이 널리 알려져 있다.물고기가 비늘을 세우고 올라갔다는 이야기가 전해져 내려오는 어등산 자락에는 양씨삼강문, 광산김씨효열문, 선암사지 삼층석탑 등의 명소가 자리하고 있다.또한 이곳 어등산과 황룡강이 맞닿는 곳에 위치했던 선암장터는 옛날 어등산과 용진산을 근거로 활동했던 항일의병들이 이 시장을 통해 의류, 양고 등 군수물자를 공급 받았다고 전해진다.어등산 남쪽 골짜기 깊숙한 곳에 위치한 절골마을에는 연화약수라는 석간수가 있어 위장병과 성인병에 효험이 뛰어나다고 알려져 있다.남서 방향으로 뻗은 능선은 황룡강을 사이에 두고 복룡산과 마주보고 있으며 송산유원지로 내려서는 언덕에 패러글라이딩 활공장이 있어 이를 즐기려는 사람들의 발길이 끊이질 않는다.", - "MNTN_HG_VL" : "290", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 광산구 산정동ㆍ박호동ㆍ서봉동", - "MNTN_NM" : "어등산" - }, - "longitude" : 126.7431679, - "latitude" : 35.205953800000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "어래산이 있는 단양군 영춘면 의풍리는 남한강의 옥동천 지류인 남대천 상류에 자리해 있으며 `정감록'을 믿고 찾아 들어온 조상들의 후예들이 터전으로 한때 외진곳을 전전하는 도박꾼들의 집합장소로 악명 높았던 곳이다.분지를 이룬 의풍리를 두고 동쪽에는 어래산이, 서쪽으로는 형제봉이 솟아 있어 남쪽에서 흘러내려온 남대천이 북쪽의 옥동천으로 빠지고 있다. 그래서 물이 흘러나가는 북쪽을 제외하고는 모두 산으로 둘러싸여 있어 외지에서 이곳으로 들어서려면 고개를 넘어야 한다. 때문에 일단 어래산 산행에 앞서 마을 진입 자체가 문제인데다 산행코스 역시 만만치 않다.이처럼 접근이 어렵다는 것은 사람들의 손때를 타지 않았다는 반증이다. 산 곳곳에 혼을 빼앗길 만큼 청정한 계곡이 흐르고 광활한 낙엽송 조림지대가 있어 수월치 않은 산행의 피로를 씻어 줄 것이다.", @@ -7606,8 +5846,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", "MNTN_NM" : "어래산" }, - "longitude" : 129.1800523, - "latitude" : 36.028150199999999 + "longitude" : 128.65534959999999, + "latitude" : 37.064015800000007 }, { "mountain" : { @@ -7619,16 +5859,6 @@ "longitude" : 128.1147469, "latitude" : 36.6442786 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "510", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", - "MNTN_NM" : "어림산" - }, - "longitude" : 129.16408229999999, - "latitude" : 35.8439938 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경기도 가평군과 양평군의 경계를 이루고 있는 어비산은 유명산 계곡을 사이에 두고 유명산의 동쪽에 솟아 있는 산이다. 어비산이란 이름은 옛부터 홍수 때 물고기가 산을 뛰어 넘는다고 하여 붙여진 이름이라 하는데, 주민들은 건너편의 유명산과 더불어 설악면과 옥천면을 경계한 산이라하여 대부산이라고도 부른다 한다.용문산에서 서쪽으로 뻗어내린 능선이 어비산을 이루고, 어비산에서 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이룬 계곡이 어비계곡이다. 이 어비계곡 또한 유명계곡에 못지 않을 정도로 아름다운 계곡이다. 큰 바위와 이따금 나타는 청정한 푸른소는 어비계곡의 자랑거리라고 할 수 있다. 계곡까지 급사면을 이룬 산록은 울창한 숲으로 뒤덮이고 숲아래 바위들은 푸른이끼옷을 입고 있고 그 아래로 흐르는 계류는 때로는 비취빛으로 바뀐다.길을 버리고 계곡을 따라 내려가는 맛이 또한 시원하다. 그러나 유명계곡처럼 완연한 협곡을 이룬 것은 아니고 길이도 유명계곡 보다는 짧은 편이어서 아쉽기는 하지만 경기도내의 아름다운 계곡중의 하나임은 분명하다. 산행은 유명산 입구인 가일리에서 오르는 코스와 대일마을에서 시작하는 방법이 있다.", @@ -7659,16 +5889,6 @@ "longitude" : 127.0386111, "latitude" : 37.173611100000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "312", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 대구면 사당리", - "MNTN_NM" : "여계산" - }, - "longitude" : 127.0386111, - "latitude" : 37.173611100000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "진도읍에서 임회면 용호마을에 이르면 단정한 모습의 선녀를 닮은 산이 보인다. 여귀산은 마치 단정하게 차려입은 선녀가 가야금을 타는 형상이라 하여 풍수지리가들은 옥녀탄금형의 산이라고 한다. 여기서 옥녀는 가야금을 타는 선녀를 지칭하는데, 선녀는 곧 귀한 여자이므로 산 이름이 여귀산이 된 걸로 추정된다.여귀산은 두 얼굴을 가진 산이다. 정상은 제법 오르기가 험난한 바위지대로 이뤄진 반면 정상을 중심으로 좌우로 흘러내린 지능선들은 부드러운 산세를 이루고 있기 때문이다. 밖에서 바라본 여귀산은 어느 방향이든 쉽게 오를 수 있을 것으로 보이지만 막상 산에 들어서면 수림이 빽빽해 기존 등산로를 벗어나서는 산행이 어렵다.그러나 일단 주능선이나 정상에 오르면 남서쪽으로 시원하게 펼쳐진 다도해국립공원을 비롯해 바다 풍경이 황홀하게 펼쳐진다. 특히 바다를 주홍빛으로 물들이는 일출과 낙조가 일품이다.", @@ -7699,16 +5919,6 @@ "longitude" : 127.0565735, "latitude" : 35.483787999999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "여우봉은 명성산 남쪽에 위치한 620m의 독립봉으로서 변화 있는 암능코스를 자랑한다. 명성산 남쪽 산록에는 여우봉과 망우봉 등으로 둘러싸여 있는 산정호수가 있는데 물이 맑고 주변 경치가 훌륭하여 관광 명소가 되고 있다.남북으로 이어지는 능선에는 암봉과 절벽, 초원 등이 다양하게 전개되어 말잔등 같이 부드러운 곡선을 이루면서 흘러내리고 주변에는 삼부연 폭포등 크고 작은 폭포들이 있으며 삼각봉 동쪽 분지의 화전민터 일대는 억새풀이 가득한 초원 지대로 장관을 이루고 있다. 봄이면 여우봉능선은 진달래꽃과 철쭉꽃 터널을 이루고 능선 바윗길은 연인들이 손을 잡아주면서 서로의 사랑을 확인할 수 있는 멋진 산오름길이다.", - "MNTN_HG_VL" : "620", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영북면 이동면", - "MNTN_NM" : "여우봉" - }, - "longitude" : 127.34282570000001, - "latitude" : 38.037779800000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "여항산은 함안의 진산이다. 진산은 보통 삶터의 북쪽에 자리를 잡는데 여항산은 남쪽에 자리잡고 있다. 이에 그 허점을 풍수지리의 비보책으로 보완, 산 이름을 물과 관련있는 여항산으로 지었다고 한다. 이름을 지은이는 1583년(선조 16년) 함주도호부사로 함안에 부임한 정구(鄭逑)라는 인물이다. ‘여항’이란 산 이름에는 삶터의 균형을 잡아 평화롭게 살고자 하는 염원이 담겨 있다.여항산은 꽃이나 단풍으로 이름난 산은 아니다. 근처에 이름 난 관광지가 있어 덤으로 유명세를 타는 산도 아니다. 그저 산과 들판 사이에 솟았다. 그러나 산은 정상 부근의 옹골찬 기세와 능선의 부드러움이 어울려 여느 명산 못지않다. 마치 세상 명리를 뿌리치고 초야에 묻혀 사는 지조 높은 옛 선비 같은 산이다.여항산 능선을 타고 남쪽으로 1시간 40분 거리에 서북산이 있다. 낙남정맥 산줄기인 여항산과 서북산은 한국전쟁 당시 낙동강 방어선이었으며 북한군 6사단과 미 25사단이 사투를 벌였던 곳이다. 미군들은 ‘갓 뎀’이라며 치를 떨었는데 이후 여항산과 서북산 일대를 갓데미산으로도 부른다고 한다. 서북산 정상에는 6.25 전적비가 있으며 당시 전투에서 전사한 미군 중대장의 아들 리처드 티몬스가 1995년 주한 미군으로 부임해 와 세웠다고 한다.", @@ -7726,8 +5936,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 공주", "MNTN_NM" : "연미산" }, - "longitude" : 127.10261819999999, - "latitude" : 36.473217099999999 + "longitude" : 127.1183333, + "latitude" : 36.484999999999999 }, { "mountain" : { @@ -7739,16 +5949,6 @@ "longitude" : 127.3316667, "latitude" : 35.9072222 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대야산 조항산을 지나온 백두대간이 청화산(984m)에 이르러 동녘으로 한줄기 곁가지를 뻗어 시루봉을 솟구치고, 다시 동녘으로 능선을 이어 아름다운 산세의 산을 일으키니 바로 연엽산이다. 연엽산은 북쪽 자락을 흘러온 궁기천과, 남녘 자락을 흘러온 농암천을 아울러 영강(潁江)으로 흐르게 하니 이 영강은 내성천과 합하여 낙동강에 들게 된다.화산리 앞에서 능선을 타고 오를 수 있으나 시루봉과 연이어 등산함이 좋고 정상은 소나무와 참나무숲이 있어서 아주 시원하다. 연엽산의 정상은 참으로 신비롭다. 멀리서 바라보았을 때 제법 뾰죽했던 정수리는 간 곳이 없고 이름 그대로 거대한 연잎을 하늘에 펼쳐놓은 듯 평평한 너른 밭과 같은 형상이었으니 말이다.이 산 정상에서는 전망이 없으나 동쪽으로 조금 내려선 헬기장에 서면 둔덕산 너머로 대야산 장성봉의 백두대간과 희양산 이만봉을 잇는 백두대간의 하늘 마루금이 초겨울 하늘 아래 눈부시다.", - "MNTN_HG_VL" : "850", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 화산리", - "MNTN_NM" : "연엽산" - }, - "longitude" : 127.8230556, - "latitude" : 37.798055599999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "연엽산은 꼭대기에서부터 사방으로 능선이 길게 여러 갈래로 뻗어있는데, 산세도 그리 험하지 않고 찾는 이도 적어 원시림이 그대로 보존된 숲과 계곡이 비경을 이루고 있다. 계곡에는 울창한 숲 사이로 기암절벽이 이어지고 크고 작은 연못이 곳곳에 흩어져 있어 등산과 함께 계곡의 경치를 즐길 수 있는 산이다.강원대학교 연습림이기도 한 연엽산은 수백년 된 노송들이 빽빽하고 나무들이 우거져 있다. 정상은 무인대피소와 아름드리 잡목이 우거져 하늘만 보인며 능선에는 철쭉이 많다.※ 강원대학교 연습림지역으로 일반인의 출입을 통제하고 있으므로 입산이 절대로 안됩니다.", @@ -7789,16 +5989,6 @@ "longitude" : 128.83388890000001, "latitude" : 35.0266667 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "암천을 따라 고성읍 서북쪽 12km 거리에 있는 산으로 옥녀봉, 선도봉, 망선봉의 세 봉우리로 이루어져 있으며 산의 북쪽 기슭에는 유서깊은 옥천사와 백련암, 청연암, 연대암 등의 암자가 있으며 특산물로는 송이버섯과 산딸기 등이 유명하다.옥천사 대웅전 뒤에 위치한 옥천샘은 사시사철 마르지 않고 항상 수량과 수온이 일정하며 이 샘의 물은 위장병, 피부병에 효험이 있다. 1948년 샘 위에 옥천각을 세워 보존하고 있다.", - "MNTN_HG_VL" : "524", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 개천면ㆍ영현면", - "MNTN_NM" : "연화산" - }, - "longitude" : 128.26530349999999, - "latitude" : 35.073357899999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "연화산으로 오르는 길은 3코스로 나누어진다.① 언양에서 365번 은칠행 버스로 은편하리 회관 앞에 내려 은편교회를 지나 태양가든 방향② 은편중리 매표소 옆 임도다라 내리재로 가는 길③ 은편중리에서 허고개 방향(남으로)15분 동신부엌가구에서 오르는 길이 열린다.산행들머리는 ③ 번째 코스로 간판 오른편 공장입구에서 왼편으로 오르는 산길이 열린다. 오른쪽에는 언양 반천일대를, 왼쪽에는 두동 은편리 일대를 끼고 능선을 걸어가노라면 고래등을 타고가는 기분이다. 발밑의 바싹 마른 낙엽은 푹신한 카페트처럼 부드럽다. 아무데나 앉아도 낙엽 자체가 방석이다.연화산 정상은 온통 나무를 베어 이곳에 집결시켜 놓고 잡목이 우거져 정상에는 들어갈 수 없을 만큼 어질러져 있다. 우거진 잡목 숲은 멧돼지의 서식지가 되고 있다.", @@ -7806,18 +5996,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 언양면", "MNTN_NM" : "연화산" }, - "longitude" : 128.26530349999999, - "latitude" : 35.073357899999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "연화산은 낙동정맥이 백두대간과 만나는 태백 한 가운데 불끈 솟아 있어 사방을 조망하는데 막힘이 없다. 태백시가 이 산을 중심으로 가락지처럼 형성되었다고 해도 과언이 아니다. 산속에 연화부수형의 명당 연당지가 있고 산의 형상이 연꽃처럼 생겨서 연화산이라 한다. 옛날엔 연화봉이라 불렀는데 최근에 와서 연화산이라 부르게 되었다. 연화산 주봉인 옥녀봉은 옛날 천지가 물바다로 되었을 때 옥녀봉에 옥녀가 피난을 왔고 통리의 유령산 갈미봉에 갈미를 쓴 남자가 피난을 왔는데 나중에 물이 다 빠진 다음 둘이 만나 세상에 사람을 퍼뜨렸다는 전설이 있다. 투구봉은 일명 비녀봉이라 한다. 봉우리가 바위 절벽으로 되어 있으며 그곳에 비녀바위가 있어 비녀봉이라 불렀다. 그런데 장군대좌형국의 뒷산 봉우리인 비녀봉의 바위 절벽을 장군의 투구로 보고 투구봉이라 부르게 되었다.", - "MNTN_HG_VL" : "1172", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 문곡동", - "MNTN_NM" : "연화산" - }, - "longitude" : 128.26530349999999, - "latitude" : 35.073357899999998 + "longitude" : 129.2058389, + "latitude" : 35.633003299999999 }, { "mountain" : { @@ -7829,16 +6009,6 @@ "longitude" : 128.5953988, "latitude" : 35.541475000000013 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "옛날 어느 도승이 여량을 지나다가 이곳 산세를 보고 저산이 화(火)자 모양을 닮아 마을에 불이 자주 일어나는 재앙이 있겠다고 하니, 마을 사람들이 어찌하면 그 재앙을 막을 수 있겠느냐며 그 비방을 알려달라 조르니,저 산봉우리에 간수를 묻으면 된다고 하여 그대로 이행하였으며, 그 후 지금까지 아무런 탈이 없었다고 한다. 그런데 1955년 초겨울에 난데없이 집 근처에 쌓아둔 짚가리나 불쏘시개로 쓰는 갈비(솔가리:말라 서 땅에 떨어진 솔잎)더미에 불이 나,사람들이 달려들어 불을 끄면 금새 꺼지며 또 여기저기 불이 붙었다. 그런데 이상하게도 그 불이 사람사는 가옥에는 전혀 피해를 주지 않고 짚가리나 갈비더미 에만 불이 일어났다. 마을 사람들이 산에 올라가 소금 단지를 열어보니 소금이 말라 있었다고 한다. 소금을 채워 넣었 더니 별일이 없었다. 그래서 소금을 감추는 산이라 하여 소금 염,감출 장,봉우리 봉 자를 써서 염장봉(鹽藏峰)이라 부른다.", - "MNTN_HG_VL" : "689", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북면 여량리", - "MNTN_NM" : "염장봉" - }, - "longitude" : 128.7305556, - "latitude" : 37.4641667 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -7859,16 +6029,6 @@ "longitude" : 127.3986111, "latitude" : 35.612499999999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "277", - "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시", - "MNTN_NM" : "영천악" - }, - "longitude" : 128.95304709999999, - "latitude" : 35.982839299999988 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -7889,16 +6049,6 @@ "longitude" : 129.05500000000001, "latitude" : 35.517000000000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "화왕산역과 맞닿아 있는 관룡산역과 연결되고 있으며, 영축산으로도 불리는 이 산은 영산면 소재지를 북쪽에서 막아서면서 너덜지대가 확연하게 보이는 산경을 지니고 있다. 험한 산세를 지닌 남쪽사면의 급한 경사면에 산객들에게는 쉽게 접근을 허락하지 않지만, 구계리 쪽으로 흘러내리는 동릉에는 계곡과 유적이 산재하고 있다. 북쪽사면은 암릉과 암봉이 모여 있어 역시 산세가 험하고 그 기세로 화왕산을 견제하고 있다. 한옥과 향교가 있는 고리가 산자락에 마을을 이루고 있어 하산길에 잠시 머물면서 옛 향기를 맛보는 재미도 얻을 수 있다.", - "MNTN_HG_VL" : "737", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 영산면", - "MNTN_NM" : "영취산" - }, - "longitude" : 127.71361159999999, - "latitude" : 34.826988399999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "여수시 북동쪽 여천 산업단지 부근에 솟은 영취산은 창녕 화왕산, 마산 무학산과 더불어 전국 3대 진달래군락지 중 한곳으로 꼽힌다. 진달래만 수만그루가 모여 군락을 이룬 15만평 규모의 넓은 진달래밭이 산 곳곳에 자리잡고 있어 봄이면 장관을 연출한다. 매년 4월 초순경에 절정을 이루는데 이때를 맞춰 진달래축제가 개최된다.영취산은 예로부터 신령스런 산으로 인식되어 기우제나 치성을 드렸던 곳이다. 영취산이란 그 이름도 석가모니가 최후로 설법했던 인도의 영취산에서 따온 것으로 추측된다. 또 산 기슭에는 전통기원 도량이었던 금성대가 있고 그 아래 기도도량인 도솔암이 지어져 오늘까지 이어지고 있다.해발 510미터의 산으로 정상에 서면 남해의 크고 작은 섬들과 동북쪽 광양의 백운산, 묘도가 선명하다. 서남쪽으로 흥국사도 또렷하게 보인다.", @@ -7909,16 +6059,6 @@ "longitude" : 127.71361159999999, "latitude" : 34.826988399999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "창녕군 영산면에 있는 영취산은 해발 682미터의 비교적 낮은 산이지만 지천에 위치한 함박산(작약산)과 더불어 영산면 소재지를 품은 형상을 하고 있다.영취산을 오르는 코스는 대략 두 가지로 나뉘는 데 영산여중·고를 지나 보덕암-632봉-정상으로 오르는 길과 영산향교-영명사-영축산성-정상길이 있다. 시간과 거리로 따지면 영산향교 코스로 오르는 것이 수월하다. 이 코스 초입에는 유명한 함박 약수터와 영산 석빙고(石氷庫)가 있다.함박 약수터는 함박산 등산이 시작되는 초입에 위치해 있고 석빙고는 더 아래에 있다. 창녕읍에 있는 석빙고보다 규모가 비교적 작은 영산 석빙고는 보존상태가 양호한 편이다. 석빙고에서 정상까지는 2시간이면 충분하다. 중간에 쉬운 암벽등반 구간도 나오는데 초보자도 별 어려움 없이 오를 수 있다.정상에서 병봉으로 내쳐 가면 보름고개와 종암산, 큰 고개를 거쳐 부곡온천까지 갈 수 있다. 시간은 줄잡아 6시간 이상 걸리는 만큼 첫 출발부터 준비를 철저히 해야하는 코스다.", - "MNTN_HG_VL" : "737", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 영산면, 계성면", - "MNTN_NM" : "영취산" - }, - "longitude" : 127.71361159999999, - "latitude" : 34.826988399999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "남양주군에 있는 예봉산은 경기도 하남시의 검단산을 바라보고 있는 산이다. 예봉산은 남북의 두 줄기가 팔당댐에서 합쳐졌다가 서울로 흘러드는 한강의 물결 파노라마를 지켜볼 수 있는 산으로 인접해 있는 예빈산(禮賓山 589m)을 거치는 것이 일반적이다.옛날에 배를 타고 영월, 정선, 충주, 단양, 춘천을 오가는 길손들이 한양을 떠나며 삼각산이 보이는 이곳에서 임금에게 예를 갖추었다 해서 예빈산이라 부르기도 했다. 그런 연유에서인지 이 산자락에서는 실학의 선구자 정약용, 건국 운동을 선동했던 몽양 여운형 선생, 가나안 농군학교를 설립해 농촌지도자를 양성하는 데 앞장섰던 김용기 장로 등 이름 있는 인물들이 많이 배출되었다.예봉산의 능선이나 정상에 올라가면 어디서나 북한강과 팔당댐이 산을 끼고 굽이쳐 흐르는 아름다운 모습을 볼 수 있다. 능선길의 단풍은 특히 좋다. 정상 주변은 옛 성터 같은 돌무더기가 있다. 예전에는 산령단이 있었다고 하나 지금은 헬기장으로 변했고, 삼각점(양수 26)과 예봉산악회가 세운 정상표지석이 있다.", @@ -7939,6 +6079,16 @@ "longitude" : 127.2611921, "latitude" : 37.559263000000001 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "362", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", + "MNTN_NM" : "예성산" + }, + "longitude" : 127.1329367, + "latitude" : 35.117416200000008 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "오갑산은 2개도(경기,충북), 3개군(음성,여주,충주)이 경계를 이루고 있는 명산으로 삼국시대 에는 오압산(梧壓山)이라 불리었다. 한때 오압사라는 거찰을 배치하고 있었으나 지금은 그 흔적을 찾아 볼 수 없으며 미륵좌불 하나만이 지방 사적으로 지정되어 보호되고 있다.삼국시대에 고구려와 신라의 국경지역이었던 오갑산은 한수지역의 거대한 농토를 확보하기 위한 양국의 크고 작은 싸움이 잦았던 곳으로 오갑산 정상에 진을 치고 군대를 주둔하면서부터 오갑산이라 불려지기 시작했다. 임진왜란 당시 명나라 장수 이여송이 왜군과 전투를 하기 위해 진을 쳤으나 왜군과의 전투는 없었던 것으로 전해지며 그 이후 오갑산 정상을 이진봉이라 하고 이진봉 북방 8부능선의 펑퍼짐한 갈대밭을 진터라고 부르고 있다.오갑산 앞의 삼태봉은 통신수단이었던 봉화터가 지리하고 있는데 맑은 날에는 사방 백리길이 훤히 보인다. 이름난 산인만큼 곳곳에 얽힌 사연들이 많이 전해져 내려오고 있다.오갑산은 바위가 거의 없는 흙산이면서 이상하리만큼 우뚝하다. 기름진 흙산이라서 숲이 울창하고 닭발처럼 사방으로 퍼져 나간 산줄기도 많다. 비탈도 산자락은 순하지만 머리 부분은 매우 가팔라서 고스락에 오를 때는 매우 힘이 들고 산행의 맛도 충분히 느낄 수 있다. 흙산인 데도 오랜 세월과 많은 비바람에 어떻게 그 우뚝함을 지키고 의연히 서있을 수 있는지 신기하다.오갑산은 2개도(경기,충북), 3개군(음성,여주,충주)이 경계를 이루고 있는 명산으로 삼국시대 에는 오압산(梧壓山)이라 불리었다. 한때 오압사라는 거찰을 배치하고 있었으나 지금은 그 흔적을 찾아 볼 수 없으며 미륵좌불 하나만이 지방 사적으로 지정되어 보호되고 있다. 삼국시대에 고구려와 신라의 국경지역이었던 오갑산은 한수지역의 거대한 농토를 확보하기 위한 양국의 크고 작은 싸움이 잦았던 곳으로 오갑산 정상에 진을 치고 군대를 주둔하면서부터 오갑산이라 불려지기 시작했다.임진왜란 당시 명나라 장수 이여송이 왜군과 전투를 하기 위해 진을 쳤으나 왜군과의 전투는 없었던 것으로 전해지며 그 이후 오갑산 정상을 이진봉이라 하고 이진봉 북방 8부능선의 펑퍼짐한 갈대밭을 진터라고 부르고 있다. 오갑산 앞의 삼태봉은 통신수단이었던 봉화터가 지리하고 있는데 맑은 날에는 사방 백리길이 훤히 보인다. 이름난 산인만큼 곳곳에 얽힌 사연들이 많이 전해져 내려오고 있다.오갑산은 바위가 거의 없는 흙산이면서 이상하리만큼 우뚝하다. 기름진 흙산이라서 숲이 울창하고 닭발처럼 사방으로 퍼져 나간 산줄기도 많다. 비탈도 산자락은 순하지만 머리 부분은 매우 가팔라서 고스락에 오를 때는 매우 힘이 들고 산행의 맛도 충분히 느낄 수 있다. 흙산인 데도 오랜 세월과 많은 비바람에 어떻게 그 우뚝함을 지키고 의연히 서있을 수 있는지 신기하다.", @@ -7949,16 +6099,6 @@ "longitude" : 127.6958333, "latitude" : 37.140000000000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "울창한 숲과 이름난 사찰, 약수, 유적지 등이 산재해 있어 관광객과 등산객으로 늘 붐비는 오대산은 강원도 평창군 진부면과 도암면, 홍천군 내면, 강릉시 연곡면의 오대산국립공원의 서부지구에 위치해 있다. 특히 짧은 산행이지만 유서깊은 사찰과 암자를 곳곳에서 볼 수 있는 상원사와 적멸보궁, 정상인 비로봉을 거쳐 미륵암으로 하산하는 코스가 가장 유명하다. 상원사는 6·25때 한암이라는 승려의 산화로 아군의 전략상 소실될 뻔 하였던 위기를 피해 현재까지 그 형태를 보존하고 있는 사찰이다. 국보 36호인 동종이 있으며 신라시대 자장법사에 의해 창건되었다.예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.높이로 본다면 비로봉은 오대산의 최고봉이자 이 산의 정상이라 할 수 있다. 백두대간의 주맥이 설악에서 이어져 두로봉과 동대산으로 연결되는 서쪽 일대에 자리하고 있는 오대산은 명산으로 이름이 난 만큼 유서깊은 사찰과 암자들이 많다. 또한 산에 관련된 신비로운 전설들이 많이 전해 내려오고 있어 오대산의 명성을 더하고 있다.오대산의 다섯 봉우리는 호령봉, 비로봉, 상왕봉, 두로봉, 동대산이다. 이 다섯 봉우리중 비로봉이 제일 높은 봉우리이고 그 다음이 호령봉이다.", - "MNTN_HG_VL" : "1565", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 홍천군 내면, 강릉시 연곡면", - "MNTN_NM" : "오대산" - }, - "longitude" : 128.5430327, - "latitude" : 37.798146699999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.", @@ -7966,28 +6106,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 강릉시 연곡면", "MNTN_NM" : "오대산 동대산" }, - "longitude" : 128.5430327, - "latitude" : 37.798146699999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "높이로 본다면 비로봉은 오대산의 최고봉이자 이 산의 정상이라 할 수 있다. 백두대간의 주맥이 설악에서 이어져 두로봉과 동대산으로 연결되는 서쪽 일대에 자리하고 있는 오대산은 명산으로 이름이 난 만큼 유서깊은 사찰과 암자들이 많다. 또한 산에 관련된 신비로운 전설들이 많이 전해 내려오고 있어 오대산의 명성을 더하고 있다.", - "MNTN_HG_VL" : "1563", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 진부면, 강릉시 연곡면, 홍천군 내면", - "MNTN_NM" : "오대산 비로봉" - }, - "longitude" : 128.52443679999999, - "latitude" : 37.779378399999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "오대산의 다섯 봉우리는 호령봉, 비로봉, 상왕봉, 두로봉, 동대산이다. 이 다섯 봉우리중 비로봉이 제일 높은 봉우리이고 그 다음이 호령봉이다.", - "MNTN_HG_VL" : "1560", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 도암면, 홍천군 내면", - "MNTN_NM" : "오대산 호령봉" - }, - "longitude" : 128.53277779999999, - "latitude" : 37.779722199999988 + "longitude" : 128.59833330000001, + "latitude" : 37.7744444 }, { "mountain" : { @@ -7999,16 +6119,6 @@ "longitude" : 128.07499999999999, "latitude" : 35.673888900000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 양산시 원동면에 자리한 오룡산은 산봉우리가 5봉으로 용처럼 굽이굽이 생겼다 하여 오룡산이라는 설과 옛날 통도사 구룡지 못에서 살던 아홉 마리 용 중 다섯 마리 용이 통도사 남서쪽에 있는 산너머 골짜기로 달아난 오룡골이 있는데 그 골짜기 위에 있는 산이라 하여 오룡산이라 한다.골짜기들이 예전에 비해 오염되고 많이 훼손되었지만 통도골과 도터진골(도태정골)은 원시의 자연을 아직 간직하고 있다. 통도골은 원동면 선리 새들마을에서 통도사로 넘어가는 가장 빠른 길이고, 도터진골은 깨침을 받은 골짜기라는 뜻이다. 두 골짜기는 산 아래로 내려오면서 하나로 합쳐져 통도-도터진골이라고 부른다.통도사에서 스님들의 수도에 방해가 된다고 하여, 일반인 출입을 막고있는 관계로 지산마을까지 버스로 그리고 자장암까지 40여분 걸어야 한다. 오룡산은 다섯 봉우리가 북에서 2봉 1봉 5봉 4봉 3봉 높이 따라 연결되어 있고, 그 위를 암릉을 타고 가는 길도 매우 험하니 왼편으로 트레버스하여 칼바위 위에 있는 곳까지 돌아가는 것이 좋다.", - "MNTN_HG_VL" : "967", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", - "MNTN_NM" : "오룡산" - }, - "longitude" : 129.0172182, - "latitude" : 35.478224900000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면과 화천군 간동면 사이에 있는 오봉산은 해발 779m이고 다섯개의 봉우리가 있다고 해서 오봉산이라고 한다. 기암절벽과 노송이 어울려 한폭의 동양화 같은 산으로 유서깊은 청평사가 있다.배후령에서 오르게 되는 첫번째 봉우리가 1봉(나한봉), 두번째 봉우리인 관음봉, 세번째 봉우리인 문수봉, 네번째 봉우리인 보현봉, 다섯번째 봉우리인 정상 비로봉이 있다. 이중 제5봉인 정상에서 청평사 방면으로 뻗어내린 암릉이 특히 빼어난 풍광을 지녔다. 이 암릉을 따라 소양호를 바라보며 내려가는 길이 오봉산행의 백미라 할 수 있다.", @@ -8026,8 +6136,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 평창군", "MNTN_NM" : "오봉산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 128.28561920000001, + "latitude" : 37.601998999999999 }, { "mountain" : { @@ -8036,8 +6146,8 @@ "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 운암면", "MNTN_NM" : "오봉산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 127.1325344, + "latitude" : 35.644214499999997 }, { "mountain" : { @@ -8046,38 +6156,8 @@ "MNTN_LOCPLC_REGION_NM" : "전남 보성군 득량면", "MNTN_NM" : "오봉산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "영남알프스는 영축산 염수봉으로 솟구치며 남으로 내리닫다가 양산시 어곡동 어곡리의 매바위 못미쳐서 두 갈래로 나눠진다. 한가락은 남서로 뻗어 토곡산(855m)을 토한 뒤 낙동강에 첨벙 뛰어들었다. 나머지 한 능선은 동남으로 방향을 잡고는 매바위를 지난 뒤 남쪽을 향하다 화제고개에서 남서로 뒤틀어 오봉산 줄기를 이루고는 살며시 낙동강으로 기어들었다. 토곡산과 오봉산은 마주보고 있는데 북은 토곡산, 남은 오봉산이고 그 사이에 낙동강에 연한 화제들판이 펼쳐졌다.오봉산의 남쪽은 양산천을 낀 물금들이고 그 건너편에 금정산이 솟아있다. 물금읍과 원동면 경계를 이룬 오봉산은 말 그대로 5개의 봉우리로 이뤄진 능선이다. 530.8미터의 제1봉이 낙동강 바로 동쪽에 자리잡았고, 그 반대편 북동쪽 강서동 부근 화제고개 못미쳐 제5봉(449.9m)이 있어 산줄기의 흐름과는 반대로 낮은 봉우리에서 마지막에 높은 봉우리를 이룬 셈이다. 이 산 마루턱에는 고운 최치원의 유상지인 임경대 유적이 있다. 임경대는 오봉산 제1봉의 7부 능선에 있는 바위봉우리로 낙동강과 그 건너편의 산, 들과 어울려 수려한 산천을 확인할 수 있는 훌륭한 명소 중 하나다.특히 매바위 암릉은 설악산의 공룡릉에 버금가는 경치라고 이 지역 등산인들은 말한다. 산 자체의 경관보다는 이 산등성이에서 바라보는 낙동강 주변의 널찍한 풍광이 특히 손꼽아 줄만한 장관이라고 말하기도 한다.", - "MNTN_HG_VL" : "633", - "MNTN_LOCPLC_REGION_NM" : "경남 양산시 교동", - "MNTN_NM" : "오봉산" - }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "오봉산은 다섯 개의 낙타등 같은 봉우리가 솟았다 하여 유래한다. 경주 시내에서 서쪽 외곽인 건천읍과 서면 일대에 있으며 문헌을 보면 부산의 위성봉임을 알 수 있다. 일명 주사산이라 불리기도 하는데, 이는 정상의 주사암에서 따온 것이다.오봉산에서 가장 유명한 것은 여근곡이다. 건천읍 신평리에서 오봉산을 볼 때 산기슭에 불두덩처럼 도톰한 부분이 보이는데 희한하게 가운데 오목한 골홈이 패여 있다.산행은 여근곡쪽으로 올라 오봉산과 주사암, 고랭지채소밭을 지나 동문 쪽인 송선리로 하산하는 것이 일반적이며, 성암사를 기준으로 능선과 임도를 따라 도는 원점회귀산행도 가능하다. 오봉산 원점회귀산행의 도상거리를 7.6킬로미터, 가민 콜로라도 300GPS로 확인한 실주행거리는 11.4킬로미터다오봉산은 부산성과 주사암, 지맥석, 여근곡 등의 역사적 의미와 유래를 알아보고 산행한다면 더욱 재미없는 산행이 될 것이다. 더불어 정상과 지맥석에서의 시원한 경치는 땀방울을 식히기에 모자람이 없다. 평범한 산이지만 그 자락에는 신라 천 년의 사연과 설화가 배어있다.", - "MNTN_HG_VL" : "324", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 서면, 건천읍", - "MNTN_NM" : "오봉산" - }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "101", - "MNTN_LOCPLC_REGION_NM" : "인천시 남동구 도림동", - "MNTN_NM" : "오봉산" - }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 127.16861110000001, + "latitude" : 34.752777799999997 }, { "mountain" : { @@ -8086,18 +6166,18 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", "MNTN_NM" : "오봉산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 128.8075, + "latitude" : 37.704722199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "오봉산(五峰山)은 이안천변의 야트막한 산이다. 옛부터 상당히 큰 고을이었던 함창의 정남방에 들판위로 다섯 봉우리가 섬처럼 떠있어 이름이 났다. 기우단이 있었고 남산고성과 성산봉수대 터가 남아있다. 산록 여기저기 고분이 산재하나 대부분 도굴된 상태라 관리의 소홀함과 세월의 야박함을 동시에 느끼게 해주는 역사의 현장이다. 1992년 등산로가 개설되어 함창읍 사람들이 즐겨 찾는다.정상에는 표석이 설치되어 있으나 잡목이 시야를 가리기 때문에 산행중 간간이 보이는 장소에서 주변을 감상하는 것이 좋다. 하산하는 길에 난간을 두른 바위에 이르게 되다. 이 곳은 주변이 탁트여 주변을 조망하기에 가장 좋은 장소의 하나이다. 함창.점촌시내가 한눈에 보이고 끝없이 펼쳐지는 벌판과 운달산.천주봉이 더 멋지게 솟아있다.", - "MNTN_HG_VL" : "235", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주 합창읍 신흥리, 공검면 역곡리", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "곡성땅을 관통해 흐르면서 남동쪽으로 향하던 섬진강 물줄기를 북진시키는 오산은 자라가 섬진강 물을 마시고 있는 모습이라는 데서 이름을 따왔다고도 하고 정상의 벼랑 때문에 이런 이름을 얻었다고도 한다. 정상까지 걸리는 시간도 1시간 내외에 불과하지만 산꼭대기 고스락은 분수처럼 비밀을 내뿜는 화수분 같은 산이다.오산 사성암 전망바위에서 내려다 본 구례들판. 문척면 나들목인 신·구 문척교와 그 아래로 넉넉하게 흐르는 섬진강이 한눈에 들어오며 지리산 북서쪽 자락도 파노라마처럼 펼쳐진다. 그 하나는 넋을 빼앗는 조망의 즐거움이다.'산에 들면 산을 모르고 산을 벗어나면 그 산이 보인다'는 말이 있다. 오산에 오르면 바로 헌걸찬 지리산이 한눈에 들어온다. 북동쪽으론 노고단,반야봉,삼도봉이 뚜렷하고 멀리 명선,촛대봉이 아련하다. 동쪽으론 문수리가 아스라이 펼쳐지며 그 오른쪽으로 왕시루봉과 황장산이 능파를 이루며 달리고 있다. 한마디로 말하면 지리산 최고 전망대인 셈이다.두번째 비밀 역시 풍광의 아름다움이다. 실핏줄 같은 개울 물을 모아 남도의 이산 저산의 뭉툭한 허리를 감돌며 굽이치는 섬진강이 가장 찬란한 빛으로 흐른다. 지리산 어떤 전망대도 오산에서 바라보는 섬진강의 비경을 따라잡기 힘들 듯 싶다.세번째 비밀은 오산의 보석 사성암의 전설로 시작된다. 깎아지른 벼랑에 제비 집처럼 붙여 지은 사성암은 582년 연기조사가 세운 이래 원효,의상,도선,진각 등 4대 성인이 수도를 했다는 곳이다. 사성암이란 이름도 여기서 유래했다. 절 주변 곳곳에 성인들의 흔적이 전설 혹은 설화로 전해 내려온다. 시간이 있다면 고려 때 새겨진 마애불도 둘러볼 만하다. 마지막 비밀은 사성암 주변 수직바위 군. 오산십이대라 불리는 이 바위들은 갖가지 전설과 기기묘묘한 형태로 탐방객들의 눈길을 끌고 있다. 또한 3월이 되면 보리밭이 푸릇해지고 여기저기 매화와 산수유꽃이 피어나 한 폭의 산수화를 그려낸다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면", + "MNTN_NM" : "오산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 127.4819578, + "latitude" : 35.179359300000002 }, { "mountain" : { @@ -8106,8 +6186,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", "MNTN_NM" : "오산 (자라산)" }, - "longitude" : 127.0687686, - "latitude" : 37.147824800000002 + "longitude" : 127.4819578, + "latitude" : 35.179359300000002 }, { "mountain" : { @@ -8116,18 +6196,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", "MNTN_NM" : "오산(자라산)" }, - "longitude" : 127.0687686, - "latitude" : 37.147824800000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "오서산은 금북정맥의 최고봉으로 까마귀가 많다하여 유래된 이름이다. 서해안에서 가장 높고 웅장하게 솟아 있는 산이어서 인근 바다를 지나가는 배들이 쉽게 알아보고 뱃길을 가늠한다고 해 ‘서해의 등대’라고 불리기도 한다. 국내 5대 억새산 중 하나로 손꼽힐 만큼 억새밭이 장관을 이루며 사방으로 탁 트여있는 조망까지 만끽할 수 있어 만추산행으로 제격이다.오서산은 정상까지 바위가 발달되어 있어 악산의 성격을 띠다가 하산코스에서는 완만한 곡선이 이어져 바위지대가 흔하지 않은 육산으로 되어 있다. 오르는 길에 기암괴석이 즐비하고 단풍길도 이어져 있다. 산의 능선이 용의 머리 같다고 해서 이름이 붙여진 용허리나 줌방바위, 대문바위, 은폭동 폭포, 신랑신부바위, 농바위가 눈길을 끈다. 산 정상에 오르면 석각으로 된 사각형의 우물 맛도 그만이다. 오서산이 위치한 광천은 감과 어리굴젖 등 해산물이 유명하다.", - "MNTN_HG_VL" : "790", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 청소면, 청라면·홍성군 광천읍", - "MNTN_NM" : "오서산" - }, - "longitude" : 126.6653237, - "latitude" : 36.449378000000003 + "longitude" : 127.4819578, + "latitude" : 35.179359300000002 }, { "mountain" : { @@ -8141,13 +6211,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "대미산에서 뻗어나온 줄기가 운달산과 부운령을 지나 남쪽 끝에 마지막으로 일군 산이 경북 문경의 오정산이다. 조선조 학자 서거정의 팔경에 나오는 `오정종류'가 바로 이 산을 일컫는 말이다. 많은 양의 석탄을 품고 있는 이산은 그 기슭에 광산촌을 이루었다.삼국시대 초기에 축조된것으로 알려진 고모산성과 성황당을 지나 유명한 토끼비리를 따라 산행이 시작된다. 돌을 쪼아내 만든 토끼비리의 시작 지점에서 부터 희미한 길을 따라 능선을 타고 오르게 된다. 이곳에는 아직도 일부 산성이 남아 있다. 더 올라서서 623 봉에 오르면 이곳에서의 조망은 일품이다. 이 능선에 진달래 군락이 형성되어있다. 진남교반을 휘감아 도는 영강과 시원스런 3번 국도의 모습이 장관을 이룬다. 이곳에서 약 1시간 가량오르면 정상에 닿게된다.정상은 비슷한 높이의 3 개의 봉우리로 되어 있고 밑에서 보기보다 올라와서 보면 암벽이 의외로 많이 보이는 산이다. 여기헬기장에서 북쪽으로 정상이 있는데 헬기장에서의 전망이 제일 좋다. 정상에서 보면 멀리 영순면으로부터 북서쪽의 백두대간이 병풍처럼 둘러친 모습이 보인다. 정상의 조망 때문에 문경의 최고 일출 산행지로 이곳을 꼽는다.", - "MNTN_HG_VL" : "810", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 호계면", - "MNTN_NM" : "오정산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 홍천읍, 횡성군 공근면", + "MNTN_NM" : "오음산" + }, + "longitude" : 127.92222219999999, + "latitude" : 37.605555600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "강원도 횡성과 홍천사이에 뿌리룰 둔 오음산은 유독 새들이 많고 봄이 되면 들꽃잔치로 꽃내음이 산야를 뒤덮는 옛산의 풍치를 고스란히 간직한 태고의 산이다. 삼마치에서 오음산으로 이어지는 능선은 군데군데 벌목된 코스가 있고 굴곡이 심하므로 주의해야 한다. 급경사 산길을 올라 완만한 능선을 따라가다 울창한 숲길 아래 능선을 탄다. 급경사를 올라 정상에 서면 주변에서 가장 높은 산임을 알 수 있다. 정상 봉우리에는 삼각점이 있다.정상에서는 고사목 전망장소와는 비교가 안될 정도로 광활한 파노라마가 펼쳐진다. 북으로는 가리산이 멀리 사명산과 함께 조망되고, 북동으로는 공작산이 보인다. 그 뒤 멀리로 백우산과 가마봉이 보이고, 더 멀리로는 장수대 방면 안산과 설악산 대청봉도 보인다.", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 홍천군", + "MNTN_NM" : "오음산" }, - "longitude" : 128.12652310000001, - "latitude" : 36.660165800000001 + "longitude" : 127.92222219999999, + "latitude" : 37.605555600000002 }, { "mountain" : { @@ -8169,6 +6249,16 @@ "longitude" : 128.74241280000001, "latitude" : 35.539616799999997 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평군에 위치해 있는 옥녀봉은 30리에 달하는 용추계곡을 끼고 있어 여름철 가족 산행지로 적합하다. 특히 곰바위 소바위 미륵바위 용세수대야 등이 몰려 있는 용추폭포 일대가 용추계곡의 백미다.옥녀봉은 마치 여자가 치마자락을 펼쳐 놓은 것 같다하여 옥녀봉이라 한다.가평읍에서 북면을 향해 2.3㎞ 정도 가다가 다리를 지나 좌회전하여 군부대 돌담을 끼고 2㎞ 정도 들어가면 용추계곡 주차장이다.차에서 내리면 바로 용추폭포가 보인다. 높이 20m의 용추폭포는 언뜻 보기엔 별 볼품이 없으나 소용돌이가 심한 소를 이루고 있어 청량감을 자아낸다.옛날 용이 승천했다는 전설을 지닌 용추폭포 옆 경사진 바위에는 용이 누웠던 자리라 일컬어지는 깊게 파인 자국이 나있다. 또 폭 1m의 용세수대야라는 바위 웅덩이가 있다.이 산은 입구에서부터 약초향이 물씬 풍긴다. 취나물과 더덕처럼 생긴 보약제 잔디등 많은 약제가 등산로 양옆으로 나 있어 약초를 캐는 재미도 솔솔하다.", + "MNTN_HG_VL" : "715", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 승안리", + "MNTN_NM" : "옥녀봉" + }, + "longitude" : 127.4877778, + "latitude" : 37.8636111 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "\"보령 시가지를 동남쪽으로 둘러서 있는 산이 성주산과 옥마산이다. 성주터널이 생기기 전 성주와 부여 쪽으로 가려면 옥마산을 통과하는 구절양장을 고갯길을 넘어야 했다. 비포장도로인 옛길을 가쁜 숨을 몰아쉬고 오르다보면 보령시가지가 한눈에 내려다보이는 정자가 옥마정이다.옥마정에서 성주로 향하는 내리막길에서 다시 산을 타고 오르면 보령 행패러글라이딩 활공장과 만난다. 이곳은 항공 스포츠를 즐기는 이들에게 새로운 메카 구실을 하는 곳이다. 행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하여 자세한 안내를 받을 수 있다.소요 시간 :180분 (구간별, 코스별로 다름)최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 옥마정에서 보는 시내전망, 활공장(행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하면 자세한 안내를 받을 수 있다)", @@ -8211,63 +6301,33 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "완택산은 연하리와 동강변인 삼옥리 사이에 위치하고 있다. 산세는 동고서저, 즉 주능선을 경계로 동쪽 연하리 방면은 급경사에 절벽이 많고, 서쪽 동강 방면은 완만한 산세를 이루고 있다. 산세가 이렇듯 그 옛날 완택산은 천혜의 요새였다는 전설이 전해지고 있다.주능선 동쪽은 수직절벽이 대부분이어서 자연성곽을 이루고 서쪽은 동강 물줄기가 자연적인 방어선을 이루고 있다. 그래서 완택산은 옛날 예맥의 땅이었다는 얘기가 전해지며, 퉁구스식 방법으로 축성한 산성흔적이 산자락 곳곳에 조금씩 남아있다.완택산 등산로는 급경사를 이룬 동쪽 연하리 방면에서 오르내리는 코스가 일반적이다. 그러나 요즘은 동강변 삼옥리에서 완만한 경사를 이룬 능선과 계곡 코스가 인기 있다.", - "MNTN_HG_VL" : "918", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", - "MNTN_NM" : "완택산" - }, - "longitude" : 128.55202180000001, - "latitude" : 37.2109405 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "왕모산은 안동에서 동북쪽으로 30여킬로미터 떨어진 곳에 있다. 낙동강이 굽어보이고 안동호와 가까운 산으로 산세가 수려하고 자연경관이 매우 아름답다. 주위에는 유적지가 많아 답사산행 하기에는 좋은 산이다. 안동댐을 내려다보며 우뚝 솟아 있는 왕모산은 1361년 고려 공민왕이 홍건적의 난을 피해 안동으로 왔을 때 왕의 어머니가 이 산으로 피난했다 해서 붙여진 이름이다. 전설에 의하면 홍건적이 이곳까지 진격하여 공민왕이 위태롭게 되자 백마를 탄 노장수가 번개처럼 나타나 왕을 구하고 지렁이로 변했다고 한다.이 산은 그리 높지는 않지만, 12개의 봉우리를 거쳐야만 산 정상에 오를 수 있고, 갈선대란 바위가 산 이름보다 더 유명하다. 수려한 경관 속에 펼쳐지는 왕모산성 등산로는 약 6.8킬로미터로 열두 봉우리 정상마다 특색 있는 암석들이 신비함을 더해 주고 있다.상수리나무와 굴참나무가 많은 정상에서는 수려한 낙동강이 조망되고 산 아래에는 유명한 도산서원을 품고 있으며, 고려 때 축성한 왕모산성의 흔적도 남아있다. 왕모산성 내에는 왕모당이라는 성황당이 있으며 매년 정월보름에 동산제를 지내고 있다.", - "MNTN_HG_VL" : "648", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 도산면, 예안면", - "MNTN_NM" : "왕모산" - }, - "longitude" : 128.9024215, - "latitude" : 36.731395700000007 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "포천군의 진산으로 불리어 온 왕방산은 포천읍 서쪽에 우뚝 솟아 있는 산이다. 신라 헌강왕 3년(872년)경 도선국사가 이곳에 머무르고 있을 때, 국왕이 친히 행차하여 격려하였다 하여 왕방산이라 불리어졌고 도선국사가 기거했던 절을 왕방사라 했다는 말이 전해지고 있다. 왕방산은 광주산맥 서쪽의 지맥인 천보산맥의 북단에 자리잡고 있는 산이다.산들머리에는 유명한 문례현약수가 있고 완만한 육산의 능선길과 갈림길에는 안내판이 잘 정비되어 있다.정상은 초원이며 북쪽에서부터 종현산, 금주산, 문악산, 주금산, 죽엽산등이 바라보이고, 서울 근교에 위치한 산이라 교통이 편리하다. 능선과 게곡을 두루 거칠 수 있어서 좋다. 또한 눈내린 산길은 색다른 멋이 있다. 아담한 산세의 왕방산은 초겨울 가족 산행지로 알맞다. 완만한 등로와 키를 넘는 억새풀밭, 흰 눈이 깔린 왕방산은 초심자들도 큰 힘 들이지 않고 오를 수 있다.", - "MNTN_HG_VL" : "737", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 포천읍 신북면, 동두천시", - "MNTN_NM" : "왕방산" - }, - "longitude" : 127.155833, - "latitude" : 37.896667000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "포천읍 바로 뒤에 솟은 왕방산(737.2m)은 덩치가 크고 품이 넉넉해 보이는 인자한 시골 아낙네 같은 산이다. 또한 포천읍의 진산으로 남북으로 길게 누운, 바위가 그리 많지 않은 육산이다. 신라 말(872년) 헌강왕이 지금의 보덕사(도선국사 창건설)를 친히 방문했다 하여 산 이름을 왕방산이라 하고 절 이름을 왕방사라 부르게 됐다고 전해온다.그러나 포천군읍지와 견성지 기록에 의하면 조선의 태조 이성계가 왕위에 오르기 전부터 이 산에서 무예를 익히고 사냥을 했으며, 왕위에 오른 후에도 단오와 추석에 강무(임금이 참관하는 무예시범)를 했다 하여 왕방산이라 부르게 됐다고 한다.태조 이성계가 왕위를 아들에게 물려주고 함흥에 살다가 한양으로 돌아오던 중 왕자의 난 소식을 듣고 비통한 마음을 달래고자 이 산을 찾았다는 다른 유래도 전해진다.왕방산 주변에 이와 연관된 지명으로 왕숙천, 팔야리(이성계가 한양에 들어가기 전에 여덟 밤을 지낸 마을) 등이 남아 있다. 이러한 유래를 갖고 있는 왕방산의 표기를 일제시대부터 왕자에 날 일(日)자를 붙여 旺자로 바꿔 표기했으나 최근에는 다시 ‘王’자로 바꿔 놓았다. 서울의 인왕산(仁王山)과 같은 경우다.", - "MNTN_HG_VL" : "737", - "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시, 포천시 포천읍", - "MNTN_NM" : "왕방산" + "DETAIL_INFO_DTCONT" : "남녘 해안가에 자리잡은 이 산은 높이에 비해 산세가 굉장히 웅장하다. 능선에는 상사바위봉, 섬바위봉, 기차바위, 형제바위 등 빼어난 암봉이 장관이고 아슬아슬한 암릉길이 있으며 억새 능선길, 남해 푸른 바다의 장쾌한 조망 등 아름다움을 두루 갖춘 명산이라 할 수 있다. 또한 높고 낮은 봉우리가 아흔아홉 개로 형성되어 구구연화봉이라 전해지기도 하며 5월에는 철쭉이 만개하면 온 산이 진홍색이로 물들어 장관을 이룬다.산의 형상이 거대한 용 한 마리가 누워 있는 모습과 흡사하다하여 와룡산이라 불려졌다고 하며 고려의 현종이 잠룡시(임금이 되기 전의 시절)에 놀던 곳이기 때문에 이름 지어졌다고 한다. 와룡산 기슭의 백천골은 임진왜란 때 승병들이 왜군과 싸운 곳이라는 기록도 있다. 백천골에서 와룡산 등성이를 따라 바닷가로 내려오면 성문등, 파병산, 난곡, 퇴병산 등 임진란과 관련 있는 지명이 산재해 있는 것을 보면 당시의 상황을 짐작해 볼 수가 있다.", + "MNTN_HG_VL" : "801", + "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시 사천읍", + "MNTN_NM" : "와룡산" }, - "longitude" : 127.155833, - "latitude" : 37.896667000000001 + "longitude" : 128.1139033, + "latitude" : 34.986448800000012 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "왕산은 필봉산과 더불어 산청군 금서면의 중심에 위치해 있으며 그 주변으로 마을들이 산재해 있다. 왕산은 산청군의 여타 산들처럼 지리산의 유명세에 가려져 있지만 정상에서의 조망과 필봉산으로 이어지는 날등의 철쭉과 억새밭의 조화는 가히 환상적이다. 지세는 지리산의 봉우리인 상봉, 중봉, 하봉과 왕등재 쌍재로 이어져 왕산까지 그 줄기가 이어진다. 왕산 주능선의 북동쪽은 절벽으로 되어 있으며 서쪽은 울창한 수림의 능선이 완만하게 흘러내린다. 평지 같은 정상에는 삼각점만 있으나 북쪽 주능선에는 전망이 좋은 암봉이 2개가 있고 정상이 아닌 895봉에 왕산이라 음각되 표석이 세워져 있어 정상으로 착각하기 쉽다. 정상 북쪽 절골 변에는 류의태 선생이 한약제조에 사용했다는 약수터가 있다. 또한 이 산의 자락에는 가락국 마지막 왕인 구형왕의 유물을 보존하기 위해 조선 정조 17년에 후손들이 지었다는 덕양전이 있다. 그곳에서 약 2킬로미터 위에는 사적 214호로 지정된 구형왕릉이 있다.", - "MNTN_HG_VL" : "926", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 금서면", - "MNTN_NM" : "왕산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "295", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "와룡산" }, - "longitude" : 127.8126833, - "latitude" : 35.429355200000003 + "longitude" : 128.51053659999999, + "latitude" : 35.869378900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산양면에서 위만리로 가면 산양면과 용궁면 그리고 북쪽의 산북면의 경계가 되는 산이 왕의산(王衣山)인데 산양면 위만2리 뒷산으로 고려 공민왕이 몽고의 침입으로 안동에서 피난하고 돌아오는 길에 이곳에서 옷을 벗어 나무에 걸어 놓고 쉬었다 하여 왕의산이라 부르게 되었다고 한다. 높이 300m의 산봉우리가 왕의산에서 시작하여 산양면 현리 금천까지 이어져 있다. 높이에 비해 능선이 긴 것이 특징이다.산행들머리는 산양면 위만2리 상위마을을 지나자 바로 왕의산 쪽으로 나 있는 길로 접어들면 되는데 고가수 밑을 지나 길이 잘 나 있다. 올라가는데 약 40분이면 충분하고 소나무숲 길을 올라야 하며 오봉산, 비조산까지 능선을 타고 갈 수 있다.", - "MNTN_HG_VL" : "339", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 위만리", - "MNTN_NM" : "왕의산" + "DETAIL_INFO_DTCONT" : "완택산은 연하리와 동강변인 삼옥리 사이에 위치하고 있다. 산세는 동고서저, 즉 주능선을 경계로 동쪽 연하리 방면은 급경사에 절벽이 많고, 서쪽 동강 방면은 완만한 산세를 이루고 있다. 산세가 이렇듯 그 옛날 완택산은 천혜의 요새였다는 전설이 전해지고 있다.주능선 동쪽은 수직절벽이 대부분이어서 자연성곽을 이루고 서쪽은 동강 물줄기가 자연적인 방어선을 이루고 있다. 그래서 완택산은 옛날 예맥의 땅이었다는 얘기가 전해지며, 퉁구스식 방법으로 축성한 산성흔적이 산자락 곳곳에 조금씩 남아있다.완택산 등산로는 급경사를 이룬 동쪽 연하리 방면에서 오르내리는 코스가 일반적이다. 그러나 요즘은 동강변 삼옥리에서 완만한 경사를 이룬 능선과 계곡 코스가 인기 있다.", + "MNTN_HG_VL" : "918", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "완택산" }, - "longitude" : -118.2912369, - "latitude" : 34.060234600000001 + "longitude" : 128.55202180000001, + "latitude" : 37.2109405 }, { "mountain" : { @@ -8291,43 +6351,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "모산동과 송학면 경계에 위치한 해발 871미터의 용두산은 삼한시대 축조된 의림지와 제2 의림지, 솔밭공원을 남녘 자락에 펼치고 있는 제천의 진산이다. 산기슭에서 흘러내린 물이 용두천을 이루며 의림지로 흘러든다. 북서쪽으로는 석기암산(906m)과 감악산(920m)이 이어진다. 제천 시내의 산이어서 교통이 편리하고 찾기가 수월해 주말이면 제천 시민들이 즐겨 찾는다.용두산 산행 코스는 크게 세 군데로 나눌 수 있다. 피재, 물안이골, 석기암봉 코스 중에서 사람들이 가장 많이 찾는 코스는 피재 방면이다. 산행은 솔밭공원 앞 주차장에서 시작한다. 수령 수백년을 헤아리는 노송 백여 그루가 숲을 이룬 솔향기 가득한 공원에는 여러 점의 조각이 놓여 있어 운치가 있다. 의림지 북쪽으로 약 5백미터 지점에 자리한 이 솔밭공원을 지나면 진초록 못물이 더욱 맑은 제2 의림지가 있다. 용두산 등산로는 그 위편에 위치한 청소년수련원 오른쪽으로 나 있다. 의림지와 용두산산림욕장 등을 연계해 산행하면 다양한 볼거리와 편안한 휴식을 즐길 수 있다.용두산 정상은 매우 널찍한 헬기장으로, 주위에 벤치가 10여개 설치돼 있다. 헬기장 한쪽 끄트머리에는 ‘용두산 해발 873m’라 새긴 아담한 정성석이 있다. 정상에서 바라보는 조망은남동쪽을 제외하고는 나무가 우거져 좋지 않다. 서북쪽으로 석기암(906m)과 감악산(920m) 산줄기가 이어진다.", - "MNTN_HG_VL" : "871", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면", - "MNTN_NM" : "용두산" + "DETAIL_INFO_DTCONT" : "행정구역상으로 인천광역시에 속해 있는 백령도는 서해 최북단에 위치한 섬이다. 과거에는 안보상의 이유로 출입통제가 심했으나 현재는 비교적 자유로워졌고 쾌속여객선이 취항을 시작한 이래 해상관광명소로 급부상 하게 되었다. 백령도에는 산이라고 해야 해발 150m를 넘지못하는 산이 네댓 개 있을 뿐이다. 게다가 그 중에서도 가장 높은 북포리의 업죽산은 산행금지구역이고, 기껏해야 백고지와 용기원산, 그리고 두무진산이 전부이다.", + "MNTN_HG_VL" : "136", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군 백령면", + "MNTN_NM" : "용기원산" }, - "longitude" : 129.0326226, - "latitude" : 35.100653600000001 + "longitude" : 124.7436111, + "latitude" : 37.959444400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용두산은 태백산 끝자락에 위치하며 용머리 처럼 우뚝솟아올라 용두산이라고 하며 풍수지리를 연구하는 학자들은 소백산과 만나는 곳에 위치한 용두산을 와룡(누운용)이 여의주(용수사)를 물고 있는 형상이라고도 한다. 용두산은 안동시 녹전면과 도산면의 경계에 위치하고 있으며 유학의 대가인 농암과 퇴계선생 가문의 중요한 학문탐구의 장이었던 용수사를 품고 있으며, 남쪽으로는 퇴계선생의 조부이신 이계양공이 돌아가신 단종을 애도했던 장소로 유명한 국망봉을 거느리고 있다. 산행코스는 그다지 길지 않으므로 가족과 함께 가벼운 마음으로 용수사에 들렀다가 용두산 산행후 온천욕까지 즐길수 있다.", - "MNTN_HG_VL" : "661", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 도산면 운곡리, 매정리", + "DETAIL_INFO_DTCONT" : "모산동과 송학면 경계에 위치한 해발 871미터의 용두산은 삼한시대 축조된 의림지와 제2 의림지, 솔밭공원을 남녘 자락에 펼치고 있는 제천의 진산이다. 산기슭에서 흘러내린 물이 용두천을 이루며 의림지로 흘러든다. 북서쪽으로는 석기암산(906m)과 감악산(920m)이 이어진다. 제천 시내의 산이어서 교통이 편리하고 찾기가 수월해 주말이면 제천 시민들이 즐겨 찾는다.용두산 산행 코스는 크게 세 군데로 나눌 수 있다. 피재, 물안이골, 석기암봉 코스 중에서 사람들이 가장 많이 찾는 코스는 피재 방면이다. 산행은 솔밭공원 앞 주차장에서 시작한다. 수령 수백년을 헤아리는 노송 백여 그루가 숲을 이룬 솔향기 가득한 공원에는 여러 점의 조각이 놓여 있어 운치가 있다. 의림지 북쪽으로 약 5백미터 지점에 자리한 이 솔밭공원을 지나면 진초록 못물이 더욱 맑은 제2 의림지가 있다. 용두산 등산로는 그 위편에 위치한 청소년수련원 오른쪽으로 나 있다. 의림지와 용두산산림욕장 등을 연계해 산행하면 다양한 볼거리와 편안한 휴식을 즐길 수 있다.용두산 정상은 매우 널찍한 헬기장으로, 주위에 벤치가 10여개 설치돼 있다. 헬기장 한쪽 끄트머리에는 ‘용두산 해발 873m’라 새긴 아담한 정성석이 있다. 정상에서 바라보는 조망은남동쪽을 제외하고는 나무가 우거져 좋지 않다. 서북쪽으로 석기암(906m)과 감악산(920m) 산줄기가 이어진다.", + "MNTN_HG_VL" : "871", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면", "MNTN_NM" : "용두산" }, - "longitude" : 129.0326226, - "latitude" : 35.100653600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "529", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", - "MNTN_NM" : "용림산" - }, - "longitude" : 129.16408229999999, - "latitude" : 35.8439938 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 제천시 한수면에 자리한 용마봉은 소백산맥의 머리격인 소백산에서부터 죽령을 넘어 분수봉을 겨쳐 이화령에 이르기 전에 북쪽으로 내린 가지 위에 거대한 기암괴석으로 빚은 명산 월악산을 선보이고 그 주변에 600-1000m에 이르는 크고 작은 여러 산들을 거느리고 있다.그중 하나인 용마봉은 제천시 한수면 송계리에 위치한 월악산 국립공원의 숨겨진 보석이라 일컬을 정도로 정상을 이룬 거대한 바위 능선이며 . 송계계곡을 가운데 두고 월악산 덕주골과 마주보고 있는 서쪽에 솟아 있는 그리 높지 않은 산으로 바위 능선의 모양이 말안장을 닮았다고 해서 옛부터 말마봉 또는 말마산으로 불려왔다. 비록 높지는 않으나 다른 산에서 맛볼 수 있는 산행의 묘미를 골고루 체험할 수 있어 산악인들의 사랑을 받고 있다. 기암절벽으로 이루어진 산세는 아름다움을 자랑하고 암릉지대가 많아 스릴 또한 즐길 수 있으니 높이만 보고 얕잡아 볼일이 아니다.거기다 규모는 작지만 미륵사지와 송계계곡이 한눈에 내려다 보이는 조망은 참으로 아름답다.또 산행기점인 남문(월악루) 주변에 농암, 망폭대, 용추, 사자빈신사지석탑 등 볼거리가 많아 사계절 찾는 이들의 발길이 끊이지 않는다. 임진왜란 때 남쪽으로 마주보고 있는 북바위산에서 북을 치자 이 용마봉에서 용마가 하늘을 날며 포효했다는 전설이 전해진다.정상에서는 북으로는 송계리와 구례골이 샅샅이 내려다보이고, 시계바늘 방향으로는 월악산 정상이 장쾌하게 마주보인다. 월악산 정상에서 오른쪽으로는 V자로 패어든 덕주골이 남의 집 대문 안 들여다보듯 마주보이고, 톱날 같은 월악산 남릉이 덕주봉, 용암봉, 만수산과 함께 펼쳐진다. 남으로는 미륵리로 이어지는 송계계곡에 선을 그은 듯한 자동차 길이 실낱 같고, 용추, 팔랑소, 닷돈재 일원이 한눈에 들어온다. 그 오른쪽으로는 북바위산과 박쥐봉이 멀리 주흘산과 함께 시야에 와닿는다.", - "MNTN_HG_VL" : "687", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 송계리", - "MNTN_NM" : "용마봉" - }, - "longitude" : 127.0958467, - "latitude" : 37.571184899999999 + "longitude" : 128.2108604, + "latitude" : 37.203046100000002 }, { "mountain" : { @@ -8341,23 +6381,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "이 산 아래 가람을 연 용문사가 이 산 만큼이나 유명하다. 고려 건국후에 태조가 이곳을 방문했을 때 용이 나타나 환영했고, 이를 기뻐한 태조가 산 이름을 용문산으로, 절 이름을 용문사로 각각 명명했다.용문사하면 많은 사람들이 양평 용문사를 떠올린다. 양평 용문사는 서울에서 가깝고 큰 은행나무가 있어 사람들이 많이 찾기 때문이다. 그러나 경북 예천에는 훨씬 역사가 오래된 보물인 용문사가 있다.또한 소나무가 대부분이며, 삼국시대에 축성된 것으로 추정되는 어림성이 용문면 선리 산 45와 하리면 금곡리 산 450에 소재해 있다.", - "MNTN_HG_VL" : "782", - "MNTN_LOCPLC_REGION_NM" : "경상북도 예천군 용문면, 하리면, 상리면", - "MNTN_NM" : "용문산" - }, - "longitude" : 127.5518582, - "latitude" : 37.5622124 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "용바위봉은 충북 제천시 청풍면과 단양군 적성면 경계를 이루는 금수산 주능선에 솟아있는 산이다. 용바위봉이란 지명은 단양군 소야리와 각기리에서 서쪽으로 치솟은 산을 올려다보면 대소 5개의 골짜기들이 패어져 있는데 이중 가운데 것인 큰 용바위골이 마치 승천하는 용이 올라가면서 파낸 자국처럼 보이기 때문에 두 용바위골 끝머리가 만나는 꼭대기라서 붙여진 이름이다.용바위봉 정상에는 큰 용바위골과 작은 용바위골에 걸쳐 얹힌 용머리를 닮은 커다가 바위가 두 개 있다. 용바위봉은 이름에서도 알 수 있듯이 제법 험준한 산이지만 알려지지 않은 비경이 많아 산을 찾는 이들을 즐겁게 한다.", - "MNTN_HG_VL" : "750", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 단양군", - "MNTN_NM" : "용바위봉" + "DETAIL_INFO_DTCONT" : "용봉산은 381미터에 불과한 낮은 산이지만 산 전체가 기묘한 바위와 봉우리로 이루어져 충남의 금강산이라 불릴 정도로 아름답다. 보는 위치에 따라서 각각 다른 수묵화를 보는 듯 달라지는 풍경을 즐길 수 있다. 또한 정상에서의 예당평야와 수덕사를 품은 예산 덕숭산, 서산 가야산 조망이 시원스럽다.용봉산이라는 이름은 용의 몸에 봉황의 머리를 얹은 형상이라는 데서 유래했다. 남쪽 중턱과 서쪽 산록에 완만한 경사가 길게 이어지고 군데군데 소나무 군락이 있다. 장군바위와 백제 고찰인 용봉사, 보물 355호인 마애석불 등 많은 문화재가 곳곳에 남아 있다. 옛 문헌에 영봉사라고 기록되어 있는 용봉사는 지금 대웅전과 요사체 2동만이 남아 있다. 하지만 고려시대에는 절 크기가 아흔아홉채에 달하고 불도를 닦는 승려수가 천여명에 이를 만큼 큰 절이었다고 한다. 또 용봉사에는 강마촉지인을 한 석가모니를 그린 탱화가 있다.용봉산을 낀 홍성 일대는 충절의 고향답게 만해 한용운 선사, 백야 김좌진 장군, 최영 장군, 사육신 성삼문 등의 생가와 9백의총, 위인들의 삶의 흔적과 백제 부흥의 마지막 보루였던 임존성 등 역사 유적지가 도처에 남아 있다. 더욱이 최근 개발된 홍성온천이 예산의 덕산온천과 더불어 온천 관광지로도 이름이 높다.", + "MNTN_HG_VL" : "381", + "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군 홍북면ㆍ예산군 덕산면", + "MNTN_NM" : "용봉산" }, - "longitude" : 129.0219444, - "latitude" : 37.050277800000003 + "longitude" : 126.649249, + "latitude" : 36.6435581 }, { "mountain" : { @@ -8367,47 +6397,17 @@ "MNTN_NM" : "용산봉" }, "longitude" : 128.4241667, - "latitude" : 37.024999999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "462", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", - "MNTN_NM" : "용소봉" - }, - "longitude" : 127.6578615, - "latitude" : 36.089642599999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "686", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "용암봉" - }, - "longitude" : 126.9810445, - "latitude" : 37.653481499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "용암봉은 충북 제천시 한수면 송계리에 솟아있는 봉우리로 월악산국립공원내의 만수봉(983m)에서 서북쪽 방면으로 이어지는 바위 능선상의 최고봉이다. 만수봉 부근의 산들이 모두 그렇듯 용암봉도 한폭 그림처럼 아름답다. 해묵은 노송들이 치마를 펼친 듯한 회백색 바위 사이에 군락을 이뤄 산행의 즐거움을 더해준다.용암봉(892m)은 '송계8경' 중 제1경인 팔랑소 동쪽에 병풍을 두른 듯 솟은 산이다. 또한 이 산을 중심으로 북쪽에 고무서리계곡, 남쪽에 만수골이 패어져내려 주능선에 올라 내려다보는 조망이 더욱 깊이가 있다.산 이름은 892m봉 남쪽 단애를 이루는 계곡에 높이 50m나 되는 용암폭포가 있어 붙여진 이름이다. 이 폭포는 평상시 건기에는 물이 말라 버리기 때문에 이 지역 산악인들은 물줄기가 실처럼 가늘다해서 '실폭' 이라 부르기도 한다.정상은 참나무 수림 때문에 시원한 조망이 터지지 않는다. 그러나 서쪽 팔랑소를 향하여 서서히 가라앉는 암릉인 북서릉을 타면서 부터 진수가 나타나기 시작한다. 북서릉에서는 시종 박쥐봉, 북바위산, 용마봉을 마주보며 걷게 되고, 오른쪽으로는 월악산 정상이 압도하듯 올려다 보인다. 또한 덕주봉 암릉도 거대한 아름다운 수석인 듯 느껴진다. 여기에다 덕주봉 뒤로 충주호가 내려다보이고, 송계계곡이 골골샅샅 이내려다보여 이곳 저곳 구경하느라고 누구든지 산행시간은 길어지고 만다. 북서릉은 다섯 개의 암봉으로 이어진다. 아기자기한 노송 아래 바윗길을 따라 2시간 남짓 내려서면 시원한 폭포수가 바위를 차고 내리는 팔랑소가 반긴다. 하늘 나라에서 여덟공주가 내려와 목욕을 했다는 전설이 있는 팔랑소 주변에는 200 여 평이 넘는 너럭바위가 있어 휴식을 즐기기에 그만이다.", - "MNTN_HG_VL" : "892", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 송계리", - "MNTN_NM" : "용암봉" - }, - "longitude" : 126.9810445, - "latitude" : 37.653481499999998 + "latitude" : 37.024999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "화순 한천면과 춘양면의 경계에 우뚝 솟아 있는 용암산은 화순 일대의 유순한 산세와 달리 마치 용암이 분출해 솟아 오른 듯 날카롭고 거칠며 하늘을 찌를 듯 솟은 바위봉우리와 연이은 낭떠러지로 이루어진 독특한 산이다.예전에는 금오산이라 불렀는데 산 위에 있는 샘에서 하늘로 올라가려던 금자라가 나왔다고 해 이름 붙여졌다고 한다. 하지만 실제로는 금자라가 아닌 쇠처럼 생긴 바위벼랑이 있는 모습으로 보고 금오산이라 불렀다고 하니, 예부터 용암산의 산세가 험준했다는 것을 말해준다. 하지만 언제부턴가 금오산보다 ‘바위가 솟았다’는 의미의 용암산으로 불리게 되었다.용암산이 위치한 한천면은 예로부터 물 좋기로 이름난 고장이다. 어떤 곳을 파든 맑고 시원한 샘물이 솟는 천혜의 지역으로 알려졌다.용암산 산행은 용암사를 경유해 능선으로 오르는 것과 용암산장 뒤쪽의 계곡을 통해 정상으로 오르는 두 가지 방법이 있다. 길이 뚜렷한 능선길로 오르려면 먼저 용암사 경내로 들어서야 한다.", - "MNTN_HG_VL" : "547", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 한천면ㆍ춘양면", - "MNTN_NM" : "용암산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "용소봉" }, - "longitude" : 127.0052778, - "latitude" : 34.957500000000003 + "longitude" : 127.6578615, + "latitude" : 36.089642599999998 }, { "mountain" : { @@ -8421,23 +6421,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용인등봉은 강원도 삼척시 가곡면 풍곡리 덕풍마을에서 볼 때 문지골과 괭이골 사이에 솟아 오른 산릉의 최고봉으로 착한(어진)용이란 뜻을 담고 있다. 용인등봉의 시발점인 산봉우리는 515m봉으로 마을 주민들 사이에서는 개족발봉으로 통한다. 산세가 마치 수캐의 생식기처럼 보여 개족발봉이라 부르는데 한자로 구신암(拘腎岩)이라고도 한다.개족발봉 동쪽 아래에서 문지골과 용소골의 물이 합수되는데 이곳에 패어든 용소골안 제 1용소는 옛부터 제를 지내는 신성한 구역이었다. 개족발봉 동쪽 아래에서 문지골과 용소골의 물이 합수되는데 이곳에 패어든 용소골안 제 1용소는 옛부터 제를 지내는 신성한 구역이었다.제를 올릴때는 여느제처럼 돼지를 올리지 않고 개를 제물 삼아 개의 피를 용소에 뿌렸다는 것이 특이하다. 제 1용소까지 돼지를 끌고 들어가기가 어려워서 재물로 개를 사용했다고 전해진다.산에 밑둥이 두 아름이나 되는 굴참나무가 있다. 제당으로 불리는 이 나무는 심마니들이 제사를 지내는 신목(神木)이라 하니 눈여겨 볼 만 하다.", - "MNTN_HG_VL" : "1124", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "용인등봉" - }, - "longitude" : 129.165651, - "latitude" : 37.067689999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "담양군 용면 용연리 소재 용추산(해발 523m)을 중심으로 사방 4km 주변을 가마골이라고 부르 는데, 여러 개의 깊은 계곡과 폭포, 기암괴석이 수려한 경관을 이루고 있어 사시사철 관광객 의 발길이 끊이지 않는 곳이다. 영산강의 시원으로 유명한 용소가 있고 1986년부터 관광지로 지정,개발되어 관광객을 위한 각종 볼거리, 편의시설, 운동시설, 등산로 등이 잘 갖추어져 있다. 가마골은 깊은 계곡 사이로 쏟아지는 용연폭포와갖가지 기암괴석들이 즐비해 경관이 수려 하다. 또한 약 900명이 야영할수있는 야영장을 비롯해 각족 편의시설이 개발되어 많은 관광객 이 찾고 있다. 용소 윗부분에 있는 출렁다리 또한 빼놓을 수 없는 볼거리를 제공한다.출렁거 리는 다리에서 아슬아슬한 스릴감과 함께 시원한 용소를 바라볼 수 있어 찾는 이가 많다.", - "MNTN_HG_VL" : "523", - "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 용면 용연리", - "MNTN_NM" : "용추산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 수성구 범물동", + "MNTN_NM" : "용지봉" }, - "longitude" : 127.0321063, - "latitude" : 35.436277699999998 + "longitude" : 128.64972220000001, + "latitude" : 35.803333299999998 }, { "mountain" : { @@ -8466,18 +6456,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", "MNTN_NM" : "용화산" }, - "longitude" : 127.74382540000001, - "latitude" : 38.039407599999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "435", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 둔덕면 거림리", - "MNTN_NM" : "우두봉" - }, - "longitude" : 128.12028240000001, - "latitude" : 35.823721599999999 + "longitude" : 127.0655587, + "latitude" : 36.0244456 }, { "mountain" : { @@ -8496,8 +6476,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 양평, 여주", "MNTN_NM" : "우두산" }, - "longitude" : 128.03433459999999, - "latitude" : 35.760938699999997 + "longitude" : 127.6441667, + "latitude" : 37.4052778 }, { "mountain" : { @@ -8509,16 +6489,6 @@ "longitude" : 128.03433459999999, "latitude" : 35.760938699999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "우암산(338m)은 청주시를 지켜온 산으로서 그 모양이 소가 누워있는 형상과 비슷하다고 하여 일명 와우산이라고도 부른다. 청주시 명암동·내덕동·우암동·수동·대성동·문화동·용암동에 걸쳐 있다.침엽수림과 낙엽수림이 섞인 숲이 우거지고, 약수터와 순환도로·등산로 등이 잘 정비되어 있어 시민들의 휴식처로 널리 이용되고 있다. 높이에 비해 산세가 깊은 탓에 용암사, 목암사, 보현사, 관음사, 광덕사, 문수사, 용화사, 대한불교수도원 등 사찰이 여럿 들어서 있고, 그와 함께 통일신라 말 작품으로 보이는 용암사의 석조비로자나불상, 목암사의 나한입상 등 유적들이 산기슭 곳곳에 산재해 있는 명산이다. 또 정상 부근에 삼국시대 것으로 보이는 와우산성(臥牛山城)이 있다. 와우산성은 《동국여지승람》에는 둘레가 1.587km로 되어 있으나 실제로는 내성 2km, 외성 1,800km로 총 3.8km에 이른다. 지금은 성 주변으로 민가와 농경지가 늘어나 크게 훼손된 상태이다.산 초입부분에는 1919년 3·1운동 당시 독립선언서에 서명한 민족대표 33인 중 충청북도 출신 6명의 동상을 모신 삼일공원이 있다. 또한 산자락에 많은 약수터와 운동시설 등이 있고 정상에서 조망되는 청주시 전체의 모습이 아름다우며 드라이브 코스로 적당한 우암산 순회도로를 갖고 있는 등 시민의 등산지 및 기타 여가활동공간으로서 큰 역할을 하고 있다.", - "MNTN_HG_VL" : "338", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 상당구 내덕동, 우암동, 수동, 대성동", - "MNTN_NM" : "우암산" - }, - "longitude" : 127.5038053, - "latitude" : 36.649905699999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -8549,16 +6519,6 @@ "longitude" : 127.2951884, "latitude" : 37.5720399 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "운길산은 서울에서 동쪽으로 40㎞, 북한강과 남한강이 합류되는 양수리에서 서북쪽으로 4㎞ 거리에 솟아 있는 산이다. 산 아래까지 시내버스가 연결되고 있어 교통이 편리하고, 산세가 부드럽고 등산로가 순탄하여 가족산행이나 가벼운 주말산행에 적합한 곳이다.주변에 정다산마을·팔당호·서울종합영화촬영소·금남유원지 등의 관광지가 있고 산중턱에 수종사(水鐘寺)가 있어 볼거리도 많은 편이다. 특히 수종사에서 바라보는 팔당호의 모습은 일찍이 서거정이 동방의 사찰 중 전망이 제일이라고 격찬했을 정도이다. 서쪽의 적갑산(561m)과 예봉산(683m)을 함께 종주할 때 기준점이 되는 산이기도 하다.", - "MNTN_HG_VL" : "610", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 조안면 송촌리", - "MNTN_NM" : "운길산" - }, - "longitude" : 127.2951884, - "latitude" : 37.5720399 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "백두대간의 등허리 태백에서 분기한 산줄기가 내륙을 향해 달리다 수려한 봉우리를 만들었으니 그 이름 운달산이라하여 계곡에 흐르는 물이 맑고 차갑기가 얼음같아 일명 '냉골'이라 불리워진다. 용암산(龍岩山)이라고 부르기도 하는 이 산은 문경읍 동북쪽 8km 지점에 위치한다. 산 능선은 길게 동서로 10여km에 걸쳐 뻗었으며, 그 사이의 마전령(馬轉嶺:627m)· 조항령(鳥項嶺:673m) 등 안부(鞍部)가 예로부터 문경과 다른 지방을 연결하는 교통의 요지였다. 산에는 금선대(金仙臺)를 비롯하여 많은 기암괴석으로 덮여 경치가 아름다우며, 남동사면 일대에 화장암(華藏庵)·양진암(養眞庵)·대성암(大成庵)·금룡사(金龍寺) 등 고찰이 있어 많은 관광객이 찾아든다.특히 수령 300년 이상 수고 30여미터의 전나무 숲속에 고목이 조각품마냥 운치를 더해주고 겨울철 눈꽃은 내방객의 넋을 잃게 하고 여름철에는 조용한 곳을 찾는 피서객들이 찾아 온다.또한 운달산은 김룡사를 품고 있다. 김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다. 다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다. 그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", @@ -8579,26 +6539,6 @@ "longitude" : 128.2016667, "latitude" : 37.650277799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "동으로 가지산과 이어져 있는 운문산은 산세가 웅장하며 나무들이 울창하여 등산객이 많이 찾는 산이다. 이 곳에는 운문사를 비롯한 크고 작은 절과 암자가 있고, 주변 경치가 매우 아름답다.", - "MNTN_HG_VL" : "1195", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면, 경상남도 밀양시 산내면", - "MNTN_NM" : "운문산" - }, - "longitude" : 129.034167, - "latitude" : 35.676389 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "운문산은 가지산에서 서쪽으로 다시 갈라진 능선 상에 솟아 있는 명산이다. 산세가 웅장하며 나무들이 울창하여 산악인이 많이 찾는 산이다. 정상에서의 전망은 남쪽 건너편으로 천황산의 억새밭이 황금빛으로 물결치고 동쪽으로는 가지산으로 이어지는 능선이 용틀임하는 듯 보인다.이 일대는 가지산을 필두로 신불산,운문산,재약산,간월산,취서산,고헌산,문복산등 1,000m가 넘는 대 산군을 이루고 있는 일대를 '영남의 알프스'로 불리어진다. 이중 최고봉은 가지산이며 운문산과는 동서로 약 4km의 거리이며 경상 남북도의 도계를 이루고 있다. 이곳에는 운문사를 비롯한 크고 작은 절과 암자가 있고 주변 경치가 매우 아름다우며 특히 가을철의 억새는 장관을 이룬다. 밀양시 산내면과 청도군 운문면의 경계에 솟아 있는 산으로 주봉 가지산 능선에 잇대어져 있어 가지산까지 능선을 이어 종주 산행을 많이 한다.운문산은 예로부터 호거산이라 부르며 명산으로서 조건을 모두 갖추어진 산이다. 천문지골, 심심이골, 복숭아 골, 상운암 계곡등 깊은 골짜기를 품고 대 사찰 운문사와 천상에 걸린 상운안 및 부속 암자를 두고 있고 동의 보감의 허준이 반위에 걸린 스승의 시신을 해부 한곳이 운문산의 얼음굴이라는 설이 전해 온다.심산 유곡의 깊은 골짜기에는 약초와 나물이 천지이고 기암과 산세가 어우러져 한폭의 동양화를 보는 것 같은 착각에 빠진다.운문산의 산행들머리는 석골사를 지나 상운암 계곡에 들어선다. 계곡마다 계곡수가 넘쳐흘러 계곡을 건널 때는, 그대로 발을 담가야만 한다. 운문산 정상에는 탁 트인 남명리의 벌판이 전개되고, 왼편으로 아랫재가지산 가는 길이며 오른편에 함화산 가는 길이 열려 있다.", - "MNTN_HG_VL" : "1196", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", - "MNTN_NM" : "운문산" - }, - "longitude" : 129.034167, - "latitude" : 35.676389 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -8636,8 +6576,8 @@ "MNTN_LOCPLC_REGION_NM" : "고흥군", "MNTN_NM" : "운암산" }, - "longitude" : 127.28103900000001, - "latitude" : 35.988175900000002 + "longitude" : 127.3347222, + "latitude" : 34.624166700000004 }, { "mountain" : { @@ -8646,18 +6586,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", "MNTN_NM" : "운암산" }, - "longitude" : 127.28103900000001, - "latitude" : 35.988175900000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "운장산은 전라북도 진안군 주천면, 정천면, 부귀면, 완주군 동상면에 걸쳐 있으며 남쪽과 북쪽으로 흐르는 물은 금강으로 유입되고, 서쪽 계곡으로 흐르는 물은 완주군 동상면을 지나 만경강으로 흘러 금강과 만경강의 발원지 구실도 하고 있다. 북두칠성의 전설이 담겨 있는 칠성대를 지나 한참 더 올라가면 오성대가 있는데 조선조 중종 때의 서출 성리학자 송익필이 은거하였던 곳으로 전해지고 있다.주요 등산코스는 부귀면 궁항리나 황금리로 오르는 코스와 완주군 동상면 신월리로 오르는 코스가 있고 주천면 중사, 외처사동 마을에서 시작하여 동봉으로 오르는 코스도 있다.", - "MNTN_HG_VL" : "1126", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 주천면ㆍ부귀면ㆍ정천면, 완주군 동상면", - "MNTN_NM" : "운장산" - }, - "longitude" : 127.3572838, - "latitude" : 35.910964300000003 + "longitude" : 127.3347222, + "latitude" : 34.624166700000004 }, { "mountain" : { @@ -8676,18 +6606,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 영천시 임고면, 자양면, 포항시 기계면", "MNTN_NM" : "운주산" }, - "longitude" : 127.228914, - "latitude" : 36.676924999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "조치원읍에서 국도 1호선을 따라 천안방면으로 가다보면 개미고개를 지나 전의면 경계에 이르러 운주산 입구 푯말을 만나 진입로를 따라 올라가면 주차장을 만난다. 등산을 하기 위해서는 주차장에 차를 놓고 등산로(약 1km)를 따라 30여분 올라가면 운주산성 입구에 다다른다. 운주산성은 서기 660년 백제가 멸망하고 풍왕과 복신, 도침장군을 선두로 일어났던 백제부흥운동의 최후 구국항쟁지로 평가되는 역사적으로 중요한 산성이다. 운주산성은 충청남도 지정문화재 기념물 제 79호로 지정, 관리되고 있다.운주산 정상에 오르면 “백제의 얼 상징탑”이 운주산을 찾는 탐방객을 반가이 맞이한다. 운주산에서는 독립기념관, 천안시, 청주시와 맑은 날에는 아산만까지 관망된다. 어린이나 노약자를 동반한 관람객은 운주산 중턱까지 임도가 개설되어 있어 승용차를 이용하여 올라가면 광장을 만나게 된다. 광장부근에서 정상까지는 도보로 약 10여분이 소요된다.정자도 세 곳에 있고 피숫골 주계곡은 수량이 풍부한 편이라 삼천굴,고산사 등 명소도 있다.", - "MNTN_HG_VL" : "460", - "MNTN_LOCPLC_REGION_NM" : "충청남도 연기군 전동면, 전의면", - "MNTN_NM" : "운주산" - }, - "longitude" : 127.228914, - "latitude" : 36.676924999999997 + "longitude" : 129.11027780000001, + "latitude" : 36.0777778 }, { "mountain" : { @@ -8721,13 +6641,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "문수산(일명 천호산)의 한 지맥이 서쪽으로 뻗어 형성된 해발 342m의 높지 않은 산이다.미륵산 동쪽의 왕궁면,여산면에 걸쳐있는 네 봉우리(옥녀봉,선인봉,노승봉,성태봉)를 통틀어 봉화산이라 말한다.서동공원에서 시작해 용화산의 정상부에 오르면 서쪽으로 익산의 진산인 미륵산이 보이고 여산 방면으로 가다가 우측으로 내려가면 서동요의 전설로 잘 알려진 선화공주사가가 나온다.미륵산과 용화산을 합하며모두 용화산이라 불러왔으나 지금은 미륵사가 있는곳이 미륵산이고 나머지를 용화산이라 한다. 일명 군입산(軍入山)이라고 하는데 고려 태조가 후백제를 정벌할때 군대를 주둔시켰던 곳이기 때문에 붙여진 이름이라고 신증동국여지승람은 기록하고 있다.", - "MNTN_HG_VL" : "342", - "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", - "MNTN_NM" : "원대봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "171", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 조천읍 신촌리, 삼양일동", + "MNTN_NM" : "원당봉(삼양)" }, - "longitude" : 126.94916670000001, - "latitude" : 35.186111099999998 + "longitude" : 126.59880269999999, + "latitude" : 33.5251229 }, { "mountain" : { @@ -8739,16 +6659,6 @@ "longitude" : 127.2937072, "latitude" : 35.8874104 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "168", - "MNTN_LOCPLC_REGION_NM" : "경기도 부천시", - "MNTN_NM" : "원미산" - }, - "longitude" : 126.8024796, - "latitude" : 37.5001526 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "한남정맥과 갈라진 산줄기가 북쪽으로 태화산(645m) 백마산(530m) 줄기를 떨구고 동북진하여 광주와 이천을 잇는 넓고개를 건너 솟구친 산이 바로 원적산이다. 무적산(無寂山)이라고도 한다. 동쪽 원적봉(563.5m) 기슭에 638년(선덕여왕 7년)에 창건했다는 영원사(靈源寺)라는 사찰이 있으며, 주봉인 천덕봉 기슭에는 율수폭이라는 폭포가 있다. 고려말 공민왕이 난을 피해 이곳에 머물렀다는 전설이 전한다. 신둔면 장동리 쪽에는 군사훈련장이 있어 입산이 제한되므로 산행은 백사면 경사리 쪽에서 시작한다.전체적인 능선이 부드럽고 완만해 보이지만 산 천덕봉 안쪽으로 암벽이 있으며 이 산의 최고봉인 천덕봉은 높이 635m로 이천군내에서 제일 높다. 산행기점인 송곡마을은 전국 제일의 산수유 산지로 봄이면 농가울타리와 논밭두렁이 산수유의 노란 물결로 일렁이고 가을이 되면 들 곳곳에서 열매를 따는 풍요로운 풍경이 등반객들의 마음을 넉넉하게 채워준다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.", @@ -8766,8 +6676,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", "MNTN_NM" : "원통산" }, - "longitude" : 127.68361109999999, - "latitude" : 37.078055599999999 + "longitude" : 127.20805559999999, + "latitude" : 35.511666699999999 }, { "mountain" : { @@ -8799,6 +6709,16 @@ "longitude" : 128.9252778, "latitude" : 37.756111099999998 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "구좌읍 송당리 동족에 비자림(돌오름)과 용눈이오름 사이에 우뚝 솟아있는 매끈한 풀밭오름으로 그 위용을 자랑하며, 구좌읍을 대표하는 오름이라고 할 수 있다. 비단 치마에 몸을 감싼 여인처럼 우아한 몸맵시가 가을 하늘에 말쑥하다. 정상에 분화구가 남아 있는데, 그것이 흡사 달처럼 둥글게 보인다고 하여 현지 주민들 사이에서는 ‘다랑쉬(다:달, 쉬:뫼)’라는 이름으로 불러왔다.행정 구역상 세화리에 속하며 서쪽 일부가 송당리에 걸쳐있어 쉽게 접근 할 수 있다. 월랑봉이라는 이름에서도 알 수 있듯이 달과 연관이 많은 듯한 이 오름에서의 보름달맞이는 장관이라 한다.", + "MNTN_HG_VL" : "382", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍 세화리", + "MNTN_NM" : "월랑봉" + }, + "longitude" : 126.82139429999999, + "latitude" : 33.473882400000001 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "월류봉은 충청북도 영동군 황간면에 솟아 있는 해발 400.7미터의 봉우리다. 이름 뜻 그대로 달이 머문다는 이 봉우리는 달이 머물러 갈만큼 아름답다. 하물며 이곳에선 달이 서쪽으로 그냥 넘어 가는 것이 아니라 능선 모양을 따라 서쪽으로 흐르는 듯 달이 머물다 사라진다고 한다.그리 높지 않지만 빼어난 비경을 지닌 월류봉. 영동 한천팔경이라는 것이 이 월류봉의 곳곳을 세분화하여 일컫는다는 말이 빈말은 아닌 모양이다. 한천팔경 중에서도 산세가 빼어나고 준수한 면모를 지녀 첫손에 꼽히는 월류봉이 당연지사 1경이라면, 3경인 용연동은 월류봉 아래의 깊이를 가늠할 수 없는 깊은 소를 지칭한다. 4경 산양벽은 단애 이룬 월류봉의 기암절벽을 8경은 우암 송시열(1607~1689)이 즐겨 찾던 명승지 월류봉을 감상하며 머물렀다는 한천정사를 말한다.월류봉은 들머리에서 바라보면 토산으로 보이지만 반대편 강가에서 바라보면 기암괴석이 보인다. 봄에는 신록이 우거지고 가을에는 단풍이 아름다워 관광객이 끊이지 않고 있는 산이다. 또 월류봉에 오르면 총강천 건너로 원촌리 구릉성산맥이 한반도의 모양과 똑 닮은 모습으로 자리하고 있는 것을 볼 수 있다.", @@ -8809,6 +6729,16 @@ "longitude" : 127.89136310000001, "latitude" : 36.234184999999997 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "월방산(月芳山)은 운달산의 한줄기가 길게 뻗어 영순면으로 산줄기를 뻗으면서 산북면과 호계면, 산양면 경계에 솟은 산으로 높이는 낮지만 울창한 소나무와 주변에 유적이 많아 볼거리가 많은 산이다.산행은 산양면 봉정리에서 시작하여 산신제단을 거쳐 정상에 오른 뒤 호계면 봉서리로 내려선다. 산행 시간은 2시간 정도 걸린다. 산기슭에 봉정리 탑동의 삼층석탑 부재, 마애보살입상, 마애여래상, 봉서리삼층석탑 등의 불교유적이 많이 남아 있다.정상 바로 밑에 있는 작은 산신당에 다음과 같은 전설이 전한다. 옛날에 마음씨 고운 아낙네가 산에 나물을 캐러 갔다가 미끄러져 정신을 잃었다. 이 때 꿈에 산신당의 백발노인이 나타나서 벼랑 사이에 흐르는 물을 먹고 바르라고 말하였다. 여인이 꿈에서 깨어 노인이 시키는대로 하였더니 과연 상처가 씻은 듯이 나앗다. 여인의 이야기를 들은 심술궂은 사내가 산신당 벽에 걸린 산신의 눈을 솔가지로 찌르고 벼랑 사이에 흐르는 우물을 파헤쳤다. 그러자 밤마다 귀신이 나타나 3일만에 사내가 죽고 우물물이 흙탕물로 변했으며 호랑이가 나타나 마을의 가축들을 물어갔다. 이에 주민들은 산신의 노여움을 가라앉히기 위해 매년 정월 대보름에 제사를 드리기 시작하였고, 이 제사는 지금도 이어지고 있다.", + "MNTN_HG_VL" : "360", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 봉정리", + "MNTN_NM" : "월방산" + }, + "longitude" : 128.2333333, + "latitude" : 36.633333299999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -8816,8 +6746,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", "MNTN_NM" : "월봉산" }, - "longitude" : 127.72486480000001, - "latitude" : 35.729298100000001 + "longitude" : 127.11222220000001, + "latitude" : 36.798333300000003 }, { "mountain" : { @@ -8876,8 +6806,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", "MNTN_NM" : "월악시루봉" }, - "longitude" : 127.9338889, - "latitude" : 37.163888900000003 + "longitude" : 128.09096439999999, + "latitude" : 36.889304099999997 }, { "mountain" : { @@ -8909,26 +6839,6 @@ "longitude" : 126.7104573, "latitude" : 34.774338800000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충주시 상모면에 위치한 월항삼봉은 뽀족한 봉우리 세 개가 나란히 서 있어 삼봉으로 부르기도 하고 산삼이 많이 나는 산이라서 삼봉(蔘峰)으로 부르기도 한다. 산의 형세는 웅장하지 않으나 암봉과 아름드리 장송으로 이루어져 있어 아기자기한 산행의 맛을 즐길 수 있다.월악산국립공원 내에 속하며 가까이에 미륵사지와 수안보온천 등의 관광지가 있어 봄철 산행지로 각광받는 산이다.산 북쪽에 있는 미륵사지는 고려 초기에 조성된 절터이다. 1977∼1978년에 발굴작업이 이루어졌으며 괴산미륵리오층석탑(보물 95)과 괴산미륵리석불입상(보물 96)이 남아 있다. 특히 석불입상에는 신라의 마지막 태자인 마의태자가 동생 덕주공주와 함께 금강산에 입산하는 길에 이곳에 머물러 절을 세운 뒤 석불에 자신의 자화상을 새겨 놓았다는 전설이 서려 있다.", - "MNTN_HG_VL" : "851", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면 미륵리, 경상북도 문경시", - "MNTN_NM" : "월항삼봉" - }, - "longitude" : 128.10508999999999, - "latitude" : 36.806125000000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 제천시 한수면 탄지리와 덕산면 신현리 사이에 솟은 월형산은 정상에서 바라다보이는 충주호의 경치와 월악산을 올려다보는 풍광을 만끽할 수 있어 좋은 산이다. 충주에서 단양을 잇는 국도변에서 바로 등산을 할 수 있고 등산거리가 짧아 겨울산행 코스로 제격인 산이다.보기에는 작은 산이지만 월악산은 속이 꽉 찬 만두처럼 다양한 비경들이 펼쳐져있어 산을 오르는 이들을 즐겁게 한다. 월형산 동쪽 송계팔경의 하나인 팔랑소의 시원한 물과 바위들은 여름철 피서지를 찾는 이들로 인해 인산인해를 이룬다. 흐르는 계곡물 옆으로 노송이 하늘을 찌르는 절경은 보기만 해도 마음까지 시원해진다.", - "MNTN_HG_VL" : "526", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면 탄지리", - "MNTN_NM" : "월형산" - }, - "longitude" : 127.59622779999999, - "latitude" : 36.1135831 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -8976,8 +6886,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", "MNTN_NM" : "유방산" }, - "longitude" : 128.46611110000001, - "latitude" : 34.889722200000001 + "longitude" : 126.4427778, + "latitude" : 34.806111100000003 }, { "mountain" : { @@ -9009,6 +6919,16 @@ "longitude" : 128.85859429999999, "latitude" : 35.613249099999997 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "윤산 정상에 서면 부산이 온통 산의 물결을 이룬다는 사실을 확인하게 된다. 회동수원지를 감싸고 있는 정면 한가운데 아홉산과 그 우측으로 개좌산 운봉산이, 아홉산 왼쪽 뒤 암봉이 달음산, 그 왼쪽으로 뾰족봉인 천마산 치마산(함박산) 곰내재, 그 뒤로 시명산이 확인된다.부산 금정구 부곡동 서동 금사동에 걸쳐있는 나즈막한 봉우리인 윤산(輪山·318m)에 오르면 광안대교가 보이는 광안리 해안가를 제외한 전 지역이 산의 물결을 이룬다. 크게 보면 부산도 일종의 대형 분지(盆地)라는 사실을 실감한다.조선시대 지리서인 '동국여지승람'과 1740년판 '동래부지'에는 윤산을 '동래부의 북쪽 8리에 있으며, 동래부의 진산(鎭山)'이라 적고 있다. 알다시피 진산은 도읍이나 성지의 뒤쪽에 있는 큰 산을 말하는데 결국 윤산이 동래의 뒤쪽 큰 산이니 진산이 되는 셈이다.이제 궁금증은 왜 윤산으로 명명됐느냐 하는 것. 답은 간단하다. 동래쪽에서 보면 산 모양이 수레바퀴처럼 둥글게 보여 바퀴 윤(輪)자를 차용했다. 주민들로부터 '대머리산' '둥글산'으로 불린 것도 이같은 이유에서다.그렇다면 윤산이 왜 구월산으로 불렸을까. 뚜렷한 답은 없지만 바퀴에서 연상되는 '구불다'에서 '구블다' '구을다'로 변해오다 결국 구월산으로 와전되지 않았을까 하는 것이 일반적인 추측이다.이 때문에 지역 주민들이 원래 산 이름을 되찾아야 한다고 민원을 제기했고, 이에 시는 타당성이 있다는 판단하에 국토지리정보원에 산 이름 변경을 요청했다. 결국 국토지리정보원은 지명위원회의 심의를 거쳐 윤산으로 산 이름을 복원키로 결정했다고 지난 2002년 7월 시에 알려와 시는 이때부터 공식적으로 윤산으로 부르고 있다.", + "MNTN_HG_VL" : "317", + "MNTN_LOCPLC_REGION_NM" : "부산광역시", + "MNTN_NM" : "윤산" + }, + "longitude" : 129.10360969999999, + "latitude" : 35.233632 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "주금산에서 남쪽으로 뻗어온 산줄기가 서리산, 축령산을 지나 북한강으로 빠지기 직전에 만들어 놓은 것이 바로 은두봉이다. 은두봉은 북쪽에 위치한 축령산(897m)에 딸린 한봉우리만 사람들에게 인식되어 왔다. 그러다 이 봉우리 서북쪽에 있는 운두목현의 이름을 따서 은두봉이라 불려졌다. 따라서 은두봉은 하나의 독립된 산이 아니라 축령산에 딸린 한 봉우리로 보는 것이 더 타당하다. 그런 의미로 보면 은두봉의 서북쪽 1.5km거리에 있는 오독산(621m)도 축령산에 속한 봉우리라 할 수 있다.예전 마석에서 청평으로 넘나들던 은두목현을 거쳐 동남쪽 능선길을 따라가다 보면 정상에 이르게 된다. 정상에서는 청평댐과 북한강이 한눈에 들어오며 강을 따라 이어지는 연봉의 모습도 눈을 떼지 못하게 한다. 교통이 편한데다 산세가 제법이어서 많은 산악인들의 각광을 받고 있다.", @@ -9016,8 +6936,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", "MNTN_NM" : "은두봉" }, - "longitude" : 127.41861110000001, - "latitude" : 37.841388899999998 + "longitude" : 127.39388889999999, + "latitude" : 37.744444399999999 }, { "mountain" : { @@ -9032,12 +6952,12 @@ { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "206", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군", - "MNTN_NM" : "은적산" + "MNTN_HG_VL" : "180", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍", + "MNTN_NM" : "은월봉" }, - "longitude" : 126.5812478, - "latitude" : 34.7552278 + "longitude" : 126.8561412, + "latitude" : 33.469772399999997 }, { "mountain" : { @@ -9056,8 +6976,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면ㆍ원덕읍, 경상북도 울진군 북면", "MNTN_NM" : "응봉산" }, - "longitude" : 127.02982609999999, - "latitude" : 37.548176900000001 + "longitude" : 129.2299332, + "latitude" : 37.076997599999999 }, { "mountain" : { @@ -9066,8 +6986,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", "MNTN_NM" : "응봉산" }, - "longitude" : 127.02982609999999, - "latitude" : 37.548176900000001 + "longitude" : 129.13138889999999, + "latitude" : 37.224722200000002 }, { "mountain" : { @@ -9076,8 +6996,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", "MNTN_NM" : "응봉산" }, - "longitude" : 127.02982609999999, - "latitude" : 37.548176900000001 + "longitude" : 129.13138889999999, + "latitude" : 37.224722200000002 }, { "mountain" : { @@ -9086,8 +7006,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", "MNTN_NM" : "응봉산" }, - "longitude" : 127.02982609999999, - "latitude" : 37.548176900000001 + "longitude" : 129.13138889999999, + "latitude" : 37.224722200000002 }, { "mountain" : { @@ -9096,18 +7016,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍,노곡면", "MNTN_NM" : "응봉산" }, - "longitude" : 127.02982609999999, - "latitude" : 37.548176900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 합천호 남쪽 황강(黃江)가에 솟아 있는 의룡산은 `소월출산'이라 불릴만큼 절경이 아름답고 기암괴석이 많은 곳이다. 특히 황강을 막아 만들어 놓은 북쪽 기슭의 조정지와 어울려 한 폭의 산수화 같은 멋진 풍경을 연출한다. 하산길에 본 서릉은 설악산 공룡릉의 축소판 같다. 의룡산 북쪽 황강가에 있는 용문정 쪽에서 이 산을 남쪽으로 바라보면 매우 가파른 바위산이 강기슭에서부터 표고 400여m나 치솟아 있어 어디 한군데 마땅히 발붙일 곳이 없을 것처럼 보인다.이 산은 악견산과 능선이 연결되어 있어서 3.5km 정도만 더 걸으면 의룡산 정상에 오를 수 있다. 정상에서 서쪽 악견산, 황매산 줄기, 북쪽으로 용문정, 북동쪽으로는 황강에 만든 조정지댐과 그 댐 안에 담겨있는 짙푸른 호수물이 발아래 내려다보인다.", - "MNTN_HG_VL" : "453", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", - "MNTN_NM" : "의룡산" - }, - "longitude" : 128.07158609999999, - "latitude" : 35.532140499999997 + "longitude" : 129.13138889999999, + "latitude" : 37.224722200000002 }, { "mountain" : { @@ -9119,26 +7029,6 @@ "longitude" : 128.04416670000001, "latitude" : 35.752222199999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 근간을 이루는 백화산(1063m)과 희양산(998m)사이에 우뚝 솟은 이만봉은 충북 괴산군 연풍면과 경북 문경시 가은읍의 경계에 위치해 있다. 이만봉이라는 산 이름은 임진왜란때 이곳 산골짜기로 2만여 가구가 피난을 들어와 이만봉이라 불리었다는 전설과, 옛날 이만호라는 이름을 가진 형제가 이 산에 들어와 살기 시작하면서 생긴 이름이라는 두가지 전설을 간직하고 있다.이만봉은 아직까지 많은 사람들에게 알려지지 않아 자연미가 살아 숨쉬고 있다. 배너미평전, 곰봉, 굴바위 등 환상적인 경관이 산 곳곳에 자리하고 있어 한번 찾은 등산객들을 다시 찾게 하고 있다. 정상에 오르는 도중에 만나는 능선길에는 기암절벽이 자리하고 있어 빼어난 경관을 볼 수 있다. 또 산행 도중 이화령, 월악산, 주흘산 등을 시야에 담을 수 있어 전혀 지루하지 않게 정상에 오를 수 있다.", - "MNTN_HG_VL" : "990", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면", - "MNTN_NM" : "이만봉" - }, - "longitude" : 128.02609659999999, - "latitude" : 36.719266099999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "이명산은 경남 사천시와 하동군의 경계에 위치해 있다. 인근의 봉명산과 계명산과 함께 삼명산으로 불리기도 한다.또한 이맹산(理盲山)·전야산(轉也山)·해양전산(海陽轉山)·화전산(花田山)·윤산(輪山)·봉명산이라고도 한다. 군립공원으로 지정되었으며, 산기슭의 다솔사 입구 입석에는 '봉명산'이라 적혀 있다. 삼국시대에는 신라의 남서부 지역 요충지로서 북쪽 산정 부근에 사찰을 세우고 석굴과 마애불상 등을 만들어 적의 침입에 대비하였다.옛 이름 이맹산에 얽힌 전설이 《동경지(東京誌)》에 전한다. 옛날 산 정상에 용지(龍池)가 있었는데 이 용지 때문에 동경(지금의 경주)에서 맹인이 많이 태어난다는 소문이 돌았다. 이에 동경 사람들이 불에 달군 쇠와 모래와 돌을 용지에 집어 넣자 이를 견디지 못한 용이 진교(辰橋) 아래 깊은 호수로 도망갔고 이후 동경에서 맹인이 사라졌다고 한다. 지금도 산 정상 부근에는 구운 돌과 못의 흔적이 남아 있다.등산로는 다솔사 입구에서 시작된다. 다솔사에는 경상남도유형문화재 29호로 지정된 고려시대 석조불상을 비롯하여 극락전(경상남도문화재자료 148), 응진전(경상남도문화재자료 149), 대양루(경상남도유형문화재 83), 보안암석굴(경상남도유형문화재 39) 등의 문화재가 있다.다솔사에서 보안암으로 빠지는 고개를 지나 20분을 더 가면 정상이다. 정상에 오르면 남쪽으로 금오산(849m)과 다도해, 서쪽으로 백운산(1,215m), 서북쪽으로 지리산 능선, 웅석봉(1,099m) 등이 한눈에 들어온다. 정상 아래 등산로에 시루떡을 닮은 바위가 셋 있는데 제일 위의 시루떡 바위에는 불상이 새겨져 있다.", - "MNTN_HG_VL" : "570", - "MNTN_LOCPLC_REGION_NM" : "경남 산청시 곤양면", - "MNTN_NM" : "이명산" - }, - "longitude" : 127.89100500000001, - "latitude" : 35.087016300000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -9149,16 +7039,6 @@ "longitude" : 127.8411984, "latitude" : 35.304295199999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "257", - "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군", - "MNTN_NM" : "이성산" - }, - "longitude" : 127.1822222, - "latitude" : 37.5266667 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -9231,33 +7111,33 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "178", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", - "MNTN_NM" : "임호산" + "DETAIL_INFO_DTCONT" : "정상에 일자봉과 월자봉이 솟아 있어 동해에서 솟아 오르는 해와 달을 제일 먼저 볼 수 있다해서 일월산이라고 한다. 또한 산마루에 천지가 있어 그 모양이 해와 달과 같아서 일월산이라 하였다는 설도 있다. 높은 산이면서도 산형이 험하지 않고 순하여 순산이라는 애칭도 있다. 옛부터 각종 임산물이 많고 고산식물이 곳곳에 자라며, 약초도 많다.이 산은 태백산맥에 속하며, 이 산에서 낙동강의 상류 지류인 반변천(半邊川)이 발원한다. 남서사면에 천화사(天華寺)가 있으며 동쪽 사면에 용화사지(龍化寺址)가 있다.일월산의 꼭대기에는 일자봉과 월자봉이라 부르는 두 봉우리가 사이좋게 솟아 있으며 그 줄기가 뻗어 크고 작은 산맥이 주종을 이루었으니 동해가 눈 아래 보이는 일자봉에 올라 해가 솟아오르는 장관을 볼 수 있다.", + "MNTN_HG_VL" : "1218", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 일월면", + "MNTN_NM" : "일월산" }, - "longitude" : 128.86982140000001, - "latitude" : 35.226345799999997 + "longitude" : 129.09831510000001, + "latitude" : 36.8016115 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "목포시 동쪽에 상동과 용해동에 걸쳐있는 해발 110m 산이다.산중턱에는 체육시설이 있으며 정상에서 바라보면 목포 구도심과 하당신도심 그리고남악신도심을 한눈에 볼 수 있다. 입암산 동남쪽 바닷가에 갓을 쓰고 있는 듯한 바위가 있어 이를 갓바위라 하는데갓바위가 있는 산이라 하여 갓바위산, 입암산이라 하였다 한다.목포팔경 중 입암반조(笠岩返照)라 하여 저녁노을에 물든 바닷가의 갓바위와바위절벽으로 된 입암산에 반사되는 저녁노을의 아름다움을 노래하고 있다.", - "MNTN_HG_VL" : "110", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 상동", - "MNTN_NM" : "입암산" + "DETAIL_INFO_DTCONT" : "일월산은 경상북도에서도 오지 중의 오지로 알려진 영양군과 봉화군 경계에 있다. 1200미터가 넘는 산이지만 능선은 유순하기 그지없다. 푸른 금강송이 있어 삼림욕장으로 그만이고 해마다 봄이면 산나물축제를 열만큼 온갖 자생식물이 넘쳐나는 곳이다. 여유가 있다면 일월산 최고봉인 일자봉에서 떠오르는 해를 감상하는 일출산행을 겸해도 좋다. 능선에는 식수가 없으므로 미리 준비해야 한다.천문사나 윗대티마을에서 올라 윗대티마을로 원점회귀를 해도 좋고 반대 찰당골로 종주산행을 해도 하루 산행으로 충분하다. 주차장을 기점으로 하는 원점회귀산행은 4시간 30분이면 된다.", + "MNTN_HG_VL" : "1219", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 일월면 용화리, 청기면 당리", + "MNTN_NM" : "일월산" }, - "longitude" : 126.82715090000001, - "latitude" : 35.4843118 + "longitude" : 129.09831510000001, + "latitude" : 36.8016115 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "내장산국립공원 하면 일반적으로 내장산과 백암산 두 개 산으로 알려져 있지만, 공원 서쪽으로 입암산(687m) 또한 큰 면적을 차지하고 있다. 입암산은 중부 이북의 등산인들에게는 낯설지만 호남 등산인들에게는 오래 전부터 명성이 자자한 산이다. 특히 가을철이면 내장산 못지않게 고운 단풍으로 인기를 끄는 산이다.전북 정읍시 입암면, 전남 장성군 북하면에 위치한 입암산(626.1m)은 정상의 바위가 사람이 갓을 쓴 것 같다는 말과 능선위에 바위가 우뚝 솟아 입암이라 했다는 설이 있다.전라남도와 전라북도의 경계인 이 산은 정읍시 입암면을 가로질러 해발 260m의 노령을 넘다보면 좌측으로 보이는 산이 입암산(해발 626m)이다. 정읍벌의 평야지대와 대조를 이루며 우뚝 솟아 있기에 그 모습은 더욱 인상적이다. 또한 골짜기 깊숙한 곳이 분지를 이루고 있어 군사적 요충지로 지목되기도 했다. 특히 정상부에 위치한 입암산성은 조선 효종때 개축한 것으로 사적 384호다. 입암산은 옛부터 왜적의 침입을 막던 항쟁의 장소였다. 고려시대는 송고비장군이 몽고의 6차 침입을 맞아 이곳에서 몽고군을 물리쳤다고 하며 임진왜란 때는 윤진이 소서행장과 싸우다 전사하기도 했다.", - "MNTN_HG_VL" : "626", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군 북이면, 죽하면, 전라북도 정읍시", + "DETAIL_INFO_DTCONT" : "목포시 동쪽에 상동과 용해동에 걸쳐있는 해발 110m 산이다.산중턱에는 체육시설이 있으며 정상에서 바라보면 목포 구도심과 하당신도심 그리고남악신도심을 한눈에 볼 수 있다. 입암산 동남쪽 바닷가에 갓을 쓰고 있는 듯한 바위가 있어 이를 갓바위라 하는데갓바위가 있는 산이라 하여 갓바위산, 입암산이라 하였다 한다.목포팔경 중 입암반조(笠岩返照)라 하여 저녁노을에 물든 바닷가의 갓바위와바위절벽으로 된 입암산에 반사되는 저녁노을의 아름다움을 노래하고 있다.", + "MNTN_HG_VL" : "110", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 상동", "MNTN_NM" : "입암산" }, - "longitude" : 126.82715090000001, - "latitude" : 35.4843118 + "longitude" : 126.4152778, + "latitude" : 34.796111099999997 }, { "mountain" : { @@ -9271,19 +7151,39 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제otilde;시 금성면과 단양군 적성면의 경계를 이르는 작성산(鵲城山)은 북으로 가acirc;산(819.5m), 갑산(776.7m), 호명산(475.3m), 마당재산(661.2m) 산줄기를 이어받고, 남으로 내려뻗어 동산(896.2m), 금수산(1,015.8m)을 빚는다.ucirc;풍호를 서쪽에 낀 작성산은 이웃한 동산과 더불어 제otilde;의 이름난 산이다. 원래 이 산은 현지 사람들이 부르고 있는 ‘까치성산’ 이었는데, 일제시대에 일본인들이 지형도를 만들면서 한문표기인 ‘鵲’자를 사용하면서 작성산(鵲城山)으로 더 알려졌다. 까치성산이란 이름에 얽힌 전설이 있다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명했다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.", - "MNTN_HG_VL" : "840", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면 성내리", - "MNTN_NM" : "작성산" + "DETAIL_INFO_DTCONT" : "자굴산은 얼핏 보기에는 단순한 봉우리같지만 들어서서 보면 제법 다양한 경관을 갖추고 있는 산이다. 합천이나 산청으로 이어지는 20번 국도가 이 산 밑을 지나기 때문에 이 지역 사람들에게는 매우 친숙한 곳이다.자굴산은 남명 조식선생의 싯귀에 `도굴산( 堀山)'이라 기록되어 있고 저굴산, 지굴산, 사굴산이라고 불리는 등 산 이름의 유래가 명확치 않다. 그러다가 일제말기에 지방 유지들로 구성된 등산 친목단체 `운악회'에서 고향 진산의 이름을 통일하자고 의견을 모아 빼어난 산세를 강조하기 위해 글자마다 뫼산자를 넣어 표기했다고 한다.정상에서면 지리산 천황봉이 손에 잡힐 듯 가깝게 보인다. 그리고 절터샘과 명경대, 신비로운 금지샘 등 명소가 있다. 샘에는 억새가 무성하고 조망이 좋다.", + "MNTN_HG_VL" : "897", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 칠곡면, 가례면, 대의면", + "MNTN_NM" : "자굴산" }, - "longitude" : 128.21611110000001, - "latitude" : 37.036944400000003 + "longitude" : 128.20224590000001, + "latitude" : 35.374487700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "옛 목천현의 지산으로 개목고개가 있는데 이 고개에는 주인을 구하고 죽은 의구의 전설이 있고 동남쪽에는 병천 활석광산이 있고 산상의 성지는 임진왜란 때 의병장 이복장 장군의 의병을 이끌고 침략해 온 왜병에게 항전하며 지킨 곳이라고 한다.", - "MNTN_HG_VL" : "771", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 병천면 매성리 북면 매송리", + "DETAIL_INFO_DTCONT" : "lt;의령 고을의 진산gt;자굴산은 의령 고을의 진산으로 의령 고을 자체라고 할 수 있는 산이다. 높고 큰 산일수록 두 고을 또는 여러 고을의 경계가 되는 경우가 많다. 그러나 897미터나 되는 높고 큰 산이며 경관이 좋고 많은 전설도 간직하고 있는 자굴산(897.1m)은 서북 쪽 산자락 일부를 합천군이 차지하고 있을 뿐 대부분을 의령군이 차지하고 있다. 또한 자굴산은 양의 수산인 합천의 황매산에 대응하는 음의 암산이다. 그 때문에 양의 상징인 말을 정상에 모심으로써 음기와 조화를 이루게 했다고 한다.사람들은 절골 막바지의 써래봉 바람덤 아래 절터 일대의 짙은 숲과 그 사이에 솟아 있는 바위봉우리들과 신선대와 금지샘 일대의 오묘한 경관과 시원한 조망을 가장 좋아한다. 베틀바위에서 건너다보는 홑할미너덜과 절터 신선대 일대의 조망도 일품이다. 무당들의 기도터로 많이 이용되고 있는 강선암도 그 크기와 아래로 패여 들어간 기이한 모양으로 사람들이 많이 찾는 곳이라 한다. 특히 비가 올 때는 바위 위에서 떨어지는 물줄기가 수막을 이루어 그 안에서 밖을 내다보면 신기하다.", + "MNTN_HG_VL" : "897", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 가례면, 칠곡면, 대의면", + "MNTN_NM" : "자굴산" + }, + "longitude" : 128.20224590000001, + "latitude" : 35.374487700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "897", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 가례면, 칠곡면, 대의면", + "MNTN_NM" : "자굴산" + }, + "longitude" : 128.20224590000001, + "latitude" : 35.374487700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "제otilde;시 금성면과 단양군 적성면의 경계를 이르는 작성산(鵲城山)은 북으로 가acirc;산(819.5m), 갑산(776.7m), 호명산(475.3m), 마당재산(661.2m) 산줄기를 이어받고, 남으로 내려뻗어 동산(896.2m), 금수산(1,015.8m)을 빚는다.ucirc;풍호를 서쪽에 낀 작성산은 이웃한 동산과 더불어 제otilde;의 이름난 산이다. 원래 이 산은 현지 사람들이 부르고 있는 ‘까치성산’ 이었는데, 일제시대에 일본인들이 지형도를 만들면서 한문표기인 ‘鵲’자를 사용하면서 작성산(鵲城山)으로 더 알려졌다. 까치성산이란 이름에 얽힌 전설이 있다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명했다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.", + "MNTN_HG_VL" : "840", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면 성내리", "MNTN_NM" : "작성산" }, "longitude" : 128.21611110000001, @@ -9301,33 +7201,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 괴산에는 군자산이 두 개가 있다. 지도상에는 칠성면에 있는 군자산(948)과 남쪽 능선으로 약 4.5km에 작은 군자산이 있다. 이 지역 주민들은 작은군자산을 '남군자산'이라고도 부른다. 군자산은 옛부터\"\"충북의 소금강\"\"이라 불려왔을 정도로 산세가 빼어나다.속리산 국립공원에 속해 있는 군자산은 온 산이 기암석벽과 암릉을 이뤄 산세가 험준하다. 작은군자산은 바위가 많은 산으로, 산부인과바위, 삼형제바위, 낙타바위 등 기암괴석의 전시장을 연상케 한다.조선시대 당시 수많은 유학자와 문인들이 쌍곡의 산수 경치를 사랑하여 이곳에 소요하였고 수많은 전설을 간직하고 있는 곳으로 전해진다. 구곡은 호롱소, 소금강, 병암, 문수암, 용초, 쌍벽, 선녀탕, 쌍곡폭포, 마당바위 등이다. 산 아래를 흐르는 쌍곡계곡은 물이 맑고 깨끗해서 보는 사람들의 눈을 시원스럽게 할 뿐 아니라 물놀이를 즐기기에도 제격이다. 쌍곡계곡에서 시원스런 나무숲사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2m 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다.정상에서 북동쪽으로 내려서는 주능선에는 설악산의 '용아장성'을 연상케 하는 '용아릉'란 암릉이 산행 재미를 한층 더해준다. 이 산의 남쪽 산자락에는 1981년 재단법인 오운문화재단에서 설립한 '수련마을 보람원'이 자리잡고 있다. 군자산을 더욱 돋보이게하는 것은 쌍곡계곡이다. 쌍곡계곡은 퇴계 이황과 송강 정철의 사랑을 받았던 괴산8경의 하나로 쌍계라 부르기도 한다.계곡의 길이는 쌍곡리 쌍곡교에서 선유동으로 넘어가는 제수리치까지 약 12㎞에 달한다.가을이면 굴참나무, 다래나무, 단풍나무 등이 어울려 단풍숲 터널을 이룬다.", - "MNTN_HG_VL" : "827", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단양읍, 대강면", - "MNTN_NM" : "작은군자산" - }, - "longitude" : 127.87860019999999, - "latitude" : 36.737540799999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "작은 동산은 제otilde;시와 단양군 경계를 이루는 동산(896m)에서 서쪽으로 길게 뻗은 산줄기가 성봉(825.7m)에서 가지쳐 남서방향으로 뻗어 내리다 모래고개에서 주춤한 다음 솟아 오른 봉우리다. 산의 형세가 작고 아름다울 뿐만 아니라 산줄기를ucirc;풍호에 담그고 있어 작은 동산이라 불린다.작은동산 산행은ucirc;풍면 교리 마을과ucirc;풍랜드 사이의 계곡에서 시작한다. 서너 대의 주차공간이 있다.ucirc;풍랜드 번지점프장 바로 뒤편 도로변이다. 교리마을 주차장에서 시작해도 능선에서 만난다.외솔봉 전후, 모래고개 지점에서 우회하는 길이 많아 등산 시간과 코스를 맘 내키는 대로 조정할 수 있고, 푸른 소나무와 완만한 암릉길,ucirc;풍호반과 주변 산들의 조망이 좋아 남녀노소 편안하게 즐길 만한 산이다.", - "MNTN_HG_VL" : "545", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면 교리", - "MNTN_NM" : "작은동산" - }, - "longitude" : 128.19855190000001, - "latitude" : 37.011857900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "작은 동산은 충북 제천시 청풍면 교리와 학현리 사이에 위치한 산으로 체구는 작지만 경관이 수려하고 아기자기함이 살아있다. 산행곳곳에서 마주치는 산세의 수려함은 산행의 즐거움에 흠뻑 빠지게 한다. 동산으로 이어지는 능선과 작은동산의 정상에서 바라다보이는 전망은 가슴을 푸근하게 할만큼 정겹다. 고향집 뒷산처럼 아늑하고 그러면서도 산세가 뛰어난 작은동산의 산행길은 크게 힘든 지형이 없어 아이들을 동반한 산행길로도 그만이다, 산행길에 만나는 학현폭포와 약물탕계곡은 보기만해도 가슴이 시릴만큼 청량감을 내뿜는다.노송군락으로 에워싸인 길이 8m, 높이 6m, 폭 1m 가량 되는 입석바위가 작은동산 정상이다. 입석바위 아래에는 사과상자 두 배 크기의 자연석 제단이 있다. 예전부터 주민들이 치성을 드리던 장소라 전해진다. 그래서인지 요즘도 제천의 여러 단위산악회들이 여기서 시산제를 지내고 있다.정상에서는 에워싸인 노송군락으로 시야가 막혀 시원한 조망이 터지지 않는 것이 흠이다. 그러나 정상에서 만끽하지 못한 조망은 서릉을 타면서부터 시원하게 터지기 시작한다. 정상에서 서릉으로 10분 거리에 이르면 '추락주의' 안내판이 있는 암릉 위 너럭바위 전망장소(제1전망장소)에 닿는다. 남쪽 아래가 수십 길 절벽인 이곳에서는 학현리가 골골샅샅이 내려다보인다. 학현리 위로는 저승벽, 촛대바위, 궁뎅이바위가 선명하게 드러나 보이는 미인봉 ( 저승봉)이 병풍을 두른 듯 마주보인다. 미인봉 위로는 신선봉과 망덕봉이 살짝 고개를 내민 모습도 보이고, 남동쪽으로는 충주호반 위로 월악산 정상도 시야에 와닿는다.", - "MNTN_HG_VL" : "545", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", - "MNTN_NM" : "작은동산" + "DETAIL_INFO_DTCONT" : "가뭄이 심할 때 관민이 모여 기우제를 올리던 곳으로 홍림산, 일월산과 함께 영양의 진산으로 꼽힌다. 이 산은 세 개의 봉우리가 큰 바가지를 엎어놓은 듯 하여 한박산이라 불리기도 하며 산세가 탕건 같다하여 탕건봉이라 부르기도 한다.작약산이란 이름은 이 산의 형세가 풍수지리의 작약반개형(芍藥半開形) 명당이라는 데서 유래되었다. 정상에는 소나무와 참나무가 우거져 확 트인 전망을 기대하기 어렵다. 북으로 흥림산이 손에 잡힐 듯 가까이 보이나 북쪽이 협곡을 이루어 능선이 발달하지 않아 흥림산으로 연결된 등산로가 없다. 하산길에 권영성(1881-1923)의 넋을 기리기 위해 후손들이 세운 요산영천(樂山靈泉) 입석비가 있다. 권영성은 영양읍 서부동 출생으로 행상을 해서 번 돈으로 이 지역의 복지후생에 노력한 사람이다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 영양읍, 청기면", + "MNTN_NM" : "작약산" }, - "longitude" : 128.19855190000001, - "latitude" : 37.011857900000003 + "longitude" : 129.09472220000001, + "latitude" : 36.678888899999997 }, { "mountain" : { @@ -9356,18 +7236,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 소천면", "MNTN_NM" : "장군봉" }, - "longitude" : 127.34527780000001, - "latitude" : 35.9697222 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : " 도시 생활권내의 자연휴양지로 경사가 완만하고 토질은 자갈썩인 점질토이며, 주변에는주로 소나무와 잣나무가 생육하며, 도시근교의 야산으로 부녀자와 젊은 사람이 많이 찾는곳이다. 전문 등산객은 능선을 따라 개설된 주등산로을 따라 대구시 경계까지 등산하는코스를 이용하고 있고, 정상부에서는 전망이 좋아 하양읍과 진량읍 관내을 볼수 있으며운동시설도 잘 되어 있어 많은 사람이 찾는 곳이다.", - "MNTN_HG_VL" : "314", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 하양읍 부호리", - "MNTN_NM" : "장군산" - }, - "longitude" : 127.1994444, - "latitude" : 36.4658333 + "longitude" : 129.08583329999999, + "latitude" : 36.853055599999998 }, { "mountain" : { @@ -9376,8 +7246,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", "MNTN_NM" : "장군산" }, - "longitude" : 127.1994444, - "latitude" : 36.4658333 + "longitude" : 127.7175, + "latitude" : 34.748055600000001 }, { "mountain" : { @@ -9389,16 +7259,6 @@ "longitude" : 127.5486609, "latitude" : 37.670588000000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "삼천포의 사람들이 아침등산을 각산으로 간다면 사천의 사람들이 많이 이용하는 아침 등산로이다. 많은 사람들이 이용을 하고있고 가볍게 등산하는 코스로 근처 아파트 단지 주민들이 많이 이용하고 있다.뜸북산이라고도 부른다.", - "MNTN_HG_VL" : "250", - "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시 정동면", - "MNTN_NM" : "장령산" - }, - "longitude" : 127.5553671, - "latitude" : 36.243483400000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -9406,8 +7266,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창 방림면, 대화면", "MNTN_NM" : "장미산" }, - "longitude" : 127.85416669999999, - "latitude" : 37.049999999999997 + "longitude" : 128.36008799999999, + "latitude" : 37.475849199999999 }, { "mountain" : { @@ -9416,18 +7276,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 방림면 대화면", "MNTN_NM" : "장미산" }, - "longitude" : 127.85416669999999, - "latitude" : 37.049999999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "장복산은 진해시와 창원시를 경계로 진해시를 병풍처럼 둘러싸고 있는 높이 582미터 산이다. 장복산은 「세종실록지리지」나 「경상도지리지」에lsquo;長卜山rsquo;으로 나온다. 장복이라는 사람이 무술을 닦은 곳이라는 설과 풍수설에서 이곳에 자리를 정하여 산다면lsquo;오래도록(長) 살만한 좋은 곳(卜居middot;卜地)이 될 것이라rsquo;는 설에서 이름이 유래되었다.해마다 봄이면 화사한 벚꽃이 장복산 기슭을 온통 뒤덮어 찾는 이들의 시선을 사로잡는다. 또한 송림과 편백 등 오래된 나무들이 울창하여 산림욕을 즐길 수 있는 산이다. 장복산 기슭에는 88만 여평의 넓은 녹지대에 장복산공원이 조성되어 있다. 울창한 송림과 만여 그루의 벚꽃이 조화를 이루고 있어 장관을 이룬다. 4월 초에 총 10일간에 걸쳐 군항제가 펼쳐진다. 산 일대에 대광사, 진흥사 등의 사찰이 있다.", - "MNTN_HG_VL" : "582", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 여좌동", - "MNTN_NM" : "장복산" - }, - "longitude" : 128.65882300000001, - "latitude" : 35.172026099999997 + "longitude" : 128.36008799999999, + "latitude" : 37.475849199999999 }, { "mountain" : { @@ -9436,18 +7286,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 상동읍", "MNTN_NM" : "장산" }, - "longitude" : 129.14469020000001, - "latitude" : 35.194415200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "많은 사람들이 해운대는 알아도 장산(634m)은 모른다. 장산은 그리 높지 않으나 우람하고 아름다운 산이다. 여기 저기 넓은 억새밭이 있어 가을엔 하얀 억새가 넘실거린다. 장산 능선 자락 여러 곳에 크고 작은 너덜이 있다. 특히 6부 능선길과 8부 능선길 사이에 있는 큰 너덜은 500~600미터대에서 폭 40~50미터 규모로 형성돼 있어 장쾌하고 특이한 광경을 연출한다.무엇보다 장산이 좋은 것은 바다 조망이 있다는 것이다. 끝없이 펼쳐지는 바다는 가슴을 후련하게 해준다. 오륙도가 보이고 멋진 광안대교가 한눈에 내려다보인다. 신증동국여지승람이 밝힌 바와 같이 장산은 일본 대마도를 가장 가까이 볼 수 있는 곳이다. 장산은 억새와 너덜, 그리고 조망 외에도 숲이 울창하며 계곡과 폭포도 아름답다. 대천공원으로 흘러내리는 계곡은 물론 폭포사 위 양운폭포(일명 장산폭포)는 어느 폭포와 견주어도 손색이 없을 정도로 훌륭하다. 장산폭포는 해운8경의 제3경이다.장산 들머리인 대천공원도 볼거리다. 공원에는 상징조형물과 야외무대, 놀이터, 저수지, 체육시설 등이 갖추어져 있다.", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "부산시 해운대구 좌동", - "MNTN_NM" : "장산" - }, - "longitude" : 129.14469020000001, - "latitude" : 35.194415200000002 + "longitude" : 128.86013370000001, + "latitude" : 37.127789800000002 }, { "mountain" : { @@ -9476,8 +7316,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 묘량면, 삼서면", "MNTN_NM" : "장암산" }, - "longitude" : 128.4221124, - "latitude" : 37.3872778 + "longitude" : 126.5838186, + "latitude" : 35.2580569 }, { "mountain" : { @@ -9506,18 +7346,18 @@ "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구", "MNTN_NM" : "장태산" }, - "longitude" : 127.8977778, - "latitude" : 37.068055600000001 + "longitude" : 127.33380579999999, + "latitude" : 36.210955599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "619", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", - "MNTN_NM" : "재래봉" + "DETAIL_INFO_DTCONT" : "금북정맥 구간에 해당", + "MNTN_HG_VL" : "381", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 예산군", + "MNTN_NM" : "장학산" }, - "longitude" : 129.19864290000001, - "latitude" : 35.713271400000004 + "longitude" : 126.88777779999999, + "latitude" : 36.561388899999997 }, { "mountain" : { @@ -9551,13 +7391,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "적석산은 바닷가의 산으로 산 아래 양촌에 온천이 있어 산행 뒤 온천욕을 즐길 수 있으며 다도해를 바라보며 맛있는 회를 저렴한 가격으로 맛볼 수 있는 곳이다. 또한 주변의 명소와 유적을 돌아볼 수도 있는, 실로 1석 3조의 산행지다.적석산 정상은 넓은 반석으로 남북이 바위로 까마득하게 낭떠러지를 이루고 있다. 적석산은 이름 그대로 납작바위를 차곡차곡 쌓아 올린 것처럼 보이는 산이다. 그래서 쌓을 적(積)자를 써서 적산이라고도 한다. 온 산이 바위로 되어 있다 하여도 과언이 아닐 정도로 기이하고 괴상한 바위와 돌들이 널려 있다. 적석산의 고스락은 깎아지른 바위 낭떠러지여서 조망이 좋다. 마산 앞바다와 북쪽에 오봉산, 동북쪽으로 여항산, 서북산이 보이고 동쪽으로 광려산이, 머리를 살짝 내밀고 있는 마산의 무학산도 볼 수 있다.", - "MNTN_HG_VL" : "492", - "MNTN_LOCPLC_REGION_NM" : "경남 마산시 진전면·고성군 회화면·창원시", - "MNTN_NM" : "적석산" + "DETAIL_INFO_DTCONT" : "적자봉이 있는 보길도는 다도해해상국립공원의 숨은 진주다. 해가 수평선으로 가라앉을 때 하늘과 바다를 물들이는 무지개빛 노을이 장관이다. 이처럼 찬란한 빛이 황홀경을 되쏘는 봉우리라서 ‘적자봉’이라 한다. 이 산은 남쪽에 누운 거대한 암소가 새끼를 어르듯 북으로 광대봉, 망월봉, 일락봉 등 300미터 안팎의 산들을 품고 있다. 정상 부근에는 섬회양목 등 많은 희귀식물들이 향기를 뿜고 기암괴석들이 능선을 잇는다. 멀리 해남의 땅끝과 달마산, 완도의 상황봉까지 사철 동백나무, 예덕나무, 정금나무, 곰솔 등 250여 종의 식물들이 수해를 이루어 늘푸른 산의 생기를 불어 넣는다. 가까운 예송리의 천연기념물 제40호인 상록수림과 해수욕장도 가볼 만하다.적자봉을 중심으로 광대봉, 망월봉, 일락봉이 둥근 원을 그리듯 펼쳐져 있고 안쪽으로 고산 윤선도의 적거지였던 부용동에 유적지(사적 368호)가 남아 있다. 보길도는 조선 중기의 탁월한 가객 고산 윤선도의 유배지로서 그의 체취가 물씬 풍긴다.", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 보길면", + "MNTN_NM" : "적자봉" + }, + "longitude" : 126.5313889, + "latitude" : 34.137777799999988 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도 가평군 하면과 가평읍을 사이에 두고 솟아있는 전패봉은 북으로는 명지산(1267m), 남으로는 구나무산(858m)을 등에 업고 서남쪽을 향해 매봉(929m)을 바라보고 있는 아담한 산이다. 인근 명지산의 위세와 운악산 현등사의 유명세에 가려 아직 일반에게 잘 알려지지 않았으나, 그만큼 사람들의 때가 묻지 않은 자연그대로의 숨결을 간직한 산이다. 산세가 부드러워 가족산행에 적당하다. 주능선에는 잡목과 억새풀이 어우러져 있다.이전에는 전패봉이라 하였는데, 혐오스러운 느낌을 준다는 이유로 1999년 3월 가평군 지명위원회가 우정봉으로 바꾸었고 그 아래 전패고개는 우정고개로 이름지었다. 이와 동시에 우목봉은 연인산으로, 879m봉은 장수봉으로, 구나무산은 노적봉으로 이름을 고쳤다.", + "MNTN_HG_VL" : "701", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", + "MNTN_NM" : "전패봉(우정봉)" }, - "longitude" : 128.36944439999999, - "latitude" : 35.109444400000008 + "longitude" : 127.4186114, + "latitude" : 37.898696600000001 }, { "mountain" : { @@ -9576,8 +7426,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 화천", "MNTN_NM" : "절산" }, - "longitude" : 127.471637, - "latitude" : 34.976263000000003 + "longitude" : 127.7678485, + "latitude" : 38.119342699999997 }, { "mountain" : { @@ -9599,16 +7449,6 @@ "longitude" : 128.4891374, "latitude" : 37.265738200000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "374", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 고아읍 이례리,원호리,봉한1리,대망2리,예강1리,예강리,항곡리,", - "MNTN_NM" : "접성산" - }, - "longitude" : 128.32762840000001, - "latitude" : 36.186809699999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "정각산은 경남 밀양시 단장면 한적한 곳에 자리 잡고 있다. 삼각산(887m)과 인접해 있으며 말발굽형상으로 연결되어 있는 이 산에는 유독 묘(墓)들이 눈에 띄게 많다. 그만큼 풍수지리상 좋은 자리를 차지하고 있다는 설이 있다. 대신 등산객들은 찾아 보기 어렵고 발길 닿지 않은 자연림의 형태를 잘 보존하고 있는 곳이다.정상 가까이에 묘(墓)가 많이 있으며, 이웃한 삼각산(887m)과 말발굽 모양으로 이어져 있다. 산행은 표충사에서 4Km 떨어진 범도리 아불마을에서 시작하여 정상에서 능선을 따라 삼각산을 마주보고 내려가다가 송백리로 빠져 내려온다. 산 아래로 남천이 남서쪽으로 흐르며, 산 동쪽 재약산(1108m) 자락에는 신라 진덕여왕 8년 원효대사가 창건한 표충사가 있다. 표충사에는 청동함은향완(국보 75), 삼층석탑(보물 467), 석등(경남유형문화재 14), 표충서원(경남유형문화재 52) 등의 유물이 남아 있다.", @@ -9636,8 +7476,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면", "MNTN_NM" : "정승봉" }, - "longitude" : 128.87570880000001, - "latitude" : 35.440996499999997 + "longitude" : 128.90484180000001, + "latitude" : 35.547757799999999 }, { "mountain" : { @@ -9649,16 +7489,6 @@ "longitude" : 127.34154669999999, "latitude" : 37.514297800000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "700", - "MNTN_LOCPLC_REGION_NM" : "경상북도 양산시", - "MNTN_NM" : "정족산" - }, - "longitude" : 126.487099, - "latitude" : 37.632629100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "정족산은 산의 생김새가 마치 세 발 달린 가마솥과 같다고 해서 이름 붙여진 산이다. 정족산에는 단군이 세 아들을 시켜 쌓았다는 삼랑성이 있다. 일명 정족산성이라고도 하는 삼랑성은 사적 제130호의 돌성이다. 성의 시설물로는 남문루와 동문, 서문, 북문지가 있고 성 안에는 13개의 우물이 있었다고 전하며 고구려시대에 창건된 전등사가 있다.전등사는 이 삼랑성안에 있는 사찰이다. 고구려 소수림왕 11년(372) 아도화상이 진종사(眞宗寺)라 이름한데서 시작되었다.\"\"신증동국여지승람\"\"에 의하면 충렬왕 8년(1282) 왕의 원비인 정화궁주 왕씨가 승려 인기(印奇)에게 송나라에 들어가 대장경을 가져오게 하여 이 절에 보관했다고 한다. 전등사라는 이름은 정화궁주가 불전에 옥으로 된 등잔을 올린 뒤 붙여진 이름이다. 특히 정족산에는 `조선왕조실록'을 보관했던 사고터가 남아 있어 유적답사 및 가족산행을 하기에 가장 적합한 곳이다.산행은 전등사에서 시작된다. 전등사의 요사채 뒤로 난 길을 곧바로 올라가면 정상에 닿을 수 있다. 정상에서는 나무에 둘러싸인 전등사의 고풍스러운 모습과 마니산과 서해바다의 모습을 한눈에 바라 볼 수 있다.", @@ -9666,8 +7496,8 @@ "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 길상면", "MNTN_NM" : "정족산" }, - "longitude" : 126.487099, - "latitude" : 37.632629100000003 + "longitude" : 126.4802778, + "latitude" : 37.6325 }, { "mountain" : { @@ -9689,16 +7519,6 @@ "longitude" : 127.36750000000001, "latitude" : 34.869166700000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "남도 끝자락 전남 장흥에 있는 제암산은 철쭉이 전국에서 제일 먼저 피는 곳 중의 한 곳으로 철쭉명산이다. 해발 807미터의 산으로 호남정맥의 한 줄기를 이루고 있다. ‘제암’이란 이름은 정상에 우뚝 솟구친 ‘임금바위’에서 생겨났다. 이 산은 5월 초면 곰재를 사이에 두고 솟은 곰재산의 철쭉 산상화원이 연출된다. 곰재산은 기암괴석의 험준한 제암산과 달리 평원을 이룬 듯이 나지막하게 솟아 있다. 그 능선에 전국 제일의 철쭉 군락이 있다.제암산의 지형도 상 높이는 779미터이지만 정상의 높이는 807미터이다. 그 차이는 임금 제(帝)자 모양의 임금바위가 있고 없음의 차이인 듯 하다. 임금바위는 수십명이 앉을 수 있을 정도로 편편한데 제암단이라 하여 예부터 기우제를 지내던 곳이 있다.", - "MNTN_HG_VL" : "807", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥 안양면·보성 웅치면", - "MNTN_NM" : "제암산" - }, - "longitude" : 126.97551730000001, - "latitude" : 34.709934199999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "평창군 도암면, 성산면 어흘리와 왕산면 왕산리 사이에 있는 높이 841m의 산이다. (구)대관령 휴게소에서 1시간가량 오르면 정상에 오를 수 있다. 정상에서 상제민원(옛길 주막터)방향은 내리막길의 연속으로 지세는 급,완경사지로 이루어져 있고 지형적으로는 능선을 따라 이동하면서 자연스럽게 계곡으로 이동하게 되고 대관령박물관 옛길 코스에서도 오를 수 있다.대관령 능선의 어디에서나 강릉 시가지를 볼 수 있지만 제왕산성에서 내려다 보는 강릉 시가지는 특별하다. 시야에 막힘이 없어 시원하고도심의 모습과 바다로 흐르는 남대천의 흐름까지를 전부 조망할 수 있다.소요 시간 :2시간정도최적 탐방 시기 :매년 음력 5월 5일에는 단오제가 열리고, 10월에는 율곡제·무천제가 열린다. 하지만 4계절 모두 경치가 좋음명소 : 국사성황당 및 산신각, 신재생에너지전시관, 양떼목장, 대관령박물관볼거리 : 산세가 완만하며 상제민원의 계곡이 뛰어나고, 참나무숲과 낙엽송이 우거진 수풀이 곳곳에 있다.평창군 도암면과 강릉시 성산면 경계에는 선자령이 있고, 북쪽으로 영동고속도로를 사이에 두고 대관령 및 오대산국립공원과 마주본다.숲길 명소 : 강릉영림서의 임간학교가 제왕산 계곡에 있어 삼림욕을 즐길 수 있고, 어흘리에 대관령 박물관이 있어 옛 얼을 느껴 볼 수 있다.백두대간의 한구간으로서 능경봉과 선자령구간을 탐방할 수도 있으며 뛰어난 조망점을 자랑하고 있다.", @@ -9751,13 +7571,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "낙영산과 이웃해 있는 조봉산은 충북 괴산군 청천면에 뿌리를 내리고 있으며 각종 기암괴석으로 조각된 듯한 바위만물상들이 마치 새의 입부리처럼 뾰족한 형태를 이루고 있다하여 산 이름을 조봉산이라 지었다.산 자락에는 신비스러운 자연석굴인 굴바위를 비롯하여 거대한 벽돌처럼 보이는 마당바위, 행상바위, 맷돌바위, 베틀바위, 코뿔소바위, 구멍바위, 북바위 등 바위 군락지가 있어 산행인들의 눈을 쉬지 않게 해 준다. 자연석굴을 지나면 급경사 내리막길이 시작되며 이곳 중턱에 이르면 산부인과 바위라 부르는 구멍바위가 나타난다.구멍바위를 통과해도 계속 내리막길이 이어지는데 겨울철 적설기에는 반드시 보조자일이 필요하다. 이 산 남쪽으로는 용대천 계곡이 흐르고 있어 여름철 피서지로도 그만이다.", - "MNTN_HG_VL" : "687", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", - "MNTN_NM" : "조봉산" + "DETAIL_INFO_DTCONT" : "강원도 양양군에 있는 조봉은 암반과 숲이 연출하는 풍광이 설악산을 방불케하는 숨겨진 명산이다. 이웃한 명소 미천골이 사람들의 발길을 모두 몰아가버린 덕분에 조봉은 천연 그대로의 풍광을 고스란히 보존하고 있다.산행기점에서 조금만 오르면 벽실골이 나오는데 이곳은 굴피밭골, 큰북골 등 모두 여섯 가닥의 지류가 나뉘어지는 곳으로 비선대에서 대청봉 턱밑까지 뻗은 천불동보다 조금 짧은 계곡이다. 벽실골은 하류보다 상류쪽 경관이 한층 돋보인다. 설피밭골을 거쳐 큰북골 입구를 지나면 골이 갑자기 좁아지며 널찍한 암반과 와폭 등이 이어지는데 연이어진 폭포의 절경이 마치 설악산의 12선녀탕을 연상케 한다. 12탕보다 수량은 적으나 대신 서슴없이 물줄기를 거슬러 올라가는 재미를 만끽할수 있다.", + "MNTN_HG_VL" : "1182", + "MNTN_LOCPLC_REGION_NM" : "강원도 양양군", + "MNTN_NM" : "조봉" }, - "longitude" : 126.6750438, - "latitude" : 35.7556273 + "longitude" : 128.56027779999999, + "latitude" : 37.945 }, { "mountain" : { @@ -9786,8 +7606,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군", "MNTN_NM" : "조항산" }, - "longitude" : 129.37995799999999, - "latitude" : 35.756602999999998 + "longitude" : 127.5848718, + "latitude" : 35.963462 }, { "mountain" : { @@ -9796,18 +7616,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면, 충청북도 괴산군 청천면", "MNTN_NM" : "조항산" }, - "longitude" : 129.37995799999999, - "latitude" : 35.756602999999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "종암산은 산세가 온순한데다 산악동호인들의 발길이 뜸했던 산 답지 않게 길이 또렷하고 잡목과 수풀의 훼방도 거의 없다. 눈 아래로 펼쳐지는 부곡하와이의 전경과 손 에 잡힐 듯한 창녕의 진산 영축산 조망도 그림 같다.특히 등산로 입구에서 만나는 함박산약수터(향토문화경승지 제19호)는 1천2백 여년의 역사를 지닌 영산의 명소로 당뇨와 위장병에 특별한 효험이 있는 것으로 알려져 있다. 신라시대 한 효자나무꾼에 얽힌 전설을 간직한 이 곳에는 사시사철 사람의 발길이 끊이지 않는다.", - "MNTN_HG_VL" : "546", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군", - "MNTN_NM" : "종암산" - }, - "longitude" : 124.83666669999999, - "latitude" : 40.0341667 + "longitude" : 127.93611110000001, + "latitude" : 36.633611100000003 }, { "mountain" : { @@ -9846,8 +7656,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군, 청원군", "MNTN_NM" : "좌구산" }, - "longitude" : 127.6513729, - "latitude" : 36.708345700000002 + "longitude" : 127.636263, + "latitude" : 36.717288799999999 }, { "mountain" : { @@ -9856,8 +7666,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", "MNTN_NM" : "좌구산" }, - "longitude" : 127.6513729, - "latitude" : 36.708345700000002 + "longitude" : 127.636263, + "latitude" : 36.717288799999999 }, { "mountain" : { @@ -9866,8 +7676,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", "MNTN_NM" : "좌구산" }, - "longitude" : 127.6513729, - "latitude" : 36.708345700000002 + "longitude" : 127.636263, + "latitude" : 36.717288799999999 }, { "mountain" : { @@ -9879,16 +7689,6 @@ "longitude" : 127.6088889, "latitude" : 37.720277799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "415", - "MNTN_LOCPLC_REGION_NM" : "경남 고성군", - "MNTN_NM" : "좌이산" - }, - "longitude" : 128.18729250000001, - "latitude" : 34.923567599999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "주걱봉은 설악산 국립공원의 남서부에 위치해 있는 가리봉 줄기에 자리잡고 있다. 최고봉인 가리봉을 위시하여 가리봉 북쪽 지릉의 십이연봉, 주걱처럼 생긴 주걱봉, 삼형제봉 등이 한데 어우러져 있는데 모두 바위봉으로 이뤄져 산세가 급하고 험준하다. 북쪽으로 자양천·계천이 흐르고 이 두 하천을 사이에 두고 맞은 편에 대승령(1210m)·안산(1430m)이 있다. 북쪽 산 아래에 하늘벽·장수대가 있다.주걱봉을 비롯한 가리봉 줄기를 오를때는 사전에 정확한 정보를 준비해야 한다. 점봉산처럼 원시림이 울창하고 암봉이 이어져 있으며 양쪽에 낭떠러지가 있어 능선 중앙부에 있는 가리봉으로 접근하는 일이 쉽지 않기 때문이다.", @@ -9909,35 +7709,15 @@ "longitude" : 127.2691293, "latitude" : 37.784374499999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 제천시 백운면과 봉양읍에 걸쳐 위치한 주론산은 구학산과 박달재사이에 솟아있는 산이다. 주론산이란 이름은 정상에서 동쪽 아래로 패어내려간 조백석골에서 학곡리 배론마을까지 이어지는 골짜기가 마치 배(船)밑바닥을 닮았다해서 붙여진 이름이다.일반이들에게 아직 알려지지 않은 산으로 이름조차 생소하지만 주론산은 한국 천주교사에서 빼놓을 수 없는 유서깊은 배론 성지가 있는 역사교육장이기도 하다. 이름이 널리 알려진 박달재와 탁사정이 인접하고 있어 등산을 겸한 가족나들이 코스로도 각광 받고 있다. 또 산행기점인 박달재는 고려 고종3년(1216년) 거란족의 10만대군을 김취려 장군이 섬멸시킨 전승지이기도 하다.산행보다는 역사현장을 둘러본다는 것이 더 적합할 듯하나 900m가 넘는 주론산의 산행은 결코 만만치 않으므로 단단히 채비를 하고 나서야 낭패를 당하는 일이 없다. 주론산은 부드러운 능선으로 이어져 적설기 등산지로 좋고 때묻지 않은 오지 농촌의 풍경을 간직하고 있어 더욱 좋다.", - "MNTN_HG_VL" : "903", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 봉양읍, 백운면", - "MNTN_NM" : "주론산" - }, - "longitude" : 128.04396890000001, - "latitude" : 37.161651999999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "489", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "주발봉" - }, - "longitude" : 127.4947222, - "latitude" : 37.776111100000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "주봉산은 충주시 동량면 지동리와 서운리 사이에 솟은 봉우리로 산세가 완만하고 순탄해서 누구나 별무리 없이 등산할 수 있는 산이다. 특히 이 산을 중심으로 해서 충주호가 삼면으로 둘러싸고 있어 정상에 올라서면 마치 섬안에 떠있는 듯한 느낌을 받는다. 이 산의 남쪽자락에는 서운리 마을이 자리잡고 있다. 충주호 선착장에서 충주호반을 따라 꾸불꾸불한 길을 따라 한참을 들어가면 길이 끝나는 지점에 아담한 마을이 나타나는데 이 마을 을 지키고 서 있는 산이 바로 주봉산이다.주봉산 정상에서 바라보면 남서쪽으로는 계명산이 서쪽으로는 부대산, 지등산이 옹기종기 둘러앉아 잇는 모습이다.", - "MNTN_HG_VL" : "643", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면", - "MNTN_NM" : "주봉산" + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "주발봉" }, - "longitude" : 128.54221570000001, - "latitude" : 38.172462099999997 + "longitude" : 127.4947222, + "latitude" : 37.776111100000001 }, { "mountain" : { @@ -9956,18 +7736,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군", "MNTN_NM" : "주산" }, - "longitude" : -74.005592699999994, - "latitude" : 40.8404071 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "831", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", - "MNTN_NM" : "주산" - }, - "longitude" : -74.005592699999994, - "latitude" : 40.8404071 + "longitude" : 128.25277779999999, + "latitude" : 35.731944400000003 }, { "mountain" : { @@ -9979,16 +7749,6 @@ "longitude" : 128.61694439999999, "latitude" : 35.773888900000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "국립공원 주왕산은 병풍처럼 펼쳐진 기암절벽이 장관.", - "MNTN_HG_VL" : "722", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군 청송읍ㆍ부동면, 영덕군 지품면ㆍ달산면", - "MNTN_NM" : "주왕산" - }, - "longitude" : 129.16659859999999, - "latitude" : 36.388218100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "주월산은 괴산의 명산 중 가장 짧은 코스이다. 산행에 필요한 시간은 불과 1시간 정도면 충분하기 때문이다. 그렇다고 볼거리가 없다거나 시시한 산은 절대 아니다. 느릅재 정상에서 충주 쪽으로 19번 국도를 따라 가면서 가까이 보이는 까닭에 누구든 빼어난 산의 모습에 취하면 쉽게 내려오지 못하는 산이기도 하다.바위능선이 병풍처럼 둘러쳐져 있어 산세가 빼어나고 정상에 오르면 남쪽으로 박달산을 비롯한 여러 산이 보인다. 주변에 공림사와 망개나무자생지·수안보온천 등의 명소가 있다.산행은 감나무골에서 시작한다. 능선을 타고 5분 오르면 작은 봉우리가 나오는데 이곳에서 서쪽으로 이담저수지와 마을이 보인다. 동쪽으로 10분 정도 올라가 첫번째 바위봉우리를 지나면 정상이다. 두 봉우리 주위는 마치 성곽처럼 평평한 바위로 둘러싸여 있고 그 모습이 절구의 확돌처럼 보인다 하여 산 아랫마을을 화학골이라 부르기도 한다.", @@ -9999,16 +7759,6 @@ "longitude" : 127.9037335, "latitude" : 36.849944299999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "주읍산은 양평과 용문 중간에 위치한 산으로 추읍산, 혹은 칠읍산이라 불렀다한다. 이는 주변의 일곱개 읍, 즉 양평, 용문, 개군, 지제, 강상, 옥천, 청운등이 한눈에 보인데서 유래한 것이다.용문산 동쪽 싸리재와 횡성과의 경계에 있는 성지봉에서 발원되는 신내개울이 산 기슭을 굽이 돌고 서쪽으로는 오대산과 태백산 어름에서 흘러내려온 남한강이 산 밑둥을 감싸 흐르며 산그늘을 담아내는 모습이 숭엄해 보인다.중성마을 뒤 밤나무가 많은 능선을 타고 질마재에서 소나무숲 터널을 거쳐 정상에 오르면 신내천과 남한강이 한눈에 내려다보인다. 주읍산 정상에는 1975년에 설치한 삼각점 외에 아담한 정상비가 있다. 여름철에는 신내천의 초원지대에서 마음껏 뛰어 놀수 있어 가족 단위 산행으로 제격이다.", - "MNTN_HG_VL" : "583", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 양평읍, 개군면, 지제면", - "MNTN_NM" : "주읍산" - }, - "longitude" : 127.5729425, - "latitude" : 37.456420199999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "봉황이 날개를 활짝 펴고 하늘을 날고 있다해서 이 산의 이름은 주작산이다. 해남과 강진의 경계를 이룬 주작산(약 475m) 능선은 전형적인 암릉길이다. 그동안 지척에 있는 두륜산에 가려 빛을 보지 못했지만 특유의 거칠고 까탈스런 바윗길 덕분에 이제 남도의 대표적인 암릉산행지로 주목받고 있다.주작산은 두륜산에서 동쪽으로 뻗어내린 산맥이 오소치에서 멈춘 뒤, 거친 기세로 솟아 오른 바위능선 한 귀퉁이에 솟아 있다. 그것도 주능선이 아닌 동쪽으로 조금 삐져나온 지능선 상에 위치한다. 그래서 주작산 산행은 이 주봉을 오르기보다 오소재 - 작천소령으로 연결되는 산줄기 전체를 타는 것이 일반적이다.주작산 줄기는 북으로 덕룡산(432.9m)과 석문산(272m) - 만덕산(408.6m)까지 이어진 긴 능선의 일부 구간이다. 이 산자락의 대부분 구간은 바위 봉우리와 벼랑으로 형성되어 보는 맛이 탁월하다. 특히 주작산 구간은 톱날 같은 암릉이 길게 이어져 아기자기한 산행의 묘미가 뛰어나다.주작산 산행은 접근이 편리한 오소재에서 시작해 작천소령으로 답사하는 것이 일반적이다. 초창기에는 산이 거칠고 길도 없어 10시간 이상 걸렸지만, 이제는 우회로가 많이 생겨 시간이 많이 단축됐다. 건각들은 주작 - 덕룡산 줄기를 하루에 답파하기도 한다. 위험한 구간에는 어김없이 로프를 매어 놓았지만, 아직도 아찔한 구간이 많으니 초심자가 낀 팀은 주의해야 한다.", @@ -10019,6 +7769,16 @@ "longitude" : 126.6956041, "latitude" : 34.5063703 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "주지봉은 월출산(813m)의 서쪽에 위치한 나즈막한 산이다. 도갑저수지의 서쪽에 있는 능선인데 죽순봉 아래 성기동 일대에 왕인박사 유허비를 비롯한 유적들이 산재해 있다.한반도의 서남단, 소백산맥의 끝부분에서 우뚝 솟은 월출산은 최고봉인 천황봉을 비롯하여 구정봉, 장군봉, 자봉, 향로봉, 주지봉, 노적봉 등의 영봉이 기암 괴석으로 신비롭게 이루어져 예로부터 호남의 소금강이라 일컬어져 왔고, 미왕재를 위시한 능선은 억새풀밭으로 장관을 이루며 산능의 북쪽면은 날카롭고 가파른 돌산인 반면 남쪽면은 완만한 육산으로 이루어져 있고 골짜기가 깊지 않아 곳곳에 저수지가 설치되어 있다.", + "MNTN_HG_VL" : "491", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군", + "MNTN_NM" : "주지봉" + }, + "longitude" : 126.6496305, + "latitude" : 34.745091199999997 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "김otilde;쪽에서 추풍령을 넘어 황간 가까이 내려오면 1시 방향으로 하나의 커다란 배가 하늘을 떠가는 모양을 볼 수 있다. 바로 주행봉이다. 떠가는 배의 모양을 그대로 이름으로 한 것이다.속리산에서 백두대간과 헤어진 산줄기 하나가 구병산을 거쳐 팔음산(762m, 옥otilde;ucirc;산면)으로 나아가고 이 산줄기는 한껏 낮아졌다가 백화산으로 다시 일어나 933미터의 포성봉과 874미터의 주행봉을 빚어놓았다. 이 백화산은 상주의 모동면 모서면, 옥otilde;의ucirc;산면 일대의 분지 가운데 자리잡고 있기 때문에 더욱 우뚝하고 커 보인다.국토지리정보원의 지도에는 포성봉, 주행봉으로 표기되어 있다. 포성봉이라 부르는 연유는 알 수 없으나 「신증동국여지승람」과 모든 기록에 백화산으로 되어 있고 상주쪽에서는 한성봉이라 부르기도 한다. 주행봉을 현지 주민들은 “쌀개봉”이라 부른다. 주행봉의 머리를 이루는 바위 봉우리 두 개가 옛날 디딜방아의 쌀개oacute;럼 되어있기 때문이다.", @@ -10066,28 +7826,28 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", "MNTN_NM" : "죽엽산" }, - "longitude" : 127.1855556, - "latitude" : 37.7916667 + "longitude" : 127.8472038, + "latitude" : 38.052157999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 괴산군 청천면에는 아름다운 경관을 갖춘 산들이 많이 있는데 그 중 중대봉은 아직 타지 사람들의 귀에 생소한 산이다. 백두대간상의 대야산(931m) 정상인 상대봉에서 서쪽으로 분기하는 지릉산의 최고봉이 중대봉인데 이 산은 우리나라에서 몇 안되는 `전인미답'의 경지를 보존하고 있다.중대봉은 바로 이웃인 상대봉의 상대적인 개념으로 붙여진 이름이며, 산 전체가 하나의 화강암으로 이루어져 있으며, 2∼3년 전까지만해도 워킹코스가 없어 전인 미답의 산으로 남아있었지만 최근 암벽을 이용한 코스가 개발되고 위험한 곳에는 로프를 매놓아 완벽한 등산로를 만들어 놓았다.중대봉을 가기 위하여는 청천면 소재지, 화양동, 송면 소재지를 지나 상주시 화북면으로 가는 592번 지방도를 따라 삼송 3구 마을까지 가야하는데, 이 마을은 농바위 마을이라 불리워 진다. 농바위 마을의 마지막집 담장에는 500여년이나 되는 느티나무가 노쇠한 모습으로 서 있다. 이 마을은 손꼽히는 장수마을이다. 마을 지반 전체가 신비의 돌이라는 맥반석이 깔려있고 여기서 솟는 물을 먹고 장수한다고 믿고 있다.정상에서의 조망은 동쪽과 남쪽은 확 트였지만 북쪽과 서쪽은 참나무에 가려 잘 보이지 않는다 하지만 동족은 대야산이 꽉 채우고 있으며 그 왼쪽아래 주흘산이, 조금 떨어진 동북쪽으로 희양산 하얀 바위봉우리가 우뚝하며, 남쪽으로 서서히 둔덕산과 마귀할멈 통시바위, 조항산의 백두대간이 도도히 흐르고 있다.", - "MNTN_HG_VL" : "830", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군", - "MNTN_NM" : "중대봉" + "DETAIL_INFO_DTCONT" : "중미산은 청평과 양평을 잇는 37번 도로에서 가장 높은 곳인 선어치(서너치)고개를 사이에 두고 유명산과 마주보고 있다. 중미산 남쪽의 고개를 서너치(3-4寸)라고 부르게 된 데에는 재미있는 연유가 있다.호랑이가 있다는 고개를 넘어 온 선비에게 호랑이를 못 보았느냐고 묻자\"\"호랑이는 못 보고 어찌나 나무가 울창한지 하늘만 서너치 보았오` 라고 얘기한 것에서 비롯되었다고도 하고 가마 타고 시집가는 색시가 고개를 넘으면서 지루한 나머지 하인에게\"\"길이 얼마나 남았느냐\"\"고 물을 때마다 하인이\"\"이제 서너치 남았소\"\"라고 대답했다는데서 붙여진 지명이라고 한다. 이 산 자락 아래 양현 마을이 국민휴양지로 개발되면서부터 등산객들이 늘고 있다. 인근의 산 중에서 제법 높은 산이라 정상에서의 조망이 시원스럽다.", + "MNTN_HG_VL" : "833", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면, 가평군 설악면", + "MNTN_NM" : "중미산" }, - "longitude" : 128.39222219999999, - "latitude" : 40.191666699999999 + "longitude" : 127.4716706, + "latitude" : 37.594901399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "중봉은 가지산의 전위봉으로 해발 1168.8m 이며, 영남알프스 내에서도 몇째가는 봉우리다. 산행은 언양을 출발한지 30여 분 석남사 주차장에서 밀양행 버스로 갈아타고, 석남터널을 지나 30여 분 후 삼양교 다리에 내리면, 호박소구룡소폭포 입구이다.안으로 들어서면 제일관광가든이 나오는데 이 건물 뒷편 안내문 간판이 있다. 여기서부터 시작이다. 하산길에는 선녀탕과 성제소를 만날 수 있다. 선녀탕은 특히 겨울에 암반에 걸린 물줄기가 얼어붙어 요란한 고드름이 병풍을 형성하고 그 아래 계곡수는 얼음 밑으로 유유히 흐르고 있다. 성제소는 형제소라 하는데 옛날에 어느 선비 형제가 이곳에서 공부를 하다 형이 빠뜨린 붓 대롱을 건지려다 물속에 빠져 허우적거리는 형을 동생이 구하려다 같이 죽었다는 전설이 있어 형제소라는 지명이 생겨났다.", - "MNTN_HG_VL" : "1169", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산내면", - "MNTN_NM" : "중봉" + "DETAIL_INFO_DTCONT" : "중미산은 경기도 가평군 설악면과 양평군 서종면의 경계에 위치한 산이다. 유명산, 소구니산과 더불어 서너치고개를 사이에 두고 솟아있는 중미산은 그동안 유명산에 가려 빛을 보지 못했으나 중미산자연휴양림이 조성되면서부터 각광 받고 있다.사실 중미산은 서너치고개와 소구니산 등으로 연결되어 있는, 억새숲으로 유명한 유명산과는 달리 별 특징이 없다. 단지 북쪽의 통방산(649m)에서부터 유명산까지 하나의 작은 산줄기를 형성하고 있는 여러 산 중에서 가장 높은 산이어서 정상에 서면 조망이 시원스럽다.중미산은 서너치고개에 오르면 40분 밖에 걸리지 않기 때문에 산행에 변화를 주려면 산 북쪽에 있는 명달리를 기점으로 하거나 삼태봉을 거쳐 통방산에 이르는 능선종주도 해볼 만하다. 일반적으로는 신복3리 양현마을에서 북쪽으로 계곡을 거슬러 올라 안부를 거쳐 정상에 오른 후 서너치고개로 하산하는 것이 무난하다. 요즘에는 자연휴양림이 있는 양평군 옥천면 신복리로 해서 양현마을까지 가서 산행을 시작, 정상을 거쳐 원점회귀하는 산행도 많이 이루어진다.", + "MNTN_HG_VL" : "833", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", + "MNTN_NM" : "중미산" }, - "longitude" : 126.7067349, - "latitude" : 37.625689899999998 + "longitude" : 127.4716706, + "latitude" : 37.594901399999998 }, { "mountain" : { @@ -10096,8 +7856,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", "MNTN_NM" : "중봉" }, - "longitude" : 126.7067349, - "latitude" : 37.625689899999998 + "longitude" : 127.4949902, + "latitude" : 37.9871871 }, { "mountain" : { @@ -10106,8 +7866,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", "MNTN_NM" : "중봉산" }, - "longitude" : 128.9277778, - "latitude" : 37.448611100000001 + "longitude" : 129.16957690000001, + "latitude" : 37.107853800000001 }, { "mountain" : { @@ -10116,8 +7876,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면", "MNTN_NM" : "중수봉" }, - "longitude" : 126.92749999999999, - "latitude" : 37.7575 + "longitude" : 127.34527780000001, + "latitude" : 35.9697222 }, { "mountain" : { @@ -10149,16 +7909,6 @@ "longitude" : 128.96111110000001, "latitude" : 37.333055600000002 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "108", - "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 지곡동", - "MNTN_NM" : "지곡산" - }, - "longitude" : 129.29416670000001, - "latitude" : 36.008611100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "지등산은 충북 충주시 동량면에 위치한 산으로 천등산, 인등산과 함께 3등산의 하나이다. 정상 부근은 뾰족하고 높아 이름과는 어울리지 않는 형세를 하고 있다. 산세가 특별히 아름답거나 비경을 감추고 있지만 않지만 흙으로 된 육산으로 숲이 우거져 있어 나름대로의 매력을 지닌 산이다.그러나 산세가 특별히 내세울 것이 없다보니 사람들의 관심에서 잊혀진 산이었다. 그로인해 사람들의 발길이 뜸하다보니 지등산은 깨끗한 자연환경을 간직할 수 있었고 원시림과 같은 참신한 맛을 느낄 수 있다. 우거진 숲 사이로 불어오는 청량한 바람은 건강에도 많은 도움이 되어 산행의 값을 한층 높여준다. 산 아래에는 충주호와 충주댐이 있다.정상에 서면 북쪽으로 인등산, 남동쪽으로 충주호·계명산이 보이고, 동쪽으로 관모봉(641m)이 능선을 따라 이어져 있다.", @@ -10171,13 +7921,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 청도군 운문면에 자리한 지룡산은 영남 알프스에 속하는 운문산과 바로 인접해 있는 산으로 운문산 운문사의 부속암자들이 배치된 곳이다. 청신암과 내원암, 북대암 등 사찰 규모는 크지 않지만 옛 정취를 느끼고 쉬어가기에는 충분한 공간이며 주변 경관과 더해져 한층 멋스러움을 자아낸다.낮은 산이지만 산행길은 그리 만만치 않다. 곳곳에 칼날 같은 바위능선이 있고 가파른 너덜지대와 폭 넓은 고사목이 산재해 있다. 또한 견훤이 신라 침공 때 축조한 지룡 산성이 있다.산행은 운문사에서 북쪽으로 차도를 따라 나가다 오른쪽 계곡길로 들어서 청신암,내원암을 거쳐 북대암으로 올라가면 정상이 멀지 않다.", - "MNTN_HG_VL" : "659", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면", - "MNTN_NM" : "지룡산" + "DETAIL_INFO_DTCONT" : "행정구역은 통영시지만 삼천포 앞 바다에 떠 있는 사량도에 있는 산으로 다도해 풍정이 물씬나는 한려해상국립공원에 자리잡고 있다. 우리 나라에서 대표적인 지리산과 이름이 같지만 원래 이름은 지이망산이다. 지리산이 바라보이는 산이란 뜻을 가졌다가 부르기 쉽게 줄여 육지의 지리산과 같은 이름으로 쓰이고 있다로 한다.3개의 유인도와 8개의 무인도로 이루어져 있는데, 주섬인 윗섬(상도)과 아랫섬(하도) 사이가 마주보고 그리 멀리 떨어져 있지 않아 호수처럼 잔잔하며, 윗섬의 중앙을 가로지르는 지리산, 불모산, 가마봉, 옥녀봉이 능선으로 연결되어 함께 산행을 할 수 있다. 지리산이나 옥녀봉만을 오를 수도 있고, 지리산부터 옥녀봉까지 종주할 수 있다. 옥녀봉의 암릉은 전설만큼이나 처절하리만치 빼어난 산세를 지니고 있어, 설악산의 용아릉을 연상케 할 만큼 기암괴봉과 경치가 뛰어난 곳이다. 바다와 산을 함께 즐길 수 있는 산행으로 재미를 더해 주지만 암봉, 고암릉으로 이어지는 능선길이 다소 험하다. 그러나 위험코스에는 우회코스가 있으며 등산로가 잘 정비되어 있고 안내표지가 잘되어있다. 초보자는 가급적 우회코스로 산행을 하고 세심한 주의가 필요하다.사량도의 8개 섬 중 상도(上島)에 동서로 길게 뻗은 산줄기 중 돈지리쪽의 제일 높은 봉우리로서, 한려수도의 빼어난 경관과 어우러져 '한반도 남단 최고의 비경'으로 꼽힌다. 산이름은 '지리산이 바라보이는 산'이란 뜻으로, 현지에서는 부르기 쉽게 줄여서 흔히 지리산이라고 한다. 바위산으로서 불모산(佛母山:399m)·가마봉(303m)·향봉(香峰)·옥녀봉(玉女峰:281m) 등과 연봉을 이루고 있어 함께 산행을 할 수 있는데, 높이는 낮아도 정상부의 바위산이 기암괴석을 형성하고 있으며 조망도 좋고 기묘한 바위능선으로 유명하다. 기암절벽과 경치가 뛰어난 옥녀봉에는 자기 딸에게 욕정을 품은 아버지와 그 딸 옥녀의 전설이 전해내려오고 있다. 사량도는 섬이 뱀처럼 생기고, 또 뱀이 많다고 해서 붙여진 이름이다.", + "MNTN_HG_VL" : "398", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면 (사량도)", + "MNTN_NM" : "지리산" }, - "longitude" : 127.3383333, - "latitude" : 34.680555599999998 + "longitude" : 128.18587239999999, + "latitude" : 34.8472443 }, { "mountain" : { @@ -10199,26 +7949,6 @@ "longitude" : 128.78374719999999, "latitude" : 37.290074300000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "773", - "MNTN_LOCPLC_REGION_NM" : "경북 상주시 모동면 신흥리", - "MNTN_NM" : "지장산" - }, - "longitude" : 127.20718170000001, - "latitude" : 38.101389999999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "\"지장산은 경기도 포천군과 연천군의 경계를 이룬다. 주능선에는 울창한 수림과 바위봉이 어우러져 있으며, 특히 더덕, 취나물 등 산나물이 많이 서식하고 있어 때마다 바구니를 들고 찾아오는 사람들의 발길이 끊이지 않는다. 또한 지장산은 계곡미가 뛰어난 곳이다. 숲 터널을 사이로 흐르는 계류가 곳곳에 웅덩이를 이루고 있는 5km에 달하는 지장계곡은 여름철 피서지로 손꼽히는 곳이다.산행은 대중교통을 이용하면 중리초등학교에서 약 4km에 달하는 도로를 걸어가야 하는 불편함이 있다. 승용차나 버스는 중리에서 약 4km 거리인 화전민터까지 접근할 수 있다. 이곳부터 지장산 산행의 묘미를 만끽할 수 있다. 능선까지 1시간정도의 거리는 좌우로 다래나무가 빽빽이 늘어서 있고 능선에서 정상까지는 30분정도 걸린다. 정상에 올라서면 바로 북쪽으로 민간인 통제구역인 금학산(947m)과 고대산(832m)이 우뚝 솟아있고, 동서로는 철원 평야 및 연천일대가 손에 잡힐듯 시야에 들어온다.", - "MNTN_HG_VL" : "877", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 관인면, 연천군 신서면, 강원도 철원군", - "MNTN_NM" : "지장산 (보개산)" - }, - "longitude" : 127.1466479, - "latitude" : 38.156833200000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -10226,8 +7956,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", "MNTN_NM" : "지적산" }, - "longitude" : 126.8896191, - "latitude" : 37.4949309 + "longitude" : 126.41, + "latitude" : 34.828888900000003 }, { "mountain" : { @@ -10286,28 +8016,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 화천", "MNTN_NM" : "창안산" }, - "longitude" : 126.84514729999999, - "latitude" : 37.303596499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "채계산은 여러 이름으로 불리우기도 한다. [동국여지지]에서는 화산(華山)으로, 옥천지에는 차계 산(次戒山)으로 적혀 있고 또 책과 같이 돌이 쌓여 있다하여 책여산(冊如山)이라고도 불리운다. 또한 옛부터 아미산, 광덕산(일명 강천산)과 더불어 순창의 3대명산으로 꼽고 있으며 명산답게 산 과 관련된 전설이 많이 내려오는 곳이기도 하다. 산중턱에 큰 바위가 툭 튀어나와 잇으며 그 바위밑에는 큰 굴이 잇는데 이 굴이 바로 전설에서 전 하는 세칭 금돼지굴이고, 채계산 밑 적성강변에 천재지변에 따라 색깔을 달리하는 거대한 흰바위 가 있는데 높이가 6자가 실히 된데다가 그 형상이 마치 백발노인이 우뚝 서 있는 모습과 같아 사 람들은 이 바위를 ‘화산옹’ 이라 불러오고 있다. 얼핏보면 늙은 사람과 같다 하여 이름도 사람 에 비유하여 ‘화산늙은이’라고 한 것 같다.그런데 이 화산옹은 이상한 능력을 가지고 있다고 전 한다. 그것은 그해 풍년이 들려면 색깔이 희고 아름답게 보이지만 반대로 흉년이 들려면 색깔이 검은색을 띄게 된다. 또 큰불이 난다거나 전염병이 퍼져 인명의 피해가 많은 해는 바위 색깔이 파 란색을 띄게 된다. 그리고 전쟁이 일어나거나 천재지변이 있을 때는 붉은 색깔을 띄게 된다는 전 설이 전해져 내려오고 있다. 읍의 동쪽 약 10km쯤 떨어져 있는 이산은 멀리 장수 팔공산에서부터 뻗어난 줄기가 이산을 이루는 데 정상에서 내려다보면 적성강 물줄기가 보여 그 경치를 더해준다. 산중턱부터 정상부까지 암반 으로 이루어져 있어 그 경치가 빼어나다.", - "MNTN_HG_VL" : "348", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 적성면", - "MNTN_NM" : "채계산" - }, - "longitude" : 127.226091, - "latitude" : 35.401224399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "341", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군", - "MNTN_NM" : "채계산" - }, - "longitude" : 127.226091, - "latitude" : 35.401224399999997 + "longitude" : 127.5457596, + "latitude" : 38.103257200000002 }, { "mountain" : { @@ -10339,26 +8049,6 @@ "longitude" : 127.4425, "latitude" : 37.358333299999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "575", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면, 북후면", - "MNTN_NM" : "천등산" - }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "안동의 진산인 학가산(870m)과 마주보고 있는 천등산은 산세가 부드럽고 풍수지리상 곳곳에 명당이 포진해 있으며 천년 고찰 봉정사(鳳停寺)를 품고 있다.봉정사는 신라 문무와 12년(672년) 의상대사가 명찰을 지을 명당을 찾기 위해 소백산 부석사에서 종이학을 만들어 보냈는데 그 학이 지금의 안동 제 1의 명찰인 봉정사에 떨어졌다고 한다. 이 사찰 극락전에서 발견된 상량문에 의하면, 의상대사의 제자인 능인대덕이 창건한 이래 조선시대까지 여러 차례 중수한 기록이 있어 국내에서 가장 오래된 목조 건물로 확인됐다. 이밖에도 조선시대의 대웅전을 비롯해 고금당, 화엄강당 등은 우리나라 건축연구에 중요한 자료가 된다.", - "MNTN_HG_VL" : "707", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면", - "MNTN_NM" : "천등산" - }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "고흥반도 최남단에 솟아 있는 천등산은 겉에서 보면 그냥 커다란 바위산 같지만 오르면서 보면 암릉들이 골고루 세밀하게 나뉜 것이 산행의 재미를 더해준다. 능선에는 상여바위, 암릉지대, 염소바위, 뭉치바위 등이 있고, 능선 곳곳에는 억새 밭이 장관을 이루고 정상 서편 천동마을 위쪽에는 철꾹동산이 잘 조성되어 있다.정상에는 조선조 때의 봉수대 축성이 흐트러져 있고 기우단으로서도 유명한 곳이며, 고흥 반도에서 팔영산에 이어 두 번째로 높은 산이라 남해의 조망이 특히 뛰어나다.정상 동쪽 금사에는 전남 유형 문화재로 지정된 고찰 금탑사의 극락전이 있다. 이 극락전은 삼국시대에 창건된 후로 여러 번 중수되었으나, 조선시대 말기적인 건축 모습을 잘 보여주는 건물로 알려 있다. 절 주변에는 천연기념물 제 2399호로 지정된 비자나무 숲이 유명하고, 이 나무는 신라 선덕여왕 6년에 처음 심어진 것이라 전해오고 있으며 동백나무 거목 군락지도 있다.", @@ -10366,8 +8056,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 풍양면, 포두면, 도화면", "MNTN_NM" : "천등산" }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 + "longitude" : 127.2780763, + "latitude" : 34.541848000000002 }, { "mountain" : { @@ -10376,8 +8066,8 @@ "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 풍양면, 도화면, 포두면", "MNTN_NM" : "천등산" }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 + "longitude" : 127.2780763, + "latitude" : 34.541848000000002 }, { "mountain" : { @@ -10386,8 +8076,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 운주면", "MNTN_NM" : "천등산" }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 + "longitude" : 127.3088889, + "latitude" : 36.085555599999999 }, { "mountain" : { @@ -10409,76 +8099,6 @@ "longitude" : 127.272778, "latitude" : 37.680556000000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "170", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 인천", - "MNTN_NM" : "천마산" - }, - "longitude" : 127.272778, - "latitude" : 37.680556000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "문경시 동로면에서 내려오는 금천이 산북면 산양면을 지나고 영순면에 와서 예천군에서 내려오는 내성천과 합쳐지고 다시 내성천이 낙동강과 합해지면서 영순면 달지리 삼강이 된다. 이곳에서 낙동강변을 따라 영순면이 있으며, 문경시의 젖줄기인 영강이 낙동강과 다시 만나는 곳 영순면 말응리 영풍교반까지 문경시의 제일 남쪽을 막고 있는 산이 천마산이다. 이 산이 영순면 달지리에서 영순면 이목리와 말응리까지 이어져 있어 낮지만 낙동강을 바라보며 지키고 있는 산이다.옛날 낙동강이 주요물품의 이동통로였을 당시에는 이 천마산 기슭 나룻가에 많은 배들이 드나들었다고 하며 아직도 금포 백포라는 이름이 불리어지고 있다. 그리고 옛날 산에 평령암(平岺庵)이 있다고 하나 지금은 없고 해장골에 해장사(海張寺)라는 작은 암자가 있다.천마산의 산행은 무엇보다도 낙동강을 굽어보는 모습이 아주 좋다. 귀파재에서 오르는 길 외에는 잡목과 덤불로 덮여 있다.", - "MNTN_HG_VL" : "278", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 영순면 이목리", - "MNTN_NM" : "천마산" - }, - "longitude" : 127.272778, - "latitude" : 37.680556000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "천마산은 내와리와 복안리에 걸쳐 있는 산으로 천(天)은 높음을 뜻하고 마(馬)는 뫼(山)을 뜻하니 결국은 높은 산이라는 뜻을 지닌 해발 610.5m의 산이다. 산행을 하려면 언양에서 봉계행 버스(30분 간격)로 25분 후 미호에 하차한다. 고속도로 굴다리를 지나 30여 분 농로길을 따르면 두서 초등학교가 나오는데 상동(마리골)이다.상동상회에서 오른쪽 아스팔트 길을 따라 오르면 고개 언덕에 올라선다. 음지 마을로 내려서는 오작골이며 그 아래 오작골못이 보이고 언덕 밑에는 큰 노송이 버티고 있다. 본격적인 산행은 고개를 넘어서면서 시작된다. 정상에서는 주변 시야를 볼 수 없다.", - "MNTN_HG_VL" : "611", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울주군 두서면 내화리", - "MNTN_NM" : "천마산" - }, - "longitude" : 127.272778, - "latitude" : 37.680556000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "324", - "MNTN_LOCPLC_REGION_NM" : "충청남도 서천군 판교면, 문산면", - "MNTN_NM" : "천방산" - }, - "longitude" : 127.1466667, - "latitude" : 34.714444399999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "충청남도 서천", - "MNTN_NM" : "천방산" - }, - "longitude" : 127.1466667, - "latitude" : 34.714444399999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "485", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군", - "MNTN_NM" : "천방산" - }, - "longitude" : 127.1466667, - "latitude" : 34.714444399999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "의정부과 동두천 중간쯤에 양주시 덕정리 철로변 마을에서 동쪽으로 나 있는 길을 따라가다 보면 남북으로 뻗은 산줄기가 보인다. 양주와 포천 땅을 가르는 산줄기인데 이 산줄기의 중앙부에 우뚝 솟은 산이 천보산이다. 연이은 바위봉과 소나무 군락이 어울려 산 전체가 수려한 경치를 뽐내고 있다. 능선은 바위봉우리로 되어 있고 소나무 군락이 많다.산자락에는 고려 때 3대 사찰이었던 회암사지(사적 128)와 회암사지선각왕사비(보물 387), 회암사지부도(보물 88), 회암사지쌍사자석등(보물 389) 등이 있고, 회암사지 왼편길을 오르면 1828년(순조 28)에 창건한 회암사가 있다. 주변에 불곡산·백화암·장흥국민관광지·권율장군묘 등이 있다. 정상에서는 북쪽으로 소요산이 손에 잡힐 듯 가까이 보이고 남쪽으로는 천길 절벽을 이루고 있다", - "MNTN_HG_VL" : "337", - "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 회천읍", - "MNTN_NM" : "천보산" - }, - "longitude" : 127.0667052, - "latitude" : 37.763901099999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "천봉산은 상주 삼악의 하나인 석악으로 상주의 명산이다. 천년에 한 번 봉황이 나타난다고 해서 천봉산(千峰山)이라는 설과 정상에 서면 주변의 천개의 산봉우리를 볼 수 있다고 하여 천봉산(千峰山)이라는 주장하는 사람도 있다. 산경표는 천봉산(天峰山)으로 표기되어 있다.천봉산에는 일찍부터 민속 문화가 발생하여, 성황사를 비롯해 산신제단이 현재도 남아 있고, 암석 신앙에서 비롯된 영암각이 있다. 성황사는 만민이 평안하고 풍요하며 신공으로 우순풍조하여 풍년이 들 것을 기원하던 자리다. 조선 후기까지도 고지기를 두어 지키게 하고 매년 제사를 지냈다 한다. 한마디로 천봉산은 민속 문화의 보고라 일컬을 만하다.정상은 황악산, 속리산, 주흘산 그리고 굽이쳐 흐르는 낙동강 등 산이 낮으면서도 주변 경치를 한 눈에 볼 수 있는 천연전망대다.최근 신년 일출산행지로 각광받고 있다.", @@ -10496,18 +8116,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군 문덕면", "MNTN_NM" : "천봉산" }, - "longitude" : 128.1429444, - "latitude" : 36.442608999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "천비산은 만인산에서 산줄기가 북서쪽으로 달리다 어남산(464.5m)을 거쳐 유등천에서 떨어지기 직전에 정생동에서 힘을 모아 솟구친 산이다.천비산의 정기를 이어온 이 산 언저리는 옛날부더 오늘에 이르기까지 민족사의 중요한 역할을 담당해 온 한편, 민족정기를 크게 불러 일으킨 곳이다.", - "MNTN_HG_VL" : "466", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 중구 침산동, 서구 정생동", - "MNTN_NM" : "천비산" - }, - "longitude" : 127.3910219, - "latitude" : 36.2360647 + "longitude" : 127.1333333, + "latitude" : 34.946666700000002 }, { "mountain" : { @@ -10556,8 +8166,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", "MNTN_NM" : "천왕산" }, - "longitude" : 128.28416669999999, - "latitude" : 34.990833299999998 + "longitude" : 128.59414770000001, + "latitude" : 35.5852754 }, { "mountain" : { @@ -10566,28 +8176,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", "MNTN_NM" : "천왕산" }, - "longitude" : 128.28416669999999, - "latitude" : 34.990833299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "156", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 수성구 고산동", - "MNTN_NM" : "천을산" - }, - "longitude" : 128.70492100000001, - "latitude" : 35.845638899999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "시루봉(웅산)줄기가 남으로 뻗어 이룬 줄기에 있는 천자봉은 기반암이 노출하는 큰 암괴로 되어 있으며 성채처럼 보인다. 산록은 가파르고 곳에 따라 산정과 산능에서 떨어져 나온 자갈들이 즐비하여 산 전체가 돌산처럼 보이기도 한다.웅장한 산세 때문에 조선 태조(이성계), 명나라 태조(주원장), 주(朱)씨, 이(李)씨, 천자(天子) 등과 관련된 전설이 여럿 전한다.옛날 천자봉 연못의 이무기가 용이 못 되자 마을 사람을 못살게 굴었다. 이에 염라대왕이 이무기에게 용대신 천자가 되라고 권하여 연못 아래 백일마을의 주(朱)씨 가문 아기로 태어났다. 이 아기가 뒷날 중국으로 건너가 명나라 태조인 주원장이 되었다고 한다. 다른 전설도 전한다. 함경도 사람 이씨가 하인인 주씨를 데리고 명당을 찾으러 천자봉에 올랐더니 바다에서 반인반어(半人半漁)의 괴물이 나타나 바닷속에 굴이 둘 있는데 오른쪽 굴이 천자가 태어날 명당이라고 점지해 주었다. 하인 주씨가 욕심이 나서 자기 선친은 오른쪽에 묻고 주인 이씨의 유골은 왼쪽에 묻었다. 그래서 주씨 가문에서는 명나라 태조 주원장이 태어났고, 이씨 가문에서는 조선 태조 이성계가 태어났다고 한다.천자봉 정상에서 바라다 보이는 남해바다의 크고 작은 섬들이 이뤄내는 한 폭의 수채화 같은 정취를 자아내게 하는 조망은 가히 절경이다.", - "MNTN_HG_VL" : "502", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진해시 자은동, 웅천 1동", - "MNTN_NM" : "천자봉" - }, - "longitude" : 128.72499999999999, - "latitude" : 35.126666700000001 + "longitude" : 128.59414770000001, + "latitude" : 35.5852754 }, { "mountain" : { @@ -10596,8 +8186,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 전주시 상림동", "MNTN_NM" : "천장봉" }, - "longitude" : 127.8280278, - "latitude" : 36.755976400000002 + "longitude" : 127.0819444, + "latitude" : 35.808333300000001 }, { "mountain" : { @@ -10606,8 +8196,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", "MNTN_NM" : "천재산" }, - "longitude" : 128.91524039999999, - "latitude" : 37.095739199999997 + "longitude" : 127.7422222, + "latitude" : 34.763611099999999 }, { "mountain" : { @@ -10619,16 +8209,6 @@ "longitude" : 128.59073989999999, "latitude" : 35.271812500000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산 남동쪽의 산행 출발점으로는 간송1리인 천주마을과 천주에서 975번 도로를 따라 북쪽으로 약 1km 더 올라가면 만나는 천주사 입구가 있다. 산의 북쪽에서는 동로면 소재지에서 노래이(동로면 노은1리 지형도에는 노루이라고 표기됨)로 접근한 다음 산행을 시작할 수 있다. 다만 어느 코스로 오르든 암벽지대를 오르게 되므로 주의를 요한다. 천주마을에서 산행을 시작하려면 이 마을 포장도로길을 따라 올라가면\"천산정\"이 나오는데 이곳에서 물을 준비해야 한다.계곡을 따라 20분 정도 오르면 능선으로 이어진 길이 나타나는데 이 능선길로 접어들면 된다. 능선길을 따라 40분정도 오르면 큼직한 돌로 형성된 너덜지대를 지나게 되고 이곳에서는 천주마을과 지나온 길을 모두 돌아볼 수 있어 전망이 좋다이 너덜지대를 지나면 절벽이 나타나서 길이 없어진 것처럼 보인다. 하지만 오른쪽으로 자세히 찾아보면 절벽사이로 난 길을 발견할 수 있다. 이곳을 지나 조금 더 오르면 정상이 보이고 다시 오른쪽으로 틀면 노송이 한 그루 나타난다.소요 시간 : 2시간최적 탐방 시기 : 4~10월 \/ 봄, 여름, 가을볼거리 : 경천호 경천댐,큰봉 정상에 서면 운달산, 대미산, 문수봉, 황장산이 한눈에 보여 백두대간의 웅장함을 실감할 수 있다.숲길 명소 : 돌탑, 암벽", - "MNTN_HG_VL" : "836", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면 노은리", - "MNTN_NM" : "천주산" - }, - "longitude" : 128.59073989999999, - "latitude" : 35.271812500000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강원도 원주시 소초면과 횡성군 안흥면의 경계를 이루는 천지봉은 치악산과 매화산 중간에 우뚝 솟은 봉으로 치악산 정상인 비로봉의 유명도에 밀려 아직도 깨끗함을 간직하고 있다.남쪽 능선길은 부드럽고 많은 산악인으로 붐비는 구간인 반면, 북쪽 천지봉으로 이어지는 능선은 굴곡이 심하고 전망 좋은 암봉이 곳곳에 있으며 섬뜩한 기운이 감돌기조차 하는 한적한 산길이라 대조적이다.영말골과 세렴골계곡은 울창한 수림이 하늘을 가리고 군데군데의 폭포와 옥 같은 계류가 어우러져 매우 아름답고 산길은 원시림을 방불케 해서 더욱 좋다. 정상에는 삼각점이 있고 밋밋하기는 하나 비로봉,백덕산,매화산,삼봉 등 사방을 바라보는 전망이 일품이다.", @@ -10636,18 +8216,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면, 횡성군 안흥면", "MNTN_NM" : "천지봉" }, - "longitude" : 127.2261958, - "latitude" : 36.2128242 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "천제봉은 용암산 아래 제전마을 위에 있으며 천제봉이 있는 무수등에는 지형이 소의 등처럼 생겼다 하여 무소등에서 유래됐다.가뭄이 들 때면 이곳 바위에서 상녀들이 춤을 추며 기우제를 지냈다. 이곳에서 기우제를 지내는 이유는 비를 내리게 하는 용이 북쪽 용암산에 숨어 있다고 믿었기 때문이다. 무수등에서 천제봉으로 가는 길은 바위로 구성되어 아슬아슬한 암벽을 타고 내려야 한다.", - "MNTN_HG_VL" : "685", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면", - "MNTN_NM" : "천지봉(천제봉)" - }, - "longitude" : 128.72499999999999, - "latitude" : 35.126666700000001 + "longitude" : 128.09777779999999, + "latitude" : 37.405833299999998 }, { "mountain" : { @@ -10659,26 +8229,6 @@ "longitude" : 127.6135306, "latitude" : 36.157161500000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "392", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시", - "MNTN_NM" : "천태산" - }, - "longitude" : 127.6135306, - "latitude" : 36.157161500000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "천태산은 천성산, 영축산과 함께 양산의 3대 명산으로 예부터 경치가 빼어나기로 유명할뿐 아니라 남서쪽으로 낙동강, 북서쪽으로 삼랑진 양수발전소댐, 그리고 동북쪽으로 여름철 피서지로 유명한 배내골이 연계되어 부산, 울산, 마산 등에서 산행지로 유명세를 떨치고 있다.특히 정상에서 바라본 낙동강의 낙조는 탄성을 자아내도 모자랄 만큼 아름답고 신비하다.남쪽에 위치한 천태각(천태정사)에서 용연폭포에 이르는 30여리의 긴 계곡은 태고의 신비를 그대로 간직한 맑고 깨끗한 자연경관을 자랑하고 있다.또 하나 볼거리로 산 정상 이르기 전에 조그마한 암자가 있는데 그곳을 따라 골짜기를 오르면 기암절벽을 이룬 절경을 만날 수 있으며 정상에 오르면 넓은 바위가 평지처럼 놓여있어 마치 하늘 밑 구름에 떠 있는 느낌을 받는다. 물소리를 들으며 주위경관에 취해 산행을 하다보면 도원경(桃源境)에서 신선들과 장기나 바둑을 두면서 현세의 시름을 잊을 것 같은 착각에 빠져들기도 한다.임진왜란 때 박진 밀양부사가 작원관을 최후의 교두보로 하고 왜적에 대항했으나 이기지 못하고 눈물을 머금고 후퇴했던 곳이다. 이곳은 관(국경이나 중요한 지역에 두어 지나는 사람과 물건 등을 조사하게 하던곳)이기 때문에 서울로 가는 행객들이 여기서 검문을 받기도 하고 쉬어가는 곳이기도 했다.", - "MNTN_HG_VL" : "631", - "MNTN_LOCPLC_REGION_NM" : "경남 양산시 원동면", - "MNTN_NM" : "천태산" - }, - "longitude" : 127.6135306, - "latitude" : 36.157161500000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -10686,18 +8236,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 강진", "MNTN_NM" : "천태산" }, - "longitude" : 127.6135306, - "latitude" : 36.157161500000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "천택산(川擇山)은 화남 임곡에 솟아있는 육산으로 이 산 밑에는 지금도 우복길지의 비결을 믿고 사는 사람들이 있다. 조선 후기의 술사 이량박이 임실 즉 임곡 안골을 우복동(牛腹洞)이라 칭하였기 때문이다. 일대에는 우복동과 관련된 태조산, 대모산, 용굴, 시루봉, 적(赤)바위 등이 있다. 태조산은 안골에서 보는 구병산을 가리킨다. 남자의 얼굴 모양이라는 것이다. 안골 바로 앞산은 또 여인이 누워있는 형상이라며 대모산(大母山)이라고 부른다. 적바위는 대모산에 있는데 임곡리 옆동네 이름 적암리가 여기서 유래했다. 시루봉은 적암리의 25번 국도변에 있다.또한 일대는 석회암지대로 석회를 채굴하고 있으며 석탄을 캔 흔적도 남아 있는 특이한 지형이다. 동학농민운동 때 지도부의 은신처로 사용되던 석회암 동굴인 용굴이 있다. 정상에서는 봉황산에서 국수봉으로 이어지는 백두대간과 구병산·팔음산·백화산이 보인다. 하산은 올라왔던 길로 되돌아 내려간다.", - "MNTN_HG_VL" : "683", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화남면 임곡리, 화서면 사산리", - "MNTN_NM" : "천택산" - }, - "longitude" : 139.76481200000001, - "latitude" : 35.708142000000002 + "longitude" : 126.91666669999999, + "latitude" : 34.899999999999999 }, { "mountain" : { @@ -10706,18 +8246,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", "MNTN_NM" : "천호봉" }, - "longitude" : 126.79073750000001, - "latitude" : 37.445665300000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만행산 천황봉은 백두대간 장수 영취산에서 금남호남정맥으로 분기되어 남서쪽으로 뻗어가다가, 팔공산을 솟구쳐 놓았다. 이곳에서 섬진 2지맥으로 갈리어, 묘목산(846m), 상서산(627.4), 만행산, 약산, 묘적봉(567.7m), 풍악산(620m), 응봉(579m), 주생터널, 문덕봉(598.1m), 삿갓봉(629.1), 고리봉(708m), 상귀티 730번 도로, 섬진강까지 이어지는 산줄기의 중간지점의 만행산 줄기 가운데서 우뚝 솟아 오른 봉우리이다.천황봉은 유난히 뾰족하게 우뚝 솟은 삼각봉이어서 지리산같은 큰산에서 작은 산을 찾기는 어렵지만, 이 산은 매우 특이해서 많은 산 가운데서 쉽게 눈에 띈다.", - "MNTN_HG_VL" : "910", - "MNTN_LOCPLC_REGION_NM" : "전북 남원시", - "MNTN_NM" : "천황봉" - }, - "longitude" : 127.20583329999999, - "latitude" : 36.342500000000001 + "longitude" : 127.2411111, + "latitude" : 36.204166700000002 }, { "mountain" : { @@ -10736,8 +8266,8 @@ "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면", "MNTN_NM" : "철마산" }, - "longitude" : 127.24682780000001, - "latitude" : 37.720437500000003 + "longitude" : 129.13749999999999, + "latitude" : 35.310000000000002 }, { "mountain" : { @@ -10746,28 +8276,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", "MNTN_NM" : "철마산" }, - "longitude" : 127.24682780000001, - "latitude" : 37.720437500000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "첨찰산은 등산로 주변에 인공보조물이 전무해 태고적 자연미가 그대로 살아 있다. 또한 산길이 천연기념물 107호로 지정된 상록수림 터널로 이어지고 있어 신선미가 넘친다. 상록수림에는 동백, 후박, 참가시, 감탕, 종가시, 생달, 모새, 참식, 차, 자금우, 광나무, 붉가시나무, 메밀잣밤 등 상록성을 띈 나무는 물론, 졸참, 자귀, 느릅, 말오줌때, 쥐똥, 실거리, 조록, 소사나무 등 50여종에 달하는 낙엽성을 띄고 있는 나무들이 섞여 쌍계사 주변에 숲을 이루고 있다.이런 다양한 수림 덕분에 사계절 산과일을 맛보며 산행을 즐길 수 있다. 봄에는 보리똥, 꼬지딸, 보리딸을, 여름에는 먹딸, 수릿딸, 박딸(산딸), 신금열매가 있고 가을에는 넝쿨식물인 산능금, 으름, 잣밤, 윤노리, 산감, 돌배, 머루, 다래, 갈매나무 열매 등이 군침을 돌게 한다.첨찰산 산행을 하며 쌍계사를 둘러보지 않을 수 없다. 신라 때 도선국사가 창건한 이 사찰은 사찰 양편으로 하천이 흐른다 하여 절 이름이 쌍계사로 지어졌다. 건립 연대는 숙종 23년 (1697년)으로 약 1미터 높이의 자연석 기단에 주춧돌을 놓고 그 위에 원주를 세운 대웅전이 볼만하다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "전남 진도군 고군면ㆍ의신면", - "MNTN_NM" : "첨찰산" - }, - "longitude" : 126.304923, - "latitude" : 34.465848000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "첩푸산은 시어골을 가운데에 두고 대미산과 마주서서 두상에서 풍부하게 흘러내리는 물줄기로 중산저수지를 만들어 놓았다. 첩푸산은 옛날 이 산자락에 금광이 있었다는 데서 적보산이라 불렀고, 아홉 개의 지능선이 마치 머리빗같은 형상으로 뻗어내린 데서 구봉산이라 불렀는데 옛날 어느 마을에 마음씨 착한 총각이 살았다. 그가 아름다운 처녀와 결혼해 가정을 꾸렸는데 그녀가 색을 지나치게 탐하는 바람에 남편은 견딜 수가 없었다. 그래 궁리 끝에 이 산으로 도망해 와 숨어 살았고 그 후 이 산을 첩푸산이라 부르기 시작했다고 한다.남쪽자락 상모면 소재지에 수안보 온천이 자리잡고 있어 산오름한 뒤 온천욕을 즐길 수 있다.", - "MNTN_HG_VL" : "699", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 상모면 중산리, 온천리", - "MNTN_NM" : "첩푸산" - }, - "longitude" : 127.986448, - "latitude" : 36.844752000000007 + "longitude" : 128.69147169999999, + "latitude" : 35.593220600000002 }, { "mountain" : { @@ -10776,8 +8286,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", "MNTN_NM" : "청계산" }, - "longitude" : 127.0415787, - "latitude" : 37.414165699999998 + "longitude" : 127.3701707, + "latitude" : 37.933052600000003 }, { "mountain" : { @@ -10796,18 +8306,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 양평 서종면, 양서면", "MNTN_NM" : "청계산" }, - "longitude" : 127.0415787, - "latitude" : 37.414165699999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산이 두리뭉실하다고 하여 두루봉이라고 했던가. 유래는 알 수 없지만 인근 마을에서 두루봉이라고 부른다. 대궐터산이라고 부르는 사람들도 있는데 이는 후백제를 건국한 견훤이 이 산에 성을 쌓고 대궐을 지었다고 청계마을 사람들이 말하는 것을 보고 누군가가 대궐터산이라는 이름을 붙인 것으로 추측된다.그러나 상주의 역사책 상산지에 이 산이 청계산(淸溪山)이라고 나와 있으니 청계산 두루봉이라고 부르는 것이 맞다. 대궐터산 명칭을 꼭 붙이려면 극락정사 뒤 삼각점이 있는 곳에만 한정해야 한다.", - "MNTN_HG_VL" : "658", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화서면 화송리, 화남면 동관리", - "MNTN_NM" : "청계산" - }, - "longitude" : 127.0415787, - "latitude" : 37.414165699999998 + "longitude" : 127.4027778, + "latitude" : 37.553611099999998 }, { "mountain" : { @@ -10846,28 +8346,58 @@ "MNTN_LOCPLC_REGION_NM" : "인천광역시 인천", "MNTN_NM" : "청량산" }, - "longitude" : 128.90838890000001, - "latitude" : 36.7964974 + "longitude" : 126.67919689999999, + "latitude" : 37.431407100000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "796", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "청룡산" + "MNTN_HG_VL" : "155", + "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", + "MNTN_NM" : "청명산" + }, + "longitude" : 126.7261111, + "latitude" : 37.175555600000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가리왕산에서 뻗어 내려간 주능선이 서쪽으로 중왕산을 일으키고 여기서 남쪽으로 다리를 놓은 듯 가로질러 내려가는 능선 끝에 일으킨 산이 바로 청옥산이다, 산세는 가리왕산과 흡사한 점이 있고, 중후한 육산의 형태를 띠고 있다.청옥산은 '곤드레' 나물과 더불어 '청옥' 이란 산채가 많이 자생하여 이름 붙여진 산이다. 능선이 비교적 평탄한 지형으로 그 면적이 볍씨 6백두락이나 된다는 뜻에서 지어진 '육백마지기'가 산 정상에 위치하고 있으며 고랭지 채소를 주로 재배하고 있다.산행은 백일동에서 동남계곡을 따라 밸패재에 올라 남쪽 능선으로 정상에 올랐다가 서쪽 능선을 따라 삿갓봉(1,055m)으로 이어지는 능선 중간에서 지동리를 지나 창선탄광 입구 고길리로 하산할 수 있다.", + "MNTN_HG_VL" : "1256", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "청옥산" + }, + "longitude" : 128.50805560000001, + "latitude" : 37.410277800000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "청옥산은 백두대간이 금강산, 설악산, 오대산 등을 빚으며 동해안을 따라 남동쪽으로 내려가다가 동해지방 해안가에 이르러 솟아 오른 명산이다. 두타산과 함께 사방에 드리운 능선과 고개를 끼고 있으며, 짙푸른 동해를 손아래로 굽어 보고 있다. 이 산은 여러 등산로와 유적지가 있어 아름다운 절경을 감상하는 등산객의 발길이 끊이지 않는 곳이기도 하다. 두타산과의 거리는 약4km정도여서 일찍 서두른다면 두타산과 청옥산을 함께 오를수도 있다. 청옥산과 두타산 산아래 펼쳐진 국민관광지 1호 무릉계곡은 100여명을 수용할 수 있는 무릉반석과 학소대, 선녀탕 그리고 계곡 양편에 깎아지른 듯한 병풍바위 등 웅장한 절경을 안고 있다.두타산 북릉에는 두타산성이 있고, 바위가 좋아서 오르기엔 안성마춤인 코스이다. 상대적으로 두타산에서 청옥산에 이르는 코스는 부드럽고 완만하여 하산로로 이용하는것이 좋다. 청옥산까지 종주한후 연칠성령이나 학등을 이용하여 하산할경우 거리도 약 20km나 되고 소요시간도 대략 9시간정도가 소요될걸로 생각된다. 산이 워낙 크고 깊기때문에 눈이나 비가 많이 올때는 삼가하는편이 좋다.", + "MNTN_HG_VL" : "1403", + "MNTN_LOCPLC_REGION_NM" : "강원도 동해시 삼화동, 삼척시 정선군", + "MNTN_NM" : "청옥산" + }, + "longitude" : 128.9735857, + "latitude" : 37.433949400000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "태백산 망경대 정상에서 남동편에 위치한 산이다. 소천면 늦재에서 능선 따라 망경대로 이어지는 등산로가 있다. 이 산에는 세계최남단의 열목어 서식으로 유명한 백천계곡이 있고, 산 기슭 중턱에는 사명대사가 수도했다는 홍제사가 있다.태백산을 중심으로 이 산을 비롯해 일대에 1,000m가 넘는 산들만도 9개 봉이나 되어 심산유곡의 자연미를 만끽할 수 있다. 백두대간 갓대배기봉에서 동남으로 갈래친 능선 위에 있고, 소천면 늦재에서 능선을 따라 망경대로 이어지는 등산로가 있다.일대 1억 53만㎡가 청옥산 자연휴양림으로 지정되었는데, 한국의 휴양림 가운데 가장 넓고 물놀이장, 체력단련장, 산막, 야영장, 캠프파이어장 등의 편의시설이 완비되어 있다. 산기슭 중턱에는 유정(惟政)이 수도했다는 홍제사가 있고 산 옆으로 흐르는 고선계곡은 길이 100리에 이르는 깊은 원시림계곡을 이룬다.태백산 문수봉과 청옥산 사이에서 시작되어 조록바위봉까지 이르는 12㎞의 백천계곡은 낙동강의 상류이며 세계 최남단의 열목어(천연기념물 74) 서식지로 유명하다. 일대는 천연기념물 및 천연림 보호지역이므로 출입을 제한한다.그밖에 주변에는 5만 영령위로탑이 세워져 있는 현불사와 오전약수, 우곡약수터, 불영사, 다덕약수관광지, 두내약수관광지, 청량산 도립공원, 사미정(四未亭) 등의 관광지가 있다. 또한 겨울철에는 적설량이 많아 늦은 봄까지 눈을 볼 수 있고, 임도가 넓어 산악스키를 즐기기에 적당하다.", + "MNTN_HG_VL" : "1256", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 석포면, 소천면", + "MNTN_NM" : "청옥산" }, - "longitude" : 126.9470587, - "latitude" : 37.474794199999998 + "longitude" : 128.96222220000001, + "latitude" : 37.0433333 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "155", - "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", - "MNTN_NM" : "청명산" + "MNTN_HG_VL" : "1277", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 석포면, 소천면", + "MNTN_NM" : "청옥산" }, - "longitude" : 127.08305559999999, - "latitude" : 37.258888900000002 + "longitude" : 128.96222220000001, + "latitude" : 37.0433333 }, { "mountain" : { @@ -10879,16 +8409,6 @@ "longitude" : 127.4138889, "latitude" : 37.780833299999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "둔내면 두원리에 위치한 청태산은 두원리와 평창군 방림면 계촌리의 경계를 이루고 있으며, 영동고속도로가 태기산을 잇는 능선을 가로 지르고 있다. 산마루에는 잣나무, 소나무, 참나무, 싸리나무 등 각종 수목이 울창할 뿐 아니라 도라지, 더덕, 삽주삭 등 많은 약초가 자생하고 있다.91년 산림청에서 조성한 청태산 자연 휴양림은 영동 고속도로에 위치해 교통편이 좋으며 삼림욕장, 산책로, 야영장, 전망대, 산막, 잔디 광장, 주차장, 자연관찰원 등 각종 편의 시설과 체육시설이 구비되어 있어 하계 수련대회장으로 활용하기에 적합하다. 또한 겨울철에는 춥고 눈이 많이 오는 곳이다. 특히 둔내 일대의 산야가 온통 하얗게 뒤덮인 풍경은 한 폭의 동양화가 같다. 겨울 등산 장비를 갖추었다면 청태산 정상에 오르는 것도 좋다.", - "MNTN_HG_VL" : "1200", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 둔내면, 평창군 봉평면, 방림면", - "MNTN_NM" : "청태산" - }, - "longitude" : 128.30148149999999, - "latitude" : 37.511260399999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "백두대간 마루금상의 청화산(984m)은 정상은 경상북도 상주와 문경시, 충청북도의 괴산군과 경계를 이루고 있다. 북쪽 대야산에서 남진하여 조항산을 지나온 백두대간이 청화산에 이르면 방향을 남서쪽으로 틀어 눌재로 떨어진 다음 속리산으로 이어져 나간다.lt;택리지gt;에서 이중환은 “청화산은 뒤에 내외의 선유동을 두고 앞에는 용유동에 임해 있어 경치가 지극히 좋음은 속리산보다 낫다”고 표현할 만큼 이름다운 산이다. 육산의 웅장함과 바위산의 아기자기한 맛을 함께 맛볼 수 있을 뿐만 아니라 백악산, 군자산 등 속리산국립공원 일원의 산봉들을 조망할 수 있다. 청화산 오름길은 크게 세 코스다. 오래전부터 많이 이용돼온 입석1리나 심송2리에서 송면지~갓바위재를 경유하는 코스와 사계절 인기 있는 백두대간상의 눌재 기점, 그리고 쌍룡계곡 병천에서 화산마을로 들어가 정상 접근이 가장 ª은 원적사를 경유하는 코스가 있다.", @@ -10916,8 +8436,18 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 도개면 다곡리", "MNTN_NM" : "청화산" }, - "longitude" : 127.91937729999999, - "latitude" : 36.624444099999998 + "longitude" : 128.4005908, + "latitude" : 36.289798699999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "636", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "초례봉" + }, + "longitude" : 128.75, + "latitude" : 35.899999999999999 }, { "mountain" : { @@ -10929,16 +8459,6 @@ "longitude" : 129.0714347, "latitude" : 37.522134999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "152", - "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", - "MNTN_NM" : "초록산" - }, - "longitude" : 126.956596, - "latitude" : 37.092230999999998 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "전남 보성은 차 다음으로 철쭉이 유명한 고장이다. 이에 제암산과 일림산은 5월이면 사람들이 줄 지어 찾아 오른다. 반면 같은 보성임에도 불구하고 여유롭게 철쭉을 즐길 수 있는 산이 있으니 바로 겸백면에 위치한 초암산이다.제암산, 일림산이 산 정상에 오르면 푸른 바다와 어우러진 철쭉을 볼 수 있다는 장점이 있는 반면 초암산은 철쭉 하나로 승부한다. 단출하게 느껴지지만 그만큼 색이 분산되지 않는 단정한 미학이 살아 있는 산이다. 또한 초암산은 철쭉이라는 핵심만을 즐기고 내려올 수도 있다는 간편함이 두드러진다. 최근 너무 힘든 산행보다는 간편하게 즐기면서 오를 수 있는 산을 찾는 사람들이 증가한 만큼 초암산은 앞으로 많은 사람들이 찾기에 매력적이다. 북쪽 임도를 이용해 철쭉밭 바로 아래까지 차량으로 올라간 다음 정상 철쭉밭을 구경한 후 되내려오는 거의 관광에 가까운 탐방이 가능하다.너무 간단하게 느껴진다면 호남정맥 일부를 이루고 있는 광대코재~주월산~방장산~오도재 능선을 포함한 원점회귀형의 사뭇 긴 당일산행 코스를 잡을 수도 있다. 겸백면은 이 원점회귀형 등산로의 출발지인 수암리에 널쩍한 주차장도 새로 만들었다.더불어 보성군은 ‘녹차와 철쭉이 어우러진 보성’이라는 모토로 작년부터는 초암산에서도 철쭉제를 열고 있다.", @@ -10956,18 +8476,8 @@ "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면·강원도 춘천시 사북면", "MNTN_NM" : "촉대봉" }, - "longitude" : 127.7001509, - "latitude" : 35.314562500000008 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "촛대봉도 대야산에서 불란치재 사이 백두대간에 있으며 1\/5,000 지도에는 높이가 671.2m로 표시되어 있다.산행은 대야산 돌마당 식당을 지나 20분 정도 올라가면 용추가 나오는데 용추의 오른쪽 능선을 타면 촛대봉으로 바로 오를 수 있고 정상에서 대야산이나 불란치재로 내려갈 수 있다. 정상에 무덤이 있다. 능선길은 소나무와 바위가 잘 조화되어 있는 아름다운 산이다.", - "MNTN_HG_VL" : "661", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 화산리", - "MNTN_NM" : "촛대봉" - }, - "longitude" : 127.7001509, - "latitude" : 35.314562500000008 + "longitude" : 127.5444444, + "latitude" : 37.975833299999998 }, { "mountain" : { @@ -10989,16 +8499,6 @@ "longitude" : 126.9756112, "latitude" : 35.3992133 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "243", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "추화산" - }, - "longitude" : -121.95104910000001, - "latitude" : 37.318331800000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "화도읍(마석)에서 북동쪽으로 12km 거리에 있는 축령산(887.1m)은 조종천과 수동천의 사이에 솟아 있다. 이 산에는 일명 '남이바위'라고 하는 바위가 있는데, 이는 조선시대 때 남이장이 이 곳에서 심신을 수련하였다 하여 붙여진 이름이라고 한다.축령산의 울창한 수림과 계곡을 이용하여 자연 휴양림을 조성, 삼림욕장, 휴계소, 체육시설, 놀이시설, 야영장 등 편의 시설이 두루 갖추어 진 곳이다.", @@ -11016,28 +8516,8 @@ "MNTN_LOCPLC_REGION_NM" : "전북 고창군 고수면, 전남 장성군 서삼면", "MNTN_NM" : "축령산" }, - "longitude" : 127.3330406, - "latitude" : 37.752879499999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 산 아래 뻗어있는 계곡은 통도사 주변 암자와 연결되어 있어 산책하기 좋은 코스이기도 하다. 취서산 (영축산)통도사는 양산8경의 제 1경이다. 그밖의 8경으로는 천성산, 내원사계곡, 홍룡폭포, 배내골, 천태산, 오봉산 임경대, 대운산 탑골휴양림 등이 있다.", - "MNTN_HG_VL" : "1059", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 하북면, 원동면, 울산광역시 울주군 삼남면, 상북면", - "MNTN_NM" : "취서산" - }, - "longitude" : 129.05500000000001, - "latitude" : 35.517000000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "321", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", - "MNTN_NM" : "취암산" - }, - "longitude" : 127.18480460000001, - "latitude" : 36.782106200000001 + "longitude" : 126.7291354, + "latitude" : 35.368435099999999 }, { "mountain" : { @@ -11059,16 +8539,6 @@ "longitude" : 129.17500000000001, "latitude" : 37.154166699999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경주와 울산의 경계를 이루고 있는 산이 치술령이다.치술령은 조망도 특별하다. 남북으로 뻗은 능선의 좌우로 아름다운 산하가 펼쳐지는데다 정상주변에서는 삼태봉 너머로 손에 잡힐 듯 들어오는 잿빛 동해바다의 싱그러움이 닫힌 마음을 열어주기 때문이다.치술령에는 신라 충신 박제상과 그의 부인에 관한 애절한 전설이 있어,「삼국사기」와 「삼국유사」에 전해 내려오고 있다. 박제상은 눌지왕 즉위 후 고구려와 일본에 볼모로 잡혀 있던 두 왕제를 구출코자, 먼저 고구려에 가 있는 복호를 구출해 귀국시킨 후, 일본으로 건너가 미사흔을 구출해 내었다. 그러나 정작 자신은 일본에 잡혀 심한 고문 끝에 소사 당했다. 이때 박제상의 김씨부인은 두 딸을 데리고 치술령에 올라 일본에 간 남편을 기다리다 죽으니 그 몸은 돌로 변하여 망부석이 되고, 그 영혼은 날아가 숨었는데 그 곳을 은을암이라 한다. 그 후 왕은 박제상의 딸을 미해공의 부인으로 삼고 박제상에게 대아찬으로 관위를 높혀주고, 김씨부인은 국대부인에 추봉하였으며, 사당을 짓고 그 뜻을 기리는 제를 봉행토록 한 곳을 치산서원이라 한다.", - "MNTN_HG_VL" : "765", - "MNTN_LOCPLC_REGION_NM" : "울산시 울주군 두동면, 경북 경주시 외동읍", - "MNTN_NM" : "치술령" - }, - "longitude" : 129.27522060000001, - "latitude" : 35.657918299999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "치악산은 강원도 원주시와 횡성군의 경계를 이루는 산으로, 산세가 뛰어난 데다 영동고속국도와 중앙고속국도에 인접해 있어 교통이 편리해 중부권 산행지로 인기가 높다.", @@ -11079,36 +8549,6 @@ "longitude" : 128.05050990000001, "latitude" : 37.3716893 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "칠갑산은 해발 561m의 낮은 산이기는 하나 산세가 거칠고 가파르다. 아직은 널리 알려지지 않아서 자연 그대로의 울창한 숲을 이루고 있다. 산위에 오르면 서해가 바라다 보이고 골짜기마다 흐르는 물이 모여 지천과 사천을 이룬다.", - "MNTN_HG_VL" : "560", - "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군 대치면, 정산면, 장평면", - "MNTN_NM" : "칠갑산" - }, - "longitude" : 126.884288, - "latitude" : 36.413367800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "한국전쟁을 전후해 이 산에 본부를 두고 있던 빨치산과 전투하던 국군이 작전지도에 편의상 붙인 것이 그대로 이름이 된 칠백육고지는 산의 높이도 이름처럼 706m다.이곳을 중심으로 볼 때 서, 남, 북쪽을 섬진강이 감싸고 있고, 동쪽으로는 등재에서 시작하는 능선이 둘러쳐져 있어 요새로서 적합한 곳이기 때문에 빨치산이 본부를 두었다고 한다. 멀리서 보았을 때 정상에 초원이 부드럽게 펼쳐져 있어 얼핏 보기에는 예사로운 산처럼 느껴지니 그야말로 천연의 요새라 할 만하다. 산의 능선에 초원이 드넓고 억새가 무리지어 서있는 이곳은 아직까지 사람의 발길이 많이 닿지 않은 곳이어서 멧돼지나 노루같은 산짐승도 간간이 만날 수 있다.또한 바위의 중간에 패인 부분들이 광대가 쓰는 가면을 닮았다는 광대바위와 불을 밝히는 호롱처럼 생겼다는 호롱바위 등 특색 있는 바위들이 산행하는 발걸음을 더 들뜨게 한다. 그리고 정상에서는 지리산과 회문산, 원통산, 오봉산, 모악산, 성수산 등을 조망할 수 있다.", - "MNTN_HG_VL" : "706", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 강진면", - "MNTN_NM" : "칠백육고지" - }, - "longitude" : 127.1113728, - "latitude" : 37.347777800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "칠백이고지는 편안하면서도 숨이 차는 숲길과 원형이 잘 보존된 숯가마터, 깨끗한 계곡이 자랑거리다. 숲길은 동네 뒷산을 걸을 때처럼 부담이 없다가도 계곡이 끝나면서 가파르게 전개되어 그 재미가 독특하며, 옛날 사람들이 연료와 생활용품으로 사용한 숯을 만들었던 숯가마터에서는 숲이 우리에게 베푸는 혜택을 새삼 느끼게 된다.더하여 비가 아무리 많이 내려도 물이 무릎까지밖에 안차고 바위도 깔끔한데다가 3㎞쯤 완만하게 누운 계곡은 그 물에 발을 담그고 옆에 누워도 좋을 만큼 여유롭다. 산의 높이는 701m인데도 이름을 칠백이고지라 한 이유를 인근 지역 사람들에게 알아보는 것도 산행의 재미를 더한다.", - "MNTN_HG_VL" : "701", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", - "MNTN_NM" : "칠백이고지" - }, - "longitude" : 127.3305556, - "latitude" : 36.016111100000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "칠보산은 충북 괴산군 칠성면과 장연면의 경계를 이루는 산으로, 쌍곡계곡을 사이에 두고 군자산과 마주보고 있다. 칠보는 불교의 무량수경이나 법화경에 나오는 일곱가지 보배인 금, 은, 파리, 마노, 기거, 유리, 산호를 뜻한다고 한다.산의 규모는 작지만 기암괴석이 곳곳에 널려 있고, 고사목과 노송이 암봉과 조화를 이루어 한폭의 동양화를 보는 듯 하다. 이 산은 송이버섯 산지로 유명하며, 또한 칠보산에 오르는 길목에는 신라시대에 창건하였다는 고찰 각연사가 자리잡고 있다. 이 사찰에는 보물 제 433호인 석조비로 사나불좌상, 통일대사탑비 등이 있어 관광 코스로도 손색이 없는 곳이다. 정상에 서면 북쪽 아래로 각연사와 청석골 계곡이 보이고, 동북쪽으로는 덕가산과 희양산이, 서북쪽으로는 쌍곡계곡과 군자산이 가깝게 보인다.", @@ -11116,8 +8556,8 @@ "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 청안면", "MNTN_NM" : "칠보산" }, - "longitude" : 126.9333333, - "latitude" : 37.25 + "longitude" : 127.67984060000001, + "latitude" : 36.771560800000003 }, { "mountain" : { @@ -11129,16 +8569,6 @@ "longitude" : 126.9333333, "latitude" : 37.25 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 영덕군 창수면, 울진군 온정면에 자리한 칠보산 (七寶山 810m ) 은 더덕, 황기, 산삼, 돌옷, 멧돼지, 철, 구리 등 동식물과 광물질 등 7가지가 풍부하다해서 붙여진 이름이다.1993년에 개장된 칠보산자연휴양림은 칠보산(810m)과 등운산(767m)을 잇는 능선 아래 자리하고 있다. 동해바다가 지척인 이곳에서는 고래불해수욕장이 한눈에 내려다보이고 아르드리 소나무 숲은 휴양림 입구부터 산 정상부까지 계속 이어진다. 고래불해수욕장은 병풍처럼 둘러친 송림을 끼고 타원으로 펼쳐지는 명사 20리 백사장과 송림을 가지고 있다. '고래불' 이란 고려말 목은 이색 선생이 시를 읊으며 유년시절에 상대산에 올라가 바다를 바라보니 고래가 하얀 분수를 뿜으며 놀고 있는 모습과 같아 고래불이란 명칭을 사용하게 되어 지금가지 전해져 내려오고 있다.어린 소나무 한 그루가 지키고 섰는 정상에는 오래 전부터 자리한 돌탑 무더기와 영해 산사랑산악회에서 세운 정상표지석이 세워져 있다.", - "MNTN_HG_VL" : "810", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영덕군 창수면, 울진군 온정면", - "MNTN_NM" : "칠보산" - }, - "longitude" : 126.9333333, - "latitude" : 37.25 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "봉우리가 7개인 데서 칠봉산이라 유래되었다. 동쪽으로 임천고개를 넘어 선바위산과 운암산으로 이어지고, 서쪽에 십리산, 남쪽에 평안산, 북쪽에는 백운산이 있다.", @@ -11146,18 +8576,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 대학리", "MNTN_NM" : "칠봉산" }, - "longitude" : 127.093144, - "latitude" : 37.871221800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 양주시 회천읍에 자리한 칠봉산은 그리 높지않은 산이지만 유서깊은 사찰을 거느리고 있어 주변에 알려진 산이다. 칠봉산은 500m급 밖에 되지 않는 산이지만 암릉이 많고 시선을 끄는 경치들이 많아 산행의 아기자기함으로 등산인들을 즐겁게 한다. 발치봉·응봉·석봉·기대봉·투구봉·솔치봉·돌봉 등 7개 봉우리가 솟아 있어 칠봉이라는 이름이 붙었다. 주변에 삼봉산·오봉산·구봉산 등 홀수로 된 이름을 가진 산들이 많다.조선시대 세조가 말년에 과거의 잘못을 뉘우치며 이곳에 올랐다 하여 어등산(御登山)이라고도 하고, 가을단풍이 아름다워 비단병풍에 비유하여 금병산(錦屛山)이라고도 한다.산행을 하려면 송내동에서 대도사를 지나 능선을 따라 정상에 오른 뒤 송전탑을 지나 천보산을 거쳐 회암사를 지나 회암동으로 하산한다. 대도사와 회암사 뒷편에는 괴이하게 생긴 바위들이 있으며, 회암사지 주변에는 많은 사적이 남아 있어 가족을 동반한 가벼운 산행지로도 좋다.", - "MNTN_HG_VL" : "506", - "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 회천읍", - "MNTN_NM" : "칠봉산" - }, - "longitude" : 127.093144, - "latitude" : 37.871221800000001 + "longitude" : 127.0130546, + "latitude" : 36.3687921 }, { "mountain" : { @@ -11169,16 +8589,6 @@ "longitude" : 127.093144, "latitude" : 37.871221800000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "일곱 봉우리로 이루어진 칠봉산은 경북 문경 농암면과 상주시 은척면에 걸쳐 있는 산으로 높이는 낮지만 유명한 전설속에 명소를 감추고 있는 곳이다. 산 높이는 그리 높은 편은 아니지만 유명한 전설속에 명소를 감추고 있는 곳이다. 산 중턱에 조자룡 굴이 있는데 이곳 칠봉산의 전설에 따르면 이곳은 옛날 중국 삼국지에 나오는 조자룡이 태어난 곳이며 무술을 연마했던 곳이라고 한다. 현재는 토속신앙의 기도처로 이용되고 있다.중국의 유명한 삼국지의 주인공이 어찌하여 한국 경북의 문경에서 태어 났겠는가?전설이니 전설이려니 하는편이 나을듯 싶다. 산이 있으면 고개가 있고 이 칠봉산에도 옛 고개인 황령을 비롯하여 절 이름이 예사롭지 않은 황령사라는 절도 있다.산행시작은 농암면 갈동리로 가면 되지 않고 농암면 지동리나 선곡리로 가야 된다. 아니면 상주 은척면 남곡리로 가도 된다. 칠봉산은 상주시와 문경시 경계에 있는 산이므로 경계선을 타고 산행을 계속하여도 되지만 남곡 용추에서 능선을 타고 산행하는게 가장 추천할만한 코스이다.", - "MNTN_HG_VL" : "595", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면 갈동리", - "MNTN_NM" : "칠봉산" - }, - "longitude" : 127.093144, - "latitude" : 37.871221800000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -11186,8 +8596,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", "MNTN_NM" : "칠봉산" }, - "longitude" : 127.093144, - "latitude" : 37.871221800000001 + "longitude" : 128.8485613, + "latitude" : 37.714190700000003 }, { "mountain" : { @@ -11236,28 +8646,18 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량도", "MNTN_NM" : "칠현산" }, - "longitude" : 127.3977778, - "latitude" : 37.0113889 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도초는 신라시대 당나라에 교역시 기항지였는데 당나라 사람들이 지형을 볼때 꼭 자기나라 수도와 같은 형태이며, 지역마다 초목이 무성하여 목마지로도 활용하였기에 '도초(도초)'라 칭하였다.도초도에 남쪽끝에 자리하고 있는 큰산은 좌측은 도초에 자랑 시목해수욕장을 끼고 있으며반대편은 다도해의 수많은 섬들을 내려다 보는 형세이다.", - "MNTN_HG_VL" : "202", - "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군 도초면 엄목리", - "MNTN_NM" : "큰산" - }, - "longitude" : 126.9398793, - "latitude" : 37.548087600000002 + "longitude" : 128.2317299, + "latitude" : 34.8234979 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "탄항산(월항삼봉)은 백두대간이 북쪽으로 향하여 부봉을 지나 오른쪽 능선을 뻗어 주흘산을 만들어 놓으며 가고 다시 평천재를 지나 하늘재 사이에 있는 산으로서 지도에는 산이름이 표시되어 있지 않다.옛날에는 봉화를 올리던 곳으로 산 남쪽 월항마을 사람들은 봉화봉이라고 부르기도 한 산이다. 정상은 노송과 절벽,괴석 등으로 어우러지고 정남으로 주흘산과 마주보고 있으며, 백두대간상의 하늘재 직전에서 남쪽으로 들어간 계곡이 아름답고, 정상 서편에서 북쪽으로 뻗은 칼바위등길은 너럭바위, 홈바위, 칼바위 등으로 어우러져 스릴 있는 하산 길이다.", - "MNTN_HG_VL" : "857", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", - "MNTN_NM" : "탄항산" + "DETAIL_INFO_DTCONT" : "경기도 가평군 가평읍 승안리와 경반리의 경계를 이루는 칼봉산은 수락폭포와 용추폭포로 유명한 산이다. 가평읍에서 경반리 골짜기 안으로 12km 거리에 있는 수락폭포는 높이 30m쯤 되는 비교적 큰 폭포이다. 칼봉산의 물안골계곡은 옥계구곡이라는 이름이 있을 정도로 폭포와 소, 아름다운 물구비가 있어서 산행을 하지 않더라도 서울에서 하루 쉬어 오기에 아주 적당한 곳이다. 계곡 초입에 있는 용추폭폭포와 소는 관광지도에는 빠지지 않을 정도의 명소이다.칼봉산이란 이름은 주능선이 마치 칼날처럼 날카로운 암릉으로 이루어져 있어 붙여졌다고 한다. 경반리 방면은 버스가 다니지않아 교통이 불편하여 교통이 편리한 승안리 방면으로 등산을 하고 있다. 이 산도 더덕 등 산나물이 많이 서식하고 있는 곳이다.산행은 우무동 입구에서 서쪽 길을 따라 들어가면 양아터 마을의 맨 위에 있는 민가에 닿게되고, 이곳에서 서쪽 지능선을 가로질러 나가면 큰 소나무가 한그루 있는 십자로에 닿는다. 십자로에서 서쪽 계류를 건너 능선을 하나 넘어 북쪽길을 따라 수목이 울창한 주능선에 올라 서쪽으로 약간 올라가면 정상이다.", + "MNTN_HG_VL" : "900", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍", + "MNTN_NM" : "칼봉산" }, - "longitude" : 128.10508999999999, - "latitude" : 36.806125000000002 + "longitude" : 127.436694, + "latitude" : 37.862840200000001 }, { "mountain" : { @@ -11296,28 +8696,18 @@ "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 태봉동", "MNTN_NM" : "태수산" }, - "longitude" : -77.004718999999994, - "latitude" : 38.888683999999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "692", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 일선리,도문리", - "MNTN_NM" : "태조산(냉산)" - }, - "longitude" : 128.4007306, - "latitude" : 36.258746899999998 + "longitude" : 127.09657319999999, + "latitude" : 36.410788500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태청산은 전남 영광군 대마면과 장성군 삼계면ㆍ삼서면의 경계를 이루며 솟은 영광군 최고봉이다. 큰 바위가 있다고 해서 석태산(石太山)으로도 불린다. 새재에서 호남정맥을 벗어난 산줄기를 영산북기맥이라 부르는데, 영산북기맥은 길고 긴 능선을 이어 태청산을 일으키고 다시 장암산(481.5m)과 불갑산(516m)으로 흘러간다.태청산은 영광군 내 최고봉답게 정상에서의 조망이 빼어나다. 세 개의 바위로 된 정상부에 서면 북서쪽 월랑산과 고성산, 방장산을 지나 내장산까지 거침없고, 동남쪽 광주 무등산과 남쪽의 장암산과 불갑산이 멋진 산너울을 이루며 그림처럼 펼쳐진다. 서쪽으로는 영광시가지 너머 서해바다가 아스라하다.", - "MNTN_HG_VL" : "593", - "MNTN_LOCPLC_REGION_NM" : "전남 영광군 대마면, 장성군 삼계면ㆍ삼서면", - "MNTN_NM" : "태청산" + "DETAIL_INFO_DTCONT" : "경북 청송군에 위치한 태양산은 주왕산국립공원 북부지역의 비경지대인 너구골 북쪽에 병풍을 두른 듯 솟아 있다. 5만분의 1지도에는 태행산으로 잘못 표기되어 있으나 태양산이 바른 명칭이다. 태양산은 댕댕이산 또는 부덕골로 불리기도 한다.경북 청송은 산악지대로 곳곳에 비경이 살아있고 동해가 가까워 인파가 사계절 끊일 날이 없는 관광명소이다. 동해와 내륙지방을 가르는 산맥을 형성하고 있는 태양산 산자락에는 마치 조각가가 심혈을 기울여 빚어놓은 듯한 단애를 이룬 기암괴석과 아름다운 계곡, 폭포 등이 어우러져 빼어난 산세를 자랑한다. 이 일대는 어디를 가나 심산유곡의 청정함을 자랑한다. 산행을 통해 비경을 만끽하는 것 만큼이나 오고가는 여정 또한 경치가 뛰어나 일상에 지친 마음을 맑게 해 준다.", + "MNTN_HG_VL" : "933", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군", + "MNTN_NM" : "태양산" }, - "longitude" : 126.5835598, - "latitude" : 35.273987499999997 + "longitude" : 129.1299612, + "latitude" : 36.456375800000004 }, { "mountain" : { @@ -11326,8 +8716,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍, 충청북도 단양군 영춘면", "MNTN_NM" : "태화산" }, - "longitude" : 127.2886111, - "latitude" : 37.291944399999998 + "longitude" : 128.48475329999999, + "latitude" : 37.117061700000001 }, { "mountain" : { @@ -11339,26 +8729,6 @@ "longitude" : 127.2886111, "latitude" : 37.291944399999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "855", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", - "MNTN_NM" : "토곡산" - }, - "longitude" : 128.95459579999999, - "latitude" : 35.371205400000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "토곡산은 달음산과 더불어 부산 근교의 3대 악산(惡山)으로 꼽힌다. 계곡능선으로 연결되는 산행로의 경사도 만만치 않은데다 곳곳에 암릉이 많아 험준한 산길이 이어져 있기 때문이다. 그러나 토곡산은 곳곳에 설악산의 `용아릉' 못지 않은 아름다운 암릉군을 감추고 있어 산 타는 재미와 함께 보는 것만으로도 충만한 자연미를 안겨다 준다.경부선 원동역에 접해 있어 열차를 이용한 등산대상지로 안성맞춤이다. 정상에 오르면 남서편으로는 낙동강이 유유히 흐르고 강 건너 무척산과 신어산을 바라보는 조망이 좋고, 동쪽은 천성산에서 금정산으로 뻗어 내린 낙동정맥의 산군이 장쾌하다. 정상에서 서쪽으로 뻗은 능선의 남쪽면은 암벽지대이고 능선 곳곳에 바위지대가 있으며, 북쪽 산록에는 자연휴양림이 조성되어 있고, 앞으로는 선장천이 흘러 가족단위로 조용히 휴식을 취하기에도 더 없이 좋다.", - "MNTN_HG_VL" : "855", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면", - "MNTN_NM" : "토곡산" - }, - "longitude" : 128.95459579999999, - "latitude" : 35.371205400000001 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "토함산은 호국의 진산으로 예로부터 신성시 되어온 산이다. 신라의 영산으로 일명 동악이라 불리었으며, 서악 선도산, 남악 금오산, 북악 금강산, 중악 남산과 더불어 신라 5악이다. 신라의 4대 임금인 석탈해왕이 죽은 후 동악의 산이 되었다고 한다. 석탈해왕은 토해왕이라고도 했는데 토함산의 이름은 동악의 산이 된 데에서 유래된 듯하다.경주에서 가장 큰 산으로서 울산광역시와 경계를 이루며 동쪽으로는 추령재를 지나 기림사와 죽어서 동해의 큰 용이 되어 왜적으로부터 동해를 지키겠다는 문무대왕의 수중릉이 있는 동해바로 이어진다. 서쪽으로는 대덕산과 노천박물관으로 불리는 남산과 마주하고 있다. 북쪽으로는 만호봉을 지나 보문관광단지에 이른다.토함산 기슭에 위치한 불국사와 석굴암 이외에도 무덤에 물이 괴어 널을 걸어 묻었다는 전설로 유명한 괘능, 아사달과 아사녀의 애절한 전설이 담긴 영지못 등 주변에는 많은 문화재가 있다. 일출이 일품인 정상은 신년일출산행지로 손꼽히는 곳이다.", @@ -11366,8 +8736,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 불국동", "MNTN_NM" : "토함산" }, - "longitude" : 129.37361100000001, - "latitude" : 35.756667 + "longitude" : 129.345, + "latitude" : 35.801666599999997 }, { "mountain" : { @@ -11379,16 +8749,6 @@ "longitude" : 129.19194440000001, "latitude" : 36.898611099999997 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "통내산은 경북 청도의 주 하천인 동창천이 매전면쪽으로 흐르다 북서쪽으로 갈라져 나온 관하천을 끼고 있는 산으로 청도군 금천면 금곡리에 자리잡고 있다. 소나무숲과 바위능선 지대가 어우러져 있으며 주변에 동창천이 흐른다.산행은 수무동 버스정류장에서 시작한다. 마을을 지나 능선에 오르면 오른쪽으로 낙타등처럼 보인다 해서 낙타봉이라 이름 붙인 두 개의 봉우리가 보이는데, 뒤로 보이는 것이 정상이다. 앞의 봉우리를 지나 정상에 오르면 무덤이 있고 숲이 앞을 가려 전망은 좋지 않다. 정상에서 두 개의 봉우리를 지나 동창마을로 내려온다.", - "MNTN_HG_VL" : "674", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 매전면", - "MNTN_NM" : "통내산" - }, - "longitude" : 127.0308757, - "latitude" : 37.494464200000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "섬진강과 보성강을 가르고 있는 통명산은 그리 높은 산은 아니지만 지리상으로 중요한 위치를 점하고 있다. 통명산을 주산으로 주부산과 곤명산 산줄기가 섬진강과 보성강을 가르고 있기 때문이다. 일반적으로 곡성하면 동악산을 생각하지만 최고봉은 분명 통명산이다. 4개 면의 경계가 되는 지리적인 요충지 외에도 이름조차도 하늘의 옥황상제가 기거한다는 통명전을 뜻하니 말이다. 또한 곡성이 배출한 명장 신숭겸과 마천목은 각각 고려초와 조선초기에 주군을 도와 나라의 기초를 다지는데 기여한 인물들인데 바로 통명산 자락에서 태어났다.제단을 쌓은 듯 평평한 정수리의 조망은 시원하기 이를 데 없다. 북쪽으로 동악산과 곡성읍이, 동쪽으로는 주부산과 지리산의 위용이, 남쪽으로는 조계산을 이어 달리는 호남정맥과 주암호를 지나온 보성강 물줄기가 섬진강을 향하여 굽어드는 절경이 펼쳐진다.", @@ -11419,16 +8779,6 @@ "longitude" : 129.2583333, "latitude" : 36.344999999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "팔강산은 중랑구 신내동과 구리시 갈매동 경계에 있는 구릉산 북쪽에 위치한 조그만 봉우리로 서울시 자료에는 표시가 안되어 있으며, 일부 지도 및 구리시 지도에 표시된 산이다. 북쪽으론 불암산을 바라보고 있으며 남서쪽으론 봉화산이 보인다. 정상은 능선으로 되어 있으며, 그 능선을 따라 중랑구와 구리시의 경계가 갈린다.", - "MNTN_HG_VL" : "150", - "MNTN_LOCPLC_REGION_NM" : "경기도 구리시 갈매동", - "MNTN_NM" : "팔강산" - }, - "longitude" : 128.69499999999999, - "latitude" : 36.016944000000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "경북 경산시의 북쪽에 위치한 해발1,192.3m 산이고. 관봉은 852m 봉우리로써 아주 험준한 산은 아니고 보통인은 등산하기에 알맞고 능선부위에 암반이 많은 곳으며, 자연경관이 좋고 관봉에서는 전망도 좋으며. 일년내내 불자신도와 등산객이 가장많은 장소이다.", @@ -11446,8 +8796,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군", "MNTN_NM" : "팔공산" }, - "longitude" : 128.69499999999999, - "latitude" : 36.016944000000002 + "longitude" : 127.46611110000001, + "latitude" : 35.620555600000003 }, { "mountain" : { @@ -11456,8 +8806,8 @@ "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서면 팔봉리", "MNTN_NM" : "팔봉산" }, - "longitude" : 127.753889, - "latitude" : 37.702778000000002 + "longitude" : 127.6954236, + "latitude" : 37.6974485 }, { "mountain" : { @@ -11466,8 +8816,8 @@ "MNTN_LOCPLC_REGION_NM" : "충남 서산시 팔봉면", "MNTN_NM" : "팔봉산" }, - "longitude" : 127.753889, - "latitude" : 37.702778000000002 + "longitude" : 126.3708271, + "latitude" : 36.810449699999999 }, { "mountain" : { @@ -11476,8 +8826,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군", "MNTN_NM" : "팔암산" }, - "longitude" : 127.1822171, - "latitude" : 34.828257000000001 + "longitude" : 126.82715090000001, + "latitude" : 35.4843118 }, { "mountain" : { @@ -11489,16 +8839,6 @@ "longitude" : 127.4341153, "latitude" : 34.618202699999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도심에 자리잡은 산자락에는 일제 강점기에 만들어져 오랫동안 마산시민의 식수를 공급했고 수원지에 이르는 길은 침엽수가 울창하여 경관이 뛰어남 서쪽 먼등골에는 한시민이 1993년 산사태가 난후에 계곡을 정비하면서 돌탑을 쌓기 시작하여 지금까지 700여개가 넘는 돌탑군을 쌓아 많은 사람들이 즐긴다.소요 시간 :3시간 30분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 봉암저수지 둘레일반등산객이 정상까지 등반 할 수 있게 안내판, 이정표, 목계단, 안전가드레인이 잘정비 되어 있다.", - "MNTN_HG_VL" : "328", - "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시, 창원시", - "MNTN_NM" : "팔용산" - }, - "longitude" : 128.59123829999999, - "latitude" : 35.226665799999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "등산을 즐기는 사람이라도 경기도 양평에 편전산이 있다는 것을 아는 사람은 그다지 많지 않다. 널리 알려지지 않은 산들이 그렇듯이 편전산은 호젓한 산행을 즐기기 좋으며 수풀이 우거져 덮수룩한 산길을 걷는 묘미가 있는 산행지이다. 이 산에는 특히 소나무와 참나무가 많으며 곳곳에 억새풀 수풀림이 형성되어 있다. 정상에 서면 북쪽 건너편에 동그마니 들어앉은 마유산이 보이고 동쪽으로 용문산 주봉과 그 연릉이 남으로 길게 뻗어 나가다 솟구친 백운봉이 가깝게 눈에 든다.정상에 오르면 북쪽 건너편에 커다란 무덤처럼 둥근 산세를 지닌 마유산이 보이고 동쪽으로는 용문산의 주봉과 그 연릉이 남으로 길게 뻗어가다가 솟은 백운봉이 가깝게 조망된다.", @@ -11511,33 +8851,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "포성봉은 충북 영동과 경북 상주시에 걸쳐 있으며 맑은 물과 아름다운 경치로 인해 산을 타는 사람들의 사랑을 받고 있는 곳이다. 여름철이면 풍부한 수량과 짙은 녹음을 찾는 이들로 인해 붐빈다. 산행 길목 어디서든지 들을 수 있는 시원한 물소리는 한여름의 더위마져도 무색케 한다.", - "MNTN_HG_VL" : "933", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시, 충청북도 영동군", - "MNTN_NM" : "포성봉" - }, - "longitude" : 127.8877233, - "latitude" : 36.278346300000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "포암산은 반듯한 암벽이 키대로 우뚝 서, 산 모습이 마치 거대한 피륙을 펼쳐 놓은 것처럼 바라보여, '베바우산'으로 불리기도 한다. 또한 희고 우뚝 솟은 바위가 삼대 즉, 지릅같이 보여서 마골산이라고 불렸다는 기록도 전해오고 있다. 만수계곡에서 들어가면 쌍봉의 육산처럼 보이지만 문경시 쪽에서 보면 암봉으로 보인다.백두대간의 중심부에 자리잡고 있고 산세가 험하여 삼국시대부터 군사적 요충지였다. 이 산 밑 고개인 하늘재는 신라시대부터 사용한 옛고개로 북방의 문화를 영남지방에 전해주던 관문이었고 지금도 성벽이 남아 있다.하늘재 밑의 미륵사지는 고려 초기에 조성된 약 4천 평의 대사찰로 주흘산을 진산으로 하며 좌우로는 신선봉과 이 산을 끼고 멀리 월악산을 조산으로 하는 중심혈에 자리잡고 있다. 이곳에는 보물 제95호인 5층석탑과 보물 제96호인 미륵석불이 있다. 미륵석불은 우리나라에서는 보기 힘든 '북향석불'이다. 이 석불은 마의태자가 금강산으로 들어가는 길에 이곳에 머물렀다는 전설을 담고 있어 마의태자 자화상으로도 불린다. 산행은 문경읍 관음리 하늘재에서 시작한다.", - "MNTN_HG_VL" : "962", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍, 충청북도 충주시 상모면", - "MNTN_NM" : "포암산" + "DETAIL_INFO_DTCONT" : "p class=\"bonmun\"토정비결을 지은이지함이 올라가서 편하게 자리잡아 앉았다 해서 평안산이라 하기도 하며, 옛 성 터가 있어 이곳에 피난한 사람은 모두 무사하였다 하여 평안산이라 불리운다고 한다. 공주시가지로부터 남서쪽에 위치해 있으며, 북쪽으로는 금강과 칠봉산이, 남쪽으로는 장군봉이 위치해 있다.", + "MNTN_HG_VL" : "168", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 운곡리", + "MNTN_NM" : "평안산" }, - "longitude" : 128.11840900000001, - "latitude" : 36.821261999999997 + "longitude" : 127.0177778, + "latitude" : 36.3541667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "풍악산은 남원시 대산면과 순창군 동계면의 경계에 자리한 해발 600미터의 아담한 산이다. 산은 높지 않지만lsquo;단풍나무산rsquo;이라는 이름만큼이나 아름다운 경관을 지니고 있다. 섬진강 옆의 평지에 우뚝 솟아올라 산행할 때 조망이 좋으며, 해발 230미터 중턱에 돌을 쌓아 올린 축대 위로 올려다보이는 마애불은 열반길에 접어든 고목과 어우러지며 범상치 않은 분위기를 연출한다.특히 시원한 조망을 갖춘 정상부는 온갖 기암괴석과 울창한 송림이 어울린 경관이 빼어나다. 전일상호신용금고에서 세운 팻말이 자리한 정상 동쪽으로는 참으로 아름다운 산세와 묘한 이름을 가진 교룡산이 손닿을 듯 다가오고, 그 너머로 지리산의 웅장한 산세가 눈부신 하늘 아래 산평선을 그으며 동쪽으로 달려간다. 남쪽으로는 올림픽고속국도 너머로 곡성의 명산 동악산과 통명산이, 북쪽으로는 장수군의 명산 팔공산이 우뚝한 위용을 자랑한다.풍악산 정상에는 묘한 형상의 바위가 놓여 있다. 어찌보면 조물주가 큼직한 붓으로 일필휘지한 듯한 뫼 산(山) 형상의 바위는 자그마한 연못까지 갖추고 있다.", - "MNTN_HG_VL" : "600", - "MNTN_LOCPLC_REGION_NM" : "전북 남원시 대산면, 전남 순창군 동계면", - "MNTN_NM" : "풍악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "748", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", + "MNTN_NM" : "포도산" }, - "longitude" : 128.10495800000001, - "latitude" : 38.6566951 + "longitude" : 129.22692240000001, + "latitude" : 36.519314600000001 }, { "mountain" : { @@ -11561,23 +8891,23 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "학가산은 경북 안동시 서후면과 북후면, 예천군 보문면의 경계를 이루고 있으며 주변에 막힘없이 우뚝 솟아 있는 산으로 학이 날아가는 형상이라 해서 붙여진 이름이다. 백두대간 선달산에서 옥돌봉을 지나 남쪽 지맥으로 내달리다 청량산과 이나리강을 사이에 두고 남쪽으로 내려서면 봉정사를 품은 천등산을 지나 학가산에 이르러 주변에서 가장 높이 솟아 있다. 정상은 거대한 바위로 이루어져 있는데 국사봉이다. 산의 남쪽에는 고려 공민왕 때 축성된 학가산성이 있고, 북쪽 산등성이에는 자연적으로 쌓여진 자연석탑이 산재해 있다.주변에는 곳곳에 서원과 고택이 많으며 사찰이 골골이 들어차 있고 옛 문인들의 흔적이 고스란히 남아 있다. 학가산을 중심으로 안동은 북서풍을 막아주고, 예천은 일출을 맞이하는 해가 뜨는 동산, 영주에서는 앞산이 되어 풍수지리적으로 안산의 역할을 하고 있어 어느 곳에서나 진산의 면모를 갖추고 있다. 신라시대 능인대사, 학조대사, 학가산 사랑이 남달랐던 송암 권호문 선생 등 역사적 인물과 관계가 깊은 산이다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 서후면, 북후면ㆍ예천군 보문면", - "MNTN_NM" : "학가산" + "DETAIL_INFO_DTCONT" : "한라산은 우리나라 최남단에 위치해 있으면서 남한에서 가장 높은 산이다. 해발 1950m, 면적 151.35㎢ 로 1970년 3월 24일 국립공원으로 지정된 이 산은 3대 영산중의 하나로 다양한 식생분포를 이뤄 학술적 가치가 높은 동식물의 보고이기도 하다.", + "MNTN_HG_VL" : "1947", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시, 서귀포시", + "MNTN_NM" : "한라산" }, - "longitude" : 128.64811270000001, - "latitude" : 36.589284300000003 + "longitude" : 126.5291666, + "latitude" : 33.3616666 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "118", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구", - "MNTN_NM" : "학산" + "DETAIL_INFO_DTCONT" : "한산이라는 명칭은 산 아래에 한씨의 묘가 있어 한산소라 불리는 마을 이름에서 유래된 것으로 추정된다. 출구쪽은 밤나무 단지와 연결되어 있으며 경사가 심하다.", + "MNTN_HG_VL" : "121", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 웅진동", + "MNTN_NM" : "한산" }, - "longitude" : -118.3204549, - "latitude" : 33.819496399999998 + "longitude" : 127.0999884, + "latitude" : 36.452894499999999 }, { "mountain" : { @@ -11626,8 +8956,8 @@ "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", "MNTN_NM" : "함박산" }, - "longitude" : 127.18888889999999, - "latitude" : 37.2141667 + "longitude" : 129.1802778, + "latitude" : 35.306111100000003 }, { "mountain" : { @@ -11639,26 +8969,6 @@ "longitude" : 128.9176271, "latitude" : 37.1615368 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 양평군 옥천면과 용문면 경계에 있는 함왕봉(947m)은 용문산과 2km거리를 두고 인접해 있는 산으로 용문산의 유명세에 눌려 호젓한 산행을 즐길 수 있는 곳이다. 명찰 용문사가 있는 용문산은 주말이면 행락객들로 만원을 이루는 곳이다.서쪽에 함왕골,동쪽에 연수천 계곡이 흐르고 있어 정상까지 오르면 고봉에 오른듯한 느낌을 주며 산 남쪽으로 남한강이 있어 조망 또한 일품이다.함왕봉에 있는 사나사는 신라 경명왕 7년(923년) 대경대사가 창건한 고찰로 경내에는 석종,3층석탑, 원증국사비, 부도, 함씨각 등이 있고 분지 형태의 함왕성터에는 한겨울에도 얼지 않는 고산샘터가 있다. 양평군 옥천면과 용문면 경계에 있는 함왕봉(947m)은 호젓한 산행을 즐기기에 좋은 산이다. 고찰 사나사를 끼고 있으며 고즈넉한 분위기를 자아낸다.정상에서는 북쪽으로 함왕봉의 모산(母山)인 용문산과 그 옆으로 유명산이 아름다운 자태로 시야에 들어온다. 남쪽으로는 백운봉과 남한강 물줄기가 시원하게 펼쳐져 보인다.", - "MNTN_HG_VL" : "947", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군", - "MNTN_NM" : "함왕봉" - }, - "longitude" : 127.551089, - "latitude" : 37.544308899999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "장수군 장계면과 함양군 서상면으 경계로 육십령고개 바로 북쪽에 솟아 있는 암봉이 할미봉이다. 북으로 남덕유산의 우람한 두 봉우리를 올려다 보게 되고, 동으로 월봉산 금원산 황석산을 볼 수 있으며, 남으로 백운산 장안산 왕산 지리산 줄기가 조망된다. 서쪽으로는 팔공산 덕태산이 보이며 운장산도 보인다.", - "MNTN_HG_VL" : "1024", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 장계면 명덕리", - "MNTN_NM" : "합미봉" - }, - "longitude" : 127.6611111, - "latitude" : 35.735277799999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "해남 금강산은 한반도 서남쪽 끝머리에 자리잡은 해남읍을 병풍처럼 두르고 있다. 한양과 멀다는 이유로 이곳은 귀양지로 이름을 날린 고장이다. 그러나 귀양 온 양반들이 심어놓은 문화와 유적은 오랫동안 이어져 유배문화의 본산이 된다.그 때문일까. 해남의 산들에는 독특한 정서가 스며있어 산을 찾는 이들마저 시 한 수 읊지 않고는 견딜 수 없게 만든다. 비록 작은 산이지만 기암과 괴석으로 된 암장들이 포진해 있는 금강산 정상에서는 해남읍내와 인근의 목포, 강진, 진도, 완도, 장흥, 영암일대를 조망할 수 있다.", @@ -11691,13 +9001,13 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "향로산의 산행들머리는 원동에서 장선행 버스편으로 선리 마을에서 내려, 마을 상점 옆 계곡을 따라 언곡(담재)에 도착한다. 마을에서 식수를 준비하고 왼편길을 따라 나서면, 이 마을의 수호목으로 언제나 해송 4그루가 마중 나와 반기고 있다.바위봉우리인 향로산(香爐山) 정상은 시야가 좋고 사방이 트였다. 뒤로 돌아보면 쌍봉이 의좋게 나란히 서 있는 모습이 정겨워 보인다. 오른 편으로 향로봉이 가까이 보이고 멀리 김해 무척산 신어산까지 뚜렷하다. 산들이 겹겹이 둘러쳐진 그림같은 모습은 근교에선 보기 힘든 빼어난 광경으로 손꼽힌다. 향로산의 본 모습은 염수봉에서 보아야 제맛이다.", - "MNTN_HG_VL" : "976", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "향로산" + "DETAIL_INFO_DTCONT" : "치악산 정상인 비로봉에서 남쪽으로 5km 지점에 솟아 있는 향로봉은 강원도 원주시와 횡성군의 경계를 이루는 산으로 교통이 편리하여 당일 산행지로 적합하다. 등산객으로 붐비는 구룡사계곡에 비해 호젓한 산행을 즐길 수 있는 곳이다.원주역에서 산행기점인 행구동까지는 버스로 20분 정도로 가까운 거리인 향로봉을 오른 후, 북쪽 비로봉이나 남쪽 남대봉 등 어느 방향으로나 산행이 가능하다. 치악산 일대의 억새군락은 단연 고둔치를 최고로 친다. 향로봉 남쪽 능선에 위치한 치악평전은 일명 '금두고원'이라고 부르는데, '금두' 라는 말은 억새밭이 햇빛을 받아 금빛 찬란하게 빛나기 때문에 붙여진 이름이다.", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 행구동, 판부면, 신림면, 횡성군 강림면", + "MNTN_NM" : "향로봉" }, - "longitude" : 127.66742739999999, - "latitude" : 36.020660100000008 + "longitude" : 128.03416669999999, + "latitude" : 37.330833300000002 }, { "mountain" : { @@ -11719,16 +9029,6 @@ "longitude" : 127.20184399999999, "latitude" : 36.292887800000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "허굴산은 인접한 봉화산(금성산), 악견산과 더불어 암릉이 험준하기로 이름난 삼산으로 알려져 있다. 전체적으로 산의 속이 비어 있다고 해서 허굴산이라 이름 붙였다고 하는데 이 산과 관련한 전설과 일화과 있다.하나는 마고할미와 관련한 이야기다. 마고할미 박랑이 가려움증에 시달려 고생하고 있을 때 꿈에서 황매산 자락에 사는 허굴산 신령이 자신의 배꼽 부분에 박힌 돌멩이를 뽑아주면 가려움증이 사라질 것이라 귀띔해 주었다. 박랑 할멈은 곧장 황매산 협곡의 중간에 있는 배꼽바위로 가서 끼인 돌을 뽑아내었다. 그러자 허굴산 속에 가득 찼던 더운 김이 왈칵 빠져나오면서 박랑의 가려움증이 씻은 듯이 나았다고 한다.또 하나는 임진왜란 때 허굴산 정상 아래 고리바위와 남쪽의 여산봉(494m) 정상에 줄을 걸어놓고 허수아비를 만들어 마치 장수가 하늘을 날아 다니는 것처럼 꾸며 쳐들어 오던 왜군들이 겁을 먹고 달아났다는 실화가 그것이다.허굴산 북쪽 허리쪽에는 백년 전에 건립한 청강사가 있다. 산신각, 대웅전, 종루, 요사채, 동굴방이 있는데 양쪽에 놓인 두 개의 큰 바위와의 조화가 눈길을 끈다. 또한 등산로를 따라 가다보변 위장병과 피부병을 고쳤다는 약샘이 있고 허굴산 최고의 전망대인 용바위가 나온다. 수십길 깊이의 바위틈을 건너야 하는 어려움이 따르기 때문에 용바위를 다녀 온 사람은 10년을 더 산다는 말이 전해 내려오고 있다.", - "MNTN_HG_VL" : "681", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", - "MNTN_NM" : "허굴산" - }, - "longitude" : 128.04514599999999, - "latitude" : 35.508830099999997 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "강화군 내가면 고천리에 위치한 해발 466m의 혈구산은 강화도의 중심에 위치한 산이다. 고려산과 고비고개를 사이에 두고 남북으로 이어져있으나 혈구산이 더 높고 산세도 부드러운 고려산에 비해 뾰족하면서 굴곡이 있어 힘이 넘친다. 고비고개에서 정상에 이르는 능선길은 4개의 봉우리로 이루어져있으며 첫 번째 봉우리를 지나면서 방향이 우측으로 심하게 휘면서 2봉을 만나고 남쪽으로 진행하다 3봉이 된 후 다시 왼쪽으로 휘어지며 4봉인 혈구산 정상부를 만들어 낸다.각 봉우리 오름길은 매우 가파라서 숨이 가쁘지만 봉우리에 올라서면 시원한 조망을 제공해주며 다음 봉우리 사이 안부까지 내리막길이 있어 강약이 조화를 이루는 코스라 할 수 있다. 그러면서도 쉬는 시간을 포함해 2시간밖에 걸리지 않는 짧은 거리여서 가족산행지로도 적격이다. 정상부에 올라서면 사방으로 전망이 트이며 강화도의 전모가 드러난다.", @@ -11739,16 +9039,6 @@ "longitude" : 126.4405556, "latitude" : 37.720277799999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "912", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 마산면 황전리", - "MNTN_NM" : "형제봉" - }, - "longitude" : 127.0388889, - "latitude" : 37.328888900000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "충청북도 단양군 영춘면과 경상북도 영주시 단산면에 걸쳐 있는 형제봉은 동·북 비탈면에서 남한강 지류 남대천이 발원한다. 소백의 남서쪽 끝자락에 이름 그대로 두 봉우리가 우뜩 솟은 형제봉(1,177.5m)은 소벡산 중에서도 찾는 이가 거의 없는 곳이다. 소백산의 주능선과 이어져 있지만 거의 독립된 봉우리라 해도 과언이 아니다.소백산 끝자락에 온화하게 솟은 산. 비로봉에서 북동쪽으로 직선거리 11.5Km 지점에 솟은 형제봉은 이름 그대로 두 봉우리가 사이좋게 솟아 소백의 남서쪽 끝자락에 자리잡고 있다. 죽령에서 시작하여 비로봉을 지나 국망봉에서 내려오면 형제봉을 바로 앞두고 칼바위에서 서쪽으로 백두대간이 갈려나가고 형제봉을 지나 의풍리로 빠져 나오면 총 39km로 소백산의 가장 긴 종주코스에 해당한다.", @@ -11756,38 +9046,8 @@ "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영춘면", "MNTN_NM" : "형제봉" }, - "longitude" : 127.0388889, - "latitude" : 37.328888900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "한강, 낙동강, 금강의 분수령인 삼파수 속리산 천황봉(1058m)을 지나는 백두대간의 동남쪽 6km 지점에 바위봉을 우뚝 세운 형제봉(828m)은 서쪽 골짜기속에 십승지 중의 하나인 만수동을 감싸고 있다.형제봉의 비경을 빛내는 명소로 금란정과 장각폭포를 꼽을 수 있는데 천황봉에서 동쪽으로 흘러내린 계곡이 상오리에 이르러 높이 6m의 폭포와 소를 이룬 모습이 주변의 경관과 어우러져 선경을 연출한다.", - "MNTN_HG_VL" : "1178", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시, 충청북도 보은군", - "MNTN_NM" : "형제봉" - }, - "longitude" : 127.0388889, - "latitude" : 37.328888900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "낙남정맥이 삼신봉에 이르러 섬진강 쪽으로 지맥을 흘러 강 언저리에 솟구쳐 만든 산봉이 형제봉이다. 하동군민이\"\"형\"\"을\"\"성\"\"이라 부르는 언행에서 형제봉을 성제봉으로도 부르는데, 어찌된 셈인지 정상에는 어진 임금이라는 성제봉이라고 표기된 표지석이 산객을 어리둥절하게 한다.악양면소재지 서쪽편으로 막아서서 남쪽으로 길게 뻗어내린 이 산역은 동쪽사면으로 산세를 열어 박경리의 소설 「토지」에 나오는 평사리를 비롯한 마을을 산자락에 포용하고 있다.", - "MNTN_HG_VL" : "1115", - "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군 악양면", - "MNTN_NM" : "형제봉" - }, - "longitude" : 127.0388889, - "latitude" : 37.328888900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "호구산은 지형도에는 이름이 표기되어 있지 않지만, 남해군에서는 송등산, 괴음산 등 산군을 엮어 호구산으로 대표되는 호구산군립공원으로 지정하고 있다. 남해군의 군립공원으로 지정된 것은 그만큼 자연경관이 뛰어나고 보존가치가 있는 곳이라는 뜻이다.남해읍 이동면에 솟은 호구산은 남해 산꾼들이 외부에 알리기를 꺼릴 만큼 아름다운 산으로 소나무, 벚나무, 단풍나무 등 수림이 울창하다.신라 애장왕 때 개창한 남해에서 가장 오래된 절인 용문사에는 대웅전을 비롯해 석불좌상, 천왕각, 명부전, 촌은선생의 집책판, 삼혈포와 수국사 금패 등 많은 문화재가 있으며 부속암자로 백련암, 염불암을 품고 있다.또 암봉으로 된 정상에서 바라보는 앵강만의 풍경은 놓칠 수 없는 볼거리다. 물을 베고 누워 있는 다도해 섬들 사이로 서포 김만중이 유배생활을 하며 「사씨남정기」를 집필했던 노도도 내려다보인다.호구산은 원산 또는 납산으로도 불린다. 호구산(虎丘山)은 정상에서 용문사 쪽으로 뻗어내린 산줄기의 형상이 호랑이가 누워있는 것과 같다해 얻은 이름이다. 원산(猿山)은 이 산을 북쪽에서 보았을 때 원숭이가 웅크리고 있는 것처럼 보인다해 부르는 이름이다. 납산의lsquo;납rsquo;은 원숭이의 옛말이다.", - "MNTN_HG_VL" : "619", - "MNTN_LOCPLC_REGION_NM" : "경남 남해군 이동면 용소리", - "MNTN_NM" : "호구산" - }, - "longitude" : 127.905485, - "latitude" : 34.790899799999998 + "longitude" : 128.56805560000001, + "latitude" : 37.036111099999999 }, { "mountain" : { @@ -11829,6 +9089,16 @@ "longitude" : 127.4460303, "latitude" : 37.729328899999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "280", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "호암산" + }, + "longitude" : 127.71566850000001, + "latitude" : 34.768495399999999 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -11839,26 +9109,6 @@ "longitude" : 127.83861109999999, "latitude" : 35.797499999999999 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "물을 받는 통처럼 골이 깊고 물이 많다는 뜻의 이름을 지닌 홀통골산은 충북 단양군 영춘면남천리 남천계곡 동쪽에 자리한 형제봉(1178m)과 맥을 같이하고 있다.정상의 남쪽 멀리로 소백산의 신선봉이 조망되고 그 아래로 범놀이골, 새삼박골, 활골, 너래골, 석골 등 도원경을 연상케 하는 남천계곡이 보인다.수림지대로 뒤덮여 길을 찾기 어려우므로 지형도와 개념도, 나침반을 준비하고 장마기간에는 남천계곡을 건널 20m이상의 보조자일을 준비해 가야 한다", - "MNTN_HG_VL" : "1029", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영천면", - "MNTN_NM" : "홀통골산" - }, - "longitude" : 126.3372732, - "latitude" : 35.0612329 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "섬 산행은 언제나 가슴 설레게 만든다. 사면이 바다이고 공기가 맑고 깨끗하며, 특히강화군은 많은 유적지와 역사적 의미가 곳곳에 어우러져 있어 더욱 좋다. 화개산은 누구나 등반하기 좋으며, 산세가 아름답고 숲이 잘 가꾸어져 있다. 토사와 암반이 적당하게 조화를 이루고있으며 정상부에 있는 약수터는 과거 산성으로서의 가치가 매우 우수했으리라 짐작된다. 정상부는 산성으로 이용하기 좋은 구조이며, 과거에도 큰 역할을 했으리라 생각된다. 남한산성이나 행주산성 처럼 용수 시설을 포함하고 있는 포곡식 산성인 화개산은 동쪽으로는 절벽의 지형을 잘 이용하고 있으며, 북과 남으로 길게 늘어져 있는 형태이다. 봉수대는 동쪽으로 봉천산 봉수대와 연락을 했고, 남으로는 덕산봉수와 대응했다고 신동국여지승람에 전한다.", - "MNTN_HG_VL" : "262", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 교동면 대룡리", - "MNTN_NM" : "화개산" - }, - "longitude" : 126.29608589999999, - "latitude" : 37.779330000000002 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "화란봉은 이름 그대로 꽃모양을 하고 있는 산으로 부채살처럼 펼쳐진 화관이 화란봉을 중심으로 겹겹이 에워싼 형상이다.산행기점인 벌마을에는 용수골이 있는데 이곳은 옛날에 이무기가 하늘로 오르다 힘이 부쳐 떨어진 곳이라 한다. 지금도 그때 자국이 용수골 너럭바위에 남아있다.화란봉에선 닭목재가 한눈에 들어온다.화란봉 주위에는 기암괴석과 몇 아름 되는 노송들이 바위 틈새에서 우람하게 자라는 모습을 보면 마치 한 폭의 동양화를 연상하게 된다.", @@ -11869,6 +9119,16 @@ "longitude" : 128.78916670000001, "latitude" : 37.626388899999988 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "화부산은 길안면 대사리와 고란리를 경계로 남북으로 길게 자리잡고 있는 산이다. 비교적 낮은 산이지만 치솟는 경사와 아기자기한 능선, 그리고 촛대바위, 문살바위 등이매우 아름답게 어우러져 있다. 정상부근에는 잡목이 무성하여 어디가 정상인지 분간조차 할 수 없으며 정상에서는조망이 불가능하다.", + "MNTN_HG_VL" : "626", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 길안면 대사리,고란리", + "MNTN_NM" : "화부산" + }, + "longitude" : 128.9526189, + "latitude" : 36.387769600000013 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "화악산은 경북 청도군 경남 밀양시의 도경계를 이루고 있다. 비슬산에서 남쪽으로 이어져 한 줄기는 창녕 화왕산으로 갈라지고, 화악산을 지나 철마산으로 뻗어내려 물길을 만나면서 멈춘다.화악산은 부드러운 육산과 곳곳에 바윗길을 드러낸 골산이 합쳐진 형태의 산으로 청도에서 손꼽을 만큼 아름다운 산이다. 정상은 세 봉우리가 주봉을 중심으로 나란히 솟아 있고 그 등성이가 황소의 등을 방불케 하며, 두 봉우리의 중간쯤에서 남쪽으로 또 한 봉우리가 솟아 있는데 이를 속칭 작은 화악산이라고 한다.화악이란 이름은 정상의 세개 봉우리 형상이 중국 오악의 하나인 서악, 즉 화악의 삼봉과 비슷하다고 하여 붙여진 것이다. 또 산의 생김새가 덕성스러워 덕기에 둔취되어 있다는 뜻에서 둔덕산이라고도 한다. 화악산은 영남알프스까지 이어지는 만만찮은 높이에 시원스런 조망과 아기자기한 암릉 그리고 봄철에는 철쭉이 피어 가족산행지로 적합하다.", @@ -11876,6 +9136,16 @@ "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 청도읍ㆍ경상남도 밀양시 청도면", "MNTN_NM" : "화악산" }, + "longitude" : 128.69147169999999, + "latitude" : 35.593220600000002 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기 5악 중의 으뜸인 화악산(1,468m)은 강원도와 경기도를 가르는 분기점에 우뚝 솟아 있는 산이다. 경기도의 최고봉이다. 화악산을 중심으로 동쪽에 매봉, 서쪽에 중봉이 위치하며 이들을 삼형제봉이라고도 한다. 여기서 발원하는 물은 화악천을 이루며 가평천의 주천이 되어 북한강으로 흘러든다.정상 주변은 군사지역으로 출입이 금지되어 있어 가까운 곳에서 보는 것으로 만족해야 하는 점이 아쉽다. 지금은 정상 서남쪽 1km 거리에 있는 중봉 산행으로 화악산 정상을 대신하고 있다. 화악산 주능선에 오르면 가평, 춘천 일원을 굽어볼 수 있어 산행의 재미를 더해 준다.", + "MNTN_HG_VL" : "1468", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 화천군 사내면", + "MNTN_NM" : "화악산(중봉)" + }, "longitude" : 127.5031003, "latitude" : 37.9950197 }, @@ -11889,26 +9159,6 @@ "longitude" : 127.4279782, "latitude" : 37.671530099999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 창녕에 자리한 화왕산은 험준한 산이다.특히 봄이면 진달래와 철쭉, 여름에는 녹음과 계곡물, 가을에는 억새, 겨울에는 설경이 유명하다. 봄철 진달래 경치와 가을철 억새가 유명한데, 봄철이면 진달래 군락지를 이루고 있는 화왕산성 주위의 비탈과 관룡산으로 이어지는 능선 일대는 마치 분홍물감을 쏟아부은 듯하다. 매년 4월 하순에서 5월 초순까지 그야말로 산 전체가 불타오르듯 만발한 진달래의 붉은 기운으로 뒤덮인다.화왕산 최대의 명물이라면 정상 주변의 넓고 평평한 억새밭인 '십리억새밭'이다.그 십리 억새밭이 평지에서 급경사 벽으로 뚝 떨어지는 경계선인 능선을 따라 화왕산 성벽이 쌓여 있으며, 그 바깥 경사면 거의 모두가 진달래밭을 이루고 있다. 매년 10월이면 이곳에서 화왕산 억새제가 개최된다. 화왕산은 선사시대 화산으로 추정되며, 3개의 못(龍池)가 있으며, 창녕조(曺)씨가 득성하였다는 득성비가 화왕산성(사적제64호)가 있다. 또 서쪽 능선으로는 사적 65호인 목마산성이 보인다. 능선의 동쪽 5km 거리에 관룡사가 있다.", - "MNTN_HG_VL" : "758", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕군 창녕읍 옥천리 일대", - "MNTN_NM" : "화왕산" - }, - "longitude" : 128.56055559999999, - "latitude" : 35.537222200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 연천군 신서면과 포천군 관인면에 걸친 지장산(877m)은 일반인의 등산이 허용된 산중 최북단이다. 화인봉은 삼형제봉쪽으로 뻗은 남쪽길을 버리고 북릉을 타고 고도를 높여가면 나타난다.바위봉우리인 화인봉에서는 김일성이 휴전 후 눈물을 흘리며 아까워했다는 철원평야가 한눈에 들어온다. 화인봉을 한자로 쓰면 어떤지 모르지만 자꾸 fine봉이라는 영어가 떠오른다. 그처럼 그림 같은 봉우리이기 때문이다.", - "MNTN_HG_VL" : "805", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 관인면 중리", - "MNTN_NM" : "화인봉" - }, - "longitude" : 127.17340609999999, - "latitude" : 38.1419122 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "장흥과 가깝고 험한 능선이 있어 전란의 소용돌이에 끊임없이 휘말려들었던 화학산은 오르다보면 실제로는 그리 험하지 않다. 나무도 거의 잡목이고 육산인데다가 주능선도 바위지대가 없이 길게 남북으로 늘어져 있다.정상은 좁은 데다가 꺽다리 억새들이 무성해서 주위경관을 감상하기는 쉽지 않다. 하지만 남쪽으로 조금 내려와 헬기장에 서면 천태산과 금성산, 용암산과 국사봉을 모두 볼 수 있다.", @@ -11916,8 +9166,8 @@ "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 청풍면, 도암면", "MNTN_NM" : "화학산" }, - "longitude" : 127.5031003, - "latitude" : 37.9950197 + "longitude" : 126.9208333, + "latitude" : 34.863333300000001 }, { "mountain" : { @@ -11949,16 +9199,6 @@ "longitude" : 127.9744444, "latitude" : 35.495833300000001 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "103", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 중구 장현동", - "MNTN_NM" : "황방산" - }, - "longitude" : 127.098922, - "latitude" : 35.834747 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "황병산은 높이 1,407m의 명산으로 청학동 소금강의 절경을 끼고 구룡폭포, 만물상, 금강사, 십자소 등 수많은 명승 고적을 품고 있다.75년 오대산이 국립공원으로 지정되면서 황병산 또한 국립공원으로 편입됐지만, 사람들 사이에서는 잘 알려지지 않은 편이다. 잘 알려지지 않은 까닭에 황병산은 자연 그대로의 아름다움을 간직할 수 있었다. 골골이 깊은 산중의 계곡 하며, 희귀식물, 원시림 등은 황병산의 또 다른 자랑이다.육산이라 산행도 수월한 편이며 부드러운 흙을 밟으며 산행 할 수 있어 좋다. 특히 여름이면 계곡을 끼고 가는 코스가 인기다. 정상은 입산금지 구역이다.", @@ -11999,16 +9239,6 @@ "longitude" : 128.27611099999999, "latitude" : 36.813056000000003 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1069", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면 활기리,화장면 번천리", - "MNTN_NM" : "황장산" - }, - "longitude" : 128.27611099999999, - "latitude" : 36.813056000000003 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "황적봉은 계룡산의 봉우리중 하나이다. 계룡산은 충청남도 공주군과 논산군에 걸쳐있으며 주봉인 천왕봉(845m)아래로 쌀개봉(828m), 황적봉(664m),수창봉(662m) 도덕봉(524m)등 거대한 산혼을 횡성하고 산세는 대체로 경사가 완만한 편이며 정상 부근은 경사가 급하다. 이들 봉우리 사이에는 7개의 계곡과 3개의 폭포가 있어 운치를 더해주며, 골짜기에는 동학사갑사신원사 그리고 구룡사의 대가람을 배치한 불교의 명지이며, 다양한 식, 생물분포의 학술적 자원이 풍부하며 자연경관이 빼어난 국립공원으로 이름이 높다.출입이 금지되어 있는 황적봉-쌀개봉 능선은 계룡산 산행의 또 하나의 모험이자, 신선한 충격이다. 황적봉-쌀개봉능선을 잇는 산행은 때로는 한가할 정도로 평탄한 산행길이지만 변화 많은 봉우리로 점철 돼 있어 잔재미가 많으며 때로는 위험한 바윗길이 숨어있는 호방한 산행의 기분도 만끽할 수 있는 아름다운 코스이다. 특히 쌀개능선의 호방한 바위암릉위에서 바라보는 연천봉에서 관음봉을 거쳐 자연성능, 삼불봉으로 이어지는 이 산의 이른바\"\"주코스\"\"의 능선과 봉우리들을 바라보는 경관은 전혀 다른 매력으로 다가온다.", @@ -12029,6 +9259,16 @@ "longitude" : 128.33677549999999, "latitude" : 36.845008499999999 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "769", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "황학산" + }, + "longitude" : 128.87916670000001, + "latitude" : 36.375833299999996 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "회령봉은 강원도 평창군 봉평면에 위치한 준봉으로써, 육산이며 숲이 울창하고 산록엔 더덕이 많다. 멀지 않은 곳에 솟아 있는 흥정산과 산세와 규모가 비슷한 산이다.산길은 대체로 또렷하나 숲이 짙으므로 길 찾기가 쉽지 않다. 능선엔 진달래와 철쭉나무가 군락을 이룬다.사람들이 거의 찾지 않는 강원도의 오지 산 중의 하나이다.", @@ -12039,26 +9279,6 @@ "longitude" : 128.3663889, "latitude" : 37.686111099999998 }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 순창에 있는 회문산은 북에서 동으로 섬진강 줄기가 꺾여 흐르며 남으로 구림천이 섬진강으로 휘돌아 빠지는 지점에 둔중한 줄기로 솟아 있다. 우리나라 5대 명당 중 하나로 옛부터 영산으로 이름난 회문산은 홍문대사(홍성문)가 이 산에서 도통하여, 회문산가 24혈의 명당 책자를 만들었다고 해서 유래되었다. 이 책에는 회문산 정상에 24명당과 오선위기가 있는데, 이곳에 묘를 쓰면 당대부터 발복하여 59대까지 갈 것이라 했다.회문산은 순창군과 임실군을 가르는 산으로서 봉우리와 골짜기가 많아 첩첩산중을 이루고 있는데다 서쪽을 제외한 삼면이 강으로 둘러싸여 있어 예로부터 천혜의 요새로 알려져 있다. 이러한 지형적인 특성 때문에 역사적으로 많은 사연을 품고 있다.소설남부군의 배경이 되기도 했으며 한말에 임병찬 최익현 양윤숙 선생이 의병을 일으켜 일제에 항거했고, 6·25때는 북한의 남부군총사령부가 있었던 곳이다. 그러나 지금은 회문산자연휴양림이 조성되어 지난날의 흔적을 찾아보기가 어렵다.", - "MNTN_HG_VL" : "837", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 덕치면", - "MNTN_NM" : "회문산" - }, - "longitude" : 127.10604069999999, - "latitude" : 35.499814700000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "효양산은 삼족당 기대유 공이 마을에 부임해 와서, 마을 뒷산의 엄청난 위용과 험준함을 보고, 마을에 무슨 피해라도 있을까봐 공이 산을 받든다는 뜻에서 이 산을 효양산이라고 이름을 지었다. 그 이후 마을에는 효자, 효부가 많이 났다고 한다.산행들머리는 나무 왼편 골목길에서 파란 기와집 오른쪽으로 오르면 산자락에 접어드는데 식수는 반드시 이 마을에서 준비해야 한다. 정상은 5,6 명이 겨우 설 수 있을 정도로 좁다.", - "MNTN_HG_VL" : "580", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "효양산" - }, - "longitude" : 127.4807519, - "latitude" : 37.272978999999999 - }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", @@ -12069,6 +9289,16 @@ "longitude" : 127.8288889, "latitude" : 37.923333300000003 }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "흑석산은 해남과 영암을 남북으로 가르는 산으로 호남정맥이 땅끝으로 가기 전 월출산과 두륜산 사이에 솟아 있다. 인근의 월출산이 남성, 두륜산이 여성의 이미지를 풍기는 산이라면 흑석산은 중후한 중년 신사 같은 산이다.「동국여지승람」에서 가학산(駕鶴山)으로 표기되어 있으나 「대동여지도」에는 가학산과 흑석산(깃대봉)으로 표시되어 있다. ‘가학’은 학이 날지 못하도록 학 앞에 멍에 가를 씌운 풍수지리상 비보(裨補)의 의미를 담고 있다. 또 ‘흑석’은 바위의 색깔이 검어 유래된 것으로 비가 올 때 물을 머금은 흑석산의 모습은 실제로도 검다. 강진 성전면 제전마을에서 올려다 본 산은 ‘밤하늘의 별처럼 아름답다’고 해서 별뫼산으로 불리지만 혹은 별매산으로 종종 혼용되어 표기한다. 해남군이 세운 이정표에는 별뫼산으로 적고 있어 산이란 뜻의 ‘뫼’로 풀이하면 무리가 없을 듯하다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면, 학산면", + "MNTN_NM" : "흑석산" + }, + "longitude" : 126.633217, + "latitude" : 34.675793599999999 + }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", From 5ef3527a1fde20b4e154cd37348af8c0e2dbb8fc Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 4 Nov 2021 15:48:33 +0900 Subject: [PATCH 052/465] =?UTF-8?q?[Fix]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 2427922..210a1b2 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -6,7 +6,6 @@ // import UIKit -import MapKit protocol Coordinator: AnyObject { var childCoordinator: [Coordinator] { get set } From 8ac861a89c7d62fab8d280e4f334934da82bb5ca Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 16:28:44 +0900 Subject: [PATCH 053/465] =?UTF-8?q?[Fix]=20RecordingUseCase=20Combine=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 95e8231..e915dc4 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -6,28 +6,17 @@ // import Foundation -import Combine protocol RecordingUseCase { - var currentTime: String { get set } - var kilometer: String { get set } - var altitude: String { get set } - var walk: String { get set } var recording: RecordingModel { get set } func save(completion: @escaping (Result) -> Void) } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { - @Published var currentTime = "" - @Published var kilometer = "" - @Published var altitude = "" - @Published var walk = "" - var recording: RecordingModel private let recordRepository: RecordRepository - private var subscriptions = Set() init(recordRepository: RecordRepository, recordingModel: RecordingModel) { self.recordRepository = recordRepository From 3a5dafa58e982d098cb062f91f566053247a8404 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 4 Nov 2021 16:54:42 +0900 Subject: [PATCH 054/465] =?UTF-8?q?[Fix]=20RecordingViewCoordinator=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 16 +++++++--------- .../RecordingScene/RecordingViewController.swift | 2 +- .../RecordingViewCoordinator.swift | 5 +++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 54bb8c7..f1a624b 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -11,12 +11,6 @@ class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController = UINavigationController() var childCoordinator: [Coordinator] = [] - var recordingViewCoordinator: RecordingViewCoordinator? - - init() { - self.recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) - self.recordingViewCoordinator?.parentCoordinator = self - } func start() { } @@ -32,9 +26,13 @@ class MapViewCoordinator: Coordinator { extension MapViewCoordinator { func presentRecordingViewController() { - guard let recordingViewCoordinator = self.recordingViewCoordinator else { return } - self.childCoordinator.append(recordingViewCoordinator) - recordingViewCoordinator.start() + if self.childCoordinator.isEmpty { + let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + self.childCoordinator.append(recordingViewCoordinator) + recordingViewCoordinator.parentCoordinator = self + } + + childCoordinator.first?.start() } private func injectDependencies() -> MapViewModel { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 492b71b..3d105af 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -151,6 +151,6 @@ class RecordingViewController: UIViewController { } @objc private func locationButtonAction(_ sender: UIResponder) { - self.coordinator?.dismiss() + self.coordinator?.hide() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 533de95..a867451 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -26,8 +26,13 @@ class RecordingViewCoordinator: Coordinator { self.navigationController.present(recordingViewController, animated: true) } + func hide() { + self.navigationController.dismiss(animated: true) + } + func dismiss() { self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinator.removeAll() } } From c975000e4426c80bb128e0697bd7a857d85320d8 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 4 Nov 2021 20:35:16 +0900 Subject: [PATCH 055/465] =?UTF-8?q?[Fix]=20=ED=81=B4=EB=9F=AC=EC=8A=A4?= =?UTF-8?q?=ED=84=B0=EB=A7=81=EC=9D=B4=20=EC=A0=95=EC=83=81=EC=A0=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9E=91=EB=8F=99=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 3a91490..65c1907 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -147,12 +147,10 @@ class MapViewController: UIViewController { extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { guard let annotation = annotation as? MountainAnnotation else { return nil } - - guard let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: MountainAnnotationView.ReuseID) as? MountainAnnotationView else { - return MountainAnnotationView(annotation: annotation, reuseIdentifier: MountainAnnotationView.ReuseID) - } - dequeuedView.annotation = annotation - return dequeuedView + return MountainAnnotationView( + annotation: annotation, + reuseIdentifier: MountainAnnotationView.ReuseID + ) } } From 46899a0c17484b9b968cb144e622a81d4f654ae2 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Fri, 5 Nov 2021 22:43:31 +0900 Subject: [PATCH 056/465] =?UTF-8?q?[Feat]=20#73=20=EC=85=80=20=EC=96=91?= =?UTF-8?q?=EC=AA=BD=20=EC=97=AC=EB=B0=B1=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 16 +++++++++++++++- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 6c161e2..023c5ff 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -13,7 +13,7 @@ class MapOptionCell: UITableViewCell { private(set) var title: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 17) + label.font = UIFont.systemFont(ofSize: 14) label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -38,6 +38,20 @@ class MapOptionCell: UITableViewCell { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override var frame: CGRect { + get { + return super.frame + } + set (newFrame) { + var frame = newFrame + let newWidth = frame.width * 0.90 + let space = (frame.width - newWidth) / 2 + frame.size.width = newWidth + frame.origin.x += space + super.frame = frame + } + } private func configureView() { self.contentView.addSubview(self.title) diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 45239df..cb972eb 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -19,7 +19,7 @@ class ToggleOptionCell: UITableViewCell { private var title: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 17) + label.font = UIFont.systemFont(ofSize: 14) label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -41,6 +41,20 @@ class ToggleOptionCell: UITableViewCell { fatalError("init(coder:) has not been implemented") } + override var frame: CGRect { + get { + return super.frame + } + set (newFrame) { + var frame = newFrame + let newWidth = frame.width * 0.90 + let space = (frame.width - newWidth) / 2 + frame.size.width = newWidth + frame.origin.x += space + super.frame = frame + } + } + @objc func onClickSwitch(sender: UISwitch) { guard let title = self.title.text else { return } self.delegate?.toggleOptionCellSwitchChanged(self, From 0654d948c15f25e393db4cfa42478d2d2a52c5c0 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Fri, 5 Nov 2021 22:44:18 +0900 Subject: [PATCH 057/465] =?UTF-8?q?[Feat]=20#73=20=EC=84=B9=EC=85=98=20?= =?UTF-8?q?=EB=AA=A8=EC=84=9C=EB=A6=AC=20=EB=91=A5=EA=B8=80=EA=B2=8C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/SettingsViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 5a19b8b..fc9a053 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -26,10 +26,12 @@ class SettingsViewController: UIViewController { }() private var tableView: UITableView = { - let tableView = UITableView() + let tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.translatesAutoresizingMaskIntoConstraints = false tableView.register(ToggleOptionCell.self, forCellReuseIdentifier: ToggleOptionCell.identifier) tableView.register(MapOptionCell.self, forCellReuseIdentifier: MapOptionCell.identifier) + tableView.backgroundColor = .systemGray5 + tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0) return tableView }() @@ -42,7 +44,6 @@ class SettingsViewController: UIViewController { private func configureTableView() { self.tableView.dataSource = self self.tableView.delegate = self - self.tableView.backgroundColor = .systemGray5 } private func configureView() { From 6cb4b1f4940e7ee5b0b036d2347e40d488f309ba Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Fri, 5 Nov 2021 22:46:01 +0900 Subject: [PATCH 058/465] =?UTF-8?q?[Feat]=20#73=20UISwitch=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index cb972eb..f3d4b67 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -28,6 +28,7 @@ class ToggleOptionCell: UITableViewCell { let controlSwitch = UISwitch() controlSwitch.translatesAutoresizingMaskIntoConstraints = false controlSwitch.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) + controlSwitch.onTintColor = .systemBlue return controlSwitch }() From 83cb2f993d3874e8af3b0e269b5cb1ca45bf319d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Sat, 6 Nov 2021 09:40:08 +0900 Subject: [PATCH 059/465] =?UTF-8?q?[Feat]=20#73=20TableView=20Header=20?= =?UTF-8?q?=EB=8B=A4=ED=81=AC=EB=AA=A8=EB=93=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/SettingsViewController.swift | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index fc9a053..90e4f17 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -13,7 +13,7 @@ class SettingsViewController: UIViewController { private var headerView: UIView = { let headerView = UIView() headerView.translatesAutoresizingMaskIntoConstraints = false - headerView.backgroundColor = .white + headerView.backgroundColor = .systemBackground return headerView }() @@ -31,7 +31,6 @@ class SettingsViewController: UIViewController { tableView.register(ToggleOptionCell.self, forCellReuseIdentifier: ToggleOptionCell.identifier) tableView.register(MapOptionCell.self, forCellReuseIdentifier: MapOptionCell.identifier) tableView.backgroundColor = .systemGray5 - tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0) return tableView }() @@ -47,7 +46,7 @@ class SettingsViewController: UIViewController { } private func configureView() { - self.view.backgroundColor = .white + self.view.backgroundColor = .systemBackground self.view.addSubview(self.headerView) let headerViewConstrain = [ self.headerView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), @@ -96,10 +95,6 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { return 10.0 } - func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - return " " - } - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return settings[section].count } From bd2c9c4a12f19f5f4dcd779819f36dadd91505b5 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Sun, 7 Nov 2021 15:00:58 +0900 Subject: [PATCH 060/465] =?UTF-8?q?[Feat]=20#74=20UserDefaults=20=EB=8B=A4?= =?UTF-8?q?=EB=A3=A8=EB=8A=94=20=EA=B0=9D=EC=B2=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ SanTa/SanTa/SettingsScene/MapOptionCell.swift | 2 +- .../SettingsViewController.swift | 7 ++- .../UserDefaultsSettingsStorage.swift | 55 +++++++++++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 12aefee..2f0ab6d 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -39,6 +39,7 @@ 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; + 98A913012736844E008AAE39 /* UserDefaultsSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; @@ -80,6 +81,7 @@ 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; + 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsSettingsStorage.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; @@ -154,6 +156,7 @@ 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */, 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */, 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, + 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */, ); path = SettingsScene; sourceTree = ""; @@ -336,6 +339,7 @@ 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, + 98A913012736844E008AAE39 /* UserDefaultsSettingsStorage.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 023c5ff..d7d551c 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -71,6 +71,6 @@ class MapOptionCell: UITableViewCell { func update(option: MapOption) { self.title.text = option.text - self.map.text = option.map.description + self.map.text = option.map.name } } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 90e4f17..8920f74 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -76,7 +76,7 @@ class SettingsViewController: UIViewController { private func showMapActionSheet(cellTitle: String) { let alert = UIAlertController(title: "지도형식", message: nil, preferredStyle: .actionSheet) Map.allCases.forEach { - alert.addAction(UIAlertAction(title: $0.description, style: .default, handler: { action in + alert.addAction(UIAlertAction(title: $0.name, style: .default, handler: { action in print(cellTitle, action.title!) })) } @@ -139,12 +139,13 @@ extension SettingsViewController: ToggleOptionCellDelegate { //MARK: - dummy data -enum Map: String, CustomStringConvertible, CaseIterable { +enum Map: String, CaseIterable { + case infomation = "정보지도" case normal = "일반지도" case satellite = "위성지도" - var description: String { + var name: String { return self.rawValue } } diff --git a/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift b/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift new file mode 100644 index 0000000..70eaba8 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift @@ -0,0 +1,55 @@ +// +// UserDefaultSettingsStorage.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/06. +// + +import Foundation + +protocol SettingsStorage { + func save(value: T, key: Settings) + func exist(key: Settings) -> Bool + func bool(key: Settings) -> Bool + func string(key: Settings) -> String? +} + +final class UserDefaultsSettingsStorage: SettingsStorage { + + let userDefaults: UserDefaults + + init(useuserDefaults: UserDefaults = UserDefaults.standard) { + self.userDefaults = useuserDefaults + } + + func save(value: T, key: Settings) { + self.userDefaults.set(value, forKey: key.title) + } + + func exist(key: Settings) -> Bool { + return self.userDefaults.object(forKey: key.title) != nil + } + + func bool(key: Settings) -> Bool { + return self.userDefaults.bool(forKey: key.title) + } + + func string(key: Settings) -> String? { + return self.userDefaults.string(forKey: key.title) + } +} + + +enum Settings: String { + case recordPhoto = "사진 기록하기" + case photosOnMap = "지도에 사진표시" + case autoPauseResume = "자동 일시정지, 재시작" + case autoPauseResumeVoiceGuidance = "자동 일시정지, 재시작 음성 안내" + case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" + case mapFormat = "지도 형식" + case markHikingTrailsOnTheMap = "지도에 등산로 표시" + + var title: String { + return self.rawValue + } +} From ef78ba983cce61870509eb83574cbbc0c9fe8f09 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 8 Nov 2021 12:05:42 +0900 Subject: [PATCH 061/465] [Feat] calculateDistance method --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 ++++++++++ SanTa/SanTa/MapScene/MapViewController.swift | 3 ++ SanTa/SanTa/MapScene/MapViewCoordinator.swift | 6 ++++ .../MountainDetailUseCase.swift | 30 +++++++++++++++++++ .../MountainDetailViewController.swift | 22 ++++++++++++++ .../MountainDetailViewCoordinator.swift | 29 ++++++++++++++++++ .../MountainDetailViewModel.swift | 12 ++++++++ 7 files changed, 118 insertions(+) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 12aefee..56d9c95 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -8,6 +8,10 @@ /* Begin PBXBuildFile section */ 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; + 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; + 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */; }; + 49D5A94D2738C71700937821 /* MountainDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */; }; + 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -47,6 +51,10 @@ /* Begin PBXFileReference section */ 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; + 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; + 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewController.swift; sourceTree = ""; }; + 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewModel.swift; sourceTree = ""; }; + 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailUseCase.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -142,6 +150,10 @@ 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */ = { isa = PBXGroup; children = ( + 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */, + 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */, + 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */, + 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -317,9 +329,11 @@ files = ( 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, + 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */, 984DDEC127325D67003BE56B /* Record.swift in Sources */, + 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, @@ -346,9 +360,11 @@ DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, + 49D5A94D2738C71700937821 /* MountainDetailViewModel.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, + 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 65c1907..e752dc8 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -152,6 +152,9 @@ extension MapViewController: MKMapViewDelegate { reuseIdentifier: MountainAnnotationView.ReuseID ) } + func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { + print(view.annotation?.title) + } } extension MapViewController: CLLocationManagerDelegate { diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index f1a624b..945d682 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -35,6 +35,12 @@ extension MapViewCoordinator { childCoordinator.first?.start() } + func presentMountainDetailViewController() { + for coordinator in childCoordinator { + if coordinator + } + } + private func injectDependencies() -> MapViewModel { return MapViewModel(useCase: MapViewUseCase(repository: DefaultMapViewRespository(mountainExtractor: MountainExtractor()))) } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift new file mode 100644 index 0000000..61b422f --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -0,0 +1,30 @@ +// +// MountainDetailUseCase.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/08. +// + +import Foundation +import CoreLocation + +class MountainDetailUseCase { + private let mountainAnnotation: MountainAnnotation + private let locationManager: CLLocationManager + + init(mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { + self.mountainAnnotation = mountainAnnotation + self.locationManager = locationManager + } + + private func calculateDistance(to mountainLocation: CLLocationCoordinate2D) -> Double? { + let canGetCurrentLocation = locationManager.authorizationStatus == .authorizedWhenInUse || + locationManager.authorizationStatus == .authorizedAlways + guard canGetCurrentLocation, let currentLocation = locationManager.location else { + return nil + } + let distance = currentLocation.distance(from: CLLocation(latitude: mountainLocation.latitude, longitude: mountainLocation.longitude)) + + return distance + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift new file mode 100644 index 0000000..4d582f0 --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -0,0 +1,22 @@ +// +// MountainDetailViewController.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/08. +// + +import UIKit + +class MountainDetailViewController: UIViewController { + weak var mountainDetailViewCoordinator: MountainDetailViewCoordinator? + private var mountainAnnotation: MountainAnnotation? + + convenience init(annotation: MountainAnnotation) { + self.init() + self.mountainAnnotation = annotation + } + + override func viewDidLoad() { + super.viewDidLoad() + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift new file mode 100644 index 0000000..bcd68b4 --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -0,0 +1,29 @@ +// +// MountainDetailViewCoordinator.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/08. +// + +import UIKit + +class MountainDetailViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController + var childCoordinator: [Coordinator] + var mountainDetailViewController: MountainDetailViewController + + func start() { + <#code#> + } + + + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + let viewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) + self.recordingViewController = RecordingViewController(viewModel: viewModel) + self.recordingViewController.coordinator = self + } + +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift new file mode 100644 index 0000000..0be5563 --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift @@ -0,0 +1,12 @@ +// +// MountainDetailViewModel.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/08. +// + +import Foundation + +class MountainDetailViewModel { + +} From b3cd05c7aa84ae8c14675188f7247d024b59345d Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 15:47:48 +0900 Subject: [PATCH 062/465] =?UTF-8?q?[Feat]=20Location=20=EC=A0=95=ED=99=95?= =?UTF-8?q?=EB=8F=84=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 2589bc2..7504ff8 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -50,6 +50,7 @@ final class RecordingModel: NSObject, ObservableObject { private func configureLocationManager() { self.locationManager.requestWhenInUseAuthorization() + self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.delegate = self } From 3c4acf323eb254999b9a653c9cd3077d927aef82 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 15:48:53 +0900 Subject: [PATCH 063/465] =?UTF-8?q?[Feat]=20LocationManager=20Background?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 7504ff8..0cfdd21 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -52,6 +52,7 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.requestWhenInUseAuthorization() self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() + self.locationManager.allowsBackgroundLocationUpdates = true self.locationManager.delegate = self } From 1f0742336bb4fdea7d7bdabcae9990b5254ae81e Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 15:49:43 +0900 Subject: [PATCH 064/465] =?UTF-8?q?[Feat]=20LocationManager=20=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=EC=A0=95=EC=A7=80=20=EC=84=A4=EC=A0=95=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 0cfdd21..e0dbbb8 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -53,6 +53,7 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.allowsBackgroundLocationUpdates = true + self.locationManager.pausesLocationUpdatesAutomatically = true self.locationManager.delegate = self } From 67ffd911da5931bf1f49e69f281908dc67a35c54 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 15:23:04 +0900 Subject: [PATCH 065/465] =?UTF-8?q?[Fix]=20#75=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=EB=90=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 65c1907..6aaf724 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -56,8 +56,6 @@ class MapViewController: UIViewController { private func configureViews() { self.mapView = MKMapView(frame: view.bounds) guard let mapView = mapView else { return } - mapView.showsUserLocation = true - mapView.delegate = self self.view.addSubview(mapView) mapView.showsUserLocation = true mapView.showsScale = true From 44774110bea92dd0a2a274418fd046a23ff078a7 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 15:56:10 +0900 Subject: [PATCH 066/465] =?UTF-8?q?[Refactor]=20#78=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=EC=8B=9C=20Switch=EB=AC=B8=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EB=B6=84=EA=B8=B0=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 6aaf724..fd7dede 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -28,10 +28,10 @@ class MapViewController: UIViewController { } override func viewWillAppear(_ animated: Bool) { - if manager.authorizationStatus == .authorizedAlways || - manager.authorizationStatus == .authorizedWhenInUse { + switch self.manager.authorizationStatus { + case .authorizedAlways, .authorizedWhenInUse: userTrackingButton.isHidden = false - } else { + default: userTrackingButton.isHidden = true } } @@ -155,15 +155,17 @@ extension MapViewController: MKMapViewDelegate { extension MapViewController: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.first { - manager.stopUpdatingLocation() + self.manager.stopUpdatingLocation() self.render(location) } } func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - if manager.authorizationStatus == .authorizedWhenInUse || - manager.authorizationStatus == .authorizedAlways { + switch self.manager.authorizationStatus { + case .authorizedAlways, .authorizedWhenInUse: userTrackingButton.isHidden = false + default: + userTrackingButton.isHidden = true } } } From 80e7f04412c216f5d5b57b1409253fb8d5e459a1 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 16:07:58 +0900 Subject: [PATCH 067/465] =?UTF-8?q?[Feat]=20Timer=20Type=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingModel.swift | 10 ++++++---- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 487f807..4f1f035 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,7 +8,7 @@ import Foundation struct Record { - let time: Int + let time: Date let step: Int let distance: Double diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index e0dbbb8..0e38a64 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -24,7 +24,7 @@ final class RecordingModel: NSObject, ObservableObject { private var currentKilo: Double = 0 private var location = [Location]() - private var currentTime = 0 { + private var currentTime = Date() { didSet { self.timeConverter() self.checkPedoMeter() @@ -58,9 +58,11 @@ final class RecordingModel: NSObject, ObservableObject { } private func timeConverter() { - let seconds = currentTime % 60 - let minutes = (currentTime / 60) % 60 - let hours = (currentTime / 3600) + let elapsedTimeSeconds = Int(Date().timeIntervalSince(self.currentTime)) + + let seconds = elapsedTimeSeconds % 60 + let minutes = (elapsedTimeSeconds / 60) % 60 + let hours = (elapsedTimeSeconds / 3600) time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index e915dc4..16bdae8 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -24,6 +24,6 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func save(completion: @escaping (Result) -> Void) { - self.recordRepository.save(record: recording.cancel(), completion: completion) +// self.recordRepository.save(record: recording.cancel(), completion: completion) } } From cde1c48af7613203079d28cad0f4c8c9a572dc1b Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 16:10:13 +0900 Subject: [PATCH 068/465] =?UTF-8?q?[Feat]=20=EC=84=A4=EC=A0=95=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=20=EC=93=B0=EC=9D=B4=EB=8A=94=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/Option.swift | 33 +++++++++++++++ SanTa/SanTa/SettingsScene/Settings.swift | 41 +++++++++++++++++++ .../SettingsScene/SettingsRepository.swift | 8 ++++ .../SanTa/SettingsScene/SettingsUsecase.swift | 8 ++++ .../SettingsScene/SettingsViewModel.swift | 8 ++++ 5 files changed, 98 insertions(+) create mode 100644 SanTa/SanTa/SettingsScene/Option.swift create mode 100644 SanTa/SanTa/SettingsScene/Settings.swift create mode 100644 SanTa/SanTa/SettingsScene/SettingsRepository.swift create mode 100644 SanTa/SanTa/SettingsScene/SettingsUsecase.swift create mode 100644 SanTa/SanTa/SettingsScene/SettingsViewModel.swift diff --git a/SanTa/SanTa/SettingsScene/Option.swift b/SanTa/SanTa/SettingsScene/Option.swift new file mode 100644 index 0000000..2b8a9f4 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/Option.swift @@ -0,0 +1,33 @@ +// +// Option.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/08. +// + +import Foundation + +enum Map: String, CaseIterable { + + case infomation = "정보지도" + case normal = "일반지도" + case satellite = "위성지도" + + var name: String { + return self.rawValue + } +} + +protocol Option { + var text: String { get } +} + +struct ToggleOption: Option { + let text: String + let toggle: Bool +} + +struct MapOption: Option { + let text: String + let map: Map +} diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/SettingsScene/Settings.swift new file mode 100644 index 0000000..3d210ca --- /dev/null +++ b/SanTa/SanTa/SettingsScene/Settings.swift @@ -0,0 +1,41 @@ +// +// Settings.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/08. +// + +import Foundation + +enum Settings: String, CaseIterable { + case recordPhoto = "사진 기록하기" + case photosOnMap = "지도에 사진표시" + case autoPauseResume = "자동 일시정지, 재시작" + case autoPauseResumeVoiceGuidance = "자동 일시정지, 재시작 음성 안내" + case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" + case mapFormat = "지도 형식" + case markHikingTrailsOnTheMap = "지도에 등산로 표시" + + var title: String { + return self.rawValue + } + + var initValue: Any { + switch self { + case .recordPhoto: + return true + case .photosOnMap: + return true + case .autoPauseResume: + return false + case .autoPauseResumeVoiceGuidance: + return false + case .voiceGuidanceEveryOnekm: + return true + case .mapFormat: + return "정보지도" + case .markHikingTrailsOnTheMap: + return true + } + } +} diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift new file mode 100644 index 0000000..27970bf --- /dev/null +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -0,0 +1,8 @@ +// +// SettingRepository.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/07. +// + +import Foundation diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift new file mode 100644 index 0000000..a08d6c9 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -0,0 +1,8 @@ +// +// SettingsUsecase.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/07. +// + +import Foundation diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift new file mode 100644 index 0000000..611e564 --- /dev/null +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -0,0 +1,8 @@ +// +// File.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/07. +// + +import Foundation From d326957dd36092cbd087cfbef8bc89b05ea527ba Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 16:15:27 +0900 Subject: [PATCH 069/465] =?UTF-8?q?[Feat]=20Background=20Modes=20Location?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 ++++++ SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 ++++-- SanTa/SanTa/Resources/Info.plist | 10 ++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 12aefee..939ed02 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -492,6 +492,9 @@ DEVELOPMENT_TEAM = B3PWYBKFUK; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = SanTa/Resources/Info.plist; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Please allow to use app on background"; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Please allow to see current location"; + INFOPLIST_KEY_NSMotionUsageDescription = "Allow my app to access motion usage."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; @@ -519,6 +522,9 @@ DEVELOPMENT_TEAM = B3PWYBKFUK; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = SanTa/Resources/Info.plist; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Please allow to use app on background"; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Please allow to see current location"; + INFOPLIST_KEY_NSMotionUsageDescription = "Allow my app to access motion usage."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 0e38a64..46f81a7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -42,7 +42,7 @@ final class RecordingModel: NSObject, ObservableObject { self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) self.timer?.schedule(deadline: .now(), repeating: 1) self.timer?.setEventHandler(handler: { [weak self] in - self?.currentTime += 1 + self?.currentTime = Date() }) self.resume() @@ -58,7 +58,9 @@ final class RecordingModel: NSObject, ObservableObject { } private func timeConverter() { - let elapsedTimeSeconds = Int(Date().timeIntervalSince(self.currentTime)) + guard let startDate = self.date else { return } + + let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) let seconds = elapsedTimeSeconds % 60 let minutes = (elapsedTimeSeconds / 60) % 60 diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index 24dc5da..bf8c508 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,12 +2,6 @@ - NSMotionUsageDescription - Allow my app to access motion usage. - NSLocationWhenInUseUsageDescription - Please allow to see current location - NSLocationAlwaysAndWhenInUseUsageDescription - Please allow to use app on background UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -25,5 +19,9 @@ + UIBackgroundModes + + location + From 5f08a3fdd041902d8f20f7f263ca3c38122aae58 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 16:12:41 +0900 Subject: [PATCH 070/465] =?UTF-8?q?[Feat]=20#74=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Retositoy=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SettingsScene/SettingsRepository.swift | 48 +++++++++++++++++++ .../UserDefaultsSettingsStorage.swift | 33 ++++--------- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift index 27970bf..9d3e18d 100644 --- a/SanTa/SanTa/SettingsScene/SettingsRepository.swift +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -6,3 +6,51 @@ // import Foundation + +protocol SettingsRepository { + func save(value: T, key: Settings) + func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) + func getMapOption(key: Settings, completion: @escaping (Option) -> Void) +} + +final class DefaultSettingsRepository: SettingsRepository { + + let settingsStorage: SettingsStorage + + init(settingsStorage: SettingsStorage) { + self.settingsStorage = settingsStorage + } + + func save(value: T, key: Settings) { + self.settingsStorage.save(value: value, key: key) + } + + func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) { + self.settingsStorage.exist(key: key) { exist in + if !exist { + guard let value = key.initValue as? Bool else { return } + self.settingsStorage.save(value: value, key: key) + } + self.settingsStorage.bool(key: key) { value in + let option = ToggleOption(text: key.title, toggle: value) + completion(option) + } + } + } + + func getMapOption(key: Settings, completion: @escaping (Option) -> Void) { + self.settingsStorage.exist(key: key) { exist in + if !exist { + guard let value = key.initValue as? String else { return } + self.settingsStorage.save(value: value, key: key) + } + self.settingsStorage.string(key: key) { value in + guard let value = value else { return } + guard let map = Map.init(rawValue: value) else { return } + let option = MapOption(text: key.title, map: map) + completion(option) + } + } + } +} + diff --git a/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift b/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift index 70eaba8..4f21757 100644 --- a/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift +++ b/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift @@ -9,9 +9,9 @@ import Foundation protocol SettingsStorage { func save(value: T, key: Settings) - func exist(key: Settings) -> Bool - func bool(key: Settings) -> Bool - func string(key: Settings) -> String? + func exist(key: Settings, completion: @escaping (Bool) -> Void) + func bool(key: Settings, completion: @escaping (Bool) -> Void) + func string(key: Settings, completion: @escaping (String?) -> Void) } final class UserDefaultsSettingsStorage: SettingsStorage { @@ -26,30 +26,15 @@ final class UserDefaultsSettingsStorage: SettingsStorage { self.userDefaults.set(value, forKey: key.title) } - func exist(key: Settings) -> Bool { - return self.userDefaults.object(forKey: key.title) != nil + func exist(key: Settings, completion: @escaping (Bool) -> Void) { + completion(self.userDefaults.object(forKey: key.title) != nil) } - func bool(key: Settings) -> Bool { - return self.userDefaults.bool(forKey: key.title) + func bool(key: Settings, completion: @escaping (Bool) -> Void) { + completion(self.userDefaults.bool(forKey: key.title)) } - func string(key: Settings) -> String? { - return self.userDefaults.string(forKey: key.title) - } -} - - -enum Settings: String { - case recordPhoto = "사진 기록하기" - case photosOnMap = "지도에 사진표시" - case autoPauseResume = "자동 일시정지, 재시작" - case autoPauseResumeVoiceGuidance = "자동 일시정지, 재시작 음성 안내" - case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" - case mapFormat = "지도 형식" - case markHikingTrailsOnTheMap = "지도에 등산로 표시" - - var title: String { - return self.rawValue + func string(key: Settings, completion: @escaping (String?) -> Void) { + completion(self.userDefaults.string(forKey: key.title)) } } From a991d84309db335f79947fafc3d67d596e6a429f Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 16:17:36 +0900 Subject: [PATCH 071/465] =?UTF-8?q?[Feat]=20#83=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20UseCase=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/SettingsScene/SettingsUsecase.swift | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index a08d6c9..4c6cc04 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -6,3 +6,59 @@ // import Foundation + +protocol SettingsUsecase { + func save(value: T, key: Settings) + func makeSettings() -> [[Option]] +} + +final class DefaultSettingsUsecase: SettingsUsecase { + + let settingsRepository: SettingsRepository + + init(settingsRepository: SettingsRepository) { + self.settingsRepository = settingsRepository + } + + func save(value: T, key: Settings) { + self.settingsRepository.save(value: value, key: key) + } + + func makeSettings() -> [[Option]] { + var options: [[Option]] = [] + var photoSettings: [Option] = [] + var autoSettins: [Option] = [] + var voiceSettings: [Option] = [] + var mapSetting: [Option] = [] + + self.settingsRepository.getToggleOption(key: Settings.recordPhoto) { value in + photoSettings.append(value) + } + self.settingsRepository.getToggleOption(key: Settings.photosOnMap) { value in + photoSettings.append(value) + } + self.settingsRepository.getToggleOption(key: Settings.autoPauseResume) { value in + autoSettins.append(value) + } + self.settingsRepository.getToggleOption(key: Settings.autoPauseResumeVoiceGuidance) { value in + autoSettins.append(value) + } + self.settingsRepository.getToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in + voiceSettings.append(value) + } + self.settingsRepository.getMapOption(key: Settings.mapFormat) { value in + mapSetting.append(value) + } + self.settingsRepository.getToggleOption(key: Settings.markHikingTrailsOnTheMap) { value in + mapSetting.append(value) + } + + options.append(photoSettings) + options.append(autoSettins) + options.append(voiceSettings) + options.append(mapSetting) + + return options + } +} + From f476e05ca7c5d1de2b9b46dee4d4c3101cf2c25f Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 16:18:57 +0900 Subject: [PATCH 072/465] =?UTF-8?q?[Feat]=20#84=20ViewModel=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20View=20=EB=B0=94=EC=9D=B8=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SettingsViewController.swift | 78 +++++++------------ .../SettingsScene/SettingsViewModel.swift | 31 ++++++++ 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 8920f74..147c449 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -6,10 +6,11 @@ // import UIKit +import Combine class SettingsViewController: UIViewController { weak var coordinator: SettingsViewCoordinator? - + private var headerView: UIView = { let headerView = UIView() headerView.translatesAutoresizingMaskIntoConstraints = false @@ -34,10 +35,20 @@ class SettingsViewController: UIViewController { return tableView }() + private var viewModel: SettingsViewModel? + private var subscriptions = Set() + + convenience init(viewModel: SettingsViewModel) { + self.init() + self.viewModel = viewModel + } + override func viewDidLoad() { super.viewDidLoad() self.configureTableView() self.configureView() + self.bind() + self.viewModel?.viewDidLoad() } private func configureTableView() { @@ -73,11 +84,19 @@ class SettingsViewController: UIViewController { NSLayoutConstraint.activate(tableViewConstrain) } + private func bind() { + self.viewModel?.$settings.sink { [weak self] _ in + self?.tableView.reloadData() + }.store(in: &self.subscriptions) + } + private func showMapActionSheet(cellTitle: String) { - let alert = UIAlertController(title: "지도형식", message: nil, preferredStyle: .actionSheet) + let alert = UIAlertController(title: Settings.mapFormat.title, message: nil, preferredStyle: .actionSheet) Map.allCases.forEach { alert.addAction(UIAlertAction(title: $0.name, style: .default, handler: { action in - print(cellTitle, action.title!) + guard let title = action.title else { return } + guard let key = Settings(rawValue: cellTitle) else { return } + self.viewModel?.change(value: title, key: key) })) } alert.addAction(UIAlertAction(title: "닫기", style: .cancel, handler: nil)) @@ -88,7 +107,7 @@ class SettingsViewController: UIViewController { extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { func numberOfSections(in tableView: UITableView) -> Int { - return 4 + return self.viewModel?.sectionCount ?? 0 } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { @@ -96,11 +115,12 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return settings[section].count + guard let itemCount = self.viewModel?.settings[section].count else { return 0 } + return itemCount } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch settings[indexPath.section][indexPath.item] { + switch self.viewModel?.settings[indexPath.section][indexPath.item] { case let option as ToggleOption: guard let cell = self.tableView.dequeueReusableCell(withIdentifier: ToggleOptionCell.identifier, for: indexPath) as? ToggleOptionCell @@ -133,49 +153,7 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { extension SettingsViewController: ToggleOptionCellDelegate { func toggleOptionCellSwitchChanged(_ cell: ToggleOptionCell, title: String, switchOn: Bool) { - print(title, switchOn) - } -} - -//MARK: - dummy data - -enum Map: String, CaseIterable { - - case infomation = "정보지도" - case normal = "일반지도" - case satellite = "위성지도" - - var name: String { - return self.rawValue + guard let key = Settings(rawValue: title) else { return } + self.viewModel?.change(value: switchOn, key: key) } } - -protocol Option { - var text: String { get } -} - -struct ToggleOption: Option { - let text: String - let toggle: Bool -} - -struct MapOption: Option { - let text: String - let map: Map -} - -let photoSettings1 = ToggleOption(text: "사진 기록하기", toggle: true) -let photoSettings2 = ToggleOption(text: "지도에 사진표시", toggle: true) - -let autoSettins1 = ToggleOption(text: "자동 일시정지/재시작", toggle: false) -let autoSettins2 = ToggleOption(text: "자동 일시정지/재시작 음성 안내", toggle: false) - -let voiceSettings1 = ToggleOption(text: "1킬로미터 마다 음성 안내", toggle: true) - -let mapSetting1 = MapOption(text: "지도 형식", map: .infomation) -let mapSetting2 = ToggleOption(text: "지도에 등산로 표시", toggle: true) - -let settings: [[Option]] = [[photoSettings1, photoSettings2], - [autoSettins1, autoSettins2], - [voiceSettings1], - [mapSetting1, mapSetting2]] diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift index 611e564..37ff192 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -6,3 +6,34 @@ // import Foundation +import Combine + +final class SettingsViewModel { + + @Published var settings: [[Option]] = [] + + let settingsUseCase: SettingsUsecase + + var sectionCount: Int { + return settings.count + } + + init(settingsUseCase: SettingsUsecase) { + self.settingsUseCase = settingsUseCase + } + + func viewDidLoad() { + self.reloadSettings() + } + + func change(value: T, key: Settings) { + self.settingsUseCase.save(value: value, key: key) + if value is String { + self.reloadSettings() + } + } + + private func reloadSettings() { + self.settings = self.settingsUseCase.makeSettings() + } +} From ee840b9ad5c8f2aceef0978a075949bcb874c671 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 16:19:35 +0900 Subject: [PATCH 073/465] =?UTF-8?q?[Feat]=20#84=20Coordinator=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 26 ++++++++++++++++--- .../SettingsViewCoordinator.swift | 14 +++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 2f0ab6d..99cabab 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -31,6 +31,8 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; + 9826F3DD2739035E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; + 9826F3DF273904010064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; @@ -41,6 +43,9 @@ 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; 98A913012736844E008AAE39 /* UserDefaultsSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; + 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; + 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; + 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; @@ -73,6 +78,8 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9826F3DC2739035E0064FA85 /* Option.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = ""; }; + 9826F3DE273904010064FA85 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; 984DDEC027325D67003BE56B /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCase.swift; sourceTree = ""; }; 984DDEC427325FB9003BE56B /* RecordRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordRepository.swift; sourceTree = ""; }; @@ -83,6 +90,9 @@ 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsSettingsStorage.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; + 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; + 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; @@ -151,12 +161,17 @@ 5428FDBB272F8C32002F9D40 /* SettingsScene */ = { isa = PBXGroup; children = ( - 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */, - 54296954272FC3EC0070B362 /* SettingsViewController.swift */, + 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */, 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */, - 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, + 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */, + 54296954272FC3EC0070B362 /* SettingsViewController.swift */, + 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */, + 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */, + 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */, 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */, + 9826F3DE273904010064FA85 /* Settings.swift */, + 9826F3DC2739035E0064FA85 /* Option.swift */, ); path = SettingsScene; sourceTree = ""; @@ -325,6 +340,7 @@ 984DDEC127325D67003BE56B /* Record.swift in Sources */, 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, + 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, @@ -335,6 +351,7 @@ 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, + 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, @@ -346,12 +363,15 @@ 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, + 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, + 9826F3DF273904010064FA85 /* Settings.swift in Sources */, 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, + 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 493e8d1..668db7f 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -12,12 +12,24 @@ class SettingsViewCoordinator: Coordinator { var childCoordinator: [Coordinator] = [] func start() { + } func startPush() -> SettingsViewController { - let settingsViewController = SettingsViewController() + let settingsViewController = injectDependencies() settingsViewController.coordinator = self return settingsViewController } } + +extension SettingsViewCoordinator { + private func injectDependencies() -> SettingsViewController { + let persistence = UserDefaultsSettingsStorage() + let repository = DefaultSettingsRepository(settingsStorage: persistence) + let usecase = DefaultSettingsUsecase(settingsRepository: repository) + let viewModel = SettingsViewModel(settingsUseCase: usecase) + let viewController = SettingsViewController(viewModel: viewModel) + return viewController + } +} From c988d817d79b5d6ab8e3ff10c43348e5bf32c1c4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 16:25:34 +0900 Subject: [PATCH 074/465] =?UTF-8?q?[Feat]=20startTime,=20endTime=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 3 ++- SanTa/SanTa/RecordingScene/RecordingModel.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 4f1f035..cf90373 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,7 +8,8 @@ import Foundation struct Record { - let time: Date + let startTime: Date + let endTime: Date let step: Int let distance: Double diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 46f81a7..028ee52 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -101,7 +101,8 @@ final class RecordingModel: NSObject, ObservableObject { } func cancel() -> Record { - let resultRecord = Record(time: self.currentTime, + let resultRecord = Record(startTime: self.time, + endTime: self.currentTime, step: self.currentWalk, distance: self.currentKilo, locations: self.location) From e5ce7fbf4a42df4858de89fef5f0eb189e535867 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 16:28:18 +0900 Subject: [PATCH 075/465] =?UTF-8?q?[Feat]=20#81=20startTime,=20endTime=20R?= =?UTF-8?q?ecord=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 028ee52..2d33225 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -100,8 +100,10 @@ final class RecordingModel: NSObject, ObservableObject { timer?.resume() } - func cancel() -> Record { - let resultRecord = Record(startTime: self.time, + func cancel() -> Record? { + guard let date = self.date else { return nil } + + let resultRecord = Record(startTime: date, endTime: self.currentTime, step: self.currentWalk, distance: self.currentKilo, From 8874f5b1c29ef3b9e0de1bb1458bb26bd0ece9ea Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 16:31:48 +0900 Subject: [PATCH 076/465] =?UTF-8?q?[Feat]=20#79=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=B8=A1=EC=A0=95=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EC=9D=B4=EC=A0=84=EC=97=90=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=97=AC=EB=B6=80=EB=A5=BC=20=ED=99=95=EC=9D=B8?= =?UTF-8?q?=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index fd7dede..071dcff 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -136,9 +136,26 @@ class MapViewController: UIViewController { let region = MKCoordinateRegion(center: coordinate, span: span) mapView.setRegion(region, animated: true) } + + private func authAlert() -> UIAlertController { + let alert = UIAlertController(title: "위치정보 활성화", message: "지도에 현재 위치를 표시할 수 있도록 위치정보를 활성화해주세요", preferredStyle: .alert) + let cancel = UIAlertAction(title: "아니요", style: .cancel) + let confirm = UIAlertAction(title: "활성화", style: .default) { _ in + guard let url = URL(string: UIApplication.openSettingsURLString) else { return } + UIApplication.shared.open(url) + } + alert.addAction(cancel) + alert.addAction(confirm) + return alert + } @objc private func presentRecordingViewController() { - coordinator?.presentRecordingViewController() + switch self.manager.authorizationStatus{ + case .authorizedWhenInUse, .authorizedAlways: + self.coordinator?.presentRecordingViewController() + default: + self.present(authAlert(), animated: false) + } } } From f1097f2cdbdc2dea18434a05eaf12801441552ae Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 8 Nov 2021 16:34:31 +0900 Subject: [PATCH 077/465] [Feat] Mountain Detail View UseCase, ViewModel --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ SanTa/SanTa/MapScene/MapViewController.swift | 10 ++++- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- SanTa/SanTa/MapScene/MountainAnnotation.swift | 7 +++- .../MountainDetailModel.swift | 18 ++++++++ .../MountainDetailUseCase.swift | 20 +++++++-- .../MountainDetailViewController.swift | 19 +++++++-- .../MountainDetailViewCoordinator.swift | 34 ++++++++------- .../MountainDetailViewModel.swift | 41 +++++++++++++++++++ 9 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 56d9c95..74b51a8 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */; }; 49D5A94D2738C71700937821 /* MountainDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */; }; 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */; }; + 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -55,6 +56,7 @@ 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewController.swift; sourceTree = ""; }; 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewModel.swift; sourceTree = ""; }; 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailUseCase.swift; sourceTree = ""; }; + 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailModel.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -154,6 +156,7 @@ 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */, 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */, 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */, + 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -345,6 +348,7 @@ DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, + 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index e752dc8..f432959 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -47,7 +47,9 @@ class MapViewController: UIViewController { title: mountainEntity.mountain.mountainName, subtitle: mountainEntity.mountain.mountainHeight, latitude: mountainEntity.latitude, - longitude: mountainEntity.longitude + longitude: mountainEntity.longitude, + mountainDescription: mountainEntity.mountain.mountainShortDescription, + region: mountainEntity.mountain.mountainRegion ) mapView?.addAnnotation(mountainAnnotation) } @@ -153,7 +155,11 @@ extension MapViewController: MKMapViewDelegate { ) } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { - print(view.annotation?.title) + guard let annotation = view.annotation as? MountainAnnotation else { return } + + + + //navigate using annotation } } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 945d682..ede2bee 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -37,7 +37,7 @@ extension MapViewCoordinator { func presentMountainDetailViewController() { for coordinator in childCoordinator { - if coordinator + } } diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index 33ed817..c5d9708 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -12,14 +12,19 @@ class MountainAnnotation: NSObject, MKAnnotation { var subtitle: String? var latitude: Double var longitude: Double + var mountainDescription: String + var region: String + var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - init(title: String, subtitle: String, latitude: Double, longitude: Double) { + init(title: String, subtitle: String, latitude: Double, longitude: Double, mountainDescription: String, region: String) { self.title = title self.subtitle = subtitle self.latitude = latitude self.longitude = longitude + self.mountainDescription = mountainDescription + self.region = region } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailModel.swift new file mode 100644 index 0000000..e8f9552 --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailModel.swift @@ -0,0 +1,18 @@ +// +// MountainDetailModel.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/08. +// + +import Foundation + +struct MountainDetailModel { + let moutainName: String + let distance: Double? + let regions: [String] + let altitude: String + let latitude: Double + let longitude: Double + let mountainDescription: String +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 61b422f..26ef51f 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -17,14 +17,28 @@ class MountainDetailUseCase { self.locationManager = locationManager } - private func calculateDistance(to mountainLocation: CLLocationCoordinate2D) -> Double? { + private func calculateDistance() -> Double? { let canGetCurrentLocation = locationManager.authorizationStatus == .authorizedWhenInUse || - locationManager.authorizationStatus == .authorizedAlways + locationManager.authorizationStatus == .authorizedAlways guard canGetCurrentLocation, let currentLocation = locationManager.location else { return nil } - let distance = currentLocation.distance(from: CLLocation(latitude: mountainLocation.latitude, longitude: mountainLocation.longitude)) + let mountainLocation = CLLocation(latitude: self.mountainAnnotation.latitude, longitude: self.mountainAnnotation.longitude) + let distance = currentLocation.distance(from: CLLocation(latitude: mountainLocation.coordinate.latitude, longitude: mountainLocation.coordinate.longitude)) return distance } + + private func mountainRegions() -> [String] { + return mountainAnnotation.region.components(separatedBy: ", ") + } +} + +extension MountainDetailUseCase { + func transferMountainInformation(completion: @escaping (MountainDetailModel) -> Void) { + guard let name = mountainAnnotation.title, + let altitude = mountainAnnotation.subtitle else { return } + + completion(MountainDetailModel(moutainName: name, distance: calculateDistance(), regions: mountainRegions(), altitude: altitude, latitude: mountainAnnotation.latitude, longitude: mountainAnnotation.longitude, mountainDescription: mountainAnnotation.mountainDescription)) + } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 4d582f0..2325dc9 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -9,14 +9,27 @@ import UIKit class MountainDetailViewController: UIViewController { weak var mountainDetailViewCoordinator: MountainDetailViewCoordinator? - private var mountainAnnotation: MountainAnnotation? + private var viewModel: MountainDetailViewModel? - convenience init(annotation: MountainAnnotation) { + convenience init(viewModel: MountainDetailViewModel) { self.init() - self.mountainAnnotation = annotation + self.viewModel = viewModel } override func viewDidLoad() { super.viewDidLoad() } + + private func configureViewModel() { + self.viewModel?.mountainInfoReceived = { mountainDetail in + self.layoutMountainDetailView(mountainDetail: mountainDetail) + } + viewModel?.setUpViewModel() + } +} + +extension MountainDetailViewController { + private func layoutMountainDetailView(mountainDetail: MountainDetailModel) { + + } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index bcd68b4..ebe6223 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -7,23 +7,21 @@ import UIKit -class MountainDetailViewCoordinator: Coordinator { - weak var parentCoordinator: Coordinator? - var navigationController: UINavigationController - var childCoordinator: [Coordinator] - var mountainDetailViewController: MountainDetailViewController +//class MountainDetailViewCoordinator: Coordinator { +// weak var parentCoordinator: Coordinator? +// var navigationController: UINavigationController +// var childCoordinator: [Coordinator] +// var mountainDetailViewController: MountainDetailViewController - func start() { - <#code#> - } +// func start() { +// <#code#> +// } +// +// +// +// init(navigationController: UINavigationController) { +// self.navigationController = navigationController +// let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: <#T##MountainAnnotation#>, locationManager: <#T##CLLocationManager#>), mountainInfo: <#T##MountainDetailModel#>) +// } - - - init(navigationController: UINavigationController) { - self.navigationController = navigationController - let viewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) - self.recordingViewController = RecordingViewController(viewModel: viewModel) - self.recordingViewController.coordinator = self - } - -} +//} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift index 0be5563..cca0040 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift @@ -8,5 +8,46 @@ import Foundation class MountainDetailViewModel { + private let useCase: MountainDetailUseCase + var mountainDetail: MountainDetailModel? + var mountainInfoReceived: (MountainDetailModel) -> Void = { info in } + init(useCase: MountainDetailUseCase) { + self.useCase = useCase + } + + func setUpViewModel() { + useCase.transferMountainInformation { [weak self] mountainInfo in + self?.mountainDetail = mountainInfo + self?.mountainInfoReceived(mountainInfo) + } + } + +// func mountainName() -> String { +// return self.mountainDetail.moutainName +// } +// +// func distanceToMountainFromCurrentLocation() -> Double? { +// return self.mountainDetail.distance +// } +// +// func mountainRegions() -> [String] { +// return self.mountainDetail.regions +// } +// +// func altitude() -> String { +// return self.mountainDetail.altitude + "m" +// } +// +// func mountainDescription() -> String { +// return self.mountainDetail.mountainDescription +// } +// +// func latitude() -> Double { +// return self.mountainDetail.latitude +// } +// +// func longitude() -> Double { +// return self.mountainDetail.longitude +// } } From 7250065a59b72f4275e968913f122dc3c91b688b Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 8 Nov 2021 17:35:27 +0900 Subject: [PATCH 078/465] [Feat] MountainDetailView Dummy View --- .../MountainDetailViewController.swift | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 2325dc9..b89c31b 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -6,9 +6,10 @@ // import UIKit +import MapKit class MountainDetailViewController: UIViewController { - weak var mountainDetailViewCoordinator: MountainDetailViewCoordinator? +// weak var mountainDetailViewCoordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? convenience init(viewModel: MountainDetailViewModel) { @@ -30,6 +31,56 @@ class MountainDetailViewController: UIViewController { extension MountainDetailViewController { private func layoutMountainDetailView(mountainDetail: MountainDetailModel) { + let mapSnapShot = upperMapHeaderView(mountainDetail: mountainDetail) + let titleView = lowerMountainTitleView(mountainDetail: mountainDetail) + let tableView = configuredTableView(mountainDetail: mountainDetail) + let mapConstraints = [ + mapSnapShot.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3), + mapSnapShot.topAnchor.constraint(equalTo: view.topAnchor), + mapSnapShot.leftAnchor.constraint(equalTo: view.leftAnchor), + mapSnapShot.rightAnchor.constraint(equalTo: view.rightAnchor) + + ] + NSLayoutConstraint.activate(mapConstraints) + + let titleViewConstraints = [ + titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor), + titleView.leftAnchor.constraint(equalTo: view.leftAnchor), + titleView.rightAnchor.constraint(equalTo: view.rightAnchor), + titleView.heightAnchor.constraint(equalToConstant: 100) + ] + NSLayoutConstraint.activate(titleViewConstraints) + + let tableViewConstraints = [ + tableView.topAnchor.constraint(equalTo: titleView.bottomAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + tableView.leftAnchor.constraint(equalTo: view.leftAnchor), + tableView.rightAnchor.constraint(equalTo: view.rightAnchor) + ] + NSLayoutConstraint.activate(tableViewConstraints) + } + + private func configuredTableView(mountainDetail: MountainDetailModel) -> UITableView { + return UITableView() + } + + private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { +// let mapOptions = MKMapSnapshotter.Options.init() +// mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan()) +// mapOptions.size = CGSize(width: view.bounds.width, height: view.bounds.height / 3) +// mapOptions.mapType = .satellite +// let mountainAnnotationView = MountainAnnotationView(annotation: MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: mountainDetail.regions.join), reuseIdentifier: MountainAnnotationView.ReuseID) +// mountainAnnotationView.canShowCallout = true +// mountainAnnotationView.calloutOffset = CGPoint(x: 0, y: 5) + let imgVIew = UIImageView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height / 3)) + imgVIew.backgroundColor = .yellow + return imgVIew + } + + private func lowerMountainTitleView(mountainDetail: MountainDetailModel) -> UIView { + let empty = UIView() + empty.backgroundColor = .blue + return empty } } From d069186311e3155f5d08a585ebcdf3f61392070c Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 17:47:26 +0900 Subject: [PATCH 079/465] =?UTF-8?q?[Feat]=20Background=20GPS=20Tracking=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index b5e1c76..6300fa1 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -25,7 +25,7 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage.performBackgroundTask { context in let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", into: context) - recordObject.setValue(record.time, forKey: "time") +// recordObject.setValue(record.time, forKey: "time") recordObject.setValue(record.distance, forKey: "distance") recordObject.setValue(record.step, forKey: "step") diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 2d33225..27ffa5d 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -54,6 +54,7 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.startUpdatingLocation() self.locationManager.allowsBackgroundLocationUpdates = true self.locationManager.pausesLocationUpdatesAutomatically = true + self.locationManager.showsBackgroundLocationIndicator = true self.locationManager.delegate = self } From 37728d7e90c0ba2c53c4e5236bc3a8777ce17e01 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 18:06:57 +0900 Subject: [PATCH 080/465] =?UTF-8?q?[Feat]=20MapViewController=EA=B0=80=20R?= =?UTF-8?q?ecordingView=EC=9D=98=20Hide=EC=99=80=20Dismiss=EC=97=90=20?= =?UTF-8?q?=EB=B0=98=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 8 ++++++++ SanTa/SanTa/MapScene/MapViewCoordinator.swift | 10 ++++++++++ .../RecordingScene/RecordingViewCoordinator.swift | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 071dcff..88b86b8 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -157,6 +157,14 @@ class MapViewController: UIViewController { self.present(authAlert(), animated: false) } } + + func presentAnimation() { + print("1") + } + + func unpresentAnimation(){ + print("2") + } } extension MapViewController: MKMapViewDelegate { diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index f1a624b..bad5e5b 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -9,6 +9,7 @@ import UIKit class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? + weak var mapViewController: MapViewController? var navigationController: UINavigationController = UINavigationController() var childCoordinator: [Coordinator] = [] @@ -18,6 +19,7 @@ class MapViewCoordinator: Coordinator { func startPush() -> UINavigationController { let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self + self.mapViewController = mapViewController self.navigationController.setViewControllers([mapViewController], animated: false) return navigationController @@ -35,6 +37,14 @@ extension MapViewCoordinator { childCoordinator.first?.start() } + func recordingViewDidHide(){ + self.mapViewController?.presentAnimation() + } + + func recordingViewDidDismiss(){ + self.mapViewController?.unpresentAnimation() + } + private func injectDependencies() -> MapViewModel { return MapViewModel(useCase: MapViewUseCase(repository: DefaultMapViewRespository(mountainExtractor: MountainExtractor()))) } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index a867451..efde4f3 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -28,10 +28,14 @@ class RecordingViewCoordinator: Coordinator { func hide() { self.navigationController.dismiss(animated: true) + guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } + mapViewCoordinator.recordingViewDidHide() } func dismiss() { self.navigationController.dismiss(animated: true) + guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } + mapViewCoordinator.recordingViewDidDismiss() self.parentCoordinator?.childCoordinator.removeAll() } } From 93ded3ba3ddccdbb5523959ebdda338104c69691 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 18:51:51 +0900 Subject: [PATCH 081/465] =?UTF-8?q?[Feat]=20#71=20=EC=8B=9C=EC=9E=91=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=97=90=20=EC=95=A0=EB=8B=88=EB=A9=94?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 +++++ SanTa/SanTa/MapScene/MapViewController.swift | 5 +-- SanTa/SanTa/MapScene/UIImage+Gif.swift | 32 ++++++++++++++++++ SanTa/SanTa/Resources/walkingManAnimation.gif | Bin 0 -> 361073 bytes 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 SanTa/SanTa/MapScene/UIImage+Gif.swift create mode 100644 SanTa/SanTa/Resources/walkingManAnimation.gif diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 12aefee..c0b6c6d 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695A273026B10070B362 /* MountainAnnotationView.swift */; }; 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */; }; 54731B65272F84D300534097 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54731B64272F84D300534097 /* MapViewModel.swift */; }; + 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */ = {isa = PBXBuildFile; fileRef = 547CDD9927392474007CCA29 /* walkingManAnimation.gif */; }; + 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */; }; 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851281272A6AD500407F28 /* AppDelegate.swift */; }; 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851283272A6AD500407F28 /* SceneDelegate.swift */; }; 54851286272A6AD500407F28 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851285272A6AD500407F28 /* MapViewController.swift */; }; @@ -64,6 +66,8 @@ 5429695A273026B10070B362 /* MountainAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotationView.swift; sourceTree = ""; }; 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterAnnotationView.swift; sourceTree = ""; }; 54731B64272F84D300534097 /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = ""; }; + 547CDD9927392474007CCA29 /* walkingManAnimation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = walkingManAnimation.gif; sourceTree = ""; }; + 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Gif.swift"; sourceTree = ""; }; 5485127E272A6AD500407F28 /* SanTa.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SanTa.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54851281272A6AD500407F28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 54851283272A6AD500407F28 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -186,6 +190,7 @@ 5429695A273026B10070B362 /* MountainAnnotationView.swift */, 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */, 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */, + 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */, ); path = MapScene; sourceTree = ""; @@ -206,6 +211,7 @@ 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */, 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */, 5485128D272A6AD600407F28 /* Assets.xcassets */, + 547CDD9927392474007CCA29 /* walkingManAnimation.gif */, 54851292272A6AD600407F28 /* Info.plist */, ); path = Resources; @@ -305,6 +311,7 @@ files = ( 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */, 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */, + 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -338,6 +345,7 @@ 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, + 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */, diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 88b86b8..505abf4 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -159,11 +159,12 @@ class MapViewController: UIViewController { } func presentAnimation() { - print("1") + let image = UIImage.gifImage(named: "walkingManAnimation") + self.startButton.setImage(image, for: .normal) } func unpresentAnimation(){ - print("2") + self.startButton.setImage(nil, for: .normal) } } diff --git a/SanTa/SanTa/MapScene/UIImage+Gif.swift b/SanTa/SanTa/MapScene/UIImage+Gif.swift new file mode 100644 index 0000000..633f7d4 --- /dev/null +++ b/SanTa/SanTa/MapScene/UIImage+Gif.swift @@ -0,0 +1,32 @@ +// +// UIImage+Gif.swift +// SanTa +// +// Created by shin jae ung on 2021/11/08. +// +// 참고: https://github.com/kiritmodi2702/GIF-Swift/blob/master/GIF-Swift/iOSDevCenters%2BGIF.swift + +import UIKit +import ImageIO + +extension UIImage { + class func gifImage(named: String) -> UIImage? { + guard let bundleURL = Bundle.main.url(forResource: named, withExtension: "gif"), + let imageData = try? Data(contentsOf: bundleURL), + let source = CGImageSourceCreateWithData(imageData as CFData, nil) + else { return nil } + return UIImage.animatedImageWithSource(source) + } + + private class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? { + let count: Int = CGImageSourceGetCount(source) + let images: [UIImage] = (0..Y}3i~CQu8NVN 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

Cg8Gkj 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 z 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òUiXgW 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 Date: Mon, 8 Nov 2021 19:08:51 +0900 Subject: [PATCH 082/465] =?UTF-8?q?[Feat]=20MapSnapShot=20=EC=82=B0=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=ED=99=94=EB=A9=B4=EC=97=90=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 12 +++--- SanTa/SanTa/MapScene/MapViewController.swift | 5 +++ SanTa/SanTa/MapScene/MapViewCoordinator.swift | 25 ++++++++---- .../MountainDetailViewController.swift | 38 +++++++++++++----- .../MountainDetailViewCoordinator.swift | 39 ++++++++++++------- .../MountainListViewCoordinator.swift | 2 +- .../RecordingViewCoordinator.swift | 6 +-- .../ResultScene/ResultViewCoordinator.swift | 2 +- .../SettingsViewCoordinator.swift | 2 +- 9 files changed, 87 insertions(+), 44 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 210a1b2..2e915b8 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -8,13 +8,13 @@ import UIKit protocol Coordinator: AnyObject { - var childCoordinator: [Coordinator] { get set } + var childCoordinators: [Coordinator] { get set } func start () } class AppCoordinator: Coordinator { - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] let window: UIWindow? private var firstViewController: UIViewController! @@ -40,28 +40,28 @@ class AppCoordinator: Coordinator { let mapViewCoordinator = MapViewCoordinator() mapViewCoordinator.parentCoordinator = self - childCoordinator.append(mapViewCoordinator) + childCoordinators.append(mapViewCoordinator) let mapViewController = mapViewCoordinator.startPush() mapViewController.tabBarItem = firstItem mapViewController.tabBarItem.image = .init(systemName: "play.fill") let resultViewCoordinator = ResultViewCoordinator() resultViewCoordinator.parentCoordinator = self - childCoordinator.append(resultViewCoordinator) + childCoordinators.append(resultViewCoordinator) let resultViewController = resultViewCoordinator.startPush() resultViewController.tabBarItem = secondItem resultViewController.tabBarItem.image = .init(systemName: "list.dash") let mountainListViewCoordinator = MountainListViewCoordinator() mountainListViewCoordinator.parentCoordinator = self - childCoordinator.append(mountainListViewCoordinator) + childCoordinators.append(mountainListViewCoordinator) let mountainListViewController = mountainListViewCoordinator.startPush() mountainListViewController.tabBarItem = thirdItem mountainListViewController.tabBarItem.image = .init(systemName: "text.below.photo") let settingsViewCoordinator = SettingsViewCoordinator() settingsViewCoordinator.parentCoordinator = self - childCoordinator.append(settingsViewCoordinator) + childCoordinators.append(settingsViewCoordinator) let settingsViewController = settingsViewCoordinator.startPush() settingsViewController.tabBarItem = fourthItem settingsViewController.tabBarItem.image = .init(systemName: "gearshape.fill") diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index f432959..3c674a7 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -144,6 +144,10 @@ class MapViewController: UIViewController { @objc private func presentRecordingViewController() { coordinator?.presentRecordingViewController() } + +// @objc private func presentMountainDetailViewController() { +// coordinator?.presentMountainDetailViewController() +// } } extension MapViewController: MKMapViewDelegate { @@ -160,6 +164,7 @@ extension MapViewController: MKMapViewDelegate { //navigate using annotation + coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation, locationManager: self.manager) } } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index ede2bee..28a6ad6 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -6,11 +6,12 @@ // import UIKit +import CoreLocation class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController = UINavigationController() - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] func start() { } @@ -26,19 +27,27 @@ class MapViewCoordinator: Coordinator { extension MapViewCoordinator { func presentRecordingViewController() { - if self.childCoordinator.isEmpty { + if self.childCoordinators.isEmpty { let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) - self.childCoordinator.append(recordingViewCoordinator) + self.childCoordinators.append(recordingViewCoordinator) recordingViewCoordinator.parentCoordinator = self } - childCoordinator.first?.start() + childCoordinators.first?.start() } - func presentMountainDetailViewController() { - for coordinator in childCoordinator { - - } + func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { +// for coordinator in childCoordinators { +// if coordinator is MountainDetailViewCoordinator { +// coordinator.start() +// return +// } +// } + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, locationManager: locationManager) + mountainDetailViewCoordinator.parentCoordinator = self + self.childCoordinators.append(mountainDetailViewCoordinator) + + mountainDetailViewCoordinator.start() } private func injectDependencies() -> MapViewModel { diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index b89c31b..649b51b 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -9,7 +9,7 @@ import UIKit import MapKit class MountainDetailViewController: UIViewController { -// weak var mountainDetailViewCoordinator: MountainDetailViewCoordinator? + weak var coordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? convenience init(viewModel: MountainDetailViewModel) { @@ -19,6 +19,7 @@ class MountainDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.configureViewModel() } private func configureViewModel() { @@ -31,29 +32,48 @@ class MountainDetailViewController: UIViewController { extension MountainDetailViewController { private func layoutMountainDetailView(mountainDetail: MountainDetailModel) { + let headerView = UIView() let mapSnapShot = upperMapHeaderView(mountainDetail: mountainDetail) let titleView = lowerMountainTitleView(mountainDetail: mountainDetail) let tableView = configuredTableView(mountainDetail: mountainDetail) + headerView.translatesAutoresizingMaskIntoConstraints = false + mapSnapShot.translatesAutoresizingMaskIntoConstraints = false + titleView.translatesAutoresizingMaskIntoConstraints = false + tableView.translatesAutoresizingMaskIntoConstraints = false + + headerView.addSubview(mapSnapShot) + headerView.addSubview(titleView) + view.addSubview(headerView) + view.addSubview(tableView) + + let headerConstraints = [ + headerView.topAnchor.constraint(equalTo: view.topAnchor), + headerView.leftAnchor.constraint(equalTo: view.leftAnchor), + headerView.rightAnchor.constraint(equalTo: view.rightAnchor), + headerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5) + ] + NSLayoutConstraint.activate(headerConstraints) + let mapConstraints = [ - mapSnapShot.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.3), - mapSnapShot.topAnchor.constraint(equalTo: view.topAnchor), - mapSnapShot.leftAnchor.constraint(equalTo: view.leftAnchor), - mapSnapShot.rightAnchor.constraint(equalTo: view.rightAnchor) + mapSnapShot.topAnchor.constraint(equalTo: headerView.topAnchor), + mapSnapShot.leftAnchor.constraint(equalTo: headerView.leftAnchor), + mapSnapShot.rightAnchor.constraint(equalTo: headerView.rightAnchor), + mapSnapShot.heightAnchor.constraint(equalTo: headerView.heightAnchor, multiplier: 0.85) ] NSLayoutConstraint.activate(mapConstraints) let titleViewConstraints = [ titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor), - titleView.leftAnchor.constraint(equalTo: view.leftAnchor), - titleView.rightAnchor.constraint(equalTo: view.rightAnchor), - titleView.heightAnchor.constraint(equalToConstant: 100) + titleView.leftAnchor.constraint(equalTo: headerView.leftAnchor), + titleView.rightAnchor.constraint(equalTo: headerView.rightAnchor), + titleView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor) ] NSLayoutConstraint.activate(titleViewConstraints) let tableViewConstraints = [ - tableView.topAnchor.constraint(equalTo: titleView.bottomAnchor), + tableView.topAnchor.constraint(equalTo: headerView.bottomAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), tableView.leftAnchor.constraint(equalTo: view.leftAnchor), tableView.rightAnchor.constraint(equalTo: view.rightAnchor) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index ebe6223..27d0d2a 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -6,22 +6,31 @@ // import UIKit +import CoreLocation -//class MountainDetailViewCoordinator: Coordinator { -// weak var parentCoordinator: Coordinator? -// var navigationController: UINavigationController -// var childCoordinator: [Coordinator] -// var mountainDetailViewController: MountainDetailViewController +class MountainDetailViewCoordinator: Coordinator { + var childCoordinators: [Coordinator] = [] -// func start() { -// <#code#> -// } -// -// -// -// init(navigationController: UINavigationController) { -// self.navigationController = navigationController -// let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: <#T##MountainAnnotation#>, locationManager: <#T##CLLocationManager#>), mountainInfo: <#T##MountainDetailModel#>) + weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController + var mountainDetailViewController: MountainDetailViewController + + func start() { + self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) + } + + + //지도화면에서 바로 올때 + init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { + self.navigationController = navigationController + let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation, locationManager: locationManager)) + self.mountainDetailViewController = MountainDetailViewController(viewModel: viewModel) + self.mountainDetailViewController.coordinator = self + } + + //산 목록에서 올때 +// init(navigationController: UINavigationController, mountainDetailModel: MountainDetailModel) { +// // } -//} +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 7ef649c..1e6ccdf 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -9,7 +9,7 @@ import UIKit class MountainListViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController init() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index a867451..6316943 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -11,7 +11,7 @@ import UIKit class RecordingViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] var recordingViewController: RecordingViewController init(navigationController: UINavigationController) { @@ -22,7 +22,7 @@ class RecordingViewCoordinator: Coordinator { } func start() { - recordingViewController.modalPresentationStyle = .fullScreen + self.recordingViewController.modalPresentationStyle = .fullScreen self.navigationController.present(recordingViewController, animated: true) } @@ -32,7 +32,7 @@ class RecordingViewCoordinator: Coordinator { func dismiss() { self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinator.removeAll() + self.parentCoordinator?.childCoordinators.removeAll() } } diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index 4558173..b526b6a 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -9,7 +9,7 @@ import UIKit class ResultViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController init() { diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 493e8d1..4ed4d9b 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -9,7 +9,7 @@ import UIKit class SettingsViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] func start() { } From cdbaf87f93def4d282eb1bec1a93bf12fb80e42e Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 8 Nov 2021 21:11:39 +0900 Subject: [PATCH 083/465] [Feat] #81 Remove RecordingView Request Authorization --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 27ffa5d..ec507d2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -49,7 +49,6 @@ final class RecordingModel: NSObject, ObservableObject { } private func configureLocationManager() { - self.locationManager.requestWhenInUseAuthorization() self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.allowsBackgroundLocationUpdates = true From 726c6babf511d0314ca179cd87c634a4363dd278 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 8 Nov 2021 21:40:34 +0900 Subject: [PATCH 084/465] =?UTF-8?q?[Refactor]=20=EC=82=B0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4,=20=EC=A7=80=EB=8F=84=ED=99=94?= =?UTF-8?q?=EB=A9=B4,=20=EA=B8=B0=EB=A1=9D=ED=99=94=EB=A9=B4=20=EC=BD=94?= =?UTF-8?q?=EB=94=94=EB=84=A4=EC=9D=B4=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 20 +++++--------- .../MountainDetailViewController.swift | 26 +++++++++++++------ .../MountainDetailViewCoordinator.swift | 7 +++++ .../RecordingViewCoordinator.swift | 4 ++- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 28a6ad6..b350fb9 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -15,34 +15,26 @@ class MapViewCoordinator: Coordinator { func start() { } - + func startPush() -> UINavigationController { let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self self.navigationController.setViewControllers([mapViewController], animated: false) - + return navigationController } } extension MapViewCoordinator { func presentRecordingViewController() { - if self.childCoordinators.isEmpty { - let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) - self.childCoordinators.append(recordingViewCoordinator) - recordingViewCoordinator.parentCoordinator = self - } + let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + self.childCoordinators.append(recordingViewCoordinator) + recordingViewCoordinator.parentCoordinator = self - childCoordinators.first?.start() + recordingViewCoordinator.start() } func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { -// for coordinator in childCoordinators { -// if coordinator is MountainDetailViewCoordinator { -// coordinator.start() -// return -// } -// } let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, locationManager: locationManager) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 649b51b..edd81f0 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -42,6 +42,7 @@ extension MountainDetailViewController { titleView.translatesAutoresizingMaskIntoConstraints = false tableView.translatesAutoresizingMaskIntoConstraints = false + headerView.addSubview(mapSnapShot) headerView.addSubview(titleView) view.addSubview(headerView) @@ -86,16 +87,25 @@ extension MountainDetailViewController { } private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { -// let mapOptions = MKMapSnapshotter.Options.init() -// mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan()) -// mapOptions.size = CGSize(width: view.bounds.width, height: view.bounds.height / 3) -// mapOptions.mapType = .satellite -// let mountainAnnotationView = MountainAnnotationView(annotation: MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: mountainDetail.regions.join), reuseIdentifier: MountainAnnotationView.ReuseID) + let mapOptions = MKMapSnapshotter.Options.init() + mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) + mapOptions.size = CGSize(width: view.bounds.width, height: view.bounds.height / 3) + mapOptions.mapType = .satellite +// let mountainAnnotationView = MountainAnnotationView(annotation: MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: mountainDetail.regions.joined(separator: ", ")), reuseIdentifier: MountainAnnotationView.ReuseID) +// // mountainAnnotationView.canShowCallout = true // mountainAnnotationView.calloutOffset = CGPoint(x: 0, y: 5) - let imgVIew = UIImageView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height / 3)) - imgVIew.backgroundColor = .yellow - return imgVIew + + let imgView = UIImageView() + let snapShotter = MKMapSnapshotter(options: mapOptions) + snapShotter.start { snapShot, error in + if let snapShot = snapShot { + imgView.image = snapShot.image + } else if let error = error { + print(error.localizedDescription) + } + } + return imgView } private func lowerMountainTitleView(mountainDetail: MountainDetailModel) -> UIView { diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 27d0d2a..576a7af 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -19,6 +19,13 @@ class MountainDetailViewCoordinator: Coordinator { self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) } + func dismiss() { + self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinators.removeAll(where: { coordinator in + coordinator is Self + }) + } + //지도화면에서 바로 올때 init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 6316943..7f699c5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -32,7 +32,9 @@ class RecordingViewCoordinator: Coordinator { func dismiss() { self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinators.removeAll() + self.parentCoordinator?.childCoordinators.removeAll(where: { coordinator in + coordinator is Self + }) } } From 17960511cef0933e79d17898e1367055ff59e33d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 22:04:13 +0900 Subject: [PATCH 085/465] =?UTF-8?q?[Feat]=20#95=20SettingsUsecase=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SettingsUsecaseTests.swift | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 SanTa/SettingsSceneTests/SettingsUsecaseTests.swift diff --git a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift new file mode 100644 index 0000000..3b474c0 --- /dev/null +++ b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift @@ -0,0 +1,54 @@ +// +// SettingsUseCaseTests.swift +// SettingsTests +// +// Created by CHANGMIN OH on 2021/11/08. +// + +import XCTest + +class SettingsUsecaseTests: XCTestCase { + + class MockRepository: SettingsRepository { + func save(value: T, key: Settings) where T : Decodable, T : Encodable { + + } + + func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) { + completion(ToggleOption(text: "토글", toggle: true)) + } + + func getMapOption(key: Settings, completion: @escaping (Option) -> Void) { + completion(MapOption(text: "맵", map: .infomation)) + } + } + + private var useCase: SettingsUsecase! + private var repository: MockRepository! + + override func setUpWithError() throws { + repository = MockRepository() + useCase = DefaultSettingsUsecase(settingsRepository: repository) + } + + func test_repository반환_값에_따른_배열생성() { + let options = useCase.makeSettings() + + let option1 = options[0][0] as? ToggleOption + let option2 = options[0][1] as? ToggleOption + let option3 = options[1][0] as? ToggleOption + let option4 = options[1][1] as? ToggleOption + let option5 = options[2][0] as? ToggleOption + let option6 = options[3][0] as? MapOption + let option7 = options[3][1] as? ToggleOption + + XCTAssertNotNil(option1) + XCTAssertNotNil(option2) + XCTAssertNotNil(option3) + XCTAssertNotNil(option4) + XCTAssertNotNil(option5) + XCTAssertNotNil(option6) + XCTAssertNotNil(option7) + } +} + From 1e19f836390d5b593845c57dd66db0f92cab8f69 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 8 Nov 2021 22:04:37 +0900 Subject: [PATCH 086/465] =?UTF-8?q?[Feat]=20#95=20SettingsViewModel=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 147 ++++++++++++++++++ .../xcshareddata/xcschemes/SanTa.xcscheme | 20 +++ .../SettingsViewModelTests.swift | 50 ++++++ 3 files changed, 217 insertions(+) create mode 100644 SanTa/SettingsSceneTests/SettingsViewModelTests.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 99cabab..465da03 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -33,6 +33,14 @@ 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; 9826F3DD2739035E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 9826F3DF273904010064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + 9826F436273954020064FA85 /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */; }; + 9826F437273954030064FA85 /* SettingsUsecaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */; }; + 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; + 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; + 9826F43B2739546E0064FA85 /* UserDefaultsSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */; }; + 9826F43C2739546E0064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + 9826F43D2739546E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; @@ -51,6 +59,16 @@ DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 9826F431273953FB0064FA85 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; @@ -80,6 +98,9 @@ 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9826F3DC2739035E0064FA85 /* Option.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = ""; }; 9826F3DE273904010064FA85 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; + 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelTests.swift; sourceTree = ""; }; + 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecaseTests.swift; sourceTree = ""; }; + 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SettingsSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 984DDEC027325D67003BE56B /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCase.swift; sourceTree = ""; }; 984DDEC427325FB9003BE56B /* RecordRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordRepository.swift; sourceTree = ""; }; @@ -106,6 +127,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9826F42A273953FB0064FA85 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -233,6 +261,7 @@ isa = PBXGroup; children = ( 54851280272A6AD500407F28 /* SanTa */, + 9826F42E273953FB0064FA85 /* SettingsSceneTests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -241,6 +270,7 @@ isa = PBXGroup; children = ( 5485127E272A6AD500407F28 /* SanTa.app */, + 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, ); name = Products; sourceTree = ""; @@ -263,6 +293,15 @@ path = SanTa; sourceTree = ""; }; + 9826F42E273953FB0064FA85 /* SettingsSceneTests */ = { + isa = PBXGroup; + children = ( + 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */, + 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */, + ); + path = SettingsSceneTests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -283,6 +322,24 @@ productReference = 5485127E272A6AD500407F28 /* SanTa.app */; productType = "com.apple.product-type.application"; }; + 9826F42C273953FB0064FA85 /* SettingsSceneTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9826F435273953FB0064FA85 /* Build configuration list for PBXNativeTarget "SettingsSceneTests" */; + buildPhases = ( + 9826F429273953FB0064FA85 /* Sources */, + 9826F42A273953FB0064FA85 /* Frameworks */, + 9826F42B273953FB0064FA85 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9826F432273953FB0064FA85 /* PBXTargetDependency */, + ); + name = SettingsSceneTests; + productName = SettingsSceneTests; + productReference = 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -296,6 +353,10 @@ 5485127D272A6AD500407F28 = { CreatedOnToolsVersion = 13.0; }; + 9826F42C273953FB0064FA85 = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; }; }; buildConfigurationList = 54851279272A6AD500407F28 /* Build configuration list for PBXProject "SanTa" */; @@ -312,6 +373,7 @@ projectRoot = ""; targets = ( 5485127D272A6AD500407F28 /* SanTa */, + 9826F42C273953FB0064FA85 /* SettingsSceneTests */, ); }; /* End PBXProject section */ @@ -326,6 +388,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9826F42B273953FB0064FA85 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -376,8 +445,31 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9826F429273953FB0064FA85 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */, + 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */, + 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, + 9826F43B2739546E0064FA85 /* UserDefaultsSettingsStorage.swift in Sources */, + 9826F43C2739546E0064FA85 /* Settings.swift in Sources */, + 9826F43D2739546E0064FA85 /* Option.swift in Sources */, + 9826F437273954030064FA85 /* SettingsUsecaseTests.swift in Sources */, + 9826F436273954020064FA85 /* SettingsViewModelTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 9826F432273953FB0064FA85 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 9826F431273953FB0064FA85 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; @@ -560,6 +652,52 @@ }; name = Release; }; + 9826F433273953FB0064FA85 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5X25M942H6; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.SettingsSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + 9826F434273953FB0064FA85 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5X25M942H6; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.SettingsSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -581,6 +719,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 9826F435273953FB0064FA85 /* Build configuration list for PBXNativeTarget "SettingsSceneTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9826F433273953FB0064FA85 /* Debug */, + 9826F434273953FB0064FA85 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index 2774787..18d624d 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -28,6 +28,26 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + (value: T, key: Settings) { + + } + + func makeSettings() -> [[Option]] { + return options + } + } + + private var viewModel: SettingsViewModel! + private var useCase: MockUseCase! + + override func setUpWithError() throws { + useCase = MockUseCase() + viewModel = SettingsViewModel(settingsUseCase: useCase) + } + + func test_viewDidLoad시_UseCase의_반환값_settings프로퍼티에_세팅() throws { + viewModel.viewDidLoad() + guard let mapOption = viewModel.settings[0][0] as? MapOption else { return } + XCTAssertEqual(mapOption.text, "맵") + XCTAssertEqual(mapOption.map, .infomation) + } + + func test_change호출시_문자열이면_settings프로퍼티_업데이트() throws { + viewModel.change(value: 1, key: .mapFormat) + XCTAssertEqual(viewModel.sectionCount, 0) + + viewModel.change(value: "string", key: .mapFormat) + let mapOption = viewModel.settings[0][0] as? MapOption + XCTAssertNotNil(mapOption) + XCTAssertEqual(mapOption?.text, "맵") + XCTAssertEqual(mapOption?.map, .infomation) + } +} From 8f873e4c5ffe41e5a464146761e512dd114c0d99 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 8 Nov 2021 22:05:17 +0900 Subject: [PATCH 087/465] [Docs] comment clean-up --- SanTa/SanTa/MapScene/MapViewController.swift | 9 +----- .../MountainDetailViewCoordinator.swift | 1 + .../MountainDetailViewModel.swift | 28 ------------------- 3 files changed, 2 insertions(+), 36 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 3c674a7..cafe532 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -45,7 +45,7 @@ class MapViewController: UIViewController { self.viewModel?.mountains?.forEach{ mountainEntity in let mountainAnnotation = MountainAnnotation( title: mountainEntity.mountain.mountainName, - subtitle: mountainEntity.mountain.mountainHeight, + subtitle: mountainEntity.mountain.mountainHeight + "m", latitude: mountainEntity.latitude, longitude: mountainEntity.longitude, mountainDescription: mountainEntity.mountain.mountainShortDescription, @@ -144,10 +144,6 @@ class MapViewController: UIViewController { @objc private func presentRecordingViewController() { coordinator?.presentRecordingViewController() } - -// @objc private func presentMountainDetailViewController() { -// coordinator?.presentMountainDetailViewController() -// } } extension MapViewController: MKMapViewDelegate { @@ -161,9 +157,6 @@ extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { guard let annotation = view.annotation as? MountainAnnotation else { return } - - - //navigate using annotation coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation, locationManager: self.manager) } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 576a7af..db61d3a 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -16,6 +16,7 @@ class MountainDetailViewCoordinator: Coordinator { var mountainDetailViewController: MountainDetailViewController func start() { +// if self.parentCoordinator is MountainListViewCoordinator { } self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift index cca0040..0fd1f70 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift @@ -22,32 +22,4 @@ class MountainDetailViewModel { self?.mountainInfoReceived(mountainInfo) } } - -// func mountainName() -> String { -// return self.mountainDetail.moutainName -// } -// -// func distanceToMountainFromCurrentLocation() -> Double? { -// return self.mountainDetail.distance -// } -// -// func mountainRegions() -> [String] { -// return self.mountainDetail.regions -// } -// -// func altitude() -> String { -// return self.mountainDetail.altitude + "m" -// } -// -// func mountainDescription() -> String { -// return self.mountainDetail.mountainDescription -// } -// -// func latitude() -> Double { -// return self.mountainDetail.latitude -// } -// -// func longitude() -> Double { -// return self.mountainDetail.longitude -// } } From 9852bb397691e1639e3fcbcc02f4ef2259f99dab Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 8 Nov 2021 22:08:36 +0900 Subject: [PATCH 088/465] =?UTF-8?q?[Feat]=20#76,=20#77,=20#88=20=EC=95=B1?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EB=B0=8F=20Annotation=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MapScene/ClusterAnnotationView.swift | 12 ++++----- SanTa/SanTa/MapScene/MapViewController.swift | 2 +- .../MapScene/MountainAnnotationView.swift | 6 ++--- .../AppIcon.appiconset/1024x1024.png | Bin 0 -> 98366 bytes .../AppIcon.appiconset/120x120-1.png | Bin 0 -> 8539 bytes .../AppIcon.appiconset/120x120.png | Bin 0 -> 8539 bytes .../AppIcon.appiconset/152x152.png | Bin 0 -> 11669 bytes .../AppIcon.appiconset/167x167.png | Bin 0 -> 13289 bytes .../AppIcon.appiconset/180x180.png | Bin 0 -> 13953 bytes .../AppIcon.appiconset/20x20.png | Bin 0 -> 896 bytes .../AppIcon.appiconset/29x29.png | Bin 0 -> 1440 bytes .../AppIcon.appiconset/40x40-1.png | Bin 0 -> 2065 bytes .../AppIcon.appiconset/40x40-2.png | Bin 0 -> 2065 bytes .../AppIcon.appiconset/40x40.png | Bin 0 -> 2065 bytes .../AppIcon.appiconset/58x58-1.png | Bin 0 -> 3164 bytes .../AppIcon.appiconset/58x58.png | Bin 0 -> 3164 bytes .../AppIcon.appiconset/60x60.png | Bin 0 -> 3387 bytes .../AppIcon.appiconset/76x76.png | Bin 0 -> 4494 bytes .../AppIcon.appiconset/80x80-1.png | Bin 0 -> 4657 bytes .../AppIcon.appiconset/80x80.png | Bin 0 -> 4657 bytes .../AppIcon.appiconset/87x87.png | Bin 0 -> 5633 bytes .../AppIcon.appiconset/Contents.json | 18 ++++++++++++++ .../SantaColor.colorset/Contents.json | 20 +++++++++++++++ .../SantaImage.imageset/120x120Circle.png | Bin 0 -> 9683 bytes .../SantaImage.imageset/40x40Circle.png | Bin 0 -> 2392 bytes .../SantaImage.imageset/80x80Circle.png | Bin 0 -> 5550 bytes .../SantaImage.imageset/Contents.json | 23 ++++++++++++++++++ 27 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/1024x1024.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120-1.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/152x152.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/167x167.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/180x180.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/20x20.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/29x29.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-1.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-2.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/58x58-1.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/58x58.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/60x60.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/76x76.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/80x80-1.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/80x80.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/87x87.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/SantaColor.colorset/Contents.json create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/120x120Circle.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/40x40Circle.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/80x80Circle.png create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/Contents.json diff --git a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift index 582f529..3d036a3 100644 --- a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift +++ b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift @@ -24,17 +24,17 @@ class ClusterAnnotationView: MKAnnotationView { if let cluster = annotation as? MKClusterAnnotation { let count = cluster.memberAnnotations.count - image = UIGraphicsImageRenderer(size: CGSize(width: 40, height: 40)).image { _ in + image = UIGraphicsImageRenderer(size: CGSize(width: 30, height: 30)).image { _ in UIColor.white.setFill() - UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 40, height: 40)).fill() - UIColor.blue.setFill() - UIBezierPath(ovalIn: CGRect(x: 5, y: 5, width: 30, height: 30)).fill() + UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 30, height: 30)).fill() + UIColor(named: "SantaColor")?.setFill() + UIBezierPath(ovalIn: CGRect(x: 3, y: 3, width: 24, height: 24)).fill() let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.white, - NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)] + NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 11)] let text = count > 99 ? "99+" : "\(count)" let size = text.size(withAttributes: attributes) - let rect = CGRect(x: 20 - size.width / 2, y: 20 - size.height / 2, width: size.width, height: size.height) + let rect = CGRect(x: 15 - size.width / 2, y: 15 - size.height / 2, width: size.width, height: size.height) text.draw(in: rect, withAttributes: attributes) } } diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 505abf4..d0f8e9c 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -63,7 +63,7 @@ class MapViewController: UIViewController { mapView.delegate = self self.view.addSubview(self.startButton) - self.startButton.backgroundColor = .blue + self.startButton.backgroundColor = UIColor(named: "SantaColor") self.startButton.translatesAutoresizingMaskIntoConstraints = false self.startButton.setTitle("시작", for: .normal) self.startButton.setTitleColor(.white, for: .normal) diff --git a/SanTa/SanTa/MapScene/MountainAnnotationView.swift b/SanTa/SanTa/MapScene/MountainAnnotationView.swift index 90e16ce..bf04c8c 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotationView.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotationView.swift @@ -8,7 +8,7 @@ import UIKit import MapKit -class MountainAnnotationView: MKMarkerAnnotationView { +class MountainAnnotationView: MKAnnotationView { static let ReuseID = "MountainAnnotation" override init(annotation: MKAnnotation?, reuseIdentifier: String?) { @@ -26,7 +26,7 @@ class MountainAnnotationView: MKMarkerAnnotationView { override func prepareForDisplay() { super.prepareForDisplay() displayPriority = .defaultHigh - markerTintColor = .blue - glyphImage = UIImage(systemName: "play.fill") + self.image = UIImage(named: "SantaImage") + self.frame = CGRect(x: 30, y: 30, width: 30, height: 30) } } diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/1024x1024.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..cb701450eeaf88d6e617f709343e880dba606b07 GIT binary patch literal 98366 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120-1.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120-1.png new file mode 100644 index 0000000000000000000000000000000000000000..3050d9f987b8676447a39c30d35e413d560d76f3 GIT binary patch literal 8539 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 V2qyWZVIKeh002ovPDHLkV1ngH)g%A_ literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..3050d9f987b8676447a39c30d35e413d560d76f3 GIT binary patch literal 8539 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 V2qyWZVIKeh002ovPDHLkV1ngH)g%A_ literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/152x152.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..41ce9da35bfc6ad4509f877ed39e3c8fdbfe3812 GIT binary patch literal 11669 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/167x167.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/167x167.png new file mode 100644 index 0000000000000000000000000000000000000000..7f93f90b27c2a15d71cea85f19f431a46386a5f2 GIT binary patch literal 13289 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-1.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-1.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9adefc18f3c765a65ecac5b7addb0914edf235 GIT binary patch literal 2065 zcmV+s2=4cZP)PENjoV81^B}Z%*&SXnBSq3$cL(R4QH+YufV0} z;O#_e2~^nwM~p}OJeuR33xM0>!p9%>ATl-qca9T8Q9dV}+Qx8_>(v|s@p?SCeBm;l zSg-+y_jSM_*&xXxC{a67k_wz|I~-0sNHRH1I06uo8D>5c93jZ@xe<*=v7qn~{*`A} zzJ!hsK0?6n<82t6H`k4!;J`xrD=Q!ffYW8?+MNncje&*+H7Cgk8`p3MHY!no z*WtmNzk3JR4}`;E4q3hA2UxXqHLAb<6NG~oV6)3ucwe=#33;P_H(VY&L=jWMS!H6% zLQZK0XgVAleZb?#hwYu%x}pIG-+d1S1qD#JV*s!2YT)?;UtES4e)c-990yMHbR!;* zC1^j*t44lDZ_x=>M)j!5}?q9%x zL{T&#qp>K@ch@(fX>Sv5y`>B`n+?Z~{vB&7wjy+92)+`CnK%!D)JVEWEjha&_whYc>918={w2j87tgLyxkhj|4Hd1t5k`{41YQzdev zf}u(FouZ;5ba!`S+qP}kzJ0qZ1Goi0|3xjFE*nHiu zG{1EaFRtH#ojYE`>kAu!xCSCf22grp+GMG$tPD*}O<1>X9a>sijJGBx{()n=fYyUY z;SadAn3)Qv+r60LwU+Zkp4*S39mnwWkDkGn&0DbY@fE0AvIxm!67B8nIB?(qVzF2T zoE~!YR9RVxO`A4h{`~m}27_Gcayik{-HQ#?uOfK*Jcs1=n+C_qLPz9%DiS~e(N+h7 z8NOVcJlT)$moCRQZ!JgLi9?31SvAIBWm(Pu92^`(e}6y9%gYT}US1xChldf3M&WQc zxa`k=dC&aBsHni=#fyy=`qW!B{7~s~>@VDf_P1Wf=#>d5$s|9Q*b*Wlwzz47 z?D6_?FdiK@;0DhPayVSW)~1@?hK2^z)YPE0wKb!T!Ru*X@1KCf!25e!;19S|uO{X+ zOSN^6Zf0jtwrP@V64o!N!`Yq?x=(bYWKIe9#L>}FK1I_>x|Wq?uN&dWgpx-V=x#*c<3B14i7>h5%@eaP>}xx6crYuu;@nQ<@?~z%YobD;NgO4 zruX;&jeUAiPeS&< z@t~)li&KxC*#T#05L|;q{f+B|n|!Nu{ct*tHe& zTO}BbdRPR}LKu68cdnj4)HZrwY8!Ph>MFy2yW%dyr8s1E)lbD3zp%DyF=gcJok_K& v+sYL6hL$Yvr2N-}<$dD{hH$v3Gl_o#O`B`zXN6hU00000NkvXXu0mjfsyyZ1 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-2.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40-2.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9adefc18f3c765a65ecac5b7addb0914edf235 GIT binary patch literal 2065 zcmV+s2=4cZP)PENjoV81^B}Z%*&SXnBSq3$cL(R4QH+YufV0} z;O#_e2~^nwM~p}OJeuR33xM0>!p9%>ATl-qca9T8Q9dV}+Qx8_>(v|s@p?SCeBm;l zSg-+y_jSM_*&xXxC{a67k_wz|I~-0sNHRH1I06uo8D>5c93jZ@xe<*=v7qn~{*`A} zzJ!hsK0?6n<82t6H`k4!;J`xrD=Q!ffYW8?+MNncje&*+H7Cgk8`p3MHY!no z*WtmNzk3JR4}`;E4q3hA2UxXqHLAb<6NG~oV6)3ucwe=#33;P_H(VY&L=jWMS!H6% zLQZK0XgVAleZb?#hwYu%x}pIG-+d1S1qD#JV*s!2YT)?;UtES4e)c-990yMHbR!;* zC1^j*t44lDZ_x=>M)j!5}?q9%x zL{T&#qp>K@ch@(fX>Sv5y`>B`n+?Z~{vB&7wjy+92)+`CnK%!D)JVEWEjha&_whYc>918={w2j87tgLyxkhj|4Hd1t5k`{41YQzdev zf}u(FouZ;5ba!`S+qP}kzJ0qZ1Goi0|3xjFE*nHiu zG{1EaFRtH#ojYE`>kAu!xCSCf22grp+GMG$tPD*}O<1>X9a>sijJGBx{()n=fYyUY z;SadAn3)Qv+r60LwU+Zkp4*S39mnwWkDkGn&0DbY@fE0AvIxm!67B8nIB?(qVzF2T zoE~!YR9RVxO`A4h{`~m}27_Gcayik{-HQ#?uOfK*Jcs1=n+C_qLPz9%DiS~e(N+h7 z8NOVcJlT)$moCRQZ!JgLi9?31SvAIBWm(Pu92^`(e}6y9%gYT}US1xChldf3M&WQc zxa`k=dC&aBsHni=#fyy=`qW!B{7~s~>@VDf_P1Wf=#>d5$s|9Q*b*Wlwzz47 z?D6_?FdiK@;0DhPayVSW)~1@?hK2^z)YPE0wKb!T!Ru*X@1KCf!25e!;19S|uO{X+ zOSN^6Zf0jtwrP@V64o!N!`Yq?x=(bYWKIe9#L>}FK1I_>x|Wq?uN&dWgpx-V=x#*c<3B14i7>h5%@eaP>}xx6crYuu;@nQ<@?~z%YobD;NgO4 zruX;&jeUAiPeS&< z@t~)li&KxC*#T#05L|;q{f+B|n|!Nu{ct*tHe& zTO}BbdRPR}LKu68cdnj4)HZrwY8!Ph>MFy2yW%dyr8s1E)lbD3zp%DyF=gcJok_K& v+sYL6hL$Yvr2N-}<$dD{hH$v3Gl_o#O`B`zXN6hU00000NkvXXu0mjfsyyZ1 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9adefc18f3c765a65ecac5b7addb0914edf235 GIT binary patch literal 2065 zcmV+s2=4cZP)PENjoV81^B}Z%*&SXnBSq3$cL(R4QH+YufV0} z;O#_e2~^nwM~p}OJeuR33xM0>!p9%>ATl-qca9T8Q9dV}+Qx8_>(v|s@p?SCeBm;l zSg-+y_jSM_*&xXxC{a67k_wz|I~-0sNHRH1I06uo8D>5c93jZ@xe<*=v7qn~{*`A} zzJ!hsK0?6n<82t6H`k4!;J`xrD=Q!ffYW8?+MNncje&*+H7Cgk8`p3MHY!no z*WtmNzk3JR4}`;E4q3hA2UxXqHLAb<6NG~oV6)3ucwe=#33;P_H(VY&L=jWMS!H6% zLQZK0XgVAleZb?#hwYu%x}pIG-+d1S1qD#JV*s!2YT)?;UtES4e)c-990yMHbR!;* zC1^j*t44lDZ_x=>M)j!5}?q9%x zL{T&#qp>K@ch@(fX>Sv5y`>B`n+?Z~{vB&7wjy+92)+`CnK%!D)JVEWEjha&_whYc>918={w2j87tgLyxkhj|4Hd1t5k`{41YQzdev zf}u(FouZ;5ba!`S+qP}kzJ0qZ1Goi0|3xjFE*nHiu zG{1EaFRtH#ojYE`>kAu!xCSCf22grp+GMG$tPD*}O<1>X9a>sijJGBx{()n=fYyUY z;SadAn3)Qv+r60LwU+Zkp4*S39mnwWkDkGn&0DbY@fE0AvIxm!67B8nIB?(qVzF2T zoE~!YR9RVxO`A4h{`~m}27_Gcayik{-HQ#?uOfK*Jcs1=n+C_qLPz9%DiS~e(N+h7 z8NOVcJlT)$moCRQZ!JgLi9?31SvAIBWm(Pu92^`(e}6y9%gYT}US1xChldf3M&WQc zxa`k=dC&aBsHni=#fyy=`qW!B{7~s~>@VDf_P1Wf=#>d5$s|9Q*b*Wlwzz47 z?D6_?FdiK@;0DhPayVSW)~1@?hK2^z)YPE0wKb!T!Ru*X@1KCf!25e!;19S|uO{X+ zOSN^6Zf0jtwrP@V64o!N!`Yq?x=(bYWKIe9#L>}FK1I_>x|Wq?uN&dWgpx-V=x#*c<3B14i7>h5%@eaP>}xx6crYuu;@nQ<@?~z%YobD;NgO4 zruX;&jeUAiPeS&< z@t~)li&KxC*#T#05L|;q{f+B|n|!Nu{ct*tHe& zTO}BbdRPR}LKu68cdnj4)HZrwY8!Ph>MFy2yW%dyr8s1E)lbD3zp%DyF=gcJok_K& v+sYL6hL$Yvr2N-}<$dD{hH$v3Gl_o#O`B`zXN6hU00000NkvXXu0mjfsyyZ1 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/58x58-1.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/58x58-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dc11492ca0c9d40ee1bb50a23800969aed757f GIT binary patch literal 3164 zcmV-i45RajP)?T2xGn3hK&+DGw z`5xyxXE)qY>8K<@f-fm~zfxbB{M6mE@}%VDtdf`1)=ZwMlglNhT%AW?xx|!*X`|#h zuLQ47fX6QH)r%jAg$`R1c_byHY@NeU{Ud&?2 z<7@pT-+c650qv3p0(lk@xZYzegJYz`DN^F35bu$? z%}bmJFDJ^N-9m;@S3mV)RWC>_eaq~p(jlJ%`i4+fsHPA?O+)rk-Y@*5AVb-4caUly zNm3<>s~-~4LrRj*SqXlYdzC^;5*XkpAQ>$cB-XqBfRI63&J}%7vChyt=#jwcY3iPAJ@bhSvbf7F$2uc>aJBf6F#eRJnE711Vs z4M9TG*cgdMDaimE_)#FcZ7^m4bY!K?}8^NiONi?SBdk)EBh5^e4_*qkvGj@pta!W?6w^|^o9j@t8eaKu_^eP19Y zCC`<17At36DLiCUjz^YeydxH6N4~(L>2v+;pG)9?I^coKd-44G+34!*LThs?3?@Bd ztY&O_a=Pj6U=S^7q-V%7dB3%?tIiN=?Nui5}N9goPw7(#UI>tI2sQT`#26^iA zDNS|VXWjI3*T#IjmAw;2lL3|(6RdU%KHR#OLXvcJ-*LQ`TLiPk0G*Dfix({rY)P0dVMO*i=qgN#e%bE&(i0$3pXKeYY}3t4jd}@3`-tc zP0L?;`6WC#>q-1|{_7~)e+_O|T2)b{V6_$LMp8-T{T zCb=w9NUFLVRbB2#$0t4;?X69ceM->5X0akS`)#a#b^{%zrltmoiHTH_JkJLK@7S>e z4?g&y2LFqD?m}U~UakK0=~Ear>IRxWSo;>W)7BPZuaN`{64e5I7ms#5wNZ7x5ke{+ z(quNkXf$a392Pr1&O4|<=H=&6NQru2UV|YJYM*J-reW#QrCQz6tYx&mv$K;vr>2g= zyYIbA^Z$BvH{Ei`_7f?jI$x@~C7%5fF;tO_PJ$p6`z3ZLiLlx%sIP6H&xuI`V1XH* ze*QTgo-mtE>UWusW8)jSAyrmQtdu8Do{YS_JeqHAZidxrrF*DOr=w-_=FP*JHEXcu zzt1E6m*Y@hBL^EjLPCPRQFeKy+Jm4)TY zm;1qsUUay0@xs~}^AQ+N7Gd3D7;_;WH&2B|oXB(c$ctM-`nKNgo z_gt`GfmW8EpHDwkN%WLdiN?prIOzq(9WZf!b2*d8Bv_JGBkWj~+c5d-v|8`KeQ-F8r^TLG-w4K3V@N+&JHf+GGS+i)qwzd`t2?>6tpuTTg$#RTH9f*cYO`s+m6cdx} zMTd5M2NTqXxJ>4F4i1wYg&*wGAUAK`Od-|8LaN|{1`VQ+J*jS8T^+`cA5ZfHlE9Gk z#1l_o&YU?kPqrv1Dy(ih1fHbn=`WzU$qlRBM5D5BCmmUJmBK(s@)sB5#Al_SC-hB z752o56ZA7THy7*Iuh%3`QhM4Xx)?h)9Kmh73V+af=3>ak6dI+89sbC-Q45i z;`$6nw4|!43ZVe*WLSg>*$+S@wdY3~5f zK?XH?2MJ7lpg#7rF$xwo>l-YSh)H( z$e1<}ot{oKyINtO67_&P*qkrvlvtN|UT;?yigq5r%2}&JPWJry^B6pMa718kw;Siq zokK-M1rC=SM$Vd?pfXy%Ld-PRCI@ zbh}#V{`q}XEl!qyhl%xUaPh|hA}rM(_0Aw+G?brd6Le{(H}Gr)g?zEv(bca zzp29RZAI9)Vq4JU=Fgu`qaw1$+3j{}N5pQ)q*_{9=stJst7BNZZfyvB4%6rS3S(|b zLCOt7Fl0mm;u9To!@peb!ljFi6rk~v3$Df%w7T1K^OBn^#&J=O}NQJ~w{#cCpvDtz|IF}%OI zII6ML^oK@h+o&Mh=mFPjlQs6?WAgFp}D7ORQc7EwW~-3*i22)#i^RnXJsK}ScY_MT&9 zr*ZO&O65M+3X@q+$KtrqhYfif1P$iBU0yUdwc=7u6Gn|4f(esSwc7`>pOS?%XrN6W z_(_z7?D-TQ#YsP+_WoZbgd8he;11syY&`)bs>`#tf7co$dzB){gCX<{;7=Tq{nlJi z?})BdNcEG6b+1iHs?UC^`-4JCqHjW15K{dVe6i(K2FaH95mL5M^021u)b^E5eS6W?r2g#13T#iM% zwM4mv^aCV%3#m9-zu)U#eU7JZl4OI1C{;HK$MYlEWVm($`M(hIFB9ay3E=Zfte}}^ z-Zz=R$w_Q~K16*W4Ch;f5DOuXp{gxHEJSy3K2tP%%;?Z{Kp_A8LjEsAy?T2xGn3hK&+DGw z`5xyxXE)qY>8K<@f-fm~zfxbB{M6mE@}%VDtdf`1)=ZwMlglNhT%AW?xx|!*X`|#h zuLQ47fX6QH)r%jAg$`R1c_byHY@NeU{Ud&?2 z<7@pT-+c650qv3p0(lk@xZYzegJYz`DN^F35bu$? z%}bmJFDJ^N-9m;@S3mV)RWC>_eaq~p(jlJ%`i4+fsHPA?O+)rk-Y@*5AVb-4caUly zNm3<>s~-~4LrRj*SqXlYdzC^;5*XkpAQ>$cB-XqBfRI63&J}%7vChyt=#jwcY3iPAJ@bhSvbf7F$2uc>aJBf6F#eRJnE711Vs z4M9TG*cgdMDaimE_)#FcZ7^m4bY!K?}8^NiONi?SBdk)EBh5^e4_*qkvGj@pta!W?6w^|^o9j@t8eaKu_^eP19Y zCC`<17At36DLiCUjz^YeydxH6N4~(L>2v+;pG)9?I^coKd-44G+34!*LThs?3?@Bd ztY&O_a=Pj6U=S^7q-V%7dB3%?tIiN=?Nui5}N9goPw7(#UI>tI2sQT`#26^iA zDNS|VXWjI3*T#IjmAw;2lL3|(6RdU%KHR#OLXvcJ-*LQ`TLiPk0G*Dfix({rY)P0dVMO*i=qgN#e%bE&(i0$3pXKeYY}3t4jd}@3`-tc zP0L?;`6WC#>q-1|{_7~)e+_O|T2)b{V6_$LMp8-T{T zCb=w9NUFLVRbB2#$0t4;?X69ceM->5X0akS`)#a#b^{%zrltmoiHTH_JkJLK@7S>e z4?g&y2LFqD?m}U~UakK0=~Ear>IRxWSo;>W)7BPZuaN`{64e5I7ms#5wNZ7x5ke{+ z(quNkXf$a392Pr1&O4|<=H=&6NQru2UV|YJYM*J-reW#QrCQz6tYx&mv$K;vr>2g= zyYIbA^Z$BvH{Ei`_7f?jI$x@~C7%5fF;tO_PJ$p6`z3ZLiLlx%sIP6H&xuI`V1XH* ze*QTgo-mtE>UWusW8)jSAyrmQtdu8Do{YS_JeqHAZidxrrF*DOr=w-_=FP*JHEXcu zzt1E6m*Y@hBL^EjLPCPRQFeKy+Jm4)TY zm;1qsUUay0@xs~}^AQ+N7Gd3D7;_;WH&2B|oXB(c$ctM-`nKNgo z_gt`GfmW8EpHDwkN%WLdiN?prIOzq(9WZf!b2*d8Bv_JGBkWj~+c5d-v|8`KeQ-F8r^TLG-w4K3V@N+&JHf+GGS+i)qwzd`t2?>6tpuTTg$#RTH9f*cYO`s+m6cdx} zMTd5M2NTqXxJ>4F4i1wYg&*wGAUAK`Od-|8LaN|{1`VQ+J*jS8T^+`cA5ZfHlE9Gk z#1l_o&YU?kPqrv1Dy(ih1fHbn=`WzU$qlRBM5D5BCmmUJmBK(s@)sB5#Al_SC-hB z752o56ZA7THy7*Iuh%3`QhM4Xx)?h)9Kmh73V+af=3>ak6dI+89sbC-Q45i z;`$6nw4|!43ZVe*WLSg>*$+S@wdY3~5f zK?XH?2MJ7lpg#7rF$xwo>l-YSh)H( z$e1<}ot{oKyINtO67_&P*qkrvlvtN|UT;?yigq5r%2}&JPWJry^B6pMa718kw;Siq zokK-M1rC=SM$Vd?pfXy%Ld-PRCI@ zbh}#V{`q}XEl!qyhl%xUaPh|hA}rM(_0Aw+G?brd6Le{(H}Gr)g?zEv(bca zzp29RZAI9)Vq4JU=Fgu`qaw1$+3j{}N5pQ)q*_{9=stJst7BNZZfyvB4%6rS3S(|b zLCOt7Fl0mm;u9To!@peb!ljFi6rk~v3$Df%w7T1K^OBn^#&J=O}NQJ~w{#cCpvDtz|IF}%OI zII6ML^oK@h+o&Mh=mFPjlQs6?WAgFp}D7ORQc7EwW~-3*i22)#i^RnXJsK}ScY_MT&9 zr*ZO&O65M+3X@q+$KtrqhYfif1P$iBU0yUdwc=7u6Gn|4f(esSwc7`>pOS?%XrN6W z_(_z7?D-TQ#YsP+_WoZbgd8he;11syY&`)bs>`#tf7co$dzB){gCX<{;7=Tq{nlJi z?})BdNcEG6b+1iHs?UC^`-4JCqHjW15K{dVe6i(K2FaH95mL5M^021u)b^E5eS6W?r2g#13T#iM% zwM4mv^aCV%3#m9-zu)U#eU7JZl4OI1C{;HK$MYlEWVm($`M(hIFB9ay3E=Zfte}}^ z-Zz=R$w_Q~K16*W4Ch;f5DOuXp{gxHEJSy3K2tP%%;?Z{Kp_A8LjEsAy~P2-zM{_p?(|95=e z?|Sd;E^~}O#`EBzBr(qm|9Is_xbjM=bT60iO1W|`wjkx@_f`4OXS(%Nb>uuBQeRyz z))k*IK^{RP50<=O03!`SVG}b9LfE7-)f|yF8ErK%ytXN!4kHhmp(WA;GBOC{_w?@7 zWhBdJ`c%ymRNORg3bJV7y#Zs zue2XAtXN<4(o%@-%CPDU6KmHOeuwKUTeZ8p?PLsn_Uh9icRI`6D%EY(-F zr-{Q|78a^Fta#`M)wtcT92f?0IbyJHTLJ#DavK~@8(7u|p5wkJ*pN6Zck&(BEU6dk zaO3#VlgRkZ+q8w0e#!X7lVfo+a1+5`FbtMVgvo5Ab^TsHov@C>3ggkPwC*r07YxE3 z<3#D@%Xs>M-^snaGARp%dyl~7j0uA!b)qb0a6yj#nW9*5q9)ufEH5&MD$UC(+NRA$ z0?P&AaM@Ac)PToRrqd=4A321)FY;*qxv{UJ6g;78nc+=0BNJTj1bDCH4@f>p2RLWX^O z{9`h#TBQjr4Og+TIDPuGSSrB&WY9odxlks*J8kN8q@|@{$&mdl@eW-cri z3(ZUFzjCEu8VhDD$GKCbaK|~QM{hSQulyN!S;FmywK^e<_Zl@}hwX&r3Y zD>^Oimasg>(^ZenY{9yvA0qqJ4_XEB`~6^9mZ~I?Qd>!qB1x&KsW@`v2+eyu9z;h+ zYuZ_~C{{vCAx(W6JpSVcuevP!lm5m?Dy_wU~?*O0V?v=ayfMBq$%&3N{GlpMbVS2w#Hs@ha( zaFUn4H7v=ytxg;)EW(1xS@iXV3m0P6tXYVUkH@4*ldx~!KAb;)9_!Yv!-x?huy^m? zc1bo=y`!R{P*x^*>4OIk;>|bTqe)k1|S^z0#@ zGl63`U05=EaWSztd+q`z_IsLkG;H`#96fwY9yA%O+6#NVUMl(IQB88id7b(&6{{(cPo6T zWXKR~+qRA7pLpU4oH}(%Zl9zF9~^<~?01p>+1L0Y=LoE}DC)>~J{(rPzcxtQrcl^m zkVA~qj;59-Jd!w79x7QTk~m2ut7oHX_|{^tI`!?_7lQ{6mfuy|D*;`)bSce~cdDza z=>$v9=goT_eS7uClIJ(z>!TOpinS^B911IM4|Qyqz>sYk@!W5uEk_Vu`Uj z*Nd%@CP`Y$moKN+kt0XatJ+>)e)(lgohnQ?@fXr_5(!8;UVMmNpZ(?As4TmI7`K&f zP1Ufe^P479Rv)*REYCEG(ps zP=b=u=FOWickWzzH*@ApdL=eblGEwJ@e_hSc|HAa)Rrw)GYzA9n+)UZ*Jms;@X|^X zG?+WgHst2)!jie~(uQWwo{hze7s~@6VJ9&$vE5j30IjKhwi{1bTQq4~lv$$1i|NHZfN1GTla$j;90FsziCnwoI=@@2g8 z>MO|GnHN#r$&;VLi!aW{ph1H$ecDWH-?0_hIcd0mWIt42uLUE1eS&ytkJ(3nck%{~ zAqOmUHje%KB<7F*qo&b|7cZhupFVVb{P4pMqpq$FF)=Z>4cOS&i1PAsl$4aqsd_F3{;^Jbu zl4?yme*N4y^c#E^l6of~p{EN@w;j^zJY#{W5NP{f`Ia9ms*oK7cfHXDt* zl06f91|3Gijq4Qz{%+&QAwie<)sxUyHtUz z7p|eQtO^xn6*zhH9MGf;An`un?v%kuO74a3N%4s9;YNISH)0c=SI*CjhhRc*?7mU?h24ytHw$2kxF654*#Hgr41y(k}@OwT<+AY2qv|Jz@o2 zB^h9jV(D=!sY4d^WTQ^%5fvnM81M(s+~h^T7oYVrxH{{w*KRdra1A7sggdGbSa8CZ2) z@dI(ak1skAtWKYi!b&PFcxg4m!E%b)>cFb60x;EpHUJ}n?Lg?cEm*Xw z#!{P-cP_jae#ouo6OR1Wm5 zx^?UEyZ^81tEx_fgW^F^ga~br<0AWy%OR?tEF1T{sNNTK`B<8$Ekleblg}rYqIpJN zwy3)=m%z70DJyDzU46PZ`7wlmkWqw*Mqq%5uojGtp}I0F#s!)~SSh z%X)eupDIS)=ar?q7nxs_`>fDZRl)KKoGO%Sfm4w_P0;pUWUUe)cbU-6d{{rTf&Mk=eAH*BCy2h_vL#gjlkLh zR-2k(BFc&#SNdsSc6}RG?6_Qyfd_CKR%3CsTmz3GDX_#_9hOqGbglKnep0hxf^q1_ zu-mYj9K%G(57P}_w_(X;LKl~=P1>#{0*mw8eh9EQ(@6>}xg7>oEQu=X2LwyWmo!*% zoub(IpnuDlVX~E_q{;sq)P}VNtY{7T5x`Qe#VCV*i(v6@<5o9AE=~CX^d{Nt0ltl4 zwV|>^rZCyl*SP+TDys=tT>eC1g~MUk99FusnVYp24S@zY-FAdRp}&u^fJj)}CtFK4 zuB@iUEa(~(KP*uU!)i0bVl?C9`5W-^q&ax+g(b8cr`v%rg%&weB~@8sG+1h0I_QgB zLlQE>7Qqr>Fc{#rx{&k9R{Ukwhj64?koC7Ov2^w-Sj}cw?G~y)UTJ*i#jps$Ai!ic zCdUl-6c`>jCP}Y(O!V+5sD;x?V#p^|3Q8E5)@HG1LfBtSNjvhVAUfrL6 zJr}#a$b--0fk6;BE0ACri~_tVZtUKC03*^TqWto8_|iPI?AC_GKO=k{+%27631S?u zqM1hGusl8&YN~7Tkb4XRR9#&Sr_+h=zyBV+d-rDPEBDXGfI)q5?do;;bW!SPT6-V9 z*_n^$e(@qr?Kijw7UjGSqftOjl^+5-0Bs#urjP;krUuR=<5E@&VTHr6J8d+5&a`=~ z>b$%>3X7E4t5+}N=H{|{lOCLof-^-(P505~$-mV0KAg@!$6$5pordFIpT*jRS#%OH znGM_o(Q;UPoNe#KWri()MV=w!jooa+$M0{%rsZ2{39r8TDh3Z83_c7SHVn&`FJ~#^ zdOeFPm#)H>=B8$Msh|{@_x_&UzjV5selC1@HTHga2;LMItxptN3ziZUA>;*jiDcU~ z%ng*ufJH1M&69#1U+%{5e>IbJmiSv_wj|2oKS`J|V+Q8VolCF1=`Q4){fG|m!_qP} zfG=FQfR(FO;^kQ{)A+{Y3((~sI-=rgC7nfE42yX94F=SkgAnopxhk+E!6Jinn$L$5 z-=0Qh|KG5Vo;-OHci(-t1`-K;{NA76i~OVc^m^!{_o1O7g#BCcS>A$z0^D`iUG!Rz z1}@xlUtcW9c>yMi3AI(VbUbSbEINkCz_cgdtqhA)LSx{--_lj@ae4MJ$v@Vv(G-OD_a|kMk9URVzJ=TrAzGIop;`et3@}kX3ZK5 z88Sqptd1Q!VrTA7di}v`>#%$CL3n&lu7AyhrA#2y57Y2!9xT!^;zT-JcKS)435z1E zb}Nj65esH5#l`PSS*LgI+{sK&>1?#1C@&);1Nr%q85R~6(odVsrg=hX=kQ^}@z&dK z(d$1@##*ZJ5!-o&EI03Ji<{xML5d#MHqu0}i%}3?+ zD!9B3h~aSaV2SEK?Lls$utc)cV1vbE!s>U|;a_@A!s}D#Vq11Dii<8G=d*2i^|^Q8 zLK+Ir72wGypTxLv<8o;>So_xvc8X_vrj^I*s3U2(x$w{9JUrF16Iz|Wj3R;FF*Pu9K-ZSRVVa=4?dt}6c-m$1&kd# zmfg$D%*4fu7b&df0E0YpD$pt`D_MG0Ru<;Xo5!H>eVH<43Nj~7px2ZBX#rK3+iRDh zB?3!|3w!IfiH5L%FqAhF8y4}a(!4$tUA%}#yG&$_o;Gb7=FguW(aE!C&tm`n{doH6 zr)m7FufD>F5hI!fObLqVk+O-4qJ*tmw_@bTkrDa)em@)z2TjZT?I=utEfaOM^$64l zd>om*REX{K72TfpE+{|J$m$rSZa|~Mc=-CX`VkXc@Dpt@QcE!eqGw9Pak~p$tM!9DNAwU@HzO>T%4=XI4s_^kbBqkm}PfbVSs>l z|9cVgcYntkc;dtfcsw4qNjQD_G+uh?B?b+$`bl_y z!9ux()mZd@SrnGdZqX?%3M_WaCXW&?(6{LN{mC-AbnE3hg=V|)qYxiLDx;!{sWThfR zb!ws87UI4i772@FOm+EiNo5*kDKAU~DD0{E zLUJpFum%=sK$-t_cz+`M^{K2cIqLKUYE zWOt);=gusZxF6lScaO+7^G`2g&Kqyi>y3wAL0WqcDl4jCV85oMf-(n{`Qzzyd5qOV0@(A5YXiY$TP+$>tm6erIzl#KA^O5X{kv5UT z6EXpH?b?;CANeq8(j=Nr6#3X=k1SQm1divG?0hYrpjU<|f_b7ur;OpRlAR16{5-9Dk`FT^hC)Yee@9y9Xb><|G3G+(6e6`q_y|bMYSizN&Q8u)kL>* z6f+9e2T@b)rw|Cd!ZW4V{^_?UE+~y!?z+4`q5U0RRNbgy{uu+dtLk&n$Oe6hrrlx1 zjq*w?`ri++aY+s>q|2RMP+VFJ1k{2jOqjr??&gGR*RIhe3)xNGzI{90T#OYaO!+1H zKiCTyUE9Ie&P^dXoL0JTPY*g|CzYHm(QC!o6a=a^!64=F*Va>bCvfWGyKbV`3WpAv;fvxH>J_)I5DY#x< zL8tDAAAT6Asi|}Z^Z9(#1+ZGJYz;`vtFEq&&ThmVAf`pW7O-T=l9+&oKXxA;{6&BC z=-V0XI;J2c-3^!94zpR>@2{=)qxxno>T2pJ1aji-ucYxKW$yZrXgKK3saJl$8P8_{}zrMKzzj@)GF?QmEnpsj-*e1~!5)cx? z8b^)H6vV@KyPT-5t-+}yXRtGCA6C4zzS)XuDhwRa2lox_gS+qTM$Z*f(>=6vL_I`B z;f4@ylvm-}0k<9fI|txa%4ENFVeY*bTk!>4GlZ+M#_$3e08$ zf`JD5a<5#fpf8|Z2M@PfVS?XU4`J8MY-*A!Fy8-AcUE0)2ZF&Mu9cRf@XSS=KT(Ja zr;D-u)4eD!xsebUv(1E&;|EhH=^3fW=$el9ozmzS8X;%VuZnH zKq%NiO^H4m3NzowXfh&D7r=p?$5B#P24AY19%z_M23>pA%}?!DJE7f;(B<{l)T5;6 z8oKw%z`!9rXx-W!St&0Y^m8k-*r4AStcWjla0RvKn}51S#eZ(tSpGOpf1*;Ut!icuJOQ%wuSp+g~iv&ej_(FtSHh>1dbAqyYsC8OSfol2`s)YlUh+M zWkr&Xt*m%pft8gMWwkOarA+RZv)WQwjhW34RavS9n$)2ywz6&sGmKkVjlHx+(nPg= z>ffzs6J;dqy896M}^%VWAON z{2m=QhN+Ec8)dZ+7C*ozQCS*`)6bGWPFPJVD=t`aovI%u+yby7RMVQuieoJ2f9Lzh z2P;u!H4aNv9=NrnkZf3JJy>W8Rx6EJy73F5;#M?ESuq-w4A+5&C30mZ6&BAzN|y$G zA}=9Xu##Yg3B!t3S3JtnvrycMc$F1%E!ax1be%~Ktk?s5gt>F@42i+QPXLxqSvn=M zG3>Uo)a$6Q6q6*U-sF$EippP_r5^&`{Y>-jY8hsv7VCo@9c9KEU z!PPvgQ4%x&$+bP;K)@7)iTt@>@)vMJ0^g}9jf+D$v8MQD&615mid2DCSyAfbttK8t g>CBSAs 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/80x80.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/80x80.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3b331a8fad9288aebccbc0447ec14a1aec3cd6 GIT binary patch literal 4657 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/87x87.png b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/87x87.png new file mode 100644 index 0000000000000000000000000000000000000000..54e3ffe06c806fdf184433fe341b6b23417580d9 GIT binary patch literal 5633 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 blY;m^O&0Lu`X?7w00000NkvXXu0mjf*U9%% literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json index 9221b9b..b51241a 100644 --- a/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/SanTa/SanTa/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,91 +1,109 @@ { "images" : [ { + "filename" : "40x40.png", "idiom" : "iphone", "scale" : "2x", "size" : "20x20" }, { + "filename" : "60x60.png", "idiom" : "iphone", "scale" : "3x", "size" : "20x20" }, { + "filename" : "58x58.png", "idiom" : "iphone", "scale" : "2x", "size" : "29x29" }, { + "filename" : "87x87.png", "idiom" : "iphone", "scale" : "3x", "size" : "29x29" }, { + "filename" : "80x80.png", "idiom" : "iphone", "scale" : "2x", "size" : "40x40" }, { + "filename" : "120x120.png", "idiom" : "iphone", "scale" : "3x", "size" : "40x40" }, { + "filename" : "120x120-1.png", "idiom" : "iphone", "scale" : "2x", "size" : "60x60" }, { + "filename" : "180x180.png", "idiom" : "iphone", "scale" : "3x", "size" : "60x60" }, { + "filename" : "20x20.png", "idiom" : "ipad", "scale" : "1x", "size" : "20x20" }, { + "filename" : "40x40-1.png", "idiom" : "ipad", "scale" : "2x", "size" : "20x20" }, { + "filename" : "29x29.png", "idiom" : "ipad", "scale" : "1x", "size" : "29x29" }, { + "filename" : "58x58-1.png", "idiom" : "ipad", "scale" : "2x", "size" : "29x29" }, { + "filename" : "40x40-2.png", "idiom" : "ipad", "scale" : "1x", "size" : "40x40" }, { + "filename" : "80x80-1.png", "idiom" : "ipad", "scale" : "2x", "size" : "40x40" }, { + "filename" : "76x76.png", "idiom" : "ipad", "scale" : "1x", "size" : "76x76" }, { + "filename" : "152x152.png", "idiom" : "ipad", "scale" : "2x", "size" : "76x76" }, { + "filename" : "167x167.png", "idiom" : "ipad", "scale" : "2x", "size" : "83.5x83.5" }, { + "filename" : "1024x1024.png", "idiom" : "ios-marketing", "scale" : "1x", "size" : "1024x1024" diff --git a/SanTa/SanTa/Resources/Assets.xcassets/SantaColor.colorset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/SantaColor.colorset/Contents.json new file mode 100644 index 0000000..5c8fb6b --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/SantaColor.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "95", + "green" : "205", + "red" : "130" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/120x120Circle.png b/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/120x120Circle.png new file mode 100644 index 0000000000000000000000000000000000000000..2f87f90820095ea2cbefe1192fb6281b37733dda GIT binary patch literal 9683 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 KMNUMnLSTZzsCHHW literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/80x80Circle.png b/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/80x80Circle.png new file mode 100644 index 0000000000000000000000000000000000000000..fad4f6e6dd34d2a13839df44af1720c0e1092172 GIT binary patch literal 5550 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 literal 0 HcmV?d00001 diff --git a/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/Contents.json new file mode 100644 index 0000000..5f1d19c --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/SantaImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "40x40Circle.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "80x80Circle.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "120x120Circle.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} From 999e3ba0ba95b2ae396a934c45e4583e599b006d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 9 Nov 2021 09:10:42 +0900 Subject: [PATCH 089/465] =?UTF-8?q?[Fix]=20UserDefaults=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=EA=B0=9D=EC=B2=B4=20=EC=9D=B4=EB=A6=84,=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 10 ++++------ .../UserDefaultsStorage.swift} | 4 ++-- SanTa/SanTa/SettingsScene/SettingsRepository.swift | 4 ++-- .../SanTa/SettingsScene/SettingsViewCoordinator.swift | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) rename SanTa/SanTa/{SettingsScene/UserDefaultsSettingsStorage.swift => Persistences/UserDefaultsStorage.swift} (92%) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 465da03..31d45f5 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -38,7 +38,6 @@ 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; - 9826F43B2739546E0064FA85 /* UserDefaultsSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */; }; 9826F43C2739546E0064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; 9826F43D2739546E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; @@ -49,7 +48,7 @@ 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF62272FDA98002413D9 /* MountainCell.swift */; }; 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */; }; 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; - 98A913012736844E008AAE39 /* UserDefaultsSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */; }; + 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; @@ -109,7 +108,7 @@ 985EEF62272FDA98002413D9 /* MountainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainCell.swift; sourceTree = ""; }; 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleOptionCell.swift; sourceTree = ""; }; 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; - 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsSettingsStorage.swift; sourceTree = ""; }; + 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsStorage.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; @@ -197,7 +196,6 @@ 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */, 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */, 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */, - 98A913002736844E008AAE39 /* UserDefaultsSettingsStorage.swift */, 9826F3DE273904010064FA85 /* Settings.swift */, 9826F3DC2739035E0064FA85 /* Option.swift */, ); @@ -217,6 +215,7 @@ children = ( 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */, 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */, + 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */, ); path = Persistences; sourceTree = ""; @@ -425,7 +424,7 @@ 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, - 98A913012736844E008AAE39 /* UserDefaultsSettingsStorage.swift in Sources */, + 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, @@ -452,7 +451,6 @@ 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */, 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */, 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, - 9826F43B2739546E0064FA85 /* UserDefaultsSettingsStorage.swift in Sources */, 9826F43C2739546E0064FA85 /* Settings.swift in Sources */, 9826F43D2739546E0064FA85 /* Option.swift in Sources */, 9826F437273954030064FA85 /* SettingsUsecaseTests.swift in Sources */, diff --git a/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift similarity index 92% rename from SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift rename to SanTa/SanTa/Persistences/UserDefaultsStorage.swift index 4f21757..888bdd2 100644 --- a/SanTa/SanTa/SettingsScene/UserDefaultsSettingsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -7,14 +7,14 @@ import Foundation -protocol SettingsStorage { +protocol UserDefaultsStorage { func save(value: T, key: Settings) func exist(key: Settings, completion: @escaping (Bool) -> Void) func bool(key: Settings, completion: @escaping (Bool) -> Void) func string(key: Settings, completion: @escaping (String?) -> Void) } -final class UserDefaultsSettingsStorage: SettingsStorage { +final class DefaultUserDefaultsStorage: UserDefaultsStorage { let userDefaults: UserDefaults diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift index 9d3e18d..aa9c28b 100644 --- a/SanTa/SanTa/SettingsScene/SettingsRepository.swift +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -15,9 +15,9 @@ protocol SettingsRepository { final class DefaultSettingsRepository: SettingsRepository { - let settingsStorage: SettingsStorage + let settingsStorage: UserDefaultsStorage - init(settingsStorage: SettingsStorage) { + init(settingsStorage: UserDefaultsStorage) { self.settingsStorage = settingsStorage } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 668db7f..5184476 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -25,7 +25,7 @@ class SettingsViewCoordinator: Coordinator { extension SettingsViewCoordinator { private func injectDependencies() -> SettingsViewController { - let persistence = UserDefaultsSettingsStorage() + let persistence = DefaultUserDefaultsStorage() let repository = DefaultSettingsRepository(settingsStorage: persistence) let usecase = DefaultSettingsUsecase(settingsRepository: repository) let viewModel = SettingsViewModel(settingsUseCase: usecase) From 0d5785ec5d02343059fc6e9a8b81bef51caa660d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 9 Nov 2021 11:40:16 +0900 Subject: [PATCH 090/465] =?UTF-8?q?[Fix]=20SettingsRepository=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=86=A0=EC=BD=9C=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 1 + SanTa/SanTa/SettingsScene/SettingsRepository.swift | 8 ++++---- SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 14 +++++++------- .../SettingsSceneTests/SettingsUsecaseTests.swift | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index d0f8e9c..023afa5 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -25,6 +25,7 @@ class MapViewController: UIViewController { self.registerAnnotationView() self.configureCoreLocationManager() self.configureViewModel() + //print(UserDefaults.standard.string(forKey: "지도 형식")) } override func viewWillAppear(_ animated: Bool) { diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift index aa9c28b..903de8f 100644 --- a/SanTa/SanTa/SettingsScene/SettingsRepository.swift +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -9,8 +9,8 @@ import Foundation protocol SettingsRepository { func save(value: T, key: Settings) - func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) - func getMapOption(key: Settings, completion: @escaping (Option) -> Void) + func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) + func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) } final class DefaultSettingsRepository: SettingsRepository { @@ -25,7 +25,7 @@ final class DefaultSettingsRepository: SettingsRepository { self.settingsStorage.save(value: value, key: key) } - func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) { + func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) { self.settingsStorage.exist(key: key) { exist in if !exist { guard let value = key.initValue as? Bool else { return } @@ -38,7 +38,7 @@ final class DefaultSettingsRepository: SettingsRepository { } } - func getMapOption(key: Settings, completion: @escaping (Option) -> Void) { + func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) { self.settingsStorage.exist(key: key) { exist in if !exist { guard let value = key.initValue as? String else { return } diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 4c6cc04..a4977c2 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -31,25 +31,25 @@ final class DefaultSettingsUsecase: SettingsUsecase { var voiceSettings: [Option] = [] var mapSetting: [Option] = [] - self.settingsRepository.getToggleOption(key: Settings.recordPhoto) { value in + self.settingsRepository.makeToggleOption(key: Settings.recordPhoto) { value in photoSettings.append(value) } - self.settingsRepository.getToggleOption(key: Settings.photosOnMap) { value in + self.settingsRepository.makeToggleOption(key: Settings.photosOnMap) { value in photoSettings.append(value) } - self.settingsRepository.getToggleOption(key: Settings.autoPauseResume) { value in + self.settingsRepository.makeToggleOption(key: Settings.autoPauseResume) { value in autoSettins.append(value) } - self.settingsRepository.getToggleOption(key: Settings.autoPauseResumeVoiceGuidance) { value in + self.settingsRepository.makeToggleOption(key: Settings.autoPauseResumeVoiceGuidance) { value in autoSettins.append(value) } - self.settingsRepository.getToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in + self.settingsRepository.makeToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in voiceSettings.append(value) } - self.settingsRepository.getMapOption(key: Settings.mapFormat) { value in + self.settingsRepository.makeMapOption(key: Settings.mapFormat) { value in mapSetting.append(value) } - self.settingsRepository.getToggleOption(key: Settings.markHikingTrailsOnTheMap) { value in + self.settingsRepository.makeToggleOption(key: Settings.markHikingTrailsOnTheMap) { value in mapSetting.append(value) } diff --git a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift index 3b474c0..b47b1a3 100644 --- a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift +++ b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift @@ -14,11 +14,11 @@ class SettingsUsecaseTests: XCTestCase { } - func getToggleOption(key: Settings, completion: @escaping (Option) -> Void) { + func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) { completion(ToggleOption(text: "토글", toggle: true)) } - func getMapOption(key: Settings, completion: @escaping (Option) -> Void) { + func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) { completion(MapOption(text: "맵", map: .infomation)) } } From 1edb049218034a4466a480b7d81606da8a4d3ea3 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 9 Nov 2021 13:59:48 +0900 Subject: [PATCH 091/465] =?UTF-8?q?[Feat]=20#100=20=EC=95=B1=20=EC=B2=98?= =?UTF-8?q?=EC=9D=8C=20=EC=8B=A4=ED=96=89=20=EC=8B=9C=20UserDefaults=20?= =?UTF-8?q?=EA=B0=92=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 1 + SanTa/SanTa/Application/SceneDelegate.swift | 1 - SanTa/SanTa/MapScene/MapViewController.swift | 1 - .../Persistences/UserDefaultsStorage.swift | 41 +++++++++++++++++-- .../SettingsScene/SettingsRepository.swift | 29 ++++--------- .../SettingsViewCoordinator.swift | 3 +- 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 210a1b2..e91fd63 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -25,6 +25,7 @@ class AppCoordinator: Coordinator { } func start() { + DefaultUserDefaultsStorage.shared.makeFirstData() let tabBarController = self.setTabBarController() self.window?.rootViewController = tabBarController } diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 18e4a5e..0e4098a 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -15,7 +15,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let windowScene = (scene as? UIWindowScene) else { return } self.window = UIWindow(windowScene: windowScene) self.appCoordinator = AppCoordinator(window) - appCoordinator?.start() } diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 023afa5..d0f8e9c 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -25,7 +25,6 @@ class MapViewController: UIViewController { self.registerAnnotationView() self.configureCoreLocationManager() self.configureViewModel() - //print(UserDefaults.standard.string(forKey: "지도 형식")) } override func viewWillAppear(_ animated: Bool) { diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index 888bdd2..1b2017d 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -9,16 +9,18 @@ import Foundation protocol UserDefaultsStorage { func save(value: T, key: Settings) - func exist(key: Settings, completion: @escaping (Bool) -> Void) + func exist(key: Settings) -> Bool func bool(key: Settings, completion: @escaping (Bool) -> Void) func string(key: Settings, completion: @escaping (String?) -> Void) } final class DefaultUserDefaultsStorage: UserDefaultsStorage { + static let shared = DefaultUserDefaultsStorage() + let userDefaults: UserDefaults - init(useuserDefaults: UserDefaults = UserDefaults.standard) { + private init(useuserDefaults: UserDefaults = UserDefaults.standard) { self.userDefaults = useuserDefaults } @@ -26,8 +28,8 @@ final class DefaultUserDefaultsStorage: UserDefaultsStorage { self.userDefaults.set(value, forKey: key.title) } - func exist(key: Settings, completion: @escaping (Bool) -> Void) { - completion(self.userDefaults.object(forKey: key.title) != nil) + func exist(key: Settings) -> Bool { + return self.userDefaults.object(forKey: key.title) != nil } func bool(key: Settings, completion: @escaping (Bool) -> Void) { @@ -37,4 +39,35 @@ final class DefaultUserDefaultsStorage: UserDefaultsStorage { func string(key: Settings, completion: @escaping (String?) -> Void) { completion(self.userDefaults.string(forKey: key.title)) } + + func makeFirstData() { + if !self.exist(key: .recordPhoto) { + self.save(value: Settings.recordPhoto.initValue as? Bool, + key: .recordPhoto) + } + if !self.exist(key: .photosOnMap) { + self.save(value: Settings.photosOnMap.initValue as? Bool, + key: .photosOnMap) + } + if !self.exist(key: .autoPauseResume) { + self.save(value: Settings.autoPauseResume.initValue as? Bool, + key: .autoPauseResume) + } + if !self.exist(key: .autoPauseResumeVoiceGuidance) { + self.save(value: Settings.autoPauseResumeVoiceGuidance.initValue as? Bool, + key: .autoPauseResumeVoiceGuidance) + } + if !self.exist(key: .voiceGuidanceEveryOnekm) { + self.save(value: Settings.voiceGuidanceEveryOnekm.initValue as? Bool, + key: .voiceGuidanceEveryOnekm) + } + if !self.exist(key: .mapFormat) { + self.save(value: Settings.mapFormat.initValue as? String, + key: .mapFormat) + } + if !self.exist(key: .markHikingTrailsOnTheMap) { + self.save(value: Settings.markHikingTrailsOnTheMap.initValue as? Bool, + key: .markHikingTrailsOnTheMap) + } + } } diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift index 903de8f..356b2fd 100644 --- a/SanTa/SanTa/SettingsScene/SettingsRepository.swift +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -26,31 +26,18 @@ final class DefaultSettingsRepository: SettingsRepository { } func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) { - self.settingsStorage.exist(key: key) { exist in - if !exist { - guard let value = key.initValue as? Bool else { return } - self.settingsStorage.save(value: value, key: key) - } - self.settingsStorage.bool(key: key) { value in - let option = ToggleOption(text: key.title, toggle: value) - completion(option) - } + self.settingsStorage.bool(key: key) { value in + let option = ToggleOption(text: key.title, toggle: value) + completion(option) } } func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) { - self.settingsStorage.exist(key: key) { exist in - if !exist { - guard let value = key.initValue as? String else { return } - self.settingsStorage.save(value: value, key: key) - } - self.settingsStorage.string(key: key) { value in - guard let value = value else { return } - guard let map = Map.init(rawValue: value) else { return } - let option = MapOption(text: key.title, map: map) - completion(option) - } + self.settingsStorage.string(key: key) { value in + guard let value = value else { return } + guard let map = Map.init(rawValue: value) else { return } + let option = MapOption(text: key.title, map: map) + completion(option) } } } - diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 5184476..7c8f2d9 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -25,8 +25,7 @@ class SettingsViewCoordinator: Coordinator { extension SettingsViewCoordinator { private func injectDependencies() -> SettingsViewController { - let persistence = DefaultUserDefaultsStorage() - let repository = DefaultSettingsRepository(settingsStorage: persistence) + let repository = DefaultSettingsRepository(settingsStorage: DefaultUserDefaultsStorage.shared) let usecase = DefaultSettingsUsecase(settingsRepository: repository) let viewModel = SettingsViewModel(settingsUseCase: usecase) let viewController = SettingsViewController(viewModel: viewModel) From 13ec2cd6a4bc79cc8a441f46f0441009b00359e0 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 9 Nov 2021 14:04:57 +0900 Subject: [PATCH 092/465] =?UTF-8?q?[Refactor]=20#93,=20#91,=20#85=20CLLoca?= =?UTF-8?q?tionManager=20=EB=8C=80=EC=8B=A0=20CLLocation=3F=20=EC=9D=84=20?= =?UTF-8?q?MountainDetailViewUseCase=20=EC=9D=98=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 2 +- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 15 +++++++------- .../MountainDetailUseCase.swift | 20 +++++++------------ .../MountainDetailViewController.swift | 5 +++++ .../MountainDetailViewCoordinator.swift | 19 ++++++------------ 5 files changed, 27 insertions(+), 34 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index cafe532..33e8eff 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -157,7 +157,7 @@ extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { guard let annotation = view.annotation as? MountainAnnotation else { return } - coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation, locationManager: self.manager) + coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation, location: self.manager.location) } } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index b350fb9..cfda20a 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -27,15 +27,16 @@ class MapViewCoordinator: Coordinator { extension MapViewCoordinator { func presentRecordingViewController() { - let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) - self.childCoordinators.append(recordingViewCoordinator) - recordingViewCoordinator.parentCoordinator = self - - recordingViewCoordinator.start() + if self.childCoordinators.isEmpty { + let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + self.childCoordinators.append(recordingViewCoordinator) + recordingViewCoordinator.parentCoordinator = self + } + childCoordinators.first?.start() } - func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, locationManager: locationManager) + func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation, location: CLLocation?) { + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: location) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 26ef51f..91972e2 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -10,31 +10,24 @@ import CoreLocation class MountainDetailUseCase { private let mountainAnnotation: MountainAnnotation - private let locationManager: CLLocationManager + private let location: CLLocation? - init(mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { + init(mountainAnnotation: MountainAnnotation, location: CLLocation?) { self.mountainAnnotation = mountainAnnotation - self.locationManager = locationManager + self.location = location } private func calculateDistance() -> Double? { - let canGetCurrentLocation = locationManager.authorizationStatus == .authorizedWhenInUse || - locationManager.authorizationStatus == .authorizedAlways - guard canGetCurrentLocation, let currentLocation = locationManager.location else { - return nil - } let mountainLocation = CLLocation(latitude: self.mountainAnnotation.latitude, longitude: self.mountainAnnotation.longitude) - let distance = currentLocation.distance(from: CLLocation(latitude: mountainLocation.coordinate.latitude, longitude: mountainLocation.coordinate.longitude)) - + let distance = location?.distance(from: mountainLocation) + print(distance) return distance } private func mountainRegions() -> [String] { return mountainAnnotation.region.components(separatedBy: ", ") } -} - -extension MountainDetailUseCase { + func transferMountainInformation(completion: @escaping (MountainDetailModel) -> Void) { guard let name = mountainAnnotation.title, let altitude = mountainAnnotation.subtitle else { return } @@ -42,3 +35,4 @@ extension MountainDetailUseCase { completion(MountainDetailModel(moutainName: name, distance: calculateDistance(), regions: mountainRegions(), altitude: altitude, latitude: mountainAnnotation.latitude, longitude: mountainAnnotation.longitude, mountainDescription: mountainAnnotation.mountainDescription)) } } + diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index edd81f0..a9c33d6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -22,6 +22,11 @@ class MountainDetailViewController: UIViewController { self.configureViewModel() } + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + self.coordinator?.dismiss() + } + private func configureViewModel() { self.viewModel?.mountainInfoReceived = { mountainDetail in self.layoutMountainDetailView(mountainDetail: mountainDetail) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index db61d3a..0b53972 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -16,29 +16,22 @@ class MountainDetailViewCoordinator: Coordinator { var mountainDetailViewController: MountainDetailViewController func start() { -// if self.parentCoordinator is MountainListViewCoordinator { } - self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) + if self.parentCoordinator is MapViewCoordinator { + self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) + } } func dismiss() { self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinators.removeAll(where: { coordinator in - coordinator is Self - }) + self.parentCoordinator?.childCoordinators.removeLast() } - //지도화면에서 바로 올때 - init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation, locationManager: CLLocationManager) { + init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation, location: CLLocation?) { self.navigationController = navigationController - let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation, locationManager: locationManager)) + let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation, location: location)) self.mountainDetailViewController = MountainDetailViewController(viewModel: viewModel) self.mountainDetailViewController.coordinator = self } - //산 목록에서 올때 -// init(navigationController: UINavigationController, mountainDetailModel: MountainDetailModel) { -// -// } - } From 41625b862f328e73bb77aa9eebf8f7f9900ab67c Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 14:51:32 +0900 Subject: [PATCH 093/465] =?UTF-8?q?[Feat]=20#103=20RecordingTitle=20View?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 12 ++ .../RecordingTitleViewController.swift | 126 ++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 24328f0..8e3f614 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -55,6 +55,7 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; @@ -117,6 +118,7 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; + DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; @@ -290,6 +292,7 @@ 54731B61272F7F7600534097 /* MapScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, + DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB9272F8BD9002F9D40 /* MountainListScene */, 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, @@ -307,6 +310,14 @@ path = SettingsSceneTests; sourceTree = ""; }; + DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */ = { + isa = PBXGroup; + children = ( + DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */, + ); + path = RecordingTitleScene; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -441,6 +452,7 @@ 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, + DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */, DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 9826F3DF273904010064FA85 /* Settings.swift in Sources */, diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift new file mode 100644 index 0000000..6607156 --- /dev/null +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -0,0 +1,126 @@ +// +// RecordingTitleViewController.swift +// SanTa +// +// Created by 김민창 on 2021/11/09. +// + +import UIKit + +class RecordingTitleViewController: UIViewController { + + private var displayView: UIView = { + let view = UIView() + view.backgroundColor = .white + view.layer.masksToBounds = true + view.layer.cornerRadius = 12 + return view + }() + + private let recordingTitle: UILabel = { + let label = UILabel() + label.text = "기록 제목" + label.font = .boldSystemFont(ofSize: 24) + label.textColor = .systemGray + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let recordingTitleDescription: UILabel = { + let label = UILabel() + label.text = "이 기록에 대한 제목을 입력해주세요." + label.font = .systemFont(ofSize: 20) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let recordingTitleText: UITextField = { + let textField = UITextField() + textField.font = .systemFont(ofSize: 22) + textField.clearButtonMode = .whileEditing + textField.textAlignment = .center + textField.borderStyle = .none + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let inputButton: UIButton = { + let button = UIButton() + button.backgroundColor = .systemBlue + button.setTitle("입력", for: .normal) + button.setTitleColor(.white, for: .normal) + button.layer.masksToBounds = true + button.layer.cornerRadius = 6 + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private let notInputButton: UIButton = { + let button = UIButton() + button.setTitle("입력 안함", for: .normal) + button.setTitleColor(.systemBlue, for: .normal) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + private let titleStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 12 + stackView.axis = .vertical + stackView.distribution = .fillEqually + stackView.alignment = .center + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + override func viewDidLoad() { + super.viewDidLoad() + + self.configureConstraints() + self.titleTextFieldUnderLine() + } + + private func configureConstraints() { + let frameWidth = view.frame.width + let frameHeight = view.frame.height + + self.displayView.frame = CGRect(x: 6, y: frameHeight/2 - frameWidth * 2/3, width: frameWidth - 12, height: frameHeight/3) + + [self.recordingTitle, self.recordingTitleDescription, self.recordingTitleText, self.inputButton, self.notInputButton].forEach { + self.titleStackView.addArrangedSubview($0) + } + + self.view.addSubview(displayView) + self.displayView.addSubview(titleStackView) + + let inputButtonConstraints = [ + self.inputButton.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let recordingTitleText = [ + self.recordingTitleText.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let titleStackViewConstraints = [ + self.titleStackView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 16), + self.titleStackView.leadingAnchor.constraint(equalTo: self.displayView.leadingAnchor, constant: 16), + self.titleStackView.trailingAnchor.constraint(equalTo: self.displayView.trailingAnchor, constant: -16), + self.titleStackView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -16) + ] + + NSLayoutConstraint.activate(recordingTitleText) + NSLayoutConstraint.activate(inputButtonConstraints) + NSLayoutConstraint.activate(titleStackViewConstraints) + + self.view.layoutIfNeeded() + } + + private func titleTextFieldUnderLine() { + let border = CALayer() + border.frame = CGRect(x: 1, y: self.recordingTitleText.frame.size.height - 1, width: self.recordingTitleText.frame.width - 1, height: 1) + border.borderWidth = 1 + border.backgroundColor = UIColor.systemGray2.cgColor + self.recordingTitleText.layer.addSublayer(border) + } + +} From ec36db284c8be0612c14d29e346c0bbcf8f041d9 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 14:58:25 +0900 Subject: [PATCH 094/465] =?UTF-8?q?[Feat]=20#103=20RecordingTitleView=20?= =?UTF-8?q?=ED=82=A4=EB=B3=B4=EB=93=9C=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleViewController.swift | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 6607156..b30560b 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -73,13 +73,21 @@ class RecordingTitleViewController: UIViewController { return stackView }() + private var keyHeight: CGFloat? + override func viewDidLoad() { super.viewDidLoad() + self.configureNotification() self.configureConstraints() self.titleTextFieldUnderLine() } + private func configureNotification() { + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) + } + private func configureConstraints() { let frameWidth = view.frame.width let frameHeight = view.frame.height @@ -124,3 +132,19 @@ class RecordingTitleViewController: UIViewController { } } + +extension RecordingTitleViewController { + @objc func keyboardWillShow(_ sender: Notification) { + let userInfo:NSDictionary = sender.userInfo! as NSDictionary + let keyboardFrame:NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue + let keyboardRectangle = keyboardFrame.cgRectValue + let keyboardHeight = keyboardRectangle.height + keyHeight = keyboardHeight + + self.view.frame.size.height -= keyboardHeight + } + + @objc func keyboardWillHide(_ sender: Notification) { + self.view.frame.size.height += keyHeight! + } +} From 7ab46492aff0d11a432f06553479ec6bb45de94f Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 15:53:24 +0900 Subject: [PATCH 095/465] =?UTF-8?q?[Feat]=20#102=20RcordingTitleView=20Coo?= =?UTF-8?q?rdinator=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20Present?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 +++ .../RecordingViewController.swift | 12 ++++--- .../RecordingViewCoordinator.swift | 9 ++++++ .../RecordingTitleViewController.swift | 9 ++++-- .../RecordingTitleViewCoordinator.swift | 32 +++++++++++++++++++ 5 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 8e3f614..eed33b7 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; + DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; @@ -119,6 +120,7 @@ 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; + DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; @@ -314,6 +316,7 @@ isa = PBXGroup; children = ( DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */, + DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */, ); path = RecordingTitleScene; sourceTree = ""; @@ -457,6 +460,7 @@ 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 9826F3DF273904010064FA85 /* Settings.swift in Sources */, 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, + DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 3d105af..a0489b4 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -139,11 +139,13 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in - self?.recordingViewModel?.save() { [weak self] completion in - DispatchQueue.main.async { - self?.coordinator?.dismiss() - } - } + self?.coordinator?.presentRecordingTitleViewController() + +// self?.recordingViewModel?.save() { [weak self] completion in +// DispatchQueue.main.async { +// self?.coordinator?.dismiss() +// } +// } } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index efde4f3..18f1ea7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -40,3 +40,12 @@ class RecordingViewCoordinator: Coordinator { } } +extension RecordingViewCoordinator { + func presentRecordingTitleViewController() { + let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(navigationController: self.navigationController) + self.childCoordinator.append(recordingTitleViewCoordinator) + recordingTitleViewCoordinator.parentCoordinator = self + + recordingTitleViewCoordinator.start() + } +} diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index b30560b..0bf789f 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -8,6 +8,7 @@ import UIKit class RecordingTitleViewController: UIViewController { + weak var coordinator: RecordingTitleViewCoordinator? private var displayView: UIView = { let view = UIView() @@ -92,7 +93,7 @@ class RecordingTitleViewController: UIViewController { let frameWidth = view.frame.width let frameHeight = view.frame.height - self.displayView.frame = CGRect(x: 6, y: frameHeight/2 - frameWidth * 2/3, width: frameWidth - 12, height: frameHeight/3) + self.displayView.frame = CGRect(x: 6, y: frameHeight - frameHeight/2, width: frameWidth - 12, height: frameHeight/3) [self.recordingTitle, self.recordingTitleDescription, self.recordingTitleText, self.inputButton, self.notInputButton].forEach { self.titleStackView.addArrangedSubview($0) @@ -141,10 +142,12 @@ extension RecordingTitleViewController { let keyboardHeight = keyboardRectangle.height keyHeight = keyboardHeight - self.view.frame.size.height -= keyboardHeight + self.displayView.frame.origin.y -= keyboardHeight } @objc func keyboardWillHide(_ sender: Notification) { - self.view.frame.size.height += keyHeight! + guard let keyHeight = keyHeight else { return } + + self.displayView.frame.origin.y += keyHeight } } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift new file mode 100644 index 0000000..af93c4f --- /dev/null +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -0,0 +1,32 @@ +// +// RecordingTitleViewCoordinator.swift +// SanTa +// +// Created by 김민창 on 2021/11/09. +// + +import UIKit + +class RecordingTitleViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController + var childCoordinator: [Coordinator] = [] + var recordingTitleViewController: RecordingTitleViewController + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + self.recordingTitleViewController = RecordingTitleViewController() + self.recordingTitleViewController.coordinator = self + } + + func start() { + guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + + recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) + } + + func dismiss() { + self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinator.removeAll() + } +} From 135e973966f3a7055d01c6e5abff3f4aa7b98c07 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:00:17 +0900 Subject: [PATCH 096/465] =?UTF-8?q?[Feat]=20#105=20RecordingViewDelegate?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingViewController.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index a0489b4..31c2b66 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -8,6 +8,10 @@ import UIKit import Combine +protocol RecordingViewDelegate: AnyObject { + func didTitleWriteDone(title: String) +} + class RecordingViewController: UIViewController { weak var coordinator: RecordingViewCoordinator? @@ -156,3 +160,9 @@ class RecordingViewController: UIViewController { self.coordinator?.hide() } } + +extension RecordingViewController: RecordingViewDelegate { + func didTitleWriteDone(title: String) { + + } +} From c0aec2c4c24fca24698f563d842260a098938ea0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:01:24 +0900 Subject: [PATCH 097/465] =?UTF-8?q?[Feat]=20#105=20RecordingTitleView=20De?= =?UTF-8?q?legate=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 0bf789f..df800cf 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -9,7 +9,8 @@ import UIKit class RecordingTitleViewController: UIViewController { weak var coordinator: RecordingTitleViewCoordinator? - + weak var delegate: RecordingViewDelegate? + private var displayView: UIView = { let view = UIView() view.backgroundColor = .white From 2927aea2a4d3e4567112cfba5cfd7f5372e5ab08 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 9 Nov 2021 15:13:02 +0900 Subject: [PATCH 098/465] =?UTF-8?q?[Fix]=20#104=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=90=9C=20self=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index d0f8e9c..808b258 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -30,9 +30,9 @@ class MapViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { switch self.manager.authorizationStatus { case .authorizedAlways, .authorizedWhenInUse: - userTrackingButton.isHidden = false + self.userTrackingButton.isHidden = false default: - userTrackingButton.isHidden = true + self.userTrackingButton.isHidden = true } } @@ -49,7 +49,7 @@ class MapViewController: UIViewController { latitude: mountainEntity.latitude, longitude: mountainEntity.longitude ) - mapView?.addAnnotation(mountainAnnotation) + self.mapView?.addAnnotation(mountainAnnotation) } } @@ -181,17 +181,17 @@ extension MapViewController: MKMapViewDelegate { extension MapViewController: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.first { - self.manager.stopUpdatingLocation() + manager.stopUpdatingLocation() self.render(location) } } func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - switch self.manager.authorizationStatus { + switch manager.authorizationStatus { case .authorizedAlways, .authorizedWhenInUse: - userTrackingButton.isHidden = false + self.userTrackingButton.isHidden = false default: - userTrackingButton.isHidden = true + self.userTrackingButton.isHidden = true } } } From 0c17b98bf87d09f451659df0c7d7674e379daf96 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 9 Nov 2021 15:50:43 +0900 Subject: [PATCH 099/465] =?UTF-8?q?[Refactor]=20#106=20protocol=EC=9D=84?= =?UTF-8?q?=20=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EA=B0=84=EC=A0=91=20=EC=B0=B8?= =?UTF-8?q?=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 13 ++++++++++--- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 8 ++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 808b258..787829e 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -6,6 +6,11 @@ // import MapKit +protocol Animatable: AnyObject { + func shouldAnimate() + func shouldStopAnimate() +} + class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var mapView: MKMapView? @@ -157,13 +162,15 @@ class MapViewController: UIViewController { self.present(authAlert(), animated: false) } } - - func presentAnimation() { +} + +extension MapViewController: Animatable { + func shouldAnimate() { let image = UIImage.gifImage(named: "walkingManAnimation") self.startButton.setImage(image, for: .normal) } - func unpresentAnimation(){ + func shouldStopAnimate() { self.startButton.setImage(nil, for: .normal) } } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index bad5e5b..94e00a5 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -9,7 +9,6 @@ import UIKit class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? - weak var mapViewController: MapViewController? var navigationController: UINavigationController = UINavigationController() var childCoordinator: [Coordinator] = [] @@ -19,7 +18,6 @@ class MapViewCoordinator: Coordinator { func startPush() -> UINavigationController { let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self - self.mapViewController = mapViewController self.navigationController.setViewControllers([mapViewController], animated: false) return navigationController @@ -38,11 +36,13 @@ extension MapViewCoordinator { } func recordingViewDidHide(){ - self.mapViewController?.presentAnimation() + guard let animatableViewController = navigationController.viewControllers.first as? Animatable else { return } + animatableViewController.shouldAnimate() } func recordingViewDidDismiss(){ - self.mapViewController?.unpresentAnimation() + guard let animatableViewController = navigationController.viewControllers.first as? Animatable else { return } + animatableViewController.shouldStopAnimate() } private func injectDependencies() -> MapViewModel { From 40066c66ac3141027b4cb1cfa16fb2d79ade60f2 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:16:00 +0900 Subject: [PATCH 100/465] [Feat] #105 RecordingTitleView Button Add Action --- .../RecordingTitleViewController.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index df800cf..b6c9c3a 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -82,6 +82,7 @@ class RecordingTitleViewController: UIViewController { self.configureNotification() self.configureConstraints() + self.configureTarget() self.titleTextFieldUnderLine() } @@ -125,6 +126,11 @@ class RecordingTitleViewController: UIViewController { self.view.layoutIfNeeded() } + private func configureTarget() { + self.inputButton.addTarget(self, action: #selector(inputButtonAction), for: .touchUpInside) + self.notInputButton.addTarget(self, action: #selector(notInputButtonButtonAction), for: .touchUpInside) + } + private func titleTextFieldUnderLine() { let border = CALayer() border.frame = CGRect(x: 1, y: self.recordingTitleText.frame.size.height - 1, width: self.recordingTitleText.frame.width - 1, height: 1) @@ -132,6 +138,14 @@ class RecordingTitleViewController: UIViewController { border.backgroundColor = UIColor.systemGray2.cgColor self.recordingTitleText.layer.addSublayer(border) } + + @objc private func inputButtonAction(sender: UIButton) { + + } + + @objc private func notInputButtonButtonAction(sender: UIButton) { + + } } From f5972634a27a6ce4b6c60e5573348c627a86f49a Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:18:09 +0900 Subject: [PATCH 101/465] =?UTF-8?q?[Feat]=20#105=20RecordingTitleView=20De?= =?UTF-8?q?legate=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift | 2 +- .../RecordingTitleScene/RecordingTitleViewCoordinator.swift | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 18f1ea7..763dadb 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -42,7 +42,7 @@ class RecordingViewCoordinator: Coordinator { extension RecordingViewCoordinator { func presentRecordingTitleViewController() { - let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(navigationController: self.navigationController) + let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(navigationController: self.navigationController, delegate: self.recordingViewController) self.childCoordinator.append(recordingTitleViewCoordinator) recordingTitleViewCoordinator.parentCoordinator = self diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index af93c4f..9129378 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -13,9 +13,10 @@ class RecordingTitleViewCoordinator: Coordinator { var childCoordinator: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController - init(navigationController: UINavigationController) { + init(navigationController: UINavigationController, delegate: RecordingViewDelegate) { self.navigationController = navigationController self.recordingTitleViewController = RecordingTitleViewController() + self.recordingTitleViewController.delegate = delegate self.recordingTitleViewController.coordinator = self } From 766aa2f4e2d591e2b9dd3b95a960b096c12fa7d8 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:21:13 +0900 Subject: [PATCH 102/465] =?UTF-8?q?[Feat]=20#105=20RecoringTitleView=20But?= =?UTF-8?q?ton=20Action=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewController.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index b6c9c3a..904737d 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -140,11 +140,16 @@ class RecordingTitleViewController: UIViewController { } @objc private func inputButtonAction(sender: UIButton) { + guard let title = self.recordingTitleText.text else { + self.delegate?.didTitleWriteDone(title: "") + return + } + self.delegate?.didTitleWriteDone(title: title) } @objc private func notInputButtonButtonAction(sender: UIButton) { - + self.delegate?.didTitleWriteDone(title: "") } } From ee0954890aeb7a132de075af7343ba61c96db51c Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 9 Nov 2021 16:26:31 +0900 Subject: [PATCH 103/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=A7=80=EB=8F=84=EC=97=90=20=EB=A7=88?= =?UTF-8?q?=EC=BB=A4=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MountainAnnotation.swift | 9 +++++++++ .../MountainDetailViewController.swift | 17 +++++++++++------ .../RecordingViewCoordinator.swift | 4 +--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index c5d9708..c85116b 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -27,4 +27,13 @@ class MountainAnnotation: NSObject, MKAnnotation { self.mountainDescription = mountainDescription self.region = region } + + init(title: String, subtitle: String) { + self.title = title + self.subtitle = subtitle + self.latitude = 0 + self.longitude = 0 + self.mountainDescription = "" + self.region = "" + } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index a9c33d6..5c2eb70 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -94,18 +94,23 @@ extension MountainDetailViewController { private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { let mapOptions = MKMapSnapshotter.Options.init() mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) - mapOptions.size = CGSize(width: view.bounds.width, height: view.bounds.height / 3) mapOptions.mapType = .satellite -// let mountainAnnotationView = MountainAnnotationView(annotation: MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: mountainDetail.regions.joined(separator: ", ")), reuseIdentifier: MountainAnnotationView.ReuseID) -// -// mountainAnnotationView.canShowCallout = true -// mountainAnnotationView.calloutOffset = CGPoint(x: 0, y: 5) let imgView = UIImageView() let snapShotter = MKMapSnapshotter(options: mapOptions) snapShotter.start { snapShot, error in if let snapShot = snapShot { - imgView.image = snapShot.image + let mapImage = snapShot.image + + UIGraphicsBeginImageContext(mapImage.size) + mapImage.draw(in: CGRect(origin: CGPoint.zero, size: mapImage.size)) + UIImage(systemName: "heart.fill")?.draw(at: snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + imgView.image = image + + print(snapShot.image.size, snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) } else if let error = error { print(error.localizedDescription) } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 7f699c5..6316943 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -32,9 +32,7 @@ class RecordingViewCoordinator: Coordinator { func dismiss() { self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinators.removeAll(where: { coordinator in - coordinator is Self - }) + self.parentCoordinator?.childCoordinators.removeAll() } } From f312af87ce62ff8090806845a67707d48e1011bd Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:30:32 +0900 Subject: [PATCH 104/465] [Feat] #105 RecordingTitleView Dismiss --- .../RecordingScene/RecordingViewController.swift | 2 +- .../RecordingTitleViewController.swift | 3 +++ .../RecordingTitleViewCoordinator.swift | 11 +++++++++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 31c2b66..b7048b4 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -163,6 +163,6 @@ class RecordingViewController: UIViewController { extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { - + print(title) } } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 904737d..c8e2cb2 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -142,14 +142,17 @@ class RecordingTitleViewController: UIViewController { @objc private func inputButtonAction(sender: UIButton) { guard let title = self.recordingTitleText.text else { self.delegate?.didTitleWriteDone(title: "") + self.coordinator?.dismiss() return } self.delegate?.didTitleWriteDone(title: title) + self.coordinator?.dismiss() } @objc private func notInputButtonButtonAction(sender: UIButton) { self.delegate?.didTitleWriteDone(title: "") + self.coordinator?.dismiss() } } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 9129378..17cc60a 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -27,7 +27,14 @@ class RecordingTitleViewCoordinator: Coordinator { } func dismiss() { - self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinator.removeAll() + guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + + recordingCoordinator.recordingViewController.dismiss(animated: true) + self.parentCoordinator?.childCoordinator.enumerated().forEach { (index, coordinator) in + if coordinator is RecordingTitleViewCoordinator { + parentCoordinator?.childCoordinator.remove(at: index) + return + } + } } } From 0976b92d50a7a51b1133498835824b1186a7fcab Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:32:37 +0900 Subject: [PATCH 105/465] =?UTF-8?q?[Feat]=20#105=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=A2=85=EB=A3=8C=20=EC=8B=9C=EC=97=90=20RecordingView=20Backg?= =?UTF-8?q?round=20Color=20Black=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b7048b4..6129404 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -143,6 +143,7 @@ class RecordingViewController: UIViewController { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in + self?.view.backgroundColor = .black self?.coordinator?.presentRecordingTitleViewController() // self?.recordingViewModel?.save() { [weak self] completion in From 8586bd600f2c1db7f33fc69b7b6a295797d75d14 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 16:45:22 +0900 Subject: [PATCH 106/465] =?UTF-8?q?[Feat]=20#105=20#98=20RecordingView=20D?= =?UTF-8?q?elegate=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 ++-- .../RecordingScene/RecordingViewController.swift | 12 +++++------- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 16bdae8..303bac7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -10,7 +10,7 @@ import Foundation protocol RecordingUseCase { var recording: RecordingModel { get set } - func save(completion: @escaping (Result) -> Void) + func save(title: String, completion: @escaping (Result) -> Void) } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { @@ -23,7 +23,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording = recordingModel } - func save(completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { // self.recordRepository.save(record: recording.cancel(), completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 6129404..47cf23a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -145,12 +145,6 @@ class RecordingViewController: UIViewController { let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in self?.view.backgroundColor = .black self?.coordinator?.presentRecordingTitleViewController() - -// self?.recordingViewModel?.save() { [weak self] completion in -// DispatchQueue.main.async { -// self?.coordinator?.dismiss() -// } -// } } stopAlert.addAction(noneAction) stopAlert.addAction(terminationAction) @@ -164,6 +158,10 @@ class RecordingViewController: UIViewController { extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { - print(title) + self.recordingViewModel?.save(title: title) { [weak self] completion in + DispatchQueue.main.async { + self?.coordinator?.dismiss() + } + } } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index d36f51c..3cc64b0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -52,7 +52,7 @@ final class RecordingViewModel: ObservableObject { .store(in: &self.subscriptions) } - func save(completion: @escaping (Result) -> Void) { - self.recordingUseCase?.save(completion: completion) + func save(title: String, completion: @escaping (Result) -> Void) { + self.recordingUseCase?.save(title: title, completion: completion) } } From 597daf0e6aef90002d8850c021652b305698a42b Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 17:00:58 +0900 Subject: [PATCH 107/465] =?UTF-8?q?[Feat]=20#99=20RecordingTiteView=20?= =?UTF-8?q?=EC=A0=9C=EB=AA=A9=EC=9D=84=2020=EC=9E=90=EA=B0=80=20=EB=84=98?= =?UTF-8?q?=EC=96=B4=EA=B0=80=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleViewController.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index c8e2cb2..fe543e2 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -80,12 +80,17 @@ class RecordingTitleViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.configureDelegate() self.configureNotification() self.configureConstraints() self.configureTarget() self.titleTextFieldUnderLine() } + private func configureDelegate() { + self.recordingTitleText.delegate = self + } + private func configureNotification() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) @@ -154,7 +159,17 @@ class RecordingTitleViewController: UIViewController { self.delegate?.didTitleWriteDone(title: "") self.coordinator?.dismiss() } +} +extension RecordingTitleViewController: UITextFieldDelegate { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + guard let text = textField.text else { return false } + if text.count >= 20 && range.length == 0 && range.location >= 20 { + return false + } + + return true + } } extension RecordingTitleViewController { From 337426a031d03f291bfbee75ce0d7c1763ea316e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 9 Nov 2021 17:02:45 +0900 Subject: [PATCH 108/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=82=B0=20=EC=9D=B4=EB=A6=84=EB=B0=8F=20?= =?UTF-8?q?=EA=B1=B0=EB=A6=AC=20=ED=91=9C=EC=8B=9C=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EB=B7=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ .../MountainDetailTitleView.swift | 46 +++++++++++++++++++ .../MountainDetailUseCase.swift | 7 +-- .../MountainDetailViewController.swift | 7 +-- 4 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 74b51a8..0943f49 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 49D5A94D2738C71700937821 /* MountainDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */; }; 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */; }; 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */; }; + 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -57,6 +58,7 @@ 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewModel.swift; sourceTree = ""; }; 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailUseCase.swift; sourceTree = ""; }; 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailModel.swift; sourceTree = ""; }; + 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTitleView.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -157,6 +159,7 @@ 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */, 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */, 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, + 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -357,6 +360,7 @@ DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, + 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */, 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift new file mode 100644 index 0000000..f717e1a --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift @@ -0,0 +1,46 @@ +// +// MountainDetailTitleView.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/09. +// + +import UIKit + +class MountainDetailTitleView: UIView { + private let titleLabel = UILabel() + private let distanceLabel = UILabel() + + + override func draw(_ rect: CGRect) { + super.draw(rect) + self.layoutTitleView() + } + + private func layoutTitleView() { + titleLabel.translatesAutoresizingMaskIntoConstraints = false + distanceLabel.translatesAutoresizingMaskIntoConstraints = false + + self.addSubview(titleLabel) + self.addSubview(distanceLabel) + + let titleConstraints = [ + titleLabel.topAnchor.constraint(equalTo: self.topAnchor), + titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor) + ] + NSLayoutConstraint.activate(titleConstraints) + + let distanceLabelConstraints = [ + distanceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), + distanceLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor) + ] + NSLayoutConstraint.activate(distanceLabelConstraints) + } + + func configure(with title: String, distance: Double?) { + self.titleLabel.text = title + guard let distance = distance else { return } + let distanceRepresentation = String(format:"%.2f", distance) + self.distanceLabel.text = "현재 위치로부터 약 \(distanceRepresentation)km (직선거리)" + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 91972e2..14c5c2e 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -19,9 +19,10 @@ class MountainDetailUseCase { private func calculateDistance() -> Double? { let mountainLocation = CLLocation(latitude: self.mountainAnnotation.latitude, longitude: self.mountainAnnotation.longitude) - let distance = location?.distance(from: mountainLocation) - print(distance) - return distance + guard let distance = location?.distance(from: mountainLocation) else { + return nil + } + return distance / 1000 } private func mountainRegions() -> [String] { diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 5c2eb70..3269216 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -119,8 +119,9 @@ extension MountainDetailViewController { } private func lowerMountainTitleView(mountainDetail: MountainDetailModel) -> UIView { - let empty = UIView() - empty.backgroundColor = .blue - return empty + let titleView = MountainDetailTitleView() + titleView.configure(with: mountainDetail.moutainName, distance: mountainDetail.distance) + titleView.backgroundColor = .white + return titleView } } From 419ab16e7862a7558293b9ed67dac31356a71dcf Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 17:03:31 +0900 Subject: [PATCH 109/465] =?UTF-8?q?[Feat]=20#109=20RecordingTitleView=20?= =?UTF-8?q?=EC=A0=9C=EB=AA=A9=20TextField=20=EB=8F=99=EC=A0=81=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingTitleScene/RecordingTitleViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index fe543e2..e742300 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -42,6 +42,7 @@ class RecordingTitleViewController: UIViewController { textField.clearButtonMode = .whileEditing textField.textAlignment = .center textField.borderStyle = .none + textField.adjustsFontSizeToFitWidth = true textField.translatesAutoresizingMaskIntoConstraints = false return textField }() From 23aa84b5f2ace16ceec8e780166e76c49b36603d Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 17:06:34 +0900 Subject: [PATCH 110/465] =?UTF-8?q?[Feat]=20#103=20=ED=82=A4=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=EC=9D=98=20Tpye=EC=9D=B4=20=EB=B0=94=EB=80=9C?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20Height=EA=B0=80=20=EA=B3=84?= =?UTF-8?q?=EC=86=8D=20=EB=82=B4=EB=A0=A4=EA=B0=80=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index e742300..2b9c902 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -175,6 +175,7 @@ extension RecordingTitleViewController: UITextFieldDelegate { extension RecordingTitleViewController { @objc func keyboardWillShow(_ sender: Notification) { + guard self.keyHeight == nil else { return } let userInfo:NSDictionary = sender.userInfo! as NSDictionary let keyboardFrame:NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue let keyboardRectangle = keyboardFrame.cgRectValue @@ -188,5 +189,6 @@ extension RecordingTitleViewController { guard let keyHeight = keyHeight else { return } self.displayView.frame.origin.y += keyHeight + self.keyHeight = nil } } From e237bed621ce7fe20eb66915eaca8d403f65e887 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 17:33:00 +0900 Subject: [PATCH 111/465] =?UTF-8?q?[Feat]=20#111=20Recording=20ViewModel,?= =?UTF-8?q?=20Model,=20UseCase,=20ViewController=20Pause=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 5 +++++ SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index ec507d2..580ebd1 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -92,7 +92,7 @@ final class RecordingModel: NSObject, ObservableObject { } } - func suspend() { + func pause() { timer?.suspend() } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 303bac7..5139ab9 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,6 +11,7 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) + func pause() } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { @@ -23,6 +24,10 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording = recordingModel } + func pause() { + self.recording.pause() + } + func save(title: String, completion: @escaping (Result) -> Void) { // self.recordRepository.save(record: recording.cancel(), completion: completion) } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 47cf23a..8891c34 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -136,7 +136,7 @@ class RecordingViewController: UIViewController { } @objc private func pauseButtonAction(_ sender: UIResponder) { - + self.recordingViewModel?.pause() } @objc private func stopButtonAction(_ sender: UIResponder) { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 3cc64b0..729c8a9 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -52,6 +52,10 @@ final class RecordingViewModel: ObservableObject { .store(in: &self.subscriptions) } + func pause() { + self.recordingUseCase?.pause() + } + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } From 9830c211e4d061b784f4186ac01bb7b184d85774 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 9 Nov 2021 17:49:48 +0900 Subject: [PATCH 112/465] =?UTF-8?q?[Feat]=20#116=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 14 ++++++++++ SanTa/SanTa/MapScene/MapViewCoordinator.swift | 9 +++++- SanTa/SanTa/MapScene/MapViewModel.swift | 13 ++++++++- SanTa/SanTa/MapScene/MapViewRepository.swift | 28 ++++++++++++++++++- SanTa/SanTa/MapScene/MapViewUseCase.swift | 12 ++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 787829e..eb56a9f 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -33,6 +33,7 @@ class MapViewController: UIViewController { } override func viewWillAppear(_ animated: Bool) { + viewModel?.viewWillAppear() switch self.manager.authorizationStatus { case .authorizedAlways, .authorizedWhenInUse: self.userTrackingButton.isHidden = false @@ -43,6 +44,7 @@ class MapViewController: UIViewController { private func configureViewModel() { self.viewModel?.markersShouldUpdate = { self.configureMarkers() } + self.viewModel?.mapShouldUpdate = { self.configureMap() } self.viewModel?.viewDidLoad() } @@ -58,6 +60,18 @@ class MapViewController: UIViewController { } } + private func configureMap() { + guard let map = viewModel?.map else { return } + switch map { + case .infomation: + mapView?.mapType = .mutedStandard + case .normal: + mapView?.mapType = .standard + case .satellite: + mapView?.mapType = .satellite + } + } + private func configureViews() { self.mapView = MKMapView(frame: view.bounds) guard let mapView = mapView else { return } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 94e00a5..8dab77a 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -46,6 +46,13 @@ extension MapViewCoordinator { } private func injectDependencies() -> MapViewModel { - return MapViewModel(useCase: MapViewUseCase(repository: DefaultMapViewRespository(mountainExtractor: MountainExtractor()))) + return MapViewModel( + useCase: MapViewUseCase( + repository: DefaultMapViewRespository( + mountainExtractor: MountainExtractor(), + userDefaultsStorage: DefaultUserDefaultsStorage() + ) + ) + ) } } diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index b7944c9..d033518 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -10,11 +10,14 @@ import Foundation class MapViewModel { private let useCase: MapViewUseCase private(set) var mountains: [MountainEntity]? + private(set) var map: Map? var markersShouldUpdate: () -> Void + var mapShouldUpdate: () -> Void init(useCase: MapViewUseCase) { self.useCase = useCase - self.markersShouldUpdate = { } + self.markersShouldUpdate = {} + self.mapShouldUpdate = {} } func viewDidLoad() { @@ -23,4 +26,12 @@ class MapViewModel { self?.markersShouldUpdate() } } + + func viewWillAppear() { + self.useCase.prepareMap{ [weak self] map in + guard let map = map else { return } + self?.map = map + self?.mapShouldUpdate() + } + } } diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index 89c34ad..1e9fa74 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -9,6 +9,7 @@ import Foundation protocol MapViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) + func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) } class DefaultMapViewRespository { @@ -16,10 +17,20 @@ class DefaultMapViewRespository { case decodingFailed } + enum userDefaultsError: Error { + case notExists + } + + enum optionError: Error { + case notExists + } + private let mountainExtractor: MountainExtractor + private let settingsStorage: UserDefaultsStorage - init(mountainExtractor: MountainExtractor) { + init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage) { self.mountainExtractor = mountainExtractor + self.settingsStorage = userDefaultsStorage } } @@ -37,4 +48,19 @@ extension DefaultMapViewRespository: MapViewRepository { } } } + + func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) { + self.settingsStorage.string(key: key) { value in + guard let value = value else { + completion(.failure(userDefaultsError.notExists)) + return + } + guard let map = Map(rawValue: value) else { + completion(.failure(optionError.notExists)) + return + } + let option = MapOption(text: key.title, map: map) + completion(.success(option.map)) + } + } } diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index 38e2930..73764ae 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -26,4 +26,16 @@ class MapViewUseCase { } } } + + func prepareMap(completion: @escaping (Map?) -> Void) { + self.repository.fetchMapOption(key: Settings.mapFormat) { result in + switch result { + case .failure(let error): + os_log(.error, log: .default, "\(error.localizedDescription)") + completion(nil) + case .success(let map): + completion(map) + } + } + } } From 9e884911d119905c416cf2e62d58e4e3b261f365 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 17:52:48 +0900 Subject: [PATCH 113/465] =?UTF-8?q?[Feat]=20#111=20#112=20#113=20#114=20?= =?UTF-8?q?=ED=83=80=EC=9D=B4=EB=A8=B8=20=EC=9D=BC=EC=8B=9C=EC=A0=95?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 580ebd1..36fe4e0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -93,11 +93,13 @@ final class RecordingModel: NSObject, ObservableObject { } func pause() { - timer?.suspend() + self.timer?.suspend() + self.locationManager.stopUpdatingLocation() } func resume() { - timer?.resume() + self.timer?.resume() + self.locationManager.startUpdatingLocation() } func cancel() -> Record? { From faeb1b7eb702ad93a3d13669e5f113c58358c85a Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 18:01:48 +0900 Subject: [PATCH 114/465] =?UTF-8?q?[Fix]=20#112=20Timer=20=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=EC=A0=95=EC=A7=80=EB=A5=BC=20=EC=9C=84=ED=95=9C=20sta?= =?UTF-8?q?rtDate,=20endDate=20Type=EC=9D=84=20=EB=B0=B0=EC=97=B4=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 4 +-- .../SanTa/RecordingScene/RecordingModel.swift | 26 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index cf90373..2451040 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,8 +8,8 @@ import Foundation struct Record { - let startTime: Date - let endTime: Date + let startTime: [Date] + let endTime: [Date] let step: Int let distance: Double diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 36fe4e0..464fc2f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,7 +19,8 @@ final class RecordingModel: NSObject, ObservableObject { private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? - private var date: Date? + private var startDate: [Date]? + private var endDate: [Date]? private var currentWalk = 0 private var currentKilo: Double = 0 private var location = [Location]() @@ -33,7 +34,7 @@ final class RecordingModel: NSObject, ObservableObject { override init() { super.init() - self.date = Date() + self.startDate = [Date()] self.configureTimer() self.configureLocationManager() } @@ -58,9 +59,10 @@ final class RecordingModel: NSObject, ObservableObject { } private func timeConverter() { - guard let startDate = self.date else { return } + guard let startDate = self.startDate, + let date = startDate.last else { return } - let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) + let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(date)) let seconds = elapsedTimeSeconds % 60 let minutes = (elapsedTimeSeconds / 60) % 60 @@ -70,7 +72,8 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkPedoMeter() { - guard let date = self.date else { return } + guard let startDate = self.startDate, + let date = startDate.last else { return } pedoMeter.queryPedometerData(from: date, to: Date()) { [weak self] data, error in guard let activityData = data, @@ -93,6 +96,12 @@ final class RecordingModel: NSObject, ObservableObject { } func pause() { + if self.endDate == nil { + self.endDate = [self.currentTime] + } else { + self.endDate?.append(self.currentTime) + } + self.timer?.suspend() self.locationManager.stopUpdatingLocation() } @@ -103,10 +112,11 @@ final class RecordingModel: NSObject, ObservableObject { } func cancel() -> Record? { - guard let date = self.date else { return nil } + guard let startdate = self.startDate, + let endDate = self.endDate else { return nil } - let resultRecord = Record(startTime: date, - endTime: self.currentTime, + let resultRecord = Record(startTime: startdate, + endTime: endDate, step: self.currentWalk, distance: self.currentKilo, locations: self.location) From bf230d313fdda3b2ad2e986d69384abccd9006b9 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 9 Nov 2021 18:01:49 +0900 Subject: [PATCH 115/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=85=8C=EC=9D=B4=EB=B8=94=EB=B7=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ .../MountainDetailTableViewCell.swift | 57 +++++++++++++++++++ .../MountainDetailViewController.swift | 51 ++++++++++++++++- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 0943f49..cbd73b3 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */; }; 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */; }; 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */; }; + 49D5A957273A62F800937821 /* MountainDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -59,6 +60,7 @@ 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailUseCase.swift; sourceTree = ""; }; 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailModel.swift; sourceTree = ""; }; 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTitleView.swift; sourceTree = ""; }; + 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTableViewCell.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -160,6 +162,7 @@ 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */, 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, + 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -337,6 +340,7 @@ 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, + 49D5A957273A62F800937821 /* MountainDetailTableViewCell.swift in Sources */, 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */, 984DDEC127325D67003BE56B /* Record.swift in Sources */, 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift new file mode 100644 index 0000000..71d728b --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -0,0 +1,57 @@ +// +// MountainDetailTableViewCell.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/09. +// + +import UIKit + +class MountainDetailTableViewCell: UITableViewCell { + static let identifier = "MountainDetailTableViewCellID" + + let categoryLabel = UILabel() + let contentLabel = UILabel() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setLayout() { + categoryLabel.backgroundColor = .green + categoryLabel.textColor = .white + + contentLabel.numberOfLines = 0 + contentLabel.lineBreakMode = .byCharWrapping + + categoryLabel.translatesAutoresizingMaskIntoConstraints = false + contentLabel.translatesAutoresizingMaskIntoConstraints = false + + self.addSubview(categoryLabel) + self.addSubview(contentLabel) + + let categoryLabelConstraints = [ + categoryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + categoryLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20) + ] + NSLayoutConstraint.activate(categoryLabelConstraints) + + let contentLabelConstraints = [ + contentLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + contentLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10), + contentLabel.topAnchor.constraint(equalTo: categoryLabel.bottomAnchor, constant: 10), + contentLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ] + NSLayoutConstraint.activate(contentLabelConstraints) + } + + func configure(category: String, content: String) { + categoryLabel.text = category + contentLabel.text = content + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 3269216..ed313f3 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -88,7 +88,13 @@ extension MountainDetailViewController { } private func configuredTableView(mountainDetail: MountainDetailModel) -> UITableView { - return UITableView() + let tableView = UITableView() + + tableView.register(MountainDetailTableViewCell.self, forCellReuseIdentifier: MountainDetailTableViewCell.identifier) + tableView.separatorStyle = .none + tableView.delegate = self + tableView.dataSource = self + return tableView } private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { @@ -125,3 +131,46 @@ extension MountainDetailViewController { return titleView } } + +extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSource { + enum MountainDetailCategories: Int, CaseIterable { + case region = 0 + case altitude = 1 + case description = 2 + + var text: String { + switch self { + case .region: + return "소재지" + case .altitude: + return "고도" + case .description: + return "설명" + } + } + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = tableView.dequeueReusableCell(withIdentifier: MountainDetailTableViewCell.identifier, for: indexPath) as? MountainDetailTableViewCell, + let category = MountainDetailCategories(rawValue: indexPath.row) else { + return UITableViewCell() + } + + var content: String? = "" + switch category { + case .region: + content = self.viewModel?.mountainDetail?.regions.joined(separator: "\n") + case .altitude: + content = self.viewModel?.mountainDetail?.altitude + case .description: + content = self.viewModel?.mountainDetail?.mountainDescription + } + + cell.configure(category: category.text, content: content ?? "") + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return MountainDetailCategories.allCases.count + } +} From 0426199ed456a8237ee4c0f824ff528b081a8f3a Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 9 Nov 2021 19:13:55 +0900 Subject: [PATCH 116/465] =?UTF-8?q?[Feat]=20#118=20=EC=9E=A5=EC=86=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B2=84=ED=8A=BC=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 52 ++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index eb56a9f..b6a026f 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -15,6 +15,7 @@ class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var mapView: MKMapView? private var startButton = UIButton() + private var addAnnotationButton = UIButton() private var manager = CLLocationManager() private var userTrackingButton = MKUserTrackingButton() private var viewModel: MapViewModel? @@ -120,6 +121,29 @@ class MapViewController: UIViewController { self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) ] NSLayoutConstraint.activate(userTrackingButtonConstraints) + + self.view.addSubview(self.addAnnotationButton) + self.addAnnotationButton.isHidden = true + self.addAnnotationButton.translatesAutoresizingMaskIntoConstraints = false + self.addAnnotationButton.backgroundColor = UIColor(named: "SantaColor") + self.addAnnotationButton.setTitle("이곳을 알고 계시나요?", for: .normal) + self.addAnnotationButton.setTitleColor(.white, for: .normal) + self.addAnnotationButton.titleLabel?.font = .boldSystemFont(ofSize: 15) + self.addAnnotationButton.layer.cornerRadius = 15 + self.addAnnotationButton.layer.shadowColor = UIColor.gray.cgColor + self.addAnnotationButton.layer.shadowOpacity = 1 + self.addAnnotationButton.layer.shadowRadius = 3 + self.addAnnotationButton.layer.shadowOffset = CGSize(width: 0, height: 2) + let addAnnotationButtonConstraints = [ + self.addAnnotationButton.widthAnchor.constraint(equalToConstant: 150), + self.addAnnotationButton.heightAnchor.constraint(equalToConstant: 30), + self.addAnnotationButton.bottomAnchor.constraint( + equalTo: startButton.topAnchor, + constant: -10 + ), + self.addAnnotationButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) + ] + NSLayoutConstraint.activate(addAnnotationButtonConstraints) } private func registerAnnotationView() { @@ -197,6 +221,34 @@ extension MapViewController: MKMapViewDelegate { reuseIdentifier: MountainAnnotationView.ReuseID ) } + func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) { + switch mode { + case .follow, .followWithHeading: + if addAnnotationButton.isHidden { + self.addAnnotationButton.isHidden = false + self.addAnnotationButton.alpha = 0 + UIView.transition( + with: addAnnotationButton, + duration: 0.5, + options: [], + animations: { [weak self] in + self?.addAnnotationButton.alpha = 1 + } + ) + } + default: + UIView.transition( + with: addAnnotationButton, + duration: 0.5, + options: [], + animations: { [weak self] in + self?.addAnnotationButton.alpha = 0 + }, completion: { [weak self] _ in + self?.addAnnotationButton.isHidden = true + } + ) + } + } } extension MapViewController: CLLocationManagerDelegate { From 2fdb65b220cca17ebffd9769d685ec17ee1cc9d1 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 22:49:29 +0900 Subject: [PATCH 117/465] =?UTF-8?q?[Feat]=20#112=20Records=20Struct=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 5 ++ .../SanTa/RecordingScene/RecordingModel.swift | 55 +++++++++++++------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 2451040..4d1a243 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -7,7 +7,12 @@ import Foundation +struct Records { + let record: [Record] +} + struct Record { + let title: String? let startTime: [Date] let endTime: [Date] let step: Int diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 464fc2f..9afa06a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,6 +19,7 @@ final class RecordingModel: NSObject, ObservableObject { private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? + private var records: Records?g private var startDate: [Date]? private var endDate: [Date]? private var currentWalk = 0 @@ -72,25 +73,43 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkPedoMeter() { - guard let startDate = self.startDate, - let date = startDate.last else { return } + guard let startDate = self.startDate else { return } + + self.currentWalk = 0 + self.currentKilo = 0 + + let dispatchGroup = DispatchGroup() + + startDate.enumerated().forEach { index, date in + var endDate: Date? + switch index { + case 0: + endDate = currentTime + default: + endDate = self.endDate?[index] + } + guard let endDate = endDate else { return } + dispatchGroup.enter() + pedoMeter.queryPedometerData(from: date, to: endDate) { [weak self] data, error in + guard let activityData = data, + error == nil else { return } + + guard let walk = self?.walk, + let walkNumber = Int(walk) else { return } + + self?.currentWalk += walkNumber + + guard let distance = activityData.distance else { return } + let transformatKilometer = Double(truncating: distance) / 1000 + self?.currentKilo += transformatKilometer + dispatchGroup.leave() + } + } - pedoMeter.queryPedometerData(from: date, to: Date()) { [weak self] data, error in - guard let activityData = data, - error == nil else { return } - - self?.walk = "\(activityData.numberOfSteps)" - - guard let walk = self?.walk, - let walkNumber = Int(walk) else { return } - - self?.currentWalk = walkNumber - - guard let distance = activityData.distance else { return } - let transformatKilometer = Double(truncating: distance) / 1000 - self?.currentKilo = transformatKilometer - let distanceString = String(format: "%.2f", transformatKilometer) - + dispatchGroup.notify(queue: .main) { [weak self] in + guard let currentKilo = self?.currentKilo else { return } + self?.walk = "\(String(describing: self?.currentWalk))" + let distanceString = String(format: "%.2f", currentKilo) self?.kilometer = "\(distanceString)" } } From 98a3fbad4011d7fd09473446ccbaa22f2384efdc Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 22:51:17 +0900 Subject: [PATCH 118/465] =?UTF-8?q?[Feat]=20Record=20Ttite=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20mutating=20func?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 4 ++++ SanTa/SanTa/RecordingScene/RecordingModel.swift | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 4d1a243..c2093b4 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -19,6 +19,10 @@ struct Record { let distance: Double let locations: [Location] + + mutating func configureTitle(title: String) { + self.title = title + } } struct Location { diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 9afa06a..3e31864 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,7 +19,7 @@ final class RecordingModel: NSObject, ObservableObject { private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? - private var records: Records?g + private var records: Records? private var startDate: [Date]? private var endDate: [Date]? private var currentWalk = 0 @@ -134,7 +134,8 @@ final class RecordingModel: NSObject, ObservableObject { guard let startdate = self.startDate, let endDate = self.endDate else { return nil } - let resultRecord = Record(startTime: startdate, + let resultRecord = Record(title: nil, + startTime: startdate, endTime: endDate, step: self.currentWalk, distance: self.currentKilo, From 51877857d0c4b0061908726a0438bb45db81acf5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 22:51:45 +0900 Subject: [PATCH 119/465] =?UTF-8?q?[Fix]=20title=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0=20var=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index c2093b4..e483c8a 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -12,7 +12,7 @@ struct Records { } struct Record { - let title: String? + var title: String? let startTime: [Date] let endTime: [Date] let step: Int From 40382968c40d486d614aa18e72214a83b869cdf9 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:03:15 +0900 Subject: [PATCH 120/465] =?UTF-8?q?[Feat]=20#112=20RecordingViewModel=20pa?= =?UTF-8?q?use,=20checkPedoMeter=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EB=B0=8F=20Records,=20Record=20=EA=B5=AC=EC=A1=B0=EC=B2=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 16 +-- .../SanTa/RecordingScene/RecordingModel.swift | 104 ++++++++---------- 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index e483c8a..030d7f9 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,21 +8,21 @@ import Foundation struct Records { - let record: [Record] + var title: String? + var record: [Record] + + mutating func configureTitle(title: String) { + self.title = title + } } struct Record { - var title: String? - let startTime: [Date] - let endTime: [Date] + let startTime: Date + let endTime: Date let step: Int let distance: Double let locations: [Location] - - mutating func configureTitle(title: String) { - self.title = title - } } struct Location { diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 3e31864..c5ba104 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -20,8 +20,7 @@ final class RecordingModel: NSObject, ObservableObject { private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? private var records: Records? - private var startDate: [Date]? - private var endDate: [Date]? + private var startDate: Date? private var currentWalk = 0 private var currentKilo: Double = 0 private var location = [Location]() @@ -35,7 +34,7 @@ final class RecordingModel: NSObject, ObservableObject { override init() { super.init() - self.startDate = [Date()] + self.startDate = Date() self.configureTimer() self.configureLocationManager() } @@ -54,16 +53,15 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.allowsBackgroundLocationUpdates = true - self.locationManager.pausesLocationUpdatesAutomatically = true + self.locationManager.pausesLocationUpdatesAutomatically = false self.locationManager.showsBackgroundLocationIndicator = true self.locationManager.delegate = self } private func timeConverter() { - guard let startDate = self.startDate, - let date = startDate.last else { return } + guard let startDate = self.startDate else { return } - let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(date)) + let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) let seconds = elapsedTimeSeconds % 60 let minutes = (elapsedTimeSeconds / 60) % 60 @@ -73,77 +71,65 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkPedoMeter() { - guard let startDate = self.startDate else { return } - - self.currentWalk = 0 - self.currentKilo = 0 - - let dispatchGroup = DispatchGroup() + guard let date = self.startDate else { return } - startDate.enumerated().forEach { index, date in - var endDate: Date? - switch index { - case 0: - endDate = currentTime - default: - endDate = self.endDate?[index] - } - guard let endDate = endDate else { return } - dispatchGroup.enter() - pedoMeter.queryPedometerData(from: date, to: endDate) { [weak self] data, error in - guard let activityData = data, - error == nil else { return } - - guard let walk = self?.walk, - let walkNumber = Int(walk) else { return } - - self?.currentWalk += walkNumber - - guard let distance = activityData.distance else { return } - let transformatKilometer = Double(truncating: distance) / 1000 - self?.currentKilo += transformatKilometer - dispatchGroup.leave() - } - } - - dispatchGroup.notify(queue: .main) { [weak self] in - guard let currentKilo = self?.currentKilo else { return } - self?.walk = "\(String(describing: self?.currentWalk))" - let distanceString = String(format: "%.2f", currentKilo) + pedoMeter.queryPedometerData(from: date, to: self.currentTime) { [weak self] data, error in + guard let activityData = data, + error == nil else { return } + + self?.walk = "\(activityData.numberOfSteps)" + + guard let walk = self?.walk, + let walkNumber = Int(walk) else { return } + + self?.currentWalk = walkNumber + + guard let distance = activityData.distance else { return } + let transformatKilometer = Double(truncating: distance) / 1000 + self?.currentKilo = transformatKilometer + let distanceString = String(format: "%.2f", transformatKilometer) + self?.kilometer = "\(distanceString)" } } - func pause() { - if self.endDate == nil { - self.endDate = [self.currentTime] - } else { - self.endDate?.append(self.currentTime) + private func appendRecord() { + guard let startdate = self.startDate else { return } + let record = Record(startTime: startdate, + endTime: self.currentTime, + step: self.currentWalk, + distance: self.currentKilo, + locations: self.location) + + guard self.records != nil else { + + self.records = Records(title: nil, record: [record]) + return } + self.records?.record.append(record) + } + + func pause() { + self.appendRecord() self.timer?.suspend() self.locationManager.stopUpdatingLocation() + self.startDate = nil } func resume() { self.timer?.resume() self.locationManager.startUpdatingLocation() + self.startDate = Date() } - func cancel() -> Record? { - guard let startdate = self.startDate, - let endDate = self.endDate else { return nil } - - let resultRecord = Record(title: nil, - startTime: startdate, - endTime: endDate, - step: self.currentWalk, - distance: self.currentKilo, - locations: self.location) + func cancel() -> Records? { + guard let records = self.records else { return nil } + timer?.cancel() timer = nil - return resultRecord + return records } } From 00a8877ea616e2fa248e86eab4a96d8225b79325 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:05:17 +0900 Subject: [PATCH 121/465] =?UTF-8?q?[Feat]=20RecordingModel=20resume,=20pau?= =?UTF-8?q?se=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index c5ba104..d3728b5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -121,13 +121,15 @@ final class RecordingModel: NSObject, ObservableObject { self.timer?.resume() self.locationManager.startUpdatingLocation() self.startDate = Date() + self.location = [Location]() } func cancel() -> Records? { guard let records = self.records else { return nil } - timer?.cancel() - timer = nil + self.timer?.cancel() + self.timer = nil + self.locationManager.stopUpdatingLocation() return records } From c7ed7d68c1f5cd9621dba115ee0c38b492f6e5bf Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:17:55 +0900 Subject: [PATCH 122/465] =?UTF-8?q?[Feat]=20#112=20#113=20#114=20#115=20Re?= =?UTF-8?q?cordingViewController=20=EC=9D=BC=EC=8B=9C=EC=A0=95=EC=A7=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=AC=EC=8B=9C=EC=9E=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 5 +++++ .../SanTa/RecordingScene/RecordingViewController.swift | 10 +++++++++- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 5139ab9..17411e6 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -12,6 +12,7 @@ protocol RecordingUseCase { func save(title: String, completion: @escaping (Result) -> Void) func pause() + func resume() } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { @@ -28,6 +29,10 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording.pause() } + func resume() { + self.recording.resume() + } + func save(title: String, completion: @escaping (Result) -> Void) { // self.recordRepository.save(record: recording.cancel(), completion: completion) } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 8891c34..fec6204 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -82,6 +82,7 @@ class RecordingViewController: UIViewController { private var recordingViewModel: RecordingViewModel? private var subscriptions = Set() + private var currentState = true convenience init(viewModel: RecordingViewModel) { self.init() @@ -136,7 +137,13 @@ class RecordingViewController: UIViewController { } @objc private func pauseButtonAction(_ sender: UIResponder) { - self.recordingViewModel?.pause() + if currentState { + self.view.backgroundColor = .black + self.recordingViewModel?.pause() + } else { + self.view.backgroundColor = .systemBlue + self.recordingViewModel?.pause() + } } @objc private func stopButtonAction(_ sender: UIResponder) { @@ -163,5 +170,6 @@ extension RecordingViewController: RecordingViewDelegate { self?.coordinator?.dismiss() } } + self.coordinator?.dismiss() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 729c8a9..6473fec 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -56,6 +56,10 @@ final class RecordingViewModel: ObservableObject { self.recordingUseCase?.pause() } + func resume() { + self.recordingUseCase?.resume() + } + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } From d7e52f717b2d3b8f2d9010aefde85c14ff3480d0 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 9 Nov 2021 23:19:44 +0900 Subject: [PATCH 123/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=ED=85=8C=EC=9D=B4=EB=B8=94=EB=B7=B0=20?= =?UTF-8?q?=EC=85=80=20=EC=9D=B8=ED=84=B0=EB=A0=89=EC=85=98=20=EB=B9=84?= =?UTF-8?q?=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailTableViewCell.swift | 1 + .../MountainDetailViewController.swift | 27 ++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index 71d728b..31990b9 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -15,6 +15,7 @@ class MountainDetailTableViewCell: UITableViewCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) + self.selectionStyle = .none self.setLayout() } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index ed313f3..c0d5ea6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -11,6 +11,9 @@ import MapKit class MountainDetailViewController: UIViewController { weak var coordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? + private var mutatingTopConstraint: NSLayoutConstraint? + private var mutatingBottomConstraint: NSLayoutConstraint? + private let maxRollUpDistance: CGFloat = 100 convenience init(viewModel: MountainDetailViewModel) { self.init() @@ -70,16 +73,23 @@ extension MountainDetailViewController { ] NSLayoutConstraint.activate(mapConstraints) - let titleViewConstraints = [ - titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor), + self.mutatingTopConstraint = titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor) + self.mutatingBottomConstraint = titleView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor) + var titleViewConstraints = [ titleView.leftAnchor.constraint(equalTo: headerView.leftAnchor), titleView.rightAnchor.constraint(equalTo: headerView.rightAnchor), - titleView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor) ] + + if let upperConstraint = self.mutatingTopConstraint, + let lowerConstraint = self.mutatingBottomConstraint { + titleViewConstraints.append(upperConstraint) + titleViewConstraints.append(lowerConstraint) + } + NSLayoutConstraint.activate(titleViewConstraints) let tableViewConstraints = [ - tableView.topAnchor.constraint(equalTo: headerView.bottomAnchor), + tableView.topAnchor.constraint(equalTo: titleView.bottomAnchor), tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), tableView.leftAnchor.constraint(equalTo: view.leftAnchor), tableView.rightAnchor.constraint(equalTo: view.rightAnchor) @@ -174,3 +184,12 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour return MountainDetailCategories.allCases.count } } + +extension MountainDetailViewController: UIScrollViewDelegate { + func scrollViewDidScroll(_ scrollView: UIScrollView) { + if scrollView.contentOffset.y < self.maxRollUpDistance && scrollView.contentOffset.y > 0 { + self.mutatingTopConstraint?.constant = -scrollView.contentOffset.y + self.mutatingBottomConstraint?.constant = -scrollView.contentOffset.y + } + } +} From 497e237abc146347c105aba037aea93832684bf1 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:24:55 +0900 Subject: [PATCH 124/465] =?UTF-8?q?[Feat]=20#111=20RecordingViewController?= =?UTF-8?q?=20=EC=9D=BC=EC=8B=9C=EC=A0=95=EC=A7=80=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?Image=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingViewController.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index fec6204..3069535 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -139,10 +139,20 @@ class RecordingViewController: UIViewController { @objc private func pauseButtonAction(_ sender: UIResponder) { if currentState { self.view.backgroundColor = .black + var pauseConfiguration = UIButton.Configuration.plain() + pauseConfiguration.image = UIImage(systemName: "play.fill") + pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) + self.pauseButton.configuration = pauseConfiguration self.recordingViewModel?.pause() + self.currentState = false } else { self.view.backgroundColor = .systemBlue + var pauseConfiguration = UIButton.Configuration.plain() + pauseConfiguration.image = UIImage(systemName: "pause.fill") + pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) + self.pauseButton.configuration = pauseConfiguration self.recordingViewModel?.pause() + self.currentState = true } } From 7a63b0b1087412b60d966f2a22fa51b7fa27dc1f Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:26:55 +0900 Subject: [PATCH 125/465] =?UTF-8?q?[Feat]=20#112=20RecordingViewController?= =?UTF-8?q?=20Resume=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 3069535..6001b5e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -151,7 +151,7 @@ class RecordingViewController: UIViewController { pauseConfiguration.image = UIImage(systemName: "pause.fill") pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) self.pauseButton.configuration = pauseConfiguration - self.recordingViewModel?.pause() + self.recordingViewModel?.resume() self.currentState = true } } From 09b55d11b595e4ca5b1ce639b665f405cde3346e Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 9 Nov 2021 23:36:39 +0900 Subject: [PATCH 126/465] =?UTF-8?q?[Feat]=20#112=20Timer=20=EC=9D=BC?= =?UTF-8?q?=EC=8B=9C=EC=A0=95=EC=A7=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 +- .../SanTa/RecordingScene/RecordingModel.swift | 29 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 030d7f9..89055e0 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -9,7 +9,7 @@ import Foundation struct Records { var title: String? - var record: [Record] + var records: [Record] mutating func configureTitle(title: String) { self.title = title diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index d3728b5..2ce0c51 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -27,7 +27,7 @@ final class RecordingModel: NSObject, ObservableObject { private var currentTime = Date() { didSet { - self.timeConverter() + self.timeCalculation() self.checkPedoMeter() } } @@ -58,22 +58,36 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.delegate = self } - private func timeConverter() { + private func timeCalculation() { guard let startDate = self.startDate else { return } + var elapsedTimeSeconds = 0 - let elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) + elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) + + guard let records = records else { + self.timeConverter(elapsedTimeSeconds: elapsedTimeSeconds) + return + } + records.records.forEach { + elapsedTimeSeconds += Int($0.endTime.timeIntervalSince($0.startTime)) + } + + self.timeConverter(elapsedTimeSeconds: elapsedTimeSeconds) + } + + private func timeConverter(elapsedTimeSeconds: Int) { let seconds = elapsedTimeSeconds % 60 let minutes = (elapsedTimeSeconds / 60) % 60 let hours = (elapsedTimeSeconds / 3600) - time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) + self.time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) } private func checkPedoMeter() { guard let date = self.startDate else { return } - pedoMeter.queryPedometerData(from: date, to: self.currentTime) { [weak self] data, error in + self.pedoMeter.queryPedometerData(from: date, to: self.currentTime) { [weak self] data, error in guard let activityData = data, error == nil else { return } @@ -102,12 +116,11 @@ final class RecordingModel: NSObject, ObservableObject { locations: self.location) guard self.records != nil else { - - self.records = Records(title: nil, record: [record]) + self.records = Records(title: nil, records: [record]) return } - self.records?.record.append(record) + self.records?.records.append(record) } func pause() { From 4769115ff6d1776de2d51453e7742ef81d10ecd4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 00:01:22 +0900 Subject: [PATCH 127/465] =?UTF-8?q?[Feat]=20#113=20#115=20=EA=B1=B8?= =?UTF-8?q?=EC=9D=8C=20=EC=88=98,=20=EC=9D=B4=EB=8F=99=EA=B1=B0=EB=A6=AC?= =?UTF-8?q?=20=EC=B8=A1=EC=A0=95=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 45 ++++++++++++++++--- .../RecordingViewController.swift | 11 ++--- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 2ce0c51..d82ce73 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -86,25 +86,58 @@ final class RecordingModel: NSObject, ObservableObject { private func checkPedoMeter() { guard let date = self.startDate else { return } + let dispatchGroup = DispatchGroup() + self.currentWalk = 0 + self.currentKilo = 0 + + dispatchGroup.enter() self.pedoMeter.queryPedometerData(from: date, to: self.currentTime) { [weak self] data, error in guard let activityData = data, error == nil else { return } - self?.walk = "\(activityData.numberOfSteps)" + let walk = "\(activityData.numberOfSteps)" - guard let walk = self?.walk, - let walkNumber = Int(walk) else { return } + guard let walkNumber = Int(walk) else { return } - self?.currentWalk = walkNumber + self?.currentWalk += walkNumber guard let distance = activityData.distance else { return } let transformatKilometer = Double(truncating: distance) / 1000 - self?.currentKilo = transformatKilometer - let distanceString = String(format: "%.2f", transformatKilometer) + self?.currentKilo += transformatKilometer + dispatchGroup.leave() + } + + dispatchGroup.notify(queue: .main) { [weak self] in + guard let walk = self?.currentWalk else { return } + + self?.walk = "\(walk)" + guard let currentKile = self?.currentKilo else { return } + let distanceString = String(format: "%.2f", currentKile) self?.kilometer = "\(distanceString)" } + + guard let records = records else { return } + + records.records.forEach { + dispatchGroup.enter() + self.pedoMeter.queryPedometerData(from: $0.startTime, to: $0.endTime) { [weak self] data, error in + guard let activityData = data, + error == nil else { return } + + let walk = "\(activityData.numberOfSteps)" + + guard let walkNumber = Int(walk) else { return } + + self?.currentWalk += walkNumber + + guard let distance = activityData.distance else { return } + let transformatKilometer = Double(truncating: distance) / 1000 + self?.currentKilo += transformatKilometer + dispatchGroup.leave() + } + } } private func appendRecord() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 6001b5e..56ec1ea 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -161,6 +161,7 @@ class RecordingViewController: UIViewController { let noneAction = UIAlertAction(title: "아니요", style: .default) let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in self?.view.backgroundColor = .black + self?.recordingViewModel?.pause() self?.coordinator?.presentRecordingTitleViewController() } stopAlert.addAction(noneAction) @@ -175,11 +176,11 @@ class RecordingViewController: UIViewController { extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { - self.recordingViewModel?.save(title: title) { [weak self] completion in - DispatchQueue.main.async { - self?.coordinator?.dismiss() - } - } +// self.recordingViewModel?.save(title: title) { [weak self] completion in +// DispatchQueue.main.async { +// self?.coordinator?.dismiss() +// } +// } self.coordinator?.dismiss() } } From 5722802797beba5c8a4a9f67fdbd74ea3de8b05c Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 10 Nov 2021 11:42:18 +0900 Subject: [PATCH 128/465] =?UTF-8?q?[Fix]=20=EB=A8=B8=EC=A7=80=20=EC=9D=B4?= =?UTF-8?q?=ED=9B=84=20=EB=B0=9C=EC=83=9D=ED=95=9C=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- .../SanTa/RecordingScene/RecordingViewCoordinator.swift | 4 ++-- .../RecordingTitleViewCoordinator.swift | 9 ++------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index a93b5a6..31418d0 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -58,7 +58,7 @@ extension MapViewCoordinator { useCase: MapViewUseCase( repository: DefaultMapViewRespository( mountainExtractor: MountainExtractor(), - userDefaultsStorage: DefaultUserDefaultsStorage() + userDefaultsStorage: DefaultUserDefaultsStorage.shared ) ) ) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index e276a04..fdc15d2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -36,14 +36,14 @@ class RecordingViewCoordinator: Coordinator { self.navigationController.dismiss(animated: true) guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } mapViewCoordinator.recordingViewDidDismiss() - self.parentCoordinator?.childCoordinator.removeAll() + self.parentCoordinator?.childCoordinators.removeAll() } } extension RecordingViewCoordinator { func presentRecordingTitleViewController() { let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(navigationController: self.navigationController, delegate: self.recordingViewController) - self.childCoordinator.append(recordingTitleViewCoordinator) + self.childCoordinators.append(recordingTitleViewCoordinator) recordingTitleViewCoordinator.parentCoordinator = self recordingTitleViewCoordinator.start() diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 17cc60a..556791e 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -10,7 +10,7 @@ import UIKit class RecordingTitleViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController - var childCoordinator: [Coordinator] = [] + var childCoordinators: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController init(navigationController: UINavigationController, delegate: RecordingViewDelegate) { @@ -30,11 +30,6 @@ class RecordingTitleViewCoordinator: Coordinator { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } recordingCoordinator.recordingViewController.dismiss(animated: true) - self.parentCoordinator?.childCoordinator.enumerated().forEach { (index, coordinator) in - if coordinator is RecordingTitleViewCoordinator { - parentCoordinator?.childCoordinator.remove(at: index) - return - } - } + self.parentCoordinator?.childCoordinators.removeLast() } } From 3d07538593c7afbe15154eedf6373c8628903c11 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 10 Nov 2021 14:54:54 +0900 Subject: [PATCH 129/465] =?UTF-8?q?[Refactor]=20#125=20Persistence=20?= =?UTF-8?q?=EC=A3=BC=EC=9E=85=20=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 11 ++++++--- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 20 +++++++++++++--- .../Persistences/UserDefaultsStorage.swift | 4 +--- .../RecordingViewCoordinator.swift | 19 ++++++++++++--- .../SettingsViewCoordinator.swift | 24 ++++++++++++------- 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 01457dd..882ad90 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -18,6 +18,9 @@ class AppCoordinator: Coordinator { let window: UIWindow? private var firstViewController: UIViewController! + private let coreDataStorage = CoreDataStorage() + private let mountainExtractor = MountainExtractor() + private let userDefaultsStorage = DefaultUserDefaultsStorage() init(_ window: UIWindow?) { self.window = window @@ -25,7 +28,7 @@ class AppCoordinator: Coordinator { } func start() { - DefaultUserDefaultsStorage.shared.makeFirstData() + self.userDefaultsStorage.makeFirstData() let tabBarController = self.setTabBarController() self.window?.rootViewController = tabBarController } @@ -39,7 +42,9 @@ class AppCoordinator: Coordinator { let thirdItem = UITabBarItem(title: "목록", image: nil, tag: 2) let fourthItem = UITabBarItem(title: "설정", image: nil, tag: 3) - let mapViewCoordinator = MapViewCoordinator() + let mapViewCoordinator = MapViewCoordinator(userDefaultsStorage: self.userDefaultsStorage, + mountainExtractor: self.mountainExtractor, + coreDataStorage: self.coreDataStorage) mapViewCoordinator.parentCoordinator = self childCoordinators.append(mapViewCoordinator) let mapViewController = mapViewCoordinator.startPush() @@ -60,7 +65,7 @@ class AppCoordinator: Coordinator { mountainListViewController.tabBarItem = thirdItem mountainListViewController.tabBarItem.image = .init(systemName: "text.below.photo") - let settingsViewCoordinator = SettingsViewCoordinator() + let settingsViewCoordinator = SettingsViewCoordinator(userDefaultsStorage: self.userDefaultsStorage) settingsViewCoordinator.parentCoordinator = self childCoordinators.append(settingsViewCoordinator) let settingsViewController = settingsViewCoordinator.startPush() diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 31418d0..4984bf5 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -13,6 +13,18 @@ class MapViewCoordinator: Coordinator { var navigationController: UINavigationController = UINavigationController() var childCoordinators: [Coordinator] = [] + private let userDefaultsStorage: UserDefaultsStorage + private let mountainExtractor: MountainExtractor + private let coreDataStorage: CoreDataStorage + + init(userDefaultsStorage: UserDefaultsStorage, + mountainExtractor: MountainExtractor, + coreDataStorage: CoreDataStorage) { + self.userDefaultsStorage = userDefaultsStorage + self.mountainExtractor = mountainExtractor + self.coreDataStorage = coreDataStorage + } + func start() { } @@ -28,7 +40,9 @@ class MapViewCoordinator: Coordinator { extension MapViewCoordinator { func presentRecordingViewController() { if self.childCoordinators.isEmpty { - let recordingViewCoordinator = RecordingViewCoordinator(navigationController: self.navigationController) + let recordingViewCoordinator = RecordingViewCoordinator( + navigationController: self.navigationController, + coreDataStorage: self.coreDataStorage) self.childCoordinators.append(recordingViewCoordinator) recordingViewCoordinator.parentCoordinator = self } @@ -57,8 +71,8 @@ extension MapViewCoordinator { return MapViewModel( useCase: MapViewUseCase( repository: DefaultMapViewRespository( - mountainExtractor: MountainExtractor(), - userDefaultsStorage: DefaultUserDefaultsStorage.shared + mountainExtractor: mountainExtractor, + userDefaultsStorage: self.userDefaultsStorage ) ) ) diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index 1b2017d..806f4e6 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -16,11 +16,9 @@ protocol UserDefaultsStorage { final class DefaultUserDefaultsStorage: UserDefaultsStorage { - static let shared = DefaultUserDefaultsStorage() - let userDefaults: UserDefaults - private init(useuserDefaults: UserDefaults = UserDefaults.standard) { + init(useuserDefaults: UserDefaults = UserDefaults.standard) { self.userDefaults = useuserDefaults } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index fdc15d2..029824b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -14,10 +14,23 @@ class RecordingViewCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] var recordingViewController: RecordingViewController - init(navigationController: UINavigationController) { + private let coreDataStorage: CoreDataStorage + + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage) { self.navigationController = navigationController - let viewModel = RecordingViewModel(recordingUseCase: DefaultRecordingUseCase(recordRepository: DefaultRecordRepository(recordStorage: CoreDataRecordStorage(coreDataStorage: CoreDataStorage())), recordingModel: RecordingModel())) - self.recordingViewController = RecordingViewController(viewModel: viewModel) + self.coreDataStorage = coreDataStorage + self.recordingViewController = RecordingViewController( + viewModel: RecordingViewModel( + recordingUseCase: DefaultRecordingUseCase( + recordRepository: DefaultRecordRepository( + recordStorage: CoreDataRecordStorage( + coreDataStorage: self.coreDataStorage + ) + ), + recordingModel: RecordingModel() + ) + ) + ) self.recordingViewController.coordinator = self } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 9d003b9..50f9e92 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -10,13 +10,19 @@ import UIKit class SettingsViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] - + + private var userDefaultsStorage: UserDefaultsStorage + + init(userDefaultsStorage: UserDefaultsStorage) { + self.userDefaultsStorage = userDefaultsStorage + } + func start() { } func startPush() -> SettingsViewController { - let settingsViewController = injectDependencies() + let settingsViewController = SettingsViewController(viewModel: injectDependencies()) settingsViewController.coordinator = self return settingsViewController @@ -24,11 +30,13 @@ class SettingsViewCoordinator: Coordinator { } extension SettingsViewCoordinator { - private func injectDependencies() -> SettingsViewController { - let repository = DefaultSettingsRepository(settingsStorage: DefaultUserDefaultsStorage.shared) - let usecase = DefaultSettingsUsecase(settingsRepository: repository) - let viewModel = SettingsViewModel(settingsUseCase: usecase) - let viewController = SettingsViewController(viewModel: viewModel) - return viewController + private func injectDependencies() -> SettingsViewModel { + return SettingsViewModel( + settingsUseCase: DefaultSettingsUsecase( + settingsRepository: DefaultSettingsRepository( + settingsStorage: self.userDefaultsStorage + ) + ) + ) } } From abffd453c1f63d801f03a169e20adfda71411fa9 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 10 Nov 2021 16:10:29 +0900 Subject: [PATCH 130/465] =?UTF-8?q?[Feat]=20#128=20CoreData=EC=97=90?= =?UTF-8?q?=EC=84=9C=20NSManagedObject=ED=83=80=EC=9E=85=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20fetch=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/CoreDataRecordStorage.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index 6300fa1..95122e8 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -11,6 +11,7 @@ import CoreData protocol RecordsStorage { func save(record: Record, completion: @escaping (Result) -> Void) + func fetch(completion: @escaping (Result<[NSManagedObject], Error>) -> Void) } final class CoreDataRecordStorage: RecordsStorage { @@ -49,5 +50,15 @@ final class CoreDataRecordStorage: RecordsStorage { } } - + func fetch(completion: @escaping (Result<[NSManagedObject], Error>) -> Void) { + self.coreDataStorage.performBackgroundTask { context in + do { + let requset = NSFetchRequest(entityName: "Records") + let result = try context.fetch(requset) + completion(.success(result)) + } catch { + completion(.failure(error)) + } + } + } } From 1255b2f11a90ba03046b481385625896e8824173 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 17:25:04 +0900 Subject: [PATCH 131/465] =?UTF-8?q?[Fix]=20RecordingView=20Dismiss=20?= =?UTF-8?q?=EC=8B=9C=EC=97=90=20=ED=81=AC=EB=9E=98=EC=89=AC=EA=B0=80=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 11 +++++++++++ SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 1 + .../RecordingScene/RecordingViewController.swift | 14 +++++++++----- .../RecordingScene/RecordingViewCoordinator.swift | 8 ++++++-- .../RecordingTitleViewController.swift | 10 +++++++--- .../RecordingTitleViewCoordinator.swift | 12 +++++++----- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index d82ce73..63e0408 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,6 +19,7 @@ final class RecordingModel: NSObject, ObservableObject { private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() private var timer: DispatchSourceTimer? + private var timerIsRunning = false private var records: Records? private var startDate: Date? private var currentWalk = 0 @@ -157,6 +158,9 @@ final class RecordingModel: NSObject, ObservableObject { } func pause() { + guard self.timerIsRunning == true else { return } + + self.timerIsRunning = false self.appendRecord() self.timer?.suspend() self.locationManager.stopUpdatingLocation() @@ -164,6 +168,9 @@ final class RecordingModel: NSObject, ObservableObject { } func resume() { + guard self.timerIsRunning == false else { return } + + self.timerIsRunning = true self.timer?.resume() self.locationManager.startUpdatingLocation() self.startDate = Date() @@ -173,6 +180,10 @@ final class RecordingModel: NSObject, ObservableObject { func cancel() -> Records? { guard let records = self.records else { return nil } + if !self.timerIsRunning { + self.timer?.resume() + } + self.timer?.cancel() self.timer = nil self.locationManager.stopUpdatingLocation() diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 17411e6..150088b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -34,6 +34,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func save(title: String, completion: @escaping (Result) -> Void) { + recording.cancel() // self.recordRepository.save(record: recording.cancel(), completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 56ec1ea..a7bded2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -172,15 +172,19 @@ class RecordingViewController: UIViewController { @objc private func locationButtonAction(_ sender: UIResponder) { self.coordinator?.hide() } + + deinit { + print("😇RecordingViewController is deinit \(Date())!!😇") + } } extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { -// self.recordingViewModel?.save(title: title) { [weak self] completion in -// DispatchQueue.main.async { -// self?.coordinator?.dismiss() -// } -// } + self.recordingViewModel?.save(title: title) { [weak self] completion in + DispatchQueue.main.async { + self?.coordinator?.dismiss() + } + } self.coordinator?.dismiss() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index fdc15d2..00a48fb 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -36,13 +36,17 @@ class RecordingViewCoordinator: Coordinator { self.navigationController.dismiss(animated: true) guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } mapViewCoordinator.recordingViewDidDismiss() - self.parentCoordinator?.childCoordinators.removeAll() + self.parentCoordinator?.childCoordinators.removeLast() + } + + deinit { + print("😇RecordingViewCoordinator is deinit \(Date())!!😇") } } extension RecordingViewCoordinator { func presentRecordingTitleViewController() { - let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(navigationController: self.navigationController, delegate: self.recordingViewController) + let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(delegate: self.recordingViewController) self.childCoordinators.append(recordingTitleViewCoordinator) recordingTitleViewCoordinator.parentCoordinator = self diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 2b9c902..55e7ff0 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -147,18 +147,22 @@ class RecordingTitleViewController: UIViewController { @objc private func inputButtonAction(sender: UIButton) { guard let title = self.recordingTitleText.text else { - self.delegate?.didTitleWriteDone(title: "") self.coordinator?.dismiss() + self.delegate?.didTitleWriteDone(title: "") return } - self.delegate?.didTitleWriteDone(title: title) self.coordinator?.dismiss() + self.delegate?.didTitleWriteDone(title: title) } @objc private func notInputButtonButtonAction(sender: UIButton) { - self.delegate?.didTitleWriteDone(title: "") self.coordinator?.dismiss() + self.delegate?.didTitleWriteDone(title: "") + } + + deinit { + print("😇RecordingTitleViewController is deinit \(Date())!!😇") } } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 556791e..a52f2be 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -9,12 +9,10 @@ import UIKit class RecordingTitleViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? - var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController - init(navigationController: UINavigationController, delegate: RecordingViewDelegate) { - self.navigationController = navigationController + init(delegate: RecordingViewDelegate) { self.recordingTitleViewController = RecordingTitleViewController() self.recordingTitleViewController.delegate = delegate self.recordingTitleViewController.coordinator = self @@ -23,13 +21,17 @@ class RecordingTitleViewCoordinator: Coordinator { func start() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) + recordingCoordinator.recordingViewController?.present(recordingTitleViewController, animated: true) } func dismiss() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - recordingCoordinator.recordingViewController.dismiss(animated: true) + recordingCoordinator.recordingViewController?.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } + + deinit { + print("😇RecordingTitleViewCoordinator is deinit \(Date())!!😇") + } } From 4f50f01a19a3d86633c49eccefd985aec0b93c2c Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 17:27:12 +0900 Subject: [PATCH 132/465] =?UTF-8?q?[Fix]=20RecordingTitleViewCoordinator?= =?UTF-8?q?=20recordingViewController=20=EC=98=B5=EC=85=94=EB=84=90=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewCoordinator.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index a52f2be..cf44fca 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -21,13 +21,13 @@ class RecordingTitleViewCoordinator: Coordinator { func start() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - recordingCoordinator.recordingViewController?.present(recordingTitleViewController, animated: true) + recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) } func dismiss() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - recordingCoordinator.recordingViewController?.dismiss(animated: true) + recordingCoordinator.recordingViewController.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } From b49f1251754b625578ccc02e7cd68a41b0e7dd71 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 18:00:51 +0900 Subject: [PATCH 133/465] =?UTF-8?q?[Refactor]=20#132=20Records=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=EC=B2=B4=20title=20=ED=94=84=EB=A1=9C=ED=8D=BC?= =?UTF-8?q?=ED=8B=B0=20=EC=98=B5=EC=85=94=EB=84=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 89055e0..0533436 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,7 +8,7 @@ import Foundation struct Records { - var title: String? + var title: String var records: [Record] mutating func configureTitle(title: String) { diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 63e0408..198e3fe 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -150,7 +150,7 @@ final class RecordingModel: NSObject, ObservableObject { locations: self.location) guard self.records != nil else { - self.records = Records(title: nil, records: [record]) + self.records = Records(title: "", records: [record]) return } From f023bac0033085e70e1a08a352fcf0da2e6417f0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 18:05:09 +0900 Subject: [PATCH 134/465] =?UTF-8?q?[Fix]=20RecordingViewController=20Backg?= =?UTF-8?q?round=20Color=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingViewController+Extension.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index fcc4b62..a245ac8 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -55,7 +55,7 @@ extension RecordingViewController { func configureConstraints() { - self.view.backgroundColor = .systemBlue + self.view.backgroundColor = UIColor(named: "SantaColor") [self.timeLabel, self.altitudeLabel, self.walkLabel].forEach { self.calculateStackView.addArrangedSubview($0) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index a7bded2..9561358 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -146,7 +146,7 @@ class RecordingViewController: UIViewController { self.recordingViewModel?.pause() self.currentState = false } else { - self.view.backgroundColor = .systemBlue + self.view.backgroundColor = UIColor(named: "SantaColor") var pauseConfiguration = UIButton.Configuration.plain() pauseConfiguration.image = UIImage(systemName: "pause.fill") pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) From 55956952a62a9af6b4b281bc1d4f6a14a6e344ca Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 18:08:47 +0900 Subject: [PATCH 135/465] =?UTF-8?q?[Feat]=20#132=20Records=20Title=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 150088b..549f19d 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -34,7 +34,9 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func save(title: String, completion: @escaping (Result) -> Void) { - recording.cancel() + guard var records = recording.cancel() else { return } + + records.configureTitle(title: title) // self.recordRepository.save(record: recording.cancel(), completion: completion) } } From b77bcd9315d97044b07264402922730975c8bcdb Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 18:12:13 +0900 Subject: [PATCH 136/465] =?UTF-8?q?[Refactor]=20#132=20Completion=20Handle?= =?UTF-8?q?r=20=EB=B0=98=ED=99=98=20=EA=B0=92=20Record=20->=20Records=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift | 6 +++--- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index 6300fa1..0d84563 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -10,7 +10,7 @@ import CoreData protocol RecordsStorage { func save(record: Record, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) } final class CoreDataRecordStorage: RecordsStorage { @@ -21,7 +21,7 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage = coreDataStorage } - func save(record: Record, completion: @escaping (Result) -> Void) { + func save(record: Record, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", into: context) @@ -42,7 +42,7 @@ final class CoreDataRecordStorage: RecordsStorage { do { try context.save() - completion(.success(record)) +// completion(.success(record)) } catch { completion(.failure(error)) } diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index f6024a4..2168e65 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -9,7 +9,7 @@ import Foundation protocol RecordRepository { func save(record: Record, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) } final class DefaultRecordRepository: RecordRepository { @@ -20,7 +20,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage = recordStorage } - func save(record: Record, completion: @escaping (Result) -> Void) { + func save(record: Record, completion: @escaping (Result) -> Void) { self.recordStorage.save(record: record, completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 549f19d..673ddde 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -10,7 +10,7 @@ import Foundation protocol RecordingUseCase { var recording: RecordingModel { get set } - func save(title: String, completion: @escaping (Result) -> Void) + func save(title: String, completion: @escaping (Result) -> Void) func pause() func resume() } @@ -33,7 +33,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording.cancel() else { return } records.configureTitle(title: title) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 6473fec..36fbcb3 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -60,7 +60,7 @@ final class RecordingViewModel: ObservableObject { self.recordingUseCase?.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } } From 1063e91092236b2968c2c8088114203ed5f2f61d Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 21:34:06 +0900 Subject: [PATCH 137/465] =?UTF-8?q?[Refactor]=20#132=20CoreData=20Records?= =?UTF-8?q?=20Entity=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoreDataRecordStorage.swift | 38 +++++++++---------- .../RecordingScene/RecordRepository.swift | 4 +- .../SanTa.xcdatamodel/contents | 12 ++++-- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index 0d84563..46b6d05 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -9,7 +9,7 @@ import Foundation import CoreData protocol RecordsStorage { - func save(record: Record, + func save(record: Records, completion: @escaping (Result) -> Void) } @@ -21,32 +21,32 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage = coreDataStorage } - func save(record: Record, completion: @escaping (Result) -> Void) { + func save(record: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", into: context) // recordObject.setValue(record.time, forKey: "time") - recordObject.setValue(record.distance, forKey: "distance") - recordObject.setValue(record.step, forKey: "step") +// recordObject.setValue(record.distance, forKey: "distance") +// recordObject.setValue(record.step, forKey: "step") - record.locations.forEach { - let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", - into: context) as? LocationEntityMO - locationObject?.altitude = $0.altitude - locationObject?.latitude = $0.latitude - locationObject?.longitude = $0.longitude - - guard let locationObject = locationObject else { return } - (recordObject as? RecordEntityMO)?.addToLocations(locationObject) +// record.locations.forEach { +// let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", +// into: context) as? LocationEntityMO +// locationObject?.altitude = $0.altitude +// locationObject?.latitude = $0.latitude +// locationObject?.longitude = $0.longitude +// +// guard let locationObject = locationObject else { return } +// (recordObject as? RecordEntityMO)?.addToLocations(locationObject) } - do { - try context.save() +// do { +// try context.save() // completion(.success(record)) - } catch { - completion(.failure(error)) - } - } +// } catch { +// completion(.failure(error)) +// } +// } } diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 2168e65..76f5aae 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -8,7 +8,7 @@ import Foundation protocol RecordRepository { - func save(record: Record, + func save(record: Records, completion: @escaping (Result) -> Void) } @@ -20,7 +20,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage = recordStorage } - func save(record: Record, completion: @escaping (Result) -> Void) { + func save(record: Records, completion: @escaping (Result) -> Void) { self.recordStorage.save(record: record, completion: completion) } } diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 51d819d..51629f9 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -11,9 +11,15 @@ + + + + + - - + + + \ No newline at end of file From 1cf716e64e964476938c972b0887db5b68d35596 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 10 Nov 2021 21:54:28 +0900 Subject: [PATCH 138/465] =?UTF-8?q?[Feat]=20#133=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Dynamic=20Type=20Text=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 14 ++++++++++++-- .../SettingsScene/SettingsViewController.swift | 4 ++++ SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 10 +++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index d7d551c..7d125ca 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -13,20 +13,29 @@ class MapOptionCell: UITableViewCell { private(set) var title: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 14) + label.font = UIFont.preferredFont(forTextStyle: .caption1) + label.adjustsFontForContentSizeCategory = true label.translatesAutoresizingMaskIntoConstraints = false + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.setContentCompressionResistancePriority(.init(rawValue: 800), for: .horizontal) + label.adjustsFontSizeToFitWidth = true return label }() private var map: UILabel = { let label = PaddingLabel() label.padding(top: 5, bottom: 5, left: 10, right: 10) - label.font = UIFont.systemFont(ofSize: 12) + label.font = UIFont.preferredFont(forTextStyle: .caption2) + label.adjustsFontForContentSizeCategory = true label.textColor = .white label.backgroundColor = .darkGray label.translatesAutoresizingMaskIntoConstraints = false label.clipsToBounds = true label.layer.cornerRadius = 5 + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.setContentCompressionResistancePriority(.init(rawValue: 1000), for: .horizontal) return label }() @@ -65,6 +74,7 @@ class MapOptionCell: UITableViewCell { let mapConstrain = [ self.map.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), self.map.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), + self.map.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 10), ] NSLayoutConstraint.activate(mapConstrain) } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 147c449..2523b7e 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -149,6 +149,10 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { self.showMapActionSheet(cellTitle: title) self.tableView.deselectRow(at: indexPath, animated: true) } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableView.automaticDimension + } } extension SettingsViewController: ToggleOptionCellDelegate { diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index f3d4b67..eebd4bb 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -19,8 +19,13 @@ class ToggleOptionCell: UITableViewCell { private var title: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 14) + label.font = UIFont.preferredFont(forTextStyle: .caption1) + label.adjustsFontForContentSizeCategory = true label.translatesAutoresizingMaskIntoConstraints = false + label.numberOfLines = 0 + label.lineBreakMode = .byWordWrapping + label.setContentCompressionResistancePriority(.init(rawValue: 800), for: .horizontal) + label.adjustsFontSizeToFitWidth = true return label }() @@ -29,6 +34,7 @@ class ToggleOptionCell: UITableViewCell { controlSwitch.translatesAutoresizingMaskIntoConstraints = false controlSwitch.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) controlSwitch.onTintColor = .systemBlue + controlSwitch.setContentCompressionResistancePriority(.init(rawValue: 1000), for: .horizontal) return controlSwitch }() @@ -64,6 +70,7 @@ class ToggleOptionCell: UITableViewCell { } private func configureView() { + self.contentView.addSubview(self.title) let locationConstrain = [ self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), @@ -75,6 +82,7 @@ class ToggleOptionCell: UITableViewCell { let switchConstrain = [ self.controlSwitch.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), self.controlSwitch.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), + self.controlSwitch.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 10), ] NSLayoutConstraint.activate(switchConstrain) } From 78a5207d44fe06e95f075be990847d18ccca9e2f Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 22:07:30 +0900 Subject: [PATCH 139/465] =?UTF-8?q?[Refactor]=20#132=20CoreData=20Store=20?= =?UTF-8?q?Records=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoreDataRecordStorage.swift | 58 +++++++++++-------- .../RecordingScene/RecordRepository.swift | 6 +- .../RecordingScene/RecordingUseCase.swift | 2 +- .../RecordingViewController.swift | 2 +- .../SanTa.xcdatamodel/contents | 7 ++- 5 files changed, 44 insertions(+), 31 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index 46b6d05..547142f 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -9,7 +9,7 @@ import Foundation import CoreData protocol RecordsStorage { - func save(record: Records, + func save(records: Records, completion: @escaping (Result) -> Void) } @@ -21,32 +21,44 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage = coreDataStorage } - func save(record: Records, completion: @escaping (Result) -> Void) { + func save(records: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in - let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", - into: context) -// recordObject.setValue(record.time, forKey: "time") -// recordObject.setValue(record.distance, forKey: "distance") -// recordObject.setValue(record.step, forKey: "step") + let recordsObject = NSEntityDescription.insertNewObject(forEntityName: "RecordsEntity", + into: context) -// record.locations.forEach { -// let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", -// into: context) as? LocationEntityMO -// locationObject?.altitude = $0.altitude -// locationObject?.latitude = $0.latitude -// locationObject?.longitude = $0.longitude -// -// guard let locationObject = locationObject else { return } -// (recordObject as? RecordEntityMO)?.addToLocations(locationObject) + recordsObject.setValue(records.title, forKey: "title") + + records.records.forEach { + let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", + into: context) as? RecordEntityMO + + recordObject?.startTime = $0.startTime + recordObject?.endTime = $0.endTime + recordObject?.distance = $0.distance + recordObject?.step = Int16($0.step) + + guard let recordObject = recordObject else { return } + (recordsObject as? RecordsEntityMO)?.addToRecords(recordObject) + + $0.locations.forEach { + let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", + into: context) as? LocationEntityMO + locationObject?.altitude = $0.altitude + locationObject?.latitude = $0.latitude + locationObject?.longitude = $0.longitude + + guard let locationObject = locationObject else { return } + recordObject.addToLocations(locationObject) + } } -// do { -// try context.save() -// completion(.success(record)) -// } catch { -// completion(.failure(error)) -// } -// } + do { + try context.save() + completion(.success(records)) + } catch { + completion(.failure(error)) + } + } } diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 76f5aae..a32837c 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -8,7 +8,7 @@ import Foundation protocol RecordRepository { - func save(record: Records, + func save(records: Records, completion: @escaping (Result) -> Void) } @@ -20,7 +20,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage = recordStorage } - func save(record: Records, completion: @escaping (Result) -> Void) { - self.recordStorage.save(record: record, completion: completion) + func save(records: Records, completion: @escaping (Result) -> Void) { + self.recordStorage.save(records: records, completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 673ddde..b014b60 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -37,6 +37,6 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { guard var records = recording.cancel() else { return } records.configureTitle(title: title) -// self.recordRepository.save(record: recording.cancel(), completion: completion) + self.recordRepository.save(records: records, completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 9561358..1ff5f55 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -182,9 +182,9 @@ extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { self.recordingViewModel?.save(title: title) { [weak self] completion in DispatchQueue.main.async { + print(completion) self?.coordinator?.dismiss() } } - self.coordinator?.dismiss() } } diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 51629f9..6ed1d12 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -8,18 +8,19 @@ + + - - + - + \ No newline at end of file From 01e23b4b37e659a90c729e7cf5495712c3d7b8f4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 22:58:21 +0900 Subject: [PATCH 140/465] =?UTF-8?q?[Feat]=20#135=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5,=20=EC=A0=80=EC=9E=A5=20=EC=8B=A4=ED=8C=A8?= =?UTF-8?q?=20=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 1ff5f55..1ecdc62 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -182,8 +182,12 @@ extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { self.recordingViewModel?.save(title: title) { [weak self] completion in DispatchQueue.main.async { - print(completion) - self?.coordinator?.dismiss() + switch completion { + case .success(_): + self?.coordinator?.dismiss() + case .failure(_): + break + } } } } From 18e42eb60069c6ddf4b1f1630d7a9ea1d6077afa Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 23:07:33 +0900 Subject: [PATCH 141/465] =?UTF-8?q?[Feat]=20#136=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20CoreDataErro?= =?UTF-8?q?r=20Enum=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/Persistences/CoreDataStorage.swift | 4 ++++ .../RecordingScene/RecordingUseCase.swift | 5 +++- .../RecordingViewController.swift | 23 +++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/Persistences/CoreDataStorage.swift b/SanTa/SanTa/Persistences/CoreDataStorage.swift index 7eb519f..2f88d43 100644 --- a/SanTa/SanTa/Persistences/CoreDataStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataStorage.swift @@ -7,6 +7,10 @@ import CoreData +enum CoreDataError: Error { + case coreDataError +} + final class CoreDataStorage { private lazy var persistentContainer: NSPersistentContainer = { diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index b014b60..432d670 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -34,7 +34,10 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func save(title: String, completion: @escaping (Result) -> Void) { - guard var records = recording.cancel() else { return } + guard var records = recording.cancel() else { +// completion(.failure(error)) + return + } records.configureTitle(title: title) self.recordRepository.save(records: records, completion: completion) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 1ecdc62..b761558 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -181,12 +181,25 @@ class RecordingViewController: UIViewController { extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { self.recordingViewModel?.save(title: title) { [weak self] completion in - DispatchQueue.main.async { - switch completion { - case .success(_): + switch completion { + case .success(_): + DispatchQueue.main.async { self?.coordinator?.dismiss() - case .failure(_): - break + } + case .failure(_): + let resultAlert = UIAlertController(title: "저장 실패", message: "데이터 저장에 실패했습니다.", preferredStyle: UIAlertController.Style.alert) + let restoreAction = UIAlertAction(title: "다시 저장하기", style: .default) { [weak self] (action) in + self?.didTitleWriteDone(title: title) + } + let endAction = UIAlertAction(title: "저장하지 않기", style: .default) { [weak self] (action) in + DispatchQueue.main.async { + self?.coordinator?.dismiss() + } + } + resultAlert.addAction(restoreAction) + resultAlert.addAction(endAction) + DispatchQueue.main.async { + self?.present(resultAlert, animated: true, completion: nil) } } } From 758fc042b2f402844b9580fd8b18e2e714edf3df Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 23:09:46 +0900 Subject: [PATCH 142/465] =?UTF-8?q?[Fix]=20#136=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20Error=20?= =?UTF-8?q?=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift | 6 +++--- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift index 547142f..cd0d577 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift @@ -10,7 +10,7 @@ import CoreData protocol RecordsStorage { func save(records: Records, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) } final class CoreDataRecordStorage: RecordsStorage { @@ -21,7 +21,7 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage = coreDataStorage } - func save(records: Records, completion: @escaping (Result) -> Void) { + func save(records: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordsObject = NSEntityDescription.insertNewObject(forEntityName: "RecordsEntity", into: context) @@ -56,7 +56,7 @@ final class CoreDataRecordStorage: RecordsStorage { try context.save() completion(.success(records)) } catch { - completion(.failure(error)) + completion(.failure(CoreDataError.coreDataError)) } } } diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index a32837c..a661e62 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -9,7 +9,7 @@ import Foundation protocol RecordRepository { func save(records: Records, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) } final class DefaultRecordRepository: RecordRepository { @@ -20,7 +20,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage = recordStorage } - func save(records: Records, completion: @escaping (Result) -> Void) { + func save(records: Records, completion: @escaping (Result) -> Void) { self.recordStorage.save(records: records, completion: completion) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 432d670..c7ea5ef 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -10,7 +10,7 @@ import Foundation protocol RecordingUseCase { var recording: RecordingModel { get set } - func save(title: String, completion: @escaping (Result) -> Void) + func save(title: String, completion: @escaping (Result) -> Void) func pause() func resume() } @@ -33,7 +33,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording.cancel() else { // completion(.failure(error)) return diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 36fbcb3..e1aa200 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -60,7 +60,7 @@ final class RecordingViewModel: ObservableObject { self.recordingUseCase?.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } } From 9364498f4316065ddc3fce9787cf74e44c7e0dfa Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 10 Nov 2021 23:14:31 +0900 Subject: [PATCH 143/465] =?UTF-8?q?[Feat]=20#135,=20#136,=20#137,=20#138?= =?UTF-8?q?=20CoreData=20=EC=A0=80=EC=9E=A5=20=EC=8B=A4=ED=8C=A8=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 3 +-- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index c7ea5ef..66b1daf 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -35,10 +35,9 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording.cancel() else { -// completion(.failure(error)) + completion(.failure(CoreDataError.coreDataError)) return } - records.configureTitle(title: title) self.recordRepository.save(records: records, completion: completion) } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b761558..9ba7e6f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -191,7 +191,7 @@ extension RecordingViewController: RecordingViewDelegate { let restoreAction = UIAlertAction(title: "다시 저장하기", style: .default) { [weak self] (action) in self?.didTitleWriteDone(title: title) } - let endAction = UIAlertAction(title: "저장하지 않기", style: .default) { [weak self] (action) in + let endAction = UIAlertAction(title: "저장하지 않기", style: .destructive) { [weak self] (action) in DispatchQueue.main.async { self?.coordinator?.dismiss() } From c2ae95f5f5a253ebc04b2b841ae9c5a3208f27cc Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 11 Nov 2021 11:15:05 +0900 Subject: [PATCH 144/465] =?UTF-8?q?[Refactor]=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 2 +- .../CoreDataRecordStorage.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename SanTa/SanTa/{RecordingScene => Persistences}/CoreDataRecordStorage.swift (99%) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f3c4a0c..35af3ca 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -167,7 +167,6 @@ DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */, 984DDEC427325FB9003BE56B /* RecordRepository.swift */, - 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */, 984DDEC027325D67003BE56B /* Record.swift */, DAB37D4F273256B900EC523F /* RecordingModel.swift */, ); @@ -245,6 +244,7 @@ 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */, 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */, 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */, + 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */, ); path = Persistences; sourceTree = ""; diff --git a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift similarity index 99% rename from SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift rename to SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 976575a..fb10cf3 100644 --- a/SanTa/SanTa/RecordingScene/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -15,7 +15,7 @@ protocol RecordsStorage { } final class CoreDataRecordStorage: RecordsStorage { - + private let coreDataStorage: CoreDataStorage init(coreDataStorage: CoreDataStorage) { From c1056770af781058b597dafe5bccbfa61b1085ac Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 11 Nov 2021 11:30:13 +0900 Subject: [PATCH 145/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailScene/MountainDetailViewController.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index c0d5ea6..ec31b39 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -187,7 +187,9 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour extension MountainDetailViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { - if scrollView.contentOffset.y < self.maxRollUpDistance && scrollView.contentOffset.y > 0 { + let remainingScroll = scrollView.contentSize.height - scrollView.bounds.size.height + let rollUp = min(remainingScroll, self.maxRollUpDistance) + if scrollView.contentOffset.y < rollUp && scrollView.contentOffset.y > 0 { self.mutatingTopConstraint?.constant = -scrollView.contentOffset.y self.mutatingBottomConstraint?.constant = -scrollView.contentOffset.y } From cc0b0cbfe6a65c1060b325992836d3e331d7f3a0 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 11 Nov 2021 11:43:35 +0900 Subject: [PATCH 146/465] =?UTF-8?q?[Fix]=20#128=20CoreData=20RecordEntity?= =?UTF-8?q?=20=EC=A0=95=EB=A0=AC=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 6ed1d12..f8c8289 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -16,11 +16,11 @@ - + - + \ No newline at end of file From c40eb7b697b32988b2d43de3eb9f8072f361b3b4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:29:24 +0900 Subject: [PATCH 147/465] =?UTF-8?q?[Feat]=20#141=20Diffable=20Datasource?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20nested=20enum=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainListViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index b3149e3..ff7aa3a 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -8,6 +8,9 @@ import UIKit class MountainListViewController: UIViewController { + enum MountainListSection: Int, CaseIterable { + case main + } weak var coordinator: MountainListViewCoordinator? From 10f1dab2b0ea459a858540f7b3f70e37c1e8a917 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:30:31 +0900 Subject: [PATCH 148/465] =?UTF-8?q?[Feat]=20#141=20Diffable=20Datasource?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20typealias=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainListViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index ff7aa3a..642c831 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -12,6 +12,9 @@ class MountainListViewController: UIViewController { case main } + typealias MountainListDataSource = UICollectionViewDiffableDataSource + typealias MountainListSnapshot = NSDiffableDataSourceSnapshot + weak var coordinator: MountainListViewCoordinator? private var tableView: UITableView = { From 63b06931d0f7b7a5fa9062654f6c642731e98c73 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:36:40 +0900 Subject: [PATCH 149/465] =?UTF-8?q?[Feat]=20#141=20TableView=EB=A5=BC=20Co?= =?UTF-8?q?llectionView=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewController.swift | 53 +++++++------------ 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 642c831..fa2ff28 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -17,56 +17,43 @@ class MountainListViewController: UIViewController { weak var coordinator: MountainListViewCoordinator? - private var tableView: UITableView = { - let tableView = UITableView() - tableView.translatesAutoresizingMaskIntoConstraints = false - tableView.register(MountainCell.self, forCellReuseIdentifier: MountainCell.identifier) - return tableView + let mountainListCollectionView: UICollectionView = { + let flowLayout = UICollectionViewFlowLayout() + let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + + return collectionView }() override func viewDidLoad() { super.viewDidLoad() - self.configureTableView() + self.configureCollectionView() self.configureView() } - private func configureTableView() { - self.tableView.delegate = self - self.tableView.dataSource = self + private func configureCollectionView() { + self.mountainListCollectionView.delegate = self } private func configureView() { - self.view.addSubview(self.tableView) - let tableViewConstrain = [ - self.tableView.topAnchor.constraint(equalTo: self.view.topAnchor), - self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), - self.tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.view.addSubview(self.mountainListCollectionView) + let collectionViewConstrain = [ + self.mountainListCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor), + self.mountainListCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + self.mountainListCollectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.mountainListCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor), ] - NSLayoutConstraint.activate(tableViewConstrain) + NSLayoutConstraint.activate(collectionViewConstrain) } } -extension MountainListViewController: UITableViewDelegate, UITableViewDataSource { - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return dummy.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = self.tableView.dequeueReusableCell(withIdentifier: MountainCell.identifier, for: indexPath) - as? MountainCell - else { - return UITableViewCell() - } - cell.update(mountain: dummy[indexPath.row]) - return cell - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - self.tableView.deselectRow(at: indexPath, animated: true) +extension MountainListViewController: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + collectionView.deselectItem(at: indexPath, animated: true) } } + struct Mountain { let name: String let height: String From d3bd9450c6b59f473268bf8473fc320e9dab6c53 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:39:26 +0900 Subject: [PATCH 150/465] =?UTF-8?q?[Feat]=20#141=20TableViewCell=EC=9D=84?= =?UTF-8?q?=20CollectionViewCell=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index a951b1c..3b49bd1 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -7,7 +7,7 @@ import UIKit -final class MountainCell: UITableViewCell { +final class MountainCell: UICollectionViewCell { static let identifier = "MountainCell" @@ -41,10 +41,10 @@ final class MountainCell: UITableViewCell { return stackView }() - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - self.configureView() - self.accessoryType = .disclosureIndicator + override init(frame: CGRect) { + super.init(frame: frame) + + configureView() } required init?(coder: NSCoder) { From 55eb37b611cf2194582abb3ded2310cd64134752 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:41:30 +0900 Subject: [PATCH 151/465] =?UTF-8?q?[Feat]=20#141=20CompositionalLayout=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewController.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index fa2ff28..dd196c9 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -33,6 +33,7 @@ class MountainListViewController: UIViewController { private func configureCollectionView() { self.mountainListCollectionView.delegate = self + self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() } private func configureView() { @@ -45,6 +46,18 @@ class MountainListViewController: UIViewController { ] NSLayoutConstraint.activate(collectionViewConstrain) } + + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { + return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(0.25))) + item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(180)),subitems: [item]) + let section = NSCollectionLayoutSection(group: group) + section.orthogonalScrollingBehavior = .none + section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + return section + } + } } extension MountainListViewController: UICollectionViewDelegate { From f6521cdb048c492c42842a046af4a1f80b4f8a4a Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:44:27 +0900 Subject: [PATCH 152/465] [Feat] #141 Configure Section Data --- .../MountainListViewController.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index dd196c9..1bcf5df 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -17,6 +17,8 @@ class MountainListViewController: UIViewController { weak var coordinator: MountainListViewCoordinator? + var dataSource: MountainListDataSource? + let mountainListCollectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -29,6 +31,7 @@ class MountainListViewController: UIViewController { super.viewDidLoad() self.configureCollectionView() self.configureView() + self.configureData() } private func configureCollectionView() { @@ -58,6 +61,14 @@ class MountainListViewController: UIViewController { return section } } + + private func configureData() { + var snapshot = MountainListSnapshot() + MountainListSection.allCases.forEach { + snapshot.appendSections([$0]) + } + dataSource?.apply(snapshot, animatingDifferences: true) + } } extension MountainListViewController: UICollectionViewDelegate { From 6df2010921076bcbd9371e0ec3f3bee48518d877 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:45:42 +0900 Subject: [PATCH 153/465] [Feat] #141 CollectionView Register Cell --- SanTa/SanTa/MountainListScene/MountainListViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 1bcf5df..caf94bd 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -37,6 +37,7 @@ class MountainListViewController: UIViewController { private func configureCollectionView() { self.mountainListCollectionView.delegate = self self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() + self.mountainListCollectionView.register(MountainCell.self, forCellWithReuseIdentifier: MountainCell.identifier) } private func configureView() { From c54ad480c843a69cbc95ccbea59d49cbf25d3e99 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 13:52:07 +0900 Subject: [PATCH 154/465] [Feat] #141 CollectionView Configuare DataSource --- .../MountainListViewController.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index caf94bd..bb6024a 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -31,6 +31,7 @@ class MountainListViewController: UIViewController { super.viewDidLoad() self.configureCollectionView() self.configureView() + self.configuareDataSource() self.configureData() } @@ -63,6 +64,20 @@ class MountainListViewController: UIViewController { } } + private func configuareDataSource() { + let datasource = MountainListDataSource (collectionView: self.mountainListCollectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MountainCell.identifier, for: indexPath) as? MountainCell else { + return UICollectionViewCell() } + guard let item = item as? Mountain else { return cell } + cell.update(mountain: item) + return cell + }) + + self.dataSource = datasource + self.mountainListCollectionView.dataSource = dataSource + } + private func configureData() { var snapshot = MountainListSnapshot() MountainListSection.allCases.forEach { From 8ae847088ac5556c75fc30ab0086fd4a2dfb94ea Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:05:22 +0900 Subject: [PATCH 155/465] [Feat] #141 Bind SnapShot Apply --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++++ SanTa/SanTa/MountainListScene/Mountain.swift | 23 +++++++++++++++++++ .../MountainListViewController.swift | 19 +++++++++------ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 SanTa/SanTa/MountainListScene/Mountain.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f3c4a0c..613bd3f 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; + DAAF4D6A273CDBB300780DC8 /* Mountain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D69273CDBB300780DC8 /* Mountain.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; /* End PBXBuildFile section */ @@ -136,6 +137,7 @@ DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; + DAAF4D69273CDBB300780DC8 /* Mountain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mountain.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -195,6 +197,7 @@ children = ( 54296952272FC3530070B362 /* MountainListViewCoordinator.swift */, 54296950272FC3290070B362 /* MountainListViewController.swift */, + DAAF4D69273CDBB300780DC8 /* Mountain.swift */, 985EEF62272FDA98002413D9 /* MountainCell.swift */, ); path = MountainListScene; @@ -459,6 +462,7 @@ 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, + DAAF4D6A273CDBB300780DC8 /* Mountain.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/Mountain.swift b/SanTa/SanTa/MountainListScene/Mountain.swift new file mode 100644 index 0000000..0558885 --- /dev/null +++ b/SanTa/SanTa/MountainListScene/Mountain.swift @@ -0,0 +1,23 @@ +// +// Mountain.swift +// SanTa +// +// Created by 김민창 on 2021/11/11. +// + +import Foundation + +struct Mountain: Hashable { + var id = UUID() + let name: String + let height: String + let location: String + + func hash(into hasher: inout Hasher) { + hasher.combine(id) + } + + static func == (lhs: Mountain, rhs: Mountain) -> Bool { + lhs.id == rhs.id + } +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index bb6024a..a9a9d58 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -33,6 +33,18 @@ class MountainListViewController: UIViewController { self.configureView() self.configuareDataSource() self.configureData() + + self.bindSnapShotApply(section: MountainListSection.main, item: dummy) + } + + func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { + DispatchQueue.global().sync { + guard var snapshot = dataSource?.snapshot() else { return } + item.forEach { + snapshot.appendItems([$0], toSection: section) + } + dataSource?.apply(snapshot, animatingDifferences: true) + } } private func configureCollectionView() { @@ -93,12 +105,5 @@ extension MountainListViewController: UICollectionViewDelegate { } } - -struct Mountain { - let name: String - let height: String - let location: String -} - let dummy = [Mountain(name: "백두산", height: "1000m", location: "북한"), Mountain(name: "한라산", height: "2000m", location: "제주도")] From 6bc00805ee546a075c11b6f56d5669753aa6f955 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 11 Nov 2021 14:07:17 +0900 Subject: [PATCH 156/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 + .../ResultDetailSmallerInfoView.swift | 149 ++++++++++++++++++ .../ResultDetailViewController.swift | 48 ++++++ 3 files changed, 205 insertions(+) create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f3c4a0c..bc4c2fa 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; + 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */; }; @@ -80,6 +82,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; + 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewController.swift; sourceTree = ""; }; @@ -186,6 +190,8 @@ 5428FDB7272F8B34002F9D40 /* ResultDetailScene */ = { isa = PBXGroup; children = ( + 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, + 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -470,6 +476,7 @@ 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, + 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */, 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, @@ -491,6 +498,7 @@ 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, + 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */, ); diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift new file mode 100644 index 0000000..76670a3 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -0,0 +1,149 @@ +// +// ResultDetailSmallerInfoView.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/11. +// + +import UIKit + +class ResultDetailSmallerInfoView: UIView { + + private let kilo = UILabel() + private let time = UILabel() + private let steps = UILabel() + private let maxAltitude = UILabel() + private let minAltitude = UILabel() + private let avgSpeed = UILabel() + + private let kiloStackView = UIStackView() + private let timeStackView = UIStackView() + private let stepStackView = UIStackView() + private let maxAltStackView = UIStackView() + private let minAltStackView = UIStackView() + private let avgSpdStackView = UIStackView() + + private let leftInset: CGFloat = 20 + private let rightInset: CGFloat = 20 + private let topInset: CGFloat = 20 + + + init() { + super.init(frame: CGRect.zero) + self.layout() + print("layout swipeview") + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func layout() { + displayArrowImage() + self.configureKilometerStackView(with: "3.14") + self.configureTimeStackView(time: "00:18") + self.configureStepStackView(with: "1,456") + self.configureMaxAltStackView(with: "48") + self.configureMinAltStackView(with: "19") + self.configureAvgSpeedStackView(with: "3.34") + + let upperStack = UIStackView() + upperStack.axis = .horizontal + upperStack.addArrangedSubview(kiloStackView) + upperStack.addArrangedSubview(timeStackView) + upperStack.addArrangedSubview(stepStackView) + + let lowerStack = UIStackView() + lowerStack.axis = .horizontal + lowerStack.addArrangedSubview(maxAltStackView) + lowerStack.addArrangedSubview(minAltStackView) + lowerStack.addArrangedSubview(avgSpdStackView) + + let totalStack = UIStackView() + totalStack.axis = .vertical + totalStack.addArrangedSubview(upperStack) + totalStack.addArrangedSubview(lowerStack) + self.addSubview(totalStack) + + totalStack.translatesAutoresizingMaskIntoConstraints = false + let constraints = [ + totalStack.centerXAnchor.constraint(equalTo: self.centerXAnchor), + totalStack.centerYAnchor.constraint(equalTo: self.centerYAnchor) + ] + NSLayoutConstraint.activate(constraints) + } + + private func displayArrowImage() { + let arrow = UIImage(systemName: "chevron.compact.up") + let imageView = UIImageView(image: arrow) + self.addSubview(imageView) + imageView.translatesAutoresizingMaskIntoConstraints = false + + let arrowConstraints = [ + imageView.topAnchor.constraint(equalTo: self.topAnchor), + imageView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + imageView.heightAnchor.constraint(equalToConstant: 20) + ] + NSLayoutConstraint.activate(arrowConstraints) + } + + private func configureKilometerStackView(with kilometer: String) { + self.addSubview(kiloStackView) + self.kilo.text = kilometer + let kiloDescription = UILabel() + kiloDescription.text = "킬로미터" + self.kiloStackView.axis = .vertical + self.kiloStackView.addArrangedSubview(kilo) + self.kiloStackView.addArrangedSubview(kiloDescription) + } + + private func configureTimeStackView(time: String) { + self.addSubview(timeStackView) + self.time.text = time + let timeDescription = UILabel() + timeDescription.text = "시간" + self.timeStackView.axis = .vertical + self.timeStackView.addArrangedSubview(self.time) + self.timeStackView.addArrangedSubview(timeDescription) + } + + private func configureStepStackView(with steps: String) { + self.addSubview(stepStackView) + self.steps.text = steps + let stepDescription = UILabel() + stepDescription.text = "걸음" + self.stepStackView.axis = .vertical + self.stepStackView.addArrangedSubview(self.steps) + self.stepStackView.addArrangedSubview(stepDescription) + } + + private func configureMaxAltStackView(with maxAltitude: String) { + self.addSubview(maxAltStackView) + self.maxAltitude.text = maxAltitude + let maxAltDescription = UILabel() + maxAltDescription.text = "최고 고도" + self.maxAltStackView.axis = .vertical + self.maxAltStackView.addArrangedSubview(self.maxAltitude) + self.maxAltStackView.addArrangedSubview(maxAltDescription) + } + + private func configureMinAltStackView(with minAltitude: String) { + self.addSubview(minAltStackView) + self.minAltitude.text = minAltitude + let minAltDescription = UILabel() + minAltDescription.text = "최저 고도" + self.minAltStackView.axis = .vertical + self.minAltStackView.addArrangedSubview(self.minAltitude) + self.minAltStackView.addArrangedSubview(minAltDescription) + } + + private func configureAvgSpeedStackView(with speed: String) { + self.addSubview(avgSpdStackView) + self.avgSpeed.text = speed + let avgSpeedDescription = UILabel() + avgSpeedDescription.text = "평균 속도" + self.avgSpdStackView.axis = .vertical + self.avgSpdStackView.addArrangedSubview(self.avgSpeed) + self.avgSpdStackView.addArrangedSubview(avgSpeedDescription) + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift new file mode 100644 index 0000000..0f1d688 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -0,0 +1,48 @@ +// +// ResultDetailViewController.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/11. +// + +import UIKit +import MapKit + +class ResultDetailViewController: UIViewController { + private let mapView = MKMapView() + private let miniInfoView = ResultDetailSmallerInfoView() + + override func viewDidLoad() { + super.viewDidLoad() + self.layout() + // Do any additional setup after loading the view. + } +} + +extension ResultDetailViewController { + private func layout() { + self.view.addSubview(self.mapView) + self.mapView.translatesAutoresizingMaskIntoConstraints = false + + let mapViewConstraints = [ + mapView.topAnchor.constraint(equalTo: self.view.topAnchor), + mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + mapView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.75) + ] + NSLayoutConstraint.activate(mapViewConstraints) + + self.view.addSubview(self.miniInfoView) + self.miniInfoView.translatesAutoresizingMaskIntoConstraints = false + + let swipeViewConstraints = [ + miniInfoView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), + miniInfoView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + miniInfoView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + miniInfoView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) + ] + miniInfoView.backgroundColor = .red + NSLayoutConstraint.activate(swipeViewConstraints) + } + +} From 39a4bc34340a4cec0d18e018324a6f5678664e8e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 11 Nov 2021 14:24:12 +0900 Subject: [PATCH 157/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EC=A0=95=EB=B3=B4=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailSmallerInfoView.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 76670a3..5e1fff4 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -49,18 +49,23 @@ class ResultDetailSmallerInfoView: UIView { let upperStack = UIStackView() upperStack.axis = .horizontal + upperStack.distribution = .fillEqually + upperStack.spacing = 50 upperStack.addArrangedSubview(kiloStackView) upperStack.addArrangedSubview(timeStackView) upperStack.addArrangedSubview(stepStackView) let lowerStack = UIStackView() lowerStack.axis = .horizontal + lowerStack.distribution = .fillEqually + lowerStack.spacing = 50 lowerStack.addArrangedSubview(maxAltStackView) lowerStack.addArrangedSubview(minAltStackView) lowerStack.addArrangedSubview(avgSpdStackView) let totalStack = UIStackView() totalStack.axis = .vertical + totalStack.spacing = 30 totalStack.addArrangedSubview(upperStack) totalStack.addArrangedSubview(lowerStack) self.addSubview(totalStack) @@ -74,7 +79,7 @@ class ResultDetailSmallerInfoView: UIView { } private func displayArrowImage() { - let arrow = UIImage(systemName: "chevron.compact.up") + let arrow = UIImage(systemName: "chevron.compact.up")?.withTintColor(.black) let imageView = UIImageView(image: arrow) self.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false @@ -93,6 +98,7 @@ class ResultDetailSmallerInfoView: UIView { let kiloDescription = UILabel() kiloDescription.text = "킬로미터" self.kiloStackView.axis = .vertical + self.kiloStackView.alignment = .center self.kiloStackView.addArrangedSubview(kilo) self.kiloStackView.addArrangedSubview(kiloDescription) } @@ -103,6 +109,7 @@ class ResultDetailSmallerInfoView: UIView { let timeDescription = UILabel() timeDescription.text = "시간" self.timeStackView.axis = .vertical + self.timeStackView.alignment = .center self.timeStackView.addArrangedSubview(self.time) self.timeStackView.addArrangedSubview(timeDescription) } @@ -113,6 +120,7 @@ class ResultDetailSmallerInfoView: UIView { let stepDescription = UILabel() stepDescription.text = "걸음" self.stepStackView.axis = .vertical + self.stepStackView.alignment = .center self.stepStackView.addArrangedSubview(self.steps) self.stepStackView.addArrangedSubview(stepDescription) } @@ -123,6 +131,7 @@ class ResultDetailSmallerInfoView: UIView { let maxAltDescription = UILabel() maxAltDescription.text = "최고 고도" self.maxAltStackView.axis = .vertical + self.maxAltStackView.alignment = .center self.maxAltStackView.addArrangedSubview(self.maxAltitude) self.maxAltStackView.addArrangedSubview(maxAltDescription) } @@ -133,6 +142,7 @@ class ResultDetailSmallerInfoView: UIView { let minAltDescription = UILabel() minAltDescription.text = "최저 고도" self.minAltStackView.axis = .vertical + self.minAltStackView.alignment = .center self.minAltStackView.addArrangedSubview(self.minAltitude) self.minAltStackView.addArrangedSubview(minAltDescription) } @@ -143,6 +153,7 @@ class ResultDetailSmallerInfoView: UIView { let avgSpeedDescription = UILabel() avgSpeedDescription.text = "평균 속도" self.avgSpdStackView.axis = .vertical + self.avgSpdStackView.alignment = .center self.avgSpdStackView.addArrangedSubview(self.avgSpeed) self.avgSpdStackView.addArrangedSubview(avgSpeedDescription) } From d0b5829bd92fc583665ac3f05cc8bf06b3eb708e Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:31:49 +0900 Subject: [PATCH 158/465] =?UTF-8?q?[Feat]=20#140,=20#143=20UseCase,=20Repo?= =?UTF-8?q?sitory=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20Repository=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 12 +++++ .../MountainListViewModel.swift | 12 +++++ .../MountainListViewRepository.swift | 50 +++++++++++++++++++ .../MountainListViewUseCase.swift | 12 +++++ 4 files changed, 86 insertions(+) create mode 100644 SanTa/SanTa/MountainListScene/MountainListViewModel.swift create mode 100644 SanTa/SanTa/MountainListScene/MountainListViewRepository.swift create mode 100644 SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 613bd3f..900da40 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -66,6 +66,9 @@ DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; DAAF4D6A273CDBB300780DC8 /* Mountain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D69273CDBB300780DC8 /* Mountain.swift */; }; + DAAF4D6C273CE02400780DC8 /* MountainListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */; }; + DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */; }; + DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; /* End PBXBuildFile section */ @@ -138,6 +141,9 @@ DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; DAAF4D69273CDBB300780DC8 /* Mountain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mountain.swift; sourceTree = ""; }; + DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewModel.swift; sourceTree = ""; }; + DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewUseCase.swift; sourceTree = ""; }; + DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -197,6 +203,9 @@ children = ( 54296952272FC3530070B362 /* MountainListViewCoordinator.swift */, 54296950272FC3290070B362 /* MountainListViewController.swift */, + DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */, + DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */, + DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */, DAAF4D69273CDBB300780DC8 /* Mountain.swift */, 985EEF62272FDA98002413D9 /* MountainCell.swift */, ); @@ -457,6 +466,7 @@ 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, + DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, @@ -479,6 +489,8 @@ 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, + DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */, + DAAF4D6C273CE02400780DC8 /* MountainListViewModel.swift in Sources */, 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */, 985EEF65273010BD002413D9 /* ToggleOptionCell.swift in Sources */, 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift new file mode 100644 index 0000000..ae254bf --- /dev/null +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -0,0 +1,12 @@ +// +// MountainListViewModel.swift +// SanTa +// +// Created by 김민창 on 2021/11/11. +// + +import Combine + +final class MountainListViewModel { + +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift new file mode 100644 index 0000000..fec9ac4 --- /dev/null +++ b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift @@ -0,0 +1,50 @@ +// +// MountainListRepository.swift +// SanTa +// +// Created by 김민창 on 2021/11/11. +// + +import Foundation + +protocol MountainListViewReposiory { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) +} + +class DefaultMountainListViewReposiory { + enum JSONDecodeError: Error { + case decodingFailed + } + + enum userDefaultsError: Error { + case notExists + } + + enum optionError: Error { + case notExists + } + + private let mountainExtractor: MountainExtractor + private let settingsStorage: UserDefaultsStorage + + init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage) { + self.mountainExtractor = mountainExtractor + self.settingsStorage = userDefaultsStorage + } +} + +extension DefaultMountainListViewReposiory: MountainListViewReposiory { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + self.mountainExtractor.extract { result in + switch result { + case .failure(let error): + return completion(.failure(error)) + case .success(let dataAsset): + guard let decodedObjects = try? JSONDecoder().decode([MountainEntity].self, from: dataAsset.data) else { + return completion(.failure(JSONDecodeError.decodingFailed)) + } + completion(.success(decodedObjects)) + } + } + } +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift new file mode 100644 index 0000000..0154e18 --- /dev/null +++ b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift @@ -0,0 +1,12 @@ +// +// MountainListUseCase.swift +// SanTa +// +// Created by 김민창 on 2021/11/11. +// + +import Foundation + +final class MountainListUseCase { + +} From e6de9f084640097c6d89923b4421ee633b49481c Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:34:44 +0900 Subject: [PATCH 159/465] =?UTF-8?q?[Feat]=20#140,=20#143=20UseCase=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewRepository.swift | 8 ++------ .../MountainListViewUseCase.swift | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift index fec9ac4..049fb54 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift @@ -7,7 +7,7 @@ import Foundation -protocol MountainListViewReposiory { +protocol MountainListViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) } @@ -20,10 +20,6 @@ class DefaultMountainListViewReposiory { case notExists } - enum optionError: Error { - case notExists - } - private let mountainExtractor: MountainExtractor private let settingsStorage: UserDefaultsStorage @@ -33,7 +29,7 @@ class DefaultMountainListViewReposiory { } } -extension DefaultMountainListViewReposiory: MountainListViewReposiory { +extension DefaultMountainListViewReposiory: MountainListViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { self.mountainExtractor.extract { result in switch result { diff --git a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift index 0154e18..22e56e0 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift @@ -6,7 +6,24 @@ // import Foundation +import OSLog final class MountainListUseCase { + private let repository: MountainListViewRepository + init(repository: MountainListViewRepository) { + self.repository = repository + } + + func prepareMountainList(completion: @escaping ([MountainEntity]?) -> Void) { + self.repository.fetchMountains { result in + switch result { + case .failure(let error): + os_log(.error, log: .default, "\(error.localizedDescription)") + completion(nil) + case .success(let mountains): + completion(mountains) + } + } + } } From ed0cbfd41bb380c540282eaf8a68bbe68d71bdbe Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:39:12 +0900 Subject: [PATCH 160/465] =?UTF-8?q?[Feat]=20#140,=20#143=20ViewModel=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewModel.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift index ae254bf..75f2edd 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -8,5 +8,17 @@ import Combine final class MountainListViewModel { + @Published private(set) var mountains: [MountainEntity]? + private let useCase: MountainListUseCase + + init(useCase: MountainListUseCase) { + self.useCase = useCase + } + + func viewDidLoad() { + self.useCase.prepareMountainList { [weak self] mountains in + self?.mountains = mountains + } + } } From 17405a10453e8200c6fe229c0733f3c97addc795 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:43:12 +0900 Subject: [PATCH 161/465] =?UTF-8?q?[Feat]=20#140,=20#143=20Controller=20in?= =?UTF-8?q?it=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewController.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index a9a9d58..5a383f0 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -19,6 +19,8 @@ class MountainListViewController: UIViewController { var dataSource: MountainListDataSource? + private var viewModel: MountainListViewModel? + let mountainListCollectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -27,6 +29,11 @@ class MountainListViewController: UIViewController { return collectionView }() + convenience init(viewModel: MountainListViewModel) { + self.init() + self.viewModel = viewModel + } + override func viewDidLoad() { super.viewDidLoad() self.configureCollectionView() From 23ac73506d0293ea053a071ddf334a8bcd5fd2f8 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 14:54:40 +0900 Subject: [PATCH 162/465] =?UTF-8?q?[Feat]=20#140,=20#143=20Controller=20Bi?= =?UTF-8?q?nding=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Entities/MountainEntity.swift | 11 ++++++++++- .../MountainListViewController.swift | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/Entities/MountainEntity.swift b/SanTa/SanTa/Entities/MountainEntity.swift index 4fd417f..63b2ff5 100644 --- a/SanTa/SanTa/Entities/MountainEntity.swift +++ b/SanTa/SanTa/Entities/MountainEntity.swift @@ -7,7 +7,8 @@ import Foundation -struct MountainEntity: Codable { +struct MountainEntity: Codable, Hashable { + var id = UUID() struct MountainDetail: Codable { let mountainName, mountainRegion, mountainHeight, mountainShortDescription: String @@ -29,4 +30,12 @@ struct MountainEntity: Codable { case latitude = "latitude" case longitude = "longitude" } + + func hash(into hasher: inout Hasher) { + hasher.combine(id) + } + + static func == (lhs: MountainEntity, rhs: MountainEntity) -> Bool { + lhs.id == rhs.id + } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 5a383f0..b96eb57 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -6,6 +6,7 @@ // import UIKit +import Combine class MountainListViewController: UIViewController { enum MountainListSection: Int, CaseIterable { @@ -20,6 +21,7 @@ class MountainListViewController: UIViewController { var dataSource: MountainListDataSource? private var viewModel: MountainListViewModel? + private var subscriptions = Set() let mountainListCollectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() @@ -40,11 +42,10 @@ class MountainListViewController: UIViewController { self.configureView() self.configuareDataSource() self.configureData() - - self.bindSnapShotApply(section: MountainListSection.main, item: dummy) + self.configureBinding() } - func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { + private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { DispatchQueue.global().sync { guard var snapshot = dataSource?.snapshot() else { return } item.forEach { @@ -54,6 +55,16 @@ class MountainListViewController: UIViewController { } } + private func configureBinding() { + self.viewModel?.$mountains + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] mountains in + guard let mountains = mountains else { return } + self?.bindSnapShotApply(section: MountainListSection.main, item: mountains) + }) + .store(in: &self.subscriptions) + } + private func configureCollectionView() { self.mountainListCollectionView.delegate = self self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() From 7919451a8fd3106e2438a7471455f42b040d2baf Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:01:43 +0900 Subject: [PATCH 163/465] =?UTF-8?q?[Feat]=20#140,=20#143=20Coordinator=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 3 ++- .../MountainListViewCoordinator.swift | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 882ad90..ff541fd 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -58,7 +58,8 @@ class AppCoordinator: Coordinator { resultViewController.tabBarItem = secondItem resultViewController.tabBarItem.image = .init(systemName: "list.dash") - let mountainListViewCoordinator = MountainListViewCoordinator() + let mountainListViewCoordinator = MountainListViewCoordinator(userDefaultsStorage: self.userDefaultsStorage, + mountainExtractor: self.mountainExtractor) mountainListViewCoordinator.parentCoordinator = self childCoordinators.append(mountainListViewCoordinator) let mountainListViewController = mountainListViewCoordinator.startPush() diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 1e6ccdf..3c05658 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -10,17 +10,22 @@ import UIKit class MountainListViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] - var navigationController: UINavigationController + var navigationController: UINavigationController = UINavigationController() - init() { - self.navigationController = UINavigationController() + private let userDefaultsStorage: UserDefaultsStorage + private let mountainExtractor: MountainExtractor + + init(userDefaultsStorage: UserDefaultsStorage, + mountainExtractor: MountainExtractor) { + self.userDefaultsStorage = userDefaultsStorage + self.mountainExtractor = mountainExtractor } func start() { } func startPush() -> UINavigationController { - let mountainListViewController = MountainListViewController() + let mountainListViewController = MountainListViewController(viewModel: self.injectDependencies()) mountainListViewController.coordinator = self self.navigationController.setViewControllers([mountainListViewController], animated: true) self.navigationController.navigationBar.topItem?.title = "산 목록" @@ -28,3 +33,15 @@ class MountainListViewCoordinator: Coordinator { return navigationController } } + +extension MountainListViewCoordinator { + private func injectDependencies() -> MountainListViewModel { + return MountainListViewModel( + useCase: MountainListUseCase( + repository: DefaultMountainListViewReposiory( + mountainExtractor: self.mountainExtractor, + userDefaultsStorage: self.userDefaultsStorage))) + + } +} + From f8b3cc6e61f1f2b9726b9e207296150a93deb476 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:06:49 +0900 Subject: [PATCH 164/465] =?UTF-8?q?[Feat]=20#140,=20#141,=20#143=20?= =?UTF-8?q?=EC=82=B0=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/Mountain.swift | 23 -------------------- 1 file changed, 23 deletions(-) delete mode 100644 SanTa/SanTa/MountainListScene/Mountain.swift diff --git a/SanTa/SanTa/MountainListScene/Mountain.swift b/SanTa/SanTa/MountainListScene/Mountain.swift deleted file mode 100644 index 0558885..0000000 --- a/SanTa/SanTa/MountainListScene/Mountain.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// Mountain.swift -// SanTa -// -// Created by 김민창 on 2021/11/11. -// - -import Foundation - -struct Mountain: Hashable { - var id = UUID() - let name: String - let height: String - let location: String - - func hash(into hasher: inout Hasher) { - hasher.combine(id) - } - - static func == (lhs: Mountain, rhs: Mountain) -> Bool { - lhs.id == rhs.id - } -} From 22d5fac9cf0d592259f9bcec4b53900676864649 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:07:38 +0900 Subject: [PATCH 165/465] =?UTF-8?q?[Feat]=20#140,=20#141,=20#143=20Mountai?= =?UTF-8?q?n=20struct=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20MountainEntity?= =?UTF-8?q?=EB=A1=9C=20=EC=BD=94=EB=93=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ---- SanTa/SanTa/MountainListScene/MountainCell.swift | 8 ++++---- .../MountainListScene/MountainListViewController.swift | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 900da40..cfe5249 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -65,7 +65,6 @@ DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; - DAAF4D6A273CDBB300780DC8 /* Mountain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D69273CDBB300780DC8 /* Mountain.swift */; }; DAAF4D6C273CE02400780DC8 /* MountainListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */; }; DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */; }; DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; @@ -140,7 +139,6 @@ DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; - DAAF4D69273CDBB300780DC8 /* Mountain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mountain.swift; sourceTree = ""; }; DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewModel.swift; sourceTree = ""; }; DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewUseCase.swift; sourceTree = ""; }; DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; @@ -206,7 +204,6 @@ DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */, DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */, DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */, - DAAF4D69273CDBB300780DC8 /* Mountain.swift */, 985EEF62272FDA98002413D9 /* MountainCell.swift */, ); path = MountainListScene; @@ -472,7 +469,6 @@ 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, - DAAF4D6A273CDBB300780DC8 /* Mountain.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 3b49bd1..2eac8e0 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -68,9 +68,9 @@ final class MountainCell: UICollectionViewCell { NSLayoutConstraint.activate(locationConstrain) } - func update(mountain: Mountain) { - self.name.text = mountain.name - self.height.text = mountain.height - self.location.text = mountain.location + func update(mountain: MountainEntity) { + self.name.text = mountain.mountain.mountainName + self.height.text = mountain.mountain.mountainHeight + self.location.text = mountain.mountain.mountainRegion } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index b96eb57..7ee9d94 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -43,6 +43,7 @@ class MountainListViewController: UIViewController { self.configuareDataSource() self.configureData() self.configureBinding() + self.viewModel?.viewDidLoad() } private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { @@ -99,7 +100,7 @@ class MountainListViewController: UIViewController { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MountainCell.identifier, for: indexPath) as? MountainCell else { return UICollectionViewCell() } - guard let item = item as? Mountain else { return cell } + guard let item = item as? MountainEntity else { return cell } cell.update(mountain: item) return cell }) @@ -122,6 +123,3 @@ extension MountainListViewController: UICollectionViewDelegate { collectionView.deselectItem(at: indexPath, animated: true) } } - -let dummy = [Mountain(name: "백두산", height: "1000m", location: "북한"), - Mountain(name: "한라산", height: "2000m", location: "제주도")] From c3958f762df4140a20f0ec176b6b4fc46127be5d Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:12:53 +0900 Subject: [PATCH 166/465] =?UTF-8?q?[Feat]=20#140,=20#143=20Navigation=20Ba?= =?UTF-8?q?r=20Large=20Title=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20=ED=91=9C=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 2 +- SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 2eac8e0..067875a 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -70,7 +70,7 @@ final class MountainCell: UICollectionViewCell { func update(mountain: MountainEntity) { self.name.text = mountain.mountain.mountainName - self.height.text = mountain.mountain.mountainHeight + self.height.text = mountain.mountain.mountainHeight + " m" self.location.text = mountain.mountain.mountainRegion } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 3c05658..d5ebba2 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -29,6 +29,7 @@ class MountainListViewCoordinator: Coordinator { mountainListViewController.coordinator = self self.navigationController.setViewControllers([mountainListViewController], animated: true) self.navigationController.navigationBar.topItem?.title = "산 목록" + self.navigationController.navigationBar.prefersLargeTitles = true return navigationController } From e40134d54ef47987feede0ae2cc278a11cc9085d Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:27:11 +0900 Subject: [PATCH 167/465] [Feat] #147 SearchBarController Configure --- .../MountainListScene/MountainListViewController.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 7ee9d94..f9db307 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -38,6 +38,7 @@ class MountainListViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.configureSearchBar() self.configureCollectionView() self.configureView() self.configuareDataSource() @@ -46,6 +47,12 @@ class MountainListViewController: UIViewController { self.viewModel?.viewDidLoad() } + private func configureSearchBar() { + let searchController = UISearchController(searchResultsController: nil) + searchController.searchBar.placeholder = "검색" + self.navigationItem.searchController = searchController + } + private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { DispatchQueue.global().sync { guard var snapshot = dataSource?.snapshot() else { return } From fbef0817805ac78467de76f9ff784b9fcec7ab44 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:28:53 +0900 Subject: [PATCH 168/465] =?UTF-8?q?[Feat]=20#147=20Scroll=EC=9D=84=20?= =?UTF-8?q?=ED=95=B4=EB=8F=84=20SearchBar=EA=B0=80=20=EC=82=AC=EB=9D=BC?= =?UTF-8?q?=EC=A7=80=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainListViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index f9db307..4f7f04d 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -51,6 +51,7 @@ class MountainListViewController: UIViewController { let searchController = UISearchController(searchResultsController: nil) searchController.searchBar.placeholder = "검색" self.navigationItem.searchController = searchController + self.navigationItem.hidesSearchBarWhenScrolling = false } private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { From 8f127339bf4320c3de8148116e211c7b6143bc09 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:32:11 +0900 Subject: [PATCH 169/465] =?UTF-8?q?[Feat]=20#145=20searchResultsUpdater=20?= =?UTF-8?q?delegate=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewController.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 4f7f04d..29e9733 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -50,6 +50,8 @@ class MountainListViewController: UIViewController { private func configureSearchBar() { let searchController = UISearchController(searchResultsController: nil) searchController.searchBar.placeholder = "검색" + searchController.searchResultsUpdater = self + self.navigationItem.searchController = searchController self.navigationItem.hidesSearchBarWhenScrolling = false } @@ -131,3 +133,9 @@ extension MountainListViewController: UICollectionViewDelegate { collectionView.deselectItem(at: indexPath, animated: true) } } + +extension MountainListViewController: UISearchResultsUpdating { + func updateSearchResults(for searchController: UISearchController) { + + } +} From 57cc2e4bedde1d4d35d735a2e3fee0b018245aec Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 15:40:59 +0900 Subject: [PATCH 170/465] =?UTF-8?q?[Feat]=20#145=20UseCase=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=82=B0=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewModel.swift | 4 ++++ .../MountainListViewUseCase.swift | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift index 75f2edd..3d6aa34 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -21,4 +21,8 @@ final class MountainListViewModel { self?.mountains = mountains } } + + func findMountains(name: String) { + + } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift index 22e56e0..b5d99be 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift @@ -10,20 +10,35 @@ import OSLog final class MountainListUseCase { private let repository: MountainListViewRepository + private var entireMountains: [MountainEntity]? init(repository: MountainListViewRepository) { self.repository = repository } func prepareMountainList(completion: @escaping ([MountainEntity]?) -> Void) { + guard self.entireMountains == nil else { + completion(self.entireMountains) + return + } + self.repository.fetchMountains { result in switch result { case .failure(let error): os_log(.error, log: .default, "\(error.localizedDescription)") completion(nil) case .success(let mountains): + self.entireMountains = mountains completion(mountains) } } } + + func findMountains(name: String, completion: @escaping ([MountainEntity]?) -> Void) { + guard self.entireMountains == nil else { + return + } + + completion(entireMountains?.filter { $0.mountain.mountainName == name }) + } } From 382b511fdb84242280f0f9f49668cd1cec0b7999 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 16:24:11 +0900 Subject: [PATCH 171/465] =?UTF-8?q?[Feat]=20#141,=20#142,=20#145,=20#147?= =?UTF-8?q?=20Combine=20debounce=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewController.swift | 17 +++++++++++++---- .../MountainListViewModel.swift | 10 ++++++++-- .../MountainListViewUseCase.swift | 10 ++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 29e9733..0250266 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -57,12 +57,13 @@ class MountainListViewController: UIViewController { } private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { - DispatchQueue.global().sync { - guard var snapshot = dataSource?.snapshot() else { return } + DispatchQueue.main.async { [weak self] in + var snapshot = MountainListSnapshot() + snapshot.appendSections([.main]) item.forEach { snapshot.appendItems([$0], toSection: section) } - dataSource?.apply(snapshot, animatingDifferences: true) + self?.dataSource?.apply(snapshot, animatingDifferences: true) } } @@ -74,6 +75,13 @@ class MountainListViewController: UIViewController { self?.bindSnapShotApply(section: MountainListSection.main, item: mountains) }) .store(in: &self.subscriptions) + + self.viewModel?.$mountainName + .debounce(for: 0.7, scheduler: RunLoop.main) + .sink { [weak self] _ in + self?.viewModel?.findMountains() + } + .store(in: &subscriptions) } private func configureCollectionView() { @@ -136,6 +144,7 @@ extension MountainListViewController: UICollectionViewDelegate { extension MountainListViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { - + guard let mountainName = searchController.searchBar.text else { return } + self.viewModel?.mountainName = mountainName } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift index 3d6aa34..2ed0df8 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -9,8 +9,10 @@ import Combine final class MountainListViewModel { @Published private(set) var mountains: [MountainEntity]? + @Published var mountainName: String? private let useCase: MountainListUseCase + private var cancellables = Set() init(useCase: MountainListUseCase) { self.useCase = useCase @@ -22,7 +24,11 @@ final class MountainListViewModel { } } - func findMountains(name: String) { - + func findMountains() { + guard let name = mountainName else { return } + self.useCase.findMountains(name: name) { [weak self] mountains in + print(mountains) + self?.mountains = mountains + } } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift index b5d99be..e2b83e7 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift @@ -22,23 +22,25 @@ final class MountainListUseCase { return } - self.repository.fetchMountains { result in + self.repository.fetchMountains { [weak self] result in switch result { case .failure(let error): os_log(.error, log: .default, "\(error.localizedDescription)") completion(nil) case .success(let mountains): - self.entireMountains = mountains + self?.entireMountains = mountains completion(mountains) } } } func findMountains(name: String, completion: @escaping ([MountainEntity]?) -> Void) { - guard self.entireMountains == nil else { + guard self.entireMountains != nil else { return } + guard name.isEmpty != true else { + completion(self.entireMountains) return } - completion(entireMountains?.filter { $0.mountain.mountainName == name }) + completion(self.entireMountains?.filter { $0.mountain.mountainName == name }) } } From 0e99d9035c504ebd25c2de58c62423074c687c9c Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 16:25:58 +0900 Subject: [PATCH 172/465] =?UTF-8?q?[Refactor]=20ViewModel=20Print=EB=AC=B8?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainListViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift index 2ed0df8..7a140ab 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -27,7 +27,6 @@ final class MountainListViewModel { func findMountains() { guard let name = mountainName else { return } self.useCase.findMountains(name: name) { [weak self] mountains in - print(mountains) self?.mountains = mountains } } From fb80bacd4923a7fe63b7d175c02b8422df83cced Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 16:27:11 +0900 Subject: [PATCH 173/465] =?UTF-8?q?[Refactor]=20#141=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20Configure=20=EC=BD=94=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewController.swift | 9 --------- 1 file changed, 9 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 0250266..029f882 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -42,7 +42,6 @@ class MountainListViewController: UIViewController { self.configureCollectionView() self.configureView() self.configuareDataSource() - self.configureData() self.configureBinding() self.viewModel?.viewDidLoad() } @@ -126,14 +125,6 @@ class MountainListViewController: UIViewController { self.dataSource = datasource self.mountainListCollectionView.dataSource = dataSource } - - private func configureData() { - var snapshot = MountainListSnapshot() - MountainListSection.allCases.forEach { - snapshot.appendSections([$0]) - } - dataSource?.apply(snapshot, animatingDifferences: true) - } } extension MountainListViewController: UICollectionViewDelegate { From d6258cbdcd801dc23e8f6c3952ed8b9465486800 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 11 Nov 2021 16:49:22 +0900 Subject: [PATCH 174/465] =?UTF-8?q?[Feat]=20#128=20Repository=EA=B0=80=20C?= =?UTF-8?q?oreData=EC=97=90=EC=84=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20fetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Persistences/CoreDataRecordStorage.swift | 6 ++-- .../SanTa/ResultScene/ResultRepository.swift | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa/ResultScene/ResultRepository.swift diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index fb10cf3..fe0100c6 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -11,7 +11,7 @@ import CoreData protocol RecordsStorage { func save(records: Records, completion: @escaping (Result) -> Void) - func fetch(completion: @escaping (Result<[NSManagedObject], Error>) -> Void) + func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) } final class CoreDataRecordStorage: RecordsStorage { @@ -62,10 +62,10 @@ final class CoreDataRecordStorage: RecordsStorage { } } - func fetch(completion: @escaping (Result<[NSManagedObject], Error>) -> Void) { + func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) { self.coreDataStorage.performBackgroundTask { context in do { - let requset = NSFetchRequest(entityName: "Records") + let requset = NSFetchRequest(entityName: "RecordsEntity") let result = try context.fetch(requset) completion(.success(result)) } catch { diff --git a/SanTa/SanTa/ResultScene/ResultRepository.swift b/SanTa/SanTa/ResultScene/ResultRepository.swift new file mode 100644 index 0000000..e058cbf --- /dev/null +++ b/SanTa/SanTa/ResultScene/ResultRepository.swift @@ -0,0 +1,32 @@ +// +// ResultRepository.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/11. +// + +import Foundation + +protocol ResultRepository { + func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) +} + +final class DefaultResultRepository: ResultRepository { + + private let recordStorage: CoreDataRecordStorage + + init(recordStorage: CoreDataRecordStorage) { + self.recordStorage = recordStorage + } + + func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) { + self.recordStorage.fetch { result in + switch result { + case .success(let objects): + completion(.success(objects)) + case .failure(let error): + completion(.failure(error)) + } + } + } +} From abe725d9e64e99f91ec92681b9e074a6c3c6dfa7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 11 Nov 2021 17:35:06 +0900 Subject: [PATCH 175/465] =?UTF-8?q?[Feat]=20RecordingView=20Label=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EB=A7=9E=EC=B6=94=EA=B8=B0=20=EB=B0=8F=20?= =?UTF-8?q?RecordingTitleView=20=EB=8B=A4=ED=81=AC=20=EB=AA=A8=EB=93=9C=20?= =?UTF-8?q?=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController+Extension.swift | 1 + .../RecordingTitleViewController.swift | 2 +- .../Contents.json | 33 +++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/RecordingSubViewBackgroundColor.colorset/Contents.json diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index a245ac8..7f6f785 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -33,6 +33,7 @@ extension RecordingViewController { $0.textAlignment = .center $0.textColor = .white $0.translatesAutoresizingMaskIntoConstraints = false + $0.adjustsFontSizeToFitWidth = true } } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 55e7ff0..13de1aa 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -13,7 +13,7 @@ class RecordingTitleViewController: UIViewController { private var displayView: UIView = { let view = UIView() - view.backgroundColor = .white + view.backgroundColor = UIColor(named: "RecordingSubViewBackgroundColor") view.layer.masksToBounds = true view.layer.cornerRadius = 12 return view diff --git a/SanTa/SanTa/Resources/Assets.xcassets/RecordingSubViewBackgroundColor.colorset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/RecordingSubViewBackgroundColor.colorset/Contents.json new file mode 100644 index 0000000..1e4c78d --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/RecordingSubViewBackgroundColor.colorset/Contents.json @@ -0,0 +1,33 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "platform" : "ios", + "reference" : "systemGray6Color" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} From 03c003ecb23f03762a5a6d11a380369bac746935 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 11 Nov 2021 17:23:29 +0900 Subject: [PATCH 176/465] =?UTF-8?q?[Feat]=20#153=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultScene/ResultViewController.swift | 360 +++++++++++++++++- 1 file changed, 359 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index a22c124..a673db9 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -7,11 +7,369 @@ import UIKit +struct TopMain { + let distance = "42.195" + let count = "1" + let time = "02:30" + let steps = "99999" +} + +struct HeaderInfo { + let month = "2021. 11" + let count = "6회" + let distance = "31.084" + let time = "01:45" +} + +struct CellInfo { + let date = "어제(목) 오후 3시 46분" + let distance = "2.56" + let time = "03.01" + let altitude = "20" + let steps = "512" +} + +class TopMainCell: UICollectionViewCell { + static let identifier = "TopMainCell" + let kilometerNumber = UILabel() + let kilometer = UILabel() + let countNumber = UILabel() + let count = UILabel() + let timeNumber = UILabel() + let time = UILabel() + let stepsNumber = UILabel() + let steps = UILabel() + let horizontalStackView = UIStackView() + let countVerticalStackView = UIStackView() + let timeVerticalStackView = UIStackView() + let stepsVerticalStackView = UIStackView() + + func configure(distance: String, count: String, time: String, steps: String) { + self.configureSubviews() + self.configureLayout() + self.kilometerNumber.text = distance + self.kilometerNumber.font = .systemFont(ofSize: 60) + self.kilometer.text = "킬로미터" + self.kilometer.font = .systemFont(ofSize: 15) + self.countNumber.text = count + self.countNumber.font = .systemFont(ofSize: 25) + self.count.text = "횟수" + self.count.font = .systemFont(ofSize: 15) + self.timeNumber.text = time + self.timeNumber.font = .systemFont(ofSize: 25) + self.time.text = "시간" + self.time.font = .systemFont(ofSize: 15) + self.stepsNumber.text = steps + self.stepsNumber.font = .systemFont(ofSize: 25) + self.steps.text = "걸음" + self.steps.font = .systemFont(ofSize: 15) + self.backgroundColor = .systemGray6 + let border = CALayer() + border.frame = CGRect.init(x: 0, y: self.frame.height, width: self.frame.width, height: -1) + border.backgroundColor = UIColor.systemGray4.cgColor + self.layer.addSublayer(border) + } + + private func configureSubviews() { + self.addSubview(self.kilometerNumber) + self.addSubview(self.kilometer) + self.addSubview(self.horizontalStackView) + self.horizontalStackView.addArrangedSubview(countVerticalStackView) + self.horizontalStackView.addArrangedSubview(timeVerticalStackView) + self.horizontalStackView.addArrangedSubview(stepsVerticalStackView) + self.horizontalStackView.axis = .horizontal + self.horizontalStackView.distribution = .fillEqually + self.countVerticalStackView.axis = .vertical + self.countVerticalStackView.alignment = .center + self.countVerticalStackView.spacing = 5 + self.timeVerticalStackView.axis = .vertical + self.timeVerticalStackView.alignment = .center + self.timeVerticalStackView.spacing = 5 + self.stepsVerticalStackView.axis = .vertical + self.stepsVerticalStackView.alignment = .center + self.stepsVerticalStackView.spacing = 5 + self.countVerticalStackView.addArrangedSubview(countNumber) + self.countVerticalStackView.addArrangedSubview(count) + self.timeVerticalStackView.addArrangedSubview(timeNumber) + self.timeVerticalStackView.addArrangedSubview(time) + self.stepsVerticalStackView.addArrangedSubview(stepsNumber) + self.stepsVerticalStackView.addArrangedSubview(steps) + } + + private func configureLayout() { + self.kilometerNumber.translatesAutoresizingMaskIntoConstraints = false + self.kilometer.translatesAutoresizingMaskIntoConstraints = false + self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.kilometerNumber.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.kilometerNumber.topAnchor.constraint(equalTo: self.topAnchor, constant: 60), + self.kilometer.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.kilometer.topAnchor.constraint(equalTo: self.kilometerNumber.bottomAnchor, constant: 0), + self.horizontalStackView.topAnchor.constraint(equalTo: self.kilometer.bottomAnchor, constant: 50), + self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.horizontalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) + ]) + } +} + +class Header: UICollectionReusableView { + static let identifier = "header" + let monthLabel = UILabel() + let countLabel = UILabel() + let distanceLabel = UILabel() + let timeLabel = UILabel() + + func configure(month: String, count: String, distance: String, time: String){ + self.backgroundColor = .white + self.monthLabel.text = month + self.monthLabel.font = .boldSystemFont(ofSize: 17) + self.countLabel.text = count + self.countLabel.font = .systemFont(ofSize: 15) + self.countLabel.textColor = .systemGray + self.distanceLabel.text = distance + self.distanceLabel.font = .systemFont(ofSize: 15) + self.distanceLabel.textColor = .systemGray + self.timeLabel.text = time + self.timeLabel.font = .systemFont(ofSize: 15) + self.timeLabel.textColor = .systemGray + self.configureSubviews() + self.configureLayout() + } + + private func configureSubviews(){ + self.addSubview(monthLabel) + self.addSubview(countLabel) + self.addSubview(distanceLabel) + self.addSubview(timeLabel) + self.monthLabel.translatesAutoresizingMaskIntoConstraints = false + self.countLabel.translatesAutoresizingMaskIntoConstraints = false + self.distanceLabel.translatesAutoresizingMaskIntoConstraints = false + self.timeLabel.translatesAutoresizingMaskIntoConstraints = false + } + + private func configureLayout() { + NSLayoutConstraint.activate([ + self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), + self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.distanceLabel.rightAnchor.constraint(equalTo: self.timeLabel.leftAnchor, constant: -10), + self.countLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10) + ]) + } +} + +class MyCollectionViewCell: UICollectionViewCell { + static let identifier = "MyCollectionViewCell" + let date = PaddingLabel() + let horizontalStackView = UIStackView() + let distanceStackView = UIStackView() + let distance = UILabel() + let distanceLabel = UILabel() + let timeStackView = UIStackView() + let time = UILabel() + let timeLabel = UILabel() + let altitudeStackView = UIStackView() + let altitude = UILabel() + let altitudeLabel = UILabel() + let stepsStackView = UIStackView() + let steps = UILabel() + let stepsLabel = UILabel() + + func configure(date: String, distance: String, time: String, altitude: String, steps: String) { + self.date.padding(top: 2, bottom: 2, left: 2, right: 2) + self.date.text = date + self.date.backgroundColor = UIColor.init(red: 0.50, green: 0.8, blue: 0.37, alpha: 1) + self.date.layer.cornerRadius = 3 + self.date.clipsToBounds = true + self.date.textColor = .white + self.date.font = .boldSystemFont(ofSize: 13) + self.distance.text = distance + self.distance.font = .boldSystemFont(ofSize: 20) + self.distanceLabel.text = "거리" + self.time.text = time + self.time.font = .boldSystemFont(ofSize: 20) + self.timeLabel.text = "시간" + self.altitude.text = altitude + self.altitude.font = .boldSystemFont(ofSize: 20) + self.altitudeLabel.text = "고도차" + self.steps.text = steps + self.steps.font = .boldSystemFont(ofSize: 20) + self.stepsLabel.text = "걸음" + self.configureSubviews() + self.configureLayout() + } + + private func configureSubviews() { + self.addSubview(date) + self.addSubview(horizontalStackView) + self.horizontalStackView.distribution = .fillEqually + self.horizontalStackView.axis = .horizontal + self.distanceStackView.axis = .vertical + self.distanceStackView.alignment = .center + self.timeStackView.axis = .vertical + self.timeStackView.alignment = .center + self.altitudeStackView.axis = .vertical + self.altitudeStackView.alignment = .center + self.stepsStackView.axis = .vertical + self.stepsStackView.alignment = .center + self.horizontalStackView.addArrangedSubview(distanceStackView) + self.horizontalStackView.addArrangedSubview(timeStackView) + self.horizontalStackView.addArrangedSubview(altitudeStackView) + self.horizontalStackView.addArrangedSubview(stepsStackView) + self.distanceStackView.spacing = 5 + self.distanceStackView.addArrangedSubview(distance) + self.distanceStackView.addArrangedSubview(distanceLabel) + self.timeStackView.spacing = 5 + self.timeStackView.addArrangedSubview(time) + self.timeStackView.addArrangedSubview(timeLabel) + self.altitudeStackView.spacing = 5 + self.altitudeStackView.addArrangedSubview(altitude) + self.altitudeStackView.addArrangedSubview(altitudeLabel) + self.stepsStackView.spacing = 5 + self.stepsStackView.addArrangedSubview(steps) + self.stepsStackView.addArrangedSubview(stepsLabel) + } + + private func configureLayout() { + self.date.translatesAutoresizingMaskIntoConstraints = false + self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.date.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.date.topAnchor.constraint(equalTo: self.topAnchor, constant: 15), + self.horizontalStackView.topAnchor.constraint(greaterThanOrEqualTo: self.date.bottomAnchor, constant: 10), + self.horizontalStackView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -15), + self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) + ]) + } +} + class ResultViewController: UIViewController { weak var coordinator: ResultViewCoordinator? + + private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: ResultViewController.createCompositionalLayout()) + private let topMain = TopMain() + private let headerInfo = HeaderInfo() + private let cellInfo = CellInfo() override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .green + view.addSubview(collectionView) + self.navigationController?.navigationBar.isHidden = true + self.navigationController?.navigationBar.topItem?.title = topMain.distance + "km" + collectionView.register(TopMainCell.self, forCellWithReuseIdentifier: TopMainCell.identifier) + collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: MyCollectionViewCell.identifier) + collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: Header.identifier) + collectionView.frame = view.bounds + collectionView.delegate = self + collectionView.dataSource = self + } + + private static func createCompositionalLayout() -> UICollectionViewCompositionalLayout { + return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + switch sectionNumber { + case 0: return ResultViewController.firstLayoutSection() + default: return ResultViewController.secondLayoutSection() + } + } + } + + private static func firstLayoutSection() -> NSCollectionLayoutSection { + let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(300)) + let item = NSCollectionLayoutItem(layoutSize: itemSize) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(300)) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1) + let section = NSCollectionLayoutSection(group: group) + return section + } + + private static func secondLayoutSection() -> NSCollectionLayoutSection { + let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(130)) + let item = NSCollectionLayoutItem(layoutSize: itemSize) + item.contentInsets = .init(top: 3, leading: 10, bottom: 13, trailing: 10) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(130)) + let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1) + group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + let section = NSCollectionLayoutSection(group: group) + + let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) + let header = NSCollectionLayoutBoundarySupplementaryItem( + layoutSize: headerSize, + elementKind: UICollectionView.elementKindSectionHeader, + alignment: .top + ) + header.pinToVisibleBounds = true + section.boundarySupplementaryItems = [header] + + return section + } +} + +extension ResultViewController: UICollectionViewDataSource { + func numberOfSections(in collectionView: UICollectionView) -> Int { + return 3 + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + switch section { + case 0: return 1 + case 1: return 6 + case 2: return 6 + default : return 0 + } + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + switch indexPath.section { + case 0: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: TopMainCell.identifier, + for: indexPath + ) as? TopMainCell else { + return UICollectionViewCell() + } + cell.configure(distance: topMain.distance, count: topMain.count, time: topMain.time, steps: topMain.steps) + return cell + default: + guard let cell = collectionView.dequeueReusableCell( + withReuseIdentifier: MyCollectionViewCell.identifier, + for: indexPath + ) as? MyCollectionViewCell else { + return UICollectionViewCell() + } + cell.layer.cornerRadius = 10 + cell.backgroundColor = .white + cell.layer.shadowColor = UIColor.gray.cgColor + cell.layer.shadowRadius = 2 + cell.layer.shadowOpacity = 0.8 + cell.layer.shadowOffset = CGSize(width: 0, height: 0.5) + cell.configure(date: cellInfo.date, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitude, steps: cellInfo.steps) + return cell + } + } + + func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { + guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Header.identifier, for: indexPath) as? Header else { + return UICollectionReusableView() + } + header.configure(month: headerInfo.month, count: headerInfo.count, distance: headerInfo.distance, time: headerInfo.time) + return header + } +} + +extension ResultViewController: UICollectionViewDelegate { + func scrollViewDidScroll(_ scrollView: UIScrollView) { + guard let navigationBar = self.navigationController?.navigationBar else { return } + let navigationBarChangePointY = 100.0 + if scrollView.contentOffset.y > navigationBarChangePointY { + navigationBar.isHidden = false + navigationBar.layer.opacity = Float(0.05 * (scrollView.contentOffset.y - navigationBarChangePointY)) + } else { + navigationBar.isHidden = true + } } } From dfb51475072f3bccaee635e8a35f8b8a73b67927 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Fri, 12 Nov 2021 17:18:20 +0900 Subject: [PATCH 177/465] =?UTF-8?q?[Feat]=20#152=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=ED=86=B5=ED=95=9C=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 119 +++++++++++++++++- .../SanTa/RecordingScene/RecordingModel.swift | 2 +- 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 0533436..30cbcd6 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -7,13 +7,117 @@ import Foundation +class TotalRecords { + private(set) var totalRecords: [DateSeperateRecords] = [] + + private var mappingDateSeperateRecords: [String : DateSeperateRecords] = [:] + + var totalDistances: Double { + return totalRecords.reduce(0) { $0 + $1.distances } + } + + var count: Int { + return totalRecords.count + } + + var totalTimes: Double { + return totalRecords.reduce(0) { $0 + $1.times } + } + + var totalSteps: Int { + return totalRecords.reduce(0) { $0 + $1.steps } + } + + subscript(section: Int, item: Int) -> Records? { + guard self.count > section && totalRecords[section].count > item else { return nil } + return totalRecords[section].dateSeperateRecords[item] + } + + func add(records: Records) { + guard let year = records.year else { return } + guard let month = records.month else { return } + let key = "\(year)\(month)" + + if let seperateDateRecords = self.mappingDateSeperateRecords[key] { + seperateDateRecords.add(records: records) + } else { + let seperateDateRecords = DateSeperateRecords(year: year, month: month) + seperateDateRecords.add(records: records) + self.mappingDateSeperateRecords[key] = seperateDateRecords + self.totalRecords.append(seperateDateRecords) + } + } +} + +class DateSeperateRecords { + let year: Int + let month: Int + + private(set) var dateSeperateRecords: [Records] = [] + + init(year: Int, month: Int) { + self.year = year + self.month = month + } + + var distances: Double { + return dateSeperateRecords.reduce(0) { $0 + $1.distances } + } + + var count: Int { + return dateSeperateRecords.count + } + + var times: Double { + return dateSeperateRecords.reduce(0) { $0 + $1.times } + } + + var steps: Int { + return dateSeperateRecords.reduce(0) { $0 + $1.steps } + } + + func add(records: Records) { + self.dateSeperateRecords.append(records) + } +} + + struct Records { - var title: String - var records: [Record] + private(set) var title: String + private(set) var records: [Record] + + var year: Int? { + return records.isEmpty ? nil : Calendar.current.component(.year, from: records[0].startTime) + } + + var month: Int? { + return records.isEmpty ? nil : Calendar.current.component(.month, from: records[0].startTime) + } + + var distances: Double { + return records.reduce(0) { $0 + $1.distance } + } + + var times: Double { + return records.reduce(0) { $0 + $1.time } + } + + var steps: Int { + return records.reduce(0) { $0 + $1.step } + } + + var maxAltitudeDifference: Double { + let max = records.max { $0.altitudeDifference < $1.altitudeDifference } + return (max?.altitudeDifference ?? 0) + } mutating func configureTitle(title: String) { self.title = title } + + mutating func add(record: Record) { + self.records.append(record) + } } struct Record { @@ -21,8 +125,17 @@ struct Record { let endTime: Date let step: Int let distance: Double - let locations: [Location] + + var time: TimeInterval { + return endTime.timeIntervalSinceReferenceDate - startTime.timeIntervalSinceReferenceDate + } + + var altitudeDifference: Double { + let min = locations.min { $0.altitude < $1.altitude } + let max = locations.max { $0.altitude < $1.altitude } + return (max?.altitude ?? 0) - (min?.altitude ?? 0) + } } struct Location { diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 198e3fe..39ffcf1 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -154,7 +154,7 @@ final class RecordingModel: NSObject, ObservableObject { return } - self.records?.records.append(record) + self.records?.add(record: record) } func pause() { From 6818220afa15be1629bd3e2255483868272d17d2 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Fri, 12 Nov 2021 17:19:13 +0900 Subject: [PATCH 178/465] =?UTF-8?q?[Feat]=20#152=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=EB=A7=8C=EB=93=A4=EC=96=B4=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC=ED=95=98=EB=8A=94=20UseCase=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 ++ .../Persistences/CoreDataRecordStorage.swift | 4 +- .../SanTa.xcdatamodel/contents | 2 +- SanTa/SanTa/ResultScene/ResultUseCase.swift | 78 +++++++++++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa/ResultScene/ResultUseCase.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 35af3ca..30dfaf0 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -40,6 +40,8 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; + 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821C273CB45D006A847A /* ResultRepository.swift */; }; + 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821E273CE16E006A847A /* ResultUseCase.swift */; }; 9826F3DD2739035E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 9826F3DF273904010064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; 9826F436273954020064FA85 /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */; }; @@ -115,6 +117,8 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9800821C273CB45D006A847A /* ResultRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultRepository.swift; sourceTree = ""; }; + 9800821E273CE16E006A847A /* ResultUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultUseCase.swift; sourceTree = ""; }; 9826F3DC2739035E0064FA85 /* Option.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = ""; }; 9826F3DE273904010064FA85 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelTests.swift; sourceTree = ""; }; @@ -178,6 +182,8 @@ children = ( 5429694C272FC1390070B362 /* ResultViewController.swift */, 5429694E272FC1740070B362 /* ResultViewCoordinator.swift */, + 9800821E273CE16E006A847A /* ResultUseCase.swift */, + 9800821C273CB45D006A847A /* ResultRepository.swift */, ); path = ResultScene; sourceTree = ""; @@ -471,7 +477,9 @@ 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, + 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, + 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index fe0100c6..d777f82 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -65,8 +65,8 @@ final class CoreDataRecordStorage: RecordsStorage { func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) { self.coreDataStorage.performBackgroundTask { context in do { - let requset = NSFetchRequest(entityName: "RecordsEntity") - let result = try context.fetch(requset) + let request = NSFetchRequest(entityName: "RecordsEntity") + let result = try context.fetch(request) completion(.success(result)) } catch { completion(.failure(error)) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index f8c8289..5209325 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -20,7 +20,7 @@ - + \ No newline at end of file diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift new file mode 100644 index 0000000..3f7bc99 --- /dev/null +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -0,0 +1,78 @@ +// +// ResultUseCase.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/11. +// + +import Foundation +import OSLog + +protocol ResultUseCase { + func fetch(completion: @escaping (TotalRecords?) -> Void) +} + + +final class DefaultResultUseCase { + + private let resultRepository: ResultRepository + + init(resultRepository: ResultRepository) { + self.resultRepository = resultRepository + } + + func fetch(completion: @escaping (TotalRecords?) -> Void) { + self.resultRepository.fetch { result in + switch result { + case .success(let objects): + let totalRecords = self.makeTotalRecords(objects: objects) + completion(totalRecords) + case .failure(let error): + os_log(.error, log: .default, "\(error.localizedDescription)") + completion(nil) + } + } + } + + private func makeTotalRecords(objects: [RecordsEntityMO]) -> TotalRecords { + let totalRecords = TotalRecords() + objects.reversed().forEach { + guard let records = self.makeRecords(recordsEntityMO: $0) else { return } + totalRecords.add(records: records) + } + return totalRecords + } + + private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { + guard let title = recordsEntityMO.title else { return nil } + var records: [Record] = [] + recordsEntityMO.records?.forEach { + guard let recordEntityMO = $0 as? RecordEntityMO else { return } + guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } + records.append(record) + } + return Records(title: title, records: records) + } + + private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { + guard let startTime = recordEntityMO.startTime else { return nil } + guard let endTime = recordEntityMO.endTime else { return nil } + let step = Int(recordEntityMO.step) + let distance = recordEntityMO.distance + + var locations: [Location] = [] + recordEntityMO.locations?.forEach{ + guard let locationEntityMO = $0 as? LocationEntityMO else { return } + let location = Location(latitude: locationEntityMO.latitude, + longitude: locationEntityMO.longitude, + altitude: locationEntityMO.altitude) + locations.append(location) + } + return Record(startTime: startTime, + endTime: endTime, + step: step, + distance: distance, + locations: locations) + } +} + From 1ea2cfdd7dcfb9a58e04e50cf04446b4968858f4 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Sun, 14 Nov 2021 15:19:41 +0900 Subject: [PATCH 179/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EC=A0=95=EB=B3=B4=EC=B0=BD=20?= =?UTF-8?q?=ED=99=95=EB=8C=80/=EC=B6=95=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 ++ .../ResultDetailLargerInfoView.swift | 33 ++++++++ .../ResultDetailSmallerInfoView.swift | 14 ++-- .../ResultDetailViewController 2.swift | 43 ++++++++++ .../ResultDetailViewController.swift | 78 ++++++++++++------- 5 files changed, 141 insertions(+), 33 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index bc4c2fa..0c0dd10 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; + 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */; }; @@ -84,6 +85,7 @@ /* Begin PBXFileReference section */ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; + 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewController.swift; sourceTree = ""; }; @@ -192,6 +194,7 @@ children = ( 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, + 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -462,6 +465,7 @@ 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, + 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, @@ -661,6 +665,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = B3PWYBKFUK; @@ -691,6 +696,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = B3PWYBKFUK; diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift new file mode 100644 index 0000000..4b6d069 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -0,0 +1,33 @@ +// +// DetailInfoView.swift +// SwipeView +// +// Created by Jiwon Yoon on 2021/11/11. +// + +import UIKit + +class ResultDetailLargerInfoView: UIView { + + override init(frame: CGRect) { + super.init(frame: frame) + self.backgroundColor = .green + } + + init() { + super.init(frame: .zero) + self.backgroundColor = .red + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + /* + // Only override draw() if you perform custom drawing. + // An empty implementation adversely affects performance during animation. + override func draw(_ rect: CGRect) { + // Drawing code + } + */ + +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 5e1fff4..6652566 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -1,8 +1,8 @@ // -// ResultDetailSmallerInfoView.swift -// SanTa +// SwipeViewBefore.swift +// SwipeView // -// Created by Jiwon Yoon on 2021/11/11. +// Created by Jiwon Yoon on 2021/11/10. // import UIKit @@ -29,9 +29,13 @@ class ResultDetailSmallerInfoView: UIView { init() { - super.init(frame: CGRect.zero) + super.init(frame: .zero) + self.layout() + } + + override init(frame: CGRect) { + super.init(frame: frame) self.layout() - print("layout swipeview") } required init?(coder: NSCoder) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift new file mode 100644 index 0000000..aceade8 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift @@ -0,0 +1,43 @@ +// +// ResultDetailViewController.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/10. +// + +/* + func addPolylineToMap(locations: [CLLocation]) { + let coordinates = locations.map { $0.coordinate } + let geodesic = MKGeodesicPolyline(coordinates: coordinates, count: coordinates.count) + mapView.add(geodesic) + } + */ + +import UIKit +import MapKit + +class ResultDetailViewController: UIViewController { + + private let mapView = MKMapView() + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } +} + +extension ResultDetailViewController { + private func layoutResultDetailView() { + self.view.addSubview(mapView) + mapView.translatesAutoresizingMaskIntoConstraints = false + + let mapViewConstraints = [ + mapView.topAnchor.constraint(equalTo: self.view.topAnchor), + mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + mapView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.65) + ] + NSLayoutConstraint.activate(mapViewConstraints) + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 0f1d688..5875b06 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -1,48 +1,70 @@ // -// ResultDetailViewController.swift -// SanTa +// ViewController.swift +// SwipeView // -// Created by Jiwon Yoon on 2021/11/11. +// Created by Jiwon Yoon on 2021/11/10. // import UIKit import MapKit class ResultDetailViewController: UIViewController { - private let mapView = MKMapView() - private let miniInfoView = ResultDetailSmallerInfoView() + private var mapView: MKMapView? + private var infoView: UIView? override func viewDidLoad() { super.viewDidLoad() - self.layout() - // Do any additional setup after loading the view. + self.layoutInitialRecordDetailView() + self.registerRecognizers() } } extension ResultDetailViewController { - private func layout() { - self.view.addSubview(self.mapView) - self.mapView.translatesAutoresizingMaskIntoConstraints = false + private func registerRecognizers() { + let swipeDownRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showSmallInfoView)) + swipeDownRecognizer.direction = .down + self.infoView?.addGestureRecognizer(swipeDownRecognizer) - let mapViewConstraints = [ - mapView.topAnchor.constraint(equalTo: self.view.topAnchor), - mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - mapView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.75) - ] - NSLayoutConstraint.activate(mapViewConstraints) - - self.view.addSubview(self.miniInfoView) - self.miniInfoView.translatesAutoresizingMaskIntoConstraints = false + let swipeUpRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showLargeInfoView)) + swipeUpRecognizer.direction = .up + self.infoView?.addGestureRecognizer(swipeUpRecognizer) + } + + private func layoutInitialRecordDetailView() { + let mapFrame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height * 0.75) + self.mapView = MKMapView(frame: mapFrame) + if let mapView = self.mapView { self.view.addSubview(mapView) } - let swipeViewConstraints = [ - miniInfoView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), - miniInfoView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - miniInfoView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - miniInfoView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) - ] - miniInfoView.backgroundColor = .red - NSLayoutConstraint.activate(swipeViewConstraints) + self.infoView = UIView(frame: CGRect(x: 0, y: self.view.bounds.height * 0.75, width: self.view.bounds.width, height: self.view.bounds.height * 0.25)) + if let infoView = self.infoView { + self.view.addSubview(infoView) + infoView.addSubview(ResultDetailSmallerInfoView(frame: infoView.bounds)) + } + } +} + +extension ResultDetailViewController { + @objc private func showLargeInfoView() { + self.infoView?.subviews.forEach { $0.removeFromSuperview() } + let newY = self.view.bounds.height * 0.1 + let newHeight = self.view.bounds.height * 0.9 + self.mapView?.isUserInteractionEnabled = false + UIView.animate(withDuration: 0.25) { + self.infoView?.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) + } + self.infoView?.addSubview(ResultDetailLargerInfoView(frame: self.infoView?.bounds ?? CGRect.zero)) } + @objc private func showSmallInfoView() { + self.infoView?.subviews.forEach { $0.removeFromSuperview() } + let newY = self.view.bounds.height * 0.75 + let newHeight = self.view.bounds.height * 0.25 + self.mapView?.isUserInteractionEnabled = true + UIView.animate(withDuration: 0.25) { + self.infoView?.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) + } + self.infoView?.addSubview(ResultDetailSmallerInfoView(frame: self.infoView?.bounds ?? CGRect.zero)) + } } + + From b04cca4a2e058de64edd136b56a5bc3b5aadc188 Mon Sep 17 00:00:00 2001 From: MinChang Date: Sun, 14 Nov 2021 18:52:05 +0900 Subject: [PATCH 180/465] =?UTF-8?q?[Feat]=20#158=20Coordinator,=20ViewCont?= =?UTF-8?q?roller=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20Coordinator=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 ++++++++ .../RecordingPhotoCoordinator.swift | 37 +++++++++++++++++++ .../RecordingPhotoViewController.swift | 18 +++++++++ 3 files changed, 71 insertions(+) create mode 100644 SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift create mode 100644 SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 6e6644c..a62fcdf 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -74,6 +74,8 @@ DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; + DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; + DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -152,6 +154,8 @@ DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; + DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; + DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -337,6 +341,7 @@ 5428FDB6272F8B2B002F9D40 /* ResultScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, + DAFA9B55274112AB00BF168C /* RecordingPhotoScene */, 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB9272F8BD9002F9D40 /* MountainListScene */, 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, @@ -363,6 +368,15 @@ path = RecordingTitleScene; sourceTree = ""; }; + DAFA9B55274112AB00BF168C /* RecordingPhotoScene */ = { + isa = PBXGroup; + children = ( + DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */, + DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */, + ); + path = RecordingPhotoScene; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -478,8 +492,10 @@ DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, + DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, + DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift new file mode 100644 index 0000000..3a78394 --- /dev/null +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift @@ -0,0 +1,37 @@ +// +// RecordingPhotoCoordinator.swift +// SanTa +// +// Created by 김민창 on 2021/11/14. +// + +import UIKit + +class RecordingPhotoViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var childCoordinators: [Coordinator] = [] + var recordingPhotoViewController: RecordingPhotoViewController + + init(delegate: RecordingViewDelegate) { + self.recordingPhotoViewController = RecordingPhotoViewController() + self.recordingPhotoViewController.delegate = delegate + self.recordingPhotoViewController.coordinator = self + } + + func start() { + guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + + recordingCoordinator.recordingViewController.present(recordingPhotoViewController, animated: true) + } + + func dismiss() { + guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + + recordingCoordinator.recordingViewController.dismiss(animated: true) + self.parentCoordinator?.childCoordinators.removeLast() + } + + deinit { + print("😇RecordingPhotoViewCoordinator is deinit \(Date())!!😇") + } +} diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift new file mode 100644 index 0000000..8bf97eb --- /dev/null +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -0,0 +1,18 @@ +// +// RecordingPhotoViewController.swift +// SanTa +// +// Created by 김민창 on 2021/11/14. +// + +import UIKit + +class RecordingPhotoViewController: UIViewController { + weak var coordinator: RecordingPhotoViewCoordinator? + weak var delegate: RecordingViewDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + } +} From ccfa55b541e5dec3ee084f861db792064599b968 Mon Sep 17 00:00:00 2001 From: MinChang Date: Sun, 14 Nov 2021 19:02:47 +0900 Subject: [PATCH 181/465] =?UTF-8?q?[Feat]=20#158=20ViewController=20View?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index 8bf97eb..1c874e2 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -10,6 +10,49 @@ import UIKit class RecordingPhotoViewController: UIViewController { weak var coordinator: RecordingPhotoViewCoordinator? weak var delegate: RecordingViewDelegate? + + private var displayView: UIView = { + let view = UIView() + view.backgroundColor = UIColor(named: "RecordingSubViewBackgroundColor") + view.layer.masksToBounds = true + view.layer.cornerRadius = 12 + return view + }() + + private let recordingPhotoImage: UIImageView = { + let image = UIImageView() + image.image = UIImage(systemName: "camera.fill") + image.translatesAutoresizingMaskIntoConstraints = false + return image + }() + + private let recordingPhotoTitle: UILabel = { + let label = UILabel() + label.text = "사진 기록하기" + label.font = .preferredFont(forTextStyle: .headline) + label.textColor = .systemGray + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let recordingPhotoDescription: UILabel = { + let label = UILabel() + label.text = "사진을 찍으면 지도에 표시됩니다." + label.font = .preferredFont(forTextStyle: .body) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let agreeButton: UIButton = { + let button = UIButton() + button.backgroundColor = .systemBlue + button.setTitle("허용하기", for: .normal) + button.setTitleColor(.white, for: .normal) + button.layer.masksToBounds = true + button.layer.cornerRadius = 6 + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() override func viewDidLoad() { super.viewDidLoad() From 3e720e48aab0933b6f7c74b42c6ed50a9f42e3d8 Mon Sep 17 00:00:00 2001 From: MinChang Date: Sun, 14 Nov 2021 19:08:45 +0900 Subject: [PATCH 182/465] =?UTF-8?q?[Feat]=20#158=20stackView=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EB=B0=8F=20Constraints=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index 1c874e2..769318b 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -53,9 +53,63 @@ class RecordingPhotoViewController: UIViewController { button.translatesAutoresizingMaskIntoConstraints = false return button }() + + private let photoStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 12 + stackView.axis = .vertical + stackView.distribution = .fillEqually + stackView.alignment = .center + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() override func viewDidLoad() { super.viewDidLoad() - + + self.configureConstraints() + } + + private func configureConstraints() { + let frameWidth = view.frame.width + let frameHeight = view.frame.height + + self.displayView.frame = CGRect(x: 6, y: frameHeight - frameHeight/2, width: frameWidth - 12, height: frameHeight/3) + + [self.recordingPhotoTitle, self.recordingPhotoImage, self.recordingPhotoDescription, self.agreeButton].forEach { + self.photoStackView.addArrangedSubview($0) + } + + self.view.addSubview(displayView) + self.displayView.addSubview(photoStackView) + + let recordingPhotoTitleConstraints = [ + self.recordingPhotoTitle.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let recordingPhotoImageConstraints = [ + self.recordingPhotoImage.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let recordingPhotoDescriptionText = [ + self.recordingPhotoDescription.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let agreeButtonConstraints = [ + self.agreeButton.widthAnchor.constraint(equalToConstant: frameWidth - 12) + ] + + let titleStackViewConstraints = [ + self.photoStackView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 16), + self.photoStackView.leadingAnchor.constraint(equalTo: self.displayView.leadingAnchor, constant: 16), + self.photoStackView.trailingAnchor.constraint(equalTo: self.displayView.trailingAnchor, constant: -16), + self.photoStackView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -16) + ] + + NSLayoutConstraint.activate(recordingPhotoTitleConstraints) + NSLayoutConstraint.activate(recordingPhotoImageConstraints) + NSLayoutConstraint.activate(recordingPhotoDescriptionText) + NSLayoutConstraint.activate(agreeButtonConstraints) + NSLayoutConstraint.activate(titleStackViewConstraints) } } From 5bbc5db0e6c40c03e0cfa5cf0b86963b2a5fbfeb Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 15 Nov 2021 12:22:18 +0900 Subject: [PATCH 183/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=9D=BC=EB=B2=A8=20padding,=20=EC=A0=9C?= =?UTF-8?q?=EB=AA=A9=EB=B7=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 + .../MountainDetailCategoryLabel.swift | 29 + .../MountainDetailTableViewCell.swift | 8 +- .../MountainDetailTitleView.swift | 24 +- .../MountainDetailViewController.swift | 2 +- .../Contents.json | 2 +- ...ithLocation2.json => UniqueMountains.json} | 10884 +++++++--------- 7 files changed, 4912 insertions(+), 6041 deletions(-) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift rename SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/{MountainsWithLocation2.json => UniqueMountains.json} (88%) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 5ce02fb..2d76ef5 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; + 49450A4D274205040062CD51 /* MountainDetailCategoryLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; @@ -90,6 +91,7 @@ /* Begin PBXFileReference section */ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; + 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailCategoryLabel.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; @@ -233,6 +235,7 @@ 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, + 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -479,6 +482,7 @@ 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, + 49450A4D274205040062CD51 /* MountainDetailCategoryLabel.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */, diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift new file mode 100644 index 0000000..f7edea7 --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift @@ -0,0 +1,29 @@ +// +// MountainDetailCategoryLabel.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/15. +// 출처: https://ios-development.tistory.com/698 + +import UIKit + +class MountainDetailCategoryLabel: UILabel { + private var defaultPadding = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3) + + convenience init(padding: UIEdgeInsets) { + self.init() + self.defaultPadding = padding + } + + override func drawText(in rect: CGRect) { + super.drawText(in: rect.inset(by: defaultPadding)) + } + + override var intrinsicContentSize: CGSize { + var contentSize = super.intrinsicContentSize + contentSize.height += defaultPadding.top + defaultPadding.bottom + contentSize.width += defaultPadding.left + defaultPadding.right + + return contentSize + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index 31990b9..f82db85 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -10,7 +10,7 @@ import UIKit class MountainDetailTableViewCell: UITableViewCell { static let identifier = "MountainDetailTableViewCellID" - let categoryLabel = UILabel() + let categoryLabel = MountainDetailCategoryLabel() let contentLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { @@ -24,11 +24,15 @@ class MountainDetailTableViewCell: UITableViewCell { } private func setLayout() { - categoryLabel.backgroundColor = .green + categoryLabel.backgroundColor = .init(named: "SantaColor") categoryLabel.textColor = .white + categoryLabel.clipsToBounds = true + categoryLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold) + categoryLabel.layer.cornerRadius = 5 contentLabel.numberOfLines = 0 contentLabel.lineBreakMode = .byCharWrapping + contentLabel.font = UIFont.systemFont(ofSize: 15, weight: .regular) categoryLabel.translatesAutoresizingMaskIntoConstraints = false contentLabel.translatesAutoresizingMaskIntoConstraints = false diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift index f717e1a..69d1f4e 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift @@ -15,31 +15,45 @@ class MountainDetailTitleView: UIView { override func draw(_ rect: CGRect) { super.draw(rect) self.layoutTitleView() + self.addShadow() + } + + private func addShadow() { + self.layer.shadowOpacity = 0.5 + self.layer.shadowRadius = 1 + self.layer.shadowColor = UIColor.lightGray.cgColor + self.layer.shadowOffset = CGSize(width: 0, height: 1) + print("add shadow") } private func layoutTitleView() { titleLabel.translatesAutoresizingMaskIntoConstraints = false + titleLabel.font = UIFont.systemFont(ofSize: 20, weight: .bold) distanceLabel.translatesAutoresizingMaskIntoConstraints = false - + distanceLabel.font = UIFont.systemFont(ofSize: 13, weight: .regular) + distanceLabel.textColor = .lightGray self.addSubview(titleLabel) self.addSubview(distanceLabel) let titleConstraints = [ - titleLabel.topAnchor.constraint(equalTo: self.topAnchor), - titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor) + titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), + titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20) ] NSLayoutConstraint.activate(titleConstraints) let distanceLabelConstraints = [ distanceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), - distanceLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor) + distanceLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20) ] NSLayoutConstraint.activate(distanceLabelConstraints) } func configure(with title: String, distance: Double?) { self.titleLabel.text = title - guard let distance = distance else { return } + guard let distance = distance else { + self.distanceLabel.text = "현재 위치를 알 수 없어 산까지의 거리를 불러올 수 없습니다." + return + } let distanceRepresentation = String(format:"%.2f", distance) self.distanceLabel.text = "현재 위치로부터 약 \(distanceRepresentation)km (직선거리)" } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index ec31b39..8935e57 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -53,8 +53,8 @@ extension MountainDetailViewController { headerView.addSubview(mapSnapShot) headerView.addSubview(titleView) - view.addSubview(headerView) view.addSubview(tableView) + view.addSubview(headerView) let headerConstraints = [ headerView.topAnchor.constraint(equalTo: view.topAnchor), diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json index 5f17223..d86c4fc 100644 --- a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/Contents.json @@ -1,7 +1,7 @@ { "data" : [ { - "filename" : "MountainsWithLocation2.json", + "filename" : "UniqueMountains.json", "idiom" : "universal" } ], diff --git a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/UniqueMountains.json similarity index 88% rename from SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json rename to SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/UniqueMountains.json index db51b43..7c9f5be 100644 --- a/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/MountainsWithLocation2.json +++ b/SanTa/SanTa/Resources/Assets.xcassets/MountainsWithLocation.dataset/UniqueMountains.json @@ -1,13 +1,43 @@ [ { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기 제 1봉인 화악산(1,468m)에서 동남쪽으로 뻗어 내린 능선상에 솟아 있는 가덕산은 몽덕산과 북배산의 능선 중간에 자리잡고 있다. 억새산이라고 할만큼 가을철에 억새가 볼만하다.수백평의 억새밭인 가덕산 정상에 오르면 서북방향으로 화악산이 보이고, 남쪽으로는 목동평야와 북배산, 계관산 너머로 삼악산으로 이어지는 능선이 한눈에 들어 온다. 동쪽으로는 의암호와 춘천호, 그리고 호반의 도시, 춘천시가 보인다.가덕산은 계관산, 북배산, 몽덕산과 더불어 네 개의 산을 연결하여 등산하는 유명한 종주코스이다. 이 능선에 구축된 등산길은 넓게 길이 잘 뚫려 있고 굴곡이 심하지 않아 겨울철 능선 종주산행지로 적격이다.", - "MNTN_HG_VL" : "858", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", - "MNTN_NM" : "가덕산" + "DETAIL_INFO_DTCONT" : "용두리에서 홍천 방향으로 이어지는 44번 국도 동쪽 옆에 솟아 있는 갈기산은 산 높이는 낮으나 능선 곳곳에 바위가 돌출 되어 전망이 좋은 산이다. 봄이면 바위들과 진달래, 철쭉이 어우러져 고운 빛깔로 물들이고, 가을이면 형형색색의 단풍으로 자태를 뽐내는 산으로, 유명 산에 비해 한적하고 쾌적한 산행을 하기에 안성맞춤인 산이다.국토지리정보원 발행 지형도상 갈기산의 한자 표기는 칡 '갈' 자에 터 '기' 자를 쓴 '葛基山'이지만 과거에는 일어날 기(起)자를 썼다고 한다. 구한말 기록에는 부동산(不動産), 그 이전에는 감물악(甘勿岳)이라고 불렀다고 한다.정상 주변은 온통 암릉으로 되어 있어 전망이 좋으나 주의를 요하는 곳이다. 계곡이 깨끗하고 물이 차가워 송어 양식에 적합한 장소로 산자락에는 송어회집이 여러 곳 있다.", + "MNTN_HG_VL" : "685", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 홍천군", + "MNTN_NM" : "갈기산" }, - "longitude" : 127.61222220000001, - "latitude" : 37.940555600000003 + "longitude" : 127.7844462, + "latitude" : 37.578187 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "330", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "보납산" + }, + "longitude" : 127.4686111, + "latitude" : 37.694722200000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "도봉산은 서울 근교의 산으로 예로부터 북한산과 하나의 산으로 취급되어 왔다. 우이령을 경계로 북한산과 나란히 솟아 있어 현재 두 산을 북한산국립공원에 함께 포함시키고 있다. 북한산 면적 55㎢에 비해 도봉산은 약 24㎢로 절반에 불과하나 산세가 아름다워 등산객이 끊이지 않는 곳이다.주능선상에는 최고봉인 자운봉을 비롯해 만장봉, 선인봉, 주봉 등의 암봉과 서쪽으로 다섯개의 암봉이 나란히 줄지어 있는 오봉이 있다. 선인봉, 만장봉, 주봉, 우이암은 각기 거대한 암벽들이다. 도봉산은 우람한 기암괴석과 뾰족히 솟은 암봉들이 장관을 이루며, 사방으로 뻗은 계곡을 따라 녹음이 우거져 명소를 만들고 있다.사계절 모두 즐겨 찾는 산이지만 가을이면 단풍의 물결이 여느 산 못지 않다. 도봉산의 3대 계곡은 문사동계곡, 망월사계곡(원도봉계곡), 보문사계곡(무수골) 이다. 이 계곡들이 바로 산행기점과 연결된다. 도봉산은 등산코스가 다양한데 그 중에서 우이동, 도봉유원지, 망월사역(장수원), 성황당 코스가 대표적이다.도봉산의 주봉은 자운봉(740.2m)으로, 정상을 기점으로 등산로가 사방으로 거미줄 같이 수십 가닥이 펼쳐져 있다. 모두 합쳐 100여개의 산행 코스가 있다. 그 중 도봉산 등산로의 핵심은 포대능선으로, 이 산의 등뼈를 이루는 포대능선-자운봉-칼바위-우이암 능선으로 이어진다. 포대능선은 능선 중간에 대공포진지인 포대(砲臺)가 있었다고 해서 붙여진 이름이다. 도봉산 산행 들머리는 수 없이 많지만 크게 분류하면, 안골유원지, 회룡사입구, 원도봉유원지, 도봉유원지, 성황당, 우이동, 송추 7개 코스를 꼽을 수 있다. 빼어난 암릉미를 자랑하는 도봉산은 어느 코스이든 바위 암릉이 곳곳에 도사리고 있어 주의가 필요하다. 수도권 등산객이 많이 몰리는 휴일에는 주능선인 포대능선 등에 정체 현상이 벌어질 정도로 붐빈다. 갈림길이 무수히 많아 길을 잃을 수 있으므로 사전에 지도를 꼼꼼히 챙겨야 되는 산이다.", + "MNTN_HG_VL" : "740", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 도봉구, 경기도 의정부시 호원동ㆍ양주시 장흥면", + "MNTN_NM" : "도봉산(자운봉)" + }, + "longitude" : 127.0156843, + "latitude" : 37.700463499999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "고고산은 강원도 영월군 영월읍 문산리와 중동면 연하리, 정선군 신동읍 고성리와 경계를 이루며 동강변에 솟아 있는 산이다.설악산 용아름의 축소판인 암릉은 이 산의 백미로 구들장 같은 바위들이 층층이 쌓여 있고 암릉 위에는 분재와 같은 노송들이 뿌리를 내려 거대한 한 폭의 동양화를 연상하게 한다. 북릉을 타고 전망바위 정상에서 북으로 보면 신병산과 능암덕산이 마주 보이고 오른쪽으로는 백운산과 곰봉 사이를 가로 지르는 동강이 조망된다.", + "MNTN_HG_VL" : "854", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군, 정선군", + "MNTN_NM" : "고고산" + }, + "longitude" : 128.57913009999999, + "latitude" : 37.220578799999998 }, { "mountain" : { @@ -21,763 +51,703 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가리봉은 설악산국립공원에 속하는 산으로 설악산 귀때기청봉(1,580m)과 대승령을 잇는 설악산 서북 주능선과 마주보고 있어 독립된 산처럼 보인다. 멀리서 보면 봉우리가 둥글둥글 완만해 보이지만 험준한 암봉들이 많은 산이다.산행 들머리는 옥녀탕앞이나 한계령에서 시작하는데 오르다 보면 산의 남서쪽에 이 산의 명물 팔례 약수가 있다.가리봉 주능선은 등산인들의 왕래가 거의 없는 관계로 등산로가 뚜렷하지 않으므로 산행시 주의해야 하는 곳이다.", - "MNTN_HG_VL" : "1519", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", - "MNTN_NM" : "가리봉" + "DETAIL_INFO_DTCONT" : "옥천 이원의 달이산은 비단폭 같은 푸른 금강 물줄기와 벗하며 뻗어 있다. 달이산은 이원 사람들에게는 정다운 산이며 달을 연상하게 하는 산이다.달이산 줄기의 전체적인 가닥은 ‘H’자 모양이다. 서쪽 세로 획이 원줄기로 금강 물줄기와 벗하고 있다. 또 멀리서 보면 날카롭거나 까다로워 보이지 않고 순하고 무던하게 보이지만 산에 들어서면 곳곳에 기암절벽이 도사리고 있는 외유내강의 산이라 할 수 있다. 까마득한 바위 낭떠러지가 여러 곳에 있고 그 위는 넓은 암반이어서 쉬기도 좋고 조망하기도 좋다.달이산의 기암괴봉 중 으뜸인 것은 ‘H’자의 가로지른 획 가운데 자리 잡고 있는 암봉이다.정상에서 507미터의 서봉으로 건너가는 산등성이에 있는 둥근 투구모양의 봉우리가 그것이다. 남쪽은 높고 아득한 바위 낭떠러지이며 동쪽도 밧줄을 잡고 오르도록 되어 있을 만큼 높은 바위벽이다. 북쪽과 서쪽도 바위벽이기는 하지만 그리 높지는 않아 오르내릴 만하다.", + "MNTN_HG_VL" : "555", + "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 이원면", + "MNTN_NM" : "달이산(월이산)" }, - "longitude" : 128.34222220000001, - "latitude" : 38.093611099999997 + "longitude" : 127.6561111, + "latitude" : 36.228888900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산은 험준한 암릉으로 이루어진 산이다.산 아래에서 볼 때 정산 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입금지구역으로 주의를 요하는 곳이다.백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산(774.3m)은 험준한 암릉으로 이루어진 산이다. 산 아래에서 볼때 정상 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입 금지구역으로 주의를 요하는 곳이다.정상에서의 사방 조망은 경기 제일의 고봉인 화악산, 명지산에 이어 세번째로 높은 국망봉(1,168m)과 신로봉으로 이어지는 능선이 파노라마를 이룬다. 도평교를 하산 지점으로 잡을 경우 하산길은 지루함을 느낄만큼 계곡길의 연속이다.가리산이란 명칭은 현재 폐광된 산 입구의 가리광산에서 유래됐다는 설이 전해진다. 가리란 바로 비료의 주성분 가운데 하나인 칼륨의 일본식 발음이다.", - "MNTN_HG_VL" : "774", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면 장암리", - "MNTN_NM" : "가리산" + "DETAIL_INFO_DTCONT" : "낙조를 찾아 떠날 산행지는 요즘 들어 일몰 관광지로 인기를 끌고 있는 강화도 고려산(高麗山)이다. 고려산은 읍내에서 5킬로미터쯤 떨어져 있으며 원래 이름은 오련산이었으나 고려가 몽고의 침략을 받아 도읍을 강화로 천도하면서 송도의 고려산 이름을 따 고려산으로 고쳐 부르게 되었다고 한다. 또한, 고려산은 연개소문이 태어난 곳이라는 전설이 있으며 주능선에 오르면 탁 트인 서해 바다의 시원스런 조망은 물론, 황해도의 연백군 해안과 예성강 하구를 조망할 수 있어 민족분단의 현실을 직접 눈으로 확인 할 수 있는 곳이기도 하다. 현재 고려산에는 백련사, 청련사, 적석사, 원통암 등 세 개의 사찰과 한 개의 암자가 있다. 그 중 청련사의 분위기가 제일 뛰어나나 남향에 자리한 사찰 전등사 역시 이에 뒤지지 않을 만큼 그윽하고 멋스러운 풍경을 자랑한다. 적석사 서쪽 절 정상 낙조봉에서 바라보는 서해 일몰은 강화 8경 중 하나로 꼽힌다. 게다가 인천시 기념물 제26호로 지정되어 있는 고창, 화순의 고인돌군도 만나 볼 수 있어 아이들과 함께 하는 가족산행지로 더 없이 좋은 곳이다.", + "MNTN_HG_VL" : "436", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 강화읍, 하점면, 송해면, 내가면", + "MNTN_NM" : "고려산" }, - "longitude" : 127.403469, - "latitude" : 38.037748999999998 + "longitude" : 126.4372675, + "latitude" : 37.744586699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 홍천군 내천면과 인제군 상남면의 경계에 걸쳐 있는 가마봉은 산을 즐겨 타는 등반객들에게도 잘 알려지지 않아 자연 그대로의 정경을 간직한 산이다.산행기점인 김부리는 신라의 마지막 왕인 김부(金傅)에서 유래한 지명인데 세월이 흐르면서 현재 `金富'로 변했다고 한다.", - "MNTN_HG_VL" : "925", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 인제군 남면", - "MNTN_NM" : "가마봉" + "DETAIL_INFO_DTCONT" : "운길산(610m)은 경기도 남양주시 조안면 송촌리 북한강변에 위치한다. 이 산은lsquo;구름이 산에 걸려서 멈춘다rsquo; 또는lsquo;길상한 구름에 뒤덮인 산rsquo;이라는 뜻을 함축하고 있다. 수종사에서 조망되는 북한강과 남한강이 합수되는 두물머리의 서정적 풍광이 일품이다. 양수리 풍경은 어디서 봐도 아름답지만 이곳이 진yen;다. 조선 초 판서를 지낸 서거정이 수종사를lsquo;동방에서 제일의 전망을 가진 사찰rsquo;이라고 하여 남긴 시가 있을 정도다. 그러다보니 운길산에 오른다는 건 수종사를 보러 가자는 것과 마찬가지다.검단산을 좌측 배경으로 양수리가 훤히 보이면서 예봉산 아래 정약용 생가 유적지도 눈에 들어온다. 규모는 작지만, 긴 역사와 경관이 기가 막힌 곳에 자리 잡아 꼭 들러야 하는 사찰이다. 송촌리나 진중리에서 올라 수종사만 보고 가도 아쉽지 않다. 정상에서 두물머리쪽은 수림에 가려 전혀 조망이 안 된다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 와부읍", + "MNTN_NM" : "운길산" }, - "longitude" : 128.1766667, - "latitude" : 37.886111100000001 + "longitude" : 127.2951884, + "latitude" : 37.5720399 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "대구의 명산 팔공산 정상에서 서쪽으로 약 10킬로미터 떨어진 가산은 일명 칠봉산이라고도 불리며 칠곡군 내 최고봉으로 가산면 가산리에 있다. 7개의 봉이 7개의 골짜기를 이루어 칠곡(七谷)이라 한 것이 오늘의 칠곡(漆谷)이 되었다. 1640년(인조 18)에 가산성을 쌓고 칠곡도호부의 치소가 약 180년간 산성 내에 있었다.<>한국전쟁 때의 격전지로서 선조의 호국의지가 깃들어 있는 가산산성과 가산바위 등 명소가 많으며 울창한 수림, 계곡의 석간수는 한여름에도 서늘함을 느낄 만큼 시원하여 가족 단위의 등산객이 많이 찾고 있다.<>가산바위는 산성 서쪽에 있는 80여평의 넓은 바위로, 신라시대의 고승 도선(道詵, 827∼898년)이 산천을 편력하면서 가산바위에 쇠로 만든 소와 말의 형상을 묻어 지기를 눌렀다고 전한다. 용의 모습을 닮은 용바위, 신선이 노닐었다는 유선대는 가산 정상에 우뚝 솟아 있다.", - "MNTN_HG_VL" : "902", - "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 동명면", - "MNTN_NM" : "가산" + "DETAIL_INFO_DTCONT" : "진안의 동쪽으로는 성수산, 팔공산, 선각산, 삿갓봉 등 해발 1000미터 이상 되는 봉우리가 병풍처럼 둘러싸고 있다. 이 웅장한 산줄기에 덕태산이 자리하고 있다. 덕태산에는 수많은 미개척 계곡과 전인미답의 능선이 원시림에 가려 있으며, 험준한 절벽과 갖가지 형상의 바위가 도처에 산재해있다. 봄철 골짜기를 가득 메운 철쭉과 가을철 은근한 단풍은 암릉과 울창한 숲이 어우러져 빼어난 경치를 자랑하는 백운동계곡과 함께 덕태산의 자랑이다.능선의 동쪽으로는 시루봉과 함께 금남호남정맥 마루금이 지나고, 남쪽으로는 선각산과 함께 섬진강 발원지인 데미샘을 품고 있다. 정상에 서면 지리산과 남덕유산, 마이산과 내동산, 고덕산 등이 사방으로 조망되는데, 호쾌하게 뻗은 산줄기를 보고 있자면 감탄사가 절로 나온다.덕태산에는 ‘라장사’의 전설과, ‘점전바위’ 사이에 풀잎을 꽂으면 아들을 낳는다는 전설이 전해져 온다.", + "MNTN_HG_VL" : "1113", + "MNTN_LOCPLC_REGION_NM" : "전북 진안군 백운면", + "MNTN_NM" : "덕태산" }, - "longitude" : 128.58266399999999, - "latitude" : 36.037387899999999 + "longitude" : 127.4473366, + "latitude" : 35.6892979 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가야산은 경남 합천군 가야면과 거창군 가북면, 경북 성주군 가천면 수륜면을 한몸에 품고있다. 우리나라 12대 명산중의 하나로 산세가 천하에서 으뜸이고, 지덕은 해동에서 제일이라 하여, 대한 8경에 속하는 명산이다. 가야산 지역이 옛날 가야국이 있었던 곳이고 이 산이 가야국에서 가장 높고 훌륭한 산이었기 때문에 자연스럽게 가야의 산이라 불렀다고 한다.가야산은 소머리 같다 해서 우두산(산 머리의 큰 바위 아래에 소의 코라는 뜻의 우비정이란 샘도 있다) 이라는 이름외에 상왕산, 설산, 중향산 등으로도 불리워졌다. '택리지'에 기암괴봉을 불꽃에 비유하여 석화성(石火星)이라고 하였는데, 가야산은 보는 방향에 따라서 한송이 연꽃으로도 보였다가 서쪽으로 겹겹이 솟은 산봉우리 사이사이 또는 골짜기에 하얀구름이 잠기면 많은 섬이 떠 있는 바다가 된다.해발 1천m가 넘는 고봉들이 불꽃처럼 솟아 있는 자태하며, 북에서 남으로 이르는 장쾌한 대덕유의 줄기와 아스라히 떠오른 구름위로 지리산을 볼 수 있는 조망, 홍류동천의 아름다운 계곡 등 장중하고 덕성스러운 모습을 곳곳에서 볼 수 있다.가야산 고스락에 서면 금오산, 팔공산, 비슬산이 보이고 화왕산, 자굴산이 보이는가 하면 가까이에 두무산, 오도산, 비계산, 조금 멀리에 백운산, 수도산, 대덕산 등이 보인다.여기에 우리나라 3보 사찰중 하나인 해인사가 들어서고, 조선시대 때 강화도에서 팔만대장경을 옮겨온 이후 불교의 성지로 자리메김하였다. 근래에는 백련암에서 수도했던 성철 스님으로 인하여 더욱 유명해졌다.", - "MNTN_HG_VL" : "1433", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군ㆍ거창군, 경상북도 성주군", - "MNTN_NM" : "가야산" + "DETAIL_INFO_DTCONT" : "호남정맥의 마루금에 위치한 경각산은 구이저수지 서쪽에서 모악산을 마주보며 우뚝 솟아있다. 경각산(鯨角山)의 한자 그대로 고래등에 난 뿔처럼 생긴 두 개의 바위가 정상부에 솟아, 산 아래에서 바라보면 모악산 방향으로 머리를 둔 고래의 모습과 흡사하다. 이 때문에 어머니를 상징하는 모악산과 달리 경각산은 남성을 상징한다.산 정상에서는 전주와 익산 시내, 미륵산, 고덕산, 마이산, 오봉산이 선명하게 보인다. 특히 가을 단풍과 겨울 선경으로 이름 높지만, 모악산에 비해 상대적으로 덜 알려져 있어 주말에도 호젓한 산행을 할 수 있다. 패러글라이딩 활공장이 있어 날씨가 좋은 날에는 하늘 높이 날아가는 패러글라이딩의 모습도 볼 수 있다.경각산 아래 정각사는 고려말기에acirc;건된 태고종 사찰로 많은 고승들의 수도oacute;가 되었다고 전해진다.", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 신덕면", + "MNTN_NM" : "경각산" }, - "longitude" : 128.1179362, - "latitude" : 35.822099600000001 + "longitude" : 127.15733539999999, + "latitude" : 35.728343799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 서산시와 예산군의 경계를 이루는 가야산은 예산, 당진, 서산, 태안 지역에서 무소불위의 힘을 떨치는 산이다. 산은 그 자체로 서해를 향해 호령할 듯 섰다. 산세 또한 그 근방에서 찾아 볼 수 없는 암산으로 기암들이 징검다리 마냥 하늘을 받치고 있다. 백두대간 칠현산에서 분기한 금북정맥의 산답게 당찬 힘을 발휘한다. 가야산에서 석문봉까지 암릉을 형성한 후 두 줄기로 나뉘어 일락산과 옥양봉, 수정봉을 향해 갈래 친다.가야산 자락에는 사방 곳곳에 백제에서 조선시대에 걸쳐 이어진 문화재가 산자락마다 있다. 가야산 서쪽으로는 커다란 은행나무를 품고 있는 고풍스런 해미읍성이 자릴 꿰차고 있으며 북쪽에는 보물 143호로 지정된 대웅전이 있는 개심사가 있다. 북동쪽 자락에는 조선시대의 명지관인 정만인이 점지한 남원군묘와 육관대사로 알려진 풍수지리도사인 손석우의 묘가 있다. 그뿐만 아니다. 남쪽에는 충남 서북부를 대표하는 1500여년 된 역사를 자랑하는 백제시대의 수덕사가 명성을 떨치고 있다.", - "MNTN_HG_VL" : "678", - "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 운산면·예산군 덕산면", - "MNTN_NM" : "가야산" + "DETAIL_INFO_DTCONT" : "봉화읍에서 동남쪽으로 26km 떨어진 청량산(869.7m)에는 금탑봉을 비롯하여 아름다운 봉우리 12개와 8개의 동굴이 있다.자연경관이 수려하여 옛부터 소금강이라 전하여지는 명산으로써 태백산에서부터 시작되는 낙동강 줄기가 절벽을 감아돌아 절경을 빚어내고 있으며, 신선이 내려와 바둑을 두었다는 신선대와 선녀가 가무유희를 즐겼다는 선녀봉을 비롯하여 12봉의 기암괴석으로 이루어져 있고, 신라때부터 근세에 이르기까지 김생, 퇴계이황등 선현들이 수도를 하던 유불선교 발상지로 널리 알려져 있을뿐만 아니라 고려 공민왕 10년에 제2차 홍건적의 난을 피하여 왕이 이곳에 와 마지막요새로써 산성을 축조하였고, 난이 끝난후 왕이 이곳을 떠나자 주민들이 왕을 추모하기 위하여 공민왕당을 세우고 봄, 가을로 공을 드리자 대란이 있을때 마다 소리가 울려 재난을 피할수 있었다는 전설이 있으며, 이곳 공민왕당을 오르는 등산로는 말 다섯 마리가 한꺼번에 지나다녔다는 五馬道가 있다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 명호면", + "MNTN_NM" : "청량산" }, - "longitude" : 126.6117509, - "latitude" : 36.707605200000003 + "longitude" : 128.90838890000001, + "latitude" : 36.7964974 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", - "MNTN_NM" : "가야산" + "DETAIL_INFO_DTCONT" : "황병산은 높이 1,407m의 명산으로 청학동 소금강의 절경을 끼고 구룡폭포, 만물상, 금강사, 십자소 등 수많은 명승 고적을 품고 있다.75년 오대산이 국립공원으로 지정되면서 황병산 또한 국립공원으로 편입됐지만, 사람들 사이에서는 잘 알려지지 않은 편이다. 잘 알려지지 않은 까닭에 황병산은 자연 그대로의 아름다움을 간직할 수 있었다. 골골이 깊은 산중의 계곡 하며, 희귀식물, 원시림 등은 황병산의 또 다른 자랑이다.육산이라 산행도 수월한 편이며 부드러운 흙을 밟으며 산행 할 수 있어 좋다. 특히 여름이면 계곡을 끼고 가는 코스가 인기다. 정상은 입산금지 구역이다.", + "MNTN_HG_VL" : "1407", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면 병내리", + "MNTN_NM" : "황병산" }, - "longitude" : 126.6117509, - "latitude" : 36.707605200000003 + "longitude" : 128.66333330000001, + "latitude" : 37.7577778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가은산은 금수산(1015.8m) 정상에서 남쪽 말목산(720m)으로 흐르는 산줄기와 중계탑이 서 있는 802봉, 남서쪽으로 흐르는 산줄기에 있는 산이다. 가은산은 청풍호반을 사이에 두고 청풍호의 최고 경승지 옥순·구담봉과 마주 서 있다. 그래서 제천 지역의 그 어느 산에서보다 청풍호반의 아름다운 풍광을 만끽할 수 있다. 또한 등산로 곳곳에 기암괴석과 그 사이에서 자라는 노송들이 한데 어울려 한 폭의 동양화를 그려낸다. 뿐만 아니라 남쪽에는 월악산 영봉과 만수봉으로 이어지는 들쑥날쑥한 능선이 막힘없이 펼쳐진다. 등산로 곳곳에 물개바위, 기와집바위, 손바닥바위, 시계바위, 곰바위 등 독특한 이름을 갖고 있는 기암들이 있어 산행의 즐거움을 더한다. 가은산은 원래 ‘가는산’으로 불렸다고 한다. 전설에 의하면 옛날 마고할미가 이 산에 놀러 왔다가 반지를 잃어버려 모든 능선과 골짜기를 뒤지며 찾다가 아흔아홉번째 골짜기에서 비로소 찾게 되었다. 그리고 나서 “한 골짜기만 더 있었어도 한양이 들어설 골짜기인데, 내가 눌러 앉아 살려 해도 한양이 되지 못하므로 떠나겠다”는 말을 남기고 떠났다는 데서 ‘가는산’이란 이름이 붙었다고 한다.", - "MNTN_HG_VL" : "575", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면", - "MNTN_NM" : "가은산" + "DETAIL_INFO_DTCONT" : "음식의 양념으로 또는 한약제로도 쓰인 향취나 맛이 뛰어나 전국적으로 널리 알려진\"\"봉두생강\"\"의 주산지 봉동읍의 서북쪽에 우뚝 솟아 있는 산이 봉실산이다.이 산은 그리높지 않으나 봉동평야의 동북쪽으로 길게 뻗은 산맥으로 옥녀봉을 거느린 두 봉우리와 암봉으로 이루어진 산으로 정상에 서면 그 주위에 산이 없으므로 사방 거침없이 펼쳐진 들녘이 확 트여 시원스럽기 그지없는 전망이 일품이다.바둑판같이 잘 정리된 농경지이며 옹기종기 모여 있는 마을과 마을 동북에서 서남쪽으로 흘러내린 고산천의 물줄기가 푸른 농경지 사이로 아름답게 내려다보인다.", + "MNTN_HG_VL" : "372", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주 봉동읍, 비봉면", + "MNTN_NM" : "봉실산" }, - "longitude" : 128.25128050000001, - "latitude" : 36.955438000000001 + "longitude" : 127.15235730000001, + "latitude" : 35.972536599999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1241", - "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상북도 청도군, 경상남도 밀양시", - "MNTN_NM" : "가지산" + "MNTN_HG_VL" : "868", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "연점산" }, - "longitude" : 129.00305599999999, - "latitude" : 35.621110999999999 + "longitude" : 128.9556479, + "latitude" : 36.337886699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "신라말 원표대사(元表大師)가 인도에 계실 때 신비한 기운이 삼한의 밖 아득히 먼 곳으로부터 비쳐와 그 기운만을 바라보고 산을 넘고 바다를 건너 오묘한 곳을 찾아내 자리를 잡으니 산세가 인도의 가지산, 중국의 가지산과 같아서 가지산이라 명하고 지어진 절이 보림사로 창건에 얽힌 이야기가 전해져 오듯 국보와 보물이 많이 있으며 가지산은 규모는 작지만 산세가 좋아 정상에서 둘러보면 금방 명산이라는 것을 느낄 수 있다.특히 가을철에는 산 전체가 단풍으로 붉게 물들어 그 아름다움은 극치에 달하고 정상부의 바위들은 돌을 깍아세운 듯 하다. 한편 보림사 봉덕 계곡은 사시사철 깨끗한 물이 흐르고 있어 많은 탐방객들이 찾고 있으며 여름철에는 최고의 가족 휴양지로 꼽힌다.", - "MNTN_HG_VL" : "510", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 장평면 우산리", - "MNTN_NM" : "가지산" + "DETAIL_INFO_DTCONT" : "박지산은 강원도 평창에 위치한 산으로 오대산에서 발원하는 청정류 가운데 가장 때묻지 않은 계곡인 아차골을 품고 있다. 말복까지 얼음을 볼 수 있는 박지골과 경치가 수려한 아차골 등 박지산 골짜기는 등산인들의 발길이 뜸하여 오지의 신비함을 간직하고 있다.박지산은 두타산(頭陀山)이라고도 하는데 2007년 인쇄된 국토지리정보원 지형도상의 공식명칭으로 ‘우리 산 이름 바로 찾기 운동’에 따라 2002년 박지산에서 두타산으로 이름이 바뀌었다. 그러나 백두대간의 삼척 두타산(1352.7m)과 혼돈되기 때문에 여전히 박지산이라 일컫는 이들이 많다.정상에는 2미터 높이의 돌탑이 있는데 칠원성군(七元星君)을 모셨다하여 칠성대라 부르며, 칠원성군이란 불교에서 북두의 일곱 성군을 뜻한다. 칠원성군은 북두칠성을 인격화한 신(神)이며 농사와 생사(生死), 화복(禍福)을 맡아본다고 한다. 박지산은 이곳 주민들에겐 단순히 이끼가 많은 산이 아니라 북두칠성의 산이기도 하다.", + "MNTN_HG_VL" : "1391", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면", + "MNTN_NM" : "박지산(두타산)" }, - "longitude" : 126.9025627, - "latitude" : 34.820325599999997 + "longitude" : 128.60083330000001, + "latitude" : 37.583888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼봉약수에 있는 가칠봉(1,240m)에서 직선거리로 약 14km 북쪽에 위치한 가칠봉은 곰배령으로 더 유명하다. 곰배령 일대의 넓은 초원지대는 봄부터 가을까지 온갖 야생화가 피어나 지나는 이의 눈길을 끌고 놓지 않는다.<><>가칠봉 산자락에 사는 주민들은 일년 내내 산골 곳곳을 누비며 약초와 나물을 캐러 다니고 있다. 그래서 99년 5월부터 곰배령,가칠봉 일대를 입산 금지하고 있어, 입산코자 할 경우 인제 군청에 미리 확인해 봐야 한다.<><>가칠봉에서 북쪽으로 이어지는 주능선을 따라가면 곰배령을 지나 작은 점봉산(1,295m)으로 이어지고 이어서 점봉산(1,424m)으로 연결되어 한계령으로 능선이 뻗어 나가면서 설악의 품으로 들어간다. 가칠봉 일대는 교통이 불편한 관계로 접근이 어려워 아직도 깨끗한 계곡과 경관을 유지하고 있다.", - "MNTN_HG_VL" : "1242", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면 진동리", - "MNTN_NM" : "가칠봉" + "DETAIL_INFO_DTCONT" : "청도읍에서 남서쪽으로, 밀양시에서는 북서쪽으로 솟은 화악산은 이 일대에서는 가장 높은 산이다. 이 산은 화악산의 북쪽, 같은 능선에서 솟은 산으로 산 북쪽에는 신둔사가 있고 동쪽에는 적천사가 있다.먼 옛날 청도에는 이서국(伊西國)이란 부족국가의 도읍지가 있었다고 한다. 그래서 한 나라의 수도였던 곳에만 있는 남산이 이곳 청도에도 있다.삼국사기와삼국유사에서 전하는 이서국은 한때 신라를 공격해 위기에 빠뜨릴 정도의 강국이었으나 결국 신라에 합병되었다. 그래서 남산에는 신라군사에 쫓긴 이서국의 왕이 숨어들었다는 전설을 갖고 있는 은왕봉이 있다. 서울과 경주, 개성의 남산이 300m 정도인데 비해 청도 남산은 800m 대의 높이를 자랑하는데 등산로가 여럿 있어 그 위용을 알 만하다. 산 곳곳에 뛰어난 암릉 전망대를 품고 있으며 정상 북쪽에는 비구니 사찰인 죽림사가 자리잡고 있다. 이곳 명소 가운데 하나인 약수폭포는 상부의 저수지에 물을 저장하고 있다가 여름에 풀어내 절경의 극치를 보여준다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "청도남산" }, - "longitude" : 128.42111109999999, - "latitude" : 38.0038889 + "longitude" : 128.70460869999999, + "latitude" : 35.614273900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월출산에서 남으로 뻗은 능선이 강진군 성전면과 영암군 학산면을 잇는 회랑에서 2번국도에 길을 내주는등 잠시 바닥에 깔렸다가 고도를 높여 별매산을 만들고 서쪽으로 진행하며 영암군과 해남군사이의 장벽을 이룬다. 이 산줄기는 동으로부터 별매산, 가학산, 흑석산, 두억봉, 418봉등으로 이어지며 계속 서진한뒤 영암호에 이른다.봄철 철쭉철이면 철쭉군락지가 산재한 이 산줄기의 곳곳이 붉게 물들어 장관을 연출한다. 높지 않으면서도 수려한 봉우리들이 중첩되고 조망도 시원한 산들이 가학산, 흑석산이다. 별매산(465m)에서 흑석산(黑石山,650m)으로 이어지는 능선에 우뚝 솟아 있는 가학산의 정상부는 거대한 돔형의 바위 봉으로 되어 있어 해발에 비해 웅장함을 자랑하고 있다.가학산 정상은 평평하고 넓은 공터를 이루고 있으나 양쪽이 절벽으로 이루어져 있어 주의해야 하는 곳이다. 정상에서 북동쪽으로 월출산이 손에 잡힐 듯 가까이 보이고, 남쪽으로는 두륜산이 아스라히 보인다. 가학산 주능선은 온통 바위능선으로 되어 있어 등산로 이외 탈출로가 많지 않은 산이다.", - "MNTN_HG_VL" : "575", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면 당산리", - "MNTN_NM" : "가학산" + "DETAIL_INFO_DTCONT" : "태백의 한 지맥이 동해를 향해 꿈틀대다 크게 용트림해 만들었을까, 아니면 동해가 뒤집히면서 푸른 하늘과 응어리지어 그 정수를 한 곳에 모아둔 것인가? 그리 높지 않으면서도 정상은 큰 바위덩어리로 되어있어 장엄한 맛을 주는 산이다. 또 정상에 서면 동해가 짙푸른 윤기를 발산하며 넘실대고 있어 상쾌함이 등산복을 간지럽힌다.부산에서 1시간 남짓 걸리며 산행시간도 3시간 30분에 불과해 초심자나 가족단위 등산객에게는 안성맞춤의 산이다. 특히 정상 부근의 바위는 특별한 장비가 없이도 몸의 밸런스와 리듬만으로 바위틈새를 타고 오를 수 있어 암벽등반의 묘미도 느끼기에 충분하다.이 산 초입에 있는 일광광산은 지난 날 일본인들이 철광을 캐던 곳으로 지금은 폐광이 되어 있으나 광산마을이 그대로 있고 탄광도 거의 원형 그대로 남아있어 학생들에게는 자연학습의 장소로도 좋다.안부와 바위 틈새는 철쭉 군락지대로 부산근교에서는 정상 주변의 경관이 제일 아름다운 곳이다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "부산시 기장군", + "MNTN_NM" : "달음산" }, - "longitude" : 126.6408333, - "latitude" : 34.680277799999999 + "longitude" : 129.21083329999999, + "latitude" : 35.307777799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "192", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 서구, 경기도 김포시", - "MNTN_NM" : "가현산" + "DETAIL_INFO_DTCONT" : "양성산은 문의면의 진산이다. 높지는 않으나 여러 가지 역사유적과 전설을 간직하고 있으며 문헌에 기록되어 있는 산이다. 산자락에 규모 큰 문화재단지가 있고 맞은편에는 대통령 별장이었던 청남대도 있다. 산 아래 푸른 대청호가 펼쳐져 있어 조망 또한 좋다.지도상 양성산으로 표기된 주봉은 297미터로 문의면사무소가 있는 미천리 마을 뒷봉우리다. 상봉은 378미터로 산행 들머리인 불당골로 오르는 가장 높은 봉우리다. 따라서 양성산은 주봉과 상봉으로 나누어 부를 필요가 있다. 산행은 상봉을 중심으로 이루어진다.양성산은 백제시대 일보산, 신라시대에는 연산이라 불렸다. 그 뒤에는 양승산, 양성산 등으로 불리며 지금에 이르렀다.삼국사기에 의하면 양성산 안의 일모산성은 474년에 쌓은 것으로 기록되어 있다. 신라시대 화랑 출신의 화은대사가 양성산을 보고 ‘저 산은 중이 바리를 들고 시주를 구하는 형세’라 했다. 중을 양성하기에 흠잡을 데가 없는 땅이라 감탄하고 승병 300명을 제자로 삼아 불경과 무예를 익히도록 했다.", + "MNTN_HG_VL" : "301", + "MNTN_LOCPLC_REGION_NM" : "충북 청원군 문의면", + "MNTN_NM" : "양성산" }, - "longitude" : 126.6497777, - "latitude" : 37.626327199999999 + "longitude" : 127.48339439999999, + "latitude" : 36.512921899999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "각화산은 태백산 남쪽 15Km 지점 경북 봉화군 춘양면 석현리에 위칙하고 있으며, 가을에는 정상을 오르는 등산로에 단풍이 곱게 물들어 많은 사람들이 찾는다.각화산이란 명칭은 시라 문무왕 16년 (676년)원효대사가 춘양면 서동리에 있던 람화사(覽華寺)를 이 산자락 밑으로 이전한 뒤 생각\"각\"자로 바꿔 부른데서 기인한다. 이 람화사에는 보물 52호로 지정된 3층 석탑이 있으며, 각화사에서 2Km 떨어진 곳에는 조선왕조실록을 보관하던 조선 5대사고 가운데 하나인 태백산고지지(사적348호)가 위치하고 있으며 산림이 무성하여 찾기가 힘들고 오전에 등반해야 하산을 할 수 있다.", - "MNTN_HG_VL" : "1176", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 춘양면", - "MNTN_NM" : "각화산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "225", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 연제구, 수영구", + "MNTN_NM" : "배산" }, - "longitude" : 128.9002778, - "latitude" : 37.009999999999998 + "longitude" : 129.09638889999999, + "latitude" : 35.18 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "각희산은 화암국민관광지에서 동대천 북쪽으로 병풍처럼 펼친 듯 솟아 있는 산이며, 동대천을 사이에 두고 행산과 화암약수터가 있는 군의산과 마주하고 있다. 동대천을 거슬러 올라가면 남전산과 지억산이 버티고 있다. 동대천변의 화암8경을 보려는 사람들의 발길은 끊이지 않는데 반해 각희산은 등산로가 잘 알려지지 않아 아직 태고의 신비를 고스란히 간직하고 있다. 각희산 바로 옆 행산과 군의산, 남전산과 지억산이 어깨를 두르고 있다. 정상에서 보면 청옥산, 민둥산이 보이고 그 뒤로 두위봉도 보인다. 각희산은 예로부터 신성시하여 나라에서 벌채를 금지했던 곳으로 알려져 있다.", - "MNTN_HG_VL" : "1083", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면, 임계면", - "MNTN_NM" : "각희산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", + "MNTN_NM" : "안락산" }, - "longitude" : 128.81333330000001, - "latitude" : 37.360833300000003 + "longitude" : 126.88249999999999, + "latitude" : 36.694722200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "502", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면 신기리", - "MNTN_NM" : "간대산" + "DETAIL_INFO_DTCONT" : "행정구역은 통영시지만 삼천포 앞 바다에 떠 있는 사량도에 있는 산으로 다도해 풍정이 물씬나는 한려해상국립공원에 자리잡고 있다. 우리 나라에서 대표적인 지리산과 이름이 같지만 원래 이름은 지이망산이다. 지리산이 바라보이는 산이란 뜻을 가졌다가 부르기 쉽게 줄여 육지의 지리산과 같은 이름으로 쓰이고 있다로 한다.3개의 유인도와 8개의 무인도로 이루어져 있는데, 주섬인 윗섬(상도)과 아랫섬(하도) 사이가 마주보고 그리 멀리 떨어져 있지 않아 호수처럼 잔잔하며, 윗섬의 중앙을 가로지르는 지리산, 불모산, 가마봉, 옥녀봉이 능선으로 연결되어 함께 산행을 할 수 있다. 지리산이나 옥녀봉만을 오를 수도 있고, 지리산부터 옥녀봉까지 종주할 수 있다. 옥녀봉의 암릉은 전설만큼이나 처절하리만치 빼어난 산세를 지니고 있어, 설악산의 용아릉을 연상케 할 만큼 기암괴봉과 경치가 뛰어난 곳이다. 바다와 산을 함께 즐길 수 있는 산행으로 재미를 더해 주지만 암봉, 고암릉으로 이어지는 능선길이 다소 험하다. 그러나 위험코스에는 우회코스가 있으며 등산로가 잘 정비되어 있고 안내표지가 잘되어있다. 초보자는 가급적 우회코스로 산행을 하고 세심한 주의가 필요하다.사량도의 8개 섬 중 상도(上島)에 동서로 길게 뻗은 산줄기 중 돈지리쪽의 제일 높은 봉우리로서, 한려수도의 빼어난 경관과 어우러져 '한반도 남단 최고의 비경'으로 꼽힌다. 산이름은 '지리산이 바라보이는 산'이란 뜻으로, 현지에서는 부르기 쉽게 줄여서 흔히 지리산이라고 한다. 바위산으로서 불모산(佛母山:399m)·가마봉(303m)·향봉(香峰)·옥녀봉(玉女峰:281m) 등과 연봉을 이루고 있어 함께 산행을 할 수 있는데, 높이는 낮아도 정상부의 바위산이 기암괴석을 형성하고 있으며 조망도 좋고 기묘한 바위능선으로 유명하다. 기암절벽과 경치가 뛰어난 옥녀봉에는 자기 딸에게 욕정을 품은 아버지와 그 딸 옥녀의 전설이 전해내려오고 있다. 사량도는 섬이 뱀처럼 생기고, 또 뱀이 많다고 해서 붙여진 이름이다.", + "MNTN_HG_VL" : "398", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면 (사량도)", + "MNTN_NM" : "지리산" }, - "longitude" : 129.09671549999999, - "latitude" : 37.343407200000001 + "longitude" : 128.18587239999999, + "latitude" : 34.8472443 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "간월산은 왕봉재(간월재)에서 천화현(배내고개) 사이에 해발 1068.8m 고봉 일대를 말하는 것으로 상북면 등억에서 배내에 걸쳐 있다. 간(肝)은 우리 민족이 오래 전부터 써오던 신성이라는 뜻이며 월(月)은 신명이라 하여에서 유래되어 평원을 의미하는 벌의 뜻이다. 그러므로 간월산은 평원이 있는 신성한 산으로 신불산과 밝얼산과 같은 뜻을 지니고 있다. 또한 간월이라는 이름은 다음과 같이 肝月, 看月, 澗月, 澗越, 肝越 등 다양하게 쓰이기도 한다.한반도의 남동단인 영남지방에 해발 1000m가 넘는 고헌산, 가지산, 운문산, 천황산, 간월산, 신불산, 취서산 등의 준봉이 일대 산군을 이루며 솟아 있는데 이 산군을 유럽의 알프스와 풍광이 버금간다는 뜻에서 영남알프스라하고 영남 산악인들에게는 천혜의 등산대상이 되고 있는 곳이다.간월산은 신불산 북쪽의 준봉으로서\"영남 알프스\"의 일부분을 구성하고 있으며 홍류폭포 등의 절경과 최근 자연휴양림이 조성돼 찾는 이들이 많아졌다.간월산에서 발원해 언양 쪽으로 흐르는 시냇물 작괘천은 각양각색의 바위들 사이로 옥류가 굽이치는 아름다움은 절경이다. 간월산 기슭의 등억온천은 게르마늄 함량이 높아 피부병과 무좀에 특효가 있고 당뇨와 고혈압, 신경통 등에도 효험이 있는 것으로 알려져 있다.억새가 만개하는 가을, 봄 순으로 많이 찾는다. 억새 테마산행을 위한 간월산-신불산-영축산 연계산행의 산행기점으로도 인기 있다.", - "MNTN_HG_VL" : "1069", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "간월산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "391", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", + "MNTN_NM" : "관모산" }, - "longitude" : 129.04077340000001, - "latitude" : 35.551204400000003 + "longitude" : 126.8583333, + "latitude" : 36.6969444 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "기암괴봉과 깍아지른 바위벼랑이 한 폭의 동양화처럼 아름답고 능선이 반원형으로 가운데가 깊숙한 골을 이루며 암벽들이 산기슭을 감돌아 흐르는 금강줄기와 어울러져 경관을 자랑한다.또한 천태산, 서대산등 주변의 산 군을 바라볼 수 있는 조망이 좋은 산이다.", - "MNTN_HG_VL" : "585", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", - "MNTN_NM" : "갈기산" + "DETAIL_INFO_DTCONT" : "제주시에서 동쪽으로 48km 떨어져 있는 성산포 바닷가에는 삼면이 바다로 둘러싸인 성산반도의 위쪽에 분화구로 이루어진 돌산이 있다.이곳이 바로 아름다운 성산일출봉인데, 한덩이의 왕관같은 99개 기암 봉우리와 짙푸른 바다 위를 솟아 오르는 아침 햇살이 장관을 이룬다.", + "MNTN_HG_VL" : "182", + "MNTN_LOCPLC_REGION_NM" : "제주도 남제주군 성산읍 성산리 114", + "MNTN_NM" : "성산 일출봉" }, - "longitude" : 127.6280556, - "latitude" : 36.116666700000003 + "longitude" : 126.9425, + "latitude" : 33.458056000000013 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "갈기산(585m)의 갈기는 말이나 사자의 갈기를 의미하는 것으로, 산행 중 만나는 울퉁불퉁한 바위능선길이 마치 갈기를 닮았다고 해서 붙여진 이름이다. 산 이름 속에 산세가 내포된 특이한 케이스다.이름 그대로 바위가 많은 갈기산은 산기슭을 휘감은 금강 줄기와 어우러져 흔치 않은 경관을 이룬다. 바위 낭떠러지라는 의미의 영동 일대 사투리인 '덜게기'는 금강 쪽으로 수 백길의 절벽을 이루고 있고 강 주변의 들녘은 한폭의 한국화를 연상시킨다. 주능선 좌우의 절벽은 남성적인 모습을 보인다. 암릉산행의 묘미를 느끼게 하면서도 정상에서는 그림 같이 흐르는 금강을 보여주며 부드러운 조망을 선물한다.금강을 중심으로 천태산과 마주보고 있는 갈기산은 천태산 때문에 상대적으로 관심을 덜 받아 왔지만 지금은 산꾼들의 입소문을 타면서 찾는 이가 많다. 등산코스는 크게 세 가지다. 주차장에서 정상을 밟고 관광농원으로 하산하거나 주차장에서 정상을 밟고 570봉과 560봉을 차례로 밟으며 소골재에서 소골로 길을 잡아 하산하는 길. 그리고 소골재에서 월영봉을 밟고 485봉을 지나 소골로 하산하는 길이 있다.", - "MNTN_HG_VL" : "585", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 양산면", - "MNTN_NM" : "갈기산" - }, - "longitude" : 127.6280556, - "latitude" : 36.116666700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "용두리에서 홍천 방향으로 이어지는 44번 국도 동쪽 옆에 솟아 있는 갈기산은 산 높이는 낮으나 능선 곳곳에 바위가 돌출 되어 전망이 좋은 산이다. 봄이면 바위들과 진달래, 철쭉이 어우러져 고운 빛깔로 물들이고, 가을이면 형형색색의 단풍으로 자태를 뽐내는 산으로, 유명 산에 비해 한적하고 쾌적한 산행을 하기에 안성맞춤인 산이다.국토지리정보원 발행 지형도상 갈기산의 한자 표기는 칡 '갈' 자에 터 '기' 자를 쓴 '葛基山'이지만 과거에는 일어날 기(起)자를 썼다고 한다. 구한말 기록에는 부동산(不動産), 그 이전에는 감물악(甘勿岳)이라고 불렀다고 한다.정상 주변은 온통 암릉으로 되어 있어 전망이 좋으나 주의를 요하는 곳이다. 계곡이 깨끗하고 물이 차가워 송어 양식에 적합한 장소로 산자락에는 송어회집이 여러 곳 있다.", - "MNTN_HG_VL" : "685", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 홍천군", - "MNTN_NM" : "갈기산" + "DETAIL_INFO_DTCONT" : "까치산은 경상북도 청도군 운문면 방음리 말음 마을에 있다.말음 마울의 말음의 뜻은 계곡의 경관이 빼어나고 산중유곡이라 하여, 옛날에 신선과 선녀들이 모여 놀던 곳으로, 선녀들이 노닐 때마다 부르는 노래 소리가 언제나 끝 후렴만 들려오고 주된 부분은 들리지 않아 끝소리를 다서 말음이라 한 것이 마을 이름으로 되었다.산행들머리는 방음리에 내려 포장길안으로 100m 쯤 마을로 들어서면 ‘원두막’이라는 간판이 보이고 그 위에 2채의 빨간 벽돌집이 보인다.", + "MNTN_HG_VL" : "571", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면 방음리", + "MNTN_NM" : "까치산" }, - "longitude" : 127.7844462, - "latitude" : 37.578187 + "longitude" : 128.94111179999999, + "latitude" : 35.702323399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "촉새봉(십자봉,985m)에서 남쪽으로 강원도와 충청북도를 가르며 뻗어 내린 능선이 옥녀봉에 이르면 동쪽과 서쪽으로 갈라진다.옥녀봉에서 동쪽으로 이어지는 능선은 시루봉(734m), 비지재, 강승갱이재를 지나 오청산(655m)으로 이어지고, 서쪽으로 가지를 친 능선상의 최고봉이 갈미봉이다. 갈미봉에서 남서쪽으로 능선이 휘어지며 세가닥으로 능선이 갈라져, 목계의 제내편봉(288m), 오량리의 묵봉산(490m)과 청계봉(390m)을 일으키고 그 여맥을 남한강 물 속으로 잠긴다.갈미봉 정상은 약 20여평의 공터로 둘레를 참나무와 잡목으로 울타리를 친 듯 둘러싸여 있는 게 흠이다.", - "MNTN_HG_VL" : "595", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 충주시", - "MNTN_NM" : "갈미봉" + "DETAIL_INFO_DTCONT" : "목포시 동쪽에 상동과 용해동에 걸쳐있는 해발 110m 산이다.산중턱에는 체육시설이 있으며 정상에서 바라보면 목포 구도심과 하당신도심 그리고남악신도심을 한눈에 볼 수 있다. 입암산 동남쪽 바닷가에 갓을 쓰고 있는 듯한 바위가 있어 이를 갓바위라 하는데갓바위가 있는 산이라 하여 갓바위산, 입암산이라 하였다 한다.목포팔경 중 입암반조(笠岩返照)라 하여 저녁노을에 물든 바닷가의 갓바위와바위절벽으로 된 입암산에 반사되는 저녁노을의 아름다움을 노래하고 있다.", + "MNTN_HG_VL" : "110", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 상동", + "MNTN_NM" : "입암산" }, - "longitude" : 127.9080556, - "latitude" : 37.167222199999998 + "longitude" : 126.4152778, + "latitude" : 34.796111099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "갈전산은 산청,거창군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳 경계에서 양분 되어 한줄기는 덕갈산을 거쳐 생초면 소재지 방향으로 달리고 다른 한줄기가 바로 갈전산을 거쳐 철마산, 소룡산, 바랑산을 거쳐 황매산으로 길게 이어져 있다.갈전산은 덕갈산과 마주보고 있어 생초면소재지 까지 뻗어 있는 덕갈산 줄기를 조망하기에 좋은 곳이다. 날씨가 좋으면 덕유산과 함양군의 고봉들도 조망이 가능하며 지리산과 그 아래 산들도 조 망이 가능하다. 갈전산은 규모가 크거나 산세가 수려하지는 않다. 하지만 이웃한 철마산과 함께 연결하여 산세를 본다면 결코 작은 산이라고 말할 수 없다.", - "MNTN_HG_VL" : "764", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 생초면", - "MNTN_NM" : "갈전산" + "DETAIL_INFO_DTCONT" : "어룡산은 경북 8경인 진남교반을 사이에 두고 오정산(805m)과 마주보고 있는 산이다. 오정산 쪽의 고모산성과 함께 이 산의 고부산성이 옛 길인 `토끼비리'를 지키고 있다.영강가에 솟은 미봉 어룡산은 작은 것이 아름답다는 것을 깨닫게 하는 산이다. 문경읍을 거쳐 20분 정도 달리면 강변을 따라 병풍을 둘러친 듯 기암괴석이 보이는 곳이 있는데 여기가 바로 유명한 경북팔경 중의 제1경으로 일컫는 진남교반이다. 경북 도민이 제 1경으로 꼽을 만큼 절경지인 영강 진남교 옆에 솟아있는 어룡산은 산속으로 들어서면 넋을 잃기 마련이다.울창한 숲과 영강과 어우러진 산세가 절경이기때문이다.이 진남교반을 끼고있는 어룡산은 많은 전설과 얘기가 전해오고 있으며, 고모산성과 돌고개, 성황당, 그리고 영남대로의 옛 모습을 그대로 잘 간직하고 있는 관갑천(토천,토끼비리)이 있고 진남유원지와 휴게소에는 지나는 사람들의 발길이 끊이질 않는다.작은 암봉이 있는 정상에 서면 보면 주흘산과 백화산이 눈앞에 있으며 멀리 산군들이 첩첩이 펼쳐 보인다. 어룡산은 주변의 풍광이 수려하고 볼거리와 즐길거리가 많으며 아래 영강에는 여름철 강수욕과 피서지로 이름나 있는 곳이다. 문경읍에는 보양천인 문경온천이 있다. 봄, 여름 산행지로 인기가 높은 곳이다. 또 황티기국, 부곡숫굴, 부곡암굴 등 동굴이 산 곳곳에 산재해 있다.", + "MNTN_HG_VL" : "617", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면", + "MNTN_NM" : "어룡산" }, - "longitude" : 127.866356, - "latitude" : 35.556904500000002 + "longitude" : 128.1147469, + "latitude" : 36.6442786 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "예로부터 수덕이 뛰어나 삼각산의 영광을 뒷받침한 경기 오악중 북악에 속하는 이 산은 지형적 특성으로 삼국시대에부터 전략적인 요충지로 6.25전쟁 때까지 치열한 격전이 있던 곳이다. 그런 연유로 산자락 설마치계곡 양쪽으로 영국군 전전비와 대한의열단 전적비가 세워져 있다. 바위 사이로 검은빛과 푸른빛이 동시에 흘러나온다 하여 감악(紺岳), 즉 감색바위라고 하였다.또한 조선 명종때 구월산 청석골을 거점으로 활약하던 임꺽정의 중간거점이 있던 곳으로 그와 연관된 지명이 곳곳에 산재해 있다. 정상에는 현재도 군사시설이 있으며, 북한산 진흥왕 순수비와 유사한 일명 삐뜰대왕비 설인귀비가 위치해 있다. 이 비는 아직도 전쟁때 탄흔자국을 가지고 있으며 파주군 향토유적 제 8호로 지정되어 있다. 전체적인 산세는 암릉과 작은 암봉들이 조화를 이루고 있으며 간간이 절벽지대가 있으므로 주의를 요한다.원래 감악사, 운계사, 범륜사, 운림사 등의 4개 사찰이 있었다는데 현재는 1970년 옛 운계사 터에 재창건한 범륜사만 남아 있다.서울에서 그리 멀지 않으며, 의정부 북쪽 회천에서 양주시 남면을 지나 설마리를 거쳐 감악산 계곡을 따라 들어가면 높이 20여 미터에 달하는 운계폭포가 나온다. 폭포 뒤로 범륜사가 있고 그뒤로 전형적인 암산의 모습을 띤 감악산이 보인다. 맑은 날에는 개성의 송악산과 북한산이 보인다.", - "MNTN_HG_VL" : "675", - "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 남면, 연천군 전곡읍, 파주시 적성면", - "MNTN_NM" : "감악산" + "DETAIL_INFO_DTCONT" : "구좌읍 송당리 동족에 비자림(돌오름)과 용눈이오름 사이에 우뚝 솟아있는 매끈한 풀밭오름으로 그 위용을 자랑하며, 구좌읍을 대표하는 오름이라고 할 수 있다. 비단 치마에 몸을 감싼 여인처럼 우아한 몸맵시가 가을 하늘에 말쑥하다. 정상에 분화구가 남아 있는데, 그것이 흡사 달처럼 둥글게 보인다고 하여 현지 주민들 사이에서는 ‘다랑쉬(다:달, 쉬:뫼)’라는 이름으로 불러왔다.행정 구역상 세화리에 속하며 서쪽 일부가 송당리에 걸쳐있어 쉽게 접근 할 수 있다. 월랑봉이라는 이름에서도 알 수 있듯이 달과 연관이 많은 듯한 이 오름에서의 보름달맞이는 장관이라 한다.", + "MNTN_HG_VL" : "382", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍 세화리", + "MNTN_NM" : "월랑봉" }, - "longitude" : 126.9689597, - "latitude" : 37.941738699999988 + "longitude" : 126.82139429999999, + "latitude" : 33.473882400000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "925", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "감악산" + "MNTN_HG_VL" : "794", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "수덕산" }, - "longitude" : 127.92212739999999, - "latitude" : 35.596956200000001 + "longitude" : 127.5135183, + "latitude" : 37.915029699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "지리산 자락을 밟는 근교산행은 언제나 산꾼들을 설레게 한다. 어디라 할 것 없이 속속들이 드러나 있을 것 같은 이\"어머니산\"의 또다른 속내를 경험해 볼 수 있기 때문이다. 다 같은 무명의 봉우리들이라도 지리산의 혈통을 이어 받았다면 여러가지 면에서 양상이 달라진다. 산의 기세가 다르고, 조망이 다르고, 오르는 사람들의 감흥이 다르다.감투봉,이방산(二方山)은 구곡산 같이 지리산 위성봉으로서 천왕봉 산행이 곤란할때 적절하게 이용할 수 있는 매력있는 산인데 등산로가 명확하지 않아 독도에 자신이 있어야 즐거운 산행이 보장되나 무엇보다 원시림 그대로이기 때문에 매력만점 산행지로는 손색이 없는 산이다.이방산 등산로 입구의 덕교리 마을 앞에는 파구정이란 곳이 있는데 임진왜란 때에 손씨 3형제가 이끄는 의병들이 잠복하였다가 왜적을 맞아서 싸워 이긴 곳으로 왜구를 파멸시켰다고 하여 이런 이름이 유래하였다.삼장면과 시천면 사이에 우뚝 솟은 이방산은 임진왜란 때 의병을 일으킨 유서 깊은 곳으로서 그 발자취가 역력하며, 삼장면 덕교리에서 해발 600미터에 이르는 이방산을 넘어서면 시천면 사리인 마근담에 이르게 되는데 이곳은 웅석봉에서 남으로 뻗은 지맥이 갈라진 골짜기로 인적이 드문 깊은 산골이다.", - "MNTN_HG_VL" : "768", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 시천면 사리", - "MNTN_NM" : "감투봉" + "DETAIL_INFO_DTCONT" : "서울의 진산 북한산은 조선조 초기에는 삼각산(三角山)으로 불렀다. 삼각산이란 이름은 〈신증동국여지승람〉에 '삼각산은 양주의 경계에 있다. 일명 화산(華山)이라 하고, 신라시대에는 부아악(負兒岳)이라고 불렀다.이 산은 경성(京城)의 진산으로 동명왕의 아들 온조가 한산(漢山)에 이르러 부아악에 올라가서 살 만한 곳을 살폈다'는 기록이 있으며, '백운봉 (白雲峰, 지금의 백운대), 인수봉 (仁壽峰), 만경봉 (萬景峰,지금의 만경대)등 세 봉우리가 있으므로 그렇게 이름한 것이다'라고 유래를 기록하고 있다. 북한산성에 대해서는 〈신증동국여지승람〉과 〈북한지〉에 상세히 기록되어 있다. 북한산성은 백제 온조왕이 터를 잡았고 그후 개루왕 때 성터를 쌓았다는 기록이 있으며, 조선시대에 임진왜란, 병자호란을 치른 뒤 숙종 37년(1711년)에 시작하여, 6개월 만인 그해 10월에 완공하였다 한다.북한산성은 험한 산세를 이용하여 정상을 기점으로 서쪽 산자락부터 원효봉, 염초봉, 백운대, 만경대, 용암봉, 문수봉, 나한봉, 나월봉, 용출봉, 의상봉까지 연결하여 쌓은 산성으로 총 길이가 10km에 달한다. 당시 산성에는 14개의 성문을 냈는데, 산성의 정문 격인 대서문을 중심으로 북쪽으로 수문, 서암문(시구문), 북문, 백운대를 지나 위문, 용암문, 대동문, 보국문, 대성문, 대남문, 청수동암문, 대서문에서 북서쪽으로 이어지는 산성에는, 부황동암문, 가사동암문이 설치되었다.현재는 대부분 성문을 복원하였다. 북한산에 수많은 등산로 거미줄 같이 얽혀 있어 산행시 주의를 요하는 곳이다. 북한산의 산행 들머리는 대표적으로 여섯 군데를 꼽고 있다. 우이동 기점, 4.19탑 기점, 정릉 기점, 세검정 기점, 불광동 기점, 구파발 북한산성 기점으로 구분할 수 있다.", + "MNTN_HG_VL" : "836", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강북구ㆍ성북구ㆍ종로구ㆍ은평구, 경기도 고양시ㆍ양주시", + "MNTN_NM" : "북한산" }, - "longitude" : 127.8411984, - "latitude" : 35.304295199999999 + "longitude" : 126.99333300000001, + "latitude" : 37.660832999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "갑장산은 아름다움이 으뜸이요(甲), 사장(四長)을 이룬다는 뜻에서 그 이름이 비롯된 산이다. 고려 충렬왕이 승장사에서 잠시 쉬었다 가며 ‘영남의 으뜸 산’이라 하여 갑장이라 명명했다는 설도 전한다. 상산 삼악의 하나인 연악(淵岳)이라고도 한다. 연악이란 이름은 구룡연에서 유래되었다. 구룡연은 갑장사 뒤 사거리에서 웃승장 방향으로 50미터 정도 내려가면 우측에 있는데, 천제와 기우제를 지내던 신성스런 연못이다. 구룡연에서 북쪽으로 문필봉이 우뚝 솟아 있는데, 바위 3개가 붓처럼 뭉쳐져 있다. 이 문필봉의 정기를 받아 갑장산 주변에 장원급제한 인물들이 많이 나왔다고 하여 장원향이라는 이름을 남기기도 하였다. 용포 쪽에는 백운 이규보가 1196년 요양하며 시를 남긴 용담사터가 있고, 승장계곡에는 옥류정과 승장폭포, 그리고 상주 사장사(四長寺), 갑장사(甲長寺), 승장사(勝長寺), 북장사(北長寺), 남장사(南長寺)) 중 하나였던 승장사터가 있다. 갑장산 정상 부근에는 고려 공민왕 22년(1373) 나옹선사가 창건한 갑장사가 자리 잡고 있다.", - "MNTN_HG_VL" : "806", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 지천동, 낙동면", - "MNTN_NM" : "갑장산" + "DETAIL_INFO_DTCONT" : "경남 합천군 대병면에 자리하고 있는 악견산은 금성산, 허굴산과 더불어 합천의 삼산으로 불린다. 세 산은 합천호 부근에 옹기종기 모여 있다. 크고 작은 바위들이 들쭉날쭉 빚어내는 경관이 수려하고도 야무지다.악견산은 합천댐 설치로 더욱 돋보이게 되고 유명해졌다. 일반적으로 산의 정상은 암봉으로 되어 있거나 둥그스름한 봉우리로 되어 있는데 이 산의 정상은 집채만한 큰 바위들이 수없이 쌓이고 엉켜 정상부를 형성하고 있다. 이 산에서의 조망은 서쪽 능선따라 오르면서 뒤돌아 본 합천댐의 풍경이 매우 아름답다.악견산에는 임진왜란 때 왜적과 격전을 벌였던 악견산성이 남아있다. 이곳은 임진왜란 때 민중의 영웅으로 이름을 떨친 의병장 곽재우 장군의 전설이 담겨 있어 의구한 역사도 깃들어 있는 곳이다. 악견산성(경남 기념물 제218호)은 1439년(세종 21)에 축조된 테뫼식 산성으로 임진왜란 때(1594년) 유성룡의 지시를 받아 성주 목사로 있던 곽재우가 보수공사를 했다고 한다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", + "MNTN_NM" : "악견산" }, - "longitude" : 128.1886111, - "latitude" : 36.347222199999997 + "longitude" : 128.0494783, + "latitude" : 35.531882899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "갑하산은 계룡산국립공원에 인접해 있는 아기자기한 암릉과 숲이 잘 어우러진 전망이 좋은 산이다. 유성에서 계룡산의 동학사 가는 길목 옆에 자리 잡고 있어 접근하기도 쉽고 산세가 험하지 않아 어느 때 찾아가도 등산의 재미를 만끽할 수 있다. 특히, 봄에는 온 산에 진달래가 붉게 물들고 여름에는 안진바위 골짜기의 넓은 암반과 폭포가 시원하며, 가을 단풍과 겨울의 설경이 아름답다. 산 이름은 옛날에 이 지역이 갑소여서 갑골, 갑동의 지명에서 유래된 듯하며, 이 산은 세 개의 봉우리가 불상을 닮았다고 하여 삼불봉이라고 부르기도 한다. 이 산 아래의 안진바위마을은 조선 태종 임금이 유성에서 목욕을 하고 신도안으로 갈 때 냇가의 바위에서 쉬어 갔다고 해서 유래됐고, 두리봉 아래의 매평마을은 매화낙지형의 명당자리여서 사람들이 모여 살았었는데 현재는 국립대전현충원이 자리 잡고 있다.<>우산봉은 계룡산 천황봉에서 산줄기가 백운봉, 도덕봉을 휘돌아 갑하산을 거쳐 치달리다가 금강에 떨어지기 전에 불끈 솟아 올린 봉우리이다. 이 산의 등마루는 숲과 암릉이 적당히 어우러진 가운데, 특히 소나무가 많아서 걷기가 편하고 봄에는 진달래와 철쭉이 흐드러지게 피어난다.", + "DETAIL_INFO_DTCONT" : "월아산은 해맞이, 달맞이가 아름다운 산으로 봉긋한 두 봉우리 사이로 수줍게 떠오르는 해와 달은 한 폭의 그림이다. 달을 토해내듯하다는 월아산은 산이 구릉을 이루고 있지만 숲이 아름답고 아담해 가족 단위 등산인들이 주말을 이용해 즐겨 찾는 산이다. 월아산은 장군대산과 이어지는데 장군대산 높이도 482.4미터밖에 되지 않아 한나절 산행으로 알맞다.진주 동쪽에 있는 월아산은 나라에 한발이 계속되면 나라에서 기우제를 지내던 곳으로 일명 ‘무제등’이라고도 한다. 1950년대까지도 기우제를 지냈다는 기록이 남아있다.산행 들머리는 갈전리의 청곡사와 용아리의 금호지 또는 질매재에서 시작한다. 갈전리 청곡사에서 할 경우 장군대산과 월아산 국사봉을 무리하지 않고 종주할 수 있어 좋다. 표식기가 많이 붙어있으며 등산로 중간에 땀을 식힐 수 있는 편의시설이 갖추어져 있다. 날머리 금호지는 커다란 자연 호수로 물이 맑고 푸르며 깊이가 깊어 명주실 3꾸리가 들어갔다는 전설이 있다. 그러나 지금은 제방둑을 쌓아 농업용 저수지로 만들어놓았다.산행 들머리에 있는 청곡사는 신라 헌강왕 5년에 도선국사가 창건한 절로 남강의 청학이 월아산으로 날아드니 사기가 충만함을 보고 정해진 절터라 전해온다. 절 입구에 있는 방학교와 ‘학을 불러들인다’는 뜻의 환학루가 이 전설을 뒷받침하고 있다.", "MNTN_HG_VL" : "469", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성구·충남 공주시 반포면", - "MNTN_NM" : "갑하산" + "MNTN_LOCPLC_REGION_NM" : "경남 진주시 금산면ㆍ진성면", + "MNTN_NM" : "월아산" }, - "longitude" : 127.27722369999999, - "latitude" : 36.367463499999999 + "longitude" : 128.1900574, + "latitude" : 35.191648100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 포천군과 가평군의 경계를 이루는 강씨봉은 옛날 이 곳에 강씨가 모여 살았다 하여 붙여진 이름이라 한다. 강씨봉에서 동남쪽으로 뻗어 내리는 능선 길에 강씨봉고개가 있으며, 고갯마루에서 동쪽 아래에 강씨봉 마을터가 남아있다.전체 산세가 완만하고 부드러워 산행이 힘들지 않으며, 한나무골 계곡은 아직도 맑고 깨끗함을 간직하고 있다. 강씨봉은 포천시과 가평군을 경계로하는 아기자기한 등산코스를 지니고 있지만 주위에 유명한 산들이 많아, 등산객이 많지 않은 조용한 산행을 즐길 수 있어 가족산행지로 가볼만 하다.특히 겨울설경이 아름다우며 산꼭대기 좌우로 매우 아름다운 경관을 가진 산으로 한나무골의 계곡은 맑고 깨끗하다. 마지막 능선의 억새밭과 싸리나무, 봄철의 진달래와 철쭉이 어우러진 모습이 볼 만하다.", - "MNTN_HG_VL" : "830", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시, 가평군", - "MNTN_NM" : "강씨봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "무선산" }, - "longitude" : 127.38239059999999, - "latitude" : 37.969131699999998 + "longitude" : 127.6480638, + "latitude" : 34.7671888 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "순창읍에서 10km의 가까운 거리에 있는 강천산은 호남의 소금강이라고 불릴 정도로 도처에 기봉이 솟아 있고, 크고 작은 수많은 바위 사이로 폭포를 이루고 있으며, 4km에 이르는 깊은 계곡과 계곡을 뒤덮은 울창한 숲은 자연 그대로의 아름다움을 고이 간직하고 있다.원래는 생김새가 용이 꼬리를 치며 승천하는 모습과 닮았다 하여 용천산(龍天山)이라 불렸다. 또한 유서깊은 강천사와 삼인대 5층 석탑, 금성산성 등 문화유적이 산재하고, 비경이 많이 숨겨져 있다. 일명 광덕산이라고도 불리는 강천산은 1981년 국내에서 최초로 군립공원으로 지정된 곳이기도 하며, 길이 76m의 현수교가 지상 50m 높이에 설치돼 있어 웅장함을 더해주고 있다.볼거리는 11월 초순에 절정을 이루는 단풍과 4월 초순에 만개하는 산벚꽃이 유명한데, 산 입구의 강천호 주변뿐 아니라 등산로 어디에서나 즐길 수 있다. 산 암봉 아래에는 887년(신라 진성여왕 1) 도선국사(道詵國師)가 세운 강천사가 있다.이 곳의 석탑은 전라북도 유형문화재 92호로 지정되었고, 절 입구의 모과나무는 전라북도기념물 97호이다. 그 밖에 순창 삼인대(三印臺:전북유형문화재 27), 금성산성(金城山城:전북기념물 52) 등의 문화유적이 있다. 내장산(內藏山:763.5m)·백양사(白羊寺)·담양댐 등과도 가깝다.", - "MNTN_HG_VL" : "586", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 팔덕면, 전라남도 담양군 용면", - "MNTN_NM" : "강천산" + "DETAIL_INFO_DTCONT" : "경기도 포천군 일동면과 가평군 하면에 경계를 이루는 갈매봉은 갈매고개를 사이에 두고 청계산(849)과 마주 보고 있는 산이다. 시원한 계곡과 울창한 수림으로 휴식처가 많아 여름철 피서 산행지로 안성맞춤이다.주능선은 바위로 되어 있어 아기자기한 암릉산행에 묘미를 느낄 수 있으며, 아찔한 바위능선을 지나는 스릴도 만끽 할 수 있다.산행기점에는 청계 저수지가 자리하고 있어서 등산과 낚시를 함께 즐길 수 있는 가족 산행지로 적합하다. 갈매재를 기준으로 동쪽(하판리 방향)은 군 사격장으로 출입이 통제되는 지역임으로 주의를 해야 한다.길매봉은 청계산(849m)과 운악산 사이에 위치한 산으로 주능선과 지능선 상에 암릉지대가 많고 주능선 북사면 하단부 높이 10m, 중단부 10m, 상단부 20m나 되는 복계폭포가 있다.길매재, 바위능선을 거쳐 정상에 이른다. 정상 조망은 시원하다. 우선 청계산 방면으로는 청계산 뒤로 국망봉으로부터 흘러오는 한북정맥이 넘실거린다. 청계산 오른쪽으로는 명지산이 하늘금을 이루고, 명지산에서 시계바늘 방향으로는 아재비고개, 월출산, 전패봉, 매봉 등이 한줄로 이어져 시야에 들어온다.남으로는 하판리를 가래질한 듯 패어져 나간 조종천 계곡과 그 오른쪽으로 운악산이 피라밋처럼 우뚝 솟아 있다.북서쪽 아래로는 청계저수지로 패어져 내린 계곡이 한눈에 내려다보인다.", + "MNTN_HG_VL" : "735", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", + "MNTN_NM" : "길매봉" }, - "longitude" : 127.048889, - "latitude" : 35.404167000000001 + "longitude" : 127.4158333, + "latitude" : 37.856666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "379", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 대전", - "MNTN_NM" : "개머리산" + "DETAIL_INFO_DTCONT" : "마이산은 옛날 용출산, 동금산 등으로 불려 오다가 이조때 태종이 말 귀를 닮았다고 한 뒤부터 마이산이라 칭하게 됐다. 재미있는 것은 마이산은 바라보는 방향에 따라 그 모습이 달라 보인다는 것이다.그래서 마이산의 기이한 모습과 특이한 경관 때문에 여러 가지 이름을 갖고 있다. 붓끝같다해서 문필봉, 바위가 많아서 개골산, 방향을 달리해 보면 돛대를 닮아 돛대봉, 용의 뿔 같다해서 용각봉 등으로 불려진다.마이산은 동서로 큰 암수봉우리 두개가 있다. 동편 숫봉우리는 거대한 남성을 닮았다 하여 서다산(西多山)이라는 옛 이름도 지니고 있는데, 강한 양기를 품고 있어 산길이 험준하여 등산을 할 수가 없다. 서편에 있는 암마이봉은 나긋나긋하게 손짓하는 여성처럼 많은 등산객을 맞이하고 있다. 마이산에서 북쪽으로 흐르는 물은 금강 물줄기를 이루고, 남쪽으로 흐르는 물줄기는 섬진강으로 흐른다. 그 흐름이 반원을 그리고 있어 마이산은 금강과 섬진강의 분수령이 되고 있으며 두 강의 물줄기는 마이산을 중심으로 태극을 이루고 있다.마이산은 조선을 개국한 이성계와 인연이 깊은 산이다. 이성계는 마이산을 속금산(束金山)이라 불렀다. 일찍이 큰 꿈을 품었던 이성계는 금산 등 전국 각지의 명산을 찾아 기도를 올렸는데, 기도가 끝난 어느 날 밤 꿈에 신이 나타나 금척(모든 제도의 표준임을 말하며를 마음대로 헤아리도록 하라\"\"라고 했다 한다. 그 뒤 고려 우왕 6년(1380년) 고려의 장군 이성계는 전라도 운봉땅 황산에서 왜구를 무찌르고 개선 길에 마이산을 보고 놀랐다. 꿈에 신에게서 금척을 받은 장소가 바로 마이산이기 때문이었다.", + "MNTN_HG_VL" : "687", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍ㆍ마령면", + "MNTN_NM" : "마이산" }, - "longitude" : 127.4697881, - "latitude" : 36.387103499999988 + "longitude" : 127.404811, + "latitude" : 35.762177399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "개이빨산은 경기도 포천군 이동면과 가평군 북면의 경계를 이루는 산으로 국망봉(國望峰.1,168m)과 강씨봉(姜氏峰.830m) 사이에 위치해 있다.멀리서 이 산 정상부를 바라보면 정상 일원의 능선 10여개가 톱니처럼 돌출돼 있어 마치 개이빨을 연상케해 이 산의 이름을 개이빨산이라 부르게 된 것이다. 때문에 산자락에 사는 주민들은 이 산을 일명 견치산(犬齒山), 또는 견아산(犬牙山)이라 불러 왔다고 한다.", - "MNTN_HG_VL" : "1110", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 포천군", - "MNTN_NM" : "개이빨산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1241", + "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상북도 청도군, 경상남도 밀양시", + "MNTN_NM" : "가지산" }, - "longitude" : 127.32489889999999, - "latitude" : 37.878003 + "longitude" : 129.00305599999999, + "latitude" : 35.621110999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "오대산을 지나 설악산으로 달리던 백두대간이 갈전곡봉에 이르러 서쪽으로 가지를 뻗은 산이 개인산이다.<>개인산은 개인, 삼봉, 방동약수로 유명하며 이 약수 섞인 물은 개인산의 북면을 흐르는 방대천과 서남면을 돌아가 방대천을 합하는 20킬로미터의 내린천으로 흘러들어 차례로 소양강, 북한강, 한강이 된다. 계곡은 수려하나 보이지 않고 산날은 치솟았지만 바위를 드러내지 않는다. 공기 좋고 물이 맑아 전염병이 들지 않고 먹거리가 많다. 입구는 좁고 안은 너른 형세다.<>이런 곳은 여덟 군데 살둔, 달둔, 월둔, 아침가리, 명지가리, 적가리, 곁가리, 연가리의 ‘삼둔오갈’을 두었는데 물, 불, 바람 즉 흉년, 전염병, 전쟁을 피할 수 있는 곳으로 내우외환이 끊이지 않았던 불행한 시대에 개인산은 많은 민추들을 보듬어 주었음을 역사는 전한다. 그리하여 개인산은 지리산과 금강산처럼 장엄하거나 빼어나진 않지만 그 어느 것보다 한국적인 산이다.", - "MNTN_HG_VL" : "1342", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 상남면ㆍ홍천군 내면", - "MNTN_NM" : "개인산" + "DETAIL_INFO_DTCONT" : "경기도 양주시 주내면에 위치한 불곡산(일명 불국산)은 작은 규모에 비해서 암릉이 많은, 아기자기하고 길게 이어지는 바위산이라 스릴 있으면서도 위험하지 않아서 산행의 묘미를 한껏 즐길 수 있는 산이다.의정부에서 시내버스로 10분이면 등산기점에 이를 수 있어 교통이 편리하고 서울 근교에 위치하여 당일 산행으로 제격이며 인적도 많지 않아 호젓한 산행지로 선택하기 좋다.산행은 유양리 백화암에서 출발, 부흥사로 하산할 수 있고 부흥사에서 산행을 시작해 백화암으로 하산하는 역코스도 있다. 불곡산은 옛날에 회양목이 많아서 겨울이 되면 빨갛게 물든다 하여 붙여진 이름이라한다. 산중턱에는 500여년쯤 된 우람한 느티나무와 신라시대 고찰인 백화암이 있다. 불곡산은 국립지리원에서 낸 지도에는 ‘불국산(佛國山)’으로 표기되어 있다. 그러나 「산경표」 한북정맥편에는 ‘불곡산’이라고 또렷이 적고 있다.불곡산은 갖가지 모양의 바위 전시장이다. 보는 이에 따라 온갖 모양이 연출된다. 너럭바위, 곰바위, 고양이바위, 투구바위, 상투바위, 산파바위, 시루떡바위 등 기묘한 바위를 찾으며 산행하는 것도 재미를 더한다. 불곡산 남쪽에 자리하고 있는 유양동에는 유양팔경이 전한다. 산성낙조, 기당폭포, 화암종성, 선동자화, 금화모연, 승학연루, 도봉제월, 수락귀운 등이다.", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 유양동", + "MNTN_NM" : "불곡산" }, - "longitude" : 128.4002778, - "latitude" : 37.861666700000001 + "longitude" : 127.02581929999999, + "latitude" : 37.799757100000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "449", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", - "MNTN_NM" : "개좌산" + "MNTN_HG_VL" : "299", + "MNTN_LOCPLC_REGION_NM" : "경기도 시흥", + "MNTN_NM" : "소래산" }, - "longitude" : 129.14583329999999, - "latitude" : 35.250555599999998 + "longitude" : 126.7789089, + "latitude" : 37.450962099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "128", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 강서구", - "MNTN_NM" : "개화산" + "DETAIL_INFO_DTCONT" : "경기도 여주군 강천면, 남한강이 휘감아 도는 자리에 보금산이 솟아 있다. 그러나 이 산은 솟아 있다는 말 자체가 무색하리 만치 낮은 산으로 해발 400미터가 채 안되는 봉우리이다.섬강과 남한강이 산을 둘러싸고 흘러 경치가 아름답다. 높지는 않지만, 등산로 곳곳에 암릉이 많다. 보금산에서 가장 뛰어난 풍경은 정상 부근에 있는 기암이다. 가파른 절벽 위에 있는 기암으로, 마귀할멈 측간바위라고 부른다. 마치 치마 입은 여인이 턱을 두 손에 괴고 앉아 있는 모습처럼 보여 눈길을 끈다산행은 당고개에서 시작한다. 이 고개는 삿갓재라고도 부르는데, 옛날에는 산적이 많았다고 전한다. 그래서 50명이 모여서야 겨우 이 고개를 넘었다고 하여, 오십명고개라고 부르기도 한다. 주변에는 1993년 불교목공예가 박찬수가 설립한 목아불교박물관이 있다. 또, 북내면에는 남한강변에 자리한 신륵사가 있다. 신라 진평왕 때 원효대사가 창건하였다고 전하며, 보물로 지정된 문화재가 다수 있다.", + "MNTN_HG_VL" : "364", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면", + "MNTN_NM" : "보금산" }, - "longitude" : 126.8038889, - "latitude" : 37.582777800000002 + "longitude" : 127.7236111, + "latitude" : 37.315277799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고성 동쪽의 거류면에 솟은 거류산은 고성의 진산이다. 기암과 청송, 진달래 산성 등 야산이 갖출 수 있는 조건들을 두루 갖추고 있다. 정상 가까이에 약수터가 있고 조망이 일품으로 다도해가 시원하게 보인다. 건너편 들녘에는 구절산이 보이고, 고성 전역과 한려해상의 전경이 한눈에 들어오는 산정에는 2천여 년 전 소가야 때 신라의 침공을 막기 위해 쌓은 거류산성의 흔적이 남아 있다. 이 성은 소가야 마지막 왕이 신라의 침입 때 피신처로 사용하였으나 신라가 가야를 합병함에 따라 폐성되었지만 곳곳에 산성의 자취가 남아 있고, 지금은 유적지로서 복원되었다. 소가야 때는 태조산(太朝山)이라 불렀고 조선 초기에는 거리산(巨吏山)으로, 조선 말엽에 거류산으로 부르게 되었다. 또한 거류산이 깎아지른 듯 삼각형 모양으로 서 있는 모습이 스위스의 마터호른을 닮았다고 해서 일명 고성의 ‘마터호른’으로 불리기도 한다.", - "MNTN_HG_VL" : "572", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 거류면", - "MNTN_NM" : "거류산" + "DETAIL_INFO_DTCONT" : "치악산국립공원에 속하는 삼봉은 치악산 정상인 비로봉(1288)에서 서북쪽으로 이어지는 능선 상에 솟아 있는 산이다. 삼봉을 지나면서부터 1km 간격으로 투구봉(1,002m), 토끼봉(887m)이 이어져 있다.삼봉에서 짜릿한 묘미를 즐기려는 이들은 낚시봉 코스를 선호한다. 삼거리에서 지능선으로 20분 오르면 약수터가 반기는 절터에 닿는다. 이 절터에서는 거리 100m를 두고 두 개의 샘이 있다. 그러나 관리가 되지 않아 늦가을이나 겨울에는 물에 낙엽이나 이물질들이 담기거나 얼어붙어 크게 기대할 것은 못된다. 두번째 샘터에서 숲속으로 15분 가량 올라가면 동쪽으로 이어지는 능선길을 밟는다. 이 능선길을 오르다가 참나무숲을 벗어나면 바윗길이 나타나기 시작한다. 바윗길은 급경사 바위를 피하느라 능선 좌우로 횡단하며 이어진다.삼각점(89년 재설)이 박혀있는 정상에서 휘둘러보는 조망은 막힘이 없다. 먼저 동으로는 도실암골 건너로 석탑 3기가 마치 쇠머리에 돋아난 뿔처럼 보이는 치악산 정상 비로봉이 천지봉과 함께 시야에 들어온다. 비로봉 정상에 오른 등산인들의 움직임도 뚜렷하다. 남쪽으로는 향로봉 능선이 꿈틀거린다. 향로봉에서 오른쪽 멀리로는 남대봉과 백운산이 하늘금을 이루고, 백운산 방향에서 오른쪽 아래로는 원주시내가 한눈에 내려다보인다.서쪽 조망도 일품이다. 흥양리 분지로 패어내린 범골, 밤나무골, 삼장골, 되미골 협곡이 아찔하게 내려다보이고 흥양리 오른쪽으로는 새말로 이어지는 영동고속도로가 실낱같다. 멀리로는 양평 용문산 정상이 가물거린다.", + "MNTN_HG_VL" : "1073", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", + "MNTN_NM" : "삼봉" }, - "longitude" : 128.37976710000001, - "latitude" : 34.995313600000003 + "longitude" : 128.03805560000001, + "latitude" : 37.370555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1184", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", - "MNTN_NM" : "거망산" + "DETAIL_INFO_DTCONT" : "담양의 명산인 병풍산은 담양군의 산 가운데 가장 높은 산으로 일명 용구산이라고도 한다. 담양군 수북면 소재지에서 이 산을 바라보면 왜 병풍산이라 했는지 쉽게 짐작할 수 있다. 오른쪽 투구봉을 시작으로 우뚝 솟은 옥녀봉, 중봉, 천자봉을 거쳐 정상인 깃대봉과 신선대까지 고르게 뻗은 산줄기는 한눈에 보아도 틀림없는 병풍이다.정상에서의 조망은 장관을 이루어 ‘강동8경’이라 한다. 북으로 내장산, 백암산, 입암산이 보이고 추월산, 담양읍내는 물론 지리산도 시야에 들어온다. 북동에서 남서쪽으로 길게 뻗은 병풍산은 등줄기 양옆으로 무수히 많은 작은 능선이 있는데 이 능선 사이에 일궈진 골짜기가 99개에 달한다.특히 한재골은 기암괴석과 푸른 송림 등 갖가지 수목이 울창하게 우거져 천혜의 경관을 자랑하고, 가을 단풍과 겨울 설경은 기이한 아름다움을 지니고 있다. 광주와 가까운 이곳은 매년 관광객이 증가하고 있어 야영지, 체육시설, 풀장, 조경시설 등을 갖추어 가고 있다.", + "MNTN_HG_VL" : "826", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 수북면, 월산면ㆍ장성군 북하면", + "MNTN_NM" : "병풍산(용구산)" }, - "longitude" : 127.7369444, - "latitude" : 35.683055600000003 + "longitude" : 126.88611109999999, + "latitude" : 35.325000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 평창군 용평면과 대화면 사이에 솟아 있는 거문산은 오대산에서 서쪽으로 뻗어 내린 산줄기가 계방산에 이르러 남쪽으로 이어지면서 백적산(1,141m)에서 서쪽으로 가지를 친 능선이 금당산(1,173m)을 빚어 놓고 그 여력으로 우뚝 솟은 산이다. 이 산을 일으키고 남쪽으로 뻗어 내린 지맥은 평창강과 대화천을 가라앉힌다.금당산(錦塘山)·백적산(白積山)·형제봉(兄弟峰) 등과 함께 한국의 척량부(脊梁部)를 이루는 태백산맥(太白山脈)의 일부를 구성한다. 중부지방을 북서쪽으로 흐르는 한강(漢江)의 지류인 평창강(平昌江)의 발원지를 이룬다.", - "MNTN_HG_VL" : "1173", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", - "MNTN_NM" : "거문산" + "DETAIL_INFO_DTCONT" : "응복산은 설악산과 오대산을 잇는 백두대간의 중간에 서있는 산으로 오대산으로 들어가는 들머리에 해당하기도 한다. 실제로 응복산에서 오대산 두로봉까지는 10km도 안 떨어져 있어 응복산∼두로봉이나 응복산∼약수산∼구룡령을 잇는 구간을 장기산행 할 수도 있다. 원당초교명개리 계곡은 명개분교에서 북대사 길로 접어들면 얼마간 걷다보면 약수골과 바랑골이 만나는 곳에 닿는데 이곳까지는 임도가 나있다.진달래군락지를 지나 오르게 되는 정상은 주목 한 그루가 자리를 지키고 있는데 시야가 탁 트여있다. 주변에 708년(신라 성덕왕 7)에 원효대사가 창건한 수타사(水墮寺)와 철분을 비롯한 유리탄산·불소·칼슘 등이 들어 있어 만성위장병과 고혈압·빈혈·당뇨 등에 효과가 있다는 삼봉약수터가 있다. 울창한 수림과 맑은 물이 흐르는 계곡을 안고 있는 응복산에는 희귀 동식물과 어류들이 많이 서식하고 있어 훼손 안된 자연의 모습이 어떠한지를 잘 말해주고 있다.산행이 시작되는 서울에서 청도까지는 약5시간이 소요되는 등 교통이 불편하므로 미리 청도에 가서 민박을 알아두거나 통바람계곡에서 야영을 해야 하는 불편을 감수해야 한다. 또한 계곡이 넓어 장마철에는 계곡물이 불어나기 쉬우므로 이 기간에는 산행을 피하는 것이 좋다.", + "MNTN_HG_VL" : "1156", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "응복산" }, - "longitude" : 128.42388890000001, - "latitude" : 37.527500000000003 + "longitude" : 128.56705579999999, + "latitude" : 37.875693300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "기장군 철마면에 위치한 거문산(543m)은 여름 등산지로 권할만한 곳이다.산행을 시작해 1시간이면 정상에 닿을 수 있고 휴식을 포함해 3시간이면 완주할 정도로 코스가 짧은데다 우거진 녹음이 있기 때문이다. 또 사람이 적게 다닌 곳이라 곳곳에 탐스럽게 열린 산딸기를 따먹어 가면서 산을 오르는 즐거움을 맛볼 수 있으며 고사리 같은 산나물이 군락 이룬 자연을 구경할 수도 있다. 하산길에 수십 년된 우리의 전통 초가를 감상할 수 있는 것도 산행재미를 더해준다.", - "MNTN_HG_VL" : "543", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면 웅천리", - "MNTN_NM" : "거문산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "201", + "MNTN_LOCPLC_REGION_NM" : "경상북도 합천군", + "MNTN_NM" : "단봉산" }, - "longitude" : 129.1552418, - "latitude" : 35.301902699999999 + "longitude" : 128.2624572, + "latitude" : 35.567715799999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉각산이라 불리기도 하는 검각산은 그 이름에 걸맞게 산봉우리가 창을 맞대어 세워놓은 듯한 풍모를 가지고 있다.영월의 팔경 가운데 하나인 `검각창송'이란 평창강과 주천강이 합해져 서강이 되어 단종의 슬픈 역사를 담은 청령포를 지나 남한강으로 흘러가는 어귀에서 그 강물과 어우러지는 이 산의 빼어난 자태를 칭송한 것이다. 이 산에는 소의 뿔에서 땀이 날 정도로 험하고 넘기 힘들다는 각한치가 있는데, 억새가 빼곡이 서있는 풍경에 홀려 힘든 것도 모르고 가게 된다.", - "MNTN_HG_VL" : "505", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 남면", - "MNTN_NM" : "검각산" + "DETAIL_INFO_DTCONT" : "영월군 동쪽 상동읍과 중동면의 경계를 이루는 매봉산은 정상에 오르면 사방으로 터진 시원한 조망이 일품이다. 산행기점은 아시내 마을이다. 아시내를 출발하여 멧둔골을 경유하여 정상에 오른 후, 서봉 - 남릉 - 원천계곡, 또는 849봉을 경유하여 주채마을로 내려선다.정상은 둥그스름한 토봉이며, 남쪽은 천혜의 절벽으로 이루어져 있고 , 북쪽은 부드러운 사면으로 이루어진 산으로 기암절벽에 어우러진 노송과 울창한 숲을 간직한 비경의 산이다.", + "MNTN_HG_VL" : "1095", + "MNTN_LOCPLC_REGION_NM" : "강원 영월 상동읍. 중동면", + "MNTN_NM" : "매봉산" }, - "longitude" : 128.4233333, - "latitude" : 37.184166699999999 + "longitude" : 128.7738889, + "latitude" : 37.1438889 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "하남시청에서 동쪽으로 5킬로미터 떨어져 있는 산으로 일설에 의하면 검단선사가 은거하였다 하여 검단산으로 불린다. 산행 초입은 야산과 같아 느낌을 주지만 산 중간쯤 오르면 어느 산 못지않게 뛰어난 숲과 아름다운 풍경과 고사목이 군데군데 널려 있다.정상은 넓은 공터로 사방이 확 트여 있고 팔당댐은 물론, 북한강과 남한강의 합류 지점인 양수리 일대를 시원하게 내려다 볼 수 있으며 예봉산, 운길산, 도봉산, 북한산 등을 조망할 수 있다.검단산 산행 들머리인 배알미동은 ‘도성을 떠나는 사람들이 이곳부터는 임금이 거처하는 곳이 보이지 않거나, 또는 멀리서 도성 근처로 다가오는 길손이 이곳에 들면 임금을 배알할 수 있게 된다’는 설이 전해지는 마을이다. 검단산은 최근에 지어진 ‘통일정사’로 인해 불경을 들으며 산행을 시작할 수 있다.", - "MNTN_HG_VL" : "658", - "MNTN_LOCPLC_REGION_NM" : "경기도 하남시 천현동", - "MNTN_NM" : "검단산" + "DETAIL_INFO_DTCONT" : "서울의 진산 자리를 놓고 삼각산과 다투다가 휘적휘적 내려와 버렸다는 전설이 있을 만큼 빼어난 산이다. 정상에서 남봉으로 뻗어내린 1000m를 넘나드는 능선이 특히 준걸해 흡사 삼각산 백운대에서 보현봉에 이르는 장쾌한 능선을 빼다 놓은 듯하다. 일반등산로는 정상으로 알려진 1075봉을 중심으로 6방으로 나있는데 이 중 상봉인 주흘영봉과 부봉을 지나 동화원로 이어지는 줄기의 능선미가 일품이다. 월항삼봉으로 해서 하늘재로 내려서는 코스도 좋은데 월악산에서는 이 둘의 하늘금이 리듬체조의 리본처럼 역동적으로 보인다. 산이 솟음이 우세한 형국이라 썩 발달한 계곡은 없다. 대신 곡충골의 여궁폭포와 파랑소, 조곡골의 꽃밭서덜이 이채롭다. 너덜 사이를 듬성듬성 뚫고 올라온 진달래가 꽃을 피운 모습은 어디서도 찾아보기 힘들다. 도립공원으로 지정돼있는 문경새재는 주흘관, 조곡관, 조령관의 관문과 아울러 자연보도로도 유명하다. 근래에는 여기에 드라마왕건 세트장과 산악영화제가 보태졌다.", + "MNTN_HG_VL" : "1108", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "주흘산" }, - "longitude" : 127.2472779, - "latitude" : 37.521461799999997 + "longitude" : 128.10060530000001, + "latitude" : 36.788566500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "검봉은 춘천시 남산면 강촌리 북한강변에 솟아 있으며 구곡폭포로 유명한 봉화산(487m)과 산줄기를 잇고 있다. 봉화산과 이웃해 있어 구곡폭포 방향을 산행 기점으로 삼을 수도 있으나 구곡폭포에서 문배마을에 이르는 널따란 길이 나 있어 산행 첫머리로는 어울리지 않아 강촌리 강선사를 들머리로 하는 것이 보통이다.검봉은 칼을 세워 놓은 것처럼 생겼다고 해서 칼봉으로도 불린다. 또 주위 경관이 아름다워 사계절 내내 많은 관광객이 찾고 있으며 특히 겨울철에는 빙벽 교육 장소로도 인기 있다.강촌역 뒤 강선사로 오르면 첫 번째 봉우리에서 오른쪽으로는 의암호가 보이며 왼쪽으로는 경기도와 경계 지점인 도계휴게소 및 강촌휴게소가 보인다. 아득하게 보이는 발아래 경치를 감상 한 뒤 능선을 따라 2~3시간 정도 오르면 아홉 구비 계곡을 돌아 볼 수 있는 구곡정이 나타나며 50여 미터 높이의 구곡폭포에서물안개를 일으키며 떨어지는 물줄기가 보인다.", - "MNTN_HG_VL" : "530", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", - "MNTN_NM" : "검봉" + "DETAIL_INFO_DTCONT" : "고덕산은 전주시 남동쪽에 있는 산으로 등산인들에게 잘 알려져 있는 명산은 아니지만 전주시민들에게는 더할 나위 없이 좋은 휴식공간을 제공한다. 산자락에 남고산성, 남고사, 만경대, 관성묘 등의 많은 유적들을 품고 있는 산이기도 하다.산행 들머리는 관성묘 입구 마을로 한다. 삼경사 갈림길 능선을 따라 오르는 등산 코스는 오가는 이들이 적어 호젓하게 산행을 즐길 수 있다. 능선을 따라 오르면 산성터가 나타난다. 남고산성은 고덕산과 천경대, 만경대, 억경대 등 봉우리를 이어쌓은 산성이다. 남동쪽으로는 남원, 고창으로 통하는 교통상의 중요한 곳을 지키고, 북쪽으로는 전주를 내려다 보는 자리에 위치하고 있다.후백제를 세운 견훤이 이곳에 고덕산성을 쌓았다는 이야기가 전해오며, 조선 순조 13년(1813)에 성을 고쳐 쌓고 남고산성이라 했다. 이 성은 유래가 매우 오래된 것으로 알려져 있는데, 「세종실록지리지」와 「동국여지승람」에도 기록이 보인다. 순조 13년에 보수공사를 할 때 성 안에는 4개의 연못과 25개의 우물이 있었으며, 민가 100여 채가 있었다고 한다. 서쪽에는 비밀문이 하나 있었으며 동서남북에 각각 하나씩 포루가 설치되어 있고, 관청, 창고, 화약고, 무기고를 비롯한 각종 건물이 많았다.정상은 널따란 헬기장으로, 북서쪽으로는 전주시가지가 내려다보이며 운장산, 만덕산, 모악산 등이 고덕산을 감싸 듯 둘러 서 있다.", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전북 전주시 완산구, 완주군 구이면ㆍ상관면", + "MNTN_NM" : "고덕산" }, - "longitude" : 127.5986521, - "latitude" : 37.805322400000001 + "longitude" : 127.1788889, + "latitude" : 35.772222200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "530", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "검봉산" + "DETAIL_INFO_DTCONT" : "아미산은 홍천군 서석면에 자리한 해발 961미터의 산이다. 평창군 봉평면의 청량봉에서 한강기맥과 이별한 춘천지맥이 응봉산(1097m)을 눈앞에 둔 각근치에서 남서쪽으로 곁가지를 일으킨다. 이 산줄기는 무명봉(1009m)과 아미산, 고양산(675m)을 일으킨 후 홍천강으로 흘러드는 내촌천에 가라앉는다.우리나라에는 아미산이라 이름을 가진 산이 부산, 울산, 전남, 전북, 충남, 충북 등에 여럿 있으며 중국의 산동성에도 무협소설에 등장하는 같은 이름의 산이 있다. ‘아미’란 이름의 뜻은 우리가 흔히 생각하는 아미(蛾眉) 즉, 미인의 눈썹이 아니며 불교에서 아미타불(阿彌陀佛)의 약칭으로 말하는 아미도 아니다. 높을 아(峨)에 풍치가 아름다울 미(媚), 즉 ‘높고도 풍치가 아름다운 산’이 바로 홍천의 아미산이다. 아미산은 대중교통으로 접근하기에도 좋은 산이다. 서울에서 홍천, 홍천에서 서석으로 수시 운행하는 버스편을 이용하면 쉽게 다녀올 수 있는 산이다.아미산은 북으로는 가리산, 동으로는 계방산, 회령봉, 흥정산 줄기가 한눈에 들어오고 서쪽으로는 공작산을 조망할 수 있다. 아미산 끝자락에 있는 고양산은 사람들의 발길이 닿지 않은 곳으로 ª은 거리의 등산과 함께 깨끗한 내촌천에서 물놀이도 즐길 수 있다.", + "MNTN_HG_VL" : "961", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", + "MNTN_NM" : "아미산" }, - "longitude" : 127.5986521, - "latitude" : 37.805322400000001 + "longitude" : 128.209, + "latitude" : 37.738999999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "호남정맥의 마루금에 위치한 경각산은 구이저수지 서쪽에서 모악산을 마주보며 우뚝 솟아있다. 경각산(鯨角山)의 한자 그대로 고래등에 난 뿔처럼 생긴 두 개의 바위가 정상부에 솟아, 산 아래에서 바라보면 모악산 방향으로 머리를 둔 고래의 모습과 흡사하다. 이 때문에 어머니를 상징하는 모악산과 달리 경각산은 남성을 상징한다.산 정상에서는 전주와 익산 시내, 미륵산, 고덕산, 마이산, 오봉산이 선명하게 보인다. 특히 가을 단풍과 겨울 선경으로 이름 높지만, 모악산에 비해 상대적으로 덜 알려져 있어 주말에도 호젓한 산행을 할 수 있다. 패러글라이딩 활공장이 있어 날씨가 좋은 날에는 하늘 높이 날아가는 패러글라이딩의 모습도 볼 수 있다.경각산 아래 정각사는 고려말기에acirc;건된 태고종 사찰로 많은 고승들의 수도oacute;가 되었다고 전해진다.", - "MNTN_HG_VL" : "659", - "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 신덕면", - "MNTN_NM" : "경각산" + "DETAIL_INFO_DTCONT" : "복두산은 강원도 삼척시 가곡면에 숨어 있는 오지의 산이다. 이 산은 북으로 육백산과 매봉산, 동쪽으로 치바위산, 남쪽으로 면산, 서쪽으로 백병산이 둥그렇게 에워싸고 있는 곳으로 열매로 치면 두터운 껍질에 쌓인 알맹이 부위라 할 수 있다.그래서 옛날 이 마을 사람들은 이 산을 복동아리산이라 하였다. 산 아랫마을 이름은 동활리인데 이것은 복두산에서 기인한 것으로 본래 `복동아리' 또는 `도화리(桃花里)라 불리던 곳이 와전된 것이다.촛대처럼 뾰족한 기이한 바위 등 군데군데 암봉이 많다. 등산로는 다소 험하며, 복두천은 여름철 피서지로 각광받고 있는 곳으로 휴가철에는 마을에서 입장료를 받고 계곡을 관리하고 있다.", + "MNTN_HG_VL" : "978", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "복두산" }, - "longitude" : 127.15733539999999, - "latitude" : 35.728343799999998 + "longitude" : 129.1268848, + "latitude" : 37.162401899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "659", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군,임실군", - "MNTN_NM" : "경각산" + "DETAIL_INFO_DTCONT" : "불곡산은 경기도 성남시 분당구와 광주군 오포면의 경계를 이루는 해발 312.9m의 낮은 산으로 분당시민의 휴식처 역할을 톡톡히 하는 산이다. 산행은 수내동, 불정동, 정자동, 구미동에서 아무곳으로나 올랐다가 내려가면 된다.", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "경기도 성남시 분당구, 광주군 오포면", + "MNTN_NM" : "불곡산" }, - "longitude" : 127.15733539999999, - "latitude" : 35.728343799999998 + "longitude" : 127.1352778, + "latitude" : 37.346111100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "몽덕산(680m)에서 뻗어 내린 능선이 가덕산(858m),북배산(867m)을 일으키고 싸리재를 지나 서남쪽으로 이어지는 능선에 우뚝 솟아 있는 계관산은 강원도 춘천시 서면과 경기도 가평군 북면의 경계를 이루는 산이다.몽덕산에서 계관산으로 이어지는 주능선 마루에는 폭 20여 미터에 방화선이 만들어져 있는데 이곳에 억새풀이 빼곡이 들어 서 있다. 가을이면 황금빛으로 물들어 산행 재미를 더해 준다. 정상에 서면 북으로는 북배산, 그 뒤로 가덕산과 몽덕산이 가까이 보이고, 그 오른쪽으로 용화산과 오봉산이 한눈에 들어오며, 동쪽 발 아래로는 물위에 떠 있는 듯한 춘천시내와 의암호가 거울처럼 보인다.서북쪽으로는 구나무산, 월출봉, 백둔봉, 명지산, 수덕산, 화악산 등의 산맥이 줄지어 솟아 있다.", - "MNTN_HG_VL" : "736", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 강원도 춘천시", - "MNTN_NM" : "계관산" + "DETAIL_INFO_DTCONT" : "삼신봉은 어미의 품처럼 넓은 지리산 자락에 흩어진 수십개 봉우리 중의 하나로 영신봉(1652m)에서 남쪽으로 길게 뻗은 능선상의 최고봉이다. 또한 지리산 주능선의 전망대로서 참다운 가치를 가질 뿐만 아니라 악양으로 흘러내린 형제봉 능선과 멀리 남해 바다의 일망무제, 탁트인 전경을 선사해준다.특히 인적드문 비경의 남부능선 한가운데에 우뚝 솟아 동으로는 묵계 치를, 서쪽으로 생불재(상불재), 남으로는 청학동을, 북쪽으로는 수곡재와 세석 을 이어주는 사통팔달 요충지로서의 역할을 한다.지리산 하동지역은 쌍계사, 칠불사 등의 절을 비롯하여 불일폭포, 화계계곡, 청학동, 도인촌 등의 볼거리도 많다. 청학동 마을에서 삼신봉을 바라보면 왼쪽부터 쇠통바위, 가운데는 내삼신봉, 오른쪽이 외삼신봉으로 세 개의 봉우리가 눈에 들어온다.특히 삼신봉은 봄의 벚꽃 산행지로 이름 나 있다. 하동-쌍계사 십리 벚꽃길, 섬진강 60리 벚꽃길이 매년 4월 초순이면 장관을 이룬다. 수령 60년이 넘은 아름드리 벚나무가 구불구불한 계곡을 따라 활짝 필때 벚꽃산행지로 많은 사람들이 찾는다. 10리 벚꽃길은 젊은 남녀들이 걸으며 백년해로를 기약하는 경우가 많다고 해서\"\"혼례길목\"\"으로 불린다.섬진강 벚꽃길 60리는 섬진강 꽃길 따라 60리를 간다.구례에서부터 따라붙은 섬진강은 지리산에서 거친 숨결로 내려온 화개천과 만나 물줄기가 굵어진다. 이곳이 바로 화개장터로 불리는 탑리이다.", + "MNTN_HG_VL" : "1285", + "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군", + "MNTN_NM" : "삼신봉" }, - "longitude" : 127.6083333, - "latitude" : 37.883055599999999 + "longitude" : 127.70404569999999, + "latitude" : 35.264464199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "계룡산은 백두대간에서 갈라져나온 금남정맥의 한 줄기를 이루는 산으로, 충남 공주시와 논산시의 경계를 이루고 있다. 산세가 마치 닭의 벼슬을 쓴 용의 형상을 했다고 해서 계룡산으로 불리게 되었다고 한다.계룡산은 조선조 초기에 씌어진 예언서인 〈정감록〉의 `왕도입지설'로 유명한 산으로,정상인 천황봉(天皇峰)을 중심으로 쌀개봉(830.6m), 관음봉(765.8m), 문필봉(735.6m), 삼불봉(777.1m), 연천봉(742.9m)이 주능선에 줄지어 솟아 있다. 계룡산 산자락 곳곳에 문화 유적이 산재해 있는데, 동북쪽에는 동학사가,서북쪽에는 갑사가,서남쪽에는 신원사 사찰이 자리잡고 있다. 특히 갑사에는 보물 제257호인 부도(浮屠)와 보물 제256호인 철당간 및 지주.보물 제478호인 동종(銅鐘)등의 문화재가 있으며, 〈월인석보〉를 찍어낸 목판도 소장되어 있다. 〈월인석보〉는 세종29년(1447년)에 간행된 〈석보상절〉과 세종 31년에 간행된 〈월인천강지곡〉을 합편하여, 세조가 1459년에 간행한 것이다.상봉을 중심으로 동쪽에 동학사, 서쪽에 갑사, 남쪽에 신원사가 자리하여 현재까지도 보존되고 북쪽의 구룡사는 절터만 남아 있다. 계룡사에는 노루, 담비, 청설모, 황매화 등 희귀 동.식물 1227종이 서식하고 있으며, 계룡 8경으로 꼽히는 천황봉(일출), 삼불봉(설화), 연천봉(낙조), 관음봉(한운), 동학계곡(신록), 은선폭포(운무), 갑사계곡(단풍), 남매탑(명월) 등은 울창한 숲과 기암절벽을 더불어 장관을 이루고 있다.", - "MNTN_HG_VL" : "847", - "MNTN_LOCPLC_REGION_NM" : "대전광역시, 충청남도 공주시 계룡면ㆍ논산시 상월면ㆍ계룡시 신도안면", - "MNTN_NM" : "계룡산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "140", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "망마산" }, - "longitude" : 127.20583329999999, - "latitude" : 36.342500000000001 + "longitude" : 127.6708675, + "latitude" : 34.754024100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제주도에 이어 두 번째로 큰 섬인 거제도는 총 면적 399.3㎢에 부속 섬 60여개를 안고 있는 큰 섬이다. 거제도에는 계룡산을 비롯하여 옥녀봉(555m),산방산(507m), 노자산(565m), 앵산(507m) 등 500m급의 크고 작은 산들이 솟아 있다.주능선에 용이 승천하는 듯한 형상의 바위가 솟아 있어 계룡산이라 이름 붙여진 이 산은 봄에는 진달래, 가을이면 억새로 비경을 자아내고 있다.이곳 향토사학자들은 '계룡산하 구백만(鷄龍山下 九百萬)'이라고 표현한 〈정감록〉의 계룡산은 거제도에 있는 계룡산을 말한다고 주장하고 있다. 6.25때 충청도 계룡산에 피난 갔던 수많은 사람들은 피해를 입었지만, 이곳 거제 계룡산은 많은 주민과 피란민, 포로들까지 피해를 입지 않은 곳이었기 때문이라 한다.", - "MNTN_HG_VL" : "845", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", - "MNTN_NM" : "계룡산" + "DETAIL_INFO_DTCONT" : "경기도 가평에는 한북정맥의 주를 이루는 1000미터급 고봉이 밀집되어 있다. 촉대봉은 경기도에서 제일 높은 화악산에서 동쪽으로 뻗어 내린 능선이 응봉(1436m)에서 동남쪽 홍적이고개로 이어지는 능선에 솟아 있는 산이다. 이름은 정상 부분이 봉우리 세 개로 되어 있고 끝이 뾰족한 데서 유래하였으며 촉대봉(燭臺峰)이라 한다. 화악산이 북쪽에서 남쪽을 바라보며 버티고 서 있는 형상이라면 촉대봉은 왼쪽 어깨에 해당하는 것으로 거대한 바위와 나무가 우거진 능선이 웅장하고 정상에서의 경치가 장관이다. 특히 겨울 설경과 가을 단풍이 아름답다.강원도 춘천시 사북면과 경기도 가평군 북면의 경계를 이루고 있는 촉대봉에는 동쪽 산자락인 강원도 춘천시 사북면 지암리에 집다리골자연휴양림이 조성되어 있다. 능선 끝의 멱골, 싸리재마을은 의병운동와 독립만세운동의 중심지였다.", + "MNTN_HG_VL" : "1125", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면·강원도 춘천시 사북면", + "MNTN_NM" : "촉대봉" }, - "longitude" : 128.608, - "latitude" : 34.871299999999998 + "longitude" : 127.5444444, + "latitude" : 37.975833299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "566", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시 신현읍, 거제면", - "MNTN_NM" : "계룡산" + "DETAIL_INFO_DTCONT" : "석화봉은 충북 단양의 수리봉과 황정산 사이에 동북 방향의 가지를 치고 그 지능선상에 솟아 있는 산이다. 석화봉을 가운데 두고 북으로 황정산, 동으로 올산(858m), 남서로 선미봉과 수리봉 암릉이 사방으로 에워싸고 있는 무풍지대다.형형색색의 기암괴석과 암봉 및 암벽, 암릉, 암굴 등으로 이루어진 신비로운 암산인 석화봉이란 이름은 시원스레 뻗은 암릉 위로 거대한 화강암 바위가 꽃처럼 피어 있는 형상에서 비롯된 것이다. 뿐만 아니라 정상 부근 낙타바위를 비롯해서 725봉 아래에 보는 이로 하여금 절로 웃음을 짓게하는 째진바위, 궁둥이 바위,백곰바위등이 산행을 즐겁게 하여준다. 산으로 오를수록 암릉길과 슬랩(경사),침니코스가 나온다 약간의 보조자일도 필요하다.정상에서의 조망은 시원하게 터진다.북동쪽으로 도솔봉과 흰봉산이 하늘금을 그리고 동쪽으로는 저수령 방면 백두대간과 그 아래 올산 마을이 아름답게 펼쳐진다.북서쪽으로는 암릉을 끌고 나가는 황정산이 우뚝하다.", + "MNTN_HG_VL" : "834", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "석화봉" }, - "longitude" : 128.608, - "latitude" : 34.871299999999998 + "longitude" : 128.5541667, + "latitude" : 37.086388900000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "775", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "계명산" + "MNTN_HG_VL" : "828", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시", + "MNTN_NM" : "도장산" }, - "longitude" : 128.93972220000001, - "latitude" : 36.420833299999998 + "longitude" : 127.94232150000001, + "latitude" : 36.552953100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "양주군 백석면과의 사이에 있는 해발 622미터의 아담한 높이의 산으로, 고찰인 보광사가 있기도 하다.평평한 산 정상에서 바라보면 북으로 파주군과 양주군의 나지막한 산들이 건너다 보이고, 동쪽으로 죽 늘어선 불국산, 사패산, 도봉산 암봉, 남쪽으로 북한산 백운대의 당당한 모습이 보인다.산행은 보광사에서 시작하여 도솔암을 오른 후 헬기장을 거쳐 정상에 오른 후, 서릉을 거쳐 보광사로 하산하는 것이 좋다.", - "MNTN_HG_VL" : "622", - "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 석현면", - "MNTN_NM" : "계명산" + "DETAIL_INFO_DTCONT" : "대부산은 경기도 양평군 옥천면에 위치한 산으로 유명산과 이웃하고 있는 산이다. 소구니산, 유명산, 어비산, 대부산, 용문산으로 이루어진 이 곳의 산군은 경기도내에서 정말 보기 드문 경치를 자랑한다.70년대초 이곳에 고랭지채소를 키우기 위해 산에 불을 질러 나무를 다 태워 버렸기 때문에 초원의 느낌을 맛볼 수 있기도 하다. 또한 이곳은 페러글라이딩 장소로도 많이 이용되기 때문에 산행을 하다보면 하늘을 날고 있는 낙하산을 심심지 않게 볼 수 있기도 하다.예로부터 홍수 때면 물고기가 산을 뛰어 넘는다고 하여 어비산이 되었으며, 마주보는 유명산과 함께 설악면과 옥천면을 가르는 산이라 하여 마을에서는 대부산이라고도 부른다. 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이루는 곳에 어비계곡이 흐른다.", + "MNTN_HG_VL" : "743", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면", + "MNTN_NM" : "대부산" }, - "longitude" : 126.9333333, - "latitude" : 37.745555600000003 + "longitude" : 127.48808649999999, + "latitude" : 37.5675995 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "계명산은 충주시내 동복쪽에 위치하여 마즈막재(620m)를 사이에 두고 동남쪽의 남산(636mㆍ금봉산)과 더불어 충주시를 두팔로 감싸 안듯 병풍을 두르고 있다. 또한 충주댐을 끼고 있어 산 위에 올라서면 충주호가 굽어보이고 월악산의 선경이 호반 위로 펼쳐진다. 충주시내가 가깝기 때문에 시민들이 많이 찾는 도심의 산이다.산 이름과 관련해 다음과 같은 유래가 전한다. 충주가 삼국시대 백제 영토로 있을 때였다. 왕족을 자칭하는 성주가 마고성의 성주도 겸하며 충주읍성(예성) 내관과의 왕래가 잦았다. 그러던 어느날 마고성주의 딸이 심항산 밑을 지나다가 지네에게 물려 갖은 약을 다 써봤으나 상처가 악화되어 죽고 말았다. 그날부터 성주는 관민들에게 지네를 모두 잡아 치우라고 명을 내렸지만 그 피해가 날로 심해졌다. 성주는 하는 수 없이 심항산 마루에 제단을 설치하고 매일 정심기도를 올렸다. 그러던 어느날 꿈에 용두백발을 한 신선이 나타나 “지네는 닭과 상극이니 많은 닭을 산에 방목하라 그러면 근절시킬 수 있을 것이다.”하고 일렀다.성주는 많은 닭을 방목했고 지네가 근절됐다. 그러나 또다시 지네가 번성할까 두려워 계속 닭을 놓아기르니 산 곳곳에 닭이 밟지 않은 데가 없었다. 그래서 원래 오동산, 심항산 등으로 불리던 이름이 계족산이라 부르게 됐는데 풍수설에 충주에 큰 부자가 안 나는 것은 계족산이 닭발의 형상이고 분산을 뜻한다고 해 1958년 충주시에서 산 이름을 여명을 알리는 뜻의 계명산으로 개칭했다.", - "MNTN_HG_VL" : "622", - "MNTN_LOCPLC_REGION_NM" : "충북 충주시 안림동ㆍ용탄동ㆍ종민동", - "MNTN_NM" : "계명산" + "DETAIL_INFO_DTCONT" : "환성산은 팔공산과 무학산이 서로 연결되는 중앙산록으로 예부터 이 산의 생김새가 서로 고리를 걸어 당기는 형상이라 해 환성산이라 불렀다. 하양 명산으로 산 아래에는 신라 헌덕왕의 왕자인 심지왕사가 창건했다는 환성사가 있다.안심에서 산행을 시작해 뾰족한 봉우리를 오르면 초래봉이다. 태조 왕건 촬영지로 알려져 많은 등산인들이 찾고 있다. 뒤로는 대구시가지와 금호강 줄기가, 동쪽으로는 카톨릭대학과 하양읍내가 보인다. 초래봉은 바위로 이루어져있는데 정상표석은 대안산악회에서 설치했다. 이 산은 고려 태조 왕건이 후백제 견훤이 패하여 이곳에 이르렀다가 후에 여기서 제를 올렸다는 이야기가 전한다.정상을 지나면 불굴사에 닿는다. 경내에는 갓바위약사여래불과 동시대 것으로 추정되는 약사여래입상과 보물 429호인 불굴사 삼층석탑이 있다. 불굴사 주방 뒤로 가면 절벽 위에 자연석굴이 있는데 지금은 홍주암이라는 암자로 쓰인다. ‘불굴’, ‘원효굴’, ‘관음굴’로도 불리며 굴 속에 ‘아동제일약수(我東第一藥水)’가 있다. 원효굴은 김유신 장군이 이 물을 마시면서 삼국통일의 염원을 기도했던 장소로도 알려져 있다.", + "MNTN_HG_VL" : "811", + "MNTN_LOCPLC_REGION_NM" : "대구시 동구, 경북 경산시 하양읍ㆍ와촌읍", + "MNTN_NM" : "환성산" }, - "longitude" : 127.977, - "latitude" : 36.989999999999988 + "longitude" : 128.74083329999999, + "latitude" : 35.936944400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남한에서 한라산(1947.3m) 지리산(1915.4m) 설악산(1708.1m) 덕유산(1614.2m)에 이어 다섯 번째로 높은 계방산은 겨울철 적설등반 산행지로 유명한 산이다.강원도 홍천군 내면과 평창군 진부면에 걸쳐 있는 광대한 산맥을 거느리고 있으나, 북동쪽으로 연결되어 있는 오대산의 명성에 가려 빛을 보지 못했던 명산이다. 높은 산이면서도 유순한 산세와 능선을 가지고 있으며 가을이면 온 산을 단풍으로 물들이고 겨울철에서 무릎이상 빠질정도의 적설량으로 등산인들의 사랑을 듬뿍 받고 있는 산이다. 산기슭에 있는 방아다리 약수는 위장병, 피부병에 효험이 있는데 메밀꽃 필 무렵 마시면 특효가 있다고 한다.", - "MNTN_HG_VL" : "1579", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면, 평창군 용편면ㆍ진부면", - "MNTN_NM" : "계방산" + "DETAIL_INFO_DTCONT" : "갈전산은 산청,거창군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳 경계에서 양분 되어 한줄기는 덕갈산을 거쳐 생초면 소재지 방향으로 달리고 다른 한줄기가 바로 갈전산을 거쳐 철마산, 소룡산, 바랑산을 거쳐 황매산으로 길게 이어져 있다.갈전산은 덕갈산과 마주보고 있어 생초면소재지 까지 뻗어 있는 덕갈산 줄기를 조망하기에 좋은 곳이다. 날씨가 좋으면 덕유산과 함양군의 고봉들도 조망이 가능하며 지리산과 그 아래 산들도 조 망이 가능하다. 갈전산은 규모가 크거나 산세가 수려하지는 않다. 하지만 이웃한 철마산과 함께 연결하여 산세를 본다면 결코 작은 산이라고 말할 수 없다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 생초면", + "MNTN_NM" : "갈전산" }, - "longitude" : 128.4448506, - "latitude" : 37.707517000000003 + "longitude" : 127.866356, + "latitude" : 35.556904500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "계족산은 말 그대로 닭의 발처럼 산줄기가 사방으로 뻗어있다. 대전시 동북쪽에 울타리를 이룬 시민의 산인지라 온 산이 공원화 되어 있다. 등산로만 해도 입구가 20여 군데에 달할 정도다. 산 남서쪽에는 경부고속도로가 시내와 경계를 지으며 산줄기와 나란히 달리고, 그 맞은편인 동쪽 산자락에는 푸른 대청호가 넘실거린다.산 자락에는 각종 유적과 문화재 등이 즐비하다. 들머리인 용화사에는 석불입상, 날머리인 비래사에는 동춘당이 지은 정자인 옥류각, 그 아랫마을인 송촌동에는 동춘당이 있다. 우암 송시열 선생이 학문을 닦고 제자를 가르쳤던 곳에는 우암사적 공원이 들어섰다. 과거와 현재, 미래가 공존하는 도시인 대전답게 계족산 역시 그 모습을 고스란히 반영하고 있다.계족산에는 계족산성이 북에서 남으로 길게 산정을 형성하고 있다. 삼국시대 백제 부흥군이 활동했던 옹산성으로 추정되는 이 성은 둘레만 해도 1037미터로 이 고장 최대의 산성이다. 성벽은 안쪽의 흙을 깎아내고 바깥쪽에만 돌을 쌓는 수법으로 만들어졌다.", - "MNTN_HG_VL" : "424", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구, 동구", - "MNTN_NM" : "계족산" + "DETAIL_INFO_DTCONT" : "경기도 포천군과 가평군의 경계를 이루는 강씨봉은 옛날 이 곳에 강씨가 모여 살았다 하여 붙여진 이름이라 한다. 강씨봉에서 동남쪽으로 뻗어 내리는 능선 길에 강씨봉고개가 있으며, 고갯마루에서 동쪽 아래에 강씨봉 마을터가 남아있다.전체 산세가 완만하고 부드러워 산행이 힘들지 않으며, 한나무골 계곡은 아직도 맑고 깨끗함을 간직하고 있다. 강씨봉은 포천시과 가평군을 경계로하는 아기자기한 등산코스를 지니고 있지만 주위에 유명한 산들이 많아, 등산객이 많지 않은 조용한 산행을 즐길 수 있어 가족산행지로 가볼만 하다.특히 겨울설경이 아름다우며 산꼭대기 좌우로 매우 아름다운 경관을 가진 산으로 한나무골의 계곡은 맑고 깨끗하다. 마지막 능선의 억새밭과 싸리나무, 봄철의 진달래와 철쭉이 어우러진 모습이 볼 만하다.", + "MNTN_HG_VL" : "830", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시, 가평군", + "MNTN_NM" : "강씨봉" }, - "longitude" : 127.43934659999999, - "latitude" : 36.385547600000002 + "longitude" : 127.38239059999999, + "latitude" : 37.969131699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "890", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", - "MNTN_NM" : "계족산" + "DETAIL_INFO_DTCONT" : "백두대간 마루금상의 청화산(984m)은 정상은 경상북도 상주와 문경시, 충청북도의 괴산군과 경계를 이루고 있다. 북쪽 대야산에서 남진하여 조항산을 지나온 백두대간이 청화산에 이르면 방향을 남서쪽으로 틀어 눌재로 떨어진 다음 속리산으로 이어져 나간다.lt;택리지gt;에서 이중환은 “청화산은 뒤에 내외의 선유동을 두고 앞에는 용유동에 임해 있어 경치가 지극히 좋음은 속리산보다 낫다”고 표현할 만큼 이름다운 산이다. 육산의 웅장함과 바위산의 아기자기한 맛을 함께 맛볼 수 있을 뿐만 아니라 백악산, 군자산 등 속리산국립공원 일원의 산봉들을 조망할 수 있다. 청화산 오름길은 크게 세 코스다. 오래전부터 많이 이용돼온 입석1리나 심송2리에서 송면지~갓바위재를 경유하는 코스와 사계절 인기 있는 백두대간상의 눌재 기점, 그리고 쌍룡계곡 병천에서 화산마을로 들어가 정상 접근이 가장 ª은 원적사를 경유하는 코스가 있다.", + "MNTN_HG_VL" : "984", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 상주시, 충청북도 괴산군", + "MNTN_NM" : "청화산" }, - "longitude" : 128.5200261, - "latitude" : 37.169667099999998 + "longitude" : 127.91937729999999, + "latitude" : 36.624444099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고고산은 강원도 영월군 영월읍 문산리와 중동면 연하리, 정선군 신동읍 고성리와 경계를 이루며 동강변에 솟아 있는 산이다.설악산 용아름의 축소판인 암릉은 이 산의 백미로 구들장 같은 바위들이 층층이 쌓여 있고 암릉 위에는 분재와 같은 노송들이 뿌리를 내려 거대한 한 폭의 동양화를 연상하게 한다. 북릉을 타고 전망바위 정상에서 북으로 보면 신병산과 능암덕산이 마주 보이고 오른쪽으로는 백운산과 곰봉 사이를 가로 지르는 동강이 조망된다.", - "MNTN_HG_VL" : "854", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군, 정선군", - "MNTN_NM" : "고고산" + "DETAIL_INFO_DTCONT" : "옥교산은 병풍바위 남쪽에 가마같이 생긴 봉우리라 하여 산 모양을 보고 산 이름을 지었다. 이 곳에 선녀가 옥교를 타고 와서 놀다가 갔다는 전설이 있다.밀양 옥교산을 동물에 비유하자면 꾀꼬리 정도가 적당할 것 같다. 산이 그만큼 덩치가 작고 정답게 느껴지기 때문이다. 밀양 도심에서 멀지 않은 이 산은 멀리서 보자면 `사철 발벗은' 아낙처럼 `예쁠 것도 없는' 평범한 모습 이다. 산꾼의 주목을 끌지 못하는 이런 수수한 외모가 옥교산의 매력을 더해줬다.낮게 달리는 능선길은 겨울답지 않게 폭신한 낙엽과 솔잎으로 가득 덮혀있다. 길지 않은 산행시간. 이번 산행은 가볍게 트래킹하는 기분으로 맑은 공기를 마음껏 마시고 올 수 있 는 산뜻한 코스다.산행은 교동 동사무소에 내려 포장도로를 따라 춘복타워 맨션으로 오른다. 그 맨션에서 아스팔트길로 150m 더 오르면 오른편에 교동 배수지가 보인다. 여기서부터 산행을 시작한다. 정상은 수림으로 둘러싸여 어느 쪽으로도 조망이 불가능하며, 그냥 정상임만을 짐작할 뿐이다.", + "MNTN_HG_VL" : "538", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 안인리", + "MNTN_NM" : "옥교산" }, - "longitude" : 128.57913009999999, - "latitude" : 37.220578799999998 + "longitude" : 128.74241280000001, + "latitude" : 35.539616799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "396", - "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 서호동", - "MNTN_NM" : "고근산" + "DETAIL_INFO_DTCONT" : "백두산에서 시작되는 백두대간은 동해안 따라 뻗어 내리다 강원도 태백 피재에서 남서 향으로 방향을 틀어 한반도의 내륙을 따라 남해안으로 달려간다. 백운산은 백두대간에서 뻗어 나온 호남정맥이 남해바다로 잠들기전 마지막 힘을 다해 밀어 올린 산으로, 호남정맥의 최고봉이다.섬진강을 사이에 두고 지리산과 남북으로 마주보고 있는 백운산은 정상에서 서쪽으로 또아리봉(1127m),도솔봉(1153.2m)이, 동으로는 호남정맥으로 이어지는 매봉(866.9m)이, 남으로는 억불봉(1,007.5m)을 거느리고 있는 큰 산맥을 이루고 있다. 백운산 아래 옥룡면은 삼면이 산줄기로 둘러싸인 큰 골짜기로 남쪽만 열려 있는 자루 모양을 하고 있다. 이 골짜기를 불당골이라고 부를 만큼 불교 흔적이 많은 곳이다.지리도참설과 풍수사상의 원조라 할 수 있는 도선국사가 37세부터 35년 동안 옥룡사(지금은 남아 있지 않음)에서 주로 기거하다, 72세에 이 절에서 입적하였다. 백운산 산행기점인 동동 마을 왼쪽 옥룡사 터가 있는 백계산(505.8m)에 도선국사가 심었다는 동백 숲이 천연기념물로 지정되어 있다. 이 산에는 고로쇠나무가 많이 자라고 있는데, 예로부터 고로쇠나무에서 나온 수액이 만병통치약이라고 하여 경칩을 전후로 하여 많은 사람이 백운산을 찾아오고 있다.", + "MNTN_HG_VL" : "1222", + "MNTN_LOCPLC_REGION_NM" : "전라남도 광양시 봉강면ㆍ옥룡면ㆍ진상면ㆍ다압면, 구례군 간전면", + "MNTN_NM" : "백운산(광양)" }, - "longitude" : 126.51384419999999, - "latitude" : 33.266262900000001 + "longitude" : 127.621944, + "latitude" : 35.107222 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "175", - "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 애월읍 고내리", - "MNTN_NM" : "고내봉" + "DETAIL_INFO_DTCONT" : "높이 887m의 비교적 낮은 산인 조계산은 1979년 12월 도립공원으로 지정되었는데, 산세가 부드럽고 아늑한 것이 특징이다. 산 속 깊은 계곡에는 젖줄과 같은 맑은 물이 흐르며, 만수봉과 모후산이 송광사 일대를 병풍처럼 둘러싸고 있어 마치 어머니 품처럼 포근함을 느낄 수 있다. 전국 3대사찰의 하나인 송광사와 고찰인 선암사가 주능선을 중심으로 동서에 자리하고 선암사 계곡을 흐르는 동부계곡은 이사천으로 남부계곡은 보성강으로 흘러들게 된다.선암사 둘레에는 월출봉, 장군봉, 깃대봉, 일월석 등이 줄지어 솟아있어 장관을 연출한다. 조계산 산행은 송광사나 선암사 어느 쪽에서 시작해도 비슷한 시간대에 다양한 코스를 즐길 수 있으며, 산세가 험하지 않고 평탄한 길이 많아 연인끼리 또는 가족단위 소풍코스로도 알맞다. 송광사 3대 명물중의 하나인 800년이 넘은 천연기념물 쌍향수도 이곳을 찾아오는 사람들의 눈길을 끌고 있다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 승주읍ㆍ송광면", + "MNTN_NM" : "조계산" }, - "longitude" : 126.3418004, - "latitude" : 33.459126500000004 + "longitude" : 127.31361099999999, + "latitude" : 35.002499999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경원선 철도가 휴전선에 막혀 더 이상 달리지 못하고 멈추는 곳에 고대산이 솟아 있다. 고대산은 등산객들이 자유롭게 산행을 할 수 있는 산 중에서 휴전선에 가장 가깝게 위치해 있는 산이다. 경기도 최북단인 연천군 신서면 신탄리와 강원도 철원군 사이에 있는 고대산 정상에서는 북녘의 철원평야와 6·25 때 격전지인 백마고지, 금학산과 지장봉, 북대산, 향로봉은 물론 한탄강 기슭의 종자산까지 한눈에 들어온다. 분단의 한, 망향의 한이 굽이쳐 북녘이 그리울 때, 멀리서나마 북녘땅을 바라볼 수 있는 3대 명산으로 고대산, 복계산, 지장봉을 꼽는데 해마다 6월이면 분단 상황을 체험해 보려는 많은 등산인들이 고대산을 찾는다. 수려한 전망과 적당한 코스 등 최적의 산행코스를 갖췄음에도 전략적 요충지라는 이유로 웬만한 지도에는 감춰진 산이다. 휴전선과 가장 가까운 곳에 있기 때문에 여태껏 사람들에게 잘 알려지지 않았다는 것이 이 산이 간직한 매력이기도 하다.", - "MNTN_HG_VL" : "832", - "MNTN_LOCPLC_REGION_NM" : "경기도 연천군 신서면·강원도 철원군 철원읍", - "MNTN_NM" : "고대산" + "DETAIL_INFO_DTCONT" : "동부면 망골과 망치고개를 경계로 하여, 신현읍 삼거리에 주맥을 내려 뻗어 문동과 아주골 옥녀봉 줄기와 연결되어 있다. 망치고개에 고려시대에 축성했다는 성지가 산중간에서 마을까지 길게 뻗어 있다. 문동계곡 상류에는 문동폭포가 있고, 삼거리에는 신라시대에 있었다는 은적사 절터가 있다.장승포, 일운, 동부에서 고현으로 다니던 세갈래 길이 협곡에 있는 삼거리 마을은 교통의 중심지였다. 문동폭포가 있는 북병산은 그 높이가 465.4m로 고현을 병풍친 듯 둘렀다고 북병산이라 하며 북쪽을 막아 평풍을 두른 듯 하다고 북병산이라고 한다.북병산 고개를 넘어 동부 일운 거제 고현 등지로 통하는 세 갈래 길이 있어 삼거리로 통한다. 이 산에는 옛 신라시대 엄적사와 법률사란 큰절이 있었다고 하나 현재는 주춧돌만이 남아 있어 당시의 역사를 말해 주고 있다. 법률사는 그 경내가 방대하여 아주리까지 뻗어 있었다고 하며 그 절의 삼층 석탑비가 지금도 대우조선소 내에 남아 있다. 북병산 계곡에서 흐르는 물이 문동 폭포수가 되어 문동 저수지를 형성하여 그 모습이 장관이다.", + "MNTN_HG_VL" : "465", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제", + "MNTN_NM" : "북병산" }, - "longitude" : 127.1549062, - "latitude" : 38.198599399999999 + "longitude" : 128.65655140000001, + "latitude" : 34.823366700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "603", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", - "MNTN_NM" : "고덕산" + "DETAIL_INFO_DTCONT" : "어래산이 있는 단양군 영춘면 의풍리는 남한강의 옥동천 지류인 남대천 상류에 자리해 있으며 `정감록'을 믿고 찾아 들어온 조상들의 후예들이 터전으로 한때 외진곳을 전전하는 도박꾼들의 집합장소로 악명 높았던 곳이다.분지를 이룬 의풍리를 두고 동쪽에는 어래산이, 서쪽으로는 형제봉이 솟아 있어 남쪽에서 흘러내려온 남대천이 북쪽의 옥동천으로 빠지고 있다. 그래서 물이 흘러나가는 북쪽을 제외하고는 모두 산으로 둘러싸여 있어 외지에서 이곳으로 들어서려면 고개를 넘어야 한다. 때문에 일단 어래산 산행에 앞서 마을 진입 자체가 문제인데다 산행코스 역시 만만치 않다.이처럼 접근이 어렵다는 것은 사람들의 손때를 타지 않았다는 반증이다. 산 곳곳에 혼을 빼앗길 만큼 청정한 계곡이 흐르고 광활한 낙엽송 조림지대가 있어 수월치 않은 산행의 피로를 씻어 줄 것이다.", + "MNTN_HG_VL" : "1064", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "어래산" }, - "longitude" : 127.3434029, - "latitude" : 35.659716299999999 + "longitude" : 128.65534959999999, + "latitude" : 37.064015800000007 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고덕산은 전주시 남동쪽에 있는 산으로 등산인들에게 잘 알려져 있는 명산은 아니지만 전주시민들에게는 더할 나위 없이 좋은 휴식공간을 제공한다. 산자락에 남고산성, 남고사, 만경대, 관성묘 등의 많은 유적들을 품고 있는 산이기도 하다.산행 들머리는 관성묘 입구 마을로 한다. 삼경사 갈림길 능선을 따라 오르는 등산 코스는 오가는 이들이 적어 호젓하게 산행을 즐길 수 있다. 능선을 따라 오르면 산성터가 나타난다. 남고산성은 고덕산과 천경대, 만경대, 억경대 등 봉우리를 이어쌓은 산성이다. 남동쪽으로는 남원, 고창으로 통하는 교통상의 중요한 곳을 지키고, 북쪽으로는 전주를 내려다 보는 자리에 위치하고 있다.후백제를 세운 견훤이 이곳에 고덕산성을 쌓았다는 이야기가 전해오며, 조선 순조 13년(1813)에 성을 고쳐 쌓고 남고산성이라 했다. 이 성은 유래가 매우 오래된 것으로 알려져 있는데, 「세종실록지리지」와 「동국여지승람」에도 기록이 보인다. 순조 13년에 보수공사를 할 때 성 안에는 4개의 연못과 25개의 우물이 있었으며, 민가 100여 채가 있었다고 한다. 서쪽에는 비밀문이 하나 있었으며 동서남북에 각각 하나씩 포루가 설치되어 있고, 관청, 창고, 화약고, 무기고를 비롯한 각종 건물이 많았다.정상은 널따란 헬기장으로, 북서쪽으로는 전주시가지가 내려다보이며 운장산, 만덕산, 모악산 등이 고덕산을 감싸 듯 둘러 서 있다.", - "MNTN_HG_VL" : "603", - "MNTN_LOCPLC_REGION_NM" : "전북 전주시 완산구, 완주군 구이면ㆍ상관면", - "MNTN_NM" : "고덕산" + "DETAIL_INFO_DTCONT" : "충북 영동군 양산면과 충남 금산군 제원면의 경계를 이루는 천태산은 기암절벽과 수림이 조화를 이루고 있어 일명 '충북의 설악'이라 불리고 있는 산이다. 등산로는 바위지대에다 안내표지와 로프가 설치되어 있어 아기자기한 바위산행을 만끽할 수 있는 묘미가 있는 산이며 뛰어난 자연경관을 자랑하는 산이기도 하다.이름난 명소가 산재해 있어 가족동반 등산지로도 좋다. 계곡은 비록 짧으나 시원하게 쏟아지는 용추폭포와 진주폭포가 있고, 봄에는 진달래, 벚꽂이 온 산을 뒤덮고 가을에는 단풍 또한 좋다.천태산에는 양산 8경 중 제1경인 영국사가 있으며, 10km 떨어진 곳에 여의정, 강선대, 용암 등이 있어 볼거리가 많은 곳이다. 영국사 앞 등산로 입구에는 천연기념물 제233호로 지정된 수령 천년이 넘는 은행나무가 서 있다.이 나무는 높이 18m, 둘레가 6m에 달하는 거목이다. 나라를 평안하게 하는 뜻을 가진 영국사는 고려 31대 공민왕이 홍건적의 난을 피해 이 근처에 와서 천일기도를 드린 끝에 난을 평정한 것을 기념하여 절을 짓고 이름을 영국사라 붙였다고 전해지고 있다.", + "MNTN_HG_VL" : "715", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 양산면, 충청남도 금산면 제원면", + "MNTN_NM" : "천태산" }, - "longitude" : 127.1788889, - "latitude" : 35.772222200000002 + "longitude" : 127.6135306, + "latitude" : 36.157161500000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "계방서정맥(桂芳西正脈)이라 불리는 산줄기 도미(掉尾)를 장식하며, 경기의 곡창지대인 여주 들녁에 우뚝 서 한 바다에 고래 등처럼 떠 있는 이산은 '고달산(高達山)'으로 불리기도 하며, 예로부터 고려장을 하던 '고려산'으로 불리었다.서남쪽으로 위치한 우두산(牛頭山) 남쪽에 사적 제382호로 지정된 '고달사지(高達寺址)'라는 사적지를 가지고 있으며, 금동마을 뒤쪽으로는 고려장 굴이 있어 옛 고려장 관습에 흔적을 가지고 있는 산이다.산세는 육산으로 가파른 경사를 이루고 있으며, 지제면 대평리쪽은 골프장 개발공사로 자연이 훼손되고 등산로가 없어졌으므로 여주 북내면쪽으로만 산행이 가능하다. 고달사지는 국보 제4호로 지정된 고달사부도를 위시해, 보물 3점, 향토유적지등이 있어, 산행과 문화재 탐방을 함께 할 수 있는 산이다.", - "MNTN_HG_VL" : "543", - "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면, 양평군 지제면", - "MNTN_NM" : "고래산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "313", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "안마산" }, - "longitude" : 127.658602, - "latitude" : 37.417704200000003 + "longitude" : 127.7494444, + "latitude" : 37.842222199999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "낙조를 찾아 떠날 산행지는 요즘 들어 일몰 관광지로 인기를 끌고 있는 강화도 고려산(高麗山)이다. 고려산은 읍내에서 5킬로미터쯤 떨어져 있으며 원래 이름은 오련산이었으나 고려가 몽고의 침략을 받아 도읍을 강화로 천도하면서 송도의 고려산 이름을 따 고려산으로 고쳐 부르게 되었다고 한다. 또한, 고려산은 연개소문이 태어난 곳이라는 전설이 있으며 주능선에 오르면 탁 트인 서해 바다의 시원스런 조망은 물론, 황해도의 연백군 해안과 예성강 하구를 조망할 수 있어 민족분단의 현실을 직접 눈으로 확인 할 수 있는 곳이기도 하다. 현재 고려산에는 백련사, 청련사, 적석사, 원통암 등 세 개의 사찰과 한 개의 암자가 있다. 그 중 청련사의 분위기가 제일 뛰어나나 남향에 자리한 사찰 전등사 역시 이에 뒤지지 않을 만큼 그윽하고 멋스러운 풍경을 자랑한다. 적석사 서쪽 절 정상 낙조봉에서 바라보는 서해 일몰은 강화 8경 중 하나로 꼽힌다. 게다가 인천시 기념물 제26호로 지정되어 있는 고창, 화순의 고인돌군도 만나 볼 수 있어 아이들과 함께 하는 가족산행지로 더 없이 좋은 곳이다.", - "MNTN_HG_VL" : "436", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 강화읍, 하점면, 송해면, 내가면", - "MNTN_NM" : "고려산" + "DETAIL_INFO_DTCONT" : "일명 `찌걱산'이라 불리는 지각산은 삼척시 하장면에 있는 오지의 산이다. 부근에 광동댐이 들어서면서 일부 훼손된 부분이 있으나 광동호와 인접해 있는 이 산의 경관은 지나가는 사람들의 발길을 붙잡기에 충분하다. 특히 광동댐 관리사무소가 들어선 능선부근은 남녀가 마주치면 그냥 지나치지 못하고 꼭 일이 생긴다는 말이 전해질 만큼 계곡 경관이 수려하다.지각산 동쪽 깎아지른 절벽에는 설패바위, 촛대바위,금강문 등 수많은 기암이 하늘을 찌를 듯이 솟아 선경을 이루는 별유천지이다. 건너편 미륵봉 밑에는 천연기념물 178호로 지정된 환선동굴이 있으며 황금색 종유석, 석순 폭포 등 기묘한 현상으로 감탄을 금치 못한다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", + "MNTN_NM" : "지각산" }, - "longitude" : 126.4372675, - "latitude" : 37.744586699999999 + "longitude" : 128.96111110000001, + "latitude" : 37.333055600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고루포기산은 강원도 강릉시 왕산면과 평창군 도암면의 경계를 이루는 산으로, 주변의 발왕산, 제왕산, 능경봉의 명성에 가려 찾는 이들이 많지 않았던 산이다.태백산맥의 지맥인 해안 산맥에 딸린 산으로, 북서쪽의 빗면은 한때 대관령 스키장이 있었던 곳이다. 부근의 횡계리(橫溪里) 일대는 평탄면을 이룬다.서쪽에는 남한강의 지류인 송천(松川)이 감입곡류를 이루면서 남쪽으로 흘러 하안단구를 이룬다. 북동쪽 빗면으로 흐르는 수계는 왕산면 왕산리(旺山里)에서 강릉 남대천(南大川)의 지류로 흘러든다.", - "MNTN_HG_VL" : "1238", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", - "MNTN_NM" : "고루포기산" - }, - "longitude" : 128.73346340000001, - "latitude" : 37.647446599999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "크게 화려하거나 요란하지 않지만 그런 대로 쏠쏠하게 볼거리가 있고 전망도 좋은 산이다.해발 500여 미터정도의 나지막한 산이지만 정상에 오르면 멀리 영광쪽 바다에 배가 떠다니는 모습이 보이고 무등산을 물론 광주시내까지도 조명할 수 있는 산이다. 광주에서 거리도 그리 멀지 않아 당일치기로 다녀와도 무리가 없다. 작은 규모에 비해 등산로는 꽤 가파른 편이며 아기자기한 암벽미도 그만이다.", - "MNTN_HG_VL" : "98", - "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 성송면\/전라남도 장성군 삼계면 부성리", - "MNTN_NM" : "고성산" - }, - "longitude" : 126.6333333, - "latitude" : 35.299999999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "186", - "MNTN_LOCPLC_REGION_NM" : "강원도 고성군간성읍 금수리", - "MNTN_NM" : "고성산" - }, - "longitude" : 128.45110779999999, - "latitude" : 38.352438200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "546", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", - "MNTN_NM" : "고성산" - }, - "longitude" : 128.45110779999999, - "latitude" : 38.352438200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 정선군에서도 가장 오지 마을이라 할 수 있는 임계면 고양리에 위치한 산이다. 그리고 반론산(1068)은 고양산에서 북쪽 여량 방면으로 뻗은 능선상 최고봉으로 고양산과는 약 4km 정도 거리를 두고 있는 산이다.이 두 산의 주체는 베낭족의 낙원이라 불리던 골지천(骨只川)이 된다. 즉 골지천에서도 가장 하이라이트라 할 수 있는 구미동, 어전동, 성북동, 봉정리 등이 이 두 산을 감싸면서 휘돌고 있다.골지천(骨只川)에 솟아 있는 어머니 같이 넉넉하고 편안한 품을 펼치고 있는 고양산은 정선의 오지 중에 오지인 임계면에 자리잡고 있다.", - "MNTN_HG_VL" : "1151", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", - "MNTN_NM" : "고양산" + "DETAIL_INFO_DTCONT" : "북악산은 서울의 주산으로 경복궁 뒤쪽에 위치하고 남산과 대칭하여 북쪽에 있다하여 북악이며 일명 백악, 면악, 공극산으로도 불리고 있다.북악산길이 시작되는acirc;의문 일대의 부암동은 서울에서는 보기 드문 산촌 같은 마을이다. 백석동otilde;으로 이어지는 산길, 백사실계곡 등 때 묻지 않은 자연을 그대로 간직하고 있다. 곳곳에 문화유적과 미술관, 독특한 인테리어의 음식점 등 볼거리도 널려 있어 출사지로 꼭 한 번씩은atilde;는 명소다.부암동에서 출발하는 북악산 산aring;길은acirc;의문에서 시작해 산 뒤를 휘감아 도는 북악 스카이웨이를 따라 성북구 정릉까지 6.2km 이어진다. 지금은 등산로가 나 있지만 조선시대에는 도성을 지키는 순라꾼들이 오르내리던 길이었고 일반인에게 개방되기 전까지만 해도ucirc;와대를 경비하는 군인들만 오르내리던 길이었다. 산aring;길을 쉬엄쉬엄 걷다 보면 한쪽에는 북한산 보현봉 자락이, 가을이면 한쪽으로 노을oacute;럼#376;오르는 북악산 단풍의 모습이 일품이다.서울에 남은 유일한 생태축인 서울 성곽은 옛 한양의 문화와 역사를 느낄 수 있는 공간이다. 인왕산 성곽길에 이어 2007년 북악산 숙정문~acirc;의문 구간이 개방되면서 서울 성곽 전uuml;를 연결해서 걸을 수 있게 되었다. 18.2km의 성곽길 중에서도 북악산 능선을 따라 이어지는 성벽 길이 인기 코스다. 오랫동안 통행이 금지되어서 성곽의 모습이 잘 보존되어 있고 전망도 빼어나다.", + "MNTN_HG_VL" : "342", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 종로구 부암동", + "MNTN_NM" : "북악산" }, - "longitude" : 128.77055559999999, - "latitude" : 37.416944399999998 + "longitude" : 126.97333329999999, + "latitude" : 37.5930556 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "675", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", - "MNTN_NM" : "고양산" - }, - "longitude" : 128.17715340000001, - "latitude" : 37.736119500000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;계곡과 억새로 유명한 영남알프스의 산gt;이른바 '영남알프스'는 억새산행으로 유명한 산군이다. 취서~신불산 구간이 그렇고, 재약산 사자평이 그렇다. 당연히 가을이 되면 많은 등산인들이 몰린다. 고헌산(1032.8m)은 이 산군에 속하면서도 동쪽에 치우쳐 있다. 유명한 비구니사찰인 석남사를 품고 있는 가지산(1240m)이 바로 옆에 있어 언양에서 들어선 등산인들은 대부분 가지산으로 몰리기 마련이다. 그렇기에 고헌산은 오히려 호젓한 억새산행을 만끽할 수 있는 대상 산이다. 뿐만 아니라 고헌산 대통골은 더위만 살짝 앗아갈 적당한 온도의 계곡물, 암벽등반의 묘미도 함께 즐길 수 있는 곳이다. 반면 경험자의 안내와 암벽등반 장비가 필요하다. 계곡 옆으로 우회로가 있어 위험한 구간은 돌아가면 되지만 긴장을 늦추어서는 안 된다. 대통골 초입은 강산교라는 작은 다리를 지나자마자 사방댐 표석이 있는 곳이나 다리 위에 새로 지은 전원주택을 돌아가면 보인다. 2시간 정도 걸리는 계곡갈림길까지가 좋다. 갈림길에서 왼쪽 계곡을 100m 정도 올라 오른쪽 능선을 타고 주능선으로 가길 권한다. 더 올라가면 계곡이 음습하고 암벽들도 어려워진다. 딱히 돌아갈 만한 길도 없고 낙석의 위험도 있다.", - "MNTN_HG_VL" : "1033", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 언양읍, 상북면, 두서면, 경북 경주시 산내면", - "MNTN_NM" : "고헌산" + "MNTN_HG_VL" : "1055", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "삿갓봉" }, - "longitude" : 129.08707190000001, - "latitude" : 35.646332800000003 + "longitude" : 128.95833329999999, + "latitude" : 37.601388900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1033", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 언양읍, 상북면, 두서면, 경북 경주시 산내면", - "MNTN_NM" : "고헌산" + "DETAIL_INFO_DTCONT" : "능곡산은 백화산 줄기가 구랑리에 와서 맺힌 산으로서 마성면 정리 솥골에서 상내리로 넘어가는 나리재에서 능선을 타고 백화산 반대 방향으로 올라가면 되고, 아니면 마성면 상내리에서 오르는 길이 있고 정상에는 삼각점이 있다.능곡산(571.6m)은 마성면 정리에 위치해 있으며 상내리와 접해 있다. 능곡산을 오르기 위해 찾는 산행객은 드물다. 백화산에서 남으로 뻗어온 산줄기로 인접해 전국에서 워낙 이름난 백두대간상의 명산인 백화산이 버티고 있기 때문이다.백화산에서 여러 방향으로 뻗어나간 한 줄기에 자리잡고 있고 해발도 그리 높지도 못하다.정상은 잡목이 있어서 조망이 되질 않고 정상 전 헬기장에서 백화산과 이만봉쪽으로 펼쳐진 풍경이 들어온다. 동으로 정리와 주지봉 방향은 나뭇가지 사이로 보일뿐 역시 잡목 때문에 조망이 희미하다.정리쪽에서 보는 능곡산은 산세가 아주 순하게 생겼지만, 상내리 질마재골 쪽에서 보면 하늘로 봉이 치솟아 경사도가 심한 삼각형 모양을 하고 있어 위협적으로 느껴진다.", + "MNTN_HG_VL" : "572", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 상내리", + "MNTN_NM" : "능곡산" }, - "longitude" : 129.08707190000001, - "latitude" : 35.646332800000003 + "longitude" : 128.08266570000001, + "latitude" : 36.679440399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "억새군락으로 유명한 영남알프스로 불리는 7개 산 중 하나인 고헌산은 경부고속국도 언양IC에서 서북쪽에 솟아 있는 산이다. 서쪽으로 영남알프스 산 중 가장 높은 가지산과 가까이 있다. 산 동쪽 아래에는 사연댐이 있다.고헌산은 상북면과 언양읍 두서면의 경계를 이루고 있는 높은 산이다. 태양을 숭배하는 민족들한 발자국이라도 태양에 가까운 높은 산은 태양신에 접근하기 쉬운 것으로 생각하였으며 또 하늘의 신이 하계 할 때는 하늘에 가까운 높은 산으로 내려오는 것으로 믿고 있었다. 이 고헌산은 언양 사람들이 가뭄이 되면 기우제를 지내던 곳이기도 한데, 기우제를 지내는 것은 비가 내리고 안 내리는 것이 오로지 신의 작용에 의한 것이라 믿는 우주관에서 비롯된 것이라 할 수 있다. 그들은 용샘이 있는 높은 정상에서 부정을 피해 하늘과 산신과 비를 다스리는 용신에게 정성껏 비를 빌었다한다.경부고속도로 언양 IC에서 서북방향으로 9㎞ (석남사길)쯤 들어간 장성리 쪽에서 북으로 보이는 산으로 서쪽으로 가지산이, 남으로는 신불산 간월산과 영취산(취서산)이 이어져 있으며, 산꼭대기는 돌멱으로 이루어져 있으며, 산 아래 동쪽에는 사연댐이 있다.", - "MNTN_HG_VL" : "1033", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 두서면, 경상북도 경주시 산내면", - "MNTN_NM" : "고헌산" + "DETAIL_INFO_DTCONT" : "노성산은 논산8경 중 제8경인 노성산성이 있는 산이다. 이 산성은 백제시대에 축성된 것으로 자연적인 지세를 교묘하게 이용하여 둘레 약 1킬로미터를 석축으로 거의 완벽하게 쌓은 성지이다. 동면, 북면, 서면을 활석을 다듬어 네모지게 하여 쌓았고, 봉우리 정상에는 장대지로 추정되는 곳과 동벽으로 약간 내려온 곳에 봉수대로 보이는 곳이 남아있다. 성내에는 우물지가 4개소 있고, 건물지로 보이는 여러 개의 유지가 있으며 백제시대의 기와편과 토기편 그리고 고려, 조선시대에 이르기까지 다양한 유물들이 산재해 있다.동쪽으로 계룡산이 막아서고 남쪽으로는 논산평야가 바라다 보이며 북쪽으로는 공주, 서쪽으로는 부여 방면이 한눈에 조망되는 요지로, 연산 황산성과 함께 백제와 신라가 대치했던 방어선에 위치한 산성이다. 그 중요성 때문에 노성산성은 삼국시대부터 조선시대에 이르기까지 계속해서 사용했던 것으로 전해진다.노성산에는 논산시민들이 해맞이를 즐기는 넓은 공터가 있다. 이곳에 오르면 우리나라 3대 곡창지대 중 하나인 논산평야가 황금빛으로 물들어 풍요롭게 보인다. 더 멀리 기운찬 계룡산의 향적봉, 국사봉, 천황봉, 그리고 관음봉으로 이어지는 마루금이 인상적이다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "충남 논산시 노성면", + "MNTN_NM" : "노성산" }, - "longitude" : 129.08707190000001, - "latitude" : 35.646332800000003 + "longitude" : 127.12361110000001, + "latitude" : 36.2955556 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "곡달산" + "DETAIL_INFO_DTCONT" : "충청남도 공주시 사곡면 화월리와 우성면 방문리의 경계를 이루는 산", + "MNTN_HG_VL" : "280", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", + "MNTN_NM" : "약산" }, - "longitude" : 127.4664193, - "latitude" : 37.657477 + "longitude" : 127.05457490000001, + "latitude" : 36.497249500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "곡달산이 자리한 설악면은 경기도에서 오지다.ucirc;평호수와 용문산 줄기가 감싸는 곳에 마을이 형성되어 교통이 불편하고 접근하기가 쉽지 않다. 경춘국도에서ucirc;평댐을 건너 이십리를 달리면 솔치재가 나온다. 이 고개에서 오르는 코스가 가장 무난하다.otilde;otilde;히 오른다 해도 정상까지 두 시간이면 충분하다.산행에 들기 전에 물을 준비하는 것을 잊지 말아야 한다. 솔치재 휴게소나 서쪽의 도로를 따라가다가 작은 개울에서 물을 구할 수 있다. 곡달산 산행 중에는 샘이라고는atilde;을 수 없다. 한우재에서 오를 수도 있으나 정상까지 비탈을 오르는 단조로움이 있다.정상에 오른 후 솔고개로 하산하거나 금강사로 하산할 수 있다. 금강사 쪽에서 오를 수도 있겠으나 골프장이 생긴 후로 다니는 사람이 드물다. 지금 한acirc; 공사중인 동서고속도로가 준공되고 설악면 나들목이 생기면 이 산은 서울에서 30분도 안 걸리는 서울 근교의 산으로 각광받을 것으로 보인다. 힘들지 않게 봉우리를 오르내릴 수 있어 가족 산행이나 실버 산행지로 권할 만하다.", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", - "MNTN_NM" : "곡달산" + "DETAIL_INFO_DTCONT" : "하설산은 충북 제천에 자리잡은 산이다. 백두대간이 대미산 부근에서 북으로 갈라져 솟은 봉우리가 문수봉이고 이곳에서 북서로 뻗어 우뚝 솟은 봉우리가 바로 하설산이다. 이 산은 대미산에서 갈린 산줄기이며 문수봉과 매두막에서 이어지며 월악산국립공원 안에 있다. 여름에도 눈이 온다는 뜻을 지닌 산 이름은 실제로 눈이 오지는 않지만 그만큼 시원하다는 의미를 담고 있다. 특히 산 아래 자리잡은 용하구곡은 경치가 아름답고 계곡물이 차기로 이름 나 있다. 계곡의 물은 대미산에서 발원한 광천에서 흘러들어온다.정상에서의 조망은 월악산국립공원 일대가 한눈에 들어오고 북쪽으로 충주호와 금수산이, 동쪽으로는 도락산 줄기 너머로 소백산 연화봉과 죽령이 보인다. 정상 주변에는 참나무 수림이 빽빽하고 산딸기나무 군락이 1천 평 남짓 형성되어 있다.", + "MNTN_HG_VL" : "1028", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면", + "MNTN_NM" : "하설산" }, - "longitude" : 127.4664193, - "latitude" : 37.657477 + "longitude" : 128.1758734, + "latitude" : 36.874696399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 영월군 하동면 와석리 곡골 동쪽에 우뚝 솟은 곰봉은 산자락 곳곳에 산나물이 즐비하게 자생할 정도로 오염되지 않은 청정지역이다. 곰봉 정상에는 돌을 고여놓고 가마솥을 얹어 놓은 듯한 형상인 자동차 크기의 바위가 세 개 놓여 있다. 정상에 곰 모양의 바위가 있어 곰봉이라 부른다.국립지리원에서 발행한 지형도에 마대산은 표기되어 있으나 곰봉은 이름도 없이 산을 의미하는 기호에 산 높이만 적혀 있다. 이 산은 마대산보다 암릉이 잘 발달되어 있어 전망이 좋다. 암릉에는 소나무가 우거져 있으며, 그 뒤로는 산들이 첩첩하게 서 있어 매우 아름답다.산행은 희귀한 민화를 전시하고 있는 조선민화박물관을 출발하여 암릉을 타고 올라 855m 봉우리에서 시루봉을 지나 정상에 오른다.", - "MNTN_HG_VL" : "1015", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", - "MNTN_NM" : "곰봉" + "DETAIL_INFO_DTCONT" : "사달산은 노추산과 마주보고 있으며 산세는 동서로 6km에 걸쳐진 산이다. 노추산의 남쪽 봉우리가 바로 사달산(四達山)이다. 성현(聖賢) 네 분이 나신다는 산이다. 사통팔달 길이 사방으로 통한다는 이 사달산에서 공부를 하면 학문에 통달하게 되는데 지금까지 설총, 율곡, 인회 같은 이가 학문을 닦았다한다. 설총과 이율곡 선생이 동국십팔현(東國十八賢)의 반열에 올랐으니 앞으로 두 분의 성현(聖賢)이 더 나실 거라고 사람들은 믿고 있다.", + "MNTN_HG_VL" : "1187", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉, 정선", + "MNTN_NM" : "사달산" }, - "longitude" : 128.65944440000001, - "latitude" : 37.2841667 + "longitude" : 128.77932329999999, + "latitude" : 37.543793399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "공덕산은 백두대간이 포암산(961)과 조령산(1017)으로 남하하다가 대미산에서 지맥을 갈래쳐 여우목고개를 지나 일군 산이다. 교통이 불편해 아직 원시림 그대로의 거친 수림을 간직한 산으로 산 중턱 바위사면에 불상이 조각되어 있어 사불산이라고도 불린다.이름에서도 불교적 색채를 느낄 수 있듯이 이 산은 불교를 전파한 고승들과 오랜 인연을 맺고 있다. 신라 진평왕때 창건된 대승사는 1400여년의 역사를 지켜오면서 수많은 고승대덕을 배출하였다. 대웅전에는 보물 575호인 목각탱화와 관련문서가 모셔져 있고 선실에는 보물 991호인 금동보살좌상이 있다.또 멀지 않은 거리에 비구니승들의 수도처인 윤필암이 있어 쉬엄쉬엄 오르는 수행코스로도 손색이 없는 산이다.등산로 입구에는 옛날 중국을 다녀온 나옹이 기념으로 심었다는 아람드리 전나무가 반겨주고 산행내내 아람드리 참나무와 소나무가 반겨주는산, 종주중 반정도는 육산으로서 울창한 나무숲에 가려 원시림은 때묻은 속세의 모든 일들을 잊어버리게 하고 나머지 반은 노송과 함께 어우러진 암릉길은 속세에 나가 어려운 풍파를 헤쳐나가기 위하여 사전 수련을 하듯이 전개되는 바위길의 묘미를 볼 수 있는 산이다.즉 육산과 바위산위 공존하는 산으로 대승사에서 남쪽 능선을 따라 공덕산 823봉까지는 길이 아주 좋은 육산으로 울창한 숲에 가려 조망이 없어 실망을 하는 산이나 823봉부터 윤필암 하산길 까지는 노송과 바위가 어울려 한폭의 동양화를 연출하는 상반된 얼굴을 보이는 산이다.", - "MNTN_HG_VL" : "913", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 동로면", - "MNTN_NM" : "공덕산" + "DETAIL_INFO_DTCONT" : "강원도 양양군에 있는 조봉은 암반과 숲이 연출하는 풍광이 설악산을 방불케하는 숨겨진 명산이다. 이웃한 명소 미천골이 사람들의 발길을 모두 몰아가버린 덕분에 조봉은 천연 그대로의 풍광을 고스란히 보존하고 있다.산행기점에서 조금만 오르면 벽실골이 나오는데 이곳은 굴피밭골, 큰북골 등 모두 여섯 가닥의 지류가 나뉘어지는 곳으로 비선대에서 대청봉 턱밑까지 뻗은 천불동보다 조금 짧은 계곡이다. 벽실골은 하류보다 상류쪽 경관이 한층 돋보인다. 설피밭골을 거쳐 큰북골 입구를 지나면 골이 갑자기 좁아지며 널찍한 암반과 와폭 등이 이어지는데 연이어진 폭포의 절경이 마치 설악산의 12선녀탕을 연상케 한다. 12탕보다 수량은 적으나 대신 서슴없이 물줄기를 거슬러 올라가는 재미를 만끽할수 있다.", + "MNTN_HG_VL" : "1182", + "MNTN_LOCPLC_REGION_NM" : "강원도 양양군", + "MNTN_NM" : "조봉" }, - "longitude" : 128.2832276, - "latitude" : 36.7557683 + "longitude" : 128.56027779999999, + "latitude" : 37.945 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "공덕산은 경북 문경시 산북면과 동로면의 경계를 이루는 산이다. 주능선은 백두대간 포암산(961m)과 조령산(1017m)으로 뻗어 내리다가 대미산(1115m)에서 지맥이 갈라져otilde;주봉(842m)과 함께 나란히 우뚝 솟아올라 있다.이 산은 지형도상의 공덕산뿐만 아니라 예전부터 사불산(四佛山)이라고도 불리는 산이다. 공덕산 정상에서 서쪽으로 능선을 따르다 832미터 봉에서 윤필암으로 내려서는 능선에 네 면에 불상이 새겨진 바위가 있어 사불암이라 했고, 사불산이라 불리게 되었다고 한다.이름난 산에는 이름난 절이 있기 마련이듯 공덕산에도 예외는 아니다. 신라 진평왕 9년(587년)에acirc;건되어 많은 고승대덕을 배출한 대승사가 그렇다. 비구니스님들의 수도oacute;인 윤필암, ‘ucirc;산은 나를 보고 말없이 살라 하고\/acirc;공은 나를 보고 티 없이 살라하네’로 시작하는 선시를 지은 나옹선사가 득도하였다는 묘적암, 보현암을 부속암자로 거느리고 있는 거찰들이 있다.", - "MNTN_HG_VL" : "913", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면ㆍ동로면", - "MNTN_NM" : "공덕산" + "DETAIL_INFO_DTCONT" : "불금봉은 강원도 홍천군 북방면에 소재한 성치산의 봉우리이다. 성치산은 나지막한 산이지만, 남북으로 잇는 주능선이 의연하고 떡갈나무, 굴참나무 등 참나무류가 산초나무와 어울려 길을 가린다. 특히 등산 초입인 원골과 진골 일대는 장송이 하늘을 가려 마치 심산에 온 느낌을 준다. 불금봉에서 정상에 이르는 주능선 길 도중엔 몇 개의 무덤이 자리잡고 있어 그때마다 전망이 열리기도 한다.정상에는 괴이한 모양의 바위가 서있고 북동쪽으로 절벽을 이루면서 기암괴봉이 늘어서 있다. 또 그 아래 용담저수지가 아름답기 그지없다. 특히 강원도 홍천에 자리하고 있어 인적이 드물어 깨끗한 자연 그대로는 보존하고 있는 산중의 하나이다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면 성동리", + "MNTN_NM" : "불금봉" }, - "longitude" : 128.2832276, - "latitude" : 36.7557683 + "longitude" : 127.84704670000001, + "latitude" : 37.733613599999998 }, { "mountain" : { @@ -791,93 +761,93 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "391", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", - "MNTN_NM" : "관모산" + "DETAIL_INFO_DTCONT" : "가평역 서쪽에 위치한 대금산은 명지산(1267m) 남서봉에서 남쪽으로 이어지는 연인산 - 우정봉 - 매봉 - 깃대봉 - 약수봉에 이어 자리하고 있는 산이다. 대금산에서 계속 이어지는 산릉은 592.7미터봉에 이르러 짧은 능선을 남쪽 청우산에 맡긴 다음, 남동으로 나아가 불기산 - 주발봉 - 호명산을 빚어 놓은 다음 여맥을 청평호 일원 북한강에 가라앉힌다. 대금산은 일제 때 이 산에 있던 소림광산에서 말(馬)만큼 큰 금광석이 나왔다고 해서 그렇게 불리기 시작했다 전해진다. 대금산 아래 두밀리의 옛 지명은 ‘삼이곡’이었고, 예부터 나라에 난리가 날 때면 다른 지방 사람들이 이곳을 피난처로 이용한 오지였다고 한다.", + "MNTN_HG_VL" : "706", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", + "MNTN_NM" : "대금산" }, - "longitude" : 126.8583333, - "latitude" : 36.6969444 + "longitude" : 127.4210301, + "latitude" : 37.818873099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "391", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍", - "MNTN_NM" : "관모산" + "DETAIL_INFO_DTCONT" : "해명산은 인천시 삼산면 석모도에 위치한 산으로 서해에서 불어오는 해풍을 받으며 산과 바다의 정취를 동시에 즐길 수 있는 곳이다. 서해에서 불어오는 해풍을 듬뿍 받으며 산행을 할 수 있는 해명산의 정상에서면 낙가산과 상봉산의 모습이 한눈에 들어오고 서쪽바다에는 이름모를 섬들이 아른거리고, 정상을 떠나 주변 바다를 보면서 군데군데 피어있는 진달래 능선을 따라 낙가산으로 갈 때면 마치 바다 위를 걷는 기분이 든다.산세가 아기자기해 가족동반 산행지로 적합하며 산행이 수월하므로 인접한 낙가산 산행을 곁들이는 것이 좋다.", + "MNTN_HG_VL" : "309", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", + "MNTN_NM" : "해명산" }, - "longitude" : 126.8583333, - "latitude" : 36.6969444 + "longitude" : 126.3494724, + "latitude" : 37.676399099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "관산은 천진암 성지가 있는 앵자봉의 주능선이 좌측으로 이어지다 북쪽으로 이어진 산이다. 서쪽으로 무갑리 계곡과 무갑산이 지척이고, 천진암 성지도 가까워 성지 순례와 겸한 산행도 가능하다.양자산, 앵자봉, 관산이 북에서부터 남으로 능선으로 이어져 통상 이 세 산을 연결하여 종주 하는 경우도 많으며 서울시에서 별로 멀지않아 휴일이면 산악회에서 단체로 산행하는 경우가 많다.", - "MNTN_HG_VL" : "501", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면", - "MNTN_NM" : "관산" + "DETAIL_INFO_DTCONT" : "태백산은 경상북도 봉화군 석포면 대현리와 태백시 문곡소도동 그리고 강원도 영월군 상동면 천평리와 접경을 이루며 동경 128。56\"북위 37。05\"에 자리잡은 해발 1,566.7m의 명산이다. 이 산에서 발원하는 물이 영남평야의 젖줄인 낙동강과 우리민족의 역사와 함께한 한강, 삼척의 오십천을 이루니 국토의 종산이자 반도 이남의 모든 산의 모태가 되는 뿌리산이다.태백산은 천제단이 있는 영봉을 중심으로 북쪽에 장군봉(1567m) 동쪽에 문수봉(1,514.9m), 영봉과 문수봉사이의 부쇠봉(1,549.4m)로 이루어져 있다. 암벽이 적고 경사가 완만하여 남녀노소 누구나 쉽게 오를 수 있는 산으로 정상에는 고산식물이 자생하고 봄이면 산철쭉, 진달래의 군락지가 등산객을 맞이하고 여름에는 울창한 수목과 차고 깨끗한 계곡물이 한여름 더위를 잊기에 충분하며 가을은 형형색색의 단풍으로 수놓으며 겨울은 흰 눈으로 뒤덮인 주목군락의 설경을 보여 주는 곳으로 남성다운 중후한 웅장함과 포용력을 지닌 육산으로 이루어져 있다.또한 정상에서 바라보는 일출과 낙조는 장엄하여 세속을 떠난 천상계를 연상케 하고 맑은 날 멀리 동해 바다를 볼 수 있는 것도 태백산이 가지고있는 자랑거리이다. 이 밖에도 최고높은 곳에 위치한 한국명수중 으뜸수 용정, 용담이 있다.1989년 5월 13일 17.44㎢의 면적이 도립공원으로 지정되었으며 소도집단시설지구에 콘도형인 태백산 민박촌을 비롯하여 숙박시설,음식점,야영장 등이 마련되어 있으며 석탄의 역사를 한 눈에 볼 수 있는 석탄박물관이 있고, 겨울철에는 대규모의 눈썰매장이 개장된다.", + "MNTN_HG_VL" : "1567", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "태백산" }, - "longitude" : 127.3583333, - "latitude" : 37.4186111 + "longitude" : 128.91524039999999, + "latitude" : 37.095739199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "관악산은 서울시 관악구와 금천구, 경기도 과천시와 안양시에 걸쳐 있어 북한산,도봉산과 더불어 누구나 쉽게 찾는 친근한 산이다. 멀리서 보면 온통 바위로 뒤덮여 있는 산세를 가진 관악산은 해발은 낮으나 등산로 곳곳에 위험한 암릉이 있어 조심해야 한다.관악산은 예로부터 불의 산(火山)이라 하여 조선 태조가 궁터를 지금의 경복궁 자리로 옮길 때, 무학대사가 이곳은 관악산과 마주 보이는 자리로 관악산의 화기가 궁을 눌러서 내우외환이 끊이지 않을 것이라며 반대했지만, 정도전의 남쪽에 한강이 가로질러 있어서 영향이 없을 것이라는 주장을 받아 들여 지금의 경복궁을 창건하였다 한다. 그후 태종때 왕자의 난, 세조의 왕위 찬탈, 임진왜란, 병자호란, 그리고 경복궁에 발생한 수차례의 화재가 발생한 것을 풍수지리설로 해석하는 이도 있다. 대원군은 경복궁을 재건할 때 관악산의 화기를 누르기 위해 경복궁 정문인 광화문 앞에 바다의 신으로 상상의 동물인 해태 조각상을 만들어 세웠다.관악산 연주대는 고려가 망하자 남은 유신 열 사람이 관악산 절에 숨어살며 경복궁을 바라보며 통곡을 했다 하여, 임금을 사모한다는 뜻으로 연주대(戀主臺)라 불려 지게 되었다 한다. 이성계가 연주암을 중창한 뒤, 태종의 두 아들인 양녕대군과 효령대군은 태종이 왕위를 셋째 충녕대군(세종)에게 물려줄 뜻을 알고 관악산에 입산하였다 한다. 예전에 관악산을 삼성산이라 부른 것은 신라의 고승 원효,의상,윤필이 이 산에서 세 승려가 일막,이막,삼막의 세 암자를 짓고 따로 수도하여 득도하였다 하여 붙여진 것으로 전해지고 있다. 임진왜란때 일막,이막은 소실되고 삼막사(三幕寺)만 남았다는 것이다.", - "MNTN_HG_VL" : "632", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구ㆍ금천구, 경기도 안양시ㆍ과천시", - "MNTN_NM" : "관악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "155", + "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", + "MNTN_NM" : "청명산" }, - "longitude" : 126.9610024, - "latitude" : 37.442938499999997 + "longitude" : 126.7261111, + "latitude" : 37.175555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "관인봉은 정상에서 남봉으로 뻗어내린 능선과 평행선을 이루고 주능선은 대부분 암릉과 암벽지대로 이루어져 있고, 이러한 천혜의 지형을 이용행 보가산성을 축조한 석축이 남아있다. 지장봉계곡을 사이에 두고 서로 마주보고 있는 삼형제봉과 지장봉은 일직선으로 연결되어있고 관인봉은 관인북봉 위쪽에서 예각으로 좌회전하여 서진하면 지장봉과 만난다.경기도 포천군 관인면 서북단에 위치한 관인봉 일원은 예로부터 전략적 요충지로 삼국시대 때 고구려, 백제, 신라가 영토 분쟁을 하였던 곳이다. 삼국시대 초기에는 백제 땅이었다가 고구려 광개토왕 6년(396년)에는 고구려령이 되었고, 신라 진흥왕 12년(551년)에는 신라의 국토에 편입되어 경덕왕 16년(757년)에는 칠성군에 속해 있었다는 기록이 있다. 신라 말에는 궁예가 태봉국을 건국하여 철원에 도읍을 정하였을 때 태봉국의 영역에 속하게 되었다한다. 태봉국왕인 궁예의 폭정에 못 견딘 어진(仁) 관리(官)들이 관직을 버리고 이 지역에 모여 살았다는 유래로 이 지역이 관인으로 불리게 되었다 한다.정상에서 조망은 북으로는 철원군의 고대산(高臺山.832m)과 금학산(金鶴山.947m)이, 동쪽으로는 고남산(古南山.644m)이, 남쪽으로는 종자산(種子山.643m), 서쪽으로는 지장봉(地藏峰.877m)이 관인봉을 감싸고 있다. 울창한 수림으로 수량이 많은 큰골은 계곡 피서지로서 유명하고 가을 단풍도 좋다.", - "MNTN_HG_VL" : "710", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시", - "MNTN_NM" : "관인봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군", + "MNTN_NM" : "금계산" }, - "longitude" : 127.17340609999999, - "latitude" : 38.1419122 + "longitude" : 128.44862860000001, + "latitude" : 35.7696118 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "광교산은 원래 광악산이었는데 928년 왕건이 후백제 견훤을 평정하고 나서 산근처에 행궁을 차리고 군사를 위로할 때 산 정상에서 불빛이 하늘로 솟아오르는 것을 보고 이 산은 '부처님의 가르침을 주는 산' 이라 하여 이름을 광교산으로 붙였다고 전해진다.광교산은 물이 풍부한 산으로 광교저수지, 낙생저수지, 고기동 물놀이터가 시민의 사랑을 받고 있으며 국가보물 제9호 서봉사지 현오국사타비, 경기도 문화재 제38호 김준용 장군 승전비가 있다.", - "MNTN_HG_VL" : "582", - "MNTN_LOCPLC_REGION_NM" : "경기도", - "MNTN_NM" : "광교산" + "DETAIL_INFO_DTCONT" : "강원도 평창군 용평면과 대화면 사이에 솟아 있는 거문산은 오대산에서 서쪽으로 뻗어 내린 산줄기가 계방산에 이르러 남쪽으로 이어지면서 백적산(1,141m)에서 서쪽으로 가지를 친 능선이 금당산(1,173m)을 빚어 놓고 그 여력으로 우뚝 솟은 산이다. 이 산을 일으키고 남쪽으로 뻗어 내린 지맥은 평창강과 대화천을 가라앉힌다.금당산(錦塘山)·백적산(白積山)·형제봉(兄弟峰) 등과 함께 한국의 척량부(脊梁部)를 이루는 태백산맥(太白山脈)의 일부를 구성한다. 중부지방을 북서쪽으로 흐르는 한강(漢江)의 지류인 평창강(平昌江)의 발원지를 이룬다.", + "MNTN_HG_VL" : "1173", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "거문산" }, - "longitude" : 127.01508370000001, - "latitude" : 37.3280368 + "longitude" : 128.42388890000001, + "latitude" : 37.527500000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "지형적으로는 공주시 유구읍, 아산시 송악면, 천안시 광덕면이 광덕산을 끼고있다. 산세가 높으며 나무들이 오래되어 경관이 보기가 좋은곳이다. 특히 노약자도 많이 이용하는데산림과에서 만든 소방도로로 이용을 많이 한다.", - "MNTN_HG_VL" : "638", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 천안시 광덕리", - "MNTN_NM" : "광덕산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "봉수산" }, - "longitude" : 127.034266, - "latitude" : 36.693891999999998 + "longitude" : 128.7333333, + "latitude" : 36.733333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한북정맥에 들머리가 되는 광덕산은 경기도에서는 가장 북쪽에 위치한 산이며, 강원도 화천군과 철원군의 경계를 이루고 있으며, 거의 정상 부위까지 군사 비상도로가 개설되어 있고 산자락 곳곳에 군사시설이 있어 지형적으로 군사 요충지임을 말해주는 산이다.가을이면 오색단풍의 물경이 겨울이면 설경이 아름다운 곳이다. 이 산은 교통편이 좋아 쉽게 찾을 수 있고, 또 주위에 백암산, 적근산, 복주산 등 여러 산과 백운계곡이 유원지화되어 있어 올때마다 새로움을 느낄 수 있다.", - "MNTN_HG_VL" : "699", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 철원군 서면, 화천군 사내면", - "MNTN_NM" : "광덕산" + "DETAIL_INFO_DTCONT" : "비슬산의 주봉에서 동쪽으로 이어지는 능선이 북으로 방향을 바꾸어 올라가다 솟구쳐서 이루어진 산(900m)이다. 비슬산 주봉우리의 동쪽 능선이 북쪽으로 이어져 솟은 산이다. 비슬산과 산세가 비슷하며, 700m 부근부터는 경사가 완만한 고위평탄면 지형을 이룬다. 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 봄에는 진달래 천국을 이루고 가을에는 단풍이 온산을 물들여 대구 근교 지방의 주민들에게는 매우 친근한 산이다.정상 일대 능선에는 억새풀과 진달래가 군락을 이루어 자란다. 주암산과는 능선으로 이어져 있으며 두 산을 연결하여 산행하면 좋다.", + "MNTN_HG_VL" : "905", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", + "MNTN_NM" : "최정산" }, - "longitude" : 127.4307982, - "latitude" : 38.115392399999998 + "longitude" : 128.60083330000001, + "latitude" : 35.763888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 아산시 송악면과 천안시 광덕면의 경계를 이룬 광덕산은 높이에 비해 산세와 조망이 뛰어난 산으로 정평이 나 있다. 온양온천을 지척에 두고 있어 온천산행지로도 널리 알려진 광덕산은 천안, 아산, 공주의 분기점이자 금북정맥 상의 각흘고개와 갈재고개 사이의 무명봉에서 북쪽으로 갈래 쳐 천안시와 아산시를 가르며 뻗은 산줄기의 최고봉으로서, 흔히 내포지방이라 일컫는 아산, 당진, 서산뿐 아니라 평택, 천안, 대전 등 충남북 일원을 한눈에 조망할 수 있는 산이다. 크고 풍후(豊厚)하여 옛날부터 덕이 있다고 하는 광덕산은 난리가 나거나 불길한 큰 일이 있으면 산이 운다는 전설이 있으며 계곡에는 언제나 맑은 물이 흘러 곡교천의 상류가 되며 남록인 공주시 사곡면 운암리에는 유서 깊은 마곡사가 자리하고 있다.또한 호두나무가 풍성한 광덕사 주변은 갑신정변을 일으켰던 풍운아 김옥균, 임시정부 주석 김구 선생 등 역사적인 인물들이 은신했던 곳으로도 알려져 있다.", - "MNTN_HG_VL" : "699", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시 광덕면, 아산시 송악면", - "MNTN_NM" : "광덕산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "192", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 서구, 경기도 김포시", + "MNTN_NM" : "가현산" }, - "longitude" : 127.034266, - "latitude" : 36.693891999999998 + "longitude" : 126.6497777, + "latitude" : 37.626327199999999 }, { "mountain" : { @@ -891,193 +861,183 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "진주와 함안의 경계지점에 터잡고 있는 계방산과 방어산은 가족산행지로는 더없이 좋은 곳이다.계방산은 500m급의 산에 불과하지만 능선의 굴곡이 심한데다 군데군데 암반을 올라야 하고 끝없이 이어지는 소나무터널이 산행의 묘미를 한층 더하게 해 준다. 여기다 방어산 7부능선에 터잡은 보물 159호\"\"마애약사삼존불\"\"도 만날 수 있고 능선에 오르면 남강에서 불어오는 싱그러운 바람을 맞으며 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "451", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진주, 함안", - "MNTN_NM" : "괘방산" - }, - "longitude" : 128.30583329999999, - "latitude" : 35.225277800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 강릉시 강동면 정동진역과 안인진역 사이에 위치해 있다. 이 산은 서울 경복궁에서 정동(正東)에 있다 하여 붙여진 이름인 정동진의 열차역이 산행들머리다.해수욕장이 있는 등명에서 서쪽으로 솟은 산이 괘방산으로 등명과 산 정상 사이에 락가사가 동해바다를 향해 자리잡고 있다. 등명락가사에서 북으로 500m거리인 대포동은 96년 9월 18일 북한 무장공비들이 잠수함으로 침투한 곳이다. 이 사건을 계기로 괘방산에다 안보체험 등산로를 개설하게 되어 이 산이 유명하게 되었다. 당시 침투했던 잠수함은 대포동 바닷가에 전시하고 통일공원이 조성되어 있다.괘방산이라는 산 이름은 옛날 과거에 급제하면 이 산 어디엔가에 두루마기에다 급제자의 이름을 쓴 방을 붙여 고을 사람들에게 알렸다는 데서 생긴 이름이라 전해지고 있다.", - "MNTN_HG_VL" : "339", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 강동면", - "MNTN_NM" : "괘방산" + "DETAIL_INFO_DTCONT" : "구학산은 충북 제천시 백운면,봉양면과 강원도 원주시 신림면의 경계를 이루는 산이다. 남쪽 끝머리에 자리한 남대봉(1,187m)에서 서남쪽 백운산(1,087m)으로 뻗어 내리던 능선이 백운산 정상을 약 2km 남겨둔 981m봉에서 동남쪽으로 뻗어 내린 능선이 구력재를 지나 첫 번째로 높이 솟아 있는 산이다.구학산을 일으킨 능선은 남쪽으로 흘러내리며 주론산을 빚어 놓은 뒤, 남쪽으로 이어지다 박달재에서 맥을 낮추어 박달재를 이루고, 다시 고도를 높이며 시랑산(691), 면위산(780), 마미산(601)을 빚어 놓고 그 여맥을 충주호에 가라앉힌다. 산 이름에는 유래가 있듯이, 구학산에는 옛날 이 산에서 살던 아홉 마리의 학이 사방으로 날아가 아홉 군데의 '학'자가 들어가는 지명이 생겨났다는 전설이 전해 내려오고 있다.구학산에서 살던 아홉 마리의 학이, 신림 방면의 황학동, 상학동, 선학동과, 봉양 방면의 학산리와 구학리, 백운면 방면의 방학리와 운학리, 송학면의 송학산과 충북 영동의 황학산으로 한 마리씩 날아가 마을 이름이 생겨났다고 한다.구학산은 부드러운 능선으로 이어져 적설기 등산지로 좋고, 때묻지 않은 오지 농촌의 순박한 풍경을 볼 수 있어 더욱 좋다. 구학산은 산 전체가 육산으로 울창한 수림으로 덮여 있으나 정상은 바위로 돌출 되어 있어 전망이 좋은 편이다. 북으로는 백운산이 가깝게 보이고, 동으로는 감악산, 석기암산, 용두산과 제천시가 아스라히 보인다. 남으로는 주론산과 시랑산 사이로 박달재 고갯길이 보이고, 서쪽으로는 촉새봉(십자봉)과 삼봉산이 한눈에 들어온다.", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", + "MNTN_NM" : "구학산" }, - "longitude" : 128.99863020000001, - "latitude" : 37.713526999999999 + "longitude" : 128.04027780000001, + "latitude" : 37.188888899999988 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "518", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시", - "MNTN_NM" : "교룡산" + "MNTN_HG_VL" : "1084", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선", + "MNTN_NM" : "반론산" }, - "longitude" : 127.3522969, - "latitude" : 35.429327299999997 + "longitude" : 128.7305556, + "latitude" : 37.4641667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구곡산 산행 기점은 진주서 중산리 가는길에 위치한 산청군 덕산리 덕산서원(조선시대 대유학자 남명 조식선생 사적지로 사적305호)이다. 약간 불투명한 하산길 말고는 험로는 없지만 무성한 산죽군락이 가을이면 누렇게 변해 황금능선이란 이름이 붙은 산행후반부는 산행 재미가 꽤 빼어나다.지리산 남부능선에 솟아 있는 산으로 대원사 길과 중산리 길이 갈라지는 덕산마을 서쪽에 있다. 이 산에서부터 국사봉을 거쳐 써리봉까지 이어지는 20여 ㎞에 이르는 능선을 일명 '황금능선'이라 하는데 이는 가을이면 산죽군락이 누렇게 변해서 붙여진 이름이다.황금능선의 가장 긴 코스는 구곡산 남쪽 마을인 외공마을에서 시작, 산청군의 4대 사찰 중 하나인 도솔암 직전의 왼쪽 계곡을 타면서 본격적인 산행에 나서게 되는데 산중턱에 있는 도솔암까지는 대개 차량으로 오른다.정상에는 정상석이 세워져 있으며, 천왕봉, 칠선봉, 삼신봉, 촛대봉, 장터목, 제석봉 등 이른바 남부능선의 봉우리들이 시원하게 펼쳐진다. 글자 그대로 아홉계곡이 있다고하여 구곡산이다. 구곡산은 황금능선의 들머리로서 능선에 서면 지리산 천황봉이 손에 잡힐듯이 가까워 보이며, 구곡산 정상에 서면 장괘한 지리산 주능이 가장 가까이 조망되고 봄이면 철쭉, 가을이면 단풍등 후회없는 산행이 된다.", - "MNTN_HG_VL" : "961", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청", - "MNTN_NM" : "구곡산" + "DETAIL_INFO_DTCONT" : "인천에서 영종도 선착장이 있는 구읍배터 앞에 있는 아담한 석화산은 우리 역사의 개항과 더불어 열강의 수난을 겪은 산이다. 병인양요(1866)때는 우리 강화도에서 우리 원군에 패해 하여각종 문서와 유물을 훔쳐 달아나는 프랑스 함선으로부터 무차별 포격을 받았으며, 상인(商人)오페르트는(1868) 대원군의 아버지인 남인군묘를 도굴하고 이곳을 한동안 점령하면서 개항을요구하기도 했으며, 신미양요(1871)때는 초지진과 덕진진에 이어 광성보까지 무너졌던 아픈 상처를 같이 했던 곳이다. 3개의 봉우리로 구성된 석화산은 조림 사업이 잘 된 곳 중에 한곳이다. 소나무가 우거져 있으며숲길은 낙엽으로 된 방석을 딛고 걷는 듯한 착각이 들 정도로 감촉이 좋다. 특히 솔잎 낙엽 길은솔 향 내음이 더욱 좋은 산이다.", + "MNTN_HG_VL" : "143", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구 중산동", + "MNTN_NM" : "석화산" }, - "longitude" : 127.79553679999999, - "latitude" : 35.277158700000001 + "longitude" : 126.5508463, + "latitude" : 37.5047292 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부산광역시의 대표적인 진산 중의 하나인 구덕산은 울창한 수림을 자랑하고 있다.구덕산은 해발 562m로 북구 학장동과 사하구 당리동, 서구 서대신동의 경계에 솟아 있다. 태백산맥의 말단 금정산 줄기 끝자락에 위치하고 있으며, 북동쪽으로는 엄광산에, 남서쪽으로는 시약산에 각각 이어져 있다.산기슭에는 구덕사가 있고, 시민의 휴식공간으로도 널리 이용되고 있는 대신공원과 한때 대규모 꽃 재배단지로 유명했던 꽃마을, 구덕수원지 등을 품고 있어 곳곳에 원예수와 꽃이 재배되어 시민들의 산책로로도 많이 이용된다. 구덕고개 밑으로는 구덕 터널이 뚫려 있다. 예전에는 이 산을 구덕산(舊德山) 또는 엄광산(嚴光山)이라고 불렀다.", - "MNTN_HG_VL" : "562", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 북구, 사하구, 서구", - "MNTN_NM" : "구덕산" + "DETAIL_INFO_DTCONT" : "적자봉이 있는 보길도는 다도해해상국립공원의 숨은 진주다. 해가 수평선으로 가라앉을 때 하늘과 바다를 물들이는 무지개빛 노을이 장관이다. 이처럼 찬란한 빛이 황홀경을 되쏘는 봉우리라서 ‘적자봉’이라 한다. 이 산은 남쪽에 누운 거대한 암소가 새끼를 어르듯 북으로 광대봉, 망월봉, 일락봉 등 300미터 안팎의 산들을 품고 있다. 정상 부근에는 섬회양목 등 많은 희귀식물들이 향기를 뿜고 기암괴석들이 능선을 잇는다. 멀리 해남의 땅끝과 달마산, 완도의 상황봉까지 사철 동백나무, 예덕나무, 정금나무, 곰솔 등 250여 종의 식물들이 수해를 이루어 늘푸른 산의 생기를 불어 넣는다. 가까운 예송리의 천연기념물 제40호인 상록수림과 해수욕장도 가볼 만하다.적자봉을 중심으로 광대봉, 망월봉, 일락봉이 둥근 원을 그리듯 펼쳐져 있고 안쪽으로 고산 윤선도의 적거지였던 부용동에 유적지(사적 368호)가 남아 있다. 보길도는 조선 중기의 탁월한 가객 고산 윤선도의 유배지로서 그의 체취가 물씬 풍긴다.", + "MNTN_HG_VL" : "431", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 보길면", + "MNTN_NM" : "적자봉" }, - "longitude" : 128.99967799999999, - "latitude" : 35.122726499999999 + "longitude" : 126.5313889, + "latitude" : 34.137777799999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구룡산(九龍山) 정상은 해발307.7m의 서울특별시 서초구 염곡동, 내곡동, 양재동과 강남구 개포동 일대에 위치한 산이다. 구룡산은 열 마리의 용이 승천하는 것을 인근을 지나가던 임신한 여성이 보고 크게 놀라 소리를 질러 용 한마리가 떨어져 죽고, 아홉 마리만 하늘로 승천하였다고 한다. 아홉 마리의 용이 승천하면서 남긴 흔적이 구룡산이라 불리게 되었으며, 하늘에 승천하지 못하고 죽은 용이 있던 자리가 물이 되어 양재천(良才川)이 되었다는 전설이 있다. 실제로 산을 자세히 보면 9개의 계곡으로 이루어져 있다.정상보다 낮은 이 산의 주봉(主峰)은 국수봉(國守峰)이라고 하는데, 조선시대 전부터 정상에 봉수대(烽燧臺)가 있어 국가를 지킨다고 해서 붙여진 것으로 이 곳에는 바위굴 국수방(國守房)이 있어 봉수군(烽燧軍)이 기거했다고 한다. 『여지도서』 광주목에\"관아의 남쪽 30리에 있다. 봉수대가 설치되어 있다\"고 기록되어 있다.내곡동에 있는 헌인릉과 함께 구룡산 기슭에 세종대왕이 묻힌 영릉(英陵)이 있었으나, 1469년(예종 1년)에 여주로 천장(遷葬)하였다. 초장지(初葬地)였던 구룡산 내곡동에 국가정보원이 들어서 있다.구룡산 제2봉인 국수봉전망대는 서울 강남.강북과 경기도 한강하류와 상류지역까지를 관망할 수 있는 최적지로 주.야경 조망명소이다.약 300m의 산으로 산높이나 길이 험하지 않아 가족과의 산행코드로는 제격이며, 접근성도 용이하여 부담없이 즐길 수 있다.구룡산에는 능인선원과 자룡사가 있다. 2015년 9월 13일 능인선원에 세계 최대 약사여래좌불을 점안하여 이름을\"서울약사대불\"이라 하였다.이 산에는 자작나무과인 수피가 얇은 종잇장처럼 벗겨지는 물박달나무 군락지가 산재해 있으며, 그 외에 신갈나무, 리기다소나무, 아까시나무 등이 있다. 관악산, 청계산, 우면산 등과 산자락이 이어진다.", - "MNTN_HG_VL" : "308", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 염곡동ㆍ내곡동, 강남구 개포동", - "MNTN_NM" : "구룡산" + "DETAIL_INFO_DTCONT" : "치악산은 강원도 원주시와 횡성군의 경계를 이루는 산으로, 산세가 뛰어난 데다 영동고속국도와 중앙고속국도에 인접해 있어 교통이 편리해 중부권 산행지로 인기가 높다.", + "MNTN_HG_VL" : "1282", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 횡성군, 영월군", + "MNTN_NM" : "치악산" }, - "longitude" : 127.0572222, - "latitude" : 37.469166700000002 + "longitude" : 128.05050990000001, + "latitude" : 37.3716893 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구룡산은 강원도 영월군 수주면을 감싸 흐르는 서만이 강변에서 북쪽으로 솟아 있는 산이다. 구룡산 남쪽 산자락 끝에 위치한 '섬안'이라는 마을을 동, 남, 서쪽으로 감싸 흐르는 강줄기 이름이 서만이강인데 옛날 명칭은 '섬안이강'이라고 전해지고 있다.정상에 오르면 치악산과 매화산이 스카이라인을 이루고, 산갓봉, 화채봉, 백덕산, 사자산, 돼지봉, 배거리산 등 숲겨지 명산들이 주변에 있고, 선달산과 소백산, 금수산까지 보인다. 때묻지 않고 수수하며 능선과 깨끗한 계곡이 좋고, 사철 등산하기에도 그만이다.", - "MNTN_HG_VL" : "283", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", - "MNTN_NM" : "구룡산" + "DETAIL_INFO_DTCONT" : "산이 바위로 이루어져 봉우리마다 하늘을 찌를 듯 솟아있는 천관산은 지리산, 월출산, 내장산, 내변산과 함께 호남의 5대 명산중 하나다.아기바위, 사자바위, 종봉, 천주봉, 관음봉, 선재봉, 대세봉, 석선봉, 돛대봉, 구룡, 갈대봉, 독성암, 아육탑 등을 비롯 수십개의 기암괴석과 기봉이 꼭대기 부분에 비죽비죽 솟아 있는데, 그 모습이 주옥으로 장식된 천자의 면류관 같다하여 천관산이라 불렀다고 한다.", + "MNTN_HG_VL" : "724", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍, 대덕읍", + "MNTN_NM" : "천관산" }, - "longitude" : 128.21341229999999, - "latitude" : 37.3214763 + "longitude" : 126.91597160000001, + "latitude" : 34.532343099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구만산(九萬山)은 낙동정맥의 가지산에서 서쪽으로 뻗은 운문지맥에 솟은 산이다. 구만산은 근oacute;의 억산(962m), 육화산(670m)과 함께 숫자로 된 재미있는 이름을 가졌다. 구만산은임진왜란 당시 구만명이 이 산으로 피했다고 붙여진 이름이라고 한다. 구만산 서쪽에는 4km의ucirc;정한 구만계곡이 있다.능선에 오르면 주변으로 펼쳐진 영남알프스의 연봉들을 감상할 수 있고 능선 곳곳에서 툭툭 불거져 나온 기암들이 많아 풍광이 좋다. 또 같은 산줄기에 솟은 억산이나 육산과 연계한 산행도 할만 해 자신의 일정이나uuml;력에 따라 다양한 코스를 계획할 수 있다.교통이 편리한 밀양시 산내면 쪽을 들머리로 잡는 게 좋다.", - "MNTN_HG_VL" : "785", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산내면, 경상북도 청도군 매전면", - "MNTN_NM" : "구만산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "334", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천", + "MNTN_NM" : "절산" }, - "longitude" : 128.88059190000001, - "latitude" : 35.626136899999999 + "longitude" : 127.7678485, + "latitude" : 38.119342699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "785", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "구만산" + "DETAIL_INFO_DTCONT" : "경기도 안성군 삼죽면, 죽산면, 금광면에 위치한\"\"칠장산군\"\"(덕성산-칠현산-칠장산)은 백두대간 중 속리산에서 가지쳐 나온 정맥인 금북정맥에 속한 산이다. 높이는 높지 않지만 산의 폭이 크고 숲이 울창하여 그 일부는 안성시와 진천군의 경계를 이루고 있으며, 산 기슭에 칠장사란 고찰이 있어 유명해진 산이다.636년(신라 선덕여왕 5) 자장율사가 창건한 칠장사는 조선 명종 때 임꺽정이 승려인 병해와 함께 10여 년 머물던 사찰이다. 칠장사오불회괘불탱(국보 296), 칠장사혜소국사비(보물 488), 봉업사석불입상(보물 983), 조선 후기에 진흙으로 빚은 사천왕상(경기유형문화재 11)을 비롯하여 대웅전(경기유형문화재 114), 인목대비친필족자(경기유형문화재 34), 철당간(경기유형문화재 39) 등 많은 문화재를 보유하고 있다.국보와 보물이 있는 한적한 고찰 칠장사를 둘러 보고, 숲이 울창한 칠장산에 올라 시원한 공기를 마시고 내려와 칠장사 혜소국사비 아래쪽 골짜기 약수터를 둘러보면 칠장산과 칠장산 순례는 끝난다.", + "MNTN_HG_VL" : "492", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 죽산면, 금광면, 삼죽면", + "MNTN_NM" : "칠장산" }, - "longitude" : 128.88059190000001, - "latitude" : 35.626136899999999 + "longitude" : 127.3912223, + "latitude" : 37.030774200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "애오라지 산만 찾아다니는 산꾼들이라도 경주에 들어서면 가슴이 설렌다. 어딜 가나 역사와 전통의 향기에 마주치게 되는 천년고도인 것이다.비록 산만 찾아 나선 길이라 해도 언제 어디서 뜻밖의 문화유산과 접하게 될지 모른다는 기대감을 가져도 좋은 것이 경주쪽 산행이다. 산행초입에는 천도교의 유적지이자 성지인 용담정(龍潭亭)이 들어서 있어 색다른 경주의 역사유적을 만나는 기쁨도 있다.", - "MNTN_HG_VL" : "594", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", - "MNTN_NM" : "구미산" + "DETAIL_INFO_DTCONT" : "주걱봉은 설악산 국립공원의 남서부에 위치해 있는 가리봉 줄기에 자리잡고 있다. 최고봉인 가리봉을 위시하여 가리봉 북쪽 지릉의 십이연봉, 주걱처럼 생긴 주걱봉, 삼형제봉 등이 한데 어우러져 있는데 모두 바위봉으로 이뤄져 산세가 급하고 험준하다. 북쪽으로 자양천·계천이 흐르고 이 두 하천을 사이에 두고 맞은 편에 대승령(1210m)·안산(1430m)이 있다. 북쪽 산 아래에 하늘벽·장수대가 있다.주걱봉을 비롯한 가리봉 줄기를 오를때는 사전에 정확한 정보를 준비해야 한다. 점봉산처럼 원시림이 울창하고 암봉이 이어져 있으며 양쪽에 낭떠러지가 있어 능선 중앙부에 있는 가리봉으로 접근하는 일이 쉽지 않기 때문이다.", + "MNTN_HG_VL" : "1401", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면, 인제읍", + "MNTN_NM" : "주걱봉" }, - "longitude" : 129.1364494, - "latitude" : 35.884555400000004 + "longitude" : 128.3327778, + "latitude" : 38.096944399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "세종식록지리지에 상주 삼명산의 하나라고 했을 정도로 빼어난 산세를 가지고 있다. 그래서 속리산이 아니면서도 속리산국립공원의 남쪽 경계에 포함되었다. 지금은 거의가 보은군 땅이다.25번 국도를 타고가다 보면 금방 눈에 띄다. 군계일학인 까닭이다. 자락에는 시루를 엎어놓은 듯한 봉우리까지 있어 정말 신령스런 산이라는 생각이 들게 한다. 그래서인지 구령산(九靈山)이라고도 했다. 구병산은 충북 보은군과 경북 상주군의 속리산 국립공원 남쪽 국도변에 자리잡고 있다.예로부터 보은 지방에서는 속리산의 천황봉은 지아비 산, 구병산은 지어미 산, 금적산은 아들 산이라 하여 이들을 '삼산'이라 일컫는다. 속리산의 명성에 가려 일반인에게는 잘 알려져 있지 않아 산 전체가 깨끗하고 조용하며 보존이 잘 되어 있는 편이다. 보은군청에서는 속리산과 구병산을 잇는 43.9km 구간을 1999년 5월 17일 '충북 알프스'로 업무표장 등록을 하여 관광상품으로 널리 홍보하고 있다. 6·25전쟁 때 폐허가 된 토골사 터가 있고 절 터 앞뒤로 수백년 생의 참나무들이 있다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 보은군 마로면ㆍ속리산면", - "MNTN_NM" : "구병산" + "DETAIL_INFO_DTCONT" : "가리왕산에서 뻗어 내려간 주능선이 서쪽으로 중왕산을 일으키고 여기서 남쪽으로 다리를 놓은 듯 가로질러 내려가는 능선 끝에 일으킨 산이 바로 청옥산이다, 산세는 가리왕산과 흡사한 점이 있고, 중후한 육산의 형태를 띠고 있다.청옥산은 '곤드레' 나물과 더불어 '청옥' 이란 산채가 많이 자생하여 이름 붙여진 산이다. 능선이 비교적 평탄한 지형으로 그 면적이 볍씨 6백두락이나 된다는 뜻에서 지어진 '육백마지기'가 산 정상에 위치하고 있으며 고랭지 채소를 주로 재배하고 있다.산행은 백일동에서 동남계곡을 따라 밸패재에 올라 남쪽 능선으로 정상에 올랐다가 서쪽 능선을 따라 삿갓봉(1,055m)으로 이어지는 능선 중간에서 지동리를 지나 창선탄광 입구 고길리로 하산할 수 있다.", + "MNTN_HG_VL" : "1256", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "청옥산" }, - "longitude" : 127.8616372, - "latitude" : 36.469489500000002 + "longitude" : 128.50805560000001, + "latitude" : 37.410277800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "세종식록지리지에 상주 삼명산의 하나라고 했을 정도로 빼어난 산세를 가지고 있다. 그래서 속리산이 아니면서도 속리산국립공원의 남쪽 경계에 포함되었다. 지금은 거의가 보은군 땅이다.25번 국도를 타고가다 보면 금방 눈에 띄다. 군계일학인 까닭이다. 자락에는 시루를 엎어놓은 듯한 봉우리까지 있어 정말 신령스런 산이라는 생각이 들게 한다. 그래서인지 구령산(九靈山)이라고도 했다. 구병산은 충북 보은군과 경북 상주군의 속리산 국립공원 남쪽 국도변에 자리잡고 있다.예로부터 보은 지방에서는 속리산의 천황봉은 지아비 산, 구병산은 지어미 산, 금적산은 아들 산이라 하여 이들을 '삼산'이라 일컫는다. 속리산의 명성에 가려 일반인에게는 잘 알려져 있지 않아 산 전체가 깨끗하고 조용하며 보존이 잘 되어 있는 편이다. 보은군청에서는 속리산과 구병산을 잇는 43.9km 구간을 1999년 5월 17일 '충북 알프스'로 업무표장 등록을 하여 관광상품으로 널리 홍보하고 있다. 6·25전쟁 때 폐허가 된 토골사 터가 있고 절 터 앞뒤로 수백년 생의 참나무들이 있다.", - "MNTN_HG_VL" : "877", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화남면 평온리, 보은군 마로면 적암리, 외속리면 구병리", - "MNTN_NM" : "구병산" + "DETAIL_INFO_DTCONT" : "달마산은 옛날 영암의 송양현에 속했을 정도로 월출산과 가깝다. 달마산은 바위들이 갖가지 형상을 하고 있어 마치 금강산을 길게 펼쳐 놓은 듯하다 하여 ‘호남의 소금강’이라 불러왔다. 또 하나의 자랑은 산자락에 있는 미황사다. 미황사는 한반도 최남단에 위치한 사찰로서 바닷길 불교 전래를 추측케 하는 신비로운 전설을 간직한 천년 고찰이다. 사람들은 바위의 누런 이끼, 금빛 나는 금샘, 달마전 낙조를 미황사의 3황으로 꼽는다. 달마산 종주산행을 하면 이 산자락에 숨겨져 있는 보물과 다도해를 운행 중 시종일관 볼 수 있다. 운이 좋으면 보길도 격자산 쪽으로 제주 한라산의 원경도 볼 수 있다.북으로 두륜산이 접해 있고 삼면은 모두 바다와 닿아있는 산, 송호리에는 소나무와 참나무가 무성하여 모두 백여 척이나 되는 것들이 치마를 두른 듯 서 있다. 그 위에 마주한 기암괴석들은 우뚝 솟은 깃발과 같다. 혹 사자가 찡그리고 하품하는 것 같고 또는 용과 범이 발톱과 이빨을 벌리고 있는 것 같기도 하며 멀리서 바라보면 하얗게 쌓인 눈이 공중에 한 발짝 다가서 서 있는 듯하다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 송지면, 북평면", + "MNTN_NM" : "달마산" }, - "longitude" : 127.8616372, - "latitude" : 36.469489500000002 + "longitude" : 126.5852778, + "latitude" : 34.3825 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구봉대산(870m)은 강원도 영월군 수주면 북쪽에 아홉 봉우리를 자랑하며 솟은 산이다. 우리나라 5대 적멸보궁 중 하나인 사자산 법흥사 적멸보궁을 감싸 안은 우백호의 자리에 해당하기도 한다. 백덕산(1349m)에서 사자산 지나 삿갓봉(1028m)으로 이어지는 서쪽의 산줄기 중간에서 남쪽으로 뻗어 내린 구봉대산은 북쪽의 1봉에서 남쪽 9봉에 이르는 각 봉우리마다 사람이 태어나서 죽을 때까지의 과정을 뜻하는 단어들이 각각 이름으로 붙어있다.4봉부터는 등반을 해야 할 정도로 암릉구간이 곳곳에 나타나지만 모두 우회하는 길이 아래로 나 있어 힘들지 않게 산행할 수 있다. 법흥사에서 출발해 계곡을 따라 1봉에 올라 능선 따라 9봉까지 간 다음 다시 법흥사로 내려오면 된다. 총 산행시간은 4시간 정도 걸린다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면", - "MNTN_NM" : "구봉대산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "475", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "소주봉" }, - "longitude" : 128.25140740000001, - "latitude" : 37.362444199999999 + "longitude" : 127.66861110000001, + "latitude" : 37.762500000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 용인의 구봉산은 속리산에서 뻗어 나온 한남금북정맥 선상에 위치하고 있다. 산명에서도 알 수 있듯이 많은 봉우리로 이루어진 구봉산에는 재미있는 전설이 전해오고 있다.예전 구봉산 자락인 용인군 원삼면 일대가 도읍지가 될 자리였는데 당시 1백개의 봉우리로 이루어진 구봉산이 어느날 큰 홍수로 끝봉우리가 떨어져 나갔고 이로 인해 이곳이 도읍지가 되지 못했다고 한다.구봉산 산행은 산의 동북쪽 끝인 외사면 근창리 창동에서 시작된다. 등산로는 인적이 적은 만큼 호젓한 산행의 재미를 느낄 수 있다. 이러한 소로길을 따라가다 보면 만나는 뾰족한 봉우리는 414봉이다. 정상은 여기에서 건너편 산줄기를 1시간 30분 정도를 더 걸어야 만날 수 있다. 정상에서는 고삼저수지와 주변의 너른 평야가 한눈에 들어온다.", - "MNTN_HG_VL" : "469", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 원삼면, 외사면", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "충남 예산에 자리잡은 덕숭산은 기기묘묘한 형상의 괴석들이 많아 절묘한 산세를 뽐내며 1973년 3월 6일 도립공원으로 지정되었다. 호서의 금강산이라 불릴 만큼 아름다운 경관을 갖추고 있는데다 아담한 산세 곳곳에 유명한 암자들이 배치되어 있어 찾는 이들의 발길이 끊이지 않는 곳이다.그 중 비구니의 도량으로 알려진 수덕사는 고려 충렬왕 34년(1308)에 창건된 사찰로 국보 제 49호로 지정된 대웅전이 있는데 이 건물은 무량수전과 더불어 현존하는 목조건물 중 가장 오래된 것이다. 부처님의 진본사리가 안치된 황화루를 비롯, 김일엽 스님의 거쳐였던 환희대, 만공스님을 기리기 위한 미륵불상등 수행의 역사를 조망할 수 있는 흔적들이 눈길을 끈다. 수덕사와 창건연대가 같은 정혜사는 구한말에 만공 스님이 한국 선불교를 중흥시킨 곳으로 청방, 정강, 용성 등의 대스님이 거쳐갔던 명소다. 덕숭산은 이밖에도 만공탑, 여승당, 보덕사 등 많은 문화재를 간직하고 있으며 주변에 온천이 있어 배낭 하나 메고 가볍게 떠날 수 있는 가족 나들이 코스로 손색 없는 산이다.", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면", + "MNTN_NM" : "덕숭산(수덕산)" }, - "longitude" : 127.3269444, - "latitude" : 37.120555600000003 + "longitude" : 126.6187789, + "latitude" : 36.672609600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "440", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "충청남도 예산에서 서해안으로 나가면 덕산온천과 수덕사를 감싸안고 큰산들이 무리를 이루고 있는 가야산의 장관을 만난다. 가야산은 예산군과 당진군 서산군등 3개군에 걸쳐 들판에 우뚝 솟아 산세가 당당하고 곳곳에 사찰이 자리하고 있어 은은한 풍경을 자아낸다.일락산은 가야봉(677.6m), 원효봉(677m), 석문봉(653m), 옥양봉(621.4m), 수정봉(453m), 상왕산(307.2m)등의 봉우리와 더불어 가야산에 오밀조밀하게 자리잡고 있으며, 가야산은 온통 산을 뒤덮은 철쭉과 진달래가 산행의 즐거움을 더해주고 깨끗한 계곡은 많은 산악인과 관광객의 발길이 끊이지 않는 곳이다.예로부터 많은 문화유적을 간직한 명산으로 상왕산 기슭에 백제의 미소로 불리는 서산마애산존불상을 비롯하여 보원사지, 백암사지, 명종대왕태실 등 유서깊은 문화유적과 개심사, 일락사, 문수사, 송덕암 등의 명사찰이 있으며, 21.06km2의 거대산 산지를 개발하여 산악축산의 요람으로 성장한 한우목장이 있다.", + "MNTN_HG_VL" : "521", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시", + "MNTN_NM" : "일락산" }, - "longitude" : 127.7820761, - "latitude" : 37.891676400000001 + "longitude" : 126.5948908, + "latitude" : 36.730963199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 진안군 주천면과 정천면 경계에 우뚝 솟은 구봉산(九峰山)은 아홉 개의 봉우리가 시원한 조망을 보여주는 전망 좋은 산이다. 주봉인 천황봉(장군봉)과 8개의 봉우리는 설악산의 공룡능선처럼 험준하게 솟아 있는데, 각각의 봉우리에 오를 때 마다 서쪽으로는 복두봉과 운장산, 남쪽으로는 부귀산과 마이산의 두 봉우리가 선명하며, 동쪽으로는 덕유산을 위시한 백두대간 능선이 한눈에 펼쳐진다.<>구봉산은 연꽃산이라고도 불리는데, 천황봉을 제외한 8개의 봉우리가 막 피어오르는 연꽃을 닮았다고 해서 붙여진 이름이다. 훌륭한 조망과 함께 북쪽으로 운일암 반일암계곡과 남쪽의 갈거리계곡 등 크고 아름다운 계곡을 끼고 있고, 용담댐과 메타쉐콰이어 길 등 볼거리가 많아 사람들의 발길이 계속 이어지고 있다.<>구봉산 남동쪽으로는 875년 창건한 천황사가 자리하고 있는데, 천황사 앞 전나무는 국내에서 가장 규모가 크고 아름답기로 정평이 나 있다.", - "MNTN_HG_VL" : "1002", - "MNTN_LOCPLC_REGION_NM" : "전북 진안군 주천면ㆍ정천면", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "한국의 계곡을 대표하는 불영계곡과 인적이 끊긴 내천인 와피천을 가슴에 품고 있는 산이다. 낙동정맥의 주맥으로 울창한 원시림과 맑은 물은 가히 선경(仙境)을 방불케한다. 단지 교통이 불편해서 찾기 어렵다는 단점이 있지만, 마음먹고 찾아간 사람들에게는 자연이 줄 수 있는 최상의 선물을 분명 안겨주는 곳이다.이 산은 왕피천과 한국토종 소나무 자생군락지로 유명한 불영계곡을 품은 낙동정맥의 산이다 주위에 왕궁목재로 이용되던 황장목 보호구역이었던 곳도 있으며 울창한 산림을 이용개발한 통고산 자연휴양림이 있는 곳이다. 각종 나무마다 팻말이 붙어있는 등 가족단위로 나들이 하기엔 안성맞춤이고 산장들은 통나무로 지어져 있고 이름도\"\"머루랑\"\",\"\"다래랑\"\"등 자연그대로의 분위기를 살린 곳이며 삼림욕장 개장과 동시 임산 도로의 개설로 접근이 쉬워진 산이기도 하다. 또한 신라 진덕여왕 5년에 의상대사가 창건한 불영사가 자리잡고 있다.정상에 서면 50평 남짓한 헬기장으로 울진 원자력 발전소에서 세운 둥근 정상 표지판이 반긴다. 시야가 탁 트이면서 조망도 매우 좋다 . 동해 바다의 넘실대는 파도가 손에 잡힐듯 하며 불영계곡과 왕피천계곡이 펼쳐진다. 북쪽으로는 낙동정맥이 굽이 굽이 물결치는 가운데 응봉산이 올려다 보이고 남으로는 저 멀리 아련히 일월산 장군봉이 눈에 들어온다.", + "MNTN_HG_VL" : "1067", + "MNTN_LOCPLC_REGION_NM" : "경상북도 울진군 서면", + "MNTN_NM" : "통고산" }, - "longitude" : 127.4168889, - "latitude" : 35.924352599999999 + "longitude" : 129.19194440000001, + "latitude" : 36.898611099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "178", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "안평산은 금남정맥의 산줄기가 대둔산 태고사 앞산인 오대산을 타고 내려와 대전광역시 남서쪽 끝에 와서 불끈 힘을 모아 솟아올린 산이다. 안평산 은 덩치가 우람하고 수림이 매우 울창하며, 아직 때가 묻지 않은 산으로 산 언저리에는 두메산골의 풍경이 그대로 간직되어 있기도 하다.안평산의 이름은 산 속에 만인이 피난을 와서 살 곳이 있다고 해서 안평산이라 부르게 되었다고 하며, 이 산 위에 있는 장태산 휴양림은 대전광역시8경의 하나로서 관광명소로 자리잡아 가고 있다.또한 수양,압점.안평의 세 봉우리로 이루어진 안평산은 옛날부터 시인 묵객들이 자주 찾았던 곳이며,임진왜란 때는 의병활동의 본거지 역할을 했을 것으로 짐작된다.장안동 주민들이 애착심을 갖고 관리하고 있는 산으로 코스와 등산로가 잘 정비되어 있다.울창한 수림,오지를 걷는 듯한 사면길,안평산 정상의 가슴 확트이는 조망봉에서 바라보는 용태울 저수지 방향의 그림같은 풍경,신앙 굿당지들의 이색볼거리 등 대전에서는 잘 알려지는 않은 산이다. 마을 주민들이 등로를 정비 개발하고 주황색 물호스를 잘라 리본을 만들어 코스코스 마다 매달아 놓아 리본을 따라 진행하면 어려움이 전혀 없다.안평산 정상에서의 조망은 사방으로 뛰어나며, 특히 구불거리며 흐르는 유등천이 인상적이다.", + "MNTN_HG_VL" : "471", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구", + "MNTN_NM" : "장태산" }, - "longitude" : 126.4441667, - "latitude" : 37.525833300000002 + "longitude" : 127.33380579999999, + "latitude" : 36.210955599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "호남고속도로를 지나면 차창으로 아름다운 구봉산을 볼 수 있다. 아홉 봉우리의 산이라는 뜻의 구봉산은 높이가 264미터로 낮은 산이지만 바위봉우리가 늘어서 있는 경관이 매우 아름다워 신선이 내려와 노닌다는 전설이 전해지고 있다. 또 다른 이야기로는 구봉산이 아홉 마리의 봉황새 모양이어서 새 봉(鳳)자를 쓴 구봉산(九鳳山)이라 부른다는 이야기도 있고 구봉산의 아홉 개 봉우리가 마치 대신들이 한 줄로 늘어서서 허리를 굽히고 계룡산 신도 안으로 들어가는 형국의 산세라 하여 ‘군신입조형(君臣入朝形-신하들이 임금을 뵈려고 조정에 들어가는 형국)’의 명산이라고 한다. 재미있는 것은 아홉 바위 봉우리 가운데 맨 동쪽, 대전 중심부 가까이 있는 봉우리만이 계룡산을 외면하고 있어 아홉 신하 가운데 한 사람은 반역을 꾀한다는 이야기도 있다.", - "MNTN_HG_VL" : "264", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구 가수원동", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "원통산" }, - "longitude" : 127.3343871, - "latitude" : 36.2865854 + "longitude" : 127.20805559999999, + "latitude" : 35.511666699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구봉산은 남,여 등산객들의 발길이 끊이지 않아 사방에서 등산할 수 있도록 등산로가 잘 정비되어 있으며, 정상에서는 시내를 한눈에 바라볼 수 있고,특히 여수항과, 오동도, 돌산대교를 먼저 볼 수 있다. 국동, 봉산동에서 오르는 길중턱 한산사 아래의 약수는 질이 좋아 여수시민들이 많이이용하며 체육시설도 잘 가꾸어져 있다. 한산사는 여수 8경중 3경으로 한산사에서 내려다 보면여수앞바다의 전경이 매우 아름답다.구봉산은 밑에 서당이 있었다 하여 서당산 이라고도 하며, 하홉마리 봉황이살다가 이 곳에서 승천했다는 전설에 따라 산 이름이 붙여다고 하는데, 정상에거암이 솟은 잔구가 있어 산악의 미가 돋보인다.", - "MNTN_HG_VL" : "388", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "구봉산" + "DETAIL_INFO_DTCONT" : "온통 산으로 둘러싸인 거창에서 숨은 진주를 꼽으라면 보해산을 꼽을 수 있다. 칼날처럼 날카로운 바위 봉우리를 여럿 거느리고, 천길 낭떠러지 위에 우뚝 선 이 산을 누군가는 ‘거창의 용아장성’이라고 표현했을 정도로 풍광이 시원스럽다.능선에는 바늘을 꽂아둔 듯 빼곡히 자라는 소나무나 철쭉이 인상적이며, 시야가 트인 능선 너머로는 흰대미산과 수도산 등 여러 산들이 켜켜이 늘어서 멋진 산수화를 펼쳐 보인다. 산길은 동서남북 사방으로 나 있어 다양한 코스를 즐길 수 있으나 주능선 상에서는 식수를 구하기 어려운 것이 아쉬운 따름이다.일명 상대산이라고 부르는 보해산은 보해사라는 절과 여러 부속암자를 거느리고 있었는데, 현재 절은 없어지고 ‘보해’라는 이름을 가진 산과 여러 지명만 남아있을 뿐이라고 한다. 산 서쪽 기슭으로는 송이버섯이 많이 나는데, 모두 임자 있는 송이이니 산행 중에 손을 대지 않도록 주의한다.", + "MNTN_HG_VL" : "909", + "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가북면, 주상면", + "MNTN_NM" : "보해산" }, - "longitude" : 127.70833330000001, - "latitude" : 34.737777800000003 + "longitude" : 127.96511940000001, + "latitude" : 35.745744799999997 }, { "mountain" : { @@ -1091,303 +1051,313 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구왕봉은 백두대간의 주봉인 희양산(998m)의 서쪽에 위치한 산이다. 바위로 이루어진 구왕봉은 바로 이웃한 희양산의 명성에 눌려 찾는 등산객의 수가 그리 많지 않아 깨끗한 자연 그대로의 모습을 유지하고 있는 산이다.구왕봉은 깨끗한 등산로와 아기자기한 능선길이 등산하는 즐거움을 느낄 수 있는 산이지만 급경사 암릉지대도 있으므로 보조자일을 준비하는 것이 좋다. 구왕봉 자락에는 신라 헌강왕 5년 지증대사에 의해 창건된 유서깊은 사찰인 봉암사가 자리하고 있다. 또한 지름티재의 가을 정취는 아름답기 그지없다.충분한 습도와 풍부한 영양으로 단풍의 색깔이 다른 지역보다 곱고 색도 가지가지여서 산행을 하는 이들의 마음까지도 온통 울긋불긋하게 물들고 만다.", - "MNTN_HG_VL" : "877", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면", - "MNTN_NM" : "구왕봉" + "DETAIL_INFO_DTCONT" : "담양읍에서 13km 정도 떨어진 높이 731.2m의 추월산은 전라남도 기념물 4호이자 전라남도 5대 명산중의 하나로 손꼽힌다.담양군의 최북단인 용면 월계리와 전라북도 순창 북흥면과 도경계를 이룬다. 많은 수림과 기암괴석, 깎아세운 듯한 석벽이 마치 성을 쌓은 듯이 둘러있고 서쪽에 겨우 사람 하나 통행 할 정도의 길이 트여 있다.", + "MNTN_HG_VL" : "731", + "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 용면, 전라북도 순창군 복흥면", + "MNTN_NM" : "추월산" }, - "longitude" : 127.9833333, - "latitude" : 36.716666699999998 + "longitude" : 126.9756112, + "latitude" : 35.3992133 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고성군이 남해와 접해있는 지역 중에 대부분을 차지하고 있는 동해면의 산역은 수양산과 철마산, 그리고 구절봉의 이음이 전부다. 거류면의 거류산과 마주보면서 남북으로 길게 뻗은 산줄기는 겉에서 보기에는 그저 평범한 산세를 지니고 있어 산객의 관심을 끌지 못하고 있지만, 남서쪽 계곡에 자리잡고 있는 폭포암 근처에 있는 삼단폭으로 된 구절폭포는 작은 규모에 비해 절경을 지니고 있다. 북릉은 동으로 굽어져 철마산과 이어져 있고, 남릉은 당동만에 자락을 씻고 있다. 정상에 서면 건너편 거류산역과 벽방산의 산경이 한 눈에 들어오고 수양산릉 넘어있는 남해의 시원한 경관이 산객의 마음을 열어준다.", - "MNTN_HG_VL" : "521", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 동해면", - "MNTN_NM" : "구절산" + "DETAIL_INFO_DTCONT" : "장흥과 가깝고 험한 능선이 있어 전란의 소용돌이에 끊임없이 휘말려들었던 화학산은 오르다보면 실제로는 그리 험하지 않다. 나무도 거의 잡목이고 육산인데다가 주능선도 바위지대가 없이 길게 남북으로 늘어져 있다.정상은 좁은 데다가 꺽다리 억새들이 무성해서 주위경관을 감상하기는 쉽지 않다. 하지만 남쪽으로 조금 내려와 헬기장에 서면 천태산과 금성산, 용암산과 국사봉을 모두 볼 수 있다.", + "MNTN_HG_VL" : "614", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 청풍면, 도암면", + "MNTN_NM" : "화학산" }, - "longitude" : 128.42027780000001, - "latitude" : 35.024722199999999 + "longitude" : 126.9208333, + "latitude" : 34.863333300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산에 아홉 개의 큰 절들이 있다는 데서 유래했다고 전하며, '무수산(無愁山)'으로 불린다고 한다. 신풍면 백룡리, 입동리, 선학리에 걸쳐있는 산으로 예전에 아홉 개의 절이 있었으나 현재는 다 없어졌다.굴티 오른쪽, 오름실 아래쪽에 위치하고 있다.", - "MNTN_HG_VL" : "359", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 신풍면", - "MNTN_NM" : "구절산" + "DETAIL_INFO_DTCONT" : "전라남도 신안군 흑산면 홍도리에 위치하고 있는 홍도는 대흑산 본섬의 부속 도서로서 다도해 해상 국립공원으로 매가도라고도 한다. 홍도는 본 섬을 비롯한 20여 개의 부속 섬이 절정을 이루어 남해의 소금강으로 불린다. 그 중에서 녹섬의 해돋이는 가히 장관이 아닐 수 없다. 파도와 바닷물이 출렁거리는 가운데 2개의 바위 사이로 해가 떠오른 광경은 말로 표현할 수 없을 정도로 아름답다. 여기에 덧붙여 홍도의 낙조 또한 놓칠 수 없는 비경이다.어미섬의 주봉인 깃대봉(해발 367m)과 남쪽의 깃대봉 주변에는 아름드리 동백나무 숲, 후박나무, 식나무 등 휘귀식물 5백여종이 있으며 2백여 종의 동물과 곤충이 함께 서식하고 있다.깃대봉 산행은 가파르기 그지 없고 철쭉,동백등 이름모를 나무들이 온통 빽빽이 자라고, 주봉에 닿으면 뾰족한 모양이 마치 바늘같다.남서로 양상봉의 연봉이 한 폭의 동양화를 펼쳐 놓은 듯하고 동쪽으로는 설풍서전의 울창한 숲이 장관이다.", + "MNTN_HG_VL" : "382", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안 흑산면 홍도", + "MNTN_NM" : "깃대봉" }, - "longitude" : 126.97027780000001, - "latitude" : 36.487777800000003 + "longitude" : 125.201944, + "latitude" : 34.695 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "등산로 곳곳에 전설이 담겨있는 명소가 산재한 구절산은 연엽산의 남쪽에 자리하고 있다. 강원도 춘천시 동산면과 홍천군 북방면의 경계를 이루고 있으나 일반인들에게는 널리 알려지지 않아 비교적 훼손이 덜 된 산이다.강원도 춘천시의 동녘 경계에 한 마리 거대한 용이 물을 마시러 하늘에서 내려온 듯 그 머리를 맑고 푸른 소양호로 향한 듬직한 산세의 산이 해발 899미터의 대룡산이거니와 그 정상에서 정남향으로 길게 능선이 달려 응봉(759m)과 연엽산(850m)이 거대한 비늘인양 솟아 있고, 다시 그 남녘의 엉치 부분에 까마득한 아홉 폭의 절벽 병풍을 펼친 산이 구절산(750.4m)이다.활엽수의 시원한 녹색 차양 사이로 멀리 연엽산의 아름다운 모습이 둥두렷이 떠오르는 능선길을 따르노라면 문득 높다란 암벽이 앞을 가로막는다. 왼쪽으로 돌아가는 길을 찾아 다시 오르면 어느 틈에 삼각점이 기다리는 정상이다. 삼각점에서 조금 떨어진 곳에 춘천 그냥산악회가 1993년 1월에 설치한 약 1미터의 금속팻말에는 ‘구절산 760m’라고 새겨져 있다.", - "MNTN_HG_VL" : "750", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천군 북방면", - "MNTN_NM" : "구절산" + "DETAIL_INFO_DTCONT" : "부흥산이란 이름은 나매기(나뫼기,난뫼기)로부터 범산까지 크게 부흥할 것이라하여 부흥산이라했다 한다.", + "MNTN_HG_VL" : "73", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 옥암동", + "MNTN_NM" : "부흥산" }, - "longitude" : 127.831547, - "latitude" : 37.772691899999998 + "longitude" : 126.4427778, + "latitude" : 34.806111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구학산은 충북 제천시 백운면,봉양면과 강원도 원주시 신림면의 경계를 이루는 산이다. 남쪽 끝머리에 자리한 남대봉(1,187m)에서 서남쪽 백운산(1,087m)으로 뻗어 내리던 능선이 백운산 정상을 약 2km 남겨둔 981m봉에서 동남쪽으로 뻗어 내린 능선이 구력재를 지나 첫 번째로 높이 솟아 있는 산이다.구학산을 일으킨 능선은 남쪽으로 흘러내리며 주론산을 빚어 놓은 뒤, 남쪽으로 이어지다 박달재에서 맥을 낮추어 박달재를 이루고, 다시 고도를 높이며 시랑산(691), 면위산(780), 마미산(601)을 빚어 놓고 그 여맥을 충주호에 가라앉힌다. 산 이름에는 유래가 있듯이, 구학산에는 옛날 이 산에서 살던 아홉 마리의 학이 사방으로 날아가 아홉 군데의 '학'자가 들어가는 지명이 생겨났다는 전설이 전해 내려오고 있다.구학산에서 살던 아홉 마리의 학이, 신림 방면의 황학동, 상학동, 선학동과, 봉양 방면의 학산리와 구학리, 백운면 방면의 방학리와 운학리, 송학면의 송학산과 충북 영동의 황학산으로 한 마리씩 날아가 마을 이름이 생겨났다고 한다.구학산은 부드러운 능선으로 이어져 적설기 등산지로 좋고, 때묻지 않은 오지 농촌의 순박한 풍경을 볼 수 있어 더욱 좋다. 구학산은 산 전체가 육산으로 울창한 수림으로 덮여 있으나 정상은 바위로 돌출 되어 있어 전망이 좋은 편이다. 북으로는 백운산이 가깝게 보이고, 동으로는 감악산, 석기암산, 용두산과 제천시가 아스라히 보인다. 남으로는 주론산과 시랑산 사이로 박달재 고갯길이 보이고, 서쪽으로는 촉새봉(십자봉)과 삼봉산이 한눈에 들어온다.", - "MNTN_HG_VL" : "983", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", - "MNTN_NM" : "구학산" + "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면에 소재한 삽디리봉은 소양호 건너편에 있다는 불편 때문에 찾는 이들의 발길이 그리 흔치 않은 산이다. 자연히 천혜의 경관을 그대로 간직하고 있으며 물빛과 어우러진 자연경관 역시 일품이다.산속은 대체로 평이한 형세를 하고 있어 산행 코스로 짚어 줄 만한 특징적인 장소는 없으나 삽다리골 초입에서부터 정상까지 살아있는 자연의 숨결을 한껏 만끽할 수 있다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "삽다리봉" }, - "longitude" : 128.04027780000001, - "latitude" : 37.188888899999988 + "longitude" : 127.93611110000001, + "latitude" : 37.926666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산 모양이 '닭의 볏(계관)'처럼 생겼다 하여 비슬산이라고도 한다.산행은 사람의 흔적을 거의 찾아볼 수 없어, 독립된 산으로서의 산행보다는 인근의 석대산-구현산-화왕산을 연계하는 코스를 이용하는 것이 좋다. 산길은 후반부에 해당하는 구현고개에 닿을 때까지 등산객의 흔적을 거의 발견할 수 없었을 정도로 깨끗하고 묵은 산길이 큰 매력이었다. 석대산 정상까지 이어지는 암릉구간은 산행의 재미를 더해준다. 화왕산(756m)은 그리 높은 산은 아니지만 화려한 암릉으로 유명한 산이다.석대산 바위 구간은 규모 면에서는 이에 미치지 못하지만 아기자기함과 시원하게 트인 조망은 일품이다. 화왕산에서 구현산올 흐르는 남북 능선에과 비탈은 전체가 온통 바위로 까려 있고 능선에는 진달래가 많다.", - "MNTN_HG_VL" : "581", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕", - "MNTN_NM" : "구현산" + "DETAIL_INFO_DTCONT" : "광주시가지에서 동쪽으로 불과 10km 거리에 자리하고 있는 무등산은 도립공원으로 지정되어 있다.산의 형세가 험하지 않고 대부분이 흙으로 이루어져 있어 누구나 쉽게 오를 수 있으며, 곳곳에 맑은 물이 흐르고 있다. 특히 산위에는 서석대, 규봉, 입석대등의 웅장한 바위들이 있으며 산기슭과 중턱에는 약사암, 증심사, 원효사 등의 이름난 절들이 자리잡고 있다. 1972년 도립공원으로 지정되었으며 산 아래에는 각종 놀이 및 편의시설이 들어서 있다.", + "MNTN_HG_VL" : "1187", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구, 전라남도 담양군 남면ㆍ화순군 이서면", + "MNTN_NM" : "무등산" }, - "longitude" : 128.53222220000001, - "latitude" : 35.513055600000001 + "longitude" : 126.9887555, + "latitude" : 35.134134000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충주시 앙성면에 위치한 국망산의 옛이름은 금방산이었다.국망산으로 불리워지게 된 세월은 그리 길지않다. 임오군란 당시 명성황후가 이곳으로 피난을 오게 됐다. 피난을 와서 한양소식이 궁금한 황후는 매일 이 산마루에 올라가 한양을 바라보며 초조해 했었다는데서 국망산이라 불려지게 된 것이다.당시 황후는 충주목사인 민옹식의 집으로 피난을 가기로 하였으나 피난지가 알려지면 신변이 위험할 것 같아 이곳으로 피한 것이다. 황후가 피신한 집은 가난한 초가집이었는데 그 집에는 이도령이라는 총각이 홀어머니를 모시고 나무장사를 하면서 살고 있었다. 이도령은 가난하였으나 황후를 극진히 대접하였다.황후가 피난생활을 마치고 환도한 후 이 도령을 불러 사례하고자 하였으나 사양하여 황후는 이 도령에게 음성군수를 시켰다. 이도령은 군수 재직중 선정을 베풀어 주민들로부터 칭송을 받았으며 그 후 5개 마을의 군수를 지냈다. 마을에서는 이 도령의 집을 이음성집이라 부르고 그의 집터를 대궐터라고 부르고 있다.", - "MNTN_HG_VL" : "770", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면 본평리", - "MNTN_NM" : "국망산" + "DETAIL_INFO_DTCONT" : "장백산령이 나려오면서 남으로 많은 산군을 융기시켰다. 청도군과 경산시의 경계를 이루는 선의산, 용각산이 융기되고 이현 복고개에서 힘을 다하는 것 같았으나 다시 마지막 힘을 뻗어 대왕산을 이루었다.학일산은 일제가 우리나라를 강제로 점령하자 학일산의 영험을 빌어 나라를 지키고자 마을 이름을 내촌에서 학일이라 고쳐 불렀다. 이와 마찬가지로 항일 죽창 의거사건과 관련이 깊은 대왕산 또한 민족혼이 어린 명산이라 하겠다. 근래 마을에는 수질, 수온, 수량 등 조건이 양호한 온천수가 발견되었다.", + "MNTN_HG_VL" : "605", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "대왕산" }, - "longitude" : 127.73527780000001, - "latitude" : 37.0777778 + "longitude" : 128.83631489999999, + "latitude" : 35.746121799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "399", - "MNTN_LOCPLC_REGION_NM" : "충청남도공주", - "MNTN_NM" : "국사봉" + "DETAIL_INFO_DTCONT" : "강원도 홍천군 북방면과 남면의 경계에 솟은 금확산은 655미터의 아담한 산이다. 하지만 정상에서 바라보는 전경은 1000미터가 넘는 산들과 비교해 결코 뒤지지 않는다. 그 배경이 되는 홍천강은 금확산을 더욱 아름답게 해주는 역할 중 으뜸이다.들머리는 북방면 노일리에 있는 노일분교다. 이곳에서 서쪽으로 300미터쯤 있는 버스종점의 콘크리트 포장길을 따라 북쪽으로 6분쯤 가면 간판 없는 작은 목장이 나온다. 등산로는 축사 뒤 계곡으로 뚜렷하게 나 있다.초입에서 40분쯤 걸리는 전망대바위에서 내려다보는 산태극 수태극을 그리며 흐르는 홍천강의 경치가 산행의 하이라이트다. 다시 산길을 30여분 오르면 정상이다. 용문산의 북녘 줄기인 봉미산에서 나산을 거쳐 장락산으로 이어지는 산세는 마치 봉황의 꼬리를 보는 듯하다.하산은 올라온 길을 다시 내려가 큰 소나무가 있는 삼거리에서 오른쪽 능선길로 빠지는 길, 홍천강이 지척으로 보이는 동남쪽 능선의 두 코스로 할 수 있다.", + "MNTN_HG_VL" : "655", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면, 남면", + "MNTN_NM" : "금확산" }, - "longitude" : 127.22861109999999, - "latitude" : 36.410277800000003 + "longitude" : 127.7519444, + "latitude" : 37.694166699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "미타산에서 남으로 뻗어 내린 산릉의 끝머리에 암봉이 불쑥 고개를 내밀고, 산릉을 좌우로 마치 날아가는 독수리가 나래를 편 형세로 자리잡고 있는 산이 의령군민들에게 사랑을 받고 있는 국사봉이다.합천군 대양면, 의령군 봉수면에 걸쳐 산역을 펼치고 있는 이 산은 인근 주민들 이외는 별로 알려진 산은 아니지만 아기자기한 암릉과 깨끗한 산의 모습이 산객들에게 호감을 주고 있다.국사라는 이름을 가진 산에는 옛날 나라일에 관해 행사를 치렀다는 기록이 남아 있다.", - "MNTN_HG_VL" : "613", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 봉수면", - "MNTN_NM" : "국사봉" + "DETAIL_INFO_DTCONT" : "전남 장흥군 용산면 운주리를 부채모양으로 싸감고 있는 부용산은 동학운동의 최후 격적지로 봄이 되면 진달래 철쭉 등이 화사한 꽃빛으로 불태우는데 아직 등산로가 제대로 나 있지 않아 찾는 이가 드문 산이다. 또한 부채모양을 이루고 있기 때문에 다양한 원점회귀 산행이 가능하다.전란의 시달림에서 안전한 보호막이 돼 주었던 부용산의 덕성은 임진왜란까지 거슬러 오른다. 당시 이맹(李孟)이란 장수가 골목 어귀에 서 있다가 들어오는 왜적을 모조리 쏘아 죽여서 피란민들의 안전을 지켜주었던 곳이 있는데 이곳이 바로 지금의 장구목재다. 부용산은 부처가 솟은 산이라는 `불용산(佛聳山)', 산삼 등 약초가 많다고 해서 `약다산(藥多山), 돌이 많아 '석다산(石多山)등으로 불린다.곳곳에 튀어나온 바위에서 바라보는 도암만과 다도해 전경이 시원하며 바다에서 솟아오른 듯한 천관산을 바로 눈앞에서 감상할 수 있다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍 성산리", + "MNTN_NM" : "부용산" }, - "longitude" : 128.2488889, - "latitude" : 35.492777800000013 + "longitude" : 126.8758333, + "latitude" : 34.593333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "239", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", - "MNTN_NM" : "국사봉" + "DETAIL_INFO_DTCONT" : "주산은 대가야의 고분이 남아있고 순장묘 등 고분군이 발견된 산으로 역사적 가치가 높다. 남동쪽 구릉의 동남쪽 사면에 위치한 대가야시대의 무덤들은 현재와 고대를 연결하는 시간의 문을 연상케 한다. 또한 고령군민과 외지인들이 많이#52287;는 고령의 명산이다.고령의 진산인 주산정상(3백11M)에 오르면 북서쪽으로 가야산과 미숭산이 멀찌감치서 절묘한 자태를 드러낸다. 동쪽 산아래로는 고령읍이 한눈에 들어 오고 산능선을 넘나드는 한줄기 바람과 봄철에만 피어나는 철쭉꽃이 만발해 보는이로 하여금 가슴을 져미게 만든다.주산정상에서 고분군으로 내려오는 길 옆에는 명상의 숲을 꾸며 놓았다. 나무벤치 앞마다 주옥같은 명시를 기록해 나그네를 잠시 쉬어가게도 한다. 대가야 시대에 축조된 지산동고분군은 주산의 남동쪽 능선을 따라 내려 가면서 낙타등 처럼 이어지는데 언뜻 보면 거대한 봉분들만 눈에 띄지만 능선 아래로 크고 작은 무덤들이 마치 잊혀진 역사처럼 풀숲에 수도 없이 묻혀 있다고 해고 과언이 아닐듯 하다.높이 6m 지름 25~27m 규모인 제51호 고분을 비롯, 32호 고분까지 규모가 큰 고분이 이어지는데 특히 지난 78년 발굴. 조사결과 우리나라에서 첫 확인된 순장묘로 밝혀진 제44호 고분이 눈길을 끈다. 고분 주위를 걷다가 잠시 무덤가에 앉아 낙동강을 타고 오르는 바람결에 땀을 식히노라면 여기서도 고령읍내가 훤하게 보인다. 능선을 따라 줄곳 내려가면 44호분의 실물 크기로 순장묘 전시관이 나타난다.16대 도설지왕 때인 서기 562년에 신라에 멸망한 후기 가야연맹의 맹주국이던 대가야, 대가야의 5백년 역사는 삼국사기나 삼국유사에서도 어렴풋이 기록되어 있을뿐 정복당한 왕조의 애달픈 사연을 고분안에 묻은 채 빛바랜 대가야의 찬란했던 문화는 아직도 우리 역사에서 전설로 남아 있다.", + "MNTN_HG_VL" : "310", + "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군", + "MNTN_NM" : "주산" }, - "longitude" : 126.41622390000001, - "latitude" : 37.383214000000002 + "longitude" : 128.25277779999999, + "latitude" : 35.731944400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "국통산은 우보면 나호리에 위치한 산으로서 해발 336.8m로 그리 높지 않은 산이나 정상부위의 등산로에서 맑은날 내려다보면 동북쪽으로 금성산, 동쪽으로 선암산, 뱀산, 동남쪽으로 옥녀봉, 남쪽으로 팔공산과 매봉산이 보이며 북서쪽으로는 마정산, 선방산 등이 관측된다.", - "MNTN_HG_VL" : "337", - "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 우보면 나호리", - "MNTN_NM" : "국통산" + "DETAIL_INFO_DTCONT" : "적상산은 사방이 깎아지른 듯한 암벽으로 이루어져 있으며, 그 절벽 주변에 유난히도 빨간 단풍나무가 많이 서식하여 가을철이면 마치 온 산이 빨간 치마를 입은 여인네의 모습과 같다 하여 붙어진 이름이다. 이 산에는 장도바위, 장군바위 등 자연 명소와 함께 최영 장군이 건의하여 축조했다는 적상산성(사적 제 146호)이 있다.이는 고려 공민왕 23년(1374) 최영 장군이 탐라를 토벌한 후 귀경길에 이 곳을 지나다가 산의 형세가 요새로서 적지임을 알고 왕에게 축성을 건의하여 건설된 것이라 한다. 현재의 성은 조선 인조6년(1628년)에 다시 쌓은 것으로서 둘레가 8.143㎞에 이른다. 적상산성 안에는 고찰 안국사 등 유서깊은 문화유적이 있어 이 곳을 찾아온 사람들에게 운치를 더해 준다.한편 고려 충렬왕 3년(1227년) 월인화상이 창건했다고 전해지는 안국사 및 조선시대 인조 21년(1643년)에 창건한 호국사도 있다.", + "MNTN_HG_VL" : "1031", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군 적상면", + "MNTN_NM" : "적상산" }, - "longitude" : 128.6382653, - "latitude" : 36.198841799999997 + "longitude" : 127.6897512, + "latitude" : 35.947660200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산행은 쌍곡리에서 시작한다. 쌍곡계곡에서 시원스런 나무숲 사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2미터 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다. 원효굴에서 조금 더 가면 첫 봉우리에 이른다. 다시 고개 하나를 지나면정상이다. 하산은 서남쪽 고개를 돌아 계곡을 타고 내려온다. 큰군자산 종주 코스는 비지정등산로이며 현재 국립공원 지정등산로는 소금강 - 큰군자산 - 도마골 정도니 그 외 등산로는 허가를 받아야 한다.", - "MNTN_HG_VL" : "948", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면", - "MNTN_NM" : "군자산" + "DETAIL_INFO_DTCONT" : "남해 금산은 남해섬을 대표하는 산으로, 한려해상국립공원이 말 그대로 거의 다 바다로 지정되어 있는데 유일하게 산이 해상 공원에 포함된 것이 금산이다.금산은 비단을 두를 뻔한 산으로 유명하다. 금산의 본래 이름은 보광산(普光山)이다. 이성계가 왕이 되고자 보리암 아래 있는 '이태조기단'에서 백일기도를 드리면서 자신이 왕이 되면 이 산을 비단으로 덮겠다는 약속을 했다. 이성계가 조선을 개국한 뒤, 약속을 지킬 일을 생각하니 난감했다.이때 사려 깊은 신하가 산 이름을 하사하면 비단보다 오래 갈 것이라고 제안해 이름을 비단 '금(錦)'자를 써 이전의 산 이름을 금산으로 바꿈으로 이성계는 자신의 약속을 절묘하게 지킬 수 있었다고 전해지고 있다.매표소에서 보리암으로 이어지는 등산로 왼편으로 사선대가 올려다 보인다. 사선대는 먼 옛날 동서남북의 네 신선이 조그만 암봉에서 놀았다는 곳이다. 사선대 맞은편에는 절벽을 이룬 웅장한 바위는 만장대이다.", + "MNTN_HG_VL" : "705", + "MNTN_LOCPLC_REGION_NM" : "경상남도 남해군 상주면ㆍ이동면ㆍ삼동면", + "MNTN_NM" : "금산" }, - "longitude" : 127.87860019999999, - "latitude" : 36.737540799999998 + "longitude" : 127.9774498, + "latitude" : 34.7561125 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "동쪽과 북쪽은 지세가 험하여 일반등산화 이상을 싣고 등반하여야 하는 곳이다.자연 경관은 산불피해를 입어서 앙상한 나뭇가지들이 있어 경관을 헤치고 있다.강원도 삼척시 미로면에 위치한 근산은 삼척에서 자랑하는 미로 8경중의 하나이다. 강을 건너는 나무다리가 오십개나 있었다 해서 이름 지어진 오십천에 물을 보태는 근산은 삼척에서 바라보면 마치 우산을 펼쳐 세워 놓은 것처럼 보인다.원시림을 그대로 간직하고 있고 동해바다를 끼고 오르는 산과 바다를 즐길 수 있는 산행을 즐길 수 있다", - "MNTN_HG_VL" : "514", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면", - "MNTN_NM" : "근산" + "DETAIL_INFO_DTCONT" : "무술목 남쪽 크고 아름다운 산이란 뜻을 가진 대미산(大美山)이 있는데 이에 비해 작다고 하여 소미산(小美山)이란 명칭을 붙였다고 한다. 돌산도(突山島)에는 대미산,소미산,수죽산,천마산,봉황산,두산(斗山),천왕산,금오산의 8대 명산이 있는데 소미산이 그 중 하나이다.대미산 북쪽 해발 210m에 위치하고 있으며, 무술목에서 오르는 코스와 소굴전마을에서 오르는 코스가 있다. 산의 높이가 낮고 또 인근에 높은 산이 없어서 관망하기에 좋은 산이다. 인근에 무술목유원지와 해수욕장, 해양수산과학관이 있어 가족 관광지로서도 아주 좋은 곳이다.", + "MNTN_HG_VL" : "210", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 돌산", + "MNTN_NM" : "소미산" }, - "longitude" : 129.1358333, - "latitude" : 37.407777799999998 + "longitude" : 127.7763889, + "latitude" : 34.688611100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강과 바다 들녘이 어우러진 서남쪽 끝머리에 자리 잡은 해남에는 먼 이북의 아름다운 금강산과 토시 하나 틀리지 않는 똑같은 이름을 가지고 있는 금강산이 자리하고 있다. 기암괴석으로 된 암장과 아열대 수림으로 덮여 있고, 봄이면 춘란이 무리지어 갈잎 속에 꽃대를 올려 개화를 시작한다.lsquo;옥녀탄금rsquo;의 형상이라는 해남읍의 지형에서 가야금을 타는 선녀에 해당하는 금강산은 병풍처럼 해남읍을 두르고 있고 정상에는 금강산성이 성곽을 이루고 있으며 아래로는 은적사, 금강폭포, 미암 등이 자리하고 있다. 해남에 이름 있는 많은 산들의 유명세에 가려서 사람들이 많이 찾는 곳은 아니지만 비교적 산을 오르기 쉬우며 사람의 발길이 닿지 않는 야생의 모습을 그대로 간직하고 있는 산이다. 크고 작은 돌무더기와 암벽들을 산길 곳곳에서 접하게 되고, 인적이 드물어 사람의 흔적이 묻어나지 않은 억새풀 숲과 수목들로 가득 차 있어 조바심을 내지 않고 트레킹 하는 기분으로 천천히 오르기에 알맞은 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "481", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 마산면", - "MNTN_NM" : "금강산" + "DETAIL_INFO_DTCONT" : "신라말 원표대사(元表大師)가 인도에 계실 때 신비한 기운이 삼한의 밖 아득히 먼 곳으로부터 비쳐와 그 기운만을 바라보고 산을 넘고 바다를 건너 오묘한 곳을 찾아내 자리를 잡으니 산세가 인도의 가지산, 중국의 가지산과 같아서 가지산이라 명하고 지어진 절이 보림사로 창건에 얽힌 이야기가 전해져 오듯 국보와 보물이 많이 있으며 가지산은 규모는 작지만 산세가 좋아 정상에서 둘러보면 금방 명산이라는 것을 느낄 수 있다.특히 가을철에는 산 전체가 단풍으로 붉게 물들어 그 아름다움은 극치에 달하고 정상부의 바위들은 돌을 깍아세운 듯 하다. 한편 보림사 봉덕 계곡은 사시사철 깨끗한 물이 흐르고 있어 많은 탐방객들이 찾고 있으며 여름철에는 최고의 가족 휴양지로 꼽힌다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 장평면 우산리", + "MNTN_NM" : "가지산" }, - "longitude" : 126.5997222, - "latitude" : 34.591666699999998 + "longitude" : 126.9025627, + "latitude" : 34.820325599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "489", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군", - "MNTN_NM" : "금계산" + "DETAIL_INFO_DTCONT" : "기양산과 수선산이 자리한 상주시는 예로부터 삼백(쌀, 누에고치, 곶감)의 고장으로 낙양으로도 불리었다.수선산은 상주시 청리면 청상리와 낙동면 수정에 솟아있는 육산으로 연산군 시절 연산군의 만행을 싫어하여 피신 은둔 수도한 서비가 많았다고 하여 이름지어진 산이다. 접근하는 방법에는 청리면 청상리 수선지 뒤 계곡길을 이용하거나 기양산에서 수선산을 거쳐 돌티로 하산하는 두 방법이 있으나 청상코스는 수선지 뒤 계곡이 끝나는 지점까지는 길이 잘 나 있으나 그 이후 길이 확실치 않고 잡목이 길을 막기 때문에 가급적 삼가고 기양산 코스를 이용하여 수선산으로 가는 방법을 택해야 한다.", + "MNTN_HG_VL" : "684", + "MNTN_LOCPLC_REGION_NM" : "상주시 청리면 청상리 \/ 낙동면 수정리", + "MNTN_NM" : "수선산" }, - "longitude" : 128.44862860000001, - "latitude" : 35.7696118 + "longitude" : 128.1716667, + "latitude" : 36.299722199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 거창군의 분지 가운데에 우뚝 솟아있는 금귀봉은 산의 모양이 탕건의 모양을 하여 `탕근산'이라고도 불린다.또 금귀봉 정상에는 아직까지 봉수대의 흔적이 남아있어 주변 마을 사람들은 봉수산이라고도 부른다.금귀봉에는 많은 문화유적이 있는데 현재도 샘터와 금귀사 절터 등이 남아있다. 또한 금귀봉의 동남쪽 기슭 석장골에는 지난 71년 발굴된 고려 초기의 문마 벽화고분과 양평리 석조여래입상 등의 문화 유적이 있다.", - "MNTN_HG_VL" : "827", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", - "MNTN_NM" : "금귀봉" + "DETAIL_INFO_DTCONT" : "정상에 일자봉과 월자봉이 솟아 있어 동해에서 솟아 오르는 해와 달을 제일 먼저 볼 수 있다해서 일월산이라고 한다. 또한 산마루에 천지가 있어 그 모양이 해와 달과 같아서 일월산이라 하였다는 설도 있다. 높은 산이면서도 산형이 험하지 않고 순하여 순산이라는 애칭도 있다. 옛부터 각종 임산물이 많고 고산식물이 곳곳에 자라며, 약초도 많다.이 산은 태백산맥에 속하며, 이 산에서 낙동강의 상류 지류인 반변천(半邊川)이 발원한다. 남서사면에 천화사(天華寺)가 있으며 동쪽 사면에 용화사지(龍化寺址)가 있다.일월산의 꼭대기에는 일자봉과 월자봉이라 부르는 두 봉우리가 사이좋게 솟아 있으며 그 줄기가 뻗어 크고 작은 산맥이 주종을 이루었으니 동해가 눈 아래 보이는 일자봉에 올라 해가 솟아오르는 장관을 볼 수 있다.", + "MNTN_HG_VL" : "1218", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 일월면", + "MNTN_NM" : "일월산" }, - "longitude" : 127.9513889, - "latitude" : 35.729999999999997 + "longitude" : 129.09831510000001, + "latitude" : 36.8016115 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금당산은 광주 풍암지구를 병풍처럼 둘러싸고 있는 산으로 북쪽으로는 옥녀봉, 서쪽으로는 황새봉을 거느리고 있다.옥녀봉에서 황새봉에 이르는 능선을 따라 걷다보면 무등산 정상인 천황봉을 비롯해 동화사터와 장불재, 광주 월드컵 경기장이 한눈에 바라보이고, 광주 시가지와 멀리 어등산이 어렴풋이 눈에 들어온다. 서쪽으로는 함평 들녘으로 떨어지는 아름다운 일몰을 감상할 수도 있다.광주시 서구청에서 8.2킬로미터에 이르는 산책로를 정비해 노약자나 어린이들도 쉽게 접근이 가능하다. 등산로 곳곳에는 쉼터와 체육시설 등을 설치하고 나무 이름표를 달아놓아 어린이들의 자연학습장으로도 좋다. 주변의 아파트 단지를 따라 많은 등산로가 개설되어 있어 작은 산이지만 다양한 코스를 즐길 수 있는 것이 장점이다.", - "MNTN_HG_VL" : "304", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 서구 풍암동", - "MNTN_NM" : "금당산" + "DETAIL_INFO_DTCONT" : "백암산 하면 내장산국립공원에 속한 전남 장성 백암산(741.2m)과 경북 울진군 온정면에 자리한 백암산이 대표적이다. 장성 백암산은 백양사와 더불어 가을 단풍지로 각광받고 있지만 대체로 많은 이들이 울진 백암산을 먼저 떠올린다.산 정상부에 흰바위가 있어 백암산이라 이름 붙여진 1004미터 고봉은 국민관광지로 지정된 백암온천의 유명세 덕분에 많이 알려져 있다. 또한 신라시대 한 사냥꾼이 사슴을 쫓다가 발견했다는 백암산은 고려 공민왕이 난리를 피해 숨었던 산이라 전한다. 그러나 무엇보다도 백암산은 북쪽 검마산에서 이어져 남쪽 아랫삼승령으로 이어지는 낙동정맥의 한 산줄기로 험하지 않지만 위용있는 산세를 자랑한다.백암산의 대표적인 등산로는 크게 세 코스다. 숙박시설단지를 지나 능선을 타고 백암산을 오르거나 백암폭포를 지나 가파른 길을 따라 정상에 닿을 수 있다. 나머지 하나는 용소를 비롯한 12개의 소가 이어져 있다는 선시골계곡을 따라 오르는 길이다.백암산 꼭대기에 서면 동해바다가 한눈에 들어온다.바다에 차츰 붉은 기운이 감돌다가 불쑥 떠오르는 해돋이는 말 그대로 장관이다. 더욱이 맑은 날이면 멀리 울릉도까지도 눈에 들어온다.백암산 중턱에는 예부터 뛰어난 효험을 자랑하는 백암온천이 자리잡고 있다.", + "MNTN_HG_VL" : "1004", + "MNTN_LOCPLC_REGION_NM" : "경북 울진군 온정면, 영양군 수비면", + "MNTN_NM" : "백암산" }, - "longitude" : 126.88861110000001, - "latitude" : 35.117777799999999 + "longitude" : 129.29821530000001, + "latitude" : 36.717375500000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금당산은 강원도 평창군 봉평면과 대화면 경계를 이루는 산으로 평창강 상류의 금당계곡을 끼고 있어 물놀이를 겸할 수 있는 가족단위 산행지로 적합한 곳이다.산 자락 밑에 흐르는 금당계곡에는 높이 60m의 직벽으로 된 봉황대라는 곳이 있는데 이곳은 옛날부터 봉황새 이외의 다른 새는 근접을 하지 못했다고 한다.강원도 산골로 이름 높은 평창군 일대는 오대산(1,563m), 계방산 (1,577m) 등 1,000m를 넘는 고산이 운집해 있다. 신리 쪽에서 바라보면 왼쪽의 거문산(1,175m)이 훨씬 높아 보이고 밋밋한 평행선의 능선 끝 오른쪽에 약간 튀어 오른 금당산의 정상이 보인다.정상에서는 동쪽의 잠두, 백석산의 능선이 선명하게 조망되며 이곳에서 바라보는 잠두산은 누에가 기어가는 모습 그대로의 형상이다. 금당산 정상은 펑퍼짐한 봉우리로서 태기산, 회령봉, 계방산 등의 조망이 더욱 좋은 위치이다.금당산은 봄에는 진달래, 여름에는 원시림을 방불케 하는 울창한 나무숲, 가을에는 오색의 단풍 물결, 겨울에는 눈꽃으로 아름다움을 나타내고 있는 산이다.계곡의 물은 아주 깨끗하며 계곡물이 매우 차기 때문에 한여름에도 산행로가 선선함을 느낄 수 있다.", - "MNTN_HG_VL" : "1173", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 용평면", - "MNTN_NM" : "금당산" + "DETAIL_INFO_DTCONT" : "충남 서산시와 예산군의 경계를 이루는 가야산은 예산, 당진, 서산, 태안 지역에서 무소불위의 힘을 떨치는 산이다. 산은 그 자체로 서해를 향해 호령할 듯 섰다. 산세 또한 그 근방에서 찾아 볼 수 없는 암산으로 기암들이 징검다리 마냥 하늘을 받치고 있다. 백두대간 칠현산에서 분기한 금북정맥의 산답게 당찬 힘을 발휘한다. 가야산에서 석문봉까지 암릉을 형성한 후 두 줄기로 나뉘어 일락산과 옥양봉, 수정봉을 향해 갈래 친다.가야산 자락에는 사방 곳곳에 백제에서 조선시대에 걸쳐 이어진 문화재가 산자락마다 있다. 가야산 서쪽으로는 커다란 은행나무를 품고 있는 고풍스런 해미읍성이 자릴 꿰차고 있으며 북쪽에는 보물 143호로 지정된 대웅전이 있는 개심사가 있다. 북동쪽 자락에는 조선시대의 명지관인 정만인이 점지한 남원군묘와 육관대사로 알려진 풍수지리도사인 손석우의 묘가 있다. 그뿐만 아니다. 남쪽에는 충남 서북부를 대표하는 1500여년 된 역사를 자랑하는 백제시대의 수덕사가 명성을 떨치고 있다.", + "MNTN_HG_VL" : "678", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 운산면·예산군 덕산면", + "MNTN_NM" : "가야산" }, - "longitude" : 128.41599729999999, - "latitude" : 37.540842300000001 + "longitude" : 126.6117509, + "latitude" : 36.707605200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 태백시 창죽동에 위치한 금대봉은 지형도상에는 이름 없이 높이만 표기되어 있는 무명산으로 그리 많이 알려지지 않은 산이다.백두대간의 주맥에 솟아 동쪽의 매봉 줄기를 받아 남쪽의 함백산, 태백산으로 맥을 이어주는 역할을 한다. 이 봉우리 북사면 골짜기에는 한강의 발원지 역할을 하는 고목나무샘, 검용소 등이 있고 낙동강 천리 물길이 시작되는 용수골이 자리하고 있다.뿐만 아니라 매봉산 동쪽 가지인 1145m봉에서 낙동강 동쪽 산세를 형성하는 낙동정맥이 뻗어 있으니 금대봉이 갖는 의미는 각별하다.함백산에서 금대봉구간은 1993년 환경부가 생태계 보전지역으로 지정해 등산이 일부구간만 허용되는 곳이다.봄부터 가을까지 만흥 식물들이 자생하면서 ‘산상의 화원’이란 이름으로 알려진 곳으로 곳곳에 ‘백두대간 나무심기’ 라는 팻말을 품고 있는 수목들이 쉽게 눈에 띄는 것도 식물자원 보호구역으로 지정되면서 자연을 지키려는 노력의 결실이기도 하다.이 때문에 금대봉은 산행뿐 아니라 다양한 꽃과 자생식물을 촬영하려는 생태 탐방객들이 즐겨찾는 곳이다. 금대봉에서 두메기름나물, 바이칼바람꽃, 등 백두산에서 백두대간을 타고 내려온 북방계 식물을 비롯해 한국 특산식물이 15종, 희귀식물은 16종 이상을 조사한 바 있는 현진오 박사는 해발1,200m를 넘는 고산 정상부에서 다양한 초본 식물상을 한꺼번에 관찰할 수 있는 곳은 금대봉 일대가 우리나라에서 거의 유일하다고 밝힌바 있다.금대봉에는 높고 추운 산꼭대기에서 자라는 만병초도 자생하는 것으로 알려져 있다. 『정선총쇄록』에도 “이 약은 이 고을의 갈래사(葛來寺) 동편 골짜기에서만 나는데 만병통치로 즉효를 보지 못한 건시 없다고 하나 아직 시험해 보지 못했는데 각처 사람들이 많이 와서 잎을 뜯어간다”고 나와 있다.금대봉 정상에 오르면 두문동재 넘어 천의봉과 함백산이 웅장하게 다가온다. 금대봉을 오른 사람들은 주로 38번 국도상의 두문동재(1,268m)에 정상까지 가는 동안 두개의 헬기장을 지나며 방화선을 따라 이어지는 산길 주변으로는 봄이면 얼레지, 노루귀, 꿩의바람 등 산상의 화원에 펼쳐진 야생화에 빠져들다 보면 예상 등산시간보다 훨씬 더 소요된다.", - "MNTN_HG_VL" : "1418", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", - "MNTN_NM" : "금대봉" + "DETAIL_INFO_DTCONT" : "마산은 백두대간의 남한쪽 분단이다. 강원도 고성군 간성읍과 토성면의 경계에 위치하고 있는데 북으로 더 이상 나가지 못하고 있어 아쉬운 마음이 든다.현재는 대단위 종합레져타운을 기슭에 품고 있는 화려한 산이 되었지만, 예전에는 고원의 넉넉한 평원을 굽어보는 수수한 산이었다. 동쪽으로 끝없이 펼쳐진 바다와 함께 호수의 조망이 일품이다. 날씨가 좋을 경우 진부령에서 향로봉, 비로봉을 비롯한 금강산 연봉까지 아슴푸레하게 볼 수 있다.마산과 신선봉은 능선으로 바로 연결이 되있으며 알프스 스키장이 산행 초입리가 되어 겨울철에는 알프스 스키장까지 이동하는 차편이 무궁무진하여 교통은 어렵지 않다. 신선봉은 백두대간 종주 등산로에서 약간 동쪽으로 벗어나 있는 봉우리다. 너덜이 깔린 신선동 정상에 서면 동해와 신평벌, 설악산이 한눈에 들어온다. 두 산을 종주 하거나 거꾸로 미시령에서 시작해서 알프스 스키장으로 하산할 수 있다.", + "MNTN_HG_VL" : "1052", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 간성읍", + "MNTN_NM" : "마산" }, - "longitude" : 128.91526469999999, - "latitude" : 37.212530600000008 + "longitude" : 128.47333330000001, + "latitude" : 38.403611099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금물산은 경기도 양평군과 강원도 횡성군의 경계를 이루고 있다. 예전에 도둑이 많이 나타나서 붙여진 도둑고개에서 동쪽 횡성 방향으로 내려가면 왼쪽에 나타나는 산이다.산은 그다지 높지 않으나 주능선 길이가 10km를 넘어 계곡이 길고 깊다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑아 가재와 식용 개구리가 많다.금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서북으로 뻗어나가고 있다.\"성지봉\"이라는 이름은 옛날 임금의 행차가 쉬어갔다고 하여 붙여진 이름이라 하며, 이곳은 여름에는 길섶의 풀이 웃자라 긴팔, 긴바지가 아니면 통과하기 힘들다.성지봉에서 정상까지는 봉우리가 두 개 있어 길이 오르락 내리락 한다.정상은 일부 바위도 있으며, 특히 양평 쪽으로 뻗은 서봉과의 사이에 자리하고 있는 계곡 쪽으로는 절벽을 이루고 있다.조망도 좋아 동쪽으로는 가리산이 보이고, 북쪽으로는 넓은 시동리와 유치리 일대의 분지가 보인다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼 만하다.", - "MNTN_HG_VL" : "774", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 횡성군", - "MNTN_NM" : "금물산" + "DETAIL_INFO_DTCONT" : "나라 안팎으로 이름난 산, 북한산이 남쪽으로 보현봉을 솟구치고 다시 북악에서 한 줄기는 동쪽 낙산으로 또 한 줄기는 서쪽으로 뻗어 인왕산을 빚어 놓았다. 풍수상으로 보면 조산인 북한산에서 주산인 북악산에 연결되고 낙산이 좌청룡이면 인왕산은 우백호가 된다.인왕산은 서울 어느 방향에서 오르든지 한 시간이면 오를 수 있고 오르면 조망이 뛰어나다.서울의 중심에 솟아있으며 높지는 않지만 산세는 웅장하다. 특히 동쪽 기슭이 아늑하고 풍치가 빼어나 장안 제일의 명승지라 할 수 있다. 북쪽 자락에 있는 부암동은 무계동이라 불리던 곳으로 중국의 무릉도원에 버금갈 정도의 아름다운 경치를 자랑하던 곳이다.인왕산이란 명칭은 산자락에 인왕사라는 절이 있어 붙여진 이름이다. 조선 중종 때는 필운산이라 불리기도 해, 지금도 사직공원 근처엔 동네 이름으로 남아있다.인왕산하면 떠오르는 이야기가 몇 가지 있다. 그중 첫 번째가 호랑이다. 조선시대 인왕산은 호랑이의 출몰로 호환이 끊이지 않았다. 민가는 물론이요 경복궁이나 창덕궁에까지 들어와 소란을 피웠다. 피해가 커지자 조정에서 군대를 동원해 호랑이를 잡을 정도였다. 불과 100년 전인 1901년에도 경복궁에 호랑이가 출몰한 기록이 있다.수려한 경치 덕분에 인왕산을 배경으로 한 산수화가 많다. 겸재 정선의 ‘인왕제색도’가 널리 알려져있다. 국보 216호인 이 작품은 비온 뒤 안개가 피어오르는 인왕산의 모습을 잘 표현한 걸작이다.또 한 가지 인왕산에 대한 일화는 무장공비사건이다. 1968년 북한의 김신조 일당이 청와대를 습격하기 위해 인왕산 옆 산길로 질러왔다. 그 사건 뒤로 인왕산은 일반인 출입이 통제되었다가 1993년 2월 24일부터 오를 수 있게 됐다.", + "MNTN_HG_VL" : "340", + "MNTN_LOCPLC_REGION_NM" : "서울시 종로구, 서대문구", + "MNTN_NM" : "인왕산" }, - "longitude" : 127.8491667, - "latitude" : 37.553611099999998 + "longitude" : 126.95930420000001, + "latitude" : 37.584948900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "춘천시에서 남쪽으로 8킬로미터 지점에 자리 잡은 산으로 일명 진병산(陳兵山)으로 불리며, 춘천시를 에워싼 산들 중 최고봉이라고 할 수 있는 대룡산(899m)에서 남서쪽으로 뻗어내린 능선이 수리봉(645m)을 솟구친 후 그 맥이 원창고개에서 잠시 가라앉았다가 마지막으로 솟은 산이다. 사계절 중 겨울에 오르기 가장 좋은 산으로 가을이면 낙엽이 무릎까지 빠질 정도로 수목이 울창하다. 김유정의 고향 실례마을을 품고 있는 산이며, 춘천의 문인들이 그의 소설 제목을 따서 만부방길, 동백꽃길, 봄봄길 등의 이름을 붙인 정겨운 등산길이 눈길을 끈다. 본래 금병산 정상은 참나무숲으로 에워싸여 조망이 어려웠지만, 최근 춘천시에서 100여 평 정도 깨끗하게 베어내 이제는 사방으로 막힘없는 조망을 즐길 수 있다.", - "MNTN_HG_VL" : "652", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신동면, 동산면", - "MNTN_NM" : "금병산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "인내산" }, - "longitude" : 127.7452778, - "latitude" : 37.8125 + "longitude" : 129.1022293, + "latitude" : 35.921467 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남해 금산은 남해섬을 대표하는 산으로, 한려해상국립공원이 말 그대로 거의 다 바다로 지정되어 있는데 유일하게 산이 해상 공원에 포함된 것이 금산이다.금산은 비단을 두를 뻔한 산으로 유명하다. 금산의 본래 이름은 보광산(普光山)이다. 이성계가 왕이 되고자 보리암 아래 있는 '이태조기단'에서 백일기도를 드리면서 자신이 왕이 되면 이 산을 비단으로 덮겠다는 약속을 했다. 이성계가 조선을 개국한 뒤, 약속을 지킬 일을 생각하니 난감했다.이때 사려 깊은 신하가 산 이름을 하사하면 비단보다 오래 갈 것이라고 제안해 이름을 비단 '금(錦)'자를 써 이전의 산 이름을 금산으로 바꿈으로 이성계는 자신의 약속을 절묘하게 지킬 수 있었다고 전해지고 있다.매표소에서 보리암으로 이어지는 등산로 왼편으로 사선대가 올려다 보인다. 사선대는 먼 옛날 동서남북의 네 신선이 조그만 암봉에서 놀았다는 곳이다. 사선대 맞은편에는 절벽을 이룬 웅장한 바위는 만장대이다.", - "MNTN_HG_VL" : "705", - "MNTN_LOCPLC_REGION_NM" : "경상남도 남해군 상주면ㆍ이동면ㆍ삼동면", - "MNTN_NM" : "금산" + "DETAIL_INFO_DTCONT" : "황적봉은 계룡산의 봉우리중 하나이다. 계룡산은 충청남도 공주군과 논산군에 걸쳐있으며 주봉인 천왕봉(845m)아래로 쌀개봉(828m), 황적봉(664m),수창봉(662m) 도덕봉(524m)등 거대한 산혼을 횡성하고 산세는 대체로 경사가 완만한 편이며 정상 부근은 경사가 급하다. 이들 봉우리 사이에는 7개의 계곡과 3개의 폭포가 있어 운치를 더해주며, 골짜기에는 동학사갑사신원사 그리고 구룡사의 대가람을 배치한 불교의 명지이며, 다양한 식, 생물분포의 학술적 자원이 풍부하며 자연경관이 빼어난 국립공원으로 이름이 높다.출입이 금지되어 있는 황적봉-쌀개봉 능선은 계룡산 산행의 또 하나의 모험이자, 신선한 충격이다. 황적봉-쌀개봉능선을 잇는 산행은 때로는 한가할 정도로 평탄한 산행길이지만 변화 많은 봉우리로 점철 돼 있어 잔재미가 많으며 때로는 위험한 바윗길이 숨어있는 호방한 산행의 기분도 만끽할 수 있는 아름다운 코스이다. 특히 쌀개능선의 호방한 바위암릉위에서 바라보는 연천봉에서 관음봉을 거쳐 자연성능, 삼불봉으로 이어지는 이 산의 이른바\"\"주코스\"\"의 능선과 봉우리들을 바라보는 경관은 전혀 다른 매력으로 다가온다.", + "MNTN_HG_VL" : "664", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 반포면, 논산시 두마", + "MNTN_NM" : "황적봉" }, - "longitude" : 127.9774498, - "latitude" : 34.7561125 + "longitude" : 127.2319444, + "latitude" : 36.348611099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "비봉산(672m)과 금성산(550m)은 경북 의성군 금성면, 가음면, 춘산면, 사곡면에 걸쳐 있는 비교적 알려지지 않은 산이다. 금성산 서녘자락인 금성면 탑리에는 국보 77호 의성탑리오층석탑이 있다. 또한 28번 국도와 927번 지방도가 만나는 초전리에는 문익점선생기념비와 삼한시대 부족국가인 조문국의 경덕왕릉이 있어 문화유적답사를 겸하여 한 번은 올라야 할 산이다.몇 년 전만 해도 의성 부근은 교통이 불편하여 당일산행은 언감생심이었다. 그러나 최근 중앙고속국도의 개통으로 군위, 의성에 있는 오지 산도 당일산행이 가능해졌다.의성군 금성면의 탑리 시가지를 벗어나 산운리의 68번 지방도에서 북쪽으로 올려다보면 금성산 비봉산의 산세는 참으로 눈부시다. 겨울 햇볕에 빛나는 산세는 한번 우러르기만 하면 도저히 참을 수 없는 산행에의 정열이 저절로 솟구친다.산행 종점 인근에는 신라시대 의상조사가 창건한 유서깊은 고찰인 수정사가 있고 탑리 오층석탑, 관덕리 삼층석탑, 빙산사지 오층석탑 등 우리나라 석탑 양식을 살펴볼 수 있는 석탑과 제오리 공룡발자국 화석지 등의 유적지가 금성산 일원을 따라 자리잡고 있다. 이중 빙산사지 오층석탑이 있는 빙계계곡은 여름철 피서지로서 빙혈과 풍혈로 유명하다.", - "MNTN_HG_VL" : "609", - "MNTN_LOCPLC_REGION_NM" : "경북 의성군 금성면ㆍ가음면ㆍ춘산면ㆍ사곡면", - "MNTN_NM" : "금성산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "631", + "MNTN_LOCPLC_REGION_NM" : "충청남도 부여", + "MNTN_NM" : "성태산" }, - "longitude" : 128.7093678, - "latitude" : 36.262196699999997 + "longitude" : 126.7236111, + "latitude" : 36.373333299999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "672", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군", - "MNTN_NM" : "금성산" + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "운계봉" }, - "longitude" : 128.03661880000001, - "latitude" : 35.516717800000002 + "longitude" : 128.78583330000001, + "latitude" : 37.805277799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부여읍내에서 아주 가까운 동쪽에 위치, 청마산과 연결되어 도심형등산코스이며, 청마산은 금남정맥의 끝부분임", - "MNTN_HG_VL" : "121", - "MNTN_LOCPLC_REGION_NM" : "충청남도 부여군 부여읍", - "MNTN_NM" : "금성산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1006", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "상정바위" }, - "longitude" : 126.92388889999999, - "latitude" : 36.277500000000003 + "longitude" : 128.71916669999999, + "latitude" : 37.423611100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전국 8대 명산의 하나로 알려진 나주의 금성산은 동쪽의 노적봉(露積峰), 서쪽의 오도봉(悟道峰), 남쪽의 다복봉(多福峰), 북쪽의 정녕봉(定寧峰) 등 4개의 봉우리로 이루어져 있다. 금성산은 예부터 군사요충지였으며 현재도 군사보호지역으로 묶여있다. 금성산에는 1011년 고려 현종이 거란족의 침입을 피해 10여일 머물렀던 금성산성의 흔적이 남아있다.또한 고려시대부터 국가에서 산신제를 지냈던 영산으로 매년 봄, 가을이면 나주뿐만 아니라 전국 각지에서 사람들이 모여들어 한 해의 풍년과 태평함을 기원하였던 곳이기도 하다. 특히 금성산에는 5개의 사당이 있었는데, 산 정상에는 상실사(上室祠), 중턱에는 중실사(中室祠), 산 기슭에는 하실사(下室祠)와 국제사(國際祠)가 있었으며, 금성산성 안에는 이조당(爾朝堂)이 있었지만 현재는 모두 소실되었다. 금성산 주변은 요즘도 도처에서 치성을 드리기 위해 찾아온다.현재 정상부는 군사보호지역으로 산행이 불가능하지만, 1월 1일에는 해맞이 행사를 개최하고 일반인들이 올라갈 수 있다.", - "MNTN_HG_VL" : "451", - "MNTN_LOCPLC_REGION_NM" : "전남 나주시 경현동 대호동", - "MNTN_NM" : "금성산" + "DETAIL_INFO_DTCONT" : "조항산은 청화산과 이웃해 있는 산으로 해발이 제법 높은데 비하여 많이 알려지지 않아 인적이 드문 산이다. 조항산에 오르기전에 삼송리라는 마을을 거치게 되는데 이곳에는 천연기념물 제 290호로 지정된 `용송'이 볼만하다. 수령 약 600여년이 된 소나무로 밑둥둘레가 약 5m에 높이가 15미터나 되며 용의 형상으로 가지를 드리운 폭이 20미터가 넘는다. 주변에는 아름드리 노송 20여그루를 거느리고 있어 일명 왕소나무라 불리기도 한다.정상에 오르면 북쪽으로는 대야산과 둔덕산 줄기너머로 군자산 장성봉, 희양산이 보이고 남으로는 청화산이 서쪽으로는 백악산 정상이 한눈에 들어온다.갓바위재와의 중간지점에 있는 병풍 같은 암릉지대가 이 산에서는 제일 절경이며, 정상 서편 770봉 주변 암릉지대에 있는 거암군 또한 일품이다.", + "MNTN_HG_VL" : "951", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면, 충청북도 괴산군 청천면", + "MNTN_NM" : "조항산" }, - "longitude" : 126.6972222, - "latitude" : 35.055 + "longitude" : 127.93611110000001, + "latitude" : 36.633611100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금수봉은 계룡산 천황봉에서 뻗어나온 산줄기가 민목재를 지나서 백운봉(535.5m)에서 두갈래로 갈라져 오른쪽에 금수봉을 왼쪽에 도덕봉을 빚어 놓았다. 이 같은 명산의 정기를 이어받은 금수봉은 정상 에 올라서서 사방을 내려다보면 주위의 풍경이 비단에 수를 놓은 것 같다고 하여 금수봉이라고 부른다.대전의 금수봉은 이름 그대로 아름다운 산이다. 맑은 개울이 있고 짙은 숲이 있으며 아기자기한 바위등성이가 있다.봄에는 꽃이 아름답고 가을에는 단풍이 곱다. 금수봉 바로 옆의 봉우리 이름은 '백운봉'이다. 금수봉과 백운봉 고운 이름을 가진 두 산이 한 곳에 있는 곳은 우리나라에서 여기뿐일 것이다.금수봉은 큰암벽이 없이 우거진 수림으로 감싸고 있어 초여름 비단같은 신록에 산꽃이 수를 놓은듯이 박힌 아름다운 산으로 유성구에서 수통골 계곡에 레포츠 공원을 조성하여 놓아 시민들이 많이 찾고 있다.", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성", - "MNTN_NM" : "금수봉" + "DETAIL_INFO_DTCONT" : "경상남도 밀양시 단장면·산내면과 울산광역시 울주군 상북면(上北面)의 경계에 있는 산이다. 주봉(主峰)은 사자봉이다. 남쪽 5km 부근에 솟아 있는 재약산(載藥山:주봉은 수미봉 1,018m)과 맥이 이어져, 천황산을 재약산으로 일컫기도 하는데, 이러한 혼동은 천황산이 일제강점기 때 붙은 이름이라 하여 '우리 이름 되찾기' 운동의 일환으로 사자봉을 재약산 주봉으로, 재약산을 수미봉으로 부르면서 생겨났다.산세가 수려하여 삼남금강(三南金剛)이라 부르며, 인근 일대의 해발고도 1,000m 이상의 준봉들로 이루어진 영남알프스 산군(山郡)에 속하는 산이다. 산세는 부드러운 편이나 정상 일대에는 거대한 암벽을 갖추고 있다. 수미봉·사자봉·능동산·신불산·취서산으로 이어지는 능선은 드넓은 억새평원으로서 사자평 고원지대라고 부르는데, 일대는 해발고도가 800m에 달해 목장으로 개발되어 있다.서쪽 산기슭에 있는 유명한 대찰(大刹)인 표충사(表忠寺)를 비롯하여 부근에 내원암(內院庵)·서상암(西上庵) 등의 절과, 높이 20m의 폭포 2개가 연이어 있는 칭칭폭포[層層瀑布:毘盧瀑布], 무지개가 걸리는 높이 25m의 금강폭포 등 명소가 있다. 천황산의 북쪽 사면에는 가마볼·호박소[臼淵] 등의 명소 외에 단열냉각에 의한 물리적 현상으로 여름에도 골짜기에 얼음이 어는 얼음골(천연기념물 224)이 있다.", + "MNTN_HG_VL" : "1189", + "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상남도 밀양시", + "MNTN_NM" : "천황산" }, - "longitude" : 127.2811111, - "latitude" : 36.328888900000003 + "longitude" : 128.97150189999999, + "latitude" : 35.557452300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금수산, 이름 그대로 비단에 수를 놓은 듯한 모양을 하고 있다. 월악산 국립공원권 최북단에 위치한 이 산의 이름은 본래 백악산이었다. 조선조 중엽 퇴계 이황 선생이 단양 군수로 있던 시절, 너무도 아름다운 경치에 감탄해 금수산으로 이름을 고쳐 부르게 되었다고 한다.특히 가을 경치가 빼어난 아름다운 암산으로, 봄속에 겨울을 만날 수 있는 신비한 산이다.매년 4월초까지 얼음이 얼다가 처서가 지나면 얼음이 녹는 얼음골에는 돌구덩이를 30cm정도 들추면 밤톨만한 얼음 덩어리가 가을까지 나오고 있어 자연의 신비감을 더해준다. 금수산 주능선은 상어 이빨을 연상케하는 암릉길로 스릴 만점이다.산 중턱에는 바위틈에서 한해나 장마에도 꾸준한 물줄기를 뿜어내고 있어, 산을 찾는 이들의 목을 축여주고 있다. 발길마다 눈길마다 은은히 차고 도는 풍경에 취해 걷다 보면, 어느새 산 정상. 그곳에서 내려다 보면 다소곳이 트인 산세와 충주호의 푸른 물이 어우러져 은은한 채색이 베인 화선지 위에 선 기분이 든다.", - "MNTN_HG_VL" : "1016", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면ㆍ단양군 적성면", - "MNTN_NM" : "금수산" + "DETAIL_INFO_DTCONT" : "백석봉은 백두대간상의 노인봉에서 남쪽으로 길게 뻗어 내린 산맥이 소황병산과 용산, 박지산을 크게 일으키고 오대천과 조양천의 합류지점인 북평면에 솟아 있는데, 정선 9대 명산 중의 하나이다.산정에 백색을 띈 큰 바위로 인해 백석봉이라 불리게 된 이 산은 숙암리와 나전 2리에 등산로를 새로 개설하여 등산하기 편해졌다. 산 정상에는 신기한 약효가 있는 샘이 있는데 이 물을 부정한 사람이 마시면 마른다는 전설이 있으며 이 웅봉이 검게 변하면 수일내에 비가 내린다는 전설이 전해내려 오고 있다.정상에 서면 철쭉이 군락지를 이루고 있는 숙암계곡이 아찔하게 내려다 보인다. 이 계곡 주변에는 맑고 깨끗한 숙암샘터가 있다. 등산 외에도 계곡길을 따라 드라이브를 즐기기에 좋은 코스다. 능선에는 진달래 군락지가 곳곳에 있고 참나무 군락지에는 겨우살이가 지천이다. 듬직한 능선길은 고산다운 풍경이여서 좋고, 등산로는 안내판이 잘 설치되어 있다.", + "MNTN_HG_VL" : "1170", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면", + "MNTN_NM" : "백석봉" }, - "longitude" : 128.25666799999999, - "latitude" : 36.983795800000003 + "longitude" : 128.6408333, + "latitude" : 37.481944400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구미역에서 남서쪽으로 약 4km 떨어져 우뚝 솟은 금오산은 1970년 도립공원으로 지정된 산이다. 산 전체가 바위로 이루어져 기암절벽과 경사가 심한 산세를 이루고 있으며, 산아래 대혜폭포까지 케이블카가 설치되어 있다.", - "MNTN_HG_VL" : "977", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시, 칠곡군 북삼읍, 김천시 남면", - "MNTN_NM" : "금오산" + "DETAIL_INFO_DTCONT" : "위봉산은 별로 높지 않고 많이 알려져 있지도 않은 산이다. 추줄산이라고도 한다. 삼국시대 백제와 신라의 국경지대를 이루었고 조선시대에는 성리학의 영남학파와 기호학파를 구분짓는 학풍적 경계를 이루었던 곳이다. 하지만 분지에 위봉산성과 위봉사를 품고 있고, 전주의 8경 중 하나라 일컬어지는 2단 위봉폭포도 거느리고 있어 이름만 알려지지 않았을 뿐이지 실세라 할 수 있다. 또한 이 명물들을 구경하면서 오르는 산길은 부드럽게 이어져 마치 공원에 나온 듯한 착각이 들 정도로 편한 산이다.정상에 서면 북으로 동상저수지, 동으로 연석산, 운장산, 남으로 원등산, 마이산, 만덕산, 서로는 종남산, 서방산 등을 조망할 수 있다.위봉사는 604년(백제 무왕 5) 창건된 것인데 한국 불교사찰 31본산의 하나로서 경내에는 보광명전(普光明殿;보물 608) 등이 있다. 위봉산성은 송광사에서 위봉사로 넘어가는 고개 위에 그 터가 남아 있는데 성내에는 행궁과 진전의 터도 있다. 송광사에서 더 깊이 골짜기를 타고 4㎞쯤 위봉산 고개길을 오르면 위봉산성 서문이 나온다. 이 위봉산성 서문을 지나 300m쯤 내려가면 위봉사가 나온다.위봉산성은 이태조의 영정을 봉안하기 위해 축성했던 성이다. 성의 규모는 길이 16㎞, 높이 4~5m, 폭 3m의 홍예석문이 지방기념물로 보존되고 있다. 이 산성은 1675년 (숙종 원년) 7년의 세월과 인근 7개 군민을 동원하여 쌓은 것을 임진왜란, 정유재란, 병자호란을 겪으면서 전주 경기전의 영정과 왕조실록을 묘향산까지 피난시켰고, 무주 적상산성에 설치한 사고도 어려움이 많아 전주에서 가까운 험한 지형을 골라 새로 성을 쌓아서 이태조 영정을 피난시키는데 목적이 있었다. 사찰 앞에서 1백여미터 아래에 있는 위봉폭포가 장관이다. 절벽사이로 비류직하 하는 60여미터의 폭포와 빼어난 경관은 그 아래로 펼쳐진 골짜기, 그리고 동상댐 호반의 절경 등이 어우러져 주말뿐 아니라 평일에도 이곳을 찾는 차량의 행렬이 줄을 잇고 있다.", + "MNTN_HG_VL" : "524", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 소양면, 동상면", + "MNTN_NM" : "위봉산" }, - "longitude" : 128.30529999999999, - "latitude" : 36.088487800000003 + "longitude" : 127.2619316, + "latitude" : 35.918517299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "지리산 왕시리봉에서 섬진강을 내려다보면 굽이쳐 가던 섬진강 끝자락에 삼각형 실루엣으로 우뚝 솟은 산이 눈길을 사로잡는데, 하동의 진산인 금오산(849m)이다. 금오산 정상은 남해 조망이 일품이다. 오른쪽으로 광양제철소와 화력발전소, 정면으로 다도해의 수많은 섬들이 점점이 떠 있고, 왼쪽 사천만 뒤로 우뚝한 와룡산의 멋진 자태 또한 일품이다. 정상에 선 중계탑으로 인해 실제로 오를 수 있는 정상부가 한쪽으로 밀려나 있는 게 아쉽다.남해를 비추며 떠오르는 달맞이와 해맞이, 아름다움을 간직한 해넘이는 금오산이 자랑하는 최고의 볼거리다. 달맞이 전망대로는 금오산 남쪽의 너덜지대에 위치한 석굴암이 최고로 꼽힌다. 달이 없는 밤이라도 불야성을 이룬 광양제철소의 야경 또한 황홀한 볼거리를 제공한다.석굴암과 봉수대, 비구니도량 금성암 등 산행하면서 둘러볼 수 있는 볼거리 외에도 1973년 완공된 남해대교와 충무공의 얼을 기리는 충렬사, 그 앞 노량 앞바다에 떠 있는 거북선 등 많은 명소가 있다.", - "MNTN_HG_VL" : "849", - "MNTN_LOCPLC_REGION_NM" : "경남 하동군 금남면ㆍ진교면", - "MNTN_NM" : "금오산" + "DETAIL_INFO_DTCONT" : "대전 동구 식장산은 높이 598미터로 대전에 있는 산 중 가장 높으며 우람하다. 또 무성한 숲과 높은 바위벼랑, 깨끗한 호수와 맑은 물이 흐르는 개울도 있다. 식장산 남북으로 양 날개를 펼친 산줄기는 대전의 동쪽 울타리를 이루고 있다. 대전 시민들은 식장산 위로 여명 해솟음을 보며 떠오르는 달을 본다.5월 하순 아카시아 꽃이 필 무렵이면 세천공원에서 철탑 사거리를 지나 구절사 길까지 온통 아카시아 꽃천지다. 온 산에 짙게 밴 꽃향기를 맡으며 하얀 아카시아꽃으로 뒤덮인 길을 걷노라면 하늘나라의 화원을 걷는 것 같다. 우리나라에서 식장산의 꽃길 10리가 아카시아꽃으로는 가장 훌륭한 곳으로 꼽힌다.식장산 세천공원 수원지 아래에는 벚꽃이 유명하다. 또 수원지 호수와 계곡이 아름답다. 숲으로 싸인 호수와 독수리봉에서 후주에 이르는 계곡은 어느 산의 계곡과 견주어도 빠지지 않는다. 숲 속에 묻혀 있는 계곡은 돌, 바위, 나무가 한데 어울려 깨끗하고 아름답다.식장산에는 오래된 절 세 개가 있다. 서쪽에는 고산사, 북쪽에 개심사, 동쪽 동수리봉 아래에는 구절사가 있다. 뿐만 아니라 숲이 짙으며 대전시가지가 내려다보이고 속리산, 백화산, 덕유산, 민주지산, 대둔산, 계룡산이 조망된다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 동구, 충북 옥천군", + "MNTN_NM" : "식장산" }, - "longitude" : 127.8692594, - "latitude" : 34.993499200000002 + "longitude" : 127.4800673, + "latitude" : 36.2953647 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "664", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", + "MNTN_NM" : "일림산" + }, + "longitude" : 127.0262077, + "latitude" : 34.679327499999999 }, { "mountain" : { @@ -1401,1533 +1371,323 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼랑진과 원동에 걸쳐 있는 금오산과 천태산은 낙동강을 끼고 있어 주위 경관이 수려할 뿐 아니라 경부선열차를 이용할 수 있어 교통도 편리하다.금오산만 오를 경우 4시간, 금오산- 천태산 코스는 6시간30분, 금오산-매봉산 코스는 6시간 정도 소요된다. 3~4개의 바위봉우리로 뭉쳐진 채 힘차게 단일봉 형상을 한 금오산은 멀리서 보아도 그 자태가 당당하여 천태,만어산을 거느린 `맏형 산'으로 손색이 없다.주변에 삼랑진양수발전소가 안태호 천태호 등 인공호수와 더불어 명소로 등장했고 가락국 때부터 있어온 부은암은 이 곳을 찾는 사람들에게 오늘과 어제를 가르쳐 주는 역사의 현장이다.", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼량진읍, 양산 원동", - "MNTN_NM" : "금오산" + "DETAIL_INFO_DTCONT" : "수리봉은 수리가 긴 날개를 벌리고 내려앉은 형상의 품 넓은 산으로 정상에 서면 사방으로 첩첩이 둘러쌓은 능선의 바다를 만끽할 수 있는 오지의 산이기도 하다. 전반적으로 산세가 온화하지만 코스가 제법 길고, 무엇보다 지맥들이 수없이 갈려나가 독도에 각별한 주의를 요한다. 정상에서 여무재 쪽으로 10분쯤 떨어지면 수십km를 일망무제로 펼쳐진 숲과 능선의 바다가 펼쳐진 전망바위를 만날 수 있다.", + "MNTN_HG_VL" : "1019", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 횡성군", + "MNTN_NM" : "수리봉" }, - "longitude" : 128.90615080000001, - "latitude" : 35.416717800000001 + "longitude" : 128.24333329999999, + "latitude" : 37.479722199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "속리산과 구병산 사이에 빼꼼히 솟아오른 금적산은 충북 보은군 삼승면에 그 터를 두고 있다. 예로부터 전국민이 3일간 먹을 수 있는 보배가 묻혀 있다고 전해오는 이 산은 주변에 어울린 명산을 닮아 수려한 산세를 자랑하고 있다.또한 이 산은 이름과 관련하여 금으로 된 동물이야기를 전설로 전하고 있다. 옛날 이 산에는 금송아지와 금비둘기가 살고 있었다. 금송아지는 금비둘기를 아내로 맞이하기 위하여 산기슭에 밭을 일구어 금비둘기가 좋아하는 여러 가지 곡식을 가꾸었다. 양지 바른 곳에 집을 짓고 바위아래 옹달샘을 파서 보금자리도 마련했다.그런 다음 금비둘기에게 청혼하여 둘은 결혼을 하게 되었고 금슬좋은 부부로 행복한 나날을 보내고 있었다.그러던 어느날 금송아지는 밭을 갈다가 넘어지는 바람에 두눈을 잃고 말았다. 금비둘기는 눈먼 남편을 위하여 열심히 봉양하였으나 금비둘기의 벌이로 금송아지를 먹이기에는 역부족이었다.", - "MNTN_HG_VL" : "652", - "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 삼승면 서원리", - "MNTN_NM" : "금적산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", + "MNTN_NM" : "뾰루봉" }, - "longitude" : 127.70805559999999, - "latitude" : 36.406388900000003 + "longitude" : 127.42475520000001, + "latitude" : 37.710080900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "낙안읍성 북쪽에 솟은 금전산은 낙안의 진산이다. 옛 이름은 쇠산이었으나 백여년 전에 금전산으로 바뀌게 되었으며 한자 뜻풀이로 보면 금(金)으로 된 돈(錢) 산이 된다. 그러나 금강암 스님의 말에 의하면 금전산은 불가에서 유래한 이름으로 부처의 뛰어난 제자들인 오백비구(오백나한) 중 금전비구에서 산 이름을 따왔다고 한다. 또한 풍수지리를 공부하는 사람들은 금전산의 산세를 이렇게 해석하기도 한다.금전산 북동쪽에는 옥녀봉이 있고 동남쪽 줄기에는 오봉산과 제석산이 있다. 서남쪽에는 백이산이 있는데 전체적으로 놓고 볼 때 이것은 옥녀산발형이라 말할 수 있다. 풀어 말한다면 옥녀가 장군에게 투구와 떡을 드리려고 화장을 하기 위해 거울 앞에서 머리를 풀어헤친 형상이라고 한다. 이러한 말을 뒷받침하듯 낙안읍성 남쪽에 있는 평촌리 평촌못은 옥녀의 거울에 해당하는 조건을 완벽하게 갖춘 못이기 때문에 예부터 낙안에는 미인들이 여느 지역보다 유난히 많이 났다고 한다.금전산 산행 초입에 높이가 10여미터 되는 형제바위가 있는데 원래는 두 개가 사이좋게 서 있었다고 한다. 그런데 80년대 초반 동생바위가 허물어져 형님바위만 남았다고 한다. 들어갈 때는 금강문이고 나갈 때는 해탈문이라는 바위굴을 나서면 금강암에 오른다. 금강암은 백제 위덕왕 때 창건되었다고 한다. 금강암을 지나면 의상대라 불리는 바위에 올라설 수 있다.", - "MNTN_HG_VL" : "668", - "MNTN_LOCPLC_REGION_NM" : "전남 순천시 낙안면", - "MNTN_NM" : "금전산" + "DETAIL_INFO_DTCONT" : "기장군 철마면에 위치한 거문산(543m)은 여름 등산지로 권할만한 곳이다.산행을 시작해 1시간이면 정상에 닿을 수 있고 휴식을 포함해 3시간이면 완주할 정도로 코스가 짧은데다 우거진 녹음이 있기 때문이다. 또 사람이 적게 다닌 곳이라 곳곳에 탐스럽게 열린 산딸기를 따먹어 가면서 산을 오르는 즐거움을 맛볼 수 있으며 고사리 같은 산나물이 군락 이룬 자연을 구경할 수도 있다. 하산길에 수십 년된 우리의 전통 초가를 감상할 수 있는 것도 산행재미를 더해준다.", + "MNTN_HG_VL" : "543", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면 웅천리", + "MNTN_NM" : "거문산" }, - "longitude" : 127.3497222, - "latitude" : 34.924722199999998 + "longitude" : 129.1552418, + "latitude" : 35.301902699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "포천읍에서 북쪽으로 약 10km 떨어진 나즈막한 산으로 교통이 편리하고 산길이 짧아 산을 처음 오르는 사람이나 여성들에게 인기가 있다. 산중턱에 금룡사라는 절과 커다란 미륵불상이 자리하고 있어 문화적 가치도 높은 산이다.정상에는 삼각점이 있고, 백운산,국망봉,청계산 등 조망이 뛰어나다.봄의 진달래, 늦가을의 낙엽, 겨울의 설경 또한 좋으며 계곡은 능선 북쪽편이 좋다.산록에는 사시사철 철철 넘치는 석간수가 있고, 일동에는 유황,하와이,사이판온천 등이 있다.", - "MNTN_HG_VL" : "569", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영중면 금주리", - "MNTN_NM" : "금주산" + "DETAIL_INFO_DTCONT" : "부여읍내에서 아주 가까운 동쪽에 위치, 청마산과 연결되어 도심형등산코스이며, 청마산은 금남정맥의 끝부분임", + "MNTN_HG_VL" : "121", + "MNTN_LOCPLC_REGION_NM" : "충청남도 부여군 부여읍", + "MNTN_NM" : "금성산" }, - "longitude" : 127.272735, - "latitude" : 37.957242299999997 + "longitude" : 126.92388889999999, + "latitude" : 36.277500000000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "947", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "금학산" + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제", + "MNTN_NM" : "아미산" }, - "longitude" : 128.91777780000001, - "latitude" : 36.377499999999998 + "longitude" : 128.20861110000001, + "latitude" : 37.7386111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정상은 947m 이며, 산전체가 철원군에 속해있다. 계산상 걷는 거리는 약 2km 정도여서 짧은편이나 코스의 굴곡이 있는 편이므로 2 시간 이상은 잡아야 한다.구불구불하게 이어진 산행은 아기자기하고 재미있는 편이며,부엽토길이 많아서 푹신함을 느낄수 있다.넓은 철원평야의 서쪽에 위치하므로 능선에서 철원 시내를 훤히 내려다 볼 수 있으며 등산로 곳곳에 벙커나 참호,전선등 군사시설을 볼 수 있다.", - "MNTN_HG_VL" : "576", - "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 동송읍", - "MNTN_NM" : "금학산" + "DETAIL_INFO_DTCONT" : "국립지리원 발행의 지형도에는 도덕봉(道德峰 534m)이라 표기되어 있으나 마을 주민들은 흑룡산(黑龍山)이라 부른다. 이 산은 도덕봉과 한줄기인 백운봉(白雲峰 536m), 금수봉(錦繡峰 532m), 빈계산(牝鷄山 415m)등을 포함하고 있다.도덕봉 정상 동쪽은 거대한 절벽이 장관이고 굴골에는 큰 동굴과 작은 석관 2개, 폭포 등으로 어우러진 계곡 오솔길 주변은 단풍이 좋다. 남릉은 서면이 50-100m의 암벽을 이루고 암릉 끝에는 커다란 수통굴이 있다. 일제때 구리를 캐던 곳으로 추정되는 구리골을 경유하여 수통굴로 가면 굴속에는 무속인들의 움집이 한채 있고 굴속 끝에는 작고 맑은 샘이 있어 산행길의 쉼터로 그만이다. 옛날에 이 골짜기에 도독이 많이 살고 있던 데서 산 이름이 유래한다.조망은 주변 숲에 가려져 시야가 좁고 트인 경관을 구경키 어렵다. 봄철에는 진달래가 붉게 물들고 산벚꽃이 많이 핀다.", + "MNTN_HG_VL" : "534", + "MNTN_LOCPLC_REGION_NM" : "충남 공주시 반포면, 대전 유성구", + "MNTN_NM" : "도덕봉 (흑룡산)" }, - "longitude" : 127.201291, - "latitude" : 38.184018700000003 + "longitude" : 127.2780556, + "latitude" : 36.348888899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 홍천군 북방면과 남면의 경계에 솟은 금확산은 655미터의 아담한 산이다. 하지만 정상에서 바라보는 전경은 1000미터가 넘는 산들과 비교해 결코 뒤지지 않는다. 그 배경이 되는 홍천강은 금확산을 더욱 아름답게 해주는 역할 중 으뜸이다.들머리는 북방면 노일리에 있는 노일분교다. 이곳에서 서쪽으로 300미터쯤 있는 버스종점의 콘크리트 포장길을 따라 북쪽으로 6분쯤 가면 간판 없는 작은 목장이 나온다. 등산로는 축사 뒤 계곡으로 뚜렷하게 나 있다.초입에서 40분쯤 걸리는 전망대바위에서 내려다보는 산태극 수태극을 그리며 흐르는 홍천강의 경치가 산행의 하이라이트다. 다시 산길을 30여분 오르면 정상이다. 용문산의 북녘 줄기인 봉미산에서 나산을 거쳐 장락산으로 이어지는 산세는 마치 봉황의 꼬리를 보는 듯하다.하산은 올라온 길을 다시 내려가 큰 소나무가 있는 삼거리에서 오른쪽 능선길로 빠지는 길, 홍천강이 지척으로 보이는 동남쪽 능선의 두 코스로 할 수 있다.", - "MNTN_HG_VL" : "655", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면, 남면", - "MNTN_NM" : "금확산" + "DETAIL_INFO_DTCONT" : "대덕산은 대부분 바위로 이루어진 산으로 경사가 급한 편이다.임휴사방면 등산로는 나팔바위 등 가파른 바위로 이루어져 있어 힘들게 오른 만큼 앞산에서볼 수 있는 경치 중 가장 아름답게 느껴지는 곳이다.임휴사는 1988년 전국 70여개 전통사찰중이의 하나로 문공부에 등록된 유서 깊은 사찰이다.신라 경명왕 5년(921년) 영조대사(靈照大師)께서 최초 창건하셨고 서기 1811년(순조11년)에 무주선사가 중창하였다.고려 태조 왕건이 팔공산에서 후백제 견훤과 동수대전에 패하여 이곳으로 와 군사 및 재정비하고관음성현께 기도 드린후 편히 쉬어갔다 하여 임휴사라 했다.매자골이란 옛날 매화(梅花) 낙화지(洛花地)에서 연유되었다. 지금으로부터 300年 전에 대덕산에성기도사가 있었다. 도사가 이 곡의 지세를 목형으로 보았다. 그런 어느 해 이른 봄 이 골짜기에매화가 탐스럽게 피더니 구암동(지금의 송현동)에 떨어졌다 하여 매자골이라고 부르게 되었다.", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구 송현동", + "MNTN_NM" : "대덕산" }, - "longitude" : 127.7519444, - "latitude" : 37.694166699999997 + "longitude" : 128.56388889999999, + "latitude" : 35.816666699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "자연경관이 좋고 등산로가 원만하여 누구나 쉽게 오를수 있고, 산림욕 하기 좋다. 산을 오르면서 동식물들을 접할수 있어 자연학습에 도움이 많이 된다. 정상에 올라가면 비봉산과 인제읍 시가지가 한눈에 내려다 보이며 경관이 좋다.", - "MNTN_HG_VL" : "662", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 인제읍 상동리", - "MNTN_NM" : "기룡산" + "DETAIL_INFO_DTCONT" : "장흥과 보성의 진산인 사자산은 곰재를 사이에 두고 제암산(779)과 마주보고 있다. 철쭉으로 유명한 '화산(花山)' 으로 해발은 낮으나 바닷가의 산이 다 그러하듯이 내륙의 산과 달리 웅장한 산세를 갖추고 있다. 사자산 정상 주변은 나무가 없이 억새와 바위로 완만한 능선을 이루고 있어 남쪽 발아래로 확 트인 남해바다의 풍경을 볼 수 있다.장흥벌을 향하여 울부짖는 사자형상으로 일컬어지는 사자산(獅子山 666m) 은 제암산, 억불산(518m)과 더불어 장흥의 삼산으로 꼽히는 명산이다 . 장흥읍쪽 봉이 사자머리 같다하여 사자두봉, 정상은 남릉과 더불어 꼬리같다고하여 사자미봉으로 불린다. 장흥벌에 솟구친 사자산은 철따라 다양한 모습을 보여준다.봄이면 파르한 기운이 스며 들면서 생명의 신비함을 느끼게 하고 여름이면 푸른 초원으로 변하고 가을이면 억새가 날리면서 강렬한 인상을 주는 산이다 사자두봉에서 사자미봉까지 이어지는 약 2km의 능선은 부드러움과 거친 자연미를 느낄 수 있다 .특히 남서면의 기암 절벽은 설악산의 어느 암릉에도 뒤지지않을 정도로 웅장하고 힘찬 자연미를 보여준다. 주능선 중간쯤의 안부와 능선 남쪽 사면은 전국에서도 유명한 활공장이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군, 보성군", + "MNTN_NM" : "사자산" }, - "longitude" : 128.1527778, - "latitude" : 38.0816667 + "longitude" : 126.9809063, + "latitude" : 34.683520700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "기룡산은 화북면과 자영면을 경계 짓는 산으로, 일반인에게는 그리 알려지지 않은 관계로 아직은 때 묻지 않은 능선을 따라 호젓하게 산행을 즐길 수 있는 산이다. 정상에서 남쪽으로 3.3킬로미터 떨어진 고깔산과 연계해 능선을 이을 수 있으며 남쪽 아래 영천댐(자양호)의 시원하고 넓은 호수를 굽어보는 맛은 일품이다.북쪽 보현산 천문대를 건너다보며 정상 서릉을 따라 이어지는 아기자기한 암릉을 오르내리는 길은 기룡산의 백미라 할 수 있다. 정상 남쪽 아래에는 신라천년 고찰인 묘각사가 있고 기룡산이란 이름도 이 묘각사를 창건할 당시 동해 용왕이 의상대사에게 설법을 청하고자 말처럼 달려왔다는데서 연유한 이름이라 한다.기룡산 정상 부근은 조망 즐기기에 좋은 암릉으로 되어 있으며 정상에는 무인산불감시카메라와 2000년 해맞이기념비가 있다. 탑전리 너머로 천문대가 자리하고 있는 보현산과 면봉산이 보이며 동쪽으로는 낙동정맥 산줄기를 따라 운주산과 침곡산이 있다. 서쪽으로는 방가산과 봉림산, 화산이 산줄기를 이으며 자리잡고 있다.영천호에서 고깔산을 따라 기룡산까지 이어지는 능선은 마치 승천을 기다리는 잠룡의 모습처럼 그 산세가 웅장하고 정상의 산불감시탑은 용의 뿔처럼 보인다.", - "MNTN_HG_VL" : "875", - "MNTN_LOCPLC_REGION_NM" : "경북 영천시 자양면", - "MNTN_NM" : "기룡산" + "DETAIL_INFO_DTCONT" : "전북 완주군 운주면에 위치한 천등산은 대둔산의 명성에 가려져 있었다. 그러나 천등산은 금남정맥의 주맥인 대둔산(878m)과 함께 도립공원으로 지정되면서 주말이면 대전과 전주에서 산을 찾는 사람들로 붐빈다.능선은 암릉지대가 많고 곳곳에 기암이 산재하며 절벽은 층층을 이루면서 노송과 어우러져 절경이다. 특히 521봉에서 감투봉으로 오르는 등선에는 거북등 같은 모양의 바위가 넓게 깔려 이색적이며 암봉도 빼어나다.빈덕바위 남쪽 절벽 밑에 있는 신망 터에는 동굴 속에 샘과 제단이 설치된 명소가 있는데 식수는 이곳에서 준비하는 것이 좋다. 정상 서편 골짜기에는 돌탑이 많고 무당의 기도 터인 움막과 석굴이 있다. 정상 북쪽 갈림능선에서 북동으로 꼬부라져 내려가는 구간은 암벽지대의 험로이므로 노약자는 서쪽 지능선길을 택하는 게 안전할 것이다.", + "MNTN_HG_VL" : "707", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 운주면", + "MNTN_NM" : "천등산" }, - "longitude" : 129.0124543, - "latitude" : 36.120247200000001 + "longitude" : 127.3088889, + "latitude" : 36.085555599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "271", - "MNTN_LOCPLC_REGION_NM" : "전라북도 전주", - "MNTN_NM" : "기린봉" + "DETAIL_INFO_DTCONT" : "강과 바다 들녘이 어우러진 서남쪽 끝머리에 자리 잡은 해남에는 먼 이북의 아름다운 금강산과 토시 하나 틀리지 않는 똑같은 이름을 가지고 있는 금강산이 자리하고 있다. 기암괴석으로 된 암장과 아열대 수림으로 덮여 있고, 봄이면 춘란이 무리지어 갈잎 속에 꽃대를 올려 개화를 시작한다.lsquo;옥녀탄금rsquo;의 형상이라는 해남읍의 지형에서 가야금을 타는 선녀에 해당하는 금강산은 병풍처럼 해남읍을 두르고 있고 정상에는 금강산성이 성곽을 이루고 있으며 아래로는 은적사, 금강폭포, 미암 등이 자리하고 있다. 해남에 이름 있는 많은 산들의 유명세에 가려서 사람들이 많이 찾는 곳은 아니지만 비교적 산을 오르기 쉬우며 사람의 발길이 닿지 않는 야생의 모습을 그대로 간직하고 있는 산이다. 크고 작은 돌무더기와 암벽들을 산길 곳곳에서 접하게 되고, 인적이 드물어 사람의 흔적이 묻어나지 않은 억새풀 숲과 수목들로 가득 차 있어 조바심을 내지 않고 트레킹 하는 기분으로 천천히 오르기에 알맞은 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "481", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 마산면", + "MNTN_NM" : "금강산" }, - "longitude" : 127.1736111, - "latitude" : 35.809722200000003 + "longitude" : 126.5997222, + "latitude" : 34.591666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "기백산은 1983년 함양군이 군립공원으로 지정했으며, 옛 이름은 지우산(知雨山)이다. 기백산 자락의 거창, 안의 지역은 기백산의 날씨 변화에 따라 비가 내릴 것을 미리 알 수 있었다고 한다. 백두대간인 덕유산 능선이 무룡산, 삿갓봉, 장수 덕유산으로 구비쳐오다 남덕유에서 갈라져 남동 방향으로 꺾어진 뒤 월봉산, 금원산을 일으킨 다음 거창 쪽으로 깊숙이 들어와 솟았다. 산 고스락 남쪽에 원추리와 싸리나무군락으로 이루는 기백평전이 펼쳐져 있으며 지우샘이 솟아 맞은편 황석산과 수망령에서 시작한 물줄기와 합하여 안의 지우천을 이룬다. 지우천이 흐르는 장수동은 옛 안의 삼동 가운데 하나인 심진동으로 지금은 용추사 계곡으로 더 알려져 장수사 조계문, 용추폭포, 용추사들의 명소가 널려있다. 또 기백산 안봉에서 솟기 시작한 물줄기는 고학천 용폭을 이루고 쌀다리와 용원정 명소를 간직하고 있다.", - "MNTN_HG_VL" : "1331", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 위천면·함양군 안의면", - "MNTN_NM" : "기백산" + "DETAIL_INFO_DTCONT" : "한산이라는 명칭은 산 아래에 한씨의 묘가 있어 한산소라 불리는 마을 이름에서 유래된 것으로 추정된다. 출구쪽은 밤나무 단지와 연결되어 있으며 경사가 심하다.", + "MNTN_HG_VL" : "121", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 웅진동", + "MNTN_NM" : "한산" }, - "longitude" : 127.7850818, - "latitude" : 35.709718100000003 + "longitude" : 127.0999884, + "latitude" : 36.452894499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "704", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시", - "MNTN_NM" : "기양산" + "DETAIL_INFO_DTCONT" : "숙종의 태를 묻었던 곳으로, 태봉동이라 하였다. 비석 중 하나는 1661년(현종 2)에 고종의 태(胎)를 처음 이곳에 안치할 때 세운 것이며, 다른 하나는 숙종이 임금에 즉위한 후 9년 후인 1683년에 건립한 것이다. 1869년(고종 2) 태와 태실은 경기도 양주로 옮겨가고 지금은 비석만 남아 있다. 관리가 잘 되어있어 남녀노소 누구나 건강증진에 좋다.", + "MNTN_HG_VL" : "133", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 태봉동", + "MNTN_NM" : "태수산" }, - "longitude" : 128.15472220000001, - "latitude" : 36.295277800000001 + "longitude" : 127.09657319999999, + "latitude" : 36.410788500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정상 아래에 석이바위라는 멋진 조망처가 있는데, 옛날에 기우제를 지내던 장소로 산 이름은 여기에서 유래한다. 주민들은 물비리산 또는 물빌이산이라고 부른다. 기우산성(祈雨山城)과 산자락을 따라 삼국시대 말기에 조성된 것으로 추정되는 14기의 신월리 고분군이 남아 있다. 인근 조양산(朝陽山; 684m)과 연계된 산행코스가 개발되어 있으며, 소요시간은 4시간이다. 산행은 상월리에서 시작하여 우암사와 석이바위를 거쳐 정상에 오른 뒤 719봉과 북동릉 산행을 경유하여 조양산에 오르고 송림지대를 따라 성불사로 내려오는 코스이다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 신월리", - "MNTN_NM" : "기우산" + "DETAIL_INFO_DTCONT" : "월출산은 국내에서 규모가 제일 작은 국립공원으로 천태만상의 기암괴석이 수석 전시장을 연상케한다. 남성적인 웅장함을 갖춘 북쪽의 가파른 돌산과 여성적인 섬세함을 갖춘 완만한 남쪽산이 조화를 이뤄 지리산, 변산, 천관산, 내장산과 함께 호남의 5대 명산으로 꼽히고 있다. 신라시대에는 월나산(月奈山), 고려시대에는 월생산(月生山) 그리고 조선시대부터 월출산이라고 불리어졌다.", + "MNTN_HG_VL" : "811", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 영암읍ㆍ군서면ㆍ학산면, 강진군 성전면", + "MNTN_NM" : "월출산" }, - "longitude" : 128.6730556, - "latitude" : 37.3561111 + "longitude" : 126.7104573, + "latitude" : 34.774338800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 포천군 일동면과 가평군 하면에 경계를 이루는 갈매봉은 갈매고개를 사이에 두고 청계산(849)과 마주 보고 있는 산이다. 시원한 계곡과 울창한 수림으로 휴식처가 많아 여름철 피서 산행지로 안성맞춤이다.주능선은 바위로 되어 있어 아기자기한 암릉산행에 묘미를 느낄 수 있으며, 아찔한 바위능선을 지나는 스릴도 만끽 할 수 있다.산행기점에는 청계 저수지가 자리하고 있어서 등산과 낚시를 함께 즐길 수 있는 가족 산행지로 적합하다. 갈매재를 기준으로 동쪽(하판리 방향)은 군 사격장으로 출입이 통제되는 지역임으로 주의를 해야 한다.길매봉은 청계산(849m)과 운악산 사이에 위치한 산으로 주능선과 지능선 상에 암릉지대가 많고 주능선 북사면 하단부 높이 10m, 중단부 10m, 상단부 20m나 되는 복계폭포가 있다.길매재, 바위능선을 거쳐 정상에 이른다. 정상 조망은 시원하다. 우선 청계산 방면으로는 청계산 뒤로 국망봉으로부터 흘러오는 한북정맥이 넘실거린다. 청계산 오른쪽으로는 명지산이 하늘금을 이루고, 명지산에서 시계바늘 방향으로는 아재비고개, 월출산, 전패봉, 매봉 등이 한줄로 이어져 시야에 들어온다.남으로는 하판리를 가래질한 듯 패어져 나간 조종천 계곡과 그 오른쪽으로 운악산이 피라밋처럼 우뚝 솟아 있다.북서쪽 아래로는 청계저수지로 패어져 내린 계곡이 한눈에 내려다보인다.", - "MNTN_HG_VL" : "735", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", - "MNTN_NM" : "길매봉" + "DETAIL_INFO_DTCONT" : "금물산은 경기도 양평군과 강원도 횡성군의 경계를 이루고 있다. 예전에 도둑이 많이 나타나서 붙여진 도둑고개에서 동쪽 횡성 방향으로 내려가면 왼쪽에 나타나는 산이다.산은 그다지 높지 않으나 주능선 길이가 10km를 넘어 계곡이 길고 깊다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑아 가재와 식용 개구리가 많다.금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서북으로 뻗어나가고 있다.\"성지봉\"이라는 이름은 옛날 임금의 행차가 쉬어갔다고 하여 붙여진 이름이라 하며, 이곳은 여름에는 길섶의 풀이 웃자라 긴팔, 긴바지가 아니면 통과하기 힘들다.성지봉에서 정상까지는 봉우리가 두 개 있어 길이 오르락 내리락 한다.정상은 일부 바위도 있으며, 특히 양평 쪽으로 뻗은 서봉과의 사이에 자리하고 있는 계곡 쪽으로는 절벽을 이루고 있다.조망도 좋아 동쪽으로는 가리산이 보이고, 북쪽으로는 넓은 시동리와 유치리 일대의 분지가 보인다. 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼 만하다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군, 강원도 횡성군", + "MNTN_NM" : "금물산" }, - "longitude" : 127.4158333, - "latitude" : 37.856666699999998 + "longitude" : 127.8491667, + "latitude" : 37.553611099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전라남도 신안군 흑산면 홍도리에 위치하고 있는 홍도는 대흑산 본섬의 부속 도서로서 다도해 해상 국립공원으로 매가도라고도 한다. 홍도는 본 섬을 비롯한 20여 개의 부속 섬이 절정을 이루어 남해의 소금강으로 불린다. 그 중에서 녹섬의 해돋이는 가히 장관이 아닐 수 없다. 파도와 바닷물이 출렁거리는 가운데 2개의 바위 사이로 해가 떠오른 광경은 말로 표현할 수 없을 정도로 아름답다. 여기에 덧붙여 홍도의 낙조 또한 놓칠 수 없는 비경이다.어미섬의 주봉인 깃대봉(해발 367m)과 남쪽의 깃대봉 주변에는 아름드리 동백나무 숲, 후박나무, 식나무 등 휘귀식물 5백여종이 있으며 2백여 종의 동물과 곤충이 함께 서식하고 있다.깃대봉 산행은 가파르기 그지 없고 철쭉,동백등 이름모를 나무들이 온통 빽빽이 자라고, 주봉에 닿으면 뾰족한 모양이 마치 바늘같다.남서로 양상봉의 연봉이 한 폭의 동양화를 펼쳐 놓은 듯하고 동쪽으로는 설풍서전의 울창한 숲이 장관이다.", - "MNTN_HG_VL" : "382", - "MNTN_LOCPLC_REGION_NM" : "전라남도 신안 흑산면 홍도", - "MNTN_NM" : "깃대봉" + "DETAIL_INFO_DTCONT" : "구봉산은 남,여 등산객들의 발길이 끊이지 않아 사방에서 등산할 수 있도록 등산로가 잘 정비되어 있으며, 정상에서는 시내를 한눈에 바라볼 수 있고,특히 여수항과, 오동도, 돌산대교를 먼저 볼 수 있다. 국동, 봉산동에서 오르는 길중턱 한산사 아래의 약수는 질이 좋아 여수시민들이 많이이용하며 체육시설도 잘 가꾸어져 있다. 한산사는 여수 8경중 3경으로 한산사에서 내려다 보면여수앞바다의 전경이 매우 아름답다.구봉산은 밑에 서당이 있었다 하여 서당산 이라고도 하며, 하홉마리 봉황이살다가 이 곳에서 승천했다는 전설에 따라 산 이름이 붙여다고 하는데, 정상에거암이 솟은 잔구가 있어 산악의 미가 돋보인다.", + "MNTN_HG_VL" : "388", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "구봉산" }, - "longitude" : 125.201944, - "latitude" : 34.695 + "longitude" : 127.70833330000001, + "latitude" : 34.737777800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "깃대봉은 경기도 가평군 하면과 가평읍의 경계를 이루고 있다. 가평군 내에는 깃대봉이 두곳에 있는데, 또 다른 깃대봉은 청평리 북쪽에 솟아 있는 해발 624m인 산으로 대성리 뒷산인 은두봉(銀頭峰.678m)과 같은 능선으로 이어져 있다.깃대봉은 가평의 명지산에서 남쪽으로 가지를 친 능선상의 매봉(929m)과 약수봉(850m) 사이에 솟은 산이다. 정상에 서면 매봉, 명지산, 칼봉산, 화악산, 구나무산, 불기산, 대금산, 축령산, 서리산, 주금산 등이 시원하게 펼쳐저 보인다.산행 들머리는 대금산과 같은 두밀리에서 시작하고 깃대봉 정상에 오르면 10여평의 공터를 만날 수 있다. 북으로는 매봉과 칼봉산 넘어 전패봉, 명지산, 화악산 등이 펼쳐져 있고, 가평읍 넘어 멀리 삼악산이 보이며, 남으로는 대금산이 손에 잡힐 듯 가깝게 보인다. 서남쪽으로 축령산과 주금산이, 서북쪽으로는 운악산이 한눈에 들어온다.", - "MNTN_HG_VL" : "835", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 가평읍", - "MNTN_NM" : "깃대봉" - }, - "longitude" : 127.41861110000001, - "latitude" : 37.841388899999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "가평에 깃대봉이 2개 있다. 청평휴게소 뒷산인 깃대봉(644m)과 대금산 뒤의 가평군 두밀리의 깃대봉(910m)이다. 청평휴게소 뒷산인 깃대봉(644m)봉은 북한강을 한눈에 볼 수 있는 조망을 갖춘 산으로 청평역에 인근하고 있다.두 산 모두 경춘선으로 다녀올 수 있는데, 가평읍 경계의 깃대봉은 가평역에서 산행 들목까지 버스나 택시로 이동해야 하지만, 청평 깃대봉은 청평역에서 곧바로 산행을 시작할 수 있다. 또한 두 산은 이름은 같지만 족보가 차이가 난다. 물론 근원은 한북정맥이지만 가평 깃대봉은 명지산(1,267m)에 뿌리를 두었고, 청평 깃대봉은 축령산(879m)에 두고 있다.이웃에 대금산, 불기산, 청우산이 있어 깃대봉 정상에 서면 능선이 한눈에 들어오고 시간이 날 경우 완전히 하산하여 다시 조종천을 끼고 이웃한 산들을 접할 수도 있다. 깃대봉은 청평 휴게소와 대갈교에서 오르는 길이 있으나, 대갈교쪽 교통이 편리하다.", - "MNTN_HG_VL" : "520", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍 상면", - "MNTN_NM" : "깃대봉" - }, - "longitude" : 127.39388889999999, - "latitude" : 37.744444399999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "까치산은 경상북도 청도군 운문면 방음리 말음 마을에 있다.말음 마울의 말음의 뜻은 계곡의 경관이 빼어나고 산중유곡이라 하여, 옛날에 신선과 선녀들이 모여 놀던 곳으로, 선녀들이 노닐 때마다 부르는 노래 소리가 언제나 끝 후렴만 들려오고 주된 부분은 들리지 않아 끝소리를 다서 말음이라 한 것이 마을 이름으로 되었다.산행들머리는 방음리에 내려 포장길안으로 100m 쯤 마을로 들어서면 ‘원두막’이라는 간판이 보이고 그 위에 2채의 빨간 벽돌집이 보인다.", - "MNTN_HG_VL" : "571", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 운문면 방음리", - "MNTN_NM" : "까치산" - }, - "longitude" : 128.94111179999999, - "latitude" : 35.702323399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "꾀꼬리봉은 충북 제천시 덕산면 억수리 깊은 협곡인 용하구곡 청벽대 남쪽에 위치한 산으로, 월악산 국립공원권에 속한다. 비경지대인 청벽대에서 남쪽 직선거리로 약 2km 지점에 수석처럼 솟아 있는 꾀꼬리봉은 예로부터 다른 산에 비해 꾀꼬리가 많이 살았기 때문에 붙여진 이름이라고 한다. 기암과 노송이 어울려져있고,용하구곡 물줄기도 시원스럽게 보인다. 용하구곡으로 내려서면 선녀가 목욕을 즐겼다는 선미대가 보이고 용하구곡 물줄기를 따라 30 분가량 걸으면 청벽대가 반긴다.용하구곡 물줄기는 잠시 속세와 적을 끊은 무릉도원을 연상케한다.정상에서의 조망은 북쪽에서부터 하설산,문수봉,대미산이 용하초등교를 감싸고 있고 남쪽에서 서쪽으로는 백두대간이 보이고,서북쪽으로는 메밀봉과 월악산이 첩첩산중을 이룬다.꾀꼬리봉 산행의 백미는 하산길에 있다. 전망대바위?암벽지대? 일주암을 거쳐 용하구곡으로 내려오는 코스는 급경사 암벽지대가 많아 초심자에게는 다소 부담스럽지만 보조자일이 설치돼 있어 큰 어려움은 없다.", - "MNTN_HG_VL" : "890", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면 월악리", - "MNTN_NM" : "꾀꼬리봉" - }, - "longitude" : 127.86333329999999, - "latitude" : 37.100833299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "낙동강 1300리 중에서 유일하게 낙동이라는 지명을 가진 상주시 낙동면 낙동리에 낙동강과 어우러져 솟아있는 산이 나각산(螺角山)이다. 산체가 둥글어 소라 형국이고 정상 능선에는 뿔 모양을 하고 있다. 하나는 둥글어 원봉이고 또 하나는 첨봉인데 두 개가 쌍립하여 기묘하다. 부의 상징인 노적봉과 귀를 보장하는 필봉을 겸한 셈이다.산세가 부드럽고 완만하여 가족 동반 산행을 하기에 좋은 산으로 소나무가 많이 우거져 있어 삼림욕을 하기에도 적당한 곳이다.특이한 것은 이 산은 원래 강으로서, 융기되어 만들어졌다는 것을 바위에 박혀 있는 강돌과 등산로 주변에 흩어져 있는 둥근돌 등을 보면 금방 알 수가 있고 정상 주변의 바위에는 군락을 이루고 있는 부처손들이 특징이다.산행시간이 짧기 때문에 비봉산과 연계해 산행하는 것이 좋으며 산행 후 낙단교 휴양단지에서 낙동강을 감상하며 휴식을 취하는 것도 좋다.", - "MNTN_HG_VL" : "240", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 낙동면 물량리", - "MNTN_NM" : "나각산" - }, - "longitude" : 128.30134760000001, - "latitude" : 36.382563500000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "544", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", - "MNTN_NM" : "나래산" - }, - "longitude" : 127.1250915, - "latitude" : 35.612496 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "662", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 광하리", - "MNTN_NM" : "나팔봉" - }, - "longitude" : 128.60795680000001, - "latitude" : 37.346452900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "낙가산의 산명은 신라 선덕여왕 4년 금강산 보덕암에서 수도하던 회정스님이 이곳 봉황이 날아와 집을 짓는 형국의 명당에 자리잡고 절을 세울 때, 관세음보살이 계신다는 인도 남해의 보타 낙가산의 이름을 따라 뒷산을 낙가산이라 불리게 되었다고 하며, 해명산, 상봉산보다 낮으나 주변 경관이 좋다.강화도의 끝, 외포리 항구에서 배를 타고 들어가다 보면 누에고치처럼 나지막히 자리잡은 석모도(席毛島)라는 섬이 있다. 이곳에는 300m 남짓한 산들이 섬 가운데에 길게 누워있는데 그 많은 봉우리안에 낙가산이 자리잡고 있다. 석모도의 주봉은 해명산이지만, 낙가산과 줄기를 같이하는 해명산(327m)과 상봉산(316m)에 비해 더 잘 알려진 까닭은 유명 사찰인 보문사가 있기 때문이다.산은 야트막하고 작지만 맵시 있고 적당한 다리품을 팔기에 그만이다. 보문사는 절 위에 모신 눈썹바위의 불상이 영험하다고 하여 불자들의 발길이 끊이지 않는데 눈썹바위에서 내려다보는 서해의 절경이 장관이다. 점점이 흩어져 있는 자그마한 암초들과 무인도는 절로 경탄을 자아낸다. 이 광경은 일찍이 강화 8경으로 알려졌을 정도로 뛰어나다.", - "MNTN_HG_VL" : "267", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", - "MNTN_NM" : "낙가산" - }, - "longitude" : 126.3276408, - "latitude" : 37.691369100000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "낙영산은 속리산(1,058)을 조산(祖山)으로 백악산(858)과 도명산(642)사이에 기암절벽을 이룬 산이다. 남과 북으로 용대천과 화양구곡을 안고 있으며 암골미(岩骨美)가 뛰어나 괴산의 명산으로 불리고 있다.낙영산은 속리산국립공원권에 속한 산답게 산자락 곳곳에 두꺼비바위,코끼리바위등 기암을 가지고 있으며, 암릉이 산재해 있어 아기자기한 암릉산행 묘미와 시원스런 조망을 동시에 즐길 수 있는 곳이다. 또 이 산자락에 위치한 공림사(公林寺)도 볼 만 하다. 공림사는 법주사의 말사로 신라 경문왕(861-874)때 자정선사가 창건한 천년 고찰이다.정상에 서면 백두대간 주능선에 장쾌한 모습과 속리산 연봉들에 아름다운 모습을 볼 수 있고 산행 후에는 용대천과 화양구곡에서 깨끗한 자연을 만끽 할 수 있다. 하지만 암벽지대가 많아 다소 위험한 곳이 있으므로 주의해야 한다.", - "MNTN_HG_VL" : "746", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", - "MNTN_NM" : "낙영산" - }, - "longitude" : 127.81869210000001, - "latitude" : 36.640329199999996 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "임란이 일어나 왜군이 이곳까지 들어오자 가곡마을에 살던 밀양 박씨의 부녀자인 여흥 민씨(박희량의 처)는 다른 부녀자와 함께 이 산 바위굴에 피난했다. 그러나 왜군에게 발각되어 화를 면할 수 없게 되자 이 사 바위 절벽에서 몸을 던져 스스로 목숨을 끊었다. 임란이 평정되자 민씨의 정절을 표창하였고, 그 이후 그 절벽은 민씨가 꽃처럼 깨끗하게 떨어져 죽은 바위라 하여 낙화암이라고 부르고, 또 산의 형세가 꽃이 지는 것 같다 하여 낙화산이라 했다. 낙화산 정상에는 표지가 없으나 이리저리 산악회에서 달아놓은 리본들로 어지럽다.밀양시 산외면 소재 낙화산(落花山)은 정상으로 가는 도중 봉우리가 열댓개 되는 산으로 이 봉우리들을 그다지 힘들지 않게 넘을 수 있어 그 재미가 상당하다. 따라서 많은 산행인들이 이 산을 밟으려고 생각을 하고 있으나 코스를 어떻게 잡아야 할지 몰라 섣불리 발을 내딛지 못하는 형편이다.", - "MNTN_HG_VL" : "597", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 도곡리", - "MNTN_NM" : "낙화산" - }, - "longitude" : 128.8251827, - "latitude" : 35.544978800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "치악산 국립공원의 최고봉인 비로봉(1,288m)에서 남쪽 치악재 방향으로 뻗어 내린 능선 상에 우뚝 솟은 남대봉은 강원도 원주시 판부면과 신림면의 경계를 이루는 산이다.남대봉에서는 상원사, 영원사 등 치악산의 이름난 절 3개곳중 둘이 보이고 절이 있는 상원골과 영원골등 2개의 긴 계곡도 보인다. 둘다 구룡사가 있는구룡계곡에 못지 않는 계곡이다. 또한 4계절마다 그 모습을 달리하며 호젓한 등산로 때문에 많은 산악인과 관광객의 발길이 끊이지 않고 있다.정상 동남쪽 아래에 있는 상원사 대웅전 앞에는 꿩과 구렁이의 보은의 전설을 간직한 삼층석탑 2기가 눈길을 끈다. 정상에 서면 북쪽으로 고둔치와 치악산맥의 연릉과 치악산 정상인 비로봉이 아스라히 보인다.", - "MNTN_HG_VL" : "1182", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 판부면, 신림면", - "MNTN_NM" : "남대봉" - }, - "longitude" : 128.0519444, - "latitude" : 37.308333300000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간상에 있는 남덕유산은 거창군, 함양군 장수군의 경계선에 솟아 있다.덕유산 산행하면 으레 향적봉을 목표로 하는 것이 일반적이다. 그래서 거의 모든 등산로가 향적봉을 향해 뚫려 있으나 등산인들이 별로 찾지 않는 남덕유도 향적봉에 견줄만한 산세를 지닌 산이다.남덕유산 정상에는 맑은 참샘이 있어 겨울에는 김이 무럭무럭 나는 온수이고, 여름에는 손을 담글 수 없는 찬물이 솟아 오르는데 천지 자연의 신비한 이치는 사람으로서 말하기 어렵고 그저 그렇게 되려니하고 인정하기란 너무 오묘한 자연의 신비감이 있다.남덕유산은 3대강의 발원샘을 갖고 있다는 것이 특징이다. 임진왜란 당시 나라를 구하기 위해 왜구들과 싸웠던 덕유산 의병들이 넘나들었던 육십령은 금강(錦江)의 발원샘이며 정상 남쪽 기슭 참샘은 거룩한 논개의 충정을 담고 있는 진주 남강(南江)의 첫물길이 되며 북쪽 바른 골과 삿갓골샘은 낙동강(洛東江)의 지류 황강(黃江)의 첫물길이다.삿갈골샘에는 대피소가 있어 백두대간을 종주하는 산악인의 쉼터로 인기 있고, 동서 사면은 가을 단풍이 특히 좋다. 그리고 적설량이 많아 설경 또한 뛰어난 산이다.", - "MNTN_HG_VL" : "1507", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "남덕유산" - }, - "longitude" : 127.67942360000001, - "latitude" : 35.768681399999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "해발 164미터의 남망산은 접도의 주산(主山)으로 산 자uuml;가 접도라 해도 과언이 아니다. 접도는 진도군 동남쪽에 위치한 아주 작은 섬으로 예부터 접섬, 금갑도, 갑도, 접배도 등으로 불리던 유배지였다. 지금은 진도와 접도를 잇는 연육교가 있어 접근이 수월하다. 남망산(南望山)은 산을 이루는 기암들이 모두 남쪽바다를 바라보고 있어서 붙은 이름이다. 높이는 낮지만 ª게는 1시간, 길게는 총 12킬로미터의 5시간yen;리 코스 등 다양하게 등산로가 조성되어 일정에 맞는 산행코스를 선택할 수 있는 것이 장점이다. 또 이정표 설치 및 등산로 정비가 잘 되어있어 길atilde;기의 어려움이 없으며 흙길도 걷고 바닷길도 걷는 이색산행을 즐길 수 있다. 솔섬에서 작은여미로 이어지는 길에는 몽돌해변에 맨발uuml;험 등산로가 조성되어 있으며 쥐바위에서 거북바위 구간에는 웰빙등산로가 만들어져 가족 산행지로도 제격이다. 가뭄에는 전 구간에 물이 없으므로 사전에 식수를 준비해야 한다.", - "MNTN_HG_VL" : "164", - "MNTN_LOCPLC_REGION_NM" : "전남 진도군 의신면", - "MNTN_NM" : "남망산" - }, - "longitude" : 126.29203390000001, - "latitude" : 34.381267399999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "남병산은 강원도 평창군 대화면과 방림면, 평창읍의 경계를 이루는 산이다. 남병산은 북쪽 멀리 오대산에서 서쪽 계방산으로 이어지는 능선에 솟아 있는 산이다.첩첩 산중인 평창의 가리왕산(1,560m)과 이웃하고 있다. 주변에 유명한 오대산, 계방산, 발왕산 등 높고 큰 산이 많아 국도변에 위치하여 있으면서도 지나쳐 버리는 산으로 취급되어 왔으나 인적이 드문 관계로 해묵은 수목이 군락을 이루어 볼만하다.육산 남병산에는 그러나 평창강가로 지긋이 다가서 있어서 정상능선에서 평창강을 내려다 보는 각별한 맛이 있다. 또한 20여평의 공터로 사방이 확 트여 전망이 좋은 편이다. 북동쪽으로는 중왕산과 가리왕산이, 동으로는 청옥산이, 남으로는 장암산과 삼방산이, 서쪽으로는 백덕산, 중대갈봉과 장미산, 절구봉이 스카이라인을 이룬다. 평창강은 우리나라의 대표적인 사행하천(구비가 많은)으로 계방산에서 발원하여 장평에서 흥정산, 태기산에서 발원한 흥정천을 합치고 금당계곡을 흘러내려와 방림에서 백덕산에서 흘러내려온 계촌천을 합쳐 평창을 지나고 주천을 거쳐 영월에서 동강과 합류, 남한강이 되어 흘러내려간다.", - "MNTN_HG_VL" : "1150", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", - "MNTN_NM" : "남병산" - }, - "longitude" : 128.45249999999999, - "latitude" : 37.427499999999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경주 남산은 곧 신라라해도 과언이 아니다. 그만큼 신라 건국에서부터 멸망에 이르는 동안의 수많은 유적과 신라를 지탱해 온 불교유적의 보고이다.신라의 건국설화에 나오는 나정(羅井)에서부터 종말기의 포석정이 남산 기슭에 자리잡았다. 그 사이의 시간 간격이 900년이다.", - "MNTN_HG_VL" : "495", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 남산동ㆍ내남면", - "MNTN_NM" : "남산" - }, - "longitude" : 129.22555600000001, - "latitude" : 35.768056000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "남산은 충주시 직동과 살미면의 경계선상에 자리하고 있는 산으로 일명 금봉산이라고도 한다. 예전에 봉황이 살았던 상서로운 산이라고 한다.마즈막재를 사이에 두고 북쪽에 위치한 계명산과 마치 형제처럼 마주하고 있으며 이 산 남쪽 기슭에는 신라 시대 때 창건하였다는 창룡사를 비롯하여 시내 쪽 기슭에는 각종 체육시설 및 약수터가 있어 충주 시민의 발길이 끊이지 않는 산이다. 또한 이 산 정상에는 삼국 시대에 축성된 것으로 보여지는 산성이 자리잡고 있는데 이 성이 충주산성이다. 이 산성은 삼한시대 마고선녀가 축성했다는 전설을 간직하고 있어 마고성이라고도 알려져 있다.이 산 남쪽 기슭에는 약 1300년 전 신라 원효대사가 창건하였다는 창룡사가 있고 이곳 북방 3km 지점의 탑대라는 곳에는 3층석탑이 지금도 있을 뿐 아니라 부근의 지명이 윗절골, 아래절골 등으로 불리어 지는 것으로 보아 창룡사를 중심으로 한 직동일대가 대사찰지였던 것으로 보인다.", - "MNTN_HG_VL" : "636", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 직동, 살미면", - "MNTN_NM" : "남산" - }, - "longitude" : 127.9743071, - "latitude" : 36.954960700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "냉산은 구미 해평면, 도개면, 군위군 소보면의 경계에 위치하고 있는 아담한 산으로 잘 알려지지 않은 산이다.낙동강 동쪽에 위치하며, 팔공산맥(八公山脈)에 속한다. 일명 `태조봉(太祖峰)'이라고도 한다. 고려 태조가 견훤을 정벌하기 위해 축성한 숭신산성이 있고, 산 초입에 신라에 불교를 처음 전한 아도화상이 창건한 것으로 전해진 도리사가 유명하다.도리사는 신라에 최초로 불교를 전한 아도화상(阿道和尙)이 세웠다고 전해지며, 경내에 있는 극락전(極樂殿)과 5층석탑(五層石塔)은 보물로 지정되어 있다.", - "MNTN_HG_VL" : "693", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면, 도개리", - "MNTN_NM" : "냉산" - }, - "longitude" : 128.4007306, - "latitude" : 36.258746899999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "429", - "MNTN_LOCPLC_REGION_NM" : "경기도 양주시,고양시", - "MNTN_NM" : "노고산" - }, - "longitude" : 126.94474719999999, - "latitude" : 37.6841309 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "노성산은 논산8경 중 제8경인 노성산성이 있는 산이다. 이 산성은 백제시대에 축성된 것으로 자연적인 지세를 교묘하게 이용하여 둘레 약 1킬로미터를 석축으로 거의 완벽하게 쌓은 성지이다. 동면, 북면, 서면을 활석을 다듬어 네모지게 하여 쌓았고, 봉우리 정상에는 장대지로 추정되는 곳과 동벽으로 약간 내려온 곳에 봉수대로 보이는 곳이 남아있다. 성내에는 우물지가 4개소 있고, 건물지로 보이는 여러 개의 유지가 있으며 백제시대의 기와편과 토기편 그리고 고려, 조선시대에 이르기까지 다양한 유물들이 산재해 있다.동쪽으로 계룡산이 막아서고 남쪽으로는 논산평야가 바라다 보이며 북쪽으로는 공주, 서쪽으로는 부여 방면이 한눈에 조망되는 요지로, 연산 황산성과 함께 백제와 신라가 대치했던 방어선에 위치한 산성이다. 그 중요성 때문에 노성산성은 삼국시대부터 조선시대에 이르기까지 계속해서 사용했던 것으로 전해진다.노성산에는 논산시민들이 해맞이를 즐기는 넓은 공터가 있다. 이곳에 오르면 우리나라 3대 곡창지대 중 하나인 논산평야가 황금빛으로 물들어 풍요롭게 보인다. 더 멀리 기운찬 계룡산의 향적봉, 국사봉, 천황봉, 그리고 관음봉으로 이어지는 마루금이 인상적이다.", - "MNTN_HG_VL" : "349", - "MNTN_LOCPLC_REGION_NM" : "충남 논산시 노성면", - "MNTN_NM" : "노성산" - }, - "longitude" : 127.12361110000001, - "latitude" : 36.2955556 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "이 산은 백제, 신라, 고구려가 각축을 벌이던 토성으로 옛 문헌에는\"노성산은 음죽현의 주산이며 영산이다.\"라 하고 전설에 의하면 노성산, 마국산, 설성산 사이에 용맹한 말 한 마리가 나타나니 세산에 주둔한 장수가 서로 차지하려다 다툼을 벌였는데 이기는 순서대로 말 머리, 몸통, 꼬리를 차지하기로 했다고 한다. 노성산 장수가 말머리를 몸통은 마국산 장수가 설성산 장수가 꼬리를 차지하여 노성산 정상바위를 말머리 바위라 하며 산의 높이는 310m로 낮으나 산 정상에서 보면 충북 감곡, 안성, 일죽, 여주, 양평까지 보인다.", - "MNTN_HG_VL" : "310", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 설성면", - "MNTN_NM" : "노성산" - }, - "longitude" : 127.5040697, - "latitude" : 37.127014500000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "오대산국립공원권에 속해 있는 노인봉은, 강원도 강릉시와 평창군의 경계를 이루고 있는 산으로, 유명한 소금강계곡을 산자락에 거느리고 있다. 금강산의 축소판이라 일컫는 '소금강'이라는 이름은 율곡선생이 청학동을 탐방하고 쓴 〈청학산기〉에서 유래되었으며 무릉계옆 바위에 아직 '소금강'이라는 글씨가 남아 있다.산의 정상에는 기묘하게 생긴 화강암 봉우리가 우뚝 솟아 있으며, 그 모습을 멀리서 바라보면 백발노인과 같이 보인다 하여 노인봉이라 붙여졌다 한다.정상에서 소금강계곡으로 내려서면 낙영폭포가 나타난다. 낙영폭포에서 무릉계까지 7km 가량 이어지는 소금강계곡은 30여개의 다리를 건너야 하는 아기자기한 산행길이다. 낙영폭포를 지나면,광폭포,삼폭포,백운대를 지나 만물상으로 이어진다.", - "MNTN_HG_VL" : "1338", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", - "MNTN_NM" : "노인봉" - }, - "longitude" : 128.6394444, - "latitude" : 37.782499999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평", - "MNTN_NM" : "노적봉" - }, - "longitude" : 127.4788889, - "latitude" : 37.880833299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;아홉 굽이 절경 펼쳐지는 가평의 명산gt;노적봉은 한북정맥 강씨봉과 청계산 사이에서 흘러나온 명지지맥이 연인산에서 동쪽으로 흐르면서 가평군 가평읍과 북면을 가르는 능선 상에 있다. 노적봉은 육산으로 험로가 없고 전 구간 나무 그늘이 잘 되어 있으며, 여름 장마철을 제외한다면 사계절 산행지로 좋다. 구나무가 많이 자라고 있어 구나무산으로도 불린다. 구나무란 너도밤나무과 참나무속 굴참나무의 방언으로 수피에 콜크가 많은 낙엽 교목이다. 노적봉 남쪽은 여름철 피서지로 유명한 가평 제3경 용추구곡이고 북쪽은 백둔계곡이다. 등산기점 또한 용추구곡이 있는 승안리나, 백둔계곡이 있는 백둔리를 선택한다. 원점회기 산행의 경우 들머리를 백둔계곡보다 용추구곡으로 잡는 것이 좋다. 산행거리도 적당하고 용추구곡을 빠트릴 수 없기 때문이다. 산행 코스를 길게 잡고 싶다면 노적봉-연인산 연결 종주산행을 하면 된다. 하산은 둘레길, 능선, 계곡을 다양하게 선택할 수 있다. 이 일대는 2005년 도립공원으로 지정되면서 변화의 바람이 불고 있다. 최근 가평군에서 옛 임도를 이용한 걷기산행 코스와 MTB코스를 개발, 각광받고 있다.", - "MNTN_HG_VL" : "859", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", - "MNTN_NM" : "노적봉 (구나무산)" - }, - "longitude" : 127.4788889, - "latitude" : 37.880833299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "859", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 북면", - "MNTN_NM" : "노적봉(구나무산)" - }, - "longitude" : 127.4788889, - "latitude" : 37.880833299999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "제왕산의 모산으로 오르기가 다소 힘드나 찾는이가 적어 자연이 그대로 보존된 산이다. 백두대간이 동해를 끼고 설악산(1708)과 오대산(1563), 황병산(1407)을 일으키고, 대관령에서 몸을 낮췄다가 다시 솟아오른 산이 능경봉이다. 겨울철에는 무릎이 빠질 정도로 눈이 많이 쌓이는 곳이나, 비교적 힘들이지 않고 눈덮힌 겨울산을 즐길 수 있는 곳이다.능경봉 산행 들머리는 해발 850m가 넘는 대관령 고개마루인 대관령 남쪽휴게소에서 시작된다. 대관령에는 고갯길을 내고 두 번씩이나 죽음을 당한 고형산(高荊山)이라는 사람 얘기가 유명하다. 본래 대관령 고갯길은 오솔길이었으나, 이 고갯길을 조선시대 중종때 고형산이라는 사람이 사재를 털어 수개월 간에 걸쳐 우마차가 다닐수 있도록 넓혀 놓았다. 따라서 강릉과 한양간의 교통이 편리해졌다.", - "MNTN_HG_VL" : "1123", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", - "MNTN_NM" : "능경봉" - }, - "longitude" : 128.7647929, - "latitude" : 37.672805199999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "능곡산은 백화산 줄기가 구랑리에 와서 맺힌 산으로서 마성면 정리 솥골에서 상내리로 넘어가는 나리재에서 능선을 타고 백화산 반대 방향으로 올라가면 되고, 아니면 마성면 상내리에서 오르는 길이 있고 정상에는 삼각점이 있다.능곡산(571.6m)은 마성면 정리에 위치해 있으며 상내리와 접해 있다. 능곡산을 오르기 위해 찾는 산행객은 드물다. 백화산에서 남으로 뻗어온 산줄기로 인접해 전국에서 워낙 이름난 백두대간상의 명산인 백화산이 버티고 있기 때문이다.백화산에서 여러 방향으로 뻗어나간 한 줄기에 자리잡고 있고 해발도 그리 높지도 못하다.정상은 잡목이 있어서 조망이 되질 않고 정상 전 헬기장에서 백화산과 이만봉쪽으로 펼쳐진 풍경이 들어온다. 동으로 정리와 주지봉 방향은 나뭇가지 사이로 보일뿐 역시 잡목 때문에 조망이 희미하다.정리쪽에서 보는 능곡산은 산세가 아주 순하게 생겼지만, 상내리 질마재골 쪽에서 보면 하늘로 봉이 치솟아 경사도가 심한 삼각형 모양을 하고 있어 위협적으로 느껴진다.", - "MNTN_HG_VL" : "572", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면 상내리", - "MNTN_NM" : "능곡산" - }, - "longitude" : 128.08266570000001, - "latitude" : 36.679440399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "능동산은 영남알프스의 산군 중에 하나이며 가지산과 천황산, 재약산의 유명세에 가려 그 이름이 묻혀 버렸다. 석남재에서 천황산에 뻗은 산줄기의 중간지점에 우뚝 솟아 있는 산이며, 언양에서 얼음골로 넘어가는 도로가 개통되기 전에는 주변의 산세속에서 아주 깊이 뭍혀 있었던 산이였다.그러나 언양과 밀양을 잇는 도로가 개통되면서 지금은 석남터널에서 가까이 보이고, 또 천황산에 가는 길목의 능선에 위치하고 있어서 많은 등산객들이 지나는 산이다. 특히 이 산에서 천황산과 배내봉 방향의 능선이 갈라지고 있으므로 영남알프스 종주길에 반드시 거치게 되는 지점에 위치하고 있다.능동산 산행은 석남사 주차장 안쪽에서 시작된다. 포근한 산길에 경쾌한 걸음으로 40여 분 후 전망대에 오르는데 여기서 영남 알프스 1000m 고지들이 시야에 전개되고 시원한 바람까지 불어온다. 능동산은 영남 알프스 중앙에 위치해있기 때문에 정상에 오르면 전망을 두루두루 관망할 수 있다. 정상에는 돌무더기를 쌓아 두었는데 아마도 등산객들이 소원성취와 안전을 기원하면서 돌을 하나 둘 올리다보니 돌무더기로 변한 듯 싶다. 하산은 반대쪽으로 하면 된다.", - "MNTN_HG_VL" : "983", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "능동산" - }, - "longitude" : 129.01635809999999, - "latitude" : 35.584783199999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "468", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "능천산" - }, - "longitude" : 128.70815569999999, - "latitude" : 35.908877799999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "다락산은 발왕산(1458m)의 산줄기가 남으로 뻗어 내리다 자개천과 송천에 이르러 더 나아가지 못하고 동서로 길게 누우며 솟아오른 형상이다.발왕산에서 뻗어내린 능선상의 마지막 봉우리이다. 송천을 사이에 두고 노추산을 마주 보고 있다. 산 남쪽의 구절리는 오지마을로 남아 있다가 1960년 대 산업철도 구절선이 생기면서 탄광촌으로 흥청거리기도 했으나 광맥이 끊기고 몰려들었던 사람도 다 떠난 지금은 다시 고즈넉한 옛 모습이다.등산로마다 숲이 우거졌고 야생란을 위시한 자생식물이 남아있으며, 자개천의 푸른 물빛이 오염되지 않은 비경을 이루는 깨끗한 산이다. 원시의 냄새를 풍기는 다락산의 초본류는 그 무성하고 수수한 모양새로 그런 것을 좋아하게 마련인 등산객을 유혹한다. 산 꽃 촬영에 적당한 산이다.", - "MNTN_HG_VL" : "1018", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선 북면", - "MNTN_NM" : "다락산" - }, - "longitude" : 128.7613806, - "latitude" : 37.5412933 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "201", - "MNTN_LOCPLC_REGION_NM" : "경상북도 합천군", - "MNTN_NM" : "단봉산" - }, - "longitude" : 128.2624572, - "latitude" : 35.567715799999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "문경시는 백두대간을 병풍처럼 두른 후에 남쪽방향으로 길게 뻗은 여러 개의 산줄기를 두고 평야지대와 산 구릉지대가 조화롭게 이룬 사람 살기 좋은 고장이다. 특히 지하자원이 풍부하여 조선시대 철의 생산지로 기록되어 있으며 일제시대와 현재까지 석탄 생산지로 유명하였다. 탄전지대는 단산을 중심으로 발전하였는데 운달산과 단산, 오정산을 중심으로 탄전이 모여 있다.단산은 오정산과 운달산 사이에 있는데 길게 뻗은 정상부는 깊은 산 속에 있는 산봉우리 같은 느낌을 준다.정상에서는 주흘산과 운달산이 눈앞에 들어오고 문경읍과 산북면 모습이 보인다.이 산은 능선을 타는 것이 가장 좋으며 잡목을 많이 헤치고 길을 찾으며 가야 한다. 광산 채굴 때문에 생긴 함몰지대를 조심하고 우회를 많이 해야 한다. 산에는 패러글라이딩의 활공장이 있다.", - "MNTN_HG_VL" : "956", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면", - "MNTN_NM" : "단산" - }, - "longitude" : 128.18333329999999, - "latitude" : 36.716666699999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경부고속도로 건천나들목에서 남쪽으로 바라다 보이는 산이다. 산은 건천읍 송선리 우중골에 있으며, 산 7-8부 능선에는 4개의 바위가 둘러싸인 천연굴이 있는데 옛날에는 상인암(上人巖, 일명 탱바위)이라고 불리었다고 한다. 화랑들은 이 바위굴 속에 불상을 새기고 그 위에 지붕을 덮어 석굴사원을 만들었다. 이 절을 신선사(神仙寺) 또는 단석사(斷石寺)라고 부른다. 내부의 마애불상은 국보 제199호로 지정되었다. 단석산은 경주에서 가장 높은 산으로 백제에 대한 신라의 국방의 요충지였다.이 지역은 진달래 군락지로 봄철 산악 애호가들의 사랑을 받고 있으며, 인근 조래봉(657m)과 더불어 등산 코스로 각광을 받고 있다. 단석산으로 올라가려면 방내리에서 큰골로 가는 숲길이 있는데 화랑도량의 표시인 화랑바위가 있고, 화랑들을 불러 면회하던 급제바위가 있으며 정상 가까이에 올라가면 김유신이 칼 쓰기 연습을 하다가 남았다는 기둥바위가 있으니 사람들이 고단석이라 부른다.", - "MNTN_HG_VL" : "827", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", - "MNTN_NM" : "단석산" - }, - "longitude" : 129.09134510000001, - "latitude" : 35.793620900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "달마산은 옛날 영암의 송양현에 속했을 정도로 월출산과 가깝다. 달마산은 바위들이 갖가지 형상을 하고 있어 마치 금강산을 길게 펼쳐 놓은 듯하다 하여 ‘호남의 소금강’이라 불러왔다. 또 하나의 자랑은 산자락에 있는 미황사다. 미황사는 한반도 최남단에 위치한 사찰로서 바닷길 불교 전래를 추측케 하는 신비로운 전설을 간직한 천년 고찰이다. 사람들은 바위의 누런 이끼, 금빛 나는 금샘, 달마전 낙조를 미황사의 3황으로 꼽는다. 달마산 종주산행을 하면 이 산자락에 숨겨져 있는 보물과 다도해를 운행 중 시종일관 볼 수 있다. 운이 좋으면 보길도 격자산 쪽으로 제주 한라산의 원경도 볼 수 있다.북으로 두륜산이 접해 있고 삼면은 모두 바다와 닿아있는 산, 송호리에는 소나무와 참나무가 무성하여 모두 백여 척이나 되는 것들이 치마를 두른 듯 서 있다. 그 위에 마주한 기암괴석들은 우뚝 솟은 깃발과 같다. 혹 사자가 찡그리고 하품하는 것 같고 또는 용과 범이 발톱과 이빨을 벌리고 있는 것 같기도 하며 멀리서 바라보면 하얗게 쌓인 눈이 공중에 한 발짝 다가서 서 있는 듯하다.", - "MNTN_HG_VL" : "499", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 송지면, 북평면", - "MNTN_NM" : "달마산" - }, - "longitude" : 126.5852778, - "latitude" : 34.3825 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "136", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 봉화읍", - "MNTN_NM" : "달봉산" - }, - "longitude" : 128.69057369999999, - "latitude" : 36.885565799999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "태백의 한 지맥이 동해를 향해 꿈틀대다 크게 용트림해 만들었을까, 아니면 동해가 뒤집히면서 푸른 하늘과 응어리지어 그 정수를 한 곳에 모아둔 것인가? 그리 높지 않으면서도 정상은 큰 바위덩어리로 되어있어 장엄한 맛을 주는 산이다. 또 정상에 서면 동해가 짙푸른 윤기를 발산하며 넘실대고 있어 상쾌함이 등산복을 간지럽힌다.부산에서 1시간 남짓 걸리며 산행시간도 3시간 30분에 불과해 초심자나 가족단위 등산객에게는 안성맞춤의 산이다. 특히 정상 부근의 바위는 특별한 장비가 없이도 몸의 밸런스와 리듬만으로 바위틈새를 타고 오를 수 있어 암벽등반의 묘미도 느끼기에 충분하다.이 산 초입에 있는 일광광산은 지난 날 일본인들이 철광을 캐던 곳으로 지금은 폐광이 되어 있으나 광산마을이 그대로 있고 탄광도 거의 원형 그대로 남아있어 학생들에게는 자연학습의 장소로도 좋다.안부와 바위 틈새는 철쭉 군락지대로 부산근교에서는 정상 주변의 경관이 제일 아름다운 곳이다.", - "MNTN_HG_VL" : "587", - "MNTN_LOCPLC_REGION_NM" : "부산시 기장군", - "MNTN_NM" : "달음산" - }, - "longitude" : 129.21083329999999, - "latitude" : 35.307777799999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "옥천 이원의 달이산은 비단폭 같은 푸른 금강 물줄기와 벗하며 뻗어 있다. 달이산은 이원 사람들에게는 정다운 산이며 달을 연상하게 하는 산이다.달이산 줄기의 전체적인 가닥은 ‘H’자 모양이다. 서쪽 세로 획이 원줄기로 금강 물줄기와 벗하고 있다. 또 멀리서 보면 날카롭거나 까다로워 보이지 않고 순하고 무던하게 보이지만 산에 들어서면 곳곳에 기암절벽이 도사리고 있는 외유내강의 산이라 할 수 있다. 까마득한 바위 낭떠러지가 여러 곳에 있고 그 위는 넓은 암반이어서 쉬기도 좋고 조망하기도 좋다.달이산의 기암괴봉 중 으뜸인 것은 ‘H’자의 가로지른 획 가운데 자리 잡고 있는 암봉이다.정상에서 507미터의 서봉으로 건너가는 산등성이에 있는 둥근 투구모양의 봉우리가 그것이다. 남쪽은 높고 아득한 바위 낭떠러지이며 동쪽도 밧줄을 잡고 오르도록 되어 있을 만큼 높은 바위벽이다. 북쪽과 서쪽도 바위벽이기는 하지만 그리 높지는 않아 오르내릴 만하다.", - "MNTN_HG_VL" : "555", - "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 이원면", - "MNTN_NM" : "달이산(월이산)" - }, - "longitude" : 127.6561111, - "latitude" : 36.228888900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "516", - "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시", - "MNTN_NM" : "대곡산" - }, - "longitude" : 128.53958030000001, - "latitude" : 35.1897935 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "가평역 서쪽에 위치한 대금산은 명지산(1267m) 남서봉에서 남쪽으로 이어지는 연인산 - 우정봉 - 매봉 - 깃대봉 - 약수봉에 이어 자리하고 있는 산이다. 대금산에서 계속 이어지는 산릉은 592.7미터봉에 이르러 짧은 능선을 남쪽 청우산에 맡긴 다음, 남동으로 나아가 불기산 - 주발봉 - 호명산을 빚어 놓은 다음 여맥을 청평호 일원 북한강에 가라앉힌다. 대금산은 일제 때 이 산에 있던 소림광산에서 말(馬)만큼 큰 금광석이 나왔다고 해서 그렇게 불리기 시작했다 전해진다. 대금산 아래 두밀리의 옛 지명은 ‘삼이곡’이었고, 예부터 나라에 난리가 날 때면 다른 지방 사람들이 이곳을 피난처로 이용한 오지였다고 한다.", - "MNTN_HG_VL" : "706", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", - "MNTN_NM" : "대금산" - }, - "longitude" : 127.4210301, - "latitude" : 37.818873099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 거제시 장목면 대금리와 연초면에 있는 산으로 대금산이란 이름은 신라시대에 쇠를 생산했던 곳이라 하여 붙여진 것이다. 그리 높지 않은 산이지만 산세가 순하고 비단폭 같은 풀이 온 산을 덮고 있어 크게 비단을 두른 산이라는 뜻의 같은 이름으로 불리기도 한다.더구나 호위봉인 358미터, 285미터의 중봉이 이 산에 비해 낮기 때문에 상대적으로 우뚝해 보이고 정상이 바위 봉우리라 실제 높이보다 우람하고 드높게 보인다.중봉을 가리켜 중금산이라고도 하며 조선 말기에 축성한 성이 있는데 대금, 시방, 율천 등 3개 마을 주민들이 성을 쌓고 군량을 저장하여 남해안의 각 진에 공급하는 일에 함께 참여했다는 산성이다. 이곳에는 약수터와 기우제를 올리던 제단이 있고 약수터에는 칠석과 보름에 많은 사람들이 찾아와 목욕하고 음용하기도 한다. 멀리서 보면 잘생긴 여인이 아기를 품은 듯한 이 산은 봄이면 진달래가 온 산을 붉게 불태우고, 정상에서 본 중금산성과 소금산성은 마치 여인의 젖가슴과 같이 생겼고, 어머니의 품속에서 소록소록 잠을 자는 아기와 같은 형국을 하고 있다.최근에는 산 중턱까지 도로가 뚫려 자동차로 오를 수도 있어 일요일이면 사람들로 붐빈다. 산행은 장목면 시방(일명 살방)에서 붓골을 거쳐 정상에 오르는 것이 대표적 코스며 정상에 오르면 멀리 대마도와 부산, 마산, 진해가 눈 아래 있음을 느낄 수 있다.", - "MNTN_HG_VL" : "439", - "MNTN_LOCPLC_REGION_NM" : "거제도 연초면ㆍ장목면", - "MNTN_NM" : "대금산" - }, - "longitude" : 128.69916670000001, - "latitude" : 34.949444399999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "태백과 정선 경계를 이룬 대덕산은 초원 산릉과 여름 꽃으로 이름난 산이다. 보름 간격으로 바뀌어 피어나는 야생화는 초원 산릉을 이룬 정상부를 말 그대로 천상의 화원으로 가꾸곤 한다. 게다가 폭 200~300미터에 길이 약 1킬로미터의 정상 능선은 함백산에서 금대봉을 거쳐 매봉으로 이어지는 백두대간뿐 아니라 두타산을 거쳐 오대산까지 이어지는 산릉도 한눈에 들어오는 등 멋진 조망을 제공한다. 8월 대덕산 초원능선은 둥근이질풀, 마타리, 제비꼬깔, 산박하가 만개하고, 9월로 들어서면 보랏빛 산비장이와 자줏빛 쑥부쟁이가 활짝 피는 등 야생화 100여 종이 만개한다. 대덕산의 산행기점은 한강 발원지로 이름난 태백시 삼수동 검룡소에서 시작한다.", - "MNTN_HG_VL" : "1310", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", - "MNTN_NM" : "대덕산" - }, - "longitude" : 128.92944439999999, - "latitude" : 37.240833299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대덕산은 이웃한 삼도봉과 함께 경남,북과 전북의 3도를 나눈다. 산 이름이 대덕으로 불리우게 된 것은 이곳으로 살러오는 사람들마다 모두 큰 재산을 모음에 따라 산의 덕을 입었다는데서 연유됐다.대덕산은 가야산을 향해 뻗은 능선을 사이에 두고 경북 김천과 경남 거창을 갈라 놓은 삼도 분기점, 즉 해발1,250m의 초첨산을 옆에 둔 명산으로, 옛날에는 다락산, 다악산으로 불리었고 정사에는 기우단이 있었다고 전하는 명산이다.부드럽게 생겼으면서도 우직한 남성다운 덕기가 어린 이 산은 옛부터 수많은 인걸들을 배출했고, 또한 이 산이 있는 무풍동은 남사고의 십승지지중 하나로 알려진 고장이기에 유명하다.또한 영·호남 지방의 분수령으로 금강의 지류인 무풍천과 낙동강의 지류인 감천(甘川)이 각각 동서 사면에서 발원한다. 산 서쪽은 덕유산국립공원, 남동쪽은 가야산국립공원이 인접한다.", - "MNTN_HG_VL" : "425", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대덕면, 전라북도 무주군 무풍면", - "MNTN_NM" : "대덕산" - }, - "longitude" : 127.8805948, - "latitude" : 35.9249163 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "육백산과 오봉산,도화산을 마주보며 도계읍내를 감싸고 서 있는 산이다.정상을 향 하는 주능선에 올라 서면 도계읍내의 전경은 물론 주변의 겹겹이 쌓여 있는수 많은 크고 작은 산들의 조망이 일품이다.이 산은 도계읍내 도심권에 위치하고 있으며 산의 규모가 작은 편이라 외지의 등산객보다는 주로 도계읍민들의 등산과 운동 코스로 사랑받고 있다.", - "MNTN_HG_VL" : "1290", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍", - "MNTN_NM" : "대덕산" - }, - "longitude" : 128.92944439999999, - "latitude" : 37.240833299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대덕산은 대부분 바위로 이루어진 산으로 경사가 급한 편이다.임휴사방면 등산로는 나팔바위 등 가파른 바위로 이루어져 있어 힘들게 오른 만큼 앞산에서볼 수 있는 경치 중 가장 아름답게 느껴지는 곳이다.임휴사는 1988년 전국 70여개 전통사찰중이의 하나로 문공부에 등록된 유서 깊은 사찰이다.신라 경명왕 5년(921년) 영조대사(靈照大師)께서 최초 창건하셨고 서기 1811년(순조11년)에 무주선사가 중창하였다.고려 태조 왕건이 팔공산에서 후백제 견훤과 동수대전에 패하여 이곳으로 와 군사 및 재정비하고관음성현께 기도 드린후 편히 쉬어갔다 하여 임휴사라 했다.매자골이란 옛날 매화(梅花) 낙화지(洛花地)에서 연유되었다. 지금으로부터 300年 전에 대덕산에성기도사가 있었다. 도사가 이 곡의 지세를 목형으로 보았다. 그런 어느 해 이른 봄 이 골짜기에매화가 탐스럽게 피더니 구암동(지금의 송현동)에 떨어졌다 하여 매자골이라고 부르게 되었다.", - "MNTN_HG_VL" : "600", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달서구 송현동", - "MNTN_NM" : "대덕산" - }, - "longitude" : 128.56388889999999, - "latitude" : 35.816666699999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "899", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", - "MNTN_NM" : "대룡산" - }, - "longitude" : 127.8202778, - "latitude" : 37.844999999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산이라고 하기에는 염치가 없을 정도로 나즈막한 높이의 대모산은 서울시 강남구에 위치해 있다. 예전에는 국수봉이라고도 불리웠는데 언제부터 대모산으로 부르게 되었는지 확실치 않다.서울 변두리에 위치해 있어 잊혀지다시피한 산이었으나 인근에 아파트가 들어선 후로는 시민들의 휴식처로서의 역할을 톡톡히 하고 있다. 이른 아침 가벼운 산책을 하려는 시민들의 발길이 끊이지 않고 주말이면 많은 사람들이 이곳에 나와 도심의 찌든 때를 씻는다.이 산의 남쪽 기슭에는 헌인릉이 있어 둘러볼 만한데 헌인릉이란 조선 3대 태종과 그 왕비의 능침인 헌릉과 제23대 순조와 그 왕비의 능침인 인릉을 합쳐서 부르는 이름이다.", - "MNTN_HG_VL" : "293", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 강남구", - "MNTN_NM" : "대모산" - }, - "longitude" : 127.0783333, - "latitude" : 37.475000000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "359", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "대미산" - }, - "longitude" : 127.77444439999999, - "latitude" : 34.674166700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대부산은 경기도 양평군 옥천면에 위치한 산으로 유명산과 이웃하고 있는 산이다. 소구니산, 유명산, 어비산, 대부산, 용문산으로 이루어진 이 곳의 산군은 경기도내에서 정말 보기 드문 경치를 자랑한다.70년대초 이곳에 고랭지채소를 키우기 위해 산에 불을 질러 나무를 다 태워 버렸기 때문에 초원의 느낌을 맛볼 수 있기도 하다. 또한 이곳은 페러글라이딩 장소로도 많이 이용되기 때문에 산행을 하다보면 하늘을 날고 있는 낙하산을 심심지 않게 볼 수 있기도 하다.예로부터 홍수 때면 물고기가 산을 뛰어 넘는다고 하여 어비산이 되었으며, 마주보는 유명산과 함께 설악면과 옥천면을 가르는 산이라 하여 마을에서는 대부산이라고도 부른다. 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이루는 곳에 어비계곡이 흐른다.", - "MNTN_HG_VL" : "743", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면", - "MNTN_NM" : "대부산" - }, - "longitude" : 127.48808649999999, - "latitude" : 37.5675995 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대성산은 충북 옥천군과 충남 금산군을 가르며 남북으로 뻗쳐있는 산줄기 가운데 있는 산이다. 천태산과 장룡산 외 새봉, 마성산, 용봉 등도 이 산줄기를 따라 이어져있다. 이 줄기는 백제와 신라의 경계였으며 모두가 아름답다. 천태산은 그 아름다움이 널리 알려진지 오래며 기암괴석이 많은 장룡산은 물론 대성산도 폭포가 많은 산으로 유명하다. 이 지역 주민들은 대성산 품안에 열 개의 폭포가 있다고 자랑한다.하지만 폭포만이 매력의 전부가 아니다. 폭포가 아니어도 여기저기 솟아 있는 바위봉우리에서 바라보는 조망이 좋다. 이 봉우리들은 천길 낭떠러지를 이루며 좁고 깊은 골짜기 위에 우뚝 솟아있기 때문에 조망이 좋고 무척 시원하다.대성산은 열 개의 폭포와 함께 열 개의 조망이 있는 산이라 할 수 있다. 그 가운데 유난히 뾰족해 멀리서 눈에 잘 띄는 국사봉 위의 조망대는 아예 ‘전망대’라는 정식 이름까지 붙여져 있다. 천길 벼랑 위에 있는 이 전망대에서는 옥천 일대가 발아래 펼쳐지고 멀리 속리산, 덕유산, 민주지산, 백화산, 포성봉과 함께 주행봉, 황악산 등을 조망할 수 있어 좋다.", - "MNTN_HG_VL" : "706", - "MNTN_LOCPLC_REGION_NM" : "충북 옥천군 이원면, 충남 금산군 군북면", - "MNTN_NM" : "대성산" - }, - "longitude" : 127.6154454, - "latitude" : 36.217931999999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대암산 정상 부근에는 큰 용늪, 작은 용늪이라 불리는 고지습원이 있는데, 작은 용늪은 이미 그 원래의 모습을 상실하여 숲으로 변해버리고 말았다. 큰 용늪은 우리나라에서 유일한 고지습원으로 연중 안개끼는 날이 많은 특수한 환경이 조성되고 있어 생태계 연구에 좋은 자료를 제공하고 있다.큰 용늪에는 물이끼, 삿갓사초, 꼬리조팝나무, 꽃쥐손이풀 등의 식물군락이 있으며, 손바닥 난초, 비로용담, 끈끈이주걱 등의 희귀식물도 자라고 있다. 그 밖에 식물성 플랑크톤 63종, 돌말 19종과 천연기념물인 산양과 검독수리가 관찰된 바 있으며, 도룡뇽, 무당개구리, 줄흰나비 등도 볼 수 있다. 또 이 지역과 연결된 두타연계곡에서는 열목어를 비롯한 특산 어류 10여 종이 살고 있다.대암산·대우산 천연보호구역은 분지·습원등 지형적으로 다양한 특징을 지니고 있고, 기후조건이 특이하여 희귀동식물이 자라고 있다. 또한 동식물의 남북한계·동서 구분의 현상이 나타나는 등 식물생태학·식물지리학적·식물분류학적 연구가치가 매우 큰 지역일 뿐만 아니라 다양한 동물상, 특이한 지형·지세 및 기후적 특성 등 다양한 자연 환경을 가지고 있어 학술적 가치가 크므로 쳔연기념물로 지정·보호하고 있다.", - "MNTN_HG_VL" : "1313", - "MNTN_LOCPLC_REGION_NM" : "강원 양구군 동면, 인제군 서화면", - "MNTN_NM" : "대암산" - }, - "longitude" : 128.1350874, - "latitude" : 38.211199499999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대야산은 백두대간에 자리잡고 있으면서 대간능선이 꿈틀이고 지나며 아름다운 보석들을 흩뿌려 놓은 문경의 산들 중에서도 그 명성을 높이 사고 있는 명산이다. 경북 문경시(聞慶市) 가은읍(加恩邑) 완장리(完章里)에 속한 대야산은 대간 마루금을 경계로 충북 괴산군(槐山郡) 청천면(靑川面) 삼송리(三松里)와 접하고 있다. 내\/외선유동을 거느리고 있는 대야산은 2002년 세계 산의 해를 맞아 문경의 주흘산, 황장산, 희양산과 함께 산림청에서 선정한 한국 100대 명산에 올라서 있다. 예로부터 명산으로 받들어 온 대야산은 여러 기록들에 ‘大耶山’으로 적고 있으며 특히 철 종 조의 대동지지[(大東地志(1861년 이후 추정)]에는「大耶山 曦陽山南支上峯曰毘盧爲仙遊 洞主山西距淸州華陽洞三十里(희양산남지상봉왈비로위선유동주산서거청주화양동삼십리: 대야산은 희양산의 남쪽 갈래로 제일 높은 봉우리가 비로봉이고, 선유동의 주산이다. 서쪽의 청주 화양동이 30리다)라고 기록하고 있어 대야산 정상을‘비로봉(毘盧峯)’으로 부르고 있음을 알 수가 있다.", - "MNTN_HG_VL" : "931", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 청천면", - "MNTN_NM" : "대야산" - }, - "longitude" : 127.9324859, - "latitude" : 36.670577600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "장백산령이 나려오면서 남으로 많은 산군을 융기시켰다. 청도군과 경산시의 경계를 이루는 선의산, 용각산이 융기되고 이현 복고개에서 힘을 다하는 것 같았으나 다시 마지막 힘을 뻗어 대왕산을 이루었다.학일산은 일제가 우리나라를 강제로 점령하자 학일산의 영험을 빌어 나라를 지키고자 마을 이름을 내촌에서 학일이라 고쳐 불렀다. 이와 마찬가지로 항일 죽창 의거사건과 관련이 깊은 대왕산 또한 민족혼이 어린 명산이라 하겠다. 근래 마을에는 수질, 수온, 수량 등 조건이 양호한 온천수가 발견되었다.", - "MNTN_HG_VL" : "605", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "대왕산" - }, - "longitude" : 128.83631489999999, - "latitude" : 35.746121799999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "대운산은 울산광역시와 부산광역시, 경남 양산시의 경계에 있는 산이다. 금정산에서 원효산, 천성산을 이어가는 낙동정맥이 그 중간에서 동쪽으로 곁가지를 내려 백운산(520m), 철마산(604m), 거문산(543m), 달음산(588m), 용천산(545m) 등을 차례로 일으킨다. 그 중 최고봉인 대운산은 2개 광역시와 경상남도의 경계선을 긋는 중요한 곳에 자리하고 있으며, 장안사, 척판암, 내원암 등 역사의 향기가 가득한 명찰을 자락에 품고 있는 남녘의 명산이다.대운산을 오르는 산길은 다양하나 겨레의 영원한 스승 원효대사의 발자취를 찾아 기장군 장안읍에 자리한 장안사를 거쳐 오를 수 있다. 장안사는 신라 문무왕 13년(서기 673년) 원효대사가 창건한, 오랜 역사를 자랑하는 고찰이다.‘불광산(대운산의 다른 이름) 대운사’라고 쓰인 문을 지나 들어선 장안사 뜨락에는 동백꽃이 뚝뚝 지고 고목들이 연륜을 알려주는 경내에는 불향이 그득 넘친다. 장안사 절문을 나서면 오른쪽에 참으로 특이한 해우소(변소)가 보인다. 굵은 왕대를 엮어 울타리를 두른 멋진 해우소. 볼 일이 급하지 않더라도 잠시 들러 왕대나무 화장실의 멋을 엿보아야 한다.", - "MNTN_HG_VL" : "742", - "MNTN_LOCPLC_REGION_NM" : "경남 양산시 웅상읍, 울산시 온양면, 부산시 기장군", - "MNTN_NM" : "대운산" - }, - "longitude" : 129.21184489999999, - "latitude" : 35.402419600000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 홍천군 동면과 서석면의 경계에 자리한 대학산은 양옆으로 공작산(887m)과 발교산(998m)을 끼고 있으며 수림이 울창하여 첩첩산중이라는 말이 실감나는 오지의 산이다.이 산에 있는 물골은 본래 `수동'이라 불리었으며 계곡이 크다 해서 예로부터 주민들 사이에는 큰골로 통했다. 물골에서 시작하는 이 산행은 교통이 불편한 게 흠이지만 일단 산에 들어서면 속세와 완전히 격리된 듯한 분위기를 만끽할 수 있는 곳이다.숲과 단애, 낙엽송 수림, 노송이 있는 6월의 대학산은 자연의 생기찬 모습이 그대로 전달되어 오는 자연에 푹 빠진 산행으로 코스를 마칠 수 있는 깨끗한 산이다.정상에서의 조망은 서북쪽으로 공작산이 가깝게 보이고 동쪽으로는 수리봉에서 병무산으로 이어지는 능선이 시야를 막고 있다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 서석면", - "MNTN_NM" : "대학산" - }, - "longitude" : 128.085553, - "latitude" : 37.674847499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "괴산군 연풍면과 장연면의 경계를 이루고 있는 덕가산은 충북의 유명산 악휘봉(940m)과 이웃해 있다. 악휘봉이란 명산에 가려져 빛을 보지 못한 산이기도 하다.덕가산은 악희봉과 반대로 육산이며, 정상에는 삼각점과 깃대봉이 있다. 주능선에는 상수리나무가 주종을 이루고 등산화를 파묻히게 하는 낙엽의 아삭아삭하는 소리가 홀로 걷는 이의 빈 마음을 채워주어서 좋다.주위에 여러산들이 기암절벽으로 산을 감싸고 있는 반면 산세가 부드럽고 장송들이 많아 여성적인 자태를 지니고 있다.", - "MNTN_HG_VL" : "855", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면", - "MNTN_NM" : "덕가산" - }, - "longitude" : 127.95, - "latitude" : 36.75 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕갈산은 산청,거창,함양군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳에서 양분 되어 한줄기는 갈전, 철마, 소룡, 바랑산을 거쳐 황매산으로 뻗어있고 또하나가 바로 덕갈산 줄 기를 이루며 그 끝은 태봉산까지 길게 이어져 있다. 마치 떡가래처럼 널어져 있는 형세를 하고 있으며 그 줄기위에서는 지리산을 정면으로 바라볼수 있어 주변의 1000m 내외의 산들과 구별되어 산중에 제왕임을 한눈에 알 수 있게한다. 또한 덕유산에서 지리산으로 흐르다 출렁이면서 솟아 오 른 고봉들도 조망이 가능하여 덕갈산을 방문한 등산객에게만 산행의 참맛을 선사한다. 덕갈산은 가슴을 확트이게하고 눈을 즐겁게 하는 산으로 자신을 자랑하기보다는 주변 산들의 기상 과 기세를 칭찬하는 겸손한 산이다.", - "MNTN_HG_VL" : "669", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군,거창군,함양군", - "MNTN_NM" : "덕갈산" - }, - "longitude" : 127.86333329999999, - "latitude" : 35.576111099999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "산자락에 천년고찰 봉복사를 안고 있는 덕고산은 사찰 안에 덕고산 봉복사(德高山 鳳腹寺)라는 현판이 걸려 있어 그렇게 불리는데, 강원도 횡성군 청일면과 홍천군 서석면의 사이에 서서 경계를 이룬다.태기산과 성골계곡을 사이에 두고 마주보고 있는 덕고산은 삼한시대 말 진한의 마지막 왕인 태기왕이 새로 일어나는 신라군에 쫓기어 이곳에 성을 쌓고 군사를 길러 신라군과 싸웠다는 전설을 안고 있다. 그래서 이 산의 성골 골짜기에서는 태기왕 때의 것으로 보이는 허물어진 성벽 일부와 기와조각, 샘터 등이 발견되고 있다.산기슭에는 복조리의 재료인 산죽(山竹:시누대)이 많이 자란다.수림이 빽빽하여 정상에서의 조망이 시원하지는 않지만 깊고 조용한 산이다. 산행 들머리에는 신라시대의 것으로 6·25전쟁 때 총탄에 맞은 흔적이 여러 군데 있는 것을 빼고는 비교적 원형이 잘 보존되어 있는 삼층석탑(강원유형문화재 60)이 있다.", - "MNTN_HG_VL" : "1125", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 홍천군", - "MNTN_NM" : "덕고산" - }, - "longitude" : 128.16441259999999, - "latitude" : 37.471818200000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕룡산과 주작산은 높이에 따라 산세가 좌우되지 않는다는 사실을 깨닫게 하는 산이다. 해남 두륜산과 이어져 있고 높이라야 고작 400미터를 조금 넘지만 산세만 놓고 보면 1000미터 높이의 산에 뒤지지 않는다. 이 산은 웅장하면서도 창끝처럼 날카롭게 솟구친 암릉과 암릉 사이의 초원능선 등 능선이 표현할 수 있는 아름다움과 힘의 진수를 보여준다. 두륜산과 경계를 이루는 오소재에서 주작산, 덕룡산, 소석문까지 이어지는 11킬로미터 암릉은 마치 봉황이 날개를 펴고 하늘로 비상하는 형상이다. 봄이면 산꾼의 가슴을 태워버릴 듯 암릉에 흐드러지게 핀 진달래가 탄성을 자아내게 하고, 여름이면 은빛으로 빛나는 다도해와 누렇게 익은 보리밭의 조망, 가을이면 억새와 단풍 그리고 사시사철 신이 빚어 놓은 만물상이 연이어지는 스릴 넘치는 암릉이 산행의 백미다. 주작산은 강진군 신전면, 도암면, 해남군 옥천면, 북일면을 경계하고, 덕룡산은 강진군 도암면과 신전면을 경계한다. 덕룡산 정상에서 조망은 북으로 흑석산과 만의산, 만덕산과 월출산, 북동으로 궁성산과 국사봉, 수인산과 제암산, 동으로 천관산과 일림산, 남으로 두륜산과 상황봉, 서쪽은 두륜산과 첨찰산이 보인다.", - "MNTN_HG_VL" : "433", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", - "MNTN_NM" : "덕룡산" - }, - "longitude" : 126.7021027, - "latitude" : 34.540005299999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "474", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍 수철리 449", - "MNTN_NM" : "덕봉산" - }, - "longitude" : 126.8822222, - "latitude" : 36.713611100000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 예산에 자리잡은 덕숭산은 기기묘묘한 형상의 괴석들이 많아 절묘한 산세를 뽐내며 1973년 3월 6일 도립공원으로 지정되었다. 호서의 금강산이라 불릴 만큼 아름다운 경관을 갖추고 있는데다 아담한 산세 곳곳에 유명한 암자들이 배치되어 있어 찾는 이들의 발길이 끊이지 않는 곳이다.그 중 비구니의 도량으로 알려진 수덕사는 고려 충렬왕 34년(1308)에 창건된 사찰로 국보 제 49호로 지정된 대웅전이 있는데 이 건물은 무량수전과 더불어 현존하는 목조건물 중 가장 오래된 것이다. 부처님의 진본사리가 안치된 황화루를 비롯, 김일엽 스님의 거쳐였던 환희대, 만공스님을 기리기 위한 미륵불상등 수행의 역사를 조망할 수 있는 흔적들이 눈길을 끈다. 수덕사와 창건연대가 같은 정혜사는 구한말에 만공 스님이 한국 선불교를 중흥시킨 곳으로 청방, 정강, 용성 등의 대스님이 거쳐갔던 명소다. 덕숭산은 이밖에도 만공탑, 여승당, 보덕사 등 많은 문화재를 간직하고 있으며 주변에 온천이 있어 배낭 하나 메고 가볍게 떠날 수 있는 가족 나들이 코스로 손색 없는 산이다.", - "MNTN_HG_VL" : "495", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면", - "MNTN_NM" : "덕숭산(수덕산)" - }, - "longitude" : 126.6187789, - "latitude" : 36.672609600000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "163", - "MNTN_LOCPLC_REGION_NM" : "경기도 평택시,안성시", - "MNTN_NM" : "덕암산" - }, - "longitude" : 127.12527780000001, - "latitude" : 37.066666699999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕우산은 강릉시 왕산면 고단리와 정선군 임계면 송계리의 경계를 이루는 산으로 해발 1007 m 이며 이산은 백두대간이 첩첩이 병풍처럼 두러쳐진 한가운데에 위치하여 정상에서 바라보면 먼저 고루포기산, 서득봉, 화란봉, 대화실산, 두리봉, 석병산, 자병산, 상월산, 등이 시계 방향으로 돌며 보이고 서쪽으로는 노추산과 사달산이 보이는 전망좋은 산이다. 덕우산에는 피나무골 샘터가 있는데 이산에서 발원한 물은 송게촌과 어울여 남한강의 원류가 된다. 강릉시에서 오를 수 있는 등산로은 고단 1리 고단초교 뒷등으로 통현사를 거쳐 오르는 코스와 남한강 발원지 피나무골 샘터 표지석에서 고냉지 채소밭을 거쳐 오르는 코스와 배모탱이 안고단 마을에서 둥우리재를 거쳐 오르는 코스로 3개 등산로가 있다. 백두대간이 첩첩이 병풍처럼 둘러쳐진 다운데에 위치하여 동서를 길게 드러누운것이 마치 소가 한가롭게 여물을 되새김질 하는 와우형의 산이다.", - "MNTN_HG_VL" : "1007", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선군 임계면", - "MNTN_NM" : "덕우산" - }, - "longitude" : 128.83387450000001, - "latitude" : 37.512631599999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "덕유산은 전북 무주군과 장수군, 경남 거창군과 함양군의 경계를 이루며, 2도 4군 8개면에 걸쳐있다. 한라산.지리산.설악산에 이어 남한에서 4번째로 높고 1000미터 이상의 봉우리가 20개도 넘는 거대한 산이다.덕유라는 이름은 덕이 있고 크며 넉넉한 산의 모습을 나타낸 말이다. 무학대사가 골치아픈 정권에서 벗어나 첩첩산중 경치 아름다운 산을 물색하다가 발견했다는 산이 바로 덕유산이다.", - "MNTN_HG_VL" : "1614", - "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군ㆍ장수군, 경상남도 거창군ㆍ함양군", - "MNTN_NM" : "덕유산(향적봉)" - }, - "longitude" : 127.7468314, - "latitude" : 35.860032799999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "138", - "MNTN_LOCPLC_REGION_NM" : "경기도 평택시", - "MNTN_NM" : "덕지산" - }, - "longitude" : 126.9354044, - "latitude" : 37.061012400000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "진안의 동쪽으로는 성수산, 팔공산, 선각산, 삿갓봉 등 해발 1000미터 이상 되는 봉우리가 병풍처럼 둘러싸고 있다. 이 웅장한 산줄기에 덕태산이 자리하고 있다. 덕태산에는 수많은 미개척 계곡과 전인미답의 능선이 원시림에 가려 있으며, 험준한 절벽과 갖가지 형상의 바위가 도처에 산재해있다. 봄철 골짜기를 가득 메운 철쭉과 가을철 은근한 단풍은 암릉과 울창한 숲이 어우러져 빼어난 경치를 자랑하는 백운동계곡과 함께 덕태산의 자랑이다.능선의 동쪽으로는 시루봉과 함께 금남호남정맥 마루금이 지나고, 남쪽으로는 선각산과 함께 섬진강 발원지인 데미샘을 품고 있다. 정상에 서면 지리산과 남덕유산, 마이산과 내동산, 고덕산 등이 사방으로 조망되는데, 호쾌하게 뻗은 산줄기를 보고 있자면 감탄사가 절로 나온다.덕태산에는 ‘라장사’의 전설과, ‘점전바위’ 사이에 풀잎을 꽂으면 아들을 낳는다는 전설이 전해져 온다.", - "MNTN_HG_VL" : "1113", - "MNTN_LOCPLC_REGION_NM" : "전북 진안군 백운면", - "MNTN_NM" : "덕태산" - }, - "longitude" : 127.4473366, - "latitude" : 35.6892979 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다. 또한 기슭에는 고찰 도갑사(道岬寺)가 있고 이곳에는 국보로 지정된 해탈문, 보물로 지정된 석조여래좌상 등이 있다. 특히, 도갑산을 포함한 월출산이 국립공원으로 지정된 후 관광지로서 각광을 받고 있다.", - "MNTN_HG_VL" : "376", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 군서면", - "MNTN_NM" : "도갑산" - }, - "longitude" : 126.6725, - "latitude" : 34.744444399999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도고산은 충남 아산시 도고면에 자리해 있으며 산가에 도고저수지를 끼고 있다. 산 정상에는 조선시대에 통신수단으로 사용하던 봉화대 유적이 원형에 가깝게 잘 보존되어 있다. 정상에 서면 예당평야와 아산만은 물론 멀리 천안시까지 한눈에 들어와 서해안의 초계와 방어를 위한 군사적 요지로 유명하다.옛날 천지가 개벽할 때 온 천지에 물이 찼는데, 산꼭대기만 도구통만하게 남았다는 설화에서 산 이름이 유래한다.삽교천방조제가 세워지기 전에는 바로 산 밑까지 바닷물이 들어왔으며, 주봉인 국사봉에는 봉수대가 남아 있다. 1390년(고려 공양왕 2) 6월에 서해안에 침입한 왜구가 이곳에 진을 치고 약탈을 자행하자 윤사덕과 유용생이 이끄는 관군이 물리쳤다는 기록도 남아 있다.도고면에서는 가파른 곳에는 로프를 설치했으며 등산로 곳곳에는 쉴 수 있는 긴 의자를 만들어 놓았고, 안내판도 세워놓았다.인근에 도고온천이 있어 산행과 온천을 겸한 여행지로 알맞다. 도고중학교에서 출발하여 정상에 오른 뒤 다시 내려오는 코스가 개발되어 있으며 약 2시간 30분 소요된다. 주변에는 중요민속자료 194호로 지정된 아산 성준경가옥 등의 문화재가 있다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "충남 아산시 도고면, 예산군 예산읍", - "MNTN_NM" : "도고산" - }, - "longitude" : 126.895, - "latitude" : 36.725000000000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "국립지리원 발행의 지형도에는 도덕봉(道德峰 534m)이라 표기되어 있으나 마을 주민들은 흑룡산(黑龍山)이라 부른다. 이 산은 도덕봉과 한줄기인 백운봉(白雲峰 536m), 금수봉(錦繡峰 532m), 빈계산(牝鷄山 415m)등을 포함하고 있다.도덕봉 정상 동쪽은 거대한 절벽이 장관이고 굴골에는 큰 동굴과 작은 석관 2개, 폭포 등으로 어우러진 계곡 오솔길 주변은 단풍이 좋다. 남릉은 서면이 50-100m의 암벽을 이루고 암릉 끝에는 커다란 수통굴이 있다. 일제때 구리를 캐던 곳으로 추정되는 구리골을 경유하여 수통굴로 가면 굴속에는 무속인들의 움집이 한채 있고 굴속 끝에는 작고 맑은 샘이 있어 산행길의 쉼터로 그만이다. 옛날에 이 골짜기에 도독이 많이 살고 있던 데서 산 이름이 유래한다.조망은 주변 숲에 가려져 시야가 좁고 트인 경관을 구경키 어렵다. 봄철에는 진달래가 붉게 물들고 산벚꽃이 많이 핀다.", - "MNTN_HG_VL" : "534", - "MNTN_LOCPLC_REGION_NM" : "충남 공주시 반포면, 대전 유성구", - "MNTN_NM" : "도덕봉 (흑룡산)" - }, - "longitude" : 127.2780556, - "latitude" : 36.348888899999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "두덕산(斗德山)이라 불리기도 했던 이 산은 산세야 그리 빼어나다고 할 수 없지만, 아담하고 조망이 시원한 정겨운 산이다. 낙동정맥 마루금이 지나면서 경북 경주시 안강읍과 영천시 고경면을 가르는 배티재 옆에 비켜 앉은 도덕산은 결국 그 지맥이 북쪽, 낙동정맥으로 이어진다. 아직까지 널리 알려져 있지 않은 관계로 이 지역 등산객들과 정맥 종주꾼들이 간간이 찾을 정도다. 남쪽의 자옥산(紫玉山, 569.9m)과는 능선을 맞대고 이웃해 있으며, 산기슭에는 볼 만한 문화유적도 많다. 동쪽 산자락을 따라 흐르는 옥산천(玉山川)의 자연과 어우러진 독락당, 옥산서원을 비롯해 주변에 산재한 문화유적을 둘러볼 수 있다.", - "MNTN_HG_VL" : "703", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 안강읍·영천시 고경면", - "MNTN_NM" : "도덕산" - }, - "longitude" : 129.1391667, - "latitude" : 36.025277799999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 이천의 도드람산은 높이도 보잘 것 없고 코스도 짧다. 하지만 능선 전체가 암석으로 이뤄져 바위타는 재미에 있어서는 수도권 산 가운데 으뜸이다. 등산 동호인들의 말을 빌리자면 '바위맛'이 좋은 산이라고 한다. '바위맛'이란 발뿐 아니라 손을 이용해 바위 뿌리 등을 잡고 가는 등산로의 아기자기함을 뜻하는 은어이다.'이천의 소금강'이라 불리는 도드람산은 일명 저명산(猪鳴山)이라고도 부른다. 저명산의 한문 표기의 '돗 저''울 명'의 돗울음산이 변하여 도드람산으로 부르게 된 것으로 전해지고 있다산 중턱에 있는 영보사 뒷편 절벽 아래서 샘솟는 차고 시원한 석관수의 맛이 일품이며,능선을 따라 바위를 오르는 등산객의 아기자기함이 산행의 묘미를 만끽하게 해준다.", - "MNTN_HG_VL" : "349", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 마장면", - "MNTN_NM" : "도드람산" - }, - "longitude" : 127.39193779999999, - "latitude" : 37.266356700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "‘이otilde;의 소금강’으로 불리는 도드람산은 남북으로 이어진 작고 낮은 산줄기에 불뚝불뚝 솟아오른 암봉의 아기자기한 모양새가 가시가 돋아 난 공룡 등brvbar;과도 같다. 저명산(돼지울음산, 猪鳴山)이라는 독특한 이름으로도 불리는 이 산은 높이는 낮지만 기암괴석의 봉우리들로 이어진 산세가 절경을 이루고 있어 이otilde; 제일의 명산으로 불린다. 또한 산과 관련된 여러 전설이 깃든 곳이고, 바위를#376;고 넘는 등산로가 일품이어서 주말이면 많은 등산인들이atilde;는 이름난 명승지이기도 하다.산은 그다지 높지 않아도 평지에 솟아 있어 조망이 좋고 힘들지 않게 암릉산행을 즐길 수 있는 이점이 있다.", - "MNTN_HG_VL" : "349", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 마장면", - "MNTN_NM" : "도드람산" - }, - "longitude" : 127.39193779999999, - "latitude" : 37.266356700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "우암 송시열 선생이\"도를 깨닫고 스스로 즐길 만한 곳이다\"해서 도락산이라 명명한 이 산은 경북과 충북의 도경계선에 근접해 있다.월악산국립공원권에 속해 있는 산으로, 충북 단양군 단양읍과 대강면의 경계를 이루고 있으며 도락산 산자락에는 단양 8경 중 4경인 사인암,상선암,중선암,하선암 등이 있어 관광의 보고이기도 하다.", - "MNTN_HG_VL" : "965", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면, 대강면", - "MNTN_NM" : "도락산" - }, - "longitude" : 128.31169420000001, - "latitude" : 36.856228899999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "뛰어난 풍광으로 우암 송시열이 낙향하여 머물던 화양구곡 중앙부에 위치한 도명산은 국립공원 속리산에 속하여 있으며 태고의 신비와 자연의 오묘한 섭리를 안고 있는 산이다. 첨성대 바위, 흔들바위 등 자연이 빚어낸 기묘한 형태에 기암과 암릉(岩陵)이 곳곳에 산재해 있으며 특히 정상부를 차지하고 있는 기암 덩어리인 정상 바위는 가히 일품이라 할 수 있다.정상은 크고 작은 바위 다섯 개가 하나로 정상을 이루고 있다. 정상에서의 조망은 북쪽 아래로는 화양동 계곡과 군자산, 칠보산이 펼쳐지고, 동쪽으로는 대하산, 남쪽으로는 낙영산, 주봉산, 멀리 속리산 능선과 문장대가 들어온다. 주변에는 분재처럼 자란 소나무가 정취를 더한다. 화양동계곡은 기암괴석으로 이뤄진 절경이 아홉 곳이나 된다고 해서 '화양구곡'(華陽九曲) 또는 '화양동 소금강'으로 불린다. 이곳은 경치가 너무 아름답고 물이 맑아 조선시대의 조선조 대유학자였던 우암 송시열 선생이 조정을 물러나와 은거하던 곳으로도 유명하다.이곳에 반한 조선 후기의 유학자 우암 송시열은 화양동주(洞主)로서 은거하며 이곳이 중국의 무이구곡을 닮았다 하여 9곡의 이름을 짓고 경천벽·금사담\\·첨성대 등의 바위에 글씨를 새겼다.제1곡 경천벽은 깎아지른 층암절벽이 하늘을 떠받치고 있으며, 화양2교 옆의 2곡 운영담은 구름이 비치는 담 주변에 넓은 모래사장이 있다. 3곡은 우암이 새벽에 올라 효종의 승하를 통곡했다는 읍궁암으로 민박집과 식당이 많다. 서원철폐의 빌미가 된 화양서원을 거쳐 하마소와 채운사 등의 명소가 있다.제일 수려한 4곡 금사담은 금모래가 반짝이며 넓은 암반 위에 우암의 암서재가 노송 사이에 있다. 화양3교 직전 바른쪽 낙영산 정상의 기암절벽인 5곡 첨성대는 별을 관측하던 곳이다. 더 가면 심곡에 큰 2층바위인 6곡 능운대가 나오며 7곡 와룡암, 8곡 학소대, 9곡 파천이 있다.", - "MNTN_HG_VL" : "642", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", - "MNTN_NM" : "도명산" - }, - "longitude" : 127.8167474, - "latitude" : 36.652938800000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도봉산은 서울 근교의 산으로 예로부터 북한산과 하나의 산으로 취급되어 왔다. 우이령을 경계로 북한산과 나란히 솟아 있어 현재 두 산을 북한산국립공원에 함께 포함시키고 있다. 북한산 면적 55㎢에 비해 도봉산은 약 24㎢로 절반에 불과하나 산세가 아름다워 등산객이 끊이지 않는 곳이다.주능선상에는 최고봉인 자운봉을 비롯해 만장봉, 선인봉, 주봉 등의 암봉과 서쪽으로 다섯개의 암봉이 나란히 줄지어 있는 오봉이 있다. 선인봉, 만장봉, 주봉, 우이암은 각기 거대한 암벽들이다. 도봉산은 우람한 기암괴석과 뾰족히 솟은 암봉들이 장관을 이루며, 사방으로 뻗은 계곡을 따라 녹음이 우거져 명소를 만들고 있다.사계절 모두 즐겨 찾는 산이지만 가을이면 단풍의 물결이 여느 산 못지 않다. 도봉산의 3대 계곡은 문사동계곡, 망월사계곡(원도봉계곡), 보문사계곡(무수골) 이다. 이 계곡들이 바로 산행기점과 연결된다. 도봉산은 등산코스가 다양한데 그 중에서 우이동, 도봉유원지, 망월사역(장수원), 성황당 코스가 대표적이다.도봉산의 주봉은 자운봉(740.2m)으로, 정상을 기점으로 등산로가 사방으로 거미줄 같이 수십 가닥이 펼쳐져 있다. 모두 합쳐 100여개의 산행 코스가 있다. 그 중 도봉산 등산로의 핵심은 포대능선으로, 이 산의 등뼈를 이루는 포대능선-자운봉-칼바위-우이암 능선으로 이어진다. 포대능선은 능선 중간에 대공포진지인 포대(砲臺)가 있었다고 해서 붙여진 이름이다. 도봉산 산행 들머리는 수 없이 많지만 크게 분류하면, 안골유원지, 회룡사입구, 원도봉유원지, 도봉유원지, 성황당, 우이동, 송추 7개 코스를 꼽을 수 있다. 빼어난 암릉미를 자랑하는 도봉산은 어느 코스이든 바위 암릉이 곳곳에 도사리고 있어 주의가 필요하다. 수도권 등산객이 많이 몰리는 휴일에는 주능선인 포대능선 등에 정체 현상이 벌어질 정도로 붐빈다. 갈림길이 무수히 많아 길을 잃을 수 있으므로 사전에 지도를 꼼꼼히 챙겨야 되는 산이다.", - "MNTN_HG_VL" : "740", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 도봉구, 경기도 의정부시 호원동ㆍ양주시 장흥면", - "MNTN_NM" : "도봉산(자운봉)" - }, - "longitude" : 127.0156843, - "latitude" : 37.700463499999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도비산은 서산시에서 연암산(441m)과 팔봉산(362m)에 이어 3번째로 높다. 정상에 올라서면 서해 조망이 뛰어나다. 주변에는 안면도 간월암 수덕사 등 관광명소가 산재해 있어 여름철 가족 산행지로 적격이다.산행 들머리는 추평리 부석사 입구에서 시작된다. 이곳서 시멘트로 포장된 농로를 따라 30여분을 올라가면 부석사에 닿는다. 급경사길을 20여분 오르면 능선에 닿는다. 능선길을 따라 15분 정도 걸으면 바로 정상. 그만큼 산행을 하기에 어려움이 없다. 정상에 오르면 천수만 간척지를 비롯해 너른 들판과 그 너머로 서해바다가 손짓한다. 도심에서는 느낄 수 없는 포근함이 다가온다. 또 겨울이면 간월호와 부남호의 철새를 볼 수 있다.일설에 의하면 산 대부분이 나무로 덮여 있어 봄이면 복숭아꽃으로 산을 장식하고, 주위에 낙화가 소복이 쌓이는 데서 연유되어 [복숭아 도]자 와 [살찔 비]자를 써서 도비산이라 이름 붙였다고 한다.", - "MNTN_HG_VL" : "352", - "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 인지면", - "MNTN_NM" : "도비산" - }, - "longitude" : 126.41607550000001, - "latitude" : 36.702880200000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "도일봉은 경기도 양평군의 상징산인 용문산과 마주한 산이다. 용문면과 단월면의 경계를 이루는 높이 864 m의 중봉으로 용문산의 명성에 가려 아직 찾는 사람이 적어서 오염되지 않은 깨끗한 계곡을 간직하고 있다.등산로 입구인 상현마을에서 약 30여분 정도 오르다보면 중원폭포가 나온다. 이곳은 도일봉과 중원산을 오르는 갈림길이자 휴식처이다. 약 8km에 달하는 중원계곡은 요즘 보기 드문 청정계곡이다. 중원계곡의 입구는 길과 담, 벼랑이 모두 바위로 이루어져 있는데 '폭포' 라는 이름에 비해 높이는 겨우 2미터정도다.하지만 발광하듯 쏟아져내리는 물길은 산행하며 쏟아 부운 온갖 기운을 충만하게 채워준다. 무성한 숲이 개울위까지 차양을 치고 있어 여름에도 더위가 끼여들 틈이 없어 계곡안은 냉기류가 감돈다. 5m 높이에서 떨어져 하얀 포말을 일으키는 중원폭포와 바위에 부딪혀 하얀 웨딩드레스를 펼친 듯이 떨어지는 치마폭포도 보는 이의 가슴을 시원하게 쓸어내려 준다. 도일봉에는 소나무가 많아서 산행길 내내 소나무숲향기가 함께 해서 더욱 좋다.", - "MNTN_HG_VL" : "864", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", - "MNTN_NM" : "도일봉" - }, - "longitude" : 127.61333329999999, - "latitude" : 37.575000000000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "828", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시", - "MNTN_NM" : "도장산" - }, - "longitude" : 127.94232150000001, - "latitude" : 36.552953100000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "상주시 화북면과 문경시 농암면 경계에 솟은 도장산은 계곡미가 빼어난 경북의 숨은 명산이다. 용추에서ucirc;룡, 황룡이 살았다하여 쌍용계곡이라 불리는 골yen;기를 따라 선녀들이 내려와 목욕을 하였다는 선녀탕, 암반 아래에 명주실 한#376;래가 들어간다는 깊은 용추(용소) 등 오랜 세월 풍화를 겪은 기암괴석과 맑고 깊은 물이 어우러져 시원한 절경을 자아낸다.도장산이 걸쳐있는 상주시 화북면은 십승지 중 하나인 우복동otilde;(牛腹洞川)의 명당터로 알려져 있다. 그리하여 예부터 ‘삼산삼수(三山三水)의 고장’으로 불리어왔는데 도장산이 속리산(1057.7m),ucirc;화산(984m)과 함께 삼산에 속해 경치 좋고 사람 살기 좋은 곳으로 꼽혀왔다. 상주시에서는 이 삼산을 하나로 엮어 2007년 ‘우복동otilde;’ 산행 코스를 정비하였다. 이 중 도장산은 5.2킬로미터 구간이 조성되어 있다.도장산 정상은 밋밋한 편이다. 그러나 속리산을 조망하기에는 더 없이 좋다. 정상에 서면 속리산otilde;황봉으로부터 뻗어지는 문장대까지 한눈에 볼 수 있다. 산자락에 위치한 심원사는 원효대사가acirc;건한 고찰로서 고즈넉하고 소박한 암자의 모습을 간직하고 있다.", - "MNTN_HG_VL" : "828", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면 용유리, 문경시 농암면", - "MNTN_NM" : "도장산" - }, - "longitude" : 127.94232150000001, - "latitude" : 36.552953100000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 영덕군에 위치한 동대산은 곳곳에 절경을 숨기고 있는 지역의 명산이다. 타지에는 많이 알려지지 않았지만 경관이 뛰어나 발빠른 등산인들이 호젓한 산행을 즐기며 오염되지 않은 산채가 많아 약초꾼들이 은밀히 오가는 곳이다.향로봉 내연산 문수산의 디딤돌로 발판이 되어 잠깐 솟구처오른 동대산은 바데산을 머리에 이고 동서로 여러갈래의 골짜기를 만들어 놓고있다.서쪽 마실골과 북서쪽 경방골은 아직도 자연의 신비감을 그대로 간직하고 있는 절경의 골짜기들이다. 바데산 동대산 내연산 서쪽으로 길게 패인 하옥리 계곡은 경관이 배어나 여름이면 사람공해를 이룬다. 바데산에서 동대산으로 가는 날등길을 걸으며 드넓은 동해바다를 바라보는 눈망울도 쉽게 깜박여지지 않는다.하옥리 계곡에서 갈치기한 마실골은 기암절벽이 골 양옆에 솟구친 가운데 맑고 푸른 물이 소와 담에 담겨 있으며 골짜기와 산사면은 온통 울창 숲으로 우거져 있다. 골 깊숙히 들어가면 널다란 암반이 나타나고 때를 잘 마추어 이 마실골에 들어서면 수백마리의 나비떼를 만나게 된다.동대산 일원은 동해의 습한 기운과 서쪽의 차가운 기운이 맞닿아 안개가 자주 낀다. 때문에 이곳 지형을 잘 알지 못하는 이들은 특히 봄철 안개가 자주 낄 때 조심해야 한다.경방골과 물텀벙이골은 골이 깊고 바위와 절벽이 어우러져 누구든 이 골짜기를 들어오면 한여름에는 담소에 몸을 던지기 일수이다. 여름산행은 바데산으로 올라가서 동대산을 거처 후줄근하게 땀으로 샤워를 한몸 경방골로 내려오며 말끔히 헹궈내는 방법도 솔솔한 재미가 있다.", - "MNTN_HG_VL" : "791", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영덕군", - "MNTN_NM" : "동대산" - }, - "longitude" : 129.28397870000001, - "latitude" : 36.310201900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 제천시 금성면, 청풍면 교리·단양군 적성면 경계에 솟은 동산(東山)은 남근석으로 유명하다. 이 남근석이 동산을 대표한다 해도 과언이 아니다. 어른 두 세 명이 팔로 에둘러야 할 정도의 굵기와 약 3미터 높이의 크기를 자랑하는 남근석은 동산의 생명력과 원천의 상징이기도 하다. 대체로 산세가 가파르나 수려하며 동산을 지키는 수많은 기암괴석은 노송과 어우러져 운치를 더한다. 동산의 정상은 원래 세 개의 봉우리를 형성하고 있어 삼봉(三峰)이라 불렸다고 한다. 북으로는 작성산(848m), 마당재산(661.2m), 호조산(475.3m)의 산줄기를 이어받아 솟은 동산은 남으로는 금수산(1015.8m)을 빚는다.", - "MNTN_HG_VL" : "896", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면, 청풍면·단양군 적성면", - "MNTN_NM" : "동산" - }, - "longitude" : 128.22666670000001, - "latitude" : 37.024722200000006 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "융단같은 능선길을 마음대로 달릴 수 있는 산이 부산광역시의 근교에 터잡고 있다. 김해 백두산 동신어산 종주능선이 바로 이 같은 곳이다. 이 종주능선길은 부드러우면서도 아기자기한데다 산악동호인들의 발길조차 전혀 닿지 않아 근교의 새로운 워킹산행지로 인기를 끌기에 충분하다.백두산 동신어산 종주능선상에서는 또 부산을 둘러싸고 있는 산군의 능선을 모 두 조망할 수 있다. 금정산 주능선길은 물론 영남알프스의 남쪽능선, 낙동 낙남정맥상의 산군, 그리고 김해 무척산 물금 오봉산 원동 토곡산 울산 원효, 천성산 등 동부경남의 크고 작은 산을 눈으로 확인할 수 있다.", - "MNTN_HG_VL" : "460", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해 상동면", - "MNTN_NM" : "동신어산" - }, - "longitude" : 128.92087570000001, - "latitude" : 35.270207599999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 영월에 화채봉과 구룡산 사이에 솟아 있는 된불데기산은 위험지대가 없고 묵밭지대 초원이 산재해 있어 가족산행지로 안성맞춤이다.된불이란 말은 사냥꾼들이 쓰는 용어로 급소를 맞힌 총알을 일컫는데 전에 이 산에 멧돼지가 많아 마을 주민들이 멧돼지 사냥을 하면서 된불데기 산이라 불렀던 것이 산 이름의 유래가 되었다. 사람들 발길이 뜸하여 기름진 땅에서 자란 약초들은 유난히 향이 진하다.정상에 서면 북으로 화채봉과 삿갓봉 오봉산이 펼쳐져 있고 동으로는 백덕산이, 남으로는 구룡산이 시야에 들어온다.서쪽으로는 운학천 계곡 건너로 배향산이 멀리의 치악산 비로봉과 매화산 등과 함께 조망된다.", - "MNTN_HG_VL" : "910", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", - "MNTN_NM" : "된불데기산" - }, - "longitude" : 128.2186111, - "latitude" : 37.347499999999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "춘천 소양호에 에워싸인 두루봉은 오랜 세월 등산인들을 등지고 있어 태고적 자연 상태 그대로를 보존하고 있는 산이다.바위지대와 굴참나무숲, 낙엽송숲길을 지나 정상에 이르면 확 트인 조망에 가슴까지 시원해지는 기분이다. 북으로는 마적산 오봉산 부용산 봉화산이 한눈에 들고 동으로는 사명산 바위봉 곧은봉 가리산이 소양호에 산영을 담그고 있다.", - "MNTN_HG_VL" : "1226", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "두루봉" - }, - "longitude" : 128.64944439999999, - "latitude" : 37.572222199999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "두류산은 강원도 화천군 사내면과 하남면 사이에 위치한 산으로 위도상 38도선 북방 12km거리에 자리하고 있어 민간인들의 출입이 뜸한 곳이다. 그래서 백마계곡의 수려한 계곡미와 울창한 수림, 기암절벽이 이룬 아름다운 조화를 그대로 간직하고 있다.백마계곡에는 대명사와 신선바위 등이 있고, 청정지대로 유지되고 있다. 계곡 물이 맑고 숲이 울창해 여름산행에는 제격인 산이다.정상은 운모가 섞인 광석토양이라 나무 한그루 풀 한 포기 없지만, 사방으로 펼쳐진 두류산의 주름진 자락을 한눈에 볼 수 있다.금강산을 찾아가던 신선들이 이 산 경관에 반해 잠시 머물다 갔다는 전설이 전해질 정도니 이 산을 직접 가보지 못한 사람들도 그 절경은 가히 짐작할 만 하다.마치 명월이가 누워 있는 옆모습 같다 하여 두류산이라 불리며, 마을 이름도 명월리이다.", - "MNTN_HG_VL" : "993", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면 하남면", - "MNTN_NM" : "두류산" - }, - "longitude" : 127.5457596, - "latitude" : 38.103257200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "993", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천", - "MNTN_NM" : "두류산" - }, - "longitude" : 127.5457596, - "latitude" : 38.103257200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "993", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면, 하남면", - "MNTN_NM" : "두류산" - }, - "longitude" : 127.5457596, - "latitude" : 38.103257200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "정읍에서 약 12킬로미터 떨어진 곳으로 갑오동학혁명의 진원지인 고부면 신중리 죽산마을에 동학혁명모의탑이 세워져 있다. 정읍시는 동학농민운동의 시발 지이자 주요무대다. 특히 고부면은 동학농민운동의 진원지로 모의탑이 세워져 있다. 덕천면의 황토현 전적지(사적 295)를 중심으로 고부관아터, 만석보터, 전봉준 고택지(사적 293) 등 많은 관련 유적이 있다.이 산은 정읍시와 고창군 일대는 물론 내장산, 방장산, 입암산 등 명산이 한눈에 들어오는 확 트인 전망이 유명한 산이다. 정상에는 넓은 공간에 큰 바위와 나무와 초지가 서로 어우러져 휴식을 취하기에 좋다.두승산 이름의 유래는 옛날 고부관아에서 도량형의 기준이 되는 말(斗)과 되(升)를 돌로 만들어 고부군의 진산인 이 산의 남쪽 봉우리(말봉) 바위 위에 설치해 놓았다. 이후 사람들은 이 산을 ‘말과 되가 있는 산’ 이라 하여 두승산이라 부르게 되었다.정상부에는 작은 봉우리가 몇 개 있는데, 세 번째 봉우리가 정상이고 네 번째 봉우리가 말봉이다. 두승산 주위로는 동학혁명에 관한 역사 유적지가 많다. 특히 고부면은 동학농민운동에 앞장선 전봉준 고택지(사적 293) 등 많은 관련 유적이 있어 산행 후 역사 공부를 겸해 둘러봄직 하다.", - "MNTN_HG_VL" : "444", - "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 고부면ㆍ덕천면ㆍ소성면", - "MNTN_NM" : "두승산" - }, - "longitude" : 126.7980117, - "latitude" : 35.606852199999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "사북읍 뒤편에 있는 강원 정선 두위봉은 탄광으로 널리 알려져 있지만 최근에는 초여름 철쭉산행지로 각광받고 있다. 이 산에는 빽빽하게 군락을 이룬 철쭉지대가 수만 평이 넘도록 펼쳐져 있어 마치 연분홍 양탄자가 깔려있는 듯한 착각에 빠진다. 탁 트인 시야와 초원지대 한 가운데 고인 맑은 연못, 수령 1천 8백년을 자랑하는 국내 최고의 주목, 깎아지른 듯한 절벽 등 갖가지 절경도 접할 수 있다.두위봉은 산이 두루뭉실하다 하여 ‘두리봉’으로도 부른다. 특이한 것은 정상이 주능선의 1킬로미터 거리에 두 개가 있다. 삼각점이 있는 봉우리가 정상이었는데, 철쭉기념비를 세워놓은 바위로 된 봉우리가 경관이 더 좋아 1999년 이곳에 정상 표지석을 세웠다고 한다.자미원이나 함백마을에서 올라가면 만나는 능선의 아라리 고개에서 도사곡으로 갈라지는 사이의 주능선과 계곡의 등산로가 울창한 산림으로 우거져 있다. 정상에서 아라리 고개 사이에 참나무 군락지, 도사곡 및 자미원에서 오르는 등산로 주위에 자작나무 군락지가 있고 도사곡에는 국내에서 나이가 가장 많다는 주목나무가 있다.", - "MNTN_HG_VL" : "1470", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면, 사북읍·영월군 중동면 직동리", - "MNTN_NM" : "두위봉" - }, - "longitude" : 128.7534191, - "latitude" : 37.212416400000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "두타산은 진천군 초평면, 괴산군 도안면과 증평읍의 경계를 이루고 있으며, 능선이 마치 부처가 누워있는 모습을 하고 있다. 진천의 상산8경 중 하나인 고찰 영수사를 산자락에 품고 있으며 은은한 종소리와 함께 아름다움을 간직한 명산으로 손꼽힌다.두타산 정상엔 삼국시대에 축조된 것으로 추정되는 석성이 자리하고 있는데, 길이 1킬로미터, 높이 1.2미터의 규모로 성내에는 두 개의 우물터가 있으며, 이따금 통일신라시대의 토기편과 기와 조각 등이 발견 되고 있으며 고려 시대의 유물도 출토된 적이 있다.두타산이란 산 지명은 단군이 팽우에게 높은 산과 냇물 등 산천을 다스리게 했는데, 그때 하루도 빠짐없이 비가 내려 온 산천이 모두 물에 잠기게 되자 사람들이 높은 곳으로 피난을 가야했다. 이때 팽우는 이 산에 머물게 되었고 산꼭대기가 섬처럼 조금 남아 있었다고 하여 두타산이라 이름 지었다고 한다.두타산의 산행기점은 진천 쪽 초평저수지에서 영수사를 거쳐 오르는 길과 대평주유소 전 동잠교에서 계곡을 따라 큰재로 오른 후 북동쪽 능선을 타고 정상에 오르는 길이 자주 이용된다. 이외에 증평읍 자양마을에서 오르는 길이 있지만 접근이 어렵고 능선을 넘어 다시 계곡으로 떨어져야하므로 거의 이용되지 않고 있다.", - "MNTN_HG_VL" : "599", - "MNTN_LOCPLC_REGION_NM" : "충북 진천군 초평면, 괴산군 도안면, 증평읍", - "MNTN_NM" : "두타산" - }, - "longitude" : 127.5661554, - "latitude" : 36.830412799999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "둔덕산은 문경팔경의 하나인 용추를 품고 운강 이강년 선생의 탄생설화가 얽힌 산이다. 백두대간이 조항산을 지나면서 동쪽으로 가지를 쳐 만들어진 둔덕산은 멋진 경승지를 품고 있음에도 근처의 대야산이나 희양산의 명성에 가려져 아직까지 호젓한 산행을 즐길 수 있는 문경의 숨은 명산이다.둔덕산이 있는 가은읍 완장리 자락에는 이 산의 자랑거리가 집중되어 있는데 괴선의 외선유동에 비견되는 용추를 품고 있는 내선유동계곡과 이강년 선생의 생가터, 조선조 이재 선생의 후학들이 그를 기려 세웠다는 학천정 등 유서 깊은 정자가 그것이다. 따라서 둔덕산 산행은 볼거리가 풍부한 완장리를 기점으로 원점회귀 하는 코스를 가장 추천할 만하다.둔덕산은 국운이 위태롭던 한 말에 일본 침략자에 항거 경상도, 충청도, 강원도에 걸쳐 13년간 오로지 의병대장으로서 활동하고 순국한 전국도창의대장 운강 이강년 선생 탄생과 관련 있는데, 이강년 선생이 태어나기 3일전부터 둔덕산이 ‘웅웅’ 소리를 내며 울었다고 한다. 당시 사람들은 둔덕산이 우는 것은 처음 있는 일이라고 하며 신기해했으나 운강 선생이 태어나자 울음을 그쳤다고 한다.", - "MNTN_HG_VL" : "970", - "MNTN_LOCPLC_REGION_NM" : "경북 문경시 가은읍, 농암면", - "MNTN_NM" : "둔덕산" - }, - "longitude" : 127.9733714, - "latitude" : 36.651080700000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "둔지미산은 충북 단양군 어상천면과 가곡면 사이에 아담하게 솟아오른 봉우리로 삼태산(876m)에서 남한강으로 뻗은 능선상의 가장 끄트머리에 있는 산이다.이 산이 소재한 단양에는 비경지대가 많아 신단양 8경이 등장했다. 그 중 하나가 절벽기암이 병풍을 두른 듯 비경을 이룬 영춘 북벽인데 이 보다 두배나 높은 수직절벽의 비경지대가 바로 둔지미산의 노갈봉이다.노갈봉은 노인이 갈잎으로 만든 도롱이를 쓰고 남한강물에 낚시대를 드리운 산세를 하고 있다고 해서 붙여진 것이라고 전해진다.노갈봉 정상에 이르면 멀리 북동쪽으로 태화산과 영춘, 마대산이 보이고 발 밑으로 푸른 남한강이 내려다 보인다. 무더운 여름날에는 노갈봉에서 웃통을 드러낸채 발밑에 보이는 강물로 뛰어들어 한바탕 헤엄을 치고싶은 생각이 절로든다. 그렇다고 수직절벽에서 뛰어내리는 것은 둔지미산 명예드럽힌죄로 적용될 지도 모른다. 고개를 쪼금들어 강너머를 보면 용산봉이 방끗이 웃고있다.", - "MNTN_HG_VL" : "650", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "둔지미산" - }, - "longitude" : 128.40333330000001, - "latitude" : 37.059166699999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "둔철산은 황매산에서 흘러내린 능선이 정수산을 거쳐 경호강에 산자락을 내리면서 우뚝 솟아있는 산이다. 산청읍과 신안면, 신등면 사이에 있으면서 웅석봉과 마주하며 철을 생산했다는 전설을 갖고 있다. 그러나 둔철(屯鐵)이라는 지명은 생산보다는 보관했다는 말에 더욱 설득력이 있다.산 동쪽 해발 500미터에는 넓은 분지가 조성되어 있어 대단위 목장과 농장으로 활용하고 있다. 서쪽으로는 산청시내가 내려다보이고 경호강을 사이에 두고 왕산 및 칠봉산과 웅석봉이 병풍처럼 펼쳐져 있다.동쪽은 사정천이 흐르며 북쪽은 철쭉으로 유명한 황매산과 수려한 암군으로 각광받고 있는 모산재가 둘러싸고 있는 산이다. 정상에 서면 사방 막힘이 없고 지리산에서 가지내린 수많은 산군을 조망할 수 있어 가슴이 후련하다.범학에서 계곡을 따라 오르면 와폭과 깨끗한 담과 소가 오염되지 않아 좋다. 그러나 길이 희미해서 한여름이면 오르기 힘들다. 척지에서 오를 수 있고 정취암에서 능선을 타고 대성산~둔철산으로 갈 수 있으나 여름보다 겨울에 산행하는 것이 적당하다. 정취암은 의상대사가 창건했으며 문가학이라는 도인이 여우로부터 둔갑술을 배웠다고 전해온다.", - "MNTN_HG_VL" : "812", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 산청읍 척지리", - "MNTN_NM" : "둔철산" - }, - "longitude" : 127.9456586, - "latitude" : 35.387092799999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "고흥읍에서 율리치를 지나 고개를 넘어 송정리로 들어서면 천등산과 벼락산이 한눈에 든다. 천등산 정상부와 함께 겹쳐 보이는 바위산이 그 앞에 보이는데, 이 산 이름은 딸각산이다.바위를 밟고 오르노라면\"딸각딸각\"소리가 난다 해서 그곳 주민들은 그렇게 부른다고 한다. 그러나 옛 기록에는 월각산(月角山)이라 기록하고 있다.\"딸각\"이\"달각\"으로, 달각이 월각으로 변한 것이다. 산행은 산 중턱을 가로 넘는 임도가 세 가닥이 나 있어 어떤면에서는 쉽게 오를 수 있는 산이지만 임도 때문에 오히려 산행의 맛이 덜할 수도 있다.", - "MNTN_HG_VL" : "420", - "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", - "MNTN_NM" : "딸각산" - }, - "longitude" : 127.2780763, - "latitude" : 34.541848000000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "우리나라에서 다섯번째로 큰 섬인 강화도에는 고려산, 혈구산, 진강산, 마니산 등 400m 이상의 4개산이 남북으로 일직선상에 솟아 있는데 그 중 제일 높은 산이 마니산이다. 〈고려사〉〈세종실록지리지〉〈태종실록〉 등 조선 초기에 발간된 문헌에는 머리산, 우두머리산이란 뜻의 마리산(摩利山) 또는 두악(頭嶽)으로 쓰여 있다. 그래서 지금도 마리산이라는 이름을 혼용해서 사용하고 있지만, 오랫 동안 마니산이라 불러왔는데 새삼 마리산이라고 하여 혼동을 줄 필요는 없을 것같다.마니산은 비교적 낮고 수도권에 가까운 거리에 있어 친정을 찾는 기분으로 편하게 찾을 수 있다. 해발이 낮더라도 주능선이 암릉으로 되어 있으니 등산의 묘미도 한껏 만끽할 수 있는 산이다.동남으로 가느다랗게 뻗은 능선을 따라 오르다 보면 망망한 서해를 조망할 수 있다. 조국순례 안내판이 있는 '개미허리'에서 98개의 계단길을 올라가면 사적 제 136호인 '참성단'(塹星壇)을 만날 수 있다. 이곳에서 매년 개천절과 전국체전때마다 성화가 채화된다. 참성단은 단군 왕검 재위 51년(BC2283년)에 운사(雲師)인 배달신(倍達臣)이 마리산에 쌓은 제단으로, 〈삼국사기〉에 의하면,고구려.신라.백제의 여러 왕들이 이 곳에서 하늘에 제사를 지냈다. 고려 공민왕 때와 조선 인조.숙종 때 각각 보수되어 현재 이른다. 이 단은 화강석을 쌓아올려 만든 것으로, 밑부분은 둥글고 윗부분은 사각형이며, 높이가 총6m에 달한다. 참성단 위에 오르면, 동쪽으로 정상이 손에 잡힐 듯 가깝게 보이고, 남쪽 아래로는 푸른 물결이 넘실거리는 넓은 바다가 발아래로 펼쳐지고, 동남쪽 멀리 인천시가지가 아득히 보인다.정상 서쪽 산기슭에는 신라 선덕여왕 8년(639년)에 창건했다는 정수사와 함허대사(涵虛大師)가 수도하였다는 함허동천이 자리잡고 있다. 함허동천에는 1백여m의 암반위로 물이 흐르고, 암반에는 함허대사가 새겼다는 '涵虛洞天'(함허동천)이란 글자가 음각 되어 있다. 외침을 자주 받았던 고려가 부처의 힘으로 나라를 지켜 보려고 강화도에서 크게 불사를 펼쳤던 까닭인지 강화도에는 내력 있는 절이 많다.", - "MNTN_HG_VL" : "472", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 화도면", - "MNTN_NM" : "마니산" - }, - "longitude" : 126.434827, - "latitude" : 37.611603000000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "마니산에는 거대한 바위성 같은 바위절벽을 안고 선 향로봉이 있다. 수려한 산세를 가졌지만, 아직도 이 산을 찾는 이가 그리 많지 않다. 바로 서쪽에 영동의 명산 천태산의 명성에 가려져 있기 때문이다.향로봉의 동면 아래에 있는 중심이 마을쪽은 좌우가 모두 깍아지른 바위벼랑이며 향로봉 둘레 575봉과 564봉의 남면 모두가 엄청난 높이의 낭떠러지를 이루고 있어 장관이다. 전체적인 마니산의 지형은 한 마리의 문어가 금강을 향해 발을 뻗친 모양이다. 그 발 끝에는 어류산, 시루봉, 노고산, 봉화산, 동골산이 있다. 동면에는 마니산 성터와 공민왕의 거처였다는 절터가 있다. 마니산 능선에서 고려 공민왕때 홍건적의 난을 피해 들어 왔을 때 쌓은 산성벽이 지금도 남아있다.", - "MNTN_HG_VL" : "469", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군, 옥천군", - "MNTN_NM" : "마니산" - }, - "longitude" : 127.6519444, - "latitude" : 36.171666700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "마대산은 우리나라의 마지막 비경지대를 간직한 산으로 강원도 영월군 하동면과 충북 단양군 영춘면의 경계를 이루고 있다. 마대산 서쪽 아래로는 고씨동굴 앞을 흐르는 남한강의 수려한 풍광과 북으로 흐르는 옥동천이 남한강으로 합수되어 보기드문 비경을 연출한다.이 산이 특히 유명해 진 것은 조선의 방랑시인이자 풍자시인인 김병연 속칭 김삿삿이 숨어 살던 터에 복원한 집과 무덤 등 유적이 있기 때문이다. 한 여름이면 자연과 위대한 시선의 흔적을 밟으려는 외지인들로 붐빈다", - "MNTN_HG_VL" : "1052", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 충청북도 단양군 영춘면", - "MNTN_NM" : "마대산" - }, - "longitude" : 128.573329, - "latitude" : 37.087678099999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "385", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "마래산" - }, - "longitude" : 127.7422222, - "latitude" : 34.763611099999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "전라남도 고흥군은 보성에서 끝날듯하던 한반도 남단이 벌교를 지나 계속 남쪽으로 내달으면서 형성된 반도를 이룬 군이다. 때문에 고흥 하면 바다만 보일 것만 같은 선입견을 갖기 마련이다.하지만 실제 고흥땅을 밟으면 해발 500~600m대 높이의 산들이 수없이 많다는 사실을 깨닫게 된다. 말이 엎드려 있는 형상이라는 이름을 갖고 있듯 마복산은 해창벌에서 바라보면 그저 동서로 길 게 뻗은 동네 뒷산처럼 평범하게 느껴진다. 하지만 파고들면 생각지도 못했던 모습에 마음을 빼앗기고 만다. 산등성이에는 수많은 지릉이 흘러내리고 그 지릉마다 바위꽃이 활짝 피어 있어 마치 금강산이나 설악산의 축소판을 보는 듯하다. 이러한 경관 때문에 마복산은 소개골산(少皆骨山)이라 불리기도 한다.마복산이 지닌 또 하나의 자랑거리는 다도해 전경이다.산 남쪽 바다는 다도해 해상국립공원으로 지정되어 있을 만큼 아름다운 곳이다. 산 등성이에 올라 푸른 바다 위를 떠다니는 듯한 올망졸망한 섬들 부드러운 선으로 이어지는 해안선과 그 사이사이 들어앉은 포구를 바라 보노라면 보는 이마저도 바다에 떠 있는 듯한 느낌에 사로잡히고 만다.", - "MNTN_HG_VL" : "539", - "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", - "MNTN_NM" : "마복산" - }, - "longitude" : 127.3888716, - "latitude" : 34.536739400000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "마산은 백두대간의 남한쪽 분단이다. 강원도 고성군 간성읍과 토성면의 경계에 위치하고 있는데 북으로 더 이상 나가지 못하고 있어 아쉬운 마음이 든다.현재는 대단위 종합레져타운을 기슭에 품고 있는 화려한 산이 되었지만, 예전에는 고원의 넉넉한 평원을 굽어보는 수수한 산이었다. 동쪽으로 끝없이 펼쳐진 바다와 함께 호수의 조망이 일품이다. 날씨가 좋을 경우 진부령에서 향로봉, 비로봉을 비롯한 금강산 연봉까지 아슴푸레하게 볼 수 있다.마산과 신선봉은 능선으로 바로 연결이 되있으며 알프스 스키장이 산행 초입리가 되어 겨울철에는 알프스 스키장까지 이동하는 차편이 무궁무진하여 교통은 어렵지 않다. 신선봉은 백두대간 종주 등산로에서 약간 동쪽으로 벗어나 있는 봉우리다. 너덜이 깔린 신선동 정상에 서면 동해와 신평벌, 설악산이 한눈에 들어온다. 두 산을 종주 하거나 거꾸로 미시령에서 시작해서 알프스 스키장으로 하산할 수 있다.", - "MNTN_HG_VL" : "1052", - "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 간성읍", - "MNTN_NM" : "마산" - }, - "longitude" : 128.47333330000001, - "latitude" : 38.403611099999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 중원 상모면과 괴산 연풍면 그리고 문경읍과 경계를 이루는 마역봉(馬驛峰)은 임진왜란때 신립장군의 한이서린 조령삼관문을 안고 있는 산이다.주말 산행 코스로 인기를 누리고 있는 신선봉(967m) 동쪽 1.5km 거리에 독립봉으로 우뚝 솟은 마역봉은 927m 의 높이에 비해 의외로 쉽게 오를수가 있다. 출발지점인 지릅재가 표고가 해발 650m 이기때문이다.산행의 들머리는 조령삼관문에서 오르거나 신선봉을 경유해도 되고 또 다른 코스는 소조령 3번 국도에서 고사리 마을을 지나 조령산 휴양림 매표소에 도착한 후 매표소에서 삼관문쪽 길을 따라 50m쯤 가면 급커브를 돌면서 왼쪽으로 훤히 뚫린 산길이 보이는데 여기가 신선봉과 마패봉의 중간능선으로 오르는 등산로다.산길을 접어들면 200여미터 거리에 비닐포장 가건물을 지어 놓고 밤낮없이 정성을 드리는 장소가 있는데, 바위 위로는 10여미터 폭포가 흘러내려 장관을 이룬다. 길은 폭포의 오른쪽 반석을 타고 올라 계류를 건너 물길을 따라 오르게 되는데 계곡이 v자 모양의 협곡으로 물이 흐를 때는 장관을 이룬다. 계류 옆으로 난 바위를 따라 조금 더 오르면 왼쪽으로 거대한 바위가 나타나는데 이것이 바로 치마바위이다.바위의 동쪽끝에서 바라보고 있노라면 그 끝자락은 분명히 곱디고운 여인이 치마가 땅에 닿을까봐 조심스레 치마폭을 추스리고 있는 것 같은 모습처럼 느껴진다. 혹시나 여인의 속살이라도 보일 것 같아 겸연쩍어진다. 마역봉은 뚜렷한 정상이 없이 50여미터 더 가면 전망대가 나오는데 월악산을 중심으로 한 북바위, 수리봉, 덕주봉, 만수봉, 포암산등 바위산의 진면목을 보여준다. 단순히 마역봉을 등산하기보다는 신선봉과 함께 등산하는 것이 일반적이다.소요 시간 :약 2시간 20분 소요최적 탐방 시기 : 9월 \/ 가을(단풍)볼거리 : 문경새재, 용유담, 신선봉, 각연사, 고산구곡, 화양동구곡숲길 명소 : 치마바위, 남쪽 계곡의 오솔길", - "MNTN_HG_VL" : "940", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 충주시 상모면", - "MNTN_NM" : "마역봉" - }, - "longitude" : 128.03113740000001, - "latitude" : 36.753807299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 이천시는 광주산맥의 줄기가 뻗어내려 북부에 여러 구릉을 기복시키고, 남부는 차령산맥에 연접하므로 북 서쪽은 산맥들로 이루어져 높고, 남동쪽은 점점 낮아진다. 북서쪽은 천덕봉(630m), 정개산(461m), 양각산(386m), 설봉산(394m), 건지산(411m), 마옥산(445.4m) 등이 솟아 있으며, 남동쪽에는 마이산(472m), 팔성산(378m), 백족산(402m) 등이 뻗어 있다. 중앙부에는 복하천이 남한강으로 흘러 들어가며 남동부에는 청미천이 음성군과 경계를 이룬다.마옥산은 마국산, 마고산, 마곡산 등으로 불리우기도 하며 여러 문헌을 통해 옛날에 오음산이라 부리웠음을 알 수 있다. 마옥산은 산이 중첩되고 험준하며 골이 깊기로 으뜸이다. 모가면 서쪽에 위치해 동남쪽은 설성면 서남쪽은 안성군 일죽면과 경계를 이루는데 굴바위, 병풍바위, 말바위, 구모바위등 유서 깊은 전설을 간직한 기암괴석들이 산재해 있고 군내 제일의 산간부락인 산내리. 대죽리등이 기슭에 위치해 있다. 또 복잡하게 얽힌 산줄기로 인해 사람이 되고 싶은 여우와 마옥산 99골짜기의 전설이 전해 내려오기도 한다.이산에는 안양사라는 대찰이 있었다고 하나 폐사된지 오래되어 지금은 그 정확한 위치조차 알 수 없고 마국산의 일맥인 소고리 서쪽 산골짜기에는 동쪽을 향한 넓은 바위 면에 뛰어난 솜씨로 선각된 마애여래좌상과 적극적이고 과장된 표현이 눈길을 끈 마애삼존불상이 있으며 조선시대 백자요지, 폐사지에 방치된 채 남아있는 부도 등의 유적이 있다.마국산의 심장부가 되는 산내리 서쪽산기슭에는 중종때 우의정을 지낸 영창부원군 권균의 묘소와 신도비가 있고 산내리 마을상단에 그의 사묘가 있다.서울에서 그리 멀지 않고, 인파도 붐비지 않는 호젓한 산행지로 각광을 받고 있는 곳이다. 수목이 울창하고 수려한 계곡과 기이한 암봉이 있는 산은 아니지만, 영창대군의 초라한 능묘와 사연이 있는 듯한 산속의 빈집이 특이한 점같아 보이며 때묻지 않고 깨끗한 산이라 좋다.", - "MNTN_HG_VL" : "446", - "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 일죽면 고은리", - "MNTN_NM" : "마옥산" - }, - "longitude" : 127.450046, - "latitude" : 37.167619700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "마이산은 옛날 용출산, 동금산 등으로 불려 오다가 이조때 태종이 말 귀를 닮았다고 한 뒤부터 마이산이라 칭하게 됐다. 재미있는 것은 마이산은 바라보는 방향에 따라 그 모습이 달라 보인다는 것이다.그래서 마이산의 기이한 모습과 특이한 경관 때문에 여러 가지 이름을 갖고 있다. 붓끝같다해서 문필봉, 바위가 많아서 개골산, 방향을 달리해 보면 돛대를 닮아 돛대봉, 용의 뿔 같다해서 용각봉 등으로 불려진다.마이산은 동서로 큰 암수봉우리 두개가 있다. 동편 숫봉우리는 거대한 남성을 닮았다 하여 서다산(西多山)이라는 옛 이름도 지니고 있는데, 강한 양기를 품고 있어 산길이 험준하여 등산을 할 수가 없다. 서편에 있는 암마이봉은 나긋나긋하게 손짓하는 여성처럼 많은 등산객을 맞이하고 있다. 마이산에서 북쪽으로 흐르는 물은 금강 물줄기를 이루고, 남쪽으로 흐르는 물줄기는 섬진강으로 흐른다. 그 흐름이 반원을 그리고 있어 마이산은 금강과 섬진강의 분수령이 되고 있으며 두 강의 물줄기는 마이산을 중심으로 태극을 이루고 있다.마이산은 조선을 개국한 이성계와 인연이 깊은 산이다. 이성계는 마이산을 속금산(束金山)이라 불렀다. 일찍이 큰 꿈을 품었던 이성계는 금산 등 전국 각지의 명산을 찾아 기도를 올렸는데, 기도가 끝난 어느 날 밤 꿈에 신이 나타나 금척(모든 제도의 표준임을 말하며를 마음대로 헤아리도록 하라\"\"라고 했다 한다. 그 뒤 고려 우왕 6년(1380년) 고려의 장군 이성계는 전라도 운봉땅 황산에서 왜구를 무찌르고 개선 길에 마이산을 보고 놀랐다. 꿈에 신에게서 금척을 받은 장소가 바로 마이산이기 때문이었다.", - "MNTN_HG_VL" : "687", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍ㆍ마령면", - "MNTN_NM" : "마이산" - }, - "longitude" : 127.404811, - "latitude" : 35.762177399999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "청평사라는 명찰을 품은 오봉산의 남쪽에 자리한 산이다. 북쪽으로 오봉산(779m)과 연결되어 있고, 동쪽으로는 봉화산(736m)과 맞대고 있다. 마적산은 오봉산의 주능선이 서남쪽으로 나가다가 정남 방향으로 꺾이면서 최고봉인 785고지를 만들고 일직선으로 뻗어 내려가면서 크고 작은 여러 개의 봉우리를 일구고 있다. 마적산 산행의 백미라 하면 하산을 하면서 소양호를 감상 할 수 있다는 것이다.능선에는 주로 떡갈나무, 상수리나무 같은 참나무류가 숲을 이루고 있으며 도중에 무수한 칡덩쿨과 드룹나무 군락이 있다. 정상에서는 춘천시와 시가지를 가로지르는 소양강이 눈에 들어온다.", - "MNTN_HG_VL" : "610", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신북읍, 북산면", - "MNTN_NM" : "마적산" - }, - "longitude" : 127.79229549999999, - "latitude" : 37.952335800000007 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "311", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구", - "MNTN_NM" : "마집봉" - }, - "longitude" : 126.9480556, - "latitude" : 35.109999999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "274", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군, 경상북도 칠곡군", - "MNTN_NM" : "마천산" - }, - "longitude" : 128.46111110000001, - "latitude" : 35.899722200000006 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만덕산은 완주군 소양면 화심에서 진안으로 가는 구 도로에 우뚝 솟아 있다. 그리고 임진왜란 당시 왜군을 맞아 치열한 전투를 벌였던 역사적 전적지이며 6·25 때 공비 출몰이 심했던 곳 중 하나로 곰티재를 지키고 있는 수문장과 같은 곳이다. 만덕산은 한자로 일만 만(萬)과 큰 덕(德)을 써서 만인에게 덕을 베푸는 산이라는 뜻이다. 그 이름 덕분인지 주민들의 말에 따르면 수많은 전란을 겪으면서도 지역 주민들은 큰 화를 입지 않았다고 한다. 암봉과 육산으로 조화를 이루어 가을 단풍, 겨울 설경의 풍치가 한 폭의 그림과도 같다. 특히 이 산의 동남쪽 기슭에 자리 잡고 있는 미륵사 일대의 경관은 일품이며 바로 아래 높이 50미터의 만덕폭포와 그 주변의 풍광은 등산객들의 발길을 사로잡는데 부족함이 없다. 겨울철의 빙폭은 젊은 산악인들의 빙벽 훈련장으로 사랑을 받고 있다. 전주에서 가깝고 교통이 편리한데다 등산 코스가 다양하여 모악산 다음으로 전주시민이 즐겨 찾는 곳이다.", - "MNTN_HG_VL" : "766", - "MNTN_LOCPLC_REGION_NM" : "전북 완주군 상관면, 소양면", - "MNTN_NM" : "만덕산" - }, - "longitude" : 127.2724339, - "latitude" : 35.791643800000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "만덕산은 강진읍 남쪽에 위치한 높이 412미터의 야트막한 산으로 마을 뒷산처럼 보잘것 없지만, 산 안으로 파고들면 앙팡지고 아기자기한데다 능선에는 상당한 크기의 암석들이 많으며, 그윽한 정취마저 넘치는 산이다. 산기슭에는 천년고찰 백련사와 조선 말기의 실학자 다산선생의 실학정신이 깃들어 있는 다산초당 등 역사적 자취를 더듬어 볼만한 곳이 있어 등산과 유적지 답사를 겸한 산행으로 제격이다.산세 또한 부드러워 가족산행지로도 권장할 만하다. 바람재에서 석문사에 이르는 등산로는 사람들의 발길이 닿지 않아 잡목과 잡초가 등산로를 뒤덮고 있으나 이정표가 군데군데 설치되어 있어 산행하는 데는 큰 어려움이 없다. 백련사 주변으로는 천연기념물 제151호로 지정된 1500여 그루 동백나무가 1.3헥타르에 걸쳐 자라고 있으며, 특히 절 앞에 많이 모여 자란다.", - "MNTN_HG_VL" : "412", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 강진읍, 도암면", - "MNTN_NM" : "만덕산" - }, - "longitude" : 126.7438889, - "latitude" : 34.592222200000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "망경대산은 백둣대간의 상의 함백산을 모산으로 두위봉을 지나 질운산과 예미산을 지나 수라리재에서 잠시 능선을 가라앉았다가 다시 솟구친 산이다. 강원도 영월군 중동면과 하동면 경계를 이루고 있는 망경대산은 등반 경력을 가진 산악 동호인에게 조차 생소한 산이다. 10여년 전까지만해도 탄광이 들어서 있어서 산행지와 거리가 멀었다. 탄광이 빠져나가면서 이 산 인근의 산꾼들이 오르내리기 시작하여 지금은 등산로를 찾기가 수월해 졌다. 정상에 서면 남쪽으로 와석리 무릉계곡과 마대산 줄기가 장쾌한 파노라마로 펼쳐져 있고 멀리 선달산에서 소백산으로 이어지는 백두대간이 광활하게 펼쳐진다.망경대산의 산이름은 어린 단종이 숙부인 수양대군에게 왕위를 찬탈당하였다는 소식을 들은 충신 추익환이 산위에 올라 한양을 바라보며 눈물을 흘렸다는 데에서 유래되었다고 전해지며 영월 영모전에는 추익환이 단종에게 산머루를 진상하는 그림이 보관되어 있다.정상은 헬기장으로 이루어져 사방 막힘이 없이 좋은 조망을 보여준다. 북으로는 가리왕산 능선이 하늘금을 그리고 북동쪽으로는 예미산, 질운산, 두위봉으로 이어지는 능선이 보이고 동으로는 단풍산과 매봉산, 장산이 시야에 들어오고 그너머 태백산에서 선달산으로 이어지는 백두대간의 주능선이 한눈에 들어온다.남서쪽으로는 하동면 옥동리 마을이 분지처럼 보이고 산자락을 굽이치며 흐르는 옥동천이 그림같고 서쪽으로는 응봉산 방면으로 부드럽게 뻗은 능선이 시야에 들어온다.", - "MNTN_HG_VL" : "1088", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면", - "MNTN_NM" : "망경대산" - }, - "longitude" : 128.61972220000001, - "latitude" : 37.161388900000013 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "140", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "망마산" - }, - "longitude" : 127.6708675, - "latitude" : 34.754024100000002 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "통방산의 서쪽에 위치한 매곡산은 호젓한 맛이 일품이다. 주위에 통방산이 자리하며 청평가도를 따라가면 우측으로 고동산, 화야산, 뽀루봉의 줄기가 이어서 바로 바라다 보인다.산이 높지는 않지만 일반인들이 이 산의 존재를 잘 모르기 때문이다. 또한 사람들의 발길이 적어 나무들과 산을 흘러내리는 물이 별 방해를 받지 않고 살고 있다. 그래서 이 산을 오르다 보면 다른 산들에 비해 유난히 숲이 울창하고 계곡의 물소리 또한 나무들의 사색을 방해하지 않으려는 듯 조용조용 흐르는 것을 알게 된다. 요즘은 산을 즐기는 사람들에 의해 조금씩 알려지고 있다.", - "MNTN_HG_VL" : "507", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면", - "MNTN_NM" : "매곡산" - }, - "longitude" : 127.39749999999999, - "latitude" : 37.6211111 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두산에서 남하하는 백두대간이 금강산 북쪽 분수령부근에서 서남쪽으로 한북정맥을 내주었는데 이 정맥은 휴전선을 넘어 대성산과 백운산을 솟구치고 서울의 진산인 삼각산으로 달려가다가 동남쪽으로 갈래친 줄기위로 이 매봉을 빚어놓았다. 매봉의 북쪽으로는 전패봉과 명지산이 있고 남으로 깃대봉(910m) 대금산(704m)이 보이며 동쪽에는 칼봉산(900m)이 나란히 앉아 있다.매봉은 바위지대가 많아 험준한 산으로 사전에 코스 선택에 신중을 기해야 한다. 특히 6.5km에 달하는 회목고개에서 승안리에 이르는 코스는 초행자가 오르기에는 다소 힘든 거리다. 하산은 회목고개로 내려오는 것보다 정상에서 서쪽능선 길을 따라 마일리로 내려오거나 깃대봉쪽 갈림길에서 마일리로 내려가야 힘이 덜 든다. 하지만 힘들게 오른다 해도 정상에서 만나는 시원한 조망 앞에서 누구나 산행의 피로를 잊게 된다.", - "MNTN_HG_VL" : "865", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 가평읍", - "MNTN_NM" : "매봉" - }, - "longitude" : 127.4158333, - "latitude" : 37.856666699999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "매봉산은 치악산국립공원 동남쪽 끝머리인 성남리 동쪽 선바위봉(1,001m)에서 감악산으로 이어지는 능선상의 최고봉이다. 감악산(945m)을 마주보고 있는 이 산은 예로부터 산삼이 발견되고 있는 산으로 유명하고 옛날 정상에서 매를 풀어 토끼와 꿩사냥을 하였다하여 매봉산이라 불리었다.치악산 국립공원 구역에서 살짝 비껴 앉은 이 산은 주변산에 비해 호젓한 산행을 즐길 수 있으며 겨울철에는 적설량이 많아 겨울산행을 즐기기에도 안성맞춤이다. 가을이면 치악산에서 매봉까지 병풍처럼 펼쳐지는 오색단풍이 일품이다.정상에 서면 북으로 당골계곡, 남으로 감악산, 동으로 사자산, 백덕산 등 주변 산악지대가 장관을 이루고 있다. 또 당골계곡 너머로 치악산 비로봉과 매화산이 단아한 자태를 드러낸다.", - "MNTN_HG_VL" : "806", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면, 영월군 수주면", - "MNTN_NM" : "매봉산" - }, - "longitude" : 128.12416669999999, - "latitude" : 37.274999999999999 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "영월군 동쪽 상동읍과 중동면의 경계를 이루는 매봉산은 정상에 오르면 사방으로 터진 시원한 조망이 일품이다. 산행기점은 아시내 마을이다. 아시내를 출발하여 멧둔골을 경유하여 정상에 오른 후, 서봉 - 남릉 - 원천계곡, 또는 849봉을 경유하여 주채마을로 내려선다.정상은 둥그스름한 토봉이며, 남쪽은 천혜의 절벽으로 이루어져 있고 , 북쪽은 부드러운 사면으로 이루어진 산으로 기암절벽에 어우러진 노송과 울창한 숲을 간직한 비경의 산이다.", - "MNTN_HG_VL" : "1095", - "MNTN_LOCPLC_REGION_NM" : "강원 영월 상동읍. 중동면", - "MNTN_NM" : "매봉산" - }, - "longitude" : 128.7738889, - "latitude" : 37.1438889 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "정상에서 서남쪽으로 능선이 이어지면서 치악산과 합해지고, 동쪽으로는 백악산과 마주보는 큰 산이다. 그 동안은 이웃한 치악산의 명성에 가려 세상에 알려지지 않았다.그러나 봄철이면 철쭉과 진달래가 붉게 물들어 여성적인 아름다움을 간직하고 있어 산행을 권할 만하다.옛날 신선이 살았다는 전설을 간직한 신선봉이 있다.(연중 입산 및 등산 불가 지역입니다.) 치악산 국립공원 내에 속하는데 치악산에 비해 찾는 이가 거의 없으니 의외로 호젓한 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "954", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면", - "MNTN_NM" : "매화산" - }, - "longitude" : 128.09777779999999, - "latitude" : 37.405833299999998 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 합천군 가야면에 위치한 매화산은 가야산국립공원에 속해 있으면서도 가야산의 유명세에 아직 빛을 발하지 못하는 명산이다. 흡사 금강산 축소판과 같은 산세에 날카로운 바위능선이 있는가 하면 울창한 상록수림이 녹색과 붉은색의 조화를 이루기도 한다.매화산은 가야남산·천불산이라고도 부른다. 가야산의 지맥으로 산세가 웅장하며 가야산에 버금가는 다양한 산세를 지니고 있다. 불가에서는 천불산으로 부르는데, 이는 천개의 불상이 능선을 뒤덮고 있는 모습과 같다고 하여 붙여진 명칭이다.단풍이 수려하려면 기암괴석이 발달돼야 하는데 매화산이 바로 그런 산이다. 암봉 사이사이에 단풍이 물들어 그 사이로 뚫린 등산로를 통과하는 산행의 묘미는 특히 일품이다. 봄이면 진달래꽃, 가을이면 붉게 물든 단풍이 절정에 이르고, 겨울이면 소나무 숲이 어울려 설경이 가히 천하제일의 절경을 빚어낸 찬탄을 금치 못하게 한다.", - "MNTN_HG_VL" : "1085", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 가야면", - "MNTN_NM" : "매화산" - }, - "longitude" : 128.09546739999999, - "latitude" : 35.773327199999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 홍천군 내면에 소재해 있는 맹현봉은 우리나라 최후의 오지라는 강원도 심산유곡으로 내린천변에 맹렬한 형상으로 솟아있는 산이다. 명현봉 서쪽에서 정상밑으로 난 운리동골은 커다란 암반과 소, 폭포가 어울어져 수려한 골짜기를 이루며 사방으로 뛰어난 경관을 갖추고 있다.이 산은 사람들의 발길이 닿지 않은 깊은 산이면서도 위험한 코스가 별로 없는데 지류가 여러갈래로 나눠져 있으므로 정상쪽으로 이어지는 주류를 잘 선택해야 한다. 특히 운리동골 입구를 지나 2km남짓 되는 곳에서 골이 오른쪽으로 크게 휘는 곳에서 길을 잃기 쉬우므로 유의해야 한다. 맹현봉 정상은 널찍한 헬리포트가 닦여 있는데 정상에서의 하산길은 두 갈래다.", - "MNTN_HG_VL" : "1214", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", - "MNTN_NM" : "맹현봉" - }, - "longitude" : 128.3197222, - "latitude" : 37.830833299999988 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "면산은 창말의 앞에 있다 해서 마을 사람들이 붙인 이름이다. 이 산은 사람들이 많이 찾지 않아 처녀림의 신비함을 간직하고 있으며 정상에서는 노루와 같은 야생동물들의 흔적을 쉽게 발견할 수 있다. 이 산 부근의 다른 산들도 여전히 사람들의 시선에서 벗어나 있어 훼손되지 않은 곳이 많다.정상에 오르면 대덕산, 매봉산이 뾰족하다. 금대봉, 함백산 중계탑 사이로 장산, 그 뒤로도 끝없는 산이 이어진다. 서쪽에 강원탄광이 위치하고 영동선(嶺東線)이 통리(桶里)를 넘어 동해시에 이른다. 낙동강 상류의 작은 지류가 발원한다.", - "MNTN_HG_VL" : "1245", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", - "MNTN_NM" : "면산" - }, - "longitude" : 129.09555560000001, - "latitude" : 37.100277800000008 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "명위산이 위치해 있는 충주시 동량면 하천리는 옛날에 토정(土亭)이 살았던 곳으로 `하천팔경 또는 개천팔경(開天八景)' 이라는 명소(名所)를 가지고 있으며, 풍수학적으로 화를 피할 수 있는 피난지로 알려진 곳이다. 이곳에 충주 호반과 어우러져 수석처럼 아름답게 솟아 있는 면위산에는 남쪽 능선에 2개의 옥녀봉이 있으며, 옥녀봉에는 물맛 좋은 약수가 있어 옛날 선녀들이 내려와 물맛과 이 곳의 경치를 즐기다가 하늘로 올라갔다는 전설이 전해지고 있다. 약수는 중탕과 상탕, 2곳이 있다.면위산은 옥녀봉으로 많이 불리우며 부산으로 불리게 된지는 얼마되지 않는다. 일제시대 때 지명정리를 하면서 동네사람들로부터 면위산(免危山) 이란 말을 며느리산으로 잘못 듣고 며느리 부(婦)자를 써서 부산(婦山)으로 잘못 쓰게 된 것이라고 한다. 이 산은 마을 이름을 따서 하천팔경(荷川八景), 또는 하늘을 연다는 뜻인 개천팔경(開天八景)이라는 명소들을 산자락에 거느리고 있어 산행의 즐거움을 배가시 키고 있다.", - "MNTN_HG_VL" : "780", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면", - "MNTN_NM" : "면위산" - }, - "longitude" : 128.05472219999999, - "latitude" : 37.041388900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "329", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시", - "MNTN_NM" : "명덕산" - }, - "longitude" : 127.1847222, - "latitude" : 36.426944399999996 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "명봉산은 작지만 오밀조밀한 맛이 있다. 능선에는 노송이 많고 때묻지 않은 채 유지되고 있으며, 산길은 점토질이 많아 걷는 촉감이 매우 좋고 포근한 분위기에 젖게 하는 매력적인 산이다.시골집 같이 정겨운 분위기의 염불암, 원시림처럼 우거져 침침하기까지 한 북릉의 숲, 신선과 사람이 바둑을 두었다는 신선바위, 수량이 풍부해 보기만 해도 시원한 계곡, 수령이 500년 가까이 된 커다란 느티나무 등이 곳곳에 흩어져 있어 이것들을 둘러보노라면 산에 오르내리는 일이 지겹거나 힘들지가 않다.", - "MNTN_HG_VL" : "599", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 문막", - "MNTN_NM" : "명봉산" - }, - "longitude" : 127.8568085, - "latitude" : 37.297361400000007 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "명성산은 서울에서 동북으로 84Km, 운천에서 약 4Km 거리에 위치해 있다. 산자락에 산정호수를 끼고 있어 등산과 호수의 정취를 만끽 할 수 있는 산이다.일명 '울음산'이라 불리기도 하는데 거기에는 안타까운 전설이 전해 내려오고 있다. 신라의 마지막 왕자인 마의태자가 망국의 슬픔으로 이 산에서 통곡을 하자 산도 따라 울었다 한다. 나라를 잃은 슬픔을 산도 알았을까. 그런 연유로 '울 명' '소리 성'자를 붙여 명성산으로 불리게 되었다는 것이다.산전체가 암벽으로 이루어져 산세가 당당하고 가파르며 가을이면 억새풀이 장관을 이룬다. 암릉과 암벽이 같이 형성된 산이라서 사시사철 다양한 풍경을 연출해 등산객들로 하여금 철따라 다른 느낌을 느끼게 해 준다. 정상은 민등봉이나 전망이 매우 좋으며, 남쪽으로 이어진 12봉 능선의 모습이 장쾌하다. 능선에서 우거진 억새풀밭을 오르락내리락 하는 사이에 지루한 줄 모르고 걷게 된다.", - "MNTN_HG_VL" : "922", - "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 갈말읍, 경기도 포천시 영북면ㆍ이동면", - "MNTN_NM" : "명성산" - }, - "longitude" : 127.3377243, - "latitude" : 38.1069751 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도에서 화악산(1,468.3m)에 이어 두 번째로 높은 명지산은 정상을 오를 수 있는 산으로는 최고봉이다. 거대한 산맥을 이룬 명지산은 산 크기만큼이나 등산로도 많이 있으나 어느 길이나 정상까지 3시간 이상 소요된다. 서울에서 가까운 곳에 있으면서도 아직 오염되지 않은 깨끗한 계곡과 울창한 수림을 간직하고 있다.가평천을 사이에 두고 화악산과 마주보고 있는 명지산은 정상을 기점으로 사방으로 산자락을 펼치며, 귀목봉, 사향봉, 백둔봉 등을 거느리고 있는 웅장한 산이다. 명지산의 울창한 수림은 일상에 지쳐 산을 찾는 이들을 포근히 감싸안는데 그 깊이를 가늠할 수 없다.사계절이 다 아름다운 명지산은 특히 봄에는 진달래와 쩔쭉이 온산에 흐드러져 봄날의 산행을 즐기는 이들을 황홀경에 젖게 만든다. 가을 단풍은 가평 팔경 중 제 4경으로 지정 되었다. 우리나라 가을 산은 어디나 아름답지만 명지산의 단풍은 수십년 묵은 고목과 기암괴석들과 조화를 이루어 더욱 더 깊이를 더 한다. 또한 겨울에는 적설량이 많아 설화가 장관을 이뤄 겨울산행을 나선 이들을 반긴다.명지산 입구인 익근리에서 약 1Km가량 올라가면 규모가 작은 사찰인 승천사가 나타나고, 이어서 2Km가량 더 가면 등산로 왼쪽으로 높이 6m에서 시원한 물줄기가 쏟아 내리는 명지폭포를 만나게 된다. 한여름 불볕더위도 식혀 버리는 명지폭포 아래 깊은 웅덩이는 옛날에 명주실 한타레가 다 들어갈 정도로 깊어 명지폭포로 이름이 붙여졌다 한다.", - "MNTN_HG_VL" : "1252", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ하면", - "MNTN_NM" : "명지산" + "DETAIL_INFO_DTCONT" : "전북 진안군 주천면과 정천면 경계에 우뚝 솟은 구봉산(九峰山)은 아홉 개의 봉우리가 시원한 조망을 보여주는 전망 좋은 산이다. 주봉인 천황봉(장군봉)과 8개의 봉우리는 설악산의 공룡능선처럼 험준하게 솟아 있는데, 각각의 봉우리에 오를 때 마다 서쪽으로는 복두봉과 운장산, 남쪽으로는 부귀산과 마이산의 두 봉우리가 선명하며, 동쪽으로는 덕유산을 위시한 백두대간 능선이 한눈에 펼쳐진다.<>구봉산은 연꽃산이라고도 불리는데, 천황봉을 제외한 8개의 봉우리가 막 피어오르는 연꽃을 닮았다고 해서 붙여진 이름이다. 훌륭한 조망과 함께 북쪽으로 운일암 반일암계곡과 남쪽의 갈거리계곡 등 크고 아름다운 계곡을 끼고 있고, 용담댐과 메타쉐콰이어 길 등 볼거리가 많아 사람들의 발길이 계속 이어지고 있다.<>구봉산 남동쪽으로는 875년 창건한 천황사가 자리하고 있는데, 천황사 앞 전나무는 국내에서 가장 규모가 크고 아름답기로 정평이 나 있다.", + "MNTN_HG_VL" : "1002", + "MNTN_LOCPLC_REGION_NM" : "전북 진안군 주천면ㆍ정천면", + "MNTN_NM" : "구봉산" }, - "longitude" : 127.43194440000001, - "latitude" : 37.941666699999999 + "longitude" : 127.4168889, + "latitude" : 35.924352599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "385", - "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시", - "MNTN_NM" : "모락산" + "DETAIL_INFO_DTCONT" : "등산로 곳곳에 전설이 담겨있는 명소가 산재한 구절산은 연엽산의 남쪽에 자리하고 있다. 강원도 춘천시 동산면과 홍천군 북방면의 경계를 이루고 있으나 일반인들에게는 널리 알려지지 않아 비교적 훼손이 덜 된 산이다.강원도 춘천시의 동녘 경계에 한 마리 거대한 용이 물을 마시러 하늘에서 내려온 듯 그 머리를 맑고 푸른 소양호로 향한 듬직한 산세의 산이 해발 899미터의 대룡산이거니와 그 정상에서 정남향으로 길게 능선이 달려 응봉(759m)과 연엽산(850m)이 거대한 비늘인양 솟아 있고, 다시 그 남녘의 엉치 부분에 까마득한 아홉 폭의 절벽 병풍을 펼친 산이 구절산(750.4m)이다.활엽수의 시원한 녹색 차양 사이로 멀리 연엽산의 아름다운 모습이 둥두렷이 떠오르는 능선길을 따르노라면 문득 높다란 암벽이 앞을 가로막는다. 왼쪽으로 돌아가는 길을 찾아 다시 오르면 어느 틈에 삼각점이 기다리는 정상이다. 삼각점에서 조금 떨어진 곳에 춘천 그냥산악회가 1993년 1월에 설치한 약 1미터의 금속팻말에는 ‘구절산 760m’라고 새겨져 있다.", + "MNTN_HG_VL" : "750", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천군 북방면", + "MNTN_NM" : "구절산" }, - "longitude" : 126.98119699999999, - "latitude" : 37.369781099999997 + "longitude" : 127.831547, + "latitude" : 37.772691899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "모락산은 낮은 산이지만 암봉이 연이어 솟아있고 숲이 우겨져 있어 암봉을 오르내리는 아기자기한 산행의 맛을 느낄 수 있다. 고스락에 서면 조망이 좋아 북쪽의 관악산, 동쪽의ucirc;계산, 백운산, 광교산을 볼 수 있고 서쪽으로 수리산이 보인다. 도시 가운데 산이라 여러 곳에 갖가지 운동기구와 의자 등 쉴 수 있는 시설도 많다.근래 발행된 지도에는 모락산(帽洛山)으로 표기 되어있지만 모락산(慕洛山)이 옳은 이름이라는 주장도 있다.조선시대 제7대 임금인 세조가 12세기에 등극한 단종을 사사하고 왕위에 오른 것을 목격한 임영대군(1418~1469, 세종대왕의 넷°아들)은 왕위도 좋지만 혈족 간에 살생까지 한 세조에게 반감이 생겨 매일 이 산에 올라 옛 중국의 수도인 낙양을 사모하여 소임하였다하여 모락산이라 부르고 있다고 전해진다.", - "MNTN_HG_VL" : "385", - "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시 오전동, 내손동", - "MNTN_NM" : "모락산" + "DETAIL_INFO_DTCONT" : "경북 문경시 가은읍 서쪽에 위치한 장성봉은 예전에는 수정을 캐던 수정광산으로 알려지기도 했지만 그마져도 그 분야에 상관이 있는 사람들이나 알 수 있었을 만큼 알려지지 않은 산이다. 산을 찾는 사람들이 많아지다 보니 요즘은 이름이 덜 알려진 산들이 자꾸만 개발이 되고 장성봉 역시 그런 산들 중 하나이다.장성봉(915m)은 경북 문경시 가은읍 서쪽에서 백두대간의 허리를 떠받치고 있는 숨은 명산이다. 1\/5,000지도에는 높이가 907.8m로 표시되어 있고 산이름이 그렇듯 마치 거대한 만리장성의 일부를 보는 듯한 장성봉은 북쪽으로부터 남진하는 백두대간이 희양산(999m)에서 서쪽으로 꺾였다가 악희봉(843m)을 솟구친 후, 다시 직각으로 꺾여 남족의 대야산(931m)으로 치닫다가 악희봉과 대야산 중간쯤에 이르러 우뚝 솟아 있다.이 때문에 장성봉을 중심으로 12시 방향인 북쪽 악희봉에서 시계바는 방향으로 구왕봉(898m), 희양산(999m), 애기암봉(731m), 둔덕산(970m), 대야산(930.7m), 군자산(910m) 등이 원을 그린 듯 에워싸고 있어 제법 심산유곡에 들어선 것처럼 느껴지는 산이다. 또, 북쪽의 깊고 긴 계곡이 봉암사 계곡인 봉암용곡임을 아는 사람은 많지 않다. 아뭏튼 장성봉은 경북 문경시와 충북 괴산군 경계를 이루는 백두대간 일원의 주말산행코스로 이용되는 여러 산들 중에서 아직까지는 가장 조용하고 오염이 안된 산으로 남아있는 것이 자랑거리이다.등산로가 확실하지 않고, 산 속에 들어서면 이따금 사람을 보고도 놀라는 기색없이 발길을 옮기는 노루와 토끼, 그리고 희귀식물인 솜다리(에델바이스)가 눈에 보이는 것만으로도 장성봉이 얼마나 오염이 안된 산인가를 입증하고 있다.", + "MNTN_HG_VL" : "915", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍", + "MNTN_NM" : "장성봉" }, - "longitude" : 126.98119699999999, - "latitude" : 37.369781099999997 + "longitude" : 127.9552778, + "latitude" : 36.701944400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "모악산은 전라북도 김제시 금산면과 전주시 완산구와 완주군 구이면의 경계를 이루는 산으로 호남정맥에 솟아 있다.예로부터 호남사경의 하나인 '모악춘경'으로 유명한 모악산은 봄이면 온 산을 벚꽃으로 뒤덮는다. 특히, 금산사에 이르는 벚꽃 길은 바람 불어 꽃잎이 휘날리면 마치 눈이 내리는 듯한 환상에 빠질 정도로 화려하다. 그러나 모악산이란 이름에서 알 수 있듯이 '악'자를 품고 있는 이 산의 산행은 결코 만만치 않다. 구이쪽에서 정상을 향해 오르는 길은 특히 험하여 정상을 얼마 남겨두지 않을 무렵에는 웬만큼 산에 단련이 된 사람이라 할지라도 숨이 턱에 차 오른다. 모든 산이 그렇듯 모악산 역시 마지막 고비와의 힘겨운 줄다리기를 치른 후에야 비로소 정상에 오르는 기쁨을 맛볼 수 있다.정상에 오르면 전주시내와 호남의 넓은 들판이 한눈에 들어와 보는 것만으로도 풍요로운 마음이 드는 호남평야의 전경을 마음껏 즐길 수 있다. 김제쪽으로 하산하는 길은 비교적 수월해 쉬엄쉬엄 주위의 경치를 감상하며 내려오면 된다. 비록 800m도 채 안되는 모악산이지만 덩치와는 다르게 구비구비에 다양한 풍경들을 연출해 산행하는 이들의 시선을 즐겁게 한다. 1971년 도립공원으로 지정된 이 산은 미륵신앙과 많은 연관을 가지고 있어 산자락 곳곳에 이와 관련된 흔적이 많이 남아있다.", - "MNTN_HG_VL" : "795", - "MNTN_LOCPLC_REGION_NM" : "전라북도 김제시 금산면ㆍ전주시 완산구ㆍ완주군 구이면", - "MNTN_NM" : "모악산" + "DETAIL_INFO_DTCONT" : "충북 충주시에 위치해 있는 인등산은 천등산, 지등산과 함께 삼등산으로 불리기도 한다. 땅 위에 사람이 있고 사람 위에 하늘이 있듯이 천등산, 인등산, 지등산이 북에서 남으로 나란히 위치하고 있다. 그래서 차례로 천(天)ㆍ지(地)ㆍ인(人)의 3재(三才)를 이루는 특이한 이름을 갖고 있다.7부 능선까지 임도가 나 있으며, 정상에 오르면 남쪽으로 지등산과 월악산이 충주호와 함께 보이고 북쪽으로는 천등산과 그 산자락에 있는 서대마을터가 보인다. 충북선 동량역에서 산행을 시작하여 삼탄역에서 산행을 끝내는 철도 산행지로 유명하다.인등산 자락에 위치한 소모천마을에는 돌무더기 가운데 사람 키만한 높이로 장승처럼 세워진 조똘바위가 자리잡고 있는데, 전설에 의하면 옛날 소모천마을의 남자들이 변고로 죽어가자 노승이 이곳의 산세가 요녀의 허리모양을 하고 있으니 요녀 형국의 요부에 혈을 찔러서 음기를 눌러야 한다 하여 큰 돌을 운반해 혈을 누른 곳이 바로 조똘바위라고 한다.정상에서는 남서쪽으로 남한강을, 북동쪽으는 충주호의 지류인 주포천을 끼고 있어 산수가 수려한 편이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "충북 충주시 동량면ㆍ산척면", + "MNTN_NM" : "인등산" }, - "longitude" : 127.0843701, - "latitude" : 35.729759000000008 + "longitude" : 128.0067454, + "latitude" : 37.057504399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "모후산은 섬진7지맥의 한 봉우리로 백아산의 산줄기를 타고 내려와 동복천을 앞에 두고 멈춰선 곳이다. 이 산은 광주 무등산과 순천시 조계산의 그늘에 가려 잘 알려지지 않았으나 유마사, 주암호, 사평폭포 등의 명소가 곳곳에 있고, 항상 푸른 계곡물이 넘쳐 있어 관광객과 등산객에게 각광을 받고 있다. 또한 우리나라 최초의 고려인삼 시배지이기도 하다.모후산은 고려 공민왕 10년(1361) 홍건적이 쳐들어왔을 때 왕과 왕비가 태후를 모시고 이곳까지 피난을 왔던 산이다. 공민왕은 수려한 산세에 반해 가궁을 짓고 환궁할 때까지 1여년 남짓 머물렀다고 한다. 그 뒤 나복산을 어머니의 품속 같은 산이라 하여 모후산으로 바꾸었다.또한 임진왜란 때 이곳 동복현감인 서하당 김성원이 노모를 구하기 위하여 필사적으로 싸우다가 순절하였다고 하여 모후산을 모호산(母護山)이라 부르고 마을 이름도 모호촌이라 하였다.", - "MNTN_HG_VL" : "944", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 남면, 동북면", - "MNTN_NM" : "모후산" + "DETAIL_INFO_DTCONT" : "도일봉은 경기도 양평군의 상징산인 용문산과 마주한 산이다. 용문면과 단월면의 경계를 이루는 높이 864 m의 중봉으로 용문산의 명성에 가려 아직 찾는 사람이 적어서 오염되지 않은 깨끗한 계곡을 간직하고 있다.등산로 입구인 상현마을에서 약 30여분 정도 오르다보면 중원폭포가 나온다. 이곳은 도일봉과 중원산을 오르는 갈림길이자 휴식처이다. 약 8km에 달하는 중원계곡은 요즘 보기 드문 청정계곡이다. 중원계곡의 입구는 길과 담, 벼랑이 모두 바위로 이루어져 있는데 '폭포' 라는 이름에 비해 높이는 겨우 2미터정도다.하지만 발광하듯 쏟아져내리는 물길은 산행하며 쏟아 부운 온갖 기운을 충만하게 채워준다. 무성한 숲이 개울위까지 차양을 치고 있어 여름에도 더위가 끼여들 틈이 없어 계곡안은 냉기류가 감돈다. 5m 높이에서 떨어져 하얀 포말을 일으키는 중원폭포와 바위에 부딪혀 하얀 웨딩드레스를 펼친 듯이 떨어지는 치마폭포도 보는 이의 가슴을 시원하게 쓸어내려 준다. 도일봉에는 소나무가 많아서 산행길 내내 소나무숲향기가 함께 해서 더욱 좋다.", + "MNTN_HG_VL" : "864", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", + "MNTN_NM" : "도일봉" }, - "longitude" : 127.1838229, - "latitude" : 35.033538200000002 + "longitude" : 127.61333329999999, + "latitude" : 37.575000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "229", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군", - "MNTN_NM" : "목령산" + "DETAIL_INFO_DTCONT" : "관산은 천진암 성지가 있는 앵자봉의 주능선이 좌측으로 이어지다 북쪽으로 이어진 산이다. 서쪽으로 무갑리 계곡과 무갑산이 지척이고, 천진암 성지도 가까워 성지 순례와 겸한 산행도 가능하다.양자산, 앵자봉, 관산이 북에서부터 남으로 능선으로 이어져 통상 이 세 산을 연결하여 종주 하는 경우도 많으며 서울시에서 별로 멀지않아 휴일이면 산악회에서 단체로 산행하는 경우가 많다.", + "MNTN_HG_VL" : "501", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면", + "MNTN_NM" : "관산" }, - "longitude" : 127.4357262, - "latitude" : 36.735338599999999 + "longitude" : 127.3583333, + "latitude" : 37.4186111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가평군청에서 북쪽으로 20km 떨어진 산으로 경기도 가평군과 강원도 춘천시의 경계를 이루고 있다.즐겨 찾는 이가 많지 않아 호젓한 산행으로 그만이다. 능선에는 싸리, 억새숲을 이루고 있어, 전망도 매우 좋다.정상에는 나무하나 없이 밋밋한 좁은 부위의 마루턱을 이루고 있는데 어떤 시설물이라도 있었던 것인지 여기저기 나무기둥 같은게 보인다. 여기서의 전망은 좋아서 북으로 가덕산과 그위로 몽덕산을 잇는 연릉이 일직선으로 뻗어 나간 모습을 볼수 있는가 하면 남으로 계관산을 잇는 역시 한일자로 굽이굽이 이어지는 억새수풀 능선이 그림처럼 아스라이 전개되는 모습이 장관이다.", - "MNTN_HG_VL" : "690", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", - "MNTN_NM" : "몽덕산" + "DETAIL_INFO_DTCONT" : "포성봉(933m)은 충북 영동과 경북 상주의 경계에 위치하고 있는 산으로 바위가 많고 한폭의 그림과도 같은 빼어난 자연경관을 자랑하고 있는 산이다. 지도상에는 포성봉으로 되어있으나 인근지역주민들은 이 산을 백화산으로 부르고 있다.봄이면 철쭉이 능선마다 꽃띠를 두르고 있어 꽃산행도 겸할 수 있고, 여름에는 수풀과 옥류가, 가을에는 단풍이 정상에서 능선을 타고 석천골 반야사를 온통 붉게 물들인다. 정상에서는 쉴 만한 공터와 무덤이 한쪽에 있고 남쪽으로 석천을 내려다 보면 은빛 물결을 이루고 있으며 남서쪽으로는 주행봉이,주행봉 동편에는 분묘가 어림된다. 북으로는 속리산과 구병산이 남으로는 석천너머로 황악산과 덕유산이 그리고 서쪽으로는 서대산이 펼쳐진다.", + "MNTN_HG_VL" : "1063", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면, 경상북도 상주군 모동면", + "MNTN_NM" : "백화산" }, - "longitude" : 127.60406380000001, - "latitude" : 37.9545265 + "longitude" : 127.90472219999999, + "latitude" : 36.302222200000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", - "MNTN_NM" : "무갑산" + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "주발봉" }, - "longitude" : 127.3337173, - "latitude" : 37.404533200000003 + "longitude" : 127.4947222, + "latitude" : 37.776111100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;갑옷을 두른 무사의 형상gt;서울에서 가까운 경기도 광주시 초월면에 있는 무갑산은 600m가 채 안되는 산으로 숲이 울창한 흙산이다. 또 관산, 검은골 등 아름답고 깊은 골짜기에 맑은 물이 시원하다. 정상 일대 외에는 바위도 그리 없고 대부분 편안한 흙길이며 가끔 산행의 맛을 잃지 않을 만큼 적당히 가파른 산길이 나서기도 하며 곳곳에 암벽도 볼 수 있다. 능선으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다. '무갑산' 이란 이름의 유래에 관하여 두 가지 설이 있다. '임진왜란 때에 왜병들에게 항복하기를 거부한 무인들이 은둔한 데서 무갑산이라 했다'는 이야기와 '산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다' 는 이야기다. 무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다. 마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다고 한다.", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", - "MNTN_NM" : "무갑산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "311", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구", + "MNTN_NM" : "마집봉" }, - "longitude" : 127.3337173, - "latitude" : 37.404533200000003 + "longitude" : 126.9480556, + "latitude" : 35.109999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면에 솟아있는 무갑산은 정상으로 오르는 계곡길이 아름답기로 소문난 산이다. 또한 서울 근교에 있으면서도 오지에 온 듯한 느낌이 들게 하는 곳이다. 무갑산은 능선상으로 앵자봉, 관산 등이 연결되어 있어 이들을 함께 이어 종주 산행 코스로도 많이 활용되고 있다.숲이 울창하며 골자기의 개울이 아름답고 물이 맑으며 시원한 산, 볕이 내리쬐는암릉과 기암괴봉보다 숲속 그늘의 흙길이 편안하고 가끔 알맞게 가파른 산, 거기다가 산을 내려와 시원한 개울 가에서 물을 퍼다가 등멱이라도 할 수 있는 산이다.'무갑산' 이란 이름은 산의 형태가 갑옷을 입은 모습이어서 무갑산이라 했다무갑산은 무갑리, 신월리, 선동리, 학동리 등 자연부락으로 둘러싸인 마을 사람들의 삶의 터전이었으며 그들의 신앙이기도 하다.마을 사람들은 무갑산 자락의 땅을 일구고 무갑산에서 흘러 내려오는 물을 마시며 그 물로 농사를 지어서 곡식을 거두었으며 무갑산의 무성한 나무에서 땔감을 해다가 밥을 짓고 방을 덥혔다. 광주는 자기의 명산지로 조선시대에는 훌륭한 백자를 생산했다. 이처럼 광주고을이 도자기로 유명했던 것도 무갑산에서 많은 땔감을 쉽게 댈 수 있었기 때문이었다 한다.", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월읍", - "MNTN_NM" : "무갑산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함안군", + "MNTN_NM" : "백이산" }, - "longitude" : 127.3337173, - "latitude" : 37.404533200000003 + "longitude" : 128.3497222, + "latitude" : 35.2347222 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "광주시가지에서 동쪽으로 불과 10km 거리에 자리하고 있는 무등산은 도립공원으로 지정되어 있다.산의 형세가 험하지 않고 대부분이 흙으로 이루어져 있어 누구나 쉽게 오를 수 있으며, 곳곳에 맑은 물이 흐르고 있다. 특히 산위에는 서석대, 규봉, 입석대등의 웅장한 바위들이 있으며 산기슭과 중턱에는 약사암, 증심사, 원효사 등의 이름난 절들이 자리잡고 있다. 1972년 도립공원으로 지정되었으며 산 아래에는 각종 놀이 및 편의시설이 들어서 있다.", - "MNTN_HG_VL" : "1187", - "MNTN_LOCPLC_REGION_NM" : "광주광역시 동구, 전라남도 담양군 남면ㆍ화순군 이서면", - "MNTN_NM" : "무등산" + "DETAIL_INFO_DTCONT" : "lt;계곡과 억새로 유명한 영남알프스의 산gt;이른바 '영남알프스'는 억새산행으로 유명한 산군이다. 취서~신불산 구간이 그렇고, 재약산 사자평이 그렇다. 당연히 가을이 되면 많은 등산인들이 몰린다. 고헌산(1032.8m)은 이 산군에 속하면서도 동쪽에 치우쳐 있다. 유명한 비구니사찰인 석남사를 품고 있는 가지산(1240m)이 바로 옆에 있어 언양에서 들어선 등산인들은 대부분 가지산으로 몰리기 마련이다. 그렇기에 고헌산은 오히려 호젓한 억새산행을 만끽할 수 있는 대상 산이다. 뿐만 아니라 고헌산 대통골은 더위만 살짝 앗아갈 적당한 온도의 계곡물, 암벽등반의 묘미도 함께 즐길 수 있는 곳이다. 반면 경험자의 안내와 암벽등반 장비가 필요하다. 계곡 옆으로 우회로가 있어 위험한 구간은 돌아가면 되지만 긴장을 늦추어서는 안 된다. 대통골 초입은 강산교라는 작은 다리를 지나자마자 사방댐 표석이 있는 곳이나 다리 위에 새로 지은 전원주택을 돌아가면 보인다. 2시간 정도 걸리는 계곡갈림길까지가 좋다. 갈림길에서 왼쪽 계곡을 100m 정도 올라 오른쪽 능선을 타고 주능선으로 가길 권한다. 더 올라가면 계곡이 음습하고 암벽들도 어려워진다. 딱히 돌아갈 만한 길도 없고 낙석의 위험도 있다.", + "MNTN_HG_VL" : "1033", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 언양읍, 상북면, 두서면, 경북 경주시 산내면", + "MNTN_NM" : "고헌산" }, - "longitude" : 126.9887555, - "latitude" : 35.134134000000003 + "longitude" : 129.08707190000001, + "latitude" : 35.646332800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "무릉산은 칠북면의 중심산역으로 작대산의 북쪽에 위치하면서 둥그스럼한 산릉에 부드러움을 더하고 있다. 낙동강에 산자락을 내밀고 있는 북릉은 북면 온천이 있는 마금산역에 손을 내밀면서 느긋하게 산세를 일으키고 있다.", - "MNTN_HG_VL" : "556", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 북면, 함안군 칠북면", - "MNTN_NM" : "무릉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", + "MNTN_NM" : "비봉산" }, - "longitude" : 128.56579629999999, - "latitude" : 35.328721999999999 + "longitude" : 126.95, + "latitude" : 34.983333299999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "217", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "무선산" + "MNTN_HG_VL" : "379", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대전", + "MNTN_NM" : "개머리산" }, - "longitude" : 127.6480638, - "latitude" : 34.7671888 + "longitude" : 127.4697881, + "latitude" : 36.387103499999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "무척산은 신어산, 불모산과 더불어 김해의 3대 명산으로 꼽힌다. 그다지 높지 않고 산줄기가 시원스럽지도 않지만 산천으로 둘러싸인 경치 좋은 뜻의 생림동천(生林洞天)이란 말을 만들어 낼 정도로 아름다운 산이다. 또한 기묘한 바위들이 자리 잡고 있어 그 멋스러움이 더욱 특출나 보인다. 특히 낙동강과 이어져 있어 굽이쳐 흐르는 낙동강의 조망이 탁월하며 산허리 부분에 괴상하게 생긴 암봉이 많아 경치가 수려하다.무척산은 산 이름도 다양하다. 무척산 외에도 무착산, 무쌍산, 식산으로도 불린다. 식산은 북풍을 막아주고 낙동강 물줄기를 끌어들여 들을 기름지게 해 김해 고을을 먹여 살리는 산이라 하여 부르는 이름이다. 또 산의 형세가 밥상을 받는 모양과 같다고 해 식산, 식산 대신 밥상이라고도 부른다.다양하게 불려지는 이름뿐만 아니라 무척산은 많은 설화를 간직하고 있는 산이다. 이 산의 정상 바로 밑에 천지못이 있는데, 이 연못은 김수로 왕릉의 물줄기를 잡기 위해 설치됐다는 전설을 갖고 있다. 또한 고찰 모은암은 김수로왕이 어머니의 은혜를 갚기 위해 지었다고 전해진다. 가락국의 불교를 중흥시키기 위해 창건되었다는 백운암도 유명하다.하늘벽, 가야벽, 탕건바위, 장군봉 등 개척된 암장이 여럿 있으며 부산, 경남 클라이머에게 인기가 높다.", - "MNTN_HG_VL" : "702", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 생림면, 상동면", - "MNTN_NM" : "무척산" + "DETAIL_INFO_DTCONT" : "경북 영덕군에 위치한 동대산은 곳곳에 절경을 숨기고 있는 지역의 명산이다. 타지에는 많이 알려지지 않았지만 경관이 뛰어나 발빠른 등산인들이 호젓한 산행을 즐기며 오염되지 않은 산채가 많아 약초꾼들이 은밀히 오가는 곳이다.향로봉 내연산 문수산의 디딤돌로 발판이 되어 잠깐 솟구처오른 동대산은 바데산을 머리에 이고 동서로 여러갈래의 골짜기를 만들어 놓고있다.서쪽 마실골과 북서쪽 경방골은 아직도 자연의 신비감을 그대로 간직하고 있는 절경의 골짜기들이다. 바데산 동대산 내연산 서쪽으로 길게 패인 하옥리 계곡은 경관이 배어나 여름이면 사람공해를 이룬다. 바데산에서 동대산으로 가는 날등길을 걸으며 드넓은 동해바다를 바라보는 눈망울도 쉽게 깜박여지지 않는다.하옥리 계곡에서 갈치기한 마실골은 기암절벽이 골 양옆에 솟구친 가운데 맑고 푸른 물이 소와 담에 담겨 있으며 골짜기와 산사면은 온통 울창 숲으로 우거져 있다. 골 깊숙히 들어가면 널다란 암반이 나타나고 때를 잘 마추어 이 마실골에 들어서면 수백마리의 나비떼를 만나게 된다.동대산 일원은 동해의 습한 기운과 서쪽의 차가운 기운이 맞닿아 안개가 자주 낀다. 때문에 이곳 지형을 잘 알지 못하는 이들은 특히 봄철 안개가 자주 낄 때 조심해야 한다.경방골과 물텀벙이골은 골이 깊고 바위와 절벽이 어우러져 누구든 이 골짜기를 들어오면 한여름에는 담소에 몸을 던지기 일수이다. 여름산행은 바데산으로 올라가서 동대산을 거처 후줄근하게 땀으로 샤워를 한몸 경방골로 내려오며 말끔히 헹궈내는 방법도 솔솔한 재미가 있다.", + "MNTN_HG_VL" : "791", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영덕군", + "MNTN_NM" : "동대산" }, - "longitude" : 128.87060070000001, - "latitude" : 35.340642799999998 + "longitude" : 129.28397870000001, + "latitude" : 36.310201900000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1013", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "문복산" - }, - "longitude" : 129.03833330000001, - "latitude" : 35.679166700000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간이 동로면 벌재를 지나 대미산을 빚어놓고 대미산 정상에 못 미친 1,045m고지에서 북으로 한줄기 뻗어 문수봉을 솟아 놓았다. 충북 제천시 덕산면과 경북 문경시 동로면의 경계를 이룬 문수봉은 월악산 국립공원에 속해 있으며 육산으로 이루어져 있어 등반하기 수월한 산이다. 폭포, 탕, 소 등이 사방 곳곳에 흩어져 있어 여름철 가족 피서지로 적합한 이 산의 자랑은 단연 용하구곡이다. 용하구곡이란 이름 자체가 `여름을 갖고 논다'는 뜻에서 비롯된만큼 더위를 씻어내는 야영지로서의 조건을 다 갖추고 있다.옛날 시인 묵객들이 시문을 겨뤘던 청벽대에서부터 선미대, 가학정, 석운대, 수룡대, 우화굴,세심폭, 활래담 마지막 9경인 강서대에 이르기까지 편편한 반석과 깨끗한 물줄기가 절경을 이룬다. 능선 안부에서 곰취, 취나물, 신선초 등 무공해 산나물을 채취하는 재미도 솔솔하며 봄에는 능선안부께에 철쭉나무 군락이 터널을 이루어 산행의 묘미를 더해준다.", - "MNTN_HG_VL" : "1517", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 경상북도 문경시", - "MNTN_NM" : "문수봉" + "MNTN_HG_VL" : "895", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 두촌면", + "MNTN_NM" : "백우산" }, - "longitude" : 128.21333329999999, - "latitude" : 36.850277800000001 + "longitude" : 128.08235389999999, + "latitude" : 37.842965800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간 주능선에 위치한 문수봉은 태백산 천제단을 마주하고 있으며 풍수 지리적으로 영험한 기(氣)가 있다 하여 무속 신앙인들과 이와 유사한 사람들의 기도처가 많은 산이다.산 정상부가 돌무더기로 되어 있어 이색적인 느낌을 주는 산이고 정상에는 태고때부터 하늘에 제사를 지내던 천제단이 있다. 삼국사기에 왕이 친히 천제를 올렸다는 기록이 있고 세종실록지리지에는 신라에서 오악 가운데 태백산을 북악으로 받들어 봄,가을에 제사를 지냈다고 한다. 천제단을 중심으로 북쪽지점에 태백산의 주봉인 가장 높은 장군봉, 남동쪽으로 능선을 타고 가면 멀리 수만개의 바위로 이루어진 문수봉이 있다. 서울에서 내려온 한 처사가 쌓고 있는 조그마한 돌탑이 있다.신라 진평왕때 자장율사가 이 봉우리에 문수보살을 모시기 위해 망경사를 지었다고 하며, 그 외 사찰로도 백단사, 유일사, 만덕사, 청원사등이 있다.태백산은 겨울의 눈과 설화가 환상적이다. 주목과 어우러진 설화는 동화속의 설경이다. 적설량이 많고 바람이 세차기로 유명하여 눈이 잘 녹지 않고 쌓인다. 세차게 몰아치는 바람이 눈을 달려 설화를 만든다.", - "MNTN_HG_VL" : "1162", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", - "MNTN_NM" : "문수봉" + "DETAIL_INFO_DTCONT" : "백두대간의 한 뼈대를 이루며 높이 솟아있는 이 산은 이름이 여럿 있다. 황정산(黃庭山)이라고도 하고 작성산(鵲城山), 또는 황장봉산 등으로 표기되고 있으나 황장목이 많아 황장산으로 통칭되고 있다.소나무의 한 종류인 황장목은 균열이 적고 단단해 임금의 관(棺)이나 대궐을 만드는데 많이 쓰인 귀한 나무이다. 이 때문에 조선조 숙종 때인 1680년에 이 산에서의 벌목과 개간을 금지하는 봉산(封山) 표석이 동로면 명전리 벌천계곡 하류에 세워졌다. 또 산 깊숙한 문안골 계곡에는 우람한 석문이 있는 작성산성이 있는데 축조방식으로 보아 고구려 시대 것으로 추정된다. 산 아래 금천에는 버들치 등 1급수 어류가 살고 있다.", + "MNTN_HG_VL" : "1079", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면", + "MNTN_NM" : "황장산" }, - "longitude" : 128.94, - "latitude" : 37.0944444 + "longitude" : 128.27611099999999, + "latitude" : 36.813056000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "문수산은 일명 청량산이라고도 하는데 이 산을 가리켜 신라 문수 보살이 산세가 청량하고 아름다워 여기에 살았으므로 처음에는 청량산으로 부르다가 다시 문수산으로 바뀌었다. 청량산은 중국의 산서성 오대현에 있는 오대산의 별명으로 5봉이 솟았고 꼭대기에는 나무가 없어 흙을 모아 놓은 대처럼 생겼고 산의 특성상 여름에 덥지 않으므로 청량산이라 했다. 지금 문수사 절 현판에 청량산으로 표기되어 있다.이 산 정상 넓은 초원에는 중계탑이 있고 서쪽의 신불산 능선과 남쪽의 천성산,대운산,동쪽의 울산시가지와 동해까지 막힘없이 조망할 수 있어서 좋다. 능선길에는 이정표가 세워져 있어서 좋고 곳곳에 쉼터가 있으며 정상 남쪽에는 유명한 문수사가 있는데 매우 아담하게 단장되어 있다. 그리고 가을에는 문수사 주변의 단풍이 절경이다.", - "MNTN_HG_VL" : "600", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", - "MNTN_NM" : "문수산" + "DETAIL_INFO_DTCONT" : "춘천 소양호에 에워싸인 두루봉은 오랜 세월 등산인들을 등지고 있어 태고적 자연 상태 그대로를 보존하고 있는 산이다.바위지대와 굴참나무숲, 낙엽송숲길을 지나 정상에 이르면 확 트인 조망에 가슴까지 시원해지는 기분이다. 북으로는 마적산 오봉산 부용산 봉화산이 한눈에 들고 동으로는 사명산 바위봉 곧은봉 가리산이 소양호에 산영을 담그고 있다.", + "MNTN_HG_VL" : "1226", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "두루봉" }, - "longitude" : 129.21639630000001, - "latitude" : 35.534487400000003 + "longitude" : 128.64944439999999, + "latitude" : 37.572222199999999 }, { "mountain" : { @@ -2941,1303 +1701,1333 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간에서 갈라진 산줄기가 경기도에 이르러 화악산과 명지산 등 고산을 일구고, 운악산과 천마산으로 이어져 북한강가에 이르러 빚어놓은 산이 문안산이다.산은 낮으나 북한강가에 자리잡고 있어 경치가 뛰어나고 험한 곳이 없어 어린아이를 동반한 가족 산행지로 적합한 곳이다. 봄에는 능선길의 진달래가 볼만하고 하산길엔 북한강이 한눈에 들어온다 .문안산이라는 이름의 유래는 날씨가 좋은 날 정상에 오르면 서울의 문안까지 환히 보여서 붙은 이름이라고 한다.", - "MNTN_HG_VL" : "536", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 화도읍 금남리", - "MNTN_NM" : "문안산" + "DETAIL_INFO_DTCONT" : "구룡산은 강원도 영월군 수주면을 감싸 흐르는 서만이 강변에서 북쪽으로 솟아 있는 산이다. 구룡산 남쪽 산자락 끝에 위치한 '섬안'이라는 마을을 동, 남, 서쪽으로 감싸 흐르는 강줄기 이름이 서만이강인데 옛날 명칭은 '섬안이강'이라고 전해지고 있다.정상에 오르면 치악산과 매화산이 스카이라인을 이루고, 산갓봉, 화채봉, 백덕산, 사자산, 돼지봉, 배거리산 등 숲겨지 명산들이 주변에 있고, 선달산과 소백산, 금수산까지 보인다. 때묻지 않고 수수하며 능선과 깨끗한 계곡이 좋고, 사철 등산하기에도 그만이다.", + "MNTN_HG_VL" : "283", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "구룡산" }, - "longitude" : 127.329767, - "latitude" : 37.621951000000003 + "longitude" : 128.21341229999999, + "latitude" : 37.3214763 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "문암산은 정북녘에 자리한 방태산을 위시해 오대산, 계방산, 회령봉, 응봉산 등의 기라성 같은 명산이 한 바퀴 원을 그리며 둘러싸고 있다. ‘돌꽃산(石化山)’이라는 별명에 어울리는 아름다운 바위경관과 듬직한 산세가 멋지고 유명한 내린천의 상류와 자운천, 문암천이 동서녘 자락을 스치며 지난다.철따라 온갖 들꽃들이 앞다투어 피어나는 남북으로 길게 뻗은 주능선을 걷노라면 주변의 내로라하는 산들과 어울린 풍경에 콧노래가 절로 나오는 멋진 산이다. 지역 사람들은 문암산을 ‘석화산’이라 부른다. 이름처럼 푸른 숲 사이로 툭툭 삐져나온 바위전망대가 많아 저마다 조망이 시원스럽다.", - "MNTN_HG_VL" : "1146", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", - "MNTN_NM" : "문암산" + "DETAIL_INFO_DTCONT" : "청우산(해발 619.3m)은 46번 경춘국도를 따라 가평 춘천 방면으로 진행하다가 청평 건문소에서 현리 포천방면 37번국도로 옮겨 오다보면 가평 사계절 썰매장을 막지나 광성교회수련원앞에광진교를 건너면서 산행이 시작된다.청우산은 명지산에서 시작하여 매봉, 대봉, 대금산이 가평을 동서로 가루는 산줄기의 끝 지점에 위치해 있다. 그리 높지 않은 산임에도 정상에 경치가 매우 아름답다 동쪽으로 경춘국도를 사이에 두고 호명산과 주발봉으로 이어지는 산맥이 옆으로 길게 누운 모습이 한눈에 들어온다.#65517;소요 시간 : 정상까지 2시간#65517;볼거리 : 아침고요수목원#65517;최적 탐방 시기 :4월 \/봄 잣나무숲을 끼고 청오사를 지나 능선마루에 오르면 봄이면 능선마다 진달래와 철쭉이 만발하고 참나무숲이 우거져 있다.#65517;숲길 명소 : 정상에서 조망#65517;문화재 : 경기 가평군 하면 대보리 산176-1번지 기념물 제28호 조종암(朝宗巖)이 바위는 조선(朝鮮) 숙종(肅宗) 10년(1684)에 가평군수(加平郡守) 이제두(李齊杜)와 허격(許格) 백해명(白海明) 등이 명(明)나라가 임진왜란(壬辰倭亂) 때 베푼 은혜와 청(淸)나라로부터 당한 굴욕을 잊지 말자는 뜻을 새긴 숭명배청사상(崇明排淸思想)의 기념물이다.#65517;산이 험하지 않아 청우산만 오른다면 하루거리로 적당한 산행이 될수 있고 주변 산장국민관광지는 가족과 즐길수 있는 야영캠프장과 어린이 놀이터, 다목적운동시설 등이 있다.", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 상면, 외서면", + "MNTN_NM" : "청우산" }, - "longitude" : 128.37694440000001, - "latitude" : 37.782499999999999 + "longitude" : 127.4138889, + "latitude" : 37.780833299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "인천 남구 문학동에 있는 높이 217미터의 문학산은 학산이나 남산이라고도 불린다. 지금은 들어볼 수 없지만 예전에는 산봉우리가 마치 사람이 배꼽을 내놓고 누워있는 모양을 하고 있어 배꼽산이라고 했다. 하지만 현재는 그 형세가 많이 달라졌을 뿐만 아니라 기억하고 있는 이 조차 드물어 문학산이라고 부른다.문학산 봉우리와 노적봉 사이에는 관교동에서 청학동으로 넘어가는 긴 고갯길이 있는데 이 길을 삼호현, 삼해주현, 사모현 등으로 부른다. 백제 근초고왕 때(372년) 중국으로 가는 바닷길 한나루로 가는 길목으로 1600년 전 고개를 넘으면서 전송나온 사람들과 이별하던 곳이라고 한다. 삼호현은 이곳까지 따라온 가족이나 친지들이 능허대 쪽으로 멀어져 가는 사신들이 무사히 잘 다녀오기를 빌면서 크게 세 번 불렀다 해 생긴 이름이다.문학산 정상은 산의 동남부에 위치한 군사지역이며, 산지의 서쪽 봉우리는 연경산으로 정상부에 ‘연경정’이 있다. 정상부 및 남서쪽은 군사지역으로 일반인의 출입이 통제되고 있다. 산의 북쪽은 제2경인고속도로 관통, 동쪽은 문학월드컵경기장이 있다.", - "MNTN_HG_VL" : "217", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 남구 문학동", - "MNTN_NM" : "문학산" + "DETAIL_INFO_DTCONT" : "응봉산은 강원도 삼척군과 경북 울진군의 경계를 이루며 산 주변에 전인미답의 여러 계곡들을 끼고 계곡탐험코스로 적합한 산이다. 응봉산을 중심으로 북쪽의 기곡천과 재랑박골, 서쪽의 용소골, 문지골, 갱이골, 보리골 등이 있으며 남쪽 울진군내에 대광천과 동해안쪽 폭포골, 성우골등이 즐비하게 들어서 있다. 호산에서 버스종점을 지나 1km쯤 들어서면 폐광터가 나오는데 여기서 조금 더 올라가면 연이어진 2개의 폭포가 힘차게 흐른다. 조금 더 올라가면 오른쪽 깊은 계곡 아래로 헤아릴 수 없는 폭포지대를 만날 수 있다. 금강산의 축소판을 연상케 하는 이곳은 3단까지는 시야에 들어오나 그 아래로는 워낙 협곡이어서 몇단까지 폭포가 꺽어져 내리는지 셀 수 없을 정도다. 용소골을 탐험할 경우에는 암벽등반 경험자가 동행해야 하며 20m자일 두동쯤은 있어야 위험지대를 통과할 수 있다.", + "MNTN_HG_VL" : "1000", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면ㆍ원덕읍, 경상북도 울진군 북면", + "MNTN_NM" : "응봉산" + }, + "longitude" : 129.2299332, + "latitude" : 37.076997599999999 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "230", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초", + "MNTN_NM" : "청대산" + }, + "longitude" : 128.56960169999999, + "latitude" : 38.1778786 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천삼산은 치악산(1288m)의 남대봉에서 뻗어 내려 온 능선이 감악봉을 조금 못미쳐 남서쪽으로 흘러내리는 곳에 위치한 산이다. 옛부터 약초가 많고 위장병에 효험 있는 천수암 약수터가 있어 영험한 산으로 알려진 이 산에는 사찰이 세 개나 있으며 한때 새마을 운동의 일환으로 많은 사람들이 교육받았던 가나안농군학교가 터를 잡고 있다.또한 20여리에 달하는 능선 자락에 시루봉, 상봉, 중봉, 동굴, 천수암터, 흔들바위등 기기묘묘한 바위의 천국이다. 용암 3리 선터골 상단부에 철철바위가 있는데 늦가을철 비가 내리면 이 바위 위로 산삼씨앗이 흘러내려와서 하늘에서 산삼씨앗을 준다는 전설이 있는 산이다. 그래서 하늘이 산삼을 내리는 산, 천삼산으로 부르게 되었다고한다.", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", + "MNTN_NM" : "천삼산" }, - "longitude" : 126.67919689999999, - "latitude" : 37.431407100000001 + "longitude" : 128.1018985, + "latitude" : 37.209571099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산 이름에서부터 대단한 품위가 느껴지는 산, 문형산. 문형(文衡)이란 고려나 조선 때에 대제학(大提學)의 별칭으로, 학자들에게 가장 품격 높은 벼슬이다. 정2품에 해당하는 관직이기는 했으나 정승 부럽지 않은 벼슬이었고 한번 오르면 죽을 때까지 명예가 지켜지는 자리였다. ‘삼왕비불여일정승(三王妃不如一政丞)이며 삼정승불여일선생(三政丞不如一先生)’이라는 말 또한 대제학을 기리는 것이었으니 문형은 대단한 명예가 따르는 자리였다.정상은 너름 공터다. 운동시설이 있고 긴 의자가 두 개 놓여 있다. 북쪽으로만 조망이 좋다. 멀리 분당시가지와 영장(414.2m)이 뚜렷하다. 뒤로는 서울이 보인다.정상 표석 앞면에는 ‘文衡山 497m’ 뒷면에는 ‘1995년 광주문화원에서 주관하고 동원산악회에서 건립한 이 표석은 1998년에 훼손되어 오포면 이장협의회에서 복원하였음’이라 적혔다. 옆면에는 ‘1999년 1월 1일 오포면 이장협의회 증’이라는 글씨가 음각되었다.문형산의 본디 이름은 문수산이라는 설이 있다. 문수보살을 모신 산이라는 뜻인 듯하다. 또 다른 이름으로 신증동국여지승람에 ‘문현산’이 보인다. 오늘날 산 이름은 고려말 대제학을 지낸 이가 이곳에 들러 쉬면서 경치가 아름다워 ‘문형산’이라 하자 마을 이름까지 덩달아 ‘문형리’가 되었다는 것이다. 장상표석에 기록된 내용이다.", - "MNTN_HG_VL" : "499", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 오포읍", - "MNTN_NM" : "문형산" + "DETAIL_INFO_DTCONT" : "여항산은 함안의 진산이다. 진산은 보통 삶터의 북쪽에 자리를 잡는데 여항산은 남쪽에 자리잡고 있다. 이에 그 허점을 풍수지리의 비보책으로 보완, 산 이름을 물과 관련있는 여항산으로 지었다고 한다. 이름을 지은이는 1583년(선조 16년) 함주도호부사로 함안에 부임한 정구(鄭逑)라는 인물이다. ‘여항’이란 산 이름에는 삶터의 균형을 잡아 평화롭게 살고자 하는 염원이 담겨 있다.여항산은 꽃이나 단풍으로 이름난 산은 아니다. 근처에 이름 난 관광지가 있어 덤으로 유명세를 타는 산도 아니다. 그저 산과 들판 사이에 솟았다. 그러나 산은 정상 부근의 옹골찬 기세와 능선의 부드러움이 어울려 여느 명산 못지않다. 마치 세상 명리를 뿌리치고 초야에 묻혀 사는 지조 높은 옛 선비 같은 산이다.여항산 능선을 타고 남쪽으로 1시간 40분 거리에 서북산이 있다. 낙남정맥 산줄기인 여항산과 서북산은 한국전쟁 당시 낙동강 방어선이었으며 북한군 6사단과 미 25사단이 사투를 벌였던 곳이다. 미군들은 ‘갓 뎀’이라며 치를 떨었는데 이후 여항산과 서북산 일대를 갓데미산으로도 부른다고 한다. 서북산 정상에는 6.25 전적비가 있으며 당시 전투에서 전사한 미군 중대장의 아들 리처드 티몬스가 1995년 주한 미군으로 부임해 와 세웠다고 한다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "경남 함안군 여항면, 마산시 진전면", + "MNTN_NM" : "여항산" }, - "longitude" : 127.1875, - "latitude" : 37.369166700000001 + "longitude" : 128.40670359999999, + "latitude" : 35.196818100000002 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "369", - "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", - "MNTN_NM" : "미궐산" + "MNTN_HG_VL" : "516", + "MNTN_LOCPLC_REGION_NM" : "경상남도 마산시", + "MNTN_NM" : "대곡산" }, - "longitude" : 126.9933333, - "latitude" : 36.440833300000001 + "longitude" : 128.53958030000001, + "latitude" : 35.1897935 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "미녀봉의 본 이름은 문재산(文載山)이다. 그러나 미인이 머리를 풀고 누워있는 형상이라 하여 미녀봉(美女峰)으로 널리 불린다. 미녀봉에는 두 가지 전설이 전한다. 옛날 바다였던 이곳에 장군이 탄 나룻배가 표류하자 옥황상제가 딸을 지상으로 보내 구하고자 했다. 장군은 딸과 사랑하게 되었고 그런 딸을 보고 노한 옥황상제는 너희 둘은 영원히 산으로 누워 있으라는 형벌을 내렸다고 한다. 또 다른 전설은 예쁜oacute;녀가 어머니 병을 고치기 위해 미녀봉에만 있는 약초를 캐려 했는데 뱀에 물려 죽자 불쌍히 여긴 산신이 죽은oacute;녀의 모습대로 만든 산이 미녀봉이라 한다. 88고속도로 인터uuml;인지에서 바라보는 미녀봉은 참으로 감탄스럽기 그지없다. 잘 다듬어진 이마, 세련된 화장술로 그려낸 듯한 눈썹, 오똑한 코, 힘겨워 헤 벌리고 있는 입, 봉긋 달덩이oacute;럼 솟아오른 젖가슴, 아이를 잉태한 듯한 볼록한 배 등 산봉우리들이 모여 하나의 아름답고 고운 여인 형상을 빚고 있다. 미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀봉을 눈부시게 만든다.", - "MNTN_HG_VL" : "930", - "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가조면, 합천군 봉산면", - "MNTN_NM" : "미녀봉(숙성산)" + "DETAIL_INFO_DTCONT" : "제천 백운산은 바로 옆 치악산의 그늘에 가려 등산인들에게 널리 알려지지 않았다. 그러나 그만큼 찾는 이가 드물어 등산로의 훼손이 적고 오염이 덜 되었으니 호젓하고 쾌적한 산행을 즐길 수 있다.서쪽에서부터 십자봉(984.8m), 조두봉(966.6m), 백운산(1,087.1m), 보름갈이봉(860m), 수리봉(909.9m), 벼락바위봉(937.6m)으로 이어지며 1000미터를 넘나드는 산줄기가 거대한 성곽처럼 도열해 제천시의 북쪽을 굳건히 지키고 선 모습은 가히 장관이다. 이 산들은 제천시계종주코스이기도 하다.백운산의 빼어난 점은 뭐니뭐니 해도 눈앞으로 펼쳐지는 일본잎갈나무(낙엽송) 조림지의 광대한 조망과 산길의 한적함이다. 북쪽인 원주 방면으로도 군데군데 보이지만, 남동쪽인 백운면 자락은 온 천지에 바늘을 꽂아둔 듯 빈틈없이 조림된 잘 자란 낙엽송 군락지가 시원하다. 백운산을 올라보면 당장 느낄 수 있지만 제천시민의 숲에 대한 보살핌과 정성, 자부심은 대단하다. 전국에서도 임도시설이 발달해 있기로 소문난 곳이기도 하다. 제천의 어느 산을 오르든지 잘 정비된 임도를 만나게 된다. 숲은 전체적으로 간벌이 잘 되어 있어 답답하지 않고 매우 건강하다.", + "MNTN_HG_VL" : "1087", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 백운면", + "MNTN_NM" : "백운산" }, - "longitude" : 128.0521684, - "latitude" : 35.682698299999998 + "longitude" : 127.9627778, + "latitude" : 37.25 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "88고속도로를 타고 가조인터체인지 부군에서 동남쪽으로 쳐다보면 긴 머리카락을 늘 어 떠리고 반듯이 누워있는 미녀모양의 산을 발견하고 누구나 깜짝 놀란다. 미녀봉이라 알려졌지만 머리 가슴 배의 뚜렷한 봉우리가 모여 이룬 산이라 미녀산이 옳다. 정상의 위치와 높이도 893M봉이 아니라 동쪽의 930M가 더 합당하다. 황강의 지류인 가천에 긴 머리칼을 풀어 담그고 단아한 이마, 까만 눈썹, 오똑한 콧날, 헤 벌린 입, 또렷한 턱과 목을 거쳐 불룩 솟은 젖가슴 아래로 아기를 잉태한 듯 불룩한 배, 이런 모습은 산봉들이 어울려 빚어낸 자연의 걸작품으로 손색이 없다.미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아 오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀산을 눈부시게 만든다. 미녀산속에 널려있는 선바위, 음양석등 자연숭배사상이 엿보이고 산 전체가 하나의 여체로 만들어져 성적 호기심을 자아내게 만든 것은 거창 미녀산이 우리나라에서 유일하다.전해오는 전설이 두 가지 있다. 옛날에 이곳은 바다였는데, 어느 장군이 나룻배를 탄 채 표류하고 있었다. 이를 본 옥황상제가 딸을 보내 구하라고 했으나, 딸을 본 장군은 한눈에 반해 서로 사랑하게 되었다. 이에 옥황상제는 두 사람을 산으로 만들어 영원히 누워 있는 형벌을 내렸는데, 바로 미녀산과 장군봉이라는 전설이다.또 하나는 병으로 위독한 어머니의 약을 구하러 이 산에만 있다는 약초를 캐러 올랐다가 뱀에 물려 죽자 이를 불쌍하게 여긴 산신이 산의 형세를 죽은 처녀의 모습대로 만들었다는 이야기다.", - "MNTN_HG_VL" : "930", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면", - "MNTN_NM" : "미녀산" + "DETAIL_INFO_DTCONT" : "월여산은 경남 거창군 남쪽 지맥에 우뚝 솟아 있다. 인근 사람들은 3개의 봉우리로 이루어졌다해서 삼봉산으로도 부른다. 이 산은 산세가 좋아 무학대사가 금계포란형이라 지목하여 유명한 풍수가들이 즐겨 찾았던 곳이다.거창의 지형으로 보아 거창지역의 모든 물줄기는 거창읍을 거쳐 남하면에서 합수하여 합천호에 이르지만 월여산이 위치한 신원천만은 그 아래쪽으로 독립되어 흐르고 있다. 산이 높으면 골 또한 깊어 수량이 풍부하다. 그 물이 맑아 월여산을 찾는 이들을 반긴다. 정상 서쪽면은 층암절벽이 관목과 어우러져 가을 단풍이 특히 아름답다.", + "MNTN_HG_VL" : "862", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "월여산" }, - "longitude" : 128.0521684, - "latitude" : 35.682698299999998 + "longitude" : 127.9480152, + "latitude" : 35.549462400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "통영시 서남단의 미륵도에 위치한 야트막한 산이나 미륵신앙의 본거지로 불교인들 사이에는 꽤 알려진 산이다. 그래서인지 이 작은 산에는 용화사, 관음사, 도솔암, 미래사 등 크고 작은 사찰과 암자가 많다.또 임해봉(臨海峰)이라는 이름의 정상은 지난날 봉화대로서 다도해를 지킨 역사적 장소로도 기억될 만 하다. 미륵산은 한국 제일의 미항이며 충무공이 왜적을 격파한 전승지로 유명한 통영과 국내 유일의 해저터널로 연결되어 있다. 일명 `판대굴'로 불리는 이 해저터널은 일제시대 일본인이 건설한 것이나 예측된 수명을 넘어 지금도 사용되고 있어 당시 일본의 기술력을 짐작할 수 있는 표본으로 각광받고 있다.정상에 오르면 비진도, 거제도 , 한산도, 칠천도 등 한려수도를 보석처럼 장식하는 크고 작은 섬들을 한 눈에 조망할 수 있어 그 아름다움에 당황할 정도이다.", - "MNTN_HG_VL" : "458", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 산양읍ㆍ봉평동", - "MNTN_NM" : "미륵산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "136", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 봉화읍", + "MNTN_NM" : "달봉산" }, - "longitude" : 128.4163241, - "latitude" : 34.810502800000002 + "longitude" : 128.69057369999999, + "latitude" : 36.885565799999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "미륵산은 넓디넓은 호남평야 한가운데 위치한 작은 산이만 그 무게는 결코 가볍지 않다. 백제의 무왕이 된 서동과 선화공주 이야기를 간직한 미륵사가 있던 곳이고, 정상에는 마한시대 것으로 추정하는 마륵산성이 남아있기도 하다. 산 구경하기 어려운 익산땅에서 미륵산은 등산인들의 유일한 휴식처가 되기 때문에 사람들의 발길이 끊이질 않는다.정상은 주변의 넓은 평야지대로 인해 초록의 바다 위에 우뚝 솟은 섬처럼 거칠 것 없는 조망이 일품이다. 동남북 대둔산을 잇는 금남정맥 줄기가 부드럽게 이어져 있고 익산시가지가 훤히 내려다보인다. 다만 아쉬운 것은 정상에 위치한 두 개의 무덤에 훼손 방지를 위해 날카로운 철조망이 처져 있어 절대 들어오지 말라는 듯 위협한다.정상에서 동쪽으로 내려서면 미륵산성을 만난다. 일부 복원된 산성의 규모만으로도 그 크기를 짐작할 정도로 아주 크며 주변으로 높은 산이 없어 멀리까지 관찰할 수 있는 이점이 있는 곳이다.미륵산을 중심으로 금마, 삼기면 일대에는 마한 선인들이 남긴 민속놀이와 미륵산록에 찬란하게 꽃피웠던 백제문화를 보존 전승하기 위하여 매년 10월 8일에 축제를 벌인다. 축제에는 마한 때 유래된 것으로 보여지는, 깃대를 앞으로 숙여 세배를 하는 금마기세배(金馬旗歲拜)놀이를 비롯한 많은 민속놀이가 벌어진다. 특히 ‘콩 깍자, 콩 깍자’로 시작되는 ‘지게 목발 노래’는 지방무형문화재 1호로 지정된 농요(農謠)이다.", - "MNTN_HG_VL" : "430", - "MNTN_LOCPLC_REGION_NM" : "전북 익산시 금마면ㆍ낭산면ㆍ삼기면", - "MNTN_NM" : "미륵산" + "DETAIL_INFO_DTCONT" : "충북 괴산군 청천면에 위치한 사랑산의 본 이름은 제당산이다. 사기막리의 제당골에 제당이 있어 ‘제당산’이라 불리던 것이 10년 전, ‘사랑의 영원성’을 상¡하는 연리목(連理木)이 발견되면서 괴산군청에서 산 이름을 ‘사랑산’이라 바꿔 부르게 되었다. 이 연리목은 산림청으로부터 천연보호수로 지정되었다.사랑산은 아기자기한 산이다. 초보 산행자를 위한 안성맞춤 대상지로 산길이 그리 비탈지지 않고 산행시간은 2~3시간이면 족하다. 등산로가 희미한 곳이 더러 있지만 바위와 흙길이 골고루 나 있어 산행이 지루하지 않다. 조망하기 좋은 전망바위도 곳곳에 나타나 산행의 심심함을 달래준다. 이름 그대로 코뿔소 한 마리가 서 있는 듯한 코뿔소바위, 뽀뽀를 하면 사랑이 이루어진다는 사랑바위 등이 산행의 재미를 더해준다. 사랑산을 상¡하는 연리지는 사기막리와 인접한 송면리에 있다. 그 아래에는 용추폭포가 있는데 더위를 식히기에 더없이 좋다.", + "MNTN_HG_VL" : "647", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "사랑산" }, - "longitude" : 127.03903339999999, - "latitude" : 36.0250561 + "longitude" : 127.85463129999999, + "latitude" : 36.703488900000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "미륵산은 강원도 원주시에서 남쪽으로 약 22km 거리인 원주시 귀래면에 위치해 있다. 기암괴봉과 노송이 어우러져 한 폭의 동양화를 연상케 하는 산이다.미륵산은 정상에 거대한 미륵불상이 새겨져 있는 것으로 유명하다. 수석처럼 멋드러진 암봉이 12개나 치솟아 독특한 산세를 나타내며 바위틈을 비집고 붙어있는 노송이 그 절묘함을 더한다. 겨울철에는 노송과 암벽에 피어 있는 설화가 일품이다.산은 그다지 높지 않으나 부드러운 능선길과 아기자기한 암릉길이 조화를 이루고 있어 산행의 정취와 묘미를 느끼게 한다.정상인 신선대에서 북동쪽을 보면 백운산과 치악산맥이 보이며 동으로는 십자봉이, 남서쪽 멀리로는 남한강 물줄기가 보인다.신선대 아래의 미륵불상을 지나고 동쪽 능선을 따라 20분 정도 내려가면 황산사이다. 신라 경순왕 때 창건된 고찰이다. 정상에서 아기자기한 암릉으로 이어지는 남릉을 타노라면 한 폭 그림속을 거니는 기분이다. 암릉마다 분재와 같이 아름다운 노송들이 속세의 때가 묻지 않은 그대로다.산행을 마치고 황산사 를 내려오면 시원한 계곡이 흐르기에 산행의 흐른땀을 씻어준다.", - "MNTN_HG_VL" : "696", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면", - "MNTN_NM" : "미륵산" + "DETAIL_INFO_DTCONT" : "원래 차가운 비가 내리는 산이란 뜻의 찰비산이라 불리다가 나중에 찰 한(寒), 비 우(雨) 자를 쓴 한우산으로 이름이 바뀐 이 산은 의령의 명산인 자굴산과 이어져 있다.비록 지리산이나 자굴산에 비해 알려지지는 않았지만, 한우산에서 산성산까지 연결하여 산행을 하다보면 풀밭이 널찍하게 자리잡은 곳이 있어 신나게 달리다가도 수직의 빳빳한 암벽이 늘어선 암봉지대를 만나면 힘겹게 오르는 맛이 있어 숨겨진 산의 보물을 찾아내는 기분이다.산 정상에서 내려다보는 마을은 포근한 느낌이 드는 전형적인 산간마을이어서 그곳에서 하룻밤을 지내면 노곤한 몸이 생기를 되찾을 것이다. 또한 한우산은 철쭉군락지로 유명하고 아름다운 찰비골 계곡에는 민속촌이 조성되어 있다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군", + "MNTN_NM" : "한우산" }, - "longitude" : 127.8530556, - "latitude" : 37.186111099999998 + "longitude" : 128.20174539999999, + "latitude" : 35.393346600000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "미숭산은 비운의 역사를 품고 있는 산이다. 고려의 장군이었던 이미숭이란 사람이 조선을 건국한 이성계에 대항해 군사를 모으고 이 산에 성을 쌓아 고려를 회복하는 싸움을 벌였던 곳이다. 그러나 이미 대세는 조선과 이씨 왕조쪽으로 기운 상태였기 때문에 장군은 결국 고려 회복의 뜻을 이루지 못하고 순절했다고 전해진다. 산에 장군과 관련된 유적이 아직 남아 있어 대세와 명분 사이의 긴장감 넘치는 대결을 떠올리게 한다. 정상 주변에 미숭산성의 성터와 성문의 잔해가 있고, 성문터 옆에 샘물도 있다. 이 산성은 삼국시대에 축조된 후 조선시대까지 계속 이용되었다고 한다.원래 이름은 상원산이었으나 후세 사람들이 이미숭 장군의 이름을 따서 미숭산이라 부르게 되었다.미숭산을 오르다보면 사방으로 운무에 가린 산, 산, 산이 겹겹으로 늘어서 있다. 그 사이로 들녘에 반짝 빛나는 것은 낙동강이다. 한 페이지의 역사도 남기지 않고 사라진 가야의 유물과 사적지를 둘러보면서 주산과 미숭산을 오르내리다 보면 봉긋하게 솟아난 언덕만 봐도 고분으로 보이고 등산길에 맞닥뜨리는 바위마다에는 원시 암각화가 그려 있는 것 같아 유심히 살펴보게 된다. 자신도 모르게 이처럼 신비에 쌓인 가야의 역사 속으로 빨려 들어간다.", - "MNTN_HG_VL" : "757", - "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군 고령읍", - "MNTN_NM" : "미숭산" + "DETAIL_INFO_DTCONT" : "융단같은 능선길을 마음대로 달릴 수 있는 산이 부산광역시의 근교에 터잡고 있다. 김해 백두산 동신어산 종주능선이 바로 이 같은 곳이다. 이 종주능선길은 부드러우면서도 아기자기한데다 산악동호인들의 발길조차 전혀 닿지 않아 근교의 새로운 워킹산행지로 인기를 끌기에 충분하다.백두산 동신어산 종주능선상에서는 또 부산을 둘러싸고 있는 산군의 능선을 모 두 조망할 수 있다. 금정산 주능선길은 물론 영남알프스의 남쪽능선, 낙동 낙남정맥상의 산군, 그리고 김해 무척산 물금 오봉산 원동 토곡산 울산 원효, 천성산 등 동부경남의 크고 작은 산을 눈으로 확인할 수 있다.", + "MNTN_HG_VL" : "460", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해 상동면", + "MNTN_NM" : "동신어산" }, - "longitude" : 128.19232030000001, - "latitude" : 35.738110900000002 + "longitude" : 128.92087570000001, + "latitude" : 35.270207599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 정선군 남면에 위치한 민둥산은 약수산행과 억새산행, 철도산행지로 유명하다. 이름 그대로 7부 능선을 넘어서면 나무가 거의 없어 민둥민둥한 형세다. 예전에는 ‘한치뒷산’이라 불리던 이곳은, 곤드레, 딱주기나물 등이 잘 자라나도록 하기 위해 일부러 불을 낸 것이, 나무 한 그루 없는 민둥산으로 변하게 했다고 전해진다. 그러나 가을이면 온통 황금빛 억새로 한껏 치장한다. 제주도 동부 오름지대, 창녕 화왕산, 장흥 천관산, 포천 명성산, 밀양 사자평 등과 함께 억새군락지로 손꼽히는 억새평원을 자랑한다. 매년 억새꽃 축제가 열릴 만큼 20만평에 이르는 억새평원은 은빛으로 출렁이고 가을 정취를 만끽하기에 제격이다. 산세는 대체로 완만한 경사를 이루고 있으며, 등산로 정비도 잘 되어 있어 초보자들도 쉽게 오를 수 있다. 민둥산은 정선군 중앙부에 위치하여 동쪽으로 함백산, 남쪽으로 백운산, 서쪽으로 가리왕산, 북쪽으로 괘병산 등이 자리해 있어 동서남북으로 조망이 좋다. 민둥산의 또 다른 특색은 석회암이 빗물에 용해되어 지반이 내려앉는 독특한 카르스트 지형으로 돌리네가 형성되어 있는 것이다.", - "MNTN_HG_VL" : "1118", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면", - "MNTN_NM" : "민둥산" + "DETAIL_INFO_DTCONT" : "도고산은 충남 아산시 도고면에 자리해 있으며 산가에 도고저수지를 끼고 있다. 산 정상에는 조선시대에 통신수단으로 사용하던 봉화대 유적이 원형에 가깝게 잘 보존되어 있다. 정상에 서면 예당평야와 아산만은 물론 멀리 천안시까지 한눈에 들어와 서해안의 초계와 방어를 위한 군사적 요지로 유명하다.옛날 천지가 개벽할 때 온 천지에 물이 찼는데, 산꼭대기만 도구통만하게 남았다는 설화에서 산 이름이 유래한다.삽교천방조제가 세워지기 전에는 바로 산 밑까지 바닷물이 들어왔으며, 주봉인 국사봉에는 봉수대가 남아 있다. 1390년(고려 공양왕 2) 6월에 서해안에 침입한 왜구가 이곳에 진을 치고 약탈을 자행하자 윤사덕과 유용생이 이끄는 관군이 물리쳤다는 기록도 남아 있다.도고면에서는 가파른 곳에는 로프를 설치했으며 등산로 곳곳에는 쉴 수 있는 긴 의자를 만들어 놓았고, 안내판도 세워놓았다.인근에 도고온천이 있어 산행과 온천을 겸한 여행지로 알맞다. 도고중학교에서 출발하여 정상에 오른 뒤 다시 내려오는 코스가 개발되어 있으며 약 2시간 30분 소요된다. 주변에는 중요민속자료 194호로 지정된 아산 성준경가옥 등의 문화재가 있다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "충남 아산시 도고면, 예산군 예산읍", + "MNTN_NM" : "도고산" }, - "longitude" : 128.77488750000001, - "latitude" : 37.270854200000002 + "longitude" : 126.895, + "latitude" : 36.725000000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "호남의 금강이라 부르기에 손색이 없는 대둔산은 충남 논산시와 금산군, 전북 완주군 등 3개군에 걸쳐 있다. 최고봉인 마천대를 중심으로 기암괴석들이 제각기 위용을 자랑하며 늘어서 있다. 대둔산은 두 얼굴을 가지고 있다. 기경의 절벽을 이루는 전북 완주쪽과 순후한 시골아낙 같은 충남 논산,금산쪽이 바로 그것이다.바랑산은 그리높지 않은 산임에도 월성봉까지 이어지는 능선은 보기드문 절경을 자랑한다. 잘 닦인 등산로를 가지고 있으면서도 깨끗한 주변환경을 유지해 쾌적함속에 산행을 즐길 수 있는 곳이다.바랑산은 다리성 서쪽에 있고 모양이 바랑과 같이 생겼다 하여 붙여진 산명이며, 노승예불현의 명당이 있다.등산로 역시 양쪽 지형이 상반되는 것 만큼이나 특성이 뚜렷이 구분된다.", - "MNTN_HG_VL" : "555", - "MNTN_LOCPLC_REGION_NM" : "충청남도 논산시", - "MNTN_NM" : "바랑산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "859", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", + "MNTN_NM" : "죽엽산" }, - "longitude" : 127.27, - "latitude" : 36.130000000000003 + "longitude" : 127.8472038, + "latitude" : 38.052157999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "지리산자락을 따라 북서쪽 능선 끝자락에 솟아 있는 바래봉은 매년 5월이면 철쭉제가 열리는 '천상화원'으로, 온 산이 연분홍빛 철쭉꽃으로 물들인다. 바래봉 철쭉은 다른 어느 산의 철쭉꽃보다 화려한 편이다. 그 이유는 바래봉 철쭉은 주능선에는 나무가 거의 없는 푸른 초원이 펼쳐진 능선 한가운데 피어나기 때문이다. 푸른 초원 위에 연분홍빛 철쭉이 더욱 화사하게 돋보이는 것이 바래봉 철쭉의 매력이다.바래봉이란 이름은 스님들의 밥그릇인 바리때를 엎어놓은 것 같다 하여 붙여졌다 한다. 이름의 유래와 같이 바래봉 주능선은 둥그스름하고 부드러운 능선을 펼치고 있어 산행은 마치 공원을 산책하는 듯 편안하다. 그러나 산위에 있는 이 천상의 화원을 즐기기 위해서는 산을 오르는 힘겨움을 감수해야만 한다. 세상의 모든 일에는 그 대가가 따르는 것처럼 바래봉의 철쭉도 그런 수고를 감수한 이후에야 맛볼 수 있다.이렇게 바래봉은 한라산,소백산 등과 더불어 대규모 철쭉군락지로 유명한 산일 뿐만 아니라, 운성(운봉) 10경의 하나로 바래봉 달빛 아래 몰려오는 독경시에 흔드는 작은 종소리 발악월경이 포함되어 있다.", - "MNTN_HG_VL" : "1165", - "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 운봉읍, 산내면", - "MNTN_NM" : "바래봉" + "DETAIL_INFO_DTCONT" : "임란이 일어나 왜군이 이곳까지 들어오자 가곡마을에 살던 밀양 박씨의 부녀자인 여흥 민씨(박희량의 처)는 다른 부녀자와 함께 이 산 바위굴에 피난했다. 그러나 왜군에게 발각되어 화를 면할 수 없게 되자 이 사 바위 절벽에서 몸을 던져 스스로 목숨을 끊었다. 임란이 평정되자 민씨의 정절을 표창하였고, 그 이후 그 절벽은 민씨가 꽃처럼 깨끗하게 떨어져 죽은 바위라 하여 낙화암이라고 부르고, 또 산의 형세가 꽃이 지는 것 같다 하여 낙화산이라 했다. 낙화산 정상에는 표지가 없으나 이리저리 산악회에서 달아놓은 리본들로 어지럽다.밀양시 산외면 소재 낙화산(落花山)은 정상으로 가는 도중 봉우리가 열댓개 되는 산으로 이 봉우리들을 그다지 힘들지 않게 넘을 수 있어 그 재미가 상당하다. 따라서 많은 산행인들이 이 산을 밟으려고 생각을 하고 있으나 코스를 어떻게 잡아야 할지 몰라 섣불리 발을 내딛지 못하는 형편이다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 도곡리", + "MNTN_NM" : "낙화산" }, - "longitude" : 127.56, - "latitude" : 35.430000000000007 + "longitude" : 128.8251827, + "latitude" : 35.544978800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "바위산은 사람들이 쉽게 접근하는 것을 막는 여염집 아낙처럼 찾아가기가 약간 번거롭다. 다른 산에 갈 때처럼 차나 기차를 이용해 근처까지 가도 소양댐 선착장에서 배를 타고 더 들어가야 하기 때문이다. 마치 그 물을 건너야 자신을 만날 자격이 있다는 것처럼 이 산은 저 멀리 서있다.춘천의 명물 중 하나인 소양호를 이용해서 산행을 즐길 수 있는 산과 호수의 낭만이 서려 있는 산이지만, 산 이름 자체는 널리 알려져 있지않아 일반인들은 그리 많지 않은 산악인들이 찾고 있는 편이며 능선으로 매봉이 바로 이웃하여 연결되어 있는 산이다. 소양호를 내려다 보면서 정상에 오르다 보면 노송이 우겨져 있고, 나자막한 돌탑이 있다.주머니 같이 둘러싸여 있는 능선 속으로 흐르는 중밭골 계곡에는 푸른 이끼가 끼어있고 군데군데 소와 작은 폭포가 있어 깨끗하기 이를데 없으며, 오솔길에는 풀이 무성해 융단을 딛는 것 같은 촉감의 정겨운 산길이다.", - "MNTN_HG_VL" : "858", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", - "MNTN_NM" : "바위산" + "DETAIL_INFO_DTCONT" : "육화산은 북으로 청도군 매전면과 밀양군 산내면 경계 지점이 있다. 육화산은 큰 산, 작은 산, 청계수, 폭포, 적석, 흑석의 6가지를 갖추어 있는 산이라 붙여진 이름이다. 산행은 상동역 앞 슈퍼마켓에서 동곡행 버스를 타고 지전리 중남 초등학교에 내려 내동교를 지나 안내동 마을가지 30여 분 걸어야 한다.마을 입구 고목을 지나 다리를 건너 바로 왼쪽 계곡 따라 포장길을 오르는 길이 있는데 육화에서 구만 종주 코스로 많이 이용되고 있다. 육화산 정상은 한쪽 방향으로 시야가 확 트여 있어 전망만큼은 뛰어나다. 구만산과 그 뒤편으로 이어지는 억산이 파노라마처럼 보인다. 정상 주위에 진달래 터널과 진달래 군락지가 있어 봄이면 장관을 이룬다.", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 매전면 장연리", + "MNTN_NM" : "육화산" }, - "longitude" : 127.96777779999999, - "latitude" : 37.9566667 + "longitude" : 128.85859429999999, + "latitude" : 35.613249099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "박달산은 괴산군 감물면과 장연면의 경계에 자리하는 해발 825미터의 산이다. 대미산~포암산을 이어 서쪽으로 달려오던 백두대간의 주능선이 마패봉(922m)에서 직각으로 방향을 꺾어 정남쪽의 조령산을 향한다. 서쪽으로 계속 뻗어나간 산줄기는 보다 높은 신선봉(967m)을 솟구치고 괴산군에 이르러 박달산과 주월산(506m), 성불산(532m)을 일으킨 후 달천으로 내려든다. 박달산 동녘자락 장연면에는 송덕리와 추점리의 미선나무 군락지가, 오가리에는 느티나무 등 소중한 천연기념물도 품고있다.또 박달산은 독립된 봉우리로 어디에서 보나 그 덩치가 심상치 않다. 육산으로 산 안으로 들어가보면 아직 사람의 손길이 닿지 않아 원시림을 연상케 할 정도로 우거져 있는 곳이 많다.산불감시용 카메라가 설치된 철탑이 하늘을 찌를 듯 서 있는 정상에는 2002년에 세운 정상석과 1982년 복구한 삼각점이 있다. 그러나 무엇보다 이색적인 것은 정상석 옆에 자리한 ‘대한민국 국기게양대’다. 단기 4330년 음력 7월 6일(서기 1997년 8월 8일) 한국고대사연구회에서 세운 게양대와 빗돌은 박달산의 명물이 아닐 수 없다.", - "MNTN_HG_VL" : "825", - "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 감물면ㆍ장연면", - "MNTN_NM" : "박달산" + "DETAIL_INFO_DTCONT" : "구왕봉은 백두대간의 주봉인 희양산(998m)의 서쪽에 위치한 산이다. 바위로 이루어진 구왕봉은 바로 이웃한 희양산의 명성에 눌려 찾는 등산객의 수가 그리 많지 않아 깨끗한 자연 그대로의 모습을 유지하고 있는 산이다.구왕봉은 깨끗한 등산로와 아기자기한 능선길이 등산하는 즐거움을 느낄 수 있는 산이지만 급경사 암릉지대도 있으므로 보조자일을 준비하는 것이 좋다. 구왕봉 자락에는 신라 헌강왕 5년 지증대사에 의해 창건된 유서깊은 사찰인 봉암사가 자리하고 있다. 또한 지름티재의 가을 정취는 아름답기 그지없다.충분한 습도와 풍부한 영양으로 단풍의 색깔이 다른 지역보다 곱고 색도 가지가지여서 산행을 하는 이들의 마음까지도 온통 울긋불긋하게 물들고 만다.", + "MNTN_HG_VL" : "877", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면", + "MNTN_NM" : "구왕봉" }, - "longitude" : 127.923232, - "latitude" : 36.836640699999997 + "longitude" : 127.9833333, + "latitude" : 36.716666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "박지산은 강원도 평창에 위치한 산으로 오대산에서 발원하는 청정류 가운데 가장 때묻지 않은 계곡인 아차골을 품고 있다. 말복까지 얼음을 볼 수 있는 박지골과 경치가 수려한 아차골 등 박지산 골짜기는 등산인들의 발길이 뜸하여 오지의 신비함을 간직하고 있다.박지산은 두타산(頭陀山)이라고도 하는데 2007년 인쇄된 국토지리정보원 지형도상의 공식명칭으로 ‘우리 산 이름 바로 찾기 운동’에 따라 2002년 박지산에서 두타산으로 이름이 바뀌었다. 그러나 백두대간의 삼척 두타산(1352.7m)과 혼돈되기 때문에 여전히 박지산이라 일컫는 이들이 많다.정상에는 2미터 높이의 돌탑이 있는데 칠원성군(七元星君)을 모셨다하여 칠성대라 부르며, 칠원성군이란 불교에서 북두의 일곱 성군을 뜻한다. 칠원성군은 북두칠성을 인격화한 신(神)이며 농사와 생사(生死), 화복(禍福)을 맡아본다고 한다. 박지산은 이곳 주민들에겐 단순히 이끼가 많은 산이 아니라 북두칠성의 산이기도 하다.", - "MNTN_HG_VL" : "1391", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면", - "MNTN_NM" : "박지산(두타산)" + "DETAIL_INFO_DTCONT" : "망경대산은 백둣대간의 상의 함백산을 모산으로 두위봉을 지나 질운산과 예미산을 지나 수라리재에서 잠시 능선을 가라앉았다가 다시 솟구친 산이다. 강원도 영월군 중동면과 하동면 경계를 이루고 있는 망경대산은 등반 경력을 가진 산악 동호인에게 조차 생소한 산이다. 10여년 전까지만해도 탄광이 들어서 있어서 산행지와 거리가 멀었다. 탄광이 빠져나가면서 이 산 인근의 산꾼들이 오르내리기 시작하여 지금은 등산로를 찾기가 수월해 졌다. 정상에 서면 남쪽으로 와석리 무릉계곡과 마대산 줄기가 장쾌한 파노라마로 펼쳐져 있고 멀리 선달산에서 소백산으로 이어지는 백두대간이 광활하게 펼쳐진다.망경대산의 산이름은 어린 단종이 숙부인 수양대군에게 왕위를 찬탈당하였다는 소식을 들은 충신 추익환이 산위에 올라 한양을 바라보며 눈물을 흘렸다는 데에서 유래되었다고 전해지며 영월 영모전에는 추익환이 단종에게 산머루를 진상하는 그림이 보관되어 있다.정상은 헬기장으로 이루어져 사방 막힘이 없이 좋은 조망을 보여준다. 북으로는 가리왕산 능선이 하늘금을 그리고 북동쪽으로는 예미산, 질운산, 두위봉으로 이어지는 능선이 보이고 동으로는 단풍산과 매봉산, 장산이 시야에 들어오고 그너머 태백산에서 선달산으로 이어지는 백두대간의 주능선이 한눈에 들어온다.남서쪽으로는 하동면 옥동리 마을이 분지처럼 보이고 산자락을 굽이치며 흐르는 옥동천이 그림같고 서쪽으로는 응봉산 방면으로 부드럽게 뻗은 능선이 시야에 들어온다.", + "MNTN_HG_VL" : "1088", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면", + "MNTN_NM" : "망경대산" }, - "longitude" : 128.60083330000001, - "latitude" : 37.583888899999998 + "longitude" : 128.61972220000001, + "latitude" : 37.161388900000013 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1084", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선", - "MNTN_NM" : "반론산" + "MNTN_HG_VL" : "301", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 소양동", + "MNTN_NM" : "봉의산" }, - "longitude" : 128.7305556, - "latitude" : 37.4641667 + "longitude" : 127.73355309999999, + "latitude" : 37.888648099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남한의 산 중 최대면적을 가지고 있는 지리산의 산세는 세인을 압도하고도 남는다. 반야봉은 지리산 제2봉으로 산세가 웅장하고 계곡이 깊으며 수목이 울창하여 고산식물과 기암절벽이 장관을 이룬다. 이에 해마다 많은 산행인이 찾고 있다. 지리산의 모든 능선을 한눈에 볼 수 있는 지리산의 중심부로, 해질무렵 운무에 둘러쌓인 반야봉의 붉은 빛 낙조는 장엄하기 그지없어 산행인의 넋을 빼놓을 정도다. 특히 여름날 작열하던 태양이 지루한 하루를 보내고 저편 너머로 숨어들 무렵이면 반야의 하늘은 온통 진홍빛으로 물들어 보는 이들을 감동케 한다.지리산이 그토록 아름다울 수가 있는지를 끝없이 되뇌여도 반야봉의 낙조는 모자람이 없다. 화려한 불꽃잔치와 더불어 반야봉은 운해와 함께 우리에게 인식된다. 늘 발아래 운해를 거느리고 우뚝 솟아 있는 반야봉의 장관은 비경 그것이다.태산준령들 사이사이에 걸려 있는 지리산의 운해는 아마도 주봉인 천왕봉과 반야봉에 얽힌 마고할미와 반야의 애틋한 마음을 그대로 전해주려는 듯 심오함을 갖고 있다.반야봉 정상에서 동쪽으로 조금 내려가면 절벽 아래에 묘향대가 있는데 이곳은 옛부터 불도들이 수도하는 유서깊은 선암으로 유명하다.", - "MNTN_HG_VL" : "1732", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군, 전라북도 남원시, 경상남도 하동군", - "MNTN_NM" : "반야봉" + "DETAIL_INFO_DTCONT" : "경남 밀양시 단장면의 백마산은 겉보기에 산꾼의 호기심을 끌어내지 못한다. 높지도 않을 뿐더러 정상석 하나없이 밋밋한 능선이 멧부리 구실을 하는 탓이다. 하지만 모든 산이 그렇듯 백마산도 나름의 맛을 지녔다.안부까지 이어지는 계곡과 정상에서의 조망은 분명 남다르다. 특히 주변의 풍광을 흡입하듯 담고 있는 밀양댐을 한 눈에 즐기는 것은 색다른 경험이다.백마산의 산행들머리는 선리 마을에서 계곡 따라 20여 분 언곡마을 (일명 담재, 다름재라 한다)에서 식수를 준비하고 계곡 따라 오른다. 25분 후 안붕에 오르면 능선에서 오른쪽으로 20여 분 지나면 갑자기 무덤이 나오고 고개 양 옆으로 갈림길이 나온다. 풍류동에서는 둥둥재라 하며, 선리 방면에서는 깐치목이라 하기도 하는데, 왼편은 풍류동으로 하여 평리마을로 가고, 오른쪽은 가산마을로 내려선다. 가고자 하는 길은 무덤 위에도 무덤 1구가 더 나타나며 능선을 따라 길이 열린다. 백마산성이 보이고 이내 정상인 백마산에 오른다. 밋밋한 구릉지를 이루고 있기에 어디가 정상인지 구분하기가 어렵다.", + "MNTN_HG_VL" : "464", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "백마산" }, - "longitude" : 127.58, - "latitude" : 35.270000000000003 + "longitude" : 128.94467259999999, + "latitude" : 35.502180600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "발교산은 강원도 홍천군 동면과 횡성군 청일면 사이에 남북으로 길게 드러누운 산이다. 발교산은 6·25의 전화도 피해갈 만큼 주위가 온통 산으로 둘러싸여 있는 오지의 한가운데 자리하고 있다. 그런 만큼 아직까지 자연 그대로의 모습을 유지하고 있다. 산행은 봉명2리에서 시작된다.봉명리는 구접이라는 이름으로도 불리는데 산이 아홉 겹이나 둘러싸고 있다 해서 그리 불렸다고 한다. 마을을 낀 계곡길을 따라 오르다 보면 소나무숲이 나오고 곧이어 가파른 오르막이 시작된다.정상까지는 오르막이 계속되어 오르는 발걸음을 무겁게 하지만 정상에 서면 공작산, 대화산이 지척에 보이고 멀리 치악산의 줄기가 시야에 와 닿는다. 철분이 많이 섞였다는 계곡의 물소리가 산행 내내 귀를 즐겁게 해준다.", - "MNTN_HG_VL" : "998", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 횡성군 청일면", - "MNTN_NM" : "발교산" + "DETAIL_INFO_DTCONT" : "lt;모유정 전설 깃든 은혜의 산gt;부모산은 청주시 비하동과 지동동에 걸쳐 있는 해발 232m의 작은 산이다. 주변 조망이 좋고, 리기다소나무, 상수리나무, 소나무 등으로 등산로가 잘 조성되어 있어 등산인들이 많이 찾는다. 본래 이산은 아양산, 악양산 등으로 불렸다. 임진왜란 때 박춘무가 복대에서 의병을 일으켜 청주성을 탈환하고 아양산 마저 탈환하여 그 곳에 머물고 있었다. 그러나 박춘무에게 패전했던 왜병이 아양산에는 물이 없다는 것을 알고 산 주위를 포위하고 보급로를 차단하자 굶어죽는 의병들이 속출하게 되었다. 때마침 의병장 박춘무의 꿈속에 지팡이를 짚은 백발 노인이 나타나 소나무를 가리키며 일어나라고 소리쳤다. 박춘무는 꿈에서 깨어나 군사들에게 소나무를 뽑게 했다. 그곳에서 식수는 물론 말에게 목욕을 시키고도 남을 만큼의 물이 솟아났다. 이것을 알게 된 왜병들이 물러났고, 이때부터 그 은혜가 부모와 같다하여 부모산이라 칭하게 되었으며, 이 우물을 모유정이라고 불렀다고 한다. 정상에는 충북기념물 제121호로 지정된 청주 부모산성(淸州父母山城)과 연화사(蓮花寺)가 있다.", + "MNTN_HG_VL" : "232", + "MNTN_LOCPLC_REGION_NM" : "", + "MNTN_NM" : "부모산" }, - "longitude" : 128.11388890000001, - "latitude" : 37.654722199999988 + "longitude" : 127.410287, + "latitude" : 36.634100400000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "337", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 옥계면 천남리", - "MNTN_NM" : "밥봉" + "MNTN_HG_VL" : "672", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군", + "MNTN_NM" : "금성산" }, - "longitude" : 129.04410139999999, - "latitude" : 37.604346700000001 + "longitude" : 128.03661880000001, + "latitude" : 35.516717800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "방가산(方可山)은 팔공지맥으로 해발 755.8m이며 군위군과 영천시의 접경구역이다. 방가산 정상에서 영천지역의 보현산천문대의 정상부를 조망이 가능하며 인근에 군위 장곡휴양림이 위치하고 있다. 방가산 등산로를 연계하여 고로면 양지리의 아미산 등산과 연계가 가능하며 총 7~8시간의 시간이소요될 것으로 예상된다.", - "MNTN_HG_VL" : "756", - "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 고로면 인곡리, 영천시", - "MNTN_NM" : "방가산" + "DETAIL_INFO_DTCONT" : "동쪽과 북쪽은 지세가 험하여 일반등산화 이상을 싣고 등반하여야 하는 곳이다.자연 경관은 산불피해를 입어서 앙상한 나뭇가지들이 있어 경관을 헤치고 있다.강원도 삼척시 미로면에 위치한 근산은 삼척에서 자랑하는 미로 8경중의 하나이다. 강을 건너는 나무다리가 오십개나 있었다 해서 이름 지어진 오십천에 물을 보태는 근산은 삼척에서 바라보면 마치 우산을 펼쳐 세워 놓은 것처럼 보인다.원시림을 그대로 간직하고 있고 동해바다를 끼고 오르는 산과 바다를 즐길 수 있는 산행을 즐길 수 있다", + "MNTN_HG_VL" : "514", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면", + "MNTN_NM" : "근산" }, - "longitude" : 128.9064362, - "latitude" : 36.134187900000001 + "longitude" : 129.1358333, + "latitude" : 37.407777799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "방문산은 일반적으로 방장산이라고 하나 실은 고창고개를 가운데 두고, 동북쪽 장성갈재 옆에 솟아 있는 733봉을 방장산, 서남쪽네 솟아 있는 640봉을 방문산이라 구분된다.방문산은 그 남서 기슭에 미륵사, 상원사, 임공사 등의 사찰을 안고 있으며 주변에는 631년(무왕 32)에 승려 여환(如幻)이 창건한 백제 때 고찰 백양사(白羊寺), 사적 제384호로 지정된 장성 입암산성이 있다. 정상 서남쪽 아래로 고창읍 시가지를 한눈에 조망할 수 있고 북쪽으로 호남평야 일대와 동남쪽으로 장성호와 멀리 무등산까지 시야에 들어온다.산행은 미륵사나 임공사 도는 신림면 신평리 신기마을 등을 등산기점으로 할 수 있으되 하산은 석정온천과 연계시킨 코스가 좋다.", - "MNTN_HG_VL" : "640", - "MNTN_LOCPLC_REGION_NM" : "전라북도 고창읍, 신림면, 전라남도 장성 북이면", - "MNTN_NM" : "방문산" + "DETAIL_INFO_DTCONT" : "호남고속도로를 지나면 차창으로 아름다운 구봉산을 볼 수 있다. 아홉 봉우리의 산이라는 뜻의 구봉산은 높이가 264미터로 낮은 산이지만 바위봉우리가 늘어서 있는 경관이 매우 아름다워 신선이 내려와 노닌다는 전설이 전해지고 있다. 또 다른 이야기로는 구봉산이 아홉 마리의 봉황새 모양이어서 새 봉(鳳)자를 쓴 구봉산(九鳳山)이라 부른다는 이야기도 있고 구봉산의 아홉 개 봉우리가 마치 대신들이 한 줄로 늘어서서 허리를 굽히고 계룡산 신도 안으로 들어가는 형국의 산세라 하여 ‘군신입조형(君臣入朝形-신하들이 임금을 뵈려고 조정에 들어가는 형국)’의 명산이라고 한다. 재미있는 것은 아홉 바위 봉우리 가운데 맨 동쪽, 대전 중심부 가까이 있는 봉우리만이 계룡산을 외면하고 있어 아홉 신하 가운데 한 사람은 반역을 꾀한다는 이야기도 있다.", + "MNTN_HG_VL" : "264", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구 가수원동", + "MNTN_NM" : "구봉산" }, - "longitude" : 126.73999999999999, - "latitude" : 35.450000000000003 + "longitude" : 127.3343871, + "latitude" : 36.2865854 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "국내 최대의 면적을 자랑하는 자연휴양림을 거느리고 있는 방태산은 강원도 인제군과 홍천군의 경계를 이루는 산으로, 교통이 불편한 관계로 아직도 오염되지 않은 깨끗한 계곡을 간직하고 있다.청정한 자연림에 들어서면 도심에서 불과 몇시간 거리밖에 떨어져 있지 않다는 사실이 믿어지지 않는다. 빽빽한 나무들 사이에 누워 하늘을 올려다보면 한줄기의 햇살도 허용하지 않는 수림의 깊이가 느껴진다.", - "MNTN_HG_VL" : "1446", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면, 상남면", - "MNTN_NM" : "방태산" + "DETAIL_INFO_DTCONT" : "백련산은 진안군 팔공산에서 남서로 가지 친 능선이 성수산, 고덕산, 백이산을 거쳐 옥정호 동편 임실군 청운면에 솟아있는 산이다. 백련산은 일명 영취산이라고도 하며, 이산을 가운데 두고 북, 서, 남으로 옥정호와 섬진강 줄기가 휘어 감고 있어 마치 연못 한 가운데 피어 있는 연꽃 같다하여 백련산이라 한다. 정상에서 남쪽으로 강진면 갈담리까지 이어진 그곳에는 조선 8대 명당중의 하나인 잉어 명당이 있다. 옛날 이곳에 묘를 쓰려고 땅을 2~3척을 파내려가니 널빤지 같은 암반이 깔려 있어, 한쪽면을 들어 올려보니 암반 밑에서 놀던 잉어 두 마리 중 한 마리가 뛰어나오자 들어올리던 암반을 다시 놓고 묘를 썼다고 하며, 그후 명당바람으로 장자가 되었다고 한다.섬진강과 산 남서쪽에 있는 회문산의 유명세에 가려 있던 백련산은 정상 전체를 차지하고 있는 부처바위가 일품이다. 정상에는 높이 솟은 부처바위 외에도 쌍선대라는 두 개의 거대한 바위가 서있다. 정상에서 바라보이는 회문산과 필봉산이 섬진강을 끼고 솟은 모습도 장관이다.동으로는 청웅면 소재지와 임실 방면 성수산 줄기가 하늘금을 이루고, 더 멀리 진안 방면 선각산과 팔공산 줄기가 보인다. 남동으로는 백련암 계곡과 백련리 분지가 평화롭게 내려다 보이고, 멀리 지리산 연봉이 웅장한 자태로 하늘금을 이룬다.남으로는 부흥리 분지가 시원하게 내려다보아고, 순창 방면 원통산과 용골산, 무량산 줄기가 출렁이는 파도인 듯 겹겹하고, 남서쪽으로는 강진면 소재지와 필봉산 뒤로 회문산이 시원하게 펼쳐진다.", + "MNTN_HG_VL" : "754", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 청웅면, 강진면", + "MNTN_NM" : "백련산" }, - "longitude" : 128.35604789999999, - "latitude" : 37.894853599999998 + "longitude" : 127.168783, + "latitude" : 35.567224400000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "133", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "월봉산" + }, + "longitude" : 127.11222220000001, + "latitude" : 36.798333300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "225", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 연제구, 수영구", - "MNTN_NM" : "배산" + "DETAIL_INFO_DTCONT" : "충북 제천시 금성면, 청풍면 교리·단양군 적성면 경계에 솟은 동산(東山)은 남근석으로 유명하다. 이 남근석이 동산을 대표한다 해도 과언이 아니다. 어른 두 세 명이 팔로 에둘러야 할 정도의 굵기와 약 3미터 높이의 크기를 자랑하는 남근석은 동산의 생명력과 원천의 상징이기도 하다. 대체로 산세가 가파르나 수려하며 동산을 지키는 수많은 기암괴석은 노송과 어우러져 운치를 더한다. 동산의 정상은 원래 세 개의 봉우리를 형성하고 있어 삼봉(三峰)이라 불렸다고 한다. 북으로는 작성산(848m), 마당재산(661.2m), 호조산(475.3m)의 산줄기를 이어받아 솟은 동산은 남으로는 금수산(1015.8m)을 빚는다.", + "MNTN_HG_VL" : "896", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면, 청풍면·단양군 적성면", + "MNTN_NM" : "동산" }, - "longitude" : 129.09638889999999, - "latitude" : 35.18 + "longitude" : 128.22666670000001, + "latitude" : 37.024722200000006 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "353", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", - "MNTN_NM" : "백두산" + "MNTN_HG_VL" : "412", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시", + "MNTN_NM" : "백족산" }, - "longitude" : 128.96777779999999, - "latitude" : 35.254444399999997 + "longitude" : 127.60416669999999, + "latitude" : 37.097222199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백련산은 높이 215.5m의 낮은 산이지만 서울시내 서대문구와 은평구의 경계에 자리하고 있어 주말이면 응암동,홍은동 일대의 주민들이 자주 찾는 산이며, 휴식공간으로 잘 활용되고 있다. 신라 경덕왕 때(서기747년) 진표율사가 창건, 무학대사가 중건한 백련사란 절이 있어 백련산이라 불리었다.", - "MNTN_HG_VL" : "216", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 은평구, 서대문구 홍은동", - "MNTN_NM" : "백련산" + "DETAIL_INFO_DTCONT" : "경기도 이천군 실촌면과 신둔면을 가르고 선 천덕봉은 마을 뒷산처럼 큰 특징이 없는 평범한 산이다. 남서쪽의 오르막길을 향하다보면 드넓은 이천평야가 시야에 들어오는데 가을녁에 보면 황금색 벌판이 장관을 이룬다.고려말 공민왕이 홍건적의 난을 피해 이곳에 왔다고 하여 공민왕봉이라고도 한다. 원적산에서 가장 높은 봉우리이며 항상 구름과 안개에 싸여 있다. 산속에 신라 선덕여왕 때 혜법선사가 세운 영원사가 있고, 계곡에는 산간 오지마을인 실촌면의 외선리·내선리가 있다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.산행길은 대체로 완만한 편이나 천덕봉 정상에서 원적봉까지 육군 사격장지대기 때문에 산행을 하려면 다시 돌아서 남서쪽의 오르막길을 올라야 한다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 실촌면, 신둔면", + "MNTN_NM" : "천덕봉" }, - "longitude" : 126.9269444, - "latitude" : 37.589444399999998 + "longitude" : 127.4425, + "latitude" : 37.358333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백련산은 진안군 팔공산에서 남서로 가지 친 능선이 성수산, 고덕산, 백이산을 거쳐 옥정호 동편 임실군 청운면에 솟아있는 산이다. 백련산은 일명 영취산이라고도 하며, 이산을 가운데 두고 북, 서, 남으로 옥정호와 섬진강 줄기가 휘어 감고 있어 마치 연못 한 가운데 피어 있는 연꽃 같다하여 백련산이라 한다. 정상에서 남쪽으로 강진면 갈담리까지 이어진 그곳에는 조선 8대 명당중의 하나인 잉어 명당이 있다. 옛날 이곳에 묘를 쓰려고 땅을 2~3척을 파내려가니 널빤지 같은 암반이 깔려 있어, 한쪽면을 들어 올려보니 암반 밑에서 놀던 잉어 두 마리 중 한 마리가 뛰어나오자 들어올리던 암반을 다시 놓고 묘를 썼다고 하며, 그후 명당바람으로 장자가 되었다고 한다.섬진강과 산 남서쪽에 있는 회문산의 유명세에 가려 있던 백련산은 정상 전체를 차지하고 있는 부처바위가 일품이다. 정상에는 높이 솟은 부처바위 외에도 쌍선대라는 두 개의 거대한 바위가 서있다. 정상에서 바라보이는 회문산과 필봉산이 섬진강을 끼고 솟은 모습도 장관이다.동으로는 청웅면 소재지와 임실 방면 성수산 줄기가 하늘금을 이루고, 더 멀리 진안 방면 선각산과 팔공산 줄기가 보인다. 남동으로는 백련암 계곡과 백련리 분지가 평화롭게 내려다 보이고, 멀리 지리산 연봉이 웅장한 자태로 하늘금을 이룬다.남으로는 부흥리 분지가 시원하게 내려다보아고, 순창 방면 원통산과 용골산, 무량산 줄기가 출렁이는 파도인 듯 겹겹하고, 남서쪽으로는 강진면 소재지와 필봉산 뒤로 회문산이 시원하게 펼쳐진다.", - "MNTN_HG_VL" : "754", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 청웅면, 강진면", - "MNTN_NM" : "백련산" + "DETAIL_INFO_DTCONT" : "경북 경산시의 북쪽에 위치한 해발1,192.3m 산이고. 관봉은 852m 봉우리로써 아주 험준한 산은 아니고 보통인은 등산하기에 알맞고 능선부위에 암반이 많은 곳으며, 자연경관이 좋고 관봉에서는 전망도 좋으며. 일년내내 불자신도와 등산객이 가장많은 장소이다.", + "MNTN_HG_VL" : "1192", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 부계면, 영천시 신녕면, 대구광역시 동구", + "MNTN_NM" : "팔공산" }, - "longitude" : 127.168783, - "latitude" : 35.567224400000001 + "longitude" : 128.69499999999999, + "latitude" : 36.016944000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 밀양시 단장면의 백마산은 겉보기에 산꾼의 호기심을 끌어내지 못한다. 높지도 않을 뿐더러 정상석 하나없이 밋밋한 능선이 멧부리 구실을 하는 탓이다. 하지만 모든 산이 그렇듯 백마산도 나름의 맛을 지녔다.안부까지 이어지는 계곡과 정상에서의 조망은 분명 남다르다. 특히 주변의 풍광을 흡입하듯 담고 있는 밀양댐을 한 눈에 즐기는 것은 색다른 경험이다.백마산의 산행들머리는 선리 마을에서 계곡 따라 20여 분 언곡마을 (일명 담재, 다름재라 한다)에서 식수를 준비하고 계곡 따라 오른다. 25분 후 안붕에 오르면 능선에서 오른쪽으로 20여 분 지나면 갑자기 무덤이 나오고 고개 양 옆으로 갈림길이 나온다. 풍류동에서는 둥둥재라 하며, 선리 방면에서는 깐치목이라 하기도 하는데, 왼편은 풍류동으로 하여 평리마을로 가고, 오른쪽은 가산마을로 내려선다. 가고자 하는 길은 무덤 위에도 무덤 1구가 더 나타나며 능선을 따라 길이 열린다. 백마산성이 보이고 이내 정상인 백마산에 오른다. 밋밋한 구릉지를 이루고 있기에 어디가 정상인지 구분하기가 어렵다.", - "MNTN_HG_VL" : "464", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "백마산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "백이산" }, - "longitude" : 128.94467259999999, - "latitude" : 35.502180600000003 + "longitude" : 128.7102778, + "latitude" : 37.3011111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "469", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", - "MNTN_NM" : "백마산" + "DETAIL_INFO_DTCONT" : "청옥산은 백두대간이 금강산, 설악산, 오대산 등을 빚으며 동해안을 따라 남동쪽으로 내려가다가 동해지방 해안가에 이르러 솟아 오른 명산이다. 두타산과 함께 사방에 드리운 능선과 고개를 끼고 있으며, 짙푸른 동해를 손아래로 굽어 보고 있다. 이 산은 여러 등산로와 유적지가 있어 아름다운 절경을 감상하는 등산객의 발길이 끊이지 않는 곳이기도 하다. 두타산과의 거리는 약4km정도여서 일찍 서두른다면 두타산과 청옥산을 함께 오를수도 있다. 청옥산과 두타산 산아래 펼쳐진 국민관광지 1호 무릉계곡은 100여명을 수용할 수 있는 무릉반석과 학소대, 선녀탕 그리고 계곡 양편에 깎아지른 듯한 병풍바위 등 웅장한 절경을 안고 있다.두타산 북릉에는 두타산성이 있고, 바위가 좋아서 오르기엔 안성마춤인 코스이다. 상대적으로 두타산에서 청옥산에 이르는 코스는 부드럽고 완만하여 하산로로 이용하는것이 좋다. 청옥산까지 종주한후 연칠성령이나 학등을 이용하여 하산할경우 거리도 약 20km나 되고 소요시간도 대략 9시간정도가 소요될걸로 생각된다. 산이 워낙 크고 깊기때문에 눈이나 비가 많이 올때는 삼가하는편이 좋다.", + "MNTN_HG_VL" : "1403", + "MNTN_LOCPLC_REGION_NM" : "강원도 동해시 삼화동, 삼척시 정선군", + "MNTN_NM" : "청옥산" }, - "longitude" : 127.96885260000001, - "latitude" : 35.322628600000002 + "longitude" : 128.9735857, + "latitude" : 37.433949400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "286", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시", - "MNTN_NM" : "백마산" + "DETAIL_INFO_DTCONT" : "통영시 사량면 아랫섬(하도)에 위치한 해발 349m의 산으로서 남쪽으로 뻗은 산줄기를 따라 7개의 봉우리가 솟아 있어 칠현봉(七絃峰)이라 하는데 이 가운데 망산(공수산, 해발 310m)에는 옛 사량진의 봉수지(烽燧址)가 있다. 칠현봉에는 등산로와 안내판이 잘 정비되어 있고 일곱 봉우리를 오르내리는 능선길이 재미있을 뿐아니라 사방으로 탁 트인 전망 또한 좋아 근래 가장 각광받는 등산코스이다.산기슭에 칠장사가 있다. 고려 때 혜소국사가 일곱 도적을 제도하여 도를 깨치게 했다 하여 칠현산이라 불리게 되었다. 칠장산과 붙어 있어 함께 산행할 수도 있다. 산행은 걸미고개에서 시작하여 극락마을을 통해 정상에 오른 뒤 다시 극락마을로 내려와 걸미고개로 하산한다. 칠장산과 이어서 등반하려면 걸미삼거리에서 신대마을로 들어가 원효암을 지나 정상에 오른 뒤 갈림길에서 칠장사를 거쳐 칠장산에 올랐다가 사거리 갈림길에서 신미창교로 내려와 미장리 정류장으로 하산한다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량도", + "MNTN_NM" : "칠현산" }, - "longitude" : 127.27716820000001, - "latitude" : 37.368814299999997 + "longitude" : 128.2317299, + "latitude" : 34.8234979 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태백시 동쪽 경계에 있으며, 태백시계의 연봉 중 하나다. 해발 1259미터로 백두대간에서 갈라져 나온 낙동정맥의 산들 중 가장 높기도 하다. 낙동정맥은 백두대간 천의봉(매봉산, 1303m) 동쪽 능선에 있는 1145봉에서 부산 몰운대에 이르는 350여 킬로미터의 산줄기이다.백병산은 금대봉 같은 육산과 달리 정상부가 마치 바위병풍을 둘러놓은 듯하다고 해서 백병산이라 이름 붙었다. 전해오는 이야기에 따르면 병풍바위가 가뭄 때는 흰빛을, 비가 올 때는 검은 빛을 띠므로 바위 색깔만을 보고 가뭄이 올 것인지 홍수가 날 것인지를 판단했다고 한다.", - "MNTN_HG_VL" : "1259", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 황연동", - "MNTN_NM" : "백병산" + "DETAIL_INFO_DTCONT" : "경기도 포천군 관인면에 있는 종자산(643m)은 그 모양새부터 범상치 않다. 한탄강을 굽어보며 마치 병풍처럼 솟은 산으로 절벽으로 이루어졌다 해도 과언이 아니다. 하얀 물줄기와 수직으로 솟은 절벽은 서로에게 조금치의 양보도 없이 한껏 자신의 아름다움을 자랑한다. 그 모습이 눈이 부셔 이곳을 찾는 이들의 산행을 더디게 하며 진달래와 단풍 또한 좋다.정상 남동편 들머리에는 굴바위가 있는데 전설에 의하면 옛날 3대 독자의 부부가 아이를 못 낳아 고심하던 중이 굴에서 백일기도를 올린 뒤 아들을 낳았다고 하며 종자산(씨앗산) 명도 여기에서 유래되었다고 한다.정상에 다다르면 오른쪽 깎아지른 듯한 낭떠러지 아래로 고남산과 은장산 사이에서 흘러 내려오는 한탄강이 보인다. 동북쪽으로는 철원평야가 아련하고 북쪽으로는 향로봉을 지나 지장봉, 고대산으로 이어지는 능선이 가물가물하다.", + "MNTN_HG_VL" : "643", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 관인면", + "MNTN_NM" : "종자산" }, - "longitude" : 129.06833330000001, - "latitude" : 37.158333300000002 + "longitude" : 127.1907673, + "latitude" : 38.077864900000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백봉은 평범한 산이라 별다른 재미가 없다고 말할지 모른다. 그러나 숲속의 산길이 유난히 편안하고 단풍나무가 많아 화사한 것이, 평범하지만 잔잔한 재미가 있는 산이다. 백봉 산행을 뜻깊게 하는 것 중 하나는 묘적사와 홍릉 등의 유적이다.묘적사는 백봉 남쪽 골짜기에 있다. 묘적사계곡을 중심으로 백봉의 산등성이가 말발굽모양으로 둘러싼 산세이기에 묘적사는 산행 들머리 혹은 날머리 기점이 된다. 그래서 묘적사 골짜기에 들어서면 협곡의 개울을 따라 꼬불꼬불 휘돌아 들어가는 것이 마치 별천지에 들어온 느낌이 든다.지형도에는 백봉의 이름은 흰 ‘백’ 자를 쓴 백봉(白峰)으로 되어 있으나 본래 이름은 잣봉산 혹은 묘적산이다. 남양주 시지에 의하면 평내동과 화도읍 쪽에서는 백봉을 잣봉산이라 부르며 와부읍에서는 묘적산이라 부른다고 밝히고 있다.백봉은 수도권에서 멀지 않고 인구 밀집지역인 남양주 도심에서 가까이 있는 산이어서 많은 사람들이 오르내린다. 따라서 길도 좋고 갈래도 많다. 그러나 백봉의 참맛을 보려면 홍유릉과 묘적사를 잇는 산길이 가장 좋다. 이 코스가 좀 길어도 산길이 험하지 않고 편안해 4시간 정도면 산행을 마칠 수 있다.", - "MNTN_HG_VL" : "587", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 평내동, 와부읍, 화도읍", - "MNTN_NM" : "백봉산(백봉)" + "DETAIL_INFO_DTCONT" : "청계산이란 이름을 가진 산이 경기도에만 세 곳이 있다. 양평군 양서면의 청계산(658m)과 과천시와 성남시의 경계를 이루는 청계산(618m), 그리고 포천군 일동면과 가평군 하면의 경계를 이루는 청계산(849m)으로 이 중에서 포천 청계산이 가장 높고, 산세가 커 산행코스도 다양하다.수도권 지역에서 등산인들이 즐겨찾는 산들 중 하나인 청계산은, 관악산과 마주한 과천의 청계산(618m)과 양평군 양서면에 있는 청계산(658m)보다 그 규모나 아름다움에 있어 으뜸으로 꼽힐 만한 곳이다.이 청계산(849.1n)의 일반적으로 잘 알려진 등산 코스는 청계저수지를 기점으로 해서 길매고개를 거쳐 정상에 오른 뒤 동북쪽으로 뻗은 계곡을 통해 다시 청계저수지로 하산하는 것이다. 상판리 방면에서 갈매재로 올라가는 길은 1990년부터 입산금지 구역으로 지정되어 있다.실제 정상은 서북쪽에 솟은 육산의 모습을 지닌 봉우리다.정상에서 북쪽으로 내려설 때 바위지대를 지나야 하므로 안전에 유의하도록 한다.", + "MNTN_HG_VL" : "618", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", + "MNTN_NM" : "청계산" }, - "longitude" : 127.2577778, - "latitude" : 37.638888899999998 + "longitude" : 127.3701707, + "latitude" : 37.933052600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백석봉은 백두대간상의 노인봉에서 남쪽으로 길게 뻗어 내린 산맥이 소황병산과 용산, 박지산을 크게 일으키고 오대천과 조양천의 합류지점인 북평면에 솟아 있는데, 정선 9대 명산 중의 하나이다.산정에 백색을 띈 큰 바위로 인해 백석봉이라 불리게 된 이 산은 숙암리와 나전 2리에 등산로를 새로 개설하여 등산하기 편해졌다. 산 정상에는 신기한 약효가 있는 샘이 있는데 이 물을 부정한 사람이 마시면 마른다는 전설이 있으며 이 웅봉이 검게 변하면 수일내에 비가 내린다는 전설이 전해내려 오고 있다.정상에 서면 철쭉이 군락지를 이루고 있는 숙암계곡이 아찔하게 내려다 보인다. 이 계곡 주변에는 맑고 깨끗한 숙암샘터가 있다. 등산 외에도 계곡길을 따라 드라이브를 즐기기에 좋은 코스다. 능선에는 진달래 군락지가 곳곳에 있고 참나무 군락지에는 겨우살이가 지천이다. 듬직한 능선길은 고산다운 풍경이여서 좋고, 등산로는 안내판이 잘 설치되어 있다.", - "MNTN_HG_VL" : "1170", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면", - "MNTN_NM" : "백석봉" + "DETAIL_INFO_DTCONT" : "등산을 즐기는 사람이라도 경기도 양평에 편전산이 있다는 것을 아는 사람은 그다지 많지 않다. 널리 알려지지 않은 산들이 그렇듯이 편전산은 호젓한 산행을 즐기기 좋으며 수풀이 우거져 덮수룩한 산길을 걷는 묘미가 있는 산행지이다. 이 산에는 특히 소나무와 참나무가 많으며 곳곳에 억새풀 수풀림이 형성되어 있다. 정상에 서면 북쪽 건너편에 동그마니 들어앉은 마유산이 보이고 동쪽으로 용문산 주봉과 그 연릉이 남으로 길게 뻗어 나가다 솟구친 백운봉이 가깝게 눈에 든다.정상에 오르면 북쪽 건너편에 커다란 무덤처럼 둥근 산세를 지닌 마유산이 보이고 동쪽으로는 용문산의 주봉과 그 연릉이 남으로 길게 뻗어가다가 솟은 백운봉이 가깝게 조망된다.", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군", + "MNTN_NM" : "편전산" }, - "longitude" : 128.6408333, - "latitude" : 37.481944400000003 + "longitude" : 127.4802778, + "latitude" : 37.541111099999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백석산은 이승복 생가터와 방아다리약수가 있는 계곡을 구분하는 능선이 속사리재를 지나 솟아오른 산 중의 하나로 계방산과 이웃해 있다. 이 산의 주능선은 넓은 초원지대를 이루고 있으며 주능선에서 사방으로 계곡이 펼쳐져 있어 자연 그대로의 계곡미를 간직한 산이다.산 정상에 흰 바위가 있어 백석산이라고 부르게 되었다고 전해지며, 백석산 정상 평지에는 깃대봉이 세워져 있고 서편은 기암 절벽이며 동쪽으로는 가리왕산이 손에 잡힐 듯 가깝게 보인다. 정상 남쪽 마랑치에서 서쪽으로 돌아 들어가면 암봉 밑에 영암사가 있는데 100여 년 전 산삼을 캐기 위해 지은 산막이 사찰로 변하게 된 것이라고 한다.", - "MNTN_HG_VL" : "1365", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", - "MNTN_NM" : "백석산" + "DETAIL_INFO_DTCONT" : "섬진강과 보성강을 가르고 있는 통명산은 그리 높은 산은 아니지만 지리상으로 중요한 위치를 점하고 있다. 통명산을 주산으로 주부산과 곤명산 산줄기가 섬진강과 보성강을 가르고 있기 때문이다. 일반적으로 곡성하면 동악산을 생각하지만 최고봉은 분명 통명산이다. 4개 면의 경계가 되는 지리적인 요충지 외에도 이름조차도 하늘의 옥황상제가 기거한다는 통명전을 뜻하니 말이다. 또한 곡성이 배출한 명장 신숭겸과 마천목은 각각 고려초와 조선초기에 주군을 도와 나라의 기초를 다지는데 기여한 인물들인데 바로 통명산 자락에서 태어났다.제단을 쌓은 듯 평평한 정수리의 조망은 시원하기 이를 데 없다. 북쪽으로 동악산과 곡성읍이, 동쪽으로는 주부산과 지리산의 위용이, 남쪽으로는 조계산을 이어 달리는 호남정맥과 주암호를 지나온 보성강 물줄기가 섬진강을 향하여 굽어드는 절경이 펼쳐진다.", + "MNTN_HG_VL" : "764", + "MNTN_LOCPLC_REGION_NM" : "전남 곡성군 죽곡면", + "MNTN_NM" : "통명산" }, - "longitude" : 128.51604320000001, - "latitude" : 37.539788799999997 + "longitude" : 127.2616723, + "latitude" : 35.208018799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백아산은 전라남도 화순군에서도 오지라고 할 수 있는 북면에 위치한다. 그렇기 때문에 그저 평범한 산으로 지나치기 쉬우나 이 산이 전남의 명산들을 조망하기에 매우 좋은 위치에 자리하고 있다는 것은 백아산에 오르는 순간 알게 된다. 한때 빨치산 활동지로도 유명한 백아산은 그들이 차지하고 활동할 만큼 사방 수십 리에 걸쳐 거침이 없다.석회석으로 된 산봉우리가 마치 흰 거위들이 모여 앉아 있는 것처럼 보여 백아산(白鵝山)이라는 이름이 붙여졌다고 한다. 산 북쪽으로 무등산(1187m)이, 남쪽으로 모후산(919m)이 있다. 날카로운 바위가 많고 산세가 험하나 등산로가 잘 정비되어 순탄한 산행을 즐길 수 있다. 산 중턱에는 화순 아천산 천연동굴이 있다. 석회암 동굴이며, 약 2억년 전에 생성된 것으로 추정하고 있다.", - "MNTN_HG_VL" : "810", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 북면", - "MNTN_NM" : "백아산" + "DETAIL_INFO_DTCONT" : "사북읍 뒤편에 있는 강원 정선 두위봉은 탄광으로 널리 알려져 있지만 최근에는 초여름 철쭉산행지로 각광받고 있다. 이 산에는 빽빽하게 군락을 이룬 철쭉지대가 수만 평이 넘도록 펼쳐져 있어 마치 연분홍 양탄자가 깔려있는 듯한 착각에 빠진다. 탁 트인 시야와 초원지대 한 가운데 고인 맑은 연못, 수령 1천 8백년을 자랑하는 국내 최고의 주목, 깎아지른 듯한 절벽 등 갖가지 절경도 접할 수 있다.두위봉은 산이 두루뭉실하다 하여 ‘두리봉’으로도 부른다. 특이한 것은 정상이 주능선의 1킬로미터 거리에 두 개가 있다. 삼각점이 있는 봉우리가 정상이었는데, 철쭉기념비를 세워놓은 바위로 된 봉우리가 경관이 더 좋아 1999년 이곳에 정상 표지석을 세웠다고 한다.자미원이나 함백마을에서 올라가면 만나는 능선의 아라리 고개에서 도사곡으로 갈라지는 사이의 주능선과 계곡의 등산로가 울창한 산림으로 우거져 있다. 정상에서 아라리 고개 사이에 참나무 군락지, 도사곡 및 자미원에서 오르는 등산로 주위에 자작나무 군락지가 있고 도사곡에는 국내에서 나이가 가장 많다는 주목나무가 있다.", + "MNTN_HG_VL" : "1470", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면, 사북읍·영월군 중동면 직동리", + "MNTN_NM" : "두위봉" }, - "longitude" : 127.1639881, - "latitude" : 35.1661888 + "longitude" : 128.7534191, + "latitude" : 37.212416400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백악산은 속리산 문장대에서 북쪽 화양동 계곡 방면으로 이어진 긴 능선위에 솟아있는 봉우리로 경북 상주와 충북 괴산의 도계를 이루고 있다. 규모는 작지만 화강암으로 된 여러 형상의 바위들이 산악미를 보여주는 옹골찬 산이다.속리산 국립공원의 중간지점에 위치하고 있는 이 산은 정상을 중심으로 좌우 편은 암봉과 암릉으로 연결되어 장관이고, 주능선 남쪽 면은 완만한 반면 북쪽은 절벽을 이루어 아찔하다.정상 북쪽 옥양골에는 유명한 옥양폭포가 있고, 폭포위 계곡 서편으로 조금 들어가면 암벽에 기이하게 생긴 석굴이 있는데 일명 보굴이라 불리기도 한다. 수양대군의 딸이 단종의 왕위를 차지하려는 아버지의 음모를 눈치채고 발설했다가#51922;겨나 숨어 지낸 곳이라고 전해지고 있다.", - "MNTN_HG_VL" : "857", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 괴산군 청천면", - "MNTN_NM" : "백악산" + "DETAIL_INFO_DTCONT" : "미륵산은 강원도 원주시에서 남쪽으로 약 22km 거리인 원주시 귀래면에 위치해 있다. 기암괴봉과 노송이 어우러져 한 폭의 동양화를 연상케 하는 산이다.미륵산은 정상에 거대한 미륵불상이 새겨져 있는 것으로 유명하다. 수석처럼 멋드러진 암봉이 12개나 치솟아 독특한 산세를 나타내며 바위틈을 비집고 붙어있는 노송이 그 절묘함을 더한다. 겨울철에는 노송과 암벽에 피어 있는 설화가 일품이다.산은 그다지 높지 않으나 부드러운 능선길과 아기자기한 암릉길이 조화를 이루고 있어 산행의 정취와 묘미를 느끼게 한다.정상인 신선대에서 북동쪽을 보면 백운산과 치악산맥이 보이며 동으로는 십자봉이, 남서쪽 멀리로는 남한강 물줄기가 보인다.신선대 아래의 미륵불상을 지나고 동쪽 능선을 따라 20분 정도 내려가면 황산사이다. 신라 경순왕 때 창건된 고찰이다. 정상에서 아기자기한 암릉으로 이어지는 남릉을 타노라면 한 폭 그림속을 거니는 기분이다. 암릉마다 분재와 같이 아름다운 노송들이 속세의 때가 묻지 않은 그대로다.산행을 마치고 황산사 를 내려오면 시원한 계곡이 흐르기에 산행의 흐른땀을 씻어준다.", + "MNTN_HG_VL" : "696", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면", + "MNTN_NM" : "미륵산" }, - "longitude" : 127.85768899999999, - "latitude" : 36.614499700000003 + "longitude" : 127.8530556, + "latitude" : 37.186111099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백암산은 드넓은 호남평야를 마주하고 솟아오른 높이 741.2m의 산으로 내장산 국립공원에 속한다.옛부터 봄이면 백양, 가을이면 내장이라 했듯이 산하면 내장, 고적하면 백암이라 할 정도로 백암산의 절경은 내장산에 뒤지지 않는다. 백학봉과 상왕봉, 사자봉, 등의 기암괴석이 곳곳에 있으며, 산세가 험준한 편이다. 특히 비자나무숲과 회색 줄무늬 다람쥐가 유명한 이곳에는 대한 불교 조계종 18교구 본산인 대사찰 백양사도 있다.", - "MNTN_HG_VL" : "741", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 복흥면, 전라남도 장성군 북하면", - "MNTN_NM" : "백암산" + "DETAIL_INFO_DTCONT" : "고흥군 금산면 거금도에 솟아있는 적대봉은 마치 바다에 떠 있는 고래등 같은 모습을 하고 있다. 녹동에서 여객선으로 20여분 정도 걸리는 거리로, 뭍과 그리 멀리 떨어지지 않은 거금도는 섬 자체가 하나의 면을 이룰 정도로 커다란 섬이면서도 멀리서 바라보면 둥그스름한 하나의 산처럼 보이기도 하다.섬 안에 큰 금맥이 뻗어 있어 거금도라 불린다는 이 섬의 한가운데 솟아 있는 적대봉은 북쪽으로 천등산, 마복산이 서쪽으로 장흥 천관산과 마주보고 있다. 섬 산이면서도 고흥군에서는 팔영산 다음으로 높아 펑퍼짐한 산세와 달리 전망이 매우 뛰어나다. 이러한 지형적 특성 때문에 조선시대에 축조된 둘레 34미터, 지름 7미터의 큰 봉수대가 정상에 있다.정상에 서면 서쪽으로 완도, 남쪽으로 거문도, 동쪽으로 여수 일원의 바다와 섬들이 한눈에 들어올 뿐만 아니라 날씨가 좋으면 멀리 제주도가 바라보일 정도로 전망이 좋다.산행은 적대봉 서쪽 능선을 가로질러 거금도 남북을 잇는 임도의 북단에 위치한 성치마을에서 시작, 파상재를 거쳐 정상에 올라 파상재로 내려선 다음 송광암을 거쳐 면소재지로 내려서는 코스가 가장 즐겨 찾는 코스다.산기슭에는 조선시대에 목장성이 있었던 것으로 알려져 있다. 거금도는 이웃한 소록도, 절제도, 시산도, 나로도와 함께 도양 목장에 속한 속장의 하나였으며 이 산을 중심으로 성을 쌓아 말 116마리를 키웠던 세납 목장이 있었다. 거금도 남북을 가로질러 석정리와 어전리를 잇는 임도 곳곳에는 아직도 목장성 흔적이 남아 있다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 금산면", + "MNTN_NM" : "적대봉" }, - "longitude" : 126.85083299999999, - "latitude" : 35.462778 + "longitude" : 127.1802778, + "latitude" : 34.462222199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "741", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천", - "MNTN_NM" : "백암산" + "DETAIL_INFO_DTCONT" : "우리나라에서 다섯번째로 큰 섬인 강화도에는 고려산, 혈구산, 진강산, 마니산 등 400m 이상의 4개산이 남북으로 일직선상에 솟아 있는데 그 중 제일 높은 산이 마니산이다. 〈고려사〉〈세종실록지리지〉〈태종실록〉 등 조선 초기에 발간된 문헌에는 머리산, 우두머리산이란 뜻의 마리산(摩利山) 또는 두악(頭嶽)으로 쓰여 있다. 그래서 지금도 마리산이라는 이름을 혼용해서 사용하고 있지만, 오랫 동안 마니산이라 불러왔는데 새삼 마리산이라고 하여 혼동을 줄 필요는 없을 것같다.마니산은 비교적 낮고 수도권에 가까운 거리에 있어 친정을 찾는 기분으로 편하게 찾을 수 있다. 해발이 낮더라도 주능선이 암릉으로 되어 있으니 등산의 묘미도 한껏 만끽할 수 있는 산이다.동남으로 가느다랗게 뻗은 능선을 따라 오르다 보면 망망한 서해를 조망할 수 있다. 조국순례 안내판이 있는 '개미허리'에서 98개의 계단길을 올라가면 사적 제 136호인 '참성단'(塹星壇)을 만날 수 있다. 이곳에서 매년 개천절과 전국체전때마다 성화가 채화된다. 참성단은 단군 왕검 재위 51년(BC2283년)에 운사(雲師)인 배달신(倍達臣)이 마리산에 쌓은 제단으로, 〈삼국사기〉에 의하면,고구려.신라.백제의 여러 왕들이 이 곳에서 하늘에 제사를 지냈다. 고려 공민왕 때와 조선 인조.숙종 때 각각 보수되어 현재 이른다. 이 단은 화강석을 쌓아올려 만든 것으로, 밑부분은 둥글고 윗부분은 사각형이며, 높이가 총6m에 달한다. 참성단 위에 오르면, 동쪽으로 정상이 손에 잡힐 듯 가깝게 보이고, 남쪽 아래로는 푸른 물결이 넘실거리는 넓은 바다가 발아래로 펼쳐지고, 동남쪽 멀리 인천시가지가 아득히 보인다.정상 서쪽 산기슭에는 신라 선덕여왕 8년(639년)에 창건했다는 정수사와 함허대사(涵虛大師)가 수도하였다는 함허동천이 자리잡고 있다. 함허동천에는 1백여m의 암반위로 물이 흐르고, 암반에는 함허대사가 새겼다는 '涵虛洞天'(함허동천)이란 글자가 음각 되어 있다. 외침을 자주 받았던 고려가 부처의 힘으로 나라를 지켜 보려고 강화도에서 크게 불사를 펼쳤던 까닭인지 강화도에는 내력 있는 절이 많다.", + "MNTN_HG_VL" : "472", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 화도면", + "MNTN_NM" : "마니산" }, - "longitude" : 128.16748430000001, - "latitude" : 37.848827800000002 + "longitude" : 126.434827, + "latitude" : 37.611603000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백암산 하면 내장산국립공원에 속한 전남 장성 백암산(741.2m)과 경북 울진군 온정면에 자리한 백암산이 대표적이다. 장성 백암산은 백양사와 더불어 가을 단풍지로 각광받고 있지만 대체로 많은 이들이 울진 백암산을 먼저 떠올린다.산 정상부에 흰바위가 있어 백암산이라 이름 붙여진 1004미터 고봉은 국민관광지로 지정된 백암온천의 유명세 덕분에 많이 알려져 있다. 또한 신라시대 한 사냥꾼이 사슴을 쫓다가 발견했다는 백암산은 고려 공민왕이 난리를 피해 숨었던 산이라 전한다. 그러나 무엇보다도 백암산은 북쪽 검마산에서 이어져 남쪽 아랫삼승령으로 이어지는 낙동정맥의 한 산줄기로 험하지 않지만 위용있는 산세를 자랑한다.백암산의 대표적인 등산로는 크게 세 코스다. 숙박시설단지를 지나 능선을 타고 백암산을 오르거나 백암폭포를 지나 가파른 길을 따라 정상에 닿을 수 있다. 나머지 하나는 용소를 비롯한 12개의 소가 이어져 있다는 선시골계곡을 따라 오르는 길이다.백암산 꼭대기에 서면 동해바다가 한눈에 들어온다.바다에 차츰 붉은 기운이 감돌다가 불쑥 떠오르는 해돋이는 말 그대로 장관이다. 더욱이 맑은 날이면 멀리 울릉도까지도 눈에 들어온다.백암산 중턱에는 예부터 뛰어난 효험을 자랑하는 백암온천이 자리잡고 있다.", - "MNTN_HG_VL" : "1004", - "MNTN_LOCPLC_REGION_NM" : "경북 울진군 온정면, 영양군 수비면", - "MNTN_NM" : "백암산" + "DETAIL_INFO_DTCONT" : "연석산은 전북 진안군과 완주군의 경계를 이루며 운장산과 이웃해 있는 산이다. 오지에 숨겨진 산으로 맑은 물과 울창한 숲이 자연 그대로 잘 보존되었다.산행은 정겨운 농촌 풍경이 물씬 풍기는 정수암마을에서 시작되는데 이곳에서 연석산 정상으로 가는 산길 초입은 완만한 묵밭사이로 억새가 군락을 이루고 있다. 연석산 정상은 민둥봉이나 북쪽으로 뻗어나간 능선에는 병풍바위를 비롯하여 빼어난 암봉이 우뚝우뚝 서 있다. 동쪽으로는 덕유능선이 다가오듯 어른거리고, 남쪽으로는 진안 마이산이 말귀처럼 쫑긋하게 솟아있다. 서편 사봉리로 흘러내린 연골계곡 단풍이 아름다운 지대이다.", + "MNTN_HG_VL" : "928", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군", + "MNTN_NM" : "연석산" }, - "longitude" : 129.29821530000001, - "latitude" : 36.717375500000003 + "longitude" : 127.3316667, + "latitude" : 35.9072222 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "895", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 두촌면", - "MNTN_NM" : "백우산" + "DETAIL_INFO_DTCONT" : "한계령 오른쪽으로 보이는 점봉산은 설악산 대청봉과 남북으로 마주보며 설악산 국립공원의 일부를 이루고 있다.주요 관광명소로는 12담 구곡으로 불리는 주전골이 있는데, 좌우로 갖가지 모양의 바위봉우리, 원시림, 맑은 계곡물이 어우러져 절경을 이루며, 특히 주전골 입구의 오색약수터는 빼놓을 수 없는 관광지다. 군사지역으로 출입이 통제되고 있는 것이 안타까울 뿐이다. 지소 조금 아래쪽 안국사로 오르는 길은 돌비탈을 지나야 하고 길도 애매하므로 산행기점은 일반적으로 서창리지소를 택한다.", + "MNTN_HG_VL" : "1426", + "MNTN_LOCPLC_REGION_NM" : "강원도 양양군 서면, 인제군 기린면ㆍ인제읍", + "MNTN_NM" : "점봉산" }, - "longitude" : 128.08235389999999, - "latitude" : 37.842965800000002 + "longitude" : 128.4252587, + "latitude" : 38.049280499999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한마리의 새가 금방이라도 하늘을 향해 날아오르려 한껏 날개를 펼친 모습에 산새는 주변에 백암삼 가마봉 고적산 매봉산 송곳대산들이 서로의 자태를 뽐내고 있다.백우산은 높은산을 오를때와 같은 맛은 느낄수 없지만 올망졸망한 능선에 오르막 내리막이 재미있다.용소계곡에는 넓이 200여평의 작은 너래소,500여평큰 너래소를 비롯하여 자연경관이 절경이다.", - "MNTN_HG_VL" : "895", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면", - "MNTN_NM" : "백우산" + "DETAIL_INFO_DTCONT" : "여분산은 특징이 없는 그저 평범한 산이다. 그러나 정상에서의 조망은 사방이 툭트여서 막힘없이 아주 좋다. 남으로 호남정맥의 용추봉(龍秋峰)과 무등산, 동으로 지리산의 연봉들이 아스라히 마루금을 이룬다. 서로는 용추봉과 세자봉(世子峰)이 눈앞에 다가선다.때로 조용한 길을 걸으면서 주위의 생명들과 동화될 때 느껴지는 기쁨이 좋은 사람들과 만날 때의 그것보다 더 클 경우가 있다. 구림면에 위치한 여분산은 이런 기분을 최고조로 경험할 수 있게 해준다. 인적이 드물어 길이 희미한 곳도 간간이 있는 이 산은 떨어져 쌓였다가 점점 썩어가며 제 나무의 거름이 되는 잎사귀들과 그 사이를 자유롭게 오가는 산짐승들을 보며 오르는 산행을 통해 침착하고 한결 순해진 마음을 갖게 한다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 구림면", + "MNTN_NM" : "여분산" }, - "longitude" : 128.08235389999999, - "latitude" : 37.842965800000002 + "longitude" : 127.0565735, + "latitude" : 35.483787999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;새의 날개깃에 숨겨진 비경지대gt;홍천군 내촌면과 두촌면 경계에 있는 백우산은 한강기맥의 춘천지맥에 있는 백암산에서 서쪽으로 흘러나온 산이다. 겨울에 눈이 쌓이면 새가 하늘을 향해 날아오르려 날개를 펼친 것처럼 보여 백우산이라 부른다. 토질이 검고 부드러운 전형적인 육산이다. 인적이 드문 산이라 봄, 여름, 가을, 철따라 피는 여러 야생화를 볼 수 있다. 가족고개가 표고 550m 이므로 895m의 백우산 정상까지 힘들지 않게 올라간다. 하산은 홍천 9경의 하나이며 홍천강 발원지인 용소계곡(경수골)으로 하산하는 것이 좋다. 백우산 산행의 백미는 역시 용소계곡이다. 용소계곡은 남쪽의 백우산과 매봉, 북쪽의 가마봉과 소뿔산 사이로 굽이쳐 흐른다. 가족동에서 시작하여 천현리까지 봄철의 철쭉과 가을단풍 비경 30리가 이어지므로 계곡트레킹 자체만으로도 의미 있는 산행이다. 여름철 이곳에 오면 누가 권하지 않아도 다투어 옷 입은 채로 너래소에 뛰어든다. 가족고개 농가에서는 곰취, 곤드레, 야콘, 감자 등 친환경채소를 재배하면서 현지 판매도 한다. 내촌면 광암리 일원은 재래 토종벌 보호지역으로서 지역 내에 양봉 전사를 금지하고 있다.", - "MNTN_HG_VL" : "895", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 두촌면", - "MNTN_NM" : "백우산" + "DETAIL_INFO_DTCONT" : "경남 합천군 가야면에 위치한 매화산은 가야산국립공원에 속해 있으면서도 가야산의 유명세에 아직 빛을 발하지 못하는 명산이다. 흡사 금강산 축소판과 같은 산세에 날카로운 바위능선이 있는가 하면 울창한 상록수림이 녹색과 붉은색의 조화를 이루기도 한다.매화산은 가야남산·천불산이라고도 부른다. 가야산의 지맥으로 산세가 웅장하며 가야산에 버금가는 다양한 산세를 지니고 있다. 불가에서는 천불산으로 부르는데, 이는 천개의 불상이 능선을 뒤덮고 있는 모습과 같다고 하여 붙여진 명칭이다.단풍이 수려하려면 기암괴석이 발달돼야 하는데 매화산이 바로 그런 산이다. 암봉 사이사이에 단풍이 물들어 그 사이로 뚫린 등산로를 통과하는 산행의 묘미는 특히 일품이다. 봄이면 진달래꽃, 가을이면 붉게 물든 단풍이 절정에 이르고, 겨울이면 소나무 숲이 어울려 설경이 가히 천하제일의 절경을 빚어낸 찬탄을 금치 못하게 한다.", + "MNTN_HG_VL" : "1085", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 가야면", + "MNTN_NM" : "매화산" }, - "longitude" : 128.08235389999999, - "latitude" : 37.842965800000002 + "longitude" : 128.09546739999999, + "latitude" : 35.773327199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백운봉은 양평읍에서 북동쪽으로 약 10km 떨어진 용문산 남쪽끝의 바위 봉우리이다. 높이가 940m로 주변의 용문산, 도일봉, 중원산 등과 함께 경기도 안에서는 비교적 높은 산으로 알려져 있으며 함왕봉과 능선으로 이어져 있다. 서쪽에는 함왕골, 동쪽에는 연수리계곡이 있으며 정상과 주능선에는 암봉이 많다. 함왕골에는 923년(경명왕 7)에 승려 대경이 창건한 사나사(舍那寺)가 있으며, 3층석탑, 대적광전, 원증국사비, 부도 등이 있다.능선은 골이 깊고 다향하여 매혹적이고 사적지가 많다. 잘 알려지지 않아 오염이 덜 되어 있고 호젓한 산행을 즐길 수 있다. 겨울철 하산길에 즐길 수 있는 자연 눈썰매코스가 매력적이다. 정상에서 남북으로 이은 주능선과 지능선마다 소나무와 암봉들이 조화를 이루고 있고 높은 암봉으로 이루어져 있으며, 앞이 탁 트이고 멀리 운악산, 용문산이 보이며 남쪽으로는 남한강 줄기가 보인다. 능선에는 철쭉, 단풍나무, 고목들이 우거져 있고 비좁고 험한 급경사길이 있다.", - "MNTN_HG_VL" : "936", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 양평읍, 옥천면, 용문면", - "MNTN_NM" : "백운봉" + "DETAIL_INFO_DTCONT" : "한라산은 우리나라 최남단에 위치해 있으면서 남한에서 가장 높은 산이다. 해발 1950m, 면적 151.35㎢ 로 1970년 3월 24일 국립공원으로 지정된 이 산은 3대 영산중의 하나로 다양한 식생분포를 이뤄 학술적 가치가 높은 동식물의 보고이기도 하다.", + "MNTN_HG_VL" : "1947", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시, 서귀포시", + "MNTN_NM" : "한라산" }, - "longitude" : 127.52611109999999, - "latitude" : 37.533611100000002 + "longitude" : 126.5291666, + "latitude" : 33.3616666 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "255", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "봉명산(697m)은 문경읍 마원리 우무실마을에 있는 문경읍의 앞산이어서 올라서면 문경읍이 한눈에 들어오고 주흘산, 조령산, 백화산, 성주봉이 문경읍을 빙둘러 서있는 모습을 볼 수 있는 곳이다.우리나라 산업발전의 원동력이 되었던과거 석탄과 흑연을 생산하던 봉명광업소가 있던 곳이며, 금학사라는 절도 있었으나 지금은 절터만 남았다. 과거에는 산 아래에 정기적으로 물이 솟는 조천이란 샘이 있었다고 전하나 지금은 찾을 길이 없다.정상에서 탁 트인 조망은 일품이다. 정상 부근에는 강대바위와 촛대바위가 있고, 산 앞으로는 조령천이 흐른다. 아래 등산로에 시루떡을 닮은 바위가 셋이 있는데 제일위의 시루떡 바위에 불상이 새겨져 있다.문경온천과 한눈에 조망되는 주흘산 모습이 좋아 등산객이 많이 찾고 있으며 매년 등산객이 늘어나고 있다.", + "MNTN_HG_VL" : "697", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", + "MNTN_NM" : "봉명산" }, - "longitude" : 126.5169444, - "latitude" : 37.493888900000002 + "longitude" : 128.1427698, + "latitude" : 36.720131100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "우리나라의 산이름 중에 백운산 이라는 이름을 가진 산이 많다.그 중에서\"흰구름산\"이라는 이름값을 제대로 하는 산이 함양의 백운이다.높이도 1000 m 가넘는 준봉인데다 산정에서의 조망도 으뜸이라 할수있다. 남도의 명산이라 일컫는 산들이 동서남북 어떤 방향에서도 거칠것없이 한눈에 들어온다.노고단에서 천왕봉까지 남쪽 스카이라인의 지리산 파노라마는 그리움의 경지를 넘어 성스러움을 느끼게 한다. 반야봉의 자태는 너무 뚜렷해 민망스럽기까지 하다.북쪽 끄트머리에는 넉넉한 덕유산이 태평스레 앉아있고 그너머에는 황석, 거망, 월봉 산이 어깨를 맞대고 있다. 금원산 기백산도 지척으로 보이고 동북 방향으로는 가야산, 황매산도 가물거린다.백운산은 명산에 둘러싸여 명산과 어깨를 나란히 하는 이 지방 최고의 진산이다. 겹겹이 둘러싼 능파들 사이사이로 흰구름이 부리는 조화는 백운산만이 연출해 낼 수 있는 활동사진. 산세 또한 전형적인 육산이기에 사계절 내내 산행이 가능한 것이 이 산의 매력이다.", - "MNTN_HG_VL" : "1279", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 백전면", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "산 모양이 '닭의 볏(계관)'처럼 생겼다 하여 비슬산이라고도 한다.산행은 사람의 흔적을 거의 찾아볼 수 없어, 독립된 산으로서의 산행보다는 인근의 석대산-구현산-화왕산을 연계하는 코스를 이용하는 것이 좋다. 산길은 후반부에 해당하는 구현고개에 닿을 때까지 등산객의 흔적을 거의 발견할 수 없었을 정도로 깨끗하고 묵은 산길이 큰 매력이었다. 석대산 정상까지 이어지는 암릉구간은 산행의 재미를 더해준다. 화왕산(756m)은 그리 높은 산은 아니지만 화려한 암릉으로 유명한 산이다.석대산 바위 구간은 규모 면에서는 이에 미치지 못하지만 아기자기함과 시원하게 트인 조망은 일품이다. 화왕산에서 구현산올 흐르는 남북 능선에과 비탈은 전체가 온통 바위로 까려 있고 능선에는 진달래가 많다.", + "MNTN_HG_VL" : "581", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창녕", + "MNTN_NM" : "구현산" }, - "longitude" : 127.63534850000001, - "latitude" : 35.616948800000003 + "longitude" : 128.53222220000001, + "latitude" : 35.513055600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백운산(시흥)은 바라산, 광교산과 능선으로 연결되는 이웃한 산으로 능선은 매우 한적한 편이다. 경기도 의왕시의 백운저수지의 뒷산인 해발 567m의 산으로 서울특별시에서 가까워 찾기 쉬운 산이다. 백운 저수지에서 산행할 경우 임도를 이용한 한적한 산행이 가능하다. 주능선 길은 산행하기에 좋으며 소나무가 많다.", - "MNTN_HG_VL" : "567", - "MNTN_LOCPLC_REGION_NM" : "경기도 시흥시, 용인시, 수원시", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "남한에서 한라산(1947.3m) 지리산(1915.4m) 설악산(1708.1m) 덕유산(1614.2m)에 이어 다섯 번째로 높은 계방산은 겨울철 적설등반 산행지로 유명한 산이다.강원도 홍천군 내면과 평창군 진부면에 걸쳐 있는 광대한 산맥을 거느리고 있으나, 북동쪽으로 연결되어 있는 오대산의 명성에 가려 빛을 보지 못했던 명산이다. 높은 산이면서도 유순한 산세와 능선을 가지고 있으며 가을이면 온 산을 단풍으로 물들이고 겨울철에서 무릎이상 빠질정도의 적설량으로 등산인들의 사랑을 듬뿍 받고 있는 산이다. 산기슭에 있는 방아다리 약수는 위장병, 피부병에 효험이 있는데 메밀꽃 필 무렵 마시면 특효가 있다고 한다.", + "MNTN_HG_VL" : "1579", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면, 평창군 용편면ㆍ진부면", + "MNTN_NM" : "계방산" }, - "longitude" : 127.0175, - "latitude" : 37.353055599999998 + "longitude" : 128.4448506, + "latitude" : 37.707517000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제천 백운산은 바로 옆 치악산의 그늘에 가려 등산인들에게 널리 알려지지 않았다. 그러나 그만큼 찾는 이가 드물어 등산로의 훼손이 적고 오염이 덜 되었으니 호젓하고 쾌적한 산행을 즐길 수 있다.서쪽에서부터 십자봉(984.8m), 조두봉(966.6m), 백운산(1,087.1m), 보름갈이봉(860m), 수리봉(909.9m), 벼락바위봉(937.6m)으로 이어지며 1000미터를 넘나드는 산줄기가 거대한 성곽처럼 도열해 제천시의 북쪽을 굳건히 지키고 선 모습은 가히 장관이다. 이 산들은 제천시계종주코스이기도 하다.백운산의 빼어난 점은 뭐니뭐니 해도 눈앞으로 펼쳐지는 일본잎갈나무(낙엽송) 조림지의 광대한 조망과 산길의 한적함이다. 북쪽인 원주 방면으로도 군데군데 보이지만, 남동쪽인 백운면 자락은 온 천지에 바늘을 꽂아둔 듯 빈틈없이 조림된 잘 자란 낙엽송 군락지가 시원하다. 백운산을 올라보면 당장 느낄 수 있지만 제천시민의 숲에 대한 보살핌과 정성, 자부심은 대단하다. 전국에서도 임도시설이 발달해 있기로 소문난 곳이기도 하다. 제천의 어느 산을 오르든지 잘 정비된 임도를 만나게 된다. 숲은 전체적으로 간벌이 잘 되어 있어 답답하지 않고 매우 건강하다.", - "MNTN_HG_VL" : "1087", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 백운면", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "복두봉은 운장산(1,126m)에서 동쪽인 구봉산(980m)쪽으로 뻗어나간 능선의 중간지점에 솟구쳐 오른 산이다. 복두봉은 아직 사람들의 손길과 발길이 닿지 않은 천혜의 자연경관을 자랑하고 있으며, 진안의 북서쪽에 마치 울타리를 친 듯이, 운장산, 복두봉, 구봉산의 능선은 금강과 만경강의 분수령을 이루고 있다.계곡 안에는 아직 알려지지 않은 200여평에 달하는 마당바위, 해기소, 정밀폭포 등이 등산객들을 유혹하고, 갈거계곡의 최상류인 민듬분지에는 6.25동란 전까지 화전민이 살았던 농장 터가 있어, 이곳은 가을이면 수만평의 억새군락이 너울너울 춤을 추고, 산허리에는 만산홍엽 단풍물결이 어우러져 한 폭의 그림 같은 풍광을 연출한다.복두봉 북쪽 아래는 여름 피서지로 유명한 운일암, 반일암의 협곡이 자리잡고 있으며, 도 주능선에서 운일암, 반일암 방향으로 아직도 비경으로 남아 있는 늑막골과 물탕골이 있어 어느 방향에서 오르내리거나 산자수명한 계곡산행을 즐길 수 있다.", + "MNTN_HG_VL" : "1017", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안 정천면, 주천면", + "MNTN_NM" : "복두봉" }, - "longitude" : 127.9627778, - "latitude" : 37.25 + "longitude" : 127.39638890000001, + "latitude" : 35.931111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백운산은 가지산(실혜산)의 앞가슴에 해당되는 산으로 산 전채가 한 조각의 흰구름처럼 보이는 화강암으로 이루어져 있어 얻어진 이름이다. 주위의 큰 산에 가려져 이름이 나지 못했으나 정상 부근에는 온통 기암괴석으로 이루어져 경관이 빼어나며, 등산로는 아주 호젓하다. 바위봉으로 우뚝 솟은 정상을 보면 마치 중국에 있는 황산을 보는 듯한 느낌이 든다. 더구나 봄에 이곳을 다녀가면 진달래와 철쭉이 만발하여 더욱 운치를 느낄 수 있다 하여 백운산은 봄산이라는 말도 있다.산의 동편 하단부에 유명한 시례 호박소 가 있고, 동편 산허리에 구룡폭포가 있으며 서편에는 우리 나라 굴지의 산내 중석광이 있다. 남쪽 건폭은 일년 내내 산악인들의 암벽등반 훈련장이 되고 있다.", - "MNTN_HG_VL" : "885", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "939", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", + "MNTN_NM" : "울련산" }, - "longitude" : 128.98400000000001, - "latitude" : 35.594999999999999 + "longitude" : 129.23611109999999, + "latitude" : 36.771388899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 울주군에 위치한 백운산은 열박산이라 부르기도 한다. 신라 김유신은 나이 17세 때 적군의 침공을 당하자 비장한 마음으로 혼자서 보검을 들고 열박산 깊은 골자기 속으로 들어가 향을 피우며 기를 모아 적을 물리칠수 있는 힘을 내려달라고 하늘에 빌었다는 이야기가 전해온다.산행 들머리는 언양에서 다개차리로 가는 버스를 타고 상차리에서 시작하면 된다. 백운산 정상은 대체로 칼등처럼 뾰족한 형상을 보이고 있다. 또한 바위군에 올라서서 바라보는 전망도 대단하다. 오른쪽은 옛날 기우제를 지냈던 아미산, 왼쪽에 문복산가지산, 남으로 고헌산, 북으로 삼강봉이 지척에 보인다.", - "MNTN_HG_VL" : "892", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", - "MNTN_NM" : "백운산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "149", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "봉황산" }, - "longitude" : 128.98400000000001, - "latitude" : 35.594999999999999 + "longitude" : 126.6080556, + "latitude" : 36.376666700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두산에서 시작되는 백두대간은 동해안 따라 뻗어 내리다 강원도 태백 피재에서 남서 향으로 방향을 틀어 한반도의 내륙을 따라 남해안으로 달려간다. 백운산은 백두대간에서 뻗어 나온 호남정맥이 남해바다로 잠들기전 마지막 힘을 다해 밀어 올린 산으로, 호남정맥의 최고봉이다.섬진강을 사이에 두고 지리산과 남북으로 마주보고 있는 백운산은 정상에서 서쪽으로 또아리봉(1127m),도솔봉(1153.2m)이, 동으로는 호남정맥으로 이어지는 매봉(866.9m)이, 남으로는 억불봉(1,007.5m)을 거느리고 있는 큰 산맥을 이루고 있다. 백운산 아래 옥룡면은 삼면이 산줄기로 둘러싸인 큰 골짜기로 남쪽만 열려 있는 자루 모양을 하고 있다. 이 골짜기를 불당골이라고 부를 만큼 불교 흔적이 많은 곳이다.지리도참설과 풍수사상의 원조라 할 수 있는 도선국사가 37세부터 35년 동안 옥룡사(지금은 남아 있지 않음)에서 주로 기거하다, 72세에 이 절에서 입적하였다. 백운산 산행기점인 동동 마을 왼쪽 옥룡사 터가 있는 백계산(505.8m)에 도선국사가 심었다는 동백 숲이 천연기념물로 지정되어 있다. 이 산에는 고로쇠나무가 많이 자라고 있는데, 예로부터 고로쇠나무에서 나온 수액이 만병통치약이라고 하여 경칩을 전후로 하여 많은 사람이 백운산을 찾아오고 있다.", - "MNTN_HG_VL" : "1222", - "MNTN_LOCPLC_REGION_NM" : "전라남도 광양시 봉강면ㆍ옥룡면ㆍ진상면ㆍ다압면, 구례군 간전면", - "MNTN_NM" : "백운산(광양)" + "DETAIL_INFO_DTCONT" : "경기도 이천시는 광주산맥의 줄기가 뻗어내려 북부에 여러 구릉을 기복시키고, 남부는 차령산맥에 연접하므로 북 서쪽은 산맥들로 이루어져 높고, 남동쪽은 점점 낮아진다. 북서쪽은 천덕봉(630m), 정개산(461m), 양각산(386m), 설봉산(394m), 건지산(411m), 마옥산(445.4m) 등이 솟아 있으며, 남동쪽에는 마이산(472m), 팔성산(378m), 백족산(402m) 등이 뻗어 있다. 중앙부에는 복하천이 남한강으로 흘러 들어가며 남동부에는 청미천이 음성군과 경계를 이룬다.마옥산은 마국산, 마고산, 마곡산 등으로 불리우기도 하며 여러 문헌을 통해 옛날에 오음산이라 부리웠음을 알 수 있다. 마옥산은 산이 중첩되고 험준하며 골이 깊기로 으뜸이다. 모가면 서쪽에 위치해 동남쪽은 설성면 서남쪽은 안성군 일죽면과 경계를 이루는데 굴바위, 병풍바위, 말바위, 구모바위등 유서 깊은 전설을 간직한 기암괴석들이 산재해 있고 군내 제일의 산간부락인 산내리. 대죽리등이 기슭에 위치해 있다. 또 복잡하게 얽힌 산줄기로 인해 사람이 되고 싶은 여우와 마옥산 99골짜기의 전설이 전해 내려오기도 한다.이산에는 안양사라는 대찰이 있었다고 하나 폐사된지 오래되어 지금은 그 정확한 위치조차 알 수 없고 마국산의 일맥인 소고리 서쪽 산골짜기에는 동쪽을 향한 넓은 바위 면에 뛰어난 솜씨로 선각된 마애여래좌상과 적극적이고 과장된 표현이 눈길을 끈 마애삼존불상이 있으며 조선시대 백자요지, 폐사지에 방치된 채 남아있는 부도 등의 유적이 있다.마국산의 심장부가 되는 산내리 서쪽산기슭에는 중종때 우의정을 지낸 영창부원군 권균의 묘소와 신도비가 있고 산내리 마을상단에 그의 사묘가 있다.서울에서 그리 멀지 않고, 인파도 붐비지 않는 호젓한 산행지로 각광을 받고 있는 곳이다. 수목이 울창하고 수려한 계곡과 기이한 암봉이 있는 산은 아니지만, 영창대군의 초라한 능묘와 사연이 있는 듯한 산속의 빈집이 특이한 점같아 보이며 때묻지 않고 깨끗한 산이라 좋다.", + "MNTN_HG_VL" : "446", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 일죽면 고은리", + "MNTN_NM" : "마옥산" }, - "longitude" : 127.621944, - "latitude" : 35.107222 + "longitude" : 127.450046, + "latitude" : 37.167619700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "동강을 끼고 있는 백운산. '태고의 신비'와 '천혜의 비경'까지 갖춘 동강은 강원도 산 속 깊숙이 숨어서 말없이 흘러가고 있다. 그래서 일까. 백운산 산행은 마치 신선이 된 듯한 기분을 선사해준다.백운산 산행을 위해서는 동강을 건너야 한다. 그리고 산행을 마쳤을 때도강을 건너와야 한다. 하지만 물을 건너지 않고 아예 칠족령에서 문희 마을로내려선뒤 보트를 타고 섭새까지 내려오는 방법도 있다. 산과 강을 동시에즐기는 코스다. 하지만, 백운산 산행은 점재 마을에서 시작하는 것이 일반적이다.", - "MNTN_HG_VL" : "884", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 신동읍, 평창군 미탄면", - "MNTN_NM" : "백운산(정선)" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "468", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "능천산" }, - "longitude" : 128.59615439999999, - "latitude" : 37.280543999999999 + "longitude" : 128.70815569999999, + "latitude" : 35.908877799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 포천군 이동면과 강원도 화천군 사내면의 경계를 이루는 백운산은 부드러운 산세와 해발 660m 인 광덕고개에서 산행이 시작되므로 가볍게 산행을 즐기려는 사람들이 많이 찾는다. 주말을 이용해 가족과 함께 등반을 하기에도 적격인 곳이다.광덕고개는 일명 '카라멜고개'라고 불리는데, 그렇게 불리는 데는 두 가지 설이 있다. 첫 번째 설은 도로가 비포장이었던 6.25때 이 지역을 관할하던 사단장이 광덕고개를 오를 때면 운전병의 졸음을 쫓기 위해 운전병에게 카라멜을 먹게 한 데에서 유래되었다는 것이다.두번째 설은 광덕고개의 꾸불꾸불한 모양이 낙타의 등을 연상케 한다고 해서, 카멜(Camel: 낙타)이 카라멜로 변하여 카라멜고개로 불리게 되었다는 것이다.백운산 정상 서쪽 아래로 4km에 이르는 백운계곡은 풍부한 수량과 빼어난 계곡미를 자랑한다. 계곡 곳곳에 넓적한 바위가 널려있어 아무데고 앉으면 쉼터가 될 정도로 등산인들이 쉬어가기 좋은 곳이다.", - "MNTN_HG_VL" : "904", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", - "MNTN_NM" : "백운산(포천)" + "DETAIL_INFO_DTCONT" : "산 이름에서부터 대단한 품위가 느껴지는 산, 문형산. 문형(文衡)이란 고려나 조선 때에 대제학(大提學)의 별칭으로, 학자들에게 가장 품격 높은 벼슬이다. 정2품에 해당하는 관직이기는 했으나 정승 부럽지 않은 벼슬이었고 한번 오르면 죽을 때까지 명예가 지켜지는 자리였다. ‘삼왕비불여일정승(三王妃不如一政丞)이며 삼정승불여일선생(三政丞不如一先生)’이라는 말 또한 대제학을 기리는 것이었으니 문형은 대단한 명예가 따르는 자리였다.정상은 너름 공터다. 운동시설이 있고 긴 의자가 두 개 놓여 있다. 북쪽으로만 조망이 좋다. 멀리 분당시가지와 영장(414.2m)이 뚜렷하다. 뒤로는 서울이 보인다.정상 표석 앞면에는 ‘文衡山 497m’ 뒷면에는 ‘1995년 광주문화원에서 주관하고 동원산악회에서 건립한 이 표석은 1998년에 훼손되어 오포면 이장협의회에서 복원하였음’이라 적혔다. 옆면에는 ‘1999년 1월 1일 오포면 이장협의회 증’이라는 글씨가 음각되었다.문형산의 본디 이름은 문수산이라는 설이 있다. 문수보살을 모신 산이라는 뜻인 듯하다. 또 다른 이름으로 신증동국여지승람에 ‘문현산’이 보인다. 오늘날 산 이름은 고려말 대제학을 지낸 이가 이곳에 들러 쉬면서 경치가 아름다워 ‘문형산’이라 하자 마을 이름까지 덩달아 ‘문형리’가 되었다는 것이다. 장상표석에 기록된 내용이다.", + "MNTN_HG_VL" : "499", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 오포읍", + "MNTN_NM" : "문형산" }, - "longitude" : 127.4440759, - "latitude" : 38.0746477 + "longitude" : 127.1875, + "latitude" : 37.369166700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백원산은 육산으로 상주 안산의 하나이며 이 산의 조산은 갑장산이다. 일명 국사봉이라고도 한다. 서쪽 기슭에는 도곡서당과 도림사가 있고 동쪽 기슭에는 천연 기념물 제69호인 구상화강암이 분포되어 있다.거북돌이라고도 부르는데, 조선 후기에 처음 발견되었다. 화강암이고, 모양이 거북이 등처럼 생겼다. 세계에서도 100여 곳밖에 발견되지 않았으며, 특히 이곳의 구상화강암은 구조가 뚜렷하고 모양이 아름답다. 일부는 현재 상주시청에서 보관하고 있다. 서쪽 기슭에는 도곡서당과 도림사가 있다. 전해 내려오는 이야기로는 산 아래에서 나옹(혜근)이 태어났다고 하지만 확실한 위치는 알 수 없다.", - "MNTN_HG_VL" : "524", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 인평동, 거동동", - "MNTN_NM" : "백원산" + "DETAIL_INFO_DTCONT" : "중왕산은 해발 1376미터로 정선읍 북서쪽으로 평창군과 경계를 이루며 우측 해발 1560미터의 가리왕산과 함께 고산의 면모를 충분히 보여주는 산이다. 주왕산이라고도 한다.태백산맥의 지붕 역할을 하는 높은 산으로 주변에는 백석산(1,365m)·청옥산(1,256m)·가리왕산(1,561m)·중봉(1,433m)·하봉(1,380m) 등의 높은 산을 비롯하여 정선 소금강, 화암약수, 정선 아우라지, 화암종유굴 등의 명승지와 가리왕산 자연휴양림이 있다. 가리왕산(1,561m)과는 능선으로 이어져 있어 같은 산으로 보기도 한다.능선이 끝없이 펼쳐진 초원지대로 육중하고 당당하며 자작나무와 주목이 군락을 이루고 있다. 5월 하순께에는 산기슭 곳곳에 취나물, 두릅 등 수십 종의 산나물이 돋아나 산행의 즐거움을 더해준다.", + "MNTN_HG_VL" : "1376", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 정선군", + "MNTN_NM" : "중왕산" }, - "longitude" : 128.1886111, - "latitude" : 36.347222199999997 + "longitude" : 128.52379479999999, + "latitude" : 37.463714899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백월산은 동서 2km, 남북 4km, 높이 약 394m의 도상구릉(島狀丘陵)을 형성하고 있다. 백월산의 정상부는 남북 20m, 동서 15m 규모의 평정봉(平頂峰)으로서 두꺼운 토양층으로 피복(被覆)되어, 암석 미지형은 전혀 나타나지 않고 있다. 그러나 정상 북측의 해발고도 300m~350m 높이 주변지역에는 화강암지역에서 찾아볼 수 있는 일반적인 암석 미지형들이 분포하고 있는데 이 미지형들은 주로 직경 2m 내외 원형의 집단적인 토르(tor)와 토르의 상층부에 형성된 30cm 내외의 폭의 그르부 및 4~5m 높이의 암주들로서 판상의 수직 및 수평절리들의 간격이 2m 규모로 발달하였기 때문에 나타난 현상이다. 암석 미지형이 집단적으로 분포하고 있는 곳의 해발고도 250m 지점의 산록에는 높이 10m, 폭 13m, 경사 60~65˚에 이르는 암석단애를 중심으로 암석의 급사면이 나타나고 있는데 이러한 현상은 수직에 가까운 사절리들이 발달하고 있기 때문이다. 한편 직경 3~5m 크기의 원형에 가까운 토르들이 3~5개 정도가 집단으로 기반암의 풍화충인 새프롤라이트와 토양층 위로 노출되어 토르를 덮고 있는 풍화층들이 장구한 세월동안 풍화와 침식으로 제거되었음을 나타내주고 있다.옛날에 홍성 지방의 용봉산과 백월산에 각각 장수가 살고 있었다. 이 장수들 사이에는 소향이라는아주 예쁜 처녀가 살았는데 장수들은 서로 이 소향이를 짝사랑하고 있었다. 장수들은 소향이를 차지하기 위해 서로 자기가 있는 산의 돌을 상대방 산에 던지기 시작하였다. 치열한 싸움이 계속되고 용봉산에 점점 돌이 쌓였다. 백월산 장수가 더 많은 돌을 던졌기 때문이다. 결국 백월산장수가 이겨서 소향이를 차지하게 되었고 홍성읍과 홍북면 사이에 있는 소향리는 백월산이 위치하는 홍성읍에 포함되게 되었다. 용봉산 장수는 싸움에서 지긴 했지만 백월산 장수가 던진 기암괴석들 덕분에 현재 전국에서 많은 관광객이 방문하고 있다.", - "MNTN_HG_VL" : "394", - "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군", - "MNTN_NM" : "백월산" + "DETAIL_INFO_DTCONT" : "강원도 강릉시 성산면과 평창군 도암면의 경계를 이루는 선자령은 백두대간의 주능선에 우뚝 솟아 있다. 산 이름을 '산'이나 '봉'이 아닌 선자령으로 부르게 된 유래는 알 수 없으나, 옛날 기록에 의하면 여러 가지 이름으로 표기하고 있다. 〈산경표(山經表)〉에는 '대관산(大關山)'이라 하고. 〈동국여지지도(東國輿地之圖)〉 와 〈사탑고적고(寺塔古蹟攷)〉에는 그 아래 보현사의 이름에 따라 '보현산(普賢山)'이라 표기되어 있다.그리고 보현사에 관한 기록을 전하는 〈태고사법(太古寺法)〉에는 '만월산(滿月山)'으로 적혀 있다. 보현사에서 보면 선자령이 떠오르는 달로 보이기 때문에 붙여진 이름인 것으로 추정된다. 선자령은 해발 840m인 대관령의 북쪽에 솟아 있는 산으로, 대관령에서 약 6km밖에 되지 않아 산행이 힘들지 않고 겨울철 적설 등반지로 적합하다. 대관령 고갯길은 옛날에는 오솔길이었으나, 이 고갯길을 조선조 중종때 이 지방 사람인 고형산이 사재를 털어 우마차가 다닐 수 있도록 넓혀 놓았다. 따라서 거의 평지길이나 다름없는 능선을 따라 오르게 되므로 산길은 매우 완만하다.이 능선길은 적설기와 신록기가 판이하게 달라진다. 적설기에는 많은 눈에 덮여 은세계를 이루어 황홀하고, 신록기에는 새로 자라난 연녹색의 초원에 야생화가 만발하여 화원을 이루고 있다.", + "MNTN_HG_VL" : "1157", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "선자령" }, - "longitude" : 126.6222222, - "latitude" : 36.607777800000001 + "longitude" : 128.745, + "latitude" : 37.722222199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "394", - "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군 홍성읍 월산리, 구항면 오봉리, 홍북면 중계리", - "MNTN_NM" : "백월산" + "DETAIL_INFO_DTCONT" : "예전 부터 봉화를 올릴수 있다고 봉수산이라 불리었다고한다.(다성 초이선사 탄생지로 유명하다) 산정상에 오르면 뒷편으로는 확트인 칠산바다와 앞으로는 싱싱달리는 새해안 고속도로의 시발점이 보인다. 앞으로는 시원하게 달리면 자동차와 뒤로는 뻥뚫린 바다가 보이는 전망이 아주 좋은 산이다.", + "MNTN_HG_VL" : "204", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 삼향면 왕산리", + "MNTN_NM" : "봉수산" }, - "longitude" : 126.6222222, - "latitude" : 36.607777800000001 + "longitude" : 126.4154277, + "latitude" : 34.856907499999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "369", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", - "MNTN_NM" : "백이산" + "DETAIL_INFO_DTCONT" : "주지봉은 월출산(813m)의 서쪽에 위치한 나즈막한 산이다. 도갑저수지의 서쪽에 있는 능선인데 죽순봉 아래 성기동 일대에 왕인박사 유허비를 비롯한 유적들이 산재해 있다.한반도의 서남단, 소백산맥의 끝부분에서 우뚝 솟은 월출산은 최고봉인 천황봉을 비롯하여 구정봉, 장군봉, 자봉, 향로봉, 주지봉, 노적봉 등의 영봉이 기암 괴석으로 신비롭게 이루어져 예로부터 호남의 소금강이라 일컬어져 왔고, 미왕재를 위시한 능선은 억새풀밭으로 장관을 이루며 산능의 북쪽면은 날카롭고 가파른 돌산인 반면 남쪽면은 완만한 육산으로 이루어져 있고 골짜기가 깊지 않아 곳곳에 저수지가 설치되어 있다.", + "MNTN_HG_VL" : "491", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군", + "MNTN_NM" : "주지봉" }, - "longitude" : 128.7102778, - "latitude" : 37.3011111 + "longitude" : 126.6496305, + "latitude" : 34.745091199999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "983", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함안군", - "MNTN_NM" : "백이산" + "MNTN_HG_VL" : "502", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 신기면 신기리", + "MNTN_NM" : "간대산" }, - "longitude" : 128.3497222, - "latitude" : 35.2347222 + "longitude" : 129.09671549999999, + "latitude" : 37.343407200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "486", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시", - "MNTN_NM" : "백자산" + "DETAIL_INFO_DTCONT" : "정상은 947m 이며, 산전체가 철원군에 속해있다. 계산상 걷는 거리는 약 2km 정도여서 짧은편이나 코스의 굴곡이 있는 편이므로 2 시간 이상은 잡아야 한다.구불구불하게 이어진 산행은 아기자기하고 재미있는 편이며,부엽토길이 많아서 푹신함을 느낄수 있다.넓은 철원평야의 서쪽에 위치하므로 능선에서 철원 시내를 훤히 내려다 볼 수 있으며 등산로 곳곳에 벙커나 참호,전선등 군사시설을 볼 수 있다.", + "MNTN_HG_VL" : "576", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 동송읍", + "MNTN_NM" : "금학산" }, - "longitude" : 128.74805559999999, - "latitude" : 35.786666699999998 + "longitude" : 127.201291, + "latitude" : 38.184018700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "석영과 석회석이 혼합된 흰색의 바위가 많이 쌓여 있어 백적산이라는 이름이 생겨났고, 흰적산이라고도 부른다. 바위들은 날씨가 궂으면 검게 보이고 날씨가 개이면 희게 보인다고 하며, 바위 틈에는 크고 작은 뱀들이 서식하고, 힘을 솟게 한다는 샘이 있다고 한다.강원도 평창군 대화면과 진부면의 경계에 있는 백적산은 사람들의 발길이 닿지않아 원시림이 울창한 산이다. 백두대간의 주맥인 오대산에서 지맥으로 갈래쳐 계방산 동쪽 2km지점에서 남하하여 영동고속도로를 건너 뛰어 백적산을 솟구치고 그 아래로 백석산(1365m), 가리왕산(1561m), 청옥산(1256m)을 일구어 놓았다.산 곳곳에 상여바위(수리바위),삼형제바위(통관바위)등 기암괴석이 있으며 백적산 정상은 사방천지의 산들이 모두 뚜렸하게 펼쳐지므로 그야말로 하늘에 오른 느낌이다. 사방의 산들이 맑은 하늘아래 모두다 선명하게 드러내니 백적산을 찾은 보람을 완전히 만끽하는 순간이다.", - "MNTN_HG_VL" : "1141", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", - "MNTN_NM" : "백적산" + "DETAIL_INFO_DTCONT" : "통영 최고봉이라는 수식어와는 달리 멀리서 본 벽방산(碧芳山)은 눈에 잘 띄지 않는 산이다. 남해안에서 흔히 마주치는 평범한 산세이기 때문이다. 그러나 겉에서 본 산과 막상 들어갔을 때 감흥이 틀린 것이 벽방산이다. 의상대사의 자취가 남은 고찰과 아늑한 골짜기, 시원한 전망의 암봉 등 어디하나 빠지지 않는 산이다.벽방산은 벽발산(碧鉢山)이라고도 부른다. 석가의 십대 제자 중 한 사람인 가섭존자(迦葉尊者)가 벽발(碧鉢 바리때)을 받쳐 들고 있는 모습과 닮아서 생긴 이름이다.정상은 상봉(上峰) 또는 칠성봉(七星峰)이라고도 부른다. 정상 부근에는 진달래가 많아 4월 중순이면 절정을 이룬다. 정상 조망은 다도해를 비롯해 부산 앞바다가 보이며, 맑은 날에는 대마도까지도 볼 수 있다. 안정치로 내려오면 대나무 밭에 이른다. 이곳이 만리암터이며, 이 위에 솟아 있는 절벽이 만리창벽이다.벽방산에서 빼놓을 수 없는 것이 안정사다. 신라 태종무열왕 원년(서기 654)에 원효대사가 창건하여 현재까지 1400여년 동안 이어오고 있는 고찰로 대웅전은 도문화재로 지정되어 있다. 안정사 부근은 조선 영조 때 사찰 주변의 적송을 보호하라는 어송패가 내려질 만큼 소나무들이 운치 있다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "경남 통영시 광도면, 고성군 거류면ㆍ고성읍", + "MNTN_NM" : "벽방산" }, - "longitude" : 128.4913889, - "latitude" : 37.591111099999999 + "longitude" : 128.3690746, + "latitude" : 34.959345499999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "412", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시", - "MNTN_NM" : "백족산" + "MNTN_HG_VL" : "574", + "MNTN_LOCPLC_REGION_NM" : "충청남도 계룡시 향한리, 논산시 상월면", + "MNTN_NM" : "향적산" }, - "longitude" : 127.60416669999999, - "latitude" : 37.097222199999997 + "longitude" : 127.20184399999999, + "latitude" : 36.292887800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "영동군 학산면과 무주읍에 걸쳐 있는 백하산은 하얀 노을, 하얀 이내라는 뜻으로 노을이 아름다운 산이다. 백하산 줄기는 영동에서 학산을 거쳐 무주로 이어지는 19번 국도와 나란히 뻗쳐있어 차를 타고 가며 계속 그 모습을 올려다 볼 수 있다.백하산은 북쪽에서 보면 그저 거하고 짙푸른 산이지만 산에 들어서면 곳곳에 까마득한 바위 낭떠러지가 많다.동쪽 끝 여의재 남쪽에는 여의 저수지가 있으며 서쪽 끝 압재 북쪽에는 봉황저수지가 있다. 19번 국도가 백하산 아래를 지나 돌아가기 때문에 백하산 산행을 위한 교통은 편리한 편이다.백하산 아래의 안삼마을은 큰 길가 삼정마을의 일부로 산골짜기 안에 있는 삼정이라 해서 안삼이라 한다. 마을 들머리에는 명절 때 풍년과 마을의 무고를 기원하는 도랑제를 모시는 반신 석상이 있다.", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동 학산면,전라북도 무주", - "MNTN_NM" : "백하산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "203", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 동구", + "MNTN_NM" : "염포산" }, - "longitude" : 127.6891667, - "latitude" : 36.062777799999999 + "longitude" : 129.40899999999999, + "latitude" : 35.521000000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "해제면 서쪽에 위치한 해발 126M되는 산으로 서해바다와 영광 낙월도,각이도 등이 보이는 곳이며 산 바로 아래가 서해안 바다여서 넓은바다가 한눈에 보인다. 과거 이 산은 동백나무가 많은 산으로 동백꽃이 필 때면 산 전체가 동백으로 만발하였다고 한다. 고려말에 고씨 성을 가진 스님이 발견했다는 동굴 2개가 마을에 있는데 동굴 하나는 물속에 용왕님에게 가는 굴이고, 다른 사나는 용왕의 아드링 육지와 바다를 드나들던 굴이었다 한다. 어느 해에 심한 가뭄이 들어 물속에 있는 용왕에게 불공을 드려 비가 오게 해달라고 빌자 갑자기 소나니가 쏟아져 가뭄을 해갈시켰다. 이때 소나기를 내린 물속의 대사는 용왕님 몰래 비를 내리게 했다하여 용왕의 노여움을 사서 학이 되어 흰구름을 타고 어디론가 사라졌다고 한다. 이 후 마을의 산에 흰 학이 많이 서식하여 산이름을 백학산이라 부른다 한다.", - "MNTN_HG_VL" : "126", - "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 해제면 대사리", - "MNTN_NM" : "백학산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "255", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시", + "MNTN_NM" : "삼봉산" }, - "longitude" : 126.26312969999999, - "latitude" : 35.1397324 + "longitude" : 128.4447222, + "latitude" : 34.878611100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "포성봉(933m)은 충북 영동과 경북 상주의 경계에 위치하고 있는 산으로 바위가 많고 한폭의 그림과도 같은 빼어난 자연경관을 자랑하고 있는 산이다. 지도상에는 포성봉으로 되어있으나 인근지역주민들은 이 산을 백화산으로 부르고 있다.봄이면 철쭉이 능선마다 꽃띠를 두르고 있어 꽃산행도 겸할 수 있고, 여름에는 수풀과 옥류가, 가을에는 단풍이 정상에서 능선을 타고 석천골 반야사를 온통 붉게 물들인다. 정상에서는 쉴 만한 공터와 무덤이 한쪽에 있고 남쪽으로 석천을 내려다 보면 은빛 물결을 이루고 있으며 남서쪽으로는 주행봉이,주행봉 동편에는 분묘가 어림된다. 북으로는 속리산과 구병산이 남으로는 석천너머로 황악산과 덕유산이 그리고 서쪽으로는 서대산이 펼쳐진다.", - "MNTN_HG_VL" : "1063", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면, 경상북도 상주군 모동면", - "MNTN_NM" : "백화산" + "DETAIL_INFO_DTCONT" : "관악산은 서울시 관악구와 금천구, 경기도 과천시와 안양시에 걸쳐 있어 북한산,도봉산과 더불어 누구나 쉽게 찾는 친근한 산이다. 멀리서 보면 온통 바위로 뒤덮여 있는 산세를 가진 관악산은 해발은 낮으나 등산로 곳곳에 위험한 암릉이 있어 조심해야 한다.관악산은 예로부터 불의 산(火山)이라 하여 조선 태조가 궁터를 지금의 경복궁 자리로 옮길 때, 무학대사가 이곳은 관악산과 마주 보이는 자리로 관악산의 화기가 궁을 눌러서 내우외환이 끊이지 않을 것이라며 반대했지만, 정도전의 남쪽에 한강이 가로질러 있어서 영향이 없을 것이라는 주장을 받아 들여 지금의 경복궁을 창건하였다 한다. 그후 태종때 왕자의 난, 세조의 왕위 찬탈, 임진왜란, 병자호란, 그리고 경복궁에 발생한 수차례의 화재가 발생한 것을 풍수지리설로 해석하는 이도 있다. 대원군은 경복궁을 재건할 때 관악산의 화기를 누르기 위해 경복궁 정문인 광화문 앞에 바다의 신으로 상상의 동물인 해태 조각상을 만들어 세웠다.관악산 연주대는 고려가 망하자 남은 유신 열 사람이 관악산 절에 숨어살며 경복궁을 바라보며 통곡을 했다 하여, 임금을 사모한다는 뜻으로 연주대(戀主臺)라 불려 지게 되었다 한다. 이성계가 연주암을 중창한 뒤, 태종의 두 아들인 양녕대군과 효령대군은 태종이 왕위를 셋째 충녕대군(세종)에게 물려줄 뜻을 알고 관악산에 입산하였다 한다. 예전에 관악산을 삼성산이라 부른 것은 신라의 고승 원효,의상,윤필이 이 산에서 세 승려가 일막,이막,삼막의 세 암자를 짓고 따로 수도하여 득도하였다 하여 붙여진 것으로 전해지고 있다. 임진왜란때 일막,이막은 소실되고 삼막사(三幕寺)만 남았다는 것이다.", + "MNTN_HG_VL" : "632", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구ㆍ금천구, 경기도 안양시ㆍ과천시", + "MNTN_NM" : "관악산" }, - "longitude" : 127.90472219999999, - "latitude" : 36.302222200000003 + "longitude" : 126.9610024, + "latitude" : 37.442938499999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태안읍 사무소 뒤에 우뚝 솟아있는 백화산은 전설에 많은 명산으로서 주민들의 사랑을 받고 있는 아름다운 산이다. 팔봉산(362m)에서 서쪽으로 가지를 내려 태안 읍내를 품에 안은 백화산은 284미터의 작고 아담한 산이다. 그러나 서해안 인근의 산들이 대부분 단순한 육산인 반면 백화산은 온갖 수석을 모아놓은 듯 기기묘묘한 바위가 서해 바다를 배경으로 펼쳐져 아름다운 풍광을 선사한다. 산에는 기암괴석들이 많고, 바위들과 소나무가 어우러져 있고, 특히 산 정상에서 바라보는 일몰은 최고의 경관이다.백화산에는 서해 낙조를 즐기기 안성맞춤인 전망대가 있다. 시야가 트여 서해 경치가 한눈에 들어와 산행의 피로를 말끔히 가시게 해주는 이곳은 이름도 낙조봉. 정상 남쪽에 자리한 낙조봉은 변산 낙조대의 일몰에 뒤지지 않을 아름다운 조망을 제공한다.태안읍 백화산 태을암 동편 30m지점의 거암에 부조된 삼존불상(1좌3신)으로 좌우여래 입상과 중앙에 보살입상을 배치 조각했는데 크기는 중앙보살입신상이 223cm이며, 좌우여래상은 306cm, 296cm 좌우를 크게 배치한 점이 특이하다. 굳게 다문 입술가는 오히려 미소를 머금고 두 어깨에 걸친 옷자락은 양팔에 걸쳐 평행곡선으로 길게 주름진 첨단이 삼각형으로 변형된 것은 고대에 즐겨 사용된 중국 육조시대양식과 흡사하다.이같은 조각 양식으로 보아 6세기초(백제시대)작품으로 추정되는 우리나라 마애삼존불의시초이며 백제 마애석불 미술의 발상지임을 말해주는 작품이다.", - "MNTN_HG_VL" : "284", - "MNTN_LOCPLC_REGION_NM" : "충청남도 태안군 태안읍", - "MNTN_NM" : "백화산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "245", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "호룡곡산" }, - "longitude" : 126.30255699999999, - "latitude" : 36.767481500000002 + "longitude" : 126.4214736, + "latitude" : 37.378381300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "상주 백화산은 내륙 깊은 곳에 자리한 산답게 사계절 아무 때나 찾아도 산의 멋과 향과 느낌과 기운 그리고 깊은 적막감을 맘껏 누릴 수 있는 산 중 의 산이다. 맑은 물이 풍부하고, 산자락을 남동으로 휘감고 굽이치며 흐르는 석천(石川) 또한 아름답다.백화산이란 이름은 산 전체가 티없이 맑고 밝다는 뜻으로 봄이면 철쭉이 능선마다 꽃띠를 두르고 있어 꽃산행도 겸할 수 있다. 여름에는 수풀과 옥류가, 가을에는 단풍이 정상에서 능선을 타고 석천골 반야사를 온통 붉게 물들인다. 지도상에는 포성봉(捕城峰)으로 표기되어 있는데 한성봉(漢城峰)이 제 이름이다.산행들머리에 해당하는 두 곳에 보현사와 반야사라는 아담한 절집이 자리하고, 보현사 건너편 수봉리에는 조선 사학의 자존심 옥동서원(경북 기념물 제52호)과 더없이 아름다운 곳에 학처럼 자리한 정자 백옥정이 있어 볼거리 또한 풍성하다. 또 대궐터, 보문사터, 금돌산성 등 옛 호국의 유적들을 만나볼 수 있다.", - "MNTN_HG_VL" : "933", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 모서면, 모동면ㆍ충청북도 영동군 황간면", - "MNTN_NM" : "백화산(한성봉)" + "DETAIL_INFO_DTCONT" : "서해바다와 인접해 있는 변산은 호남평야를 사이에 두고 호남정맥줄기에서 떨어져 독립된 산군을 형성하고 있다. 이 산은 예로부터 능가산, 영주산, 봉래산이라 불리며 호남의 5대 명산중의 하나로 꼽혀왔다.1971년 도립공원으로 지정된 변산에는 기상봉, 망포대, 신선대, 쌍성봉, 옥녀봉, 세봉 등 400m 이상의 산이 6개 있고 계곡에는 와룡소, 가마소, 직소폭포, 성계폭포 등 장엄한 절경을 자랑하는 명소들이 산재해 있다. 이 밖에도 서해안 해식단애(海蝕斷崖)의 절경을 이루는 채석장을 비롯하여 우금바위와 산성, 굴바위, 빙봉 낙조대, 내소사, 월명암, 개암사 등 천태만상의 명소들이 진을 치고 있어 볼거리가 많은 곳이다.", + "MNTN_HG_VL" : "508", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면, 상서면, 진서면", + "MNTN_NM" : "변산" }, - "longitude" : 127.90472219999999, - "latitude" : 36.302222200000003 + "longitude" : 126.531389, + "latitude" : 35.680833 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 구미시에 위치한 베틀산은 역암, 사암의 풍화 혹은 해식 작용으로 기이한 형태의 암석모양(큰상어굴, 작은 상어굴, 베틀굴)과 색상을 나타내고 있으며 해변가에서 느끼는 침식 현상을 여러 곳에서 볼 수 있다. 산은 그리 높지 않으나, 산세가 아기자기하고 암릉과 해식굴(海蝕窟) 등이 산재하여 산행이 재미있다.베틀산은 예전에 조계산이라고 불리었다. 문익점의 동생인 문영이 산의 모양과 해평면 오상리에 있는 공상다리의 모양을 따서 베틀을 만들어 문영베를 짜는 데 성공한 이후, 산이름이 조계산에서 베틀산으로 바뀌었다고 전해진다. 그밖에 어느 선비가 과거를 보러 한양으로 가는데 산 위에서 여인의 베짜는 소리가 들려왔다거나, 임진왜란 때 많은 사람들이 베틀굴에 피난하여 베를 짰다는 전설 등이 전해진다.", - "MNTN_HG_VL" : "369", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 금산리", - "MNTN_NM" : "베틀산" + "DETAIL_INFO_DTCONT" : "쫓비산은 광양 다압면 매화마을을 둘러싸고 있는 산이다. 이름이 특이한 쫓비산은 인근 주민들에게 그 뜻을 물어도 명확한 답을 아는 이가 없다. 다만 형태가 뾰족해 사투리 ‘쪼삣’에서 유래했다는 설도 있고 섬진강의 푸른 물줄기에 빗대어 맑은 하늘이란 뜻의 ‘쪽빛’에서 유래된 이름이라는 설도 있다.쫓비산은 광양 매화마을을 둘러싸고 있는 산으로, 호남정맥 백운산에서 갈래 쳐진 산이며 섬진강을 끼고 앉은 산이다. 섬진강 550리 유장한 먼 굽이를 돌아나와 전라도와 경상도의 경계를 지으며 남해로 흘러드는 곳, 호남정맥이 끝나는 백운산 동편 산줄기에 솟은 것이 갈미봉 쫓비산 자락이다.쫓비산 하면 단연 매화꽃이 유명하다. 산 입구의 청매실농원은 매화꽃 만발해 축제가 열리는 봄이면 관광객들과 등산객으로 메워진다. 매화꽃이 유명하지만 능선으로 들면 진달래와 철쭉이 지천이다. 꽃의 개화 시기는 차이가 있어 산기슭의 매화꽃이 지면 바통을 이어받아 산등성이의 진달래와 철쭉이 핀다.", + "MNTN_HG_VL" : "537", + "MNTN_LOCPLC_REGION_NM" : "전남 광양시 진상면", + "MNTN_NM" : "쫓비산" }, - "longitude" : 128.4422836, - "latitude" : 36.206698400000001 + "longitude" : 127.6977778, + "latitude" : 35.07 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "통영 최고봉이라는 수식어와는 달리 멀리서 본 벽방산(碧芳山)은 눈에 잘 띄지 않는 산이다. 남해안에서 흔히 마주치는 평범한 산세이기 때문이다. 그러나 겉에서 본 산과 막상 들어갔을 때 감흥이 틀린 것이 벽방산이다. 의상대사의 자취가 남은 고찰과 아늑한 골짜기, 시원한 전망의 암봉 등 어디하나 빠지지 않는 산이다.벽방산은 벽발산(碧鉢山)이라고도 부른다. 석가의 십대 제자 중 한 사람인 가섭존자(迦葉尊者)가 벽발(碧鉢 바리때)을 받쳐 들고 있는 모습과 닮아서 생긴 이름이다.정상은 상봉(上峰) 또는 칠성봉(七星峰)이라고도 부른다. 정상 부근에는 진달래가 많아 4월 중순이면 절정을 이룬다. 정상 조망은 다도해를 비롯해 부산 앞바다가 보이며, 맑은 날에는 대마도까지도 볼 수 있다. 안정치로 내려오면 대나무 밭에 이른다. 이곳이 만리암터이며, 이 위에 솟아 있는 절벽이 만리창벽이다.벽방산에서 빼놓을 수 없는 것이 안정사다. 신라 태종무열왕 원년(서기 654)에 원효대사가 창건하여 현재까지 1400여년 동안 이어오고 있는 고찰로 대웅전은 도문화재로 지정되어 있다. 안정사 부근은 조선 영조 때 사찰 주변의 적송을 보호하라는 어송패가 내려질 만큼 소나무들이 운치 있다.", - "MNTN_HG_VL" : "652", - "MNTN_LOCPLC_REGION_NM" : "경남 통영시 광도면, 고성군 거류면ㆍ고성읍", - "MNTN_NM" : "벽방산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "490", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", + "MNTN_NM" : "호랑산" }, - "longitude" : 128.3690746, - "latitude" : 34.959345499999998 + "longitude" : 127.7008915, + "latitude" : 34.791603500000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "벽암산은 정선군 남면 별어곡과 신동읍 예미를 잇는 마차치고개가 산행 기점이다. 마차치고개 마루턱에서 서쪽으로 500미터쯤 내려간 곳에 마차치고개 식당이 있다. 북쪽 콘크리트길로 들어서 두 번째 삼거리인 광덕재에서 동쪽 능선으로 25분쯤 오르면 밭과 묘가 있는 안부에 이른다. 이 안부에서 15분쯤 올라서 840봉에 닿으면 능선이 둘로 갈라진다. 여기서 벽암산으로 가는 동쪽 능선은 보이질 않는다.벽암산으로 오르려면 눈에 잘 띄는 북릉으로 가지 말고 동쪽의 급경사를 내려서야 한다. 이내 능선이 나타나며 안부에 닿는다.정상에 오르니 작은 헬기장에는 삼각점과 작은 비닐코팅판이 걸려있고 나무들에 둘러싸여 조망은 막혀있다.하산은 정상에서 동남 쪽 능선을 따라간다. 능선 오른편으로 계곡이 세 개 갈라진다. 첫 번째 계곡이 통노구골, 두 번째가 금골, 세 번째가 절골이다. 세 번째 계곡인 절골로 내려서면 수광암에 닿는다.", - "MNTN_HG_VL" : "923", - "MNTN_LOCPLC_REGION_NM" : "강원 정선 남면", - "MNTN_NM" : "벽암산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "662", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 광하리", + "MNTN_NM" : "나팔봉" }, - "longitude" : 128.68777779999999, - "latitude" : 37.277777800000003 + "longitude" : 128.60795680000001, + "latitude" : 37.346452900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "522", - "MNTN_LOCPLC_REGION_NM" : "경상북도 의령군", - "MNTN_NM" : "벽화산" + "DETAIL_INFO_DTCONT" : "불태산은 담양 대전면 대치리에서 장성 백양사로 넘어가는 한재(대치)를 경계로 왼쪽에 솟아있는 해발 720미터의 봉우리다. 그동안 오른쪽의 병풍산의 그늘에 가려져 많이 알려지지 않았으나 최근 남쪽 산자락에 위치한 군사 훈련소 때문에 민간인 출입이 통제되어오던 것이 최근 완화되면서 남도 등산인들로부터 당일 산행지로 사랑받고 있다.불태산은 장성 진원면과 담양 대전면에서 바라보면 마치 거대한 부처를 연상케 한다. 이를 증명하듯 장성군에서 발간한lt;문화유적gt;에 따르면 불태산을 ‘불대산(佛大山)’으로 표기하고 있고, 또 산자락에 80개의 사찰이 있었다는 이야기가 전해지고 있다.국토지리정보원 지형도에는 636미터 봉우리를 ‘불태산(佛台山)’으로 표기하고 있으나 지역주민과 과거의 자료를 살펴보면 ‘불태봉 720m’라 적힌 정상석이 세워진 봉우리가 불태산 정상이라 하겠다. 해발 685.2미터의 ‘병장산’도 지형도에는 ‘병봉산(屛鳳山)’이라 표기되어 있다. 산세는 동쪽 사면은 가파른 절벽이고 서쪽 사면은 완만하다. 대치~천봉 구간은 육산이지만 주능선 곳곳을 이루는 암릉구간은 암릉산행의 재미를 선사한다.", + "MNTN_HG_VL" : "720", + "MNTN_LOCPLC_REGION_NM" : "전남 장성군 장성읍·진원면, 담양군 대전면", + "MNTN_NM" : "불태산" }, - "longitude" : 128.2276621, - "latitude" : 35.300024800000003 + "longitude" : 126.8666667, + "latitude" : 35.299999999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서해바다와 인접해 있는 변산은 호남평야를 사이에 두고 호남정맥줄기에서 떨어져 독립된 산군을 형성하고 있다. 이 산은 예로부터 능가산, 영주산, 봉래산이라 불리며 호남의 5대 명산중의 하나로 꼽혀왔다.1971년 도립공원으로 지정된 변산에는 기상봉, 망포대, 신선대, 쌍성봉, 옥녀봉, 세봉 등 400m 이상의 산이 6개 있고 계곡에는 와룡소, 가마소, 직소폭포, 성계폭포 등 장엄한 절경을 자랑하는 명소들이 산재해 있다. 이 밖에도 서해안 해식단애(海蝕斷崖)의 절경을 이루는 채석장을 비롯하여 우금바위와 산성, 굴바위, 빙봉 낙조대, 내소사, 월명암, 개암사 등 천태만상의 명소들이 진을 치고 있어 볼거리가 많은 곳이다.", - "MNTN_HG_VL" : "508", - "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면, 상서면, 진서면", - "MNTN_NM" : "변산" + "DETAIL_INFO_DTCONT" : "화란봉은 이름 그대로 꽃모양을 하고 있는 산으로 부채살처럼 펼쳐진 화관이 화란봉을 중심으로 겹겹이 에워싼 형상이다.산행기점인 벌마을에는 용수골이 있는데 이곳은 옛날에 이무기가 하늘로 오르다 힘이 부쳐 떨어진 곳이라 한다. 지금도 그때 자국이 용수골 너럭바위에 남아있다.화란봉에선 닭목재가 한눈에 들어온다.화란봉 주위에는 기암괴석과 몇 아름 되는 노송들이 바위 틈새에서 우람하게 자라는 모습을 보면 마치 한 폭의 동양화를 연상하게 된다.", + "MNTN_HG_VL" : "1069", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면", + "MNTN_NM" : "화란봉" }, - "longitude" : 126.531389, - "latitude" : 35.680833 + "longitude" : 128.78916670000001, + "latitude" : 37.626388899999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "병무산(兵無山 920m)은 지난봄 찾았던 발교산(髮校山 998m)과 맥락을 같이 하는 산이다.즉 차령산맥중의 지맥에 속하는 산으로서 망고개를 경계로하여 발교산과 어깨를 나란히 하면서 남쪽으로 우뚝 솟아있는 것이다. 강원도 소재의 오지의 산답게 등산코스를 개발한지 얼마되지 않아 등산객들의 왕래가 적은 이 산은 한적한 산행지로 적합하다. 이름난 산속에서 볼 수 있는 고찰도, 잘 다듬어진 등산로도 찾아보기 힘들지만 수풀과 바위 사이를 헤짚고 가는 산행의 묘미가 일품이다.", - "MNTN_HG_VL" : "920", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면, 청일면", - "MNTN_NM" : "병무산" + "DETAIL_INFO_DTCONT" : "경기도 포천군 이동면과 강원도 화천군 사내면의 경계를 이루는 백운산은 부드러운 산세와 해발 660m 인 광덕고개에서 산행이 시작되므로 가볍게 산행을 즐기려는 사람들이 많이 찾는다. 주말을 이용해 가족과 함께 등반을 하기에도 적격인 곳이다.광덕고개는 일명 '카라멜고개'라고 불리는데, 그렇게 불리는 데는 두 가지 설이 있다. 첫 번째 설은 도로가 비포장이었던 6.25때 이 지역을 관할하던 사단장이 광덕고개를 오를 때면 운전병의 졸음을 쫓기 위해 운전병에게 카라멜을 먹게 한 데에서 유래되었다는 것이다.두번째 설은 광덕고개의 꾸불꾸불한 모양이 낙타의 등을 연상케 한다고 해서, 카멜(Camel: 낙타)이 카라멜로 변하여 카라멜고개로 불리게 되었다는 것이다.백운산 정상 서쪽 아래로 4km에 이르는 백운계곡은 풍부한 수량과 빼어난 계곡미를 자랑한다. 계곡 곳곳에 넓적한 바위가 널려있어 아무데고 앉으면 쉼터가 될 정도로 등산인들이 쉬어가기 좋은 곳이다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 화천군 사내면", + "MNTN_NM" : "백운산(포천)" }, - "longitude" : 128.0997222, - "latitude" : 37.641111100000003 + "longitude" : 127.4440759, + "latitude" : 38.0746477 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "819", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 북실리", - "MNTN_NM" : "병방산" + "DETAIL_INFO_DTCONT" : "용봉산은 381미터에 불과한 낮은 산이지만 산 전체가 기묘한 바위와 봉우리로 이루어져 충남의 금강산이라 불릴 정도로 아름답다. 보는 위치에 따라서 각각 다른 수묵화를 보는 듯 달라지는 풍경을 즐길 수 있다. 또한 정상에서의 예당평야와 수덕사를 품은 예산 덕숭산, 서산 가야산 조망이 시원스럽다.용봉산이라는 이름은 용의 몸에 봉황의 머리를 얹은 형상이라는 데서 유래했다. 남쪽 중턱과 서쪽 산록에 완만한 경사가 길게 이어지고 군데군데 소나무 군락이 있다. 장군바위와 백제 고찰인 용봉사, 보물 355호인 마애석불 등 많은 문화재가 곳곳에 남아 있다. 옛 문헌에 영봉사라고 기록되어 있는 용봉사는 지금 대웅전과 요사체 2동만이 남아 있다. 하지만 고려시대에는 절 크기가 아흔아홉채에 달하고 불도를 닦는 승려수가 천여명에 이를 만큼 큰 절이었다고 한다. 또 용봉사에는 강마촉지인을 한 석가모니를 그린 탱화가 있다.용봉산을 낀 홍성 일대는 충절의 고향답게 만해 한용운 선사, 백야 김좌진 장군, 최영 장군, 사육신 성삼문 등의 생가와 9백의총, 위인들의 삶의 흔적과 백제 부흥의 마지막 보루였던 임존성 등 역사 유적지가 도처에 남아 있다. 더욱이 최근 개발된 홍성온천이 예산의 덕산온천과 더불어 온천 관광지로도 이름이 높다.", + "MNTN_HG_VL" : "381", + "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군 홍북면ㆍ예산군 덕산면", + "MNTN_NM" : "용봉산" }, - "longitude" : 128.6333333, - "latitude" : 37.348888899999999 + "longitude" : 126.649249, + "latitude" : 36.6435581 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "병풍산하면 병풍을 펼쳐 놓은 것처럼 산세가 빼어난 산이 아닌지 한번쯤 생각을 하게 된다. 병성산이라고도 불리운다. 그러나 이 산이 병풍산으로 이름 붙여진 것은 산 정상에 올라서면 시야가 탁트여 마치 병풍을 펼쳐 놓은 것처럼 주변을 감상할 수 있어서 그런 듯 하다.정상부에는 삼한시대 사벌국(沙伐國)이나 그 후계 세력인 상주 지역의 실체 파악에 주요한 단서가 되는 토석 혼축의 병풍산성(또는 아자개성)이 축조되어 있고, 산 곳곳에는 삼한시대 사벌국의 고분군(古墳群:경북기념물 125)이 널려 있다. 또한 넓은 들판과 상주 시내, 낙동강과 함께 국수봉·속리산·대야산·백화산·주흘산 등이 병풍처럼 펼쳐져 있다.", - "MNTN_HG_VL" : "366", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 동문동", - "MNTN_NM" : "병풍산" + "DETAIL_INFO_DTCONT" : "용문산 북쪽의 992m봉에서 북으로 분기하여 늪산(봉미산)을 빚고 홍천강으로 빠져들기 직전에 장락산을 만들었다.능선 주변에는 기암이 도처에 산재하고 노송이 어우러져 아름다운데다 굽이굽이 흐르는 홍천강을 시종 바라보면서 걸을 수 있는 능선길이 더욱 운치 있다. 능선의 좋은 경치는 전망이 뛰어난 615봉에서부터 시작되는데 깃대봉과 화채봉에서 절정을 이룬다.계곡은 장락골이 제일 좋고, 마곡리 일대 강변의 넓은 모래밭은 모곡 유원지로서 유명하고 형제봉에는 유명한 약수터가 있고, 깃대봉과 화채봉 사이 서편 농바위골 주변에는 강씨굴과 약수터가 또 있다.", + "MNTN_HG_VL" : "627", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 강원도 홍천군 서면", + "MNTN_NM" : "장락산" }, - "longitude" : 128.22188180000001, - "latitude" : 36.423279399999998 + "longitude" : 127.5486609, + "latitude" : 37.670588000000002 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "796", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", - "MNTN_NM" : "병풍산" + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 홍천읍, 횡성군 공근면", + "MNTN_NM" : "오음산" }, - "longitude" : 127.81778920000001, - "latitude" : 38.079237399999997 + "longitude" : 127.92222219999999, + "latitude" : 37.605555600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "담양의 명산인 병풍산은 담양군의 산 가운데 가장 높은 산으로 일명 용구산이라고도 한다. 담양군 수북면 소재지에서 이 산을 바라보면 왜 병풍산이라 했는지 쉽게 짐작할 수 있다. 오른쪽 투구봉을 시작으로 우뚝 솟은 옥녀봉, 중봉, 천자봉을 거쳐 정상인 깃대봉과 신선대까지 고르게 뻗은 산줄기는 한눈에 보아도 틀림없는 병풍이다.정상에서의 조망은 장관을 이루어 ‘강동8경’이라 한다. 북으로 내장산, 백암산, 입암산이 보이고 추월산, 담양읍내는 물론 지리산도 시야에 들어온다. 북동에서 남서쪽으로 길게 뻗은 병풍산은 등줄기 양옆으로 무수히 많은 작은 능선이 있는데 이 능선 사이에 일궈진 골짜기가 99개에 달한다.특히 한재골은 기암괴석과 푸른 송림 등 갖가지 수목이 울창하게 우거져 천혜의 경관을 자랑하고, 가을 단풍과 겨울 설경은 기이한 아름다움을 지니고 있다. 광주와 가까운 이곳은 매년 관광객이 증가하고 있어 야영지, 체육시설, 풀장, 조경시설 등을 갖추어 가고 있다.", - "MNTN_HG_VL" : "826", - "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 수북면, 월산면ㆍ장성군 북하면", - "MNTN_NM" : "병풍산(용구산)" + "DETAIL_INFO_DTCONT" : "충북 단양군 단성면 회산리와 장회리의 경계를 이루고 있는 사봉은 금수산, 소백산, 도락산 등 주변의 명산들과 함께 단양의 풍광을 연출하는 아름다운 산이다. 그러나 단양팔경의 절경과 다른 산들의 유명세에 가려 일반인들은 물론 산악인들에게도 잘 알려지지 않은 편이다. 물론 이 때문에 한결 여유롭고 아늑하게 산행을 즐길 수 있다는 이점도 있다.사봉은 일명 물레봉이라고도 하는데 옛날 홍수 때 물레만큼 남았었다하여 부르게 된 산명이라 전해오고 있다.특히 이 산 정상에는 일본인들이 한반도의 혈맥을 막기 위해 박아 놓은 쇠말뚝이 있어 역사의 기구함을 느끼게 하고 있다. 사봉 주위에는 단양팔경 중 4경의 절경들이 펼쳐져 있어 산행 후의 주변 관광을 빼 놓을수 없다.", + "MNTN_HG_VL" : "879", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", + "MNTN_NM" : "사봉" }, - "longitude" : 126.88611109999999, - "latitude" : 35.325000000000003 + "longitude" : 128.28194439999999, + "latitude" : 36.907499999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보광산은 산세가 빼어나거나 경치가 좋고 기이한 바위가 있는 그런 산은 아니다. 그저 나즈막한 육산에 불과하다. 그러나 정상의 봉학사지에 얽힌 전설이 현실에서의 인간 욕심이 무상하다는 것을 일깨워 주는 곳이기도 하다. 또한 접근이 용이하고 험하지 않아 가족단위로 등산할 수 있는 좋은 산이다.원래 이름은 봉학산이었다가, 조선 중기부터 보광산이라고 부른다. 정상에는 봉학사 터가 있다. 사찰 건물은 남아 있지 않으나, 괴산봉학사지오층석탑(충북유형문화재 29)이 전해진다. 고려 때의 작품으로 추정되며, 일제강점기 때 무너졌던 것을 1967년 복원하였다. 산 아래에는 봉학사의 후신인 보광사가 자리잡고 있다.보광사는 없어진 봉학사의 후신으로 그 명성을 간직하여 오고 있으며 봉학사지 석조여래상을 대웅전에 주존불로 모시고 있다. 대웅전 처마끝에서 보면 끝없이 펼쳐지는 낮은 산들이 손에 잡힐 듯 친근해 보이고 마음까지도 시원해 지는 곳이다. 대웅전 오른쪽 바위 밑에선 석간수가 샘솟는데 아무리 가물어도 넘쳐 나는 샘물이 맛 또한 그만이다. 흔적도 없이 사라진 절터에 홀로 남은 봉학사지 5층석탑은 고려초기의 작품으로 추정되며 지방유형 문화재로 지정되었다는 안내판이 있다.", - "MNTN_HG_VL" : "539", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 사리면", - "MNTN_NM" : "보광산" + "DETAIL_INFO_DTCONT" : "예로부터 수덕이 뛰어나 삼각산의 영광을 뒷받침한 경기 오악중 북악에 속하는 이 산은 지형적 특성으로 삼국시대에부터 전략적인 요충지로 6.25전쟁 때까지 치열한 격전이 있던 곳이다. 그런 연유로 산자락 설마치계곡 양쪽으로 영국군 전전비와 대한의열단 전적비가 세워져 있다. 바위 사이로 검은빛과 푸른빛이 동시에 흘러나온다 하여 감악(紺岳), 즉 감색바위라고 하였다.또한 조선 명종때 구월산 청석골을 거점으로 활약하던 임꺽정의 중간거점이 있던 곳으로 그와 연관된 지명이 곳곳에 산재해 있다. 정상에는 현재도 군사시설이 있으며, 북한산 진흥왕 순수비와 유사한 일명 삐뜰대왕비 설인귀비가 위치해 있다. 이 비는 아직도 전쟁때 탄흔자국을 가지고 있으며 파주군 향토유적 제 8호로 지정되어 있다. 전체적인 산세는 암릉과 작은 암봉들이 조화를 이루고 있으며 간간이 절벽지대가 있으므로 주의를 요한다.원래 감악사, 운계사, 범륜사, 운림사 등의 4개 사찰이 있었다는데 현재는 1970년 옛 운계사 터에 재창건한 범륜사만 남아 있다.서울에서 그리 멀지 않으며, 의정부 북쪽 회천에서 양주시 남면을 지나 설마리를 거쳐 감악산 계곡을 따라 들어가면 높이 20여 미터에 달하는 운계폭포가 나온다. 폭포 뒤로 범륜사가 있고 그뒤로 전형적인 암산의 모습을 띤 감악산이 보인다. 맑은 날에는 개성의 송악산과 북한산이 보인다.", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 남면, 연천군 전곡읍, 파주시 적성면", + "MNTN_NM" : "감악산" }, - "longitude" : 127.6807002, - "latitude" : 36.821610300000003 + "longitude" : 126.9689597, + "latitude" : 37.941738699999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 여주군 강천면, 남한강이 휘감아 도는 자리에 보금산이 솟아 있다. 그러나 이 산은 솟아 있다는 말 자체가 무색하리 만치 낮은 산으로 해발 400미터가 채 안되는 봉우리이다.섬강과 남한강이 산을 둘러싸고 흘러 경치가 아름답다. 높지는 않지만, 등산로 곳곳에 암릉이 많다. 보금산에서 가장 뛰어난 풍경은 정상 부근에 있는 기암이다. 가파른 절벽 위에 있는 기암으로, 마귀할멈 측간바위라고 부른다. 마치 치마 입은 여인이 턱을 두 손에 괴고 앉아 있는 모습처럼 보여 눈길을 끈다산행은 당고개에서 시작한다. 이 고개는 삿갓재라고도 부르는데, 옛날에는 산적이 많았다고 전한다. 그래서 50명이 모여서야 겨우 이 고개를 넘었다고 하여, 오십명고개라고 부르기도 한다. 주변에는 1993년 불교목공예가 박찬수가 설립한 목아불교박물관이 있다. 또, 북내면에는 남한강변에 자리한 신륵사가 있다. 신라 진평왕 때 원효대사가 창건하였다고 전하며, 보물로 지정된 문화재가 다수 있다.", - "MNTN_HG_VL" : "364", - "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면", - "MNTN_NM" : "보금산" + "DETAIL_INFO_DTCONT" : "깃대봉은 경기도 가평군 하면과 가평읍의 경계를 이루고 있다. 가평군 내에는 깃대봉이 두곳에 있는데, 또 다른 깃대봉은 청평리 북쪽에 솟아 있는 해발 624m인 산으로 대성리 뒷산인 은두봉(銀頭峰.678m)과 같은 능선으로 이어져 있다.깃대봉은 가평의 명지산에서 남쪽으로 가지를 친 능선상의 매봉(929m)과 약수봉(850m) 사이에 솟은 산이다. 정상에 서면 매봉, 명지산, 칼봉산, 화악산, 구나무산, 불기산, 대금산, 축령산, 서리산, 주금산 등이 시원하게 펼쳐저 보인다.산행 들머리는 대금산과 같은 두밀리에서 시작하고 깃대봉 정상에 오르면 10여평의 공터를 만날 수 있다. 북으로는 매봉과 칼봉산 넘어 전패봉, 명지산, 화악산 등이 펼쳐져 있고, 가평읍 넘어 멀리 삼악산이 보이며, 남으로는 대금산이 손에 잡힐 듯 가깝게 보인다. 서남쪽으로 축령산과 주금산이, 서북쪽으로는 운악산이 한눈에 들어온다.", + "MNTN_HG_VL" : "835", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 가평읍", + "MNTN_NM" : "깃대봉" }, - "longitude" : 127.7236111, - "latitude" : 37.315277799999997 + "longitude" : 127.41861110000001, + "latitude" : 37.841388899999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "330", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "보납산" + "MNTN_HG_VL" : "219", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구 신탄진동", + "MNTN_NM" : "성치산" }, - "longitude" : 127.4686111, - "latitude" : 37.694722200000001 + "longitude" : 127.48277779999999, + "latitude" : 36.432499999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "밀양군 상동면과 산외면의 경게에 있는 보두산은 비암골 동북쪽으로 솟아 있는 산봉우리로 옛날에 보담 노장이라는 천문지리에 능통한 감여가의 전설이 담긴 곳이다. 보담 노장은 옛날 중국 왕족이었는데, 나라에 죄를 지어 이곳 보두산에서 귀양살이를 하였다. 이 산에 산성을 쌓고 암자를 지어 평생을 고독하게 지내다가 생을 마감한 산이 바로 이 보두산이다. 보담산이라고도 한다.산은 높지 않지만 암벽타기와 산을 4개나 넘어면서 밀양들을 바라보는 재미가 있는 산이다.", - "MNTN_HG_VL" : "562", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 상동면", - "MNTN_NM" : "보두산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "189", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "지적산" }, - "longitude" : 128.8251827, - "latitude" : 35.544978800000003 + "longitude" : 126.41, + "latitude" : 34.828888900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보래봉은 강원도 평창군 봉평면 북쪽의 한 봉우리이다.\"\"메밀 꽃 필무렵\"\"의 이효석이 태어난 곳이고 이 소설의 무대가 바로 봉평면과 대화면이다. 진입로에 가로수가 없고 메밀을 심는다. 메밀꽃이 피는 여름에는 특히 물이 맑다.평창군은 해발 300-800미터 이상의 고랭지대로 이루어져 있는데 봉평면은 해발 600-800m의 고냉지대이다.이러한 봉평면 일원은 지대가 높고 추운 곳이어서 적설량이 풍부해 특히 겨울철산행을 즐기기에 좋은 산이다.부근에는 이효석의 동상과 소설에 관련된 곳들을 찾아볼 수 있다.", - "MNTN_HG_VL" : "1324", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면", - "MNTN_NM" : "보래봉" + "DETAIL_INFO_DTCONT" : "수레의산은 충북 음성군에 위치한 아담한 산이다. 아직 사람의 발길과 개발의 손길이 미치지 않아서 천연의 순박함을 그대로 간직하고 있는데,이 산은 이름부터가 특이하다. 산 서쪽 계곡에는 청소년수련원과 차곡저수지가 있고 수량이 많으며 수리산에서부터 산서릉의 459번도로까지 임도가 잘 뚫려있다. 박쥐굴, 굴법당, 공기바위, 병풍바위, 상여바위, 전설의못등 볼거리가 많고, 산행시간이 짧고 등산로가 잘 닦여있어 가족산행지로 제격이다.수레의산은 신비의 산이며 숨어있는 산이다. 600m가 넘는 높은 등성이(주능선)에 25평이 넘는 연못이 있고, 거기에 꽤 많은 물이 고여 있다. 이른바 전설의 못이다. 잘 이해가 되지 않는 현상이다. 수레의산은 신비스러운 산답게 사람들의 눈에 잘 띄지 않는 곳에 조용히 숨어 있다. 큰 도로들이 거미줄처럼 얽혀 있는 지금의 상황에서는 웬만한 산은 큰 길에서 그 모습을 볼 수 있다.그러나 이 산은 근처를 지나는 3번 국도(이천 - 충주)나 38번 국도(평택 - 장호원 - 제천), 또는 중부내륙고속도로에서 잘 보이지 않는다. 심지어 산 북서에서 남동으로 가까이 지나는 520번 지방도에서도 가려내기 어렵다. 그 까닭은 큰 도로들이 이 산 근처에서 산 사이를 지나는 때문이기도 하고, 주위에 고만고만한 산들이 많기도 하기 때문이다. 수레의산 주변 산줄기는 남으로 가영산 - 부용산으로 이어지고, 북으로 수리산- 원통산- 오갑산으로 뻗쳐있다. 수레의산이 그처럼 비슷한 높이의 봉우리들로 이루어진 산줄기 가운데 자리잡고 있기 때문에 알아보기 쉽지 않은 것이다.그러나 이 산은 숲이 울창하고 산길이 좋은 데다 산허리를 임도가 지나고 있어 오르내리기에 편리하다. 어디서 올라도 점심시간을 포함해 3 - 4시간이면 어려움 없이 주봉은 물론 전설의 샘(못)까지 돌아 내려올 수 있어 가족산행에 알맞다. 내내 짙은 숲속을 걷기 때문에 산뜻한 기분이 끝까지 이어지고, 군데군데 상여바위 병풍바위 박쥐굴 공기돌 굴법당들도 볼 수 있어 심심찮다 특히 전설의 샘 위에 있는 상여바위는 푸른 숲에 둘러싸인 채 우뚝 솟아 특이하고, 그 위에 오르면 조망이 좋고 시원하다.전설의 샘이 말해주듯 산에는 물이 많다. 주름이 많아 골짜기가 많고 골짜기마다 개우에 맑은 물이 흐르고 있고, 매우 차가워 손을 오래 담그고 있기 어렵다.이 좋은 수질은 이미 근방에 널리 알려졌는데 농업용수로 사용하기 위해 저장해 놓은 차곡저수지의 물조차도 수영하기 어려울 정도로 차고 깨끗하다고 한다. 그래서 근처의 주민들도 아끼고 좋아하는 산인 듯 싶었다. 고스락에 오석 표석이 두 개가 있고, 화강암 표석도 하나 있다.가장 전망좋은곳은 상여바위 꼭대기이고, 전설의못은 능선상에 있는 연못으로 청학포란형의 권근 3대묘와 연루되어 묘를 쓸때 해발 505미터의 이곳에 물을 올렸다는 전설이 있다고 한다.", + "MNTN_HG_VL" : "679", + "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 생극면", + "MNTN_NM" : "수레의산" }, - "longitude" : 128.3663889, - "latitude" : 37.686111099999998 + "longitude" : 127.6635849, + "latitude" : 37.030279200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보련산은 백두대간의 줄기가 치악산과 백운산을 거쳐 충주시로 이어진 능선위에 자리해 있으며 충북 충주시 앙성면과 노은면의 경계를 이루고 있다.이 산은 인파가 많이 몰리지 않는 탓에 호젓한 산행을 즐기기에 적당하다. 정상에서 북쪽으로 눈을 돌리면 동암계곡 끝의 온천마을이 보이고 그 뒤로 남한강이 야트막한 산들 사이로 굽이쳐 흐른다. 서쪽으로는 국망산과 오갑산이 손짓한다. 이 산의 능선은 노송군락으로 이어져 있고 자연동굴, 수룡폭포 등이 있어 주변경치가 좋고 물이 맑다. 산 정상에는 보련산성이 있는데 능선을 따라 흙과 돌로 쌓은 성의 둘레는 약 1.8km이며 일명 봉황성 또는 천룡성이라고 한다.이 성과 동쪽 맞은 편의 장미산 정상에 있는 장미산성 간에는 아주 재미있는 전설이 전해 오고 있다. 삼국시대 때 이곳 보련산 서쪽 가마골 마을에 장미라는 사람과 보련이라는 누이가 살았는데 명산의 정기를 받은 이들은 둘 다 장수의 기질을 가지고 태어났다. 그러나 옛부터 한 집안에 두 장수가 태어나면 그 중 하나는 희생되어야 하기에 두 사람은 성쌓기 겨루기를 하기로 하였다. 이 사실을 안 어머니는 가슴을 저미는 고통을 느끼게 되는데 어머니가 보기에 보련이의 성 쌓는 솜씨가 아들인 장미보다 뛰어나 고민을 하게 되었다.마침내 결심을 한 어머니는 손수 떡을해서 보련이에게 떡을 보이고 다시 성을 쌓게 했는데 보련이가 마지막 돌을 하나 올리려는 순간 장미쪽에서 성을 다 쌓았음을 알리자 보련이는 어머니가 아들을 살리려 했음을 알고 집을 떠났다고 한다. 보련이가 떠난 다음 날 보련이의 집에 큰 별이 하나 떨어졌다고 하며 그후 그 지역 산과 산성을 보련산-보련산성, 장미산-장미산성이라고 부르게 되었다.", - "MNTN_HG_VL" : "765", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면, 노은면", - "MNTN_NM" : "보련산" + "DETAIL_INFO_DTCONT" : "모악산은 전라북도 김제시 금산면과 전주시 완산구와 완주군 구이면의 경계를 이루는 산으로 호남정맥에 솟아 있다.예로부터 호남사경의 하나인 '모악춘경'으로 유명한 모악산은 봄이면 온 산을 벚꽃으로 뒤덮는다. 특히, 금산사에 이르는 벚꽃 길은 바람 불어 꽃잎이 휘날리면 마치 눈이 내리는 듯한 환상에 빠질 정도로 화려하다. 그러나 모악산이란 이름에서 알 수 있듯이 '악'자를 품고 있는 이 산의 산행은 결코 만만치 않다. 구이쪽에서 정상을 향해 오르는 길은 특히 험하여 정상을 얼마 남겨두지 않을 무렵에는 웬만큼 산에 단련이 된 사람이라 할지라도 숨이 턱에 차 오른다. 모든 산이 그렇듯 모악산 역시 마지막 고비와의 힘겨운 줄다리기를 치른 후에야 비로소 정상에 오르는 기쁨을 맛볼 수 있다.정상에 오르면 전주시내와 호남의 넓은 들판이 한눈에 들어와 보는 것만으로도 풍요로운 마음이 드는 호남평야의 전경을 마음껏 즐길 수 있다. 김제쪽으로 하산하는 길은 비교적 수월해 쉬엄쉬엄 주위의 경치를 감상하며 내려오면 된다. 비록 800m도 채 안되는 모악산이지만 덩치와는 다르게 구비구비에 다양한 풍경들을 연출해 산행하는 이들의 시선을 즐겁게 한다. 1971년 도립공원으로 지정된 이 산은 미륵신앙과 많은 연관을 가지고 있어 산자락 곳곳에 이와 관련된 흔적이 많이 남아있다.", + "MNTN_HG_VL" : "795", + "MNTN_LOCPLC_REGION_NM" : "전라북도 김제시 금산면ㆍ전주시 완산구ㆍ완주군 구이면", + "MNTN_NM" : "모악산" }, - "longitude" : 127.78390539999999, - "latitude" : 37.072415200000002 + "longitude" : 127.0843701, + "latitude" : 35.729759000000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보문산은 대전시 남쪽 중심부에 근접해 있어 대전시민들에게는 매우 친근한 휴식처이다. 이 산에는 보문산성, 보문사지, 야외음악당, 전망대 유희시설, 케이블카가 있으며 시루봉길 등 10여개의 등산로와 20여개소의 약수터가 있다. 특히, 보문산성은 시 기념물 제 10호로 1991년 12월 백제산성중 최초로 복원되었다.정상에 있는 장대루에 오르면 광활한 대전 시가지의 발전상을 한 눈에 볼 수 있는 곳이다. 본래 이 산은 보물이 많다하여 보물산이라 부르다가 후에 보문산으로 고쳐 부르게 되었다거나, 나무꾼이 죽어가는 물고기를 살려줘서 얻은 '은혜를 갚는 보물주머니'에서 이름이 유래되었다는 전설도 전해진다. 보문산 녹음(綠陰)은 대전팔경의 하나로 꼽힌다.대전광역시의 대표적인 녹음공원이자 도시자연공원으로,사정공원지구에는 스포츠와 피크닉을 위한 넓은 잔디광장과 체육시설 등이 조성되어 있다. 평일 2천명, 성수기에는 1일 평균 2만여명이 즐겨 찾는 4계절 행락지이다.", - "MNTN_HG_VL" : "457", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 중구", - "MNTN_NM" : "보문산" + "DETAIL_INFO_DTCONT" : "북한강변에 자리 잡은 호명산은 한북정맥상의 귀목봉에서 남으로 뻗은 산줄기 끝자락에 있는 산으로 청평댐 뒤로 병풍처럼 솟아 있다. 이 산은 지난 79년 산 위에 양수발전용 저수지인 호명 저수지가 생긴 다음부터 등산객들의 발길이 잦아지는 산이다.‘호랑이가 우는 산’이란 뜻의 호명산은 옛날 산림이 우거지고 사람들의 왕래가 적었을 때 호랑이 울음소리가 많이 들려오곤 했다는 데서 유래되었다. 때문에 범이 우는 마을의 호명리와 범이 입을 벌리고 있는 모습과 흡사하다는 아갈바위봉, 아갈바위골 등 호랑이와 관련된 지명이 산 곳곳에 남아있다. 남쪽으로는 청평호반과 조종천이 지척이며, 북쪽으로는 북한강과 함께 인공댐인 청평 양수발전소가 있는 천지연이 자리 잡고 있다.정상에서는 남으로 화야산 뽀루봉과 용문산이 줄지어 서있고 서북으로는 깃대봉과 축령산, 서리산 등이 조망된다. 북으로 청우산과 대금산 매봉이 뚜렷하게 보이고 명지산, 화악산, 국망봉 등이 파노라마의 장관을 연출하며 산 아래로는 청평호와 북한강, 조종천, 천지연의 물줄기가 반짝인다.", + "MNTN_HG_VL" : "632", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 청평면", + "MNTN_NM" : "호명산" }, - "longitude" : 127.42154499999999, - "latitude" : 36.301724 + "longitude" : 127.4460303, + "latitude" : 37.729328899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 괴산군에 위치한 보배산은 사람들의 발길이 닿지 않는 산으로 자연의 청정함이 그대로 살아 있다. 특히 쌍곡계곡은 소금강이라 불릴 만큼 경치가 아름다워 한폭의 동양화를 연상케 한다. 계곡을 따라 군데군데 펼쳐지는 바위와 암릉의 조화, 그 위를 흐르는 맑은 물, 단풍이라도 든다면 그야말로 가을의 운치가 물씬 묻어나는 곳이다.보배산 청석골 골짜기에는 충청북도에서 가장 오래된 사찰 각연사가 있다. 각연사는 신라 법흥왕(514~539) 때 유일대사가 창건했다. 경내에는 석조비로자나불좌상(보물 제433호), 통일대사탑비(유형문화재 제2호), 비로전(유형문화재 제123호), 대웅전(유형문화재 제126호), 그리고 대웅전 앞마당을 뒤덮은 밑둥 둘레가 두 아름이 넘는 보리수나무 등 볼거리가 많다.", - "MNTN_HG_VL" : "772", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면 태성리", - "MNTN_NM" : "보배산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "산성산" }, - "longitude" : 127.91666669999999, - "latitude" : 36.75 + "longitude" : 128.59083330000001, + "latitude" : 35.810000000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "온통 산으로 둘러싸인 거창에서 숨은 진주를 꼽으라면 보해산을 꼽을 수 있다. 칼날처럼 날카로운 바위 봉우리를 여럿 거느리고, 천길 낭떠러지 위에 우뚝 선 이 산을 누군가는 ‘거창의 용아장성’이라고 표현했을 정도로 풍광이 시원스럽다.능선에는 바늘을 꽂아둔 듯 빼곡히 자라는 소나무나 철쭉이 인상적이며, 시야가 트인 능선 너머로는 흰대미산과 수도산 등 여러 산들이 켜켜이 늘어서 멋진 산수화를 펼쳐 보인다. 산길은 동서남북 사방으로 나 있어 다양한 코스를 즐길 수 있으나 주능선 상에서는 식수를 구하기 어려운 것이 아쉬운 따름이다.일명 상대산이라고 부르는 보해산은 보해사라는 절과 여러 부속암자를 거느리고 있었는데, 현재 절은 없어지고 ‘보해’라는 이름을 가진 산과 여러 지명만 남아있을 뿐이라고 한다. 산 서쪽 기슭으로는 송이버섯이 많이 나는데, 모두 임자 있는 송이이니 산행 중에 손을 대지 않도록 주의한다.", - "MNTN_HG_VL" : "909", - "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가북면, 주상면", - "MNTN_NM" : "보해산" + "DETAIL_INFO_DTCONT" : "엄광산은 높이 503.9m로 부산광역시진구에서 제법 높은 산에 속하며, 동남으로 구봉산에 이어져 있는 산이다. 이 산은 고원견산이라 불리기도 하는데 이 명칭은\"\"산이 높아 멀리까지 볼 수 있다.\"\"는 뜻으로 일제시대부터 불려진 이름이다. 엄광산은 얼마 전까지 고원견산으로 불리던 산인데\"\"부산광역시을 가꾸는 모임\"\"이 지난 95년 4월에 엄광산(嚴光山)이라는 이름을 찾아주고 정상표지석을 세웠다. 이 산의 정상조망 역시 뛰어나다. 동래부지 산천조에 보면 엄광산의 산봉이라는 기록으로 보아 엄광산으로 통해졌던 것이라 보아진다.이 산 정상에는 부산광역시 전체가 한눈에 들어온다. 동구, 서구, 사하구, 북구, 해운대구 일부도 한눈에 들어와 부산광역시의 숨소리가 그대로 느끼어진다. 안산암질의 암석으로 구성된 엄광산(고원견산)은 산정이 대체로 평탄하며, 산 정 부근에는 잔 자갈들로 된 애추가 발달한다. 산록은 비교적 가파른 편이다. 금정산맥의 말단부에 해당되며, 남서쪽으로 구덕산,나몽쪽으 로는 구봉산으로 연결된다. 엄광산은 부산광역시만의 전망이 좋기로 이름 나 있고 산록에는 산림이 울창하여 자연공원으로서 부산광역시민의 사랑을 받고 있다.", + "MNTN_HG_VL" : "504", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 서구 동대신동, 부산광역시 진구 개금동", + "MNTN_NM" : "엄광산(고원견산)" }, - "longitude" : 127.96511940000001, - "latitude" : 35.745744799999997 + "longitude" : 129.02056450000001, + "latitude" : 35.137197399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "909", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "보해산" + "DETAIL_INFO_DTCONT" : "승학산은 보라마을 뒷산으로, 산세가 마치 학이 나는 형상이라 하여 이름 붙여졌다. 승학산 봉우리 모양은 떡시루 같이 생겼다고 하며, 또 천지 개벽때에는 물에 잠기고 떡시루 하나 놓을 만큼 남아 있었다 하여 시루봉이라는 지명도 남아 있다. 승학산 기슭에 있는 보라마을은 승학산이 비단처럼 둘러싸여있다 하여 보라(甫羅)라고 했다.밀양의 승학산은 워킹과 계곡을 함께 즐길 수 있는 산행지로 적합한 산이다. 밀양시 단장면의 승학산-정각산-정승계곡 코스는 끝없이 이어지는 능선길을 달릴 수도 있고 하산길에 10여Km나 되는 계곡 물길을 거슬러 내려가는 계곡 산행을 같이 즐길 수 있는 멋진 곳이다. 특히 정승골 계곡은 산악인들에게 아직도 알려지지 않은 곳으로 깨끗함은 물론 비경이 이어지는 새로운 계곡 산행지이다. 정각산의 여러 코스를 올라 본 산악인이라면 정승골 계곡을 먼발치에서 내려다 본 경험은 있을 것이다. 그러나 비경이 이어지는 계곡의 참모습을 물길 산행을 하면서 느껴 본 사람은 그리 많지 않을 것이다.산행들머리는 회관에서 50m 과수원 초입에서, 왼쪽 위로 돌아 별장에서 오른쪽으로 오르면 본격적인 산행이 시작된다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", + "MNTN_NM" : "승학산" }, - "longitude" : 127.96511940000001, - "latitude" : 35.745744799999997 + "longitude" : 128.86506800000001, + "latitude" : 35.537758199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보현산은 경북 영천시 화북면과 청송군 현서면, 포항시 죽장면의 경계를 이루며 솟은 육산이다. 정상 부근에는 국내 최대 규모의 보현산천문대가 있으며 천문대까지 차량으로 오를 수 있다. 참나무, 당단풍나무, 고로쇠나무 등이 숲을 이루고 있으며 야생화 천국이라 할 만큼 다양한 식물들이 자라고 있다.주능선은 이웃한 면봉산과 더불어 고산다운 산세를 지닌다. 시루봉(1124m)과 보현산(1126m), 두 봉우리가 나란히 정상군을 이루고 있다. 정상에서 동쪽 능선을 따라 3킬로미터 지점에는 826.5미터의 ‘작은 보현산’도 있다.보현산은 이 일대에서 가장 높은 산이기에 일출과 낙조를 잘 볼 수 있는 곳이다. 일출과 일몰의 아름다움이 알려지기 시작하면서 해마다 연말연시면 해돋이와 함께 새롭게 한 해를 시작하려는 이들로 인산인해를 이룬다. 이른 봄에는 고로쇠축제, 5월에는 산나물축제, 8월 중순에는 별빛축제가 열리는 들머리 정각리 별빛마을은 최근에 청정미나리로도 널리 알려져 찾는 이가 늘고 있다.", - "MNTN_HG_VL" : "1126", - "MNTN_LOCPLC_REGION_NM" : "경북 영천시 화북면, 청송군 현서면, 포항시 죽장면", - "MNTN_NM" : "보현산" + "DETAIL_INFO_DTCONT" : "정선 아라리로 유명한 아우라지가 산의 아랫부분을 감아돌며 절경을 보여주는 산으로 철쭉 군락과 오래된 주목이 눈을 즐겁게 한다. 정상에서는 사방을 시원스럽게 조망할 수 있는데, 북쪽 멀리 백두대간도 보인다. 이곳에는 중국의 무릉도원에 비견되는 전설이 전해지는데, 이 산에서는 병도 안들고 늙지도 않는다는 것이다.또한 옥갑장군이 이 산에서 무예를 닦고 그가 입었던 갑옷을 산속에 숨겼다는 옥갑산봉도 남쪽에 있다. 상원산은 강원도 정선군의 최북단인 북평면과 북면 사이에 솟아있다.동쪽에는 평창군 도암면의 황병산 부근에서 발원하여 남쪽으로 흐르는 남한강의 지류인 송천이 심한 곡류를 이루고 있다. 부근에는 정선탄전에 속하는 탄광이 있으며, 석탄을 수송하기 위해 부설된 정선선의 기점이 된다. 북쪽에 두루봉, 서쪽에 갈미봉, 남쪽에 백석봉과 옥갑산봉, 북동쪽에 노추산 등이 솟아 있다.", + "MNTN_HG_VL" : "1421", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면, 북면", + "MNTN_NM" : "상원산" }, - "longitude" : 128.97476230000001, - "latitude" : 36.1616304 + "longitude" : 128.67638890000001, + "latitude" : 37.508333299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "복계산은 대성산(1174.2m)에서 복주산(1151.9m)을 향해 뻗어나가던 한북정맥의 산줄기가 수피령을 막 지나온 지점의 마루금에서 오른쪽(북서쪽)으로 약 700미터 벗어난 거리에 빚어놓은 명산이다. 민통선 바로 아래 위치해 있어 산행의 감회가 남다르고 ‘신철원팔경’의 하나인 매월대(595m)와 매월대폭포, 1996년 SBS 특집드라마 ‘임꺽정’의 청석골세트장 등이 있어 찾는 사람들이 많다.복계산은 매월대로 더 잘 알려진 산행지다. 복계산 기슭에 위치한 높이 40미터의 절벽이 매월대로 전설에 따르면 아홉 선비가 매월대에서 바둑판을 새겨놓고 바둑을 두며 단종의 복위를 도모했다고 전해진다.복계산을 산행한 후 승리전망대를 견학하면 안보산행으로서 금상÷화다. 그러기 위해서는 승용차나 관광버스를 이용하는 것이 좋다. 매월대주차장을 기점으로 복주산 정상에 오르는 코스는 매월대코스와 매월대폭포코스, 청석골세트장코스 등이 있는데 이중에서 매월대폭포코스로 올랐다가 청석골세트장으로 하산하는 것이 가장 무난하다.", - "MNTN_HG_VL" : "1054", - "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면", - "MNTN_NM" : "복계산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "675", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", + "MNTN_NM" : "고양산" }, - "longitude" : 127.50101100000001, - "latitude" : 38.2016609 + "longitude" : 128.17715340000001, + "latitude" : 37.736119500000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "복두봉은 운장산(1,126m)에서 동쪽인 구봉산(980m)쪽으로 뻗어나간 능선의 중간지점에 솟구쳐 오른 산이다. 복두봉은 아직 사람들의 손길과 발길이 닿지 않은 천혜의 자연경관을 자랑하고 있으며, 진안의 북서쪽에 마치 울타리를 친 듯이, 운장산, 복두봉, 구봉산의 능선은 금강과 만경강의 분수령을 이루고 있다.계곡 안에는 아직 알려지지 않은 200여평에 달하는 마당바위, 해기소, 정밀폭포 등이 등산객들을 유혹하고, 갈거계곡의 최상류인 민듬분지에는 6.25동란 전까지 화전민이 살았던 농장 터가 있어, 이곳은 가을이면 수만평의 억새군락이 너울너울 춤을 추고, 산허리에는 만산홍엽 단풍물결이 어우러져 한 폭의 그림 같은 풍광을 연출한다.복두봉 북쪽 아래는 여름 피서지로 유명한 운일암, 반일암의 협곡이 자리잡고 있으며, 도 주능선에서 운일암, 반일암 방향으로 아직도 비경으로 남아 있는 늑막골과 물탕골이 있어 어느 방향에서 오르내리거나 산자수명한 계곡산행을 즐길 수 있다.", - "MNTN_HG_VL" : "1017", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안 정천면, 주천면", - "MNTN_NM" : "복두봉" + "DETAIL_INFO_DTCONT" : "전라북도 경계선이내에는 1000m 가 넘는 5대 고산이 있다. 그 중 높이가 네 번째인 운장산에서 북쪽으로 뻗어나간 대능선이 칠백이고지를 만들고 여기서 남서쪽으로 갈라진 지맥의 끄트머리에서 아름다운 대아저수지에 그림자를 드리우고 우뚝 솟아 숨어 지내온 수려한 명산이다.구름위에 솟아 있는 바위산이라고 하여 이름도 운암산이라 지었다. 이름에서부터 운치있는 산의 풍광을 떠올리게 되는데 산 정상에서의 조망은 그 기대를 저버리지 않는다. 새만금간척지로 흘러가는 대아댐이 굽어보이며 정상에서 봉화대로 이어지는 수려한 암벽능선이 인상적이다. 정상인 관봉은 옛날 봉수대자리로 그 때의 석축이 지금도 뚜렷하게 남아있다. 서쪽으로 뻗은 능선은 기암괴석으로 이어져 있고, 능선의 남쪽면은 거대한 절벽지대를 이루고 있다. 이 절벽지대는 군부대의 산악훈련장으로 이용하고 있어 입산이 통제되어 있으나 능선 등산에는 지장이 없다.", + "MNTN_HG_VL" : "597", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 고산면", + "MNTN_NM" : "운암산" }, - "longitude" : 127.39638890000001, - "latitude" : 35.931111100000003 + "longitude" : 127.28103900000001, + "latitude" : 35.988175900000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "복두산은 강원도 삼척시 가곡면에 숨어 있는 오지의 산이다. 이 산은 북으로 육백산과 매봉산, 동쪽으로 치바위산, 남쪽으로 면산, 서쪽으로 백병산이 둥그렇게 에워싸고 있는 곳으로 열매로 치면 두터운 껍질에 쌓인 알맹이 부위라 할 수 있다.그래서 옛날 이 마을 사람들은 이 산을 복동아리산이라 하였다. 산 아랫마을 이름은 동활리인데 이것은 복두산에서 기인한 것으로 본래 `복동아리' 또는 `도화리(桃花里)라 불리던 곳이 와전된 것이다.촛대처럼 뾰족한 기이한 바위 등 군데군데 암봉이 많다. 등산로는 다소 험하며, 복두천은 여름철 피서지로 각광받고 있는 곳으로 휴가철에는 마을에서 입장료를 받고 계곡을 관리하고 있다.", - "MNTN_HG_VL" : "978", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "복두산" + "DETAIL_INFO_DTCONT" : "덕룡산과 주작산은 높이에 따라 산세가 좌우되지 않는다는 사실을 깨닫게 하는 산이다. 해남 두륜산과 이어져 있고 높이라야 고작 400미터를 조금 넘지만 산세만 놓고 보면 1000미터 높이의 산에 뒤지지 않는다. 이 산은 웅장하면서도 창끝처럼 날카롭게 솟구친 암릉과 암릉 사이의 초원능선 등 능선이 표현할 수 있는 아름다움과 힘의 진수를 보여준다. 두륜산과 경계를 이루는 오소재에서 주작산, 덕룡산, 소석문까지 이어지는 11킬로미터 암릉은 마치 봉황이 날개를 펴고 하늘로 비상하는 형상이다. 봄이면 산꾼의 가슴을 태워버릴 듯 암릉에 흐드러지게 핀 진달래가 탄성을 자아내게 하고, 여름이면 은빛으로 빛나는 다도해와 누렇게 익은 보리밭의 조망, 가을이면 억새와 단풍 그리고 사시사철 신이 빚어 놓은 만물상이 연이어지는 스릴 넘치는 암릉이 산행의 백미다. 주작산은 강진군 신전면, 도암면, 해남군 옥천면, 북일면을 경계하고, 덕룡산은 강진군 도암면과 신전면을 경계한다. 덕룡산 정상에서 조망은 북으로 흑석산과 만의산, 만덕산과 월출산, 북동으로 궁성산과 국사봉, 수인산과 제암산, 동으로 천관산과 일림산, 남으로 두륜산과 상황봉, 서쪽은 두륜산과 첨찰산이 보인다.", + "MNTN_HG_VL" : "433", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", + "MNTN_NM" : "덕룡산" }, - "longitude" : 129.1268848, - "latitude" : 37.162401899999999 + "longitude" : 126.7021027, + "latitude" : 34.540005299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 철원군 근남면, 화천군 사내면 경계에 우뚝 솟은 한북정맥의 산이다. 복주산이란 산명은 그 옛날 세상이 물에 다 잠겼을 때, 이 산 꼭대기만 복주께(사발) 뚜껑만큼 남았다고 해서 이름 붙여졌다고 전한다. 대체로 산행은 SBS 청석골세트장이 있는 매월동마을 또는 한북정맥의 시작점인 수피령에서 시작한다. 산행 중에 만나는 ‘매월대’는 매월당 김시습이 바둑판을 그리고 바둑을 두었다고 하여 이름 붙여진 바위를 가리킨다. 높이 20미터의 매월대폭포는 겨울철이면 빙벽등반을 하는 이들이 즐겨 찾는 곳이다. 복주산은 복계산과 연계하여 산행이 이루어지는 것이 대부분이며, 군사지역의 최전방인 철원에 위치한 만큼 등산로 곳곳에 참호시설을 비롯한 군사시설물들로 가득 차 있어 적설량이 많은 겨울철 산행에는 조심해야 한다. 간간이 만나는 바위 구간에는 로프가 설치되어 있으며, 891.9봉과 실내고개 갈림길에 위치한 1014미터 봉우리는 주변 산록을 조망할 수 있는 훌륭한 전망대 역할을 한다.", - "MNTN_HG_VL" : "1152", - "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면·화천군 사내면", - "MNTN_NM" : "복주산" + "DETAIL_INFO_DTCONT" : "석영과 석회석이 혼합된 흰색의 바위가 많이 쌓여 있어 백적산이라는 이름이 생겨났고, 흰적산이라고도 부른다. 바위들은 날씨가 궂으면 검게 보이고 날씨가 개이면 희게 보인다고 하며, 바위 틈에는 크고 작은 뱀들이 서식하고, 힘을 솟게 한다는 샘이 있다고 한다.강원도 평창군 대화면과 진부면의 경계에 있는 백적산은 사람들의 발길이 닿지않아 원시림이 울창한 산이다. 백두대간의 주맥인 오대산에서 지맥으로 갈래쳐 계방산 동쪽 2km지점에서 남하하여 영동고속도로를 건너 뛰어 백적산을 솟구치고 그 아래로 백석산(1365m), 가리왕산(1561m), 청옥산(1256m)을 일구어 놓았다.산 곳곳에 상여바위(수리바위),삼형제바위(통관바위)등 기암괴석이 있으며 백적산 정상은 사방천지의 산들이 모두 뚜렸하게 펼쳐지므로 그야말로 하늘에 오른 느낌이다. 사방의 산들이 맑은 하늘아래 모두다 선명하게 드러내니 백적산을 찾은 보람을 완전히 만끽하는 순간이다.", + "MNTN_HG_VL" : "1141", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", + "MNTN_NM" : "백적산" }, - "longitude" : 127.5027778, - "latitude" : 38.203888900000003 + "longitude" : 128.4913889, + "latitude" : 37.591111099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "195", - "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군", - "MNTN_NM" : "봉대산" + "DETAIL_INFO_DTCONT" : "경기도 양평군 옥천면과 가평군 설악면의 경계를 이루며 솟아있는 소구니산은 오대산 두로봉의 지맥이 뻗어내려 강원도 홍천과 횡성땅을 휘휘 돌아 경기도에 용문산과 유명산을 세워놓고 우뚝 솟아있다. 유명산과는 달리 바위가 어울린 산으로 유명산에 가려 잘 알려지진 않았지만 유명산과 연결해서 많이 찾는 곳이다.산행기점은 농다치고개와 북쪽의 서너치고개가 가장 일반적이나 교통편이 불편한 것이 흠이다. 정상에 서면 전망이 좋은데 유명산쪽으로는 고냉지 채소밭이 이색적이고 멀리 마터호른 같은 백운봉이 시야에 들어온다. 하산길은 정상 남쪽으로 뻗어내린 긴 능선을 따르거나 유명산을 거쳐 하산할 수도 있다.", + "MNTN_HG_VL" : "798", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "소구니산" }, - "longitude" : 126.2736111, - "latitude" : 35.119166700000001 + "longitude" : 127.4729765, + "latitude" : 37.578820100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 영월군의 진산인 봉래산은 영월읍내를 굽어보는 자리에 우뚝 솟아있다. 영월8경의 하나이기도 한 봉래산은 `봉래채운'이라는 예전의 명성 그대로 많은 관광명소를 끼고 있다.산행도 낙화암, 민충사 등 유명한 관광지를 안고 있는 체육공원에서부터 시작된다. 체육공원에서 절터를 지나 동북쪽 능선길을 따라 오르면 정상에 다다를 수 있다. 중간에 조망되는 남한강 물줄기와 영월읍내의 모습이 보는 이의 눈을 시원하게 해준다. 정상은 참나무가 빽빽이 들어서 있는 펑퍼짐한 둔덕으로 이루어져 있다.주위에 천연기념물인 고씨동굴과 어라연 등이 자리하고 있다. 또한 영월로 들어서는 길목인 소나기재 북쪽에 단종의 능이 위치해 있으며, 천문대와 동강등 주변 관광자원과 연계해 이제 영월은 새로운 산행과 관광을 겸할 수 있다.", - "MNTN_HG_VL" : "856", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", - "MNTN_NM" : "봉래산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "350", + "MNTN_LOCPLC_REGION_NM" : "충청남도 당진시", + "MNTN_NM" : "아미산" }, - "longitude" : 128.4858619, - "latitude" : 37.197774199999998 + "longitude" : 126.6648254, + "latitude" : 36.845756000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉래산의 가장 높은 봉우리를 조봉(祖峰)이라 하고, 그 다음의 봉우리를 자봉(子峰), 그 아래의 것을 손봉(孫峰)으로 부르고 있다. 가까이 보면 세 봉우리의 구별이 잘되지 않지만 멀리서 바라보면 굽이진 봉우리의 낮아진 모습이 확연하게 드러난다.산 전체가 원추형이며 산록의 사면은 가파른 편이다. 특히 남쪽 사면은 급경사로 바다에 거의 내리박듯 수직으로 돌입한다. 산기슭에는 기계적 풍화작용에 의해 쪼개진 바위가 점점이 흩어져 있다.봉래산은 원래 동쪽바다 한 가운데 있어서 신선이 살고 불로초와 불사약이 있다는 상상속의 영산이다. 봉황이 날아드는 산이라는 의미로 영도의 중심에 위치하고 있다.봉래산에는 두 가지 속설이 있다. 봉래산은 지세가 마치 아늑한 어머니의 품같은 형상을 하고 있어 자식들인 이곳 주민이 어머니 품을 떠나면 못 살게 된다는 설, 또 봉래산 산신령이 욕심이 많아 영도로 들어오는 것을 좋아하나 밖으로 떠나는 것을 싫어해 이 곳 주민들이 영도를 떠나면 좋지 않다는 설이다. 이런 것들은 속설에 지나지 않고 영도 사람들은 유달리 인정이 많아 이곳에서 한평생을 사는 사람이 많다는데서 유래된 듯하다.", - "MNTN_HG_VL" : "395", - "MNTN_LOCPLC_REGION_NM" : "부산광역시", - "MNTN_NM" : "봉래산" + "DETAIL_INFO_DTCONT" : "석두봉은 강원도 오지중에서도 손꼽히는 오지에 위치한 탓으로 산악인들 사이에서도 잘 알려지지 않아 등산인들의 발길이 뜸하다. 그러다보니 등산로가 수풀에 둘러싸여 원시림을 헤쳐나가는 산행의 묘미를 만끽할 수 있다. 석두봉은 산이 깊어 물이 맑고 수량 또한 풍부하다.기다리던 돌산, 석두봉 올라보면 하늘과 맞닿는 느낌이다. 석두봉 정상은 이름 그대로 두 쌍의 바위로 이루어져 있다. 동봉과 서봉으로 정상을 지키고 있는 바위에 올라서면 일대의 경관을 한눈에 조망할 수 있으며 바위 사이로 자라는 철쭉들이 신기롭다.또한 참나무 노령목들이 여기저기 자라는 모습은 장관이며, 서쪽으로는 안반데기 동쪽으로는 왕산면 목계리가 한눈에 들어온다. 정상 바로 옆에 큰바위가 있는데 이곳에 오르면 상쾌한 느낌이다. 용수골을 내려다보며 큰소리로 메아리를 만들어 보는 것도 일미이다.", + "MNTN_HG_VL" : "991", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "석두봉" }, - "longitude" : 129.0552017, - "latitude" : 35.081954600000003 + "longitude" : 128.8230556, + "latitude" : 37.608333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉명산(697m)은 문경읍 마원리 우무실마을에 있는 문경읍의 앞산이어서 올라서면 문경읍이 한눈에 들어오고 주흘산, 조령산, 백화산, 성주봉이 문경읍을 빙둘러 서있는 모습을 볼 수 있는 곳이다.우리나라 산업발전의 원동력이 되었던과거 석탄과 흑연을 생산하던 봉명광업소가 있던 곳이며, 금학사라는 절도 있었으나 지금은 절터만 남았다. 과거에는 산 아래에 정기적으로 물이 솟는 조천이란 샘이 있었다고 전하나 지금은 찾을 길이 없다.정상에서 탁 트인 조망은 일품이다. 정상 부근에는 강대바위와 촛대바위가 있고, 산 앞으로는 조령천이 흐른다. 아래 등산로에 시루떡을 닮은 바위가 셋이 있는데 제일위의 시루떡 바위에 불상이 새겨져 있다.문경온천과 한눈에 조망되는 주흘산 모습이 좋아 등산객이 많이 찾고 있으며 매년 등산객이 늘어나고 있다.", - "MNTN_HG_VL" : "697", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", - "MNTN_NM" : "봉명산" + "DETAIL_INFO_DTCONT" : "초록봉은 백두대간의 연봉 청옥산의 한 봉우리로 수목이 울창하고 계곡과 자연경관이 아름다운 등산로이며 정상에서 동해시 전체가 바로 보여 동해 8경 중 제8경으로 선정되었다. 최근들어 시민들의 휴식공간 및 소원을 빌기 위한 장소로도 많은 사람들이 찾고 있다.초록봉에는 ‘칠성바위’라고 불리는 바위가 있다. 이 바위에는 전설이 전해져 오는데, 옛날 인간세상이 너무 어지러워 하느님이 세상을 바로잡기 위해 한 장수를 보냈다. 이 장수는 세상을 바로잡고 자기 일을 다 한 후 승천하기 위해 힘차게 바위를 밟고 지나갔는데 그 장수의 오른쪽 발자국은 초록봉 벼락바위에, 왼쪽 발자국은 초록봉 아래 바위에 길이 15미터, 높이 3미터의 큰 흔적으로 남았다. 후세 사람들은 그 바위에 소원을 빌면 소원성취 있다해 칠성바위라 불렀다.옛적에는 초로의 산, 비나리의 산으로 명성이 있었으나 대형 산불로 잿더미가 되는 바람에 현재는 오히려 조망 좋은 일출, 일몰 산행지로 각광받고 있다. 초록봉은 산세가 부드럽고 키 큰 나무가 적어 산행 내내 바다를 볼 수 있으며 등산로도 유추하기 쉬워 길을 잃을 염려가 없다. 중식시간을 포함하더라도 느긋하게 5시간이면 충분히 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "529", + "MNTN_LOCPLC_REGION_NM" : "강원도 동해시", + "MNTN_NM" : "초록봉" }, - "longitude" : 128.1427698, - "latitude" : 36.720131100000003 + "longitude" : 129.0714347, + "latitude" : 37.522134999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 횡성군 청일면과 홍천군 서석면의 경계를 이루는 봉복산은 남한강의 지류인 섬강의 발원지로 깨끗한 계곡과 풍부한 수량을 자랑하고 있다. 이 산은 산세가 봉황을 닮아서 '봉복산'이라고 불리우며, 산 뒤쪽에 봉복샘이 있는데 여기서 흐르는 물이 섬강을 이루는 근원이다. 산이 높은 만큼 골짜기가 깊지만 나무들이 많아 산세가 그렇게 험하지 않다. 맑고 깨끗한 물도 충분해서 좋은 산의 면모를 그대로 갖춘 산이다.봄에는 두릅, 산나물 등이 많이 나고, 여름철에는 소(沼)와 담(潭)이 많아서 시원함을 느낄 수 있다. 산이 높고 나무가 많아서 가을에는 낙엽이나 단풍도 가득하다. 단풍철만 되면 한꺼번에 몰리는 인파를 피해, 한적한 곳에서 여유롭게 단풍산행을 즐기기에 적합한 산이다. 호젓한 산길을 따라 흐르는 계곡이 너무나 맑고 깨끗하기에 기분이 무척 상쾌하기만 하다. 하얀 포말을 일으키며 쏟아지는 작은 폭포가 나타나는가 했더니 조금 더 오르면 시원한 숲그늘 속에 쉬어가기 좋은 반석을 이룬 곳들도 즐비하다. 꼭 신선놀음하는 분위기가 연이어지는 것이다.봉복산의 정상에서 내려다보는 경관은 그야말로 일품이다. 사방으로 막힘이 없이 시원하게 펼쳐져 있는 경치를 관망할 수 있다.", - "MNTN_HG_VL" : "1022", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", - "MNTN_NM" : "봉복산" + "DETAIL_INFO_DTCONT" : "경기도 남양주시 수동면과 가평군 상면 경계를 이루는 서리산(825m)은 한북정맥에서 가지를 쳐 나온 주금산(814m)을 모산으로 하는 산이다.서리산은 그동안 축령산 유명세에 가려져 있었다. 그러나 10여 년 전부터 축령산자연휴양림이 본격적으로 알려지고 주능선에 수천 평 규모의 철쭉군락이 인기를 얻으면서 축령산 못지않게 인기를 끌고있다.산세는 주능선 북쪽 사면이 바위벼랑에 가까운 급경사로 이뤄진 반면, 남쪽은 완만한 산세로 이뤄져 있다. 따라서 등산로는 축령산자연휴양림이 있는 남쪽 위주로만 발달되어있다. 들머리인 외방2리 종점가게에 이르면 북쪽으로 소 한 마리가 드러누운 듯 올려다보이는 산이 서리산이다.종점가게에서 계류 건너로 마주 보이는 능선은 서리산 남서릉이고, 그 끝에서 남서봉인 화채봉이 보인다. 정상은 보이지 않는다. 서리산 오른쪽에 우뚝 솟은 산이 축령산 정상이다. 정상에서 주능선은 855봉을 거쳐 남쪽 오독산으로 이어지는데, 855봉에서 종점가게 방향으로 가지를 치는 능선이 있다. 바로 이 능선 상에 유명한 남이바위, 수리바위, 박달고지가 있다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", + "MNTN_NM" : "서리산" }, - "longitude" : 128.2163889, - "latitude" : 37.620277799999997 + "longitude" : 127.3156252, + "latitude" : 37.768321800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "534", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "봉수산" + "DETAIL_INFO_DTCONT" : "백아산은 전라남도 화순군에서도 오지라고 할 수 있는 북면에 위치한다. 그렇기 때문에 그저 평범한 산으로 지나치기 쉬우나 이 산이 전남의 명산들을 조망하기에 매우 좋은 위치에 자리하고 있다는 것은 백아산에 오르는 순간 알게 된다. 한때 빨치산 활동지로도 유명한 백아산은 그들이 차지하고 활동할 만큼 사방 수십 리에 걸쳐 거침이 없다.석회석으로 된 산봉우리가 마치 흰 거위들이 모여 앉아 있는 것처럼 보여 백아산(白鵝山)이라는 이름이 붙여졌다고 한다. 산 북쪽으로 무등산(1187m)이, 남쪽으로 모후산(919m)이 있다. 날카로운 바위가 많고 산세가 험하나 등산로가 잘 정비되어 순탄한 산행을 즐길 수 있다. 산 중턱에는 화순 아천산 천연동굴이 있다. 석회암 동굴이며, 약 2억년 전에 생성된 것으로 추정하고 있다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 북면", + "MNTN_NM" : "백아산" }, - "longitude" : 128.7333333, - "latitude" : 36.733333299999998 + "longitude" : 127.1639881, + "latitude" : 35.1661888 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "예전 부터 봉화를 올릴수 있다고 봉수산이라 불리었다고한다.(다성 초이선사 탄생지로 유명하다) 산정상에 오르면 뒷편으로는 확트인 칠산바다와 앞으로는 싱싱달리는 새해안 고속도로의 시발점이 보인다. 앞으로는 시원하게 달리면 자동차와 뒤로는 뻥뚫린 바다가 보이는 전망이 아주 좋은 산이다.", - "MNTN_HG_VL" : "204", - "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 삼향면 왕산리", - "MNTN_NM" : "봉수산" + "DETAIL_INFO_DTCONT" : "관인봉은 정상에서 남봉으로 뻗어내린 능선과 평행선을 이루고 주능선은 대부분 암릉과 암벽지대로 이루어져 있고, 이러한 천혜의 지형을 이용행 보가산성을 축조한 석축이 남아있다. 지장봉계곡을 사이에 두고 서로 마주보고 있는 삼형제봉과 지장봉은 일직선으로 연결되어있고 관인봉은 관인북봉 위쪽에서 예각으로 좌회전하여 서진하면 지장봉과 만난다.경기도 포천군 관인면 서북단에 위치한 관인봉 일원은 예로부터 전략적 요충지로 삼국시대 때 고구려, 백제, 신라가 영토 분쟁을 하였던 곳이다. 삼국시대 초기에는 백제 땅이었다가 고구려 광개토왕 6년(396년)에는 고구려령이 되었고, 신라 진흥왕 12년(551년)에는 신라의 국토에 편입되어 경덕왕 16년(757년)에는 칠성군에 속해 있었다는 기록이 있다. 신라 말에는 궁예가 태봉국을 건국하여 철원에 도읍을 정하였을 때 태봉국의 영역에 속하게 되었다한다. 태봉국왕인 궁예의 폭정에 못 견딘 어진(仁) 관리(官)들이 관직을 버리고 이 지역에 모여 살았다는 유래로 이 지역이 관인으로 불리게 되었다 한다.정상에서 조망은 북으로는 철원군의 고대산(高臺山.832m)과 금학산(金鶴山.947m)이, 동쪽으로는 고남산(古南山.644m)이, 남쪽으로는 종자산(種子山.643m), 서쪽으로는 지장봉(地藏峰.877m)이 관인봉을 감싸고 있다. 울창한 수림으로 수량이 많은 큰골은 계곡 피서지로서 유명하고 가을 단풍도 좋다.", + "MNTN_HG_VL" : "710", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시", + "MNTN_NM" : "관인봉" }, - "longitude" : 126.4154277, - "latitude" : 34.856907499999998 + "longitude" : 127.17340609999999, + "latitude" : 38.1419122 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "음식의 양념으로 또는 한약제로도 쓰인 향취나 맛이 뛰어나 전국적으로 널리 알려진\"\"봉두생강\"\"의 주산지 봉동읍의 서북쪽에 우뚝 솟아 있는 산이 봉실산이다.이 산은 그리높지 않으나 봉동평야의 동북쪽으로 길게 뻗은 산맥으로 옥녀봉을 거느린 두 봉우리와 암봉으로 이루어진 산으로 정상에 서면 그 주위에 산이 없으므로 사방 거침없이 펼쳐진 들녘이 확 트여 시원스럽기 그지없는 전망이 일품이다.바둑판같이 잘 정리된 농경지이며 옹기종기 모여 있는 마을과 마을 동북에서 서남쪽으로 흘러내린 고산천의 물줄기가 푸른 농경지 사이로 아름답게 내려다보인다.", - "MNTN_HG_VL" : "372", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주 봉동읍, 비봉면", - "MNTN_NM" : "봉실산" + "DETAIL_INFO_DTCONT" : "박달산은 괴산군 감물면과 장연면의 경계에 자리하는 해발 825미터의 산이다. 대미산~포암산을 이어 서쪽으로 달려오던 백두대간의 주능선이 마패봉(922m)에서 직각으로 방향을 꺾어 정남쪽의 조령산을 향한다. 서쪽으로 계속 뻗어나간 산줄기는 보다 높은 신선봉(967m)을 솟구치고 괴산군에 이르러 박달산과 주월산(506m), 성불산(532m)을 일으킨 후 달천으로 내려든다. 박달산 동녘자락 장연면에는 송덕리와 추점리의 미선나무 군락지가, 오가리에는 느티나무 등 소중한 천연기념물도 품고있다.또 박달산은 독립된 봉우리로 어디에서 보나 그 덩치가 심상치 않다. 육산으로 산 안으로 들어가보면 아직 사람의 손길이 닿지 않아 원시림을 연상케 할 정도로 우거져 있는 곳이 많다.산불감시용 카메라가 설치된 철탑이 하늘을 찌를 듯 서 있는 정상에는 2002년에 세운 정상석과 1982년 복구한 삼각점이 있다. 그러나 무엇보다 이색적인 것은 정상석 옆에 자리한 ‘대한민국 국기게양대’다. 단기 4330년 음력 7월 6일(서기 1997년 8월 8일) 한국고대사연구회에서 세운 게양대와 빗돌은 박달산의 명물이 아닐 수 없다.", + "MNTN_HG_VL" : "825", + "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 감물면ㆍ장연면", + "MNTN_NM" : "박달산" }, - "longitude" : 127.15235730000001, - "latitude" : 35.972536599999998 + "longitude" : 127.923232, + "latitude" : 36.836640699999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "301", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 소양동", - "MNTN_NM" : "봉의산" + "MNTN_HG_VL" : "337", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 옥계면 천남리", + "MNTN_NM" : "밥봉" }, - "longitude" : 127.73355309999999, - "latitude" : 37.888648099999997 + "longitude" : 129.04410139999999, + "latitude" : 37.604346700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "368", - "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시", - "MNTN_NM" : "봉화봉" + "DETAIL_INFO_DTCONT" : "대구의 명산 팔공산 정상에서 서쪽으로 약 10킬로미터 떨어진 가산은 일명 칠봉산이라고도 불리며 칠곡군 내 최고봉으로 가산면 가산리에 있다. 7개의 봉이 7개의 골짜기를 이루어 칠곡(七谷)이라 한 것이 오늘의 칠곡(漆谷)이 되었다. 1640년(인조 18)에 가산성을 쌓고 칠곡도호부의 치소가 약 180년간 산성 내에 있었다.<>한국전쟁 때의 격전지로서 선조의 호국의지가 깃들어 있는 가산산성과 가산바위 등 명소가 많으며 울창한 수림, 계곡의 석간수는 한여름에도 서늘함을 느낄 만큼 시원하여 가족 단위의 등산객이 많이 찾고 있다.<>가산바위는 산성 서쪽에 있는 80여평의 넓은 바위로, 신라시대의 고승 도선(道詵, 827∼898년)이 산천을 편력하면서 가산바위에 쇠로 만든 소와 말의 형상을 묻어 지기를 눌렀다고 전한다. 용의 모습을 닮은 용바위, 신선이 노닐었다는 유선대는 가산 정상에 우뚝 솟아 있다.", + "MNTN_HG_VL" : "902", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 동명면", + "MNTN_NM" : "가산" }, - "longitude" : 129.09805560000001, - "latitude" : 36.146666699999997 + "longitude" : 128.58266399999999, + "latitude" : 36.037387899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주로 군진지와 훈련용으로 많이 쓰이고 있는 구간이다. 경사는 있지만 대부분 완만하므로 일반 등산화로도 충분히 등산이 가능하다. 정상까지 헬기장 두곳이 있으며, 그곳에 올라서면 내설악과 외설악이 한눈에 들어와 장관을 이루어 한폭의 그림을 연상케 한다.", - "MNTN_HG_VL" : "590", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면 원통리", - "MNTN_NM" : "봉화봉" + "DETAIL_INFO_DTCONT" : "산이라고 하기에는 염치가 없을 정도로 나즈막한 높이의 대모산은 서울시 강남구에 위치해 있다. 예전에는 국수봉이라고도 불리웠는데 언제부터 대모산으로 부르게 되었는지 확실치 않다.서울 변두리에 위치해 있어 잊혀지다시피한 산이었으나 인근에 아파트가 들어선 후로는 시민들의 휴식처로서의 역할을 톡톡히 하고 있다. 이른 아침 가벼운 산책을 하려는 시민들의 발길이 끊이지 않고 주말이면 많은 사람들이 이곳에 나와 도심의 찌든 때를 씻는다.이 산의 남쪽 기슭에는 헌인릉이 있어 둘러볼 만한데 헌인릉이란 조선 3대 태종과 그 왕비의 능침인 헌릉과 제23대 순조와 그 왕비의 능침인 인릉을 합쳐서 부르는 이름이다.", + "MNTN_HG_VL" : "293", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강남구", + "MNTN_NM" : "대모산" }, - "longitude" : 128.22194440000001, - "latitude" : 38.138055600000001 + "longitude" : 127.0783333, + "latitude" : 37.475000000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "476", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "남면 홍현마을에 있는 설흘산(488m)은 망산(406m)과 인접해 있다. 설흘산에서 내려다보면 깊숙하게 들어온 앵강만이 한눈에 들어오고 서포 김만중의 유배지인 노도가 아늑하게 내려다보인다. 인접하고 있는 전남 해안지역 뿐만 아니라 한려수도의 아기자기한 작은 섬들도 조망할 수 있는 곳이다.설흘산 정상 부근에는 봉수대의 흔적이 남아 있다. 원래 봉수대는 주위를 넓게 관측할 수 있는 곳에 정하는데 설흘산 역시 한려수도와 앵강만 그리고 망망한 남쪽 대해를 관측할 수 있는 곳이다.남면 구미 지역과 응봉산으로 오르는 등산로는 망망대해와 기암괴석 그리고 아래로 내려다보이는 다랭이마을의 풍경을 제대로 즐길 수 있다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경남 남해군 남면", + "MNTN_NM" : "설흘산" }, - "longitude" : 127.6119444, - "latitude" : 34.652500000000003 + "longitude" : 127.8987633, + "latitude" : 34.737474499999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "외지인들에게 구곡폭포로 더 잘 알려진 봉화산은 북한강에 둘러싸인 강원도 춘천시 남산면에 위치해 있다. 조선시대에 피웠던 봉수대가 정상에 있어 봉화산이라고 부른다.산의 규모면에서는 작으나 입구의 경관 및 편의시설이 좋아 주말 가족 야유회 장소로 더 없이 좋은 곳이다. 구곡폭포 일대에 수영장과 놀이터등 위락 시설이 있으며, 특히 강촌역 근방은 여름철이면 행락객 인파가 끊어지지 않고 모여든다. 통상 봉화산과 검봉을 한데 묶어 산행하는 경우가 더 많다. 검봉과 봉화산은 능선으로 바로 옆에 이어져 있다.경춘선 열차를 타고 가다 보면 북한강을 끼고 스쳐가는 산들이 여간 정겨운 게 아니다. 전국적인 교통난으로 주말 나들이가 고생길인 요즘, 연인끼리 또는 가족끼리 열차를 타고 다녀오는 산행은 한결 여유가 있어 좋다.특히 강과 더불어 빼어난 경관을 자랑하는 경춘선 부근의 산들은 그리 높지도 않아 당일 산행 코스로 적당하다. 경춘선을 즐겨 타는 이들에게 가장 인기있는 곳은 강촌이나 대성리 가평이다. 특히 강촌에는 해마다 겨울이면 신문과 TV에 단골로 나오는 폭포가 하나 있다. 얼음이 얼자마자 빙폭 등반을 하려는 산악인들이 줄을 서서 기다리는 곳, 바로 구곡폭포다. 그러나 정작 이 폭포를 품고 있는 봉화산은 사람들에게 그리 알려져 있지 않다. 강선사를 들머리로 하는 검봉과 더불어 봉화산 산행의 묘미는 능선길에 올라 굽어보는 북한강에 있다.구곡폭포는 아홉 굽이의 협곡을 돌아돌아 들어간다고 해서 붙여진 이름이라고도 하고 또, 옛날에 어떤 도사가 이곳에 오다가 아홉 개의 고개를 넘어 도착한 곳에 폭포가 있었다고 해서 붙여진 이름이라고도 한다. 최근에는 봉화산 진입로까지 자전거 도로가 개발되어 하이킹 코스로도 좋다.", - "MNTN_HG_VL" : "329", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "봉우리가 7개인 데서 칠봉산이라 유래되었다. 동쪽으로 임천고개를 넘어 선바위산과 운암산으로 이어지고, 서쪽에 십리산, 남쪽에 평안산, 북쪽에는 백운산이 있다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 대학리", + "MNTN_NM" : "칠봉산" }, - "longitude" : 127.6084018, - "latitude" : 37.7829087 + "longitude" : 127.0130546, + "latitude" : 36.3687921 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉화산이란 이름에서 알수 있듯 이산은 연기나 불을 피워 통신을 하던 봉화대가 있는 산으로 사방이 트인 전망이 일품이다.장수군 천천면과 계남면을 가르고 있는 봉화산 정상에 서면 북동쪽으로 파도처럼 일렁이는 덕유산 능선이 보이고 12대 종산중의 하나인 장안산이 시야에 들어온다. 봉화산 산행의 맛을 음미하자면 정북 방향의 능선을 타고 방아재쪽으로 올라야 한다. 다른 봉우리에 비해 방아재는 여러 골짜기 물을 받아 흘러가는 천천의 물줄기를 한눈에 바라볼 수 있기 때문이다.평범하기 이를 데 없는 이 봉화산에 최근 남원을 기점으로 등산인들의 발길이 잦아지고 있다. 그 이유는 몰론 철쭉 군락이 발견되었기 때문이다. 철쭉 군락이 산사면 곳곳에 널려 있는 데다가 장수와 함양 땅으로 뻗은 암릉길이 온통 철쭉꽃길이다.", - "MNTN_HG_VL" : "338", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 천천면, 계남면", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "해발 164미터의 남망산은 접도의 주산(主山)으로 산 자uuml;가 접도라 해도 과언이 아니다. 접도는 진도군 동남쪽에 위치한 아주 작은 섬으로 예부터 접섬, 금갑도, 갑도, 접배도 등으로 불리던 유배지였다. 지금은 진도와 접도를 잇는 연육교가 있어 접근이 수월하다. 남망산(南望山)은 산을 이루는 기암들이 모두 남쪽바다를 바라보고 있어서 붙은 이름이다. 높이는 낮지만 ª게는 1시간, 길게는 총 12킬로미터의 5시간yen;리 코스 등 다양하게 등산로가 조성되어 일정에 맞는 산행코스를 선택할 수 있는 것이 장점이다. 또 이정표 설치 및 등산로 정비가 잘 되어있어 길atilde;기의 어려움이 없으며 흙길도 걷고 바닷길도 걷는 이색산행을 즐길 수 있다. 솔섬에서 작은여미로 이어지는 길에는 몽돌해변에 맨발uuml;험 등산로가 조성되어 있으며 쥐바위에서 거북바위 구간에는 웰빙등산로가 만들어져 가족 산행지로도 제격이다. 가뭄에는 전 구간에 물이 없으므로 사전에 식수를 준비해야 한다.", + "MNTN_HG_VL" : "164", + "MNTN_LOCPLC_REGION_NM" : "전남 진도군 의신면", + "MNTN_NM" : "남망산" }, - "longitude" : 127.5485212, - "latitude" : 35.701548299999999 + "longitude" : 126.29203390000001, + "latitude" : 34.381267399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "487", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "마대산은 우리나라의 마지막 비경지대를 간직한 산으로 강원도 영월군 하동면과 충북 단양군 영춘면의 경계를 이루고 있다. 마대산 서쪽 아래로는 고씨동굴 앞을 흐르는 남한강의 수려한 풍광과 북으로 흐르는 옥동천이 남한강으로 합수되어 보기드문 비경을 연출한다.이 산이 특히 유명해 진 것은 조선의 방랑시인이자 풍자시인인 김병연 속칭 김삿삿이 숨어 살던 터에 복원한 집과 무덤 등 유적이 있기 때문이다. 한 여름이면 자연과 위대한 시선의 흔적을 밟으려는 외지인들로 붐빈다", + "MNTN_HG_VL" : "1052", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 충청북도 단양군 영춘면", + "MNTN_NM" : "마대산" }, - "longitude" : 127.8758333, - "latitude" : 37.708888899999998 + "longitude" : 128.573329, + "latitude" : 37.087678099999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "355", - "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 용당동,조례동", - "MNTN_NM" : "봉화산" + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 수성구 범물동", + "MNTN_NM" : "용지봉" }, - "longitude" : 127.5166667, - "latitude" : 34.966666699999998 + "longitude" : 128.64972220000001, + "latitude" : 35.803333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부용산(882m)에서 남쪽으로 능선이 뻗어 있는데, 이 능선상에서 가장 높은 봉우리이다. 부용산 외에 오봉산(779m)과도 능선이 이어져 있어, 종주 등반도 가능하다. 산의 북쪽을 제외하고는 소양호로 둘러싸여 있어, 정상에서의 조망이 시원하고 아름답다.청평사 선착장에서 서쪽길은 청평사로 이어지고 동쪽길 따라 작은 고개를 넘어가면 청평골 입구에 농막집이 있다. 농막에서 계곡 왼쪽 길을 따라 올라가서 계곡이 갈라지기 직전에 왼쪽길 따라 들어가면 동굴이 있는 기도터에 닿게 된다. 계곡을 건너서는 조금 가파른 길을 거쳐 하우고개에 이르게 된다. 하우고개 십자로에서 남쪽 길로 들어가면 봉화산에 오르게 되는데 이 길은 사람이 별로 다니지 않는 완만한 능선에 억새와 칡넝쿨이 무성하여 길바닥이 보이지 않는 상태이다.", - "MNTN_HG_VL" : "734", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "낙안읍성 북쪽에 솟은 금전산은 낙안의 진산이다. 옛 이름은 쇠산이었으나 백여년 전에 금전산으로 바뀌게 되었으며 한자 뜻풀이로 보면 금(金)으로 된 돈(錢) 산이 된다. 그러나 금강암 스님의 말에 의하면 금전산은 불가에서 유래한 이름으로 부처의 뛰어난 제자들인 오백비구(오백나한) 중 금전비구에서 산 이름을 따왔다고 한다. 또한 풍수지리를 공부하는 사람들은 금전산의 산세를 이렇게 해석하기도 한다.금전산 북동쪽에는 옥녀봉이 있고 동남쪽 줄기에는 오봉산과 제석산이 있다. 서남쪽에는 백이산이 있는데 전체적으로 놓고 볼 때 이것은 옥녀산발형이라 말할 수 있다. 풀어 말한다면 옥녀가 장군에게 투구와 떡을 드리려고 화장을 하기 위해 거울 앞에서 머리를 풀어헤친 형상이라고 한다. 이러한 말을 뒷받침하듯 낙안읍성 남쪽에 있는 평촌리 평촌못은 옥녀의 거울에 해당하는 조건을 완벽하게 갖춘 못이기 때문에 예부터 낙안에는 미인들이 여느 지역보다 유난히 많이 났다고 한다.금전산 산행 초입에 높이가 10여미터 되는 형제바위가 있는데 원래는 두 개가 사이좋게 서 있었다고 한다. 그런데 80년대 초반 동생바위가 허물어져 형님바위만 남았다고 한다. 들어갈 때는 금강문이고 나갈 때는 해탈문이라는 바위굴을 나서면 금강암에 오른다. 금강암은 백제 위덕왕 때 창건되었다고 한다. 금강암을 지나면 의상대라 불리는 바위에 올라설 수 있다.", + "MNTN_HG_VL" : "668", + "MNTN_LOCPLC_REGION_NM" : "전남 순천시 낙안면", + "MNTN_NM" : "금전산" }, - "longitude" : 127.8413889, - "latitude" : 37.967222199999988 + "longitude" : 127.3497222, + "latitude" : 34.924722199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "476", - "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", - "MNTN_NM" : "봉화산" + "DETAIL_INFO_DTCONT" : "보래봉은 강원도 평창군 봉평면 북쪽의 한 봉우리이다.\"\"메밀 꽃 필무렵\"\"의 이효석이 태어난 곳이고 이 소설의 무대가 바로 봉평면과 대화면이다. 진입로에 가로수가 없고 메밀을 심는다. 메밀꽃이 피는 여름에는 특히 물이 맑다.평창군은 해발 300-800미터 이상의 고랭지대로 이루어져 있는데 봉평면은 해발 600-800m의 고냉지대이다.이러한 봉평면 일원은 지대가 높고 추운 곳이어서 적설량이 풍부해 특히 겨울철산행을 즐기기에 좋은 산이다.부근에는 이효석의 동상과 소설에 관련된 곳들을 찾아볼 수 있다.", + "MNTN_HG_VL" : "1324", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면", + "MNTN_NM" : "보래봉" }, - "longitude" : 127.1086111, - "latitude" : 34.732777800000001 + "longitude" : 128.3663889, + "latitude" : 37.686111099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "예부터 흥양골에 군자가 많이 나서 봉황새가 날아와 보금자리를 잡았다 하여 봉황산이라 부르며선인들은 봉황을 군자의 새라 하였다. 일제 말기에 송탄유를 만들기 위해 많은 충송을 베어내어지금은 얼마 남지않았다.산세가 완만하고 코스가 적당(50분)하며 고흥읍 유민의 아침, 저녁 주 산책로이며 정상에서고흥 시가지가 한 눈에 보이며,숲의 주요 수종은 수령 50~60년생의 소나무로 천연보육림 상태로 숲이 잘 발달 되어 있다.", - "MNTN_HG_VL" : "199", - "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 고흥읍 남계리", - "MNTN_NM" : "봉황산" + "DETAIL_INFO_DTCONT" : "둔철산은 황매산에서 흘러내린 능선이 정수산을 거쳐 경호강에 산자락을 내리면서 우뚝 솟아있는 산이다. 산청읍과 신안면, 신등면 사이에 있으면서 웅석봉과 마주하며 철을 생산했다는 전설을 갖고 있다. 그러나 둔철(屯鐵)이라는 지명은 생산보다는 보관했다는 말에 더욱 설득력이 있다.산 동쪽 해발 500미터에는 넓은 분지가 조성되어 있어 대단위 목장과 농장으로 활용하고 있다. 서쪽으로는 산청시내가 내려다보이고 경호강을 사이에 두고 왕산 및 칠봉산과 웅석봉이 병풍처럼 펼쳐져 있다.동쪽은 사정천이 흐르며 북쪽은 철쭉으로 유명한 황매산과 수려한 암군으로 각광받고 있는 모산재가 둘러싸고 있는 산이다. 정상에 서면 사방 막힘이 없고 지리산에서 가지내린 수많은 산군을 조망할 수 있어 가슴이 후련하다.범학에서 계곡을 따라 오르면 와폭과 깨끗한 담과 소가 오염되지 않아 좋다. 그러나 길이 희미해서 한여름이면 오르기 힘들다. 척지에서 오를 수 있고 정취암에서 능선을 타고 대성산~둔철산으로 갈 수 있으나 여름보다 겨울에 산행하는 것이 적당하다. 정취암은 의상대사가 창건했으며 문가학이라는 도인이 여우로부터 둔갑술을 배웠다고 전해온다.", + "MNTN_HG_VL" : "812", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 산청읍 척지리", + "MNTN_NM" : "둔철산" }, - "longitude" : 127.2850741, - "latitude" : 34.603868599999998 + "longitude" : 127.9456586, + "latitude" : 35.387092799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉황산(鳳凰山)은 중화지구 화령(化寧) 북쪽에 우뚝 솟아있는 대간상의 산이다. 1300여년 전 봉황새가 이 산에 날아들어 30여년 정도 살았다는 전설에서 유래했다 한다.인근에서는 “정상을 봉황머리처럼 원만하게 빼어 올리고 좌우 양 날개를 길게 펼친 형국이 봉황새 같아서” 라고도 한다. 화령은 행정구역상 화서면이라 부르지만 지역 사람들에게는 화령으로 더 알려져 있다. 옛날 화령현 소재지였던 까닭이다. 그 당시 무사들이 살았다는 무동(武洞), 현감이 살았다는 상현(上縣), 관곡(官穀)을 보관했던 창고가 있었던 창안 등의 지명이 지금도 남아있다.", - "MNTN_HG_VL" : "741", - "MNTN_LOCPLC_REGION_NM" : "상주시 화서면 신봉리 상현리, 상곡리 화송리\/화남면 동관리", - "MNTN_NM" : "봉황산" + "DETAIL_INFO_DTCONT" : "기암괴봉과 깍아지른 바위벼랑이 한 폭의 동양화처럼 아름답고 능선이 반원형으로 가운데가 깊숙한 골을 이루며 암벽들이 산기슭을 감돌아 흐르는 금강줄기와 어울러져 경관을 자랑한다.또한 천태산, 서대산등 주변의 산 군을 바라볼 수 있는 조망이 좋은 산이다.", + "MNTN_HG_VL" : "585", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "갈기산" }, - "longitude" : 127.9403798, - "latitude" : 36.463463900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "봉황산은 경북 영주와 봉화군의 경계를 이루는 산이다. 산의 모양이 봉황을 닮았다고 해서 봉황산이라 불리는 이 산은 태백산(1567m)을 거친 백두대간이 소백산(1439m)으로 뻗어 내리다가 중간에 위치한 선달산에서 남쪽으로 가지친 지맥 선상에 자리하고 있다.사람들에게는 별로 알려지지 못한 산이지만 산자락에 자리잡은 부석사는 매우 유명하다. 부석사 무량수전은 한국에서 가장 오래된 목조건물이며, 국보 제18호로 지정되어 있다. 이 외에도 석탑, 석종 등 보물이 많고, 규모가 웅장해서 이 절을 찾는 관광객이 많다 부석사만 둘러보고 가는 관광객이 많아 한적한 산행을 즐길 수 있다. 특히 소백산 도립공원에 속해 있으면서도 주변의 영봉들에 가려 그 진가가 제대로 알려지지 않았지만 그만큼 사람들의 발길을 덜타 깨끗하고 아름다운 자연미를 그대로 간직하고 있다.부석사 무량수전 뒤편의 오솔길을 따라 능선에 오르면 정상까지 이를 수 있다. 정상까지의 길은 울창한 소나무 숲과 진달래가 군락을 이룬 숲길이 등산의 피곤함을 잊게 해준다.", - "MNTN_HG_VL" : "259", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 부석면, 봉화군 물야면", - "MNTN_NM" : "봉황산" + "longitude" : 127.6280556, + "latitude" : 36.116666700000003 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "운무산은 강원도 횡성군 청일면과 홍천군 서석면 경계에 있는, 규모는 작으나 아름다운 암봉을 갖춘 산이다. 횡성군에는 이렇다 할 산이 없을 것으로 생각되지만 그렇지 않다. 그것은 횡성군이 영동방면으로 가는 길목 이상의 역할을 하지 못했기 때문이다. 그래서 잘 알려지지 않은 아름다운 산이 적지 않다. 발교산, 덕고산, 봉복산, 운무산 등이 그런 산에 속한다. 그 중에서도 운무산은 독특한 암봉미와 아기자기한 능선을 갖추고 있어 아름답다.항상 구름과 안개가 낀 듯하다는 데서 이름이 유래한 운무산은 자연 그대로의 모습이 오롯이 남아 있는 멋스러운 산이다. 아지랑이 하롱하롱 밀려드는 봄날이 오면 야생 벚나무의 향연이 수채화 물감처럼 번져 오른다. 특히 사람의 측면 얼굴을 닮은 듯한 수리봉은 운무산 가운데 가장 전망이 뛰어난 곳으로, 이곳에 서면 운무산 전경과 청량1리의 삼근암과 새대기, 횡성의 산줄기들이 잘 조망된다.", + "MNTN_HG_VL" : "979", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", + "MNTN_NM" : "운무산" }, - "longitude" : 128.6937088, - "latitude" : 37.004579300000003 + "longitude" : 128.2016667, + "latitude" : 37.650277799999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "149", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", - "MNTN_NM" : "봉황산" + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉", + "MNTN_NM" : "석병산" }, - "longitude" : 126.6080556, - "latitude" : 36.376666700000001 + "longitude" : 128.89750000000001, + "latitude" : 37.586666699999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부귀산은 전북 진안군 부귀면과 진압읍을 가로지르며 금남정맥과 호남정맥의 마루금을 긋고 있다. 등산 코스 가운데 특별히 시선을 끌만한 장소는 없으나 수풀이 우거져 있어 한적한 분위기를 만끽할 수 있으며 전체적으로 무난한 등산로를 갖추고 있다.부귀산의 북쪽인 부귀면 대곡마을이나 손실골에서 오르면 육산, 진안읍 원정곡 마을에서 오르면 암봉으로 이루어진 산이고, 이 두 방향에서 산의 조망이 잘된다. 부귀면 대곡마을은 원래 한실골(韓室谷)인데 일본인들이 고쳤으며, 마을 뒷산인 부귀산은 사지앙천(蛇之仰天) 즉 뱀이 하늘을 우러러보는 형상인 명당이 있고, 가뭄이 들면 진안지역의 사람들이 모여서 기우제를 지내는 곳이며, 산삼을 캔 적이 있는 곳이고 한다. 결국 부귀의 이름이 말해주듯이 이 지역은 산수(山水)가 좋아 천하명당자리에 터를 잡은 부귀한 곳이라는 의미이라고 한다.대곡마을 주민들은 부귀산을 '배택산'이라고도 하는데, 말세가 되면 이산에 올라서 배를 타고 나가야 살수 있다고 하는 속설을 간직한 산이다.", - "MNTN_HG_VL" : "806", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍, 부귀면", - "MNTN_NM" : "부귀산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "276", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", + "MNTN_NM" : "송화산" }, - "longitude" : 127.3927778, - "latitude" : 35.809166699999999 + "longitude" : 129.19061189999999, + "latitude" : 35.851393700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;모유정 전설 깃든 은혜의 산gt;부모산은 청주시 비하동과 지동동에 걸쳐 있는 해발 232m의 작은 산이다. 주변 조망이 좋고, 리기다소나무, 상수리나무, 소나무 등으로 등산로가 잘 조성되어 있어 등산인들이 많이 찾는다. 본래 이산은 아양산, 악양산 등으로 불렸다. 임진왜란 때 박춘무가 복대에서 의병을 일으켜 청주성을 탈환하고 아양산 마저 탈환하여 그 곳에 머물고 있었다. 그러나 박춘무에게 패전했던 왜병이 아양산에는 물이 없다는 것을 알고 산 주위를 포위하고 보급로를 차단하자 굶어죽는 의병들이 속출하게 되었다. 때마침 의병장 박춘무의 꿈속에 지팡이를 짚은 백발 노인이 나타나 소나무를 가리키며 일어나라고 소리쳤다. 박춘무는 꿈에서 깨어나 군사들에게 소나무를 뽑게 했다. 그곳에서 식수는 물론 말에게 목욕을 시키고도 남을 만큼의 물이 솟아났다. 이것을 알게 된 왜병들이 물러났고, 이때부터 그 은혜가 부모와 같다하여 부모산이라 칭하게 되었으며, 이 우물을 모유정이라고 불렀다고 한다. 정상에는 충북기념물 제121호로 지정된 청주 부모산성(淸州父母山城)과 연화사(蓮花寺)가 있다.", - "MNTN_HG_VL" : "232", - "MNTN_LOCPLC_REGION_NM" : "", - "MNTN_NM" : "부모산" + "DETAIL_INFO_DTCONT" : "충북 옥천군에 자리한 장용산은 정상 봉우리의 모양새가 멀리서도 눈에 띨 만큼 이채롭다. 기암괴봉들이 엉켜 절경을 연출하고 있어 산을 찾는 사람들에게 기쁨을 준다.장룡산 마성산 사이의 고개를 사목재라고 하는데 장룡산에서 사목재쪽의 암릉은 왕관바위 등 기암괴봉이 이어진다. 이 암릉 동쪽(옥천쪽)비탈에는 절 용암사가 있으며 서쪽 사면은 포옹바위, 병풍바위 등 기암괴봉과 암벽으로 이루어져 있다. 이 경관 좋은 서쪽 비탈 아래 옥천군에서 조성한 장룡산휴양림 시설의 하나로 장룡산 중봉 아래 정자까지 지어 놓았다.용암사는 서기 552년 신라 진흥왕 13년에 의신조사가 속리산에 법주사를 창건하기 전에 이곳의 산세를 보고 신비로움에 감탄한 나머지 절을 세웠다고 한다. 이 절 왼편 언덕에는 충청북도 유형문화재 제3호인 쌍석탑이 있고 절 뒤에는 역시 충청북도 유형문화재 제8호인 여래입상을 양각한 마애불이 있다.", + "MNTN_HG_VL" : "656", + "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 군서면 금산리", + "MNTN_NM" : "장용산" }, - "longitude" : 127.410287, - "latitude" : 36.634100400000001 + "longitude" : 127.5663661, + "latitude" : 36.242428199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "232", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청주시 흥덕구 비하동, 지동동", - "MNTN_NM" : "부모산" + "DETAIL_INFO_DTCONT" : "충북 괴산군에 위치한 보배산은 사람들의 발길이 닿지 않는 산으로 자연의 청정함이 그대로 살아 있다. 특히 쌍곡계곡은 소금강이라 불릴 만큼 경치가 아름다워 한폭의 동양화를 연상케 한다. 계곡을 따라 군데군데 펼쳐지는 바위와 암릉의 조화, 그 위를 흐르는 맑은 물, 단풍이라도 든다면 그야말로 가을의 운치가 물씬 묻어나는 곳이다.보배산 청석골 골짜기에는 충청북도에서 가장 오래된 사찰 각연사가 있다. 각연사는 신라 법흥왕(514~539) 때 유일대사가 창건했다. 경내에는 석조비로자나불좌상(보물 제433호), 통일대사탑비(유형문화재 제2호), 비로전(유형문화재 제123호), 대웅전(유형문화재 제126호), 그리고 대웅전 앞마당을 뒤덮은 밑둥 둘레가 두 아름이 넘는 보리수나무 등 볼거리가 많다.", + "MNTN_HG_VL" : "772", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면 태성리", + "MNTN_NM" : "보배산" }, - "longitude" : 127.410287, - "latitude" : 36.634100400000001 + "longitude" : 127.91666669999999, + "latitude" : 36.75 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부암산(傅岩山)은 스승 부(傅)자를 쓰며 일명 스승바위산이라고도 하는데 사실 부암산 자락은 너무 많은 역사를 간직한 산이다. 악(岳, 嶽)이나 암(岩)자가 들어가는 산은 거의 바위산인데 이 곳 역시 예외는 아니다. 부암산은 멀리서 쳐다보아도 암반 투성이고 정상에서 주위를 둘러보아도 역시나 북쪽 산들은 모두 바위산이다. 거대한 바위들이 누룩이 포개져 있는 것처럼 층층이 포개져 있다.한적한 마을 뒤에 있으면서도 그 산세가 빼어나다. 가까이 있으면서 소문이 자자한 황매산과 모산재에 조금도 뒤지지 않는 멋진 산이다. 산길로 들어서면 우람한 낙락장송이 산을 채우며 잔가지가 많은 소나무들이 마치 담 하나를 사이에 둔 이웃처럼 함께 어울려 골짜기를 메웠다. 특히 단계천 가운데 자리잡고 있는 기암이라는 바위는 그 풍채가 당당하면서도 멋스럽다. 바위에는 많은 구멍이 뚫려있는데 옛날에 일산을 꽂았던 자리이다. 단계현 시절에 놀이가 있을 때에 이곳에서 풍악을 울리고 기생을 불러서 놀이를 하던 곳으로 전한다.", - "MNTN_HG_VL" : "696", - "MNTN_LOCPLC_REGION_NM" : "경남 합천군 가회면, 산청군 차황면ㆍ산등면", - "MNTN_NM" : "부암산" + "DETAIL_INFO_DTCONT" : "높이 755m의 화야산은 북한강이 북에서 서쪽으로 감싸고 흘러내리는 가운데 위치해 있다. 산위에서의 전망이 좋고 강물을 내려다보며 산을 오르는 이색적인 기분을 맛 볼 수 있다. 화야산은 가평군 외서면과 양평군 서정면에 걸쳐 있는 해발755m의 산으로 북한강이 산 북쪽으로 청평호를 이루면서 감싸고 돌아 남쪽으로 행해 나란히 흘러나가는 가운데 있으므로 산행중에 내려다 보이는 경치가 아름답다.청평에서 멀지않은곳에 있으므로 접근이 용이하고 정상 북쪽끝에 위치한 뾰루봉(709m)과 서쪽능선위에 일구어진 고동산(600m)이 모두 화야산에 딸린 봉우리라 할수 있다. 동서로 갈라져 내려간 능선에는 수림이 울창하고 계곡이깊어서 어느때 찾아도 만족한 산행을 할수 있다. 산행에 있어서 어느코스를 택하건 4시간 이상 소요되므로 만만히 보아서는 않된다.또 겨울철에는 적설량이 많아 겨울산행의 맛을 제 대로 느껴 볼수 있는 산이기도 하다. 북쪽의 청평 호반과 서쪽 큰골 또한 대성리 유원지와 함께 여름철 피서지로서 유명하다. 주능성에 올라서면 강물을 끼고 산행하는 기분이 좋다.", + "MNTN_HG_VL" : "755", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 외서면", + "MNTN_NM" : "화야산" }, - "longitude" : 127.9902359, - "latitude" : 35.457224099999998 + "longitude" : 127.4279782, + "latitude" : 37.671530099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전남 장흥군 용산면 운주리를 부채모양으로 싸감고 있는 부용산은 동학운동의 최후 격적지로 봄이 되면 진달래 철쭉 등이 화사한 꽃빛으로 불태우는데 아직 등산로가 제대로 나 있지 않아 찾는 이가 드문 산이다. 또한 부채모양을 이루고 있기 때문에 다양한 원점회귀 산행이 가능하다.전란의 시달림에서 안전한 보호막이 돼 주었던 부용산의 덕성은 임진왜란까지 거슬러 오른다. 당시 이맹(李孟)이란 장수가 골목 어귀에 서 있다가 들어오는 왜적을 모조리 쏘아 죽여서 피란민들의 안전을 지켜주었던 곳이 있는데 이곳이 바로 지금의 장구목재다. 부용산은 부처가 솟은 산이라는 `불용산(佛聳山)', 산삼 등 약초가 많다고 해서 `약다산(藥多山), 돌이 많아 '석다산(石多山)등으로 불린다.곳곳에 튀어나온 바위에서 바라보는 도암만과 다도해 전경이 시원하며 바다에서 솟아오른 듯한 천관산을 바로 눈앞에서 감상할 수 있다.", - "MNTN_HG_VL" : "609", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍 성산리", - "MNTN_NM" : "부용산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "769", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "황학산" }, - "longitude" : 126.8758333, - "latitude" : 34.593333299999998 + "longitude" : 128.87916670000001, + "latitude" : 36.375833299999996 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "882", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "부용산" + "DETAIL_INFO_DTCONT" : "정선의 지억산은 민둥산에 가려진 산이다. 민둥산이 가을 억새로 워낙 유명하다 보니 지척의 지억산은 민둥산 산행 중 지나치는 산 정도로 알려져 있다. 산 족보로 따지면 지억산은 백두대간 금대봉에서 뻗어 나온 산줄기다. 이 산줄기를 산꾼들은 소위 ‘정선지맥’이라 부르며 지맥 주능선상에 지억산이 있다. 민둥산은 지억산에서 갈래 쳐진 산이니 지억산이 모산이다.지억산에서 민둥산은 2.6킬로미터 거리로, 1시간 10분 정도 밖에 걸리지 않아 당일 코스로 연결해도 무리가 없다. 높이는 거의 비슷한 편이며 민둥산이 1117.8미터로 1.1미터 높다. 그러나 지억산 정상에는 억새지대가 없으며 등산인들의 발길도 뜸한 편이다. 정상에는 철망에 둘러쳐진 태양열 전지가 있으며 표지석에는 ‘몰운산’이라 적혀있다. 인근 몰운대와 몰운리라는 지명에서 온 산 이름인 듯하다. 국토지리정보원 지형도를 보면 유명한 민둥산조차 이름이 없지만 지억산만큼은 선명히 표기되어 있다. 지억산의 한문 표기를 해석해 보면 영지와 같은 평평한 버섯으로 추정되는데 산행길 역시 평탄하고 정상부의 모양새도 봉긋하다.", + "MNTN_HG_VL" : "1117", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면ㆍ남면", + "MNTN_NM" : "지억산" }, - "longitude" : 127.82734619999999, - "latitude" : 38.000608399999997 + "longitude" : 128.78374719999999, + "latitude" : 37.290074300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부흥산이란 이름은 나매기(나뫼기,난뫼기)로부터 범산까지 크게 부흥할 것이라하여 부흥산이라했다 한다.", - "MNTN_HG_VL" : "73", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 옥암동", - "MNTN_NM" : "부흥산" + "DETAIL_INFO_DTCONT" : "계룡산은 백두대간에서 갈라져나온 금남정맥의 한 줄기를 이루는 산으로, 충남 공주시와 논산시의 경계를 이루고 있다. 산세가 마치 닭의 벼슬을 쓴 용의 형상을 했다고 해서 계룡산으로 불리게 되었다고 한다.계룡산은 조선조 초기에 씌어진 예언서인 〈정감록〉의 `왕도입지설'로 유명한 산으로,정상인 천황봉(天皇峰)을 중심으로 쌀개봉(830.6m), 관음봉(765.8m), 문필봉(735.6m), 삼불봉(777.1m), 연천봉(742.9m)이 주능선에 줄지어 솟아 있다. 계룡산 산자락 곳곳에 문화 유적이 산재해 있는데, 동북쪽에는 동학사가,서북쪽에는 갑사가,서남쪽에는 신원사 사찰이 자리잡고 있다. 특히 갑사에는 보물 제257호인 부도(浮屠)와 보물 제256호인 철당간 및 지주.보물 제478호인 동종(銅鐘)등의 문화재가 있으며, 〈월인석보〉를 찍어낸 목판도 소장되어 있다. 〈월인석보〉는 세종29년(1447년)에 간행된 〈석보상절〉과 세종 31년에 간행된 〈월인천강지곡〉을 합편하여, 세조가 1459년에 간행한 것이다.상봉을 중심으로 동쪽에 동학사, 서쪽에 갑사, 남쪽에 신원사가 자리하여 현재까지도 보존되고 북쪽의 구룡사는 절터만 남아 있다. 계룡사에는 노루, 담비, 청설모, 황매화 등 희귀 동.식물 1227종이 서식하고 있으며, 계룡 8경으로 꼽히는 천황봉(일출), 삼불봉(설화), 연천봉(낙조), 관음봉(한운), 동학계곡(신록), 은선폭포(운무), 갑사계곡(단풍), 남매탑(명월) 등은 울창한 숲과 기암절벽을 더불어 장관을 이루고 있다.", + "MNTN_HG_VL" : "847", + "MNTN_LOCPLC_REGION_NM" : "대전광역시, 충청남도 공주시 계룡면ㆍ논산시 상월면ㆍ계룡시 신도안면", + "MNTN_NM" : "계룡산" }, - "longitude" : 126.4427778, - "latitude" : 34.806111100000003 + "longitude" : 127.20583329999999, + "latitude" : 36.342500000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "북배산은 고향집 바로 뒤에 솟아 있는 산처럼 향수를 자아내게 하는 산으로 크게 빼어나지도 웅장하지도 않지만 수수한 매무새의 시골 아낙 같은 자태를 하고 있다. 가덕산(858m)과 계관산(710m)으로 이어지는 능선에 위치하며 청정지역에 있는 산답게 깨끗하고 고즈넉한 산이다. 주능선은 산불을 대비해 폭 10미터 정도에 방화선이 형성되어 있으며, 이 방화산으로 능선 모두가 시원스레 조망되며 특히 눈 내린 후 가덕산에서 계관산까지 이어지는 경치는 이색적인 분위기를 느끼게 해준다.북배산은 수도권 등산인들에게 혼잡함을 피할 수 있는 당일치기 코스로 제격이다. 북배산 코스는 대개 목동2리 맴내~작은멱골을 경유하거나 또는 싸리재(마을)~싸리재고개를 경유해 정상을 다녀오는 것이다.정상에서 바라보는 조망은 막힘이 없다. 먼저 북서쪽으로는 북배산의 모산인 화악산이 하늘금을 이루고, 그 오른쪽으로는 북배산을 향해 세차게 흘러나오는 응봉, 촛대봉, 몽덕산, 가덕산 줄기가 연이어져 시야에 들어온다.동쪽으로는 병풍을 두른 듯한 대룡산 아래로 평화로운 춘천시내와 의암호가 펼쳐진다. 춘천남쪽으로 펼쳐지는 조망도 일품이다. 가장 멀리로 용문산이 하늘금을 이루고 그 아래 좌우로는 도명산, 대명스키장 슬로프, 장락산, 소리산 등이 넘실대는 파도처럼 광활하게 시야에 들어온다. 서쪽으로는 구나무산, 명지산, 월출산, 수덕산이 마주보이고, 구나무산 왼쪽 아래로 자리한 가평읍과 북한강이, 수덕산 아래로는 목동분지가 내려다보인다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", - "MNTN_NM" : "북배산" + "DETAIL_INFO_DTCONT" : "1983년 11월 23일 군립공원으로 지정된 웅석봉은 지리산에서 흘러온 산이면서도 지리산을 가장 잘 볼 수 있는 산이다. 천왕봉에서 시작된 산줄기가 중봉과 하봉으로 이어져 쑥밭재∼새재∼외고개∼왕등재∼깃대봉을 거쳐 밤머리재에 이르러 다시 한 번 치솟는데 이 산이 웅석봉이다.경남 산청의 웅석봉은 이름 그대로 ‘곰바위산’ 으로 불린다. 정상부에서 놀던 곰이 가파른 북사면으로 떨어져 죽었다는 전설에서 유래된 지명이다. 실제로 웅석봉 정상에서 보면 북쪽에 깎아지른 낭떠러지가 있어 곰이 떨어져 죽었다는 이야기가 설득력 있게 들린다.산세가 웅장한 만큼 수려한 계곡도 많다. 정상을 중심으로 뻗어 내린 곰골과 어천계곡, 청계계곡, 딱바실골 외에도 남릉에서 발원하는 백운동과 실골 같은 골짜기는 경관이 뛰어나고 물이 맑기로 유명하다.웅석봉 산행은 산청읍에서 접근해 지곡사쪽에서 오르는 것이 일반적이었다. 하지만 산청읍과 시천면을 잇는 59번 국도가 포장되면서부터 변화가 생기기 시작했다. 산청읍 쪽에서 접근할 경우 1000미터 고도차의 가파른 산길을 치고 올라야 하기 때문에 힘들 수밖에 없다. 하지만 해발 570미터의 밤머리재에서 산행을 시작하면 운치있는 능선길을 따라 쉽게 정상에 오를 수 있다. 능선에서 보는 천왕봉 동쪽 사면의 조망도 뛰어나 인기 있다.", + "MNTN_HG_VL" : "1099", + "MNTN_LOCPLC_REGION_NM" : "경남 산청군 단성면", + "MNTN_NM" : "웅석봉" }, - "longitude" : 127.6136111, - "latitude" : 37.920000000000002 + "longitude" : 127.8772768, + "latitude" : 35.364010999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "동부면 망골과 망치고개를 경계로 하여, 신현읍 삼거리에 주맥을 내려 뻗어 문동과 아주골 옥녀봉 줄기와 연결되어 있다. 망치고개에 고려시대에 축성했다는 성지가 산중간에서 마을까지 길게 뻗어 있다. 문동계곡 상류에는 문동폭포가 있고, 삼거리에는 신라시대에 있었다는 은적사 절터가 있다.장승포, 일운, 동부에서 고현으로 다니던 세갈래 길이 협곡에 있는 삼거리 마을은 교통의 중심지였다. 문동폭포가 있는 북병산은 그 높이가 465.4m로 고현을 병풍친 듯 둘렀다고 북병산이라 하며 북쪽을 막아 평풍을 두른 듯 하다고 북병산이라고 한다.북병산 고개를 넘어 동부 일운 거제 고현 등지로 통하는 세 갈래 길이 있어 삼거리로 통한다. 이 산에는 옛 신라시대 엄적사와 법률사란 큰절이 있었다고 하나 현재는 주춧돌만이 남아 있어 당시의 역사를 말해 주고 있다. 법률사는 그 경내가 방대하여 아주리까지 뻗어 있었다고 하며 그 절의 삼층 석탑비가 지금도 대우조선소 내에 남아 있다. 북병산 계곡에서 흐르는 물이 문동 폭포수가 되어 문동 저수지를 형성하여 그 모습이 장관이다.", - "MNTN_HG_VL" : "465", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거제", - "MNTN_NM" : "북병산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1134", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", + "MNTN_NM" : "삿갓봉" }, - "longitude" : 128.65655140000001, - "latitude" : 34.823366700000001 + "longitude" : 127.6388889, + "latitude" : 35.7858333 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "북악산은 서울의 주산으로 경복궁 뒤쪽에 위치하고 남산과 대칭하여 북쪽에 있다하여 북악이며 일명 백악, 면악, 공극산으로도 불리고 있다.북악산길이 시작되는acirc;의문 일대의 부암동은 서울에서는 보기 드문 산촌 같은 마을이다. 백석동otilde;으로 이어지는 산길, 백사실계곡 등 때 묻지 않은 자연을 그대로 간직하고 있다. 곳곳에 문화유적과 미술관, 독특한 인테리어의 음식점 등 볼거리도 널려 있어 출사지로 꼭 한 번씩은atilde;는 명소다.부암동에서 출발하는 북악산 산aring;길은acirc;의문에서 시작해 산 뒤를 휘감아 도는 북악 스카이웨이를 따라 성북구 정릉까지 6.2km 이어진다. 지금은 등산로가 나 있지만 조선시대에는 도성을 지키는 순라꾼들이 오르내리던 길이었고 일반인에게 개방되기 전까지만 해도ucirc;와대를 경비하는 군인들만 오르내리던 길이었다. 산aring;길을 쉬엄쉬엄 걷다 보면 한쪽에는 북한산 보현봉 자락이, 가을이면 한쪽으로 노을oacute;럼#376;오르는 북악산 단풍의 모습이 일품이다.서울에 남은 유일한 생태축인 서울 성곽은 옛 한양의 문화와 역사를 느낄 수 있는 공간이다. 인왕산 성곽길에 이어 2007년 북악산 숙정문~acirc;의문 구간이 개방되면서 서울 성곽 전uuml;를 연결해서 걸을 수 있게 되었다. 18.2km의 성곽길 중에서도 북악산 능선을 따라 이어지는 성벽 길이 인기 코스다. 오랫동안 통행이 금지되어서 성곽의 모습이 잘 보존되어 있고 전망도 빼어나다.", - "MNTN_HG_VL" : "342", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 종로구 부암동", - "MNTN_NM" : "북악산" + "DETAIL_INFO_DTCONT" : "쉰움산은 삼ocirc;시 동쪽으로 15킬로미터 떨어진 두#376;산의 북동쪽 상에 솟은 작은 봉우리다. 명산이라 함은 대개 산정의 풍치와 계곡의 아름다움, 그리고 산기슭의 명찰까지도 거론하는데 쉰움산은 이 세 조건을 모두, 그것도 최상급으로 갖췄다.그럼에도 두#376;·ucirc;옥산 사이의 무릉계곡 경관이 워낙 빼어나 대개는 무릉계곡을 따라 두#376;~ucirc;옥간 능선만 밟고 돌아 내려가는 것이 일반적이었다. 무릉계곡의 한 지류로서 쉰움산 북쪽 바로 아래로 뻗은 비린내골 입구는 또 쌍용양회의auml;석장이라 통행이 되지 않았다. 이런 연유로 쉰움산을atilde;는 이는 극히 드물었던 것이다.쉰움산만 오르려면 삼ocirc;시 동쪽 미로면 내미로리의otilde;은사로 가면 된다.otilde;은사에서 정상까지는 1시간이면 충분히 오른다. 능선으로 올라 계곡으로 내려서는otilde;은사 원점회귀코스는 ª지만 쉰움산의 알yen;배기 비경을 둘러보며 산행할 수 있어 좋다.오십정산(五十井山)이라고도 불리는 이 산은 한자 그대로 오십 개의 우물이 있다고 해 붙여진 이름이다. 정상 부근은 거대한 암반에 쉰 개 보다 훨씬 많은 웅덩이가 곰보자국oacute;럼 박혔다. 정상석에는 쉰움산이라는 이름 대신 ‘五十井 683m’라 적혀있다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면, 동해시 삼화동", + "MNTN_NM" : "쉰움산" }, - "longitude" : 126.97333329999999, - "latitude" : 37.5930556 + "longitude" : 129.0288889, + "latitude" : 37.447499999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울의 진산 북한산은 조선조 초기에는 삼각산(三角山)으로 불렀다. 삼각산이란 이름은 〈신증동국여지승람〉에 '삼각산은 양주의 경계에 있다. 일명 화산(華山)이라 하고, 신라시대에는 부아악(負兒岳)이라고 불렀다.이 산은 경성(京城)의 진산으로 동명왕의 아들 온조가 한산(漢山)에 이르러 부아악에 올라가서 살 만한 곳을 살폈다'는 기록이 있으며, '백운봉 (白雲峰, 지금의 백운대), 인수봉 (仁壽峰), 만경봉 (萬景峰,지금의 만경대)등 세 봉우리가 있으므로 그렇게 이름한 것이다'라고 유래를 기록하고 있다. 북한산성에 대해서는 〈신증동국여지승람〉과 〈북한지〉에 상세히 기록되어 있다. 북한산성은 백제 온조왕이 터를 잡았고 그후 개루왕 때 성터를 쌓았다는 기록이 있으며, 조선시대에 임진왜란, 병자호란을 치른 뒤 숙종 37년(1711년)에 시작하여, 6개월 만인 그해 10월에 완공하였다 한다.북한산성은 험한 산세를 이용하여 정상을 기점으로 서쪽 산자락부터 원효봉, 염초봉, 백운대, 만경대, 용암봉, 문수봉, 나한봉, 나월봉, 용출봉, 의상봉까지 연결하여 쌓은 산성으로 총 길이가 10km에 달한다. 당시 산성에는 14개의 성문을 냈는데, 산성의 정문 격인 대서문을 중심으로 북쪽으로 수문, 서암문(시구문), 북문, 백운대를 지나 위문, 용암문, 대동문, 보국문, 대성문, 대남문, 청수동암문, 대서문에서 북서쪽으로 이어지는 산성에는, 부황동암문, 가사동암문이 설치되었다.현재는 대부분 성문을 복원하였다. 북한산에 수많은 등산로 거미줄 같이 얽혀 있어 산행시 주의를 요하는 곳이다. 북한산의 산행 들머리는 대표적으로 여섯 군데를 꼽고 있다. 우이동 기점, 4.19탑 기점, 정릉 기점, 세검정 기점, 불광동 기점, 구파발 북한산성 기점으로 구분할 수 있다.", - "MNTN_HG_VL" : "836", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 강북구ㆍ성북구ㆍ종로구ㆍ은평구, 경기도 고양시ㆍ양주시", - "MNTN_NM" : "북한산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "호음산" }, - "longitude" : 126.99333300000001, - "latitude" : 37.660832999999997 + "longitude" : 127.83861109999999, + "latitude" : 35.797499999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "영광의 진산이라 내세울 수 있는 불갑산은 노령산맥의 정간에서 서남쪽으로 서해를 향해 힘차게 휘어 달리다가 우뚝 솟은 서지맥의 막내봉이다. 해발 516미터이며, 영광읍에서 약 10킬로미터 지점에 있다. 멀리서 보이는 산형은 마치 노서하전(老鼠下田)이라 하여 늙은 쥐가 밭을 향해 내려 오는 형세와도 같다고 한다.들길을 따라 참나무류와 싸리나무 등의 잡목 사이를 헤쳐 산 안으로 들어가다 보면 동백나무가 그 자태와 함께 빼곡하게 골짜기를 메우니 이곳이 바로 유명한 ‘불갑산 동백골’이다.정상 주변은 거대한 암봉으로 조망이 압권이며, 동쪽은 10여 미터의 깎아지른 절벽지대라 주의해야 한다.", - "MNTN_HG_VL" : "518", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 불갑면ㆍ함평군 해보면", - "MNTN_NM" : "불갑산" + "DETAIL_INFO_DTCONT" : "개이빨산은 경기도 포천군 이동면과 가평군 북면의 경계를 이루는 산으로 국망봉(國望峰.1,168m)과 강씨봉(姜氏峰.830m) 사이에 위치해 있다.멀리서 이 산 정상부를 바라보면 정상 일원의 능선 10여개가 톱니처럼 돌출돼 있어 마치 개이빨을 연상케해 이 산의 이름을 개이빨산이라 부르게 된 것이다. 때문에 산자락에 사는 주민들은 이 산을 일명 견치산(犬齒山), 또는 견아산(犬牙山)이라 불러 왔다고 한다.", + "MNTN_HG_VL" : "1110", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 포천군", + "MNTN_NM" : "개이빨산" }, - "longitude" : 126.5650998, - "latitude" : 35.190731300000003 + "longitude" : 127.32489889999999, + "latitude" : 37.878003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 양주시 주내면에 위치한 불곡산(일명 불국산)은 작은 규모에 비해서 암릉이 많은, 아기자기하고 길게 이어지는 바위산이라 스릴 있으면서도 위험하지 않아서 산행의 묘미를 한껏 즐길 수 있는 산이다.의정부에서 시내버스로 10분이면 등산기점에 이를 수 있어 교통이 편리하고 서울 근교에 위치하여 당일 산행으로 제격이며 인적도 많지 않아 호젓한 산행지로 선택하기 좋다.산행은 유양리 백화암에서 출발, 부흥사로 하산할 수 있고 부흥사에서 산행을 시작해 백화암으로 하산하는 역코스도 있다. 불곡산은 옛날에 회양목이 많아서 겨울이 되면 빨갛게 물든다 하여 붙여진 이름이라한다. 산중턱에는 500여년쯤 된 우람한 느티나무와 신라시대 고찰인 백화암이 있다. 불곡산은 국립지리원에서 낸 지도에는 ‘불국산(佛國山)’으로 표기되어 있다. 그러나 「산경표」 한북정맥편에는 ‘불곡산’이라고 또렷이 적고 있다.불곡산은 갖가지 모양의 바위 전시장이다. 보는 이에 따라 온갖 모양이 연출된다. 너럭바위, 곰바위, 고양이바위, 투구바위, 상투바위, 산파바위, 시루떡바위 등 기묘한 바위를 찾으며 산행하는 것도 재미를 더한다. 불곡산 남쪽에 자리하고 있는 유양동에는 유양팔경이 전한다. 산성낙조, 기당폭포, 화암종성, 선동자화, 금화모연, 승학연루, 도봉제월, 수락귀운 등이다.", - "MNTN_HG_VL" : "313", - "MNTN_LOCPLC_REGION_NM" : "경기도 양주시 유양동", - "MNTN_NM" : "불곡산" + "DETAIL_INFO_DTCONT" : "구름을 받치고 있는 기둥같다’는 운주산(806.2m)은 팔공산 보현산과 함께 영천의 삼산으로 불린다. 운주산은 높지 않으나 그 품이 넓고 깊어 민초들이 살아온 고된 삶의 흔적이 많이 배여있다. 임진왜란 때는 김백암장군이 이 산에 성을 쌓아 항전했고, 구한말에는 영남지방의 의병조직인 산남의진(山南義陣)이 이곳을 근거지 삼아 포항·영일 일대서 거센 항쟁을 펼쳤다. 또 한국전쟁 때는 많은 피난민들이 이 산에 은신하기도 했다.정상에서는 사방이 훤히 트인 멧부리에서는 굽이치는 낙동정맥의 자태가 한눈에 들어온다. 서쪽으로는 얼어붙은 조양호가, 북서쪽으로는 눈고깔을 하얗게 덮어쓴 보현산이 머리를 내민다. 동쪽으로는 비학산 도음산이 포항시를 감싸고 남쪽으로 도덕산 자옥산이 이어지며 영천시를 보듬고 있다.산 중턱 쯤에 안국사가 있다.안국사는 신라 때 국태민안과 왕실의 번영을 기원하기 위해 기림사와 함께 세워진 유서 깊은 고찰이다. 한때 이 골짜기에 열두 암자를 거느리며 신라 불교의 전성기를 이끌기도 했다. 그러나 구한말 의병 활동의 근거지였던 까닭에 일제에 의해 대부분 불태워졌다. 암자에서 만난 노스님은 지금도 운주산 일대에 당시 승려들이 만든 저수지와 절터가 곳곳에서 발견된다고 말했다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영천시 임고면, 자양면, 포항시 기계면", + "MNTN_NM" : "운주산" }, - "longitude" : 127.02581929999999, - "latitude" : 37.799757100000001 + "longitude" : 129.11027780000001, + "latitude" : 36.0777778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "불곡산은 경기도 성남시 분당구와 광주군 오포면의 경계를 이루는 해발 312.9m의 낮은 산으로 분당시민의 휴식처 역할을 톡톡히 하는 산이다. 산행은 수내동, 불정동, 정자동, 구미동에서 아무곳으로나 올랐다가 내려가면 된다.", - "MNTN_HG_VL" : "313", - "MNTN_LOCPLC_REGION_NM" : "경기도 성남시 분당구, 광주군 오포면", - "MNTN_NM" : "불곡산" + "DETAIL_INFO_DTCONT" : "삼방산은 남방산으로도 불리우며 강원도 평창군 평창읍 노론리와 미탄면 창리, 영월군 북면 공기리 사이에 있는 산이다. 푸른 숲을 간직하고 있는 산으로 옛부터 산과 나물의 고장으로 잘 알려진 강원도에 자리를 잡고 있어 산나물 산행지로 제격이다. 산행은 멧둔재를 중심으로 이루어지고 있으며 멧둔재는 삼방산의 동북능선을 형성하고 있다.평창읍 내에서 남동쪽 평창강 건너로 하늘금을 이루어 보이는 삼방산 이름의 의미는, 옛날 중요한 통로를 이루는 지역에는 대개 세 지점에 통행인을 검사하는 관방이 설치되어 있었던 데서 유래한다. 커다란 종 모습의 산으로, 평창읍을 자연성곽처럼 감싸고 있다.정상은 수림에 둘러싸여 동쪽을 빼고는 조망이 잘 되지 않으며, 대신 산을 내려오다 보면 900m봉을 지나 전망이 좋은 평야지대가 있다. 이곳에서는 평창 시가지 뒤로 옛날 숯가마가 있었다는 숯고개 너머로 장암산, 노성산이 보이고 멀리로는 배너미산, 무등산이 보이며 왼쪽으로는 종부리 마을을 휘감은 평창강과 수장산, 백덕산, 사재산 등이 바라보인다. 평창강변은 캠핑장소로 적합하며 부근에 이승복기념관, 오대산국립공원이 있다.", + "MNTN_HG_VL" : "980", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "삼방산" }, - "longitude" : 127.1352778, - "latitude" : 37.346111100000002 + "longitude" : 128.4325, + "latitude" : 37.339444399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 성남시 분당구 정자동과 광주시 오포읍의 경계에 있는 산으로 자연 생태계가 잘보존 되어 있으며 혼효림이 무성하여 봄,여름,가을,겨울이 새롭게 보이는 산이다. 남서나 북서 방향의 행글라이딩 이륙장을 갖추고 있고, 특히 겨울에는 분당에서 생성된 열기류가 모이는 곳이므로 행글라이딩을 하기 좋은 곳으로 이름나 있다. 도심지역에 위치 하고 있어 지역주민들의 발길이 잦으며 초행길에도 그리 어렵지 않은 산행이 될것이다.", - "MNTN_HG_VL" : "465", - "MNTN_LOCPLC_REGION_NM" : "경기도 성남시, 광주시", - "MNTN_NM" : "불곡산" + "DETAIL_INFO_DTCONT" : "제주도에 이어 두 번째로 큰 섬인 거제도는 총 면적 399.3㎢에 부속 섬 60여개를 안고 있는 큰 섬이다. 거제도에는 계룡산을 비롯하여 옥녀봉(555m),산방산(507m), 노자산(565m), 앵산(507m) 등 500m급의 크고 작은 산들이 솟아 있다.주능선에 용이 승천하는 듯한 형상의 바위가 솟아 있어 계룡산이라 이름 붙여진 이 산은 봄에는 진달래, 가을이면 억새로 비경을 자아내고 있다.이곳 향토사학자들은 '계룡산하 구백만(鷄龍山下 九百萬)'이라고 표현한 〈정감록〉의 계룡산은 거제도에 있는 계룡산을 말한다고 주장하고 있다. 6.25때 충청도 계룡산에 피난 갔던 수많은 사람들은 피해를 입었지만, 이곳 거제 계룡산은 많은 주민과 피란민, 포로들까지 피해를 입지 않은 곳이었기 때문이라 한다.", + "MNTN_HG_VL" : "845", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거제시", + "MNTN_NM" : "계룡산" }, - "longitude" : 127.1352778, - "latitude" : 37.346111100000002 + "longitude" : 128.608, + "latitude" : 34.871299999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "불금봉은 강원도 홍천군 북방면에 소재한 성치산의 봉우리이다. 성치산은 나지막한 산이지만, 남북으로 잇는 주능선이 의연하고 떡갈나무, 굴참나무 등 참나무류가 산초나무와 어울려 길을 가린다. 특히 등산 초입인 원골과 진골 일대는 장송이 하늘을 가려 마치 심산에 온 느낌을 준다. 불금봉에서 정상에 이르는 주능선 길 도중엔 몇 개의 무덤이 자리잡고 있어 그때마다 전망이 열리기도 한다.정상에는 괴이한 모양의 바위가 서있고 북동쪽으로 절벽을 이루면서 기암괴봉이 늘어서 있다. 또 그 아래 용담저수지가 아름답기 그지없다. 특히 강원도 홍천에 자리하고 있어 인적이 드물어 깨끗한 자연 그대로는 보존하고 있는 산중의 하나이다.", - "MNTN_HG_VL" : "499", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 북방면 성동리", - "MNTN_NM" : "불금봉" + "DETAIL_INFO_DTCONT" : "본래 이름은흰돌더미산이다. 흰덤이가 흰대미로 불리기도 하고 희대미로 불리기도 한다. 산 정상에 높이 약 1.5m 둘레 6m 쯤되는 흰 화강암이 놓여있는데 산이름은 여기서 유래되었다고 본다. 정상에서 북쪽으로 2km 거리에 양각산이 있고 더가면 수도산이 있다. 남쪽으로는 회남령과 이어져 보해산과 금귀봉이 자리하고 있고 서쪽으로는 웅양댐이 안겨있고거말산에서 국사봉으로 이어지는 길이 된다.", + "MNTN_HG_VL" : "1018", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가북면, 웅양면", + "MNTN_NM" : "흰대미산" }, - "longitude" : 127.84704670000001, - "latitude" : 37.733613599999998 + "longitude" : 127.9561111, + "latitude" : 35.825277799999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "601", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "불기산" + "DETAIL_INFO_DTCONT" : "정각산은 경남 밀양시 단장면 한적한 곳에 자리 잡고 있다. 삼각산(887m)과 인접해 있으며 말발굽형상으로 연결되어 있는 이 산에는 유독 묘(墓)들이 눈에 띄게 많다. 그만큼 풍수지리상 좋은 자리를 차지하고 있다는 설이 있다. 대신 등산객들은 찾아 보기 어렵고 발길 닿지 않은 자연림의 형태를 잘 보존하고 있는 곳이다.정상 가까이에 묘(墓)가 많이 있으며, 이웃한 삼각산(887m)과 말발굽 모양으로 이어져 있다. 산행은 표충사에서 4Km 떨어진 범도리 아불마을에서 시작하여 정상에서 능선을 따라 삼각산을 마주보고 내려가다가 송백리로 빠져 내려온다. 산 아래로 남천이 남서쪽으로 흐르며, 산 동쪽 재약산(1108m) 자락에는 신라 진덕여왕 8년 원효대사가 창건한 표충사가 있다. 표충사에는 청동함은향완(국보 75), 삼층석탑(보물 467), 석등(경남유형문화재 14), 표충서원(경남유형문화재 52) 등의 유물이 남아 있다.", + "MNTN_HG_VL" : "860", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면", + "MNTN_NM" : "정각산" }, - "longitude" : 127.4525, - "latitude" : 37.8030556 + "longitude" : 128.90484180000001, + "latitude" : 35.547757799999999 }, { "mountain" : { @@ -4251,513 +3041,513 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울과 경기도 의정부시, 남양주시의 경계에 솟은 그리 높지 않은 산이다. 이 산은 덕릉고개를 사이에 두고 수락산(637.7m)과 마주하며 남북으로 우뚝한, 서울 동북쪽 공원녹지의 근간을 이룬다.불암산 주봉은 그 형상이 마치 송낙(소나무 겨우살이로 만든 여승이 쓰는 모자)을 쓴 부처의 모습과 같다 하여 불암산이라 불리게 되었으며 천보산(天寶山), 필암산(筆岩山) 이라는 이름도 가지고 있다.불암산은 사암으로 된 산이라 수목이 울창하지는 않으나 능선은 기암으로 이어지고 서울 근교의 수많은 등산학교들의 암벽교장으로 애용되기도 한다. 바위로 된 정상에서는 수락산, 도봉산, 북한산을 비롯한 서울과 남양주 쪽 조망이 아주 좋다.불암산 산행 코스 중 수락산과 북한산, 도봉산 능선을 잇는 종주코스가 최근 인기가 높다. 불암산 - 수락산 - 사패산 - 도봉산 - 북한산을 무박 2일로 이어 종주하는 ‘서울 5개산 종주산행’의 첫 출발지로 보통 불암산 자락의 불암동을 잡는다.", - "MNTN_HG_VL" : "510", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 노원구 상계동, 중계동ㆍ경기도 남양주시 별내면", - "MNTN_NM" : "불암산" + "DETAIL_INFO_DTCONT" : "각희산은 화암국민관광지에서 동대천 북쪽으로 병풍처럼 펼친 듯 솟아 있는 산이며, 동대천을 사이에 두고 행산과 화암약수터가 있는 군의산과 마주하고 있다. 동대천을 거슬러 올라가면 남전산과 지억산이 버티고 있다. 동대천변의 화암8경을 보려는 사람들의 발길은 끊이지 않는데 반해 각희산은 등산로가 잘 알려지지 않아 아직 태고의 신비를 고스란히 간직하고 있다. 각희산 바로 옆 행산과 군의산, 남전산과 지억산이 어깨를 두르고 있다. 정상에서 보면 청옥산, 민둥산이 보이고 그 뒤로 두위봉도 보인다. 각희산은 예로부터 신성시하여 나라에서 벌채를 금지했던 곳으로 알려져 있다.", + "MNTN_HG_VL" : "1083", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면, 임계면", + "MNTN_NM" : "각희산" }, - "longitude" : 127.095, - "latitude" : 37.663333299999998 + "longitude" : 128.81333330000001, + "latitude" : 37.360833300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "불태산은 담양 대전면 대치리에서 장성 백양사로 넘어가는 한재(대치)를 경계로 왼쪽에 솟아있는 해발 720미터의 봉우리다. 그동안 오른쪽의 병풍산의 그늘에 가려져 많이 알려지지 않았으나 최근 남쪽 산자락에 위치한 군사 훈련소 때문에 민간인 출입이 통제되어오던 것이 최근 완화되면서 남도 등산인들로부터 당일 산행지로 사랑받고 있다.불태산은 장성 진원면과 담양 대전면에서 바라보면 마치 거대한 부처를 연상케 한다. 이를 증명하듯 장성군에서 발간한lt;문화유적gt;에 따르면 불태산을 ‘불대산(佛大山)’으로 표기하고 있고, 또 산자락에 80개의 사찰이 있었다는 이야기가 전해지고 있다.국토지리정보원 지형도에는 636미터 봉우리를 ‘불태산(佛台山)’으로 표기하고 있으나 지역주민과 과거의 자료를 살펴보면 ‘불태봉 720m’라 적힌 정상석이 세워진 봉우리가 불태산 정상이라 하겠다. 해발 685.2미터의 ‘병장산’도 지형도에는 ‘병봉산(屛鳳山)’이라 표기되어 있다. 산세는 동쪽 사면은 가파른 절벽이고 서쪽 사면은 완만하다. 대치~천봉 구간은 육산이지만 주능선 곳곳을 이루는 암릉구간은 암릉산행의 재미를 선사한다.", - "MNTN_HG_VL" : "720", - "MNTN_LOCPLC_REGION_NM" : "전남 장성군 장성읍·진원면, 담양군 대전면", - "MNTN_NM" : "불태산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "429", + "MNTN_LOCPLC_REGION_NM" : "경기도 양주시,고양시", + "MNTN_NM" : "노고산" }, - "longitude" : 126.8666667, - "latitude" : 35.299999999999997 + "longitude" : 126.94474719999999, + "latitude" : 37.6841309 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 지맥이 동쪽으로 뻗어 단지봉(1327m), 가양산(1430m), 미승봉(734m)으로 내려오다가 가야산에 이르기 전 남서쪽으로 별유산(1046m)을 지나 솟구친 것이 비계산이다.합천군과 거창군의 경계를 이루는 비계산은 인접한 별유산, 장군봉과 함께 닭이 금벼슬의 관을 쓰고 심장부에 고견사를 품고 있는 듯한 형상이다. 비계산은 닭머리 부분에 해당된다. 비계산은 돌, 너덜, 바람, 굴이 많은 산으로 유명하다. 능선상에는 암릉과 암봉들이 많아 산행시는 로프를 반드시 준비해야 한다.소요 시간 :6시간최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 갈림길에서 서쪽 능선을 따라 오른 비계산 정상은 잡목들로 어우러져 있고, 동서를 관통하는 88 고속도로 및 의상봉 상봉에서 서쪽으로 뻗은 암릉을 바라보는 경관이 좋다.도리나 거창휴게소에서 많이 올라간다. 비계산에서 시작하여 의상봉까지 종주하는 코스로 이용하기도 한다. 숲길로 활용하기 적당하나 정상부근은 안전장치가 좀더 필요할 듯하다. 휴게서외에는 식수를 구할 곳은 없다.", - "MNTN_HG_VL" : "1131", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 가야면", - "MNTN_NM" : "비계산" + "DETAIL_INFO_DTCONT" : "강원도 태백시 창죽동에 위치한 금대봉은 지형도상에는 이름 없이 높이만 표기되어 있는 무명산으로 그리 많이 알려지지 않은 산이다.백두대간의 주맥에 솟아 동쪽의 매봉 줄기를 받아 남쪽의 함백산, 태백산으로 맥을 이어주는 역할을 한다. 이 봉우리 북사면 골짜기에는 한강의 발원지 역할을 하는 고목나무샘, 검용소 등이 있고 낙동강 천리 물길이 시작되는 용수골이 자리하고 있다.뿐만 아니라 매봉산 동쪽 가지인 1145m봉에서 낙동강 동쪽 산세를 형성하는 낙동정맥이 뻗어 있으니 금대봉이 갖는 의미는 각별하다.함백산에서 금대봉구간은 1993년 환경부가 생태계 보전지역으로 지정해 등산이 일부구간만 허용되는 곳이다.봄부터 가을까지 만흥 식물들이 자생하면서 ‘산상의 화원’이란 이름으로 알려진 곳으로 곳곳에 ‘백두대간 나무심기’ 라는 팻말을 품고 있는 수목들이 쉽게 눈에 띄는 것도 식물자원 보호구역으로 지정되면서 자연을 지키려는 노력의 결실이기도 하다.이 때문에 금대봉은 산행뿐 아니라 다양한 꽃과 자생식물을 촬영하려는 생태 탐방객들이 즐겨찾는 곳이다. 금대봉에서 두메기름나물, 바이칼바람꽃, 등 백두산에서 백두대간을 타고 내려온 북방계 식물을 비롯해 한국 특산식물이 15종, 희귀식물은 16종 이상을 조사한 바 있는 현진오 박사는 해발1,200m를 넘는 고산 정상부에서 다양한 초본 식물상을 한꺼번에 관찰할 수 있는 곳은 금대봉 일대가 우리나라에서 거의 유일하다고 밝힌바 있다.금대봉에는 높고 추운 산꼭대기에서 자라는 만병초도 자생하는 것으로 알려져 있다. 『정선총쇄록』에도 “이 약은 이 고을의 갈래사(葛來寺) 동편 골짜기에서만 나는데 만병통치로 즉효를 보지 못한 건시 없다고 하나 아직 시험해 보지 못했는데 각처 사람들이 많이 와서 잎을 뜯어간다”고 나와 있다.금대봉 정상에 오르면 두문동재 넘어 천의봉과 함백산이 웅장하게 다가온다. 금대봉을 오른 사람들은 주로 38번 국도상의 두문동재(1,268m)에 정상까지 가는 동안 두개의 헬기장을 지나며 방화선을 따라 이어지는 산길 주변으로는 봄이면 얼레지, 노루귀, 꿩의바람 등 산상의 화원에 펼쳐진 야생화에 빠져들다 보면 예상 등산시간보다 훨씬 더 소요된다.", + "MNTN_HG_VL" : "1418", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", + "MNTN_NM" : "금대봉" }, - "longitude" : 128.06999999999999, - "latitude" : 35.7216667 + "longitude" : 128.91526469999999, + "latitude" : 37.212530600000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "비룡산(240m)은 높이가 낮아서인지 그리 알려지지 않은 산이다. 그러나 제2의 어라연이라 할 수 있을 만큼 그림 같은 전경을 자랑하는 회룡포를 끼고 있는 산자락으로 산행길 내내 조망이 훌륭하며, 육지 속의 섬인 의성포(義城浦)를 감싸고 있는 산이다. 1998년에 세운 정자인 회룡대에 오르면 주변 경관이 한눈에 들어오는데, 특히 낙동강의 지류인 내성천(乃城川)이 휘감아 돌아 모래사장을 만든 곳에 자리한 의성포의 절경이 잘 내려다보인다. 의성포는 이웃하고 있는 회룡마을과 함께 하나의 관광지군으로 묶여 있어 회성포라고도 부르는데, 드라마 〈가을동화〉를 찍은 곳으로 유명해져서 사람들이 많이 찾고 있다.숲이 울창하며, 정상 바로 밑에 통일신라 때 의상대사의 제자인 운명선사가 세운 장안사가 있다. 1997년 11월 복원한 봉수대는 예전에 동쪽의 서암산 봉수, 서쪽의 소이산 봉수, 북쪽의 가불산 봉수와 연락을 담당하는 군사요충지였다고 한다. 정방형이며, 높이는 2.7m이다.또 마한시대에 축성된 원산성(圓山城:또는 따뷔성, 또아리성)이 있는데, 둘레가 약 920m, 높이가 1.5~3m인 토석혼축산성이다. 《군지》에는 '비룡산성'으로 기록되어 있으나 《삼국사기》에는 원형으로 쌓았다 하여 '원산성'이라고 표기되어 있다. 백제 시조 온조가 남하할 때 이 성에서 마한을 점령하고 백제를 세웠다거나, 고구려 온달 장군이 이 성을 점령하려고 내려오다 아차산성에서 전사했다는 이야기가 전해진다. 용궁향교, 무이서당(武夷書堂), 만파루, 황목근(천연기념물 400), 삼강 나루터가 가까이 있고 그밖에 용문사 대장전(보물 145) 외에 많은 문화재를 보유하고 있는 용문사와 예천 감천면의 석송령(천연기념물 294) 등 관광명소가 있다.", - "MNTN_HG_VL" : "240", - "MNTN_LOCPLC_REGION_NM" : "경상북도 예천군", - "MNTN_NM" : "비룡산" + "DETAIL_INFO_DTCONT" : "동강을 끼고 있는 백운산. '태고의 신비'와 '천혜의 비경'까지 갖춘 동강은 강원도 산 속 깊숙이 숨어서 말없이 흘러가고 있다. 그래서 일까. 백운산 산행은 마치 신선이 된 듯한 기분을 선사해준다.백운산 산행을 위해서는 동강을 건너야 한다. 그리고 산행을 마쳤을 때도강을 건너와야 한다. 하지만 물을 건너지 않고 아예 칠족령에서 문희 마을로내려선뒤 보트를 타고 섭새까지 내려오는 방법도 있다. 산과 강을 동시에즐기는 코스다. 하지만, 백운산 산행은 점재 마을에서 시작하는 것이 일반적이다.", + "MNTN_HG_VL" : "884", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 신동읍, 평창군 미탄면", + "MNTN_NM" : "백운산(정선)" }, - "longitude" : 129.04750000000001, - "latitude" : 36.996388899999999 + "longitude" : 128.59615439999999, + "latitude" : 37.280543999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "비봉산(飛鳳山)은 낙동 중의 낙동, 중동면 오상리의 강변에 지각변동으로 솟구쳐 생긴 산이다. 봉황이 하늘을 나는 형국이라서 이런 이름이 붙어졌겠는데, 실제 보아도 그런 것이 좌우로 펴진 능선이 비행기의 날개처럼 앞면은 두껍고 뒤쪽은 얇아지면서 깃털처럼 갈라져 영락없이 새가 날개를 펼친 모양이다. 그 가운데 정상이 머리처럼 우뚝해 강 건너편의 옥주봉을 바라보고 있다.주변이는 봉황과 관련된 지명인 죽암(竹岩). 오상리의 오동(梧桐) 마을 등이 있다.산세가 부드럽고 등산로에 소나무가 우거져 산보하는 기분으로 가족산행하기 좋은 곳이다. 솔잎을 밟고 솔향기에 취하여 강바람에 옷자락 나부끼며 음풍농월하는 데도 더할 나위 없이 좋다.정상에서 보는 낙동강은 한 폭의 그림같은 멋진 풍광을 자아낸다. 한마디로 무아지경이다. 시원스럽게 불어오는 강바람도 운치를 더해준다. 저멀리 상주의 삼악인 노악.갑장.천봉산과 속리산.청계산.작약산 등이 아련히 보이고 국민관광지인 경천대가 바로 눈앞에 다가선다. 정상 밑에는 숙종 원년(1672년)에 창건한 청용사가 자리를 잡고 있다. 사찰규모는 크지 않으나 낙동강과 어우러져 아름다움을 간직하고 종소리 은은하여 좋다.", - "MNTN_HG_VL" : "230", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 중동면 오상리", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "모후산은 섬진7지맥의 한 봉우리로 백아산의 산줄기를 타고 내려와 동복천을 앞에 두고 멈춰선 곳이다. 이 산은 광주 무등산과 순천시 조계산의 그늘에 가려 잘 알려지지 않았으나 유마사, 주암호, 사평폭포 등의 명소가 곳곳에 있고, 항상 푸른 계곡물이 넘쳐 있어 관광객과 등산객에게 각광을 받고 있다. 또한 우리나라 최초의 고려인삼 시배지이기도 하다.모후산은 고려 공민왕 10년(1361) 홍건적이 쳐들어왔을 때 왕과 왕비가 태후를 모시고 이곳까지 피난을 왔던 산이다. 공민왕은 수려한 산세에 반해 가궁을 짓고 환궁할 때까지 1여년 남짓 머물렀다고 한다. 그 뒤 나복산을 어머니의 품속 같은 산이라 하여 모후산으로 바꾸었다.또한 임진왜란 때 이곳 동복현감인 서하당 김성원이 노모를 구하기 위하여 필사적으로 싸우다가 순절하였다고 하여 모후산을 모호산(母護山)이라 부르고 마을 이름도 모호촌이라 하였다.", + "MNTN_HG_VL" : "944", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 남면, 동북면", + "MNTN_NM" : "모후산" }, - "longitude" : 128.26611109999999, - "latitude" : 36.436388899999997 + "longitude" : 127.1838229, + "latitude" : 35.033538200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제천에서 82번 도로를 따서 청풍으로 가다보면 오른쪽으로 호수 위에 솟은 산이 있다. 비봉산 가운데 솟은 봉우리는 봉황의 머리, 양쪽으로 뻗은 능선은 영락없는 날개니 이름 그대로 봉황이 날아갈 듯한 자태다. 금수산이나 월악산 등 명산의 그늘과 청풍문화재단지 등의 명성에 가려서 별로 알려지지 않았으나 여덟 명당 거느린 복스러운 산이다.비봉산은 산행 들머리인 연곡리부터 시작해서 사방으로 연곡리, 계산리, 양평리, 도곡리, 대류리, 신리 같은 마을들이 둘러싸고 있다. 청풍 쪽 마을은 물태리다. 이 마을들을 잇는 순환도로를 따르면 비봉산을 한 바퀴 돌게 된다. 도곡리나 양평리에서 더 들어가 길 끝자락 호숫가에 서면 흡사 섬에 온 것과도 같은 느낌이다.연곡리에서는 이백년이 훨씬 넘어 보이는 느티나무 한 그루가 길손을 반긴다. 산행은 이 느티나무가 있는 큰 길가에서 못안마을 축사 쪽으로 난 콘크리트 포장도로로 접어들면서 시작된다. 이 길에서 보면 비봉산이 거느린 여덟 개의 명당 중 하나로 짐작될 만한 곳이 눈에 띈다. 축사 뒤편으로는 흡사 봉황의 알처럼 솟은 나지막한 봉우리 두 개가 유난히 시선을 끈다. 원래 비봉산의 산세는 새가 알을 품고 있다가 먹이를 구하려고 비상하는 모습이라 했으니 두 봉우리 뒤편으로 솟은 비봉산이 더욱 범상치 않아 보인다.", - "MNTN_HG_VL" : "361", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "가뭄이 심할 때 관민이 모여 기우제를 올리던 곳으로 홍림산, 일월산과 함께 영양의 진산으로 꼽힌다. 이 산은 세 개의 봉우리가 큰 바가지를 엎어놓은 듯 하여 한박산이라 불리기도 하며 산세가 탕건 같다하여 탕건봉이라 부르기도 한다.작약산이란 이름은 이 산의 형세가 풍수지리의 작약반개형(芍藥半開形) 명당이라는 데서 유래되었다. 정상에는 소나무와 참나무가 우거져 확 트인 전망을 기대하기 어렵다. 북으로 흥림산이 손에 잡힐 듯 가까이 보이나 북쪽이 협곡을 이루어 능선이 발달하지 않아 흥림산으로 연결된 등산로가 없다. 하산길에 권영성(1881-1923)의 넋을 기리기 위해 후손들이 세운 요산영천(樂山靈泉) 입석비가 있다. 권영성은 영양읍 서부동 출생으로 행상을 해서 번 돈으로 이 지역의 복지후생에 노력한 사람이다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 영양읍, 청기면", + "MNTN_NM" : "작약산" }, - "longitude" : 128.14326149999999, - "latitude" : 37.008540699999998 + "longitude" : 129.09472220000001, + "latitude" : 36.678888899999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "441", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면 문촌리", - "MNTN_NM" : "비봉산" + "MNTN_HG_VL" : "1236", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면, 영주시 부석면. 강원도 영월군 하동면", + "MNTN_NM" : "선달산" }, - "longitude" : 128.79523180000001, - "latitude" : 36.839934399999997 + "longitude" : 128.7094563, + "latitude" : 37.0390199 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "비봉산은 낙동정맥 가사봉 분기점에서 뻗어나온 보현지맥을 따라 보현산을 지나고 석심산에 이르러 한 줄기는 남서쪽으로 팔공지맥, 또 한줄기는 북서쪽으로 보현지맥으로 나뉘어 구무산, 문암산을 지나 비봉산에 닿았다가 낙동강으로 흘러드는 위천을 만나면서 허리를 숙인다.비봉산은 글자 그대로 ‘봉황이 날아가는 형상’이라고 해 붙여진 이름이다. 고려시대 이전에는 태행산이라 불리다가 조선 말기에는 자미산이라 하였다고 전하나 지금은 비봉산으로 부르고 있다.경상북도 의성군 다인면, 안계면 일대는 분지형으로 사방이 산으로 둘러쳐져 있으나 모두 나지막한 산들로 이어져있다. 그 중에서 우뚝한 비봉산은 바라보는 위치에 따라 모습을 달리하는데, 동쪽에서는 봉황이 날개를 넓게 펼치고 앉아 있는 모습이고, 남쪽에서 올려다보면 봉황이 위엄 있는 자세로 날갯짓을 하는 듯하다. 서쪽 다인면 소재지에서 바라보면 장군이 투구를 쓰고 서 있는 형상을 하고 있다. 의성군에서는 손에 꼽을 정도로 아름다운 산이지만 아직 일반인에게 많이 알려지지 않은 산이다.", - "MNTN_HG_VL" : "256", - "MNTN_LOCPLC_REGION_NM" : "경상북도 의성군 다인면", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "평창 청옥산(1256m)을 모산으로 해 동강을 품은 산으로 자생식물이 많고 하늘을 가리는 잡목이 우거져 있는 등 천연의 모습이 잘 간직돼있다. 심마니들을 심심찮게 볼 수 있는 것도 이 때문이다.돌리네 현상으로 땅이 꺼지면서 산줄기가 겹쳐진 형상을 하고있어 근동에서는 겹산이라 부르며, 정상은 봉분처럼 생겼다하여 묘봉, 요봉이라 한다. 산행을 마치고 동강변의 비경속에서 피서를 즐기기에 적당하다. 실제 산행을 하다보면 심밭굼이라 하는 움푹 꺼진 곳은 숲이 무성한 긴 계곡으로 나타난 난해한 지형이다.", + "MNTN_HG_VL" : "823", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "접산" }, - "longitude" : 128.3608667, - "latitude" : 36.488524099999999 + "longitude" : 128.4891374, + "latitude" : 37.265738200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "579", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "보광산은 산세가 빼어나거나 경치가 좋고 기이한 바위가 있는 그런 산은 아니다. 그저 나즈막한 육산에 불과하다. 그러나 정상의 봉학사지에 얽힌 전설이 현실에서의 인간 욕심이 무상하다는 것을 일깨워 주는 곳이기도 하다. 또한 접근이 용이하고 험하지 않아 가족단위로 등산할 수 있는 좋은 산이다.원래 이름은 봉학산이었다가, 조선 중기부터 보광산이라고 부른다. 정상에는 봉학사 터가 있다. 사찰 건물은 남아 있지 않으나, 괴산봉학사지오층석탑(충북유형문화재 29)이 전해진다. 고려 때의 작품으로 추정되며, 일제강점기 때 무너졌던 것을 1967년 복원하였다. 산 아래에는 봉학사의 후신인 보광사가 자리잡고 있다.보광사는 없어진 봉학사의 후신으로 그 명성을 간직하여 오고 있으며 봉학사지 석조여래상을 대웅전에 주존불로 모시고 있다. 대웅전 처마끝에서 보면 끝없이 펼쳐지는 낮은 산들이 손에 잡힐 듯 친근해 보이고 마음까지도 시원해 지는 곳이다. 대웅전 오른쪽 바위 밑에선 석간수가 샘솟는데 아무리 가물어도 넘쳐 나는 샘물이 맛 또한 그만이다. 흔적도 없이 사라진 절터에 홀로 남은 봉학사지 5층석탑은 고려초기의 작품으로 추정되며 지방유형 문화재로 지정되었다는 안내판이 있다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 사리면", + "MNTN_NM" : "보광산" }, - "longitude" : 126.95, - "latitude" : 34.983333299999998 + "longitude" : 127.6807002, + "latitude" : 36.821610300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "532", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 선산읍", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "지등산은 충북 충주시 동량면에 위치한 산으로 천등산, 인등산과 함께 3등산의 하나이다. 정상 부근은 뾰족하고 높아 이름과는 어울리지 않는 형세를 하고 있다. 산세가 특별히 아름답거나 비경을 감추고 있지만 않지만 흙으로 된 육산으로 숲이 우거져 있어 나름대로의 매력을 지닌 산이다.그러나 산세가 특별히 내세울 것이 없다보니 사람들의 관심에서 잊혀진 산이었다. 그로인해 사람들의 발길이 뜸하다보니 지등산은 깨끗한 자연환경을 간직할 수 있었고 원시림과 같은 참신한 맛을 느낄 수 있다. 우거진 숲 사이로 불어오는 청량한 바람은 건강에도 많은 도움이 되어 산행의 값을 한층 높여준다. 산 아래에는 충주호와 충주댐이 있다.정상에 서면 북쪽으로 인등산, 남동쪽으로 충주호·계명산이 보이고, 동쪽으로 관모봉(641m)이 능선을 따라 이어져 있다.", + "MNTN_HG_VL" : "535", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면 조동리", + "MNTN_NM" : "지등산" }, - "longitude" : 128.2994444, - "latitude" : 36.247222200000003 + "longitude" : 127.9875262, + "latitude" : 37.017703300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "138", - "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", - "MNTN_NM" : "비봉산" + "DETAIL_INFO_DTCONT" : "바위산은 사람들이 쉽게 접근하는 것을 막는 여염집 아낙처럼 찾아가기가 약간 번거롭다. 다른 산에 갈 때처럼 차나 기차를 이용해 근처까지 가도 소양댐 선착장에서 배를 타고 더 들어가야 하기 때문이다. 마치 그 물을 건너야 자신을 만날 자격이 있다는 것처럼 이 산은 저 멀리 서있다.춘천의 명물 중 하나인 소양호를 이용해서 산행을 즐길 수 있는 산과 호수의 낭만이 서려 있는 산이지만, 산 이름 자체는 널리 알려져 있지않아 일반인들은 그리 많지 않은 산악인들이 찾고 있는 편이며 능선으로 매봉이 바로 이웃하여 연결되어 있는 산이다. 소양호를 내려다 보면서 정상에 오르다 보면 노송이 우겨져 있고, 나자막한 돌탑이 있다.주머니 같이 둘러싸여 있는 능선 속으로 흐르는 중밭골 계곡에는 푸른 이끼가 끼어있고 군데군데 소와 작은 폭포가 있어 깨끗하기 이를데 없으며, 오솔길에는 풀이 무성해 융단을 딛는 것 같은 촉감의 정겨운 산길이다.", + "MNTN_HG_VL" : "858", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "바위산" }, - "longitude" : 126.79972220000001, - "latitude" : 36.501111100000003 + "longitude" : 127.96777779999999, + "latitude" : 37.9566667 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "125", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면", - "MNTN_NM" : "비봉산" + "MNTN_HG_VL" : "186", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군간성읍 금수리", + "MNTN_NM" : "고성산" }, - "longitude" : 128.79523180000001, - "latitude" : 36.839934399999997 + "longitude" : 128.45110779999999, + "latitude" : 38.352438200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "5만분의 1 지형도에는 날 비(飛)자로 표기되어 있으나 이 지역 주민들 말에 의하면 옛부터 이 산위에 구름이 걸려 있으면 꼭 비가 왔다고 해서 우리말 `비'를 붙여 비산이라 부른다고 한다. 또 일설에 의하면 서만이강이 범람했을 때 이 산 꼭대기에 배가 걸려 들어 배거리산이라 불리기도 했다. 이 서만이강은 이름도 묘하거니와, 강의 상류도 주천강이요 하류도 주천강이어서 사람들을 어리둥절하게 만들곤 한다.굽이구비돌아올라가는 솔치고개도 옛모습을 보기는 어렵다. 솔치고개밑으로 터널을 뚫어놓았기 때문에 자동차들이 솔치고개를 넘지를 않기때문이다. 이 솔치고개는 이름 그대로 송림이 울창하게 숲을 이루고 있어 지어진 이름이다. 한아름 두아름되는 노송이 늘어서있고 비산으로 가는 길은 소나무숲 길이다. 이길은 사람에게 그리도 좋다는 피톤치드를 온몸으로 느끼는 삼림욕 숲속길이다.봄이면 진달래, 복숭아, 산벚꽃이 지천으로 피어난다는 버들치 마을은 이름 그대로 아름다운 풍광에 고운 인심을 자랑하는 전형적인 산마을이다.정상에 올라 하산길로 들어서면 북으로 펼쳐지는 구룡산을 비롯하여 멀리 백덕산까지도 조망된다.", - "MNTN_HG_VL" : "694", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 영월군", - "MNTN_NM" : "비산" + "DETAIL_INFO_DTCONT" : "구미역에서 남서쪽으로 약 4km 떨어져 우뚝 솟은 금오산은 1970년 도립공원으로 지정된 산이다. 산 전체가 바위로 이루어져 기암절벽과 경사가 심한 산세를 이루고 있으며, 산아래 대혜폭포까지 케이블카가 설치되어 있다.", + "MNTN_HG_VL" : "977", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시, 칠곡군 북삼읍, 김천시 남면", + "MNTN_NM" : "금오산" }, - "longitude" : 128.21735760000001, - "latitude" : 37.278231599999998 + "longitude" : 128.30529999999999, + "latitude" : 36.088487800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 청도군과 대구광역시 달성군의 경계에 있는산, 최고봉은 대건봉이며 남쪽으로는 조화봉, 관기봉과 이어지며 유가사쪽에서 올려다보면 정상을 떠받치고 있는 거대한 바위능선이 우뚝 솟아있다.정상에서 바라보는 낙동강의 경치가 아름답고 봄철에는 철쭉, 진달래 가을에는 억새군락이 볼만하다. 스님바위, 코끼리바위, 형제바위등의 이름난 바위와 달성군 옥포면의 용연사를 비롯하여 용문사, 유가사등의 사찰이 산재한다. 정상인 대견봉에서 남쪽 능선을 따라 988봉 - 조화봉으로 이어진다.조화봉 능선에서 서쪽으로 대견사 터 - 1034봉으로 이어지며 1034봉에 팔각정 전망대가 설치되어 있다. 정상에서 북으로 이어지는 능선은 앞산으로 가는 안내표시가 되어 있다.정상에서 조화봉 까지 약 4km에 걸친 능선은 988봉 주변에 바위가 있을 뿐 육산(흑산)으로 큰 나무들이 없는 시야가 탁 트이는 초원 같은 이 능선에 가을에는 억새가, 봄에는 군락을 이룬 진달래가 붉게 물들인다.진달래 군락사이에 싸리나무 등 잡목들이 섞여 있으나 진달래가 더 많다.비슬산 진달래는 정상부근, 988봉 부근 아래, 대견사 터 산자락 등 크게 3군데에 군락을 이루고 있다. 대견사터 북쪽 광활한 30여만평의 산자락이 대규모 진달래 군락지이며, 진달래가 가장 곱고 밀집되어 있는 곳은 988봉 부근 아래 산자락이다. 진달래는 4월 중순부터 물들기 시작해 4월 말에 절정에 달한다. 4월 하순경 참꽃(진달래)제가 열린다.", - "MNTN_HG_VL" : "1083", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 옥포면ㆍ유가면ㆍ가창면, 경상북도 청도군 각북면", - "MNTN_NM" : "비슬산" + "DETAIL_INFO_DTCONT" : "강원도 철원군 근남면, 화천군 사내면 경계에 우뚝 솟은 한북정맥의 산이다. 복주산이란 산명은 그 옛날 세상이 물에 다 잠겼을 때, 이 산 꼭대기만 복주께(사발) 뚜껑만큼 남았다고 해서 이름 붙여졌다고 전한다. 대체로 산행은 SBS 청석골세트장이 있는 매월동마을 또는 한북정맥의 시작점인 수피령에서 시작한다. 산행 중에 만나는 ‘매월대’는 매월당 김시습이 바둑판을 그리고 바둑을 두었다고 하여 이름 붙여진 바위를 가리킨다. 높이 20미터의 매월대폭포는 겨울철이면 빙벽등반을 하는 이들이 즐겨 찾는 곳이다. 복주산은 복계산과 연계하여 산행이 이루어지는 것이 대부분이며, 군사지역의 최전방인 철원에 위치한 만큼 등산로 곳곳에 참호시설을 비롯한 군사시설물들로 가득 차 있어 적설량이 많은 겨울철 산행에는 조심해야 한다. 간간이 만나는 바위 구간에는 로프가 설치되어 있으며, 891.9봉과 실내고개 갈림길에 위치한 1014미터 봉우리는 주변 산록을 조망할 수 있는 훌륭한 전망대 역할을 한다.", + "MNTN_HG_VL" : "1152", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면·화천군 사내면", + "MNTN_NM" : "복주산" }, - "longitude" : 128.52333329999999, - "latitude" : 35.715555600000002 + "longitude" : 127.5027778, + "latitude" : 38.203888900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "231", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", - "MNTN_NM" : "비조봉" + "DETAIL_INFO_DTCONT" : "종현산은 신북면 덕둔리 북쪽에 우뚝 솟아 있으며 경기 포천 산악지역의 상징적 존재이기도 하다. 그러나 경기도의 소금강이라 불리는 소요산(532m) 북쪽에 인접한 산으로 유명한 산과 이웃해 있고 교통이 불편하다는 이유로 사람들 사이에 많이 알려지지 않은 산이다.높이 600미터도 못 미치는 낮은 산이지만 기암괴봉과 아기자기한 계곡미가 일품이며 온 산을 뒤덮은 활엽수림과 덩굴숲이 아늑한 분위기를 자아내 조용한 산행을 즐기기 좋다. 능선에서 내려다 보는 경치는 여느 산 못지 않게 아름답다.종현산 기슭에 삼정골이라는 취락이 있는데 조선 초기 난을 피하여 세 정승이 이 곳에 와 은거하면서 외부와의 접촉을 일체 끊고 산수를 벗삼아 일생을 살았다 하여 삼정골이라 부르게 되었다는 전설이 전해지고 있다. 병풍처럼 둘러싸여 있는 계곡에는 산내천이 서류하여 한탄강으로 흘러 내려간다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 청산면", + "MNTN_NM" : "종현산" }, - "longitude" : 126.1304785, - "latitude" : 37.219784599999997 + "longitude" : 127.1233601, + "latitude" : 37.980375600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "762", - "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", - "MNTN_NM" : "비학산" + "DETAIL_INFO_DTCONT" : "황석산이 위치해 있는 함양은 '썩은 갈치가 다 모이는 곳' 이라 할만큼 상대적으로 교통이 불편한 곳으로 사람의 발길을 덜 타는 오지이다. 그래서 이 산은 손때 묻지 않은 자연미를 그대로 보존하고 있는 곳이다.황석산 정상부로 가는 길은 억새능선이 장관을 이루고 정상부에 이르면 쌍립한 암봉의 멋스러움이 등산의 피로를 어루만져준다. 인접한 거망산 종주길도 경관이 일품인데 그 사이사이에 위험한 암릉길이 있으므로 20m정도의 보조자일을 준비하는 것이 안전하다.", + "MNTN_HG_VL" : "1193", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", + "MNTN_NM" : "황석산" }, - "longitude" : 129.2891482, - "latitude" : 36.196548900000003 + "longitude" : 127.7574192, + "latitude" : 35.656779499999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "710", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", - "MNTN_NM" : "뾰루봉" - }, - "longitude" : 127.42475520000001, - "latitude" : 37.710080900000001 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "낙동정맥이 백병산(1259m)을 빚고 육백산(1244m), 응봉산(1267m)을 지나 솟구친 산이 사금산이다. 이 산은 사금이 많이 난다고 해서 이름도 사금산이라 붙여졌다.고사목이 보이는 서쪽 무넹이골 사면을 지나면 1085m봉이 나타나는데 곧장 올라서지 않고 오른쪽 사면을 비켜나가면 그 아래 노송이 군락을 이루고 있어 쉬어가기 좋다. 산 정상에서는 북으로 응봉산 육백산이 펼쳐져 있고 그 너머로 낙동정맥이 기다랗게 도열해 있다.", - "MNTN_HG_VL" : "1092", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 원덕읍", - "MNTN_NM" : "사금산" + "MNTN_HG_VL" : "229", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군", + "MNTN_NM" : "목령산" }, - "longitude" : 129.16611109999999, - "latitude" : 37.205833299999988 + "longitude" : 127.4357262, + "latitude" : 36.735338599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "사달산은 노추산과 마주보고 있으며 산세는 동서로 6km에 걸쳐진 산이다. 노추산의 남쪽 봉우리가 바로 사달산(四達山)이다. 성현(聖賢) 네 분이 나신다는 산이다. 사통팔달 길이 사방으로 통한다는 이 사달산에서 공부를 하면 학문에 통달하게 되는데 지금까지 설총, 율곡, 인회 같은 이가 학문을 닦았다한다. 설총과 이율곡 선생이 동국십팔현(東國十八賢)의 반열에 올랐으니 앞으로 두 분의 성현(聖賢)이 더 나실 거라고 사람들은 믿고 있다.", - "MNTN_HG_VL" : "1187", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉, 정선", - "MNTN_NM" : "사달산" + "DETAIL_INFO_DTCONT" : "은석산은 천안시 북면과 병천면에 경계해 있는 높이 455미터 산이다. 산 남쪽엔 신라 문무왕 때 원효대사가 세웠다는 은석사가 있어 예로부터 시인묵객들이 많이 찾았다 한다. 또 사찰 입구엔 백여명이 앉아 쉴 수 있는 반석이 있다.남동쪽 계곡에는 도동서원이 있었던 서원마을이 자리하고 있다. 마을 이름이 ‘서원’인 것은 그 마을에 서원으로는 유일하게 도동서원이 자리하면서 마을 이름까지 서원으로 붙였다고 한다. 이 서원에선 김일손과 목천현 출신 유학자 황종배가 배출되었다고 한다.은석사를 지나면 어사로 유명한 영성군(靈城君) 박문수(1691~1756)의 묘가 있다. 암행어사 박문수는 1727년 정미환국으로 소론이 득세하자 사서에 등용되어 영남 암행어사로 나가 부정관리들을 적발했다. 이듬해 이인좌의 난 때는 종사관으로 출전, 전공을 세워 경상도 관찰사에 발탁되고, 분무공신 2등에 책록되어 영성군에 봉해졌다. 군정과 세정에 밝았으며, 암행어사 때의 많은 일화가 전해지고있다.또 은석산은 불개미로 유명한데 송충이의 천적으로 숲을 보호하는 역할을 한다. 은석산 남쪽에는 병천암이라는 커다란 바위가 있는데 천안시알파인클럽에서 이 바위에 등반길을 개척했다. 코스는 좌벽, 우벽, 중앙벽 등 3면으로 나뉘며 난이도는 5.8급에서 5.12급까지 다양하게 있다.", + "MNTN_HG_VL" : "455", + "MNTN_LOCPLC_REGION_NM" : "충남 천안시 북면ㆍ병천면", + "MNTN_NM" : "은석산" }, - "longitude" : 128.77932329999999, - "latitude" : 37.543793399999998 + "longitude" : 127.28273969999999, + "latitude" : 36.781580200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 괴산군 청천면에 위치한 사랑산의 본 이름은 제당산이다. 사기막리의 제당골에 제당이 있어 ‘제당산’이라 불리던 것이 10년 전, ‘사랑의 영원성’을 상¡하는 연리목(連理木)이 발견되면서 괴산군청에서 산 이름을 ‘사랑산’이라 바꿔 부르게 되었다. 이 연리목은 산림청으로부터 천연보호수로 지정되었다.사랑산은 아기자기한 산이다. 초보 산행자를 위한 안성맞춤 대상지로 산길이 그리 비탈지지 않고 산행시간은 2~3시간이면 족하다. 등산로가 희미한 곳이 더러 있지만 바위와 흙길이 골고루 나 있어 산행이 지루하지 않다. 조망하기 좋은 전망바위도 곳곳에 나타나 산행의 심심함을 달래준다. 이름 그대로 코뿔소 한 마리가 서 있는 듯한 코뿔소바위, 뽀뽀를 하면 사랑이 이루어진다는 사랑바위 등이 산행의 재미를 더해준다. 사랑산을 상¡하는 연리지는 사기막리와 인접한 송면리에 있다. 그 아래에는 용추폭포가 있는데 더위를 식히기에 더없이 좋다.", - "MNTN_HG_VL" : "647", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", - "MNTN_NM" : "사랑산" + "DETAIL_INFO_DTCONT" : "충북 단양군에 위치한 선미봉은 착한 산이라는 뜻의 착할 선자에다 산의 순수한 우리말인 `뫼'자를 붙여 선뫼봉으로 불리다가 오늘에 이르러서는 뫼가 아름다울 `미'로 변해 붙여진 이름이다.산이 착하다니 무슨 뜻일까. 착한산이라서 등산로마저도 편할 것 같지만 그동안 등산인들의 발길이 거의 미치지않아 등산로에는 잡목과 낙엽으로 원시림을 방불케한다. 정상에 오르면 서북쪽 풍광이 가장 먼저 시선을 끈다.선미봉과 맥락을 같이 하는 수리봉, 황정산, 도락산 정상이 시야에 와 닿고 동쪽으로는 멀리 도솔봉 부터 백두대간을 끌고온 시루봉과 촛대봉 그리고 저수령 아래로 거대한 분화구처럼 움푹패어든 목장지대가 그림처럼 펼쳐진다.", + "MNTN_HG_VL" : "1080", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 대강면", + "MNTN_NM" : "선미봉" }, - "longitude" : 127.85463129999999, - "latitude" : 36.703488900000004 + "longitude" : 128.33677549999999, + "latitude" : 36.845008499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : " 사룡산은 오봉산과 부산성으로 연결되는 군사적 요충지로서 신라시대 병사들이 이산을 거점으로적을 물리쳤다고 한다. 정상부근에는 음식을 날로 먹는 사람들이 모여 사는 곳이라고 하여 생식마을이 있고, 1300여년 전에 원효대사가 초창했다는 금정사가 있다. 한무당재에서 사룡산까지는 경주와 영천시의 경계지역이며, 낙동정맥 11구간으로 이구간에는관산과 만불산이 있으며, 대체로 오르 내림이 없는구간이나 형제지(형제목장고개)에서 사룡산까지는 계속 오르막길로 진땀을 빼는 구간이다. 전망대 바위에서 경주시 서면 소재지를 내려다 보면 아름다운 우리 강산임을 실감나게 하고,구간 구간에는 진달래 숲길과 산 벚꽃이 이어져 아름다움을 더 해준다.", - "MNTN_HG_VL" : "686", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 산내면, 영천시 북안면", - "MNTN_NM" : "사룡산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "296", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 용강동", + "MNTN_NM" : "소금강산" }, - "longitude" : 129.0133333, - "latitude" : 35.846388900000001 + "longitude" : 129.23158000000001, + "latitude" : 35.861976599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "사명산은 정상에서 양구, 화천, 춘천과 멀리 인제군 등 네 곳의 고을을 조망할 수 있다고 해서 이름 붙었다. 춘천에서 배후령을 넘어 추곡약수를 지나면 사명산 산행들머리인 웅진리와 선정사가 보인다. 계곡의 등산로를 따라 두 시간 정도 오르면 파로호가 내려다보이는 주능선에 닿고 거기서 널찍한 평지를 이룬 정상까지는 멀지 않다.정상에 서면 화천댐으로 형성된 파로호가 화천과 양구에 걸쳐 넓게 펼쳐진 시원한 풍광이 눈맛을 시원하게 한다. 파로호 건너 우뚝한 화천 일산(1190.3m)이 육중한 산세를 자랑하며 솟았고, 멀리 설악산과 점봉산 등도 눈에 들어온다. 남쪽으로 소양호와 어울린 오봉산도 잘 보인다.봄이면 진달래가, 가을날엔 단풍이 아름답다. 설경 또한 장관을 이뤄 겨울산행지로도 인기 높다. 문바위, 첩바위 등 볼거리들이 걸음을 즐겁게 하는 사명산 남쪽 약수골에는 우리나라에서 손꼽히는 ‘추곡약수’가 있다.", - "MNTN_HG_VL" : "1198", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면, 양구군 양구읍", - "MNTN_NM" : "사명산" + "DETAIL_INFO_DTCONT" : "봉각산이라 불리기도 하는 검각산은 그 이름에 걸맞게 산봉우리가 창을 맞대어 세워놓은 듯한 풍모를 가지고 있다.영월의 팔경 가운데 하나인 `검각창송'이란 평창강과 주천강이 합해져 서강이 되어 단종의 슬픈 역사를 담은 청령포를 지나 남한강으로 흘러가는 어귀에서 그 강물과 어우러지는 이 산의 빼어난 자태를 칭송한 것이다. 이 산에는 소의 뿔에서 땀이 날 정도로 험하고 넘기 힘들다는 각한치가 있는데, 억새가 빼곡이 서있는 풍경에 홀려 힘든 것도 모르고 가게 된다.", + "MNTN_HG_VL" : "505", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 남면", + "MNTN_NM" : "검각산" }, - "longitude" : 127.9064195, - "latitude" : 38.077294899999998 + "longitude" : 128.4233333, + "latitude" : 37.184166699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 단양군 단성면 회산리와 장회리의 경계를 이루고 있는 사봉은 금수산, 소백산, 도락산 등 주변의 명산들과 함께 단양의 풍광을 연출하는 아름다운 산이다. 그러나 단양팔경의 절경과 다른 산들의 유명세에 가려 일반인들은 물론 산악인들에게도 잘 알려지지 않은 편이다. 물론 이 때문에 한결 여유롭고 아늑하게 산행을 즐길 수 있다는 이점도 있다.사봉은 일명 물레봉이라고도 하는데 옛날 홍수 때 물레만큼 남았었다하여 부르게 된 산명이라 전해오고 있다.특히 이 산 정상에는 일본인들이 한반도의 혈맥을 막기 위해 박아 놓은 쇠말뚝이 있어 역사의 기구함을 느끼게 하고 있다. 사봉 주위에는 단양팔경 중 4경의 절경들이 펼쳐져 있어 산행 후의 주변 관광을 빼 놓을수 없다.", - "MNTN_HG_VL" : "879", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", - "MNTN_NM" : "사봉" + "DETAIL_INFO_DTCONT" : "경상남도 거제시 장목면 대금리와 연초면에 있는 산으로 대금산이란 이름은 신라시대에 쇠를 생산했던 곳이라 하여 붙여진 것이다. 그리 높지 않은 산이지만 산세가 순하고 비단폭 같은 풀이 온 산을 덮고 있어 크게 비단을 두른 산이라는 뜻의 같은 이름으로 불리기도 한다.더구나 호위봉인 358미터, 285미터의 중봉이 이 산에 비해 낮기 때문에 상대적으로 우뚝해 보이고 정상이 바위 봉우리라 실제 높이보다 우람하고 드높게 보인다.중봉을 가리켜 중금산이라고도 하며 조선 말기에 축성한 성이 있는데 대금, 시방, 율천 등 3개 마을 주민들이 성을 쌓고 군량을 저장하여 남해안의 각 진에 공급하는 일에 함께 참여했다는 산성이다. 이곳에는 약수터와 기우제를 올리던 제단이 있고 약수터에는 칠석과 보름에 많은 사람들이 찾아와 목욕하고 음용하기도 한다. 멀리서 보면 잘생긴 여인이 아기를 품은 듯한 이 산은 봄이면 진달래가 온 산을 붉게 불태우고, 정상에서 본 중금산성과 소금산성은 마치 여인의 젖가슴과 같이 생겼고, 어머니의 품속에서 소록소록 잠을 자는 아기와 같은 형국을 하고 있다.최근에는 산 중턱까지 도로가 뚫려 자동차로 오를 수도 있어 일요일이면 사람들로 붐빈다. 산행은 장목면 시방(일명 살방)에서 붓골을 거쳐 정상에 오르는 것이 대표적 코스며 정상에 오르면 멀리 대마도와 부산, 마산, 진해가 눈 아래 있음을 느낄 수 있다.", + "MNTN_HG_VL" : "439", + "MNTN_LOCPLC_REGION_NM" : "거제도 연초면ㆍ장목면", + "MNTN_NM" : "대금산" }, - "longitude" : 128.28194439999999, - "latitude" : 36.907499999999999 + "longitude" : 128.69916670000001, + "latitude" : 34.949444399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장흥과 보성의 진산인 사자산은 곰재를 사이에 두고 제암산(779)과 마주보고 있다. 철쭉으로 유명한 '화산(花山)' 으로 해발은 낮으나 바닷가의 산이 다 그러하듯이 내륙의 산과 달리 웅장한 산세를 갖추고 있다. 사자산 정상 주변은 나무가 없이 억새와 바위로 완만한 능선을 이루고 있어 남쪽 발아래로 확 트인 남해바다의 풍경을 볼 수 있다.장흥벌을 향하여 울부짖는 사자형상으로 일컬어지는 사자산(獅子山 666m) 은 제암산, 억불산(518m)과 더불어 장흥의 삼산으로 꼽히는 명산이다 . 장흥읍쪽 봉이 사자머리 같다하여 사자두봉, 정상은 남릉과 더불어 꼬리같다고하여 사자미봉으로 불린다. 장흥벌에 솟구친 사자산은 철따라 다양한 모습을 보여준다.봄이면 파르한 기운이 스며 들면서 생명의 신비함을 느끼게 하고 여름이면 푸른 초원으로 변하고 가을이면 억새가 날리면서 강렬한 인상을 주는 산이다 사자두봉에서 사자미봉까지 이어지는 약 2km의 능선은 부드러움과 거친 자연미를 느낄 수 있다 .특히 남서면의 기암 절벽은 설악산의 어느 암릉에도 뒤지지않을 정도로 웅장하고 힘찬 자연미를 보여준다. 주능선 중간쯤의 안부와 능선 남쪽 사면은 전국에서도 유명한 활공장이다.", - "MNTN_HG_VL" : "666", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군, 보성군", - "MNTN_NM" : "사자산" + "DETAIL_INFO_DTCONT" : "서산 팔봉산(361.5m)은 금북정맥의 금강산(361.1m)에서 분기한 지능선의 한 줄기로 금강산 서북쪽 바로 건너편에 천혜의 절경을 자랑하며 8개의 봉우리로 솟아있다. 400미터도 되지 않는 낮은 산이지만 아기자기한 암릉과 조망이 일품이다. 능선에 오르면 북쪽으로 오밀조밀한 해변이 한눈에 들어오고 차분하게 가라앉은 주변의 정취가 한 폭의 멋들어진 수채화 같다. 서해안에 접한 이곳은 특히 바위에 노을이 물드는 저녁 시간의 풍경이 장관이다.산의 위치도 바다를 조망하기 좋은 위치이며, 아담한 암릉이 주는 고즈넉한 산세는 백제인의 미소처럼 소탈하다.팔봉산 산행 가운데는 제1봉에서 제3봉 사이에 펼쳐진 암릉 구간이 백미다. 암릉을 오르내리며 걷다보면 수석처럼 현란한 바위의 조화에 절로 탄성이 터져 나온다. 예전에는 아슬아슬한 바위타기가 재미를 더했지만, 지금은 서산시에서 위험한 곳에 철계단을 설치하여 가족산행을 하기에 무리없다. 남녀노소 누구나 안전하게 팔봉산의 바위 능선을 감상할 수 있다.팔봉산만 돌아보고 내려오는데는 3시간 정도면 충분하다. 산행이ordf;다고 느껴지는 사람들은 제8봉에서 산이고개를 거쳐 금강산과 장군산으로 산행을 이어가며 구간을 늘일 수도 있다.", + "MNTN_HG_VL" : "362", + "MNTN_LOCPLC_REGION_NM" : "충남 서산시 팔봉면", + "MNTN_NM" : "팔봉산" }, - "longitude" : 126.9809063, - "latitude" : 34.683520700000003 + "longitude" : 126.3708271, + "latitude" : 36.810449699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 영월군 수주면과 횡성군 안흥면이 경계를 이루는 사자산은 지능인 연화봉 석굴에 많이 있었다는 꿀과 먹을 수 있는 흙인 전단포, 칠기의 도장 재료인 옻나무와 산삼등 네가지 재보가 많이 나기 때문에 일명 사재산(四財山)이라고 불리었다 한다. 일설에는 금.은.동이 많이 채굴되어 그렇게 부른다고도 한다.절골을 사이에 두고 백덕산(1,350m)과 마주한 이산은 남쪽 능선 끝자락으로 그림처럼 수려한 구봉대산(870)을 위시해 곳곳에 기암과 폭포를 가지고 있으며, 골이 깊어 많은 수량과 청정함을 유지하고 있어 고찰 법흥사와 조화를 이룬 산이다. 특히 겨울이면 많은 적설량에다 곳곳에 설화가 만발해 사자산을 찾는 등산객들에게 풍부한 아름다움을 선사한다.또한 등산로 경사가 완만해 가족단위 등산로로는 일품이다. 정상에 서면 가리왕산과 오대산의 산군이 물결치듯 보인다. 남쪽으로는 소백산의 고운 산줄기와 서쪽으로는 치악산맥이 한눈에 들어 온다.", - "MNTN_HG_VL" : "1181", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면, 횡성군 안흥면", - "MNTN_NM" : "사자산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "274", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군, 경상북도 칠곡군", + "MNTN_NM" : "마천산" }, - "longitude" : 128.2825, - "latitude" : 37.406111099999997 + "longitude" : 128.46111110000001, + "latitude" : 35.899722200000006 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제주도의 산중에서 가장 유명하고 경치가 빼어나며 신비스러운 분위기가 서린 곳으로, 반드시 찾아가봐야 하는 곳이 바로 산방산이다. 한라산 봉우리를 뽑아 옮겨 놓은 것이 산방산이고, 그 뽑힌 자리가 백록담이 되었다는 이야기가 있듯이 설화 속의 산방산은 수려한 용모가 단번에 찾는 이의 눈길을 빼앗을 정도로 아름답다. 매우 가파라서 오르기가 힘이드나 일단 오르고 나면 정상에서 바라보는 그 경치는 모든 피로감을 충분히 보상하고도 남으며 한번 오른 이는 다시 오르고 싶은 마음이 절로 나는산이다.또한 조면암질 안산암으로 구성되어 있으며 그 형태가 특이하다. 남서쪽 기슭, 해발고도 200m 지점에 산방굴(山房窟)이라는 자연 석굴이 있다. 그 안에 불상을 안치하였기 때문에 이 굴을 산방굴사(山房窟寺)라고도 한다. 굴 내부 천장 암벽에서 떨어지는 물방울은 산방산의 암벽을 지키는 여신 ‘산방덕(山房德)’이 흘리는 사랑의 눈물이라는 전설이 있다. 산의 남쪽 해안에는 성산포층(城山浦層)이 노출되어 있고 심한 해식(海蝕)으로 단애(斷崖)가 형성된 암석해안을 이룬다. 여기에 하멜 표류 기념탑(漂流記念塔)이 있다.", - "MNTN_HG_VL" : "507", - "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 안덕면", - "MNTN_NM" : "산방산" + "DETAIL_INFO_DTCONT" : "예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.", + "MNTN_HG_VL" : "1434", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 강릉시 연곡면", + "MNTN_NM" : "오대산 동대산" }, - "longitude" : 126.3134467, - "latitude" : 33.241068200000001 + "longitude" : 128.59833330000001, + "latitude" : 37.7744444 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "산성산" + "DETAIL_INFO_DTCONT" : "고흥읍에서 율리치를 지나 고개를 넘어 송정리로 들어서면 천등산과 벼락산이 한눈에 든다. 천등산 정상부와 함께 겹쳐 보이는 바위산이 그 앞에 보이는데, 이 산 이름은 딸각산이다.바위를 밟고 오르노라면\"딸각딸각\"소리가 난다 해서 그곳 주민들은 그렇게 부른다고 한다. 그러나 옛 기록에는 월각산(月角山)이라 기록하고 있다.\"딸각\"이\"달각\"으로, 달각이 월각으로 변한 것이다. 산행은 산 중턱을 가로 넘는 임도가 세 가닥이 나 있어 어떤면에서는 쉽게 오를 수 있는 산이지만 임도 때문에 오히려 산행의 맛이 덜할 수도 있다.", + "MNTN_HG_VL" : "420", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", + "MNTN_NM" : "딸각산" }, - "longitude" : 128.59083330000001, - "latitude" : 35.810000000000002 + "longitude" : 127.2780763, + "latitude" : 34.541848000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "순창군과 담양군의 경계를 이루며 강천산(584m)과 형제처럼 솟아있는 산성산은 비록 그 높이는 낮지만 공룡등처럼 이어져있는 능선길을 따라 곳곳에 널린 유적과 절경을 감상하는 것만으로 산행의 즐거움을 충분히 챙겨갈 수 있는 그런 산이다. 이 산에 축조된 산성 때문에 산성산이라 이름 붙여졌다 하며, 일명 금성산이라고 불리는데 이는 금성면에 위치해 있기 때문이다.산성산은 해발 600m에 가까운 철마봉의 절벽에서 시작된, 연대봉, 운대봉, 시리봉 등 사방 계곡의 능선을 이용하여 축조한\"\"금성산성\"\"으로서 강천산 줄기가 서남으로 뻗어 담양군과 순창군의 경계를 이루고 각 봉우리마다 웅장한 암봉으로 이루어져 있다. 철마봉에서 서쪽으로 조망되는 담양호, 추워란의 위용 석양의 노을진 경관이 볼 만하다.", - "MNTN_HG_VL" : "603", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군, 전라남도 담양군", - "MNTN_NM" : "산성산" + "DETAIL_INFO_DTCONT" : "축령산은 전남 장성과 전북 고창의 경계를 이루는 산으로 노령 지맥 위에 솟아 있다. 장성에서는 편박나무숲 기슭을 축령산이라 부르고 문수사에서는 청량산이라고도 부른다. 축령산은 6.25 전쟁 등 민족적 수난기에 깊은 상처를 받기도 한 산이지만 현재 축령산 남서쪽 산록은 유럽풍의 잘 조림된 침엽수림 지대를 연상케 한다.삼나무, 편백, 낙엽송, 리기다소나무 등 수령 5~50년생의 숲이 널찍하게 바다를 이루고 있으며 주변엔 천연림인 상수리, 졸참나무, 떡갈나무 등이 둘러싸고 있다.이렇듯 축령산이 세상에 알려진 것은 산을 두르고 있는 숲 덕분이다. 숲을 배경으로 영화 ‘태백산맥’, ‘내마음의 풍금’과 드라마 ‘왕초’도 촬영됐다. 하지만 축령산의 숲은 사람에 의해 인공적으로 만들어졌다. 일제시대를 겪으면서 완전히 헐벗었던 산이 지금의 모습이 되기까지 애쓴 분은 춘원 임종국 선생이다. 1956년부터 시작된 육림의지는 선생이 세상을 떠난 1987년까지 계속됐다.편백과 삼나무가 주를 이루는 축령산휴양림은 오후 1시부터 3시 사이에 산책하는 것이 좋다. 나무별로 피톤치드가 활발히 생성되는 시간이 다른데 편백과 삼나무의 피톤치드 활성 시간이 오후 1~3시 사이다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "전북 고창군 고수면, 전남 장성군 서삼면", + "MNTN_NM" : "축령산" }, - "longitude" : 127.0391056, - "latitude" : 35.379716700000003 + "longitude" : 126.7291354, + "latitude" : 35.368435099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "달성군에서는 비슬산 정상을 제외한것 중 가장 높은 구역으로 지형과 지세가 험한 곳이 있으나 그만큼의 자연경관과 조망권을 자랑합니다. 초보들에겐 다시 힘겨운 곳이긴 하나 정상 부근에 올라가면 그 동안의 힘든 고통은 조망권 하나만으로 모든 것이 잊혀 질듯합니다. 하지만 주 등산로 외엔 혼자서의 산행은 위험하니 주의를 요한다.", - "MNTN_HG_VL" : "654", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 유가면", - "MNTN_NM" : "산성산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "899", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", + "MNTN_NM" : "대룡산" }, - "longitude" : 128.59083330000001, - "latitude" : 35.810000000000002 + "longitude" : 127.8202778, + "latitude" : 37.844999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼문산(三門山)은 전남 완도군 약산면을 이루는 조약도 최고봉이다. 조약도로 가는 뱃길은 완도가 아닌 강진군 마량에서 배를 탄다. 조약도는 지형도에 표기되어 있는 행정지명이지만, 이곳 섬 주민들은 '약산도'로 부른다. 그래서 마량나루에 정박해 있는 조약도행 배에도 ‘약산’이라 붙어 있다.삼문산이라는 이름의 유래는 이렇다. 옛날 주능선 동쪽 분지인 삼개문(일명 삼감안)에서 땔감으로 쓰는 초나무나 풀을 베어 지게에 메고 서쪽 천동나루 방면으로 넘어올 때 망봉과 등거산 사이 움먹재나 망봉과 장룡산 사이 파래밭재와 큰새밭재를 넘어다녔다. 즉 세 고개를 세 문(門)으로 보았던 것이다.평범한 육산인 삼문산에 토끼바위, 쟁기바위, 부엉이바위 같은 특이한 모양의 바위들이 변화를 꽤한다. 그러나 삼문산의 매력은 사방으로 펼쳐지는 남해 바다와 여기에 떠 있는 다도해의 그림 같은 풍경에 있다. 삼문산 봉화대는 고금진의 망덕산, 신지진의 상봉, 가리포진(현재의 완도) 상황봉, 장흥 천관산으로 봉화를 하던 송신소 같은 곳이다.", - "MNTN_HG_VL" : "397", - "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 완도읍 약산면", - "MNTN_NM" : "삼문산" + "DETAIL_INFO_DTCONT" : "서대산의 높이는 904.1m이다. 충청남도 남동부의 금강분지를 둘러싸고 있는 금산고원에 속해 있으며, 노령산맥을 이루는 정수이자 충청남도의 최고봉이다. 충남에서는 높이 904.1m으로 가장 높은 산으로서 기암 절벽으로 이루어져 있다.화강암으로 이루어진 원추형 암산인 서대산은 기암절벽과 숲이 어우러지고 제법 험준해 산행의 묘미를 더한다. 정상에 올라서면 웅장하고 온화한 산세가 한눈에 들어오고 멀리 서북쪽으로 대전시내가 펼쳐진다.원흥사, 개덕사등 유명사찰과 정상 직전에 직녀 탄금대, 정상에서 북쪽 546봉으로 이어지는 능선 주변에는 장면대, 북두칠성 바위, 사자굴, 쌀바위 등이 산재해 있다.협곡을 가로 질러 높게 설치된 약 50m의 구름다리 주변은 신선바위, 벼슬바위등 기암 절벽들이 어울려 장관을 이루고 있다.", + "MNTN_HG_VL" : "904", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 추부면ㆍ군북면, 충청북도 옥천군 군서면", + "MNTN_NM" : "서대산" }, - "longitude" : 126.9094444, - "latitude" : 34.381388899999997 + "longitude" : 127.5357582, + "latitude" : 36.230901199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼방산은 남방산으로도 불리우며 강원도 평창군 평창읍 노론리와 미탄면 창리, 영월군 북면 공기리 사이에 있는 산이다. 푸른 숲을 간직하고 있는 산으로 옛부터 산과 나물의 고장으로 잘 알려진 강원도에 자리를 잡고 있어 산나물 산행지로 제격이다. 산행은 멧둔재를 중심으로 이루어지고 있으며 멧둔재는 삼방산의 동북능선을 형성하고 있다.평창읍 내에서 남동쪽 평창강 건너로 하늘금을 이루어 보이는 삼방산 이름의 의미는, 옛날 중요한 통로를 이루는 지역에는 대개 세 지점에 통행인을 검사하는 관방이 설치되어 있었던 데서 유래한다. 커다란 종 모습의 산으로, 평창읍을 자연성곽처럼 감싸고 있다.정상은 수림에 둘러싸여 동쪽을 빼고는 조망이 잘 되지 않으며, 대신 산을 내려오다 보면 900m봉을 지나 전망이 좋은 평야지대가 있다. 이곳에서는 평창 시가지 뒤로 옛날 숯가마가 있었다는 숯고개 너머로 장암산, 노성산이 보이고 멀리로는 배너미산, 무등산이 보이며 왼쪽으로는 종부리 마을을 휘감은 평창강과 수장산, 백덕산, 사재산 등이 바라보인다. 평창강변은 캠핑장소로 적합하며 부근에 이승복기념관, 오대산국립공원이 있다.", - "MNTN_HG_VL" : "980", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", - "MNTN_NM" : "삼방산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "704", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시", + "MNTN_NM" : "기양산" }, - "longitude" : 128.4325, - "latitude" : 37.339444399999998 + "longitude" : 128.15472220000001, + "latitude" : 36.295277800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼방산 산행은 태백시를 기점으로 한다. 시내버스를 타고 철암 방터골 입구 버스정차장에서 하차하여 동쪽으로 깊게 패인 방터골을 걸으면 넓은 길이 점점 좁아지며 계류도 맑아져 갑자기 깊은 산 속에 들은 기분이 든다. 실제 이곳은 태백시의 오지이다.징검다리 건너기를 여러번, 여유 있는 걸음으로 1시간 10여분 후면 원심이골 입구다. 입구에는 쌍소나무와 태백여성산악회 표지기가 있다. 원심이골에서 20분가면 합수점인데 합수점 사이 능선 대밭고리를 40분 올라 주능선 안부 전개목에 닿아 오른쪽으로 15분 능선을 따르면 늪지가 나타난다. 여기서 남쪽으로 방향을 꺾어 늪지를 내려서면 지르뫼어이 안부다. 지르뫼어이 바로 남쪽 둥그런 봉이 정상이다.하산 30분 후 돌탑에 이르러서부터는 독도에 신경을 써야 한다. 돌탑에서 육송정까지 약 2 시간 걸린다. 방터골에서 원심이골 정상을 거쳐 태백시계를 따라 육송정에 이르는 총산행 시간은 5시간 이상 소요된다.", - "MNTN_HG_VL" : "1175", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", - "MNTN_NM" : "삼방산" + "DETAIL_INFO_DTCONT" : "천주산은 자체로도 녹록치 않은 높이를 자랑하지만 주변에 버금갈 만한 산이 없어서 더욱 뛰어난 상승감을 준다. 분지로 둘러싸인 창원을 굽어보는 진달래 명산으로, 지리산 영신봉(1652m)에서 김해 신어산(631m)을 지나 낙동강 하구에 그 꼬리를 담그는 232킬로미터의 낙남정맥에 솟은 수많은 산 가운데서도 단연 돋보이는 명산이다.천주산의 주봉은 용지봉으로 주변 일대에 진달래가 군락을 이루어 있다. 조망이 시원한 정상에서는 무학산에서 정병산 지나 비음산, 용지봉까지 이어지는 낙남정맥이 마산과 창원을 감싸며 꿈틀거리듯 뻗어가는 장쾌한 모습을 감상할 수 있으며, 웅장한 산세에 둘러싸인 아름다운 도시 마산과 창원, 진해도 한눈에 볼 수 있다. 무학산과 마산 앞바다, 북쪽으로 철새들의 낙원인 주남저수지와 그 일대 들판도 그림처럼 펼쳐진다.", + "MNTN_HG_VL" : "640", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 마산회원구 구암동, 의창구 북면", + "MNTN_NM" : "천주산" }, - "longitude" : 129.07030929999999, - "latitude" : 37.084382499999997 + "longitude" : 128.59073989999999, + "latitude" : 35.271812500000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "치악산국립공원에 속하는 삼봉은 치악산 정상인 비로봉(1288)에서 서북쪽으로 이어지는 능선 상에 솟아 있는 산이다. 삼봉을 지나면서부터 1km 간격으로 투구봉(1,002m), 토끼봉(887m)이 이어져 있다.삼봉에서 짜릿한 묘미를 즐기려는 이들은 낚시봉 코스를 선호한다. 삼거리에서 지능선으로 20분 오르면 약수터가 반기는 절터에 닿는다. 이 절터에서는 거리 100m를 두고 두 개의 샘이 있다. 그러나 관리가 되지 않아 늦가을이나 겨울에는 물에 낙엽이나 이물질들이 담기거나 얼어붙어 크게 기대할 것은 못된다. 두번째 샘터에서 숲속으로 15분 가량 올라가면 동쪽으로 이어지는 능선길을 밟는다. 이 능선길을 오르다가 참나무숲을 벗어나면 바윗길이 나타나기 시작한다. 바윗길은 급경사 바위를 피하느라 능선 좌우로 횡단하며 이어진다.삼각점(89년 재설)이 박혀있는 정상에서 휘둘러보는 조망은 막힘이 없다. 먼저 동으로는 도실암골 건너로 석탑 3기가 마치 쇠머리에 돋아난 뿔처럼 보이는 치악산 정상 비로봉이 천지봉과 함께 시야에 들어온다. 비로봉 정상에 오른 등산인들의 움직임도 뚜렷하다. 남쪽으로는 향로봉 능선이 꿈틀거린다. 향로봉에서 오른쪽 멀리로는 남대봉과 백운산이 하늘금을 이루고, 백운산 방향에서 오른쪽 아래로는 원주시내가 한눈에 내려다보인다.서쪽 조망도 일품이다. 흥양리 분지로 패어내린 범골, 밤나무골, 삼장골, 되미골 협곡이 아찔하게 내려다보이고 흥양리 오른쪽으로는 새말로 이어지는 영동고속도로가 실낱같다. 멀리로는 양평 용문산 정상이 가물거린다.", - "MNTN_HG_VL" : "1073", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시", - "MNTN_NM" : "삼봉" + "DETAIL_INFO_DTCONT" : "태백산 망경대 정상에서 남동편에 위치한 산이다. 소천면 늦재에서 능선 따라 망경대로 이어지는 등산로가 있다. 이 산에는 세계최남단의 열목어 서식으로 유명한 백천계곡이 있고, 산 기슭 중턱에는 사명대사가 수도했다는 홍제사가 있다.태백산을 중심으로 이 산을 비롯해 일대에 1,000m가 넘는 산들만도 9개 봉이나 되어 심산유곡의 자연미를 만끽할 수 있다. 백두대간 갓대배기봉에서 동남으로 갈래친 능선 위에 있고, 소천면 늦재에서 능선을 따라 망경대로 이어지는 등산로가 있다.일대 1억 53만㎡가 청옥산 자연휴양림으로 지정되었는데, 한국의 휴양림 가운데 가장 넓고 물놀이장, 체력단련장, 산막, 야영장, 캠프파이어장 등의 편의시설이 완비되어 있다. 산기슭 중턱에는 유정(惟政)이 수도했다는 홍제사가 있고 산 옆으로 흐르는 고선계곡은 길이 100리에 이르는 깊은 원시림계곡을 이룬다.태백산 문수봉과 청옥산 사이에서 시작되어 조록바위봉까지 이르는 12㎞의 백천계곡은 낙동강의 상류이며 세계 최남단의 열목어(천연기념물 74) 서식지로 유명하다. 일대는 천연기념물 및 천연림 보호지역이므로 출입을 제한한다.그밖에 주변에는 5만 영령위로탑이 세워져 있는 현불사와 오전약수, 우곡약수터, 불영사, 다덕약수관광지, 두내약수관광지, 청량산 도립공원, 사미정(四未亭) 등의 관광지가 있다. 또한 겨울철에는 적설량이 많아 늦은 봄까지 눈을 볼 수 있고, 임도가 넓어 산악스키를 즐기기에 적당하다.", + "MNTN_HG_VL" : "1256", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 석포면, 소천면", + "MNTN_NM" : "청옥산" }, - "longitude" : 128.03805560000001, - "latitude" : 37.370555600000003 + "longitude" : 128.96222220000001, + "latitude" : 37.0433333 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "255", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시", - "MNTN_NM" : "삼봉산" + "MNTN_HG_VL" : "487", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군", + "MNTN_NM" : "봉화산" }, - "longitude" : 128.4447222, - "latitude" : 34.878611100000001 + "longitude" : 127.8758333, + "latitude" : 37.708888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼봉산(1,254m)은 고제면 봉계리에 정상을 둔 거창의 진산(鎭山)으로 산 고스락이 되는 봉우리는 세 개이며 그 중심 봉우리는 흡사 동구앞 돌무지 탑 같고 먼 데서 바라보면 흡사 피어나는 연꽃 모습 같다. 예로부터 소금강이라 부를 만큼 산 경치가 빼어났으며 가뭄이 들때면 삼봉산 금봉암에 있는 용머리 바위에서 기우제를 올리었다. 산기슭 좋은 터에 금봉암(金鳳庵)이라는 절이 있다. 절과 산 모두가 나한도량(羅漢道場)이라 하여 기도처로 이름나 있다. 이 산은 불심(佛心), 산심(産心), 무심(無心)의 삼심이 깃들고 금봉암을 둘러리한 바위무리들은 병풍처럼 둘려쳐 봉황의 산세를 이룬다. 칼바위, 장군바위, 석불바위, 부부봉, 문바위, 투구봉, 용바위, 노적봉, 칠성봉 들이 모두 셋씩 나란히 짝을 짓는다. 세 개의 영험스런 바위 샘물이 솟아나 목을 축일만한 데 모두 신령스럽고 영험스런 샘물이라고 하며 천지인(天地人)을 우러른 삼신사상(三神思想)과 인연이 깊다. 덕유산으로 달리는 큰 줄기에서 동쪽으로 내린 가지에는 시루봉이 솟아 있으며 남쪽 골짜기는 금(金)이 난다. 산행은 크게 두가지로 나뉘는데 갓파르고 낙석의 위험이 있는 칼바위쪽으로 올라 바위굴샘을 거쳐 억새능선을 타고 오르는 코스와 삼성각 오름길에서 북쪽 용바위용굴을 비켜 오르는 능선길 코스가 있는데 8㎞에 3시간정도 소요된다.소요 시간 : 1코스 : 4시간 30분 신풍령 → 4 km(3시간) → 삼봉산정상 → 3km(1시간30분) → 소사재 2코스 : 2시간 10분 금봉암 → 1.4km(40분) → 삼봉산정상 → 1.2km(20분) → 북능 → 3.8km(1시간 10분) → 봉계리 원기동최적 탐방 시기 :사계절볼거리 : 일봉산에서 본 조망 정상부가 세 개의 봉우리로 이루어져 있는데 멀리서 보면 그 모습이 마치 연꽃 봉우리 같이 보인다. 금봉암에서 시작되는 산행은 가파른 바윗길과 안부를 지나면 정상에 이를 수 있다. 정상은 폭이 좁지만 주변 경관은 확 트여 있어 시원한 느낌이 든다. 산행의 기점이기도 한 삼봉암은 1905년 창건된 사찰이다. 전해오는 이야기에 의하면 금봉안 창건주가 지관이 잡아둔 자리에서 가마솥 뚜껑이 덮인 샘물을 마셔가며 백일 단식기도를 드리고 회향하던 날 황금빛 새가 산봉우리와 기도처를 세 번이나 왕복한 후에 어디론가 날아가서 그 자리에 절을 지었다고 한다. 그리고 그 절의 이름을 금봉암이라 하였는데, 사찰의 요사채 뒤편엔 옛날 거창 부사가 기우제를 지내던 용머리 형상의 바위가 있다.숲길 명소 : 산행길에는 억새밭과 잣나무 숲이 펼쳐지고 정상에 서면 덕유산의 웅장한 모습이 펼쳐진다. 정상의 줄기에는 밑둥이 큰 떡갈나무들이 주종을 이루며 특히 겨울의 눈꽃이 볼 만하다.등산객은 거의 없으며, 인근 주민들이 운동삼아 오르는 정도의 작은 산. 비교적 등산로는 잘 되어 있으나, 삼봉산 정상이란 표식이 없어 정상인지 구분이 안감. 산내에 화장실, 음수대가 없어 다소 불편함.", - "MNTN_HG_VL" : "1254", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 고제면", - "MNTN_NM" : "삼봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 북실리", + "MNTN_NM" : "병방산" }, - "longitude" : 127.872652, - "latitude" : 35.892753399999997 + "longitude" : 128.6333333, + "latitude" : 37.348888899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", - "MNTN_NM" : "삼봉산" + "DETAIL_INFO_DTCONT" : "강원도 정선군 남면에 위치한 민둥산은 약수산행과 억새산행, 철도산행지로 유명하다. 이름 그대로 7부 능선을 넘어서면 나무가 거의 없어 민둥민둥한 형세다. 예전에는 ‘한치뒷산’이라 불리던 이곳은, 곤드레, 딱주기나물 등이 잘 자라나도록 하기 위해 일부러 불을 낸 것이, 나무 한 그루 없는 민둥산으로 변하게 했다고 전해진다. 그러나 가을이면 온통 황금빛 억새로 한껏 치장한다. 제주도 동부 오름지대, 창녕 화왕산, 장흥 천관산, 포천 명성산, 밀양 사자평 등과 함께 억새군락지로 손꼽히는 억새평원을 자랑한다. 매년 억새꽃 축제가 열릴 만큼 20만평에 이르는 억새평원은 은빛으로 출렁이고 가을 정취를 만끽하기에 제격이다. 산세는 대체로 완만한 경사를 이루고 있으며, 등산로 정비도 잘 되어 있어 초보자들도 쉽게 오를 수 있다. 민둥산은 정선군 중앙부에 위치하여 동쪽으로 함백산, 남쪽으로 백운산, 서쪽으로 가리왕산, 북쪽으로 괘병산 등이 자리해 있어 동서남북으로 조망이 좋다. 민둥산의 또 다른 특색은 석회암이 빗물에 용해되어 지반이 내려앉는 독특한 카르스트 지형으로 돌리네가 형성되어 있는 것이다.", + "MNTN_HG_VL" : "1118", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 남면", + "MNTN_NM" : "민둥산" }, - "longitude" : 127.872652, - "latitude" : 35.892753399999997 + "longitude" : 128.77488750000001, + "latitude" : 37.270854200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 제천시 백운면 화당리와 덕동리를 경계로 우뚝 솟아있는 삼봉산은 치악산 남대봉에서 서남쪽으로 갈라져 나온 백운산(1,078m)의 기세를 이어받은 산이다. 원주-봉양-박달재-산척-목계-귀래를 경유하여 백운산-구학산-주론산-시랑산-천등산-오청산-옥녀봉-십자봉 능선이 어깨를 맞대고 산 주변을 감싸고 있어 마치 그 가운데 푹 파묻혀 있는 듯한 느낌이 든다. 이렇듯 주변 산세에 둘러싸여 있는 까닭에 광복 전까지만 해도 호랑이가 종종 출몰했다고 전해진다. 실제로 호환을 당한 사람들의 시신을 돌무덤으로 쌓아놓은 호식장의 흔적이 남아있고, 대호지매점에서 1.5km 떨어진 지점에서는 호식총도 볼 수 있다. 원시림에 들어온 듯이 태고의 신비와 자연미가 살아있는 삼봉산은 그러나, 6.25의 아픔을 간직하고 있는 산이기도 하다. 산이 깊어 빨치산과 공비들이 숨어들자 삼봉산 아래에 비행장을 건설하려 공비를 토벌하려 했다는 이야기도 전해져 내려온다.정상에는 삼각점과 바위가 몇 개 있고, 시야를 막는 큰 나무가 없어 전망이 좋다.", - "MNTN_HG_VL" : "910", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면", - "MNTN_NM" : "삼봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "583", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "앞산(앞산공원)" }, - "longitude" : 127.96055560000001, - "latitude" : 37.190277799999997 + "longitude" : 128.57638890000001, + "latitude" : 35.816944399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;세 성인 상징하는 경산의 대표 산gt;경북 경산은 흔히 삼성현(三聖賢)의 고장으로 불린다. 세 성인, 즉 원효대사와 설총, 삼국유사를 저술한 일연이 태어난 곳이기 때문이다. 이 삼성현을 상징하는 산이 바로 삼성산이다. 경산시 남산면에 위치한 삼성산 가는 길은 대구·경북 일원에서는 물 좋기로 정평이 난 상대온천 가는 길, 상대온천이 산행의 들머리이자 날머리이기 때문이다. 그래서 삼성산은 이곳을 기점으로 온천과 연계한 산행 대상지로 제법 알려져 있다. 산의 높이가 말해주듯 산세는 크지 않은데 정상에서는 남산면과 자인면 일대의 벌판이 보이는 정도다. 그러나 이 산자락에 삼성현의 얼이 서려있는 성지곡, 성제지, 성참사, 불당지 등이 자리하고 있다. 정상 언저리에는 원효가 창건한 성지암이라는 절간이 있었던 것으로 추정되며, 현재는 외면상 그 흔적은 없고 기왓장만 간혹 출토되고 있다고 전한다. 주능선은 북서쪽으로 백화산(486m), 남서쪽으로 청도군 학일산(693m)으로 이어진다. 한편, 경산시는 2012년 완공 목표로 삼성산 진입 길목인 인흥리에 수백억 원을 들여 이른바 ‘삼성현역사문화공원’을 조성 중에 있다. 삼성현의 업적과 정신문화를 계승, 발전시키기고 위한 것으로, 공원이 들어서고 나면 삼성산은 그야말로 경산의 진산으로 거듭날 것이다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", - "MNTN_NM" : "삼성산" + "DETAIL_INFO_DTCONT" : "비봉산은 낙동정맥 가사봉 분기점에서 뻗어나온 보현지맥을 따라 보현산을 지나고 석심산에 이르러 한 줄기는 남서쪽으로 팔공지맥, 또 한줄기는 북서쪽으로 보현지맥으로 나뉘어 구무산, 문암산을 지나 비봉산에 닿았다가 낙동강으로 흘러드는 위천을 만나면서 허리를 숙인다.비봉산은 글자 그대로 ‘봉황이 날아가는 형상’이라고 해 붙여진 이름이다. 고려시대 이전에는 태행산이라 불리다가 조선 말기에는 자미산이라 하였다고 전하나 지금은 비봉산으로 부르고 있다.경상북도 의성군 다인면, 안계면 일대는 분지형으로 사방이 산으로 둘러쳐져 있으나 모두 나지막한 산들로 이어져있다. 그 중에서 우뚝한 비봉산은 바라보는 위치에 따라 모습을 달리하는데, 동쪽에서는 봉황이 날개를 넓게 펼치고 앉아 있는 모습이고, 남쪽에서 올려다보면 봉황이 위엄 있는 자세로 날갯짓을 하는 듯하다. 서쪽 다인면 소재지에서 바라보면 장군이 투구를 쓰고 서 있는 형상을 하고 있다. 의성군에서는 손에 꼽을 정도로 아름다운 산이지만 아직 일반인에게 많이 알려지지 않은 산이다.", + "MNTN_HG_VL" : "256", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의성군 다인면", + "MNTN_NM" : "비봉산" }, - "longitude" : 128.7943459, - "latitude" : 35.771673499999999 + "longitude" : 128.3608667, + "latitude" : 36.488524099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼성산은 경상북도 경산 읍내에서 남동쪽으로 약 10km 지점에 위치하고 표고는 554.2m의 나지막한 산이지만, 북쪽 산록에는 온천이 있어 가벼운 등산과 온천욕을 함께 즐길 수 있는 곳으로 인근에서는 자주 찾는 산중의 하나이다.상대 온천장 앞 버스 종점에서 서쪽 계곡을 따라 들어가면 저수지가 있고, 이 곳에서는 좌측 계곡을 따라 정상으로 바로 오르는 길과 우측길을 따라 고개를 거쳐 남동 능선을 경유, 정상으로 오르는 두 가지 길이 있다. 정상 서쪽 능선상에는 키를 넘는 억새 풀밭으로 되어 있다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", - "MNTN_NM" : "삼성산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "189", + "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 장명동,수성동", + "MNTN_NM" : "성황산" }, - "longitude" : 128.7943459, - "latitude" : 35.771673499999999 + "longitude" : 126.86145089999999, + "latitude" : 35.572579599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산", - "MNTN_NM" : "삼성산" + "DETAIL_INFO_DTCONT" : "사명산은 정상에서 양구, 화천, 춘천과 멀리 인제군 등 네 곳의 고을을 조망할 수 있다고 해서 이름 붙었다. 춘천에서 배후령을 넘어 추곡약수를 지나면 사명산 산행들머리인 웅진리와 선정사가 보인다. 계곡의 등산로를 따라 두 시간 정도 오르면 파로호가 내려다보이는 주능선에 닿고 거기서 널찍한 평지를 이룬 정상까지는 멀지 않다.정상에 서면 화천댐으로 형성된 파로호가 화천과 양구에 걸쳐 넓게 펼쳐진 시원한 풍광이 눈맛을 시원하게 한다. 파로호 건너 우뚝한 화천 일산(1190.3m)이 육중한 산세를 자랑하며 솟았고, 멀리 설악산과 점봉산 등도 눈에 들어온다. 남쪽으로 소양호와 어울린 오봉산도 잘 보인다.봄이면 진달래가, 가을날엔 단풍이 아름답다. 설경 또한 장관을 이뤄 겨울산행지로도 인기 높다. 문바위, 첩바위 등 볼거리들이 걸음을 즐겁게 하는 사명산 남쪽 약수골에는 우리나라에서 손꼽히는 ‘추곡약수’가 있다.", + "MNTN_HG_VL" : "1198", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면, 양구군 양구읍", + "MNTN_NM" : "사명산" }, - "longitude" : 128.7943459, - "latitude" : 35.771673499999999 + "longitude" : 127.9064195, + "latitude" : 38.077294899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울시 관악구와와 안양시를 경계로하는 삼성산은 관악산 주능선에서 서쪽으로 뻗어내린 팔봉능선을 타고 무너미고개로 내려 않다가 다시 솟구쳐 오른 산으로, 삼성산 아래 국기봉과 삼막사로 많이 알려져 있으며, 바위로 된 암산이다.관악산, 삼성산은 양쪽 봉우리가 서로 이어져 있어 일반 등산객들은 삼성산을 관악산의 한 작은 봉우리로 여겨 삼성산 정상에서도 관악산에 오른 것으로 생각하기도 하여 요즘은 특별하게 둘을 구분하지 않고 있다. 원효대사가 의상, 윤필과 함께 삼막사란 사찰을 짓고 수도하였다 하여, '삼성산' 이라는 이름이 붙여졌다고 한다. 이 산에는 신라 문무와 17년 (677)에 창건한 삼막사, 고려 태조때 창건한 염불암, 그리고 망월암등 절과 암자가 산자락에 자리잡고 있다.관악산 유원지로 들어서면 왼쪽이 관악산, 오른쪽 능선이 삼성산 능선이다. 삼성산의 등산로는 서울대, 시흥동, 관악역, 안양유원지 등을 기점으로 하는 코스가 있으며 삼막사, 남근석, 상불암, 망월암을 잇는 한적한 길도 있다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구, 금천구, 경기도 안양시", - "MNTN_NM" : "삼성산" + "DETAIL_INFO_DTCONT" : "방문산은 일반적으로 방장산이라고 하나 실은 고창고개를 가운데 두고, 동북쪽 장성갈재 옆에 솟아 있는 733봉을 방장산, 서남쪽네 솟아 있는 640봉을 방문산이라 구분된다.방문산은 그 남서 기슭에 미륵사, 상원사, 임공사 등의 사찰을 안고 있으며 주변에는 631년(무왕 32)에 승려 여환(如幻)이 창건한 백제 때 고찰 백양사(白羊寺), 사적 제384호로 지정된 장성 입암산성이 있다. 정상 서남쪽 아래로 고창읍 시가지를 한눈에 조망할 수 있고 북쪽으로 호남평야 일대와 동남쪽으로 장성호와 멀리 무등산까지 시야에 들어온다.산행은 미륵사나 임공사 도는 신림면 신평리 신기마을 등을 등산기점으로 할 수 있으되 하산은 석정온천과 연계시킨 코스가 좋다.", + "MNTN_HG_VL" : "640", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창읍, 신림면, 전라남도 장성 북이면", + "MNTN_NM" : "방문산" }, - "longitude" : 126.9391667, - "latitude" : 37.436111099999998 + "longitude" : 126.73999999999999, + "latitude" : 35.450000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", - "MNTN_NM" : "삼성산" + "DETAIL_INFO_DTCONT" : "광교산은 원래 광악산이었는데 928년 왕건이 후백제 견훤을 평정하고 나서 산근처에 행궁을 차리고 군사를 위로할 때 산 정상에서 불빛이 하늘로 솟아오르는 것을 보고 이 산은 '부처님의 가르침을 주는 산' 이라 하여 이름을 광교산으로 붙였다고 전해진다.광교산은 물이 풍부한 산으로 광교저수지, 낙생저수지, 고기동 물놀이터가 시민의 사랑을 받고 있으며 국가보물 제9호 서봉사지 현오국사타비, 경기도 문화재 제38호 김준용 장군 승전비가 있다.", + "MNTN_HG_VL" : "582", + "MNTN_LOCPLC_REGION_NM" : "경기도", + "MNTN_NM" : "광교산" }, - "longitude" : 128.7943459, - "latitude" : 35.771673499999999 + "longitude" : 127.01508370000001, + "latitude" : 37.3280368 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼신봉은 어미의 품처럼 넓은 지리산 자락에 흩어진 수십개 봉우리 중의 하나로 영신봉(1652m)에서 남쪽으로 길게 뻗은 능선상의 최고봉이다. 또한 지리산 주능선의 전망대로서 참다운 가치를 가질 뿐만 아니라 악양으로 흘러내린 형제봉 능선과 멀리 남해 바다의 일망무제, 탁트인 전경을 선사해준다.특히 인적드문 비경의 남부능선 한가운데에 우뚝 솟아 동으로는 묵계 치를, 서쪽으로 생불재(상불재), 남으로는 청학동을, 북쪽으로는 수곡재와 세석 을 이어주는 사통팔달 요충지로서의 역할을 한다.지리산 하동지역은 쌍계사, 칠불사 등의 절을 비롯하여 불일폭포, 화계계곡, 청학동, 도인촌 등의 볼거리도 많다. 청학동 마을에서 삼신봉을 바라보면 왼쪽부터 쇠통바위, 가운데는 내삼신봉, 오른쪽이 외삼신봉으로 세 개의 봉우리가 눈에 들어온다.특히 삼신봉은 봄의 벚꽃 산행지로 이름 나 있다. 하동-쌍계사 십리 벚꽃길, 섬진강 60리 벚꽃길이 매년 4월 초순이면 장관을 이룬다. 수령 60년이 넘은 아름드리 벚나무가 구불구불한 계곡을 따라 활짝 필때 벚꽃산행지로 많은 사람들이 찾는다. 10리 벚꽃길은 젊은 남녀들이 걸으며 백년해로를 기약하는 경우가 많다고 해서\"\"혼례길목\"\"으로 불린다.섬진강 벚꽃길 60리는 섬진강 꽃길 따라 60리를 간다.구례에서부터 따라붙은 섬진강은 지리산에서 거친 숨결로 내려온 화개천과 만나 물줄기가 굵어진다. 이곳이 바로 화개장터로 불리는 탑리이다.", - "MNTN_HG_VL" : "1285", - "MNTN_LOCPLC_REGION_NM" : "경상남도 하동군", - "MNTN_NM" : "삼신봉" + "DETAIL_INFO_DTCONT" : "순천의 제석산은 호남정맥에서 갈려져 남쪽으로 흘러내린 금전산과 오봉산 줄기의 끝자락에 위치한 산이다. 행정구역상 순천에 속해있긴 하지만 벌교 사람들은 벌교의 제석산이라고 부른다. 그럴만한 것이 벌교 어디서든 고개만 들면 보이는 곳이 제석산이기 때문이다. 능선에 올라서면 넓은 낙안벌과 순천만으로 이어지는 벌교 앞바다가 훤히 내려다보이는 전망이 특히 뛰어난데, ‘제석’은 하늘에 있는 33개의 하늘 중 가장 마지막에 있는 하늘인 도리천에 있으면서 모든 하늘을 다스리는 제석천왕을 뜻하는 불경에 나오는 이름이다.한편 벌교란 지명은 뗏목으로 잇달아 만들어 놓은 다리를 뜻하는 말로, 예전 이곳에는 벌교천을 가로지르는 뗏목다리가 있어서 벌교란 지명이 생겼다고 한다. 하지만 이 다리가 무너지고 이후 보물 304호로 지정된 홍교가 건설되었다고 한다.제석산과 벌교는 조정래의 대하소설 「태백산맥」의 주무대가 되는 곳으로 곳곳에 그 자취를 발견할 수 있어 산행뿐 아니라 문학탐방으로도 그 가치가 높다고 할 수 있다.정상에는 1995년 벌교의 제석산악회에서 세운 표지석이 있다. 이곳 행정구역이 벌교가 아닌 순천임에도 벌교에서 표지석을 세운 이유는 그만큼 벌교 사람들이 이곳을 많이 찾는다는 것이다.", + "MNTN_HG_VL" : "560", + "MNTN_LOCPLC_REGION_NM" : "전남 순천시 별량면, 보성군 벌교읍", + "MNTN_NM" : "제석산" }, - "longitude" : 127.70404569999999, - "latitude" : 35.264464199999999 + "longitude" : 127.36750000000001, + "latitude" : 34.869166700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼악산(三岳山)은 한북정맥상의 포천 백운산 밑에서 동쪽으로 갈라진 지맥이 석룡산, 화악산, 계관산으로 이어지고 옛날 경춘 간 육로교통의 춘천관문이었던 석파령을 넘어 끄트머리에서 솟아 신연강 협곡을 이루어 놓은 명산이다.또한 협곡에 설치된 의암댐으로 호수가 생겨 물 속에 투영된 산을 볼 수 있어 더 한층 좋다. 매표소에서 계곡을 오르다 보면 등선폭포, 비선폭포, 승학폭포, 백련폭포등 크고 작은 폭포가 있으며, 용화봉, 청운봉, 등선봉을 비롯 3개의 봉우리에서 뻗어내린 능선이 암봉으로 이루어져 절경을 이룬다.기암괴석이 많고 소나무, 참나무등의 수림이 울창하며 계곡미가 빼어나다.삼악산의 산행기점은 세 군데 이다. 등선폭,상원사,강촌역에서 다리건너 바로 시작하는 세 기점이 있다. 대부분의 등산객들이 등선폭쪽에서 산행을 시작하나, 의암댐이 있는 상원사입구에서 시작하여 등선폭포로 내려오는 것이 좋다.", - "MNTN_HG_VL" : "656", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 서면", - "MNTN_NM" : "삼악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "371", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군", + "MNTN_NM" : "시묘산" }, - "longitude" : 127.66031169999999, - "latitude" : 37.839902700000003 + "longitude" : 128.31055559999999, + "latitude" : 36.028055600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼암봉은 지도읍 읍내리에서 시작하여 광정리를 거쳐 감정리에 이르는 길이 10km가량으로 북서에서 동남방향으로 지도읍 중앙을 가로지르고 있다. 큰산, 깃대봉, 삼암봉으로 이어지는 3개의 봉우리가 있고주능선을 따라 등산로가 잘 정비되어있어 산행 중 섬 산행의 특성인 바다내음과 함께 다도해의 아름다운 풍광을 같이 즐길 수 있다. 옛날 삼암봉 봉우리에 작은 바위가 있는데 그바위에 조그만 웅덩이가 있었다. 일제강점기에 측량을 위해 그 웅덩이에 삼각점을 심어 현재는 웅덩이를 볼 수 없으나 옛날 삼암봉 정상부에 과일나무가 많아 삼암봉을 오르는 이들이 많았다고 한다 그러던 어느날 어떤 여인이 삼암봉에 올랐다가 웅덩이에 물을 마신후에 임신을 했고 출산을 했는데 뱃속에서 뱀들만 나왔다 하는 설화가전해진다.", - "MNTN_HG_VL" : "196", - "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군 지도읍", - "MNTN_NM" : "삼암봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면", + "MNTN_NM" : "샘봉산" }, - "longitude" : 126.17944439999999, - "latitude" : 35.090555600000002 + "longitude" : 127.54683439999999, + "latitude" : 36.455291099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼태봉은 광주산맥의 한 갈래로서 가평군에 위치하고 있다. 광주산맥의 한 갈래로 좌우에는 중미산과 화야산이 있고, 산위에 오르면 서쪽으로는 북한강, 동쪽으로는 뇌암산이 손에 잡힐 듯 다가오며 북동쪽으로는 곡달산이 바라 보인다.좌우로 중미산(834), 화야산(755), 용문산(1,157), 통반산(650)이 자리하고 있어 같이 연계하여 등산하는 것이 좋다. 특히 통반산과 같이 산행하는 것이 일반적이다.정상은 암번으로 이뤄져 있어 쉼터로 좋고, 한강의 조망이 일품이다. 그리고 통방산까지 이어지는 산길은 완만해서 좋고, 주변은 수림이 울창하다.", - "MNTN_HG_VL" : "683", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군\/양평군", - "MNTN_NM" : "삼태봉" + "DETAIL_INFO_DTCONT" : "제천에서 82번 도로를 따서 청풍으로 가다보면 오른쪽으로 호수 위에 솟은 산이 있다. 비봉산 가운데 솟은 봉우리는 봉황의 머리, 양쪽으로 뻗은 능선은 영락없는 날개니 이름 그대로 봉황이 날아갈 듯한 자태다. 금수산이나 월악산 등 명산의 그늘과 청풍문화재단지 등의 명성에 가려서 별로 알려지지 않았으나 여덟 명당 거느린 복스러운 산이다.비봉산은 산행 들머리인 연곡리부터 시작해서 사방으로 연곡리, 계산리, 양평리, 도곡리, 대류리, 신리 같은 마을들이 둘러싸고 있다. 청풍 쪽 마을은 물태리다. 이 마을들을 잇는 순환도로를 따르면 비봉산을 한 바퀴 돌게 된다. 도곡리나 양평리에서 더 들어가 길 끝자락 호숫가에 서면 흡사 섬에 온 것과도 같은 느낌이다.연곡리에서는 이백년이 훨씬 넘어 보이는 느티나무 한 그루가 길손을 반긴다. 산행은 이 느티나무가 있는 큰 길가에서 못안마을 축사 쪽으로 난 콘크리트 포장도로로 접어들면서 시작된다. 이 길에서 보면 비봉산이 거느린 여덟 개의 명당 중 하나로 짐작될 만한 곳이 눈에 띈다. 축사 뒤편으로는 흡사 봉황의 알처럼 솟은 나지막한 봉우리 두 개가 유난히 시선을 끈다. 원래 비봉산의 산세는 새가 알을 품고 있다가 먹이를 구하려고 비상하는 모습이라 했으니 두 봉우리 뒤편으로 솟은 비봉산이 더욱 범상치 않아 보인다.", + "MNTN_HG_VL" : "361", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 청풍면", + "MNTN_NM" : "비봉산" }, - "longitude" : 127.46194439999999, - "latitude" : 37.624166700000004 + "longitude" : 128.14326149999999, + "latitude" : 37.008540699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 단양군 어상천면과 영춘면 사이에 솟아있는 삼태산은 마치 삼태기 세 개를 엎어놓은 듯한 산세를 하고 있어 이와 같은 이름이 붙었다. 그러나 서쪽인 대전리나 남쪽인 임현리에서 바라보면 누에가 기어가고 있는 듯한 형상과 흡사하여 누에머리산이라고 불리기도 한다. 삼태산은 단양팔경과 인근 유명산들의 명성에 가려 산악인들에게 그리 잘 알려진 산은 아니다. 일반에게 잘 알려지지 않아 자연이 잘 보존되어 있다.어상천면과 영춘면 사이에 있는 농우재고개가 삼태산과 오기산을 이어주는데, 예로부터 주민들은 하늘 높이 솟아오른 삼태산을 남자산, 산세가 부드러운 오기산은 여자산으로 불러왔으며 두 산이 서로 바라보면서 항상 그리워한다고 여겼다.산허리의 단양팔경 중 2경인 일광굴의 신비한 풍광과, 산 구비구비 계곡 곳곳에 스며있는 애틋하고도 재미난 전설들은, 이 곳을 찾는 사람들의 발길을 즐겁게 해주고 있다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 어상천면", - "MNTN_NM" : "삼태산" + "DETAIL_INFO_DTCONT" : "백두대간의 지맥이 동쪽으로 뻗어 단지봉(1327m), 가양산(1430m), 미승봉(734m)으로 내려오다가 가야산에 이르기 전 남서쪽으로 별유산(1046m)을 지나 솟구친 것이 비계산이다.합천군과 거창군의 경계를 이루는 비계산은 인접한 별유산, 장군봉과 함께 닭이 금벼슬의 관을 쓰고 심장부에 고견사를 품고 있는 듯한 형상이다. 비계산은 닭머리 부분에 해당된다. 비계산은 돌, 너덜, 바람, 굴이 많은 산으로 유명하다. 능선상에는 암릉과 암봉들이 많아 산행시는 로프를 반드시 준비해야 한다.소요 시간 :6시간최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 갈림길에서 서쪽 능선을 따라 오른 비계산 정상은 잡목들로 어우러져 있고, 동서를 관통하는 88 고속도로 및 의상봉 상봉에서 서쪽으로 뻗은 암릉을 바라보는 경관이 좋다.도리나 거창휴게소에서 많이 올라간다. 비계산에서 시작하여 의상봉까지 종주하는 코스로 이용하기도 한다. 숲길로 활용하기 적당하나 정상부근은 안전장치가 좀더 필요할 듯하다. 휴게서외에는 식수를 구할 곳은 없다.", + "MNTN_HG_VL" : "1131", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 가야면", + "MNTN_NM" : "비계산" + }, + "longitude" : 128.06999999999999, + "latitude" : 35.7216667 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "높이 506m로천보산 지맥이 북쪽으로 이어져 솟은 산이다. 발치봉,응봉,석봉,기대봉,투구봉,솔치봉,돌봉 등 7개 봉우리가 솟아 있어 칠봉이라는 이름이 붙었다. 주변에 삼봉산,오봉산,구봉산 등 홀수로 된 이름을 가진 산들이 많다. 조선시대 세조가 말년에 과거의 잘못을 뉘우치며 이곳에 올랐다 하여 어등산(御登山) 이라고도 하고,가을 단풍이 아름다워 비단 병풍에 비유하여 금병산(錦屛山)이라고도 한다. 인근에 목행선 선생 선묘와 탑동석불이 자리잡고 있다.", + "MNTN_HG_VL" : "506", + "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시 송내동, 불현동", + "MNTN_NM" : "칠봉산" }, - "longitude" : 128.37006980000001, - "latitude" : 37.120670199999999 + "longitude" : 127.093144, + "latitude" : 37.871221800000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "73", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", - "MNTN_NM" : "삼학도" + "MNTN_HG_VL" : "195", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군", + "MNTN_NM" : "봉대산" }, - "longitude" : 126.3914317, - "latitude" : 34.782971400000001 + "longitude" : 126.2736111, + "latitude" : 35.119166700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "714", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 주문진읍 삼교리 \/ 양양군 현남면", - "MNTN_NM" : "삼형제봉" + "DETAIL_INFO_DTCONT" : "화도읍(마석)에서 북동쪽으로 12km 거리에 있는 축령산(887.1m)은 조종천과 수동천의 사이에 솟아 있다. 이 산에는 일명 '남이바위'라고 하는 바위가 있는데, 이는 조선시대 때 남이장이 이 곳에서 심신을 수련하였다 하여 붙여진 이름이라고 한다.축령산의 울창한 수림과 계곡을 이용하여 자연 휴양림을 조성, 삼림욕장, 휴계소, 체육시설, 놀이시설, 야영장 등 편의 시설이 두루 갖추어 진 곳이다.", + "MNTN_HG_VL" : "887", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", + "MNTN_NM" : "축령산" }, - "longitude" : 128.71777779999999, - "latitude" : 37.903888899999998 + "longitude" : 127.3330406, + "latitude" : 37.752879499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면에 소재한 삽디리봉은 소양호 건너편에 있다는 불편 때문에 찾는 이들의 발길이 그리 흔치 않은 산이다. 자연히 천혜의 경관을 그대로 간직하고 있으며 물빛과 어우러진 자연경관 역시 일품이다.산속은 대체로 평이한 형세를 하고 있어 산행 코스로 짚어 줄 만한 특징적인 장소는 없으나 삽다리골 초입에서부터 정상까지 살아있는 자연의 숨결을 한껏 만끽할 수 있다.", - "MNTN_HG_VL" : "610", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", - "MNTN_NM" : "삽다리봉" + "DETAIL_INFO_DTCONT" : "낙동정맥이 백병산(1259m)을 빚고 육백산(1244m), 응봉산(1267m)을 지나 솟구친 산이 사금산이다. 이 산은 사금이 많이 난다고 해서 이름도 사금산이라 붙여졌다.고사목이 보이는 서쪽 무넹이골 사면을 지나면 1085m봉이 나타나는데 곧장 올라서지 않고 오른쪽 사면을 비켜나가면 그 아래 노송이 군락을 이루고 있어 쉬어가기 좋다. 산 정상에서는 북으로 응봉산 육백산이 펼쳐져 있고 그 너머로 낙동정맥이 기다랗게 도열해 있다.", + "MNTN_HG_VL" : "1092", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 원덕읍", + "MNTN_NM" : "사금산" }, - "longitude" : 127.93611110000001, - "latitude" : 37.926666699999998 + "longitude" : 129.16611109999999, + "latitude" : 37.205833299999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1134", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", - "MNTN_NM" : "삿갓봉" + "DETAIL_INFO_DTCONT" : "삼도봉(1,176m)을 시작으로 민주지산(1,241m), 각호산(1,176m)과 함께 웅장한 서북 능선을 이루는 산군(山群)에 속한다. 각호산·민주지산·삼도봉을 잇는 능선은 수림이 우거지고 바위들이 섞여 있으며 봄이면 능선을 따라 8㎞에 걸쳐 진달래가 만발한다.그 산들 사이에는 유명한 피서지인 물한계곡(勿閑溪谷)이 자리잡고 있다. 삼도봉에서 북서쪽으로 약 40분 거리에 우뚝 솟아 있는 석기봉은 민주지산의 주릉 중에서 가장 빼어나며, 주위 전망도 일품이다.황악산이 북동으로 바로 보이고 동남으로는 가야산이 손에 잡힐 듯 가까이 보인다. 서서남으로는 마이산의 뾰족한 두 귀가 선명하다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "석기봉" }, - "longitude" : 127.6388889, - "latitude" : 35.7858333 + "longitude" : 127.8641667, + "latitude" : 36.025277799999998 }, { "mountain" : { @@ -4771,1323 +3561,1323 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삿갓봉은 백두대간의 주맥이 갈라져 나와 백적산을 세우고 청옥산을 일구며 강원도 평창 남서쪽으로 산세를 뻗쳐 솟아오른 산이다. 삿갓모양으로 우뚝 서 있어 삿갓봉이라 불리는데, 백운산, 응봉, 매봉 등과 마찬가지로 전국에 똑같은 이름의 산들이 곳곳에 산재해 있어 우리에게 친근하게 느껴지는 산이기도 하다.강원도 평창군의 삿갓봉은 강원도의 산들이 대개 그렇듯이 첩첩산중 오지 중에 오지로, 산세가 험하고 골이 깊기로 유명하다. 사람의 발길이 얼마 닿지 않아 울창한 산림이 그대로 보존되어 있고, 작은 벌레가 바스락거리는 소리까지 들릴 정도로 주변이 조용하여, 쾌적하고 여유로운 산행을 즐기기에는 안성맞춤인 산이다. 1천미터 이상의 기암괴석들이 봉우리를 이룬 정상에 오르면 북쪽으로 남병산, 남쪽으로 삼방산, 동쪽으로 청옥산, 그리고 서쪽으로는 장암산 등이 손에 잡힐 듯 조망되어 산행의 즐거움을 한껏 느낄 수 있는 산이다.", - "MNTN_HG_VL" : "400", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍, 미탄면", - "MNTN_NM" : "삿갓봉" + "DETAIL_INFO_DTCONT" : "백월산은 동서 2km, 남북 4km, 높이 약 394m의 도상구릉(島狀丘陵)을 형성하고 있다. 백월산의 정상부는 남북 20m, 동서 15m 규모의 평정봉(平頂峰)으로서 두꺼운 토양층으로 피복(被覆)되어, 암석 미지형은 전혀 나타나지 않고 있다. 그러나 정상 북측의 해발고도 300m~350m 높이 주변지역에는 화강암지역에서 찾아볼 수 있는 일반적인 암석 미지형들이 분포하고 있는데 이 미지형들은 주로 직경 2m 내외 원형의 집단적인 토르(tor)와 토르의 상층부에 형성된 30cm 내외의 폭의 그르부 및 4~5m 높이의 암주들로서 판상의 수직 및 수평절리들의 간격이 2m 규모로 발달하였기 때문에 나타난 현상이다. 암석 미지형이 집단적으로 분포하고 있는 곳의 해발고도 250m 지점의 산록에는 높이 10m, 폭 13m, 경사 60~65˚에 이르는 암석단애를 중심으로 암석의 급사면이 나타나고 있는데 이러한 현상은 수직에 가까운 사절리들이 발달하고 있기 때문이다. 한편 직경 3~5m 크기의 원형에 가까운 토르들이 3~5개 정도가 집단으로 기반암의 풍화충인 새프롤라이트와 토양층 위로 노출되어 토르를 덮고 있는 풍화층들이 장구한 세월동안 풍화와 침식으로 제거되었음을 나타내주고 있다.옛날에 홍성 지방의 용봉산과 백월산에 각각 장수가 살고 있었다. 이 장수들 사이에는 소향이라는아주 예쁜 처녀가 살았는데 장수들은 서로 이 소향이를 짝사랑하고 있었다. 장수들은 소향이를 차지하기 위해 서로 자기가 있는 산의 돌을 상대방 산에 던지기 시작하였다. 치열한 싸움이 계속되고 용봉산에 점점 돌이 쌓였다. 백월산 장수가 더 많은 돌을 던졌기 때문이다. 결국 백월산장수가 이겨서 소향이를 차지하게 되었고 홍성읍과 홍북면 사이에 있는 소향리는 백월산이 위치하는 홍성읍에 포함되게 되었다. 용봉산 장수는 싸움에서 지긴 했지만 백월산 장수가 던진 기암괴석들 덕분에 현재 전국에서 많은 관광객이 방문하고 있다.", + "MNTN_HG_VL" : "394", + "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군", + "MNTN_NM" : "백월산" }, - "longitude" : 128.53, - "latitude" : 37.343333299999998 + "longitude" : 126.6222222, + "latitude" : 36.607777800000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1055", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "삿갓봉" - }, - "longitude" : 128.95833329999999, - "latitude" : 37.601388900000003 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "강화도의 서남단 외포리 선착장에서 4km정도 떨어진 석모도에는 상봉산을 중심으로 동쪽에 해명산(327m)과 북쪽에 상주산(264m)이 있다. 3개의 산이 있다해서 삼산면으로 이중 상봉산이 가장 높다. 석모도는 위의 세 산과 상봉산 북쪽으로 펼쳐진 광활한 방죽논지대, 이렇게 네 부분이 합쳐져 섬을 이루고 있다. 상봉산 동남쪽 아래 세워진 보문사는 규모도 크지만 바다를 향해 전망 좋은 곳에 위치한 관광명소로 찾는 이들이 많다. 관광을 겸할 경우 봄과 가을이 좋다.산행하면서 서해바다의 아름다운 모습을 구경할 수 있고 특히 상봉산 정상에서 서남쪽 볼음도 방향으로 바라보는 노을과 올망졸망한 섬들의 모습이 널리 알려져 있다. 정상은 암봉으로 되어 있으며, 남쪽으로 해안선과 바다, 북쪽으로 넓은 평야지대를 볼 수 있고 동쪽으로 해명산에 이르는 주능선이 잘 바라보인다. 능선 곳곳에 암벽이 자리잡고 있고 해명산에서 낙가산으로 가는 구간에는 억새풀 군락이 멋지다.", - "MNTN_HG_VL" : "316", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 삼산면 석모도", - "MNTN_NM" : "상봉산" - }, - "longitude" : 126.3088889, - "latitude" : 37.694166699999997 - }, - { - "mountain" : { - "DETAIL_INFO_DTCONT" : "정선 아라리로 유명한 아우라지가 산의 아랫부분을 감아돌며 절경을 보여주는 산으로 철쭉 군락과 오래된 주목이 눈을 즐겁게 한다. 정상에서는 사방을 시원스럽게 조망할 수 있는데, 북쪽 멀리 백두대간도 보인다. 이곳에는 중국의 무릉도원에 비견되는 전설이 전해지는데, 이 산에서는 병도 안들고 늙지도 않는다는 것이다.또한 옥갑장군이 이 산에서 무예를 닦고 그가 입었던 갑옷을 산속에 숨겼다는 옥갑산봉도 남쪽에 있다. 상원산은 강원도 정선군의 최북단인 북평면과 북면 사이에 솟아있다.동쪽에는 평창군 도암면의 황병산 부근에서 발원하여 남쪽으로 흐르는 남한강의 지류인 송천이 심한 곡류를 이루고 있다. 부근에는 정선탄전에 속하는 탄광이 있으며, 석탄을 수송하기 위해 부설된 정선선의 기점이 된다. 북쪽에 두루봉, 서쪽에 갈미봉, 남쪽에 백석봉과 옥갑산봉, 북동쪽에 노추산 등이 솟아 있다.", - "MNTN_HG_VL" : "1421", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북평면, 북면", - "MNTN_NM" : "상원산" + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 초월면", + "MNTN_NM" : "무갑산" }, - "longitude" : 128.67638890000001, - "latitude" : 37.508333299999997 + "longitude" : 127.3337173, + "latitude" : 37.404533200000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1006", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", - "MNTN_NM" : "상정바위" + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "경기도 의왕시", + "MNTN_NM" : "모락산" }, - "longitude" : 128.71916669999999, - "latitude" : 37.423611100000002 + "longitude" : 126.98119699999999, + "latitude" : 37.369781099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1024", - "MNTN_LOCPLC_REGION_NM" : "강원도 철원군", - "MNTN_NM" : "상해봉" + "DETAIL_INFO_DTCONT" : "백악산은 속리산 문장대에서 북쪽 화양동 계곡 방면으로 이어진 긴 능선위에 솟아있는 봉우리로 경북 상주와 충북 괴산의 도계를 이루고 있다. 규모는 작지만 화강암으로 된 여러 형상의 바위들이 산악미를 보여주는 옹골찬 산이다.속리산 국립공원의 중간지점에 위치하고 있는 이 산은 정상을 중심으로 좌우 편은 암봉과 암릉으로 연결되어 장관이고, 주능선 남쪽 면은 완만한 반면 북쪽은 절벽을 이루어 아찔하다.정상 북쪽 옥양골에는 유명한 옥양폭포가 있고, 폭포위 계곡 서편으로 조금 들어가면 암벽에 기이하게 생긴 석굴이 있는데 일명 보굴이라 불리기도 한다. 수양대군의 딸이 단종의 왕위를 차지하려는 아버지의 음모를 눈치채고 발설했다가#51922;겨나 숨어 지낸 곳이라고 전해지고 있다.", + "MNTN_HG_VL" : "857", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 괴산군 청천면", + "MNTN_NM" : "백악산" }, - "longitude" : 127.4307982, - "latitude" : 38.115392399999998 + "longitude" : 127.85768899999999, + "latitude" : 36.614499700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "완도군은 전남 해남군 땅끝 동쪽의 크고 작은 섬 202개로 이루어졌다. 이 가운데 완도가 가장 큰 섬으로 군소재지다. 상황봉은 완도에서 가장 큰 산이다. 완도 사람들은 오봉산이라고도 하는데 상황봉, 업진봉, 숙승봉, 백운봉, 쉼봉 등 다섯 개의 봉우리가 솟았기 때문이다. 고대 중국 남방에 살면서 주변을 오가며 무역하던 뱃사람들은 이 산에 부처님의 흔적이 있다 해서 ‘상왕(象王)’이라 불렀다고도 한다. 부처를 낳은 마야부인은 흰 코끼리가 배에 들어오는 태몽을 꾸었다. 그래서 코끼리의 왕이라고도 한다.옛날 어느 스님이 숙승봉의 토굴에 기거하며 수도하였고, 업진봉에 이르러 업을 다하였고, 백운대에 이르러 흰구름을 벗삼고, 쉼봉에 이르러 바다를 보며 잠시 숨을 고른 다음, 상황봉에 이르러 부처가 되었다는 유래도 있다. 관음사터와 중암사지는 흔적만 남아 있지만 상황봉이 예부터 불교의 산이었음을 뒷받침하고 있다.상황봉은 조망이 빼어난 산이다. 맑은 날이면 주변에 펼쳐진 오밀조밀한 다도해 풍경은 물론, 멀리 제주도 한라산까지 볼 수 있는 뛰어난 전망대다. 서쪽으로는 해남 달마산과 함께 두륜봉, 가련봉, 덕룡산, 주작산, 월출산 등이 펼쳐지고, 동쪽으로는 천관산이 보인다.난대성 상록활엽수림이 제공하는 독특한 풍치 또한 다른 곳에서 맛보기 힘든 이색적인 경험이다. 짙푸른 난대림으로 뒤덮인 완도 상황봉 일대는 거의 대부분 완도수목원에 편입되어 있다.", - "MNTN_HG_VL" : "646", - "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 군외면", - "MNTN_NM" : "상황봉" + "DETAIL_INFO_DTCONT" : "강원도 홍천군 내면에 소재해 있는 맹현봉은 우리나라 최후의 오지라는 강원도 심산유곡으로 내린천변에 맹렬한 형상으로 솟아있는 산이다. 명현봉 서쪽에서 정상밑으로 난 운리동골은 커다란 암반과 소, 폭포가 어울어져 수려한 골짜기를 이루며 사방으로 뛰어난 경관을 갖추고 있다.이 산은 사람들의 발길이 닿지 않은 깊은 산이면서도 위험한 코스가 별로 없는데 지류가 여러갈래로 나눠져 있으므로 정상쪽으로 이어지는 주류를 잘 선택해야 한다. 특히 운리동골 입구를 지나 2km남짓 되는 곳에서 골이 오른쪽으로 크게 휘는 곳에서 길을 잃기 쉬우므로 유의해야 한다. 맹현봉 정상은 널찍한 헬리포트가 닦여 있는데 정상에서의 하산길은 두 갈래다.", + "MNTN_HG_VL" : "1214", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "맹현봉" }, - "longitude" : 126.6931914, - "latitude" : 34.348111099999997 + "longitude" : 128.3197222, + "latitude" : 37.830833299999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "상황봉(644.1m)은 완도 최고봉답게 백운봉(600m), 숙승봉(435m) 등 거물급 봉우리를 거느리고 섬 중앙에 우뚝 솟았다.완도팔경의 하나인 백설홍춘(내린 눈속에 핀 동백꽃)은 수령 백년 이상의 동백나무가 많은 죽청리 동백림을 두고 이른 것인데, 상황봉은 이 동백나무와 돈나무 등의 상록활엽수와 단풍나무, 떡갈나무 등 낙엽활엽수가 어우러져 산 전체가 식물원으로 조성된 듯한 느낌을 준다. 또한 동백나무 자생지로는 국내에서 가장 넓은 동백나무 군락지가 삼두리 전남 청소년수련원 부근에 있다.상황봉에서 보는 조망 또한 일품이다. 봄이라 시야는 좋은 날이 드물긴 하지만, 맑은 날이면 주변에 펼쳐진 치밀한 다도해의 풍정이 볼 만하다. 멀리 한라산의 장엄한 모습도 볼 수 있다면 정말 운이 좋은 사람일 것이다. 서쪽으로는 해남 달마산과 함께 두륜봉, 가련봉, 강진의 덕룡산, 주작산, 월출산 등이 병풍처럼 둘러섰고, 동쪽 가까운 곳에 천관산이 솟았다. 전남 지역의 명산을 두루 조망할 수 있는 장소다.", - "MNTN_HG_VL" : "644", - "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 완도읍 군외면", - "MNTN_NM" : "상황봉" + "DETAIL_INFO_DTCONT" : "낙영산은 속리산(1,058)을 조산(祖山)으로 백악산(858)과 도명산(642)사이에 기암절벽을 이룬 산이다. 남과 북으로 용대천과 화양구곡을 안고 있으며 암골미(岩骨美)가 뛰어나 괴산의 명산으로 불리고 있다.낙영산은 속리산국립공원권에 속한 산답게 산자락 곳곳에 두꺼비바위,코끼리바위등 기암을 가지고 있으며, 암릉이 산재해 있어 아기자기한 암릉산행 묘미와 시원스런 조망을 동시에 즐길 수 있는 곳이다. 또 이 산자락에 위치한 공림사(公林寺)도 볼 만 하다. 공림사는 법주사의 말사로 신라 경문왕(861-874)때 자정선사가 창건한 천년 고찰이다.정상에 서면 백두대간 주능선에 장쾌한 모습과 속리산 연봉들에 아름다운 모습을 볼 수 있고 산행 후에는 용대천과 화양구곡에서 깨끗한 자연을 만끽 할 수 있다. 하지만 암벽지대가 많아 다소 위험한 곳이 있으므로 주의해야 한다.", + "MNTN_HG_VL" : "746", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "낙영산" }, - "longitude" : 126.6931914, - "latitude" : 34.348111099999997 + "longitude" : 127.81869210000001, + "latitude" : 36.640329199999996 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "462", - "MNTN_LOCPLC_REGION_NM" : "충청북도 청원군 문의면", - "MNTN_NM" : "샘봉산" + "DETAIL_INFO_DTCONT" : "강원도 영월군 하동면 와석리 곡골 동쪽에 우뚝 솟은 곰봉은 산자락 곳곳에 산나물이 즐비하게 자생할 정도로 오염되지 않은 청정지역이다. 곰봉 정상에는 돌을 고여놓고 가마솥을 얹어 놓은 듯한 형상인 자동차 크기의 바위가 세 개 놓여 있다. 정상에 곰 모양의 바위가 있어 곰봉이라 부른다.국립지리원에서 발행한 지형도에 마대산은 표기되어 있으나 곰봉은 이름도 없이 산을 의미하는 기호에 산 높이만 적혀 있다. 이 산은 마대산보다 암릉이 잘 발달되어 있어 전망이 좋다. 암릉에는 소나무가 우거져 있으며, 그 뒤로는 산들이 첩첩하게 서 있어 매우 아름답다.산행은 희귀한 민화를 전시하고 있는 조선민화박물관을 출발하여 암릉을 타고 올라 855m 봉우리에서 시루봉을 지나 정상에 오른다.", + "MNTN_HG_VL" : "1015", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "곰봉" }, - "longitude" : 127.54683439999999, - "latitude" : 36.455291099999997 + "longitude" : 128.65944440000001, + "latitude" : 37.2841667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서대산의 높이는 904.1m이다. 충청남도 남동부의 금강분지를 둘러싸고 있는 금산고원에 속해 있으며, 노령산맥을 이루는 정수이자 충청남도의 최고봉이다. 충남에서는 높이 904.1m으로 가장 높은 산으로서 기암 절벽으로 이루어져 있다.화강암으로 이루어진 원추형 암산인 서대산은 기암절벽과 숲이 어우러지고 제법 험준해 산행의 묘미를 더한다. 정상에 올라서면 웅장하고 온화한 산세가 한눈에 들어오고 멀리 서북쪽으로 대전시내가 펼쳐진다.원흥사, 개덕사등 유명사찰과 정상 직전에 직녀 탄금대, 정상에서 북쪽 546봉으로 이어지는 능선 주변에는 장면대, 북두칠성 바위, 사자굴, 쌀바위 등이 산재해 있다.협곡을 가로 질러 높게 설치된 약 50m의 구름다리 주변은 신선바위, 벼슬바위등 기암 절벽들이 어울려 장관을 이루고 있다.", - "MNTN_HG_VL" : "904", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 추부면ㆍ군북면, 충청북도 옥천군 군서면", - "MNTN_NM" : "서대산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "714", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 주문진읍 삼교리 \/ 양양군 현남면", + "MNTN_NM" : "삼형제봉" }, - "longitude" : 127.5357582, - "latitude" : 36.230901199999998 + "longitude" : 128.71777779999999, + "latitude" : 37.903888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 남양주시 수동면과 가평군 상면 경계를 이루는 서리산(825m)은 한북정맥에서 가지를 쳐 나온 주금산(814m)을 모산으로 하는 산이다.서리산은 그동안 축령산 유명세에 가려져 있었다. 그러나 10여 년 전부터 축령산자연휴양림이 본격적으로 알려지고 주능선에 수천 평 규모의 철쭉군락이 인기를 얻으면서 축령산 못지않게 인기를 끌고있다.산세는 주능선 북쪽 사면이 바위벼랑에 가까운 급경사로 이뤄진 반면, 남쪽은 완만한 산세로 이뤄져 있다. 따라서 등산로는 축령산자연휴양림이 있는 남쪽 위주로만 발달되어있다. 들머리인 외방2리 종점가게에 이르면 북쪽으로 소 한 마리가 드러누운 듯 올려다보이는 산이 서리산이다.종점가게에서 계류 건너로 마주 보이는 능선은 서리산 남서릉이고, 그 끝에서 남서봉인 화채봉이 보인다. 정상은 보이지 않는다. 서리산 오른쪽에 우뚝 솟은 산이 축령산 정상이다. 정상에서 주능선은 855봉을 거쳐 남쪽 오독산으로 이어지는데, 855봉에서 종점가게 방향으로 가지를 치는 능선이 있다. 바로 이 능선 상에 유명한 남이바위, 수리바위, 박달고지가 있다.", - "MNTN_HG_VL" : "825", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", - "MNTN_NM" : "서리산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "459", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 강서구", + "MNTN_NM" : "연태봉" }, - "longitude" : 127.3156252, - "latitude" : 37.768321800000002 + "longitude" : 128.83388890000001, + "latitude" : 35.0266667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 안성시와 충청북도 진천의 경계에 선 서운산은 아담하고 바위가 거의 없는 유순한 산세를 지녔으며 봄이면 계곡과 능선에 진달래와 철쭉이 군락을 이루는 아름다운 산이다.서운산에 위치한 청룡사는 고려 원종 6년(1265)에 명본국사가 대장암이라는 이름으로 창건한 절로 공민왕 때 나옹화상이 중건하면서 청룡이 서운을 타고 내려오는 것을 보았다 하여 산 이름은 서운산, 절 이름은 청룡사로 하였다고 한다. 서운산 동북쪽 기슭에는 신라 문무왕 20년(680)에 창건한 석남사가 자리 잡고 있는데 염거국사와 혜거국사 등 이름 높은 스님들이 석남사를 거쳐 갔다.서운산에서 뻗은 서쪽 능선으로는 삼태기 모양으로 둘러싼 서운산성의 흔적을 찾을 수 있는데, 이 성은 임진왜란 당시 의병장이었던 홍계남과 이덕남이 안성을 방어하기 위해 쌓았던 군사요충지로 성 안에는 두 의병장의 대첩을 기념한 기념비와 석불이 있다.", - "MNTN_HG_VL" : "548", - "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 서운면ㆍ충청북도 진천군 백곡면", - "MNTN_NM" : "서운산" + "DETAIL_INFO_DTCONT" : "황악산은 김천시에서 서쪽으로 12km 떨어진 곳에 위치한 산이다.옛부터 학이 많이 찾아와 황학산이라 불리었으나, 직지사의 현판 및 택리지에 황악산으로 되어있다. 울창한 소나무 숲과 깊은 계곡에 옥같이 맑은 물, 가을의 단풍과 겨울의 설화가 아름답다. 일대는 국민관광지로 지정되어 더욱 개발되고 있다.전체적인 산세는 특징없이 완만한 편이나 온 산에 수림이 울창하고 산 동쪽으로 흘러내리는 계곡은 곳곳에 폭포와 소를 이뤄 그윽한 계곡미를 이루고 있다. 특히 직지사 서쪽200m 지점에 있는 천룡대에서부터 펼쳐지는 능여계곡은 이산의 대표적인 계곡으로 봄철에는 진달래, 벚꽃, 산목련이 볼만하고 가을철 단풍 또한 절경을 이룬다.황악산 정상에서 직지사를 내려다 보면 무수한 지능선이 하나씩 계곡안에서 소멸된 뒤 마지막 남은 두가닥 능선이 좌우에서 직지사를 크게 싸안으면서 산과 절의 화합은 완성된다. 1111m에 이르는 황악산의 높은 봉우리와 그 아래 학의 날개처럼 펼쳐지는 계곡이 좁은 수로를 통하여 동으로 빠져나가고 그 길목에 직지사는 자리잡고 있는 것이다.직지사는 어떻게 보면 황악산 정기가 맺은 전혀 다른 종류의 꽃봉오리 같아 보인다. 직지사는 새로 세운 대형 일주문에 동국제일가람이라는 커다란 편액을 붙여놓은 대로 국중의 사찰 가운데서도 열손가락에 들만한 거찰이다.", + "MNTN_HG_VL" : "1111", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대항면 운수리", + "MNTN_NM" : "황악산" }, - "longitude" : 127.2969842, - "latitude" : 36.929757000000002 + "longitude" : 127.966111, + "latitude" : 36.119166999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "481", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군", - "MNTN_NM" : "서원산" + "DETAIL_INFO_DTCONT" : "복계산은 대성산(1174.2m)에서 복주산(1151.9m)을 향해 뻗어나가던 한북정맥의 산줄기가 수피령을 막 지나온 지점의 마루금에서 오른쪽(북서쪽)으로 약 700미터 벗어난 거리에 빚어놓은 명산이다. 민통선 바로 아래 위치해 있어 산행의 감회가 남다르고 ‘신철원팔경’의 하나인 매월대(595m)와 매월대폭포, 1996년 SBS 특집드라마 ‘임꺽정’의 청석골세트장 등이 있어 찾는 사람들이 많다.복계산은 매월대로 더 잘 알려진 산행지다. 복계산 기슭에 위치한 높이 40미터의 절벽이 매월대로 전설에 따르면 아홉 선비가 매월대에서 바둑판을 새겨놓고 바둑을 두며 단종의 복위를 도모했다고 전해진다.복계산을 산행한 후 승리전망대를 견학하면 안보산행으로서 금상÷화다. 그러기 위해서는 승용차나 관광버스를 이용하는 것이 좋다. 매월대주차장을 기점으로 복주산 정상에 오르는 코스는 매월대코스와 매월대폭포코스, 청석골세트장코스 등이 있는데 이중에서 매월대폭포코스로 올랐다가 청석골세트장으로 하산하는 것이 가장 무난하다.", + "MNTN_HG_VL" : "1054", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 근남면", + "MNTN_NM" : "복계산" }, - "longitude" : 126.63341490000001, - "latitude" : 36.7292141 + "longitude" : 127.50101100000001, + "latitude" : 38.2016609 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "삼도봉(1,176m)을 시작으로 민주지산(1,241m), 각호산(1,176m)과 함께 웅장한 서북 능선을 이루는 산군(山群)에 속한다. 각호산·민주지산·삼도봉을 잇는 능선은 수림이 우거지고 바위들이 섞여 있으며 봄이면 능선을 따라 8㎞에 걸쳐 진달래가 만발한다.그 산들 사이에는 유명한 피서지인 물한계곡(勿閑溪谷)이 자리잡고 있다. 삼도봉에서 북서쪽으로 약 40분 거리에 우뚝 솟아 있는 석기봉은 민주지산의 주릉 중에서 가장 빼어나며, 주위 전망도 일품이다.황악산이 북동으로 바로 보이고 동남으로는 가야산이 손에 잡힐 듯 가까이 보인다. 서서남으로는 마이산의 뾰족한 두 귀가 선명하다.", - "MNTN_HG_VL" : "1176", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", - "MNTN_NM" : "석기봉" + "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", + "MNTN_HG_VL" : "1268", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", + "MNTN_NM" : "응봉산" }, - "longitude" : 127.8641667, - "latitude" : 36.025277799999998 + "longitude" : 129.13138889999999, + "latitude" : 37.224722200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "석두봉은 강원도 오지중에서도 손꼽히는 오지에 위치한 탓으로 산악인들 사이에서도 잘 알려지지 않아 등산인들의 발길이 뜸하다. 그러다보니 등산로가 수풀에 둘러싸여 원시림을 헤쳐나가는 산행의 묘미를 만끽할 수 있다. 석두봉은 산이 깊어 물이 맑고 수량 또한 풍부하다.기다리던 돌산, 석두봉 올라보면 하늘과 맞닿는 느낌이다. 석두봉 정상은 이름 그대로 두 쌍의 바위로 이루어져 있다. 동봉과 서봉으로 정상을 지키고 있는 바위에 올라서면 일대의 경관을 한눈에 조망할 수 있으며 바위 사이로 자라는 철쭉들이 신기롭다.또한 참나무 노령목들이 여기저기 자라는 모습은 장관이며, 서쪽으로는 안반데기 동쪽으로는 왕산면 목계리가 한눈에 들어온다. 정상 바로 옆에 큰바위가 있는데 이곳에 오르면 상쾌한 느낌이다. 용수골을 내려다보며 큰소리로 메아리를 만들어 보는 것도 일미이다.", - "MNTN_HG_VL" : "991", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "석두봉" + "DETAIL_INFO_DTCONT" : "조비산은 처인구 백암면 용천리,석천리,장평리에 접해 있는조그마한 돌산이다. 새가 날아가는 형상같다하여 조비산이라 부른다하며 산향이 한양도(漢陽都)를 등지고 있다하여 역적산 즉 적비산이라 부른다. 용인팔경의 하나인 조비산은 동국여지지 죽산현편에 보면현 북쪽 십오리에 한 봉우리가 돌연 우뚝 솟아 돌을 이고있는데 산이 높고 가파라서 빼어난 모양이 기이 하게 보인다.", + "MNTN_HG_VL" : "260", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 백암면", + "MNTN_NM" : "조비산" }, - "longitude" : 128.8230556, - "latitude" : 37.608333299999998 + "longitude" : 127.3672222, + "latitude" : 37.118888900000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한북정맥 지류에 있는 석룡산은 오른쪽으로 화악산, 중봉이 있고 왼쪽으로는 국망봉이 버티고 서 있다. 그 지류를 따라 서남쪽으로 내려서면 민둥산과 강씨봉이 있고 산 능선을 타고 남쪽으로 내려서면 명지산과 연인산으로 이어진다.능선코스와 계곡코스를 한번에 즐길 수 있는 석룡산은 웅장한 산세에 비해 등산로가 완만하고 산행 내내 폭포와 담소를 흐르는 시원한 물소리를 들으며 산행을 즐길 수 있어 여름산행 코스로는 이보다 좋을 순 없다.석룡산은 돌로 된 용이 있는 산이란 뜻이지만 실상, 산 어디를 가도 용을 닮은 돌은 보기가 어렵다. 그런데도 옛사람들이 이 산을 석룡산이라 했던 이유는 조무락계곡을 이루고 있는 계곡 전체가 하나의 바위로 이루어져 있고 물길에 잘 다듬어진 모습과 흰물결 굽이치며 떨어지는 계곡이 마치 용과 같다고 해서 석룡산이라 불러지고 있다.", - "MNTN_HG_VL" : "1153", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ강원도 화천군 사내면", - "MNTN_NM" : "석룡산" + "DETAIL_INFO_DTCONT" : "취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 신불산 산자락에는 홍류폭포와 작천정이 유명하다.취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.", + "MNTN_HG_VL" : "1159", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 삼남면ㆍ상북면", + "MNTN_NM" : "신불산" }, - "longitude" : 127.4755749, - "latitude" : 38.005823399999997 + "longitude" : 129.0561611, + "latitude" : 35.539955999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 예산군 덕산면의 덕산도립공원 내에 위치한 해발 653m의 암산으로 가야산 주봉인 가야봉 북쪽 1.7km지점의 바위봉이다. 주봉인 가야봉에는 중계탑이 가득하게 들어서 있어 주봉의 의미를 퇴색시킨다. 석문봉은 이런 아쉬움을 달래기에 충분한 훌륭한 바위봉으로, 뛰어난 전망을 제공한다. 남쪽 주봉과 북동쪽 1.8km 지점의 옥양봉, 북서쪽으로 일락산이 내려다보이고, 서쪽 해미쪽으로는 서해바다가 시원스럽게 펼쳐진다.산행은 덕산시내에서 덕산초등학교 앞길로 들어선후 2차선의 포장도로를 따라 큰 저수지를 지나고 나오는 상가리 주차장에서부터 시작된다. 약 1km 떨어진 남연군묘앞 공터에 주차가 가능하지만 전체적으로 코스가 길지 않기 때문에 이곳에서부터 산행을 시작하는 편이 좋을 듯하다. 남연군묘 좌측길로 들어서서 시멘트길을 따라 저수지를 끼고 돌담집을 지나 쉼터를 거쳐 안부에 오른후 북쪽 암릉을 거쳐 석문봉 정상에 오른다. 하산은 북동쪽으로 잠시 내려가다 옥녀폭포로 내려서서 2km정도 내려서면 남연군묘에 도착하고, 1km를 더 내려가면 주차장에 도착한다. 산행시간은 총 3시간 30분 정도면 족하다.", - "MNTN_HG_VL" : "653", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", - "MNTN_NM" : "석문봉" + "DETAIL_INFO_DTCONT" : "삼악산(三岳山)은 한북정맥상의 포천 백운산 밑에서 동쪽으로 갈라진 지맥이 석룡산, 화악산, 계관산으로 이어지고 옛날 경춘 간 육로교통의 춘천관문이었던 석파령을 넘어 끄트머리에서 솟아 신연강 협곡을 이루어 놓은 명산이다.또한 협곡에 설치된 의암댐으로 호수가 생겨 물 속에 투영된 산을 볼 수 있어 더 한층 좋다. 매표소에서 계곡을 오르다 보면 등선폭포, 비선폭포, 승학폭포, 백련폭포등 크고 작은 폭포가 있으며, 용화봉, 청운봉, 등선봉을 비롯 3개의 봉우리에서 뻗어내린 능선이 암봉으로 이루어져 절경을 이룬다.기암괴석이 많고 소나무, 참나무등의 수림이 울창하며 계곡미가 빼어나다.삼악산의 산행기점은 세 군데 이다. 등선폭,상원사,강촌역에서 다리건너 바로 시작하는 세 기점이 있다. 대부분의 등산객들이 등선폭쪽에서 산행을 시작하나, 의암댐이 있는 상원사입구에서 시작하여 등선폭포로 내려오는 것이 좋다.", + "MNTN_HG_VL" : "656", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 서면", + "MNTN_NM" : "삼악산" }, - "longitude" : 126.6033333, - "latitude" : 36.716666699999998 + "longitude" : 127.66031169999999, + "latitude" : 37.839902700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉", - "MNTN_NM" : "석병산" + "DETAIL_INFO_DTCONT" : "태백과 정선 경계를 이룬 대덕산은 초원 산릉과 여름 꽃으로 이름난 산이다. 보름 간격으로 바뀌어 피어나는 야생화는 초원 산릉을 이룬 정상부를 말 그대로 천상의 화원으로 가꾸곤 한다. 게다가 폭 200~300미터에 길이 약 1킬로미터의 정상 능선은 함백산에서 금대봉을 거쳐 매봉으로 이어지는 백두대간뿐 아니라 두타산을 거쳐 오대산까지 이어지는 산릉도 한눈에 들어오는 등 멋진 조망을 제공한다. 8월 대덕산 초원능선은 둥근이질풀, 마타리, 제비꼬깔, 산박하가 만개하고, 9월로 들어서면 보랏빛 산비장이와 자줏빛 쑥부쟁이가 활짝 피는 등 야생화 100여 종이 만개한다. 대덕산의 산행기점은 한강 발원지로 이름난 태백시 삼수동 검룡소에서 시작한다.", + "MNTN_HG_VL" : "1310", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 삼수동", + "MNTN_NM" : "대덕산" }, - "longitude" : 128.89750000000001, - "latitude" : 37.586666699999988 + "longitude" : 128.92944439999999, + "latitude" : 37.240833299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 강릉시 옥계면과 정선군 임계면 사이에 솟은 해발 1055미터의 석병산은 백두대간에 위치한 산이며 정상부 바로 아래 둥그런 구멍이 뚫린 일월문과 회양목 군락지, 철쭉 군락지 등 색다른 볼거리를 제공하는 웅장함과 아름다움을 겸비한 산이다.두리봉 동남쪽을 시작으로 산 전체가 돌로 쌓여있어 마치 바위가 병풍을 두른 것 같다고 해서 석병산이라 불린다. 옛날에는 산삼이 많이 자생하고 있어 약초꾼들이 많이 드나들던 곳이기도 하다.석병산은 석고암으로 형성되어 동굴이 많은 산이기 때문에 범바위골 계곡이 주류인데도 물이 흐르지 않아 특이하다. 정상이 두 개의 흰 암봉으로 이루어져 있으며, 정상 일대에는 백리향, 참바위취, 구름체꽃 같은 희귀식물들이 꽃을 피우고 있어 봄과 초여름 사이에 아름다운 꽃구경을 할 수 있으며, 두 개의 암봉 중 북봉에서 보는 경관이 일품이다. 북쪽 면은 깎아지른 절벽이고 이 암맥은 북동 능선으로 이어진다.", - "MNTN_HG_VL" : "1053", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 옥계면, 왕산면ㆍ정선군 임계면", - "MNTN_NM" : "석병산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "280", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "호암산" }, - "longitude" : 128.89750000000001, - "latitude" : 37.586666699999988 + "longitude" : 127.71566850000001, + "latitude" : 34.768495399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "석화봉은 충북 단양의 수리봉과 황정산 사이에 동북 방향의 가지를 치고 그 지능선상에 솟아 있는 산이다. 석화봉을 가운데 두고 북으로 황정산, 동으로 올산(858m), 남서로 선미봉과 수리봉 암릉이 사방으로 에워싸고 있는 무풍지대다.형형색색의 기암괴석과 암봉 및 암벽, 암릉, 암굴 등으로 이루어진 신비로운 암산인 석화봉이란 이름은 시원스레 뻗은 암릉 위로 거대한 화강암 바위가 꽃처럼 피어 있는 형상에서 비롯된 것이다. 뿐만 아니라 정상 부근 낙타바위를 비롯해서 725봉 아래에 보는 이로 하여금 절로 웃음을 짓게하는 째진바위, 궁둥이 바위,백곰바위등이 산행을 즐겁게 하여준다. 산으로 오를수록 암릉길과 슬랩(경사),침니코스가 나온다 약간의 보조자일도 필요하다.정상에서의 조망은 시원하게 터진다.북동쪽으로 도솔봉과 흰봉산이 하늘금을 그리고 동쪽으로는 저수령 방면 백두대간과 그 아래 올산 마을이 아름답게 펼쳐진다.북서쪽으로는 암릉을 끌고 나가는 황정산이 우뚝하다.", - "MNTN_HG_VL" : "834", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "석화봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "981", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 구정면, 옥계면", + "MNTN_NM" : "칠성산" }, - "longitude" : 128.5541667, - "latitude" : 37.086388900000003 + "longitude" : 128.87542120000001, + "latitude" : 37.669779900000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "인천에서 영종도 선착장이 있는 구읍배터 앞에 있는 아담한 석화산은 우리 역사의 개항과 더불어 열강의 수난을 겪은 산이다. 병인양요(1866)때는 우리 강화도에서 우리 원군에 패해 하여각종 문서와 유물을 훔쳐 달아나는 프랑스 함선으로부터 무차별 포격을 받았으며, 상인(商人)오페르트는(1868) 대원군의 아버지인 남인군묘를 도굴하고 이곳을 한동안 점령하면서 개항을요구하기도 했으며, 신미양요(1871)때는 초지진과 덕진진에 이어 광성보까지 무너졌던 아픈 상처를 같이 했던 곳이다. 3개의 봉우리로 구성된 석화산은 조림 사업이 잘 된 곳 중에 한곳이다. 소나무가 우거져 있으며숲길은 낙엽으로 된 방석을 딛고 걷는 듯한 착각이 들 정도로 감촉이 좋다. 특히 솔잎 낙엽 길은솔 향 내음이 더욱 좋은 산이다.", - "MNTN_HG_VL" : "143", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구 중산동", - "MNTN_NM" : "석화산" + "DETAIL_INFO_DTCONT" : "경상북도와 충청북도의 경계를 이루고 있는 소백산은 우리 나라 12대 명산 중의 하나로 '한국의 알프스' 라 불린다. 이 산은 총 면적이 320.5km에 달하는 거대한 산줄기로 정상인 비로봉을 비롯하여 연화봉(1,376.9m). 제 2 연화봉(1,357.3m). 국망봉(1,420.8m) 등 1천m 고봉이 줄지어 있어 웅장한 산세를 이루고 있다.", + "MNTN_HG_VL" : "1440", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 풍기읍, 충청북도 단양군 단양읍", + "MNTN_NM" : "소백산" }, - "longitude" : 126.5508463, - "latitude" : 37.5047292 + "longitude" : 128.446123, + "latitude" : 36.951719900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1236", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 물야면, 영주시 부석면. 강원도 영월군 하동면", - "MNTN_NM" : "선달산" + "DETAIL_INFO_DTCONT" : "경상북도 구미시에 위치한 베틀산은 역암, 사암의 풍화 혹은 해식 작용으로 기이한 형태의 암석모양(큰상어굴, 작은 상어굴, 베틀굴)과 색상을 나타내고 있으며 해변가에서 느끼는 침식 현상을 여러 곳에서 볼 수 있다. 산은 그리 높지 않으나, 산세가 아기자기하고 암릉과 해식굴(海蝕窟) 등이 산재하여 산행이 재미있다.베틀산은 예전에 조계산이라고 불리었다. 문익점의 동생인 문영이 산의 모양과 해평면 오상리에 있는 공상다리의 모양을 따서 베틀을 만들어 문영베를 짜는 데 성공한 이후, 산이름이 조계산에서 베틀산으로 바뀌었다고 전해진다. 그밖에 어느 선비가 과거를 보러 한양으로 가는데 산 위에서 여인의 베짜는 소리가 들려왔다거나, 임진왜란 때 많은 사람들이 베틀굴에 피난하여 베를 짰다는 전설 등이 전해진다.", + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면 금산리", + "MNTN_NM" : "베틀산" }, - "longitude" : 128.7094563, - "latitude" : 37.0390199 + "longitude" : 128.4422836, + "latitude" : 36.206698400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "선달산은 백두대간의 소백산과 태백산 사이에 솟아 있어 대간을 조망하기에 좋은 산이다. 정상에서는 동쪽으로 남대천과 어래산이 보이고 서쪽으로는 박달령이 보인다. 또한 남쪽의 갈곶산과 이어진 부드러운 구릉으로 산행하기 수월하다.선달산 부근의 문화 유적으로는 부석사 무량수전(국보 제18호)과 소수서원이 있다. 무량수전은 우리나라 최고의 목조 건물로 신라 문무왕 때 의상대사가 창건 하였다. 소수서원은 1532년 주세붕이 세운 우리나라 최초의 서원으로 창건 당시 백운동서원으로 불리다가 명종 때 풍기군수로 있던 이황의 건의로 소수서원이라 불렀다.경상북도 봉화군은 사방이 산으로 첩첩이 둘러싸여 있고 그 속에 오전, 두내, 다덕 등 전국에서 손꼽히는 약수가 여러 군데 있다. 그 중 으뜸인 오전약수는 서쪽으로 마구령과 동쪽으로 도래기재 사이의 선달산 아래 있으며, 물맛이 가장 좋기로 조선시대 최고의 약수로 뽑히기도 했다. 그리고 중종 때의 풍기 군수 주세붕은 오전약수를 마음의 병을 고치는 좋은 스승에 비길만하다고 극찬했다. 약수터 앞 음식점이 들어선 곳을 제외하고는 한가로운 농촌 마을이다. 그러나 오전약수터 주변은 주말과 단풍철이 되면 관광차와 사람들로 부산스럽다.또한 선달산은 아름다운 계곡을 품고 있으며 각종 나무가 아름답게 줄을 서 있어 산세도 우아하다. 영월군 하동면 내리 지동마을에서부터 시작되는 내리천 계곡은 초입에서부터 울창한 수림과 풍부한 수량이 마치 원시의 비경을 연상케 한다. 계곡을 거슬러 오를수록 점입가경의 계곡미가 펼쳐지는데 한가지 흠이라면 이곳의 상류가 석회암 지대인지라 계곡 바닥이 온통 석회석으로 덮혀 물을 마실 수가 없다. 그러나 늪다리에 이르러 칠룡동 계곡으로 들어서면 계곡물은 옥같이 맑고 폭포,소 등이 연이어 그야말로 심산유곡이 펼쳐진다.", - "MNTN_HG_VL" : "1236", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 경상북도 영주시, 봉화군", - "MNTN_NM" : "선달산" + "DETAIL_INFO_DTCONT" : "팔각산은 계곡을 끼고 뾰족한 암봉 8개가 이어져 있는 데에서 유래했으며 ‘옥계팔봉’이라고도 부른다. 높은 산은 아니지만 각종 기암괴석과 급경사, 암벽 등으로 인해 산세가 험한 편이다. 산 중턱에는 200여 명이 앉을 수 있을 만큼 넓고 편평한 푸른색 암반이 있다.2000년 이전엔 등산로 4.5킬러미터만 개방되었으나 이후 6.1킬로미터 등산로가 추가로 정비되었으며, 곳곳에 로프와 철봉이 설치되었다. 8개의 연이은 봉우리에 다다를 때마다 동해와 삼사해상공원, 주왕산 줄기, 옥계계곡의 물줄기가 차례로 내려다보인다. 산 북쪽에 있는 산성계곡 일대에는 삼림욕장이 조성되어 있으며, 운동시설과 삼림욕 의자, 야외탁자, 평상 등 편의시설과 음수대, 간이화장실, 안내소, 종합안내소가 있다.팔각산과 동대산에서 흘러내린 물이 합류해 이루어진 옥계계곡도 팔각산에서 빼놓을 수 없다. 1607년 손성을이 광해군의 학정을 피해 은거하며 지은 침수정(枕漱亭)이 있으며 이 계곡 일원은 경상북도기념물 45호로 지정되어 있다. 손성을은 계곡 가운데 꽃봉오리 모양으로 앉은 진주암(眞珠岩) 외에 병풍바위, 향로봉, 촛대바위 등 주변의 아름다운 곳을 골라 ‘팔각산 37경’이라는 이름을 붙였다.", + "MNTN_HG_VL" : "633", + "MNTN_LOCPLC_REGION_NM" : "경북 영덕군 달산면 주응리", + "MNTN_NM" : "팔각산" }, - "longitude" : 128.7094563, - "latitude" : 37.0390199 + "longitude" : 129.2583333, + "latitude" : 36.344999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 단양군에 위치한 선미봉은 착한 산이라는 뜻의 착할 선자에다 산의 순수한 우리말인 `뫼'자를 붙여 선뫼봉으로 불리다가 오늘에 이르러서는 뫼가 아름다울 `미'로 변해 붙여진 이름이다.산이 착하다니 무슨 뜻일까. 착한산이라서 등산로마저도 편할 것 같지만 그동안 등산인들의 발길이 거의 미치지않아 등산로에는 잡목과 낙엽으로 원시림을 방불케한다. 정상에 오르면 서북쪽 풍광이 가장 먼저 시선을 끈다.선미봉과 맥락을 같이 하는 수리봉, 황정산, 도락산 정상이 시야에 와 닿고 동쪽으로는 멀리 도솔봉 부터 백두대간을 끌고온 시루봉과 촛대봉 그리고 저수령 아래로 거대한 분화구처럼 움푹패어든 목장지대가 그림처럼 펼쳐진다.", - "MNTN_HG_VL" : "1080", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 대강면", - "MNTN_NM" : "선미봉" + "DETAIL_INFO_DTCONT" : "계명산은 충주시내 동복쪽에 위치하여 마즈막재(620m)를 사이에 두고 동남쪽의 남산(636mㆍ금봉산)과 더불어 충주시를 두팔로 감싸 안듯 병풍을 두르고 있다. 또한 충주댐을 끼고 있어 산 위에 올라서면 충주호가 굽어보이고 월악산의 선경이 호반 위로 펼쳐진다. 충주시내가 가깝기 때문에 시민들이 많이 찾는 도심의 산이다.산 이름과 관련해 다음과 같은 유래가 전한다. 충주가 삼국시대 백제 영토로 있을 때였다. 왕족을 자칭하는 성주가 마고성의 성주도 겸하며 충주읍성(예성) 내관과의 왕래가 잦았다. 그러던 어느날 마고성주의 딸이 심항산 밑을 지나다가 지네에게 물려 갖은 약을 다 써봤으나 상처가 악화되어 죽고 말았다. 그날부터 성주는 관민들에게 지네를 모두 잡아 치우라고 명을 내렸지만 그 피해가 날로 심해졌다. 성주는 하는 수 없이 심항산 마루에 제단을 설치하고 매일 정심기도를 올렸다. 그러던 어느날 꿈에 용두백발을 한 신선이 나타나 “지네는 닭과 상극이니 많은 닭을 산에 방목하라 그러면 근절시킬 수 있을 것이다.”하고 일렀다.성주는 많은 닭을 방목했고 지네가 근절됐다. 그러나 또다시 지네가 번성할까 두려워 계속 닭을 놓아기르니 산 곳곳에 닭이 밟지 않은 데가 없었다. 그래서 원래 오동산, 심항산 등으로 불리던 이름이 계족산이라 부르게 됐는데 풍수설에 충주에 큰 부자가 안 나는 것은 계족산이 닭발의 형상이고 분산을 뜻한다고 해 1958년 충주시에서 산 이름을 여명을 알리는 뜻의 계명산으로 개칭했다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "충북 충주시 안림동ㆍ용탄동ㆍ종민동", + "MNTN_NM" : "계명산" }, - "longitude" : 128.33677549999999, - "latitude" : 36.845008499999999 + "longitude" : 127.977, + "latitude" : 36.989999999999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "1\/5,000 지도에는 배나무산이라 나오며 동네에서는 선암산이라고도 한다. 호계면 선암리 상선암동네 뒷산이며 산북면 석봉리와 경계하며 호계면 부곡리 부운령에서 시작하여 배나무산을 지난 단산으로 이어지며 노송군락이 아주 좋다.", - "MNTN_HG_VL" : "814", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 석봉리", - "MNTN_NM" : "선암산" + "DETAIL_INFO_DTCONT" : "보성군 득량면으로 들어서면 도로 왼쪽으로 너른 벌판이 펼쳐지고 그 끄트머리께 우뚝 솟은 산이 두 개 보인다. 예당벌과 오봉산이란 지명이 붙어 있는 산들이다. 이곳 사람들은 왼쪽은 오봉산, 오른쪽은 작은 오봉산(284.2m)이라 부른다. 다섯 개의 위성봉을 거느리고 있는 작은 오봉산은 가까이 가면 정상부 오른쪽에 바위가 삐죽 튀어나와 있는 것이 인상적이다.반면 봉우리가 다섯 개 모여 있는 오봉산은 산 아래 다가설 때까지도 그리 독특하지 못하다. 들녘에 솟은 그저 평범한 야산 정도일 따름이다. 하지만 파고들면 점입가경 신비스럽기 그지없다. 산행 초입 오봉산은 한때 구들장으로 애용되는 돌이 대량으로 추출되었다는 명성에 걸맞게 납작한 돌 천지다. 널찍하게 이어진 등산로를 따라 오르면 멋들어지게 쌓아둔 돌탑이 산 능선마다 쌓여있다.오봉산의 참 멋은 오봉산에 들어서야 알 수 있다. 그 중 오봉산의 으뜸은 칼바위다. 30여 미터 높이의 칼바위는 마치 손가락을 위로 세우고 손을 모아서 45도 각도로 굽힌 모양 같기도 하고, 선 채로 깊숙이 허리 굽혀 인사하는 모습 같기도 하다.웅장한 바위와 깊은 골짜기, 봄을 수놓은 진달래가 오봉산의 오른쪽 얼굴이라면 득량만이 내려다보이는 탁 트인 조망은 오봉산의 왼쪽 얼굴이다.", + "MNTN_HG_VL" : "513", + "MNTN_LOCPLC_REGION_NM" : "전남 보성군 득량면", + "MNTN_NM" : "오봉산" }, - "longitude" : 128.18333329999999, - "latitude" : 36.716666699999998 + "longitude" : 127.16861110000001, + "latitude" : 34.752777799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충남 금산과 전북 완주 사이에 우뚝 솟은 선야봉은 숲이 울창하고 신선풀무대 그리고 암봉과 암릉, 바위낭떠러지, 폭포 등을 고루 갖춘 산이다. 남북으로 뻗은 크고 높은 산줄기와 그 사이로 나란히 뻗은 경관 좋은 느티골과 피묵이골이 산 아래로 흐르고 있다. 그 중 금산쪽에 위치한 느티골은 아름다운 계곡이 이어져 있고 숲이 울창한데다 자연휴양림을 조성하고 있어 훌륭한 휴식처로 개발되어 있다.느티골 안쪽에 높이 25미터의 쉰길폭포가 장관을 이룬다. 새로 개설한 선야봉 등산로는 폭포를 지나며 아기자기한 암릉을 거쳐 기암괴봉을 조망할 수 있는 능선으로 이어져 있어 많은 등산객과 휴양객들이 자연을 편하게 즐길 수 있는 곳이다.정상 능선에서 서쪽으로는 대둔산, 천등산, 서대산이 있고 동쪽으로는 전적지로 유명하며 경관이 뛰어난 백암산이 있다.", - "MNTN_HG_VL" : "759", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 남이면ㆍ전라북도 완주군 운주면", - "MNTN_NM" : "선야봉" + "DETAIL_INFO_DTCONT" : "한북정맥 지류에 있는 석룡산은 오른쪽으로 화악산, 중봉이 있고 왼쪽으로는 국망봉이 버티고 서 있다. 그 지류를 따라 서남쪽으로 내려서면 민둥산과 강씨봉이 있고 산 능선을 타고 남쪽으로 내려서면 명지산과 연인산으로 이어진다.능선코스와 계곡코스를 한번에 즐길 수 있는 석룡산은 웅장한 산세에 비해 등산로가 완만하고 산행 내내 폭포와 담소를 흐르는 시원한 물소리를 들으며 산행을 즐길 수 있어 여름산행 코스로는 이보다 좋을 순 없다.석룡산은 돌로 된 용이 있는 산이란 뜻이지만 실상, 산 어디를 가도 용을 닮은 돌은 보기가 어렵다. 그런데도 옛사람들이 이 산을 석룡산이라 했던 이유는 조무락계곡을 이루고 있는 계곡 전체가 하나의 바위로 이루어져 있고 물길에 잘 다듬어진 모습과 흰물결 굽이치며 떨어지는 계곡이 마치 용과 같다고 해서 석룡산이라 불러지고 있다.", + "MNTN_HG_VL" : "1153", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ강원도 화천군 사내면", + "MNTN_NM" : "석룡산" }, - "longitude" : 127.3666667, - "latitude" : 36.048333300000003 + "longitude" : 127.4755749, + "latitude" : 38.005823399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산", - "MNTN_NM" : "선야봉" + "DETAIL_INFO_DTCONT" : "삼태봉은 광주산맥의 한 갈래로서 가평군에 위치하고 있다. 광주산맥의 한 갈래로 좌우에는 중미산과 화야산이 있고, 산위에 오르면 서쪽으로는 북한강, 동쪽으로는 뇌암산이 손에 잡힐 듯 다가오며 북동쪽으로는 곡달산이 바라 보인다.좌우로 중미산(834), 화야산(755), 용문산(1,157), 통반산(650)이 자리하고 있어 같이 연계하여 등산하는 것이 좋다. 특히 통반산과 같이 산행하는 것이 일반적이다.정상은 암번으로 이뤄져 있어 쉼터로 좋고, 한강의 조망이 일품이다. 그리고 통방산까지 이어지는 산길은 완만해서 좋고, 주변은 수림이 울창하다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군\/양평군", + "MNTN_NM" : "삼태봉" }, - "longitude" : 127.3666667, - "latitude" : 36.048333300000003 + "longitude" : 127.46194439999999, + "latitude" : 37.624166700000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봄이면 동백꽃과 벚꽃으로 유명한 선운산은 '호남의 내금강'으로 불리는 산으로 79년 도립공원으로 지정된 명산이다. 본래 도솔산이었으나 백제 위덕왕 24년(577년)에 창건한 선운사(禪雲寺)가 있어 선운산이라 불리게 되었다.선운산은 이름 그대로 구름 속에 선(禪)을 닦는 산으로 선운사를 비롯해 참당암, 도솔암, 석상암, 동운암 등 유서 깊은 사찰과 암자가 산자락에 자리잡고 있다. 그 중 선운사는 백제 위덕왕 24년(577년)에 검단(黔丹)선사가 창건한 사찰로, 한때 89개 암자를 거느리기도 하였으나 현재는 4개의 암자만 남아있다. 선운사 대웅전 뒤에는 5천여 평의 동백나무숲(천연기념물 제184호)이 있는데 매년 4월 중순이면 붉게 피어나 보는 이의 탄성을 자아내게 한다. 김정호의 '대동여지도'에는 선운산이 표시돼 있지만 현재 각종 지도에는 선운산이라 표시되어 있지 않으며, 선운사 뒷산을 '도솔산' 또는 '수리봉' 으로 표시하고 있다. 선운사 창건 설화는 여러 가지가 있다.원래 선운사 자리는 용이 사는 용추로 검단선사가 용을 쫓아냈지만 용추를 메울 길이 없자, 용추에 꼭두각시 배를 띄우고 돌을 던져 꼭두각시 놀이를 하게 하였다 한다. 또 그 때 마을에 눈병이 퍼졌는데 숯 한 짐씩을 용추에 버린 뒤 눈을 씻으면 낫는다는 소문을 퍼뜨려 용추를 메워 선운사를 지었다는 전설이 있다.실제로는 검단선사가 그의 친구이자 신라 24대 진흥왕의 왕사인 의운(義雲)선사의 도움을 받아 진흥왕의 시주로 선운사를 창건하였다 한다. 진흥왕이 중생제도를 위해 왕위를 버리고 도솔왕비와 중애공주를 데리고 입산, 수도하였다는 진흥굴(眞興窟. 일명 좌변굴(左邊窟),열석굴(裂石窟))이 도솔암 아래에 남아있다. 낙조대에서 바라보는 서해바다의 조망과 하늘로 날아오를 듯한 모습을 한 천마봉 등 볼거리가 푸짐한 이 산은 암자와 바위, 굴마다 숱한 전설이 깃들어 있어 지루함 없이 산행을 즐길 수 있다.특히 선운산 마애불에는 재미난 전설이 전해지고 있다. 옛날부터 마애불 배꼽 속에 신기한 비결이 들어 있고 그 비결이 나오는 날 한양의 이씨가 망한다는 전설이 있었다. 전라도 감사 이서구(李書九)가 마애불의 배꼽을 열어 보려다가 뇌성벽력이 쳐, 실패한 일이 있었는데 동학혁명이 일어나기 전 동학의 간부 손화중(孫和中)이 배꼽을 열고 그 비결을 꺼내갔다고 한다.", - "MNTN_HG_VL" : "335", - "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 아산면ㆍ심원면ㆍ해리면", - "MNTN_NM" : "선운산" + "DETAIL_INFO_DTCONT" : "전북 임실과 진안을 사이에 두고 우뚝 솟은 성수산은 고려와 조선의 건국설화가 살아있는 유서 깊은 산이다. 그렇게 높은 산은 아니지만 정상의 조망이 빼어나고, 남쪽으로는 향나무와 낙엽송, 활엽수 등 수백만 그루의 잘 자란 나무들이 빼곡히 들어차 삼림욕을 하기에 좋다.성수산자연휴양림 입구에서 10여분 오르면 상이암을 만나는데 상이암은 875년 도선국사가 창건한 절로 초기에는 도선암으로 불렸다가, 조선시대 태조 이성계가 조선을 개국하기 전 이곳에 와 치성을 드리니 하늘에서 ‘왕이 될 것’이라는 소리가 들렸다 해서 상이암이라 고쳤다고 한다. 그래서인지 성수산 주변에는 이성계와 연관된 이야기가 많이 전해진다. 절 입구에는 이성계가 직접 썼다는 ‘삼청동’ 비가 세워져 있고, 왕방리는 이성계가 왜구를 물리치고 귀경하던 중 지나갔던 마을이라고 한다.한편 상이암은 의병대장 이석용이 항일운동의 근거지로 이용하던 곳인데 그 때문에 일제시대 일본군에 의해 강제로 소실되었다가 1958년 상이암재건위원들에 의해 다시 세워졌다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 성수면ㆍ진안군 백운면", + "MNTN_NM" : "성수산" }, - "longitude" : 126.571111, - "latitude" : 35.508056000000003 + "longitude" : 127.41567430000001, + "latitude" : 35.640969800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "427", - "MNTN_LOCPLC_REGION_NM" : "경상남도 고성", - "MNTN_NM" : "선유산" + "DETAIL_INFO_DTCONT" : "강원도 횡성군 청일면과 홍천군 서석면의 경계를 이루는 봉복산은 남한강의 지류인 섬강의 발원지로 깨끗한 계곡과 풍부한 수량을 자랑하고 있다. 이 산은 산세가 봉황을 닮아서 '봉복산'이라고 불리우며, 산 뒤쪽에 봉복샘이 있는데 여기서 흐르는 물이 섬강을 이루는 근원이다. 산이 높은 만큼 골짜기가 깊지만 나무들이 많아 산세가 그렇게 험하지 않다. 맑고 깨끗한 물도 충분해서 좋은 산의 면모를 그대로 갖춘 산이다.봄에는 두릅, 산나물 등이 많이 나고, 여름철에는 소(沼)와 담(潭)이 많아서 시원함을 느낄 수 있다. 산이 높고 나무가 많아서 가을에는 낙엽이나 단풍도 가득하다. 단풍철만 되면 한꺼번에 몰리는 인파를 피해, 한적한 곳에서 여유롭게 단풍산행을 즐기기에 적합한 산이다. 호젓한 산길을 따라 흐르는 계곡이 너무나 맑고 깨끗하기에 기분이 무척 상쾌하기만 하다. 하얀 포말을 일으키며 쏟아지는 작은 폭포가 나타나는가 했더니 조금 더 오르면 시원한 숲그늘 속에 쉬어가기 좋은 반석을 이룬 곳들도 즐비하다. 꼭 신선놀음하는 분위기가 연이어지는 것이다.봉복산의 정상에서 내려다보는 경관은 그야말로 일품이다. 사방으로 막힘이 없이 시원하게 펼쳐져 있는 경치를 관망할 수 있다.", + "MNTN_HG_VL" : "1022", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", + "MNTN_NM" : "봉복산" }, - "longitude" : 128.27611110000001, - "latitude" : 35.1175 + "longitude" : 128.2163889, + "latitude" : 37.620277799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "줄줄이 산릉과 산등이 융기되어 있는 선의산은 명당이 많다고 하여 지관들이 구석구석을 누비면서 지금도 찾아다니고 있다. 신라시대 사찰이 있었고 암자가 있다 하여 암자골이라 하며 그 위에 있는 선의산은 청도군과 경산시의 경계를 이루고 있다. 또한 말과 닮은 산의 형세라 하여 말안쪽산 즉 마암산이라고 부르기도 한다.", - "MNTN_HG_VL" : "756", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "선의산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평", + "MNTN_NM" : "노적봉" }, - "longitude" : 128.77348799999999, - "latitude" : 35.727622799999999 + "longitude" : 127.4788889, + "latitude" : 37.880833299999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "756", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남천면, 청도군 매전면", - "MNTN_NM" : "선의산" + "DETAIL_INFO_DTCONT" : "문경시는 백두대간을 병풍처럼 두른 후에 남쪽방향으로 길게 뻗은 여러 개의 산줄기를 두고 평야지대와 산 구릉지대가 조화롭게 이룬 사람 살기 좋은 고장이다. 특히 지하자원이 풍부하여 조선시대 철의 생산지로 기록되어 있으며 일제시대와 현재까지 석탄 생산지로 유명하였다. 탄전지대는 단산을 중심으로 발전하였는데 운달산과 단산, 오정산을 중심으로 탄전이 모여 있다.단산은 오정산과 운달산 사이에 있는데 길게 뻗은 정상부는 깊은 산 속에 있는 산봉우리 같은 느낌을 준다.정상에서는 주흘산과 운달산이 눈앞에 들어오고 문경읍과 산북면 모습이 보인다.이 산은 능선을 타는 것이 가장 좋으며 잡목을 많이 헤치고 길을 찾으며 가야 한다. 광산 채굴 때문에 생긴 함몰지대를 조심하고 우회를 많이 해야 한다. 산에는 패러글라이딩의 활공장이 있다.", + "MNTN_HG_VL" : "956", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면", + "MNTN_NM" : "단산" }, - "longitude" : 128.77333329999999, - "latitude" : 35.726388900000003 + "longitude" : 128.18333329999999, + "latitude" : 36.716666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 강릉시 성산면과 평창군 도암면의 경계를 이루는 선자령은 백두대간의 주능선에 우뚝 솟아 있다. 산 이름을 '산'이나 '봉'이 아닌 선자령으로 부르게 된 유래는 알 수 없으나, 옛날 기록에 의하면 여러 가지 이름으로 표기하고 있다. 〈산경표(山經表)〉에는 '대관산(大關山)'이라 하고. 〈동국여지지도(東國輿地之圖)〉 와 〈사탑고적고(寺塔古蹟攷)〉에는 그 아래 보현사의 이름에 따라 '보현산(普賢山)'이라 표기되어 있다.그리고 보현사에 관한 기록을 전하는 〈태고사법(太古寺法)〉에는 '만월산(滿月山)'으로 적혀 있다. 보현사에서 보면 선자령이 떠오르는 달로 보이기 때문에 붙여진 이름인 것으로 추정된다. 선자령은 해발 840m인 대관령의 북쪽에 솟아 있는 산으로, 대관령에서 약 6km밖에 되지 않아 산행이 힘들지 않고 겨울철 적설 등반지로 적합하다. 대관령 고갯길은 옛날에는 오솔길이었으나, 이 고갯길을 조선조 중종때 이 지방 사람인 고형산이 사재를 털어 우마차가 다닐 수 있도록 넓혀 놓았다. 따라서 거의 평지길이나 다름없는 능선을 따라 오르게 되므로 산길은 매우 완만하다.이 능선길은 적설기와 신록기가 판이하게 달라진다. 적설기에는 많은 눈에 덮여 은세계를 이루어 황홀하고, 신록기에는 새로 자라난 연녹색의 초원에 야생화가 만발하여 화원을 이루고 있다.", - "MNTN_HG_VL" : "1157", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", - "MNTN_NM" : "선자령" + "DETAIL_INFO_DTCONT" : "경기도 안성시와 충청북도 진천의 경계에 선 서운산은 아담하고 바위가 거의 없는 유순한 산세를 지녔으며 봄이면 계곡과 능선에 진달래와 철쭉이 군락을 이루는 아름다운 산이다.서운산에 위치한 청룡사는 고려 원종 6년(1265)에 명본국사가 대장암이라는 이름으로 창건한 절로 공민왕 때 나옹화상이 중건하면서 청룡이 서운을 타고 내려오는 것을 보았다 하여 산 이름은 서운산, 절 이름은 청룡사로 하였다고 한다. 서운산 동북쪽 기슭에는 신라 문무왕 20년(680)에 창건한 석남사가 자리 잡고 있는데 염거국사와 혜거국사 등 이름 높은 스님들이 석남사를 거쳐 갔다.서운산에서 뻗은 서쪽 능선으로는 삼태기 모양으로 둘러싼 서운산성의 흔적을 찾을 수 있는데, 이 성은 임진왜란 당시 의병장이었던 홍계남과 이덕남이 안성을 방어하기 위해 쌓았던 군사요충지로 성 안에는 두 의병장의 대첩을 기념한 기념비와 석불이 있다.", + "MNTN_HG_VL" : "548", + "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 서운면ㆍ충청북도 진천군 백곡면", + "MNTN_NM" : "서운산" }, - "longitude" : 128.745, - "latitude" : 37.722222199999997 + "longitude" : 127.2969842, + "latitude" : 36.929757000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "설악산은 한라산(1,947.3m),지리산(1,915.4m)에 이어 남한에서 세 번째로 높은 산으로 강원도 속초시와 양양군,인제군에 걸쳐 있다.옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.백두산에서 남쪽으로 내리뻗어 이 땅의 기나긴 등뼈를 이루는 백두대간의 허리를 받들고 있는 설악산은 북의 금강산과 남의 오대산 사이에 솟아있는 천하의 명산으로 우리나라 관광명소 1호로 꼽힌다. 지난 1965년 11월 5일 천연기념물지구(163.4㎞), `69년 관광지(16.2㎞) 그리고 '70년에는 국립공원(174㎞)으로 각각 지정되었다. 그리고 1971년 9월에는 설악산 국립공원 관리사무소가 개설 되었고 `77년 '78년 두차례에 걸쳐 354.6㎞로 확장되었으며, 그 후 다시 374㎞로 넓이를 확대하였다. 울산암 등산로 초입에 있는 신흥사는 대한불교 조계종 제3교구 본사로 설악산의 대표적 사찰이다. 신라때 자장율사가 노루목근처에 향성사로 창건했다가 조선조때 현위치에 다시 세웠다고 한다.", - "MNTN_HG_VL" : "1708", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동, 인제군 북면ㆍ인제읍, 양양군 서면ㆍ강현면", - "MNTN_NM" : "설악산" + "DETAIL_INFO_DTCONT" : "비룡산(240m)은 높이가 낮아서인지 그리 알려지지 않은 산이다. 그러나 제2의 어라연이라 할 수 있을 만큼 그림 같은 전경을 자랑하는 회룡포를 끼고 있는 산자락으로 산행길 내내 조망이 훌륭하며, 육지 속의 섬인 의성포(義城浦)를 감싸고 있는 산이다. 1998년에 세운 정자인 회룡대에 오르면 주변 경관이 한눈에 들어오는데, 특히 낙동강의 지류인 내성천(乃城川)이 휘감아 돌아 모래사장을 만든 곳에 자리한 의성포의 절경이 잘 내려다보인다. 의성포는 이웃하고 있는 회룡마을과 함께 하나의 관광지군으로 묶여 있어 회성포라고도 부르는데, 드라마 〈가을동화〉를 찍은 곳으로 유명해져서 사람들이 많이 찾고 있다.숲이 울창하며, 정상 바로 밑에 통일신라 때 의상대사의 제자인 운명선사가 세운 장안사가 있다. 1997년 11월 복원한 봉수대는 예전에 동쪽의 서암산 봉수, 서쪽의 소이산 봉수, 북쪽의 가불산 봉수와 연락을 담당하는 군사요충지였다고 한다. 정방형이며, 높이는 2.7m이다.또 마한시대에 축성된 원산성(圓山城:또는 따뷔성, 또아리성)이 있는데, 둘레가 약 920m, 높이가 1.5~3m인 토석혼축산성이다. 《군지》에는 '비룡산성'으로 기록되어 있으나 《삼국사기》에는 원형으로 쌓았다 하여 '원산성'이라고 표기되어 있다. 백제 시조 온조가 남하할 때 이 성에서 마한을 점령하고 백제를 세웠다거나, 고구려 온달 장군이 이 성을 점령하려고 내려오다 아차산성에서 전사했다는 이야기가 전해진다. 용궁향교, 무이서당(武夷書堂), 만파루, 황목근(천연기념물 400), 삼강 나루터가 가까이 있고 그밖에 용문사 대장전(보물 145) 외에 많은 문화재를 보유하고 있는 용문사와 예천 감천면의 석송령(천연기념물 294) 등 관광명소가 있다.", + "MNTN_HG_VL" : "240", + "MNTN_LOCPLC_REGION_NM" : "경상북도 예천군", + "MNTN_NM" : "비룡산" }, - "longitude" : 128.46555810000001, - "latitude" : 38.119550400000001 + "longitude" : 129.04750000000001, + "latitude" : 36.996388899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.", - "MNTN_HG_VL" : "1708", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동", - "MNTN_NM" : "설악산 공룡능선" + "DETAIL_INFO_DTCONT" : "강원도 영월에 화채봉과 구룡산 사이에 솟아 있는 된불데기산은 위험지대가 없고 묵밭지대 초원이 산재해 있어 가족산행지로 안성맞춤이다.된불이란 말은 사냥꾼들이 쓰는 용어로 급소를 맞힌 총알을 일컫는데 전에 이 산에 멧돼지가 많아 마을 주민들이 멧돼지 사냥을 하면서 된불데기 산이라 불렀던 것이 산 이름의 유래가 되었다. 사람들 발길이 뜸하여 기름진 땅에서 자란 약초들은 유난히 향이 진하다.정상에 서면 북으로 화채봉과 삿갓봉 오봉산이 펼쳐져 있고 동으로는 백덕산이, 남으로는 구룡산이 시야에 들어온다.서쪽으로는 운학천 계곡 건너로 배향산이 멀리의 치악산 비로봉과 매화산 등과 함께 조망된다.", + "MNTN_HG_VL" : "910", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", + "MNTN_NM" : "된불데기산" }, - "longitude" : 128.4504379, - "latitude" : 38.145543600000003 + "longitude" : 128.2186111, + "latitude" : 37.347499999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남면 홍현마을에 있는 설흘산(488m)은 망산(406m)과 인접해 있다. 설흘산에서 내려다보면 깊숙하게 들어온 앵강만이 한눈에 들어오고 서포 김만중의 유배지인 노도가 아늑하게 내려다보인다. 인접하고 있는 전남 해안지역 뿐만 아니라 한려수도의 아기자기한 작은 섬들도 조망할 수 있는 곳이다.설흘산 정상 부근에는 봉수대의 흔적이 남아 있다. 원래 봉수대는 주위를 넓게 관측할 수 있는 곳에 정하는데 설흘산 역시 한려수도와 앵강만 그리고 망망한 남쪽 대해를 관측할 수 있는 곳이다.남면 구미 지역과 응봉산으로 오르는 등산로는 망망대해와 기암괴석 그리고 아래로 내려다보이는 다랭이마을의 풍경을 제대로 즐길 수 있다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "경남 남해군 남면", - "MNTN_NM" : "설흘산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "399", + "MNTN_LOCPLC_REGION_NM" : "충청남도공주", + "MNTN_NM" : "국사봉" }, - "longitude" : 127.8987633, - "latitude" : 34.737474499999998 + "longitude" : 127.22861109999999, + "latitude" : 36.410277800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산정에 부처님을 닮은 불상이 있다하여 이름 붙여졌다는 성불산은 충북 괴산군 감물면에 울창한 삼림을 등에 지고 아담히 솟아있는 산이다. 충북 괴산군에는 아직까지 사람의 발길이 많이 닿지않아 천연의 자연상태를 보존하고 있는 산들이 다수 있는데, 성불산도 그 중 하나다.소백산의 지맥으로 갈라져 나와 다소곳이 앉아있는 성불산은 산 규모도 작고 외진 곳에 위치하여 산악인들에게 별로 알려지지 않은 산이다. 가벼이 산책하듯 오르내릴 수 있는 산이라 생각하기 십상이나, 작은 산등성엔 험준한 암봉들이 십여개가 늘어서 있고, 그 사이마다에는 노송들이 하늘을 가리우고 있어, 풍광면에서나 산행 난이도 면에서나 결코 만만히 봐서는 안된다.정상에서는 모산인 박달봉이 동쪽으로 근접해있고, 남동쪽으로는 덕가산, 치로산, 보배산 등이 둘러싸고, 서쪽 편에는 고산구경을 품고 있는 달천이 감돌아 흐른다. 강 건너 괴산 시내를 한눈으로 내려다 볼 수 있는 위치에 있는 명산이다.", - "MNTN_HG_VL" : "532", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 감물면 매전리", - "MNTN_NM" : "성불산" + "DETAIL_INFO_DTCONT" : "주암산은 앞산과 비슬산으로 대표되는 대구 남쪽 산군의 동쪽 부분을 차지한다. 가창댐이 있는 용계천과 냉천이 산자락의 북동쪽을 감싸며 흐르고, 정상에서 남서로 뻗은 산줄기는 최정산을 지나 비슬산, 청룡산 앞산으로 이어지며 거대한 산지를 이룬다. 주암산 산행은 허브힐즈 오른쪽 안양사나 광덕사 뒤 능선을 따라 오른다. 동쪽 자락의 주암산수양관, 또는 동남쪽 원장마을에서 원티골을 따라 오르는 길이 일반적이다. 어느 곳을 들머리로 삼든지 산행은 3~4시간이면 충분하다. 주암산은 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 정상 일대와 능선에는 억새풀이 무성하고, 봄에는 진달래 천국을 이루고, 가을에는 단풍이 온 산을 물들여 대구 근교지방의 주민들에게는 매우 친근한 산이다. 최정산과 주암산은 능선상으로 바로 이웃하여 있어 두 산을 종주하는 것도 좋다.", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", + "MNTN_NM" : "주암산" }, - "longitude" : 127.8619885, - "latitude" : 36.814836700000008 + "longitude" : 128.61694439999999, + "latitude" : 35.773888900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제주시에서 동쪽으로 48km 떨어져 있는 성산포 바닷가에는 삼면이 바다로 둘러싸인 성산반도의 위쪽에 분화구로 이루어진 돌산이 있다.이곳이 바로 아름다운 성산일출봉인데, 한덩이의 왕관같은 99개 기암 봉우리와 짙푸른 바다 위를 솟아 오르는 아침 햇살이 장관을 이룬다.", - "MNTN_HG_VL" : "182", - "MNTN_LOCPLC_REGION_NM" : "제주도 남제주군 성산읍 성산리 114", - "MNTN_NM" : "성산 일출봉" + "DETAIL_INFO_DTCONT" : "태백산맥에서 동남쪽으로 갈라져 나온 산줄기가 경주시 단석산(829m)을 지나 구룡산·반룡산으로 벋으며 솟은 산으로 청도 지방을 동과 서로 나누는 기준이 된다. 마을주민들이 흔히 마음산이라고 부르는 북쪽의 선의산(756.4m)과는 능선으로 이어진다. 비가 내려 산이 운무에 덮이는 광경이 아름다워 청도팔경의 하나로 꼽힌다.용각산은 용에 관한 유래가 많은 산으로 용이 물을 마셨다는 용샘, 용마가 태어나지 못하게 쇠말뚝을 박았다는 용맥, 용의 발자취가 있었다는 용바위 등 용에서 유래되어 심지어 바위샘까지도 용 자가 붙어 있다. 갖가지 용의 전설은 용을 숭배하는 토속 신앙의 표현이다. 또한 용맥은 용각산의 모습이 일본 후지산과 너무 흡사하여 임란 전에 일본에서 밀정을 파견하여 마을에 큰 인물이 나는 것을 미리 막기 위해 산정에다 쇠막뚝을 박았다는 이야기가 지금도 전해지고 있다.", + "MNTN_HG_VL" : "693", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군, 경산시 남천면", + "MNTN_NM" : "용각산" }, - "longitude" : 126.9425, - "latitude" : 33.458056000000013 + "longitude" : 128.7666667, + "latitude" : 35.6988889 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 임실과 진안을 사이에 두고 우뚝 솟은 성수산은 고려와 조선의 건국설화가 살아있는 유서 깊은 산이다. 그렇게 높은 산은 아니지만 정상의 조망이 빼어나고, 남쪽으로는 향나무와 낙엽송, 활엽수 등 수백만 그루의 잘 자란 나무들이 빼곡히 들어차 삼림욕을 하기에 좋다.성수산자연휴양림 입구에서 10여분 오르면 상이암을 만나는데 상이암은 875년 도선국사가 창건한 절로 초기에는 도선암으로 불렸다가, 조선시대 태조 이성계가 조선을 개국하기 전 이곳에 와 치성을 드리니 하늘에서 ‘왕이 될 것’이라는 소리가 들렸다 해서 상이암이라 고쳤다고 한다. 그래서인지 성수산 주변에는 이성계와 연관된 이야기가 많이 전해진다. 절 입구에는 이성계가 직접 썼다는 ‘삼청동’ 비가 세워져 있고, 왕방리는 이성계가 왜구를 물리치고 귀경하던 중 지나갔던 마을이라고 한다.한편 상이암은 의병대장 이석용이 항일운동의 근거지로 이용하던 곳인데 그 때문에 일제시대 일본군에 의해 강제로 소실되었다가 1958년 상이암재건위원들에 의해 다시 세워졌다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군 성수면ㆍ진안군 백운면", - "MNTN_NM" : "성수산" + "DETAIL_INFO_DTCONT" : "충청북도 단양군 영춘면과 경상북도 영주시 단산면에 걸쳐 있는 형제봉은 동·북 비탈면에서 남한강 지류 남대천이 발원한다. 소백의 남서쪽 끝자락에 이름 그대로 두 봉우리가 우뜩 솟은 형제봉(1,177.5m)은 소벡산 중에서도 찾는 이가 거의 없는 곳이다. 소백산의 주능선과 이어져 있지만 거의 독립된 봉우리라 해도 과언이 아니다.소백산 끝자락에 온화하게 솟은 산. 비로봉에서 북동쪽으로 직선거리 11.5Km 지점에 솟은 형제봉은 이름 그대로 두 봉우리가 사이좋게 솟아 소백의 남서쪽 끝자락에 자리잡고 있다. 죽령에서 시작하여 비로봉을 지나 국망봉에서 내려오면 형제봉을 바로 앞두고 칼바위에서 서쪽으로 백두대간이 갈려나가고 형제봉을 지나 의풍리로 빠져 나오면 총 39km로 소백산의 가장 긴 종주코스에 해당한다.", + "MNTN_HG_VL" : "1115", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영춘면", + "MNTN_NM" : "형제봉" }, - "longitude" : 127.41567430000001, - "latitude" : 35.640969800000001 + "longitude" : 128.56805560000001, + "latitude" : 37.036111099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1060", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", - "MNTN_NM" : "성수산" + "DETAIL_INFO_DTCONT" : "속리산과 구병산 사이에 빼꼼히 솟아오른 금적산은 충북 보은군 삼승면에 그 터를 두고 있다. 예로부터 전국민이 3일간 먹을 수 있는 보배가 묻혀 있다고 전해오는 이 산은 주변에 어울린 명산을 닮아 수려한 산세를 자랑하고 있다.또한 이 산은 이름과 관련하여 금으로 된 동물이야기를 전설로 전하고 있다. 옛날 이 산에는 금송아지와 금비둘기가 살고 있었다. 금송아지는 금비둘기를 아내로 맞이하기 위하여 산기슭에 밭을 일구어 금비둘기가 좋아하는 여러 가지 곡식을 가꾸었다. 양지 바른 곳에 집을 짓고 바위아래 옹달샘을 파서 보금자리도 마련했다.그런 다음 금비둘기에게 청혼하여 둘은 결혼을 하게 되었고 금슬좋은 부부로 행복한 나날을 보내고 있었다.그러던 어느날 금송아지는 밭을 갈다가 넘어지는 바람에 두눈을 잃고 말았다. 금비둘기는 눈먼 남편을 위하여 열심히 봉양하였으나 금비둘기의 벌이로 금송아지를 먹이기에는 역부족이었다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "충청북도 보은군 삼승면 서원리", + "MNTN_NM" : "금적산" }, - "longitude" : 127.4813889, - "latitude" : 35.721388900000001 + "longitude" : 127.70805559999999, + "latitude" : 36.406388900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "면적 72평방 킬로미터에 둘레가 44.12킬로미터인 울릉도는 포항에서 뱃길로 188킬로미터 떨어진 섬으로 독도를 포함해서 본토에서 가장 멀리 있는 섬이다. 섬 주변은 대부분 화산암의 해안절벽으로 되어 있는데 바로 이 섬 중심부에 성인봉이 자리해 있다.작은 땅, 울릉도 위에 하나의 봉우리가 솟아 있으니 성인봉이 곧 울릉도인 셈이다. 울릉도는 오래전부터 왕조들의 정책에 의해 백성들을 살 수 없게 하였던 곳이나 백성들이 몰래 숨어 들어 끝끝내 우리 땅으로 지켜낸 우리 민족의 기상이라고 할 수 있다. 울릉도에 관한 기록은 신라시대로 거슬러 올라간다.〈삼국사기〉와 〈삼국유사〉에 신라 22대 지증왕 때 울릉도에 관한 기록이 있다. 〈삼국사기〉에는 지증왕 13년에 우산국(于山國)이 항복했고, 하실라 군주 이사부(異斯夫)가 나무로 만든 사자를 싣고 가서 항복을 받았다고 기록되어 있는데 〈삼국유사〉의 기록은 조금 다르다. 〈삼국 유사〉에 따르면 아슬라주 동쪽 바다에서 순풍으로 이틀 걸리는 곳에 우릉도(于陵島)가 있고 이 섬에 사는 오랑캐들은 교만하게 바닷물이 깊은 것을 믿고 조공을 바치지 않아 이창 박이종(朴伊宗)이 나무사자로 위협해 항복시켰다고 한다.울릉도는 겨울에는 따뜻하고 여름에는 시원해서 누구라도 살기 좋고 모든 것이 풍요롭다. 특히 '3무'라고 해서 도둑,거지,뱀이 없고 '5다'라고 하여 향(香),풍(風),미(美),수(水),석(石))이 많기로 이름나 있다. 해안가로 나가면 구멍바위(공암), 거북바위, 사자바위, 곰바위, 말바위, 국수를 널어놓은 듯한 국수바위 등 기암괴석을 쉽게 볼 수 있다. 성인봉 북쪽 하산 길에 있는 이십 여만 평의 나리분지에는 억새 밭과 나리꽃 군락이 서쪽으로 솟아 있는 알봉(538)과 어우러져 비경을 자아낸다.울릉도 서쪽 끝 태화동에는 울릉도의 대표적 사당인 성하신당이 자리잡고 있다. 이곳 주민들은 매년 음력 2월에 농사와 어업의 풍년,풍어를 빌고 있다.전설에 의하면 성하신당은 조선 태종 때 안무사로 왔던 김인우가 세웠다고 한다. 안무사 김인우가 심한 풍랑으로 본토에 돌아가지 못하고 있을 때 신의 지시를 받고 젊은 남녀 한 쌍 태하동에 억지로 떼어놓고 본토로 돌아갈 수 있었는데 몇 년 뒤 울릉도에 다시 와 보니 두 사람이 껴안은 채 백골이 되어 있어 그들의 원혼을 달래기 위해 세운 사당이라 한다. 저동에서 봉래폭포로 이어지는 등산로에는 바위틈에서 찬바람이 나오는 〈천연에어컨〉이 땀을 시켜 준다.천연에어컨에서 정상으로 이어지는 등산로를 따라 약 40분 오르면 세 갈래 물줄기가 원시림을 뚫고 쏟아지는 봉래폭포를 만나게 된다. 나리분지에서 산행이 끝나는 지점인 천부선착장을 따라 서쪽으로 2백미터정도 걷다보면 바위굴 속에서 찬바람이 나오는 풍혈(風穴)이 있다. 봉래폭포쪽 천연에어컨보다 못하지만 여름 땀을 씻어내기에는 충분하다.", - "MNTN_HG_VL" : "987", - "MNTN_LOCPLC_REGION_NM" : "경상북도 울릉군 울릉읍 서면ㆍ북면", - "MNTN_NM" : "성인봉" - }, - "longitude" : 130.86615280000001, - "latitude" : 37.503257099999999 + "DETAIL_INFO_DTCONT" : "능동산은 영남알프스의 산군 중에 하나이며 가지산과 천황산, 재약산의 유명세에 가려 그 이름이 묻혀 버렸다. 석남재에서 천황산에 뻗은 산줄기의 중간지점에 우뚝 솟아 있는 산이며, 언양에서 얼음골로 넘어가는 도로가 개통되기 전에는 주변의 산세속에서 아주 깊이 뭍혀 있었던 산이였다.그러나 언양과 밀양을 잇는 도로가 개통되면서 지금은 석남터널에서 가까이 보이고, 또 천황산에 가는 길목의 능선에 위치하고 있어서 많은 등산객들이 지나는 산이다. 특히 이 산에서 천황산과 배내봉 방향의 능선이 갈라지고 있으므로 영남알프스 종주길에 반드시 거치게 되는 지점에 위치하고 있다.능동산 산행은 석남사 주차장 안쪽에서 시작된다. 포근한 산길에 경쾌한 걸음으로 40여 분 후 전망대에 오르는데 여기서 영남 알프스 1000m 고지들이 시야에 전개되고 시원한 바람까지 불어온다. 능동산은 영남 알프스 중앙에 위치해있기 때문에 정상에 오르면 전망을 두루두루 관망할 수 있다. 정상에는 돌무더기를 쌓아 두었는데 아마도 등산객들이 소원성취와 안전을 기원하면서 돌을 하나 둘 올리다보니 돌무더기로 변한 듯 싶다. 하산은 반대쪽으로 하면 된다.", + "MNTN_HG_VL" : "983", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "능동산" + }, + "longitude" : 129.01635809999999, + "latitude" : 35.584783199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성주산은 오서산과 함께 보령을 상징하는 명산으로 예로부터 성인, 선인이 많이 살았다 하여 성주산이라 부르고 있다. 성주산에는 질 좋은 소나무를 비롯, 느티나무, 굴참나무, 졸참나무, 때죽나무, 고로쇠나무 등이 자생하고 있는데 한낮에도 컴컴할 정도로 울창한 숲을 이루고 있다.또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다. 특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다.성주산 일대에 모란형의 명당8개소(성주8묘)가 있었는데 그중 하나가 이곳에 감추어져 있다하여 화장골이란 이름이 붙여졌다. 지금도 명당을 찾으려는 이들의 발길이 잦은 곳이기도 하다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.소요 시간 :150분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 심연동 계곡,삼림욕장,잔디광장, 전망대성주휴양림의 자랑거리가 되고 있는 숲속의 집 통나무 방갈로는 여름철뿐만 아니라 단풍이 짙어가는 가을철이나 흰눈에 싸인 겨울철에도 더할나위 없는 좋은 휴양시설로 각광받고 있다. 휴양림을 찾는 이들의 발길은 아무래도 여름철에 절정을 이룬다. 이때에는 이동도서관이 마련돼 이용자는 얼마든지 책을 대여해 시원한 계곡물에 발을 담그고, 혹은 삼림욕을 하면서 독서 삼매경에 빠질 수 있다.숲길 명소 : 휴양림 입구에서 정상 쪽으로 5백미터 오르면 휴양림을 만날 수 있고, 심연동 계곡쪽에도 휴양림 공간이 마련되어 있다. 또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다.특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.성주산 휴양림에서 정상까지 올라 산 뒤편으로 내려가도 심연동 계곡과 연결되어 있다. 예부터 깊은 골짜기가 있는 마을이라 하여 심연동이라 이름지어진 것처럼 골과 골 사이에 흘러내리는 계곡이 깊고 수려하다.휴양을 위한 각종 편의시설이 설치된 중앙의 코스 외에 외곽으로 따로 등산객을 위한 등산로가 성주산 정상까지 나 있다. 봄에는 만발한 온갖 꽃들의 안내를 받으며, 여름에는 신록의 축복 속에서 삼림욕을 하고, 가을엔 수려한 단풍에 취한 채, 겨울엔 통나무 방갈로에서 아름다운 설경을 음미할 수 있는 곳이 바로 성주산 자연휴양림이다.", - "MNTN_HG_VL" : "512", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", - "MNTN_NM" : "성주산" + "DETAIL_INFO_DTCONT" : "몽덕산(680m)에서 뻗어 내린 능선이 가덕산(858m),북배산(867m)을 일으키고 싸리재를 지나 서남쪽으로 이어지는 능선에 우뚝 솟아 있는 계관산은 강원도 춘천시 서면과 경기도 가평군 북면의 경계를 이루는 산이다.몽덕산에서 계관산으로 이어지는 주능선 마루에는 폭 20여 미터에 방화선이 만들어져 있는데 이곳에 억새풀이 빼곡이 들어 서 있다. 가을이면 황금빛으로 물들어 산행 재미를 더해 준다. 정상에 서면 북으로는 북배산, 그 뒤로 가덕산과 몽덕산이 가까이 보이고, 그 오른쪽으로 용화산과 오봉산이 한눈에 들어오며, 동쪽 발 아래로는 물위에 떠 있는 듯한 춘천시내와 의암호가 거울처럼 보인다.서북쪽으로는 구나무산, 월출봉, 백둔봉, 명지산, 수덕산, 화악산 등의 산맥이 줄지어 솟아 있다.", + "MNTN_HG_VL" : "736", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군, 강원도 춘천시", + "MNTN_NM" : "계관산" }, - "longitude" : 126.6788646, - "latitude" : 36.365286699999999 + "longitude" : 127.6083333, + "latitude" : 37.883055599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "성지봉은 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑다. 금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서남으로 뻗어나가고 있다.경기도 양평군 청운면과 강원도 횡성군 서원면의 경계를 이루는 성지봉 (791m)은 산 이름에서 나타나듯이 천주교와 관계가 깊은 곳이다. 조선 순조 원년(1801년)의 신유 박해와 고종 3년 (1866년) 병인양요, 고종 8년 (1871년) 신미양요 등으로 극심하게 탄압 받았던 천주교 신도들이 이곳 성지봉으로 숨어 들었다고 한다.직행버스는 성지봉 입구에 정차하지 않으므로 청운에서 횡성 방향으로 1.5km 못 미친 풍수원에 하차 하여야 한다. 풍수원 마을 가장 윗쪽에 강원도 유형문화재 제 69호로 지정된 풍수원 천주교회가 자리잡고 있다. 이 교회가 옛날 천주교인들의 피난처였던 것이다. 천주교회는 고종 27년 (1888년) 프랑스인 르메르이신부가 초가집 사랑방에서 초대 신부로 부임해 한국에서 네 번째 천주교회로 출발한 곳으로 유명하다.", - "MNTN_HG_VL" : "791", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 청운면, 강원도 횡성군 서원면", - "MNTN_NM" : "성지봉" + "DETAIL_INFO_DTCONT" : "전남 보성은 차 다음으로 철쭉이 유명한 고장이다. 이에 제암산과 일림산은 5월이면 사람들이 줄 지어 찾아 오른다. 반면 같은 보성임에도 불구하고 여유롭게 철쭉을 즐길 수 있는 산이 있으니 바로 겸백면에 위치한 초암산이다.제암산, 일림산이 산 정상에 오르면 푸른 바다와 어우러진 철쭉을 볼 수 있다는 장점이 있는 반면 초암산은 철쭉 하나로 승부한다. 단출하게 느껴지지만 그만큼 색이 분산되지 않는 단정한 미학이 살아 있는 산이다. 또한 초암산은 철쭉이라는 핵심만을 즐기고 내려올 수도 있다는 간편함이 두드러진다. 최근 너무 힘든 산행보다는 간편하게 즐기면서 오를 수 있는 산을 찾는 사람들이 증가한 만큼 초암산은 앞으로 많은 사람들이 찾기에 매력적이다. 북쪽 임도를 이용해 철쭉밭 바로 아래까지 차량으로 올라간 다음 정상 철쭉밭을 구경한 후 되내려오는 거의 관광에 가까운 탐방이 가능하다.너무 간단하게 느껴진다면 호남정맥 일부를 이루고 있는 광대코재~주월산~방장산~오도재 능선을 포함한 원점회귀형의 사뭇 긴 당일산행 코스를 잡을 수도 있다. 겸백면은 이 원점회귀형 등산로의 출발지인 수암리에 널쩍한 주차장도 새로 만들었다.더불어 보성군은 ‘녹차와 철쭉이 어우러진 보성’이라는 모토로 작년부터는 초암산에서도 철쭉제를 열고 있다.", + "MNTN_HG_VL" : "576", + "MNTN_LOCPLC_REGION_NM" : "전남 보성군 겸백면", + "MNTN_NM" : "초암산" }, - "longitude" : 127.84222219999999, - "latitude" : 37.5416667 + "longitude" : 127.1822171, + "latitude" : 34.828257000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "219", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구 신탄진동", - "MNTN_NM" : "성치산" + "DETAIL_INFO_DTCONT" : "해발 158m의 비교적 낮은 지역인 전주대 뒷산으로 일반 등산객들은 아주 드물게 이동하는 지역이며 주로 전주대 학생들이 즐겨 찾는 지역임", + "MNTN_HG_VL" : "158", + "MNTN_LOCPLC_REGION_NM" : "전라북도 전주시 상림동", + "MNTN_NM" : "천장봉" }, - "longitude" : 127.48277779999999, - "latitude" : 36.432499999999997 + "longitude" : 127.0819444, + "latitude" : 35.808333300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "631", - "MNTN_LOCPLC_REGION_NM" : "충청남도 부여", - "MNTN_NM" : "성태산" + "DETAIL_INFO_DTCONT" : "강원도 강릉시 강동면 정동진역과 안인진역 사이에 위치해 있다. 이 산은 서울 경복궁에서 정동(正東)에 있다 하여 붙여진 이름인 정동진의 열차역이 산행들머리다.해수욕장이 있는 등명에서 서쪽으로 솟은 산이 괘방산으로 등명과 산 정상 사이에 락가사가 동해바다를 향해 자리잡고 있다. 등명락가사에서 북으로 500m거리인 대포동은 96년 9월 18일 북한 무장공비들이 잠수함으로 침투한 곳이다. 이 사건을 계기로 괘방산에다 안보체험 등산로를 개설하게 되어 이 산이 유명하게 되었다. 당시 침투했던 잠수함은 대포동 바닷가에 전시하고 통일공원이 조성되어 있다.괘방산이라는 산 이름은 옛날 과거에 급제하면 이 산 어디엔가에 두루마기에다 급제자의 이름을 쓴 방을 붙여 고을 사람들에게 알렸다는 데서 생긴 이름이라 전해지고 있다.", + "MNTN_HG_VL" : "339", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 강동면", + "MNTN_NM" : "괘방산" }, - "longitude" : 126.7236111, - "latitude" : 36.373333299999999 + "longitude" : 128.99863020000001, + "latitude" : 37.713526999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "189", - "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 장명동,수성동", - "MNTN_NM" : "성황산" + "DETAIL_INFO_DTCONT" : "낙가산의 산명은 신라 선덕여왕 4년 금강산 보덕암에서 수도하던 회정스님이 이곳 봉황이 날아와 집을 짓는 형국의 명당에 자리잡고 절을 세울 때, 관세음보살이 계신다는 인도 남해의 보타 낙가산의 이름을 따라 뒷산을 낙가산이라 불리게 되었다고 하며, 해명산, 상봉산보다 낮으나 주변 경관이 좋다.강화도의 끝, 외포리 항구에서 배를 타고 들어가다 보면 누에고치처럼 나지막히 자리잡은 석모도(席毛島)라는 섬이 있다. 이곳에는 300m 남짓한 산들이 섬 가운데에 길게 누워있는데 그 많은 봉우리안에 낙가산이 자리잡고 있다. 석모도의 주봉은 해명산이지만, 낙가산과 줄기를 같이하는 해명산(327m)과 상봉산(316m)에 비해 더 잘 알려진 까닭은 유명 사찰인 보문사가 있기 때문이다.산은 야트막하고 작지만 맵시 있고 적당한 다리품을 팔기에 그만이다. 보문사는 절 위에 모신 눈썹바위의 불상이 영험하다고 하여 불자들의 발길이 끊이지 않는데 눈썹바위에서 내려다보는 서해의 절경이 장관이다. 점점이 흩어져 있는 자그마한 암초들과 무인도는 절로 경탄을 자아낸다. 이 광경은 일찍이 강화 8경으로 알려졌을 정도로 뛰어나다.", + "MNTN_HG_VL" : "267", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", + "MNTN_NM" : "낙가산" }, - "longitude" : 126.86145089999999, - "latitude" : 35.572579599999997 + "longitude" : 126.3276408, + "latitude" : 37.691369100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 양평군 옥천면과 가평군 설악면의 경계를 이루며 솟아있는 소구니산은 오대산 두로봉의 지맥이 뻗어내려 강원도 홍천과 횡성땅을 휘휘 돌아 경기도에 용문산과 유명산을 세워놓고 우뚝 솟아있다. 유명산과는 달리 바위가 어울린 산으로 유명산에 가려 잘 알려지진 않았지만 유명산과 연결해서 많이 찾는 곳이다.산행기점은 농다치고개와 북쪽의 서너치고개가 가장 일반적이나 교통편이 불편한 것이 흠이다. 정상에 서면 전망이 좋은데 유명산쪽으로는 고냉지 채소밭이 이색적이고 멀리 마터호른 같은 백운봉이 시야에 들어온다. 하산길은 정상 남쪽으로 뻗어내린 긴 능선을 따르거나 유명산을 거쳐 하산할 수도 있다.", - "MNTN_HG_VL" : "798", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", - "MNTN_NM" : "소구니산" + "DETAIL_INFO_DTCONT" : "봄이면 동백꽃과 벚꽃으로 유명한 선운산은 '호남의 내금강'으로 불리는 산으로 79년 도립공원으로 지정된 명산이다. 본래 도솔산이었으나 백제 위덕왕 24년(577년)에 창건한 선운사(禪雲寺)가 있어 선운산이라 불리게 되었다.선운산은 이름 그대로 구름 속에 선(禪)을 닦는 산으로 선운사를 비롯해 참당암, 도솔암, 석상암, 동운암 등 유서 깊은 사찰과 암자가 산자락에 자리잡고 있다. 그 중 선운사는 백제 위덕왕 24년(577년)에 검단(黔丹)선사가 창건한 사찰로, 한때 89개 암자를 거느리기도 하였으나 현재는 4개의 암자만 남아있다. 선운사 대웅전 뒤에는 5천여 평의 동백나무숲(천연기념물 제184호)이 있는데 매년 4월 중순이면 붉게 피어나 보는 이의 탄성을 자아내게 한다. 김정호의 '대동여지도'에는 선운산이 표시돼 있지만 현재 각종 지도에는 선운산이라 표시되어 있지 않으며, 선운사 뒷산을 '도솔산' 또는 '수리봉' 으로 표시하고 있다. 선운사 창건 설화는 여러 가지가 있다.원래 선운사 자리는 용이 사는 용추로 검단선사가 용을 쫓아냈지만 용추를 메울 길이 없자, 용추에 꼭두각시 배를 띄우고 돌을 던져 꼭두각시 놀이를 하게 하였다 한다. 또 그 때 마을에 눈병이 퍼졌는데 숯 한 짐씩을 용추에 버린 뒤 눈을 씻으면 낫는다는 소문을 퍼뜨려 용추를 메워 선운사를 지었다는 전설이 있다.실제로는 검단선사가 그의 친구이자 신라 24대 진흥왕의 왕사인 의운(義雲)선사의 도움을 받아 진흥왕의 시주로 선운사를 창건하였다 한다. 진흥왕이 중생제도를 위해 왕위를 버리고 도솔왕비와 중애공주를 데리고 입산, 수도하였다는 진흥굴(眞興窟. 일명 좌변굴(左邊窟),열석굴(裂石窟))이 도솔암 아래에 남아있다. 낙조대에서 바라보는 서해바다의 조망과 하늘로 날아오를 듯한 모습을 한 천마봉 등 볼거리가 푸짐한 이 산은 암자와 바위, 굴마다 숱한 전설이 깃들어 있어 지루함 없이 산행을 즐길 수 있다.특히 선운산 마애불에는 재미난 전설이 전해지고 있다. 옛날부터 마애불 배꼽 속에 신기한 비결이 들어 있고 그 비결이 나오는 날 한양의 이씨가 망한다는 전설이 있었다. 전라도 감사 이서구(李書九)가 마애불의 배꼽을 열어 보려다가 뇌성벽력이 쳐, 실패한 일이 있었는데 동학혁명이 일어나기 전 동학의 간부 손화중(孫和中)이 배꼽을 열고 그 비결을 꺼내갔다고 한다.", + "MNTN_HG_VL" : "335", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 아산면ㆍ심원면ㆍ해리면", + "MNTN_NM" : "선운산" }, - "longitude" : 127.4729765, - "latitude" : 37.578820100000002 + "longitude" : 126.571111, + "latitude" : 35.508056000000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "296", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 용강동", - "MNTN_NM" : "소금강산" + "MNTN_HG_VL" : "388", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "일광산" }, - "longitude" : 129.23158000000001, - "latitude" : 35.861976599999998 + "longitude" : 129.20754350000001, + "latitude" : 35.2667134 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "299", - "MNTN_LOCPLC_REGION_NM" : "경기도 시흥", - "MNTN_NM" : "소래산" + "DETAIL_INFO_DTCONT" : "충주시 살미면 향산리 남쪽에 자리잡고 있는 수주팔봉은 나즈막한 산세에 험준한 바위봉을 등에 업고 있는 작지만 커다란 산이다. 뾰족하게 서있는 바위봉들이 작은 산을 떠받치고 있어, 결코 만만히 볼 수 없는 위엄을 갖고 있다.달천강의 은빛 물결을 휘감고 있는 수주팔봉은 서쪽 이류면 문주리 팔봉마을에서 달천강 건너 동쪽의 산을 바라볼 때 정상에서 강안까지 달천강 위에 8개의 봉우리가 떠오른 것 같다 하여 붙여진 이름이다. 산 이름 그대로 산 주위에 물이 흐르고 8개의 봉우리가 있어 등산객들유혹하는 산임에는 틀림없다.또한 산 위에서의 조망이 마치 한폭의 동양화를 펼쳐 놓은 듯 절경을 이루고 송곳바위, 중바위, 칼바위 등 창검처럼 세워진 날카로운 바위들이 수직절벽을 이뤄 산행의 묘미를 더해준다. 주변에 수안보온천과 월악산국립공원이 있다.", + "MNTN_HG_VL" : "490", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 살미면 향산리", + "MNTN_NM" : "수주팔봉" }, - "longitude" : 126.7789089, - "latitude" : 37.450962099999998 + "longitude" : 127.9196749, + "latitude" : 36.902216099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "양평군 단월면의 가장 북쪽에 위치한 소리산은 강원도 홍천군과 접경을 이루는 경기도의 오지이다. 소리산은 주변의 산에 비해 큰 산은 아니지만 깎아지른 듯한 바위절벽과 기암괴석, 맑은 계곡이 어울려 예로부터 산음리 소금강이라 일컬어질 만큼 빼어난 경관을 지니고 있다. 예부터 산 속에 바위벼랑에 수리가 서식했다고 하여 수리산으로 부르다가 소리산으로 바뀌었다는 이야기가 전해진다. 인근 봉미산과 종자산이 육산인 것과 달리 소리산 정상부는 바위로 이루어져 있다.특히 산음리와 석산리 사이에 있는 용소계곡은 기암절벽과 울창한 나무들이 어우러져 한폭의 풍경화를 연상케 한다. 산 전체가 오염되지 않은 신선함과 전형적인 시골 마을의 평화로운 정취로 인해 휴식공간으로 인기가 높다. 가파른 산길을 올라 수리봉에 서면 서쪽 낭떠러지 아래로 펼쳐지는 S라인 산음천의 모습이 가히 소금강다운 아름다움을 보여주고 있다. 매년 3월에는 소리산 고로쇠축제가 열린다.", - "MNTN_HG_VL" : "480", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 단월면", - "MNTN_NM" : "소리산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "239", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", + "MNTN_NM" : "국사봉" }, - "longitude" : 127.61368330000001, - "latitude" : 37.637732100000001 + "longitude" : 126.41622390000001, + "latitude" : 37.383214000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "무술목 남쪽 크고 아름다운 산이란 뜻을 가진 대미산(大美山)이 있는데 이에 비해 작다고 하여 소미산(小美山)이란 명칭을 붙였다고 한다. 돌산도(突山島)에는 대미산,소미산,수죽산,천마산,봉황산,두산(斗山),천왕산,금오산의 8대 명산이 있는데 소미산이 그 중 하나이다.대미산 북쪽 해발 210m에 위치하고 있으며, 무술목에서 오르는 코스와 소굴전마을에서 오르는 코스가 있다. 산의 높이가 낮고 또 인근에 높은 산이 없어서 관망하기에 좋은 산이다. 인근에 무술목유원지와 해수욕장, 해양수산과학관이 있어 가족 관광지로서도 아주 좋은 곳이다.", - "MNTN_HG_VL" : "210", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 돌산", - "MNTN_NM" : "소미산" + "DETAIL_INFO_DTCONT" : "백두대간의 등허리 태백에서 분기한 산줄기가 내륙을 향해 달리다 수려한 봉우리를 만들었으니 그 이름 운달산이라하여 계곡에 흐르는 물이 맑고 차갑기가 얼음같아 일명 '냉골'이라 불리워진다. 용암산(龍岩山)이라고 부르기도 하는 이 산은 문경읍 동북쪽 8km 지점에 위치한다. 산 능선은 길게 동서로 10여km에 걸쳐 뻗었으며, 그 사이의 마전령(馬轉嶺:627m)· 조항령(鳥項嶺:673m) 등 안부(鞍部)가 예로부터 문경과 다른 지방을 연결하는 교통의 요지였다. 산에는 금선대(金仙臺)를 비롯하여 많은 기암괴석으로 덮여 경치가 아름다우며, 남동사면 일대에 화장암(華藏庵)·양진암(養眞庵)·대성암(大成庵)·금룡사(金龍寺) 등 고찰이 있어 많은 관광객이 찾아든다.특히 수령 300년 이상 수고 30여미터의 전나무 숲속에 고목이 조각품마냥 운치를 더해주고 겨울철 눈꽃은 내방객의 넋을 잃게 하고 여름철에는 조용한 곳을 찾는 피서객들이 찾아 온다.또한 운달산은 김룡사를 품고 있다. 김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다. 다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다. 그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", + "MNTN_HG_VL" : "1097", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 용연리", + "MNTN_NM" : "운달산" }, - "longitude" : 127.7763889, - "latitude" : 34.688611100000003 + "longitude" : 128.19868009999999, + "latitude" : 36.7564888 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도와 충청북도의 경계를 이루고 있는 소백산은 우리 나라 12대 명산 중의 하나로 '한국의 알프스' 라 불린다. 이 산은 총 면적이 320.5km에 달하는 거대한 산줄기로 정상인 비로봉을 비롯하여 연화봉(1,376.9m). 제 2 연화봉(1,357.3m). 국망봉(1,420.8m) 등 1천m 고봉이 줄지어 있어 웅장한 산세를 이루고 있다.", - "MNTN_HG_VL" : "1440", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 풍기읍, 충청북도 단양군 단양읍", - "MNTN_NM" : "소백산" + "DETAIL_INFO_DTCONT" : "가은산은 금수산(1015.8m) 정상에서 남쪽 말목산(720m)으로 흐르는 산줄기와 중계탑이 서 있는 802봉, 남서쪽으로 흐르는 산줄기에 있는 산이다. 가은산은 청풍호반을 사이에 두고 청풍호의 최고 경승지 옥순·구담봉과 마주 서 있다. 그래서 제천 지역의 그 어느 산에서보다 청풍호반의 아름다운 풍광을 만끽할 수 있다. 또한 등산로 곳곳에 기암괴석과 그 사이에서 자라는 노송들이 한데 어울려 한 폭의 동양화를 그려낸다. 뿐만 아니라 남쪽에는 월악산 영봉과 만수봉으로 이어지는 들쑥날쑥한 능선이 막힘없이 펼쳐진다. 등산로 곳곳에 물개바위, 기와집바위, 손바닥바위, 시계바위, 곰바위 등 독특한 이름을 갖고 있는 기암들이 있어 산행의 즐거움을 더한다. 가은산은 원래 ‘가는산’으로 불렸다고 한다. 전설에 의하면 옛날 마고할미가 이 산에 놀러 왔다가 반지를 잃어버려 모든 능선과 골짜기를 뒤지며 찾다가 아흔아홉번째 골짜기에서 비로소 찾게 되었다. 그리고 나서 “한 골짜기만 더 있었어도 한양이 들어설 골짜기인데, 내가 눌러 앉아 살려 해도 한양이 되지 못하므로 떠나겠다”는 말을 남기고 떠났다는 데서 ‘가는산’이란 이름이 붙었다고 한다.", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면", + "MNTN_NM" : "가은산" }, - "longitude" : 128.446123, - "latitude" : 36.951719900000001 + "longitude" : 128.25128050000001, + "latitude" : 36.955438000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울에서 44km, 동두천시청에서 동북쪽으로 약 5km의 거리에 있는 소요산은 경치가 뛰어나 경기도의 '소금강'이라 불린다.", - "MNTN_HG_VL" : "588", - "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시, 포천시 신북면", - "MNTN_NM" : "소요산" + "DETAIL_INFO_DTCONT" : "꾀꼬리봉은 충북 제천시 덕산면 억수리 깊은 협곡인 용하구곡 청벽대 남쪽에 위치한 산으로, 월악산 국립공원권에 속한다. 비경지대인 청벽대에서 남쪽 직선거리로 약 2km 지점에 수석처럼 솟아 있는 꾀꼬리봉은 예로부터 다른 산에 비해 꾀꼬리가 많이 살았기 때문에 붙여진 이름이라고 한다. 기암과 노송이 어울려져있고,용하구곡 물줄기도 시원스럽게 보인다. 용하구곡으로 내려서면 선녀가 목욕을 즐겼다는 선미대가 보이고 용하구곡 물줄기를 따라 30 분가량 걸으면 청벽대가 반긴다.용하구곡 물줄기는 잠시 속세와 적을 끊은 무릉도원을 연상케한다.정상에서의 조망은 북쪽에서부터 하설산,문수봉,대미산이 용하초등교를 감싸고 있고 남쪽에서 서쪽으로는 백두대간이 보이고,서북쪽으로는 메밀봉과 월악산이 첩첩산중을 이룬다.꾀꼬리봉 산행의 백미는 하산길에 있다. 전망대바위?암벽지대? 일주암을 거쳐 용하구곡으로 내려오는 코스는 급경사 암벽지대가 많아 초심자에게는 다소 부담스럽지만 보조자일이 설치돼 있어 큰 어려움은 없다.", + "MNTN_HG_VL" : "890", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면 월악리", + "MNTN_NM" : "꾀꼬리봉" }, - "longitude" : 127.0878091, - "latitude" : 37.942629599999997 + "longitude" : 127.86333329999999, + "latitude" : 37.100833299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "475", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "소주봉" + "DETAIL_INFO_DTCONT" : "정족산은 산의 생김새가 마치 세 발 달린 가마솥과 같다고 해서 이름 붙여진 산이다. 정족산에는 단군이 세 아들을 시켜 쌓았다는 삼랑성이 있다. 일명 정족산성이라고도 하는 삼랑성은 사적 제130호의 돌성이다. 성의 시설물로는 남문루와 동문, 서문, 북문지가 있고 성 안에는 13개의 우물이 있었다고 전하며 고구려시대에 창건된 전등사가 있다.전등사는 이 삼랑성안에 있는 사찰이다. 고구려 소수림왕 11년(372) 아도화상이 진종사(眞宗寺)라 이름한데서 시작되었다.\"\"신증동국여지승람\"\"에 의하면 충렬왕 8년(1282) 왕의 원비인 정화궁주 왕씨가 승려 인기(印奇)에게 송나라에 들어가 대장경을 가져오게 하여 이 절에 보관했다고 한다. 전등사라는 이름은 정화궁주가 불전에 옥으로 된 등잔을 올린 뒤 붙여진 이름이다. 특히 정족산에는 `조선왕조실록'을 보관했던 사고터가 남아 있어 유적답사 및 가족산행을 하기에 가장 적합한 곳이다.산행은 전등사에서 시작된다. 전등사의 요사채 뒤로 난 길을 곧바로 올라가면 정상에 닿을 수 있다. 정상에서는 나무에 둘러싸인 전등사의 고풍스러운 모습과 마니산과 서해바다의 모습을 한눈에 바라 볼 수 있다.", + "MNTN_HG_VL" : "200", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 길상면", + "MNTN_NM" : "정족산" }, - "longitude" : 127.66861110000001, - "latitude" : 37.762500000000003 + "longitude" : 126.4802778, + "latitude" : 37.6325 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "231", - "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군", - "MNTN_NM" : "송공산" + "DETAIL_INFO_DTCONT" : "방가산(方可山)은 팔공지맥으로 해발 755.8m이며 군위군과 영천시의 접경구역이다. 방가산 정상에서 영천지역의 보현산천문대의 정상부를 조망이 가능하며 인근에 군위 장곡휴양림이 위치하고 있다. 방가산 등산로를 연계하여 고로면 양지리의 아미산 등산과 연계가 가능하며 총 7~8시간의 시간이소요될 것으로 예상된다.", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 고로면 인곡리, 영천시", + "MNTN_NM" : "방가산" }, - "longitude" : 126.254693, - "latitude" : 34.851599899999997 + "longitude" : 128.9064362, + "latitude" : 36.134187900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "송학산은 제천에서 영월로 뻗는 38번 국도에서 왼쪽으로 올려다 보이는 산으로, 산 전체가 거의 소나무 일색이며, 송학산 자락은 주변으로 채석장이 여러 곳 있어 질 좋은 화강암이 생산되던 곳이다.산 이름 그대로 아름드리 노송은 많지 않지만 산 전체가 거의 소나무 일색으로 산행 내내 코끝을 스치는 그윽한 솔향이 일품이며, 푹신한 솔잎을 밟으며 청산의 푸른 기운을 느낄 수 있다.정상 바로 아래에는 빼어난 조망을 가진 강천사가 있으며, 짧은 코스지만 정상에 올라서면 송학면 일대의 조망이 일품이다. 남쪽으로는 무등산, 왕박산, 갑산, 가창산이 첩첩으로 포개지며 서북쪽으로는 제천의 진산 용두산과 그 뒤에 석기암, 감악산이 한 눈에 들어온다.강천사에서 조금 내려오면 급하게 굽이도는 언덕 너머에 빈대로 망했다는 전설의 소악사지가 있으며 3층석탑만 외로이 남아 무상한 역사를 말해준다.", - "MNTN_HG_VL" : "819", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면ㆍ강원도 영월군 주천면", - "MNTN_NM" : "송학산" + "DETAIL_INFO_DTCONT" : "금수산, 이름 그대로 비단에 수를 놓은 듯한 모양을 하고 있다. 월악산 국립공원권 최북단에 위치한 이 산의 이름은 본래 백악산이었다. 조선조 중엽 퇴계 이황 선생이 단양 군수로 있던 시절, 너무도 아름다운 경치에 감탄해 금수산으로 이름을 고쳐 부르게 되었다고 한다.특히 가을 경치가 빼어난 아름다운 암산으로, 봄속에 겨울을 만날 수 있는 신비한 산이다.매년 4월초까지 얼음이 얼다가 처서가 지나면 얼음이 녹는 얼음골에는 돌구덩이를 30cm정도 들추면 밤톨만한 얼음 덩어리가 가을까지 나오고 있어 자연의 신비감을 더해준다. 금수산 주능선은 상어 이빨을 연상케하는 암릉길로 스릴 만점이다.산 중턱에는 바위틈에서 한해나 장마에도 꾸준한 물줄기를 뿜어내고 있어, 산을 찾는 이들의 목을 축여주고 있다. 발길마다 눈길마다 은은히 차고 도는 풍경에 취해 걷다 보면, 어느새 산 정상. 그곳에서 내려다 보면 다소곳이 트인 산세와 충주호의 푸른 물이 어우러져 은은한 채색이 베인 화선지 위에 선 기분이 든다.", + "MNTN_HG_VL" : "1016", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 수산면ㆍ단양군 적성면", + "MNTN_NM" : "금수산" }, - "longitude" : 128.26791040000001, - "latitude" : 37.208268799999999 + "longitude" : 128.25666799999999, + "latitude" : 36.983795800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "276", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", - "MNTN_NM" : "송화산" + "DETAIL_INFO_DTCONT" : "경기도 가평군에 있는 중봉은 화악산과 남서쪽으로 이웃해 있는 산으로 화악산 정상부가 군사 통제 구역으로 묶여 있기 때문에 등산인들이 오를 수 있는 경기도내의 가장 높은 산이다. 대부분 중봉 산행은 관청리 큰골 계곡으로 올랐다가 다시 큰골로 하산하는 경우가 많은데 산행경력이 있다면 가림에서 출발하여 가파른 능선을 타고 오른 후 큰골로 하산하는 것도 괜찮다.가림마을에서 시작하는 산행은 돌집수련원 입구에서 시작되는데 초입부가 오솔길처럼 평탄하다고 해서 만만하게 보아서는 안된다. 750m 고지를 오르면서부터 산길이 급격하게 가팔라지고 험준한 길이 이어진다. 그러나 이 구간쯤에 이르면 명지산에서부터 국망봉, 백운산까지 이어지는 능선이 한눈에 들어와 피로를 잊게 해 준다.", + "MNTN_HG_VL" : "1424", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "중봉" }, - "longitude" : 129.19061189999999, - "latitude" : 35.851393700000003 + "longitude" : 127.4949902, + "latitude" : 37.9871871 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "794", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "수덕산" + "MNTN_HG_VL" : "286", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시", + "MNTN_NM" : "백마산" }, - "longitude" : 127.5135183, - "latitude" : 37.915029699999998 + "longitude" : 127.27716820000001, + "latitude" : 37.368814299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", - "MNTN_NM" : "수도산" + "DETAIL_INFO_DTCONT" : "함박산은 최악의 조건을 갖추고 있는 악산이다. 암릉은 대단히 험난하고, 식수는 처음부터 하산 지점까지 전혀 구할 수 없고, 경사도는 매우 심하고 자갈 너덜지대로 되어 있다.암릉식수경사도의 3대 최악의 조건을 구비한 산이라 하겠다. 일부 공룡능선만큼이나 험난한 암릉 코스로 중간중간 위험이 도사리는 만큼, 눈비가 오는 날이나 단독 산행은 절대 금물이다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", + "MNTN_NM" : "함박산" }, - "longitude" : 127.98164250000001, - "latitude" : 35.859287100000003 + "longitude" : 129.1802778, + "latitude" : 35.306111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수도산은 소백산맥 대덕산에서 초점산을 분기점으로 가야산으로 흘러드는 산줄기 들목에서 경남과 경북을 가르고 있는 육산이다. 경상북도 김천시 증산면 평촌리와 경상남도 거창군 가북면에 위치하는 이 산은 골짜기마다 맑은 물이 흘러넘쳐 소와 담을 이룬다.수도산이라는 이름은 정상에서 1.5킬로미터 아래 수도사가 위치하고 있는데서 유래한다. 수도사는 수도산 상부에 위치한 도량으로 옛날 도선국사가 이 도량을 보고 앞으로 무수한 수행인이 나올 것이라 하여 산과 도량 이름을 각각 수도산, 수도사라 정했다고 한다. 백 여 년 전부터는 부처님의 영험함과 이적이 많다하여 사람들이 불영산, 선령산이라고도 부른다.산 아래 수재(秀才)는 천재가 살았다는 전설에 따라 마을 이름이 되었다고 하며 심방소(尋芳所)는 고려 말 신방이란 사람이 은거한 곳이라는 뜻과 또는 땔나무가 많다는 뜻에서 신방(薪方)으로 하다가 아름다운 경치에 반해 찾는 사람들이 많다는 뜻의 심방(尋訪)으로 불렸다는 이야기가 전해진다.", - "MNTN_HG_VL" : "1317", - "MNTN_LOCPLC_REGION_NM" : "김천시 증산면, 대덕면·경상남도 거창군 가북면", - "MNTN_NM" : "수도산" + "DETAIL_INFO_DTCONT" : "간월산은 왕봉재(간월재)에서 천화현(배내고개) 사이에 해발 1068.8m 고봉 일대를 말하는 것으로 상북면 등억에서 배내에 걸쳐 있다. 간(肝)은 우리 민족이 오래 전부터 써오던 신성이라는 뜻이며 월(月)은 신명이라 하여에서 유래되어 평원을 의미하는 벌의 뜻이다. 그러므로 간월산은 평원이 있는 신성한 산으로 신불산과 밝얼산과 같은 뜻을 지니고 있다. 또한 간월이라는 이름은 다음과 같이 肝月, 看月, 澗月, 澗越, 肝越 등 다양하게 쓰이기도 한다.한반도의 남동단인 영남지방에 해발 1000m가 넘는 고헌산, 가지산, 운문산, 천황산, 간월산, 신불산, 취서산 등의 준봉이 일대 산군을 이루며 솟아 있는데 이 산군을 유럽의 알프스와 풍광이 버금간다는 뜻에서 영남알프스라하고 영남 산악인들에게는 천혜의 등산대상이 되고 있는 곳이다.간월산은 신불산 북쪽의 준봉으로서\"영남 알프스\"의 일부분을 구성하고 있으며 홍류폭포 등의 절경과 최근 자연휴양림이 조성돼 찾는 이들이 많아졌다.간월산에서 발원해 언양 쪽으로 흐르는 시냇물 작괘천은 각양각색의 바위들 사이로 옥류가 굽이치는 아름다움은 절경이다. 간월산 기슭의 등억온천은 게르마늄 함량이 높아 피부병과 무좀에 특효가 있고 당뇨와 고혈압, 신경통 등에도 효험이 있는 것으로 알려져 있다.억새가 만개하는 가을, 봄 순으로 많이 찾는다. 억새 테마산행을 위한 간월산-신불산-영축산 연계산행의 산행기점으로도 인기 있다.", + "MNTN_HG_VL" : "1069", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군", + "MNTN_NM" : "간월산" }, - "longitude" : 127.98164250000001, - "latitude" : 35.859287100000003 + "longitude" : 129.04077340000001, + "latitude" : 35.551204400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수레의산은 충북 음성군에 위치한 아담한 산이다. 아직 사람의 발길과 개발의 손길이 미치지 않아서 천연의 순박함을 그대로 간직하고 있는데,이 산은 이름부터가 특이하다. 산 서쪽 계곡에는 청소년수련원과 차곡저수지가 있고 수량이 많으며 수리산에서부터 산서릉의 459번도로까지 임도가 잘 뚫려있다. 박쥐굴, 굴법당, 공기바위, 병풍바위, 상여바위, 전설의못등 볼거리가 많고, 산행시간이 짧고 등산로가 잘 닦여있어 가족산행지로 제격이다.수레의산은 신비의 산이며 숨어있는 산이다. 600m가 넘는 높은 등성이(주능선)에 25평이 넘는 연못이 있고, 거기에 꽤 많은 물이 고여 있다. 이른바 전설의 못이다. 잘 이해가 되지 않는 현상이다. 수레의산은 신비스러운 산답게 사람들의 눈에 잘 띄지 않는 곳에 조용히 숨어 있다. 큰 도로들이 거미줄처럼 얽혀 있는 지금의 상황에서는 웬만한 산은 큰 길에서 그 모습을 볼 수 있다.그러나 이 산은 근처를 지나는 3번 국도(이천 - 충주)나 38번 국도(평택 - 장호원 - 제천), 또는 중부내륙고속도로에서 잘 보이지 않는다. 심지어 산 북서에서 남동으로 가까이 지나는 520번 지방도에서도 가려내기 어렵다. 그 까닭은 큰 도로들이 이 산 근처에서 산 사이를 지나는 때문이기도 하고, 주위에 고만고만한 산들이 많기도 하기 때문이다. 수레의산 주변 산줄기는 남으로 가영산 - 부용산으로 이어지고, 북으로 수리산- 원통산- 오갑산으로 뻗쳐있다. 수레의산이 그처럼 비슷한 높이의 봉우리들로 이루어진 산줄기 가운데 자리잡고 있기 때문에 알아보기 쉽지 않은 것이다.그러나 이 산은 숲이 울창하고 산길이 좋은 데다 산허리를 임도가 지나고 있어 오르내리기에 편리하다. 어디서 올라도 점심시간을 포함해 3 - 4시간이면 어려움 없이 주봉은 물론 전설의 샘(못)까지 돌아 내려올 수 있어 가족산행에 알맞다. 내내 짙은 숲속을 걷기 때문에 산뜻한 기분이 끝까지 이어지고, 군데군데 상여바위 병풍바위 박쥐굴 공기돌 굴법당들도 볼 수 있어 심심찮다 특히 전설의 샘 위에 있는 상여바위는 푸른 숲에 둘러싸인 채 우뚝 솟아 특이하고, 그 위에 오르면 조망이 좋고 시원하다.전설의 샘이 말해주듯 산에는 물이 많다. 주름이 많아 골짜기가 많고 골짜기마다 개우에 맑은 물이 흐르고 있고, 매우 차가워 손을 오래 담그고 있기 어렵다.이 좋은 수질은 이미 근방에 널리 알려졌는데 농업용수로 사용하기 위해 저장해 놓은 차곡저수지의 물조차도 수영하기 어려울 정도로 차고 깨끗하다고 한다. 그래서 근처의 주민들도 아끼고 좋아하는 산인 듯 싶었다. 고스락에 오석 표석이 두 개가 있고, 화강암 표석도 하나 있다.가장 전망좋은곳은 상여바위 꼭대기이고, 전설의못은 능선상에 있는 연못으로 청학포란형의 권근 3대묘와 연루되어 묘를 쓸때 해발 505미터의 이곳에 물을 올렸다는 전설이 있다고 한다.", - "MNTN_HG_VL" : "679", - "MNTN_LOCPLC_REGION_NM" : "충청북도 음성군 생극면", - "MNTN_NM" : "수레의산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "754", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "피래산" }, - "longitude" : 127.6635849, - "latitude" : 37.030279200000003 + "longitude" : 128.9761111, + "latitude" : 37.646111099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수리봉은 수리가 긴 날개를 벌리고 내려앉은 형상의 품 넓은 산으로 정상에 서면 사방으로 첩첩이 둘러쌓은 능선의 바다를 만끽할 수 있는 오지의 산이기도 하다. 전반적으로 산세가 온화하지만 코스가 제법 길고, 무엇보다 지맥들이 수없이 갈려나가 독도에 각별한 주의를 요한다. 정상에서 여무재 쪽으로 10분쯤 떨어지면 수십km를 일망무제로 펼쳐진 숲과 능선의 바다가 펼쳐진 전망바위를 만날 수 있다.", - "MNTN_HG_VL" : "1019", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 횡성군", - "MNTN_NM" : "수리봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "339", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주", + "MNTN_NM" : "연미산" }, - "longitude" : 128.24333329999999, - "latitude" : 37.479722199999998 + "longitude" : 127.1183333, + "latitude" : 36.484999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 춘천시 동내면 사암리, 동내면 원창리에 위치한 해발 645미터의 수리봉은 대룡산, 연엽산, 금병산 사이에 위치한 육산이다. 원창고개 마루에서 산행이 시작되므로 300미터만 오르면 되니 가족 동반 산행이 가능하다. 정상 넘어 쉰동골에 있는 원창저수지 상류계곡은 인적이 드물어 호젓하게 산행을 즐길 수 있지만 현재는 등산로가 끊겨 저수지까지 산행은 불가능하다. 산행 후에는 따로 저수지에 들러 깨끗한 물에 탁족으로 산행의 피로를 푸는 즐거움도 있다.비록 높이도 규모도 작지만 능선의 마지막 부분에 우뚝 솟은 652미터 봉우리는 아름다운 직벽의 암봉이다. 특히 수리봉과 응봉의 사이의 협곡은 좌우로 막아선 암벽과 울창한 수림이 맑은 계류와 어울려 경관이 빼어나다.", - "MNTN_HG_VL" : "645", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동내면ㆍ동산면", - "MNTN_NM" : "수리봉" - }, - "longitude" : 127.8202778, - "latitude" : 37.844999999999999 + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "47", + "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 토성면 운봉리", + "MNTN_NM" : "운봉산" + }, + "longitude" : 128.507882, + "latitude" : 38.2876695 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수리산은 안양, 군포, 안산시 경계에 자리한 산이다. 관악산, 삼성산, 모락산과 이웃하고 있으며 낮으면서도 암릉과 숲, 계곡의 경관이 좋아 조선시대에는 안산의 명산으로 불리기도 했다. 수리산 산세는 북쪽으로 터진 말발굽 모양을 하고 있다. 말발굽 북동쪽 끝줄기에 관모봉(426m)이 있으며 상봉인 태을봉(489m)은 관모봉 남서쪽에 있다. 태을봉에서 반 바퀴 돌아서면 서편 줄기 중간에 독수리바위인 수암봉(395m)이 있으며 산줄기가 휘돌아가는 슬기봉과 고깔봉 일대에 공공시설물이 있다.수리산 산행에서 가장 경관이 뛰어나고 산행의 맛이 좋은 곳은 태을봉에서 슬기봉까지 이어지는 암릉 구간과 수암봉이다. 산행은 안양 창박골 쪽에서 관모봉으로 올라 태을봉을 거쳐 병목안 골짜기를 끼고 반 바퀴 돌아 수암봉까지 가거나 거꾸로 수암봉에서 시작하여 관모봉으로 돌면 된다. 태을봉 바로 아래의 거대한 산본 아파트 단지에서도 등산로가 여럿 있다.", - "MNTN_HG_VL" : "489", - "MNTN_LOCPLC_REGION_NM" : "경기도 안양시·군포시·안산시", - "MNTN_NM" : "수리산" + "DETAIL_INFO_DTCONT" : "제otilde;시 금성면과 단양군 적성면의 경계를 이르는 작성산(鵲城山)은 북으로 가acirc;산(819.5m), 갑산(776.7m), 호명산(475.3m), 마당재산(661.2m) 산줄기를 이어받고, 남으로 내려뻗어 동산(896.2m), 금수산(1,015.8m)을 빚는다.ucirc;풍호를 서쪽에 낀 작성산은 이웃한 동산과 더불어 제otilde;의 이름난 산이다. 원래 이 산은 현지 사람들이 부르고 있는 ‘까치성산’ 이었는데, 일제시대에 일본인들이 지형도를 만들면서 한문표기인 ‘鵲’자를 사용하면서 작성산(鵲城山)으로 더 알려졌다. 까치성산이란 이름에 얽힌 전설이 있다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명했다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.", + "MNTN_HG_VL" : "840", + "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면 성내리", + "MNTN_NM" : "작성산" }, - "longitude" : 126.9027047, - "latitude" : 37.366196799999997 + "longitude" : 128.21611110000001, + "latitude" : 37.036944400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "기양산과 수선산이 자리한 상주시는 예로부터 삼백(쌀, 누에고치, 곶감)의 고장으로 낙양으로도 불리었다.수선산은 상주시 청리면 청상리와 낙동면 수정에 솟아있는 육산으로 연산군 시절 연산군의 만행을 싫어하여 피신 은둔 수도한 서비가 많았다고 하여 이름지어진 산이다. 접근하는 방법에는 청리면 청상리 수선지 뒤 계곡길을 이용하거나 기양산에서 수선산을 거쳐 돌티로 하산하는 두 방법이 있으나 청상코스는 수선지 뒤 계곡이 끝나는 지점까지는 길이 잘 나 있으나 그 이후 길이 확실치 않고 잡목이 길을 막기 때문에 가급적 삼가고 기양산 코스를 이용하여 수선산으로 가는 방법을 택해야 한다.", - "MNTN_HG_VL" : "684", - "MNTN_LOCPLC_REGION_NM" : "상주시 청리면 청상리 \/ 낙동면 수정리", - "MNTN_NM" : "수선산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "315", + "MNTN_LOCPLC_REGION_NM" : "대전 동구 효평동,마산동", + "MNTN_NM" : "함각산" }, - "longitude" : 128.1716667, - "latitude" : 36.299722199999998 + "longitude" : 127.47583330000001, + "latitude" : 36.395555600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수인산은 강진과 장흥의 경계를 이루고 있으며 그 높이와는 어울리지 않게 웅장하고 오묘한 산세를 이룬다. 산성으로 둘러싸인 정상부는 고려 말부터 조선말까지 전라 병영성의 전략 요충지로서 왜구가 침략할 때마다 주민들의 피난처로 이용되었고 병영면의 지명은 조선 태종 때 왜구를 막을 목적으로 병영을 설치한 데서 유래한 것이다. 실제 수인산은 병영면 소재지에서 바라보면 알을 품은 듯한 형상인 노적봉을 가운데로 주위가 온통 암벽으로 둘러 싸여 있어 천혜의 요새로 손색이 없는 철옹성 같은 산세를 보여준다.수인산은 억새로도 유명한데 정상부 천평 규모의 조릿대와 어우러져 황금벌판이 압권이다. 수인산의 대표적인 등산 코스는 강진 병영면의 수인사, 홈골에서 시작하는 것과 장흥 유치면 대리의 수덕목장에서 올라가는 길이다.무등산, 지리산, 두륜산, 천관산, 흑석산, 월출산에 둘러싸인 지점이 이곳으로 정상에서의 조망은 일품이다. 가까이는 장흥벌과 병영벌이 훤하게 내려다보인다. 장흥벌을 흐르는 탐진강이 길게 꼬리를 늘어뜨리며 다도해로 빠지고 있으며 병영면은 너른 평야를 감싸 안은 듯 산세가 이루어져 비옥한 곡창지대를 형성하고 있다.", - "MNTN_HG_VL" : "561", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 병영면·장흥군 유치면", - "MNTN_NM" : "수인산" + "DETAIL_INFO_DTCONT" : "질운산 산행은 대체적으로 힘들지 않다. 직동리 큰 터 삼거리, 직동만물슈퍼와 담배집이 산행들머리이다. 한밭골 자동차 길을 따라 40분에 효자각에 이르고, 오른쪽으로 효자각이 있는 골로 들어, 계속 광산길로 천천히 1시간 40분쯤에 새비재가 있다. 중간중간 샛길이 있으나 자동차 바퀴자국을 유심히 살피고 따르면 실수없을 것이다.새비재 고랭지 밭에는 10비터 높이의 전주만 있는데 정상으로 가는 주능선 앞에 20미터 높이의 전주가 있다. 정상은 40분 소요. 하산은 동쪽 주능으로 30분에 넓은 자운동 안부이다. 이곳에서 남쪽 광산길로 15분에 삼거리 왼쪽 길로 계속 구불구불 광산터, 붉은절벽, 폐광굴(폐쇄)를 지나며 오른쪽을 유심히 살피면 삼지창 같은 소나무를 발견할 수 있다. 여기서 오른쪽 상막골로 내려선다. 자운동 안부에서 삼지창 소나무까지 약 1시간 20분 걸린다. 총 산행시간은 6시간 30분에서 7시간 소요된다.", + "MNTN_HG_VL" : "1172", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 중동면, 정선군 신동읍", + "MNTN_NM" : "질운산" }, - "longitude" : 126.8516667, - "latitude" : 34.720555599999997 + "longitude" : 128.71722220000001, + "latitude" : 37.196111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충주시 살미면 향산리 남쪽에 자리잡고 있는 수주팔봉은 나즈막한 산세에 험준한 바위봉을 등에 업고 있는 작지만 커다란 산이다. 뾰족하게 서있는 바위봉들이 작은 산을 떠받치고 있어, 결코 만만히 볼 수 없는 위엄을 갖고 있다.달천강의 은빛 물결을 휘감고 있는 수주팔봉은 서쪽 이류면 문주리 팔봉마을에서 달천강 건너 동쪽의 산을 바라볼 때 정상에서 강안까지 달천강 위에 8개의 봉우리가 떠오른 것 같다 하여 붙여진 이름이다. 산 이름 그대로 산 주위에 물이 흐르고 8개의 봉우리가 있어 등산객들유혹하는 산임에는 틀림없다.또한 산 위에서의 조망이 마치 한폭의 동양화를 펼쳐 놓은 듯 절경을 이루고 송곳바위, 중바위, 칼바위 등 창검처럼 세워진 날카로운 바위들이 수직절벽을 이뤄 산행의 묘미를 더해준다. 주변에 수안보온천과 월악산국립공원이 있다.", - "MNTN_HG_VL" : "490", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 살미면 향산리", - "MNTN_NM" : "수주팔봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "487", + "MNTN_LOCPLC_REGION_NM" : "고흥군", + "MNTN_NM" : "운암산" }, - "longitude" : 127.9196749, - "latitude" : 36.902216099999997 + "longitude" : 127.3347222, + "latitude" : 34.624166700000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수촌이라는 마을의 `자연숲' 뒤에 솟았다고 해서 숲뒤산이라 부르는 이 산은 고양이와 개에 관한 전설이 얽혀있는 광동굴, 층층나무와 잣나무가 그득한 숲, 하늘말나리와 더덕의 향기가 은은히 퍼지는 산길, 냉기가 솟는 샘물 때문에 오지를 찾는 사람들이 저절로 발길을 멈추게 된다.비라도 내리면 광동굴에 들어앉아 비오는 풍경도 감상할 수 있어 특히 여름 산행이 즐거운 산이다. 또한 숲뒤산은 강원도 삼척시 하장면 장전리에 있는 골로 마을이 있어 볼품없는 골짜기나 계곡 중간에 식수원으로 쓰는 광동굴 입구가 여름에 시원하고 멋지다. 골지천에서 휴식을 하고 한번쯤 둘러 보는 것도 좋다.", - "MNTN_HG_VL" : "1065", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", - "MNTN_NM" : "숲뒤산" + "DETAIL_INFO_DTCONT" : "대야산은 백두대간에 자리잡고 있으면서 대간능선이 꿈틀이고 지나며 아름다운 보석들을 흩뿌려 놓은 문경의 산들 중에서도 그 명성을 높이 사고 있는 명산이다. 경북 문경시(聞慶市) 가은읍(加恩邑) 완장리(完章里)에 속한 대야산은 대간 마루금을 경계로 충북 괴산군(槐山郡) 청천면(靑川面) 삼송리(三松里)와 접하고 있다. 내\/외선유동을 거느리고 있는 대야산은 2002년 세계 산의 해를 맞아 문경의 주흘산, 황장산, 희양산과 함께 산림청에서 선정한 한국 100대 명산에 올라서 있다. 예로부터 명산으로 받들어 온 대야산은 여러 기록들에 ‘大耶山’으로 적고 있으며 특히 철 종 조의 대동지지[(大東地志(1861년 이후 추정)]에는「大耶山 曦陽山南支上峯曰毘盧爲仙遊 洞主山西距淸州華陽洞三十里(희양산남지상봉왈비로위선유동주산서거청주화양동삼십리: 대야산은 희양산의 남쪽 갈래로 제일 높은 봉우리가 비로봉이고, 선유동의 주산이다. 서쪽의 청주 화양동이 30리다)라고 기록하고 있어 대야산 정상을‘비로봉(毘盧峯)’으로 부르고 있음을 알 수가 있다.", + "MNTN_HG_VL" : "931", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 청천면", + "MNTN_NM" : "대야산" }, - "longitude" : 128.9251209, - "latitude" : 37.3435427 + "longitude" : 127.9324859, + "latitude" : 36.670577600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "쉰움산은 삼ocirc;시 동쪽으로 15킬로미터 떨어진 두#376;산의 북동쪽 상에 솟은 작은 봉우리다. 명산이라 함은 대개 산정의 풍치와 계곡의 아름다움, 그리고 산기슭의 명찰까지도 거론하는데 쉰움산은 이 세 조건을 모두, 그것도 최상급으로 갖췄다.그럼에도 두#376;·ucirc;옥산 사이의 무릉계곡 경관이 워낙 빼어나 대개는 무릉계곡을 따라 두#376;~ucirc;옥간 능선만 밟고 돌아 내려가는 것이 일반적이었다. 무릉계곡의 한 지류로서 쉰움산 북쪽 바로 아래로 뻗은 비린내골 입구는 또 쌍용양회의auml;석장이라 통행이 되지 않았다. 이런 연유로 쉰움산을atilde;는 이는 극히 드물었던 것이다.쉰움산만 오르려면 삼ocirc;시 동쪽 미로면 내미로리의otilde;은사로 가면 된다.otilde;은사에서 정상까지는 1시간이면 충분히 오른다. 능선으로 올라 계곡으로 내려서는otilde;은사 원점회귀코스는 ª지만 쉰움산의 알yen;배기 비경을 둘러보며 산행할 수 있어 좋다.오십정산(五十井山)이라고도 불리는 이 산은 한자 그대로 오십 개의 우물이 있다고 해 붙여진 이름이다. 정상 부근은 거대한 암반에 쉰 개 보다 훨씬 많은 웅덩이가 곰보자국oacute;럼 박혔다. 정상석에는 쉰움산이라는 이름 대신 ‘五十井 683m’라 적혀있다.", - "MNTN_HG_VL" : "683", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면, 동해시 삼화동", - "MNTN_NM" : "쉰움산" + "DETAIL_INFO_DTCONT" : "갑하산은 계룡산국립공원에 인접해 있는 아기자기한 암릉과 숲이 잘 어우러진 전망이 좋은 산이다. 유성에서 계룡산의 동학사 가는 길목 옆에 자리 잡고 있어 접근하기도 쉽고 산세가 험하지 않아 어느 때 찾아가도 등산의 재미를 만끽할 수 있다. 특히, 봄에는 온 산에 진달래가 붉게 물들고 여름에는 안진바위 골짜기의 넓은 암반과 폭포가 시원하며, 가을 단풍과 겨울의 설경이 아름답다. 산 이름은 옛날에 이 지역이 갑소여서 갑골, 갑동의 지명에서 유래된 듯하며, 이 산은 세 개의 봉우리가 불상을 닮았다고 하여 삼불봉이라고 부르기도 한다. 이 산 아래의 안진바위마을은 조선 태종 임금이 유성에서 목욕을 하고 신도안으로 갈 때 냇가의 바위에서 쉬어 갔다고 해서 유래됐고, 두리봉 아래의 매평마을은 매화낙지형의 명당자리여서 사람들이 모여 살았었는데 현재는 국립대전현충원이 자리 잡고 있다.<>우산봉은 계룡산 천황봉에서 산줄기가 백운봉, 도덕봉을 휘돌아 갑하산을 거쳐 치달리다가 금강에 떨어지기 전에 불끈 솟아 올린 봉우리이다. 이 산의 등마루는 숲과 암릉이 적당히 어우러진 가운데, 특히 소나무가 많아서 걷기가 편하고 봄에는 진달래와 철쭉이 흐드러지게 피어난다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성구·충남 공주시 반포면", + "MNTN_NM" : "갑하산" }, - "longitude" : 129.0288889, - "latitude" : 37.447499999999998 + "longitude" : 127.27722369999999, + "latitude" : 36.367463499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "오십개의 우물이 산 정상에 있다하여 오십정산(五十井山=쉰우물산)이다. 실제로 우물이 있는 것은 아니다. 정상의 바위표면이 흡사 달의 분화구 같기도 하고 천연두를 앓은 자국 비슷한 알터에는 가뭄에도 항상 물이 고여 있어 신비감을 더 한다.바위에 패인 자국을 누가 50개라 하였는지는 몰라도 작은 메추리 알에서 공룡알까지 또는 함지박에서 술잔 크기까지 크고 작은 것까지 따진다면 실제로 그 수를 헤아릴 수 없이 많아 이런 이름이 붙었다. 쉰움산은 강원도 삼척시 미로면과 동해시 삼화동의 경계에 위치하고 있으며 정상에서 남서쪽으로 3km지점에는 두타산이 위치해 있다.명산이라 함은 산정의 풍치와 계곡의 아르다움, 그리고 산기슭의 명찰까지도 거론하는데, 쉰움산은 이 세 조건을 그것도 최상급으로 갖추어 지녔다. 또한 이 산은 태백산과 마찬가지로 무속의 성지라 이를 만한 곳이다. 산 곳곳에 치성을 드리는 제단, 돌탑 등이 즐비하다. 어느 할머니가 이곳에 놀러왔다가 그만 신이 내려 무당이 되었다는 일화도 전한다.", - "MNTN_HG_VL" : "683", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 미로면, 동해시 삼화동", - "MNTN_NM" : "쉰움산" + "DETAIL_INFO_DTCONT" : "지리산 자락을 밟는 근교산행은 언제나 산꾼들을 설레게 한다. 어디라 할 것 없이 속속들이 드러나 있을 것 같은 이\"어머니산\"의 또다른 속내를 경험해 볼 수 있기 때문이다. 다 같은 무명의 봉우리들이라도 지리산의 혈통을 이어 받았다면 여러가지 면에서 양상이 달라진다. 산의 기세가 다르고, 조망이 다르고, 오르는 사람들의 감흥이 다르다.감투봉,이방산(二方山)은 구곡산 같이 지리산 위성봉으로서 천왕봉 산행이 곤란할때 적절하게 이용할 수 있는 매력있는 산인데 등산로가 명확하지 않아 독도에 자신이 있어야 즐거운 산행이 보장되나 무엇보다 원시림 그대로이기 때문에 매력만점 산행지로는 손색이 없는 산이다.이방산 등산로 입구의 덕교리 마을 앞에는 파구정이란 곳이 있는데 임진왜란 때에 손씨 3형제가 이끄는 의병들이 잠복하였다가 왜적을 맞아서 싸워 이긴 곳으로 왜구를 파멸시켰다고 하여 이런 이름이 유래하였다.삼장면과 시천면 사이에 우뚝 솟은 이방산은 임진왜란 때 의병을 일으킨 유서 깊은 곳으로서 그 발자취가 역력하며, 삼장면 덕교리에서 해발 600미터에 이르는 이방산을 넘어서면 시천면 사리인 마근담에 이르게 되는데 이곳은 웅석봉에서 남으로 뻗은 지맥이 갈라진 골짜기로 인적이 드문 깊은 산골이다.", + "MNTN_HG_VL" : "768", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군 시천면 사리", + "MNTN_NM" : "감투봉" }, - "longitude" : 129.0288889, - "latitude" : 37.447499999999998 + "longitude" : 127.8411984, + "latitude" : 35.304295199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "무안군을 동서로 가르고 청계면과 몽탄면을 경계로 하는 해발 318m의승달산은 노령산맥 4대 명혈중의 하나이며 목포의 유달산과 쌍벽을 이루는 명산으로 총지사지, 목우암 등 불교사적이 많다. 3백미터가 조금 넘는 이 산이 명혈로 꼽히는 이유는 고승이 제자를 모아 놓고 불공을 드리는 형상이기 때문으로 예전에는 영축산이라 불렸다고 한다.고려 인종때 원나라 승원명이 제자 500명과 함께 도를 득달한 후 이 산을 승달산이라 명하셨고 산세가 수려하고 주변경관이 아름다워 휴일이면 가족단위 피크닉 장으로 널리 알려져 있다.현재는 이 혈아래에 목포대학교가 터를 잡고 있다. 승달산은 신안군과 서해를 내려다 볼 수 있으며 반나절이면 원점회귀가 가능해 평일에도 등반이 가능한 곳이다.들머리는 국립목포대학교 농과대 실습장이 있는 도림리 천지골과 월산리 수월동, 몽탄면 목우암인데, 교통이 편한 천지골이 자주 이용되고 있다. 특히 천지골 오름은 노승봉과 318봉으로 이어지는 능선 위 하루재까지 임도가 뚫려 쉽게 접근할 수 있으며 이 임도가 하루재 건너의 법천사나 목우암 아래까지 이어져 있다. 백제 성왕 때 덕이조사가 창건했다는 법천사는 조선시대 들어서 무수히 많은 고승이 수도하던 곳으로 우리나라 불교의 4대 성지중 하나로 불린다. 조선 후기에 폐사되었지만 퇴락한 요사채가 역사를 증명해 주고 있다. 법천사 맞은편에 위치한 목우암은 승달산 제일의 명당에 자리잡았다고 한다. 목우암에는 2미터가 넘는 목조불과 산신각이 있으며 새로지은 대웅전이 번듯하기만 하다.또한 남도의 바닷가에 위치하고 있어서 해발고도에 비해 월등히 뛰어난 조망을 즐길 수 있을 뿐 아니라 겨울에도 훈훈한 훈풍을 느낄 수 있는 명산이다. 그리고 토양이나 기후 조건이 야생난이 자라기에 최적의 조건을 지니고 있어 '난(蘭)'자생지로도 이름 난 곳이다.", - "MNTN_HG_VL" : "318", - "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 청계면, 몽탄면", - "MNTN_NM" : "승달산" + "DETAIL_INFO_DTCONT" : "봉황이 날개를 활짝 펴고 하늘을 날고 있다해서 이 산의 이름은 주작산이다. 해남과 강진의 경계를 이룬 주작산(약 475m) 능선은 전형적인 암릉길이다. 그동안 지척에 있는 두륜산에 가려 빛을 보지 못했지만 특유의 거칠고 까탈스런 바윗길 덕분에 이제 남도의 대표적인 암릉산행지로 주목받고 있다.주작산은 두륜산에서 동쪽으로 뻗어내린 산맥이 오소치에서 멈춘 뒤, 거친 기세로 솟아 오른 바위능선 한 귀퉁이에 솟아 있다. 그것도 주능선이 아닌 동쪽으로 조금 삐져나온 지능선 상에 위치한다. 그래서 주작산 산행은 이 주봉을 오르기보다 오소재 - 작천소령으로 연결되는 산줄기 전체를 타는 것이 일반적이다.주작산 줄기는 북으로 덕룡산(432.9m)과 석문산(272m) - 만덕산(408.6m)까지 이어진 긴 능선의 일부 구간이다. 이 산자락의 대부분 구간은 바위 봉우리와 벼랑으로 형성되어 보는 맛이 탁월하다. 특히 주작산 구간은 톱날 같은 암릉이 길게 이어져 아기자기한 산행의 묘미가 뛰어나다.주작산 산행은 접근이 편리한 오소재에서 시작해 작천소령으로 답사하는 것이 일반적이다. 초창기에는 산이 거칠고 길도 없어 10시간 이상 걸렸지만, 이제는 우회로가 많이 생겨 시간이 많이 단축됐다. 건각들은 주작 - 덕룡산 줄기를 하루에 답파하기도 한다. 위험한 구간에는 어김없이 로프를 매어 놓았지만, 아직도 아찔한 구간이 많으니 초심자가 낀 팀은 주의해야 한다.", + "MNTN_HG_VL" : "475", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", + "MNTN_NM" : "주작산" }, - "longitude" : 126.4569444, - "latitude" : 34.908888900000001 + "longitude" : 126.6956041, + "latitude" : 34.5063703 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "승학산은 보라마을 뒷산으로, 산세가 마치 학이 나는 형상이라 하여 이름 붙여졌다. 승학산 봉우리 모양은 떡시루 같이 생겼다고 하며, 또 천지 개벽때에는 물에 잠기고 떡시루 하나 놓을 만큼 남아 있었다 하여 시루봉이라는 지명도 남아 있다. 승학산 기슭에 있는 보라마을은 승학산이 비단처럼 둘러싸여있다 하여 보라(甫羅)라고 했다.밀양의 승학산은 워킹과 계곡을 함께 즐길 수 있는 산행지로 적합한 산이다. 밀양시 단장면의 승학산-정각산-정승계곡 코스는 끝없이 이어지는 능선길을 달릴 수도 있고 하산길에 10여Km나 되는 계곡 물길을 거슬러 내려가는 계곡 산행을 같이 즐길 수 있는 멋진 곳이다. 특히 정승골 계곡은 산악인들에게 아직도 알려지지 않은 곳으로 깨끗함은 물론 비경이 이어지는 새로운 계곡 산행지이다. 정각산의 여러 코스를 올라 본 산악인이라면 정승골 계곡을 먼발치에서 내려다 본 경험은 있을 것이다. 그러나 비경이 이어지는 계곡의 참모습을 물길 산행을 하면서 느껴 본 사람은 그리 많지 않을 것이다.산행들머리는 회관에서 50m 과수원 초입에서, 왼쪽 위로 돌아 별장에서 오른쪽으로 오르면 본격적인 산행이 시작된다.", - "MNTN_HG_VL" : "539", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시", - "MNTN_NM" : "승학산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "800", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군", + "MNTN_NM" : "조항산" }, - "longitude" : 128.86506800000001, - "latitude" : 35.537758199999999 + "longitude" : 127.5848718, + "latitude" : 35.963462 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "승학산은 부산의 억새명산이다. 승학산은 부산에서 가장 서쪽에 있으며, 구덕산과 시약산의 서쪽, 엄광산의 남쪽으로 사하구 당리동의 뒷산이다. 승학산 동쪽 제석골 안부에 억새군락이 있는데, 이는 수만 평에 이르는 부산 제1의 억새밭이다. 바람 따라 일렁이는 대장관은 전국의 어느 억새명산 못지않다. 더불어 부산의 다양한 풍경을 한눈에 조망할 수 있다.승학산의 동쪽에는 영도, 감천, 송도 등의 항구와 바다가 펼쳐지며, 서쪽에는 서서히 강폭을 넓히는 낙동강과 드넓은 김해벌이 그 규모를 자랑하고 남쪽에는 연대봉이 우뚝 솟았고 북쪽에는 발아래 펼쳐진 억새밭이 눈길을 사로잡는다. 승학산은 높지 않으나 그 이름처럼, 도시 속의 고고한 학과도 같은 화려함으로 등산인들의 마음을 사로잡는 산이다. 고려말 무학대사가 전국을 두루 돌아다니며 산세를 살폈는데 이곳에 오니 산세가 준엄하고 기세가 높아 마치 학이 나는 듯 하여 승학산이란 이름을 붙였다는 전설이 전해 오며 흔히 동아대 뒷산이라고도 한다.", - "MNTN_HG_VL" : "497", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 사하구 당리동", - "MNTN_NM" : "승학산" + "DETAIL_INFO_DTCONT" : "영대산은 장수군 산서면과 임실군 성수면의 경계에 자리한 산이다. 호남금남정맥의 팔공산이 서쪽으로 한줄기 곁가지를 일으킨다. 마령치를 지난 이 산줄기는 다시 둘로 나뉘어 북녘으로 성수산, 서녘으로 영대산과 오봉산을 일으킨 후 덕재산을 지나 오수면의 오수천에서 산줄기를 마감한다. 지형도에는 한문으로 영태산(靈台山)이라 표기되어 있으나 이곳 주민들은 모두 `영대산'이라 부른다.산형이 아담하고 수려하다. 또한 인자하고 후덕한 어머니가 자식을 품에 안고 젖을 주는 듯한 산이기도 하다 또 이 산은 장수 8경의 한 경치인 영산영월의 경관을 자랑한 산이다.", + "MNTN_HG_VL" : "666", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 산서면", + "MNTN_NM" : "영대산" }, - "longitude" : 128.97999999999999, - "latitude" : 35.116666700000003 + "longitude" : 127.3986111, + "latitude" : 35.612499999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "시랑산은 충북 제천시 백운면과 봉양읍의 경계를 이룬다. 백운산을 모산으로 하고 있는 시랑산은 높이는 나즈막하나 아기자기한 산행의 맛을 즐길 수 있다. 산을 오르면서 곳곳의 지명에 얽힌 뒷이야기들을 따라가다 보면 금새 정상에 다다른다. 정상에서 내려다보이는 산행들머리인 박달재에서는 금방이라도 `울고넘는 박달재'의 노랫소리가 들려올 것만 같다. 금봉이와 박달이의 애절한 사랑이야기와 거란족 10만 대군을 섬멸시킨 려의 명장 김취려장군의 승전을 상기하며 산행으로 인해 가빠진 호흡을 가다듬는다.눈꽃과 상고대가 곱게 피어난 정수리에서 북쪽으로 하산길을 이어간다. 조금 내려가면 쉬어가기에 적당한 널찍한 공터를 만나게 된다. 봄이나 가을이면 둘러앉아 간식을 권하며 산꾼들의 우정을 나누기에 안성맞춤인 명당이다. 조금 더 내려가면 바위지대를 만나게 된다. 눈이 쌓인 겨울에 미끄러지면 다치기가 쉽상이니 조시조심 지나가야 한다.조금 더 내려가면 아름드리 소나무와 참나무가 마주서서 정답게 이야기를 나누는 일주문을 지나게 되고, 북쪽 산길을 계속 이어가면 정상을 출발한 지 50분이면 단군비석에 도달한다. '국조단둔대황조성령(國祖檀君大皇祖聖靈), 삼선사령영사령(三仙四靈令司靈), 백운산성화신령(白雲山聖化神靈) 국사산왕산신지령(國祠山王山神之靈)' 이라고 쓰여진 세 개의 비석이 몇 그루의 노송 및 바위와 어우러져 신비로운 분위기를 연출한다. 이곳에서 조금 더 내려가면 그 유명한 박달재에 내려서게 된다.기나긴 세월동안 충주와 제천을 잇는 국도로서 숱한 애환이 서린 박달재이건만 이제는 고개 밑으로 시원스런 터널이 뚫려 인적이 드문 쓸쓸한 고갯길이 되고 말았으니 격세지감을 절로 느끼게 된다.", - "MNTN_HG_VL" : "691", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면, 봉양읍", - "MNTN_NM" : "시랑산" + "DETAIL_INFO_DTCONT" : "백두대간의 주맥인 오대산(1563m)에서 뻗어나온 줄기가 계방산에서 남으로 내려와 백적산을 일구고 그 아래에 힘껏 솟구쳐 일군 봉우리가 잠두산이다. 바로 옆에 백석산이 이웃해 있고 주변에는 오대산, 계방산, 가리왕산, 청옥산, 남병산 등 평창군 일대의 고봉들이 운집해 있다. 잠두산은 산의 형상이 누에벌레를 닮았다 하여 붙여진 이름이다.잠두산 정상은 산죽으로 덮여있고, 백석산 쪽으로 내려가는 넓은 능선엔 억새밭과 콩제비꽃 지대가 있어 아름답다. 산행으로는 맑은 오대천이 흐르는 동쪽이 산세가 완만해서 가족산행으로 좋다. 들머리는 마평리, 수항리, 화의리 어디를 선택해도 좋다.", + "MNTN_HG_VL" : "1243", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "잠두산" }, - "longitude" : 128.05472219999999, - "latitude" : 37.126666700000001 + "longitude" : 128.5097222, + "latitude" : 37.5586111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "371", - "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군", - "MNTN_NM" : "시묘산" + "DETAIL_INFO_DTCONT" : "보련산은 백두대간의 줄기가 치악산과 백운산을 거쳐 충주시로 이어진 능선위에 자리해 있으며 충북 충주시 앙성면과 노은면의 경계를 이루고 있다.이 산은 인파가 많이 몰리지 않는 탓에 호젓한 산행을 즐기기에 적당하다. 정상에서 북쪽으로 눈을 돌리면 동암계곡 끝의 온천마을이 보이고 그 뒤로 남한강이 야트막한 산들 사이로 굽이쳐 흐른다. 서쪽으로는 국망산과 오갑산이 손짓한다. 이 산의 능선은 노송군락으로 이어져 있고 자연동굴, 수룡폭포 등이 있어 주변경치가 좋고 물이 맑다. 산 정상에는 보련산성이 있는데 능선을 따라 흙과 돌로 쌓은 성의 둘레는 약 1.8km이며 일명 봉황성 또는 천룡성이라고 한다.이 성과 동쪽 맞은 편의 장미산 정상에 있는 장미산성 간에는 아주 재미있는 전설이 전해 오고 있다. 삼국시대 때 이곳 보련산 서쪽 가마골 마을에 장미라는 사람과 보련이라는 누이가 살았는데 명산의 정기를 받은 이들은 둘 다 장수의 기질을 가지고 태어났다. 그러나 옛부터 한 집안에 두 장수가 태어나면 그 중 하나는 희생되어야 하기에 두 사람은 성쌓기 겨루기를 하기로 하였다. 이 사실을 안 어머니는 가슴을 저미는 고통을 느끼게 되는데 어머니가 보기에 보련이의 성 쌓는 솜씨가 아들인 장미보다 뛰어나 고민을 하게 되었다.마침내 결심을 한 어머니는 손수 떡을해서 보련이에게 떡을 보이고 다시 성을 쌓게 했는데 보련이가 마지막 돌을 하나 올리려는 순간 장미쪽에서 성을 다 쌓았음을 알리자 보련이는 어머니가 아들을 살리려 했음을 알고 집을 떠났다고 한다. 보련이가 떠난 다음 날 보련이의 집에 큰 별이 하나 떨어졌다고 하며 그후 그 지역 산과 산성을 보련산-보련산성, 장미산-장미산성이라고 부르게 되었다.", + "MNTN_HG_VL" : "765", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면, 노은면", + "MNTN_NM" : "보련산" }, - "longitude" : 128.31055559999999, - "latitude" : 36.028055600000002 + "longitude" : 127.78390539999999, + "latitude" : 37.072415200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "대전 동구 식장산은 높이 598미터로 대전에 있는 산 중 가장 높으며 우람하다. 또 무성한 숲과 높은 바위벼랑, 깨끗한 호수와 맑은 물이 흐르는 개울도 있다. 식장산 남북으로 양 날개를 펼친 산줄기는 대전의 동쪽 울타리를 이루고 있다. 대전 시민들은 식장산 위로 여명 해솟음을 보며 떠오르는 달을 본다.5월 하순 아카시아 꽃이 필 무렵이면 세천공원에서 철탑 사거리를 지나 구절사 길까지 온통 아카시아 꽃천지다. 온 산에 짙게 밴 꽃향기를 맡으며 하얀 아카시아꽃으로 뒤덮인 길을 걷노라면 하늘나라의 화원을 걷는 것 같다. 우리나라에서 식장산의 꽃길 10리가 아카시아꽃으로는 가장 훌륭한 곳으로 꼽힌다.식장산 세천공원 수원지 아래에는 벚꽃이 유명하다. 또 수원지 호수와 계곡이 아름답다. 숲으로 싸인 호수와 독수리봉에서 후주에 이르는 계곡은 어느 산의 계곡과 견주어도 빠지지 않는다. 숲 속에 묻혀 있는 계곡은 돌, 바위, 나무가 한데 어울려 깨끗하고 아름답다.식장산에는 오래된 절 세 개가 있다. 서쪽에는 고산사, 북쪽에 개심사, 동쪽 동수리봉 아래에는 구절사가 있다. 뿐만 아니라 숲이 짙으며 대전시가지가 내려다보이고 속리산, 백화산, 덕유산, 민주지산, 대둔산, 계룡산이 조망된다.", - "MNTN_HG_VL" : "597", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 동구, 충북 옥천군", - "MNTN_NM" : "식장산" + "DETAIL_INFO_DTCONT" : "태백시 동쪽 경계에 있으며, 태백시계의 연봉 중 하나다. 해발 1259미터로 백두대간에서 갈라져 나온 낙동정맥의 산들 중 가장 높기도 하다. 낙동정맥은 백두대간 천의봉(매봉산, 1303m) 동쪽 능선에 있는 1145봉에서 부산 몰운대에 이르는 350여 킬로미터의 산줄기이다.백병산은 금대봉 같은 육산과 달리 정상부가 마치 바위병풍을 둘러놓은 듯하다고 해서 백병산이라 이름 붙었다. 전해오는 이야기에 따르면 병풍바위가 가뭄 때는 흰빛을, 비가 올 때는 검은 빛을 띠므로 바위 색깔만을 보고 가뭄이 올 것인지 홍수가 날 것인지를 판단했다고 한다.", + "MNTN_HG_VL" : "1259", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시 황연동", + "MNTN_NM" : "백병산" }, - "longitude" : 127.4800673, - "latitude" : 36.2953647 + "longitude" : 129.06833330000001, + "latitude" : 37.158333300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "취서산은 일명 영취산으로 불리고 있으며, 이 산의 산자락에는 3대 사찰 중 하나인 통도사가 자리잡고 있다. 취서산 정상에서 신불산 정상까지 이어지는 억새능선이 유명하며, 신불산 산자락에는 홍류폭포와 작천정이 유명하다.취서산과 신불산은 영남 알프스의 7개 봉우리에 속하는 산으로 광활한 억새밭으로 이름 난 곳이다. 경부고속도로를 부산 방면으로 내려가다가 언양인터체인지에서부터 통도사인터체인지 사이에 오른쪽으로 고속도로로 나란히 길게 뻗어 있으며 두 산은 같은 주능선에 가까이 붙어 있어 산행도 연결해서 하고 있다.", - "MNTN_HG_VL" : "1159", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 울주군 삼남면ㆍ상북면", - "MNTN_NM" : "신불산" + "DETAIL_INFO_DTCONT" : "두덕산(斗德山)이라 불리기도 했던 이 산은 산세야 그리 빼어나다고 할 수 없지만, 아담하고 조망이 시원한 정겨운 산이다. 낙동정맥 마루금이 지나면서 경북 경주시 안강읍과 영천시 고경면을 가르는 배티재 옆에 비켜 앉은 도덕산은 결국 그 지맥이 북쪽, 낙동정맥으로 이어진다. 아직까지 널리 알려져 있지 않은 관계로 이 지역 등산객들과 정맥 종주꾼들이 간간이 찾을 정도다. 남쪽의 자옥산(紫玉山, 569.9m)과는 능선을 맞대고 이웃해 있으며, 산기슭에는 볼 만한 문화유적도 많다. 동쪽 산자락을 따라 흐르는 옥산천(玉山川)의 자연과 어우러진 독락당, 옥산서원을 비롯해 주변에 산재한 문화유적을 둘러볼 수 있다.", + "MNTN_HG_VL" : "703", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 안강읍·영천시 고경면", + "MNTN_NM" : "도덕산" }, - "longitude" : 129.0561611, - "latitude" : 35.539955999999997 + "longitude" : 129.1391667, + "latitude" : 36.025277799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 김해시 삼방동과 대동면, 상동면에 위치한 신어산은 동서로 뻗어 있는 산으로 북동쪽으로는 낙동강이 감돌아 흐르고 남쪽에는 광활한 김해평야가 펼쳐져 있는 낙남정맥의 한 줄기다. 가락국의 시조 김수로왕 탄강지로 전해오는 구지봉이 산맥의 서쪽 끝부분에 있다. 능선에서 김해시가지를 바라보며 산행할 수 있고 기암절벽 사이로는 구름다리가 있어 산행의 묘미를 더한다. 정상에서 서쪽 주능선을 따라 630봉까지 가는 도중에는 군데군데 암봉이 있고 580봉에서 남쪽 능선을 따라 460봉의 암봉에 올라서서 신어산을 바라보면 빼어난 경치에 감탄하게 된다. 460봉의 전망대 같은 바위에서 동쪽 계곡으로 내려가면 암벽 밑에 천진암이 있고 숲길과 대밭을 거쳐 은하사에 닿게 된다. 정상의 조망은 무척산, 토곡산, 매봉, 오봉산, 금정산의 고당봉 등이 선명하게 시야에 들어온다. 산림욕장이 문을 열어 가벼운 산책도 겸할 수 있어 가족산행으로도 제격이다.신어산이라는 이름은 ‘지모신이 깃들어 있는 산’을 뜻하는 ‘가모뫼’의 차차표기다.이렇듯 신어산은 예부터 신성한 산으로 인식되어져 왔다.", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 삼방동", - "MNTN_NM" : "신어산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "330", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "칠봉산" }, - "longitude" : 128.92087570000001, - "latitude" : 35.270207599999999 + "longitude" : 128.8485613, + "latitude" : 37.714190700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 원주시 귀래면과 충북 제천시 백운면의 경계를 이루는 십자봉은 원주에서 남쪽으로 15㎞ 지점에 숨어있는 명산이다.겨울에는 설경, 가을에는 단풍과 낙엽, 그리고 여름에는 시원한 계곡으로 사시사철 산행지로 각광을 받고 있는데, 특히 산으로 들어서면 등산로마다 잡목수림이 터널을 이루고 있어, 여름철에 더위를 피하기 위한 장소로 그만이다. 빽빽히 들어찬 나무사이로 4㎞ 길이의 천은계곡이 쭉 뻗어 있으며 곳곳에 소와 담, 암반이 펼쳐져 계곡미가 뛰어나다. 계곡입구에서 10분 거리에 천은사라는 아담한 절이 있다.십자봉이라는 산이름은 일제가 붙인 이름이고, 덕동리 주민들은 촉새봉이라 부른다. 산 서쪽 자락인 귀래리에 있는 천은사 절이름도 '십자봉 천은사'가 아닌 '백운산 천은사'로 부르고 있다. 촉새봉이라는 산 이름은 이곳 주민들이 예전부터 조상 대대로 불러온 이름이다.", - "MNTN_HG_VL" : "985", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면, 충청북도 제천시 백운면", - "MNTN_NM" : "십자봉" + "DETAIL_INFO_DTCONT" : "원효산은 낙동정맥이 혼신의 힘을 다해 일구어 영남 알프스의 최고봉인 가지산(1240m)의 남쪽 끝에 있는 신불산, 취서산에서 동남쪽으로 흘러내린 지맥에 위치해 있다. 통도 인터체인지에서 5km쯤 남으로 내려오다 보면 왼쪽으로 나란히 서 있는 원효산은 규모로나 높이로나 만만찮은 산이지만 일반인들에게는 그리 널리 알려져 있지 않아 다소 한적한 산행을 즐길 수 있다.현재 원효산은 정상부근이 입산통제구역으로 되어 있어 정상에 오르는 기쁨은 맛 볼 수 없다. 하지만 신라 선덕여왕 때 창건된 흥룡사와 흥룡폭포를 보는 것만으로 산행의 기쁨을 어느 정도 느낄 수 있다. 또한 암벽을 끼고 있는 원효암과 의상대의 모습이 특히 볼만하다.", + "MNTN_HG_VL" : "922", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 상북면, 하북면, 웅상읍, 동면", + "MNTN_NM" : "원효산" }, - "longitude" : 127.93055560000001, - "latitude" : 37.211111099999997 + "longitude" : 129.1058333, + "latitude" : 35.400833300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전라북도 부안의 변산반도는 아름다운 해안선을 따라 수많은 절경이 이어지는데 이 일대가 국립공원으로 지정되어 있다. 변산은 바다를 끼고 도는 외변산과 남서부 산악지의 내변산으로 구분한다. 변산반도 국립공원의 내륙은 첩첩산중으로 이루어져 있다. 최고봉인 의상봉의 높이가 해발 509m에 불과하지만 400m급 준봉들이 겹겹이 이어진다. 내륙쪽 변산반도를 가리키는 내변산의 명소로는 최고봉인 의상봉(509m)을 비롯해 쌍선봉(459.1m), 옥녀봉, 관음봉(433m 일명 가인봉), 선인봉 등 기암봉들이 여럿 솟아 있고, 직소폭포, 분옥담, 선녀당, 가마소, 와룡소, 내소사, 개암사, 우금산성, 울금바위 등이 있다. 직소폭포 골짜기는 쌍선봉 자락에서 흘러내려 부안호로 흘러 내려간다.산에 얽힌 전설이 전해지는데, 이성계가 청년시절에 부안군 보안면 우반동 굴바위 옆 저수지 안쪽의 선계안(또는 성계골)에서 영험한 두 노인에게 각각 문(文)과 무(武)를 익혀 훌륭한 청년이 된 뒤 스승들과 헤어질 때가 되었다고 한다. 스승과 제자 모두 이를 서로 아쉬워하다가 선계안으로부터 북쪽으로 삼천보나 떨어진 이곳까지 왔고, 이성계가 두 스승에게 하직 인사를 하고 보니 두 스승은 사라지고 그 앞에 높은 봉우리 두 개만 우뚝 솟아 있었다고 한다.산중턱의 월명암에서 내려다보이는 안개 낀 아침 바다의 신비로움을 일컫는 월명무애와 직소폭포는 웅연조대, 소사모종, 채석범주, 지포신경, 개암고적, 서해낙조와 함께 변산팔경(邊山八景)으로 꼽힌다.", - "MNTN_HG_VL" : "459", - "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면", - "MNTN_NM" : "쌍선봉" + "DETAIL_INFO_DTCONT" : "옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동", + "MNTN_NM" : "설악산 공룡능선" }, - "longitude" : 126.558978, - "latitude" : 35.643399299999999 + "longitude" : 128.4504379, + "latitude" : 38.145543600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군 하면에 자리한 아기봉은 백두대간에서 갈라져 내려온 한북정맥이 운악산(936m)을 솟구쳐 웅장한 기세를 뽐내고 다시 내쳐 굴고개로 내려서기 직전 649m봉 어름에서 남쪽으로 살짝 앉혀놓은 봉우리다.이 아기봉은 운악산과 능선으로 바로 연결되어 정상에 나란히 봉우리가 솟아있다. 경기의 금강이라 부르는 일명 현등산의 운악산과 더불어 함께 산행을 하는 코스이기도 하다.운악산 정상에서 남능을 따라 5km 쯤 나간곳에 우뚝솟은 봉으로 현등산이 어머니의 산이라면 아기봉은 현등산에 안긴 아기에 비유되므로 아기봉으로 불리워왔다. 아기봉을 악귀봉이라고도 불리는데 이것은 잘못 전해진 이름이다.악귀봉(아기봉) 코스는 석장 위로 안부까지 가서 서남능선을 타고 정상을 거쳐 오른쪽 계곡으로 내려오는 코스인데, 암능 코스로 제법 시간이 걸리며 산행시 주의를 요한다.악귀봉의 모든 산악 관련 서류는 운악산과 일치하는 경우가 많아 운악산 자료를 살펴보면 자세한 정보를 알수 있다.", - "MNTN_HG_VL" : "772", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면", - "MNTN_NM" : "아기봉" + "DETAIL_INFO_DTCONT" : "갑장산은 아름다움이 으뜸이요(甲), 사장(四長)을 이룬다는 뜻에서 그 이름이 비롯된 산이다. 고려 충렬왕이 승장사에서 잠시 쉬었다 가며 ‘영남의 으뜸 산’이라 하여 갑장이라 명명했다는 설도 전한다. 상산 삼악의 하나인 연악(淵岳)이라고도 한다. 연악이란 이름은 구룡연에서 유래되었다. 구룡연은 갑장사 뒤 사거리에서 웃승장 방향으로 50미터 정도 내려가면 우측에 있는데, 천제와 기우제를 지내던 신성스런 연못이다. 구룡연에서 북쪽으로 문필봉이 우뚝 솟아 있는데, 바위 3개가 붓처럼 뭉쳐져 있다. 이 문필봉의 정기를 받아 갑장산 주변에 장원급제한 인물들이 많이 나왔다고 하여 장원향이라는 이름을 남기기도 하였다. 용포 쪽에는 백운 이규보가 1196년 요양하며 시를 남긴 용담사터가 있고, 승장계곡에는 옥류정과 승장폭포, 그리고 상주 사장사(四長寺), 갑장사(甲長寺), 승장사(勝長寺), 북장사(北長寺), 남장사(南長寺)) 중 하나였던 승장사터가 있다. 갑장산 정상 부근에는 고려 공민왕 22년(1373) 나옹선사가 창건한 갑장사가 자리 잡고 있다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 지천동, 낙동면", + "MNTN_NM" : "갑장산" }, - "longitude" : 127.32489889999999, - "latitude" : 37.878003 + "longitude" : 128.1886111, + "latitude" : 36.347222199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉황새가 높이 나는 형상이라 하여 아기산 또는 봉황산이라고도 하는데, 조선조 이조참판 류복기 선생은 이 산과 연관해 호를 기봉이라 했으며 후손들은 이곳을 당산으로 모시고 정월 보름날 아기당에서 고사를 올린다.아기산은 한발이 심할 때 이곳에서 기우제를 올리면 영험이 많아 반드시 비를 내렸다고 전하는 임동면의 진산이다.아기산의 북쪽 자락에는 신라시대의 고찰인 봉황사가 있고 전주 류씨의 집성촌인 무실마을이 있다.산 정상에서 바라보면 웅장한 임동교, 수곡교와 중평단지가 한폭의 병풍 같으며, 임하호의 맑은 물이 한눈에 보인다. 또 정상에서 서쪽으로는 안동 최고봉인 학가산과 안동시가지인 용상이 보이고 동쪽으로는 일월산이, 북쪽으로는 와룡산이 시야에 들어온다. 아기산 남쪽에는 지례예술촌이 있다. 1993년 12월 임하댐이 완공되면서 섬 아닌 섬이 되어 드넓은 임하호에 두둥실 떠다니는 형국이 되었다.", - "MNTN_HG_VL" : "589", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 임동면", - "MNTN_NM" : "아기산" + "DETAIL_INFO_DTCONT" : "강원도 평창군에는 유난히 전인미답의 1000m급 고봉들이 모여 있다. 장암산은 주변에 남병산(1149m)을 비롯하여 가리왕산(1560m), 청옥산(1256m), 백덕산(1350m)등이 인접해 있어 그 유명한 산들의 위세에 눌려 이름조차 생소한 산이다.첩첩 산중의 미답지인만큼 원시림에 가까운 수림이 주를 이룬다. 이 산 서쪽으로는 오대산 산자락에서 발원한 물줄기가 속사천을 거쳐 평창강과 남한강으로 흘러들면서 장암산을 끼고 돌아 주위경관이 더욱 수려하다. 특히, 이곳의 명물인 국내 최대의 송어 양식장이 자리하고 있어 산행 후 회나 매운탕을 별미로 맛볼 수도 있다. 장암산은 남병산을 베게 삼아 남북으로 길게 누웠는데 반으로 갈라 북쪽은 장암산이라고 하고 남쪽은 송계산이라고 한다 .송계산이라 부르는 연유는 옛부터 그 자락에 살아온 송씨들의 계모임에서 그렇게 불렀다고 한다. 최근 들어서는 페러글라이딩 동호회 회원들이 최고로 꼽는 활공장으로소의 역할을 톡톡히 하고 있다.", + "MNTN_HG_VL" : "833", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", + "MNTN_NM" : "장암산" }, - "longitude" : 128.93333329999999, - "latitude" : 36.533333300000002 + "longitude" : 128.4221124, + "latitude" : 37.3872778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보령과 부여의 경계선에 있는 아미산은 호젓한 산행 코스가 자랑이지만 지금껏 알려지지 않은 산이다. 가을이면 산 전체가 불붙은 듯 단풍으로 가득한 곳, 예부터 산삼이 많이 나는 곳이며 부정한 사람이 출입하면 화를 입는다는 이야기가 전해져 오는 산이다. 높은 산은 아니지만 골이 깊고 산세가 자뭇 웅장하다. 만만히 보고 다가갔다 흠씬 비지땀을 흘려야 오를 수 있는 산이다.보령호가 담수를 시작하면서 산 끝자락이 잠겼고, 만산홍엽의 그림자가 비친 호수와 어울린 모습이 황홀경에 빠져들도록 아름답다. 미산면 용수리 동북쪽에 자리하고 있으며, 도화담에서부터 솟아오른 봉우리가 풍계리와 용수리에 걸쳐 있다. 북쪽은 부여군 외산면과 지경을 이룬다. 아미산에는 백제때 창건된 중대암이 있고 인근에는 영천이라는 약수가 있다.", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "충남 보령시 미산면, 부여군 외산면", - "MNTN_NM" : "아미산" + "DETAIL_INFO_DTCONT" : "미숭산은 비운의 역사를 품고 있는 산이다. 고려의 장군이었던 이미숭이란 사람이 조선을 건국한 이성계에 대항해 군사를 모으고 이 산에 성을 쌓아 고려를 회복하는 싸움을 벌였던 곳이다. 그러나 이미 대세는 조선과 이씨 왕조쪽으로 기운 상태였기 때문에 장군은 결국 고려 회복의 뜻을 이루지 못하고 순절했다고 전해진다. 산에 장군과 관련된 유적이 아직 남아 있어 대세와 명분 사이의 긴장감 넘치는 대결을 떠올리게 한다. 정상 주변에 미숭산성의 성터와 성문의 잔해가 있고, 성문터 옆에 샘물도 있다. 이 산성은 삼국시대에 축조된 후 조선시대까지 계속 이용되었다고 한다.원래 이름은 상원산이었으나 후세 사람들이 이미숭 장군의 이름을 따서 미숭산이라 부르게 되었다.미숭산을 오르다보면 사방으로 운무에 가린 산, 산, 산이 겹겹으로 늘어서 있다. 그 사이로 들녘에 반짝 빛나는 것은 낙동강이다. 한 페이지의 역사도 남기지 않고 사라진 가야의 유물과 사적지를 둘러보면서 주산과 미숭산을 오르내리다 보면 봉긋하게 솟아난 언덕만 봐도 고분으로 보이고 등산길에 맞닥뜨리는 바위마다에는 원시 암각화가 그려 있는 것 같아 유심히 살펴보게 된다. 자신도 모르게 이처럼 신비에 쌓인 가야의 역사 속으로 빨려 들어간다.", + "MNTN_HG_VL" : "757", + "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군 고령읍", + "MNTN_NM" : "미숭산" }, - "longitude" : 126.6911111, - "latitude" : 36.279444400000003 + "longitude" : 128.19232030000001, + "latitude" : 35.738110900000002 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "350", - "MNTN_LOCPLC_REGION_NM" : "충청남도 당진시", - "MNTN_NM" : "아미산" + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", + "MNTN_NM" : "안양산" }, - "longitude" : 126.6648254, - "latitude" : 36.845756000000002 + "longitude" : 127.02019780000001, + "latitude" : 35.102527199999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "아미산은 홍천군 서석면에 자리한 해발 961미터의 산이다. 평창군 봉평면의 청량봉에서 한강기맥과 이별한 춘천지맥이 응봉산(1097m)을 눈앞에 둔 각근치에서 남서쪽으로 곁가지를 일으킨다. 이 산줄기는 무명봉(1009m)과 아미산, 고양산(675m)을 일으킨 후 홍천강으로 흘러드는 내촌천에 가라앉는다.우리나라에는 아미산이라 이름을 가진 산이 부산, 울산, 전남, 전북, 충남, 충북 등에 여럿 있으며 중국의 산동성에도 무협소설에 등장하는 같은 이름의 산이 있다. ‘아미’란 이름의 뜻은 우리가 흔히 생각하는 아미(蛾眉) 즉, 미인의 눈썹이 아니며 불교에서 아미타불(阿彌陀佛)의 약칭으로 말하는 아미도 아니다. 높을 아(峨)에 풍치가 아름다울 미(媚), 즉 ‘높고도 풍치가 아름다운 산’이 바로 홍천의 아미산이다. 아미산은 대중교통으로 접근하기에도 좋은 산이다. 서울에서 홍천, 홍천에서 서석으로 수시 운행하는 버스편을 이용하면 쉽게 다녀올 수 있는 산이다.아미산은 북으로는 가리산, 동으로는 계방산, 회령봉, 흥정산 줄기가 한눈에 들어오고 서쪽으로는 공작산을 조망할 수 있다. 아미산 끝자락에 있는 고양산은 사람들의 발길이 닿지 않은 곳으로 ª은 거리의 등산과 함께 깨끗한 내촌천에서 물놀이도 즐길 수 있다.", - "MNTN_HG_VL" : "961", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서석면", - "MNTN_NM" : "아미산" + "DETAIL_INFO_DTCONT" : "제비봉은 충북 단양군 단양읍에서 서쪽인 충주호 방면으로 약 8km 거리인 장회리에 위치한 산으로, 단양팔경의 절정인 구담봉과 옥순봉에서 서남쪽 머리위로 올려다 보이는 바위산이다.유람선을 타고 구담봉 쪽에서 이 산을 바라보면 충주호를 향해 부챗살처럼 드리워진 기암괴봉과 바위능선이 마치 제비가 날개를 활짝 펴고 나는 듯한 형상을 갖추고 있다하여 제비봉이라 이름 붙여졌다 한다. 충주호 건너편 금수산도 단풍이 빼어나지만 바위산과 어우러진 제비봉의 단풍은 더욱 장관인데, 특히 정상에서 조망은 북쪽 발 아래로 충주호의 그림같이 시원한 경치가 보이고 그 뒤로 금수산이 우뚝 솟아 있으며 동쪽 멀리 소백산 연능이 스카리라인을 이루고, 서북쪽 아래로 단양팔경중 으뜸인 구담봉과 옥순봉이 인접해 있어 손에 잡힐 듯 하다. 이들 경치를 구경하며 산행의 묘미를 실컷 만끽할 수 있음은 물론이다.", + "MNTN_HG_VL" : "721", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", + "MNTN_NM" : "제비봉" }, - "longitude" : 128.209, - "latitude" : 37.738999999999997 + "longitude" : 128.25608639999999, + "latitude" : 36.926274999999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제", - "MNTN_NM" : "아미산" + "MNTN_HG_VL" : "762", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", + "MNTN_NM" : "비학산" }, - "longitude" : 128.20861110000001, - "latitude" : 37.7386111 + "longitude" : 129.2891482, + "latitude" : 36.196548900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "353", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", - "MNTN_NM" : "아홉산" + "DETAIL_INFO_DTCONT" : "경남 거창군의 분지 가운데에 우뚝 솟아있는 금귀봉은 산의 모양이 탕건의 모양을 하여 `탕근산'이라고도 불린다.또 금귀봉 정상에는 아직까지 봉수대의 흔적이 남아있어 주변 마을 사람들은 봉수산이라고도 부른다.금귀봉에는 많은 문화유적이 있는데 현재도 샘터와 금귀사 절터 등이 남아있다. 또한 금귀봉의 동남쪽 기슭 석장골에는 지난 71년 발굴된 고려 초기의 문마 벽화고분과 양평리 석조여래입상 등의 문화 유적이 있다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 거창읍", + "MNTN_NM" : "금귀봉" }, - "longitude" : 129.18416669999999, - "latitude" : 35.285277800000003 + "longitude" : 127.9513889, + "latitude" : 35.729999999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "부산의 진산 금정산 주능선을 내달리다 잠시 산성 끄트머리에 걸터앉아 동쪽인 오른편 저 멀리 회동수원지를 바라보면 바로 뒤에 올망졸망한 봉우리가 시야에 들어온다. 아홉산이다. 부산에는 원래 또 다른 아홉산이 있는데 기장군ouml;마면 웅otilde;리 미동마을 뒷산인 아홉산이 그것. 최근 숲uuml;험장으로 각광받고 있다고 하면 고개를 끄떡일 사람들이 제법 있을듯하다. 그러나 금정구 회동동의 아홉산은 회동수원지에서 기장군ouml;마면 장전리에 걸쳐 뻗은 산이다. 기장의 산으로 비교적 알려진 운봉산과 개좌산과 이웃해 능선으로 이어진다. 아홉산은 이름 그대로 아홉개의 봉우리로 된 회동수원지 뒷산이다. 덩치는 작지만 아홉개의 작은 봉우리를 오르내리는 재미가 쏠쏠하다. 높이가 300미터 대에 불과해 가볍게 몸풀기에 적당하다. 그렇기 때문에 산꾼들은 아홉산 하나를 오르면 왠지 허전해 바로 옆의 운봉산이나 개좌산을 함께#376;는 경우가 많다. 무엇보다 아홉산의 자랑은 시원한 조망. 금정산 주능선과 출렁거리는 동해바다는 '부산에도 이런 곳이 있었나'라는 생각이 들 정도다.", - "MNTN_HG_VL" : "353", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 금정구 기장군", - "MNTN_NM" : "아홉산" + "DETAIL_INFO_DTCONT" : "치마산은 구이면과 신덕면의 경계선상에 완만하게 솟아있는 육산으로 구이저수지 동쪽의 경각산을 바라보고 있다.이 산은 산세가 말이 달려나가는 형상이라 하여 달릴 치(馳) 자와 말 마(馬) 자를 붙여 이름을 지었다고 한다. 망산 마을이름은 마을 뒷산(치마산 북릉)이 옥토망월형이라 하여 생긴 이름이라는 설과, 모악산을 마주보는 형국이라 지어진 것이라는 설이 전해진다. 이 마을은 실와우와 돔바우 2개 마을로 이뤄져 있다.이 산을 가운데 두고 주변에 높고 너른 산과 들이 시원스럽게 펼쳐져 있어 전망이 뛰어나며 겨울이 되면 정상 헬기장 부근에 눈이 많이 쌓여 눈 등산하기에 좋다. 치마산은 겉으로 보기에는 펑퍼짐한 육산 정도로 보인다. 평범하게 보이는 이 산 속에 진안 마이산 석탑을 보는 듯한 석탑군이 형성돼 있는 용광사를 비롯해서 장군바위, 장군굴, 마애불상 등 볼거리가 적지 않아 앞으로 근교산행 대상코스로 자리매김할 수 있는 내용이 알찬 산이다.", + "MNTN_HG_VL" : "567", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 구이면, 임실군 신덕면", + "MNTN_NM" : "치마산" }, - "longitude" : 129.18416669999999, - "latitude" : 35.285277800000003 + "longitude" : 127.1461111, + "latitude" : 35.695833299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 합천군 대병면에 자리하고 있는 악견산은 금성산, 허굴산과 더불어 합천의 삼산으로 불린다. 세 산은 합천호 부근에 옹기종기 모여 있다. 크고 작은 바위들이 들쭉날쭉 빚어내는 경관이 수려하고도 야무지다.악견산은 합천댐 설치로 더욱 돋보이게 되고 유명해졌다. 일반적으로 산의 정상은 암봉으로 되어 있거나 둥그스름한 봉우리로 되어 있는데 이 산의 정상은 집채만한 큰 바위들이 수없이 쌓이고 엉켜 정상부를 형성하고 있다. 이 산에서의 조망은 서쪽 능선따라 오르면서 뒤돌아 본 합천댐의 풍경이 매우 아름답다.악견산에는 임진왜란 때 왜적과 격전을 벌였던 악견산성이 남아있다. 이곳은 임진왜란 때 민중의 영웅으로 이름을 떨친 의병장 곽재우 장군의 전설이 담겨 있어 의구한 역사도 깃들어 있는 곳이다. 악견산성(경남 기념물 제218호)은 1439년(세종 21)에 축조된 테뫼식 산성으로 임진왜란 때(1594년) 유성룡의 지시를 받아 성주 목사로 있던 곽재우가 보수공사를 했다고 한다.", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면", - "MNTN_NM" : "악견산" + "DETAIL_INFO_DTCONT" : "포천읍에서 북쪽으로 약 10km 떨어진 나즈막한 산으로 교통이 편리하고 산길이 짧아 산을 처음 오르는 사람이나 여성들에게 인기가 있다. 산중턱에 금룡사라는 절과 커다란 미륵불상이 자리하고 있어 문화적 가치도 높은 산이다.정상에는 삼각점이 있고, 백운산,국망봉,청계산 등 조망이 뛰어나다.봄의 진달래, 늦가을의 낙엽, 겨울의 설경 또한 좋으며 계곡은 능선 북쪽편이 좋다.산록에는 사시사철 철철 넘치는 석간수가 있고, 일동에는 유황,하와이,사이판온천 등이 있다.", + "MNTN_HG_VL" : "569", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 영중면 금주리", + "MNTN_NM" : "금주산" }, - "longitude" : 128.0494783, - "latitude" : 35.531882899999999 + "longitude" : 127.272735, + "latitude" : 37.957242299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "431", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산", - "MNTN_NM" : "안락산" + "DETAIL_INFO_DTCONT" : "대운산은 울산광역시와 부산광역시, 경남 양산시의 경계에 있는 산이다. 금정산에서 원효산, 천성산을 이어가는 낙동정맥이 그 중간에서 동쪽으로 곁가지를 내려 백운산(520m), 철마산(604m), 거문산(543m), 달음산(588m), 용천산(545m) 등을 차례로 일으킨다. 그 중 최고봉인 대운산은 2개 광역시와 경상남도의 경계선을 긋는 중요한 곳에 자리하고 있으며, 장안사, 척판암, 내원암 등 역사의 향기가 가득한 명찰을 자락에 품고 있는 남녘의 명산이다.대운산을 오르는 산길은 다양하나 겨레의 영원한 스승 원효대사의 발자취를 찾아 기장군 장안읍에 자리한 장안사를 거쳐 오를 수 있다. 장안사는 신라 문무왕 13년(서기 673년) 원효대사가 창건한, 오랜 역사를 자랑하는 고찰이다.‘불광산(대운산의 다른 이름) 대운사’라고 쓰인 문을 지나 들어선 장안사 뜨락에는 동백꽃이 뚝뚝 지고 고목들이 연륜을 알려주는 경내에는 불향이 그득 넘친다. 장안사 절문을 나서면 오른쪽에 참으로 특이한 해우소(변소)가 보인다. 굵은 왕대를 엮어 울타리를 두른 멋진 해우소. 볼 일이 급하지 않더라도 잠시 들러 왕대나무 화장실의 멋을 엿보아야 한다.", + "MNTN_HG_VL" : "742", + "MNTN_LOCPLC_REGION_NM" : "경남 양산시 웅상읍, 울산시 온양면, 부산시 기장군", + "MNTN_NM" : "대운산" }, - "longitude" : 126.88249999999999, - "latitude" : 36.694722200000001 + "longitude" : 129.21184489999999, + "latitude" : 35.402419600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "313", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", - "MNTN_NM" : "안마산" + "DETAIL_INFO_DTCONT" : "비봉산(672m)과 금성산(550m)은 경북 의성군 금성면, 가음면, 춘산면, 사곡면에 걸쳐 있는 비교적 알려지지 않은 산이다. 금성산 서녘자락인 금성면 탑리에는 국보 77호 의성탑리오층석탑이 있다. 또한 28번 국도와 927번 지방도가 만나는 초전리에는 문익점선생기념비와 삼한시대 부족국가인 조문국의 경덕왕릉이 있어 문화유적답사를 겸하여 한 번은 올라야 할 산이다.몇 년 전만 해도 의성 부근은 교통이 불편하여 당일산행은 언감생심이었다. 그러나 최근 중앙고속국도의 개통으로 군위, 의성에 있는 오지 산도 당일산행이 가능해졌다.의성군 금성면의 탑리 시가지를 벗어나 산운리의 68번 지방도에서 북쪽으로 올려다보면 금성산 비봉산의 산세는 참으로 눈부시다. 겨울 햇볕에 빛나는 산세는 한번 우러르기만 하면 도저히 참을 수 없는 산행에의 정열이 저절로 솟구친다.산행 종점 인근에는 신라시대 의상조사가 창건한 유서깊은 고찰인 수정사가 있고 탑리 오층석탑, 관덕리 삼층석탑, 빙산사지 오층석탑 등 우리나라 석탑 양식을 살펴볼 수 있는 석탑과 제오리 공룡발자국 화석지 등의 유적지가 금성산 일원을 따라 자리잡고 있다. 이중 빙산사지 오층석탑이 있는 빙계계곡은 여름철 피서지로서 빙혈과 풍혈로 유명하다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "경북 의성군 금성면ㆍ가음면ㆍ춘산면ㆍ사곡면", + "MNTN_NM" : "금성산" }, - "longitude" : 127.7494444, - "latitude" : 37.842222199999988 + "longitude" : 128.7093678, + "latitude" : 36.262196699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "안산의 지세는 대체로 급경사로 이루어져 있으나 높이가 297M로 낮은 편이어서 주민들의 산책로로 이용되고 있다. 면적은 약 209만제곱미터이며 여러개의 등산로가 조성되어 있고, 다양한 종류의 야생화와 함께 숲길 옆으로 소나무, 잣나무, 독일가문비, 메타세쿼이어, 벗나무, 단풍나무, 복자기나무가 울창해 도심 속에서 삼림욕을 즐길수 있는 서울 서대문구의 대표적인 명소이다. 정상에는 안산봉수대가 있으며 북한강과 인왕산, 행주산성과 한강을 조망할수 있다.", - "MNTN_HG_VL" : "297", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 서대문구 홍제동", - "MNTN_NM" : "안산" + "DETAIL_INFO_DTCONT" : "남한강과 남한강의지류인 경안천 사이에 솟아있는 산으로 팔당댐을 기준으로 하면 왼쪽인 북쪽의 양수리에서 북한강과 남한강이 합류하고 남쪽인 광주쪽에서 남한강의 경안천이 흘러드는 광주군 초월면 방향으로 팔당댐이 깊숙이 파고 든다.4백미터 남짓한 나지막한 산으로 별로 눈에 띄지 않는데다 교통도 그리 좋은 편이 아니라 찾는 이들은 그리 많지 않다. 하지만 막상 산을 찾아가면 주변 일대에 풍기는 강촌의 향취와 정상에서 내려다 보는 한강의 풍경에 감탄한다. 남북한강이 어우러지는 양수리 부근에 빼꼼히 솟아 오른 정암산은 한강을 발아래 두고 오르는 산행의 묘미가 일품이다.주변에 신라 문무왕(文武王) 때 쌓은 주장성(晝長城)의 옛터를 활용하여 1624년(인조 2)에 축성한 남한산성(사적 57)이 있다.", + "MNTN_HG_VL" : "403", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 남종면", + "MNTN_NM" : "정암산" }, - "longitude" : 126.94499999999999, - "latitude" : 37.576666699999997 + "longitude" : 127.34154669999999, + "latitude" : 37.514297800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "설악산 대청봉에서 서북능선을 따라 10km쯤 달리면 한계령으로 빠지는 갈림길이 나온다. 이곳에서 계속 전진하는 길에 귀때기청봉(1,578m)을 거쳐 10km여를 더 오르락내리락 하다보면 대승령 안부에 이른다. 여기서도 방향을 계속 서쪽으로 잡아 4km쯤 가다보면 마치 말안장을 연상시키듯 두 개의 암봉 사이가 잘룩하게 들어간 모습을 접하게 된다. 여기가 바로 안산의 정상부위로서 일명 길마산이라고도 한다.안산은 외진 위치 때문에 찾는 사람이 많지 않다. 남쪽의 장수대에서 산행을 시작하는 사람들은 대승령에서 십이선녀탕계곡으로 하산길을 잡아 이 산을 스쳐 지나는 것이 보통이다. 그래서 설악을 수십번 다닌 사람들 중에도 안산을 다녀온 사람이 드물 정도로 한적한 봉우리로 남아 있다.안산은 멀리 원통쪽에서 바라보아도 말안장을 닮은 모습이 시선을 끌고 있고, 막상 올라가보아도 처음부터 암벽으로 이루어진 협곡이 만만찮은 험산임을 느끼게해 준다. 이 산을 중심으로 옥녀탕 계곡과 12선녀탕계곡이 좌우로 펼쳐져 있고, 정상 주변에는 화강암 기암이 도처에 산재하고 조망하는 전망이 일품이어서 등산의 가치가 높은 산이다. 정상 옆에는 무악동 봉수대가 있다.", - "MNTN_HG_VL" : "1430", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면", - "MNTN_NM" : "안산" + "DETAIL_INFO_DTCONT" : "명위산이 위치해 있는 충주시 동량면 하천리는 옛날에 토정(土亭)이 살았던 곳으로 `하천팔경 또는 개천팔경(開天八景)' 이라는 명소(名所)를 가지고 있으며, 풍수학적으로 화를 피할 수 있는 피난지로 알려진 곳이다. 이곳에 충주 호반과 어우러져 수석처럼 아름답게 솟아 있는 면위산에는 남쪽 능선에 2개의 옥녀봉이 있으며, 옥녀봉에는 물맛 좋은 약수가 있어 옛날 선녀들이 내려와 물맛과 이 곳의 경치를 즐기다가 하늘로 올라갔다는 전설이 전해지고 있다. 약수는 중탕과 상탕, 2곳이 있다.면위산은 옥녀봉으로 많이 불리우며 부산으로 불리게 된지는 얼마되지 않는다. 일제시대 때 지명정리를 하면서 동네사람들로부터 면위산(免危山) 이란 말을 며느리산으로 잘못 듣고 며느리 부(婦)자를 써서 부산(婦山)으로 잘못 쓰게 된 것이라고 한다. 이 산은 마을 이름을 따서 하천팔경(荷川八景), 또는 하늘을 연다는 뜻인 개천팔경(開天八景)이라는 명소들을 산자락에 거느리고 있어 산행의 즐거움을 배가시 키고 있다.", + "MNTN_HG_VL" : "780", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면", + "MNTN_NM" : "면위산" }, - "longitude" : 128.33000000000001, - "latitude" : 38.140000000000001 + "longitude" : 128.05472219999999, + "latitude" : 37.041388900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "완주군 동북부에 있는 요지인 고산은 고려시대에는 봉성형이었으며 조선시대에는 고산군이었다. 금남정맥에서 뻗쳐와 원등산 위봉산 되실봉을 거쳐 북쪽으로 달려가 안수산을 솟구친다. 북쪽으로 나아가던 500m대의 산세가 고산을 눈앞에 두고 갑자기 멈추며 산줄기는 동쪽으로 틀어진다.북쪽으로의 진행을 멈춘 산줄기는 자연스럽게 높은 턱을 이루고 그 끝에 크나큰 암봉을 빚어놓았다. 특히 이 암봉(일명 달걀봉)은 고산천이 휘돌아 흐르는 고산마을을 굽어보고 있다. 고산에서는 물론 봉동 삼레 일대 들녘에서도 눈에 잘 띄는 특이한 산세다. 달걀봉 아래 제법 널찍한 터에 안수암이 있고 수 백년 된 느티나무가 그 연륜을 자랑하고 있다. 느티나무로 미루어 볼 때 적어도 수 백년 전부터 있었으리라 믿어지는 안수암은 모악산 금산사의 말사로 지금은 젊은 범운스님이 홀로 다스리고 있다.안수산을 고산 사람들은 고산의 지킴이로 믿고 있다. 고산천을 중심으로 펼쳐진 고산 일대의 지형이 풍수지리적으로 '지네'의 형국이라 한다. 지내의 독기를 누릴 수 있는 것은 지네와 상극인 '닭'으로 알려져 있는데이 안수산이 닭벼슬을 닮아 일명 '계봉산'으로 불린다. 또 멀찍이서 바라보면 거대한 바위로 이뤄진 주봉이 듬직한 자태로 서 있어 오르기 전부터 보는 이의 마음이 한결 뿌듯해진다.안수산 정상에서 되실봉 정상까지 약 2시간 30분 소요되는 암릉코스가 산행의 재미를 더해준다. 산행기점은 주로 청동마을이나 성재동마을로 잡는 것이 일반적인데, 안수산 서쪽 계곡 저수지로 하산하거나 안수산에서 되실봉을 거쳐 오성리로 하산할 수 있다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", - "MNTN_NM" : "안수산" + "DETAIL_INFO_DTCONT" : "월류봉은 충청북도 영동군 황간면에 솟아 있는 해발 400.7미터의 봉우리다. 이름 뜻 그대로 달이 머문다는 이 봉우리는 달이 머물러 갈만큼 아름답다. 하물며 이곳에선 달이 서쪽으로 그냥 넘어 가는 것이 아니라 능선 모양을 따라 서쪽으로 흐르는 듯 달이 머물다 사라진다고 한다.그리 높지 않지만 빼어난 비경을 지닌 월류봉. 영동 한천팔경이라는 것이 이 월류봉의 곳곳을 세분화하여 일컫는다는 말이 빈말은 아닌 모양이다. 한천팔경 중에서도 산세가 빼어나고 준수한 면모를 지녀 첫손에 꼽히는 월류봉이 당연지사 1경이라면, 3경인 용연동은 월류봉 아래의 깊이를 가늠할 수 없는 깊은 소를 지칭한다. 4경 산양벽은 단애 이룬 월류봉의 기암절벽을 8경은 우암 송시열(1607~1689)이 즐겨 찾던 명승지 월류봉을 감상하며 머물렀다는 한천정사를 말한다.월류봉은 들머리에서 바라보면 토산으로 보이지만 반대편 강가에서 바라보면 기암괴석이 보인다. 봄에는 신록이 우거지고 가을에는 단풍이 아름다워 관광객이 끊이지 않고 있는 산이다. 또 월류봉에 오르면 총강천 건너로 원촌리 구릉성산맥이 한반도의 모양과 똑 닮은 모습으로 자리하고 있는 것을 볼 수 있다.", + "MNTN_HG_VL" : "401", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면", + "MNTN_NM" : "월류봉" }, - "longitude" : 127.22648959999999, - "latitude" : 35.954262300000003 + "longitude" : 127.89136310000001, + "latitude" : 36.234184999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "347", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "안심산" + "DETAIL_INFO_DTCONT" : "신선봉에서 북진하는 능선에서 서북쪽으로 갈라져 나간 지능선에 마지막으로 솟아오른 용산봉은 단양군 남한강변인 가곡면 사평리, 보발리, 대대리 사이에 서있다. 용산봉은 어머니산인 신선봉과 비슷하다. 신선봉을 멀리서 또는 산 아래에서 보면 산세가 육산 같지만 정상이 쇠뿔 돋아난 듯 바위로 되어 있는 것처럼 용산봉도 주능선에 올라보면 바위지대가 노송 사이에 펼쳐지기 때문이다. 또한 진달래군락이 어우러져 아름답다.산행 초반부터 깔딱고개를 만나 힘을 쏟는가 하면 암릉지대를 미끄러지며 올라 정상에 서면 조망이 장관이다. 4평 정도의 공터에 국유지 표지석이 있는 정상에서 동서남북으로 이어지는 파노라마를 만나게 되는데 소백산 주능선, 국망천계곡, 제2연화봉, 도솔봉, 황장봉산, 문수산, 대미산, 충주호, 남한강, 도담삼봉, 삼태산, 태화산 등이 도열한 모습이 숨을 멈추게 한다.", + "MNTN_HG_VL" : "944", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "용산봉" }, - "longitude" : 127.65000000000001, - "latitude" : 34.733333299999998 + "longitude" : 128.4241667, + "latitude" : 37.024999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", - "MNTN_NM" : "안양산" + "DETAIL_INFO_DTCONT" : "가리봉은 설악산국립공원에 속하는 산으로 설악산 귀때기청봉(1,580m)과 대승령을 잇는 설악산 서북 주능선과 마주보고 있어 독립된 산처럼 보인다. 멀리서 보면 봉우리가 둥글둥글 완만해 보이지만 험준한 암봉들이 많은 산이다.산행 들머리는 옥녀탕앞이나 한계령에서 시작하는데 오르다 보면 산의 남서쪽에 이 산의 명물 팔례 약수가 있다.가리봉 주능선은 등산인들의 왕래가 거의 없는 관계로 등산로가 뚜렷하지 않으므로 산행시 주의해야 하는 곳이다.", + "MNTN_HG_VL" : "1519", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", + "MNTN_NM" : "가리봉" }, - "longitude" : 127.02019780000001, - "latitude" : 35.102527199999997 + "longitude" : 128.34222220000001, + "latitude" : 38.093611099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "안양산은 무등산을 잇는 가교로서 무등산, 만연산과 어우르며 화순의 알프스로 불린다. 호남정맥 종주대에 의해 알려지기 시작하면서 무등산에서 안양산까지 이어지는 능선길을 찾는 사람들이 늘고 있다. 안양산자연휴양림에서 오르는 길은 급경사 길이며 들국화마을에서 오르는 길은 목계단과 데크계단이 설치되어 있으며 약 1시간 정도 걸린다.능선부에 이르면 넓은 철쭉밭이 펼쳐져 있고 산세가 모나지 않고 둥그스름해 친근한 멋이 감도는 안양산은 5월 초에 오르면 널찍한 평지를 이룬 정상의 북쪽 완사면에 분홍 융단으로 펼쳐진 철쭉 꽃 밭이 감탄사가 절로 나오게 한다.‘안양산 키높이 철쭉놀이’라는 명칭으로 2005년부터 5월 초순이 되면 안양산 철쭉제가 열리고 있으며 그 기간에 산오름을 하면 어른 키보다 훨씬 큰 연분홍 철쭉꽃밭의 황홀함을 느낄 수 있다. 가을이면 억새 사이에 핀 야생화도 백마능선을 아름답게 장식하고 있어 봄, 가을에 서로 색다른 안양산의 풍모를 만끽할 수 있다.", - "MNTN_HG_VL" : "853", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 이서면", - "MNTN_NM" : "안양산" + "DETAIL_INFO_DTCONT" : "경기 5악 중의 으뜸인 화악산(1,468m)은 강원도와 경기도를 가르는 분기점에 우뚝 솟아 있는 산이다. 경기도의 최고봉이다. 화악산을 중심으로 동쪽에 매봉, 서쪽에 중봉이 위치하며 이들을 삼형제봉이라고도 한다. 여기서 발원하는 물은 화악천을 이루며 가평천의 주천이 되어 북한강으로 흘러든다.정상 주변은 군사지역으로 출입이 금지되어 있어 가까운 곳에서 보는 것으로 만족해야 하는 점이 아쉽다. 지금은 정상 서남쪽 1km 거리에 있는 중봉 산행으로 화악산 정상을 대신하고 있다. 화악산 주능선에 오르면 가평, 춘천 일원을 굽어볼 수 있어 산행의 재미를 더해 준다.", + "MNTN_HG_VL" : "1468", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 화천군 사내면", + "MNTN_NM" : "화악산(중봉)" }, - "longitude" : 127.02019780000001, - "latitude" : 35.102527199999997 + "longitude" : 127.5031003, + "latitude" : 37.9950197 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "583", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "앞산(앞산공원)" + "DETAIL_INFO_DTCONT" : "봉황산(鳳凰山)은 중화지구 화령(化寧) 북쪽에 우뚝 솟아있는 대간상의 산이다. 1300여년 전 봉황새가 이 산에 날아들어 30여년 정도 살았다는 전설에서 유래했다 한다.인근에서는 “정상을 봉황머리처럼 원만하게 빼어 올리고 좌우 양 날개를 길게 펼친 형국이 봉황새 같아서” 라고도 한다. 화령은 행정구역상 화서면이라 부르지만 지역 사람들에게는 화령으로 더 알려져 있다. 옛날 화령현 소재지였던 까닭이다. 그 당시 무사들이 살았다는 무동(武洞), 현감이 살았다는 상현(上縣), 관곡(官穀)을 보관했던 창고가 있었던 창안 등의 지명이 지금도 남아있다.", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "상주시 화서면 신봉리 상현리, 상곡리 화송리\/화남면 동관리", + "MNTN_NM" : "봉황산" }, - "longitude" : 128.57638890000001, - "latitude" : 35.816944399999997 + "longitude" : 127.9403798, + "latitude" : 36.463463900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충청남도 공주시 사곡면 화월리와 우성면 방문리의 경계를 이루는 산", - "MNTN_HG_VL" : "280", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", - "MNTN_NM" : "약산" + "DETAIL_INFO_DTCONT" : "미타산에서 남으로 뻗어 내린 산릉의 끝머리에 암봉이 불쑥 고개를 내밀고, 산릉을 좌우로 마치 날아가는 독수리가 나래를 편 형세로 자리잡고 있는 산이 의령군민들에게 사랑을 받고 있는 국사봉이다.합천군 대양면, 의령군 봉수면에 걸쳐 산역을 펼치고 있는 이 산은 인근 주민들 이외는 별로 알려진 산은 아니지만 아기자기한 암릉과 깨끗한 산의 모습이 산객들에게 호감을 주고 있다.국사라는 이름을 가진 산에는 옛날 나라일에 관해 행사를 치렀다는 기록이 남아 있다.", + "MNTN_HG_VL" : "613", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 봉수면", + "MNTN_NM" : "국사봉" }, - "longitude" : 127.05457490000001, - "latitude" : 36.497249500000002 + "longitude" : 128.2488889, + "latitude" : 35.492777800000013 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구룡령은 옛부터 큰 고개인 원구룡령의 남동쪽 1㎞지점에 위치해 있다. 옛 구룡령은 현고개에서 서북쪽의 1100고지를 넘어가야 있는 것이다. 약수산이란 이름은 흔히 명개리 약수라 불리는 이 산 남쪽 골짜기의 약수에서 유래한 것이라고 한다.약수산은 백두대간이 오대산에 이르기 직전 산세를 일으키고 있는 산 들 중의 하나다. 구룡령 너머 서쪽엔 갈전곡봉이, 동남으로는 응복산(1360m), 만월봉(1279m)이 한 어깨로 나란히 솟아있다. 그래서 이 산들을 연결해서 종주하는 산악인들도 여럿 있다. 홍천군 내면 목맥동 일대는 수림이 울창하고 각종 희귀 동식물과 열대어 등 어류가 서식하고 있어 자연훼손을 최소화하는 산행을 해야 겠다.약수산 북쪽으로 이어진 암산 동북으로 깊고 길게 패여진 미천골은 아직 사람들이 많이 드나들지 않아 옛날 그대로의 숲과 자연경치를 간직 한 곳이다. 양옆으로 늘어선 나무들이 시원스럽고, 계곡 안의 물속에는 물고기들이 많다.울창한 숲, 맑은 물, 기암괴석, 야생동식물, 약수터, 신라고적, 토종꿀, 각종 산림부산물 등 휴양원이 풍부하고, 또한 이곳의 미천골 자연휴양림은 5,652천㎡의 시설 구역내에 평균수명 50년 이상의 활엽수 천연림으로 삼림욕을 즐길 수 있다. 미천골 초입에는 신라 법흥왕 때 창건했다가 고려 말에 폐사되었다는 선림원터가 있다. 석등, 3층석탑, 홍각선사탑비, 부도 등의 보물급 문화재가 남아 있다.공지(空地)로 된 정상에서는 남쪽의 백두대간길과 소황병산 및 오대산 구간이 잘 바라보인다.", - "MNTN_HG_VL" : "1306", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", - "MNTN_NM" : "약수산" + "DETAIL_INFO_DTCONT" : "외지인들에게 구곡폭포로 더 잘 알려진 봉화산은 북한강에 둘러싸인 강원도 춘천시 남산면에 위치해 있다. 조선시대에 피웠던 봉수대가 정상에 있어 봉화산이라고 부른다.산의 규모면에서는 작으나 입구의 경관 및 편의시설이 좋아 주말 가족 야유회 장소로 더 없이 좋은 곳이다. 구곡폭포 일대에 수영장과 놀이터등 위락 시설이 있으며, 특히 강촌역 근방은 여름철이면 행락객 인파가 끊어지지 않고 모여든다. 통상 봉화산과 검봉을 한데 묶어 산행하는 경우가 더 많다. 검봉과 봉화산은 능선으로 바로 옆에 이어져 있다.경춘선 열차를 타고 가다 보면 북한강을 끼고 스쳐가는 산들이 여간 정겨운 게 아니다. 전국적인 교통난으로 주말 나들이가 고생길인 요즘, 연인끼리 또는 가족끼리 열차를 타고 다녀오는 산행은 한결 여유가 있어 좋다.특히 강과 더불어 빼어난 경관을 자랑하는 경춘선 부근의 산들은 그리 높지도 않아 당일 산행 코스로 적당하다. 경춘선을 즐겨 타는 이들에게 가장 인기있는 곳은 강촌이나 대성리 가평이다. 특히 강촌에는 해마다 겨울이면 신문과 TV에 단골로 나오는 폭포가 하나 있다. 얼음이 얼자마자 빙폭 등반을 하려는 산악인들이 줄을 서서 기다리는 곳, 바로 구곡폭포다. 그러나 정작 이 폭포를 품고 있는 봉화산은 사람들에게 그리 알려져 있지 않다. 강선사를 들머리로 하는 검봉과 더불어 봉화산 산행의 묘미는 능선길에 올라 굽어보는 북한강에 있다.구곡폭포는 아홉 굽이의 협곡을 돌아돌아 들어간다고 해서 붙여진 이름이라고도 하고 또, 옛날에 어떤 도사가 이곳에 오다가 아홉 개의 고개를 넘어 도착한 곳에 폭포가 있었다고 해서 붙여진 이름이라고도 한다. 최근에는 봉화산 진입로까지 자전거 도로가 개발되어 하이킹 코스로도 좋다.", + "MNTN_HG_VL" : "329", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", + "MNTN_NM" : "봉화산" }, - "longitude" : 128.5261151, - "latitude" : 37.882913799999997 + "longitude" : 127.6084018, + "latitude" : 37.7829087 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "양각산(兩角山)의 옛 이름은 금광산(金光山)이다, 북쪽 수도산 신선봉을 기점으로 남진하는 줄기의 4km 지점에 있다. 정상을 중심으로 동쪽에는 거창의 두메인 가북면 중촌리 수재 심방소가 자리하고 서쪽으로 웅양댐 위쪽에 자리한 금광(金光)마을을 품고 있다. 양각산의 양각(兩角)은 두 개의 소뿔을 의미한다. 따라서 소뿔산이라고 불러도 무방하다. 화강암지반을 갖고 높이 솟은 두 봉우리는 동서쪽으로 벼랑을 수반하고 소뿔형상의 암·수 자웅형태로 솟은 두 봉우리 가운데 복쪽 봉우리가 정상이다. 북봉의 정점이 되는 곳은 여러 형태의 바위들이 모여 있다. 그곳 중심 돌출된 바위 모양새는 남성을 상징하는 심벌처럼 생겼다. 남쪽에는 거북 모양새의 기이한 바위가 있는데 거북바위 뒷모습이 마치 여인 궁둥이처럼 생겼다. 거북바위 가까운 곳에는 바위구멍 한 개가 패여 있다. 언제 누가 양각산 정상 암반 위에 바위구멍을 파 놓았는지 알 수 없어도 성신신앙에서 비롯된 소산임을 알 수 있다. 바위구멍을 실측하여 보았더니 둘레 63cm에 길이가 15cm 된다. 이 바위구멍을 천정(天井)이라 부르는데 그 바위 구멍 속에 하늘물이 고여 있다. 북봉 주변에는 물고기 거북형상 등을 지닌 바위들이 많고 남봉에는 제단을 쌓았던 돌들로 여겨지는 막돌들을 이용하여 쌓아놓은 키 작은 돌무지탑(케언)들이 놓여 있다. 이 산의 특징은 양각이 소뿔의 의미를 담고 소와 관계된 것처럼 산이 갖는 재, 골짜기, 마을 이름들이 모두 소와 인연하여 이름이 지어졌다는 점이다. 양각산 서쪽 거창에서 김천시 대덕면으로 넘는 고개를 소머리고개 곧 우두령(牛頭嶺)이고 우두령 오르는 길에 놓은 마을은 소구시를 뜻하는 구수(口水)마을이고, 희대미산 아래 안긴 랑 우랑동(牛郞洞)이 소불알을 뜻한 마을이니 모두 소와 인연한 이름들이다. 소는 범어(梵語)로 가야(Gaya)를 뜻한다. 예날 이곳은 가야국에 속한 곳이어서 여기 ‘소’와 무관하지 만은 않다. 또한 수도산과 이어져 동쪽 가야산으로 드는 준령으로서 가야와 같은 맥락임을 알 수 있다. 양각산 예 이름인 금광산(金光山)은 고산자(古山子) 대동여지도 및「거창고읍지」에서 찾아 볼 수 있으나 금광(金光)이란 이름은 현재 양각산이 품고 있는 산아래 금광(金光)마을 이름으로 남아 있다. 금광(金光)이란 부처님을 뜻한다. 옛날 양각산 아래 금광사라 하는 절이 있었으며「거창향지」에서는 마을 근처 산에 금이 많이 묻혀 있었다는 전설에 의해 금광이라 한다고 하였다. 또 산의 반석에 항상 물이 번져 햇볕에 번쩍번쩍 금빛이 난다하여 이름 되었다고 한다. 양각산은 수도산에 인접하여 골이 깊고 옛날에는 산삼이 자생하였다고 전하며 현재에는 천마, 주치 등 한약재가 많이 자생한다. 양각산 아래 2km거리에 희대미산이 솟아 있으며 위족으로 수도산 신선봉과 연결 짓고 서쪽 거말흘산(巨末屹山, 902m)사이 우두령이 놓여 옛날에는 전략적 거점지로서 우두령은 임진왜란 때 김면(金沔)장군 지휘 아래 우척현 싸움이 있었던 곳으로 유명하다. 양각산이 품고 있는 웅양댐물은 어인동, 인삼동, 동북쪽 골짜기의 발원이다. 출처 : 「거창의 명산」 거창문화원(정태주·안수상 편저)", - "MNTN_HG_VL" : "1158", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 웅양면 산포리", - "MNTN_NM" : "양각산" + "DETAIL_INFO_DTCONT" : "구만산(九萬山)은 낙동정맥의 가지산에서 서쪽으로 뻗은 운문지맥에 솟은 산이다. 구만산은 근oacute;의 억산(962m), 육화산(670m)과 함께 숫자로 된 재미있는 이름을 가졌다. 구만산은임진왜란 당시 구만명이 이 산으로 피했다고 붙여진 이름이라고 한다. 구만산 서쪽에는 4km의ucirc;정한 구만계곡이 있다.능선에 오르면 주변으로 펼쳐진 영남알프스의 연봉들을 감상할 수 있고 능선 곳곳에서 툭툭 불거져 나온 기암들이 많아 풍광이 좋다. 또 같은 산줄기에 솟은 억산이나 육산과 연계한 산행도 할만 해 자신의 일정이나uuml;력에 따라 다양한 코스를 계획할 수 있다.교통이 편리한 밀양시 산내면 쪽을 들머리로 잡는 게 좋다.", + "MNTN_HG_VL" : "785", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 산내면, 경상북도 청도군 매전면", + "MNTN_NM" : "구만산" }, - "longitude" : 127.9610339, - "latitude" : 35.838789200000001 + "longitude" : 128.88059190000001, + "latitude" : 35.626136899999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "양성산은 문의면의 진산이다. 높지는 않으나 여러 가지 역사유적과 전설을 간직하고 있으며 문헌에 기록되어 있는 산이다. 산자락에 규모 큰 문화재단지가 있고 맞은편에는 대통령 별장이었던 청남대도 있다. 산 아래 푸른 대청호가 펼쳐져 있어 조망 또한 좋다.지도상 양성산으로 표기된 주봉은 297미터로 문의면사무소가 있는 미천리 마을 뒷봉우리다. 상봉은 378미터로 산행 들머리인 불당골로 오르는 가장 높은 봉우리다. 따라서 양성산은 주봉과 상봉으로 나누어 부를 필요가 있다. 산행은 상봉을 중심으로 이루어진다.양성산은 백제시대 일보산, 신라시대에는 연산이라 불렸다. 그 뒤에는 양승산, 양성산 등으로 불리며 지금에 이르렀다.삼국사기에 의하면 양성산 안의 일모산성은 474년에 쌓은 것으로 기록되어 있다. 신라시대 화랑 출신의 화은대사가 양성산을 보고 ‘저 산은 중이 바리를 들고 시주를 구하는 형세’라 했다. 중을 양성하기에 흠잡을 데가 없는 땅이라 감탄하고 승병 300명을 제자로 삼아 불경과 무예를 익히도록 했다.", - "MNTN_HG_VL" : "301", - "MNTN_LOCPLC_REGION_NM" : "충북 청원군 문의면", - "MNTN_NM" : "양성산" + "DETAIL_INFO_DTCONT" : "통도사 인터체인지에서 부산쪽으로 7km 떨어진 곳에 있는 산으로, 경부고속도로 위로 가설된 용연 육교를 지나 3km쯤 가면 내원사로 가는 골짜기에 다다르게 된다. 여기서부터 기암괴석과 울창한 숲이 우거져 금강산의 계곡을 방불케하는 천성산이 시작된다.", + "MNTN_HG_VL" : "920", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 하북면, 상북면, 웅상읍", + "MNTN_NM" : "천성산" }, - "longitude" : 127.48339439999999, - "latitude" : 36.512921899999988 + "longitude" : 129.11215920000001, + "latitude" : 35.420248999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "151", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", - "MNTN_NM" : "양을산" + "DETAIL_INFO_DTCONT" : "해제면 서쪽에 위치한 해발 126M되는 산으로 서해바다와 영광 낙월도,각이도 등이 보이는 곳이며 산 바로 아래가 서해안 바다여서 넓은바다가 한눈에 보인다. 과거 이 산은 동백나무가 많은 산으로 동백꽃이 필 때면 산 전체가 동백으로 만발하였다고 한다. 고려말에 고씨 성을 가진 스님이 발견했다는 동굴 2개가 마을에 있는데 동굴 하나는 물속에 용왕님에게 가는 굴이고, 다른 사나는 용왕의 아드링 육지와 바다를 드나들던 굴이었다 한다. 어느 해에 심한 가뭄이 들어 물속에 있는 용왕에게 불공을 드려 비가 오게 해달라고 빌자 갑자기 소나니가 쏟아져 가뭄을 해갈시켰다. 이때 소나기를 내린 물속의 대사는 용왕님 몰래 비를 내리게 했다하여 용왕의 노여움을 사서 학이 되어 흰구름을 타고 어디론가 사라졌다고 한다. 이 후 마을의 산에 흰 학이 많이 서식하여 산이름을 백학산이라 부른다 한다.", + "MNTN_HG_VL" : "126", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 해제면 대사리", + "MNTN_NM" : "백학산" }, - "longitude" : 126.40777780000001, - "latitude" : 34.812500000000007 + "longitude" : 126.26312969999999, + "latitude" : 35.1397324 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 여주군 금사면과 양평군 강상면의 경계에 위치한 양자산은 앵자봉과 나란한 육산으로 부근에 이웃한 산중 가장 높은 산이다. 양평군 서남쪽 남한강 건너 강상면, 강하면과 여주군 산북면의 경계 정점을 이루는 양자산은 산세가 부드럽고 수도권에 근접해 있어 오래전부터 주말산행 코스로 잘 알려진 산이다.산행은 성덕리쪽에서 오르는 것이 일반적이나 코스가 짧다. 최근 양평군에서 개척한 능선종주 코스가 있는데 양자산 정상에서 북쪽으로 뻗어나간 10km의 장쾌한 능선길이다. 이 코스는 남한강변에서부터 올라가는데 4시간, 내려오는데 3시간 30분이 걸린다. 따라서 오를 때 보다는 남한강을 조망하며 내려가는 코스가 산행의 묘미를 더 즐길수 있다.능선 초입에는 소나무가 많고 올라갈수록 싸리나무와 참나무로 덮혀 있다. 가랑잎이 쌓일대로 쌓인 깨끗한 오솔길이 심산에 들어선 느낌을 준다. 정상일때는 한키가 넘는 싸리나무와 억새가 가득하여 온화한 분위기를 자아내고 있다.", - "MNTN_HG_VL" : "712", - "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 산북면, 양평군 강상면", - "MNTN_NM" : "양자산" + "DETAIL_INFO_DTCONT" : "백두대간상에 있는 남덕유산은 거창군, 함양군 장수군의 경계선에 솟아 있다.덕유산 산행하면 으레 향적봉을 목표로 하는 것이 일반적이다. 그래서 거의 모든 등산로가 향적봉을 향해 뚫려 있으나 등산인들이 별로 찾지 않는 남덕유도 향적봉에 견줄만한 산세를 지닌 산이다.남덕유산 정상에는 맑은 참샘이 있어 겨울에는 김이 무럭무럭 나는 온수이고, 여름에는 손을 담글 수 없는 찬물이 솟아 오르는데 천지 자연의 신비한 이치는 사람으로서 말하기 어렵고 그저 그렇게 되려니하고 인정하기란 너무 오묘한 자연의 신비감이 있다.남덕유산은 3대강의 발원샘을 갖고 있다는 것이 특징이다. 임진왜란 당시 나라를 구하기 위해 왜구들과 싸웠던 덕유산 의병들이 넘나들었던 육십령은 금강(錦江)의 발원샘이며 정상 남쪽 기슭 참샘은 거룩한 논개의 충정을 담고 있는 진주 남강(南江)의 첫물길이 되며 북쪽 바른 골과 삿갓골샘은 낙동강(洛東江)의 지류 황강(黃江)의 첫물길이다.삿갈골샘에는 대피소가 있어 백두대간을 종주하는 산악인의 쉼터로 인기 있고, 동서 사면은 가을 단풍이 특히 좋다. 그리고 적설량이 많아 설경 또한 뛰어난 산이다.", + "MNTN_HG_VL" : "1507", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "남덕유산" }, - "longitude" : 127.4262073, - "latitude" : 37.4377809 + "longitude" : 127.67942360000001, + "latitude" : 35.768681399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "양천산은 진천군 문백면 평산리, 은티리, 사양리에 걸쳐 있는 산으로 말이 달리고 있는 분마형(奔馬形)을 하고 있다. 봉우리가 평원하여 반석과 같고 산중턱에는 석지(石池)가 있어 찬물이 그치지 않는 산이라 하여 냉천산(冷川山)이라 불리기도 한다.옥성교에서 그럭재마을을 지나 정상에 오르면 사양저수지가 내려다 보인다. 사미마을 쪽으로 내려오는 하산길은 경사가 급해 조심해야 한다. 임진왜란 때 주민들을 피신시킨 양천산성이 있다.", - "MNTN_HG_VL" : "350", - "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면", - "MNTN_NM" : "양천산" + "DETAIL_INFO_DTCONT" : "둔지미산은 충북 단양군 어상천면과 가곡면 사이에 아담하게 솟아오른 봉우리로 삼태산(876m)에서 남한강으로 뻗은 능선상의 가장 끄트머리에 있는 산이다.이 산이 소재한 단양에는 비경지대가 많아 신단양 8경이 등장했다. 그 중 하나가 절벽기암이 병풍을 두른 듯 비경을 이룬 영춘 북벽인데 이 보다 두배나 높은 수직절벽의 비경지대가 바로 둔지미산의 노갈봉이다.노갈봉은 노인이 갈잎으로 만든 도롱이를 쓰고 남한강물에 낚시대를 드리운 산세를 하고 있다고 해서 붙여진 것이라고 전해진다.노갈봉 정상에 이르면 멀리 북동쪽으로 태화산과 영춘, 마대산이 보이고 발 밑으로 푸른 남한강이 내려다 보인다. 무더운 여름날에는 노갈봉에서 웃통을 드러낸채 발밑에 보이는 강물로 뛰어들어 한바탕 헤엄을 치고싶은 생각이 절로든다. 그렇다고 수직절벽에서 뛰어내리는 것은 둔지미산 명예드럽힌죄로 적용될 지도 모른다. 고개를 쪼금들어 강너머를 보면 용산봉이 방끗이 웃고있다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", + "MNTN_NM" : "둔지미산" }, - "longitude" : 127.4608339, - "latitude" : 36.770334800000001 + "longitude" : 128.40333330000001, + "latitude" : 37.059166699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "789", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", - "MNTN_NM" : "어답산" + "DETAIL_INFO_DTCONT" : "문수산은 일명 청량산이라고도 하는데 이 산을 가리켜 신라 문수 보살이 산세가 청량하고 아름다워 여기에 살았으므로 처음에는 청량산으로 부르다가 다시 문수산으로 바뀌었다. 청량산은 중국의 산서성 오대현에 있는 오대산의 별명으로 5봉이 솟았고 꼭대기에는 나무가 없어 흙을 모아 놓은 대처럼 생겼고 산의 특성상 여름에 덥지 않으므로 청량산이라 했다. 지금 문수사 절 현판에 청량산으로 표기되어 있다.이 산 정상 넓은 초원에는 중계탑이 있고 서쪽의 신불산 능선과 남쪽의 천성산,대운산,동쪽의 울산시가지와 동해까지 막힘없이 조망할 수 있어서 좋다. 능선길에는 이정표가 세워져 있어서 좋고 곳곳에 쉼터가 있으며 정상 남쪽에는 유명한 문수사가 있는데 매우 아담하게 단장되어 있다. 그리고 가을에는 문수사 주변의 단풍이 절경이다.", + "MNTN_HG_VL" : "600", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시", + "MNTN_NM" : "문수산" }, - "longitude" : 128.0685852, - "latitude" : 37.584108200000003 + "longitude" : 129.21639630000001, + "latitude" : 35.534487400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "어답산(御踏山)은 한강기맥이 북쪽으로 병풍을 이루고 있고, 태기산이 동쪽으로 손에 잡힐 듯 펼쳐진 곳에 횡성댐을 품고 있는 산이다. 진한(辰韓)의 마지막 왕, 태기왕(泰岐王)과 신라 박혁거세의 전설을 품고 있는 유서 깊은 산이기도 하다. 서기 937년 경, 삼한 중에서 가장 부강했던 진한 태기왕은 신라에 대패한 후 약간의 근위병을 데리고 덕고산으로 들어가던 중 이 산에 올랐다. 그래서 왕이 올랐다는 뜻으로 '어답산(御踏山)'이라는 이름이 붙었다. 설욕을 꿈꾸던 태기왕은 덕고산(지금의 태기산)에 성을 쌓고 화전을 개간, 부하를 훈련시켰다. 그러나 신라에 탐지되어 박혁거세가 지휘하는 신라군의 원정으로 끝내 한을 풀지 못하고 덕고산의 넋이 되었다. 원정군을 지휘하던 박혁거세가 이산에 올랐다고 해서 '어답산'이라 불린다는 설도 있다. 한 때는 '한국의 오지 다섯'에 꼽히던 병지방 계곡에 포장도로가 놓이고, 삼거리에 온천이 개발되고 삼거현(三巨峴)에서 갑천까지 도로가 확포장 되어 숨겨졌던 어답산이 널리 알려지게 됐다.", - "MNTN_HG_VL" : "789", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", - "MNTN_NM" : "어답산" + "DETAIL_INFO_DTCONT" : "명성산은 서울에서 동북으로 84Km, 운천에서 약 4Km 거리에 위치해 있다. 산자락에 산정호수를 끼고 있어 등산과 호수의 정취를 만끽 할 수 있는 산이다.일명 '울음산'이라 불리기도 하는데 거기에는 안타까운 전설이 전해 내려오고 있다. 신라의 마지막 왕자인 마의태자가 망국의 슬픔으로 이 산에서 통곡을 하자 산도 따라 울었다 한다. 나라를 잃은 슬픔을 산도 알았을까. 그런 연유로 '울 명' '소리 성'자를 붙여 명성산으로 불리게 되었다는 것이다.산전체가 암벽으로 이루어져 산세가 당당하고 가파르며 가을이면 억새풀이 장관을 이룬다. 암릉과 암벽이 같이 형성된 산이라서 사시사철 다양한 풍경을 연출해 등산객들로 하여금 철따라 다른 느낌을 느끼게 해 준다. 정상은 민등봉이나 전망이 매우 좋으며, 남쪽으로 이어진 12봉 능선의 모습이 장쾌하다. 능선에서 우거진 억새풀밭을 오르락내리락 하는 사이에 지루한 줄 모르고 걷게 된다.", + "MNTN_HG_VL" : "922", + "MNTN_LOCPLC_REGION_NM" : "강원도 철원군 갈말읍, 경기도 포천시 영북면ㆍ이동면", + "MNTN_NM" : "명성산" }, - "longitude" : 128.0685852, - "latitude" : 37.584108200000003 + "longitude" : 127.3377243, + "latitude" : 38.1069751 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "어답산은 삼거리저수지 동북쪽으로 병풍을 두른 듯 솟아 있으며 선바위, 어답산 장송, 약물탕 등의 볼거리와 정상에서의 끝간 데 없이 펼쳐지는 시야 아래로 잔잔한 횡성호와 삼거리저수지가 누워있는 경관을 감상할 수 있고, 어답산 정상에서 북쪽 200m 삼각점으로 향하는 곳에 낙수대에서는 정상과는 다르게 멋진 경관을 감상할 수 있다.", - "MNTN_HG_VL" : "789", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", - "MNTN_NM" : "어답산" + "DETAIL_INFO_DTCONT" : "가곡면 풍곡리 덕풍계곡에 자리잡은 중봉산은 사람들에게 덜 알려진 만큼 훼손도 덜 된 곳이다. 그래서 호젓한 주말산행을 원하는 사람 몇 명이 뜻을 모아 함께 찾아가기에 좋다. 태백에서도 한참을 더 가서야 만날 수 있는 이 산은 시원한 덕풍계곡의 물소리가 능선길을 오르는 동안 내내 따라올 만큼 한적하다. 또한 나이를 짐작하기 어려울 정도로 밑둥이 굵은 아름드리 노송도 몇 그루 만날 수 있다.그리고 참나무와 물푸레나무 등이 울창하게 늘어선 산에서 새소리와 물소리를 들으며 함께 간 사람들과 두런두런 얘기를 나누다 보면 세속의 가면을 벗어 던진 자신을 발견할 수 있을 것이다. 한편 정상에서는 남동쪽을 조망할 수 있는데, 이곳에 한국 전쟁 당시 참호로 사용되었을 웅덩이가 남아 있어 민족의 비극을 떠올리게 한다.", + "MNTN_HG_VL" : "740", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "중봉산" }, - "longitude" : 128.0685852, - "latitude" : 37.584108200000003 + "longitude" : 129.16957690000001, + "latitude" : 37.107853800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "어래산이 있는 단양군 영춘면 의풍리는 남한강의 옥동천 지류인 남대천 상류에 자리해 있으며 `정감록'을 믿고 찾아 들어온 조상들의 후예들이 터전으로 한때 외진곳을 전전하는 도박꾼들의 집합장소로 악명 높았던 곳이다.분지를 이룬 의풍리를 두고 동쪽에는 어래산이, 서쪽으로는 형제봉이 솟아 있어 남쪽에서 흘러내려온 남대천이 북쪽의 옥동천으로 빠지고 있다. 그래서 물이 흘러나가는 북쪽을 제외하고는 모두 산으로 둘러싸여 있어 외지에서 이곳으로 들어서려면 고개를 넘어야 한다. 때문에 일단 어래산 산행에 앞서 마을 진입 자체가 문제인데다 산행코스 역시 만만치 않다.이처럼 접근이 어렵다는 것은 사람들의 손때를 타지 않았다는 반증이다. 산 곳곳에 혼을 빼앗길 만큼 청정한 계곡이 흐르고 광활한 낙엽송 조림지대가 있어 수월치 않은 산행의 피로를 씻어 줄 것이다.", - "MNTN_HG_VL" : "1064", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "어래산" + "DETAIL_INFO_DTCONT" : "용문산, 백운봉, 도일봉과 더불어 웅장한 절경을 이루어 경기의 금강산이라 불리기도 하는 중원산은 경기 양평 용문면과 단월면의 경계에 있는 산이다.주능선의 왼쪽에 용계계곡과 오른쪽에 중원폭포, 중원계곡을 끼고 있는데, 중원폭포 계곡은 머루와 달래밭으로 유명하며, 봄이면 철쭉·금낭화가 피고, 가을이면 약초와 야생과일이 많이 난다. 계곡사이로는 기암이 늘어서있고 울창한 숲 사이로 맑은물이 흘러내려온다. 계곡, 암봉과 함께 중원산에서 빼놓을 수 없는 것은 머루, 다래밭이다.산행은 중원리에 있는 주차장에서부터 시작한다. 계곡을 따라 중원폭포와 치마폭포를 지나 갈림길에서 왼쪽길로 작은 계곡을 지난다. 너들고개가 나오면 왼쪽 능선으로 정상에 오른다. 정상에 서면 동쪽으로 도일봉, 서쪽으로 용문산이 가깝게 보인다.", + "MNTN_HG_VL" : "800", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", + "MNTN_NM" : "중원산" }, - "longitude" : 128.65534959999999, - "latitude" : 37.064015800000007 + "longitude" : 127.60196449999999, + "latitude" : 37.559491399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "어룡산은 경북 8경인 진남교반을 사이에 두고 오정산(805m)과 마주보고 있는 산이다. 오정산 쪽의 고모산성과 함께 이 산의 고부산성이 옛 길인 `토끼비리'를 지키고 있다.영강가에 솟은 미봉 어룡산은 작은 것이 아름답다는 것을 깨닫게 하는 산이다. 문경읍을 거쳐 20분 정도 달리면 강변을 따라 병풍을 둘러친 듯 기암괴석이 보이는 곳이 있는데 여기가 바로 유명한 경북팔경 중의 제1경으로 일컫는 진남교반이다. 경북 도민이 제 1경으로 꼽을 만큼 절경지인 영강 진남교 옆에 솟아있는 어룡산은 산속으로 들어서면 넋을 잃기 마련이다.울창한 숲과 영강과 어우러진 산세가 절경이기때문이다.이 진남교반을 끼고있는 어룡산은 많은 전설과 얘기가 전해오고 있으며, 고모산성과 돌고개, 성황당, 그리고 영남대로의 옛 모습을 그대로 잘 간직하고 있는 관갑천(토천,토끼비리)이 있고 진남유원지와 휴게소에는 지나는 사람들의 발길이 끊이질 않는다.작은 암봉이 있는 정상에 서면 보면 주흘산과 백화산이 눈앞에 있으며 멀리 산군들이 첩첩이 펼쳐 보인다. 어룡산은 주변의 풍광이 수려하고 볼거리와 즐길거리가 많으며 아래 영강에는 여름철 강수욕과 피서지로 이름나 있는 곳이다. 문경읍에는 보양천인 문경온천이 있다. 봄, 여름 산행지로 인기가 높은 곳이다. 또 황티기국, 부곡숫굴, 부곡암굴 등 동굴이 산 곳곳에 산재해 있다.", - "MNTN_HG_VL" : "617", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 마성면", - "MNTN_NM" : "어룡산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "271", + "MNTN_LOCPLC_REGION_NM" : "전라북도 전주", + "MNTN_NM" : "기린봉" }, - "longitude" : 128.1147469, - "latitude" : 36.6442786 + "longitude" : 127.1736111, + "latitude" : 35.809722200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군과 양평군의 경계를 이루고 있는 어비산은 유명산 계곡을 사이에 두고 유명산의 동쪽에 솟아 있는 산이다. 어비산이란 이름은 옛부터 홍수 때 물고기가 산을 뛰어 넘는다고 하여 붙여진 이름이라 하는데, 주민들은 건너편의 유명산과 더불어 설악면과 옥천면을 경계한 산이라하여 대부산이라고도 부른다 한다.용문산에서 서쪽으로 뻗어내린 능선이 어비산을 이루고, 어비산에서 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이룬 계곡이 어비계곡이다. 이 어비계곡 또한 유명계곡에 못지 않을 정도로 아름다운 계곡이다. 큰 바위와 이따금 나타는 청정한 푸른소는 어비계곡의 자랑거리라고 할 수 있다. 계곡까지 급사면을 이룬 산록은 울창한 숲으로 뒤덮이고 숲아래 바위들은 푸른이끼옷을 입고 있고 그 아래로 흐르는 계류는 때로는 비취빛으로 바뀐다.길을 버리고 계곡을 따라 내려가는 맛이 또한 시원하다. 그러나 유명계곡처럼 완연한 협곡을 이룬 것은 아니고 길이도 유명계곡 보다는 짧은 편이어서 아쉽기는 하지만 경기도내의 아름다운 계곡중의 하나임은 분명하다. 산행은 유명산 입구인 가일리에서 오르는 코스와 대일마을에서 시작하는 방법이 있다.", - "MNTN_HG_VL" : "726", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", - "MNTN_NM" : "어비산" + "DETAIL_INFO_DTCONT" : "이 산은 백제, 신라, 고구려가 각축을 벌이던 토성으로 옛 문헌에는\"노성산은 음죽현의 주산이며 영산이다.\"라 하고 전설에 의하면 노성산, 마국산, 설성산 사이에 용맹한 말 한 마리가 나타나니 세산에 주둔한 장수가 서로 차지하려다 다툼을 벌였는데 이기는 순서대로 말 머리, 몸통, 꼬리를 차지하기로 했다고 한다. 노성산 장수가 말머리를 몸통은 마국산 장수가 설성산 장수가 꼬리를 차지하여 노성산 정상바위를 말머리 바위라 하며 산의 높이는 310m로 낮으나 산 정상에서 보면 충북 감곡, 안성, 일죽, 여주, 양평까지 보인다.", + "MNTN_HG_VL" : "310", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 설성면", + "MNTN_NM" : "노성산" }, - "longitude" : 127.5186384, - "latitude" : 37.589764000000002 + "longitude" : 127.5040697, + "latitude" : 37.127014500000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "엄광산은 높이 503.9m로 부산광역시진구에서 제법 높은 산에 속하며, 동남으로 구봉산에 이어져 있는 산이다. 이 산은 고원견산이라 불리기도 하는데 이 명칭은\"\"산이 높아 멀리까지 볼 수 있다.\"\"는 뜻으로 일제시대부터 불려진 이름이다. 엄광산은 얼마 전까지 고원견산으로 불리던 산인데\"\"부산광역시을 가꾸는 모임\"\"이 지난 95년 4월에 엄광산(嚴光山)이라는 이름을 찾아주고 정상표지석을 세웠다. 이 산의 정상조망 역시 뛰어나다. 동래부지 산천조에 보면 엄광산의 산봉이라는 기록으로 보아 엄광산으로 통해졌던 것이라 보아진다.이 산 정상에는 부산광역시 전체가 한눈에 들어온다. 동구, 서구, 사하구, 북구, 해운대구 일부도 한눈에 들어와 부산광역시의 숨소리가 그대로 느끼어진다. 안산암질의 암석으로 구성된 엄광산(고원견산)은 산정이 대체로 평탄하며, 산 정 부근에는 잔 자갈들로 된 애추가 발달한다. 산록은 비교적 가파른 편이다. 금정산맥의 말단부에 해당되며, 남서쪽으로 구덕산,나몽쪽으 로는 구봉산으로 연결된다. 엄광산은 부산광역시만의 전망이 좋기로 이름 나 있고 산록에는 산림이 울창하여 자연공원으로서 부산광역시민의 사랑을 받고 있다.", - "MNTN_HG_VL" : "504", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 서구 동대신동, 부산광역시 진구 개금동", - "MNTN_NM" : "엄광산(고원견산)" + "DETAIL_INFO_DTCONT" : "경기도 광주시 남쪽 끝에 자리한 도척면은 백제 온조왕이 한강유역에 도읍을 정하려고 이곳을 탐사할 때 자로 재고 또 쟀다고 해서 도척(都尺)이란 이름이 붙었다고 한다. 이러한 도척면 북서쪽을 병풍처럼 에워싸고 있는 산이 바로 태화산이다. 조선 영조 때의 고지도와 광주부읍지에는 대해산(大海山), 해동지도에는 대화산(大華山)으로 기록되어 있다.경기 남부에서 아름답기로 이름 난 태화산은 관바위, 수리바위, 병풍바위, 상사바위, 조춤바위 등 멋진 다섯 개의 바위들이 늘어선 바우산골과 조망 좋은 정상 그리고 그 바로 아래쪽의 백련암, 김병기 대감이 대화약수를 마시고 병이 나은 기념으로 썼다는 ‘大華水石’ 암각 등 볼거리 또한 풍성하다.태화산은 봄이 다 가도록 흐드러지게 피어나는 진달래와 철쭉이 특징이다. 내세울 만한 높이는 아니지만 전망 좋은 바위가 곳곳에 자리하고, 울창하게 우거진 숲은 산림욕을 즐기기에 그만이다.", + "MNTN_HG_VL" : "641", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 도척면", + "MNTN_NM" : "태화산" }, - "longitude" : 129.02056450000001, - "latitude" : 35.137197399999998 + "longitude" : 127.2886111, + "latitude" : 37.291944399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "궐리사 부터 물향기 수목원을 거쳐 지곳동과 가장동까지 노선이이어진다. 고도가 낮으며 지세도 험하지 않다.", - "MNTN_HG_VL" : "86", - "MNTN_LOCPLC_REGION_NM" : "경기도 오산시 신장동", - "MNTN_NM" : "여계산" + "DETAIL_INFO_DTCONT" : "둔덕산은 문경팔경의 하나인 용추를 품고 운강 이강년 선생의 탄생설화가 얽힌 산이다. 백두대간이 조항산을 지나면서 동쪽으로 가지를 쳐 만들어진 둔덕산은 멋진 경승지를 품고 있음에도 근처의 대야산이나 희양산의 명성에 가려져 아직까지 호젓한 산행을 즐길 수 있는 문경의 숨은 명산이다.둔덕산이 있는 가은읍 완장리 자락에는 이 산의 자랑거리가 집중되어 있는데 괴선의 외선유동에 비견되는 용추를 품고 있는 내선유동계곡과 이강년 선생의 생가터, 조선조 이재 선생의 후학들이 그를 기려 세웠다는 학천정 등 유서 깊은 정자가 그것이다. 따라서 둔덕산 산행은 볼거리가 풍부한 완장리를 기점으로 원점회귀 하는 코스를 가장 추천할 만하다.둔덕산은 국운이 위태롭던 한 말에 일본 침략자에 항거 경상도, 충청도, 강원도에 걸쳐 13년간 오로지 의병대장으로서 활동하고 순국한 전국도창의대장 운강 이강년 선생 탄생과 관련 있는데, 이강년 선생이 태어나기 3일전부터 둔덕산이 ‘웅웅’ 소리를 내며 울었다고 한다. 당시 사람들은 둔덕산이 우는 것은 처음 있는 일이라고 하며 신기해했으나 운강 선생이 태어나자 울음을 그쳤다고 한다.", + "MNTN_HG_VL" : "970", + "MNTN_LOCPLC_REGION_NM" : "경북 문경시 가은읍, 농암면", + "MNTN_NM" : "둔덕산" }, - "longitude" : 127.0386111, - "latitude" : 37.173611100000002 + "longitude" : 127.9733714, + "latitude" : 36.651080700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "진도읍에서 임회면 용호마을에 이르면 단정한 모습의 선녀를 닮은 산이 보인다. 여귀산은 마치 단정하게 차려입은 선녀가 가야금을 타는 형상이라 하여 풍수지리가들은 옥녀탄금형의 산이라고 한다. 여기서 옥녀는 가야금을 타는 선녀를 지칭하는데, 선녀는 곧 귀한 여자이므로 산 이름이 여귀산이 된 걸로 추정된다.여귀산은 두 얼굴을 가진 산이다. 정상은 제법 오르기가 험난한 바위지대로 이뤄진 반면 정상을 중심으로 좌우로 흘러내린 지능선들은 부드러운 산세를 이루고 있기 때문이다. 밖에서 바라본 여귀산은 어느 방향이든 쉽게 오를 수 있을 것으로 보이지만 막상 산에 들어서면 수림이 빽빽해 기존 등산로를 벗어나서는 산행이 어렵다.그러나 일단 주능선이나 정상에 오르면 남서쪽으로 시원하게 펼쳐진 다도해국립공원을 비롯해 바다 풍경이 황홀하게 펼쳐진다. 특히 바다를 주홍빛으로 물들이는 일출과 낙조가 일품이다.", - "MNTN_HG_VL" : "457", - "MNTN_LOCPLC_REGION_NM" : "전남 진도군", - "MNTN_NM" : "여귀산" + "DETAIL_INFO_DTCONT" : "재약산은 영남 알프스 산군중의 하나로 영남 밀양 청도 일대에 위치해 있다. 해발 1,000미터 이상의 준봉들로 이루어진 재약산(사자봉)은 산세가 부드러우면서도 정상 일대에는 거대한 암벽을 갖추고 있다.125만평에 이르는 재약산 동쪽의 사자평 고원은 광할한 분지가 온통 억새풀로 뒤덮혀 있다. 우리나라에서 가장 넓은 억새벌판이다. 억새풀이 밀집해 자라는 곳만도 5만평에 이른다. 재약산은 해발 1,108m의 수미봉과 1,189m의 사자봉으로 이루어져 있다. 사자평고원은 두 봉우리 사이의 해발 800m 지점부터 완만한 타원형의 언덕들로 이어진다.사자평 억새는 어른 가슴정도 밖에 안 올 정도로 키가 작다.산아래 밭둑이나 길가의 억새에 비하면 절반밖에 되지 않는다. 잎새도 가늘고 투박하다. 꽃이삭은 거친 산정의 바람에 닳아서인지 뭉툭하고 짧다. 그래서 가는 바람에는 이삭 끝의 낭창거림을 보기 어렵다.", + "MNTN_HG_VL" : "1119", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면ㆍ산내면, 울산광역시 울주군 상북면", + "MNTN_NM" : "재약산" }, - "longitude" : 126.2297222, - "latitude" : 34.390555599999999 + "longitude" : 128.9793348, + "latitude" : 35.547564700000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "귀한 여자란 뜻을 가진 여귀산은 북동쪽의 첨찰산과 직선거리로 약 12.5km거리를 두고 능선이 이어져 있으며, 등산로에 아기자기한 바위들이 늘어서 있어 약간의 스릴과 긴장감을 느끼게 한다.산명에 걸맞게 자태가 매우 예쁘고 아름다운 산이기도 하다. 주능선은 동서로 뻗어 있는데 319봉을 머리로 하고 370봉을 어깨, 작은여귀봉과 큰여귀봉은 풍만한 가슴으로, 국립남도국악원 뒤 안부는 허리로, 송월과 중만쪽에 다리를 뻗고 누워 있는 아름다운 여인같기도 한 산이다. 이 능선에는 솔밭지대,진달래지대,바위지대,억새지대,대밭지대 등으로 다양하게 이어나가며 시종 남해를 바라보면서 걸을 수 있는 능선길이 매우 낭만적이다. 정상에 오르면 사방은 남해와 황해의 망망대해로 수평선을 이루고 다도해 해상국립공원의 수많은 섬들이 별빛같이 반짝인다.", - "MNTN_HG_VL" : "457", - "MNTN_LOCPLC_REGION_NM" : "전라남도 진도군 임회면", - "MNTN_NM" : "여귀산" + "DETAIL_INFO_DTCONT" : "촉새봉(십자봉,985m)에서 남쪽으로 강원도와 충청북도를 가르며 뻗어 내린 능선이 옥녀봉에 이르면 동쪽과 서쪽으로 갈라진다.옥녀봉에서 동쪽으로 이어지는 능선은 시루봉(734m), 비지재, 강승갱이재를 지나 오청산(655m)으로 이어지고, 서쪽으로 가지를 친 능선상의 최고봉이 갈미봉이다. 갈미봉에서 남서쪽으로 능선이 휘어지며 세가닥으로 능선이 갈라져, 목계의 제내편봉(288m), 오량리의 묵봉산(490m)과 청계봉(390m)을 일으키고 그 여맥을 남한강 물 속으로 잠긴다.갈미봉 정상은 약 20여평의 공터로 둘레를 참나무와 잡목으로 울타리를 친 듯 둘러싸여 있는 게 흠이다.", + "MNTN_HG_VL" : "595", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 충주시", + "MNTN_NM" : "갈미봉" }, - "longitude" : 126.2297222, - "latitude" : 34.390555599999999 + "longitude" : 127.9080556, + "latitude" : 37.167222199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "여분산은 특징이 없는 그저 평범한 산이다. 그러나 정상에서의 조망은 사방이 툭트여서 막힘없이 아주 좋다. 남으로 호남정맥의 용추봉(龍秋峰)과 무등산, 동으로 지리산의 연봉들이 아스라히 마루금을 이룬다. 서로는 용추봉과 세자봉(世子峰)이 눈앞에 다가선다.때로 조용한 길을 걸으면서 주위의 생명들과 동화될 때 느껴지는 기쁨이 좋은 사람들과 만날 때의 그것보다 더 클 경우가 있다. 구림면에 위치한 여분산은 이런 기분을 최고조로 경험할 수 있게 해준다. 인적이 드물어 길이 희미한 곳도 간간이 있는 이 산은 떨어져 쌓였다가 점점 썩어가며 제 나무의 거름이 되는 잎사귀들과 그 사이를 자유롭게 오가는 산짐승들을 보며 오르는 산행을 통해 침착하고 한결 순해진 마음을 갖게 한다.", - "MNTN_HG_VL" : "774", - "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 구림면", - "MNTN_NM" : "여분산" + "DETAIL_INFO_DTCONT" : "성주산은 오서산과 함께 보령을 상징하는 명산으로 예로부터 성인, 선인이 많이 살았다 하여 성주산이라 부르고 있다. 성주산에는 질 좋은 소나무를 비롯, 느티나무, 굴참나무, 졸참나무, 때죽나무, 고로쇠나무 등이 자생하고 있는데 한낮에도 컴컴할 정도로 울창한 숲을 이루고 있다.또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다. 특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다.성주산 일대에 모란형의 명당8개소(성주8묘)가 있었는데 그중 하나가 이곳에 감추어져 있다하여 화장골이란 이름이 붙여졌다. 지금도 명당을 찾으려는 이들의 발길이 잦은 곳이기도 하다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.소요 시간 :150분최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 심연동 계곡,삼림욕장,잔디광장, 전망대성주휴양림의 자랑거리가 되고 있는 숲속의 집 통나무 방갈로는 여름철뿐만 아니라 단풍이 짙어가는 가을철이나 흰눈에 싸인 겨울철에도 더할나위 없는 좋은 휴양시설로 각광받고 있다. 휴양림을 찾는 이들의 발길은 아무래도 여름철에 절정을 이룬다. 이때에는 이동도서관이 마련돼 이용자는 얼마든지 책을 대여해 시원한 계곡물에 발을 담그고, 혹은 삼림욕을 하면서 독서 삼매경에 빠질 수 있다.숲길 명소 : 휴양림 입구에서 정상 쪽으로 5백미터 오르면 휴양림을 만날 수 있고, 심연동 계곡쪽에도 휴양림 공간이 마련되어 있다. 또한 이곳에는 성주산 계곡의 맑은 물이 흐르고 있어 더할 나위 없는 휴양지의 조건을 갖추고 있다.특히 이 일대의 계곡은 예로부터 화장골이라 하여 그 수려함이 잘 알려진 곳이다. 4킬로미터 이르는 우거진 숲과 맑은 물이 감도는 비경은 가히 선경을 연상케 하면서 자연미의 극치를 이룬다.성주산 휴양림에서 정상까지 올라 산 뒤편으로 내려가도 심연동 계곡과 연결되어 있다. 예부터 깊은 골짜기가 있는 마을이라 하여 심연동이라 이름지어진 것처럼 골과 골 사이에 흘러내리는 계곡이 깊고 수려하다.휴양을 위한 각종 편의시설이 설치된 중앙의 코스 외에 외곽으로 따로 등산객을 위한 등산로가 성주산 정상까지 나 있다. 봄에는 만발한 온갖 꽃들의 안내를 받으며, 여름에는 신록의 축복 속에서 삼림욕을 하고, 가을엔 수려한 단풍에 취한 채, 겨울엔 통나무 방갈로에서 아름다운 설경을 음미할 수 있는 곳이 바로 성주산 자연휴양림이다.", + "MNTN_HG_VL" : "512", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "성주산" }, - "longitude" : 127.0565735, - "latitude" : 35.483787999999997 + "longitude" : 126.6788646, + "latitude" : 36.365286699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "여항산은 함안의 진산이다. 진산은 보통 삶터의 북쪽에 자리를 잡는데 여항산은 남쪽에 자리잡고 있다. 이에 그 허점을 풍수지리의 비보책으로 보완, 산 이름을 물과 관련있는 여항산으로 지었다고 한다. 이름을 지은이는 1583년(선조 16년) 함주도호부사로 함안에 부임한 정구(鄭逑)라는 인물이다. ‘여항’이란 산 이름에는 삶터의 균형을 잡아 평화롭게 살고자 하는 염원이 담겨 있다.여항산은 꽃이나 단풍으로 이름난 산은 아니다. 근처에 이름 난 관광지가 있어 덤으로 유명세를 타는 산도 아니다. 그저 산과 들판 사이에 솟았다. 그러나 산은 정상 부근의 옹골찬 기세와 능선의 부드러움이 어울려 여느 명산 못지않다. 마치 세상 명리를 뿌리치고 초야에 묻혀 사는 지조 높은 옛 선비 같은 산이다.여항산 능선을 타고 남쪽으로 1시간 40분 거리에 서북산이 있다. 낙남정맥 산줄기인 여항산과 서북산은 한국전쟁 당시 낙동강 방어선이었으며 북한군 6사단과 미 25사단이 사투를 벌였던 곳이다. 미군들은 ‘갓 뎀’이라며 치를 떨었는데 이후 여항산과 서북산 일대를 갓데미산으로도 부른다고 한다. 서북산 정상에는 6.25 전적비가 있으며 당시 전투에서 전사한 미군 중대장의 아들 리처드 티몬스가 1995년 주한 미군으로 부임해 와 세웠다고 한다.", - "MNTN_HG_VL" : "770", - "MNTN_LOCPLC_REGION_NM" : "경남 함안군 여항면, 마산시 진전면", - "MNTN_NM" : "여항산" + "DETAIL_INFO_DTCONT" : "음지 마을의 주산으로 옛날에 장군이 암굴에서 철마를 타고 나왔다는 전설이 있어 불려진 산으로 화악산 줄기의 대표적인 명산이다. 정상에는 아직도 성터(철마산성)가 남아 있고 주위에는 높고 험한 산줄기가 이어져 천혜의 요새를 이루고 있다.남북으로 뻗은 산줄기를 기준으로 서쪽은 산세가 급경사를 이루어 이렇다 할 계곡도 없지만, 상대적으로 경사가 완만한 동쪽 일원에는 비금계곡이라는 남양주시 최고의 계곡과 지계곡들이 여럿 있어 여름 피서철 산행지로 이름 높다.또한 동남서 방향에 돌을 쌓았으며 불암이라는 절벽에는 장군이 나왔다는 바위굴이 있다. 그 바위굴은 장군이 말을 매어 두고 사육했던 곳으로 암반의 곳곳에 장군의 흔적이 역력히 남아 잇다. 또한 전설에 의하면 바위굴은 신라의 선인 옥단춘의 출생지로서 고려 초 보조국사가 그 자리에 한선사를 건립했다는 기록이 남아 있다.", + "MNTN_HG_VL" : "627", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "철마산" }, - "longitude" : 128.40670359999999, - "latitude" : 35.196818100000002 + "longitude" : 128.69147169999999, + "latitude" : 35.593220600000002 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "339", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주", - "MNTN_NM" : "연미산" + "MNTN_HG_VL" : "355", + "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 용당동,조례동", + "MNTN_NM" : "봉화산" }, - "longitude" : 127.1183333, - "latitude" : 36.484999999999999 + "longitude" : 127.5166667, + "latitude" : 34.966666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "연석산은 전북 진안군과 완주군의 경계를 이루며 운장산과 이웃해 있는 산이다. 오지에 숨겨진 산으로 맑은 물과 울창한 숲이 자연 그대로 잘 보존되었다.산행은 정겨운 농촌 풍경이 물씬 풍기는 정수암마을에서 시작되는데 이곳에서 연석산 정상으로 가는 산길 초입은 완만한 묵밭사이로 억새가 군락을 이루고 있다. 연석산 정상은 민둥봉이나 북쪽으로 뻗어나간 능선에는 병풍바위를 비롯하여 빼어난 암봉이 우뚝우뚝 서 있다. 동쪽으로는 덕유능선이 다가오듯 어른거리고, 남쪽으로는 진안 마이산이 말귀처럼 쫑긋하게 솟아있다. 서편 사봉리로 흘러내린 연골계곡 단풍이 아름다운 지대이다.", - "MNTN_HG_VL" : "928", - "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군", - "MNTN_NM" : "연석산" + "DETAIL_INFO_DTCONT" : "미녀봉의 본 이름은 문재산(文載山)이다. 그러나 미인이 머리를 풀고 누워있는 형상이라 하여 미녀봉(美女峰)으로 널리 불린다. 미녀봉에는 두 가지 전설이 전한다. 옛날 바다였던 이곳에 장군이 탄 나룻배가 표류하자 옥황상제가 딸을 지상으로 보내 구하고자 했다. 장군은 딸과 사랑하게 되었고 그런 딸을 보고 노한 옥황상제는 너희 둘은 영원히 산으로 누워 있으라는 형벌을 내렸다고 한다. 또 다른 전설은 예쁜oacute;녀가 어머니 병을 고치기 위해 미녀봉에만 있는 약초를 캐려 했는데 뱀에 물려 죽자 불쌍히 여긴 산신이 죽은oacute;녀의 모습대로 만든 산이 미녀봉이라 한다. 88고속도로 인터uuml;인지에서 바라보는 미녀봉은 참으로 감탄스럽기 그지없다. 잘 다듬어진 이마, 세련된 화장술로 그려낸 듯한 눈썹, 오똑한 코, 힘겨워 헤 벌리고 있는 입, 봉긋 달덩이oacute;럼 솟아오른 젖가슴, 아이를 잉태한 듯한 볼록한 배 등 산봉우리들이 모여 하나의 아름답고 고운 여인 형상을 빚고 있다. 미녀가 뻗은 발을 무뚝뚝하게 내려다보는 두무산, 미녀 무릎 옆에 앉아 명상에 잠긴 오도산, 미녀 머리 위로 날아오르는 비계산, 멀리서 지켜보는 근엄한 의상봉, 우뚝 서서 호위하는 늠름한 장군봉 등이 주위를 완벽하게 장식해 미녀봉을 눈부시게 만든다.", + "MNTN_HG_VL" : "930", + "MNTN_LOCPLC_REGION_NM" : "경남 거창군 가조면, 합천군 봉산면", + "MNTN_NM" : "미녀봉(숙성산)" }, - "longitude" : 127.3316667, - "latitude" : 35.9072222 + "longitude" : 128.0521684, + "latitude" : 35.682698299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "연엽산은 꼭대기에서부터 사방으로 능선이 길게 여러 갈래로 뻗어있는데, 산세도 그리 험하지 않고 찾는 이도 적어 원시림이 그대로 보존된 숲과 계곡이 비경을 이루고 있다. 계곡에는 울창한 숲 사이로 기암절벽이 이어지고 크고 작은 연못이 곳곳에 흩어져 있어 등산과 함께 계곡의 경치를 즐길 수 있는 산이다.강원대학교 연습림이기도 한 연엽산은 수백년 된 노송들이 빽빽하고 나무들이 우거져 있다. 정상은 무인대피소와 아름드리 잡목이 우거져 하늘만 보인며 능선에는 철쭉이 많다.※ 강원대학교 연습림지역으로 일반인의 출입을 통제하고 있으므로 입산이 절대로 안됩니다.", - "MNTN_HG_VL" : "775", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천시 북방면", - "MNTN_NM" : "연엽산" + "DETAIL_INFO_DTCONT" : "양주군 백석면과의 사이에 있는 해발 622미터의 아담한 높이의 산으로, 고찰인 보광사가 있기도 하다.평평한 산 정상에서 바라보면 북으로 파주군과 양주군의 나지막한 산들이 건너다 보이고, 동쪽으로 죽 늘어선 불국산, 사패산, 도봉산 암봉, 남쪽으로 북한산 백운대의 당당한 모습이 보인다.산행은 보광사에서 시작하여 도솔암을 오른 후 헬기장을 거쳐 정상에 오른 후, 서릉을 거쳐 보광사로 하산하는 것이 좋다.", + "MNTN_HG_VL" : "622", + "MNTN_LOCPLC_REGION_NM" : "경기도 파주시 광탄면, 양주시 석현면", + "MNTN_NM" : "계명산" }, - "longitude" : 127.8230556, - "latitude" : 37.798055599999998 + "longitude" : 126.9333333, + "latitude" : 37.745555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "연인산은 경기도 제2의 고봉 명지산의 남녘 능선을 잇는 산이다. 가평군 제1의 휴양지인 용추계곡 최상류에 자리하고 있다.연인산은 우목봉과 월출산으로 불리어왔으나 가평군이 지명을 공모하여 1999년 3월 ‘사랑이 이루어지는 곳’이란 뜻에서 이 산 이름을 연인산으로 바꾸었다. 그리고 연인산 서남쪽의 전패봉(906봉)은 우정봉, 전패고개는 우정고개, 동남쪽의 879봉은 장수봉으로 고쳤다. 또한 연인산에서 뻗은 각 능선에 우정, 연인, 장수, 청풍 등의 이름을 붙였다.연인산은 수도권에서 승용차로 2시간 이내 거리이면서 아름다운 비경과 명소들이 많은 산이다. 그중 제일비경은 용추구곡으로 연인산의 발원지이다. 용추구곡은 연인산의 부드럽고 완만한 지능선을 ‘ㄷ자’ 형태로 감싸고 있다. 연인상 정상에 오르면 사방의 조망이 막힘 없이 시원하다.가평군은 1995년 연인산 능선에 철쭉이 자생하는 것이 확인한 후 이곳을 관광지로 보존하기 위하여 1999년 5월 철쭉제를 개최하고 해마다 열고 있다. 연인산 철쭉은 5월 중순경에 만개한다.", - "MNTN_HG_VL" : "1068", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍ㆍ북면ㆍ하면", - "MNTN_NM" : "연인산" + "DETAIL_INFO_DTCONT" : "목포시와 다도해를 한눈에 굽어볼 수 있는 높이 228m의 목포 뒷산으로, 기암절벽이 첩첩하여 '호남의 개골'이라고도 한다. 산은 비록 해발고도가 낮으나 산정은 매우 날카롭고 층층기암과 절벽이 많아 경치가 수려하다. 이엉으로 바위 전체를 덮어서 마치 아군의 군량미처럼 꾸며 왜군이 감히 넘보지 못하게 하였다는 설화가 전해오는 노적봉을 비롯하여 해발 228m의 일등바위와 이등바위로 나뉘어져 있다.산정에서는 목포시와 다도해를 한눈에 바라볼 수 있고 그 사이를 오고 가는 크고 작은 선박들의 모습이 마치 한포그이 동양화를 연상케 한다. 동쪽 산꼬리에는 기상관측소 ·시청 ·법원 등 관공서가 있고, 산 중턱에는 유달사 ·수도사(修道寺) ·관음사(觀音寺) 등 사찰이 많다. 서쪽 산록은 바다에 임하며 해수욕장으로 유명하다. 또한 이 산에는 대학루, 달성각, 유선각 등 5개의 정자가 있으며, 산 주변에는 2.7km의 유달산 일주도로가 개통되어 있다. 산 아래에는 4. 19 기념탑, 충혼탑, 가수 이난영이 부른 '목포의 눈물' 기념비 등과 조각작품 65점이 전시된 조각공원과 난공원이 있다.", + "MNTN_HG_VL" : "228", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 죽교동", + "MNTN_NM" : "유달산" }, - "longitude" : 127.4186114, - "latitude" : 37.898696600000001 + "longitude" : 126.37257219999999, + "latitude" : 34.791997799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "868", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "연점산" + "DETAIL_INFO_DTCONT" : "여수시 북동쪽 여천 산업단지 부근에 솟은 영취산은 창녕 화왕산, 마산 무학산과 더불어 전국 3대 진달래군락지 중 한곳으로 꼽힌다. 진달래만 수만그루가 모여 군락을 이룬 15만평 규모의 넓은 진달래밭이 산 곳곳에 자리잡고 있어 봄이면 장관을 연출한다. 매년 4월 초순경에 절정을 이루는데 이때를 맞춰 진달래축제가 개최된다.영취산은 예로부터 신령스런 산으로 인식되어 기우제나 치성을 드렸던 곳이다. 영취산이란 그 이름도 석가모니가 최후로 설법했던 인도의 영취산에서 따온 것으로 추측된다. 또 산 기슭에는 전통기원 도량이었던 금성대가 있고 그 아래 기도도량인 도솔암이 지어져 오늘까지 이어지고 있다.해발 510미터의 산으로 정상에 서면 남해의 크고 작은 섬들과 동북쪽 광양의 백운산, 묘도가 선명하다. 서남쪽으로 흥국사도 또렷하게 보인다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 상암동, 중흥동", + "MNTN_NM" : "영취산" }, - "longitude" : 128.9556479, - "latitude" : 36.337886699999999 + "longitude" : 127.71361159999999, + "latitude" : 34.826988399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "459", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 강서구", - "MNTN_NM" : "연태봉" + "DETAIL_INFO_DTCONT" : "면산은 창말의 앞에 있다 해서 마을 사람들이 붙인 이름이다. 이 산은 사람들이 많이 찾지 않아 처녀림의 신비함을 간직하고 있으며 정상에서는 노루와 같은 야생동물들의 흔적을 쉽게 발견할 수 있다. 이 산 부근의 다른 산들도 여전히 사람들의 시선에서 벗어나 있어 훼손되지 않은 곳이 많다.정상에 오르면 대덕산, 매봉산이 뾰족하다. 금대봉, 함백산 중계탑 사이로 장산, 그 뒤로도 끝없는 산이 이어진다. 서쪽에 강원탄광이 위치하고 영동선(嶺東線)이 통리(桶里)를 넘어 동해시에 이른다. 낙동강 상류의 작은 지류가 발원한다.", + "MNTN_HG_VL" : "1245", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시", + "MNTN_NM" : "면산" }, - "longitude" : 128.83388890000001, - "latitude" : 35.0266667 + "longitude" : 129.09555560000001, + "latitude" : 37.100277800000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "연화산으로 오르는 길은 3코스로 나누어진다.① 언양에서 365번 은칠행 버스로 은편하리 회관 앞에 내려 은편교회를 지나 태양가든 방향② 은편중리 매표소 옆 임도다라 내리재로 가는 길③ 은편중리에서 허고개 방향(남으로)15분 동신부엌가구에서 오르는 길이 열린다.산행들머리는 ③ 번째 코스로 간판 오른편 공장입구에서 왼편으로 오르는 산길이 열린다. 오른쪽에는 언양 반천일대를, 왼쪽에는 두동 은편리 일대를 끼고 능선을 걸어가노라면 고래등을 타고가는 기분이다. 발밑의 바싹 마른 낙엽은 푹신한 카페트처럼 부드럽다. 아무데나 앉아도 낙엽 자체가 방석이다.연화산 정상은 온통 나무를 베어 이곳에 집결시켜 놓고 잡목이 우거져 정상에는 들어갈 수 없을 만큼 어질러져 있다. 우거진 잡목 숲은 멧돼지의 서식지가 되고 있다.", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 언양면", - "MNTN_NM" : "연화산" + "DETAIL_INFO_DTCONT" : "완도군은 전남 해남군 땅끝 동쪽의 크고 작은 섬 202개로 이루어졌다. 이 가운데 완도가 가장 큰 섬으로 군소재지다. 상황봉은 완도에서 가장 큰 산이다. 완도 사람들은 오봉산이라고도 하는데 상황봉, 업진봉, 숙승봉, 백운봉, 쉼봉 등 다섯 개의 봉우리가 솟았기 때문이다. 고대 중국 남방에 살면서 주변을 오가며 무역하던 뱃사람들은 이 산에 부처님의 흔적이 있다 해서 ‘상왕(象王)’이라 불렀다고도 한다. 부처를 낳은 마야부인은 흰 코끼리가 배에 들어오는 태몽을 꾸었다. 그래서 코끼리의 왕이라고도 한다.옛날 어느 스님이 숙승봉의 토굴에 기거하며 수도하였고, 업진봉에 이르러 업을 다하였고, 백운대에 이르러 흰구름을 벗삼고, 쉼봉에 이르러 바다를 보며 잠시 숨을 고른 다음, 상황봉에 이르러 부처가 되었다는 유래도 있다. 관음사터와 중암사지는 흔적만 남아 있지만 상황봉이 예부터 불교의 산이었음을 뒷받침하고 있다.상황봉은 조망이 빼어난 산이다. 맑은 날이면 주변에 펼쳐진 오밀조밀한 다도해 풍경은 물론, 멀리 제주도 한라산까지 볼 수 있는 뛰어난 전망대다. 서쪽으로는 해남 달마산과 함께 두륜봉, 가련봉, 덕룡산, 주작산, 월출산 등이 펼쳐지고, 동쪽으로는 천관산이 보인다.난대성 상록활엽수림이 제공하는 독특한 풍치 또한 다른 곳에서 맛보기 힘든 이색적인 경험이다. 짙푸른 난대림으로 뒤덮인 완도 상황봉 일대는 거의 대부분 완도수목원에 편입되어 있다.", + "MNTN_HG_VL" : "646", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 군외면", + "MNTN_NM" : "상황봉" }, - "longitude" : 129.2058389, - "latitude" : 35.633003299999999 + "longitude" : 126.6931914, + "latitude" : 34.348111099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "663", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 청도면 구기리", - "MNTN_NM" : "열왕산" + "DETAIL_INFO_DTCONT" : "통영시 서남단의 미륵도에 위치한 야트막한 산이나 미륵신앙의 본거지로 불교인들 사이에는 꽤 알려진 산이다. 그래서인지 이 작은 산에는 용화사, 관음사, 도솔암, 미래사 등 크고 작은 사찰과 암자가 많다.또 임해봉(臨海峰)이라는 이름의 정상은 지난날 봉화대로서 다도해를 지킨 역사적 장소로도 기억될 만 하다. 미륵산은 한국 제일의 미항이며 충무공이 왜적을 격파한 전승지로 유명한 통영과 국내 유일의 해저터널로 연결되어 있다. 일명 `판대굴'로 불리는 이 해저터널은 일제시대 일본인이 건설한 것이나 예측된 수명을 넘어 지금도 사용되고 있어 당시 일본의 기술력을 짐작할 수 있는 표본으로 각광받고 있다.정상에 오르면 비진도, 거제도 , 한산도, 칠천도 등 한려수도를 보석처럼 장식하는 크고 작은 섬들을 한 눈에 조망할 수 있어 그 아름다움에 당황할 정도이다.", + "MNTN_HG_VL" : "458", + "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 산양읍ㆍ봉평동", + "MNTN_NM" : "미륵산" }, - "longitude" : 128.5953988, - "latitude" : 35.541475000000013 + "longitude" : 128.4163241, + "latitude" : 34.810502800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "203", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 동구", - "MNTN_NM" : "염포산" + "DETAIL_INFO_DTCONT" : "철마산은 쇠말산, 샛말, 소멀미 등 비슷한 속명이 있다. 옛날 이곳은 큰홍수와 해일로 인하여 오랫동안 물속에 잠겨 있었는데, 미역바위의 용굴에서 동해 용왕의 명을 받은 용마가 나와서 물을 다스리고 나서부터는 물이 없어 용마는 환궁하지 못한 채 햇볕에 말려져 점차 굳어져서 작은 쇠말이 되어 최근까지도 그 흔적이 남아 있었기 때문에 쇠로 된 말이 있는 산이라 하여 쇠(鐵), 말(馬), 뫼(山)로 철마산이라 하였다고 한다.쇠는 소, 새와 같은 말로 샛바람이라 하는동쪽을 뜻이고, 말은 마라, 말, 머리와 동계어로서 마루라는 말로서 산마루 로 산등성이를 뜻하는 말이다.", + "MNTN_HG_VL" : "605", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면", + "MNTN_NM" : "철마산" }, - "longitude" : 129.40899999999999, - "latitude" : 35.521000000000001 + "longitude" : 129.13749999999999, + "latitude" : 35.310000000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "영대산은 장수군 산서면과 임실군 성수면의 경계에 자리한 산이다. 호남금남정맥의 팔공산이 서쪽으로 한줄기 곁가지를 일으킨다. 마령치를 지난 이 산줄기는 다시 둘로 나뉘어 북녘으로 성수산, 서녘으로 영대산과 오봉산을 일으킨 후 덕재산을 지나 오수면의 오수천에서 산줄기를 마감한다. 지형도에는 한문으로 영태산(靈台山)이라 표기되어 있으나 이곳 주민들은 모두 `영대산'이라 부른다.산형이 아담하고 수려하다. 또한 인자하고 후덕한 어머니가 자식을 품에 안고 젖을 주는 듯한 산이기도 하다 또 이 산은 장수 8경의 한 경치인 영산영월의 경관을 자랑한 산이다.", - "MNTN_HG_VL" : "666", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 산서면", - "MNTN_NM" : "영대산" + "DETAIL_INFO_DTCONT" : "설악산 대청봉에서 서북능선을 따라 10km쯤 달리면 한계령으로 빠지는 갈림길이 나온다. 이곳에서 계속 전진하는 길에 귀때기청봉(1,578m)을 거쳐 10km여를 더 오르락내리락 하다보면 대승령 안부에 이른다. 여기서도 방향을 계속 서쪽으로 잡아 4km쯤 가다보면 마치 말안장을 연상시키듯 두 개의 암봉 사이가 잘룩하게 들어간 모습을 접하게 된다. 여기가 바로 안산의 정상부위로서 일명 길마산이라고도 한다.안산은 외진 위치 때문에 찾는 사람이 많지 않다. 남쪽의 장수대에서 산행을 시작하는 사람들은 대승령에서 십이선녀탕계곡으로 하산길을 잡아 이 산을 스쳐 지나는 것이 보통이다. 그래서 설악을 수십번 다닌 사람들 중에도 안산을 다녀온 사람이 드물 정도로 한적한 봉우리로 남아 있다.안산은 멀리 원통쪽에서 바라보아도 말안장을 닮은 모습이 시선을 끌고 있고, 막상 올라가보아도 처음부터 암벽으로 이루어진 협곡이 만만찮은 험산임을 느끼게해 준다. 이 산을 중심으로 옥녀탕 계곡과 12선녀탕계곡이 좌우로 펼쳐져 있고, 정상 주변에는 화강암 기암이 도처에 산재하고 조망하는 전망이 일품이어서 등산의 가치가 높은 산이다. 정상 옆에는 무악동 봉수대가 있다.", + "MNTN_HG_VL" : "1430", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면", + "MNTN_NM" : "안산" }, - "longitude" : 127.3986111, - "latitude" : 35.612499999999997 + "longitude" : 128.33000000000001, + "latitude" : 38.140000000000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "경기도에서 화악산(1,468.3m)에 이어 두 번째로 높은 명지산은 정상을 오를 수 있는 산으로는 최고봉이다. 거대한 산맥을 이룬 명지산은 산 크기만큼이나 등산로도 많이 있으나 어느 길이나 정상까지 3시간 이상 소요된다. 서울에서 가까운 곳에 있으면서도 아직 오염되지 않은 깨끗한 계곡과 울창한 수림을 간직하고 있다.가평천을 사이에 두고 화악산과 마주보고 있는 명지산은 정상을 기점으로 사방으로 산자락을 펼치며, 귀목봉, 사향봉, 백둔봉 등을 거느리고 있는 웅장한 산이다. 명지산의 울창한 수림은 일상에 지쳐 산을 찾는 이들을 포근히 감싸안는데 그 깊이를 가늠할 수 없다.사계절이 다 아름다운 명지산은 특히 봄에는 진달래와 쩔쭉이 온산에 흐드러져 봄날의 산행을 즐기는 이들을 황홀경에 젖게 만든다. 가을 단풍은 가평 팔경 중 제 4경으로 지정 되었다. 우리나라 가을 산은 어디나 아름답지만 명지산의 단풍은 수십년 묵은 고목과 기암괴석들과 조화를 이루어 더욱 더 깊이를 더 한다. 또한 겨울에는 적설량이 많아 설화가 장관을 이뤄 겨울산행을 나선 이들을 반긴다.명지산 입구인 익근리에서 약 1Km가량 올라가면 규모가 작은 사찰인 승천사가 나타나고, 이어서 2Km가량 더 가면 등산로 왼쪽으로 높이 6m에서 시원한 물줄기가 쏟아 내리는 명지폭포를 만나게 된다. 한여름 불볕더위도 식혀 버리는 명지폭포 아래 깊은 웅덩이는 옛날에 명주실 한타레가 다 들어갈 정도로 깊어 명지폭포로 이름이 붙여졌다 한다.", + "MNTN_HG_VL" : "1252", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면ㆍ하면", + "MNTN_NM" : "명지산" + }, + "longitude" : 127.43194440000001, + "latitude" : 37.941666699999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1081", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산 하북면, 원동면, 울산시 울주군 삼남면, 상북면", - "MNTN_NM" : "영축산" + "MNTN_HG_VL" : "449", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "개좌산" + }, + "longitude" : 129.14583329999999, + "latitude" : 35.250555599999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "가평에 깃대봉이 2개 있다. 청평휴게소 뒷산인 깃대봉(644m)과 대금산 뒤의 가평군 두밀리의 깃대봉(910m)이다. 청평휴게소 뒷산인 깃대봉(644m)봉은 북한강을 한눈에 볼 수 있는 조망을 갖춘 산으로 청평역에 인근하고 있다.두 산 모두 경춘선으로 다녀올 수 있는데, 가평읍 경계의 깃대봉은 가평역에서 산행 들목까지 버스나 택시로 이동해야 하지만, 청평 깃대봉은 청평역에서 곧바로 산행을 시작할 수 있다. 또한 두 산은 이름은 같지만 족보가 차이가 난다. 물론 근원은 한북정맥이지만 가평 깃대봉은 명지산(1,267m)에 뿌리를 두었고, 청평 깃대봉은 축령산(879m)에 두고 있다.이웃에 대금산, 불기산, 청우산이 있어 깃대봉 정상에 서면 능선이 한눈에 들어오고 시간이 날 경우 완전히 하산하여 다시 조종천을 끼고 이웃한 산들을 접할 수도 있다. 깃대봉은 청평 휴게소와 대갈교에서 오르는 길이 있으나, 대갈교쪽 교통이 편리하다.", + "MNTN_HG_VL" : "520", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍 상면", + "MNTN_NM" : "깃대봉" }, - "longitude" : 129.05500000000001, - "latitude" : 35.517000000000003 + "longitude" : 127.39388889999999, + "latitude" : 37.744444399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1081", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 원동면, 하북면. 울산광역시 울주군 삼남면", - "MNTN_NM" : "영축산" + "DETAIL_INFO_DTCONT" : "양각산(兩角山)의 옛 이름은 금광산(金光山)이다, 북쪽 수도산 신선봉을 기점으로 남진하는 줄기의 4km 지점에 있다. 정상을 중심으로 동쪽에는 거창의 두메인 가북면 중촌리 수재 심방소가 자리하고 서쪽으로 웅양댐 위쪽에 자리한 금광(金光)마을을 품고 있다. 양각산의 양각(兩角)은 두 개의 소뿔을 의미한다. 따라서 소뿔산이라고 불러도 무방하다. 화강암지반을 갖고 높이 솟은 두 봉우리는 동서쪽으로 벼랑을 수반하고 소뿔형상의 암·수 자웅형태로 솟은 두 봉우리 가운데 복쪽 봉우리가 정상이다. 북봉의 정점이 되는 곳은 여러 형태의 바위들이 모여 있다. 그곳 중심 돌출된 바위 모양새는 남성을 상징하는 심벌처럼 생겼다. 남쪽에는 거북 모양새의 기이한 바위가 있는데 거북바위 뒷모습이 마치 여인 궁둥이처럼 생겼다. 거북바위 가까운 곳에는 바위구멍 한 개가 패여 있다. 언제 누가 양각산 정상 암반 위에 바위구멍을 파 놓았는지 알 수 없어도 성신신앙에서 비롯된 소산임을 알 수 있다. 바위구멍을 실측하여 보았더니 둘레 63cm에 길이가 15cm 된다. 이 바위구멍을 천정(天井)이라 부르는데 그 바위 구멍 속에 하늘물이 고여 있다. 북봉 주변에는 물고기 거북형상 등을 지닌 바위들이 많고 남봉에는 제단을 쌓았던 돌들로 여겨지는 막돌들을 이용하여 쌓아놓은 키 작은 돌무지탑(케언)들이 놓여 있다. 이 산의 특징은 양각이 소뿔의 의미를 담고 소와 관계된 것처럼 산이 갖는 재, 골짜기, 마을 이름들이 모두 소와 인연하여 이름이 지어졌다는 점이다. 양각산 서쪽 거창에서 김천시 대덕면으로 넘는 고개를 소머리고개 곧 우두령(牛頭嶺)이고 우두령 오르는 길에 놓은 마을은 소구시를 뜻하는 구수(口水)마을이고, 희대미산 아래 안긴 랑 우랑동(牛郞洞)이 소불알을 뜻한 마을이니 모두 소와 인연한 이름들이다. 소는 범어(梵語)로 가야(Gaya)를 뜻한다. 예날 이곳은 가야국에 속한 곳이어서 여기 ‘소’와 무관하지 만은 않다. 또한 수도산과 이어져 동쪽 가야산으로 드는 준령으로서 가야와 같은 맥락임을 알 수 있다. 양각산 예 이름인 금광산(金光山)은 고산자(古山子) 대동여지도 및「거창고읍지」에서 찾아 볼 수 있으나 금광(金光)이란 이름은 현재 양각산이 품고 있는 산아래 금광(金光)마을 이름으로 남아 있다. 금광(金光)이란 부처님을 뜻한다. 옛날 양각산 아래 금광사라 하는 절이 있었으며「거창향지」에서는 마을 근처 산에 금이 많이 묻혀 있었다는 전설에 의해 금광이라 한다고 하였다. 또 산의 반석에 항상 물이 번져 햇볕에 번쩍번쩍 금빛이 난다하여 이름 되었다고 한다. 양각산은 수도산에 인접하여 골이 깊고 옛날에는 산삼이 자생하였다고 전하며 현재에는 천마, 주치 등 한약재가 많이 자생한다. 양각산 아래 2km거리에 희대미산이 솟아 있으며 위족으로 수도산 신선봉과 연결 짓고 서쪽 거말흘산(巨末屹山, 902m)사이 우두령이 놓여 옛날에는 전략적 거점지로서 우두령은 임진왜란 때 김면(金沔)장군 지휘 아래 우척현 싸움이 있었던 곳으로 유명하다. 양각산이 품고 있는 웅양댐물은 어인동, 인삼동, 동북쪽 골짜기의 발원이다. 출처 : 「거창의 명산」 거창문화원(정태주·안수상 편저)", + "MNTN_HG_VL" : "1158", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 웅양면 산포리", + "MNTN_NM" : "양각산" }, - "longitude" : 129.05500000000001, - "latitude" : 35.517000000000003 + "longitude" : 127.9610339, + "latitude" : 35.838789200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "여수시 북동쪽 여천 산업단지 부근에 솟은 영취산은 창녕 화왕산, 마산 무학산과 더불어 전국 3대 진달래군락지 중 한곳으로 꼽힌다. 진달래만 수만그루가 모여 군락을 이룬 15만평 규모의 넓은 진달래밭이 산 곳곳에 자리잡고 있어 봄이면 장관을 연출한다. 매년 4월 초순경에 절정을 이루는데 이때를 맞춰 진달래축제가 개최된다.영취산은 예로부터 신령스런 산으로 인식되어 기우제나 치성을 드렸던 곳이다. 영취산이란 그 이름도 석가모니가 최후로 설법했던 인도의 영취산에서 따온 것으로 추측된다. 또 산 기슭에는 전통기원 도량이었던 금성대가 있고 그 아래 기도도량인 도솔암이 지어져 오늘까지 이어지고 있다.해발 510미터의 산으로 정상에 서면 남해의 크고 작은 섬들과 동북쪽 광양의 백운산, 묘도가 선명하다. 서남쪽으로 흥국사도 또렷하게 보인다.", - "MNTN_HG_VL" : "510", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시 상암동, 중흥동", - "MNTN_NM" : "영취산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "522", + "MNTN_LOCPLC_REGION_NM" : "경상북도 의령군", + "MNTN_NM" : "벽화산" }, - "longitude" : 127.71361159999999, - "latitude" : 34.826988399999998 + "longitude" : 128.2276621, + "latitude" : 35.300024800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남양주군에 있는 예봉산은 경기도 하남시의 검단산을 바라보고 있는 산이다. 예봉산은 남북의 두 줄기가 팔당댐에서 합쳐졌다가 서울로 흘러드는 한강의 물결 파노라마를 지켜볼 수 있는 산으로 인접해 있는 예빈산(禮賓山 589m)을 거치는 것이 일반적이다.옛날에 배를 타고 영월, 정선, 충주, 단양, 춘천을 오가는 길손들이 한양을 떠나며 삼각산이 보이는 이곳에서 임금에게 예를 갖추었다 해서 예빈산이라 부르기도 했다. 그런 연유에서인지 이 산자락에서는 실학의 선구자 정약용, 건국 운동을 선동했던 몽양 여운형 선생, 가나안 농군학교를 설립해 농촌지도자를 양성하는 데 앞장섰던 김용기 장로 등 이름 있는 인물들이 많이 배출되었다.예봉산의 능선이나 정상에 올라가면 어디서나 북한강과 팔당댐이 산을 끼고 굽이쳐 흐르는 아름다운 모습을 볼 수 있다. 능선길의 단풍은 특히 좋다. 정상 주변은 옛 성터 같은 돌무더기가 있다. 예전에는 산령단이 있었다고 하나 지금은 헬기장으로 변했고, 삼각점(양수 26)과 예봉산악회가 세운 정상표지석이 있다.", - "MNTN_HG_VL" : "683", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시", - "MNTN_NM" : "예봉산" + "DETAIL_INFO_DTCONT" : "고흥읍에서 동쪽으로 25km 떨어진 소백산맥의 맨 끝부분에 위치한 산으로 8개의 봉우리가 남쪽을 향해 일직선으로 솟아 있다.", + "MNTN_HG_VL" : "607", + "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 영남면 우천리", + "MNTN_NM" : "팔영산" }, - "longitude" : 127.2611921, - "latitude" : 37.559263000000001 + "longitude" : 127.4341153, + "latitude" : 34.618202699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 남양주시 와부읍과 조안면 경계를 이루는 예봉산(683.2m)은 한북정맥에서 가지를 친 능선 끝머리에 해당되는 산이다. 이 산줄기는 다시 남동쪽으로 이어져 율리봉, 예빈산을 들어 올린 다음 북한강과 남한강이 합수되는 두물머리와 한강에서 모두 사그라진다.팔당역을 기점삼아 정상에 서면 한강을 가로지르는 팔당대교와 그 너머로 하남시와 강동구를 필두로 한 서울, 북한강과 양수대교, 그리고 북한강과 남한강이 만나는 두물머리와 팔당호가 한눈에 들어온다.옛날 길손들이 배를#376;고 강원도로 떠날 때 마지막으로 삼각산이 보이는 예봉산 아래 팔당에서 임금에게 예(禮)를 갖췄다고 해서 산이름을 예빈산으로 지었다는 설이 있다.예봉산은 수도권에서 손꼽히는 근교산행 코스로 중앙선 팔당역이 개통되면서 각광을 받고 있다.", - "MNTN_HG_VL" : "638", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 와부읍, 조안면", - "MNTN_NM" : "예봉산" + "DETAIL_INFO_DTCONT" : "경부고속도로 건천나들목에서 남쪽으로 바라다 보이는 산이다. 산은 건천읍 송선리 우중골에 있으며, 산 7-8부 능선에는 4개의 바위가 둘러싸인 천연굴이 있는데 옛날에는 상인암(上人巖, 일명 탱바위)이라고 불리었다고 한다. 화랑들은 이 바위굴 속에 불상을 새기고 그 위에 지붕을 덮어 석굴사원을 만들었다. 이 절을 신선사(神仙寺) 또는 단석사(斷石寺)라고 부른다. 내부의 마애불상은 국보 제199호로 지정되었다. 단석산은 경주에서 가장 높은 산으로 백제에 대한 신라의 국방의 요충지였다.이 지역은 진달래 군락지로 봄철 산악 애호가들의 사랑을 받고 있으며, 인근 조래봉(657m)과 더불어 등산 코스로 각광을 받고 있다. 단석산으로 올라가려면 방내리에서 큰골로 가는 숲길이 있는데 화랑도량의 표시인 화랑바위가 있고, 화랑들을 불러 면회하던 급제바위가 있으며 정상 가까이에 올라가면 김유신이 칼 쓰기 연습을 하다가 남았다는 기둥바위가 있으니 사람들이 고단석이라 부른다.", + "MNTN_HG_VL" : "827", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", + "MNTN_NM" : "단석산" }, - "longitude" : 127.2611921, - "latitude" : 37.559263000000001 + "longitude" : 129.09134510000001, + "latitude" : 35.793620900000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "362", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", - "MNTN_NM" : "예성산" + "MNTN_HG_VL" : "369", + "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", + "MNTN_NM" : "미궐산" }, - "longitude" : 127.1329367, - "latitude" : 35.117416200000008 + "longitude" : 126.9933333, + "latitude" : 36.440833300000001 }, { "mountain" : { @@ -6101,3252 +4891,3282 @@ }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "예로부터 금강산, 한라산, 지리산과 더불어 국내 제일의 명산으로 알려져 온 오대산은 골짜기마다 아름드리 나무가 숲을 이루고 있어 남한 최대의 수림을 자랑하다. 또한 강원도 일대의 산들이 대부분 기암괴석으로 이루어진 것과는 토산으로 이루어져 있어 한국산의 전형을 보여준다.", - "MNTN_HG_VL" : "1434", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면, 강릉시 연곡면", - "MNTN_NM" : "오대산 동대산" + "DETAIL_INFO_DTCONT" : "송학산은 제천에서 영월로 뻗는 38번 국도에서 왼쪽으로 올려다 보이는 산으로, 산 전체가 거의 소나무 일색이며, 송학산 자락은 주변으로 채석장이 여러 곳 있어 질 좋은 화강암이 생산되던 곳이다.산 이름 그대로 아름드리 노송은 많지 않지만 산 전체가 거의 소나무 일색으로 산행 내내 코끝을 스치는 그윽한 솔향이 일품이며, 푹신한 솔잎을 밟으며 청산의 푸른 기운을 느낄 수 있다.정상 바로 아래에는 빼어난 조망을 가진 강천사가 있으며, 짧은 코스지만 정상에 올라서면 송학면 일대의 조망이 일품이다. 남쪽으로는 무등산, 왕박산, 갑산, 가창산이 첩첩으로 포개지며 서북쪽으로는 제천의 진산 용두산과 그 뒤에 석기암, 감악산이 한 눈에 들어온다.강천사에서 조금 내려오면 급하게 굽이도는 언덕 너머에 빈대로 망했다는 전설의 소악사지가 있으며 3층석탑만 외로이 남아 무상한 역사를 말해준다.", + "MNTN_HG_VL" : "819", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면ㆍ강원도 영월군 주천면", + "MNTN_NM" : "송학산" }, - "longitude" : 128.59833330000001, - "latitude" : 37.7744444 + "longitude" : 128.26791040000001, + "latitude" : 37.208268799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "오도산은 도선국사가 깨달음을 얻었던 곳으로 숙성산 정상에서 이 산을 보면서 산의 기운과 형상에 도취되어 꼬박 일주일을 움직이지 않았다고 한다. 이를 본 주민들이 도선이 잠든 것으라 여겨 숙성산 정상을 성수단(聖睡壇)이 된 것이라고 전해진다.도선국사가 도취될 만큼 이 산에는 지실골, 한시골, 폭포골, 두오골 등 맑고 깊은 계곡이 포진해 있어 안으로 들어가면 갈수록 깊이를 더하는 산이다. 골짜기는 오도산,미녀산,숙성산에서 흘러내리는 물들을 모아 수량이 풍부하다. 다래나무가 계곡을 가릴 정도로 많고 그 열매가 계곡 암반에 떨어져 소복히 쌓여 있고 더러는 계곡의 와폭을 따라 흐르기도 한다.정상은 통신시설 때문에 일반인의 출입은 금지하고 있다. 정상 일대의 도로에서 사방을 조망하는 맛이 그만이다. 덕유산을 비롯해 수도산, 가야산 그리고 자굴산, 황매산,지리산, 백운산, 계관산, 황석산, 기백산이 병풍을 친 듯 장관이고 남으로 합천호도 보인다.", - "MNTN_HG_VL" : "1134", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 묘산면", - "MNTN_NM" : "오도산" + "DETAIL_INFO_DTCONT" : "남병산은 강원도 평창군 대화면과 방림면, 평창읍의 경계를 이루는 산이다. 남병산은 북쪽 멀리 오대산에서 서쪽 계방산으로 이어지는 능선에 솟아 있는 산이다.첩첩 산중인 평창의 가리왕산(1,560m)과 이웃하고 있다. 주변에 유명한 오대산, 계방산, 발왕산 등 높고 큰 산이 많아 국도변에 위치하여 있으면서도 지나쳐 버리는 산으로 취급되어 왔으나 인적이 드문 관계로 해묵은 수목이 군락을 이루어 볼만하다.육산 남병산에는 그러나 평창강가로 지긋이 다가서 있어서 정상능선에서 평창강을 내려다 보는 각별한 맛이 있다. 또한 20여평의 공터로 사방이 확 트여 전망이 좋은 편이다. 북동쪽으로는 중왕산과 가리왕산이, 동으로는 청옥산이, 남으로는 장암산과 삼방산이, 서쪽으로는 백덕산, 중대갈봉과 장미산, 절구봉이 스카이라인을 이룬다. 평창강은 우리나라의 대표적인 사행하천(구비가 많은)으로 계방산에서 발원하여 장평에서 흥정산, 태기산에서 발원한 흥정천을 합치고 금당계곡을 흘러내려와 방림에서 백덕산에서 흘러내려온 계촌천을 합쳐 평창을 지나고 주천을 거쳐 영월에서 동강과 합류, 남한강이 되어 흘러내려간다.", + "MNTN_HG_VL" : "1150", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", + "MNTN_NM" : "남병산" }, - "longitude" : 128.07499999999999, - "latitude" : 35.673888900000001 + "longitude" : 128.45249999999999, + "latitude" : 37.427499999999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면과 화천군 간동면 사이에 있는 오봉산은 해발 779m이고 다섯개의 봉우리가 있다고 해서 오봉산이라고 한다. 기암절벽과 노송이 어울려 한폭의 동양화 같은 산으로 유서깊은 청평사가 있다.배후령에서 오르게 되는 첫번째 봉우리가 1봉(나한봉), 두번째 봉우리인 관음봉, 세번째 봉우리인 문수봉, 네번째 봉우리인 보현봉, 다섯번째 봉우리인 정상 비로봉이 있다. 이중 제5봉인 정상에서 청평사 방면으로 뻗어내린 암릉이 특히 빼어난 풍광을 지녔다. 이 암릉을 따라 소양호를 바라보며 내려가는 길이 오봉산행의 백미라 할 수 있다.", - "MNTN_HG_VL" : "778", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "장산은 태백시를 나와 화방재를 넘은 뒤 조금 내려오면 옥동천이 시작되면서 오른쪽으로 보이는 화려한 암봉과 능선으로 이루어진 멋진 산이다. 서울특별시에서 태백산으로 가는 길은 특히 영월을 지난 뒤 고개와 강, 숲과 협곡, 고봉과 단애가 연이어 나타나 어느 지역의 경관이 좋고 어떤 산이 높고 아름다우며, 어떤 강물이 맑으니하고 말하기가 어렵다. 하나같이 높고 아름다운 산이 연이어져 보임에서 그렇다.이산의 장점이라면 남쪽과 서쪽은 바위로만 이루어져서 경관이 수려하고 북쪽과 동쪽은 완사면으로 되어있어 올라가기가 좋다. 경사가 완만하며 바위벽이 가로막고 숲길로 이어지는 반복적인 등산로 이기에 지루함을 못느끼고 너덜지대 끝에 올라서면 시야가 확 트인다 .정상에는 조그마한 삼각점이 있고 두위봉이 시야에 들어오고 백운산,함백산 정상의 중계탑이 선명하고 태백산의 장군봉,천제단,문수봉의 너덜지대와 구룡산으로 이어지는 백두대간의 웅장한 흐름을 볼 수 있다.문자 그대로 장(壯)한 산이다. 암릉도 암릉이거니와 산행의 시작을 맑은 계류가 굽이쳐 흐르는 옥동천에서 시작한다는 것이 장산을 처음 오르는 사람도 탄성을 지르게 한다.", + "MNTN_HG_VL" : "1409", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 상동읍", + "MNTN_NM" : "장산" }, - "longitude" : 127.8060983, - "latitude" : 38.0007746 + "longitude" : 128.86013370000001, + "latitude" : 37.127789800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 평창군 방림면, 횡성군 안흥면 태백산맥에서 갈라져 나간 차령산맥의 원두에 있는 명산 백덕산(1,350m) 과 북쪽으로 연이은 능선 위에 솟아오른 산이다. 지도상에는 1,136봉이 무명으로 되어 있으나 주민들은 봉우리가 다섯개 있다고 하여 오봉산으로 부르고 있다. 소양댐 위에 있는 오봉산(779m)과 자칫 혼돈하기 쉬우니 이 점 착오없기 바란다. 문재를 가운데 두고 북쪽이오봉산, 남쪽이 백덕산인데 그래서 그런지 두 개의 산이 산세나 식물상도 매우 흡사하다.잡목이 무성한 산길을 따라가다 1126고지에 이르면 참나무 울창한 숲길을 만날 수 있다. 이곳에서 조금만 올라가면 정상이다. 사람의 흔적을 찾아보기 어려워 복잡한 도심속의 소음을 등지고 한적한 산행을 즐기기에 안성맞춤이다.", - "MNTN_HG_VL" : "1136", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 평창군", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "경상북도 봉화군에 위치하고 있으며 인근 일월산과 마주하고 있다. 풍수지리설에 의하면 장군대작(將軍大爵)의 모기(墓基)가 있다고 하여 장군봉(將軍峰)이란 이름이 명명되어 전하여 오고 있고 동서남북으로 임산도로가 개설되어 있어 접근이 용이하다.장군봉은 그 이름처럼 일월산을 지켜주는 남성산이다. 토산인 일월산이 여성산이라 그 산과 나란히 하면서 일월산을 주켜주기 위해 태동했다는 일설이 전한다. 또 봄철 두릅, 산나물 등이 많아 채취하는 사람들의 발길이 끊이지 않고 있다. 그래도 봉화에서도 가장 험악한 산악지대로 알려진 곳에 있고 찾는 이가 드물어 아직까지는 호젓한 산행을 할 수 있는 곳이다. 그러나 임도가 정상부까지 나있어 산행시간이 많이 걸리지 않는다.북쪽으로는 태백산(1,560.6m)과 청옥산(1,276.5m)을 두고 있고, 남쪽으로는 일월산(1,218m)을, 동쪽으로는 통고산(1,066.5m)을 끼고 있다. 또 서남쪽으로는 도립공원인 청량산(970.4m)을 가까이 하고 있다. 장군봉을 둘러싸고 있는 산들은 모두 사람이 많이 찾는 곳이다. 어쩌면 장군봉은 그들의 위세에 밀려 알려지지 않은 산인지도 모른다.", + "MNTN_HG_VL" : "1039", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 소천면", + "MNTN_NM" : "장군봉" }, - "longitude" : 128.28561920000001, - "latitude" : 37.601998999999999 + "longitude" : 129.08583329999999, + "latitude" : 36.853055599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 완주군 구이면과 임실군 운암면에 걸쳐있는 오봉산과 국사봉은 옥정호가 있어 그 존재가치를 인정받는 산이다. 임실군 강진면과 정읍시 산내면에 걸쳐있는 옥정호의 비경은 무엇보다도 외안날을 중심으로 피어오르는 아침 물안개다. 옥정호는 일제 강점기인 1925년 동진수리조합에서 시공에 들어간 관개용댐에서 비롯됐다. 당시 섬진강 상류인 정읍군 산외면에서 서남쪽으로 갈라져 나와 황해로 흘러들어가는 동진강 유역이 대부분 평야인데 가뭄이 심각했다. 그래서 수자원이 풍부한 섬진강 상류를 막아 반대편인 정읍군 치보로 넘겨 계화도와 호남평야에 농업용수를 제공하기 위해 1929년 운안댐이 준공됐다. 이 사업은 3공화국까지 이어졌고 1965년 섬진강 다목적댐이 완공되면서 운암댐은 수몰되고 전북에서 제일가는 인공호수가 탄생한 것이다. 옥정호란 이름은 당시 댐이 위치한 강진면 옥정리에서 유래한다.옥정호를 가장 쉽게 조망할 수 있는 방법은 국사봉전망대 휴게소로 가는 것이다. 그리고 사진 촬영을 위한 최적의 포인트는 휴게소에서 20분이면 오를 수 있는 옥정호전망대다. 외안날을 중심으로 펼쳐지는 옥정호를 조망하는 이곳은 주말에는 1시간 전에 올라야 자리를 차지할 수 있을 정도로 사진가들이 붐빈다. 정상에 오르면 옥정호 주변을 조망할 수 있을 뿐 아니라 멀리 마이산까지도 보인다.", - "MNTN_HG_VL" : "513", - "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 운암면", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "괴산군 연풍면과 장연면의 경계를 이루고 있는 덕가산은 충북의 유명산 악휘봉(940m)과 이웃해 있다. 악휘봉이란 명산에 가려져 빛을 보지 못한 산이기도 하다.덕가산은 악희봉과 반대로 육산이며, 정상에는 삼각점과 깃대봉이 있다. 주능선에는 상수리나무가 주종을 이루고 등산화를 파묻히게 하는 낙엽의 아삭아삭하는 소리가 홀로 걷는 이의 빈 마음을 채워주어서 좋다.주위에 여러산들이 기암절벽으로 산을 감싸고 있는 반면 산세가 부드럽고 장송들이 많아 여성적인 자태를 지니고 있다.", + "MNTN_HG_VL" : "855", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면", + "MNTN_NM" : "덕가산" }, - "longitude" : 127.1325344, - "latitude" : 35.644214499999997 + "longitude" : 127.95, + "latitude" : 36.75 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보성군 득량면으로 들어서면 도로 왼쪽으로 너른 벌판이 펼쳐지고 그 끄트머리께 우뚝 솟은 산이 두 개 보인다. 예당벌과 오봉산이란 지명이 붙어 있는 산들이다. 이곳 사람들은 왼쪽은 오봉산, 오른쪽은 작은 오봉산(284.2m)이라 부른다. 다섯 개의 위성봉을 거느리고 있는 작은 오봉산은 가까이 가면 정상부 오른쪽에 바위가 삐죽 튀어나와 있는 것이 인상적이다.반면 봉우리가 다섯 개 모여 있는 오봉산은 산 아래 다가설 때까지도 그리 독특하지 못하다. 들녘에 솟은 그저 평범한 야산 정도일 따름이다. 하지만 파고들면 점입가경 신비스럽기 그지없다. 산행 초입 오봉산은 한때 구들장으로 애용되는 돌이 대량으로 추출되었다는 명성에 걸맞게 납작한 돌 천지다. 널찍하게 이어진 등산로를 따라 오르면 멋들어지게 쌓아둔 돌탑이 산 능선마다 쌓여있다.오봉산의 참 멋은 오봉산에 들어서야 알 수 있다. 그 중 오봉산의 으뜸은 칼바위다. 30여 미터 높이의 칼바위는 마치 손가락을 위로 세우고 손을 모아서 45도 각도로 굽힌 모양 같기도 하고, 선 채로 깊숙이 허리 굽혀 인사하는 모습 같기도 하다.웅장한 바위와 깊은 골짜기, 봄을 수놓은 진달래가 오봉산의 오른쪽 얼굴이라면 득량만이 내려다보이는 탁 트인 조망은 오봉산의 왼쪽 얼굴이다.", - "MNTN_HG_VL" : "513", - "MNTN_LOCPLC_REGION_NM" : "전남 보성군 득량면", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "애오라지 산만 찾아다니는 산꾼들이라도 경주에 들어서면 가슴이 설렌다. 어딜 가나 역사와 전통의 향기에 마주치게 되는 천년고도인 것이다.비록 산만 찾아 나선 길이라 해도 언제 어디서 뜻밖의 문화유산과 접하게 될지 모른다는 기대감을 가져도 좋은 것이 경주쪽 산행이다. 산행초입에는 천도교의 유적지이자 성지인 용담정(龍潭亭)이 들어서 있어 색다른 경주의 역사유적을 만나는 기쁨도 있다.", + "MNTN_HG_VL" : "594", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 건천읍", + "MNTN_NM" : "구미산" }, - "longitude" : 127.16861110000001, - "latitude" : 34.752777799999997 + "longitude" : 129.1364494, + "latitude" : 35.884555400000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "235", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "오봉산" + "DETAIL_INFO_DTCONT" : "문암산은 정북녘에 자리한 방태산을 위시해 오대산, 계방산, 회령봉, 응봉산 등의 기라성 같은 명산이 한 바퀴 원을 그리며 둘러싸고 있다. ‘돌꽃산(石化山)’이라는 별명에 어울리는 아름다운 바위경관과 듬직한 산세가 멋지고 유명한 내린천의 상류와 자운천, 문암천이 동서녘 자락을 스치며 지난다.철따라 온갖 들꽃들이 앞다투어 피어나는 남북으로 길게 뻗은 주능선을 걷노라면 주변의 내로라하는 산들과 어울린 풍경에 콧노래가 절로 나오는 멋진 산이다. 지역 사람들은 문암산을 ‘석화산’이라 부른다. 이름처럼 푸른 숲 사이로 툭툭 삐져나온 바위전망대가 많아 저마다 조망이 시원스럽다.", + "MNTN_HG_VL" : "1146", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "문암산" }, - "longitude" : 128.8075, - "latitude" : 37.704722199999999 + "longitude" : 128.37694440000001, + "latitude" : 37.782499999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "곡성땅을 관통해 흐르면서 남동쪽으로 향하던 섬진강 물줄기를 북진시키는 오산은 자라가 섬진강 물을 마시고 있는 모습이라는 데서 이름을 따왔다고도 하고 정상의 벼랑 때문에 이런 이름을 얻었다고도 한다. 정상까지 걸리는 시간도 1시간 내외에 불과하지만 산꼭대기 고스락은 분수처럼 비밀을 내뿜는 화수분 같은 산이다.오산 사성암 전망바위에서 내려다 본 구례들판. 문척면 나들목인 신·구 문척교와 그 아래로 넉넉하게 흐르는 섬진강이 한눈에 들어오며 지리산 북서쪽 자락도 파노라마처럼 펼쳐진다. 그 하나는 넋을 빼앗는 조망의 즐거움이다.'산에 들면 산을 모르고 산을 벗어나면 그 산이 보인다'는 말이 있다. 오산에 오르면 바로 헌걸찬 지리산이 한눈에 들어온다. 북동쪽으론 노고단,반야봉,삼도봉이 뚜렷하고 멀리 명선,촛대봉이 아련하다. 동쪽으론 문수리가 아스라이 펼쳐지며 그 오른쪽으로 왕시루봉과 황장산이 능파를 이루며 달리고 있다. 한마디로 말하면 지리산 최고 전망대인 셈이다.두번째 비밀 역시 풍광의 아름다움이다. 실핏줄 같은 개울 물을 모아 남도의 이산 저산의 뭉툭한 허리를 감돌며 굽이치는 섬진강이 가장 찬란한 빛으로 흐른다. 지리산 어떤 전망대도 오산에서 바라보는 섬진강의 비경을 따라잡기 힘들 듯 싶다.세번째 비밀은 오산의 보석 사성암의 전설로 시작된다. 깎아지른 벼랑에 제비 집처럼 붙여 지은 사성암은 582년 연기조사가 세운 이래 원효,의상,도선,진각 등 4대 성인이 수도를 했다는 곳이다. 사성암이란 이름도 여기서 유래했다. 절 주변 곳곳에 성인들의 흔적이 전설 혹은 설화로 전해 내려온다. 시간이 있다면 고려 때 새겨진 마애불도 둘러볼 만하다. 마지막 비밀은 사성암 주변 수직바위 군. 오산십이대라 불리는 이 바위들은 갖가지 전설과 기기묘묘한 형태로 탐방객들의 눈길을 끌고 있다. 또한 3월이 되면 보리밭이 푸릇해지고 여기저기 매화와 산수유꽃이 피어나 한 폭의 산수화를 그려낸다.", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면", - "MNTN_NM" : "오산" + "DETAIL_INFO_DTCONT" : "순창읍에서 10km의 가까운 거리에 있는 강천산은 호남의 소금강이라고 불릴 정도로 도처에 기봉이 솟아 있고, 크고 작은 수많은 바위 사이로 폭포를 이루고 있으며, 4km에 이르는 깊은 계곡과 계곡을 뒤덮은 울창한 숲은 자연 그대로의 아름다움을 고이 간직하고 있다.원래는 생김새가 용이 꼬리를 치며 승천하는 모습과 닮았다 하여 용천산(龍天山)이라 불렸다. 또한 유서깊은 강천사와 삼인대 5층 석탑, 금성산성 등 문화유적이 산재하고, 비경이 많이 숨겨져 있다. 일명 광덕산이라고도 불리는 강천산은 1981년 국내에서 최초로 군립공원으로 지정된 곳이기도 하며, 길이 76m의 현수교가 지상 50m 높이에 설치돼 있어 웅장함을 더해주고 있다.볼거리는 11월 초순에 절정을 이루는 단풍과 4월 초순에 만개하는 산벚꽃이 유명한데, 산 입구의 강천호 주변뿐 아니라 등산로 어디에서나 즐길 수 있다. 산 암봉 아래에는 887년(신라 진성여왕 1) 도선국사(道詵國師)가 세운 강천사가 있다.이 곳의 석탑은 전라북도 유형문화재 92호로 지정되었고, 절 입구의 모과나무는 전라북도기념물 97호이다. 그 밖에 순창 삼인대(三印臺:전북유형문화재 27), 금성산성(金城山城:전북기념물 52) 등의 문화유적이 있다. 내장산(內藏山:763.5m)·백양사(白羊寺)·담양댐 등과도 가깝다.", + "MNTN_HG_VL" : "586", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 팔덕면, 전라남도 담양군 용면", + "MNTN_NM" : "강천산" }, - "longitude" : 127.4819578, - "latitude" : 35.179359300000002 + "longitude" : 127.048889, + "latitude" : 35.404167000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;섬진강 굽어오는 자라의 형상gt;섬진강은 오산을 만들었다. 섬진강이 감고 도는 오산은 마치 자라(鼇 오)의 형상을 하고 있다 해서 자라산이라고도 불린다. 지리산 노고단에서 남쪽으로 뻗은 왕시리봉능선이 섬진강에 잠기는 곳에서 섬진강 바로 건너에 있다. 마치 자라가 섬진강 물을 마시며 지리산을 파고드는 형국이다. 산줄기로 보면 광양시의 백운산 형제봉에서 서북진한 능선이 둥주리봉을 지나 이곳 오산에서 섬진강으로 마무리되는 끝자락 산으로 530.8m밖에 안 된다. 그러면서도 어엿한 산 이름을 얻고 자래봉(523m)이라는 봉우리까지 거느리고 있다.의상, 원효, 도선, 진각 네 고승이 수도하였다는 사성암(四聖庵)이 있고 오산 주변에는 기이하게 생긴 돌이 많아 소금강이라고도 하며 바위 절벽에 마애여래입상이 조각되어 있다. 산신각 앞과 그 오르는 길에 있는 신선대에서 보는 산줄기와 물줄기의 조화는 가히 일품이다. 동쪽으로 계족산과 마주하고 있다. 빨치산 연대장급인 이명래가 마지막 지휘부와 은신처로 사용했던 장소로 10여명이 둘러앉을 정도의 인공 굴이 있다. 헛굴과 본굴로 나뉘어 있고 은폐와 엄폐가 잘 되어 있어서 안내자 없이는 발견할 수 없는 요새와 같다.", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", - "MNTN_NM" : "오산 (자라산)" + "DETAIL_INFO_DTCONT" : "국립지리원 발행 지형도에도 마유산으로 표기하다가, 1973년 국토자오선 종주대가 이 산을 통과하면서 당시 대원 중 홍일점이었던 진유명씨의 이름을 따서 유명산으로 부르게 되었다.이 산은 정상에 이르는 능선이 완만하고 부드러우며, 산 전체에 갖가지 나무가 울창하여 봄부터 여름까지 하늘을 가릴 정도이고 여름이면 기암괴석과 우거진 숲이 조화를 이룬 계곡은 수량이 풍부해 절경을 이루고 있다.", + "MNTN_HG_VL" : "864", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "유명산" }, - "longitude" : 127.4819578, - "latitude" : 35.179359300000002 + "longitude" : 127.48761399999999, + "latitude" : 37.576265100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면 죽마리", - "MNTN_NM" : "오산(자라산)" + "DETAIL_INFO_DTCONT" : "춘천시에서 남쪽으로 8킬로미터 지점에 자리 잡은 산으로 일명 진병산(陳兵山)으로 불리며, 춘천시를 에워싼 산들 중 최고봉이라고 할 수 있는 대룡산(899m)에서 남서쪽으로 뻗어내린 능선이 수리봉(645m)을 솟구친 후 그 맥이 원창고개에서 잠시 가라앉았다가 마지막으로 솟은 산이다. 사계절 중 겨울에 오르기 가장 좋은 산으로 가을이면 낙엽이 무릎까지 빠질 정도로 수목이 울창하다. 김유정의 고향 실례마을을 품고 있는 산이며, 춘천의 문인들이 그의 소설 제목을 따서 만부방길, 동백꽃길, 봄봄길 등의 이름을 붙인 정겨운 등산길이 눈길을 끈다. 본래 금병산 정상은 참나무숲으로 에워싸여 조망이 어려웠지만, 최근 춘천시에서 100여 평 정도 깨끗하게 베어내 이제는 사방으로 막힘없는 조망을 즐길 수 있다.", + "MNTN_HG_VL" : "652", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신동면, 동산면", + "MNTN_NM" : "금병산" }, - "longitude" : 127.4819578, - "latitude" : 35.179359300000002 + "longitude" : 127.7452778, + "latitude" : 37.8125 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "227", - "MNTN_LOCPLC_REGION_NM" : "전라북도 군산시", - "MNTN_NM" : "오성산" + "MNTN_HG_VL" : "171", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 조천읍 신촌리, 삼양일동", + "MNTN_NM" : "원당봉(삼양)" }, - "longitude" : 126.78494689999999, - "latitude" : 36.013886399999997 + "longitude" : 126.59880269999999, + "latitude" : 33.5251229 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "930", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 홍천읍, 횡성군 공근면", - "MNTN_NM" : "오음산" + "MNTN_HG_VL" : "401", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", + "MNTN_NM" : "천호봉" }, - "longitude" : 127.92222219999999, - "latitude" : 37.605555600000002 + "longitude" : 127.2411111, + "latitude" : 36.204166700000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 횡성과 홍천사이에 뿌리룰 둔 오음산은 유독 새들이 많고 봄이 되면 들꽃잔치로 꽃내음이 산야를 뒤덮는 옛산의 풍치를 고스란히 간직한 태고의 산이다. 삼마치에서 오음산으로 이어지는 능선은 군데군데 벌목된 코스가 있고 굴곡이 심하므로 주의해야 한다. 급경사 산길을 올라 완만한 능선을 따라가다 울창한 숲길 아래 능선을 탄다. 급경사를 올라 정상에 서면 주변에서 가장 높은 산임을 알 수 있다. 정상 봉우리에는 삼각점이 있다.정상에서는 고사목 전망장소와는 비교가 안될 정도로 광활한 파노라마가 펼쳐진다. 북으로는 가리산이 멀리 사명산과 함께 조망되고, 북동으로는 공작산이 보인다. 그 뒤 멀리로 백우산과 가마봉이 보이고, 더 멀리로는 장수대 방면 안산과 설악산 대청봉도 보인다.", - "MNTN_HG_VL" : "930", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 홍천군", - "MNTN_NM" : "오음산" + "DETAIL_INFO_DTCONT" : "치악산 정상인 비로봉에서 남쪽으로 5km 지점에 솟아 있는 향로봉은 강원도 원주시와 횡성군의 경계를 이루는 산으로 교통이 편리하여 당일 산행지로 적합하다. 등산객으로 붐비는 구룡사계곡에 비해 호젓한 산행을 즐길 수 있는 곳이다.원주역에서 산행기점인 행구동까지는 버스로 20분 정도로 가까운 거리인 향로봉을 오른 후, 북쪽 비로봉이나 남쪽 남대봉 등 어느 방향으로나 산행이 가능하다. 치악산 일대의 억새군락은 단연 고둔치를 최고로 친다. 향로봉 남쪽 능선에 위치한 치악평전은 일명 '금두고원'이라고 부르는데, '금두' 라는 말은 억새밭이 햇빛을 받아 금빛 찬란하게 빛나기 때문에 붙여진 이름이다.", + "MNTN_HG_VL" : "579", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 행구동, 판부면, 신림면, 횡성군 강림면", + "MNTN_NM" : "향로봉" }, - "longitude" : 127.92222219999999, - "latitude" : 37.605555600000002 + "longitude" : 128.03416669999999, + "latitude" : 37.330833300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "조양강이 활등처럼 휘어도는 강변가에 푸른 소나무숲이 산기슭을 장식하고 있는 옥갑산은 강원도 정선군 북면과 북평면 사이에 자리잡은 오지의 산이다. 산이름은 옥으로 만든 갑옷을 두른 것처럼 보인다 하여 지어졌다 하며 지도에도 안 나오는 산이다.이 산의 해발 약 1000미터 지점에 상옥갑사가 있는데 옥갑사에서 조양강을 내려다보면 옥갑산 산영을 머금은 맑은 물빛과 섬뜩하리만치 높은 산의 위엄에 새삼 놀라게 된다. 능선상에서도 발 아래 조양강의 푸른 물줄기가 굽이쳐 흐르고, 겨울철에는 소백산능선에서도 보지 못한 아름다운 설경을 바라보고 있으면, 무념 속으로 빠져들어 갈 것만 같은 산이다.정상에 오르면 조양강과 여량, 아우라지 나루터가 내려다 보이고 여량 뒤로 고암산, 상정바위 능선이 흐릿하게 보인다. 정상에서 앞으로 직진하면 상원산, 동쪽으로는 노추산, 서쪽으로는 가리왕산이 있다.", - "MNTN_HG_VL" : "1285", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북면, 북평면", - "MNTN_NM" : "옥갑산" + "DETAIL_INFO_DTCONT" : "희양산은 충북의 괴산과 경북의 문경에 걸쳐 거대한 하나의 바위덩이로 이루어진 듯 당당한 위세를 뽐내고 있는 산이다. 정상에서 북쪽은 시루봉, 서쪽으로는 구왕봉으로 이어져 나가며 기세를 진정시키지만, 동남서쪽으로 노출된 암장능 곡클라이밍 코스로 다시 없이 좋아 이미 여러개의 코스가 개발되어 있다.병풍처럼 둘러쌓인 거대한 화강암벽은 설악산 울산바위에 필적할 만 하며, 암벽 하단부인 2백여m의 슬랩과 암벽은 위압감을 느끼기에 충분하다. 정상 남쪽 아래 유서깊은 봉암사가 있고, 옥석대와 그 주변 일대에 펼쳐진 옥석계곡의 뛰어난 정경은 등산의 또 다른 맛을 준다.", + "MNTN_HG_VL" : "996", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면,", + "MNTN_NM" : "희양산" }, - "longitude" : 128.68083329999999, - "latitude" : 37.495555600000003 + "longitude" : 128.0027001, + "latitude" : 36.715962300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "옥교산은 병풍바위 남쪽에 가마같이 생긴 봉우리라 하여 산 모양을 보고 산 이름을 지었다. 이 곳에 선녀가 옥교를 타고 와서 놀다가 갔다는 전설이 있다.밀양 옥교산을 동물에 비유하자면 꾀꼬리 정도가 적당할 것 같다. 산이 그만큼 덩치가 작고 정답게 느껴지기 때문이다. 밀양 도심에서 멀지 않은 이 산은 멀리서 보자면 `사철 발벗은' 아낙처럼 `예쁠 것도 없는' 평범한 모습 이다. 산꾼의 주목을 끌지 못하는 이런 수수한 외모가 옥교산의 매력을 더해줬다.낮게 달리는 능선길은 겨울답지 않게 폭신한 낙엽과 솔잎으로 가득 덮혀있다. 길지 않은 산행시간. 이번 산행은 가볍게 트래킹하는 기분으로 맑은 공기를 마음껏 마시고 올 수 있 는 산뜻한 코스다.산행은 교동 동사무소에 내려 포장도로를 따라 춘복타워 맨션으로 오른다. 그 맨션에서 아스팔트길로 150m 더 오르면 오른편에 교동 배수지가 보인다. 여기서부터 산행을 시작한다. 정상은 수림으로 둘러싸여 어느 쪽으로도 조망이 불가능하며, 그냥 정상임만을 짐작할 뿐이다.", - "MNTN_HG_VL" : "538", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 상동면 안인리", - "MNTN_NM" : "옥교산" + "DETAIL_INFO_DTCONT" : " 사룡산은 오봉산과 부산성으로 연결되는 군사적 요충지로서 신라시대 병사들이 이산을 거점으로적을 물리쳤다고 한다. 정상부근에는 음식을 날로 먹는 사람들이 모여 사는 곳이라고 하여 생식마을이 있고, 1300여년 전에 원효대사가 초창했다는 금정사가 있다. 한무당재에서 사룡산까지는 경주와 영천시의 경계지역이며, 낙동정맥 11구간으로 이구간에는관산과 만불산이 있으며, 대체로 오르 내림이 없는구간이나 형제지(형제목장고개)에서 사룡산까지는 계속 오르막길로 진땀을 빼는 구간이다. 전망대 바위에서 경주시 서면 소재지를 내려다 보면 아름다운 우리 강산임을 실감나게 하고,구간 구간에는 진달래 숲길과 산 벚꽃이 이어져 아름다움을 더 해준다.", + "MNTN_HG_VL" : "686", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 산내면, 영천시 북안면", + "MNTN_NM" : "사룡산" }, - "longitude" : 128.74241280000001, - "latitude" : 35.539616799999997 + "longitude" : 129.0133333, + "latitude" : 35.846388900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군에 위치해 있는 옥녀봉은 30리에 달하는 용추계곡을 끼고 있어 여름철 가족 산행지로 적합하다. 특히 곰바위 소바위 미륵바위 용세수대야 등이 몰려 있는 용추폭포 일대가 용추계곡의 백미다.옥녀봉은 마치 여자가 치마자락을 펼쳐 놓은 것 같다하여 옥녀봉이라 한다.가평읍에서 북면을 향해 2.3㎞ 정도 가다가 다리를 지나 좌회전하여 군부대 돌담을 끼고 2㎞ 정도 들어가면 용추계곡 주차장이다.차에서 내리면 바로 용추폭포가 보인다. 높이 20m의 용추폭포는 언뜻 보기엔 별 볼품이 없으나 소용돌이가 심한 소를 이루고 있어 청량감을 자아낸다.옛날 용이 승천했다는 전설을 지닌 용추폭포 옆 경사진 바위에는 용이 누웠던 자리라 일컬어지는 깊게 파인 자국이 나있다. 또 폭 1m의 용세수대야라는 바위 웅덩이가 있다.이 산은 입구에서부터 약초향이 물씬 풍긴다. 취나물과 더덕처럼 생긴 보약제 잔디등 많은 약제가 등산로 양옆으로 나 있어 약초를 캐는 재미도 솔솔하다.", - "MNTN_HG_VL" : "715", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 승안리", - "MNTN_NM" : "옥녀봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "227", + "MNTN_LOCPLC_REGION_NM" : "전라북도 군산시", + "MNTN_NM" : "오성산" }, - "longitude" : 127.4877778, - "latitude" : 37.8636111 + "longitude" : 126.78494689999999, + "latitude" : 36.013886399999997 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "금당산은 광주 풍암지구를 병풍처럼 둘러싸고 있는 산으로 북쪽으로는 옥녀봉, 서쪽으로는 황새봉을 거느리고 있다.옥녀봉에서 황새봉에 이르는 능선을 따라 걷다보면 무등산 정상인 천황봉을 비롯해 동화사터와 장불재, 광주 월드컵 경기장이 한눈에 바라보이고, 광주 시가지와 멀리 어등산이 어렴풋이 눈에 들어온다. 서쪽으로는 함평 들녘으로 떨어지는 아름다운 일몰을 감상할 수도 있다.광주시 서구청에서 8.2킬로미터에 이르는 산책로를 정비해 노약자나 어린이들도 쉽게 접근이 가능하다. 등산로 곳곳에는 쉼터와 체육시설 등을 설치하고 나무 이름표를 달아놓아 어린이들의 자연학습장으로도 좋다. 주변의 아파트 단지를 따라 많은 등산로가 개설되어 있어 작은 산이지만 다양한 코스를 즐길 수 있는 것이 장점이다.", + "MNTN_HG_VL" : "304", + "MNTN_LOCPLC_REGION_NM" : "광주광역시 서구 풍암동", + "MNTN_NM" : "금당산" + }, + "longitude" : 126.88861110000001, + "latitude" : 35.117777799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "\"보령 시가지를 동남쪽으로 둘러서 있는 산이 성주산과 옥마산이다. 성주터널이 생기기 전 성주와 부여 쪽으로 가려면 옥마산을 통과하는 구절양장을 고갯길을 넘어야 했다. 비포장도로인 옛길을 가쁜 숨을 몰아쉬고 오르다보면 보령시가지가 한눈에 내려다보이는 정자가 옥마정이다.옥마정에서 성주로 향하는 내리막길에서 다시 산을 타고 오르면 보령 행패러글라이딩 활공장과 만난다. 이곳은 항공 스포츠를 즐기는 이들에게 새로운 메카 구실을 하는 곳이다. 행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하여 자세한 안내를 받을 수 있다.소요 시간 :180분 (구간별, 코스별로 다름)최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 옥마정에서 보는 시내전망, 활공장(행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하면 자세한 안내를 받을 수 있다)", - "MNTN_HG_VL" : "602", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", - "MNTN_NM" : "옥마산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "601", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "불기산" }, - "longitude" : 126.6350923, - "latitude" : 36.317708400000001 + "longitude" : 127.4525, + "latitude" : 37.8030556 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "보령시내로 들어서면 병풍처럼 동남방으로 길게 뻗어 내린 해발 600m규모의 커다란 산줄기가 한눈에 들어온다. 이 산줄기는 차령산맥의 끝 부분으로 성태산, 문봉산, 성주산, 옥마산, 잔미산이 연결되어 보령시 웅천읍 대천리까지 이어지다가 화락산을 한 점으로 남기고 서해바다로 사라진다. 이 중 해발 601m의 옥마봉을 주봉으로 하는 옥마산은 보령시 명천동과 남포면을 호위하는 모습으로 우뚝 솟아있는데, 이곳에 중계탑이 설치되어 있어 누구든지 쉽게 찾을 수 있다.옥마산(봉)이라는 이름은 신라 비운의 마지막 임금인 경순왕과 화살 맞은 옥빛 말의 전설과 관련하여 전해지고 있다. 옥마봉에는 패러글라이더 이륙장이 있어 새처럼 날며 산과 바다의 조화된 아름다움을즐기려는 항공스포츠 동호인들이 전국에서 찾아오는 이름난 곳이기도 하다.", - "MNTN_HG_VL" : "601", - "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시 성주면, 명천동", - "MNTN_NM" : "옥마산" + "DETAIL_INFO_DTCONT" : "백운산(시흥)은 바라산, 광교산과 능선으로 연결되는 이웃한 산으로 능선은 매우 한적한 편이다. 경기도 의왕시의 백운저수지의 뒷산인 해발 567m의 산으로 서울특별시에서 가까워 찾기 쉬운 산이다. 백운 저수지에서 산행할 경우 임도를 이용한 한적한 산행이 가능하다. 주능선 길은 산행하기에 좋으며 소나무가 많다.", + "MNTN_HG_VL" : "567", + "MNTN_LOCPLC_REGION_NM" : "경기도 시흥시, 용인시, 수원시", + "MNTN_NM" : "백운산" }, - "longitude" : 126.6350923, - "latitude" : 36.317708400000001 + "longitude" : 127.0175, + "latitude" : 37.353055599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충청남도 예산군 덕산면에 위치한 옥양봉은 석문봉에서 약2km떨어진 곳에 있는 해발 621m의 봉우리로, 석문봉과 산행시점이 같기 때문에 옥양봉과 석문봉을 연결하여 산행하기가 쉽다. 석문봉이나 옥양봉 모두 암봉으로 이루어져 있으나, 분명히 다른 느낌을 주는데 , 석문봉의 경우는 오르고 내리는 등산로가 계곡코스이며, 옥양봉의 경우는 모두 능선으로 되어있기 때문에 분명한 차이를 느낄 수 있다.석문봉은 정상부만 암릉을 느낄 수 있지만, 옥양봉의 경우는 바위 전망대가 곳곳에 있고 석문봉에 비해 훨씬 아기자기하다. 하지만 계곡 코스가 없기 때문에 물이 없다는 점이 단점이다. 올라갈 때는 관음전코스로 올라가는 것이 산행의 재미를 높일 수 있다. 관음전으로 올라서는 길은 가을 냄새가 물씬 풍기는 숲속길로 되어있어 산책로 같은 느낌이 든다. 관음전 아래 삼거리부터는 능선이 시작되는데 많은 구간에 로프가 설치되어있고 바위 전망대가 몇 군데 있다. 이중에서도 옥양봉 정상부에 있는 암봉위에 올라서서 내려다보는 경치가 제일이다. 상가리가 내려다보이고 주변 경치가 한눈에 들어온다.", - "MNTN_HG_VL" : "621", - "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", - "MNTN_NM" : "옥양봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "857", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 재산면 동면리", + "MNTN_NM" : "조산봉" }, - "longitude" : 126.61058370000001, - "latitude" : 36.731824500000002 + "longitude" : 129.01527780000001, + "latitude" : 36.8313889 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전남 화순군 동복면에 위치한 옹성산은 거대한 암봉군으로 이루어져 있다. 항아리를 엎어놓은 듯한 바위가 여러 개 있어 옹성산이라 불렀으며, 암질이나 솟은 모양새가 진안의 마이산과 비슷하지만, 마이산처럼 하늘을 향해 치솟아 오르지 못해 외면당해 왔다고 볼 수 있다.그러나 산행을 해보면 옹성산의 암봉들이 그 절경을 자랑하는데 독아지봉이나 쌍바위봉, 문바위, 옹성암터 등 다른 산에서는 쉽게 찾아볼 수 없는 비경들이 숨어 있어 자연조각공원이라 일컬어도 손색이 없다. 바위산이면서도 곳곳에 샘도 많고 쉴 곳도 많아 뜻밖에도 좋은 산행지임을 알 수 있다.이곳에는 산성이 있는데 철옹산성이라 부른다. 고려 말 왜구의 침입에 방비하려고 쌓았다고 전하며 입암산성, 금성산성과 함께 전남의 3대 산성으로 불리기도 한다. 임진왜란 시에는 이 고을 현감을 지내고 진주성에서 순국한 황진장군이 군사를 훈련시킨 곳이라 하며 동학이 활발한 때에는 오계련이 이곳을 증축하였다고 한다. 서울에 있는 몽촌토성보다 두 배 가량 큰 것으로 조사되었다.", - "MNTN_HG_VL" : "573", - "MNTN_LOCPLC_REGION_NM" : "전남 화순군 동복면", - "MNTN_NM" : "옹성산" + "DETAIL_INFO_DTCONT" : "공덕산은 백두대간이 포암산(961)과 조령산(1017)으로 남하하다가 대미산에서 지맥을 갈래쳐 여우목고개를 지나 일군 산이다. 교통이 불편해 아직 원시림 그대로의 거친 수림을 간직한 산으로 산 중턱 바위사면에 불상이 조각되어 있어 사불산이라고도 불린다.이름에서도 불교적 색채를 느낄 수 있듯이 이 산은 불교를 전파한 고승들과 오랜 인연을 맺고 있다. 신라 진평왕때 창건된 대승사는 1400여년의 역사를 지켜오면서 수많은 고승대덕을 배출하였다. 대웅전에는 보물 575호인 목각탱화와 관련문서가 모셔져 있고 선실에는 보물 991호인 금동보살좌상이 있다.또 멀지 않은 거리에 비구니승들의 수도처인 윤필암이 있어 쉬엄쉬엄 오르는 수행코스로도 손색이 없는 산이다.등산로 입구에는 옛날 중국을 다녀온 나옹이 기념으로 심었다는 아람드리 전나무가 반겨주고 산행내내 아람드리 참나무와 소나무가 반겨주는산, 종주중 반정도는 육산으로서 울창한 나무숲에 가려 원시림은 때묻은 속세의 모든 일들을 잊어버리게 하고 나머지 반은 노송과 함께 어우러진 암릉길은 속세에 나가 어려운 풍파를 헤쳐나가기 위하여 사전 수련을 하듯이 전개되는 바위길의 묘미를 볼 수 있는 산이다.즉 육산과 바위산위 공존하는 산으로 대승사에서 남쪽 능선을 따라 공덕산 823봉까지는 길이 아주 좋은 육산으로 울창한 숲에 가려 조망이 없어 실망을 하는 산이나 823봉부터 윤필암 하산길 까지는 노송과 바위가 어울려 한폭의 동양화를 연출하는 상반된 얼굴을 보이는 산이다.", + "MNTN_HG_VL" : "913", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산북면 동로면", + "MNTN_NM" : "공덕산" }, - "longitude" : 127.1329367, - "latitude" : 35.117416200000008 + "longitude" : 128.2832276, + "latitude" : 36.7557683 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남녘 해안가에 자리잡은 이 산은 높이에 비해 산세가 굉장히 웅장하다. 능선에는 상사바위봉, 섬바위봉, 기차바위, 형제바위 등 빼어난 암봉이 장관이고 아슬아슬한 암릉길이 있으며 억새 능선길, 남해 푸른 바다의 장쾌한 조망 등 아름다움을 두루 갖춘 명산이라 할 수 있다. 또한 높고 낮은 봉우리가 아흔아홉 개로 형성되어 구구연화봉이라 전해지기도 하며 5월에는 철쭉이 만개하면 온 산이 진홍색이로 물들어 장관을 이룬다.산의 형상이 거대한 용 한 마리가 누워 있는 모습과 흡사하다하여 와룡산이라 불려졌다고 하며 고려의 현종이 잠룡시(임금이 되기 전의 시절)에 놀던 곳이기 때문에 이름 지어졌다고 한다. 와룡산 기슭의 백천골은 임진왜란 때 승병들이 왜군과 싸운 곳이라는 기록도 있다. 백천골에서 와룡산 등성이를 따라 바닷가로 내려오면 성문등, 파병산, 난곡, 퇴병산 등 임진란과 관련 있는 지명이 산재해 있는 것을 보면 당시의 상황을 짐작해 볼 수가 있다.", - "MNTN_HG_VL" : "801", - "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시 사천읍", - "MNTN_NM" : "와룡산" + "DETAIL_INFO_DTCONT" : "환희산은 진천군 문백면과 충청남도 천안군 동면을 경계로 위치해 있다. 환희산이란 이름은 말그대로 기쁨을 안겨주는 산이라는 뜻에서 그렇게 불려진다.야트막한 산을 산책 삼아 오르내리며 환희산이 안겨주는 기쁨으로 몸도 마음도 건강해질 수 있을 것이다. 환희산은 등산시간이 짧아 등산으로 인한 피로감은 전혀 느껴지지 않는다. 삼림욕을 하듯 천천히 산을 즐긴다면 맑은 공기가 가슴을 탁 트이게 한다.", + "MNTN_HG_VL" : "402", + "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면 봉죽리", + "MNTN_NM" : "환희산" }, - "longitude" : 128.1139033, - "latitude" : 34.986448800000012 + "longitude" : 127.402422, + "latitude" : 36.800996699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "295", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "와룡산" + "DETAIL_INFO_DTCONT" : "전북 완주군 구이면과 임실군 운암면에 걸쳐있는 오봉산과 국사봉은 옥정호가 있어 그 존재가치를 인정받는 산이다. 임실군 강진면과 정읍시 산내면에 걸쳐있는 옥정호의 비경은 무엇보다도 외안날을 중심으로 피어오르는 아침 물안개다. 옥정호는 일제 강점기인 1925년 동진수리조합에서 시공에 들어간 관개용댐에서 비롯됐다. 당시 섬진강 상류인 정읍군 산외면에서 서남쪽으로 갈라져 나와 황해로 흘러들어가는 동진강 유역이 대부분 평야인데 가뭄이 심각했다. 그래서 수자원이 풍부한 섬진강 상류를 막아 반대편인 정읍군 치보로 넘겨 계화도와 호남평야에 농업용수를 제공하기 위해 1929년 운안댐이 준공됐다. 이 사업은 3공화국까지 이어졌고 1965년 섬진강 다목적댐이 완공되면서 운암댐은 수몰되고 전북에서 제일가는 인공호수가 탄생한 것이다. 옥정호란 이름은 당시 댐이 위치한 강진면 옥정리에서 유래한다.옥정호를 가장 쉽게 조망할 수 있는 방법은 국사봉전망대 휴게소로 가는 것이다. 그리고 사진 촬영을 위한 최적의 포인트는 휴게소에서 20분이면 오를 수 있는 옥정호전망대다. 외안날을 중심으로 펼쳐지는 옥정호를 조망하는 이곳은 주말에는 1시간 전에 올라야 자리를 차지할 수 있을 정도로 사진가들이 붐빈다. 정상에 오르면 옥정호 주변을 조망할 수 있을 뿐 아니라 멀리 마이산까지도 보인다.", + "MNTN_HG_VL" : "513", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 구이면, 임실군 운암면", + "MNTN_NM" : "오봉산" }, - "longitude" : 128.51053659999999, - "latitude" : 35.869378900000001 + "longitude" : 127.1325344, + "latitude" : 35.644214499999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "완택산은 연하리와 동강변인 삼옥리 사이에 위치하고 있다. 산세는 동고서저, 즉 주능선을 경계로 동쪽 연하리 방면은 급경사에 절벽이 많고, 서쪽 동강 방면은 완만한 산세를 이루고 있다. 산세가 이렇듯 그 옛날 완택산은 천혜의 요새였다는 전설이 전해지고 있다.주능선 동쪽은 수직절벽이 대부분이어서 자연성곽을 이루고 서쪽은 동강 물줄기가 자연적인 방어선을 이루고 있다. 그래서 완택산은 옛날 예맥의 땅이었다는 얘기가 전해지며, 퉁구스식 방법으로 축성한 산성흔적이 산자락 곳곳에 조금씩 남아있다.완택산 등산로는 급경사를 이룬 동쪽 연하리 방면에서 오르내리는 코스가 일반적이다. 그러나 요즘은 동강변 삼옥리에서 완만한 경사를 이룬 능선과 계곡 코스가 인기 있다.", - "MNTN_HG_VL" : "918", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", - "MNTN_NM" : "완택산" + "DETAIL_INFO_DTCONT" : "고성 동쪽의 거류면에 솟은 거류산은 고성의 진산이다. 기암과 청송, 진달래 산성 등 야산이 갖출 수 있는 조건들을 두루 갖추고 있다. 정상 가까이에 약수터가 있고 조망이 일품으로 다도해가 시원하게 보인다. 건너편 들녘에는 구절산이 보이고, 고성 전역과 한려해상의 전경이 한눈에 들어오는 산정에는 2천여 년 전 소가야 때 신라의 침공을 막기 위해 쌓은 거류산성의 흔적이 남아 있다. 이 성은 소가야 마지막 왕이 신라의 침입 때 피신처로 사용하였으나 신라가 가야를 합병함에 따라 폐성되었지만 곳곳에 산성의 자취가 남아 있고, 지금은 유적지로서 복원되었다. 소가야 때는 태조산(太朝山)이라 불렀고 조선 초기에는 거리산(巨吏山)으로, 조선 말엽에 거류산으로 부르게 되었다. 또한 거류산이 깎아지른 듯 삼각형 모양으로 서 있는 모습이 스위스의 마터호른을 닮았다고 해서 일명 고성의 ‘마터호른’으로 불리기도 한다.", + "MNTN_HG_VL" : "572", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 거류면", + "MNTN_NM" : "거류산" }, - "longitude" : 128.55202180000001, - "latitude" : 37.2109405 + "longitude" : 128.37976710000001, + "latitude" : 34.995313600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "왕치산은 등산로가 대부분 임도로 이뤄져 있어 길을 잃거나 할 염려가 없으면서도 사람의 발길이 거 의 닿지 않은 우거진 숲길을 거닐며 한적한 산행을 즐길 수 있다. 고사리 등 산나물과 자생 식물이 잘 보존돼 있고 산과 어우러진 월루마을의 풍광 또한 색다른 감흥을 불러일으킨다. 산행기점인 임계-여량리간 42번 국도상의 큰너그재는 해발760m의 고지대로 정상과의 고도 차가 200m을 조금 넘는 수준이어서 부담 없이 산을 오를 수 있다.큰너그재에서 산행을 시작한다. 넓지 않고 인적이 없어 등산로와 같은 임도를 타고 정상에 도달하거나 임도 옆 능선을 타고 정상에 오르는 방법이 있다. 여기서 왼쪽 임도를 따라가면 왕치산산행이 백미라 할 월루 마을의 아름다운 풍광을 감상할수 있다. 월루마을을 둘러보고 계곡을 따라 남하하는 임도를 타면 느라방죽이 나타나고 잠시후 골지천의 비경과 천 주변의 유적들을 만날 수 있다. 반천초등학교 옆의 구용소와 숙종때 공조참의를 지낸 이자선생이 노닐던 구미정, 그리고 고수당, 난포정, 장찬성지 등이 유명하다. 골지천은 여름철 물놀이를 즐기기에 제격인 곳이다.", - "MNTN_HG_VL" : "900", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 임계면", - "MNTN_NM" : "왕치산" + "DETAIL_INFO_DTCONT" : "시랑산은 충북 제천시 백운면과 봉양읍의 경계를 이룬다. 백운산을 모산으로 하고 있는 시랑산은 높이는 나즈막하나 아기자기한 산행의 맛을 즐길 수 있다. 산을 오르면서 곳곳의 지명에 얽힌 뒷이야기들을 따라가다 보면 금새 정상에 다다른다. 정상에서 내려다보이는 산행들머리인 박달재에서는 금방이라도 `울고넘는 박달재'의 노랫소리가 들려올 것만 같다. 금봉이와 박달이의 애절한 사랑이야기와 거란족 10만 대군을 섬멸시킨 려의 명장 김취려장군의 승전을 상기하며 산행으로 인해 가빠진 호흡을 가다듬는다.눈꽃과 상고대가 곱게 피어난 정수리에서 북쪽으로 하산길을 이어간다. 조금 내려가면 쉬어가기에 적당한 널찍한 공터를 만나게 된다. 봄이나 가을이면 둘러앉아 간식을 권하며 산꾼들의 우정을 나누기에 안성맞춤인 명당이다. 조금 더 내려가면 바위지대를 만나게 된다. 눈이 쌓인 겨울에 미끄러지면 다치기가 쉽상이니 조시조심 지나가야 한다.조금 더 내려가면 아름드리 소나무와 참나무가 마주서서 정답게 이야기를 나누는 일주문을 지나게 되고, 북쪽 산길을 계속 이어가면 정상을 출발한 지 50분이면 단군비석에 도달한다. '국조단둔대황조성령(國祖檀君大皇祖聖靈), 삼선사령영사령(三仙四靈令司靈), 백운산성화신령(白雲山聖化神靈) 국사산왕산신지령(國祠山王山神之靈)' 이라고 쓰여진 세 개의 비석이 몇 그루의 노송 및 바위와 어우러져 신비로운 분위기를 연출한다. 이곳에서 조금 더 내려가면 그 유명한 박달재에 내려서게 된다.기나긴 세월동안 충주와 제천을 잇는 국도로서 숱한 애환이 서린 박달재이건만 이제는 고개 밑으로 시원스런 터널이 뚫려 인적이 드문 쓸쓸한 고갯길이 되고 말았으니 격세지감을 절로 느끼게 된다.", + "MNTN_HG_VL" : "691", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면, 봉양읍", + "MNTN_NM" : "시랑산" }, - "longitude" : 128.79443470000001, - "latitude" : 37.486439500000003 + "longitude" : 128.05472219999999, + "latitude" : 37.126666700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태백산맥에서 동남쪽으로 갈라져 나온 산줄기가 경주시 단석산(829m)을 지나 구룡산·반룡산으로 벋으며 솟은 산으로 청도 지방을 동과 서로 나누는 기준이 된다. 마을주민들이 흔히 마음산이라고 부르는 북쪽의 선의산(756.4m)과는 능선으로 이어진다. 비가 내려 산이 운무에 덮이는 광경이 아름다워 청도팔경의 하나로 꼽힌다.용각산은 용에 관한 유래가 많은 산으로 용이 물을 마셨다는 용샘, 용마가 태어나지 못하게 쇠말뚝을 박았다는 용맥, 용의 발자취가 있었다는 용바위 등 용에서 유래되어 심지어 바위샘까지도 용 자가 붙어 있다. 갖가지 용의 전설은 용을 숭배하는 토속 신앙의 표현이다. 또한 용맥은 용각산의 모습이 일본 후지산과 너무 흡사하여 임란 전에 일본에서 밀정을 파견하여 마을에 큰 인물이 나는 것을 미리 막기 위해 산정에다 쇠막뚝을 박았다는 이야기가 지금도 전해지고 있다.", - "MNTN_HG_VL" : "693", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군, 경산시 남천면", - "MNTN_NM" : "용각산" + "DETAIL_INFO_DTCONT" : "충주시 앙성면에 위치한 국망산의 옛이름은 금방산이었다.국망산으로 불리워지게 된 세월은 그리 길지않다. 임오군란 당시 명성황후가 이곳으로 피난을 오게 됐다. 피난을 와서 한양소식이 궁금한 황후는 매일 이 산마루에 올라가 한양을 바라보며 초조해 했었다는데서 국망산이라 불려지게 된 것이다.당시 황후는 충주목사인 민옹식의 집으로 피난을 가기로 하였으나 피난지가 알려지면 신변이 위험할 것 같아 이곳으로 피한 것이다. 황후가 피신한 집은 가난한 초가집이었는데 그 집에는 이도령이라는 총각이 홀어머니를 모시고 나무장사를 하면서 살고 있었다. 이도령은 가난하였으나 황후를 극진히 대접하였다.황후가 피난생활을 마치고 환도한 후 이 도령을 불러 사례하고자 하였으나 사양하여 황후는 이 도령에게 음성군수를 시켰다. 이도령은 군수 재직중 선정을 베풀어 주민들로부터 칭송을 받았으며 그 후 5개 마을의 군수를 지냈다. 마을에서는 이 도령의 집을 이음성집이라 부르고 그의 집터를 대궐터라고 부르고 있다.", + "MNTN_HG_VL" : "770", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 앙성면 본평리", + "MNTN_NM" : "국망산" }, - "longitude" : 128.7666667, - "latitude" : 35.6988889 + "longitude" : 127.73527780000001, + "latitude" : 37.0777778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "행정구역상으로 인천광역시에 속해 있는 백령도는 서해 최북단에 위치한 섬이다. 과거에는 안보상의 이유로 출입통제가 심했으나 현재는 비교적 자유로워졌고 쾌속여객선이 취항을 시작한 이래 해상관광명소로 급부상 하게 되었다. 백령도에는 산이라고 해야 해발 150m를 넘지못하는 산이 네댓 개 있을 뿐이다. 게다가 그 중에서도 가장 높은 북포리의 업죽산은 산행금지구역이고, 기껏해야 백고지와 용기원산, 그리고 두무진산이 전부이다.", - "MNTN_HG_VL" : "136", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군 백령면", - "MNTN_NM" : "용기원산" + "DETAIL_INFO_DTCONT" : "5만분의 1 지형도에는 날 비(飛)자로 표기되어 있으나 이 지역 주민들 말에 의하면 옛부터 이 산위에 구름이 걸려 있으면 꼭 비가 왔다고 해서 우리말 `비'를 붙여 비산이라 부른다고 한다. 또 일설에 의하면 서만이강이 범람했을 때 이 산 꼭대기에 배가 걸려 들어 배거리산이라 불리기도 했다. 이 서만이강은 이름도 묘하거니와, 강의 상류도 주천강이요 하류도 주천강이어서 사람들을 어리둥절하게 만들곤 한다.굽이구비돌아올라가는 솔치고개도 옛모습을 보기는 어렵다. 솔치고개밑으로 터널을 뚫어놓았기 때문에 자동차들이 솔치고개를 넘지를 않기때문이다. 이 솔치고개는 이름 그대로 송림이 울창하게 숲을 이루고 있어 지어진 이름이다. 한아름 두아름되는 노송이 늘어서있고 비산으로 가는 길은 소나무숲 길이다. 이길은 사람에게 그리도 좋다는 피톤치드를 온몸으로 느끼는 삼림욕 숲속길이다.봄이면 진달래, 복숭아, 산벚꽃이 지천으로 피어난다는 버들치 마을은 이름 그대로 아름다운 풍광에 고운 인심을 자랑하는 전형적인 산마을이다.정상에 올라 하산길로 들어서면 북으로 펼쳐지는 구룡산을 비롯하여 멀리 백덕산까지도 조망된다.", + "MNTN_HG_VL" : "694", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 영월군", + "MNTN_NM" : "비산" }, - "longitude" : 124.7436111, - "latitude" : 37.959444400000002 + "longitude" : 128.21735760000001, + "latitude" : 37.278231599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "모산동과 송학면 경계에 위치한 해발 871미터의 용두산은 삼한시대 축조된 의림지와 제2 의림지, 솔밭공원을 남녘 자락에 펼치고 있는 제천의 진산이다. 산기슭에서 흘러내린 물이 용두천을 이루며 의림지로 흘러든다. 북서쪽으로는 석기암산(906m)과 감악산(920m)이 이어진다. 제천 시내의 산이어서 교통이 편리하고 찾기가 수월해 주말이면 제천 시민들이 즐겨 찾는다.용두산 산행 코스는 크게 세 군데로 나눌 수 있다. 피재, 물안이골, 석기암봉 코스 중에서 사람들이 가장 많이 찾는 코스는 피재 방면이다. 산행은 솔밭공원 앞 주차장에서 시작한다. 수령 수백년을 헤아리는 노송 백여 그루가 숲을 이룬 솔향기 가득한 공원에는 여러 점의 조각이 놓여 있어 운치가 있다. 의림지 북쪽으로 약 5백미터 지점에 자리한 이 솔밭공원을 지나면 진초록 못물이 더욱 맑은 제2 의림지가 있다. 용두산 등산로는 그 위편에 위치한 청소년수련원 오른쪽으로 나 있다. 의림지와 용두산산림욕장 등을 연계해 산행하면 다양한 볼거리와 편안한 휴식을 즐길 수 있다.용두산 정상은 매우 널찍한 헬기장으로, 주위에 벤치가 10여개 설치돼 있다. 헬기장 한쪽 끄트머리에는 ‘용두산 해발 873m’라 새긴 아담한 정성석이 있다. 정상에서 바라보는 조망은남동쪽을 제외하고는 나무가 우거져 좋지 않다. 서북쪽으로 석기암(906m)과 감악산(920m) 산줄기가 이어진다.", - "MNTN_HG_VL" : "871", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면", - "MNTN_NM" : "용두산" + "DETAIL_INFO_DTCONT" : "백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산은 험준한 암릉으로 이루어진 산이다.산 아래에서 볼 때 정산 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입금지구역으로 주의를 요하는 곳이다.백운산과 국망봉 사이에 위치한 신로봉에서 서쪽인 이동면 장암리 방면으로 뻗어내린 능선 상에 우뚝 솟은 가리산(774.3m)은 험준한 암릉으로 이루어진 산이다. 산 아래에서 볼때 정상 주위는 두 개의 암봉으로 되어 있으며, 정상에서 서쪽과 북쪽 지역은 민간인 출입 금지구역으로 주의를 요하는 곳이다.정상에서의 사방 조망은 경기 제일의 고봉인 화악산, 명지산에 이어 세번째로 높은 국망봉(1,168m)과 신로봉으로 이어지는 능선이 파노라마를 이룬다. 도평교를 하산 지점으로 잡을 경우 하산길은 지루함을 느낄만큼 계곡길의 연속이다.가리산이란 명칭은 현재 폐광된 산 입구의 가리광산에서 유래됐다는 설이 전해진다. 가리란 바로 비료의 주성분 가운데 하나인 칼륨의 일본식 발음이다.", + "MNTN_HG_VL" : "774", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면 장암리", + "MNTN_NM" : "가리산" }, - "longitude" : 128.2108604, - "latitude" : 37.203046100000002 + "longitude" : 127.403469, + "latitude" : 38.037748999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용문산은 경기도에서 네 번째로 높은 산으로 기암괴석과 고산준령을 고루 갖추고 있는 산이다. 본디 미지산이라는 이름으로 불리었는데, 조선을 개국하고 이태조가 등극하면서 '용문산'이라 바꿔 부르게 되었다고 한다.정상은 입산통제 지역으로 우회하는 등산로가 이용되고 있다. 신라 선덕여왕때 창건한 용문사 사찰앞에는 높이 62m, 둘레 14m에 달하는 은행나무(천연기념울 제 30호)가 발걸음을 멈추게 한다.", - "MNTN_HG_VL" : "1157", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면ㆍ옥천면", - "MNTN_NM" : "용문산" + "DETAIL_INFO_DTCONT" : "성지봉은 특히 유산리에서 정상으로 이어지는 계곡과 밤골에서 주능선에 이르는 계곡이 볼만하다. 계곡이 넓어 수량도 많고 계류가 맑다. 금물산의 최고봉인 성지봉은 금물산 정상에서 서남으로 가지를 친 능선으로 그 본래의 산맥은 금물산 정상에서 서남으로 뻗어나가고 있다.경기도 양평군 청운면과 강원도 횡성군 서원면의 경계를 이루는 성지봉 (791m)은 산 이름에서 나타나듯이 천주교와 관계가 깊은 곳이다. 조선 순조 원년(1801년)의 신유 박해와 고종 3년 (1866년) 병인양요, 고종 8년 (1871년) 신미양요 등으로 극심하게 탄압 받았던 천주교 신도들이 이곳 성지봉으로 숨어 들었다고 한다.직행버스는 성지봉 입구에 정차하지 않으므로 청운에서 횡성 방향으로 1.5km 못 미친 풍수원에 하차 하여야 한다. 풍수원 마을 가장 윗쪽에 강원도 유형문화재 제 69호로 지정된 풍수원 천주교회가 자리잡고 있다. 이 교회가 옛날 천주교인들의 피난처였던 것이다. 천주교회는 고종 27년 (1888년) 프랑스인 르메르이신부가 초가집 사랑방에서 초대 신부로 부임해 한국에서 네 번째 천주교회로 출발한 곳으로 유명하다.", + "MNTN_HG_VL" : "791", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 청운면, 강원도 횡성군 서원면", + "MNTN_NM" : "성지봉" }, - "longitude" : 127.5518582, - "latitude" : 37.5622124 + "longitude" : 127.84222219999999, + "latitude" : 37.5416667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용봉산은 381미터에 불과한 낮은 산이지만 산 전체가 기묘한 바위와 봉우리로 이루어져 충남의 금강산이라 불릴 정도로 아름답다. 보는 위치에 따라서 각각 다른 수묵화를 보는 듯 달라지는 풍경을 즐길 수 있다. 또한 정상에서의 예당평야와 수덕사를 품은 예산 덕숭산, 서산 가야산 조망이 시원스럽다.용봉산이라는 이름은 용의 몸에 봉황의 머리를 얹은 형상이라는 데서 유래했다. 남쪽 중턱과 서쪽 산록에 완만한 경사가 길게 이어지고 군데군데 소나무 군락이 있다. 장군바위와 백제 고찰인 용봉사, 보물 355호인 마애석불 등 많은 문화재가 곳곳에 남아 있다. 옛 문헌에 영봉사라고 기록되어 있는 용봉사는 지금 대웅전과 요사체 2동만이 남아 있다. 하지만 고려시대에는 절 크기가 아흔아홉채에 달하고 불도를 닦는 승려수가 천여명에 이를 만큼 큰 절이었다고 한다. 또 용봉사에는 강마촉지인을 한 석가모니를 그린 탱화가 있다.용봉산을 낀 홍성 일대는 충절의 고향답게 만해 한용운 선사, 백야 김좌진 장군, 최영 장군, 사육신 성삼문 등의 생가와 9백의총, 위인들의 삶의 흔적과 백제 부흥의 마지막 보루였던 임존성 등 역사 유적지가 도처에 남아 있다. 더욱이 최근 개발된 홍성온천이 예산의 덕산온천과 더불어 온천 관광지로도 이름이 높다.", - "MNTN_HG_VL" : "381", - "MNTN_LOCPLC_REGION_NM" : "충청남도 홍성군 홍북면ㆍ예산군 덕산면", - "MNTN_NM" : "용봉산" + "DETAIL_INFO_DTCONT" : "기백산은 1983년 함양군이 군립공원으로 지정했으며, 옛 이름은 지우산(知雨山)이다. 기백산 자락의 거창, 안의 지역은 기백산의 날씨 변화에 따라 비가 내릴 것을 미리 알 수 있었다고 한다. 백두대간인 덕유산 능선이 무룡산, 삿갓봉, 장수 덕유산으로 구비쳐오다 남덕유에서 갈라져 남동 방향으로 꺾어진 뒤 월봉산, 금원산을 일으킨 다음 거창 쪽으로 깊숙이 들어와 솟았다. 산 고스락 남쪽에 원추리와 싸리나무군락으로 이루는 기백평전이 펼쳐져 있으며 지우샘이 솟아 맞은편 황석산과 수망령에서 시작한 물줄기와 합하여 안의 지우천을 이룬다. 지우천이 흐르는 장수동은 옛 안의 삼동 가운데 하나인 심진동으로 지금은 용추사 계곡으로 더 알려져 장수사 조계문, 용추폭포, 용추사들의 명소가 널려있다. 또 기백산 안봉에서 솟기 시작한 물줄기는 고학천 용폭을 이루고 쌀다리와 용원정 명소를 간직하고 있다.", + "MNTN_HG_VL" : "1331", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 위천면·함양군 안의면", + "MNTN_NM" : "기백산" }, - "longitude" : 126.649249, - "latitude" : 36.6435581 + "longitude" : 127.7850818, + "latitude" : 35.709718100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "신선봉에서 북진하는 능선에서 서북쪽으로 갈라져 나간 지능선에 마지막으로 솟아오른 용산봉은 단양군 남한강변인 가곡면 사평리, 보발리, 대대리 사이에 서있다. 용산봉은 어머니산인 신선봉과 비슷하다. 신선봉을 멀리서 또는 산 아래에서 보면 산세가 육산 같지만 정상이 쇠뿔 돋아난 듯 바위로 되어 있는 것처럼 용산봉도 주능선에 올라보면 바위지대가 노송 사이에 펼쳐지기 때문이다. 또한 진달래군락이 어우러져 아름답다.산행 초반부터 깔딱고개를 만나 힘을 쏟는가 하면 암릉지대를 미끄러지며 올라 정상에 서면 조망이 장관이다. 4평 정도의 공터에 국유지 표지석이 있는 정상에서 동서남북으로 이어지는 파노라마를 만나게 되는데 소백산 주능선, 국망천계곡, 제2연화봉, 도솔봉, 황장봉산, 문수산, 대미산, 충주호, 남한강, 도담삼봉, 삼태산, 태화산 등이 도열한 모습이 숨을 멈추게 한다.", - "MNTN_HG_VL" : "944", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "용산봉" + "DETAIL_INFO_DTCONT" : "인천 남구 문학동에 있는 높이 217미터의 문학산은 학산이나 남산이라고도 불린다. 지금은 들어볼 수 없지만 예전에는 산봉우리가 마치 사람이 배꼽을 내놓고 누워있는 모양을 하고 있어 배꼽산이라고 했다. 하지만 현재는 그 형세가 많이 달라졌을 뿐만 아니라 기억하고 있는 이 조차 드물어 문학산이라고 부른다.문학산 봉우리와 노적봉 사이에는 관교동에서 청학동으로 넘어가는 긴 고갯길이 있는데 이 길을 삼호현, 삼해주현, 사모현 등으로 부른다. 백제 근초고왕 때(372년) 중국으로 가는 바닷길 한나루로 가는 길목으로 1600년 전 고개를 넘으면서 전송나온 사람들과 이별하던 곳이라고 한다. 삼호현은 이곳까지 따라온 가족이나 친지들이 능허대 쪽으로 멀어져 가는 사신들이 무사히 잘 다녀오기를 빌면서 크게 세 번 불렀다 해 생긴 이름이다.문학산 정상은 산의 동남부에 위치한 군사지역이며, 산지의 서쪽 봉우리는 연경산으로 정상부에 ‘연경정’이 있다. 정상부 및 남서쪽은 군사지역으로 일반인의 출입이 통제되고 있다. 산의 북쪽은 제2경인고속도로 관통, 동쪽은 문학월드컵경기장이 있다.", + "MNTN_HG_VL" : "217", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 남구 문학동", + "MNTN_NM" : "문학산" }, - "longitude" : 128.4241667, - "latitude" : 37.024999999999999 + "longitude" : 126.67919689999999, + "latitude" : 37.431407100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "462", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", - "MNTN_NM" : "용소봉" + "DETAIL_INFO_DTCONT" : "백두대간에서 갈라진 산줄기가 경기도에 이르러 화악산과 명지산 등 고산을 일구고, 운악산과 천마산으로 이어져 북한강가에 이르러 빚어놓은 산이 문안산이다.산은 낮으나 북한강가에 자리잡고 있어 경치가 뛰어나고 험한 곳이 없어 어린아이를 동반한 가족 산행지로 적합한 곳이다. 봄에는 능선길의 진달래가 볼만하고 하산길엔 북한강이 한눈에 들어온다 .문안산이라는 이름의 유래는 날씨가 좋은 날 정상에 오르면 서울의 문안까지 환히 보여서 붙은 이름이라고 한다.", + "MNTN_HG_VL" : "536", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 화도읍 금남리", + "MNTN_NM" : "문안산" }, - "longitude" : 127.6578615, - "latitude" : 36.089642599999998 + "longitude" : 127.329767, + "latitude" : 37.621951000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", - "MNTN_NM" : "용암산" + "DETAIL_INFO_DTCONT" : "낙동강 1300리 중에서 유일하게 낙동이라는 지명을 가진 상주시 낙동면 낙동리에 낙동강과 어우러져 솟아있는 산이 나각산(螺角山)이다. 산체가 둥글어 소라 형국이고 정상 능선에는 뿔 모양을 하고 있다. 하나는 둥글어 원봉이고 또 하나는 첨봉인데 두 개가 쌍립하여 기묘하다. 부의 상징인 노적봉과 귀를 보장하는 필봉을 겸한 셈이다.산세가 부드럽고 완만하여 가족 동반 산행을 하기에 좋은 산으로 소나무가 많이 우거져 있어 삼림욕을 하기에도 적당한 곳이다.특이한 것은 이 산은 원래 강으로서, 융기되어 만들어졌다는 것을 바위에 박혀 있는 강돌과 등산로 주변에 흩어져 있는 둥근돌 등을 보면 금방 알 수가 있고 정상 주변의 바위에는 군락을 이루고 있는 부처손들이 특징이다.산행시간이 짧기 때문에 비봉산과 연계해 산행하는 것이 좋으며 산행 후 낙단교 휴양단지에서 낙동강을 감상하며 휴식을 취하는 것도 좋다.", + "MNTN_HG_VL" : "240", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 낙동면 물량리", + "MNTN_NM" : "나각산" }, - "longitude" : 127.0052778, - "latitude" : 34.957500000000003 + "longitude" : 128.30134760000001, + "latitude" : 36.382563500000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "634", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 수성구 범물동", - "MNTN_NM" : "용지봉" + "DETAIL_INFO_DTCONT" : "용문산은 경기도에서 네 번째로 높은 산으로 기암괴석과 고산준령을 고루 갖추고 있는 산이다. 본디 미지산이라는 이름으로 불리었는데, 조선을 개국하고 이태조가 등극하면서 '용문산'이라 바꿔 부르게 되었다고 한다.정상은 입산통제 지역으로 우회하는 등산로가 이용되고 있다. 신라 선덕여왕때 창건한 용문사 사찰앞에는 높이 62m, 둘레 14m에 달하는 은행나무(천연기념울 제 30호)가 발걸음을 멈추게 한다.", + "MNTN_HG_VL" : "1157", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면ㆍ옥천면", + "MNTN_NM" : "용문산" }, - "longitude" : 128.64972220000001, - "latitude" : 35.803333299999998 + "longitude" : 127.5518582, + "latitude" : 37.5622124 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "해발 878m의 용화산은 간동면 유촌리, 하남면 삼화리와 거레리, 춘천시 사북면 고탄리에 걸쳐있다. 북쪽으로는 파로호를, 서쪽으로는 춘천호를, 남쪽으로는 소양호의 중심에 위치한 산이다.용화산 준령과 오봉산 사이에 성불령이라는 고개가 있고 여기에 성불사 터가 있다. 옛부터 성불사 저녁 종소리와 용화산 안개와 구름, 기괴한 돌, 원천리 계곡의 맑은 물, 부용산의 밝은 달, 죽엽산의 단풍, 구운소의 물고기 등을 옛부터 팔경이라 불렀다. 산에는 광바위, 심바위, 꼭지바위, 주전자바위, 마귀할미바위, 바둑바위 등 실물을 방불케하는 기암괴석이 있다.", - "MNTN_HG_VL" : "878", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 간동면ㆍ하남면, 춘천시 사북면", - "MNTN_NM" : "용화산" + "DETAIL_INFO_DTCONT" : "경기 제 1봉인 화악산(1,468m)에서 동남쪽으로 뻗어 내린 능선상에 솟아 있는 가덕산은 몽덕산과 북배산의 능선 중간에 자리잡고 있다. 억새산이라고 할만큼 가을철에 억새가 볼만하다.수백평의 억새밭인 가덕산 정상에 오르면 서북방향으로 화악산이 보이고, 남쪽으로는 목동평야와 북배산, 계관산 너머로 삼악산으로 이어지는 능선이 한눈에 들어 온다. 동쪽으로는 의암호와 춘천호, 그리고 호반의 도시, 춘천시가 보인다.가덕산은 계관산, 북배산, 몽덕산과 더불어 네 개의 산을 연결하여 등산하는 유명한 종주코스이다. 이 능선에 구축된 등산길은 넓게 길이 잘 뚫려 있고 굴곡이 심하지 않아 겨울철 능선 종주산행지로 적격이다.", + "MNTN_HG_VL" : "858", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "가덕산" }, - "longitude" : 127.74382540000001, - "latitude" : 38.039407599999997 + "longitude" : 127.61222220000001, + "latitude" : 37.940555600000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천", - "MNTN_NM" : "용화산" + "MNTN_HG_VL" : "486", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시", + "MNTN_NM" : "백자산" }, - "longitude" : 127.74382540000001, - "latitude" : 38.039407599999997 + "longitude" : 128.74805559999999, + "latitude" : 35.786666699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "문수산(일명 천호산)의 한 지맥이 서쪽으로 뻗어 형성된 해발 342m의 높지 않은 산이다.미륵산 동쪽의 왕궁면,여산면에 걸쳐있는 네 봉우리(옥녀봉,선인봉,노승봉,성태봉)를 통틀어 봉화산이라 말한다.서동공원에서 시작해 용화산의 정상부에 오르면 서쪽으로 익산의 진산인 미륵산이 보이고 여산 방면으로 가다가 우측으로 내려가면 서동요의 전설로 잘 알려진 선화공주사가가 나온다.미륵산과 용화산을 합하며모두 용화산이라 불러왔으나 지금은 미륵사가 있는곳이 미륵산이고 나머지를 용화산이라 한다. 일명 군입산(軍入山)이라고 하는데 고려 태조가 후백제를 정벌할때 군대를 주둔시켰던 곳이기 때문에 붙여진 이름이라고 신증동국여지승람은 기록하고 있다.", - "MNTN_HG_VL" : "342", - "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", - "MNTN_NM" : "용화산" + "DETAIL_INFO_DTCONT" : "산이 부드럽고 아름다워 일명 비단산이라고도 불리는 주금산은 운악산과 천마산의 중간지점에 가장 높이 솟아있는 산이다. 남쪽의 아름다운 비금계곡은 도심 근교의 대표적 피서지 중 하나다. 남쪽 약 1.3킬로미터 지점에는 독을 엎어놓은 것 같아 ‘독바위’라 불리는 암봉이 있으며 능선에는 바위지대와 억새밭이 심심치 않게 있고 수림도 울창하다.특히 수동천 상류의 비금계곡은 자연 그대로의 모습을 잘 간직하고 있다. 이 계곡은 옛날 풍류를 즐기던 선비들이 거문고를 숨겨놓고 다녔다하여 붙은 이름이다.정상 부근의 기암과 수려한 비금계곡이 어우러져 마치 비단결 같은 산세가 이어지며, 서북쪽 산자락에는 베어스타운 스키장이 자리잡고 있다.등산 코스로는 내촌에서 오르는 길과 비금계곡에서 오르는 길, 두 가지가 있다. 두 길 모두 산세가 뛰어나 아기자기한 산행을 맛볼 수 있다. 산행 시간은 4시간 남짓으로 서울에서 당일 산행지로 적합하다.", + "MNTN_HG_VL" : "814", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 포천시 내촌면, 가평군 상면", + "MNTN_NM" : "주금산" }, - "longitude" : 127.0655587, - "latitude" : 36.0244456 + "longitude" : 127.2691293, + "latitude" : 37.784374499999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "북으로 두리봉을 거쳐 가야산국립공원으로 연결되고, 남으로 비계산과 이어지면서 거창군의 동벽 역할을 하고 있는 우두산은 가야산을 모산으로 삼고 있다. 별유산이라고도 불리는 이산의 백미는 정상 서쪽 의상봉과 장군봉을 거쳐 병산으로 뻗어내린 능선이다.거창은 산이 많기로 이름난 곳이라 알려진 산들이 많은데 우두산은 최근에 그 진가가 알려져 산을 좋아하는 동호인들 사이에서 산행인구가 꾸준히 늘고 있다. 빼어난 암릉미로 널리 알려져 있으면서 산 남쪽에 자리잡은 가조온천 덕분에 온천산행지로 이름난 산이다. 힘들게 산행을 마치고 온천에 몸을 풀면 일상의 피로까지도 개운하게 가실 것이다.소요 시간 :1코스 : 4시간 50분고견사 주차장 → 4km(1시간20분) → 마장재 → 3.6km(2시간) → 정상 → 0.8km(20분) → 의상봉 → 0.3km(10분) → 서능 → 2.5km(30분) → 고견사 → 2.2km(30분) → 주차장2코스 : 8시간가조휴게소 → 자인봉 → 마장재 → 정상 → 장군봉 → 가조면 병산마을최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 고견사, 견암폭포숲길 명소 : 은행나무(수령 700년), 쌀굴절을 지을 때 쌓아 올렸던 신라 때의 석축이 눈에 들고 고운 선생이 심었다 하는 은행나무와 만든 때가 새겨진 범종과 석불 의상대사가 수도할 때 두 사람분의 쌀이 나왔다 하는 쌀굴과 십이지신상석이 있다.산행과 더불어 역사와 경관을 맛볼 수 있다.우두산 의상봉은 외부에서 많이 찾아오는 곳이다. 관광버스로 고견사주차장에 내려서 고견사를 거쳐 의상봉에 오르거나 우두산까지 가기도 하고 마장재로 돌아오르거나 더러는 비계산부터 종주를 하기도 한다.의상봉아래에서 장군봉으로 이어지기도 한다. 의상봉은 가파르기 때문에 철계단으로 제법 올라가야하는데 철계단이 그다지 안전해보이지 않는다. 위험요소가 없는지 확인할 필요가 있다. 마장재에서 우두산 오르는 길은 바위지역을 지나가야 한다.", - "MNTN_HG_VL" : "1054", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "우두산" + "DETAIL_INFO_DTCONT" : "신증동국여지승람에 대화산이라 지칭한 태화산은 강원 영월군 영월읍 남쪽에 자리해 있다. 정상에서 북서쪽으로 뻗은 능선 끝에는 남한강이 굽이쳐 흐르고 정상으로 향하는 길에 영월읍을 두루 굽어볼 수 있는 태화산성터가 남아 있다.고구려 시대에 쌓았던 토성, 태화산성에서는 간혹 당시의 기와 파편이 발견되기도 한다. 태화산 정상에서는 멀리 남으로 소백산과 백두대간 줄기가 조망된다.", + "MNTN_HG_VL" : "1028", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍, 충청북도 단양군 영춘면", + "MNTN_NM" : "태화산" }, - "longitude" : 128.03433459999999, - "latitude" : 35.760938699999997 + "longitude" : 128.48475329999999, + "latitude" : 37.117061700000001 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "천봉산은 상주 삼악의 하나인 석악으로 상주의 명산이다. 천년에 한 번 봉황이 나타난다고 해서 천봉산(千峰山)이라는 설과 정상에 서면 주변의 천개의 산봉우리를 볼 수 있다고 하여 천봉산(千峰山)이라는 주장하는 사람도 있다. 산경표는 천봉산(天峰山)으로 표기되어 있다.천봉산에는 일찍부터 민속 문화가 발생하여, 성황사를 비롯해 산신제단이 현재도 남아 있고, 암석 신앙에서 비롯된 영암각이 있다. 성황사는 만민이 평안하고 풍요하며 신공으로 우순풍조하여 풍년이 들 것을 기원하던 자리다. 조선 후기까지도 고지기를 두어 지키게 하고 매년 제사를 지냈다 한다. 한마디로 천봉산은 민속 문화의 보고라 일컬을 만하다.정상은 황악산, 속리산, 주흘산 그리고 굽이쳐 흐르는 낙동강 등 산이 낮으면서도 주변 경치를 한 눈에 볼 수 있는 천연전망대다.최근 신년 일출산행지로 각광받고 있다.", + "MNTN_HG_VL" : "609", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 만산동, 부원동", + "MNTN_NM" : "천봉산" + }, + "longitude" : 128.1429444, + "latitude" : 36.442608999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "우두산은 고래산과 능선으로 이어져 있으며 신라때 대사찰 이었던 곳에 최근에 지은 고달사가 있다. 고달사는 764년(신라 경덕왕 23)에 창건되었다고 하며, 신라 이래의 유명한 삼원(三院), 즉 도봉원(道峰院)·희양원(曦陽院)·고달원(高達院) 중 하나로 고려시대에는 국가가 관장하는 대찰이었다. 고달사지부도(국보 4)를 비롯하여 고달사원종대사혜진탑비 귀부 및 이수(보물 6), 고달사지석불좌(보물 8), 고달사원종대사혜진탑(보물 7) 등의 문화재가 남아 있다. 불교유적도 찾아볼 수 있어 문화유적 탐방코스로도 인기가 높은 산이다.산행 기점은 곡수리이다. 고래산의 등산로는 동쪽의 쪽다리나 금동 마을에서 오르는 길과 서쪽의 곡수리를 기점으로 하는 코스가 있다. 구둔역에서 남쪽 도로를 따라가다 쪽다리에서 440봉에 올라 정상까지는 육산의 완만한 길이며 정상에는 큰바위로 구성되어 있다.", - "MNTN_HG_VL" : "359", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평, 여주", - "MNTN_NM" : "우두산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천", + "MNTN_NM" : "백암산" }, - "longitude" : 127.6441667, - "latitude" : 37.4052778 + "longitude" : 128.16748430000001, + "latitude" : 37.848827800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "우두산은 9개의 봉우리로 이루어져있는데, 산의 형세가 소머리를 닮았다고 해서 불리는 이름이다. 우두산을 의상봉이라 부르는 이도 있다. 하지만 의상봉은 신라 문무왕 때 의상 대사가 참선하던 곳으로 주변 경관이 빼어나고 아름답긴 하지만 우두산 9개 봉우리 중 2봉일 뿐이다.<>마장재에서 의상봉 구간은 저마다 빼어난 풍광과 수려한 자태를 자랑하며 불쑥불쑥 솟은 바위들이 수도 없이 나타나는데, 산 정상에서는 바라보면 단지봉과 남산제일봉, 매화산, 깃대봉, 두리봉, 가야산 등 수많은 수려한 봉우리들이 사방팔방으로 솟아있다.<>1094봉에서 마장재 사이 넓고 완만한 안부 노른재엔 산철쭉이 군락을 이루며 자라는데, 점차 넓어지는 철쭉 군락 덕분에 매년 5월이면 온통 붉은 꽃밭을 감상할 수 있다.<>산자락에는 신라 애장왕 때 순응과 이정이 창건한 고견사가 있고, 주변으로 숙종이 원효대사를 기려 내린 강생원을 비롯 의상대사가 수도할 때 매일 2인분의 쌀이 나왔다는 쌀굴 등이 있다.", - "MNTN_HG_VL" : "1046", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가북면", - "MNTN_NM" : "우두산" + "DETAIL_INFO_DTCONT" : "강원도 홍천군 동면과 서석면의 경계에 자리한 대학산은 양옆으로 공작산(887m)과 발교산(998m)을 끼고 있으며 수림이 울창하여 첩첩산중이라는 말이 실감나는 오지의 산이다.이 산에 있는 물골은 본래 `수동'이라 불리었으며 계곡이 크다 해서 예로부터 주민들 사이에는 큰골로 통했다. 물골에서 시작하는 이 산행은 교통이 불편한 게 흠이지만 일단 산에 들어서면 속세와 완전히 격리된 듯한 분위기를 만끽할 수 있는 곳이다.숲과 단애, 낙엽송 수림, 노송이 있는 6월의 대학산은 자연의 생기찬 모습이 그대로 전달되어 오는 자연에 푹 빠진 산행으로 코스를 마칠 수 있는 깨끗한 산이다.정상에서의 조망은 서북쪽으로 공작산이 가깝게 보이고 동쪽으로는 수리봉에서 병무산으로 이어지는 능선이 시야를 막고 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 서석면", + "MNTN_NM" : "대학산" }, - "longitude" : 128.03433459999999, - "latitude" : 35.760938699999997 + "longitude" : 128.085553, + "latitude" : 37.674847499999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "운계봉" + "MNTN_HG_VL" : "462", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군", + "MNTN_NM" : "용소봉" }, - "longitude" : 128.78583330000001, - "latitude" : 37.805277799999999 + "longitude" : 127.6578615, + "latitude" : 36.089642599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구름을 다리 삼아 다녀야 하는 절벽산인 운교산은 아래로 옥동천이 구비치는 모습을 내려다 보고 위로 높은 하늘을 우러르는 형상이다. 옥동천에 발을 담그려 다리를 뻗은 채 구름다리를 건너 하늘로 오르고 싶어하는 산의 마음이 전해진다. 산과 산이 연이어지고 그 산들 또한 키를 다투는 영월에서도 오지에 속하는 이 산은 암벽으로 이루어진 능선이 절경이다. 바위마다 석이버섯이 많아 주민들은 석이산으로 부르기도 한다.산행은 중동면사무소에서 시작하며 4봉·3봉·2봉으로 이어지는 암릉길이 등산의 묘미를 더해 준다. 오르막과 내리막이 모두 무척 가파르며 정상에서 동남쪽으로 옥동천을 굽어보는 조망이 아름답다.주변에 청령포와 고씨동굴 등의 명승지가 있다. 이 중 청령포는 단종이 귀양살이를 하던 곳으로, 삼면으로 깊은 강물이 흐르고 한쪽은 깎아지른 절벽으로 되어 있는 천혜의 유형지이다. 고씨동굴은 수억년 전에 생긴 전형적인 석회동굴인데, 길이가 6.3km에 이르며 굴 내부에 호수를 비롯하여 3개의 폭포와 6개의 광장이 있다. 임진왜란 때 고씨 일가가 이 동굴에 숨어 살았다 해서 고씨동굴이라 부르게 되었다는 전설이 전한다. 천연기념물 219호로 지정되었다.", - "MNTN_HG_VL" : "925", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 중동면", - "MNTN_NM" : "운교산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "180", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍", + "MNTN_NM" : "은월봉" }, - "longitude" : 128.65333330000001, - "latitude" : 37.137500000000003 + "longitude" : 126.8561412, + "latitude" : 33.469772399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "운길산(610m)은 경기도 남양주시 조안면 송촌리 북한강변에 위치한다. 이 산은lsquo;구름이 산에 걸려서 멈춘다rsquo; 또는lsquo;길상한 구름에 뒤덮인 산rsquo;이라는 뜻을 함축하고 있다. 수종사에서 조망되는 북한강과 남한강이 합수되는 두물머리의 서정적 풍광이 일품이다. 양수리 풍경은 어디서 봐도 아름답지만 이곳이 진yen;다. 조선 초 판서를 지낸 서거정이 수종사를lsquo;동방에서 제일의 전망을 가진 사찰rsquo;이라고 하여 남긴 시가 있을 정도다. 그러다보니 운길산에 오른다는 건 수종사를 보러 가자는 것과 마찬가지다.검단산을 좌측 배경으로 양수리가 훤히 보이면서 예봉산 아래 정약용 생가 유적지도 눈에 들어온다. 규모는 작지만, 긴 역사와 경관이 기가 막힌 곳에 자리 잡아 꼭 들러야 하는 사찰이다. 송촌리나 진중리에서 올라 수종사만 보고 가도 아쉽지 않다. 정상에서 두물머리쪽은 수림에 가려 전혀 조망이 안 된다.", - "MNTN_HG_VL" : "610", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 와부읍", - "MNTN_NM" : "운길산" + "DETAIL_INFO_DTCONT" : "산정에 부처님을 닮은 불상이 있다하여 이름 붙여졌다는 성불산은 충북 괴산군 감물면에 울창한 삼림을 등에 지고 아담히 솟아있는 산이다. 충북 괴산군에는 아직까지 사람의 발길이 많이 닿지않아 천연의 자연상태를 보존하고 있는 산들이 다수 있는데, 성불산도 그 중 하나다.소백산의 지맥으로 갈라져 나와 다소곳이 앉아있는 성불산은 산 규모도 작고 외진 곳에 위치하여 산악인들에게 별로 알려지지 않은 산이다. 가벼이 산책하듯 오르내릴 수 있는 산이라 생각하기 십상이나, 작은 산등성엔 험준한 암봉들이 십여개가 늘어서 있고, 그 사이마다에는 노송들이 하늘을 가리우고 있어, 풍광면에서나 산행 난이도 면에서나 결코 만만히 봐서는 안된다.정상에서는 모산인 박달봉이 동쪽으로 근접해있고, 남동쪽으로는 덕가산, 치로산, 보배산 등이 둘러싸고, 서쪽 편에는 고산구경을 품고 있는 달천이 감돌아 흐른다. 강 건너 괴산 시내를 한눈으로 내려다 볼 수 있는 위치에 있는 명산이다.", + "MNTN_HG_VL" : "532", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 감물면 매전리", + "MNTN_NM" : "성불산" }, - "longitude" : 127.2951884, - "latitude" : 37.5720399 + "longitude" : 127.8619885, + "latitude" : 36.814836700000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 등허리 태백에서 분기한 산줄기가 내륙을 향해 달리다 수려한 봉우리를 만들었으니 그 이름 운달산이라하여 계곡에 흐르는 물이 맑고 차갑기가 얼음같아 일명 '냉골'이라 불리워진다. 용암산(龍岩山)이라고 부르기도 하는 이 산은 문경읍 동북쪽 8km 지점에 위치한다. 산 능선은 길게 동서로 10여km에 걸쳐 뻗었으며, 그 사이의 마전령(馬轉嶺:627m)· 조항령(鳥項嶺:673m) 등 안부(鞍部)가 예로부터 문경과 다른 지방을 연결하는 교통의 요지였다. 산에는 금선대(金仙臺)를 비롯하여 많은 기암괴석으로 덮여 경치가 아름다우며, 남동사면 일대에 화장암(華藏庵)·양진암(養眞庵)·대성암(大成庵)·금룡사(金龍寺) 등 고찰이 있어 많은 관광객이 찾아든다.특히 수령 300년 이상 수고 30여미터의 전나무 숲속에 고목이 조각품마냥 운치를 더해주고 겨울철 눈꽃은 내방객의 넋을 잃게 하고 여름철에는 조용한 곳을 찾는 피서객들이 찾아 온다.또한 운달산은 김룡사를 품고 있다. 김룡사는,lt;운달산김룡사사적서 (蕓達山金龍寺事蹟序)gt;에 따르면, 신라 진평왕 10년(588) 운달 조사 (蕓達祖師)가 개선하여 사명을 운봉사(蕓峰寺)라 하였다고 되어 있다. 따라서 본래의 절 이름인 운봉사라 사명이 조선시대 후기까지도 그대로 사용되었다고 생각되는 것은 사중에 전해지는 괘불화기 (掛佛畵記, 1703년) 에도 운봉사라 기록하고 있기 때문이다. 다만 사명이 김룡사로 바뀐 연유는 여러 가지로 전해지고 있으나, 그 중에서 가장 믿을 만한 것은 김씨 성을 가진 사람이 죄를 지어 이곳 운봉사 아래에 피신하여 숨어 살면서 신녀가 (神女家)를 만나 매양 지극한 정성으로 불전에 참회하더니 한 아들을 낳아 이름을 용이라 하였다. 그 이후부터 가운이 크게 부유해져 사람들은 그를 김장자(金長者)라 하였고, 이로 인하여 동리 이름 또한 김룡리(金龍里)라 하였으며, 운봉사 역시 김룡사로 개칭하였다는 기록이 전해지고 있다. 그러므로 이 절은 최소한 18세기 이후 김룡사란 이름으로 되었다고 생각된다.", - "MNTN_HG_VL" : "1097", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍 용연리", - "MNTN_NM" : "운달산" + "DETAIL_INFO_DTCONT" : "남녘 해안가에 자리잡은 이 산은 높이에 비해 산세가 굉장히 웅장하다. 능선에는 상사바위봉, 섬바위봉, 기차바위, 형제바위 등 빼어난 암봉이 장관이고 아슬아슬한 암릉길이 있으며 억새 능선길, 남해 푸른 바다의 장쾌한 조망 등 아름다움을 두루 갖춘 명산이라 할 수 있다. 또한 높고 낮은 봉우리가 아흔아홉 개로 형성되어 구구연화봉이라 전해지기도 하며 5월에는 철쭉이 만개하면 온 산이 진홍색이로 물들어 장관을 이룬다.산의 형상이 거대한 용 한 마리가 누워 있는 모습과 흡사하다하여 와룡산이라 불려졌다고 하며 고려의 현종이 잠룡시(임금이 되기 전의 시절)에 놀던 곳이기 때문에 이름 지어졌다고 한다. 와룡산 기슭의 백천골은 임진왜란 때 승병들이 왜군과 싸운 곳이라는 기록도 있다. 백천골에서 와룡산 등성이를 따라 바닷가로 내려오면 성문등, 파병산, 난곡, 퇴병산 등 임진란과 관련 있는 지명이 산재해 있는 것을 보면 당시의 상황을 짐작해 볼 수가 있다.", + "MNTN_HG_VL" : "801", + "MNTN_LOCPLC_REGION_NM" : "경상남도 사천시 사천읍", + "MNTN_NM" : "와룡산" }, - "longitude" : 128.19868009999999, - "latitude" : 36.7564888 + "longitude" : 128.1139033, + "latitude" : 34.986448800000012 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "운무산은 강원도 횡성군 청일면과 홍천군 서석면 경계에 있는, 규모는 작으나 아름다운 암봉을 갖춘 산이다. 횡성군에는 이렇다 할 산이 없을 것으로 생각되지만 그렇지 않다. 그것은 횡성군이 영동방면으로 가는 길목 이상의 역할을 하지 못했기 때문이다. 그래서 잘 알려지지 않은 아름다운 산이 적지 않다. 발교산, 덕고산, 봉복산, 운무산 등이 그런 산에 속한다. 그 중에서도 운무산은 독특한 암봉미와 아기자기한 능선을 갖추고 있어 아름답다.항상 구름과 안개가 낀 듯하다는 데서 이름이 유래한 운무산은 자연 그대로의 모습이 오롯이 남아 있는 멋스러운 산이다. 아지랑이 하롱하롱 밀려드는 봄날이 오면 야생 벚나무의 향연이 수채화 물감처럼 번져 오른다. 특히 사람의 측면 얼굴을 닮은 듯한 수리봉은 운무산 가운데 가장 전망이 뛰어난 곳으로, 이곳에 서면 운무산 전경과 청량1리의 삼근암과 새대기, 횡성의 산줄기들이 잘 조망된다.", - "MNTN_HG_VL" : "979", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 청일면, 홍천군 서석면", - "MNTN_NM" : "운무산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "138", + "MNTN_LOCPLC_REGION_NM" : "충청남도 청양군", + "MNTN_NM" : "비봉산" }, - "longitude" : 128.2016667, - "latitude" : 37.650277799999998 + "longitude" : 126.79972220000001, + "latitude" : 36.501111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "47", - "MNTN_LOCPLC_REGION_NM" : "강원도 고성군 토성면 운봉리", - "MNTN_NM" : "운봉산" + "DETAIL_INFO_DTCONT" : "금당산은 강원도 평창군 봉평면과 대화면 경계를 이루는 산으로 평창강 상류의 금당계곡을 끼고 있어 물놀이를 겸할 수 있는 가족단위 산행지로 적합한 곳이다.산 자락 밑에 흐르는 금당계곡에는 높이 60m의 직벽으로 된 봉황대라는 곳이 있는데 이곳은 옛날부터 봉황새 이외의 다른 새는 근접을 하지 못했다고 한다.강원도 산골로 이름 높은 평창군 일대는 오대산(1,563m), 계방산 (1,577m) 등 1,000m를 넘는 고산이 운집해 있다. 신리 쪽에서 바라보면 왼쪽의 거문산(1,175m)이 훨씬 높아 보이고 밋밋한 평행선의 능선 끝 오른쪽에 약간 튀어 오른 금당산의 정상이 보인다.정상에서는 동쪽의 잠두, 백석산의 능선이 선명하게 조망되며 이곳에서 바라보는 잠두산은 누에가 기어가는 모습 그대로의 형상이다. 금당산 정상은 펑퍼짐한 봉우리로서 태기산, 회령봉, 계방산 등의 조망이 더욱 좋은 위치이다.금당산은 봄에는 진달래, 여름에는 원시림을 방불케 하는 울창한 나무숲, 가을에는 오색의 단풍 물결, 겨울에는 눈꽃으로 아름다움을 나타내고 있는 산이다.계곡의 물은 아주 깨끗하며 계곡물이 매우 차기 때문에 한여름에도 산행로가 선선함을 느낄 수 있다.", + "MNTN_HG_VL" : "1173", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 용평면", + "MNTN_NM" : "금당산" }, - "longitude" : 128.507882, - "latitude" : 38.2876695 + "longitude" : 128.41599729999999, + "latitude" : 37.540842300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "청평에서 북동쪽으로 약 20km 떨어진 운악산은 일명 경기 소금강이라고 불리울 만큼 뛰어난 모습을 지니고 있다. 주봉인 망경대를 둘러싸고 커다란 바위들이 봉우리마다 구름을 뚫고 솟아 있으며, 오래된 절 현등사와 물 맑은 조종천은 매력을 한층 더해준다.", - "MNTN_HG_VL" : "935", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 하면, 포천시 화현면", - "MNTN_NM" : "운악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "후봉" }, - "longitude" : 127.32489889999999, - "latitude" : 37.878003 + "longitude" : 127.8288889, + "latitude" : 37.923333300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전라북도 경계선이내에는 1000m 가 넘는 5대 고산이 있다. 그 중 높이가 네 번째인 운장산에서 북쪽으로 뻗어나간 대능선이 칠백이고지를 만들고 여기서 남서쪽으로 갈라진 지맥의 끄트머리에서 아름다운 대아저수지에 그림자를 드리우고 우뚝 솟아 숨어 지내온 수려한 명산이다.구름위에 솟아 있는 바위산이라고 하여 이름도 운암산이라 지었다. 이름에서부터 운치있는 산의 풍광을 떠올리게 되는데 산 정상에서의 조망은 그 기대를 저버리지 않는다. 새만금간척지로 흘러가는 대아댐이 굽어보이며 정상에서 봉화대로 이어지는 수려한 암벽능선이 인상적이다. 정상인 관봉은 옛날 봉수대자리로 그 때의 석축이 지금도 뚜렷하게 남아있다. 서쪽으로 뻗은 능선은 기암괴석으로 이어져 있고, 능선의 남쪽면은 거대한 절벽지대를 이루고 있다. 이 절벽지대는 군부대의 산악훈련장으로 이용하고 있어 입산이 통제되어 있으나 능선 등산에는 지장이 없다.", - "MNTN_HG_VL" : "597", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 고산면", - "MNTN_NM" : "운암산" + "DETAIL_INFO_DTCONT" : "고성군이 남해와 접해있는 지역 중에 대부분을 차지하고 있는 동해면의 산역은 수양산과 철마산, 그리고 구절봉의 이음이 전부다. 거류면의 거류산과 마주보면서 남북으로 길게 뻗은 산줄기는 겉에서 보기에는 그저 평범한 산세를 지니고 있어 산객의 관심을 끌지 못하고 있지만, 남서쪽 계곡에 자리잡고 있는 폭포암 근처에 있는 삼단폭으로 된 구절폭포는 작은 규모에 비해 절경을 지니고 있다. 북릉은 동으로 굽어져 철마산과 이어져 있고, 남릉은 당동만에 자락을 씻고 있다. 정상에 서면 건너편 거류산역과 벽방산의 산경이 한 눈에 들어오고 수양산릉 넘어있는 남해의 시원한 경관이 산객의 마음을 열어준다.", + "MNTN_HG_VL" : "521", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성군 동해면", + "MNTN_NM" : "구절산" }, - "longitude" : 127.28103900000001, - "latitude" : 35.988175900000002 + "longitude" : 128.42027780000001, + "latitude" : 35.024722199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "487", - "MNTN_LOCPLC_REGION_NM" : "고흥군", - "MNTN_NM" : "운암산" + "DETAIL_INFO_DTCONT" : "충남 금산과 전북 완주 사이에 우뚝 솟은 선야봉은 숲이 울창하고 신선풀무대 그리고 암봉과 암릉, 바위낭떠러지, 폭포 등을 고루 갖춘 산이다. 남북으로 뻗은 크고 높은 산줄기와 그 사이로 나란히 뻗은 경관 좋은 느티골과 피묵이골이 산 아래로 흐르고 있다. 그 중 금산쪽에 위치한 느티골은 아름다운 계곡이 이어져 있고 숲이 울창한데다 자연휴양림을 조성하고 있어 훌륭한 휴식처로 개발되어 있다.느티골 안쪽에 높이 25미터의 쉰길폭포가 장관을 이룬다. 새로 개설한 선야봉 등산로는 폭포를 지나며 아기자기한 암릉을 거쳐 기암괴봉을 조망할 수 있는 능선으로 이어져 있어 많은 등산객과 휴양객들이 자연을 편하게 즐길 수 있는 곳이다.정상 능선에서 서쪽으로는 대둔산, 천등산, 서대산이 있고 동쪽으로는 전적지로 유명하며 경관이 뛰어난 백암산이 있다.", + "MNTN_HG_VL" : "759", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 남이면ㆍ전라북도 완주군 운주면", + "MNTN_NM" : "선야봉" }, - "longitude" : 127.3347222, - "latitude" : 34.624166700000004 + "longitude" : 127.3666667, + "latitude" : 36.048333300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산이 높아 구름 같은 기운이 산을 감싸고있다 하여 운암산이라 부르는 고흥의 명산이며, 모악산 이라 부르기도 한다. 운암산은 포두쪽에서 바라보면 두 봉우리가 우뚝 솟아있다. 제일 높은 봉우리가 깃대봉이요, 또 한 앞 봉우리는 마치 부채를 펼쳐놓은듯한 부채봉이다. 운암산 부채봉으로 오르는 길은 세 군대가있다. 사람들의 발길이 거의 닿지 않는 자연의 모습을 그대로 간직하고 있고, 골짜기에는 많은 전설들이 있다. 정상 부근의 빼어난 봉우리들이 줄지어 서 있는 모습과 산길옆 저수지의 에메랄드 빛 초록색의 향연, 깊은 계곡들 그리고 수목들이 가슴 벅찬 아름다움을 느끼게 한다. 산꼭대기에서는 기우제를 지내기도 하였다. 조선말기 총리대신을 지낸 김홍집이 흥양현감으로 재임시 이곳 운암산에 올라 기우제를 올린 사실이 이우제문과 함께 전한다.동산동마을 축사가 있는 하산길로 내려오다보면 유난히 파란색에 빛나는 용은제가 보인다. 용이하늘로 승천하기 위해 때를 기다리며 은거하고 있는 곳이라는\"용은제\"이다.", - "MNTN_HG_VL" : "487", - "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", - "MNTN_NM" : "운암산" + "DETAIL_INFO_DTCONT" : "예부터 흥양골에 군자가 많이 나서 봉황새가 날아와 보금자리를 잡았다 하여 봉황산이라 부르며선인들은 봉황을 군자의 새라 하였다. 일제 말기에 송탄유를 만들기 위해 많은 충송을 베어내어지금은 얼마 남지않았다.산세가 완만하고 코스가 적당(50분)하며 고흥읍 유민의 아침, 저녁 주 산책로이며 정상에서고흥 시가지가 한 눈에 보이며,숲의 주요 수종은 수령 50~60년생의 소나무로 천연보육림 상태로 숲이 잘 발달 되어 있다.", + "MNTN_HG_VL" : "199", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 고흥읍 남계리", + "MNTN_NM" : "봉황산" }, - "longitude" : 127.3347222, - "latitude" : 34.624166700000004 + "longitude" : 127.2850741, + "latitude" : 34.603868599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", - "MNTN_NM" : "운제산" + "DETAIL_INFO_DTCONT" : "제주도의 산중에서 가장 유명하고 경치가 빼어나며 신비스러운 분위기가 서린 곳으로, 반드시 찾아가봐야 하는 곳이 바로 산방산이다. 한라산 봉우리를 뽑아 옮겨 놓은 것이 산방산이고, 그 뽑힌 자리가 백록담이 되었다는 이야기가 있듯이 설화 속의 산방산은 수려한 용모가 단번에 찾는 이의 눈길을 빼앗을 정도로 아름답다. 매우 가파라서 오르기가 힘이드나 일단 오르고 나면 정상에서 바라보는 그 경치는 모든 피로감을 충분히 보상하고도 남으며 한번 오른 이는 다시 오르고 싶은 마음이 절로 나는산이다.또한 조면암질 안산암으로 구성되어 있으며 그 형태가 특이하다. 남서쪽 기슭, 해발고도 200m 지점에 산방굴(山房窟)이라는 자연 석굴이 있다. 그 안에 불상을 안치하였기 때문에 이 굴을 산방굴사(山房窟寺)라고도 한다. 굴 내부 천장 암벽에서 떨어지는 물방울은 산방산의 암벽을 지키는 여신 ‘산방덕(山房德)’이 흘리는 사랑의 눈물이라는 전설이 있다. 산의 남쪽 해안에는 성산포층(城山浦層)이 노출되어 있고 심한 해식(海蝕)으로 단애(斷崖)가 형성된 암석해안을 이룬다. 여기에 하멜 표류 기념탑(漂流記念塔)이 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 안덕면", + "MNTN_NM" : "산방산" }, - "longitude" : 129.35138889999999, - "latitude" : 35.934444399999997 + "longitude" : 126.3134467, + "latitude" : 33.241068200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구름을 받치고 있는 기둥같다’는 운주산(806.2m)은 팔공산 보현산과 함께 영천의 삼산으로 불린다. 운주산은 높지 않으나 그 품이 넓고 깊어 민초들이 살아온 고된 삶의 흔적이 많이 배여있다. 임진왜란 때는 김백암장군이 이 산에 성을 쌓아 항전했고, 구한말에는 영남지방의 의병조직인 산남의진(山南義陣)이 이곳을 근거지 삼아 포항·영일 일대서 거센 항쟁을 펼쳤다. 또 한국전쟁 때는 많은 피난민들이 이 산에 은신하기도 했다.정상에서는 사방이 훤히 트인 멧부리에서는 굽이치는 낙동정맥의 자태가 한눈에 들어온다. 서쪽으로는 얼어붙은 조양호가, 북서쪽으로는 눈고깔을 하얗게 덮어쓴 보현산이 머리를 내민다. 동쪽으로는 비학산 도음산이 포항시를 감싸고 남쪽으로 도덕산 자옥산이 이어지며 영천시를 보듬고 있다.산 중턱 쯤에 안국사가 있다.안국사는 신라 때 국태민안과 왕실의 번영을 기원하기 위해 기림사와 함께 세워진 유서 깊은 고찰이다. 한때 이 골짜기에 열두 암자를 거느리며 신라 불교의 전성기를 이끌기도 했다. 그러나 구한말 의병 활동의 근거지였던 까닭에 일제에 의해 대부분 불태워졌다. 암자에서 만난 노스님은 지금도 운주산 일대에 당시 승려들이 만든 저수지와 절터가 곳곳에서 발견된다고 말했다.", - "MNTN_HG_VL" : "806", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영천시 임고면, 자양면, 포항시 기계면", - "MNTN_NM" : "운주산" + "DETAIL_INFO_DTCONT" : "북으로 두리봉을 거쳐 가야산국립공원으로 연결되고, 남으로 비계산과 이어지면서 거창군의 동벽 역할을 하고 있는 우두산은 가야산을 모산으로 삼고 있다. 별유산이라고도 불리는 이산의 백미는 정상 서쪽 의상봉과 장군봉을 거쳐 병산으로 뻗어내린 능선이다.거창은 산이 많기로 이름난 곳이라 알려진 산들이 많은데 우두산은 최근에 그 진가가 알려져 산을 좋아하는 동호인들 사이에서 산행인구가 꾸준히 늘고 있다. 빼어난 암릉미로 널리 알려져 있으면서 산 남쪽에 자리잡은 가조온천 덕분에 온천산행지로 이름난 산이다. 힘들게 산행을 마치고 온천에 몸을 풀면 일상의 피로까지도 개운하게 가실 것이다.소요 시간 :1코스 : 4시간 50분고견사 주차장 → 4km(1시간20분) → 마장재 → 3.6km(2시간) → 정상 → 0.8km(20분) → 의상봉 → 0.3km(10분) → 서능 → 2.5km(30분) → 고견사 → 2.2km(30분) → 주차장2코스 : 8시간가조휴게소 → 자인봉 → 마장재 → 정상 → 장군봉 → 가조면 병산마을최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 고견사, 견암폭포숲길 명소 : 은행나무(수령 700년), 쌀굴절을 지을 때 쌓아 올렸던 신라 때의 석축이 눈에 들고 고운 선생이 심었다 하는 은행나무와 만든 때가 새겨진 범종과 석불 의상대사가 수도할 때 두 사람분의 쌀이 나왔다 하는 쌀굴과 십이지신상석이 있다.산행과 더불어 역사와 경관을 맛볼 수 있다.우두산 의상봉은 외부에서 많이 찾아오는 곳이다. 관광버스로 고견사주차장에 내려서 고견사를 거쳐 의상봉에 오르거나 우두산까지 가기도 하고 마장재로 돌아오르거나 더러는 비계산부터 종주를 하기도 한다.의상봉아래에서 장군봉으로 이어지기도 한다. 의상봉은 가파르기 때문에 철계단으로 제법 올라가야하는데 철계단이 그다지 안전해보이지 않는다. 위험요소가 없는지 확인할 필요가 있다. 마장재에서 우두산 오르는 길은 바위지역을 지나가야 한다.", + "MNTN_HG_VL" : "1054", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "우두산" }, - "longitude" : 129.11027780000001, - "latitude" : 36.0777778 + "longitude" : 128.03433459999999, + "latitude" : 35.760938699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "939", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", - "MNTN_NM" : "울련산" + "DETAIL_INFO_DTCONT" : "곡성땅을 관통해 흐르면서 남동쪽으로 향하던 섬진강 물줄기를 북진시키는 오산은 자라가 섬진강 물을 마시고 있는 모습이라는 데서 이름을 따왔다고도 하고 정상의 벼랑 때문에 이런 이름을 얻었다고도 한다. 정상까지 걸리는 시간도 1시간 내외에 불과하지만 산꼭대기 고스락은 분수처럼 비밀을 내뿜는 화수분 같은 산이다.오산 사성암 전망바위에서 내려다 본 구례들판. 문척면 나들목인 신·구 문척교와 그 아래로 넉넉하게 흐르는 섬진강이 한눈에 들어오며 지리산 북서쪽 자락도 파노라마처럼 펼쳐진다. 그 하나는 넋을 빼앗는 조망의 즐거움이다.'산에 들면 산을 모르고 산을 벗어나면 그 산이 보인다'는 말이 있다. 오산에 오르면 바로 헌걸찬 지리산이 한눈에 들어온다. 북동쪽으론 노고단,반야봉,삼도봉이 뚜렷하고 멀리 명선,촛대봉이 아련하다. 동쪽으론 문수리가 아스라이 펼쳐지며 그 오른쪽으로 왕시루봉과 황장산이 능파를 이루며 달리고 있다. 한마디로 말하면 지리산 최고 전망대인 셈이다.두번째 비밀 역시 풍광의 아름다움이다. 실핏줄 같은 개울 물을 모아 남도의 이산 저산의 뭉툭한 허리를 감돌며 굽이치는 섬진강이 가장 찬란한 빛으로 흐른다. 지리산 어떤 전망대도 오산에서 바라보는 섬진강의 비경을 따라잡기 힘들 듯 싶다.세번째 비밀은 오산의 보석 사성암의 전설로 시작된다. 깎아지른 벼랑에 제비 집처럼 붙여 지은 사성암은 582년 연기조사가 세운 이래 원효,의상,도선,진각 등 4대 성인이 수도를 했다는 곳이다. 사성암이란 이름도 여기서 유래했다. 절 주변 곳곳에 성인들의 흔적이 전설 혹은 설화로 전해 내려온다. 시간이 있다면 고려 때 새겨진 마애불도 둘러볼 만하다. 마지막 비밀은 사성암 주변 수직바위 군. 오산십이대라 불리는 이 바위들은 갖가지 전설과 기기묘묘한 형태로 탐방객들의 눈길을 끌고 있다. 또한 3월이 되면 보리밭이 푸릇해지고 여기저기 매화와 산수유꽃이 피어나 한 폭의 산수화를 그려낸다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군 문척면", + "MNTN_NM" : "오산" }, - "longitude" : 129.23611109999999, - "latitude" : 36.771388899999998 + "longitude" : 127.4819578, + "latitude" : 35.179359300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "울련산은 대동여지도에 울연산(蔚然山)이라 표기되어 있으며 이외에 울람산, 우련산, 우렁산이라고도 불린다.서쪽으로는 즉 수비에 이르는 보잘것없는 능선을 가진것 같지만 동쪽으로는 금장산(848.7m)까지 무릇 8km의 능선이 이어지며 자못 우람한 산세를 이룬다.이 산은 낙동정맥의 동쪽에 놓여있는 산이다. 따라서 금장산과 백암산(1003.7m) 사이의 구슬령에서 동쪽이나 서쪽으로 발원한 물은 신기하게도 모두 동해로 흘러든다.서쪽으로 내린 물은 곧바로 동해로 가지 않고 수비를 경유 울련산 서쪽을 한바퀴 돈 다음 장수포천, 욍피천을 거쳐 동해로 흘러든다.이 때문에 낙동정맥의 마루금을 그을 때 주의해야 하는 지역이기도 하다. 정상은 뾰족하고 좁은 편이나 조망은 매우 좋다. 서쪽으로는 낙동정맥의 능선이 물결치고 남쪽 멀리에는 백암사 능선이 꿈틀거린다. 남쪽 신원천 건너편으로는 남이장군이 칼을 갈았다는 검마산(918.2m)이 보이며 서북쪽으로는 장수포천 너머로 일월산 정상에 서 있는 송신탑과 중계소가 한눈에 들어온다.", - "MNTN_HG_VL" : "939", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 수비면", - "MNTN_NM" : "울련산" + "DETAIL_INFO_DTCONT" : "가평군청에서 북쪽으로 20km 떨어진 산으로 경기도 가평군과 강원도 춘천시의 경계를 이루고 있다.즐겨 찾는 이가 많지 않아 호젓한 산행으로 그만이다. 능선에는 싸리, 억새숲을 이루고 있어, 전망도 매우 좋다.정상에는 나무하나 없이 밋밋한 좁은 부위의 마루턱을 이루고 있는데 어떤 시설물이라도 있었던 것인지 여기저기 나무기둥 같은게 보인다. 여기서의 전망은 좋아서 북으로 가덕산과 그위로 몽덕산을 잇는 연릉이 일직선으로 뻗어 나간 모습을 볼수 있는가 하면 남으로 계관산을 잇는 역시 한일자로 굽이굽이 이어지는 억새수풀 능선이 그림처럼 아스라이 전개되는 모습이 장관이다.", + "MNTN_HG_VL" : "690", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "몽덕산" }, - "longitude" : 129.23611109999999, - "latitude" : 36.771388899999998 + "longitude" : 127.60406380000001, + "latitude" : 37.9545265 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "1983년 11월 23일 군립공원으로 지정된 웅석봉은 지리산에서 흘러온 산이면서도 지리산을 가장 잘 볼 수 있는 산이다. 천왕봉에서 시작된 산줄기가 중봉과 하봉으로 이어져 쑥밭재∼새재∼외고개∼왕등재∼깃대봉을 거쳐 밤머리재에 이르러 다시 한 번 치솟는데 이 산이 웅석봉이다.경남 산청의 웅석봉은 이름 그대로 ‘곰바위산’ 으로 불린다. 정상부에서 놀던 곰이 가파른 북사면으로 떨어져 죽었다는 전설에서 유래된 지명이다. 실제로 웅석봉 정상에서 보면 북쪽에 깎아지른 낭떠러지가 있어 곰이 떨어져 죽었다는 이야기가 설득력 있게 들린다.산세가 웅장한 만큼 수려한 계곡도 많다. 정상을 중심으로 뻗어 내린 곰골과 어천계곡, 청계계곡, 딱바실골 외에도 남릉에서 발원하는 백운동과 실골 같은 골짜기는 경관이 뛰어나고 물이 맑기로 유명하다.웅석봉 산행은 산청읍에서 접근해 지곡사쪽에서 오르는 것이 일반적이었다. 하지만 산청읍과 시천면을 잇는 59번 국도가 포장되면서부터 변화가 생기기 시작했다. 산청읍 쪽에서 접근할 경우 1000미터 고도차의 가파른 산길을 치고 올라야 하기 때문에 힘들 수밖에 없다. 하지만 해발 570미터의 밤머리재에서 산행을 시작하면 운치있는 능선길을 따라 쉽게 정상에 오를 수 있다. 능선에서 보는 천왕봉 동쪽 사면의 조망도 뛰어나 인기 있다.", - "MNTN_HG_VL" : "1099", - "MNTN_LOCPLC_REGION_NM" : "경남 산청군 단성면", - "MNTN_NM" : "웅석봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "518", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시", + "MNTN_NM" : "교룡산" }, - "longitude" : 127.8772768, - "latitude" : 35.364010999999998 + "longitude" : 127.3522969, + "latitude" : 35.429327299999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "171", - "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 조천읍 신촌리, 삼양일동", - "MNTN_NM" : "원당봉(삼양)" + "MNTN_HG_VL" : "362", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군", + "MNTN_NM" : "예성산" }, - "longitude" : 126.59880269999999, - "latitude" : 33.5251229 + "longitude" : 127.1329367, + "latitude" : 35.117416200000008 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금남정맥상의 운장산(1126m)이 조산인 원등산은 전북 완주군 소양면과 동상면 경계를 이루며 위봉산(524m) 서방산(612m) 안수산(554m) 동성산(550m)과 맥을 같이 하고 있다. 이 산을 중심으로 북으로는 위봉산성과 송광사, 드라이브코스로 제격인 대아저수지와 동상 저수지 호안도로가 이어져 있는데 이렇게 이름난 주변 명소에 밀려 원등산은 손타지 않은 자연을 제법 잘 보존하고 있다.원등산의 옛이름은 청량산이거니와 남녘 자락에 오랜 고찰 원등사가 자리하여 세월이 흐르는 동안 원등산으로 이름이 바뀌었다. 해발 500m에 자리한 원등사에 서면 전주 시내가 한눈에 들어온다. 정상에서는 운장산과 연석산이 보이고 연석사와 연석폭포가 있는 사봉리 협곡까지 손금처럼 훤히 내려다 보인다. 기암절벽이 산줄기 곳곳에 솟아있어 산세가 아름답고 가족이 함께 산행하기에도 좋은 곳이다.해발 500m 지점에 위치한 원등사는 1200년된 고찰로 신라 문성왕 2년 보조선사가 세웠다고 전한다. 보조선사가 사찰을 세우기 위해 그곳에서 멀리 떨어진 무주 향악 난야에서 나무로 만든 오리를 날려보냈는데 오리가 앉은 곳이 원등사였다고 한다. 이곳은 또한 도승 진묵대사가 많은 기행을 남긴 곳으로도 유명한 곳이다. 동란 때 소실된 법당은 아직도 증축하지 못한 채 터만 남아 있다. 바위를 뚫어 만든 굴속에 오백나한을 모셔 놓았는데 지금은 너와집 같은 건물에 법당을 마련하고 나한을 모시고 있다.", - "MNTN_HG_VL" : "713", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군", - "MNTN_NM" : "원등산" + "DETAIL_INFO_DTCONT" : "왕치산은 등산로가 대부분 임도로 이뤄져 있어 길을 잃거나 할 염려가 없으면서도 사람의 발길이 거 의 닿지 않은 우거진 숲길을 거닐며 한적한 산행을 즐길 수 있다. 고사리 등 산나물과 자생 식물이 잘 보존돼 있고 산과 어우러진 월루마을의 풍광 또한 색다른 감흥을 불러일으킨다. 산행기점인 임계-여량리간 42번 국도상의 큰너그재는 해발760m의 고지대로 정상과의 고도 차가 200m을 조금 넘는 수준이어서 부담 없이 산을 오를 수 있다.큰너그재에서 산행을 시작한다. 넓지 않고 인적이 없어 등산로와 같은 임도를 타고 정상에 도달하거나 임도 옆 능선을 타고 정상에 오르는 방법이 있다. 여기서 왼쪽 임도를 따라가면 왕치산산행이 백미라 할 월루 마을의 아름다운 풍광을 감상할수 있다. 월루마을을 둘러보고 계곡을 따라 남하하는 임도를 타면 느라방죽이 나타나고 잠시후 골지천의 비경과 천 주변의 유적들을 만날 수 있다. 반천초등학교 옆의 구용소와 숙종때 공조참의를 지낸 이자선생이 노닐던 구미정, 그리고 고수당, 난포정, 장찬성지 등이 유명하다. 골지천은 여름철 물놀이를 즐기기에 제격인 곳이다.", + "MNTN_HG_VL" : "900", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 임계면", + "MNTN_NM" : "왕치산" }, - "longitude" : 127.2937072, - "latitude" : 35.8874104 + "longitude" : 128.79443470000001, + "latitude" : 37.486439500000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한남정맥과 갈라진 산줄기가 북쪽으로 태화산(645m) 백마산(530m) 줄기를 떨구고 동북진하여 광주와 이천을 잇는 넓고개를 건너 솟구친 산이 바로 원적산이다. 무적산(無寂山)이라고도 한다. 동쪽 원적봉(563.5m) 기슭에 638년(선덕여왕 7년)에 창건했다는 영원사(靈源寺)라는 사찰이 있으며, 주봉인 천덕봉 기슭에는 율수폭이라는 폭포가 있다. 고려말 공민왕이 난을 피해 이곳에 머물렀다는 전설이 전한다. 신둔면 장동리 쪽에는 군사훈련장이 있어 입산이 제한되므로 산행은 백사면 경사리 쪽에서 시작한다.전체적인 능선이 부드럽고 완만해 보이지만 산 천덕봉 안쪽으로 암벽이 있으며 이 산의 최고봉인 천덕봉은 높이 635m로 이천군내에서 제일 높다. 산행기점인 송곡마을은 전국 제일의 산수유 산지로 봄이면 농가울타리와 논밭두렁이 산수유의 노란 물결로 일렁이고 가을이 되면 들 곳곳에서 열매를 따는 풍요로운 풍경이 등반객들의 마음을 넉넉하게 채워준다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.", - "MNTN_HG_VL" : "564", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 백사면, 광주군 실촌면", - "MNTN_NM" : "원적산" + "DETAIL_INFO_DTCONT" : "남산은 충주시 직동과 살미면의 경계선상에 자리하고 있는 산으로 일명 금봉산이라고도 한다. 예전에 봉황이 살았던 상서로운 산이라고 한다.마즈막재를 사이에 두고 북쪽에 위치한 계명산과 마치 형제처럼 마주하고 있으며 이 산 남쪽 기슭에는 신라 시대 때 창건하였다는 창룡사를 비롯하여 시내 쪽 기슭에는 각종 체육시설 및 약수터가 있어 충주 시민의 발길이 끊이지 않는 산이다. 또한 이 산 정상에는 삼국 시대에 축성된 것으로 보여지는 산성이 자리잡고 있는데 이 성이 충주산성이다. 이 산성은 삼한시대 마고선녀가 축성했다는 전설을 간직하고 있어 마고성이라고도 알려져 있다.이 산 남쪽 기슭에는 약 1300년 전 신라 원효대사가 창건하였다는 창룡사가 있고 이곳 북방 3km 지점의 탑대라는 곳에는 3층석탑이 지금도 있을 뿐 아니라 부근의 지명이 윗절골, 아래절골 등으로 불리어 지는 것으로 보아 창룡사를 중심으로 한 직동일대가 대사찰지였던 것으로 보인다.", + "MNTN_HG_VL" : "636", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 직동, 살미면", + "MNTN_NM" : "남산" }, - "longitude" : 127.4489854, - "latitude" : 37.351347400000002 + "longitude" : 127.9743071, + "latitude" : 36.954960700000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "603", - "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", - "MNTN_NM" : "원통산" + "MNTN_HG_VL" : "353", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", + "MNTN_NM" : "아홉산" }, - "longitude" : 127.20805559999999, - "latitude" : 35.511666699999999 + "longitude" : 129.18416669999999, + "latitude" : 35.285277800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "원효산은 낙동정맥이 혼신의 힘을 다해 일구어 영남 알프스의 최고봉인 가지산(1240m)의 남쪽 끝에 있는 신불산, 취서산에서 동남쪽으로 흘러내린 지맥에 위치해 있다. 통도 인터체인지에서 5km쯤 남으로 내려오다 보면 왼쪽으로 나란히 서 있는 원효산은 규모로나 높이로나 만만찮은 산이지만 일반인들에게는 그리 널리 알려져 있지 않아 다소 한적한 산행을 즐길 수 있다.현재 원효산은 정상부근이 입산통제구역으로 되어 있어 정상에 오르는 기쁨은 맛 볼 수 없다. 하지만 신라 선덕여왕 때 창건된 흥룡사와 흥룡폭포를 보는 것만으로 산행의 기쁨을 어느 정도 느낄 수 있다. 또한 암벽을 끼고 있는 원효암과 의상대의 모습이 특히 볼만하다.", - "MNTN_HG_VL" : "922", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 상북면, 하북면, 웅상읍, 동면", - "MNTN_NM" : "원효산" + "DETAIL_INFO_DTCONT" : "충남 예산군 덕산면의 덕산도립공원 내에 위치한 해발 653m의 암산으로 가야산 주봉인 가야봉 북쪽 1.7km지점의 바위봉이다. 주봉인 가야봉에는 중계탑이 가득하게 들어서 있어 주봉의 의미를 퇴색시킨다. 석문봉은 이런 아쉬움을 달래기에 충분한 훌륭한 바위봉으로, 뛰어난 전망을 제공한다. 남쪽 주봉과 북동쪽 1.8km 지점의 옥양봉, 북서쪽으로 일락산이 내려다보이고, 서쪽 해미쪽으로는 서해바다가 시원스럽게 펼쳐진다.산행은 덕산시내에서 덕산초등학교 앞길로 들어선후 2차선의 포장도로를 따라 큰 저수지를 지나고 나오는 상가리 주차장에서부터 시작된다. 약 1km 떨어진 남연군묘앞 공터에 주차가 가능하지만 전체적으로 코스가 길지 않기 때문에 이곳에서부터 산행을 시작하는 편이 좋을 듯하다. 남연군묘 좌측길로 들어서서 시멘트길을 따라 저수지를 끼고 돌담집을 지나 쉼터를 거쳐 안부에 오른후 북쪽 암릉을 거쳐 석문봉 정상에 오른다. 하산은 북동쪽으로 잠시 내려가다 옥녀폭포로 내려서서 2km정도 내려서면 남연군묘에 도착하고, 1km를 더 내려가면 주차장에 도착한다. 산행시간은 총 3시간 30분 정도면 족하다.", + "MNTN_HG_VL" : "653", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", + "MNTN_NM" : "석문봉" }, - "longitude" : 129.1058333, - "latitude" : 35.400833300000002 + "longitude" : 126.6033333, + "latitude" : 36.716666699999998 + }, + { + "mountain" : { + "DETAIL_INFO_DTCONT" : "조양강이 활등처럼 휘어도는 강변가에 푸른 소나무숲이 산기슭을 장식하고 있는 옥갑산은 강원도 정선군 북면과 북평면 사이에 자리잡은 오지의 산이다. 산이름은 옥으로 만든 갑옷을 두른 것처럼 보인다 하여 지어졌다 하며 지도에도 안 나오는 산이다.이 산의 해발 약 1000미터 지점에 상옥갑사가 있는데 옥갑사에서 조양강을 내려다보면 옥갑산 산영을 머금은 맑은 물빛과 섬뜩하리만치 높은 산의 위엄에 새삼 놀라게 된다. 능선상에서도 발 아래 조양강의 푸른 물줄기가 굽이쳐 흐르고, 겨울철에는 소백산능선에서도 보지 못한 아름다운 설경을 바라보고 있으면, 무념 속으로 빠져들어 갈 것만 같은 산이다.정상에 오르면 조양강과 여량, 아우라지 나루터가 내려다 보이고 여량 뒤로 고암산, 상정바위 능선이 흐릿하게 보인다. 정상에서 앞으로 직진하면 상원산, 동쪽으로는 노추산, 서쪽으로는 가리왕산이 있다.", + "MNTN_HG_VL" : "1285", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 북면, 북평면", + "MNTN_NM" : "옥갑산" + }, + "longitude" : 128.68083329999999, + "latitude" : 37.495555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다.", - "MNTN_HG_VL" : "456", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군, 강진군", - "MNTN_NM" : "월각산" + "DETAIL_INFO_DTCONT" : "정상 아래에 석이바위라는 멋진 조망처가 있는데, 옛날에 기우제를 지내던 장소로 산 이름은 여기에서 유래한다. 주민들은 물비리산 또는 물빌이산이라고 부른다. 기우산성(祈雨山城)과 산자락을 따라 삼국시대 말기에 조성된 것으로 추정되는 14기의 신월리 고분군이 남아 있다. 인근 조양산(朝陽山; 684m)과 연계된 산행코스가 개발되어 있으며, 소요시간은 4시간이다. 산행은 상월리에서 시작하여 우암사와 석이바위를 거쳐 정상에 오른 뒤 719봉과 북동릉 산행을 경유하여 조양산에 오르고 송림지대를 따라 성불사로 내려오는 코스이다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 정선읍 신월리", + "MNTN_NM" : "기우산" }, - "longitude" : 126.6819335, - "latitude" : 34.721094600000001 + "longitude" : 128.6730556, + "latitude" : 37.3561111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "두산동과 입압동 경계지역에 있는 강릉시내에서 가장 해발고가 높은 산으로 꼭대기에 옛날 봉화를 올렸던 봉수대가 있었다. 지금은 강릉 봉수대비가 있어 유적의 자취를 찾아 볼수 있다. 월대산은 강릉 사주산의 하나이며 봉 서쪽 낙맥에 일제시대에 일본인들이 한국인의 기를 말살시키기 위해 철주 (쇠말뚝)을 박았던 바위가 있다. 월대산 동쪽 마을은 뻗어내린 산줄기가 곡식을 담는 말처럼 생겼다 하여 말산이라 한다. 남쪽면은 경사가 완만하고 북쪽면은 경사가 급한 편으로 거리가 짧은 편이어서 힘든 코스는 아니다. 정상에 오르는 코스가 여러갈래로 갈라져 있어 모든 코스를 등산하면 운동량이 꽤 많은 코스이다. 조망점에서 강릉시내가 한눈에 들어오는 조망권이 좋은 특징이 있다.", - "MNTN_HG_VL" : "75", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 성덕동", - "MNTN_NM" : "월대산" + "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면과 남종면의 경계에 솟은 해협산은 북으로 정암산(403m)과 한강을 끼고, 남쪽의 관산(555m), 양자산(704m)과 함께 나지막한 산이다. 비록 산은 작으나 산세가 험하지 않고 강과 연접해 있어 가족단위 산행과 물놀이를 즐기기 적당한 곳이다.천지개벽 당시에 온 천지가 물바다가 되어 많은 사람들이 배를 타고 피난을 하던 중 정상에 있는\"군두바위\"에 말뚝을 박고 배를 잡아매었다 하며 바위가 있는 곳이 골짜기라 하여 해협산이라 불렀다 한다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면, 남종면", + "MNTN_NM" : "해협산" }, - "longitude" : 128.9252778, - "latitude" : 37.756111099999998 + "longitude" : 127.3559904, + "latitude" : 37.491495200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "구좌읍 송당리 동족에 비자림(돌오름)과 용눈이오름 사이에 우뚝 솟아있는 매끈한 풀밭오름으로 그 위용을 자랑하며, 구좌읍을 대표하는 오름이라고 할 수 있다. 비단 치마에 몸을 감싼 여인처럼 우아한 몸맵시가 가을 하늘에 말쑥하다. 정상에 분화구가 남아 있는데, 그것이 흡사 달처럼 둥글게 보인다고 하여 현지 주민들 사이에서는 ‘다랑쉬(다:달, 쉬:뫼)’라는 이름으로 불러왔다.행정 구역상 세화리에 속하며 서쪽 일부가 송당리에 걸쳐있어 쉽게 접근 할 수 있다. 월랑봉이라는 이름에서도 알 수 있듯이 달과 연관이 많은 듯한 이 오름에서의 보름달맞이는 장관이라 한다.", - "MNTN_HG_VL" : "382", - "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍 세화리", - "MNTN_NM" : "월랑봉" + "DETAIL_INFO_DTCONT" : "경남 거창 주변에는 험한 산들이 많이 포진해 있다. 그 중 의상봉은 암봉과 골짜기가 조화를 이루어 옛날부터 등산인들의 사랑을 받아 온 곳이다. 의상봉(이상봉 1046.2m)은 가야산 국립공원 남서단에 위치한 바위산이다. 가야산 국립공원은 의상봉 남쪽 고견사 일원과, 의상봉에서 남동쪽 비계산으로 이어지는 능선 일원도 공원지역에 포함시키려 하고 있으나, 거창군의 반대로 2001년 2월 현재 의상봉 동쪽 일원만 국립공원으로 지정해 놓고 있다.또한 억새밭이 유명한 마장재와 쌀굴,견암폭포를 볼 수 있는 곳으로 근래 개발된 가조온천으로 인해 온천산행을 겸할 수 있는 곳으로 각광을 받고 있다.", + "MNTN_HG_VL" : "1046", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "의상봉(이상봉)" }, - "longitude" : 126.82139429999999, - "latitude" : 33.473882400000001 + "longitude" : 128.04416670000001, + "latitude" : 35.752222199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월류봉은 충청북도 영동군 황간면에 솟아 있는 해발 400.7미터의 봉우리다. 이름 뜻 그대로 달이 머문다는 이 봉우리는 달이 머물러 갈만큼 아름답다. 하물며 이곳에선 달이 서쪽으로 그냥 넘어 가는 것이 아니라 능선 모양을 따라 서쪽으로 흐르는 듯 달이 머물다 사라진다고 한다.그리 높지 않지만 빼어난 비경을 지닌 월류봉. 영동 한천팔경이라는 것이 이 월류봉의 곳곳을 세분화하여 일컫는다는 말이 빈말은 아닌 모양이다. 한천팔경 중에서도 산세가 빼어나고 준수한 면모를 지녀 첫손에 꼽히는 월류봉이 당연지사 1경이라면, 3경인 용연동은 월류봉 아래의 깊이를 가늠할 수 없는 깊은 소를 지칭한다. 4경 산양벽은 단애 이룬 월류봉의 기암절벽을 8경은 우암 송시열(1607~1689)이 즐겨 찾던 명승지 월류봉을 감상하며 머물렀다는 한천정사를 말한다.월류봉은 들머리에서 바라보면 토산으로 보이지만 반대편 강가에서 바라보면 기암괴석이 보인다. 봄에는 신록이 우거지고 가을에는 단풍이 아름다워 관광객이 끊이지 않고 있는 산이다. 또 월류봉에 오르면 총강천 건너로 원촌리 구릉성산맥이 한반도의 모양과 똑 닮은 모습으로 자리하고 있는 것을 볼 수 있다.", - "MNTN_HG_VL" : "401", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 황간면", - "MNTN_NM" : "월류봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "347", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "안심산" }, - "longitude" : 127.89136310000001, - "latitude" : 36.234184999999997 + "longitude" : 127.65000000000001, + "latitude" : 34.733333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월방산(月芳山)은 운달산의 한줄기가 길게 뻗어 영순면으로 산줄기를 뻗으면서 산북면과 호계면, 산양면 경계에 솟은 산으로 높이는 낮지만 울창한 소나무와 주변에 유적이 많아 볼거리가 많은 산이다.산행은 산양면 봉정리에서 시작하여 산신제단을 거쳐 정상에 오른 뒤 호계면 봉서리로 내려선다. 산행 시간은 2시간 정도 걸린다. 산기슭에 봉정리 탑동의 삼층석탑 부재, 마애보살입상, 마애여래상, 봉서리삼층석탑 등의 불교유적이 많이 남아 있다.정상 바로 밑에 있는 작은 산신당에 다음과 같은 전설이 전한다. 옛날에 마음씨 고운 아낙네가 산에 나물을 캐러 갔다가 미끄러져 정신을 잃었다. 이 때 꿈에 산신당의 백발노인이 나타나서 벼랑 사이에 흐르는 물을 먹고 바르라고 말하였다. 여인이 꿈에서 깨어 노인이 시키는대로 하였더니 과연 상처가 씻은 듯이 나앗다. 여인의 이야기를 들은 심술궂은 사내가 산신당 벽에 걸린 산신의 눈을 솔가지로 찌르고 벼랑 사이에 흐르는 우물을 파헤쳤다. 그러자 밤마다 귀신이 나타나 3일만에 사내가 죽고 우물물이 흙탕물로 변했으며 호랑이가 나타나 마을의 가축들을 물어갔다. 이에 주민들은 산신의 노여움을 가라앉히기 위해 매년 정월 대보름에 제사를 드리기 시작하였고, 이 제사는 지금도 이어지고 있다.", - "MNTN_HG_VL" : "360", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 봉정리", - "MNTN_NM" : "월방산" + "DETAIL_INFO_DTCONT" : "하남시청에서 동쪽으로 5킬로미터 떨어져 있는 산으로 일설에 의하면 검단선사가 은거하였다 하여 검단산으로 불린다. 산행 초입은 야산과 같아 느낌을 주지만 산 중간쯤 오르면 어느 산 못지않게 뛰어난 숲과 아름다운 풍경과 고사목이 군데군데 널려 있다.정상은 넓은 공터로 사방이 확 트여 있고 팔당댐은 물론, 북한강과 남한강의 합류 지점인 양수리 일대를 시원하게 내려다 볼 수 있으며 예봉산, 운길산, 도봉산, 북한산 등을 조망할 수 있다.검단산 산행 들머리인 배알미동은 ‘도성을 떠나는 사람들이 이곳부터는 임금이 거처하는 곳이 보이지 않거나, 또는 멀리서 도성 근처로 다가오는 길손이 이곳에 들면 임금을 배알할 수 있게 된다’는 설이 전해지는 마을이다. 검단산은 최근에 지어진 ‘통일정사’로 인해 불경을 들으며 산행을 시작할 수 있다.", + "MNTN_HG_VL" : "658", + "MNTN_LOCPLC_REGION_NM" : "경기도 하남시 천현동", + "MNTN_NM" : "검단산" }, - "longitude" : 128.2333333, - "latitude" : 36.633333299999997 + "longitude" : 127.2472779, + "latitude" : 37.521461799999997 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "133", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", - "MNTN_NM" : "월봉산" + "MNTN_HG_VL" : "882", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "부용산" }, - "longitude" : 127.11222220000001, - "latitude" : 36.798333300000003 + "longitude" : 127.82734619999999, + "latitude" : 38.000608399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 거창군 북상면(北上面)과 함양군 서상면(西上面)의 경계에 있는 산. 덕유산국립공원 남쪽에 위치한다. 북쪽 능선을 따라 덕유산(1,614m)에 이르고, 남쪽으로는 거망산擧網山:1,184m)에 이른다.동쪽 비탈면은 남강(南江)의 상류인 지우천(智雨川)의 수원이 되고, 동쪽에 위치한 기백산(箕白山:1,331m)과의 사이에 계곡을 이룬다.서쪽 비탈면은 완만하고 남강의 상류 하곡(河谷)을 이룬다. 서쪽의 장수군 장계면(長溪面)과의 사이에 육십령(六十嶺)이 있는데, 영남과 호남지방의 중요한 통로이다. 남강 하곡분지를 둘러싸고 있으며 덕유산에 이어져서 자연경관이 아름답다. 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나다.소요 시간 :1코스 (3시간정도)서상 - 영각사 - 남녕재(기점) - 능선 - 정상2코스 (4시간정도)안의 - 용추계곡 - 수망령 - 큰목재 - 정상 - 남녕재최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나며 남릉과 서북릉의 중턱위로 진달래가 군락을 이루어 천상의 화원을 걷는 기분이 든다.숲길 명소 : 남릉과 서북릉의 중턱위로 진달래 군락월봉산은 덕유산의 명성에 가려 많이 알려지지 않았다가 최근 들어 찾는 이가 늘고있는 산이다. 단독코스로도 다녀올 수 있고 금원산과 연계하여 종주하기도 하고 거망산과 연계하여 종주하기도 한다.함양군에서 안내판과 이정표를 적절히 설치해놓았다. 내계에서 가는 길은 임도길을 많이 걸어야해 산길오르기전에 지치기 쉽다. 남령 안내판에는 식수대가 그려져있지만 찾아보니 없다. 식수대가 있으면 좋을 듯하다.", - "MNTN_HG_VL" : "1294", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 서상면, 거창군 북상면", - "MNTN_NM" : "월봉산" + "DETAIL_INFO_DTCONT" : "전라남도 고흥군은 보성에서 끝날듯하던 한반도 남단이 벌교를 지나 계속 남쪽으로 내달으면서 형성된 반도를 이룬 군이다. 때문에 고흥 하면 바다만 보일 것만 같은 선입견을 갖기 마련이다.하지만 실제 고흥땅을 밟으면 해발 500~600m대 높이의 산들이 수없이 많다는 사실을 깨닫게 된다. 말이 엎드려 있는 형상이라는 이름을 갖고 있듯 마복산은 해창벌에서 바라보면 그저 동서로 길 게 뻗은 동네 뒷산처럼 평범하게 느껴진다. 하지만 파고들면 생각지도 못했던 모습에 마음을 빼앗기고 만다. 산등성이에는 수많은 지릉이 흘러내리고 그 지릉마다 바위꽃이 활짝 피어 있어 마치 금강산이나 설악산의 축소판을 보는 듯하다. 이러한 경관 때문에 마복산은 소개골산(少皆骨山)이라 불리기도 한다.마복산이 지닌 또 하나의 자랑거리는 다도해 전경이다.산 남쪽 바다는 다도해 해상국립공원으로 지정되어 있을 만큼 아름다운 곳이다. 산 등성이에 올라 푸른 바다 위를 떠다니는 듯한 올망졸망한 섬들 부드러운 선으로 이어지는 해안선과 그 사이사이 들어앉은 포구를 바라 보노라면 보는 이마저도 바다에 떠 있는 듯한 느낌에 사로잡히고 만다.", + "MNTN_HG_VL" : "539", + "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군", + "MNTN_NM" : "마복산" }, - "longitude" : 127.72486480000001, - "latitude" : 35.729298100000001 + "longitude" : 127.3888716, + "latitude" : 34.536739400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1279", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양", - "MNTN_NM" : "월봉산" + "DETAIL_INFO_DTCONT" : "백련산은 높이 215.5m의 낮은 산이지만 서울시내 서대문구와 은평구의 경계에 자리하고 있어 주말이면 응암동,홍은동 일대의 주민들이 자주 찾는 산이며, 휴식공간으로 잘 활용되고 있다. 신라 경덕왕 때(서기747년) 진표율사가 창건, 무학대사가 중건한 백련사란 절이 있어 백련산이라 불리었다.", + "MNTN_HG_VL" : "216", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 은평구, 서대문구 홍은동", + "MNTN_NM" : "백련산" }, - "longitude" : 127.72486480000001, - "latitude" : 35.729298100000001 + "longitude" : 126.9269444, + "latitude" : 37.589444399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월아산은 해맞이, 달맞이가 아름다운 산으로 봉긋한 두 봉우리 사이로 수줍게 떠오르는 해와 달은 한 폭의 그림이다. 달을 토해내듯하다는 월아산은 산이 구릉을 이루고 있지만 숲이 아름답고 아담해 가족 단위 등산인들이 주말을 이용해 즐겨 찾는 산이다. 월아산은 장군대산과 이어지는데 장군대산 높이도 482.4미터밖에 되지 않아 한나절 산행으로 알맞다.진주 동쪽에 있는 월아산은 나라에 한발이 계속되면 나라에서 기우제를 지내던 곳으로 일명 ‘무제등’이라고도 한다. 1950년대까지도 기우제를 지냈다는 기록이 남아있다.산행 들머리는 갈전리의 청곡사와 용아리의 금호지 또는 질매재에서 시작한다. 갈전리 청곡사에서 할 경우 장군대산과 월아산 국사봉을 무리하지 않고 종주할 수 있어 좋다. 표식기가 많이 붙어있으며 등산로 중간에 땀을 식힐 수 있는 편의시설이 갖추어져 있다. 날머리 금호지는 커다란 자연 호수로 물이 맑고 푸르며 깊이가 깊어 명주실 3꾸리가 들어갔다는 전설이 있다. 그러나 지금은 제방둑을 쌓아 농업용 저수지로 만들어놓았다.산행 들머리에 있는 청곡사는 신라 헌강왕 5년에 도선국사가 창건한 절로 남강의 청학이 월아산으로 날아드니 사기가 충만함을 보고 정해진 절터라 전해온다. 절 입구에 있는 방학교와 ‘학을 불러들인다’는 뜻의 환학루가 이 전설을 뒷받침하고 있다.", - "MNTN_HG_VL" : "469", - "MNTN_LOCPLC_REGION_NM" : "경남 진주시 금산면ㆍ진성면", - "MNTN_NM" : "월아산" + "DETAIL_INFO_DTCONT" : "진도읍에서 임회면 용호마을에 이르면 단정한 모습의 선녀를 닮은 산이 보인다. 여귀산은 마치 단정하게 차려입은 선녀가 가야금을 타는 형상이라 하여 풍수지리가들은 옥녀탄금형의 산이라고 한다. 여기서 옥녀는 가야금을 타는 선녀를 지칭하는데, 선녀는 곧 귀한 여자이므로 산 이름이 여귀산이 된 걸로 추정된다.여귀산은 두 얼굴을 가진 산이다. 정상은 제법 오르기가 험난한 바위지대로 이뤄진 반면 정상을 중심으로 좌우로 흘러내린 지능선들은 부드러운 산세를 이루고 있기 때문이다. 밖에서 바라본 여귀산은 어느 방향이든 쉽게 오를 수 있을 것으로 보이지만 막상 산에 들어서면 수림이 빽빽해 기존 등산로를 벗어나서는 산행이 어렵다.그러나 일단 주능선이나 정상에 오르면 남서쪽으로 시원하게 펼쳐진 다도해국립공원을 비롯해 바다 풍경이 황홀하게 펼쳐진다. 특히 바다를 주홍빛으로 물들이는 일출과 낙조가 일품이다.", + "MNTN_HG_VL" : "457", + "MNTN_LOCPLC_REGION_NM" : "전남 진도군", + "MNTN_NM" : "여귀산" }, - "longitude" : 128.1900574, - "latitude" : 35.191648100000002 + "longitude" : 126.2297222, + "latitude" : 34.390555599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "달이 떠오르는 모양을 한 산이라는 월아산은 1986년 도시자연공원으로 지정되었으며 북쪽의 봉우리는 달임산 남쪽 봉우리를 장군대라 부르는데, 장군대산 또는 달음산이라고 부르기도 한다. 두 봉우리 사이에 떠오르는 보름달이 인근 금호지에 비치는 모습을 아산토월(牙山吐月)이라 해서 진주 12경 중 하나로 꼽는다.정상은 예부터 기우제를 지내던 곳으로 임진왜란 때 김덕령 장군이 목aring;성을 쌓고 왜적을 무찌르던 곳이다. 시내에서 10분 거리로 가깝고 숲이 아름다워 가족단위의 등산객이 주말마다 즐겨atilde;는 산이다.사찰로는 산 서쪽에 있는ucirc;곡사가 많이 알려졌다.ucirc;곡사(靑谷寺)는 879년(신라 헌강왕 5)에 도선이acirc;건하고 고려말 우왕 때 실상사 장로 상총대사가 중건한 바 있으며, 임진왜란 때 불에 탄 것을 선조와 광해군 대에 걸쳐 복원한 고찰이다.ucirc;곡사 입구의 다리 방학교(訪鶴橋)에는 남강변에서 노닐던ucirc;학이 이곳으로 날아온 것을 보고 도선이 절터로 정했다는 이야기가 전한다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "경남 진주시", - "MNTN_NM" : "월아산(장군대봉)" + "DETAIL_INFO_DTCONT" : "두류산은 강원도 화천군 사내면과 하남면 사이에 위치한 산으로 위도상 38도선 북방 12km거리에 자리하고 있어 민간인들의 출입이 뜸한 곳이다. 그래서 백마계곡의 수려한 계곡미와 울창한 수림, 기암절벽이 이룬 아름다운 조화를 그대로 간직하고 있다.백마계곡에는 대명사와 신선바위 등이 있고, 청정지대로 유지되고 있다. 계곡 물이 맑고 숲이 울창해 여름산행에는 제격인 산이다.정상은 운모가 섞인 광석토양이라 나무 한그루 풀 한 포기 없지만, 사방으로 펼쳐진 두류산의 주름진 자락을 한눈에 볼 수 있다.금강산을 찾아가던 신선들이 이 산 경관에 반해 잠시 머물다 갔다는 전설이 전해질 정도니 이 산을 직접 가보지 못한 사람들도 그 절경은 가히 짐작할 만 하다.마치 명월이가 누워 있는 옆모습 같다 하여 두류산이라 불리며, 마을 이름도 명월리이다.", + "MNTN_HG_VL" : "993", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 사내면 하남면", + "MNTN_NM" : "두류산" }, - "longitude" : 128.1900574, - "latitude" : 35.191648100000002 + "longitude" : 127.5457596, + "latitude" : 38.103257200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월악산 국립공원은 충북 제천시 한수면과 덕산면의 경계를 이루는 산으로 백두대간이 이화령을 지나 조령산, 조령, 마패봉, 부봉, 월항삼봉, 하늘재, 포암산을 거쳐 대미산으로 이어지는 중간선 북쪽에 솟아있는 봉우리이다. 넓이 373㎢에 걸쳐 있는 월악산 능선은 백두대간보다 높고 무엇보다도 바위와 암릉으로 형성되어 있어 대간에 비해 능선이 훨씬 두드러져 있다.제천시 한수면과 충주시 살미면의 경계를 이루는 지점에 자리한 월악수리봉은 일반인들에게는 생소한 이름이지만 알고보면 숨겨진 비경들이 많은 명산이다. 산행을 나선 후 곳곳에서 펼쳐지는 기암절벽의 변화무쌍함은 산악인들의 탄성을 자아낸다. 숨은 절경들은 둘러보며 정상에 오르면 어느새 월악수리봉에 대한 애정이 듬뿍 생겨 다시한번 이 곳을 찾고 싶은 마음이 절로 든다.월악산(月岳山 1095.3m) 뒤안길에는 용하구곡이 30리나 늘어서 있는데 월악시루봉은 용하구곡의 서쪽에 병풍처럼 자리한 산이다. 시루봉을 가려면 일단 덕산면을 거쳐야 한다. 덕산(德山)은 이름 그대로 산의 덕을 본다는 뜻으로 덕산면은 예부터 인삼재배 적격지로 유명하다. 산 곳곳에 빼어난 경관이 산재해 있는데 특히 전망대 바위에서의 조망이 일품이다. 전망대 바위에 오르면 서북쪽의 월악산 정상이 울부짖는 호랑이 형상을 하고 있어 보는 이의 마음을 압도하며 동쪽에는 용하구곡 건너로 하설산, 매두산, 문수봉 산릉이 아름다운 풍광을 연출하고 있다.", - "MNTN_HG_VL" : "1095", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면, 덕산면", - "MNTN_NM" : "월악산" + "DETAIL_INFO_DTCONT" : "부산광역시의 대표적인 진산 중의 하나인 구덕산은 울창한 수림을 자랑하고 있다.구덕산은 해발 562m로 북구 학장동과 사하구 당리동, 서구 서대신동의 경계에 솟아 있다. 태백산맥의 말단 금정산 줄기 끝자락에 위치하고 있으며, 북동쪽으로는 엄광산에, 남서쪽으로는 시약산에 각각 이어져 있다.산기슭에는 구덕사가 있고, 시민의 휴식공간으로도 널리 이용되고 있는 대신공원과 한때 대규모 꽃 재배단지로 유명했던 꽃마을, 구덕수원지 등을 품고 있어 곳곳에 원예수와 꽃이 재배되어 시민들의 산책로로도 많이 이용된다. 구덕고개 밑으로는 구덕 터널이 뚫려 있다. 예전에는 이 산을 구덕산(舊德山) 또는 엄광산(嚴光山)이라고 불렀다.", + "MNTN_HG_VL" : "562", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 북구, 사하구, 서구", + "MNTN_NM" : "구덕산" }, - "longitude" : 128.09096439999999, - "latitude" : 36.889304099999997 + "longitude" : 128.99967799999999, + "latitude" : 35.122726499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월악산(月岳山 1093m) 뒤안길에는 용하구곡이 30리나 늘어서 있는데 월악시루봉은 용하구곡의 서쪽에 병풍처럼 자리한 산이다. 시루봉을 가려면 일단 덕산면을 거쳐야 한다. 덕산(德山)은 이름 그대로 산의 덕을 본다는 뜻으로 덕산면은 예부터 인삼재배 적격지로 유명하다. 산 곳곳에 빼어난 경관이 산재해 있는데 특히 전망대 바위에서의 조망이 일품이다. 전망대 바위에 오르면 서북쪽의 월악산 정상이 울부짖는 호랑이 형상을 하고 있어 보는 이의 마음을 압도하며 동쪽에는 용하구곡 건너로 하설산, 매두산, 문수봉 산릉이 아름다운 풍광을 연출하고 있다.", - "MNTN_HG_VL" : "770", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시", - "MNTN_NM" : "월악시루봉" + "DETAIL_INFO_DTCONT" : "제왕산의 모산으로 오르기가 다소 힘드나 찾는이가 적어 자연이 그대로 보존된 산이다. 백두대간이 동해를 끼고 설악산(1708)과 오대산(1563), 황병산(1407)을 일으키고, 대관령에서 몸을 낮췄다가 다시 솟아오른 산이 능경봉이다. 겨울철에는 무릎이 빠질 정도로 눈이 많이 쌓이는 곳이나, 비교적 힘들이지 않고 눈덮힌 겨울산을 즐길 수 있는 곳이다.능경봉 산행 들머리는 해발 850m가 넘는 대관령 고개마루인 대관령 남쪽휴게소에서 시작된다. 대관령에는 고갯길을 내고 두 번씩이나 죽음을 당한 고형산(高荊山)이라는 사람 얘기가 유명하다. 본래 대관령 고갯길은 오솔길이었으나, 이 고갯길을 조선시대 중종때 고형산이라는 사람이 사재를 털어 수개월 간에 걸쳐 우마차가 다닐수 있도록 넓혀 놓았다. 따라서 강릉과 한양간의 교통이 편리해졌다.", + "MNTN_HG_VL" : "1123", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "능경봉" }, - "longitude" : 128.09096439999999, - "latitude" : 36.889304099999997 + "longitude" : 128.7647929, + "latitude" : 37.672805199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월여산은 경남 거창군 남쪽 지맥에 우뚝 솟아 있다. 인근 사람들은 3개의 봉우리로 이루어졌다해서 삼봉산으로도 부른다. 이 산은 산세가 좋아 무학대사가 금계포란형이라 지목하여 유명한 풍수가들이 즐겨 찾았던 곳이다.거창의 지형으로 보아 거창지역의 모든 물줄기는 거창읍을 거쳐 남하면에서 합수하여 합천호에 이르지만 월여산이 위치한 신원천만은 그 아래쪽으로 독립되어 흐르고 있다. 산이 높으면 골 또한 깊어 수량이 풍부하다. 그 물이 맑아 월여산을 찾는 이들을 반긴다. 정상 서쪽면은 층암절벽이 관목과 어우러져 가을 단풍이 특히 아름답다.", - "MNTN_HG_VL" : "862", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "월여산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "978", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창 방림면, 대화면", + "MNTN_NM" : "장미산" }, - "longitude" : 127.9480152, - "latitude" : 35.549462400000003 + "longitude" : 128.36008799999999, + "latitude" : 37.475849199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "옥천군 이원면에 위치한 월이산은 말그대로 `달이 떠오르는 산'이라는 뜻이다. 순우리말로 달이산이라고도 부른다. 산세가 달처럼 둥근 모양이다. 북쪽으로 금강이 흐르며, 기암괴석으로 이루어진 정상 서쪽에 투구처럼 생긴 투구봉과 서봉(507m)이 있고 남쪽 산등성이 아래에는 높이 20m의 옥계폭포가 있다. 달이산 최고의 명소이기도 하며 달이산 줄기와 앞의 국사봉 줄기가 마주칠 듯 맞보고 서있는 사이에 한줄기 시원한 옥계폭포에는 많은 사람들이 찾는다.정상에 오르면 산을 병풍삼아 S자로 휘어져 흐르는 금강이 보이고 멀리 서쪽으로 금강철교·서대산 등이 한눈에 들어온다. 정상에서 서봉(507m)으로 넘어가는 산등성이에 있는 투구봉에서는 밧줄을 잡고 암봉을 오르는 산행의 묘미를 느낄 수 있다. 조선시대에 영동의 박달산과 대전의 계족산 봉수대를 중계하던 봉수대 터가 정상에 남아 있다.", - "MNTN_HG_VL" : "551", - "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 이원면 원동리", - "MNTN_NM" : "월이산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", + "MNTN_NM" : "감악산" }, - "longitude" : 127.6561111, - "latitude" : 36.228888900000001 + "longitude" : 127.92212739999999, + "latitude" : 35.596956200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "월출산은 국내에서 규모가 제일 작은 국립공원으로 천태만상의 기암괴석이 수석 전시장을 연상케한다. 남성적인 웅장함을 갖춘 북쪽의 가파른 돌산과 여성적인 섬세함을 갖춘 완만한 남쪽산이 조화를 이뤄 지리산, 변산, 천관산, 내장산과 함께 호남의 5대 명산으로 꼽히고 있다. 신라시대에는 월나산(月奈山), 고려시대에는 월생산(月生山) 그리고 조선시대부터 월출산이라고 불리어졌다.", - "MNTN_HG_VL" : "811", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 영암읍ㆍ군서면ㆍ학산면, 강진군 성전면", - "MNTN_NM" : "월출산" + "DETAIL_INFO_DTCONT" : "p class=\"bonmun\"토정비결을 지은이지함이 올라가서 편하게 자리잡아 앉았다 해서 평안산이라 하기도 하며, 옛 성 터가 있어 이곳에 피난한 사람은 모두 무사하였다 하여 평안산이라 불리운다고 한다. 공주시가지로부터 남서쪽에 위치해 있으며, 북쪽으로는 금강과 칠봉산이, 남쪽으로는 장군봉이 위치해 있다.", + "MNTN_HG_VL" : "168", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 운곡리", + "MNTN_NM" : "평안산" }, - "longitude" : 126.7104573, - "latitude" : 34.774338800000002 + "longitude" : 127.0177778, + "latitude" : 36.3541667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "523", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", - "MNTN_NM" : "위례산" + "DETAIL_INFO_DTCONT" : "우리나라의 산이름 중에 백운산 이라는 이름을 가진 산이 많다.그 중에서\"흰구름산\"이라는 이름값을 제대로 하는 산이 함양의 백운이다.높이도 1000 m 가넘는 준봉인데다 산정에서의 조망도 으뜸이라 할수있다. 남도의 명산이라 일컫는 산들이 동서남북 어떤 방향에서도 거칠것없이 한눈에 들어온다.노고단에서 천왕봉까지 남쪽 스카이라인의 지리산 파노라마는 그리움의 경지를 넘어 성스러움을 느끼게 한다. 반야봉의 자태는 너무 뚜렷해 민망스럽기까지 하다.북쪽 끄트머리에는 넉넉한 덕유산이 태평스레 앉아있고 그너머에는 황석, 거망, 월봉 산이 어깨를 맞대고 있다. 금원산 기백산도 지척으로 보이고 동북 방향으로는 가야산, 황매산도 가물거린다.백운산은 명산에 둘러싸여 명산과 어깨를 나란히 하는 이 지방 최고의 진산이다. 겹겹이 둘러싼 능파들 사이사이로 흰구름이 부리는 조화는 백운산만이 연출해 낼 수 있는 활동사진. 산세 또한 전형적인 육산이기에 사계절 내내 산행이 가능한 것이 이 산의 매력이다.", + "MNTN_HG_VL" : "1279", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 백전면", + "MNTN_NM" : "백운산" }, - "longitude" : 127.2547119, - "latitude" : 36.880067799999999 + "longitude" : 127.63534850000001, + "latitude" : 35.616948800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "위봉산은 별로 높지 않고 많이 알려져 있지도 않은 산이다. 추줄산이라고도 한다. 삼국시대 백제와 신라의 국경지대를 이루었고 조선시대에는 성리학의 영남학파와 기호학파를 구분짓는 학풍적 경계를 이루었던 곳이다. 하지만 분지에 위봉산성과 위봉사를 품고 있고, 전주의 8경 중 하나라 일컬어지는 2단 위봉폭포도 거느리고 있어 이름만 알려지지 않았을 뿐이지 실세라 할 수 있다. 또한 이 명물들을 구경하면서 오르는 산길은 부드럽게 이어져 마치 공원에 나온 듯한 착각이 들 정도로 편한 산이다.정상에 서면 북으로 동상저수지, 동으로 연석산, 운장산, 남으로 원등산, 마이산, 만덕산, 서로는 종남산, 서방산 등을 조망할 수 있다.위봉사는 604년(백제 무왕 5) 창건된 것인데 한국 불교사찰 31본산의 하나로서 경내에는 보광명전(普光明殿;보물 608) 등이 있다. 위봉산성은 송광사에서 위봉사로 넘어가는 고개 위에 그 터가 남아 있는데 성내에는 행궁과 진전의 터도 있다. 송광사에서 더 깊이 골짜기를 타고 4㎞쯤 위봉산 고개길을 오르면 위봉산성 서문이 나온다. 이 위봉산성 서문을 지나 300m쯤 내려가면 위봉사가 나온다.위봉산성은 이태조의 영정을 봉안하기 위해 축성했던 성이다. 성의 규모는 길이 16㎞, 높이 4~5m, 폭 3m의 홍예석문이 지방기념물로 보존되고 있다. 이 산성은 1675년 (숙종 원년) 7년의 세월과 인근 7개 군민을 동원하여 쌓은 것을 임진왜란, 정유재란, 병자호란을 겪으면서 전주 경기전의 영정과 왕조실록을 묘향산까지 피난시켰고, 무주 적상산성에 설치한 사고도 어려움이 많아 전주에서 가까운 험한 지형을 골라 새로 성을 쌓아서 이태조 영정을 피난시키는데 목적이 있었다. 사찰 앞에서 1백여미터 아래에 있는 위봉폭포가 장관이다. 절벽사이로 비류직하 하는 60여미터의 폭포와 빼어난 경관은 그 아래로 펼쳐진 골짜기, 그리고 동상댐 호반의 절경 등이 어우러져 주말뿐 아니라 평일에도 이곳을 찾는 차량의 행렬이 줄을 잇고 있다.", - "MNTN_HG_VL" : "524", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 소양면, 동상면", - "MNTN_NM" : "위봉산" + "DETAIL_INFO_DTCONT" : "백봉은 평범한 산이라 별다른 재미가 없다고 말할지 모른다. 그러나 숲속의 산길이 유난히 편안하고 단풍나무가 많아 화사한 것이, 평범하지만 잔잔한 재미가 있는 산이다. 백봉 산행을 뜻깊게 하는 것 중 하나는 묘적사와 홍릉 등의 유적이다.묘적사는 백봉 남쪽 골짜기에 있다. 묘적사계곡을 중심으로 백봉의 산등성이가 말발굽모양으로 둘러싼 산세이기에 묘적사는 산행 들머리 혹은 날머리 기점이 된다. 그래서 묘적사 골짜기에 들어서면 협곡의 개울을 따라 꼬불꼬불 휘돌아 들어가는 것이 마치 별천지에 들어온 느낌이 든다.지형도에는 백봉의 이름은 흰 ‘백’ 자를 쓴 백봉(白峰)으로 되어 있으나 본래 이름은 잣봉산 혹은 묘적산이다. 남양주 시지에 의하면 평내동과 화도읍 쪽에서는 백봉을 잣봉산이라 부르며 와부읍에서는 묘적산이라 부른다고 밝히고 있다.백봉은 수도권에서 멀지 않고 인구 밀집지역인 남양주 도심에서 가까이 있는 산이어서 많은 사람들이 오르내린다. 따라서 길도 좋고 갈래도 많다. 그러나 백봉의 참맛을 보려면 홍유릉과 묘적사를 잇는 산길이 가장 좋다. 이 코스가 좀 길어도 산길이 험하지 않고 편안해 4시간 정도면 산행을 마칠 수 있다.", + "MNTN_HG_VL" : "587", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 평내동, 와부읍, 화도읍", + "MNTN_NM" : "백봉산(백봉)" }, - "longitude" : 127.2619316, - "latitude" : 35.918517299999998 + "longitude" : 127.2577778, + "latitude" : 37.638888899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "목포시와 다도해를 한눈에 굽어볼 수 있는 높이 228m의 목포 뒷산으로, 기암절벽이 첩첩하여 '호남의 개골'이라고도 한다. 산은 비록 해발고도가 낮으나 산정은 매우 날카롭고 층층기암과 절벽이 많아 경치가 수려하다. 이엉으로 바위 전체를 덮어서 마치 아군의 군량미처럼 꾸며 왜군이 감히 넘보지 못하게 하였다는 설화가 전해오는 노적봉을 비롯하여 해발 228m의 일등바위와 이등바위로 나뉘어져 있다.산정에서는 목포시와 다도해를 한눈에 바라볼 수 있고 그 사이를 오고 가는 크고 작은 선박들의 모습이 마치 한포그이 동양화를 연상케 한다. 동쪽 산꼬리에는 기상관측소 ·시청 ·법원 등 관공서가 있고, 산 중턱에는 유달사 ·수도사(修道寺) ·관음사(觀音寺) 등 사찰이 많다. 서쪽 산록은 바다에 임하며 해수욕장으로 유명하다. 또한 이 산에는 대학루, 달성각, 유선각 등 5개의 정자가 있으며, 산 주변에는 2.7km의 유달산 일주도로가 개통되어 있다. 산 아래에는 4. 19 기념탑, 충혼탑, 가수 이난영이 부른 '목포의 눈물' 기념비 등과 조각작품 65점이 전시된 조각공원과 난공원이 있다.", - "MNTN_HG_VL" : "228", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 죽교동", - "MNTN_NM" : "유달산" + "DETAIL_INFO_DTCONT" : "검봉은 춘천시 남산면 강촌리 북한강변에 솟아 있으며 구곡폭포로 유명한 봉화산(487m)과 산줄기를 잇고 있다. 봉화산과 이웃해 있어 구곡폭포 방향을 산행 기점으로 삼을 수도 있으나 구곡폭포에서 문배마을에 이르는 널따란 길이 나 있어 산행 첫머리로는 어울리지 않아 강촌리 강선사를 들머리로 하는 것이 보통이다.검봉은 칼을 세워 놓은 것처럼 생겼다고 해서 칼봉으로도 불린다. 또 주위 경관이 아름다워 사계절 내내 많은 관광객이 찾고 있으며 특히 겨울철에는 빙벽 교육 장소로도 인기 있다.강촌역 뒤 강선사로 오르면 첫 번째 봉우리에서 오른쪽으로는 의암호가 보이며 왼쪽으로는 경기도와 경계 지점인 도계휴게소 및 강촌휴게소가 보인다. 아득하게 보이는 발아래 경치를 감상 한 뒤 능선을 따라 2~3시간 정도 오르면 아홉 구비 계곡을 돌아 볼 수 있는 구곡정이 나타나며 50여 미터 높이의 구곡폭포에서물안개를 일으키며 떨어지는 물줄기가 보인다.", + "MNTN_HG_VL" : "530", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남산면", + "MNTN_NM" : "검봉" }, - "longitude" : 126.37257219999999, - "latitude" : 34.791997799999997 + "longitude" : 127.5986521, + "latitude" : 37.805322400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "국립지리원 발행 지형도에도 마유산으로 표기하다가, 1973년 국토자오선 종주대가 이 산을 통과하면서 당시 대원 중 홍일점이었던 진유명씨의 이름을 따서 유명산으로 부르게 되었다.이 산은 정상에 이르는 능선이 완만하고 부드러우며, 산 전체에 갖가지 나무가 울창하여 봄부터 여름까지 하늘을 가릴 정도이고 여름이면 기암괴석과 우거진 숲이 조화를 이룬 계곡은 수량이 풍부해 절경을 이루고 있다.", - "MNTN_HG_VL" : "864", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", - "MNTN_NM" : "유명산" + "DETAIL_INFO_DTCONT" : "주능선이 마치 병풍을 펼친 듯한 산세로, 예부터 '소금강' 이라 불리어질 만큼 아름답다. 게다가 주능선 좌우로 홍천강이 흐르고 있어 정상에 올라서 바라보는 전망이 더 없이 좋으며, 물놀이도 겸할 수 있는 곳이다.팔봉산은 흔히 두 번 놀라게 하는 산으로 알려져 있다. 낮은 산이지만, 산세가 아름다워 놀라고 일단 산에 올라 보면 암릉이 줄지어 있어 산행이 만만치 않아 놀란다는 것이다.", + "MNTN_HG_VL" : "328", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서면 팔봉리", + "MNTN_NM" : "팔봉산" }, - "longitude" : 127.48761399999999, - "latitude" : 37.576265100000001 + "longitude" : 127.6954236, + "latitude" : 37.6974485 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "98", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", - "MNTN_NM" : "유방산" + "MNTN_HG_VL" : "178", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", + "MNTN_NM" : "구봉산" }, - "longitude" : 126.4427778, - "latitude" : 34.806111100000003 + "longitude" : 126.4441667, + "latitude" : 37.525833300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "유학산은 높다란 바위벽이 병풍처럼 둘러처져 있고 낙락장송이 어우러진 수려한 경치를 자랑하는 산이다. 하지만 6·25전쟁 때는 치열한 격전지였다. 이런 역사적 아픔 때문에 이곳에는 다부리와 왜관지구 두 곳에 전적기념관이 있다. 경치가 빼어나 학이 놀다간 산이라는 이름을 가졌지만, 잊어서는 안될 우리의 가슴 아픈 역사를 간직하고 있기에 문화답사 산행지로 적격이다.유학산은 동봉과 서봉 능선이 동서로 길게 뻗은 산으로 팔공산에서 서쪽으로 이어지는 산줄기의 서쪽 끝에 위치한다. 유학산의 서쪽면은 중턱에서부터 고스락까지 깎아지른 거대한 바위가 병풍처럼 솟아 있다.바위 벼랑이 까마득하게 높아 쉰길이나 된다는 쉰길바위가 있고 학이 놀았다는 학바위, 조망 좋고 시원한 신선대가 있다.", - "MNTN_HG_VL" : "839", - "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 석적면", - "MNTN_NM" : "유학산" + "DETAIL_INFO_DTCONT" : "우암 송시열 선생이\"도를 깨닫고 스스로 즐길 만한 곳이다\"해서 도락산이라 명명한 이 산은 경북과 충북의 도경계선에 근접해 있다.월악산국립공원권에 속해 있는 산으로, 충북 단양군 단양읍과 대강면의 경계를 이루고 있으며 도락산 산자락에는 단양 8경 중 4경인 사인암,상선암,중선암,하선암 등이 있어 관광의 보고이기도 하다.", + "MNTN_HG_VL" : "965", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면, 대강면", + "MNTN_NM" : "도락산" }, - "longitude" : 128.51033670000001, - "latitude" : 36.064411100000001 + "longitude" : 128.31169420000001, + "latitude" : 36.856228899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황조리에서 올라가는 코스는 산 중턱 까지 경사가 심하고 임도구간을 만나면 그길로 임도를 따라 등산로 길이 있다. 마교리에서 올라가는 코스도 산중턱까지는 경사가 심하고 첫번째 봉우리를 지나면 완만한 등산로길이 나온다. 숲길주변을 정비해서 인지 깔끔히 되어 있고 가는길 중간중간 마다 이정표가 설치 되어 있다. 삼척시 도계읍 신리와 항조리 사이에 위치하고 있으며 태백산맥에 속한다. 산정에는 육백산면 이라는 고위 평탄면이 있어 한국의 지형발달을 연구하는데 중요한 지표가 된다.둘레에는 해발 1000m가 넘는 봉우리 십여개가 이 산을 호위하고 있으며 이 산줄기는 근산,응봉산으로 이어져 낙동정맥과 만나 부산 금정산까지 뻗어간다.", - "MNTN_HG_VL" : "1251", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍 황조리", - "MNTN_NM" : "육백산" + "DETAIL_INFO_DTCONT" : "서울시 관악구와와 안양시를 경계로하는 삼성산은 관악산 주능선에서 서쪽으로 뻗어내린 팔봉능선을 타고 무너미고개로 내려 않다가 다시 솟구쳐 오른 산으로, 삼성산 아래 국기봉과 삼막사로 많이 알려져 있으며, 바위로 된 암산이다.관악산, 삼성산은 양쪽 봉우리가 서로 이어져 있어 일반 등산객들은 삼성산을 관악산의 한 작은 봉우리로 여겨 삼성산 정상에서도 관악산에 오른 것으로 생각하기도 하여 요즘은 특별하게 둘을 구분하지 않고 있다. 원효대사가 의상, 윤필과 함께 삼막사란 사찰을 짓고 수도하였다 하여, '삼성산' 이라는 이름이 붙여졌다고 한다. 이 산에는 신라 문무와 17년 (677)에 창건한 삼막사, 고려 태조때 창건한 염불암, 그리고 망월암등 절과 암자가 산자락에 자리잡고 있다.관악산 유원지로 들어서면 왼쪽이 관악산, 오른쪽 능선이 삼성산 능선이다. 삼성산의 등산로는 서울대, 시흥동, 관악역, 안양유원지 등을 기점으로 하는 코스가 있으며 삼막사, 남근석, 상불암, 망월암을 잇는 한적한 길도 있다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 관악구, 금천구, 경기도 안양시", + "MNTN_NM" : "삼성산" }, - "longitude" : 129.1083333, - "latitude" : 37.2233333 + "longitude" : 126.9391667, + "latitude" : 37.436111099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "육화산은 북으로 청도군 매전면과 밀양군 산내면 경계 지점이 있다. 육화산은 큰 산, 작은 산, 청계수, 폭포, 적석, 흑석의 6가지를 갖추어 있는 산이라 붙여진 이름이다. 산행은 상동역 앞 슈퍼마켓에서 동곡행 버스를 타고 지전리 중남 초등학교에 내려 내동교를 지나 안내동 마을가지 30여 분 걸어야 한다.마을 입구 고목을 지나 다리를 건너 바로 왼쪽 계곡 따라 포장길을 오르는 길이 있는데 육화에서 구만 종주 코스로 많이 이용되고 있다. 육화산 정상은 한쪽 방향으로 시야가 확 트여 있어 전망만큼은 뛰어나다. 구만산과 그 뒤편으로 이어지는 억산이 파노라마처럼 보인다. 정상 주위에 진달래 터널과 진달래 군락지가 있어 봄이면 장관을 이룬다.", - "MNTN_HG_VL" : "675", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 매전면 장연리", - "MNTN_NM" : "육화산" + "DETAIL_INFO_DTCONT" : "덕우산은 강릉시 왕산면 고단리와 정선군 임계면 송계리의 경계를 이루는 산으로 해발 1007 m 이며 이산은 백두대간이 첩첩이 병풍처럼 두러쳐진 한가운데에 위치하여 정상에서 바라보면 먼저 고루포기산, 서득봉, 화란봉, 대화실산, 두리봉, 석병산, 자병산, 상월산, 등이 시계 방향으로 돌며 보이고 서쪽으로는 노추산과 사달산이 보이는 전망좋은 산이다. 덕우산에는 피나무골 샘터가 있는데 이산에서 발원한 물은 송게촌과 어울여 남한강의 원류가 된다. 강릉시에서 오를 수 있는 등산로은 고단 1리 고단초교 뒷등으로 통현사를 거쳐 오르는 코스와 남한강 발원지 피나무골 샘터 표지석에서 고냉지 채소밭을 거쳐 오르는 코스와 배모탱이 안고단 마을에서 둥우리재를 거쳐 오르는 코스로 3개 등산로가 있다. 백두대간이 첩첩이 병풍처럼 둘러쳐진 다운데에 위치하여 동서를 길게 드러누운것이 마치 소가 한가롭게 여물을 되새김질 하는 와우형의 산이다.", + "MNTN_HG_VL" : "1007", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선군 임계면", + "MNTN_NM" : "덕우산" }, - "longitude" : 128.85859429999999, - "latitude" : 35.613249099999997 + "longitude" : 128.83387450000001, + "latitude" : 37.512631599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "윤산 정상에 서면 부산이 온통 산의 물결을 이룬다는 사실을 확인하게 된다. 회동수원지를 감싸고 있는 정면 한가운데 아홉산과 그 우측으로 개좌산 운봉산이, 아홉산 왼쪽 뒤 암봉이 달음산, 그 왼쪽으로 뾰족봉인 천마산 치마산(함박산) 곰내재, 그 뒤로 시명산이 확인된다.부산 금정구 부곡동 서동 금사동에 걸쳐있는 나즈막한 봉우리인 윤산(輪山·318m)에 오르면 광안대교가 보이는 광안리 해안가를 제외한 전 지역이 산의 물결을 이룬다. 크게 보면 부산도 일종의 대형 분지(盆地)라는 사실을 실감한다.조선시대 지리서인 '동국여지승람'과 1740년판 '동래부지'에는 윤산을 '동래부의 북쪽 8리에 있으며, 동래부의 진산(鎭山)'이라 적고 있다. 알다시피 진산은 도읍이나 성지의 뒤쪽에 있는 큰 산을 말하는데 결국 윤산이 동래의 뒤쪽 큰 산이니 진산이 되는 셈이다.이제 궁금증은 왜 윤산으로 명명됐느냐 하는 것. 답은 간단하다. 동래쪽에서 보면 산 모양이 수레바퀴처럼 둥글게 보여 바퀴 윤(輪)자를 차용했다. 주민들로부터 '대머리산' '둥글산'으로 불린 것도 이같은 이유에서다.그렇다면 윤산이 왜 구월산으로 불렸을까. 뚜렷한 답은 없지만 바퀴에서 연상되는 '구불다'에서 '구블다' '구을다'로 변해오다 결국 구월산으로 와전되지 않았을까 하는 것이 일반적인 추측이다.이 때문에 지역 주민들이 원래 산 이름을 되찾아야 한다고 민원을 제기했고, 이에 시는 타당성이 있다는 판단하에 국토지리정보원에 산 이름 변경을 요청했다. 결국 국토지리정보원은 지명위원회의 심의를 거쳐 윤산으로 산 이름을 복원키로 결정했다고 지난 2002년 7월 시에 알려와 시는 이때부터 공식적으로 윤산으로 부르고 있다.", - "MNTN_HG_VL" : "317", - "MNTN_LOCPLC_REGION_NM" : "부산광역시", - "MNTN_NM" : "윤산" + "DETAIL_INFO_DTCONT" : "백운산은 가지산(실혜산)의 앞가슴에 해당되는 산으로 산 전채가 한 조각의 흰구름처럼 보이는 화강암으로 이루어져 있어 얻어진 이름이다. 주위의 큰 산에 가려져 이름이 나지 못했으나 정상 부근에는 온통 기암괴석으로 이루어져 경관이 빼어나며, 등산로는 아주 호젓하다. 바위봉으로 우뚝 솟은 정상을 보면 마치 중국에 있는 황산을 보는 듯한 느낌이 든다. 더구나 봄에 이곳을 다녀가면 진달래와 철쭉이 만발하여 더욱 운치를 느낄 수 있다 하여 백운산은 봄산이라는 말도 있다.산의 동편 하단부에 유명한 시례 호박소 가 있고, 동편 산허리에 구룡폭포가 있으며 서편에는 우리 나라 굴지의 산내 중석광이 있다. 남쪽 건폭은 일년 내내 산악인들의 암벽등반 훈련장이 되고 있다.", + "MNTN_HG_VL" : "885", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양", + "MNTN_NM" : "백운산" }, - "longitude" : 129.10360969999999, - "latitude" : 35.233632 + "longitude" : 128.98400000000001, + "latitude" : 35.594999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주금산에서 남쪽으로 뻗어온 산줄기가 서리산, 축령산을 지나 북한강으로 빠지기 직전에 만들어 놓은 것이 바로 은두봉이다. 은두봉은 북쪽에 위치한 축령산(897m)에 딸린 한봉우리만 사람들에게 인식되어 왔다. 그러다 이 봉우리 서북쪽에 있는 운두목현의 이름을 따서 은두봉이라 불려졌다. 따라서 은두봉은 하나의 독립된 산이 아니라 축령산에 딸린 한 봉우리로 보는 것이 더 타당하다. 그런 의미로 보면 은두봉의 서북쪽 1.5km거리에 있는 오독산(621m)도 축령산에 속한 봉우리라 할 수 있다.예전 마석에서 청평으로 넘나들던 은두목현을 거쳐 동남쪽 능선길을 따라가다 보면 정상에 이르게 된다. 정상에서는 청평댐과 북한강이 한눈에 들어오며 강을 따라 이어지는 연봉의 모습도 눈을 떼지 못하게 한다. 교통이 편한데다 산세가 제법이어서 많은 산악인들의 각광을 받고 있다.", - "MNTN_HG_VL" : "678", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", - "MNTN_NM" : "은두봉" + "DETAIL_INFO_DTCONT" : "봉황새가 높이 나는 형상이라 하여 아기산 또는 봉황산이라고도 하는데, 조선조 이조참판 류복기 선생은 이 산과 연관해 호를 기봉이라 했으며 후손들은 이곳을 당산으로 모시고 정월 보름날 아기당에서 고사를 올린다.아기산은 한발이 심할 때 이곳에서 기우제를 올리면 영험이 많아 반드시 비를 내렸다고 전하는 임동면의 진산이다.아기산의 북쪽 자락에는 신라시대의 고찰인 봉황사가 있고 전주 류씨의 집성촌인 무실마을이 있다.산 정상에서 바라보면 웅장한 임동교, 수곡교와 중평단지가 한폭의 병풍 같으며, 임하호의 맑은 물이 한눈에 보인다. 또 정상에서 서쪽으로는 안동 최고봉인 학가산과 안동시가지인 용상이 보이고 동쪽으로는 일월산이, 북쪽으로는 와룡산이 시야에 들어온다. 아기산 남쪽에는 지례예술촌이 있다. 1993년 12월 임하댐이 완공되면서 섬 아닌 섬이 되어 드넓은 임하호에 두둥실 떠다니는 형국이 되었다.", + "MNTN_HG_VL" : "589", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 임동면", + "MNTN_NM" : "아기산" }, - "longitude" : 127.39388889999999, - "latitude" : 37.744444399999999 + "longitude" : 128.93333329999999, + "latitude" : 36.533333300000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "은석산은 천안시 북면과 병천면에 경계해 있는 높이 455미터 산이다. 산 남쪽엔 신라 문무왕 때 원효대사가 세웠다는 은석사가 있어 예로부터 시인묵객들이 많이 찾았다 한다. 또 사찰 입구엔 백여명이 앉아 쉴 수 있는 반석이 있다.남동쪽 계곡에는 도동서원이 있었던 서원마을이 자리하고 있다. 마을 이름이 ‘서원’인 것은 그 마을에 서원으로는 유일하게 도동서원이 자리하면서 마을 이름까지 서원으로 붙였다고 한다. 이 서원에선 김일손과 목천현 출신 유학자 황종배가 배출되었다고 한다.은석사를 지나면 어사로 유명한 영성군(靈城君) 박문수(1691~1756)의 묘가 있다. 암행어사 박문수는 1727년 정미환국으로 소론이 득세하자 사서에 등용되어 영남 암행어사로 나가 부정관리들을 적발했다. 이듬해 이인좌의 난 때는 종사관으로 출전, 전공을 세워 경상도 관찰사에 발탁되고, 분무공신 2등에 책록되어 영성군에 봉해졌다. 군정과 세정에 밝았으며, 암행어사 때의 많은 일화가 전해지고있다.또 은석산은 불개미로 유명한데 송충이의 천적으로 숲을 보호하는 역할을 한다. 은석산 남쪽에는 병천암이라는 커다란 바위가 있는데 천안시알파인클럽에서 이 바위에 등반길을 개척했다. 코스는 좌벽, 우벽, 중앙벽 등 3면으로 나뉘며 난이도는 5.8급에서 5.12급까지 다양하게 있다.", - "MNTN_HG_VL" : "455", - "MNTN_LOCPLC_REGION_NM" : "충남 천안시 북면ㆍ병천면", - "MNTN_NM" : "은석산" + "DETAIL_INFO_DTCONT" : "충북 제천시 백운면 화당리와 덕동리를 경계로 우뚝 솟아있는 삼봉산은 치악산 남대봉에서 서남쪽으로 갈라져 나온 백운산(1,078m)의 기세를 이어받은 산이다. 원주-봉양-박달재-산척-목계-귀래를 경유하여 백운산-구학산-주론산-시랑산-천등산-오청산-옥녀봉-십자봉 능선이 어깨를 맞대고 산 주변을 감싸고 있어 마치 그 가운데 푹 파묻혀 있는 듯한 느낌이 든다. 이렇듯 주변 산세에 둘러싸여 있는 까닭에 광복 전까지만 해도 호랑이가 종종 출몰했다고 전해진다. 실제로 호환을 당한 사람들의 시신을 돌무덤으로 쌓아놓은 호식장의 흔적이 남아있고, 대호지매점에서 1.5km 떨어진 지점에서는 호식총도 볼 수 있다. 원시림에 들어온 듯이 태고의 신비와 자연미가 살아있는 삼봉산은 그러나, 6.25의 아픔을 간직하고 있는 산이기도 하다. 산이 깊어 빨치산과 공비들이 숨어들자 삼봉산 아래에 비행장을 건설하려 공비를 토벌하려 했다는 이야기도 전해져 내려온다.정상에는 삼각점과 바위가 몇 개 있고, 시야를 막는 큰 나무가 없어 전망이 좋다.", + "MNTN_HG_VL" : "910", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 백운면", + "MNTN_NM" : "삼봉산" }, - "longitude" : 127.28273969999999, - "latitude" : 36.781580200000001 + "longitude" : 127.96055560000001, + "latitude" : 37.190277799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "180", - "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 구좌읍", - "MNTN_NM" : "은월봉" + "DETAIL_INFO_DTCONT" : "구룡산(九龍山) 정상은 해발307.7m의 서울특별시 서초구 염곡동, 내곡동, 양재동과 강남구 개포동 일대에 위치한 산이다. 구룡산은 열 마리의 용이 승천하는 것을 인근을 지나가던 임신한 여성이 보고 크게 놀라 소리를 질러 용 한마리가 떨어져 죽고, 아홉 마리만 하늘로 승천하였다고 한다. 아홉 마리의 용이 승천하면서 남긴 흔적이 구룡산이라 불리게 되었으며, 하늘에 승천하지 못하고 죽은 용이 있던 자리가 물이 되어 양재천(良才川)이 되었다는 전설이 있다. 실제로 산을 자세히 보면 9개의 계곡으로 이루어져 있다.정상보다 낮은 이 산의 주봉(主峰)은 국수봉(國守峰)이라고 하는데, 조선시대 전부터 정상에 봉수대(烽燧臺)가 있어 국가를 지킨다고 해서 붙여진 것으로 이 곳에는 바위굴 국수방(國守房)이 있어 봉수군(烽燧軍)이 기거했다고 한다. 『여지도서』 광주목에\"관아의 남쪽 30리에 있다. 봉수대가 설치되어 있다\"고 기록되어 있다.내곡동에 있는 헌인릉과 함께 구룡산 기슭에 세종대왕이 묻힌 영릉(英陵)이 있었으나, 1469년(예종 1년)에 여주로 천장(遷葬)하였다. 초장지(初葬地)였던 구룡산 내곡동에 국가정보원이 들어서 있다.구룡산 제2봉인 국수봉전망대는 서울 강남.강북과 경기도 한강하류와 상류지역까지를 관망할 수 있는 최적지로 주.야경 조망명소이다.약 300m의 산으로 산높이나 길이 험하지 않아 가족과의 산행코드로는 제격이며, 접근성도 용이하여 부담없이 즐길 수 있다.구룡산에는 능인선원과 자룡사가 있다. 2015년 9월 13일 능인선원에 세계 최대 약사여래좌불을 점안하여 이름을\"서울약사대불\"이라 하였다.이 산에는 자작나무과인 수피가 얇은 종잇장처럼 벗겨지는 물박달나무 군락지가 산재해 있으며, 그 외에 신갈나무, 리기다소나무, 아까시나무 등이 있다. 관악산, 청계산, 우면산 등과 산자락이 이어진다.", + "MNTN_HG_VL" : "308", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 염곡동ㆍ내곡동, 강남구 개포동", + "MNTN_NM" : "구룡산" }, - "longitude" : 126.8561412, - "latitude" : 33.469772399999997 + "longitude" : 127.0572222, + "latitude" : 37.469166700000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "응복산은 설악산과 오대산을 잇는 백두대간의 중간에 서있는 산으로 오대산으로 들어가는 들머리에 해당하기도 한다. 실제로 응복산에서 오대산 두로봉까지는 10km도 안 떨어져 있어 응복산∼두로봉이나 응복산∼약수산∼구룡령을 잇는 구간을 장기산행 할 수도 있다. 원당초교명개리 계곡은 명개분교에서 북대사 길로 접어들면 얼마간 걷다보면 약수골과 바랑골이 만나는 곳에 닿는데 이곳까지는 임도가 나있다.진달래군락지를 지나 오르게 되는 정상은 주목 한 그루가 자리를 지키고 있는데 시야가 탁 트여있다. 주변에 708년(신라 성덕왕 7)에 원효대사가 창건한 수타사(水墮寺)와 철분을 비롯한 유리탄산·불소·칼슘 등이 들어 있어 만성위장병과 고혈압·빈혈·당뇨 등에 효과가 있다는 삼봉약수터가 있다. 울창한 수림과 맑은 물이 흐르는 계곡을 안고 있는 응복산에는 희귀 동식물과 어류들이 많이 서식하고 있어 훼손 안된 자연의 모습이 어떠한지를 잘 말해주고 있다.산행이 시작되는 서울에서 청도까지는 약5시간이 소요되는 등 교통이 불편하므로 미리 청도에 가서 민박을 알아두거나 통바람계곡에서 야영을 해야 하는 불편을 감수해야 한다. 또한 계곡이 넓어 장마철에는 계곡물이 불어나기 쉬우므로 이 기간에는 산행을 피하는 것이 좋다.", - "MNTN_HG_VL" : "1156", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", - "MNTN_NM" : "응복산" + "DETAIL_INFO_DTCONT" : "충청남도 예산군 덕산면에 위치한 옥양봉은 석문봉에서 약2km떨어진 곳에 있는 해발 621m의 봉우리로, 석문봉과 산행시점이 같기 때문에 옥양봉과 석문봉을 연결하여 산행하기가 쉽다. 석문봉이나 옥양봉 모두 암봉으로 이루어져 있으나, 분명히 다른 느낌을 주는데 , 석문봉의 경우는 오르고 내리는 등산로가 계곡코스이며, 옥양봉의 경우는 모두 능선으로 되어있기 때문에 분명한 차이를 느낄 수 있다.석문봉은 정상부만 암릉을 느낄 수 있지만, 옥양봉의 경우는 바위 전망대가 곳곳에 있고 석문봉에 비해 훨씬 아기자기하다. 하지만 계곡 코스가 없기 때문에 물이 없다는 점이 단점이다. 올라갈 때는 관음전코스로 올라가는 것이 산행의 재미를 높일 수 있다. 관음전으로 올라서는 길은 가을 냄새가 물씬 풍기는 숲속길로 되어있어 산책로 같은 느낌이 든다. 관음전 아래 삼거리부터는 능선이 시작되는데 많은 구간에 로프가 설치되어있고 바위 전망대가 몇 군데 있다. 이중에서도 옥양봉 정상부에 있는 암봉위에 올라서서 내려다보는 경치가 제일이다. 상가리가 내려다보이고 주변 경치가 한눈에 들어온다.", + "MNTN_HG_VL" : "621", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 덕산면, 서산시 해미면", + "MNTN_NM" : "옥양봉" }, - "longitude" : 128.56705579999999, - "latitude" : 37.875693300000002 + "longitude" : 126.61058370000001, + "latitude" : 36.731824500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "응봉산은 강원도 삼척군과 경북 울진군의 경계를 이루며 산 주변에 전인미답의 여러 계곡들을 끼고 계곡탐험코스로 적합한 산이다. 응봉산을 중심으로 북쪽의 기곡천과 재랑박골, 서쪽의 용소골, 문지골, 갱이골, 보리골 등이 있으며 남쪽 울진군내에 대광천과 동해안쪽 폭포골, 성우골등이 즐비하게 들어서 있다. 호산에서 버스종점을 지나 1km쯤 들어서면 폐광터가 나오는데 여기서 조금 더 올라가면 연이어진 2개의 폭포가 힘차게 흐른다. 조금 더 올라가면 오른쪽 깊은 계곡 아래로 헤아릴 수 없는 폭포지대를 만날 수 있다. 금강산의 축소판을 연상케 하는 이곳은 3단까지는 시야에 들어오나 그 아래로는 워낙 협곡이어서 몇단까지 폭포가 꺽어져 내리는지 셀 수 없을 정도다. 용소골을 탐험할 경우에는 암벽등반 경험자가 동행해야 하며 20m자일 두동쯤은 있어야 위험지대를 통과할 수 있다.", - "MNTN_HG_VL" : "1000", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면ㆍ원덕읍, 경상북도 울진군 북면", - "MNTN_NM" : "응봉산" + "DETAIL_INFO_DTCONT" : "강화군 내가면 고천리에 위치한 해발 466m의 혈구산은 강화도의 중심에 위치한 산이다. 고려산과 고비고개를 사이에 두고 남북으로 이어져있으나 혈구산이 더 높고 산세도 부드러운 고려산에 비해 뾰족하면서 굴곡이 있어 힘이 넘친다. 고비고개에서 정상에 이르는 능선길은 4개의 봉우리로 이루어져있으며 첫 번째 봉우리를 지나면서 방향이 우측으로 심하게 휘면서 2봉을 만나고 남쪽으로 진행하다 3봉이 된 후 다시 왼쪽으로 휘어지며 4봉인 혈구산 정상부를 만들어 낸다.각 봉우리 오름길은 매우 가파라서 숨이 가쁘지만 봉우리에 올라서면 시원한 조망을 제공해주며 다음 봉우리 사이 안부까지 내리막길이 있어 강약이 조화를 이루는 코스라 할 수 있다. 그러면서도 쉬는 시간을 포함해 2시간밖에 걸리지 않는 짧은 거리여서 가족산행지로도 적격이다. 정상부에 올라서면 사방으로 전망이 트이며 강화도의 전모가 드러난다.", + "MNTN_HG_VL" : "466", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 내가면 고천리", + "MNTN_NM" : "혈구산" }, - "longitude" : 129.2299332, - "latitude" : 37.076997599999999 + "longitude" : 126.4405556, + "latitude" : 37.720277799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", - "MNTN_HG_VL" : "1268", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", - "MNTN_NM" : "응봉산" + "DETAIL_INFO_DTCONT" : "비봉산(飛鳳山)은 낙동 중의 낙동, 중동면 오상리의 강변에 지각변동으로 솟구쳐 생긴 산이다. 봉황이 하늘을 나는 형국이라서 이런 이름이 붙어졌겠는데, 실제 보아도 그런 것이 좌우로 펴진 능선이 비행기의 날개처럼 앞면은 두껍고 뒤쪽은 얇아지면서 깃털처럼 갈라져 영락없이 새가 날개를 펼친 모양이다. 그 가운데 정상이 머리처럼 우뚝해 강 건너편의 옥주봉을 바라보고 있다.주변이는 봉황과 관련된 지명인 죽암(竹岩). 오상리의 오동(梧桐) 마을 등이 있다.산세가 부드럽고 등산로에 소나무가 우거져 산보하는 기분으로 가족산행하기 좋은 곳이다. 솔잎을 밟고 솔향기에 취하여 강바람에 옷자락 나부끼며 음풍농월하는 데도 더할 나위 없이 좋다.정상에서 보는 낙동강은 한 폭의 그림같은 멋진 풍광을 자아낸다. 한마디로 무아지경이다. 시원스럽게 불어오는 강바람도 운치를 더해준다. 저멀리 상주의 삼악인 노악.갑장.천봉산과 속리산.청계산.작약산 등이 아련히 보이고 국민관광지인 경천대가 바로 눈앞에 다가선다. 정상 밑에는 숙종 원년(1672년)에 창건한 청용사가 자리를 잡고 있다. 사찰규모는 크지 않으나 낙동강과 어우러져 아름다움을 간직하고 종소리 은은하여 좋다.", + "MNTN_HG_VL" : "230", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 중동면 오상리", + "MNTN_NM" : "비봉산" }, - "longitude" : 129.13138889999999, - "latitude" : 37.224722200000002 + "longitude" : 128.26611109999999, + "latitude" : 36.436388899999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", - "MNTN_HG_VL" : "1268", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", - "MNTN_NM" : "응봉산" + "DETAIL_INFO_DTCONT" : "지리산자락을 따라 북서쪽 능선 끝자락에 솟아 있는 바래봉은 매년 5월이면 철쭉제가 열리는 '천상화원'으로, 온 산이 연분홍빛 철쭉꽃으로 물들인다. 바래봉 철쭉은 다른 어느 산의 철쭉꽃보다 화려한 편이다. 그 이유는 바래봉 철쭉은 주능선에는 나무가 거의 없는 푸른 초원이 펼쳐진 능선 한가운데 피어나기 때문이다. 푸른 초원 위에 연분홍빛 철쭉이 더욱 화사하게 돋보이는 것이 바래봉 철쭉의 매력이다.바래봉이란 이름은 스님들의 밥그릇인 바리때를 엎어놓은 것 같다 하여 붙여졌다 한다. 이름의 유래와 같이 바래봉 주능선은 둥그스름하고 부드러운 능선을 펼치고 있어 산행은 마치 공원을 산책하는 듯 편안하다. 그러나 산위에 있는 이 천상의 화원을 즐기기 위해서는 산을 오르는 힘겨움을 감수해야만 한다. 세상의 모든 일에는 그 대가가 따르는 것처럼 바래봉의 철쭉도 그런 수고를 감수한 이후에야 맛볼 수 있다.이렇게 바래봉은 한라산,소백산 등과 더불어 대규모 철쭉군락지로 유명한 산일 뿐만 아니라, 운성(운봉) 10경의 하나로 바래봉 달빛 아래 몰려오는 독경시에 흔드는 작은 종소리 발악월경이 포함되어 있다.", + "MNTN_HG_VL" : "1165", + "MNTN_LOCPLC_REGION_NM" : "전라북도 남원시 운봉읍, 산내면", + "MNTN_NM" : "바래봉" }, - "longitude" : 129.13138889999999, - "latitude" : 37.224722200000002 + "longitude" : 127.56, + "latitude" : 35.430000000000007 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.우리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", - "MNTN_HG_VL" : "1268", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍, 노곡면", - "MNTN_NM" : "응봉산" + "DETAIL_INFO_DTCONT" : "남한의 산 중 최대면적을 가지고 있는 지리산의 산세는 세인을 압도하고도 남는다. 반야봉은 지리산 제2봉으로 산세가 웅장하고 계곡이 깊으며 수목이 울창하여 고산식물과 기암절벽이 장관을 이룬다. 이에 해마다 많은 산행인이 찾고 있다. 지리산의 모든 능선을 한눈에 볼 수 있는 지리산의 중심부로, 해질무렵 운무에 둘러쌓인 반야봉의 붉은 빛 낙조는 장엄하기 그지없어 산행인의 넋을 빼놓을 정도다. 특히 여름날 작열하던 태양이 지루한 하루를 보내고 저편 너머로 숨어들 무렵이면 반야의 하늘은 온통 진홍빛으로 물들어 보는 이들을 감동케 한다.지리산이 그토록 아름다울 수가 있는지를 끝없이 되뇌여도 반야봉의 낙조는 모자람이 없다. 화려한 불꽃잔치와 더불어 반야봉은 운해와 함께 우리에게 인식된다. 늘 발아래 운해를 거느리고 우뚝 솟아 있는 반야봉의 장관은 비경 그것이다.태산준령들 사이사이에 걸려 있는 지리산의 운해는 아마도 주봉인 천왕봉과 반야봉에 얽힌 마고할미와 반야의 애틋한 마음을 그대로 전해주려는 듯 심오함을 갖고 있다.반야봉 정상에서 동쪽으로 조금 내려가면 절벽 아래에 묘향대가 있는데 이곳은 옛부터 불도들이 수도하는 유서깊은 선암으로 유명하다.", + "MNTN_HG_VL" : "1732", + "MNTN_LOCPLC_REGION_NM" : "전라남도 구례군, 전라북도 남원시, 경상남도 하동군", + "MNTN_NM" : "반야봉" }, - "longitude" : 129.13138889999999, - "latitude" : 37.224722200000002 + "longitude" : 127.58, + "latitude" : 35.270000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "

응봉산은 삼척시 도계읍 신리와 노곡면 상마읍리의 경계를 이룬다. 낙동정맥과 육백지맥의 사이 능선의 최고봉이다. 육백산은 조 600섬을 뿌릴 수 있을 정도로 넓은 고위평탄면이 생성되어 있다.

우 리나라에 응봉산이란 이름의 산은 무수히 많다. 강원도에 알려진 응봉산만 다섯 개에 이른다. 그중에서도 가장 유명한 산은 삼척과 울진 경계에 있는 999미터의 응봉산이다. 같은 삼척에 있으며 높이도 더 높지만 주목받지 못한 산이 1268미터의 응봉산이다. 응봉산은 999미터의 응봉산과 지척에 능선을 나란히 한 육백산에 가려 제 이름이 빛을 보지 못한 셈이다. 그러나 알려지지 않은 오지의 산답게 생태보존이 잘 되어 있어, 호젓한 자연 그대로의 원시미를 느낄 수 있다.", - "MNTN_HG_VL" : "1268", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍,노곡면", - "MNTN_NM" : "응봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "532", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 선산읍", + "MNTN_NM" : "비봉산" }, - "longitude" : 129.13138889999999, - "latitude" : 37.224722200000002 + "longitude" : 128.2994444, + "latitude" : 36.247222200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경남 거창 주변에는 험한 산들이 많이 포진해 있다. 그 중 의상봉은 암봉과 골짜기가 조화를 이루어 옛날부터 등산인들의 사랑을 받아 온 곳이다. 의상봉(이상봉 1046.2m)은 가야산 국립공원 남서단에 위치한 바위산이다. 가야산 국립공원은 의상봉 남쪽 고견사 일원과, 의상봉에서 남동쪽 비계산으로 이어지는 능선 일원도 공원지역에 포함시키려 하고 있으나, 거창군의 반대로 2001년 2월 현재 의상봉 동쪽 일원만 국립공원으로 지정해 놓고 있다.또한 억새밭이 유명한 마장재와 쌀굴,견암폭포를 볼 수 있는 곳으로 근래 개발된 가조온천으로 인해 온천산행을 겸할 수 있는 곳으로 각광을 받고 있다.", - "MNTN_HG_VL" : "1046", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "의상봉(이상봉)" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "289", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진", + "MNTN_NM" : "천태산" }, - "longitude" : 128.04416670000001, - "latitude" : 35.752222199999999 + "longitude" : 126.91666669999999, + "latitude" : 34.899999999999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "716", - "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", - "MNTN_NM" : "이방산" + "MNTN_HG_VL" : "636", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "초례봉" }, - "longitude" : 127.8411984, - "latitude" : 35.304295199999999 + "longitude" : 128.75, + "latitude" : 35.899999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "534", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시", - "MNTN_NM" : "인내산" + "DETAIL_INFO_DTCONT" : "병무산(兵無山 920m)은 지난봄 찾았던 발교산(髮校山 998m)과 맥락을 같이 하는 산이다.즉 차령산맥중의 지맥에 속하는 산으로서 망고개를 경계로하여 발교산과 어깨를 나란히 하면서 남쪽으로 우뚝 솟아있는 것이다. 강원도 소재의 오지의 산답게 등산코스를 개발한지 얼마되지 않아 등산객들의 왕래가 적은 이 산은 한적한 산행지로 적합하다. 이름난 산속에서 볼 수 있는 고찰도, 잘 다듬어진 등산로도 찾아보기 힘들지만 수풀과 바위 사이를 헤짚고 가는 산행의 묘미가 일품이다.", + "MNTN_HG_VL" : "920", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면, 청일면", + "MNTN_NM" : "병무산" }, - "longitude" : 129.1022293, - "latitude" : 35.921467 + "longitude" : 128.0997222, + "latitude" : 37.641111100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 충주시에 위치해 있는 인등산은 천등산, 지등산과 함께 삼등산으로 불리기도 한다. 땅 위에 사람이 있고 사람 위에 하늘이 있듯이 천등산, 인등산, 지등산이 북에서 남으로 나란히 위치하고 있다. 그래서 차례로 천(天)ㆍ지(地)ㆍ인(人)의 3재(三才)를 이루는 특이한 이름을 갖고 있다.7부 능선까지 임도가 나 있으며, 정상에 오르면 남쪽으로 지등산과 월악산이 충주호와 함께 보이고 북쪽으로는 천등산과 그 산자락에 있는 서대마을터가 보인다. 충북선 동량역에서 산행을 시작하여 삼탄역에서 산행을 끝내는 철도 산행지로 유명하다.인등산 자락에 위치한 소모천마을에는 돌무더기 가운데 사람 키만한 높이로 장승처럼 세워진 조똘바위가 자리잡고 있는데, 전설에 의하면 옛날 소모천마을의 남자들이 변고로 죽어가자 노승이 이곳의 산세가 요녀의 허리모양을 하고 있으니 요녀 형국의 요부에 혈을 찔러서 음기를 눌러야 한다 하여 큰 돌을 운반해 혈을 누른 곳이 바로 조똘바위라고 한다.정상에서는 남서쪽으로 남한강을, 북동쪽으는 충주호의 지류인 주포천을 끼고 있어 산수가 수려한 편이다.", - "MNTN_HG_VL" : "666", - "MNTN_LOCPLC_REGION_NM" : "충북 충주시 동량면ㆍ산척면", - "MNTN_NM" : "인등산" + "DETAIL_INFO_DTCONT" : "영광의 진산이라 내세울 수 있는 불갑산은 노령산맥의 정간에서 서남쪽으로 서해를 향해 힘차게 휘어 달리다가 우뚝 솟은 서지맥의 막내봉이다. 해발 516미터이며, 영광읍에서 약 10킬로미터 지점에 있다. 멀리서 보이는 산형은 마치 노서하전(老鼠下田)이라 하여 늙은 쥐가 밭을 향해 내려 오는 형세와도 같다고 한다.들길을 따라 참나무류와 싸리나무 등의 잡목 사이를 헤쳐 산 안으로 들어가다 보면 동백나무가 그 자태와 함께 빼곡하게 골짜기를 메우니 이곳이 바로 유명한 ‘불갑산 동백골’이다.정상 주변은 거대한 암봉으로 조망이 압권이며, 동쪽은 10여 미터의 깎아지른 절벽지대라 주의해야 한다.", + "MNTN_HG_VL" : "518", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 불갑면ㆍ함평군 해보면", + "MNTN_NM" : "불갑산" }, - "longitude" : 128.0067454, - "latitude" : 37.057504399999999 + "longitude" : 126.5650998, + "latitude" : 35.190731300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "나라 안팎으로 이름난 산, 북한산이 남쪽으로 보현봉을 솟구치고 다시 북악에서 한 줄기는 동쪽 낙산으로 또 한 줄기는 서쪽으로 뻗어 인왕산을 빚어 놓았다. 풍수상으로 보면 조산인 북한산에서 주산인 북악산에 연결되고 낙산이 좌청룡이면 인왕산은 우백호가 된다.인왕산은 서울 어느 방향에서 오르든지 한 시간이면 오를 수 있고 오르면 조망이 뛰어나다.서울의 중심에 솟아있으며 높지는 않지만 산세는 웅장하다. 특히 동쪽 기슭이 아늑하고 풍치가 빼어나 장안 제일의 명승지라 할 수 있다. 북쪽 자락에 있는 부암동은 무계동이라 불리던 곳으로 중국의 무릉도원에 버금갈 정도의 아름다운 경치를 자랑하던 곳이다.인왕산이란 명칭은 산자락에 인왕사라는 절이 있어 붙여진 이름이다. 조선 중종 때는 필운산이라 불리기도 해, 지금도 사직공원 근처엔 동네 이름으로 남아있다.인왕산하면 떠오르는 이야기가 몇 가지 있다. 그중 첫 번째가 호랑이다. 조선시대 인왕산은 호랑이의 출몰로 호환이 끊이지 않았다. 민가는 물론이요 경복궁이나 창덕궁에까지 들어와 소란을 피웠다. 피해가 커지자 조정에서 군대를 동원해 호랑이를 잡을 정도였다. 불과 100년 전인 1901년에도 경복궁에 호랑이가 출몰한 기록이 있다.수려한 경치 덕분에 인왕산을 배경으로 한 산수화가 많다. 겸재 정선의 ‘인왕제색도’가 널리 알려져있다. 국보 216호인 이 작품은 비온 뒤 안개가 피어오르는 인왕산의 모습을 잘 표현한 걸작이다.또 한 가지 인왕산에 대한 일화는 무장공비사건이다. 1968년 북한의 김신조 일당이 청와대를 습격하기 위해 인왕산 옆 산길로 질러왔다. 그 사건 뒤로 인왕산은 일반인 출입이 통제되었다가 1993년 2월 24일부터 오를 수 있게 됐다.", - "MNTN_HG_VL" : "340", - "MNTN_LOCPLC_REGION_NM" : "서울시 종로구, 서대문구", - "MNTN_NM" : "인왕산" + "DETAIL_INFO_DTCONT" : "금산읍 시내에서 남서쪽을 가로 막고 솟아 있다. 서대산, 계룡산에 이어 충청남도에서 세번째로 높은 산으로 주능선에 기암괴봉이 많고 숲이 무성하다.산자락에는 고찰 영천암과 영천약수·보석사·선공암·원효암·봉화대·관음암·관음굴·원효폭포 등 명소가 많고, 보석사 입구에는 전나무 숲과 수령 약 1000년의 은행나무(천연기념물 365)가 있다. 남이면에는 인삼시장이 서고, 금성면에서는 임진왜란 당시 왜적과 싸우다 옥쇄한 7백인의 충혼이 깃들인\"\"칠백의총(사적 제105호)을 찾아 선열들의 깊은 뜻을 새겨볼 수 있어 가족동반 코스로도 적당하다.산행은 금산읍 계진리 마을회관 앞에서 시작한다.계곡길을 따라 선공암과 빈대바위 옆을 지나 능선길을 오르면 정상이 나온다.정상에서 동쪽을 내려다 보면 수십길 깎아지른 절벽이 아찔하다. 서북쪽으로는 대둔산이 하얀 구름띠를 허리에 감고 다가오고 서대산의 기암절벽도 위용을 자랑하며 자태를 뽐낸다. 남쪽으로는 운장산과 구봉산이 마치 형제인양 맞붙은 모습으로 시야에 들어온다.", + "MNTN_HG_VL" : "732", + "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 금산읍", + "MNTN_NM" : "진락산" }, - "longitude" : 126.95930420000001, - "latitude" : 37.584948900000001 + "longitude" : 127.45882520000001, + "latitude" : 36.077696000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "388", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군", - "MNTN_NM" : "일광산" + "DETAIL_INFO_DTCONT" : "대중가요 `울고 넘는 박달재'의 배경인 박달재로부터 6km 떨어진 곳에 위치한 천등산은 수도권과 가까운데다 교통편이 좋아 등산인 들의 발길이 끊이지 않은 산이다. 천등산의 남쪽으로 5km거리에 인등산이 있고, 다시 남쪽으로 지등산이 나란히 있어, 천지조화설을 담고 있는 「천부경」의 천지인을 뜻하는 것으로도 본다.지등산, 인등산, 천등산을 옛 사람들은 삼등산이라 불렀으며, 임진왜란 때는 정감록의 예언에 따라 많은 사람들이 이 산으로 피난을 했다고 한다. 천등산에는 조선조 세조 때 황규라는 지사가 명당을 찾아 전국을 돌아다니다가 이 곳 천등산에서 신선을 보고 명당을 찾아 산세도를 그렸다는 전설이 전해지고 있다. 산행들머리는 해발 453m인 다리재 고개마루턱으로 산행이 힘들지 않은 편이다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 산척면, 제천시 백운면", + "MNTN_NM" : "천등산" }, - "longitude" : 129.20754350000001, - "latitude" : 35.2667134 + "longitude" : 128.00324459999999, + "latitude" : 37.097721700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충청남도 예산에서 서해안으로 나가면 덕산온천과 수덕사를 감싸안고 큰산들이 무리를 이루고 있는 가야산의 장관을 만난다. 가야산은 예산군과 당진군 서산군등 3개군에 걸쳐 들판에 우뚝 솟아 산세가 당당하고 곳곳에 사찰이 자리하고 있어 은은한 풍경을 자아낸다.일락산은 가야봉(677.6m), 원효봉(677m), 석문봉(653m), 옥양봉(621.4m), 수정봉(453m), 상왕산(307.2m)등의 봉우리와 더불어 가야산에 오밀조밀하게 자리잡고 있으며, 가야산은 온통 산을 뒤덮은 철쭉과 진달래가 산행의 즐거움을 더해주고 깨끗한 계곡은 많은 산악인과 관광객의 발길이 끊이지 않는 곳이다.예로부터 많은 문화유적을 간직한 명산으로 상왕산 기슭에 백제의 미소로 불리는 서산마애산존불상을 비롯하여 보원사지, 백암사지, 명종대왕태실 등 유서깊은 문화유적과 개심사, 일락사, 문수사, 송덕암 등의 명사찰이 있으며, 21.06km2의 거대산 산지를 개발하여 산악축산의 요람으로 성장한 한우목장이 있다.", - "MNTN_HG_VL" : "521", - "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시", - "MNTN_NM" : "일락산" + "DETAIL_INFO_DTCONT" : "북배산은 고향집 바로 뒤에 솟아 있는 산처럼 향수를 자아내게 하는 산으로 크게 빼어나지도 웅장하지도 않지만 수수한 매무새의 시골 아낙 같은 자태를 하고 있다. 가덕산(858m)과 계관산(710m)으로 이어지는 능선에 위치하며 청정지역에 있는 산답게 깨끗하고 고즈넉한 산이다. 주능선은 산불을 대비해 폭 10미터 정도에 방화선이 형성되어 있으며, 이 방화산으로 능선 모두가 시원스레 조망되며 특히 눈 내린 후 가덕산에서 계관산까지 이어지는 경치는 이색적인 분위기를 느끼게 해준다.북배산은 수도권 등산인들에게 혼잡함을 피할 수 있는 당일치기 코스로 제격이다. 북배산 코스는 대개 목동2리 맴내~작은멱골을 경유하거나 또는 싸리재(마을)~싸리재고개를 경유해 정상을 다녀오는 것이다.정상에서 바라보는 조망은 막힘이 없다. 먼저 북서쪽으로는 북배산의 모산인 화악산이 하늘금을 이루고, 그 오른쪽으로는 북배산을 향해 세차게 흘러나오는 응봉, 촛대봉, 몽덕산, 가덕산 줄기가 연이어져 시야에 들어온다.동쪽으로는 병풍을 두른 듯한 대룡산 아래로 평화로운 춘천시내와 의암호가 펼쳐진다. 춘천남쪽으로 펼쳐지는 조망도 일품이다. 가장 멀리로 용문산이 하늘금을 이루고 그 아래 좌우로는 도명산, 대명스키장 슬로프, 장락산, 소리산 등이 넘실대는 파도처럼 광활하게 시야에 들어온다. 서쪽으로는 구나무산, 명지산, 월출산, 수덕산이 마주보이고, 구나무산 왼쪽 아래로 자리한 가평읍과 북한강이, 수덕산 아래로는 목동분지가 내려다보인다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 춘천시 서면", + "MNTN_NM" : "북배산" }, - "longitude" : 126.5948908, - "latitude" : 36.730963199999998 + "longitude" : 127.6136111, + "latitude" : 37.920000000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "664", - "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", - "MNTN_NM" : "일림산" + "DETAIL_INFO_DTCONT" : "한북정맥에 들머리가 되는 광덕산은 경기도에서는 가장 북쪽에 위치한 산이며, 강원도 화천군과 철원군의 경계를 이루고 있으며, 거의 정상 부위까지 군사 비상도로가 개설되어 있고 산자락 곳곳에 군사시설이 있어 지형적으로 군사 요충지임을 말해주는 산이다.가을이면 오색단풍의 물경이 겨울이면 설경이 아름다운 곳이다. 이 산은 교통편이 좋아 쉽게 찾을 수 있고, 또 주위에 백암산, 적근산, 복주산 등 여러 산과 백운계곡이 유원지화되어 있어 올때마다 새로움을 느낄 수 있다.", + "MNTN_HG_VL" : "699", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 이동면, 강원도 철원군 서면, 화천군 사내면", + "MNTN_NM" : "광덕산" }, - "longitude" : 127.0262077, - "latitude" : 34.679327499999999 + "longitude" : 127.4307982, + "latitude" : 38.115392399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "일림산은 전남 보성군 웅치면 용반리, 대산리, 회otilde;면 봉강리와 장흥군 안양면 학송리와 경계에 위치한 호남정맥 중 가장 남녘에서 기운차게 우뚝 솟아 백두 기운을 다시 북으로 돌리는 산이다.제암산이 산릉의ouml;쭉 화원을 대표한다면, 호남정맥 줄기로 한나절 거리인 보성 일림산과 장흥 삼비산의ouml;쭉밭은 2000년부터 개발된 100ha 이상 전국 최대의ouml;쭉군락지를 자랑하며, 제암산과 사자산으로 연결되는ouml;쭉군락지의 길이는 12.4㎞에 달하여 가히 세계적이라 추켜 세울만하다.일림산 정상에 서면 제암산(807m), 무등산(1,186.8m), 월출산(809m),otilde;관산(723m), 팔영산(609m) 등 전남의 명산들이 한눈에 들어온다.등산인들에게 인기 있는 코스는 주차장에서 완경사 계곡 길을 따라 호남정맥 골재에 올라선 다음 골치산~삼비산~일림산을 거쳐 능선을#376;고 용추폭으로 내려서는 코스(3시간30분)로, 삼비산~일림산 사이 안부에서 보성강 발원지로 빠지는 코스도 많이 따른다(2시간30분). 호남정맥 구간인 한치~아미봉(418m)~일림산~삼비산~골치~용추폭 코스는 4시간 정도 걸린다.", - "MNTN_HG_VL" : "664", - "MNTN_LOCPLC_REGION_NM" : "전남 보성군 웅치면ㆍ화천면", - "MNTN_NM" : "일림산" + "DETAIL_INFO_DTCONT" : "연엽산은 꼭대기에서부터 사방으로 능선이 길게 여러 갈래로 뻗어있는데, 산세도 그리 험하지 않고 찾는 이도 적어 원시림이 그대로 보존된 숲과 계곡이 비경을 이루고 있다. 계곡에는 울창한 숲 사이로 기암절벽이 이어지고 크고 작은 연못이 곳곳에 흩어져 있어 등산과 함께 계곡의 경치를 즐길 수 있는 산이다.강원대학교 연습림이기도 한 연엽산은 수백년 된 노송들이 빽빽하고 나무들이 우거져 있다. 정상은 무인대피소와 아름드리 잡목이 우거져 하늘만 보인며 능선에는 철쭉이 많다.※ 강원대학교 연습림지역으로 일반인의 출입을 통제하고 있으므로 입산이 절대로 안됩니다.", + "MNTN_HG_VL" : "775", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 동산면, 홍천시 북방면", + "MNTN_NM" : "연엽산" }, - "longitude" : 127.0262077, - "latitude" : 34.679327499999999 + "longitude" : 127.8230556, + "latitude" : 37.798055599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정상에 일자봉과 월자봉이 솟아 있어 동해에서 솟아 오르는 해와 달을 제일 먼저 볼 수 있다해서 일월산이라고 한다. 또한 산마루에 천지가 있어 그 모양이 해와 달과 같아서 일월산이라 하였다는 설도 있다. 높은 산이면서도 산형이 험하지 않고 순하여 순산이라는 애칭도 있다. 옛부터 각종 임산물이 많고 고산식물이 곳곳에 자라며, 약초도 많다.이 산은 태백산맥에 속하며, 이 산에서 낙동강의 상류 지류인 반변천(半邊川)이 발원한다. 남서사면에 천화사(天華寺)가 있으며 동쪽 사면에 용화사지(龍化寺址)가 있다.일월산의 꼭대기에는 일자봉과 월자봉이라 부르는 두 봉우리가 사이좋게 솟아 있으며 그 줄기가 뻗어 크고 작은 산맥이 주종을 이루었으니 동해가 눈 아래 보이는 일자봉에 올라 해가 솟아오르는 장관을 볼 수 있다.", - "MNTN_HG_VL" : "1218", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 일월면", - "MNTN_NM" : "일월산" + "DETAIL_INFO_DTCONT" : "삼암봉은 지도읍 읍내리에서 시작하여 광정리를 거쳐 감정리에 이르는 길이 10km가량으로 북서에서 동남방향으로 지도읍 중앙을 가로지르고 있다. 큰산, 깃대봉, 삼암봉으로 이어지는 3개의 봉우리가 있고주능선을 따라 등산로가 잘 정비되어있어 산행 중 섬 산행의 특성인 바다내음과 함께 다도해의 아름다운 풍광을 같이 즐길 수 있다. 옛날 삼암봉 봉우리에 작은 바위가 있는데 그바위에 조그만 웅덩이가 있었다. 일제강점기에 측량을 위해 그 웅덩이에 삼각점을 심어 현재는 웅덩이를 볼 수 없으나 옛날 삼암봉 정상부에 과일나무가 많아 삼암봉을 오르는 이들이 많았다고 한다 그러던 어느날 어떤 여인이 삼암봉에 올랐다가 웅덩이에 물을 마신후에 임신을 했고 출산을 했는데 뱃속에서 뱀들만 나왔다 하는 설화가전해진다.", + "MNTN_HG_VL" : "196", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군 지도읍", + "MNTN_NM" : "삼암봉" }, - "longitude" : 129.09831510000001, - "latitude" : 36.8016115 + "longitude" : 126.17944439999999, + "latitude" : 35.090555600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "일월산은 경상북도에서도 오지 중의 오지로 알려진 영양군과 봉화군 경계에 있다. 1200미터가 넘는 산이지만 능선은 유순하기 그지없다. 푸른 금강송이 있어 삼림욕장으로 그만이고 해마다 봄이면 산나물축제를 열만큼 온갖 자생식물이 넘쳐나는 곳이다. 여유가 있다면 일월산 최고봉인 일자봉에서 떠오르는 해를 감상하는 일출산행을 겸해도 좋다. 능선에는 식수가 없으므로 미리 준비해야 한다.천문사나 윗대티마을에서 올라 윗대티마을로 원점회귀를 해도 좋고 반대 찰당골로 종주산행을 해도 하루 산행으로 충분하다. 주차장을 기점으로 하는 원점회귀산행은 4시간 30분이면 된다.", - "MNTN_HG_VL" : "1219", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 일월면 용화리, 청기면 당리", - "MNTN_NM" : "일월산" + "DETAIL_INFO_DTCONT" : "상림2리 다리 앞에서 차도 따라 서쪽으로 나가다 계곡 갈림길과 만나면 오른쪽 계곡길로 들어 교회 앞을 지나 15분쯤 올라간 갈림길에서 왼쪽 계곡기로 급경사를 올라가게 된다. 차츰 왼쪽 지능선으로 붙어 올라가게 되고 능선 따라 노고봉에 이른다.왼쪽(남)능선길로 들어 잠시 내려갔다가 올라가면 정광산 정상이고 남릉 따라 3개의 봉우리를 넘어선 안부에서 왼쪽(동)계곡길로 들어선다. 계곡 아래 내려서면 시어골이고 차도 따라 상림2리 다리 앞이다.", + "MNTN_HG_VL" : "563", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 모현면", + "MNTN_NM" : "정광산" }, - "longitude" : 129.09831510000001, - "latitude" : 36.8016115 + "longitude" : 127.2812524, + "latitude" : 37.323208899999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "목포시 동쪽에 상동과 용해동에 걸쳐있는 해발 110m 산이다.산중턱에는 체육시설이 있으며 정상에서 바라보면 목포 구도심과 하당신도심 그리고남악신도심을 한눈에 볼 수 있다. 입암산 동남쪽 바닷가에 갓을 쓰고 있는 듯한 바위가 있어 이를 갓바위라 하는데갓바위가 있는 산이라 하여 갓바위산, 입암산이라 하였다 한다.목포팔경 중 입암반조(笠岩返照)라 하여 저녁노을에 물든 바닷가의 갓바위와바위절벽으로 된 입암산에 반사되는 저녁노을의 아름다움을 노래하고 있다.", - "MNTN_HG_VL" : "110", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포시 상동", - "MNTN_NM" : "입암산" + "DETAIL_INFO_DTCONT" : "산경표에서는 ‘크고 밝은 뫼’의 뜻으로 대박산(大朴山), 삼국유사에서는 묘범산(妙梵山)이라 불린 함백산(1572.9m)은 5대 적멸보궁인 정암사를 품고 있으며 지하에는 무진장의 석탄을 간직한 남한 제6위의 산이다. 함백산이 품고 있는 정암사는 1300여년 전 자장율사가 문수보살의 계시에 따라 갈반지(葛盤地)를 찾아 큰 구렁이를 찾은 후 그 자리에 적멸보궁과 수마노탑을 짓고 석가모니의 진신사리를 모셨다고 한다. 적멸보궁 옆 주목은 자장율사가 꽂아둔 지팡이가 살아난 것이라 해 ‘선장단’이라 부른다.함백산 정상 부근은 주목이 군락을 이루며, 두문동재에서 만항재까지의 고원 지역에는 참나물, 누리대, 취나물 등 산나물이 많다. 특히 겨울산행을 하다보면 주목과 고사목에 핀 눈꽃이나 상고대가 추위조차 잊게 해 줄 만큼 아름답다. 함백산의 대표 등산로 중 하나인 만항재는 해발 1330미터로 남한에서 가장 높은 도로며 두문동재는 1268미터로 만항재와 버금가는 높이다.", + "MNTN_HG_VL" : "1573", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 영월군 상동읍, 정선군 고한읍", + "MNTN_NM" : "함백산" }, - "longitude" : 126.4152778, - "latitude" : 34.796111099999997 + "longitude" : 128.9176271, + "latitude" : 37.1615368 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "157", - "MNTN_LOCPLC_REGION_NM" : "울산광역시 중구 다운동", - "MNTN_NM" : "입화산" + "DETAIL_INFO_DTCONT" : "무척산은 신어산, 불모산과 더불어 김해의 3대 명산으로 꼽힌다. 그다지 높지 않고 산줄기가 시원스럽지도 않지만 산천으로 둘러싸인 경치 좋은 뜻의 생림동천(生林洞天)이란 말을 만들어 낼 정도로 아름다운 산이다. 또한 기묘한 바위들이 자리 잡고 있어 그 멋스러움이 더욱 특출나 보인다. 특히 낙동강과 이어져 있어 굽이쳐 흐르는 낙동강의 조망이 탁월하며 산허리 부분에 괴상하게 생긴 암봉이 많아 경치가 수려하다.무척산은 산 이름도 다양하다. 무척산 외에도 무착산, 무쌍산, 식산으로도 불린다. 식산은 북풍을 막아주고 낙동강 물줄기를 끌어들여 들을 기름지게 해 김해 고을을 먹여 살리는 산이라 하여 부르는 이름이다. 또 산의 형세가 밥상을 받는 모양과 같다고 해 식산, 식산 대신 밥상이라고도 부른다.다양하게 불려지는 이름뿐만 아니라 무척산은 많은 설화를 간직하고 있는 산이다. 이 산의 정상 바로 밑에 천지못이 있는데, 이 연못은 김수로 왕릉의 물줄기를 잡기 위해 설치됐다는 전설을 갖고 있다. 또한 고찰 모은암은 김수로왕이 어머니의 은혜를 갚기 위해 지었다고 전해진다. 가락국의 불교를 중흥시키기 위해 창건되었다는 백운암도 유명하다.하늘벽, 가야벽, 탕건바위, 장군봉 등 개척된 암장이 여럿 있으며 부산, 경남 클라이머에게 인기가 높다.", + "MNTN_HG_VL" : "702", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시 생림면, 상동면", + "MNTN_NM" : "무척산" }, - "longitude" : 129.2814722, - "latitude" : 35.580594300000001 + "longitude" : 128.87060070000001, + "latitude" : 35.340642799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "자굴산은 얼핏 보기에는 단순한 봉우리같지만 들어서서 보면 제법 다양한 경관을 갖추고 있는 산이다. 합천이나 산청으로 이어지는 20번 국도가 이 산 밑을 지나기 때문에 이 지역 사람들에게는 매우 친숙한 곳이다.자굴산은 남명 조식선생의 싯귀에 `도굴산( 堀山)'이라 기록되어 있고 저굴산, 지굴산, 사굴산이라고 불리는 등 산 이름의 유래가 명확치 않다. 그러다가 일제말기에 지방 유지들로 구성된 등산 친목단체 `운악회'에서 고향 진산의 이름을 통일하자고 의견을 모아 빼어난 산세를 강조하기 위해 글자마다 뫼산자를 넣어 표기했다고 한다.정상에서면 지리산 천황봉이 손에 잡힐 듯 가깝게 보인다. 그리고 절터샘과 명경대, 신비로운 금지샘 등 명소가 있다. 샘에는 억새가 무성하고 조망이 좋다.", - "MNTN_HG_VL" : "897", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 칠곡면, 가례면, 대의면", - "MNTN_NM" : "자굴산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "163", + "MNTN_LOCPLC_REGION_NM" : "경기도 평택시,안성시", + "MNTN_NM" : "덕암산" }, - "longitude" : 128.20224590000001, - "latitude" : 35.374487700000003 + "longitude" : 127.12527780000001, + "latitude" : 37.066666699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;의령 고을의 진산gt;자굴산은 의령 고을의 진산으로 의령 고을 자체라고 할 수 있는 산이다. 높고 큰 산일수록 두 고을 또는 여러 고을의 경계가 되는 경우가 많다. 그러나 897미터나 되는 높고 큰 산이며 경관이 좋고 많은 전설도 간직하고 있는 자굴산(897.1m)은 서북 쪽 산자락 일부를 합천군이 차지하고 있을 뿐 대부분을 의령군이 차지하고 있다. 또한 자굴산은 양의 수산인 합천의 황매산에 대응하는 음의 암산이다. 그 때문에 양의 상징인 말을 정상에 모심으로써 음기와 조화를 이루게 했다고 한다.사람들은 절골 막바지의 써래봉 바람덤 아래 절터 일대의 짙은 숲과 그 사이에 솟아 있는 바위봉우리들과 신선대와 금지샘 일대의 오묘한 경관과 시원한 조망을 가장 좋아한다. 베틀바위에서 건너다보는 홑할미너덜과 절터 신선대 일대의 조망도 일품이다. 무당들의 기도터로 많이 이용되고 있는 강선암도 그 크기와 아래로 패여 들어간 기이한 모양으로 사람들이 많이 찾는 곳이라 한다. 특히 비가 올 때는 바위 위에서 떨어지는 물줄기가 수막을 이루어 그 안에서 밖을 내다보면 신기하다.", - "MNTN_HG_VL" : "897", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 가례면, 칠곡면, 대의면", - "MNTN_NM" : "자굴산" + "DETAIL_INFO_DTCONT" : "평창군 도암면, 성산면 어흘리와 왕산면 왕산리 사이에 있는 높이 841m의 산이다. (구)대관령 휴게소에서 1시간가량 오르면 정상에 오를 수 있다. 정상에서 상제민원(옛길 주막터)방향은 내리막길의 연속으로 지세는 급,완경사지로 이루어져 있고 지형적으로는 능선을 따라 이동하면서 자연스럽게 계곡으로 이동하게 되고 대관령박물관 옛길 코스에서도 오를 수 있다.대관령 능선의 어디에서나 강릉 시가지를 볼 수 있지만 제왕산성에서 내려다 보는 강릉 시가지는 특별하다. 시야에 막힘이 없어 시원하고도심의 모습과 바다로 흐르는 남대천의 흐름까지를 전부 조망할 수 있다.소요 시간 :2시간정도최적 탐방 시기 :매년 음력 5월 5일에는 단오제가 열리고, 10월에는 율곡제·무천제가 열린다. 하지만 4계절 모두 경치가 좋음명소 : 국사성황당 및 산신각, 신재생에너지전시관, 양떼목장, 대관령박물관볼거리 : 산세가 완만하며 상제민원의 계곡이 뛰어나고, 참나무숲과 낙엽송이 우거진 수풀이 곳곳에 있다.평창군 도암면과 강릉시 성산면 경계에는 선자령이 있고, 북쪽으로 영동고속도로를 사이에 두고 대관령 및 오대산국립공원과 마주본다.숲길 명소 : 강릉영림서의 임간학교가 제왕산 계곡에 있어 삼림욕을 즐길 수 있고, 어흘리에 대관령 박물관이 있어 옛 얼을 느껴 볼 수 있다.백두대간의 한구간으로서 능경봉과 선자령구간을 탐방할 수도 있으며 뛰어난 조망점을 자랑하고 있다.", + "MNTN_HG_VL" : "841", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 성산면", + "MNTN_NM" : "제왕산" }, - "longitude" : 128.20224590000001, - "latitude" : 35.374487700000003 + "longitude" : 128.78527779999999, + "latitude" : 37.687777799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "897", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 가례면, 칠곡면, 대의면", - "MNTN_NM" : "자굴산" + "DETAIL_INFO_DTCONT" : "삼봉산(1,254m)은 고제면 봉계리에 정상을 둔 거창의 진산(鎭山)으로 산 고스락이 되는 봉우리는 세 개이며 그 중심 봉우리는 흡사 동구앞 돌무지 탑 같고 먼 데서 바라보면 흡사 피어나는 연꽃 모습 같다. 예로부터 소금강이라 부를 만큼 산 경치가 빼어났으며 가뭄이 들때면 삼봉산 금봉암에 있는 용머리 바위에서 기우제를 올리었다. 산기슭 좋은 터에 금봉암(金鳳庵)이라는 절이 있다. 절과 산 모두가 나한도량(羅漢道場)이라 하여 기도처로 이름나 있다. 이 산은 불심(佛心), 산심(産心), 무심(無心)의 삼심이 깃들고 금봉암을 둘러리한 바위무리들은 병풍처럼 둘려쳐 봉황의 산세를 이룬다. 칼바위, 장군바위, 석불바위, 부부봉, 문바위, 투구봉, 용바위, 노적봉, 칠성봉 들이 모두 셋씩 나란히 짝을 짓는다. 세 개의 영험스런 바위 샘물이 솟아나 목을 축일만한 데 모두 신령스럽고 영험스런 샘물이라고 하며 천지인(天地人)을 우러른 삼신사상(三神思想)과 인연이 깊다. 덕유산으로 달리는 큰 줄기에서 동쪽으로 내린 가지에는 시루봉이 솟아 있으며 남쪽 골짜기는 금(金)이 난다. 산행은 크게 두가지로 나뉘는데 갓파르고 낙석의 위험이 있는 칼바위쪽으로 올라 바위굴샘을 거쳐 억새능선을 타고 오르는 코스와 삼성각 오름길에서 북쪽 용바위용굴을 비켜 오르는 능선길 코스가 있는데 8㎞에 3시간정도 소요된다.소요 시간 : 1코스 : 4시간 30분 신풍령 → 4 km(3시간) → 삼봉산정상 → 3km(1시간30분) → 소사재 2코스 : 2시간 10분 금봉암 → 1.4km(40분) → 삼봉산정상 → 1.2km(20분) → 북능 → 3.8km(1시간 10분) → 봉계리 원기동최적 탐방 시기 :사계절볼거리 : 일봉산에서 본 조망 정상부가 세 개의 봉우리로 이루어져 있는데 멀리서 보면 그 모습이 마치 연꽃 봉우리 같이 보인다. 금봉암에서 시작되는 산행은 가파른 바윗길과 안부를 지나면 정상에 이를 수 있다. 정상은 폭이 좁지만 주변 경관은 확 트여 있어 시원한 느낌이 든다. 산행의 기점이기도 한 삼봉암은 1905년 창건된 사찰이다. 전해오는 이야기에 의하면 금봉안 창건주가 지관이 잡아둔 자리에서 가마솥 뚜껑이 덮인 샘물을 마셔가며 백일 단식기도를 드리고 회향하던 날 황금빛 새가 산봉우리와 기도처를 세 번이나 왕복한 후에 어디론가 날아가서 그 자리에 절을 지었다고 한다. 그리고 그 절의 이름을 금봉암이라 하였는데, 사찰의 요사채 뒤편엔 옛날 거창 부사가 기우제를 지내던 용머리 형상의 바위가 있다.숲길 명소 : 산행길에는 억새밭과 잣나무 숲이 펼쳐지고 정상에 서면 덕유산의 웅장한 모습이 펼쳐진다. 정상의 줄기에는 밑둥이 큰 떡갈나무들이 주종을 이루며 특히 겨울의 눈꽃이 볼 만하다.등산객은 거의 없으며, 인근 주민들이 운동삼아 오르는 정도의 작은 산. 비교적 등산로는 잘 되어 있으나, 삼봉산 정상이란 표식이 없어 정상인지 구분이 안감. 산내에 화장실, 음수대가 없어 다소 불편함.", + "MNTN_HG_VL" : "1254", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 고제면", + "MNTN_NM" : "삼봉산" }, - "longitude" : 128.20224590000001, - "latitude" : 35.374487700000003 + "longitude" : 127.872652, + "latitude" : 35.892753399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제otilde;시 금성면과 단양군 적성면의 경계를 이르는 작성산(鵲城山)은 북으로 가acirc;산(819.5m), 갑산(776.7m), 호명산(475.3m), 마당재산(661.2m) 산줄기를 이어받고, 남으로 내려뻗어 동산(896.2m), 금수산(1,015.8m)을 빚는다.ucirc;풍호를 서쪽에 낀 작성산은 이웃한 동산과 더불어 제otilde;의 이름난 산이다. 원래 이 산은 현지 사람들이 부르고 있는 ‘까치성산’ 이었는데, 일제시대에 일본인들이 지형도를 만들면서 한문표기인 ‘鵲’자를 사용하면서 작성산(鵲城山)으로 더 알려졌다. 까치성산이란 이름에 얽힌 전설이 있다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명했다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.", - "MNTN_HG_VL" : "840", - "MNTN_LOCPLC_REGION_NM" : "충북 제천시 금성면 성내리", - "MNTN_NM" : "작성산" + "DETAIL_INFO_DTCONT" : "구곡산 산행 기점은 진주서 중산리 가는길에 위치한 산청군 덕산리 덕산서원(조선시대 대유학자 남명 조식선생 사적지로 사적305호)이다. 약간 불투명한 하산길 말고는 험로는 없지만 무성한 산죽군락이 가을이면 누렇게 변해 황금능선이란 이름이 붙은 산행후반부는 산행 재미가 꽤 빼어나다.지리산 남부능선에 솟아 있는 산으로 대원사 길과 중산리 길이 갈라지는 덕산마을 서쪽에 있다. 이 산에서부터 국사봉을 거쳐 써리봉까지 이어지는 20여 ㎞에 이르는 능선을 일명 '황금능선'이라 하는데 이는 가을이면 산죽군락이 누렇게 변해서 붙여진 이름이다.황금능선의 가장 긴 코스는 구곡산 남쪽 마을인 외공마을에서 시작, 산청군의 4대 사찰 중 하나인 도솔암 직전의 왼쪽 계곡을 타면서 본격적인 산행에 나서게 되는데 산중턱에 있는 도솔암까지는 대개 차량으로 오른다.정상에는 정상석이 세워져 있으며, 천왕봉, 칠선봉, 삼신봉, 촛대봉, 장터목, 제석봉 등 이른바 남부능선의 봉우리들이 시원하게 펼쳐진다. 글자 그대로 아홉계곡이 있다고하여 구곡산이다. 구곡산은 황금능선의 들머리로서 능선에 서면 지리산 천황봉이 손에 잡힐듯이 가까워 보이며, 구곡산 정상에 서면 장괘한 지리산 주능이 가장 가까이 조망되고 봄이면 철쭉, 가을이면 단풍등 후회없는 산행이 된다.", + "MNTN_HG_VL" : "961", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청", + "MNTN_NM" : "구곡산" }, - "longitude" : 128.21611110000001, - "latitude" : 37.036944400000003 + "longitude" : 127.79553679999999, + "latitude" : 35.277158700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금수산에서 뻗어내린 능선 계곡의 금성면 성내리 무암계곡, 왼쪽이 작성산, 오른쪽이 동산이다. 능선 위에 사람 모습을 한 암봉이 줄지어 있는 모습이 인상적이다. 특히 북한산 인수봉의 축소판이라고 하는 배바위는 암벽훈련장으로도 이용되고 있다. 흔히 금수산에 배바위가 있는 것으로 알려져 있지만 실제로는 작성산에 소재하며, 원래 이름은 까치성산이나, 일제강점기에 일본인들이 지형도를 만들면서 한자 '鵲'자로 표기한 뒤부터 문헌에는 까치성산보다는 작성이라는 이름이 더 많이 쓰이게 되었다.까치성산이라는 이름에 얽힌 전설이 전한다. 옛날 어느 왕이 이 산에 신하들을 데리고 들어와 궁궐을 짓고 살았다. 어느날 아침 왕이 신하들에게 동쪽 바위 봉우리를 가리키며, 저 위에 까치가 앉을 것이니 무조건 활을 쏘아 까치를 죽이라고 명하였다. 신하들이 마침 바위 봉우리에 앉은 까치를 쏘아 죽이니 그 까치는 다름 아닌 일본의 왕이었다.작성산은 산, 호수(충주호), 계곡, 바위 등을 골고루 갖추고 있는 실속 산행지이다. 그리 높지 않으면서도 아담하고 긴 능선위로 사람형상의 암봉들이 연이어 있다. 그래서 계곡산행을 즐기는 등산객 뿐 아니라 북한산 인수봉의 축소판 배바위는 클라이머 들이 자주 찾으며 암벽훈련장으로도 이용되고 있다.작성산은 정상부근까지 흙이 많은 육산이고 정상 부근에만 기암괴석이 발달한 것이 특징이다. 등산로는 톱날같은 형상의 바위능선 사이로 나 있는데 가을이면 좌우 양편으로 샛노란 은행나무와 붉은 단풍나무가 화려한 색의 대비를 이루며 늘어서 마치 내장산의 단풍터널을 빠져나가는 기분이 든다. 정상에 서면 충주호가 저 멀리 시야에 들어온다.", - "MNTN_HG_VL" : "771", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 금성면, 단양군 적성면", - "MNTN_NM" : "작성산" + "DETAIL_INFO_DTCONT" : "삼랑진과 원동에 걸쳐 있는 금오산과 천태산은 낙동강을 끼고 있어 주위 경관이 수려할 뿐 아니라 경부선열차를 이용할 수 있어 교통도 편리하다.금오산만 오를 경우 4시간, 금오산- 천태산 코스는 6시간30분, 금오산-매봉산 코스는 6시간 정도 소요된다. 3~4개의 바위봉우리로 뭉쳐진 채 힘차게 단일봉 형상을 한 금오산은 멀리서 보아도 그 자태가 당당하여 천태,만어산을 거느린 `맏형 산'으로 손색이 없다.주변에 삼랑진양수발전소가 안태호 천태호 등 인공호수와 더불어 명소로 등장했고 가락국 때부터 있어온 부은암은 이 곳을 찾는 사람들에게 오늘과 어제를 가르쳐 주는 역사의 현장이다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 삼량진읍, 양산 원동", + "MNTN_NM" : "금오산" }, - "longitude" : 128.21611110000001, - "latitude" : 37.036944400000003 + "longitude" : 128.90615080000001, + "latitude" : 35.416717800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가뭄이 심할 때 관민이 모여 기우제를 올리던 곳으로 홍림산, 일월산과 함께 영양의 진산으로 꼽힌다. 이 산은 세 개의 봉우리가 큰 바가지를 엎어놓은 듯 하여 한박산이라 불리기도 하며 산세가 탕건 같다하여 탕건봉이라 부르기도 한다.작약산이란 이름은 이 산의 형세가 풍수지리의 작약반개형(芍藥半開形) 명당이라는 데서 유래되었다. 정상에는 소나무와 참나무가 우거져 확 트인 전망을 기대하기 어렵다. 북으로 흥림산이 손에 잡힐 듯 가까이 보이나 북쪽이 협곡을 이루어 능선이 발달하지 않아 흥림산으로 연결된 등산로가 없다. 하산길에 권영성(1881-1923)의 넋을 기리기 위해 후손들이 세운 요산영천(樂山靈泉) 입석비가 있다. 권영성은 영양읍 서부동 출생으로 행상을 해서 번 돈으로 이 지역의 복지후생에 노력한 사람이다.", - "MNTN_HG_VL" : "770", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군 영양읍, 청기면", - "MNTN_NM" : "작약산" + "DETAIL_INFO_DTCONT" : "윤산 정상에 서면 부산이 온통 산의 물결을 이룬다는 사실을 확인하게 된다. 회동수원지를 감싸고 있는 정면 한가운데 아홉산과 그 우측으로 개좌산 운봉산이, 아홉산 왼쪽 뒤 암봉이 달음산, 그 왼쪽으로 뾰족봉인 천마산 치마산(함박산) 곰내재, 그 뒤로 시명산이 확인된다.부산 금정구 부곡동 서동 금사동에 걸쳐있는 나즈막한 봉우리인 윤산(輪山·318m)에 오르면 광안대교가 보이는 광안리 해안가를 제외한 전 지역이 산의 물결을 이룬다. 크게 보면 부산도 일종의 대형 분지(盆地)라는 사실을 실감한다.조선시대 지리서인 '동국여지승람'과 1740년판 '동래부지'에는 윤산을 '동래부의 북쪽 8리에 있으며, 동래부의 진산(鎭山)'이라 적고 있다. 알다시피 진산은 도읍이나 성지의 뒤쪽에 있는 큰 산을 말하는데 결국 윤산이 동래의 뒤쪽 큰 산이니 진산이 되는 셈이다.이제 궁금증은 왜 윤산으로 명명됐느냐 하는 것. 답은 간단하다. 동래쪽에서 보면 산 모양이 수레바퀴처럼 둥글게 보여 바퀴 윤(輪)자를 차용했다. 주민들로부터 '대머리산' '둥글산'으로 불린 것도 이같은 이유에서다.그렇다면 윤산이 왜 구월산으로 불렸을까. 뚜렷한 답은 없지만 바퀴에서 연상되는 '구불다'에서 '구블다' '구을다'로 변해오다 결국 구월산으로 와전되지 않았을까 하는 것이 일반적인 추측이다.이 때문에 지역 주민들이 원래 산 이름을 되찾아야 한다고 민원을 제기했고, 이에 시는 타당성이 있다는 판단하에 국토지리정보원에 산 이름 변경을 요청했다. 결국 국토지리정보원은 지명위원회의 심의를 거쳐 윤산으로 산 이름을 복원키로 결정했다고 지난 2002년 7월 시에 알려와 시는 이때부터 공식적으로 윤산으로 부르고 있다.", + "MNTN_HG_VL" : "317", + "MNTN_LOCPLC_REGION_NM" : "부산광역시", + "MNTN_NM" : "윤산" }, - "longitude" : 129.09472220000001, - "latitude" : 36.678888899999997 + "longitude" : 129.10360969999999, + "latitude" : 35.233632 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 주맥인 오대산(1563m)에서 뻗어나온 줄기가 계방산에서 남으로 내려와 백적산을 일구고 그 아래에 힘껏 솟구쳐 일군 봉우리가 잠두산이다. 바로 옆에 백석산이 이웃해 있고 주변에는 오대산, 계방산, 가리왕산, 청옥산, 남병산 등 평창군 일대의 고봉들이 운집해 있다. 잠두산은 산의 형상이 누에벌레를 닮았다 하여 붙여진 이름이다.잠두산 정상은 산죽으로 덮여있고, 백석산 쪽으로 내려가는 넓은 능선엔 억새밭과 콩제비꽃 지대가 있어 아름답다. 산행으로는 맑은 오대천이 흐르는 동쪽이 산세가 완만해서 가족산행으로 좋다. 들머리는 마평리, 수항리, 화의리 어디를 선택해도 좋다.", - "MNTN_HG_VL" : "1243", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군", - "MNTN_NM" : "잠두산" + "DETAIL_INFO_DTCONT" : "경기도 가평군에 위치해 있는 옥녀봉은 30리에 달하는 용추계곡을 끼고 있어 여름철 가족 산행지로 적합하다. 특히 곰바위 소바위 미륵바위 용세수대야 등이 몰려 있는 용추폭포 일대가 용추계곡의 백미다.옥녀봉은 마치 여자가 치마자락을 펼쳐 놓은 것 같다하여 옥녀봉이라 한다.가평읍에서 북면을 향해 2.3㎞ 정도 가다가 다리를 지나 좌회전하여 군부대 돌담을 끼고 2㎞ 정도 들어가면 용추계곡 주차장이다.차에서 내리면 바로 용추폭포가 보인다. 높이 20m의 용추폭포는 언뜻 보기엔 별 볼품이 없으나 소용돌이가 심한 소를 이루고 있어 청량감을 자아낸다.옛날 용이 승천했다는 전설을 지닌 용추폭포 옆 경사진 바위에는 용이 누웠던 자리라 일컬어지는 깊게 파인 자국이 나있다. 또 폭 1m의 용세수대야라는 바위 웅덩이가 있다.이 산은 입구에서부터 약초향이 물씬 풍긴다. 취나물과 더덕처럼 생긴 보약제 잔디등 많은 약제가 등산로 양옆으로 나 있어 약초를 캐는 재미도 솔솔하다.", + "MNTN_HG_VL" : "715", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 승안리", + "MNTN_NM" : "옥녀봉" }, - "longitude" : 128.5097222, - "latitude" : 37.5586111 + "longitude" : 127.4877778, + "latitude" : 37.8636111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "완주군 동상면과 진안군 주천면 경계에 자리한 장군봉은 등산객의 발길이 드물어 등산로가 희미하고 표지기도 거의 없는 산이다. 이 산은 슬랩 등반, 침니 등반, 줄타기 등의 교육장으로 활용할 수 있을 정도로 다양하고, 숲도 좋고 계곡이 짧은 거리에서 험하기는 하나 진입로에는 우리나라에서 네 번째로 크고 아름다운 대야저수지와 동산저수지가 있으며, 산길에는 쇠사다리 하나 설치되어 있지 않아서 더더욱 좋다.등산지로는 전북 어느 산과 견주어도 손색이 없는 이 산이 옛 모습대로 깨끗하게 유지되고 있는 것은 눈에 잘 뜨이지 않는 오지에 있기 때문이며, 산 정상에서 내려다보는 암석의 아름다움은 누구나보아도 매료당할 정도이다.", - "MNTN_HG_VL" : "735", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 진안군 주천면", - "MNTN_NM" : "장군봉" + "DETAIL_INFO_DTCONT" : "백암산은 드넓은 호남평야를 마주하고 솟아오른 높이 741.2m의 산으로 내장산 국립공원에 속한다.옛부터 봄이면 백양, 가을이면 내장이라 했듯이 산하면 내장, 고적하면 백암이라 할 정도로 백암산의 절경은 내장산에 뒤지지 않는다. 백학봉과 상왕봉, 사자봉, 등의 기암괴석이 곳곳에 있으며, 산세가 험준한 편이다. 특히 비자나무숲과 회색 줄무늬 다람쥐가 유명한 이곳에는 대한 불교 조계종 18교구 본산인 대사찰 백양사도 있다.", + "MNTN_HG_VL" : "741", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군 복흥면, 전라남도 장성군 북하면", + "MNTN_NM" : "백암산" }, - "longitude" : 127.34527780000001, - "latitude" : 35.9697222 + "longitude" : 126.85083299999999, + "latitude" : 35.462778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상북도 봉화군에 위치하고 있으며 인근 일월산과 마주하고 있다. 풍수지리설에 의하면 장군대작(將軍大爵)의 모기(墓基)가 있다고 하여 장군봉(將軍峰)이란 이름이 명명되어 전하여 오고 있고 동서남북으로 임산도로가 개설되어 있어 접근이 용이하다.장군봉은 그 이름처럼 일월산을 지켜주는 남성산이다. 토산인 일월산이 여성산이라 그 산과 나란히 하면서 일월산을 주켜주기 위해 태동했다는 일설이 전한다. 또 봄철 두릅, 산나물 등이 많아 채취하는 사람들의 발길이 끊이지 않고 있다. 그래도 봉화에서도 가장 험악한 산악지대로 알려진 곳에 있고 찾는 이가 드물어 아직까지는 호젓한 산행을 할 수 있는 곳이다. 그러나 임도가 정상부까지 나있어 산행시간이 많이 걸리지 않는다.북쪽으로는 태백산(1,560.6m)과 청옥산(1,276.5m)을 두고 있고, 남쪽으로는 일월산(1,218m)을, 동쪽으로는 통고산(1,066.5m)을 끼고 있다. 또 서남쪽으로는 도립공원인 청량산(970.4m)을 가까이 하고 있다. 장군봉을 둘러싸고 있는 산들은 모두 사람이 많이 찾는 곳이다. 어쩌면 장군봉은 그들의 위세에 밀려 알려지지 않은 산인지도 모른다.", - "MNTN_HG_VL" : "1039", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 소천면", - "MNTN_NM" : "장군봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "796", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", + "MNTN_NM" : "병풍산" }, - "longitude" : 129.08583329999999, - "latitude" : 36.853055599999998 + "longitude" : 127.81778920000001, + "latitude" : 38.079237399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "325", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "장군산" + "DETAIL_INFO_DTCONT" : "토함산은 호국의 진산으로 예로부터 신성시 되어온 산이다. 신라의 영산으로 일명 동악이라 불리었으며, 서악 선도산, 남악 금오산, 북악 금강산, 중악 남산과 더불어 신라 5악이다. 신라의 4대 임금인 석탈해왕이 죽은 후 동악의 산이 되었다고 한다. 석탈해왕은 토해왕이라고도 했는데 토함산의 이름은 동악의 산이 된 데에서 유래된 듯하다.경주에서 가장 큰 산으로서 울산광역시와 경계를 이루며 동쪽으로는 추령재를 지나 기림사와 죽어서 동해의 큰 용이 되어 왜적으로부터 동해를 지키겠다는 문무대왕의 수중릉이 있는 동해바로 이어진다. 서쪽으로는 대덕산과 노천박물관으로 불리는 남산과 마주하고 있다. 북쪽으로는 만호봉을 지나 보문관광단지에 이른다.토함산 기슭에 위치한 불국사와 석굴암 이외에도 무덤에 물이 괴어 널을 걸어 묻었다는 전설로 유명한 괘능, 아사달과 아사녀의 애절한 전설이 담긴 영지못 등 주변에는 많은 문화재가 있다. 일출이 일품인 정상은 신년일출산행지로 손꼽히는 곳이다.", + "MNTN_HG_VL" : "746", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 불국동", + "MNTN_NM" : "토함산" }, - "longitude" : 127.7175, - "latitude" : 34.748055600000001 + "longitude" : 129.345, + "latitude" : 35.801666599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용문산 북쪽의 992m봉에서 북으로 분기하여 늪산(봉미산)을 빚고 홍천강으로 빠져들기 직전에 장락산을 만들었다.능선 주변에는 기암이 도처에 산재하고 노송이 어우러져 아름다운데다 굽이굽이 흐르는 홍천강을 시종 바라보면서 걸을 수 있는 능선길이 더욱 운치 있다. 능선의 좋은 경치는 전망이 뛰어난 615봉에서부터 시작되는데 깃대봉과 화채봉에서 절정을 이룬다.계곡은 장락골이 제일 좋고, 마곡리 일대 강변의 넓은 모래밭은 모곡 유원지로서 유명하고 형제봉에는 유명한 약수터가 있고, 깃대봉과 화채봉 사이 서편 농바위골 주변에는 강씨굴과 약수터가 또 있다.", - "MNTN_HG_VL" : "627", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 강원도 홍천군 서면", - "MNTN_NM" : "장락산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "544", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "나래산" }, - "longitude" : 127.5486609, - "latitude" : 37.670588000000002 + "longitude" : 127.1250915, + "latitude" : 35.612496 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "978", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창 방림면, 대화면", - "MNTN_NM" : "장미산" + "DETAIL_INFO_DTCONT" : "매봉산은 치악산국립공원 동남쪽 끝머리인 성남리 동쪽 선바위봉(1,001m)에서 감악산으로 이어지는 능선상의 최고봉이다. 감악산(945m)을 마주보고 있는 이 산은 예로부터 산삼이 발견되고 있는 산으로 유명하고 옛날 정상에서 매를 풀어 토끼와 꿩사냥을 하였다하여 매봉산이라 불리었다.치악산 국립공원 구역에서 살짝 비껴 앉은 이 산은 주변산에 비해 호젓한 산행을 즐길 수 있으며 겨울철에는 적설량이 많아 겨울산행을 즐기기에도 안성맞춤이다. 가을이면 치악산에서 매봉까지 병풍처럼 펼쳐지는 오색단풍이 일품이다.정상에 서면 북으로 당골계곡, 남으로 감악산, 동으로 사자산, 백덕산 등 주변 산악지대가 장관을 이루고 있다. 또 당골계곡 너머로 치악산 비로봉과 매화산이 단아한 자태를 드러낸다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 신림면, 영월군 수주면", + "MNTN_NM" : "매봉산" }, - "longitude" : 128.36008799999999, - "latitude" : 37.475849199999999 + "longitude" : 128.12416669999999, + "latitude" : 37.274999999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장미산은 차령산맥의 줄기로 산 아래로는 남한강 최상류인 평찬강이 흐르고 청태산, 금강산이 위용을 자랑하며 휘둘러있다. 산 이름은 산 모습이 노루꼬리처럼 생겼다 하여 생겨났다. 웬만한 지도책에는 나오지 않고 겉보기에도 밋밋한 산이지만 실제 올라보면 갖가지 기암괴석과 울창한 산림을 보유하여 아기자기한 맛이 있다.정상에서는 북으로 덕수산·등용산, 동으로는 백적산에서 청옥산까지 이르는 능선, 서쪽으로는 오봉산·솔이봉·청태산 등이 어렴풋이 보인다. 자연이 잘 보존되어 노랑괴불꽃, 고추냉이꽃, 줄딸기 등 희귀 식물이 많고 취나물·더덕·곰취·두릅·고사리·씀바귀 등 산나물도 흔하게 난다.봉우리 중에서 6·25전쟁 때 최악의 격전지로 유명한 중대갈봉은 민둥산이었을 때 붙은 이름이며 지금은 수림이 울창하고 거북바위와 표대봉이 있다. 장미산에서 덕수산 사이로 흐르는 금당계곡은 유동마을을 거쳐 개수교, 봉황대로 흐른다. 봉황대는 봉황이 놀았다고 하여 부근 마을에서 길조바위로 숭배하고 있다. 산행은 덕수산(913㎙)을 넘어 남쪽 능선을 따라 이어진 장미산까지 4시간 남짓의 코스. 온통 숲으로 뒤덮여 산 중턱과 정상을 가름하기 조차 힘들다.", - "MNTN_HG_VL" : "980", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 방림면 대화면", - "MNTN_NM" : "장미산" + "DETAIL_INFO_DTCONT" : "산에 아홉 개의 큰 절들이 있다는 데서 유래했다고 전하며, '무수산(無愁山)'으로 불린다고 한다. 신풍면 백룡리, 입동리, 선학리에 걸쳐있는 산으로 예전에 아홉 개의 절이 있었으나 현재는 다 없어졌다.굴티 오른쪽, 오름실 아래쪽에 위치하고 있다.", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 신풍면", + "MNTN_NM" : "구절산" }, - "longitude" : 128.36008799999999, - "latitude" : 37.475849199999999 + "longitude" : 126.97027780000001, + "latitude" : 36.487777800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장산은 태백시를 나와 화방재를 넘은 뒤 조금 내려오면 옥동천이 시작되면서 오른쪽으로 보이는 화려한 암봉과 능선으로 이루어진 멋진 산이다. 서울특별시에서 태백산으로 가는 길은 특히 영월을 지난 뒤 고개와 강, 숲과 협곡, 고봉과 단애가 연이어 나타나 어느 지역의 경관이 좋고 어떤 산이 높고 아름다우며, 어떤 강물이 맑으니하고 말하기가 어렵다. 하나같이 높고 아름다운 산이 연이어져 보임에서 그렇다.이산의 장점이라면 남쪽과 서쪽은 바위로만 이루어져서 경관이 수려하고 북쪽과 동쪽은 완사면으로 되어있어 올라가기가 좋다. 경사가 완만하며 바위벽이 가로막고 숲길로 이어지는 반복적인 등산로 이기에 지루함을 못느끼고 너덜지대 끝에 올라서면 시야가 확 트인다 .정상에는 조그마한 삼각점이 있고 두위봉이 시야에 들어오고 백운산,함백산 정상의 중계탑이 선명하고 태백산의 장군봉,천제단,문수봉의 너덜지대와 구룡산으로 이어지는 백두대간의 웅장한 흐름을 볼 수 있다.문자 그대로 장(壯)한 산이다. 암릉도 암릉이거니와 산행의 시작을 맑은 계류가 굽이쳐 흐르는 옥동천에서 시작한다는 것이 장산을 처음 오르는 사람도 탄성을 지르게 한다.", - "MNTN_HG_VL" : "1409", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 상동읍", - "MNTN_NM" : "장산" + "DETAIL_INFO_DTCONT" : "경상북도 청도군과 대구광역시 달성군의 경계에 있는산, 최고봉은 대건봉이며 남쪽으로는 조화봉, 관기봉과 이어지며 유가사쪽에서 올려다보면 정상을 떠받치고 있는 거대한 바위능선이 우뚝 솟아있다.정상에서 바라보는 낙동강의 경치가 아름답고 봄철에는 철쭉, 진달래 가을에는 억새군락이 볼만하다. 스님바위, 코끼리바위, 형제바위등의 이름난 바위와 달성군 옥포면의 용연사를 비롯하여 용문사, 유가사등의 사찰이 산재한다. 정상인 대견봉에서 남쪽 능선을 따라 988봉 - 조화봉으로 이어진다.조화봉 능선에서 서쪽으로 대견사 터 - 1034봉으로 이어지며 1034봉에 팔각정 전망대가 설치되어 있다. 정상에서 북으로 이어지는 능선은 앞산으로 가는 안내표시가 되어 있다.정상에서 조화봉 까지 약 4km에 걸친 능선은 988봉 주변에 바위가 있을 뿐 육산(흑산)으로 큰 나무들이 없는 시야가 탁 트이는 초원 같은 이 능선에 가을에는 억새가, 봄에는 군락을 이룬 진달래가 붉게 물들인다.진달래 군락사이에 싸리나무 등 잡목들이 섞여 있으나 진달래가 더 많다.비슬산 진달래는 정상부근, 988봉 부근 아래, 대견사 터 산자락 등 크게 3군데에 군락을 이루고 있다. 대견사터 북쪽 광활한 30여만평의 산자락이 대규모 진달래 군락지이며, 진달래가 가장 곱고 밀집되어 있는 곳은 988봉 부근 아래 산자락이다. 진달래는 4월 중순부터 물들기 시작해 4월 말에 절정에 달한다. 4월 하순경 참꽃(진달래)제가 열린다.", + "MNTN_HG_VL" : "1083", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 옥포면ㆍ유가면ㆍ가창면, 경상북도 청도군 각북면", + "MNTN_NM" : "비슬산" }, - "longitude" : 128.86013370000001, - "latitude" : 37.127789800000002 + "longitude" : 128.52333329999999, + "latitude" : 35.715555600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 문경시 가은읍 서쪽에 위치한 장성봉은 예전에는 수정을 캐던 수정광산으로 알려지기도 했지만 그마져도 그 분야에 상관이 있는 사람들이나 알 수 있었을 만큼 알려지지 않은 산이다. 산을 찾는 사람들이 많아지다 보니 요즘은 이름이 덜 알려진 산들이 자꾸만 개발이 되고 장성봉 역시 그런 산들 중 하나이다.장성봉(915m)은 경북 문경시 가은읍 서쪽에서 백두대간의 허리를 떠받치고 있는 숨은 명산이다. 1\/5,000지도에는 높이가 907.8m로 표시되어 있고 산이름이 그렇듯 마치 거대한 만리장성의 일부를 보는 듯한 장성봉은 북쪽으로부터 남진하는 백두대간이 희양산(999m)에서 서쪽으로 꺾였다가 악희봉(843m)을 솟구친 후, 다시 직각으로 꺾여 남족의 대야산(931m)으로 치닫다가 악희봉과 대야산 중간쯤에 이르러 우뚝 솟아 있다.이 때문에 장성봉을 중심으로 12시 방향인 북쪽 악희봉에서 시계바는 방향으로 구왕봉(898m), 희양산(999m), 애기암봉(731m), 둔덕산(970m), 대야산(930.7m), 군자산(910m) 등이 원을 그린 듯 에워싸고 있어 제법 심산유곡에 들어선 것처럼 느껴지는 산이다. 또, 북쪽의 깊고 긴 계곡이 봉암사 계곡인 봉암용곡임을 아는 사람은 많지 않다. 아뭏튼 장성봉은 경북 문경시와 충북 괴산군 경계를 이루는 백두대간 일원의 주말산행코스로 이용되는 여러 산들 중에서 아직까지는 가장 조용하고 오염이 안된 산으로 남아있는 것이 자랑거리이다.등산로가 확실하지 않고, 산 속에 들어서면 이따금 사람을 보고도 놀라는 기색없이 발길을 옮기는 노루와 토끼, 그리고 희귀식물인 솜다리(에델바이스)가 눈에 보이는 것만으로도 장성봉이 얼마나 오염이 안된 산인가를 입증하고 있다.", - "MNTN_HG_VL" : "915", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍", - "MNTN_NM" : "장성봉" + "DETAIL_INFO_DTCONT" : "오대산국립공원권에 속해 있는 노인봉은, 강원도 강릉시와 평창군의 경계를 이루고 있는 산으로, 유명한 소금강계곡을 산자락에 거느리고 있다. 금강산의 축소판이라 일컫는 '소금강'이라는 이름은 율곡선생이 청학동을 탐방하고 쓴 〈청학산기〉에서 유래되었으며 무릉계옆 바위에 아직 '소금강'이라는 글씨가 남아 있다.산의 정상에는 기묘하게 생긴 화강암 봉우리가 우뚝 솟아 있으며, 그 모습을 멀리서 바라보면 백발노인과 같이 보인다 하여 노인봉이라 붙여졌다 한다.정상에서 소금강계곡으로 내려서면 낙영폭포가 나타난다. 낙영폭포에서 무릉계까지 7km 가량 이어지는 소금강계곡은 30여개의 다리를 건너야 하는 아기자기한 산행길이다. 낙영폭포를 지나면,광폭포,삼폭포,백운대를 지나 만물상으로 이어진다.", + "MNTN_HG_VL" : "1338", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "노인봉" }, - "longitude" : 127.9552778, - "latitude" : 36.701944400000002 + "longitude" : 128.6394444, + "latitude" : 37.782499999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장안산은 장수군과 함양군의 경계선에 있는 백두대간상의 영취산에서 서쪽으로 갈라진 호남정맥의 첫머리에 솟아 있는 기봉이다. 기봉인 장안산에서 섬진강과 금강을 경계로 호남지방과 호서지방까지 뻣어 국토의 약 25%를 점유하고 풍요로운 강산을 이루고 있는 조산, 영산이기에 더욱 아름답게 가꾸어 나가야 한다. 장안산은 이 산맥에 솟아 있는 산중에서도 제일 높고 호남,지방에서는 지리산 덕유산 남덕유산에 이어 4번째로 높은 산이다.이 산은 1986년에 군립공원으로 지정되었다. 기암괴석과 울창한 원시수림을 자랑하는 장안산은 덕산용소와 방화동, 지지계곡 지구로 나뉘어져 아름다운 절경을 이루는 관광지다.", - "MNTN_HG_VL" : "1237", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 장수읍, 계남면", - "MNTN_NM" : "장안산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "578", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진주시", + "MNTN_NM" : "집현산" }, - "longitude" : 127.5959075, - "latitude" : 35.629946500000003 + "longitude" : 128.03420779999999, + "latitude" : 35.3133531 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장암산이란 이름은 산 정상에 자리잡은 너럭바위에서 비롯되었다. 장암산은 산이름이 그렇듯이 펑퍼짐한 초원을 이룬 정상에 너럭바위가 있는데, 그 모습이 옆에서 보면 마치 물위를 떠가는 조각배를 닮아 신기하기만 하다. 더욱 기이한 것은 이웃하고 있는 태청산은 이따금 눈에 띄는 단단한 바위들이 모가나 날카로운데 비해 장암산 정상에 덩그러니 올려 놓은 듯한 바위는 조각작품처럼 매끄럽게 다듬어 놓은 것 같아 맨발로 올라 앉아도 괜찮을 정도이다.장암산은 전남 영광군 묘량면, 장성군 삼서면에 위치한 나즈막한 산이다. 굴비의 고장 영광군은 서쪽으로는 서해바다를 끼고 있다. 북쪽으로는 전북 고창군과 경계를 이루지만 거의 평야를 이루고 있다. 그러나 장성군과 경계를 이루는 동쪽과 함평군과 경계를 이루는 남쪽은 400m?600m 높이로 솟은 산들이 성곽처럼 에워싸고 있다.장암산에서 남서쪽으로 활시위처럼 휘어지는 산릉은 남쪽 함평군과 경계를 이루며 불갑산(516m), 모악산(348m), 군유산(403m), 월암산(338m)을 연속적으로 들어올린 다음 그 여맥을 서해바다에 가라앉힌다.장암산은 훌륭한 등산코스일 뿐만 아니라 행글라이더들에게도 인기가 대단하다. 그만큼 정상에 오르면 마치 비행기를 타고 하늘 위에 떠있는 기분에 휩싸일 만큼 시원한 파노라마가 펼쳐진다. 행글라이더들이 뛰어내리는 방향인 서쪽 아래로는 묘량면 곡창지대 들판이 시원하게 터지며 멀리 영광읍 너머인 백수 방면 서해바다가 가물거린다.북으로는 대마면 들판 너머로 고창군 곡창지대가 시원해게 펼쳐진다. 대마면에서 오른쪽으로 하늘금을 이루는 태청산과 얼랑산 풍광도 일품이며 남으로 불갑산으로 내다르는 산릉이 첩첩산중을 이루어 장암산에 오른 보람을 만끽하고도 남는다.", - "MNTN_HG_VL" : "482", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 묘량면, 삼서면", - "MNTN_NM" : "장암산" + "DETAIL_INFO_DTCONT" : "명지산(1,267m)과 운악산(936m)을 빚은 백두대간의 줄기가 의정부에 이르러 나즈막하게 솟구쳐 오른 산이 죽엽산이다. 국수봉(605m)과 소리봉(536m)을 이웃하고 있으며 굴곡 없는 육산이다. 언뜻 보기엔 밋밋하고 신통치 않게 보이는 산이지만 이산의 특징은 울창한 수림에 있다.도봉산의 사패능선이나 포대능선처럼 경치를 볼 수 있는 탁 트인 곳은 없지만, 주능선상의 쭉쭉 뻗은 울창한 수림사이를 시원한 바람을 맞으며 걷노라면 이 산의 매력이 충분히 느껴질 것이다. 산행은 큰넓고개나 직동에서 시작한다.", + "MNTN_HG_VL" : "601", + "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 소흘읍, 내촌면", + "MNTN_NM" : "죽엽산" }, - "longitude" : 126.5838186, - "latitude" : 35.2580569 + "longitude" : 127.1855556, + "latitude" : 37.7916667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 평창군에는 유난히 전인미답의 1000m급 고봉들이 모여 있다. 장암산은 주변에 남병산(1149m)을 비롯하여 가리왕산(1560m), 청옥산(1256m), 백덕산(1350m)등이 인접해 있어 그 유명한 산들의 위세에 눌려 이름조차 생소한 산이다.첩첩 산중의 미답지인만큼 원시림에 가까운 수림이 주를 이룬다. 이 산 서쪽으로는 오대산 산자락에서 발원한 물줄기가 속사천을 거쳐 평창강과 남한강으로 흘러들면서 장암산을 끼고 돌아 주위경관이 더욱 수려하다. 특히, 이곳의 명물인 국내 최대의 송어 양식장이 자리하고 있어 산행 후 회나 매운탕을 별미로 맛볼 수도 있다. 장암산은 남병산을 베게 삼아 남북으로 길게 누웠는데 반으로 갈라 북쪽은 장암산이라고 하고 남쪽은 송계산이라고 한다 .송계산이라 부르는 연유는 옛부터 그 자락에 살아온 송씨들의 계모임에서 그렇게 불렀다고 한다. 최근 들어서는 페러글라이딩 동호회 회원들이 최고로 꼽는 활공장으로소의 역할을 톡톡히 하고 있다.", - "MNTN_HG_VL" : "833", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", - "MNTN_NM" : "장암산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "157", + "MNTN_LOCPLC_REGION_NM" : "울산광역시 중구 다운동", + "MNTN_NM" : "입화산" }, - "longitude" : 128.4221124, - "latitude" : 37.3872778 + "longitude" : 129.2814722, + "latitude" : 35.580594300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 옥천군에 자리한 장용산은 정상 봉우리의 모양새가 멀리서도 눈에 띨 만큼 이채롭다. 기암괴봉들이 엉켜 절경을 연출하고 있어 산을 찾는 사람들에게 기쁨을 준다.장룡산 마성산 사이의 고개를 사목재라고 하는데 장룡산에서 사목재쪽의 암릉은 왕관바위 등 기암괴봉이 이어진다. 이 암릉 동쪽(옥천쪽)비탈에는 절 용암사가 있으며 서쪽 사면은 포옹바위, 병풍바위 등 기암괴봉과 암벽으로 이루어져 있다. 이 경관 좋은 서쪽 비탈 아래 옥천군에서 조성한 장룡산휴양림 시설의 하나로 장룡산 중봉 아래 정자까지 지어 놓았다.용암사는 서기 552년 신라 진흥왕 13년에 의신조사가 속리산에 법주사를 창건하기 전에 이곳의 산세를 보고 신비로움에 감탄한 나머지 절을 세웠다고 한다. 이 절 왼편 언덕에는 충청북도 유형문화재 제3호인 쌍석탑이 있고 절 뒤에는 역시 충청북도 유형문화재 제8호인 여래입상을 양각한 마애불이 있다.", - "MNTN_HG_VL" : "656", - "MNTN_LOCPLC_REGION_NM" : "충청북도 옥천군 군서면 금산리", - "MNTN_NM" : "장용산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "138", + "MNTN_LOCPLC_REGION_NM" : "경기도 평택시", + "MNTN_NM" : "덕지산" }, - "longitude" : 127.5663661, - "latitude" : 36.242428199999999 + "longitude" : 126.9354044, + "latitude" : 37.061012400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "안평산은 금남정맥의 산줄기가 대둔산 태고사 앞산인 오대산을 타고 내려와 대전광역시 남서쪽 끝에 와서 불끈 힘을 모아 솟아올린 산이다. 안평산 은 덩치가 우람하고 수림이 매우 울창하며, 아직 때가 묻지 않은 산으로 산 언저리에는 두메산골의 풍경이 그대로 간직되어 있기도 하다.안평산의 이름은 산 속에 만인이 피난을 와서 살 곳이 있다고 해서 안평산이라 부르게 되었다고 하며, 이 산 위에 있는 장태산 휴양림은 대전광역시8경의 하나로서 관광명소로 자리잡아 가고 있다.또한 수양,압점.안평의 세 봉우리로 이루어진 안평산은 옛날부터 시인 묵객들이 자주 찾았던 곳이며,임진왜란 때는 의병활동의 본거지 역할을 했을 것으로 짐작된다.장안동 주민들이 애착심을 갖고 관리하고 있는 산으로 코스와 등산로가 잘 정비되어 있다.울창한 수림,오지를 걷는 듯한 사면길,안평산 정상의 가슴 확트이는 조망봉에서 바라보는 용태울 저수지 방향의 그림같은 풍경,신앙 굿당지들의 이색볼거리 등 대전에서는 잘 알려지는 않은 산이다. 마을 주민들이 등로를 정비 개발하고 주황색 물호스를 잘라 리본을 만들어 코스코스 마다 매달아 놓아 리본을 따라 진행하면 어려움이 전혀 없다.안평산 정상에서의 조망은 사방으로 뛰어나며, 특히 구불거리며 흐르는 유등천이 인상적이다.", - "MNTN_HG_VL" : "471", - "MNTN_LOCPLC_REGION_NM" : "대전광역시 서구", - "MNTN_NM" : "장태산" + "DETAIL_INFO_DTCONT" : "진주와 함안의 경계지점에 터잡고 있는 계방산과 방어산은 가족산행지로는 더없이 좋은 곳이다.계방산은 500m급의 산에 불과하지만 능선의 굴곡이 심한데다 군데군데 암반을 올라야 하고 끝없이 이어지는 소나무터널이 산행의 묘미를 한층 더하게 해 준다. 여기다 방어산 7부능선에 터잡은 보물 159호\"\"마애약사삼존불\"\"도 만날 수 있고 능선에 오르면 남강에서 불어오는 싱그러운 바람을 맞으며 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "451", + "MNTN_LOCPLC_REGION_NM" : "경상남도 진주, 함안", + "MNTN_NM" : "괘방산" }, - "longitude" : 127.33380579999999, - "latitude" : 36.210955599999998 + "longitude" : 128.30583329999999, + "latitude" : 35.225277800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금북정맥 구간에 해당", - "MNTN_HG_VL" : "381", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 예산군", - "MNTN_NM" : "장학산" + "DETAIL_INFO_DTCONT" : "강화도의 서남단 외포리 선착장에서 4km정도 떨어진 석모도에는 상봉산을 중심으로 동쪽에 해명산(327m)과 북쪽에 상주산(264m)이 있다. 3개의 산이 있다해서 삼산면으로 이중 상봉산이 가장 높다. 석모도는 위의 세 산과 상봉산 북쪽으로 펼쳐진 광활한 방죽논지대, 이렇게 네 부분이 합쳐져 섬을 이루고 있다. 상봉산 동남쪽 아래 세워진 보문사는 규모도 크지만 바다를 향해 전망 좋은 곳에 위치한 관광명소로 찾는 이들이 많다. 관광을 겸할 경우 봄과 가을이 좋다.산행하면서 서해바다의 아름다운 모습을 구경할 수 있고 특히 상봉산 정상에서 서남쪽 볼음도 방향으로 바라보는 노을과 올망졸망한 섬들의 모습이 널리 알려져 있다. 정상은 암봉으로 되어 있으며, 남쪽으로 해안선과 바다, 북쪽으로 넓은 평야지대를 볼 수 있고 동쪽으로 해명산에 이르는 주능선이 잘 바라보인다. 능선 곳곳에 암벽이 자리잡고 있고 해명산에서 낙가산으로 가는 구간에는 억새풀 군락이 멋지다.", + "MNTN_HG_VL" : "316", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 삼산면 석모도", + "MNTN_NM" : "상봉산" }, - "longitude" : 126.88777779999999, - "latitude" : 36.561388899999997 + "longitude" : 126.3088889, + "latitude" : 37.694166699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "재약산은 영남 알프스 산군중의 하나로 영남 밀양 청도 일대에 위치해 있다. 해발 1,000미터 이상의 준봉들로 이루어진 재약산(사자봉)은 산세가 부드러우면서도 정상 일대에는 거대한 암벽을 갖추고 있다.125만평에 이르는 재약산 동쪽의 사자평 고원은 광할한 분지가 온통 억새풀로 뒤덮혀 있다. 우리나라에서 가장 넓은 억새벌판이다. 억새풀이 밀집해 자라는 곳만도 5만평에 이른다. 재약산은 해발 1,108m의 수미봉과 1,189m의 사자봉으로 이루어져 있다. 사자평고원은 두 봉우리 사이의 해발 800m 지점부터 완만한 타원형의 언덕들로 이어진다.사자평 억새는 어른 가슴정도 밖에 안 올 정도로 키가 작다.산아래 밭둑이나 길가의 억새에 비하면 절반밖에 되지 않는다. 잎새도 가늘고 투박하다. 꽃이삭은 거친 산정의 바람에 닳아서인지 뭉툭하고 짧다. 그래서 가는 바람에는 이삭 끝의 낭창거림을 보기 어렵다.", - "MNTN_HG_VL" : "1119", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면ㆍ산내면, 울산광역시 울주군 상북면", - "MNTN_NM" : "재약산" + "DETAIL_INFO_DTCONT" : "월악산 국립공원은 충북 제천시 한수면과 덕산면의 경계를 이루는 산으로 백두대간이 이화령을 지나 조령산, 조령, 마패봉, 부봉, 월항삼봉, 하늘재, 포암산을 거쳐 대미산으로 이어지는 중간선 북쪽에 솟아있는 봉우리이다. 넓이 373㎢에 걸쳐 있는 월악산 능선은 백두대간보다 높고 무엇보다도 바위와 암릉으로 형성되어 있어 대간에 비해 능선이 훨씬 두드러져 있다.제천시 한수면과 충주시 살미면의 경계를 이루는 지점에 자리한 월악수리봉은 일반인들에게는 생소한 이름이지만 알고보면 숨겨진 비경들이 많은 명산이다. 산행을 나선 후 곳곳에서 펼쳐지는 기암절벽의 변화무쌍함은 산악인들의 탄성을 자아낸다. 숨은 절경들은 둘러보며 정상에 오르면 어느새 월악수리봉에 대한 애정이 듬뿍 생겨 다시한번 이 곳을 찾고 싶은 마음이 절로 든다.월악산(月岳山 1095.3m) 뒤안길에는 용하구곡이 30리나 늘어서 있는데 월악시루봉은 용하구곡의 서쪽에 병풍처럼 자리한 산이다. 시루봉을 가려면 일단 덕산면을 거쳐야 한다. 덕산(德山)은 이름 그대로 산의 덕을 본다는 뜻으로 덕산면은 예부터 인삼재배 적격지로 유명하다. 산 곳곳에 빼어난 경관이 산재해 있는데 특히 전망대 바위에서의 조망이 일품이다. 전망대 바위에 오르면 서북쪽의 월악산 정상이 울부짖는 호랑이 형상을 하고 있어 보는 이의 마음을 압도하며 동쪽에는 용하구곡 건너로 하설산, 매두산, 문수봉 산릉이 아름다운 풍광을 연출하고 있다.", + "MNTN_HG_VL" : "1095", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 한수면, 덕산면", + "MNTN_NM" : "월악산" }, - "longitude" : 128.9793348, - "latitude" : 35.547564700000002 + "longitude" : 128.09096439999999, + "latitude" : 36.889304099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고흥군 금산면 거금도에 솟아있는 적대봉은 마치 바다에 떠 있는 고래등 같은 모습을 하고 있다. 녹동에서 여객선으로 20여분 정도 걸리는 거리로, 뭍과 그리 멀리 떨어지지 않은 거금도는 섬 자체가 하나의 면을 이룰 정도로 커다란 섬이면서도 멀리서 바라보면 둥그스름한 하나의 산처럼 보이기도 하다.섬 안에 큰 금맥이 뻗어 있어 거금도라 불린다는 이 섬의 한가운데 솟아 있는 적대봉은 북쪽으로 천등산, 마복산이 서쪽으로 장흥 천관산과 마주보고 있다. 섬 산이면서도 고흥군에서는 팔영산 다음으로 높아 펑퍼짐한 산세와 달리 전망이 매우 뛰어나다. 이러한 지형적 특성 때문에 조선시대에 축조된 둘레 34미터, 지름 7미터의 큰 봉수대가 정상에 있다.정상에 서면 서쪽으로 완도, 남쪽으로 거문도, 동쪽으로 여수 일원의 바다와 섬들이 한눈에 들어올 뿐만 아니라 날씨가 좋으면 멀리 제주도가 바라보일 정도로 전망이 좋다.산행은 적대봉 서쪽 능선을 가로질러 거금도 남북을 잇는 임도의 북단에 위치한 성치마을에서 시작, 파상재를 거쳐 정상에 올라 파상재로 내려선 다음 송광암을 거쳐 면소재지로 내려서는 코스가 가장 즐겨 찾는 코스다.산기슭에는 조선시대에 목장성이 있었던 것으로 알려져 있다. 거금도는 이웃한 소록도, 절제도, 시산도, 나로도와 함께 도양 목장에 속한 속장의 하나였으며 이 산을 중심으로 성을 쌓아 말 116마리를 키웠던 세납 목장이 있었다. 거금도 남북을 가로질러 석정리와 어전리를 잇는 임도 곳곳에는 아직도 목장성 흔적이 남아 있다.", - "MNTN_HG_VL" : "587", - "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 금산면", - "MNTN_NM" : "적대봉" + "DETAIL_INFO_DTCONT" : "병풍산하면 병풍을 펼쳐 놓은 것처럼 산세가 빼어난 산이 아닌지 한번쯤 생각을 하게 된다. 병성산이라고도 불리운다. 그러나 이 산이 병풍산으로 이름 붙여진 것은 산 정상에 올라서면 시야가 탁트여 마치 병풍을 펼쳐 놓은 것처럼 주변을 감상할 수 있어서 그런 듯 하다.정상부에는 삼한시대 사벌국(沙伐國)이나 그 후계 세력인 상주 지역의 실체 파악에 주요한 단서가 되는 토석 혼축의 병풍산성(또는 아자개성)이 축조되어 있고, 산 곳곳에는 삼한시대 사벌국의 고분군(古墳群:경북기념물 125)이 널려 있다. 또한 넓은 들판과 상주 시내, 낙동강과 함께 국수봉·속리산·대야산·백화산·주흘산 등이 병풍처럼 펼쳐져 있다.", + "MNTN_HG_VL" : "366", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 동문동", + "MNTN_NM" : "병풍산" }, - "longitude" : 127.1802778, - "latitude" : 34.462222199999999 + "longitude" : 128.22188180000001, + "latitude" : 36.423279399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "적상산은 사방이 깎아지른 듯한 암벽으로 이루어져 있으며, 그 절벽 주변에 유난히도 빨간 단풍나무가 많이 서식하여 가을철이면 마치 온 산이 빨간 치마를 입은 여인네의 모습과 같다 하여 붙어진 이름이다. 이 산에는 장도바위, 장군바위 등 자연 명소와 함께 최영 장군이 건의하여 축조했다는 적상산성(사적 제 146호)이 있다.이는 고려 공민왕 23년(1374) 최영 장군이 탐라를 토벌한 후 귀경길에 이 곳을 지나다가 산의 형세가 요새로서 적지임을 알고 왕에게 축성을 건의하여 건설된 것이라 한다. 현재의 성은 조선 인조6년(1628년)에 다시 쌓은 것으로서 둘레가 8.143㎞에 이른다. 적상산성 안에는 고찰 안국사 등 유서깊은 문화유적이 있어 이 곳을 찾아온 사람들에게 운치를 더해 준다.한편 고려 충렬왕 3년(1227년) 월인화상이 창건했다고 전해지는 안국사 및 조선시대 인조 21년(1643년)에 창건한 호국사도 있다.", - "MNTN_HG_VL" : "1031", - "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군 적상면", - "MNTN_NM" : "적상산" + "DETAIL_INFO_DTCONT" : "삼문산(三門山)은 전남 완도군 약산면을 이루는 조약도 최고봉이다. 조약도로 가는 뱃길은 완도가 아닌 강진군 마량에서 배를 탄다. 조약도는 지형도에 표기되어 있는 행정지명이지만, 이곳 섬 주민들은 '약산도'로 부른다. 그래서 마량나루에 정박해 있는 조약도행 배에도 ‘약산’이라 붙어 있다.삼문산이라는 이름의 유래는 이렇다. 옛날 주능선 동쪽 분지인 삼개문(일명 삼감안)에서 땔감으로 쓰는 초나무나 풀을 베어 지게에 메고 서쪽 천동나루 방면으로 넘어올 때 망봉과 등거산 사이 움먹재나 망봉과 장룡산 사이 파래밭재와 큰새밭재를 넘어다녔다. 즉 세 고개를 세 문(門)으로 보았던 것이다.평범한 육산인 삼문산에 토끼바위, 쟁기바위, 부엉이바위 같은 특이한 모양의 바위들이 변화를 꽤한다. 그러나 삼문산의 매력은 사방으로 펼쳐지는 남해 바다와 여기에 떠 있는 다도해의 그림 같은 풍경에 있다. 삼문산 봉화대는 고금진의 망덕산, 신지진의 상봉, 가리포진(현재의 완도) 상황봉, 장흥 천관산으로 봉화를 하던 송신소 같은 곳이다.", + "MNTN_HG_VL" : "397", + "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 완도읍 약산면", + "MNTN_NM" : "삼문산" }, - "longitude" : 127.6897512, - "latitude" : 35.947660200000001 + "longitude" : 126.9094444, + "latitude" : 34.381388899999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "적자봉이 있는 보길도는 다도해해상국립공원의 숨은 진주다. 해가 수평선으로 가라앉을 때 하늘과 바다를 물들이는 무지개빛 노을이 장관이다. 이처럼 찬란한 빛이 황홀경을 되쏘는 봉우리라서 ‘적자봉’이라 한다. 이 산은 남쪽에 누운 거대한 암소가 새끼를 어르듯 북으로 광대봉, 망월봉, 일락봉 등 300미터 안팎의 산들을 품고 있다. 정상 부근에는 섬회양목 등 많은 희귀식물들이 향기를 뿜고 기암괴석들이 능선을 잇는다. 멀리 해남의 땅끝과 달마산, 완도의 상황봉까지 사철 동백나무, 예덕나무, 정금나무, 곰솔 등 250여 종의 식물들이 수해를 이루어 늘푸른 산의 생기를 불어 넣는다. 가까운 예송리의 천연기념물 제40호인 상록수림과 해수욕장도 가볼 만하다.적자봉을 중심으로 광대봉, 망월봉, 일락봉이 둥근 원을 그리듯 펼쳐져 있고 안쪽으로 고산 윤선도의 적거지였던 부용동에 유적지(사적 368호)가 남아 있다. 보길도는 조선 중기의 탁월한 가객 고산 윤선도의 유배지로서 그의 체취가 물씬 풍긴다.", - "MNTN_HG_VL" : "431", - "MNTN_LOCPLC_REGION_NM" : "전라남도 완도군 보길면", - "MNTN_NM" : "적자봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "435", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남면 발산리", + "MNTN_NM" : "좌방산" }, - "longitude" : 126.5313889, - "latitude" : 34.137777799999988 + "longitude" : 127.6088889, + "latitude" : 37.720277799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군 하면과 가평읍을 사이에 두고 솟아있는 전패봉은 북으로는 명지산(1267m), 남으로는 구나무산(858m)을 등에 업고 서남쪽을 향해 매봉(929m)을 바라보고 있는 아담한 산이다. 인근 명지산의 위세와 운악산 현등사의 유명세에 가려 아직 일반에게 잘 알려지지 않았으나, 그만큼 사람들의 때가 묻지 않은 자연그대로의 숨결을 간직한 산이다. 산세가 부드러워 가족산행에 적당하다. 주능선에는 잡목과 억새풀이 어우러져 있다.이전에는 전패봉이라 하였는데, 혐오스러운 느낌을 준다는 이유로 1999년 3월 가평군 지명위원회가 우정봉으로 바꾸었고 그 아래 전패고개는 우정고개로 이름지었다. 이와 동시에 우목봉은 연인산으로, 879m봉은 장수봉으로, 구나무산은 노적봉으로 이름을 고쳤다.", - "MNTN_HG_VL" : "701", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍, 하면", - "MNTN_NM" : "전패봉(우정봉)" + "DETAIL_INFO_DTCONT" : "김otilde;쪽에서 추풍령을 넘어 황간 가까이 내려오면 1시 방향으로 하나의 커다란 배가 하늘을 떠가는 모양을 볼 수 있다. 바로 주행봉이다. 떠가는 배의 모양을 그대로 이름으로 한 것이다.속리산에서 백두대간과 헤어진 산줄기 하나가 구병산을 거쳐 팔음산(762m, 옥otilde;ucirc;산면)으로 나아가고 이 산줄기는 한껏 낮아졌다가 백화산으로 다시 일어나 933미터의 포성봉과 874미터의 주행봉을 빚어놓았다. 이 백화산은 상주의 모동면 모서면, 옥otilde;의ucirc;산면 일대의 분지 가운데 자리잡고 있기 때문에 더욱 우뚝하고 커 보인다.국토지리정보원의 지도에는 포성봉, 주행봉으로 표기되어 있다. 포성봉이라 부르는 연유는 알 수 없으나 「신증동국여지승람」과 모든 기록에 백화산으로 되어 있고 상주쪽에서는 한성봉이라 부르기도 한다. 주행봉을 현지 주민들은 “쌀개봉”이라 부른다. 주행봉의 머리를 이루는 바위 봉우리 두 개가 옛날 디딜방아의 쌀개oacute;럼 되어있기 때문이다.", + "MNTN_HG_VL" : "874", + "MNTN_LOCPLC_REGION_NM" : "충북 영동군 황간면", + "MNTN_NM" : "주행봉" }, - "longitude" : 127.4186114, - "latitude" : 37.898696600000001 + "longitude" : 127.8877233, + "latitude" : 36.278346300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 평창군과 영월군에 걸쳐 있는 절개산은 아직 일반인들에게는 덜 알려진 곳으로 산행의 발걸음이 잦지않다. 에머랄드빛 평창강이 휘감아도는 청정지역으로 산세 또한 깨끗함을 자랑한다. 정상에 노송한그루가 자리하고 있어 절개산의 최고지임을 증명한다. 동남쪽으로 영월 봉래산과 태화산등이 조망되고 날씨가 좋은 날은 멀리 소백산까지도 시야에 들어온다. 호젖한 오르막길과 갖가지 산나물이 지천으로 생명력을 자랑하는 능선길을 걷다보면 시원한 강바람이 내내 산행길을 함께 했음을 느낄 수 있다.절개산은 이름 그대로 신념이나 신의를 굽힘이 없고 변하지 않는 절개를 대표하는 산이다. 이 산 서쪽 평창강이 에돌아 깎아 세운 뼝대 위에 관굴과 민굴이라 하는 응암동굴이 있다. 임진왜란 때 여기에 배수진을 치고, 권두문 군수는 휘하 장졸, 백성들과 함께 단기 3925년, 서기 1592년 8월7일부터 5일간 응암동굴을 본부로 삼아 왜적과 혈전을 벌였던 유적지다. 또한 군수의 부인 강소사는 왜병의 포로가 될 때 절벽에서 투신, 초개와 같이 목숨을 버려 절개를 지켰다.", - "MNTN_HG_VL" : "876", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군, 영월군", - "MNTN_NM" : "절개산" + "DETAIL_INFO_DTCONT" : "금남정맥상의 운장산(1126m)이 조산인 원등산은 전북 완주군 소양면과 동상면 경계를 이루며 위봉산(524m) 서방산(612m) 안수산(554m) 동성산(550m)과 맥을 같이 하고 있다. 이 산을 중심으로 북으로는 위봉산성과 송광사, 드라이브코스로 제격인 대아저수지와 동상 저수지 호안도로가 이어져 있는데 이렇게 이름난 주변 명소에 밀려 원등산은 손타지 않은 자연을 제법 잘 보존하고 있다.원등산의 옛이름은 청량산이거니와 남녘 자락에 오랜 고찰 원등사가 자리하여 세월이 흐르는 동안 원등산으로 이름이 바뀌었다. 해발 500m에 자리한 원등사에 서면 전주 시내가 한눈에 들어온다. 정상에서는 운장산과 연석산이 보이고 연석사와 연석폭포가 있는 사봉리 협곡까지 손금처럼 훤히 내려다 보인다. 기암절벽이 산줄기 곳곳에 솟아있어 산세가 아름답고 가족이 함께 산행하기에도 좋은 곳이다.해발 500m 지점에 위치한 원등사는 1200년된 고찰로 신라 문성왕 2년 보조선사가 세웠다고 전한다. 보조선사가 사찰을 세우기 위해 그곳에서 멀리 떨어진 무주 향악 난야에서 나무로 만든 오리를 날려보냈는데 오리가 앉은 곳이 원등사였다고 한다. 이곳은 또한 도승 진묵대사가 많은 기행을 남긴 곳으로도 유명한 곳이다. 동란 때 소실된 법당은 아직도 증축하지 못한 채 터만 남아 있다. 바위를 뚫어 만든 굴속에 오백나한을 모셔 놓았는데 지금은 너와집 같은 건물에 법당을 마련하고 나한을 모시고 있다.", + "MNTN_HG_VL" : "713", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군", + "MNTN_NM" : "원등산" }, - "longitude" : 128.40283840000001, - "latitude" : 37.324562800000002 + "longitude" : 127.2937072, + "latitude" : 35.8874104 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "334", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천", - "MNTN_NM" : "절산" + "DETAIL_INFO_DTCONT" : "벽암산은 정선군 남면 별어곡과 신동읍 예미를 잇는 마차치고개가 산행 기점이다. 마차치고개 마루턱에서 서쪽으로 500미터쯤 내려간 곳에 마차치고개 식당이 있다. 북쪽 콘크리트길로 들어서 두 번째 삼거리인 광덕재에서 동쪽 능선으로 25분쯤 오르면 밭과 묘가 있는 안부에 이른다. 이 안부에서 15분쯤 올라서 840봉에 닿으면 능선이 둘로 갈라진다. 여기서 벽암산으로 가는 동쪽 능선은 보이질 않는다.벽암산으로 오르려면 눈에 잘 띄는 북릉으로 가지 말고 동쪽의 급경사를 내려서야 한다. 이내 능선이 나타나며 안부에 닿는다.정상에 오르니 작은 헬기장에는 삼각점과 작은 비닐코팅판이 걸려있고 나무들에 둘러싸여 조망은 막혀있다.하산은 정상에서 동남 쪽 능선을 따라간다. 능선 오른편으로 계곡이 세 개 갈라진다. 첫 번째 계곡이 통노구골, 두 번째가 금골, 세 번째가 절골이다. 세 번째 계곡인 절골로 내려서면 수광암에 닿는다.", + "MNTN_HG_VL" : "923", + "MNTN_LOCPLC_REGION_NM" : "강원 정선 남면", + "MNTN_NM" : "벽암산" }, - "longitude" : 127.7678485, - "latitude" : 38.119342699999997 + "longitude" : 128.68777779999999, + "latitude" : 37.277777800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한계령 오른쪽으로 보이는 점봉산은 설악산 대청봉과 남북으로 마주보며 설악산 국립공원의 일부를 이루고 있다.주요 관광명소로는 12담 구곡으로 불리는 주전골이 있는데, 좌우로 갖가지 모양의 바위봉우리, 원시림, 맑은 계곡물이 어우러져 절경을 이루며, 특히 주전골 입구의 오색약수터는 빼놓을 수 없는 관광지다. 군사지역으로 출입이 통제되고 있는 것이 안타까울 뿐이다. 지소 조금 아래쪽 안국사로 오르는 길은 돌비탈을 지나야 하고 길도 애매하므로 산행기점은 일반적으로 서창리지소를 택한다.", - "MNTN_HG_VL" : "1426", - "MNTN_LOCPLC_REGION_NM" : "강원도 양양군 서면, 인제군 기린면ㆍ인제읍", - "MNTN_NM" : "점봉산" + "DETAIL_INFO_DTCONT" : "설악산은 한라산(1,947.3m),지리산(1,915.4m)에 이어 남한에서 세 번째로 높은 산으로 강원도 속초시와 양양군,인제군에 걸쳐 있다.옛 문헌을 보면 지금의 대청봉이 있는 양양, 속초의 산만을 `설악'이라 제한하였고 귀때기청봉이 있는 인제쪽의 산을 `한계산'이라 따로 지칭했다. 그 예로 안산 남쪽 장수대 부근에 있는 한계산성이 이를 뒷받침하고 있다. 진부령에서 대청봉까지 이어지는 북주능의 백미는 뭐니뭐니 해도 수많은 암봉들로 구성된 공룡능선인데 이 코스가 바로 북주능의 등뼈 역할을 하는 공룡능선을 가장 짧은 시간에 주파할 수 있는 길이다. 이 능선은 1963년 겨울, 당시 한국의 암벽등반 선구자이던 선우증옥, 정규현, 채태웅씨 등이 처음으로 완등한 이후 산악인들로부터 각광을 받다가 최근엔 일반인들도 쉽게 할 수 있을 만큼 등산로가 잘 닦여있다.백두산에서 남쪽으로 내리뻗어 이 땅의 기나긴 등뼈를 이루는 백두대간의 허리를 받들고 있는 설악산은 북의 금강산과 남의 오대산 사이에 솟아있는 천하의 명산으로 우리나라 관광명소 1호로 꼽힌다. 지난 1965년 11월 5일 천연기념물지구(163.4㎞), `69년 관광지(16.2㎞) 그리고 '70년에는 국립공원(174㎞)으로 각각 지정되었다. 그리고 1971년 9월에는 설악산 국립공원 관리사무소가 개설 되었고 `77년 '78년 두차례에 걸쳐 354.6㎞로 확장되었으며, 그 후 다시 374㎞로 넓이를 확대하였다. 울산암 등산로 초입에 있는 신흥사는 대한불교 조계종 제3교구 본사로 설악산의 대표적 사찰이다. 신라때 자장율사가 노루목근처에 향성사로 창건했다가 조선조때 현위치에 다시 세웠다고 한다.", + "MNTN_HG_VL" : "1708", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시 설악동, 인제군 북면ㆍ인제읍, 양양군 서면ㆍ강현면", + "MNTN_NM" : "설악산" }, - "longitude" : 128.4252587, - "latitude" : 38.049280499999988 + "longitude" : 128.46555810000001, + "latitude" : 38.119550400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "평창 청옥산(1256m)을 모산으로 해 동강을 품은 산으로 자생식물이 많고 하늘을 가리는 잡목이 우거져 있는 등 천연의 모습이 잘 간직돼있다. 심마니들을 심심찮게 볼 수 있는 것도 이 때문이다.돌리네 현상으로 땅이 꺼지면서 산줄기가 겹쳐진 형상을 하고있어 근동에서는 겹산이라 부르며, 정상은 봉분처럼 생겼다하여 묘봉, 요봉이라 한다. 산행을 마치고 동강변의 비경속에서 피서를 즐기기에 적당하다. 실제 산행을 하다보면 심밭굼이라 하는 움푹 꺼진 곳은 숲이 무성한 긴 계곡으로 나타난 난해한 지형이다.", - "MNTN_HG_VL" : "823", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군", - "MNTN_NM" : "접산" + "DETAIL_INFO_DTCONT" : "금수봉은 계룡산 천황봉에서 뻗어나온 산줄기가 민목재를 지나서 백운봉(535.5m)에서 두갈래로 갈라져 오른쪽에 금수봉을 왼쪽에 도덕봉을 빚어 놓았다. 이 같은 명산의 정기를 이어받은 금수봉은 정상 에 올라서서 사방을 내려다보면 주위의 풍경이 비단에 수를 놓은 것 같다고 하여 금수봉이라고 부른다.대전의 금수봉은 이름 그대로 아름다운 산이다. 맑은 개울이 있고 짙은 숲이 있으며 아기자기한 바위등성이가 있다.봄에는 꽃이 아름답고 가을에는 단풍이 곱다. 금수봉 바로 옆의 봉우리 이름은 '백운봉'이다. 금수봉과 백운봉 고운 이름을 가진 두 산이 한 곳에 있는 곳은 우리나라에서 여기뿐일 것이다.금수봉은 큰암벽이 없이 우거진 수림으로 감싸고 있어 초여름 비단같은 신록에 산꽃이 수를 놓은듯이 박힌 아름다운 산으로 유성구에서 수통골 계곡에 레포츠 공원을 조성하여 놓아 시민들이 많이 찾고 있다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 유성", + "MNTN_NM" : "금수봉" }, - "longitude" : 128.4891374, - "latitude" : 37.265738200000001 + "longitude" : 127.2811111, + "latitude" : 36.328888900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정각산은 경남 밀양시 단장면 한적한 곳에 자리 잡고 있다. 삼각산(887m)과 인접해 있으며 말발굽형상으로 연결되어 있는 이 산에는 유독 묘(墓)들이 눈에 띄게 많다. 그만큼 풍수지리상 좋은 자리를 차지하고 있다는 설이 있다. 대신 등산객들은 찾아 보기 어렵고 발길 닿지 않은 자연림의 형태를 잘 보존하고 있는 곳이다.정상 가까이에 묘(墓)가 많이 있으며, 이웃한 삼각산(887m)과 말발굽 모양으로 이어져 있다. 산행은 표충사에서 4Km 떨어진 범도리 아불마을에서 시작하여 정상에서 능선을 따라 삼각산을 마주보고 내려가다가 송백리로 빠져 내려온다. 산 아래로 남천이 남서쪽으로 흐르며, 산 동쪽 재약산(1108m) 자락에는 신라 진덕여왕 8년 원효대사가 창건한 표충사가 있다. 표충사에는 청동함은향완(국보 75), 삼층석탑(보물 467), 석등(경남유형문화재 14), 표충서원(경남유형문화재 52) 등의 유물이 남아 있다.", - "MNTN_HG_VL" : "860", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 단장면", - "MNTN_NM" : "정각산" + "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다.", + "MNTN_HG_VL" : "456", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군, 강진군", + "MNTN_NM" : "월각산" }, - "longitude" : 128.90484180000001, - "latitude" : 35.547757799999999 + "longitude" : 126.6819335, + "latitude" : 34.721094600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "상림2리 다리 앞에서 차도 따라 서쪽으로 나가다 계곡 갈림길과 만나면 오른쪽 계곡길로 들어 교회 앞을 지나 15분쯤 올라간 갈림길에서 왼쪽 계곡기로 급경사를 올라가게 된다. 차츰 왼쪽 지능선으로 붙어 올라가게 되고 능선 따라 노고봉에 이른다.왼쪽(남)능선길로 들어 잠시 내려갔다가 올라가면 정광산 정상이고 남릉 따라 3개의 봉우리를 넘어선 안부에서 왼쪽(동)계곡길로 들어선다. 계곡 아래 내려서면 시어골이고 차도 따라 상림2리 다리 앞이다.", - "MNTN_HG_VL" : "563", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 모현면", - "MNTN_NM" : "정광산" + "DETAIL_INFO_DTCONT" : "칠보산은 충북 괴산군 칠성면과 장연면의 경계를 이루는 산으로, 쌍곡계곡을 사이에 두고 군자산과 마주보고 있다. 칠보는 불교의 무량수경이나 법화경에 나오는 일곱가지 보배인 금, 은, 파리, 마노, 기거, 유리, 산호를 뜻한다고 한다.산의 규모는 작지만 기암괴석이 곳곳에 널려 있고, 고사목과 노송이 암봉과 조화를 이루어 한폭의 동양화를 보는 듯 하다. 이 산은 송이버섯 산지로 유명하며, 또한 칠보산에 오르는 길목에는 신라시대에 창건하였다는 고찰 각연사가 자리잡고 있다. 이 사찰에는 보물 제 433호인 석조비로 사나불좌상, 통일대사탑비 등이 있어 관광 코스로도 손색이 없는 곳이다. 정상에 서면 북쪽 아래로 각연사와 청석골 계곡이 보이고, 동북쪽으로는 덕가산과 희양산이, 서북쪽으로는 쌍곡계곡과 군자산이 가깝게 보인다.", + "MNTN_HG_VL" : "778", + "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 청안면", + "MNTN_NM" : "칠보산" }, - "longitude" : 127.2812524, - "latitude" : 37.323208899999997 + "longitude" : 127.67984060000001, + "latitude" : 36.771560800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정승골은 신라때 어느 왕이 병을 고치기 위해 재약산 표충사에 머물고 있을 때 수행한 정승이 이곳에 머물며 대기했다고 전해져와 붙여진 이름이다.산행 들머리는 밀양 산내면 남명리 남명초등학교 앞이다. 이곳은 하양마을이나 삼양마을을 거쳐 바로 운문산으로 갈 수 있고, 천황산이나 백운산 정족산 구천산 억산 등 영남알프스의 웬만한 봉우리로 손쉽게 접근 가능해 산꾼들은 흔히 이곳을 영남알프스의 '베이스 캠프'라 부른다. 정승봉에 오르면 시원한 바람에 마음의 문까지 활짝 열린다. 성장에는 표지도 없고 좁아서 몇몇 사람이 서 있기에도 마땅치 못하나, 조망은 뛰어나다.", - "MNTN_HG_VL" : "803", - "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양군 산내면", - "MNTN_NM" : "정승봉" + "DETAIL_INFO_DTCONT" : "강원도 삼척시 가곡면에 자리한 치바위산은 사금산에서 남향으로 뻗어나간 지능선상의 최고봉이다. 산을 올려다보면 산꼭대기의 바위들이 `키'처럼 보이는데 `키'의 방언이 `치'이기 때문에 치바위산이라 불리게 되었다. 서쪽으로 낙동정맥 마루금에 솟아 있는 백병산(1259m)과 복두산(978m)을 마주보고 있어 신리에서 풍곡으로 이어진 도화천협곡의 장관을 감상할 수 있다. 남서쪽으로 토산과 면산자락에 가곡자연휴양림이 조성되어 있고, 남쪽으로는 유명한 용소골이 길게 패여있으며 주위로 벼락바위봉과 범바위봉, 중봉산이 자리잡고 있다.치바위산은 크게 두 개의 봉우리로 나누어진다. 하나는 동활리쪽 835m봉으로 `동활 치바위'라 부르고 이곳에서 동쪽 오저리 방면으로 분기한 780m봉을 `오저 치바위'라 부른다.", + "MNTN_HG_VL" : "835", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", + "MNTN_NM" : "치바위산" }, - "longitude" : 128.90484180000001, - "latitude" : 35.547757799999999 + "longitude" : 129.17500000000001, + "latitude" : 37.154166699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남한강과 남한강의지류인 경안천 사이에 솟아있는 산으로 팔당댐을 기준으로 하면 왼쪽인 북쪽의 양수리에서 북한강과 남한강이 합류하고 남쪽인 광주쪽에서 남한강의 경안천이 흘러드는 광주군 초월면 방향으로 팔당댐이 깊숙이 파고 든다.4백미터 남짓한 나지막한 산으로 별로 눈에 띄지 않는데다 교통도 그리 좋은 편이 아니라 찾는 이들은 그리 많지 않다. 하지만 막상 산을 찾아가면 주변 일대에 풍기는 강촌의 향취와 정상에서 내려다 보는 한강의 풍경에 감탄한다. 남북한강이 어우러지는 양수리 부근에 빼꼼히 솟아 오른 정암산은 한강을 발아래 두고 오르는 산행의 묘미가 일품이다.주변에 신라 문무왕(文武王) 때 쌓은 주장성(晝長城)의 옛터를 활용하여 1624년(인조 2)에 축성한 남한산성(사적 57)이 있다.", - "MNTN_HG_VL" : "403", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 남종면", - "MNTN_NM" : "정암산" + "DETAIL_INFO_DTCONT" : "세종식록지리지에 상주 삼명산의 하나라고 했을 정도로 빼어난 산세를 가지고 있다. 그래서 속리산이 아니면서도 속리산국립공원의 남쪽 경계에 포함되었다. 지금은 거의가 보은군 땅이다.25번 국도를 타고가다 보면 금방 눈에 띄다. 군계일학인 까닭이다. 자락에는 시루를 엎어놓은 듯한 봉우리까지 있어 정말 신령스런 산이라는 생각이 들게 한다. 그래서인지 구령산(九靈山)이라고도 했다. 구병산은 충북 보은군과 경북 상주군의 속리산 국립공원 남쪽 국도변에 자리잡고 있다.예로부터 보은 지방에서는 속리산의 천황봉은 지아비 산, 구병산은 지어미 산, 금적산은 아들 산이라 하여 이들을 '삼산'이라 일컫는다. 속리산의 명성에 가려 일반인에게는 잘 알려져 있지 않아 산 전체가 깨끗하고 조용하며 보존이 잘 되어 있는 편이다. 보은군청에서는 속리산과 구병산을 잇는 43.9km 구간을 1999년 5월 17일 '충북 알프스'로 업무표장 등록을 하여 관광상품으로 널리 홍보하고 있다. 6·25전쟁 때 폐허가 된 토골사 터가 있고 절 터 앞뒤로 수백년 생의 참나무들이 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 충청북도 보은군 마로면ㆍ속리산면", + "MNTN_NM" : "구병산" }, - "longitude" : 127.34154669999999, - "latitude" : 37.514297800000001 + "longitude" : 127.8616372, + "latitude" : 36.469489500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정족산은 산의 생김새가 마치 세 발 달린 가마솥과 같다고 해서 이름 붙여진 산이다. 정족산에는 단군이 세 아들을 시켜 쌓았다는 삼랑성이 있다. 일명 정족산성이라고도 하는 삼랑성은 사적 제130호의 돌성이다. 성의 시설물로는 남문루와 동문, 서문, 북문지가 있고 성 안에는 13개의 우물이 있었다고 전하며 고구려시대에 창건된 전등사가 있다.전등사는 이 삼랑성안에 있는 사찰이다. 고구려 소수림왕 11년(372) 아도화상이 진종사(眞宗寺)라 이름한데서 시작되었다.\"\"신증동국여지승람\"\"에 의하면 충렬왕 8년(1282) 왕의 원비인 정화궁주 왕씨가 승려 인기(印奇)에게 송나라에 들어가 대장경을 가져오게 하여 이 절에 보관했다고 한다. 전등사라는 이름은 정화궁주가 불전에 옥으로 된 등잔을 올린 뒤 붙여진 이름이다. 특히 정족산에는 `조선왕조실록'을 보관했던 사고터가 남아 있어 유적답사 및 가족산행을 하기에 가장 적합한 곳이다.산행은 전등사에서 시작된다. 전등사의 요사채 뒤로 난 길을 곧바로 올라가면 정상에 닿을 수 있다. 정상에서는 나무에 둘러싸인 전등사의 고풍스러운 모습과 마니산과 서해바다의 모습을 한눈에 바라 볼 수 있다.", - "MNTN_HG_VL" : "200", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 길상면", - "MNTN_NM" : "정족산" + "DETAIL_INFO_DTCONT" : "호남의 금강이라 부르기에 손색이 없는 대둔산은 충남 논산시와 금산군, 전북 완주군 등 3개군에 걸쳐 있다. 최고봉인 마천대를 중심으로 기암괴석들이 제각기 위용을 자랑하며 늘어서 있다. 대둔산은 두 얼굴을 가지고 있다. 기경의 절벽을 이루는 전북 완주쪽과 순후한 시골아낙 같은 충남 논산,금산쪽이 바로 그것이다.바랑산은 그리높지 않은 산임에도 월성봉까지 이어지는 능선은 보기드문 절경을 자랑한다. 잘 닦인 등산로를 가지고 있으면서도 깨끗한 주변환경을 유지해 쾌적함속에 산행을 즐길 수 있는 곳이다.바랑산은 다리성 서쪽에 있고 모양이 바랑과 같이 생겼다 하여 붙여진 산명이며, 노승예불현의 명당이 있다.등산로 역시 양쪽 지형이 상반되는 것 만큼이나 특성이 뚜렷이 구분된다.", + "MNTN_HG_VL" : "555", + "MNTN_LOCPLC_REGION_NM" : "충청남도 논산시", + "MNTN_NM" : "바랑산" }, - "longitude" : 126.4802778, - "latitude" : 37.6325 + "longitude" : 127.27, + "latitude" : 36.130000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "제비봉은 충북 단양군 단양읍에서 서쪽인 충주호 방면으로 약 8km 거리인 장회리에 위치한 산으로, 단양팔경의 절정인 구담봉과 옥순봉에서 서남쪽 머리위로 올려다 보이는 바위산이다.유람선을 타고 구담봉 쪽에서 이 산을 바라보면 충주호를 향해 부챗살처럼 드리워진 기암괴봉과 바위능선이 마치 제비가 날개를 활짝 펴고 나는 듯한 형상을 갖추고 있다하여 제비봉이라 이름 붙여졌다 한다. 충주호 건너편 금수산도 단풍이 빼어나지만 바위산과 어우러진 제비봉의 단풍은 더욱 장관인데, 특히 정상에서 조망은 북쪽 발 아래로 충주호의 그림같이 시원한 경치가 보이고 그 뒤로 금수산이 우뚝 솟아 있으며 동쪽 멀리 소백산 연능이 스카리라인을 이루고, 서북쪽 아래로 단양팔경중 으뜸인 구담봉과 옥순봉이 인접해 있어 손에 잡힐 듯 하다. 이들 경치를 구경하며 산행의 묘미를 실컷 만끽할 수 있음은 물론이다.", - "MNTN_HG_VL" : "721", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 단성면", - "MNTN_NM" : "제비봉" + "DETAIL_INFO_DTCONT" : "경기도 이천의 도드람산은 높이도 보잘 것 없고 코스도 짧다. 하지만 능선 전체가 암석으로 이뤄져 바위타는 재미에 있어서는 수도권 산 가운데 으뜸이다. 등산 동호인들의 말을 빌리자면 '바위맛'이 좋은 산이라고 한다. '바위맛'이란 발뿐 아니라 손을 이용해 바위 뿌리 등을 잡고 가는 등산로의 아기자기함을 뜻하는 은어이다.'이천의 소금강'이라 불리는 도드람산은 일명 저명산(猪鳴山)이라고도 부른다. 저명산의 한문 표기의 '돗 저''울 명'의 돗울음산이 변하여 도드람산으로 부르게 된 것으로 전해지고 있다산 중턱에 있는 영보사 뒷편 절벽 아래서 샘솟는 차고 시원한 석관수의 맛이 일품이며,능선을 따라 바위를 오르는 등산객의 아기자기함이 산행의 묘미를 만끽하게 해준다.", + "MNTN_HG_VL" : "349", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 마장면", + "MNTN_NM" : "도드람산" }, - "longitude" : 128.25608639999999, - "latitude" : 36.926274999999997 + "longitude" : 127.39193779999999, + "latitude" : 37.266356700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "순천의 제석산은 호남정맥에서 갈려져 남쪽으로 흘러내린 금전산과 오봉산 줄기의 끝자락에 위치한 산이다. 행정구역상 순천에 속해있긴 하지만 벌교 사람들은 벌교의 제석산이라고 부른다. 그럴만한 것이 벌교 어디서든 고개만 들면 보이는 곳이 제석산이기 때문이다. 능선에 올라서면 넓은 낙안벌과 순천만으로 이어지는 벌교 앞바다가 훤히 내려다보이는 전망이 특히 뛰어난데, ‘제석’은 하늘에 있는 33개의 하늘 중 가장 마지막에 있는 하늘인 도리천에 있으면서 모든 하늘을 다스리는 제석천왕을 뜻하는 불경에 나오는 이름이다.한편 벌교란 지명은 뗏목으로 잇달아 만들어 놓은 다리를 뜻하는 말로, 예전 이곳에는 벌교천을 가로지르는 뗏목다리가 있어서 벌교란 지명이 생겼다고 한다. 하지만 이 다리가 무너지고 이후 보물 304호로 지정된 홍교가 건설되었다고 한다.제석산과 벌교는 조정래의 대하소설 「태백산맥」의 주무대가 되는 곳으로 곳곳에 그 자취를 발견할 수 있어 산행뿐 아니라 문학탐방으로도 그 가치가 높다고 할 수 있다.정상에는 1995년 벌교의 제석산악회에서 세운 표지석이 있다. 이곳 행정구역이 벌교가 아닌 순천임에도 벌교에서 표지석을 세운 이유는 그만큼 벌교 사람들이 이곳을 많이 찾는다는 것이다.", - "MNTN_HG_VL" : "560", - "MNTN_LOCPLC_REGION_NM" : "전남 순천시 별량면, 보성군 벌교읍", - "MNTN_NM" : "제석산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "325", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "장군산" }, - "longitude" : 127.36750000000001, - "latitude" : 34.869166700000001 + "longitude" : 127.7175, + "latitude" : 34.748055600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "평창군 도암면, 성산면 어흘리와 왕산면 왕산리 사이에 있는 높이 841m의 산이다. (구)대관령 휴게소에서 1시간가량 오르면 정상에 오를 수 있다. 정상에서 상제민원(옛길 주막터)방향은 내리막길의 연속으로 지세는 급,완경사지로 이루어져 있고 지형적으로는 능선을 따라 이동하면서 자연스럽게 계곡으로 이동하게 되고 대관령박물관 옛길 코스에서도 오를 수 있다.대관령 능선의 어디에서나 강릉 시가지를 볼 수 있지만 제왕산성에서 내려다 보는 강릉 시가지는 특별하다. 시야에 막힘이 없어 시원하고도심의 모습과 바다로 흐르는 남대천의 흐름까지를 전부 조망할 수 있다.소요 시간 :2시간정도최적 탐방 시기 :매년 음력 5월 5일에는 단오제가 열리고, 10월에는 율곡제·무천제가 열린다. 하지만 4계절 모두 경치가 좋음명소 : 국사성황당 및 산신각, 신재생에너지전시관, 양떼목장, 대관령박물관볼거리 : 산세가 완만하며 상제민원의 계곡이 뛰어나고, 참나무숲과 낙엽송이 우거진 수풀이 곳곳에 있다.평창군 도암면과 강릉시 성산면 경계에는 선자령이 있고, 북쪽으로 영동고속도로를 사이에 두고 대관령 및 오대산국립공원과 마주본다.숲길 명소 : 강릉영림서의 임간학교가 제왕산 계곡에 있어 삼림욕을 즐길 수 있고, 어흘리에 대관령 박물관이 있어 옛 얼을 느껴 볼 수 있다.백두대간의 한구간으로서 능경봉과 선자령구간을 탐방할 수도 있으며 뛰어난 조망점을 자랑하고 있다.", - "MNTN_HG_VL" : "841", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 성산면", - "MNTN_NM" : "제왕산" + "DETAIL_INFO_DTCONT" : "완주군 동상면과 진안군 주천면 경계에 자리한 장군봉은 등산객의 발길이 드물어 등산로가 희미하고 표지기도 거의 없는 산이다. 이 산은 슬랩 등반, 침니 등반, 줄타기 등의 교육장으로 활용할 수 있을 정도로 다양하고, 숲도 좋고 계곡이 짧은 거리에서 험하기는 하나 진입로에는 우리나라에서 네 번째로 크고 아름다운 대야저수지와 동산저수지가 있으며, 산길에는 쇠사다리 하나 설치되어 있지 않아서 더더욱 좋다.등산지로는 전북 어느 산과 견주어도 손색이 없는 이 산이 옛 모습대로 깨끗하게 유지되고 있는 것은 눈에 잘 뜨이지 않는 오지에 있기 때문이며, 산 정상에서 내려다보는 암석의 아름다움은 누구나보아도 매료당할 정도이다.", + "MNTN_HG_VL" : "735", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면, 진안군 주천면", + "MNTN_NM" : "장군봉" }, - "longitude" : 128.78527779999999, - "latitude" : 37.687777799999999 + "longitude" : 127.34527780000001, + "latitude" : 35.9697222 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "높이 887m의 비교적 낮은 산인 조계산은 1979년 12월 도립공원으로 지정되었는데, 산세가 부드럽고 아늑한 것이 특징이다. 산 속 깊은 계곡에는 젖줄과 같은 맑은 물이 흐르며, 만수봉과 모후산이 송광사 일대를 병풍처럼 둘러싸고 있어 마치 어머니 품처럼 포근함을 느낄 수 있다. 전국 3대사찰의 하나인 송광사와 고찰인 선암사가 주능선을 중심으로 동서에 자리하고 선암사 계곡을 흐르는 동부계곡은 이사천으로 남부계곡은 보성강으로 흘러들게 된다.선암사 둘레에는 월출봉, 장군봉, 깃대봉, 일월석 등이 줄지어 솟아있어 장관을 연출한다. 조계산 산행은 송광사나 선암사 어느 쪽에서 시작해도 비슷한 시간대에 다양한 코스를 즐길 수 있으며, 산세가 험하지 않고 평탄한 길이 많아 연인끼리 또는 가족단위 소풍코스로도 알맞다. 송광사 3대 명물중의 하나인 800년이 넘은 천연기념물 쌍향수도 이곳을 찾아오는 사람들의 눈길을 끌고 있다.", - "MNTN_HG_VL" : "887", - "MNTN_LOCPLC_REGION_NM" : "전라남도 순천시 승주읍ㆍ송광면", - "MNTN_NM" : "조계산" + "DETAIL_INFO_DTCONT" : "백석산은 이승복 생가터와 방아다리약수가 있는 계곡을 구분하는 능선이 속사리재를 지나 솟아오른 산 중의 하나로 계방산과 이웃해 있다. 이 산의 주능선은 넓은 초원지대를 이루고 있으며 주능선에서 사방으로 계곡이 펼쳐져 있어 자연 그대로의 계곡미를 간직한 산이다.산 정상에 흰 바위가 있어 백석산이라고 부르게 되었다고 전해지며, 백석산 정상 평지에는 깃대봉이 세워져 있고 서편은 기암 절벽이며 동쪽으로는 가리왕산이 손에 잡힐 듯 가깝게 보인다. 정상 남쪽 마랑치에서 서쪽으로 돌아 들어가면 암봉 밑에 영암사가 있는데 100여 년 전 산삼을 캐기 위해 지은 산막이 사찰로 변하게 된 것이라고 한다.", + "MNTN_HG_VL" : "1365", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 대화면, 진부면", + "MNTN_NM" : "백석산" }, - "longitude" : 127.31361099999999, - "latitude" : 35.002499999999998 + "longitude" : 128.51604320000001, + "latitude" : 37.539788799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "조계산으로 이름하기 이전에 이 산에 나무하러 간 농부가 넘어져 죽어 원통하다 하여 원통산이라고도 하였고 산이 조개처럼 생겼다하여 음차(音借)하여 조계산이라 한다. 문화 유적으로 불대사터, 무애암 등이 있다.", - "MNTN_HG_VL" : "473", - "MNTN_LOCPLC_REGION_NM" : "", - "MNTN_NM" : "조계산" + "DETAIL_INFO_DTCONT" : "태안읍 사무소 뒤에 우뚝 솟아있는 백화산은 전설에 많은 명산으로서 주민들의 사랑을 받고 있는 아름다운 산이다. 팔봉산(362m)에서 서쪽으로 가지를 내려 태안 읍내를 품에 안은 백화산은 284미터의 작고 아담한 산이다. 그러나 서해안 인근의 산들이 대부분 단순한 육산인 반면 백화산은 온갖 수석을 모아놓은 듯 기기묘묘한 바위가 서해 바다를 배경으로 펼쳐져 아름다운 풍광을 선사한다. 산에는 기암괴석들이 많고, 바위들과 소나무가 어우러져 있고, 특히 산 정상에서 바라보는 일몰은 최고의 경관이다.백화산에는 서해 낙조를 즐기기 안성맞춤인 전망대가 있다. 시야가 트여 서해 경치가 한눈에 들어와 산행의 피로를 말끔히 가시게 해주는 이곳은 이름도 낙조봉. 정상 남쪽에 자리한 낙조봉은 변산 낙조대의 일몰에 뒤지지 않을 아름다운 조망을 제공한다.태안읍 백화산 태을암 동편 30m지점의 거암에 부조된 삼존불상(1좌3신)으로 좌우여래 입상과 중앙에 보살입상을 배치 조각했는데 크기는 중앙보살입신상이 223cm이며, 좌우여래상은 306cm, 296cm 좌우를 크게 배치한 점이 특이하다. 굳게 다문 입술가는 오히려 미소를 머금고 두 어깨에 걸친 옷자락은 양팔에 걸쳐 평행곡선으로 길게 주름진 첨단이 삼각형으로 변형된 것은 고대에 즐겨 사용된 중국 육조시대양식과 흡사하다.이같은 조각 양식으로 보아 6세기초(백제시대)작품으로 추정되는 우리나라 마애삼존불의시초이며 백제 마애석불 미술의 발상지임을 말해주는 작품이다.", + "MNTN_HG_VL" : "284", + "MNTN_LOCPLC_REGION_NM" : "충청남도 태안군 태안읍", + "MNTN_NM" : "백화산" }, - "longitude" : 127.31361099999999, - "latitude" : 35.002499999999998 + "longitude" : 126.30255699999999, + "latitude" : 36.767481500000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1189", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면 대기리", - "MNTN_NM" : "조고봉" + "DETAIL_INFO_DTCONT" : "명봉산은 작지만 오밀조밀한 맛이 있다. 능선에는 노송이 많고 때묻지 않은 채 유지되고 있으며, 산길은 점토질이 많아 걷는 촉감이 매우 좋고 포근한 분위기에 젖게 하는 매력적인 산이다.시골집 같이 정겨운 분위기의 염불암, 원시림처럼 우거져 침침하기까지 한 북릉의 숲, 신선과 사람이 바둑을 두었다는 신선바위, 수량이 풍부해 보기만 해도 시원한 계곡, 수령이 500년 가까이 된 커다란 느티나무 등이 곳곳에 흩어져 있어 이것들을 둘러보노라면 산에 오르내리는 일이 지겹거나 힘들지가 않다.", + "MNTN_HG_VL" : "599", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 문막", + "MNTN_NM" : "명봉산" }, - "longitude" : 128.7668238, - "latitude" : 37.564401699999998 + "longitude" : 127.8568085, + "latitude" : 37.297361400000007 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "조령산은 경북 문경시와 충북 괴산군을 나누는 백두대간 마루능선을 이루는 산의 하나다. 충북과 경북에 걸쳐 있는 이화령과 조령3관문 사이에 위치하고, 산림이 울창하며 대암벽지대가 많아 기암괴봉이 노송과 어울려 한폭의 그림을 보는 것과도 같이 아름답다. 문경새재를 허리춤에 안고 있는 조령산은 산보다 재가 더 유명하다.이화령(큰세재)에는 휴게소와 대형 주차장이 있고, 북쪽 구새재는 조령 제 3관문(조령관)이 있으며 관문 서편에는 조령산 자연 휴양림이 조성되어 있어 여러사람이 찾아와도 부담이 없다. 주능선 상에는 정상 북쪽으로 신선봉과 치마바위봉을 비롯 대소 암봉과 암벽 지대가 많아 산의 웅장한 면모를 느낄 수 있고, 능선 서편으로는 수옥 폭포와 용송골, 절골, 심기골등 아름다운 계곡이 있어 여름철 산행으로 그만이다.", - "MNTN_HG_VL" : "1025", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 경상북도 문경시 문경읍", - "MNTN_NM" : "조령산" + "DETAIL_INFO_DTCONT" : "봉래산의 가장 높은 봉우리를 조봉(祖峰)이라 하고, 그 다음의 봉우리를 자봉(子峰), 그 아래의 것을 손봉(孫峰)으로 부르고 있다. 가까이 보면 세 봉우리의 구별이 잘되지 않지만 멀리서 바라보면 굽이진 봉우리의 낮아진 모습이 확연하게 드러난다.산 전체가 원추형이며 산록의 사면은 가파른 편이다. 특히 남쪽 사면은 급경사로 바다에 거의 내리박듯 수직으로 돌입한다. 산기슭에는 기계적 풍화작용에 의해 쪼개진 바위가 점점이 흩어져 있다.봉래산은 원래 동쪽바다 한 가운데 있어서 신선이 살고 불로초와 불사약이 있다는 상상속의 영산이다. 봉황이 날아드는 산이라는 의미로 영도의 중심에 위치하고 있다.봉래산에는 두 가지 속설이 있다. 봉래산은 지세가 마치 아늑한 어머니의 품같은 형상을 하고 있어 자식들인 이곳 주민이 어머니 품을 떠나면 못 살게 된다는 설, 또 봉래산 산신령이 욕심이 많아 영도로 들어오는 것을 좋아하나 밖으로 떠나는 것을 싫어해 이 곳 주민들이 영도를 떠나면 좋지 않다는 설이다. 이런 것들은 속설에 지나지 않고 영도 사람들은 유달리 인정이 많아 이곳에서 한평생을 사는 사람이 많다는데서 유래된 듯하다.", + "MNTN_HG_VL" : "395", + "MNTN_LOCPLC_REGION_NM" : "부산광역시", + "MNTN_NM" : "봉래산" }, - "longitude" : 128.04363900000001, - "latitude" : 36.770401 + "longitude" : 129.0552017, + "latitude" : 35.081954600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 양양군에 있는 조봉은 암반과 숲이 연출하는 풍광이 설악산을 방불케하는 숨겨진 명산이다. 이웃한 명소 미천골이 사람들의 발길을 모두 몰아가버린 덕분에 조봉은 천연 그대로의 풍광을 고스란히 보존하고 있다.산행기점에서 조금만 오르면 벽실골이 나오는데 이곳은 굴피밭골, 큰북골 등 모두 여섯 가닥의 지류가 나뉘어지는 곳으로 비선대에서 대청봉 턱밑까지 뻗은 천불동보다 조금 짧은 계곡이다. 벽실골은 하류보다 상류쪽 경관이 한층 돋보인다. 설피밭골을 거쳐 큰북골 입구를 지나면 골이 갑자기 좁아지며 널찍한 암반과 와폭 등이 이어지는데 연이어진 폭포의 절경이 마치 설악산의 12선녀탕을 연상케 한다. 12탕보다 수량은 적으나 대신 서슴없이 물줄기를 거슬러 올라가는 재미를 만끽할수 있다.", - "MNTN_HG_VL" : "1182", - "MNTN_LOCPLC_REGION_NM" : "강원도 양양군", - "MNTN_NM" : "조봉" - }, - "longitude" : 128.56027779999999, - "latitude" : 37.945 + "DETAIL_INFO_DTCONT" : "각화산은 태백산 남쪽 15Km 지점 경북 봉화군 춘양면 석현리에 위칙하고 있으며, 가을에는 정상을 오르는 등산로에 단풍이 곱게 물들어 많은 사람들이 찾는다.각화산이란 명칭은 시라 문무왕 16년 (676년)원효대사가 춘양면 서동리에 있던 람화사(覽華寺)를 이 산자락 밑으로 이전한 뒤 생각\"각\"자로 바꿔 부른데서 기인한다. 이 람화사에는 보물 52호로 지정된 3층 석탑이 있으며, 각화사에서 2Km 떨어진 곳에는 조선왕조실록을 보관하던 조선 5대사고 가운데 하나인 태백산고지지(사적348호)가 위치하고 있으며 산림이 무성하여 찾기가 힘들고 오전에 등반해야 하산을 할 수 있다.", + "MNTN_HG_VL" : "1176", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 춘양면", + "MNTN_NM" : "각화산" + }, + "longitude" : 128.9002778, + "latitude" : 37.009999999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "조비산은 처인구 백암면 용천리,석천리,장평리에 접해 있는조그마한 돌산이다. 새가 날아가는 형상같다하여 조비산이라 부른다하며 산향이 한양도(漢陽都)를 등지고 있다하여 역적산 즉 적비산이라 부른다. 용인팔경의 하나인 조비산은 동국여지지 죽산현편에 보면현 북쪽 십오리에 한 봉우리가 돌연 우뚝 솟아 돌을 이고있는데 산이 높고 가파라서 빼어난 모양이 기이 하게 보인다.", - "MNTN_HG_VL" : "260", - "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 백암면", - "MNTN_NM" : "조비산" + "DETAIL_INFO_DTCONT" : "전국 8대 명산의 하나로 알려진 나주의 금성산은 동쪽의 노적봉(露積峰), 서쪽의 오도봉(悟道峰), 남쪽의 다복봉(多福峰), 북쪽의 정녕봉(定寧峰) 등 4개의 봉우리로 이루어져 있다. 금성산은 예부터 군사요충지였으며 현재도 군사보호지역으로 묶여있다. 금성산에는 1011년 고려 현종이 거란족의 침입을 피해 10여일 머물렀던 금성산성의 흔적이 남아있다.또한 고려시대부터 국가에서 산신제를 지냈던 영산으로 매년 봄, 가을이면 나주뿐만 아니라 전국 각지에서 사람들이 모여들어 한 해의 풍년과 태평함을 기원하였던 곳이기도 하다. 특히 금성산에는 5개의 사당이 있었는데, 산 정상에는 상실사(上室祠), 중턱에는 중실사(中室祠), 산 기슭에는 하실사(下室祠)와 국제사(國際祠)가 있었으며, 금성산성 안에는 이조당(爾朝堂)이 있었지만 현재는 모두 소실되었다. 금성산 주변은 요즘도 도처에서 치성을 드리기 위해 찾아온다.현재 정상부는 군사보호지역으로 산행이 불가능하지만, 1월 1일에는 해맞이 행사를 개최하고 일반인들이 올라갈 수 있다.", + "MNTN_HG_VL" : "451", + "MNTN_LOCPLC_REGION_NM" : "전남 나주시 경현동 대호동", + "MNTN_NM" : "금성산" }, - "longitude" : 127.3672222, - "latitude" : 37.118888900000002 + "longitude" : 126.6972222, + "latitude" : 35.055 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "857", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 재산면 동면리", - "MNTN_NM" : "조산봉" + "DETAIL_INFO_DTCONT" : "기룡산은 화북면과 자영면을 경계 짓는 산으로, 일반인에게는 그리 알려지지 않은 관계로 아직은 때 묻지 않은 능선을 따라 호젓하게 산행을 즐길 수 있는 산이다. 정상에서 남쪽으로 3.3킬로미터 떨어진 고깔산과 연계해 능선을 이을 수 있으며 남쪽 아래 영천댐(자양호)의 시원하고 넓은 호수를 굽어보는 맛은 일품이다.북쪽 보현산 천문대를 건너다보며 정상 서릉을 따라 이어지는 아기자기한 암릉을 오르내리는 길은 기룡산의 백미라 할 수 있다. 정상 남쪽 아래에는 신라천년 고찰인 묘각사가 있고 기룡산이란 이름도 이 묘각사를 창건할 당시 동해 용왕이 의상대사에게 설법을 청하고자 말처럼 달려왔다는데서 연유한 이름이라 한다.기룡산 정상 부근은 조망 즐기기에 좋은 암릉으로 되어 있으며 정상에는 무인산불감시카메라와 2000년 해맞이기념비가 있다. 탑전리 너머로 천문대가 자리하고 있는 보현산과 면봉산이 보이며 동쪽으로는 낙동정맥 산줄기를 따라 운주산과 침곡산이 있다. 서쪽으로는 방가산과 봉림산, 화산이 산줄기를 이으며 자리잡고 있다.영천호에서 고깔산을 따라 기룡산까지 이어지는 능선은 마치 승천을 기다리는 잠룡의 모습처럼 그 산세가 웅장하고 정상의 산불감시탑은 용의 뿔처럼 보인다.", + "MNTN_HG_VL" : "875", + "MNTN_LOCPLC_REGION_NM" : "경북 영천시 자양면", + "MNTN_NM" : "기룡산" }, - "longitude" : 129.01527780000001, - "latitude" : 36.8313889 + "longitude" : 129.0124543, + "latitude" : 36.120247200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "800", - "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군", - "MNTN_NM" : "조항산" + "DETAIL_INFO_DTCONT" : "안산의 지세는 대체로 급경사로 이루어져 있으나 높이가 297M로 낮은 편이어서 주민들의 산책로로 이용되고 있다. 면적은 약 209만제곱미터이며 여러개의 등산로가 조성되어 있고, 다양한 종류의 야생화와 함께 숲길 옆으로 소나무, 잣나무, 독일가문비, 메타세쿼이어, 벗나무, 단풍나무, 복자기나무가 울창해 도심 속에서 삼림욕을 즐길수 있는 서울 서대문구의 대표적인 명소이다. 정상에는 안산봉수대가 있으며 북한강과 인왕산, 행주산성과 한강을 조망할수 있다.", + "MNTN_HG_VL" : "297", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서대문구 홍제동", + "MNTN_NM" : "안산" }, - "longitude" : 127.5848718, - "latitude" : 35.963462 + "longitude" : 126.94499999999999, + "latitude" : 37.576666699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "조항산은 청화산과 이웃해 있는 산으로 해발이 제법 높은데 비하여 많이 알려지지 않아 인적이 드문 산이다. 조항산에 오르기전에 삼송리라는 마을을 거치게 되는데 이곳에는 천연기념물 제 290호로 지정된 `용송'이 볼만하다. 수령 약 600여년이 된 소나무로 밑둥둘레가 약 5m에 높이가 15미터나 되며 용의 형상으로 가지를 드리운 폭이 20미터가 넘는다. 주변에는 아름드리 노송 20여그루를 거느리고 있어 일명 왕소나무라 불리기도 한다.정상에 오르면 북쪽으로는 대야산과 둔덕산 줄기너머로 군자산 장성봉, 희양산이 보이고 남으로는 청화산이 서쪽으로는 백악산 정상이 한눈에 들어온다.갓바위재와의 중간지점에 있는 병풍 같은 암릉지대가 이 산에서는 제일 절경이며, 정상 서편 770봉 주변 암릉지대에 있는 거암군 또한 일품이다.", - "MNTN_HG_VL" : "951", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 농암면, 충청북도 괴산군 청천면", - "MNTN_NM" : "조항산" + "DETAIL_INFO_DTCONT" : "강원도 홍천군 내천면과 인제군 상남면의 경계에 걸쳐 있는 가마봉은 산을 즐겨 타는 등반객들에게도 잘 알려지지 않아 자연 그대로의 정경을 간직한 산이다.산행기점인 김부리는 신라의 마지막 왕인 김부(金傅)에서 유래한 지명인데 세월이 흐르면서 현재 `金富'로 변했다고 한다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내촌면, 인제군 남면", + "MNTN_NM" : "가마봉" }, - "longitude" : 127.93611110000001, - "latitude" : 36.633611100000003 + "longitude" : 128.1766667, + "latitude" : 37.886111100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 포천군 관인면에 있는 종자산(643m)은 그 모양새부터 범상치 않다. 한탄강을 굽어보며 마치 병풍처럼 솟은 산으로 절벽으로 이루어졌다 해도 과언이 아니다. 하얀 물줄기와 수직으로 솟은 절벽은 서로에게 조금치의 양보도 없이 한껏 자신의 아름다움을 자랑한다. 그 모습이 눈이 부셔 이곳을 찾는 이들의 산행을 더디게 하며 진달래와 단풍 또한 좋다.정상 남동편 들머리에는 굴바위가 있는데 전설에 의하면 옛날 3대 독자의 부부가 아이를 못 낳아 고심하던 중이 굴에서 백일기도를 올린 뒤 아들을 낳았다고 하며 종자산(씨앗산) 명도 여기에서 유래되었다고 한다.정상에 다다르면 오른쪽 깎아지른 듯한 낭떠러지 아래로 고남산과 은장산 사이에서 흘러 내려오는 한탄강이 보인다. 동북쪽으로는 철원평야가 아련하고 북쪽으로는 향로봉을 지나 지장봉, 고대산으로 이어지는 능선이 가물가물하다.", - "MNTN_HG_VL" : "643", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 관인면", - "MNTN_NM" : "종자산" + "DETAIL_INFO_DTCONT" : "대덕산은 이웃한 삼도봉과 함께 경남,북과 전북의 3도를 나눈다. 산 이름이 대덕으로 불리우게 된 것은 이곳으로 살러오는 사람들마다 모두 큰 재산을 모음에 따라 산의 덕을 입었다는데서 연유됐다.대덕산은 가야산을 향해 뻗은 능선을 사이에 두고 경북 김천과 경남 거창을 갈라 놓은 삼도 분기점, 즉 해발1,250m의 초첨산을 옆에 둔 명산으로, 옛날에는 다락산, 다악산으로 불리었고 정사에는 기우단이 있었다고 전하는 명산이다.부드럽게 생겼으면서도 우직한 남성다운 덕기가 어린 이 산은 옛부터 수많은 인걸들을 배출했고, 또한 이 산이 있는 무풍동은 남사고의 십승지지중 하나로 알려진 고장이기에 유명하다.또한 영·호남 지방의 분수령으로 금강의 지류인 무풍천과 낙동강의 지류인 감천(甘川)이 각각 동서 사면에서 발원한다. 산 서쪽은 덕유산국립공원, 남동쪽은 가야산국립공원이 인접한다.", + "MNTN_HG_VL" : "425", + "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대덕면, 전라북도 무주군 무풍면", + "MNTN_NM" : "대덕산" }, - "longitude" : 127.1907673, - "latitude" : 38.077864900000002 + "longitude" : 127.8805948, + "latitude" : 35.9249163 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "추가령곡에서 발원한 한탄강이 철원평야를 지난 뒤 임진강과 합류하기 전에 만나는 것이 종자산이다. 우리말로 씨앗산이라 하는 종자산은 주위의 보장산이나 불무산, 은장산과는 다른 모습의 암산으로 보는 이를 압도한다.지릉에만 올라서도 산을 휘돌아 가는 한탄강의 푸른 물결이 내려다보인다. 산중 곳곳에 암릉이 버티고 있으며, 수십 명의 등산인들이 쉬었다 갈 수 있을 정도의 커다란 굴도 있다.잡목이 섞인 암릉을 통해 정상에 다다르면 오른쪽 깎아지른 듯한 낭떠러지 아래로 고남산과 은장산 사이에서 흘러 내려오는 한탄강의 물줄기가 구절양장이다. 동북쪽으로는 철원평야가 아련하고 북쪽으로는 향로봉을 지나 지장봉, 고대산으로 이어지는 능선이 가물가물하다.정상에서 가장 가까운 산행의 들머리는 포천군 관인면 중리의 늘거리다. 산행 중에는 물을 구할 수 없으므로 근처 민가에서 미리 식수를 충분히 준비해야 한다.", - "MNTN_HG_VL" : "643", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 관인면", - "MNTN_NM" : "종자산" + "DETAIL_INFO_DTCONT" : "고루포기산은 강원도 강릉시 왕산면과 평창군 도암면의 경계를 이루는 산으로, 주변의 발왕산, 제왕산, 능경봉의 명성에 가려 찾는 이들이 많지 않았던 산이다.태백산맥의 지맥인 해안 산맥에 딸린 산으로, 북서쪽의 빗면은 한때 대관령 스키장이 있었던 곳이다. 부근의 횡계리(橫溪里) 일대는 평탄면을 이룬다.서쪽에는 남한강의 지류인 송천(松川)이 감입곡류를 이루면서 남쪽으로 흘러 하안단구를 이룬다. 북동쪽 빗면으로 흐르는 수계는 왕산면 왕산리(旺山里)에서 강릉 남대천(南大川)의 지류로 흘러든다.", + "MNTN_HG_VL" : "1238", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시, 평창군", + "MNTN_NM" : "고루포기산" }, - "longitude" : 127.1907673, - "latitude" : 38.077864900000002 + "longitude" : 128.73346340000001, + "latitude" : 37.647446599999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "종현산은 신북면 덕둔리 북쪽에 우뚝 솟아 있으며 경기 포천 산악지역의 상징적 존재이기도 하다. 그러나 경기도의 소금강이라 불리는 소요산(532m) 북쪽에 인접한 산으로 유명한 산과 이웃해 있고 교통이 불편하다는 이유로 사람들 사이에 많이 알려지지 않은 산이다.높이 600미터도 못 미치는 낮은 산이지만 기암괴봉과 아기자기한 계곡미가 일품이며 온 산을 뒤덮은 활엽수림과 덩굴숲이 아늑한 분위기를 자아내 조용한 산행을 즐기기 좋다. 능선에서 내려다 보는 경치는 여느 산 못지 않게 아름답다.종현산 기슭에 삼정골이라는 취락이 있는데 조선 초기 난을 피하여 세 정승이 이 곳에 와 은거하면서 외부와의 접촉을 일체 끊고 산수를 벗삼아 일생을 살았다 하여 삼정골이라 부르게 되었다는 전설이 전해지고 있다. 병풍처럼 둘러싸여 있는 계곡에는 산내천이 서류하여 한탄강으로 흘러 내려간다.", - "MNTN_HG_VL" : "588", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 청산면", - "MNTN_NM" : "종현산" + "DETAIL_INFO_DTCONT" : "경기도 여주군 금사면과 양평군 강상면의 경계에 위치한 양자산은 앵자봉과 나란한 육산으로 부근에 이웃한 산중 가장 높은 산이다. 양평군 서남쪽 남한강 건너 강상면, 강하면과 여주군 산북면의 경계 정점을 이루는 양자산은 산세가 부드럽고 수도권에 근접해 있어 오래전부터 주말산행 코스로 잘 알려진 산이다.산행은 성덕리쪽에서 오르는 것이 일반적이나 코스가 짧다. 최근 양평군에서 개척한 능선종주 코스가 있는데 양자산 정상에서 북쪽으로 뻗어나간 10km의 장쾌한 능선길이다. 이 코스는 남한강변에서부터 올라가는데 4시간, 내려오는데 3시간 30분이 걸린다. 따라서 오를 때 보다는 남한강을 조망하며 내려가는 코스가 산행의 묘미를 더 즐길수 있다.능선 초입에는 소나무가 많고 올라갈수록 싸리나무와 참나무로 덮혀 있다. 가랑잎이 쌓일대로 쌓인 깨끗한 오솔길이 심산에 들어선 느낌을 준다. 정상일때는 한키가 넘는 싸리나무와 억새가 가득하여 온화한 분위기를 자아내고 있다.", + "MNTN_HG_VL" : "712", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 산북면, 양평군 강상면", + "MNTN_NM" : "양자산" }, - "longitude" : 127.1233601, - "latitude" : 37.980375600000002 + "longitude" : 127.4262073, + "latitude" : 37.4377809 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "좌구산은 미원면 대덕리와 증평군 증평읍 율리의 경계를 이루는 산으로 청원군에서 가장 높은 산이다. 계곡을 따라 이어진 숲길에는 사람이 다닌 자취는 거의 없고 멧돼지가 헤집은 흔적만이 곳곳에 있다.잘 뻗은 낙엽송 군락을 비록하여 다양한 활엽수가 산행을 즐기게 한다. 풀숲에는 으아리 참취가 곳곳에 군락을 이루고 대표적인 독초로 꼽히는 천남성과 부자도 자주 눈에 띄이며, 이산은 한남금북정맥 종주 구간에 포함되어 있는 산이다.", - "MNTN_HG_VL" : "659", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군, 청원군", - "MNTN_NM" : "좌구산" + "DETAIL_INFO_DTCONT" : "천봉산은 전라남도 보성군의 문덕면과 복내면의 경계에 자리한 해발 609m의 아담한 산이다. 무등산을 지나 남으로 달려가던 호남정맥이 화순군의 두봉산(631m)을 지나며 북동쪽으로 한 줄기 곁가지를 일으킨다. 이 곁가지는 장재봉과 알아리재를 지나 보성군과의 경계를 이루는 말봉산(584m)에 이르러 왼쪽으로는 까치봉을, 오른쪽으로는 천봉산을 지나 드넓은 주암호 푸른물에 스르르 내려앉게 된다.또한 이 산은 보성군을 비롯해 화순과 순천에까지 걸쳐 있는 주암호변에서 그 물기운으로 솟구쳐오른 듯한 형상이며 산세가 깊으면서도 전망이 빼어나며 깊은 계곡도 거느리고 있다. 또한 천봉산은 말봉산, 까치봉과 힘을 모아 대원사 계곡을 보호하고 있으며, 봉황에 관한 전설을 가지고 있다.들머리에 자리한 대원사는 1550년 전 백제 무령왕 3년, 아도화상에 의해 창건되었다고 전하며 6.25 동란으로 극락전만 남기고 소실되었으나 십여 년 전부터 중창불사가 시작된 규모있는 사찰이다. 문화유산으로는 지방유형문화재 제 35호인 자진원오국사 부도와 제87호인 극락전이 있다. 연못에 놓인 돌다리를 지나 경내에 들러 극락전과 부모공덕불, 500년 고목 등을 둘러보고 일주문을 나서 위쪽에 자리한 티벳박물관 앞을 지나 산행을 시작한다.", + "MNTN_HG_VL" : "436", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군 문덕면", + "MNTN_NM" : "천봉산" }, - "longitude" : 127.636263, - "latitude" : 36.717288799999999 + "longitude" : 127.1333333, + "latitude" : 34.946666700000002 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "658", - "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", - "MNTN_NM" : "좌구산" + "MNTN_HG_VL" : "385", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "마래산" }, - "longitude" : 127.636263, - "latitude" : 36.717288799999999 + "longitude" : 127.7422222, + "latitude" : 34.763611099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;거북이가 앉아 있는 형상gt;청원군 미원면 대덕리(大德里)와 괴산군 청천면(靑川面) 사이에 자리하고 있다. 한남금북정맥의 줄기이면서 가장 높으나 날카롭지 않고 둥글둥글한 모양새를 지니고 있다. 조선 광해군 때 벼슬을 지냈던 김치(金緻)는 임금의 폭정에 시달리다 신변의 위협을 느껴 관직을 그만두고 좌구산 아래 율리에서 은둔생활을 했다. 어느 날 심기원(沈器#28306;)이 찾아와 능양군(인조)을 임금으로 추대하려는 반정을 꾀하던 중 좌구산에서 개 짖는 소리에 염탐꾼이 와 있다는 것을 깨닫고는 황급히 자리를 떠 목숨도 구하고 반정에도 성공할 수 있었다. 그 후로 산 이름이 앉을 ‘좌(座)’자, 개 ‘구(拘)’자를 써 좌구산이라고 불렸다. 지금은 두타산에서 보이는 좌구산의 모습이 거북이가 앉아 있는 형상과 비슷하다 하여 거북이 ‘구(龜)’자로 바꾸어 쓰고 있다. 이름과 얽힌 이야기 외에도 화원리의 새로운 왕을 기다린다는 새왕이 마을, 한국전쟁 중 미원지구 전투에서 톱밥만으로 적군의 탱크를 폭파시켰다는 13인의 특공대 이야기 등 좌구산을 둘러싼 많은 이야기가 전해진다.", - "MNTN_HG_VL" : "658", - "MNTN_LOCPLC_REGION_NM" : "충청북도 증평군 증평읍, 청원군 미원면", - "MNTN_NM" : "좌구산" + "DETAIL_INFO_DTCONT" : "연화산으로 오르는 길은 3코스로 나누어진다.① 언양에서 365번 은칠행 버스로 은편하리 회관 앞에 내려 은편교회를 지나 태양가든 방향② 은편중리 매표소 옆 임도다라 내리재로 가는 길③ 은편중리에서 허고개 방향(남으로)15분 동신부엌가구에서 오르는 길이 열린다.산행들머리는 ③ 번째 코스로 간판 오른편 공장입구에서 왼편으로 오르는 산길이 열린다. 오른쪽에는 언양 반천일대를, 왼쪽에는 두동 은편리 일대를 끼고 능선을 걸어가노라면 고래등을 타고가는 기분이다. 발밑의 바싹 마른 낙엽은 푹신한 카페트처럼 부드럽다. 아무데나 앉아도 낙엽 자체가 방석이다.연화산 정상은 온통 나무를 베어 이곳에 집결시켜 놓고 잡목이 우거져 정상에는 들어갈 수 없을 만큼 어질러져 있다. 우거진 잡목 숲은 멧돼지의 서식지가 되고 있다.", + "MNTN_HG_VL" : "531", + "MNTN_LOCPLC_REGION_NM" : "경상남도 울산시 울주군 언양면", + "MNTN_NM" : "연화산" }, - "longitude" : 127.636263, - "latitude" : 36.717288799999999 + "longitude" : 129.2058389, + "latitude" : 35.633003299999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "435", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 남면 발산리", - "MNTN_NM" : "좌방산" + "MNTN_HG_VL" : "523", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "위례산" }, - "longitude" : 127.6088889, - "latitude" : 37.720277799999998 + "longitude" : 127.2547119, + "latitude" : 36.880067799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주걱봉은 설악산 국립공원의 남서부에 위치해 있는 가리봉 줄기에 자리잡고 있다. 최고봉인 가리봉을 위시하여 가리봉 북쪽 지릉의 십이연봉, 주걱처럼 생긴 주걱봉, 삼형제봉 등이 한데 어우러져 있는데 모두 바위봉으로 이뤄져 산세가 급하고 험준하다. 북쪽으로 자양천·계천이 흐르고 이 두 하천을 사이에 두고 맞은 편에 대승령(1210m)·안산(1430m)이 있다. 북쪽 산 아래에 하늘벽·장수대가 있다.주걱봉을 비롯한 가리봉 줄기를 오를때는 사전에 정확한 정보를 준비해야 한다. 점봉산처럼 원시림이 울창하고 암봉이 이어져 있으며 양쪽에 낭떠러지가 있어 능선 중앙부에 있는 가리봉으로 접근하는 일이 쉽지 않기 때문이다.", - "MNTN_HG_VL" : "1401", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면, 인제읍", - "MNTN_NM" : "주걱봉" + "DETAIL_INFO_DTCONT" : "덕유산은 전북 무주군과 장수군, 경남 거창군과 함양군의 경계를 이루며, 2도 4군 8개면에 걸쳐있다. 한라산.지리산.설악산에 이어 남한에서 4번째로 높고 1000미터 이상의 봉우리가 20개도 넘는 거대한 산이다.덕유라는 이름은 덕이 있고 크며 넉넉한 산의 모습을 나타낸 말이다. 무학대사가 골치아픈 정권에서 벗어나 첩첩산중 경치 아름다운 산을 물색하다가 발견했다는 산이 바로 덕유산이다.", + "MNTN_HG_VL" : "1614", + "MNTN_LOCPLC_REGION_NM" : "전라북도 무주군ㆍ장수군, 경상남도 거창군ㆍ함양군", + "MNTN_NM" : "덕유산(향적봉)" }, - "longitude" : 128.3327778, - "latitude" : 38.096944399999998 + "longitude" : 127.7468314, + "latitude" : 35.860032799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산이 부드럽고 아름다워 일명 비단산이라고도 불리는 주금산은 운악산과 천마산의 중간지점에 가장 높이 솟아있는 산이다. 남쪽의 아름다운 비금계곡은 도심 근교의 대표적 피서지 중 하나다. 남쪽 약 1.3킬로미터 지점에는 독을 엎어놓은 것 같아 ‘독바위’라 불리는 암봉이 있으며 능선에는 바위지대와 억새밭이 심심치 않게 있고 수림도 울창하다.특히 수동천 상류의 비금계곡은 자연 그대로의 모습을 잘 간직하고 있다. 이 계곡은 옛날 풍류를 즐기던 선비들이 거문고를 숨겨놓고 다녔다하여 붙은 이름이다.정상 부근의 기암과 수려한 비금계곡이 어우러져 마치 비단결 같은 산세가 이어지며, 서북쪽 산자락에는 베어스타운 스키장이 자리잡고 있다.등산 코스로는 내촌에서 오르는 길과 비금계곡에서 오르는 길, 두 가지가 있다. 두 길 모두 산세가 뛰어나 아기자기한 산행을 맛볼 수 있다. 산행 시간은 4시간 남짓으로 서울에서 당일 산행지로 적합하다.", - "MNTN_HG_VL" : "814", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 포천시 내촌면, 가평군 상면", - "MNTN_NM" : "주금산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "231", + "MNTN_LOCPLC_REGION_NM" : "전라남도 신안군", + "MNTN_NM" : "송공산" }, - "longitude" : 127.2691293, - "latitude" : 37.784374499999998 + "longitude" : 126.254693, + "latitude" : 34.851599899999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "489", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "주발봉" + "DETAIL_INFO_DTCONT" : "강원도 춘천시 북산면과 화천군 간동면 사이에 있는 오봉산은 해발 779m이고 다섯개의 봉우리가 있다고 해서 오봉산이라고 한다. 기암절벽과 노송이 어울려 한폭의 동양화 같은 산으로 유서깊은 청평사가 있다.배후령에서 오르게 되는 첫번째 봉우리가 1봉(나한봉), 두번째 봉우리인 관음봉, 세번째 봉우리인 문수봉, 네번째 봉우리인 보현봉, 다섯번째 봉우리인 정상 비로봉이 있다. 이중 제5봉인 정상에서 청평사 방면으로 뻗어내린 암릉이 특히 빼어난 풍광을 지녔다. 이 암릉을 따라 소양호를 바라보며 내려가는 길이 오봉산행의 백미라 할 수 있다.", + "MNTN_HG_VL" : "778", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면, 화천군 간동면", + "MNTN_NM" : "오봉산" }, - "longitude" : 127.4947222, - "latitude" : 37.776111100000001 + "longitude" : 127.8060983, + "latitude" : 38.0007746 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "338", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초시", - "MNTN_NM" : "주봉산" + "DETAIL_INFO_DTCONT" : "화부산은 길안면 대사리와 고란리를 경계로 남북으로 길게 자리잡고 있는 산이다. 비교적 낮은 산이지만 치솟는 경사와 아기자기한 능선, 그리고 촛대바위, 문살바위 등이매우 아름답게 어우러져 있다. 정상부근에는 잡목이 무성하여 어디가 정상인지 분간조차 할 수 없으며 정상에서는조망이 불가능하다.", + "MNTN_HG_VL" : "626", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 길안면 대사리,고란리", + "MNTN_NM" : "화부산" }, - "longitude" : 128.54221570000001, - "latitude" : 38.172462099999997 + "longitude" : 128.9526189, + "latitude" : 36.387769600000013 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주산은 대가야의 고분이 남아있고 순장묘 등 고분군이 발견된 산으로 역사적 가치가 높다. 남동쪽 구릉의 동남쪽 사면에 위치한 대가야시대의 무덤들은 현재와 고대를 연결하는 시간의 문을 연상케 한다. 또한 고령군민과 외지인들이 많이#52287;는 고령의 명산이다.고령의 진산인 주산정상(3백11M)에 오르면 북서쪽으로 가야산과 미숭산이 멀찌감치서 절묘한 자태를 드러낸다. 동쪽 산아래로는 고령읍이 한눈에 들어 오고 산능선을 넘나드는 한줄기 바람과 봄철에만 피어나는 철쭉꽃이 만발해 보는이로 하여금 가슴을 져미게 만든다.주산정상에서 고분군으로 내려오는 길 옆에는 명상의 숲을 꾸며 놓았다. 나무벤치 앞마다 주옥같은 명시를 기록해 나그네를 잠시 쉬어가게도 한다. 대가야 시대에 축조된 지산동고분군은 주산의 남동쪽 능선을 따라 내려 가면서 낙타등 처럼 이어지는데 언뜻 보면 거대한 봉분들만 눈에 띄지만 능선 아래로 크고 작은 무덤들이 마치 잊혀진 역사처럼 풀숲에 수도 없이 묻혀 있다고 해고 과언이 아닐듯 하다.높이 6m 지름 25~27m 규모인 제51호 고분을 비롯, 32호 고분까지 규모가 큰 고분이 이어지는데 특히 지난 78년 발굴. 조사결과 우리나라에서 첫 확인된 순장묘로 밝혀진 제44호 고분이 눈길을 끈다. 고분 주위를 걷다가 잠시 무덤가에 앉아 낙동강을 타고 오르는 바람결에 땀을 식히노라면 여기서도 고령읍내가 훤하게 보인다. 능선을 따라 줄곳 내려가면 44호분의 실물 크기로 순장묘 전시관이 나타난다.16대 도설지왕 때인 서기 562년에 신라에 멸망한 후기 가야연맹의 맹주국이던 대가야, 대가야의 5백년 역사는 삼국사기나 삼국유사에서도 어렴풋이 기록되어 있을뿐 정복당한 왕조의 애달픈 사연을 고분안에 묻은 채 빛바랜 대가야의 찬란했던 문화는 아직도 우리 역사에서 전설로 남아 있다.", - "MNTN_HG_VL" : "310", - "MNTN_LOCPLC_REGION_NM" : "경상북도 고령군", - "MNTN_NM" : "주산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", + "MNTN_NM" : "흑성산" }, - "longitude" : 128.25277779999999, - "latitude" : 35.731944400000003 + "longitude" : 127.208302, + "latitude" : 36.796827100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주암산은 앞산과 비슬산으로 대표되는 대구 남쪽 산군의 동쪽 부분을 차지한다. 가창댐이 있는 용계천과 냉천이 산자락의 북동쪽을 감싸며 흐르고, 정상에서 남서로 뻗은 산줄기는 최정산을 지나 비슬산, 청룡산 앞산으로 이어지며 거대한 산지를 이룬다. 주암산 산행은 허브힐즈 오른쪽 안양사나 광덕사 뒤 능선을 따라 오른다. 동쪽 자락의 주암산수양관, 또는 동남쪽 원장마을에서 원티골을 따라 오르는 길이 일반적이다. 어느 곳을 들머리로 삼든지 산행은 3~4시간이면 충분하다. 주암산은 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 정상 일대와 능선에는 억새풀이 무성하고, 봄에는 진달래 천국을 이루고, 가을에는 단풍이 온 산을 물들여 대구 근교지방의 주민들에게는 매우 친근한 산이다. 최정산과 주암산은 능선상으로 바로 이웃하여 있어 두 산을 종주하는 것도 좋다.", - "MNTN_HG_VL" : "855", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", - "MNTN_NM" : "주암산" + "DETAIL_INFO_DTCONT" : "보령과 부여의 경계선에 있는 아미산은 호젓한 산행 코스가 자랑이지만 지금껏 알려지지 않은 산이다. 가을이면 산 전체가 불붙은 듯 단풍으로 가득한 곳, 예부터 산삼이 많이 나는 곳이며 부정한 사람이 출입하면 화를 입는다는 이야기가 전해져 오는 산이다. 높은 산은 아니지만 골이 깊고 산세가 자뭇 웅장하다. 만만히 보고 다가갔다 흠씬 비지땀을 흘려야 오를 수 있는 산이다.보령호가 담수를 시작하면서 산 끝자락이 잠겼고, 만산홍엽의 그림자가 비친 호수와 어울린 모습이 황홀경에 빠져들도록 아름답다. 미산면 용수리 동북쪽에 자리하고 있으며, 도화담에서부터 솟아오른 봉우리가 풍계리와 용수리에 걸쳐 있다. 북쪽은 부여군 외산면과 지경을 이룬다. 아미산에는 백제때 창건된 중대암이 있고 인근에는 영천이라는 약수가 있다.", + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "충남 보령시 미산면, 부여군 외산면", + "MNTN_NM" : "아미산" }, - "longitude" : 128.61694439999999, - "latitude" : 35.773888900000003 + "longitude" : 126.6911111, + "latitude" : 36.279444400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주월산은 괴산의 명산 중 가장 짧은 코스이다. 산행에 필요한 시간은 불과 1시간 정도면 충분하기 때문이다. 그렇다고 볼거리가 없다거나 시시한 산은 절대 아니다. 느릅재 정상에서 충주 쪽으로 19번 국도를 따라 가면서 가까이 보이는 까닭에 누구든 빼어난 산의 모습에 취하면 쉽게 내려오지 못하는 산이기도 하다.바위능선이 병풍처럼 둘러쳐져 있어 산세가 빼어나고 정상에 오르면 남쪽으로 박달산을 비롯한 여러 산이 보인다. 주변에 공림사와 망개나무자생지·수안보온천 등의 명소가 있다.산행은 감나무골에서 시작한다. 능선을 타고 5분 오르면 작은 봉우리가 나오는데 이곳에서 서쪽으로 이담저수지와 마을이 보인다. 동쪽으로 10분 정도 올라가 첫번째 바위봉우리를 지나면 정상이다. 두 봉우리 주위는 마치 성곽처럼 평평한 바위로 둘러싸여 있고 그 모습이 절구의 확돌처럼 보인다 하여 산 아랫마을을 화학골이라 부르기도 한다.", - "MNTN_HG_VL" : "470", - "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 장연면", - "MNTN_NM" : "주월산" + "DETAIL_INFO_DTCONT" : "장암산이란 이름은 산 정상에 자리잡은 너럭바위에서 비롯되었다. 장암산은 산이름이 그렇듯이 펑퍼짐한 초원을 이룬 정상에 너럭바위가 있는데, 그 모습이 옆에서 보면 마치 물위를 떠가는 조각배를 닮아 신기하기만 하다. 더욱 기이한 것은 이웃하고 있는 태청산은 이따금 눈에 띄는 단단한 바위들이 모가나 날카로운데 비해 장암산 정상에 덩그러니 올려 놓은 듯한 바위는 조각작품처럼 매끄럽게 다듬어 놓은 것 같아 맨발로 올라 앉아도 괜찮을 정도이다.장암산은 전남 영광군 묘량면, 장성군 삼서면에 위치한 나즈막한 산이다. 굴비의 고장 영광군은 서쪽으로는 서해바다를 끼고 있다. 북쪽으로는 전북 고창군과 경계를 이루지만 거의 평야를 이루고 있다. 그러나 장성군과 경계를 이루는 동쪽과 함평군과 경계를 이루는 남쪽은 400m?600m 높이로 솟은 산들이 성곽처럼 에워싸고 있다.장암산에서 남서쪽으로 활시위처럼 휘어지는 산릉은 남쪽 함평군과 경계를 이루며 불갑산(516m), 모악산(348m), 군유산(403m), 월암산(338m)을 연속적으로 들어올린 다음 그 여맥을 서해바다에 가라앉힌다.장암산은 훌륭한 등산코스일 뿐만 아니라 행글라이더들에게도 인기가 대단하다. 그만큼 정상에 오르면 마치 비행기를 타고 하늘 위에 떠있는 기분에 휩싸일 만큼 시원한 파노라마가 펼쳐진다. 행글라이더들이 뛰어내리는 방향인 서쪽 아래로는 묘량면 곡창지대 들판이 시원하게 터지며 멀리 영광읍 너머인 백수 방면 서해바다가 가물거린다.북으로는 대마면 들판 너머로 고창군 곡창지대가 시원해게 펼쳐진다. 대마면에서 오른쪽으로 하늘금을 이루는 태청산과 얼랑산 풍광도 일품이며 남으로 불갑산으로 내다르는 산릉이 첩첩산중을 이루어 장암산에 오른 보람을 만끽하고도 남는다.", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영광군 묘량면, 삼서면", + "MNTN_NM" : "장암산" }, - "longitude" : 127.9037335, - "latitude" : 36.849944299999997 + "longitude" : 126.5838186, + "latitude" : 35.2580569 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉황이 날개를 활짝 펴고 하늘을 날고 있다해서 이 산의 이름은 주작산이다. 해남과 강진의 경계를 이룬 주작산(약 475m) 능선은 전형적인 암릉길이다. 그동안 지척에 있는 두륜산에 가려 빛을 보지 못했지만 특유의 거칠고 까탈스런 바윗길 덕분에 이제 남도의 대표적인 암릉산행지로 주목받고 있다.주작산은 두륜산에서 동쪽으로 뻗어내린 산맥이 오소치에서 멈춘 뒤, 거친 기세로 솟아 오른 바위능선 한 귀퉁이에 솟아 있다. 그것도 주능선이 아닌 동쪽으로 조금 삐져나온 지능선 상에 위치한다. 그래서 주작산 산행은 이 주봉을 오르기보다 오소재 - 작천소령으로 연결되는 산줄기 전체를 타는 것이 일반적이다.주작산 줄기는 북으로 덕룡산(432.9m)과 석문산(272m) - 만덕산(408.6m)까지 이어진 긴 능선의 일부 구간이다. 이 산자락의 대부분 구간은 바위 봉우리와 벼랑으로 형성되어 보는 맛이 탁월하다. 특히 주작산 구간은 톱날 같은 암릉이 길게 이어져 아기자기한 산행의 묘미가 뛰어나다.주작산 산행은 접근이 편리한 오소재에서 시작해 작천소령으로 답사하는 것이 일반적이다. 초창기에는 산이 거칠고 길도 없어 10시간 이상 걸렸지만, 이제는 우회로가 많이 생겨 시간이 많이 단축됐다. 건각들은 주작 - 덕룡산 줄기를 하루에 답파하기도 한다. 위험한 구간에는 어김없이 로프를 매어 놓았지만, 아직도 아찔한 구간이 많으니 초심자가 낀 팀은 주의해야 한다.", - "MNTN_HG_VL" : "475", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 도암면, 신전면", - "MNTN_NM" : "주작산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "789", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 갑천면", + "MNTN_NM" : "어답산" }, - "longitude" : 126.6956041, - "latitude" : 34.5063703 + "longitude" : 128.0685852, + "latitude" : 37.584108200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주지봉은 월출산(813m)의 서쪽에 위치한 나즈막한 산이다. 도갑저수지의 서쪽에 있는 능선인데 죽순봉 아래 성기동 일대에 왕인박사 유허비를 비롯한 유적들이 산재해 있다.한반도의 서남단, 소백산맥의 끝부분에서 우뚝 솟은 월출산은 최고봉인 천황봉을 비롯하여 구정봉, 장군봉, 자봉, 향로봉, 주지봉, 노적봉 등의 영봉이 기암 괴석으로 신비롭게 이루어져 예로부터 호남의 소금강이라 일컬어져 왔고, 미왕재를 위시한 능선은 억새풀밭으로 장관을 이루며 산능의 북쪽면은 날카롭고 가파른 돌산인 반면 남쪽면은 완만한 육산으로 이루어져 있고 골짜기가 깊지 않아 곳곳에 저수지가 설치되어 있다.", - "MNTN_HG_VL" : "491", - "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군", - "MNTN_NM" : "주지봉" + "DETAIL_INFO_DTCONT" : "강원도 정선군에서도 가장 오지 마을이라 할 수 있는 임계면 고양리에 위치한 산이다. 그리고 반론산(1068)은 고양산에서 북쪽 여량 방면으로 뻗은 능선상 최고봉으로 고양산과는 약 4km 정도 거리를 두고 있는 산이다.이 두 산의 주체는 베낭족의 낙원이라 불리던 골지천(骨只川)이 된다. 즉 골지천에서도 가장 하이라이트라 할 수 있는 구미동, 어전동, 성북동, 봉정리 등이 이 두 산을 감싸면서 휘돌고 있다.골지천(骨只川)에 솟아 있는 어머니 같이 넉넉하고 편안한 품을 펼치고 있는 고양산은 정선의 오지 중에 오지인 임계면에 자리잡고 있다.", + "MNTN_HG_VL" : "1151", + "MNTN_LOCPLC_REGION_NM" : "강원도 정선군", + "MNTN_NM" : "고양산" }, - "longitude" : 126.6496305, - "latitude" : 34.745091199999997 + "longitude" : 128.77055559999999, + "latitude" : 37.416944399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "김otilde;쪽에서 추풍령을 넘어 황간 가까이 내려오면 1시 방향으로 하나의 커다란 배가 하늘을 떠가는 모양을 볼 수 있다. 바로 주행봉이다. 떠가는 배의 모양을 그대로 이름으로 한 것이다.속리산에서 백두대간과 헤어진 산줄기 하나가 구병산을 거쳐 팔음산(762m, 옥otilde;ucirc;산면)으로 나아가고 이 산줄기는 한껏 낮아졌다가 백화산으로 다시 일어나 933미터의 포성봉과 874미터의 주행봉을 빚어놓았다. 이 백화산은 상주의 모동면 모서면, 옥otilde;의ucirc;산면 일대의 분지 가운데 자리잡고 있기 때문에 더욱 우뚝하고 커 보인다.국토지리정보원의 지도에는 포성봉, 주행봉으로 표기되어 있다. 포성봉이라 부르는 연유는 알 수 없으나 「신증동국여지승람」과 모든 기록에 백화산으로 되어 있고 상주쪽에서는 한성봉이라 부르기도 한다. 주행봉을 현지 주민들은 “쌀개봉”이라 부른다. 주행봉의 머리를 이루는 바위 봉우리 두 개가 옛날 디딜방아의 쌀개oacute;럼 되어있기 때문이다.", - "MNTN_HG_VL" : "874", - "MNTN_LOCPLC_REGION_NM" : "충북 영동군 황간면", - "MNTN_NM" : "주행봉" + "DETAIL_INFO_DTCONT" : "대암산 정상 부근에는 큰 용늪, 작은 용늪이라 불리는 고지습원이 있는데, 작은 용늪은 이미 그 원래의 모습을 상실하여 숲으로 변해버리고 말았다. 큰 용늪은 우리나라에서 유일한 고지습원으로 연중 안개끼는 날이 많은 특수한 환경이 조성되고 있어 생태계 연구에 좋은 자료를 제공하고 있다.큰 용늪에는 물이끼, 삿갓사초, 꼬리조팝나무, 꽃쥐손이풀 등의 식물군락이 있으며, 손바닥 난초, 비로용담, 끈끈이주걱 등의 희귀식물도 자라고 있다. 그 밖에 식물성 플랑크톤 63종, 돌말 19종과 천연기념물인 산양과 검독수리가 관찰된 바 있으며, 도룡뇽, 무당개구리, 줄흰나비 등도 볼 수 있다. 또 이 지역과 연결된 두타연계곡에서는 열목어를 비롯한 특산 어류 10여 종이 살고 있다.대암산·대우산 천연보호구역은 분지·습원등 지형적으로 다양한 특징을 지니고 있고, 기후조건이 특이하여 희귀동식물이 자라고 있다. 또한 동식물의 남북한계·동서 구분의 현상이 나타나는 등 식물생태학·식물지리학적·식물분류학적 연구가치가 매우 큰 지역일 뿐만 아니라 다양한 동물상, 특이한 지형·지세 및 기후적 특성 등 다양한 자연 환경을 가지고 있어 학술적 가치가 크므로 쳔연기념물로 지정·보호하고 있다.", + "MNTN_HG_VL" : "1313", + "MNTN_LOCPLC_REGION_NM" : "강원 양구군 동면, 인제군 서화면", + "MNTN_NM" : "대암산" }, - "longitude" : 127.8877233, - "latitude" : 36.278346300000003 + "longitude" : 128.1350874, + "latitude" : 38.211199499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경부고속도로를 따라 추풍령을 지날 때 영동 근처에 이르면 서북쪽으로 솟아오른 백화산(933m)이 보인다. 주행봉은 백화산이 껴안은 봉우리로 황간쪽에서 올려다 보면 물위를 떠가는 배와 같은 형상을 하고 있다. 산 아랫마을 사람들은 이 산을 쌀개봉이라고도 한다. V자로 갈라진 봉오리가 방아허리를 받치는 쌀개 같다하여 붙여진 이름이다.주행봉은 산 주름이 거의 없는 판판한 북서 사면이 장관이다. 높이 8백여 미터 내외의 산줄기가 거의 주름이 없고 4킬로미터 정도 뻗어 있다. 비탈이 대부분 가파른 너덜로 되어 있어 더욱 장관이다.", - "MNTN_HG_VL" : "874", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 모서면, 충청북도 영동군 황간면", - "MNTN_NM" : "주행봉" + "DETAIL_INFO_DTCONT" : "국통산은 우보면 나호리에 위치한 산으로서 해발 336.8m로 그리 높지 않은 산이나 정상부위의 등산로에서 맑은날 내려다보면 동북쪽으로 금성산, 동쪽으로 선암산, 뱀산, 동남쪽으로 옥녀봉, 남쪽으로 팔공산과 매봉산이 보이며 북서쪽으로는 마정산, 선방산 등이 관측된다.", + "MNTN_HG_VL" : "337", + "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 우보면 나호리", + "MNTN_NM" : "국통산" }, - "longitude" : 127.8877233, - "latitude" : 36.278346300000003 + "longitude" : 128.6382653, + "latitude" : 36.198841799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울의 진산 자리를 놓고 삼각산과 다투다가 휘적휘적 내려와 버렸다는 전설이 있을 만큼 빼어난 산이다. 정상에서 남봉으로 뻗어내린 1000m를 넘나드는 능선이 특히 준걸해 흡사 삼각산 백운대에서 보현봉에 이르는 장쾌한 능선을 빼다 놓은 듯하다. 일반등산로는 정상으로 알려진 1075봉을 중심으로 6방으로 나있는데 이 중 상봉인 주흘영봉과 부봉을 지나 동화원로 이어지는 줄기의 능선미가 일품이다. 월항삼봉으로 해서 하늘재로 내려서는 코스도 좋은데 월악산에서는 이 둘의 하늘금이 리듬체조의 리본처럼 역동적으로 보인다. 산이 솟음이 우세한 형국이라 썩 발달한 계곡은 없다. 대신 곡충골의 여궁폭포와 파랑소, 조곡골의 꽃밭서덜이 이채롭다. 너덜 사이를 듬성듬성 뚫고 올라온 진달래가 꽃을 피운 모습은 어디서도 찾아보기 힘들다. 도립공원으로 지정돼있는 문경새재는 주흘관, 조곡관, 조령관의 관문과 아울러 자연보도로도 유명하다. 근래에는 여기에 드라마왕건 세트장과 산악영화제가 보태졌다.", - "MNTN_HG_VL" : "1108", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 문경읍", - "MNTN_NM" : "주흘산" + "DETAIL_INFO_DTCONT" : "구봉대산(870m)은 강원도 영월군 수주면 북쪽에 아홉 봉우리를 자랑하며 솟은 산이다. 우리나라 5대 적멸보궁 중 하나인 사자산 법흥사 적멸보궁을 감싸 안은 우백호의 자리에 해당하기도 한다. 백덕산(1349m)에서 사자산 지나 삿갓봉(1028m)으로 이어지는 서쪽의 산줄기 중간에서 남쪽으로 뻗어 내린 구봉대산은 북쪽의 1봉에서 남쪽 9봉에 이르는 각 봉우리마다 사람이 태어나서 죽을 때까지의 과정을 뜻하는 단어들이 각각 이름으로 붙어있다.4봉부터는 등반을 해야 할 정도로 암릉구간이 곳곳에 나타나지만 모두 우회하는 길이 아래로 나 있어 힘들지 않게 산행할 수 있다. 법흥사에서 출발해 계곡을 따라 1봉에 올라 능선 따라 9봉까지 간 다음 다시 법흥사로 내려오면 된다. 총 산행시간은 4시간 정도 걸린다.", + "MNTN_HG_VL" : "870", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면", + "MNTN_NM" : "구봉대산" }, - "longitude" : 128.10060530000001, - "latitude" : 36.788566500000002 + "longitude" : 128.25140740000001, + "latitude" : 37.362444199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "명지산(1,267m)과 운악산(936m)을 빚은 백두대간의 줄기가 의정부에 이르러 나즈막하게 솟구쳐 오른 산이 죽엽산이다. 국수봉(605m)과 소리봉(536m)을 이웃하고 있으며 굴곡 없는 육산이다. 언뜻 보기엔 밋밋하고 신통치 않게 보이는 산이지만 이산의 특징은 울창한 수림에 있다.도봉산의 사패능선이나 포대능선처럼 경치를 볼 수 있는 탁 트인 곳은 없지만, 주능선상의 쭉쭉 뻗은 울창한 수림사이를 시원한 바람을 맞으며 걷노라면 이 산의 매력이 충분히 느껴질 것이다. 산행은 큰넓고개나 직동에서 시작한다.", - "MNTN_HG_VL" : "601", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천군 소흘읍, 내촌면", - "MNTN_NM" : "죽엽산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1081", + "MNTN_LOCPLC_REGION_NM" : "경상남도 양산 하북면, 원동면, 울산시 울주군 삼남면, 상북면", + "MNTN_NM" : "영축산" }, - "longitude" : 127.1855556, - "latitude" : 37.7916667 + "longitude" : 129.05500000000001, + "latitude" : 35.517000000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "859", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천군", - "MNTN_NM" : "죽엽산" + "DETAIL_INFO_DTCONT" : "오대산을 지나 설악산으로 달리던 백두대간이 갈전곡봉에 이르러 서쪽으로 가지를 뻗은 산이 개인산이다.<>개인산은 개인, 삼봉, 방동약수로 유명하며 이 약수 섞인 물은 개인산의 북면을 흐르는 방대천과 서남면을 돌아가 방대천을 합하는 20킬로미터의 내린천으로 흘러들어 차례로 소양강, 북한강, 한강이 된다. 계곡은 수려하나 보이지 않고 산날은 치솟았지만 바위를 드러내지 않는다. 공기 좋고 물이 맑아 전염병이 들지 않고 먹거리가 많다. 입구는 좁고 안은 너른 형세다.<>이런 곳은 여덟 군데 살둔, 달둔, 월둔, 아침가리, 명지가리, 적가리, 곁가리, 연가리의 ‘삼둔오갈’을 두었는데 물, 불, 바람 즉 흉년, 전염병, 전쟁을 피할 수 있는 곳으로 내우외환이 끊이지 않았던 불행한 시대에 개인산은 많은 민추들을 보듬어 주었음을 역사는 전한다. 그리하여 개인산은 지리산과 금강산처럼 장엄하거나 빼어나진 않지만 그 어느 것보다 한국적인 산이다.", + "MNTN_HG_VL" : "1342", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 상남면ㆍ홍천군 내면", + "MNTN_NM" : "개인산" }, - "longitude" : 127.8472038, - "latitude" : 38.052157999999999 + "longitude" : 128.4002778, + "latitude" : 37.861666700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "중미산은 청평과 양평을 잇는 37번 도로에서 가장 높은 곳인 선어치(서너치)고개를 사이에 두고 유명산과 마주보고 있다. 중미산 남쪽의 고개를 서너치(3-4寸)라고 부르게 된 데에는 재미있는 연유가 있다.호랑이가 있다는 고개를 넘어 온 선비에게 호랑이를 못 보았느냐고 묻자\"\"호랑이는 못 보고 어찌나 나무가 울창한지 하늘만 서너치 보았오` 라고 얘기한 것에서 비롯되었다고도 하고 가마 타고 시집가는 색시가 고개를 넘으면서 지루한 나머지 하인에게\"\"길이 얼마나 남았느냐\"\"고 물을 때마다 하인이\"\"이제 서너치 남았소\"\"라고 대답했다는데서 붙여진 지명이라고 한다. 이 산 자락 아래 양현 마을이 국민휴양지로 개발되면서부터 등산객들이 늘고 있다. 인근의 산 중에서 제법 높은 산이라 정상에서의 조망이 시원스럽다.", - "MNTN_HG_VL" : "833", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면, 가평군 설악면", - "MNTN_NM" : "중미산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1189", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면 대기리", + "MNTN_NM" : "조고봉" }, - "longitude" : 127.4716706, - "latitude" : 37.594901399999998 + "longitude" : 128.7668238, + "latitude" : 37.564401699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "중미산은 경기도 가평군 설악면과 양평군 서종면의 경계에 위치한 산이다. 유명산, 소구니산과 더불어 서너치고개를 사이에 두고 솟아있는 중미산은 그동안 유명산에 가려 빛을 보지 못했으나 중미산자연휴양림이 조성되면서부터 각광 받고 있다.사실 중미산은 서너치고개와 소구니산 등으로 연결되어 있는, 억새숲으로 유명한 유명산과는 달리 별 특징이 없다. 단지 북쪽의 통방산(649m)에서부터 유명산까지 하나의 작은 산줄기를 형성하고 있는 여러 산 중에서 가장 높은 산이어서 정상에 서면 조망이 시원스럽다.중미산은 서너치고개에 오르면 40분 밖에 걸리지 않기 때문에 산행에 변화를 주려면 산 북쪽에 있는 명달리를 기점으로 하거나 삼태봉을 거쳐 통방산에 이르는 능선종주도 해볼 만하다. 일반적으로는 신복3리 양현마을에서 북쪽으로 계곡을 거슬러 올라 안부를 거쳐 정상에 오른 후 서너치고개로 하산하는 것이 무난하다. 요즘에는 자연휴양림이 있는 양평군 옥천면 신복리로 해서 양현마을까지 가서 산행을 시작, 정상을 거쳐 원점회귀하는 산행도 많이 이루어진다.", - "MNTN_HG_VL" : "833", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면", - "MNTN_NM" : "중미산" + "DETAIL_INFO_DTCONT" : "유학산은 높다란 바위벽이 병풍처럼 둘러처져 있고 낙락장송이 어우러진 수려한 경치를 자랑하는 산이다. 하지만 6·25전쟁 때는 치열한 격전지였다. 이런 역사적 아픔 때문에 이곳에는 다부리와 왜관지구 두 곳에 전적기념관이 있다. 경치가 빼어나 학이 놀다간 산이라는 이름을 가졌지만, 잊어서는 안될 우리의 가슴 아픈 역사를 간직하고 있기에 문화답사 산행지로 적격이다.유학산은 동봉과 서봉 능선이 동서로 길게 뻗은 산으로 팔공산에서 서쪽으로 이어지는 산줄기의 서쪽 끝에 위치한다. 유학산의 서쪽면은 중턱에서부터 고스락까지 깎아지른 거대한 바위가 병풍처럼 솟아 있다.바위 벼랑이 까마득하게 높아 쉰길이나 된다는 쉰길바위가 있고 학이 놀았다는 학바위, 조망 좋고 시원한 신선대가 있다.", + "MNTN_HG_VL" : "839", + "MNTN_LOCPLC_REGION_NM" : "경상북도 칠곡군 가산면, 석적면", + "MNTN_NM" : "유학산" }, - "longitude" : 127.4716706, - "latitude" : 37.594901399999998 + "longitude" : 128.51033670000001, + "latitude" : 36.064411100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군에 있는 중봉은 화악산과 남서쪽으로 이웃해 있는 산으로 화악산 정상부가 군사 통제 구역으로 묶여 있기 때문에 등산인들이 오를 수 있는 경기도내의 가장 높은 산이다. 대부분 중봉 산행은 관청리 큰골 계곡으로 올랐다가 다시 큰골로 하산하는 경우가 많은데 산행경력이 있다면 가림에서 출발하여 가파른 능선을 타고 오른 후 큰골로 하산하는 것도 괜찮다.가림마을에서 시작하는 산행은 돌집수련원 입구에서 시작되는데 초입부가 오솔길처럼 평탄하다고 해서 만만하게 보아서는 안된다. 750m 고지를 오르면서부터 산길이 급격하게 가팔라지고 험준한 길이 이어진다. 그러나 이 구간쯤에 이르면 명지산에서부터 국망봉, 백운산까지 이어지는 능선이 한눈에 들어와 피로를 잊게 해 준다.", - "MNTN_HG_VL" : "1424", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", - "MNTN_NM" : "중봉" + "DETAIL_INFO_DTCONT" : "산행은 쌍곡리에서 시작한다. 쌍곡계곡에서 시원스런 나무숲 사이로 들어가 산 중턱에 올라서면 원효굴이 나온다. 원효굴은 두개로 나뉘어져 있는데 하나는 절벽아래 약 7.2미터 정도 넓이의 굴로 바닥에서 차가운 약수가 쏟아져 나온다. 다른 하나는 상층석실인데 이 굴은 화강암으로 이루어진 천연굴로서 원효대사가 불도를 닦던 곳이라 전해진다. 원효굴에서 조금 더 가면 첫 봉우리에 이른다. 다시 고개 하나를 지나면정상이다. 하산은 서남쪽 고개를 돌아 계곡을 타고 내려온다. 큰군자산 종주 코스는 비지정등산로이며 현재 국립공원 지정등산로는 소금강 - 큰군자산 - 도마골 정도니 그 외 등산로는 허가를 받아야 한다.", + "MNTN_HG_VL" : "948", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 칠성면", + "MNTN_NM" : "군자산" }, - "longitude" : 127.4949902, - "latitude" : 37.9871871 + "longitude" : 127.87860019999999, + "latitude" : 36.737540799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가곡면 풍곡리 덕풍계곡에 자리잡은 중봉산은 사람들에게 덜 알려진 만큼 훼손도 덜 된 곳이다. 그래서 호젓한 주말산행을 원하는 사람 몇 명이 뜻을 모아 함께 찾아가기에 좋다. 태백에서도 한참을 더 가서야 만날 수 있는 이 산은 시원한 덕풍계곡의 물소리가 능선길을 오르는 동안 내내 따라올 만큼 한적하다. 또한 나이를 짐작하기 어려울 정도로 밑둥이 굵은 아름드리 노송도 몇 그루 만날 수 있다.그리고 참나무와 물푸레나무 등이 울창하게 늘어선 산에서 새소리와 물소리를 들으며 함께 간 사람들과 두런두런 얘기를 나누다 보면 세속의 가면을 벗어 던진 자신을 발견할 수 있을 것이다. 한편 정상에서는 남동쪽을 조망할 수 있는데, 이곳에 한국 전쟁 당시 참호로 사용되었을 웅덩이가 남아 있어 민족의 비극을 떠올리게 한다.", - "MNTN_HG_VL" : "740", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "중봉산" + "DETAIL_INFO_DTCONT" : "궐리사 부터 물향기 수목원을 거쳐 지곳동과 가장동까지 노선이이어진다. 고도가 낮으며 지세도 험하지 않다.", + "MNTN_HG_VL" : "86", + "MNTN_LOCPLC_REGION_NM" : "경기도 오산시 신장동", + "MNTN_NM" : "여계산" }, - "longitude" : 129.16957690000001, - "latitude" : 37.107853800000001 + "longitude" : 127.0386111, + "latitude" : 37.173611100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "동상면 대아리 저수지의 우암교에서 은천리 계곡을 따라 2.1Km 지점에 이르면 거대한 암벽과 숲과 계곡과 반석 그리고 소(沼)로 선경을 이룬 곳이 있으니 고종황제도 이곳의 경치가 너무나 황홀하여 머물러갔다는 데서 그 이름 '왕재'라고 하는 곳이다.중수봉은 높지 않으며 바로 옆에 붙은 삼정봉의 바위들을 빼면 험한 길도 없고 능선이 완만해서 산책 삼아 오르기에 알맞은 곳이다. 삼정봉으로 이어지는 능선길과 3개의 봉우리를 잇는 암릉지대가 등산의 진수를 느끼게 해주는 산이기도하다. 은천리 계곡의 왕재에서 동쪽 중수골 계곡을 타며 산세를 조망할 수 있다.이 산의 계곡과 은천리 계곡 일대는 감나무골로 가을 단풍과 함께 주렁주렁 매달린 감나무들로 더 한층 가을의 정취를 물씬 풍겨주고 있으며 특히 이 고을 감은 씨가 없고 그 맛이 꿀과 같아 한 때는 임금님께 바치는 진상품으로서의 역사를 간직하고 있다고 한다.또한 인근에 대아자연휴양림이 있어 휴양림에 텐트를 친 후 이 산에 올랐다 내려오는 식으로 두 곳을 연결해 산행하는 것이 좋다. 그래서인지 조용하게 오붓한 시간을 보내려는 가족들이 많이 찾는다. 이곳을 찾는 사람들은 편안함과 화려함을 떠나 가장 기본적인 것만을 갖춘 채 함께 지내는 동안 가족간의 애정이 더 돈독해지는 것을 느끼게 된다고 한다.", - "MNTN_HG_VL" : "548", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 동상면", - "MNTN_NM" : "중수봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1060", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 진안군", + "MNTN_NM" : "성수산" }, - "longitude" : 127.34527780000001, - "latitude" : 35.9697222 + "longitude" : 127.4813889, + "latitude" : 35.721388900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "중왕산은 해발 1376미터로 정선읍 북서쪽으로 평창군과 경계를 이루며 우측 해발 1560미터의 가리왕산과 함께 고산의 면모를 충분히 보여주는 산이다. 주왕산이라고도 한다.태백산맥의 지붕 역할을 하는 높은 산으로 주변에는 백석산(1,365m)·청옥산(1,256m)·가리왕산(1,561m)·중봉(1,433m)·하봉(1,380m) 등의 높은 산을 비롯하여 정선 소금강, 화암약수, 정선 아우라지, 화암종유굴 등의 명승지와 가리왕산 자연휴양림이 있다. 가리왕산(1,561m)과는 능선으로 이어져 있어 같은 산으로 보기도 한다.능선이 끝없이 펼쳐진 초원지대로 육중하고 당당하며 자작나무와 주목이 군락을 이루고 있다. 5월 하순께에는 산기슭 곳곳에 취나물, 두릅 등 수십 종의 산나물이 돋아나 산행의 즐거움을 더해준다.", - "MNTN_HG_VL" : "1376", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 진부면, 정선군", - "MNTN_NM" : "중왕산" + "DETAIL_INFO_DTCONT" : "행정구역상으로 인천광역시에 속해 있는 백령도는 서해 최북단에 위치한 섬이다. 과거에는 안보상의 이유로 출입통제가 심했으나 현재는 비교적 자유로워졌고 쾌속여객선이 취항을 시작한 이래 해상관광명소로 급부상 하게 되었다. 백령도에는 산이라고 해야 해발 150m를 넘지못하는 산이 네댓 개 있을 뿐이다. 게다가 그 중에서도 가장 높은 북포리의 업죽산은 산행금지구역이고, 기껏해야 백고지와 용기원산, 그리고 두무진산이 전부이다.", + "MNTN_HG_VL" : "136", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군 백령면", + "MNTN_NM" : "용기원산" }, - "longitude" : 128.52379479999999, - "latitude" : 37.463714899999999 + "longitude" : 124.7436111, + "latitude" : 37.959444400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "용문산, 백운봉, 도일봉과 더불어 웅장한 절경을 이루어 경기의 금강산이라 불리기도 하는 중원산은 경기 양평 용문면과 단월면의 경계에 있는 산이다.주능선의 왼쪽에 용계계곡과 오른쪽에 중원폭포, 중원계곡을 끼고 있는데, 중원폭포 계곡은 머루와 달래밭으로 유명하며, 봄이면 철쭉·금낭화가 피고, 가을이면 약초와 야생과일이 많이 난다. 계곡사이로는 기암이 늘어서있고 울창한 숲 사이로 맑은물이 흘러내려온다. 계곡, 암봉과 함께 중원산에서 빼놓을 수 없는 것은 머루, 다래밭이다.산행은 중원리에 있는 주차장에서부터 시작한다. 계곡을 따라 중원폭포와 치마폭포를 지나 갈림길에서 왼쪽길로 작은 계곡을 지난다. 너들고개가 나오면 왼쪽 능선으로 정상에 오른다. 정상에 서면 동쪽으로 도일봉, 서쪽으로 용문산이 가깝게 보인다.", - "MNTN_HG_VL" : "800", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 용문면, 단월면", - "MNTN_NM" : "중원산" + "DETAIL_INFO_DTCONT" : "한석산(1,103)은 내설악 인근의 삼형제봉,가리봉,으로 연결되는 산으로 등산객에게는 많이 알려지지 않은 미지의 산이다. 삼형제봉,가리봉은 험준한 바위들로 이루어져 일반등산객들이 사전지식없이 산행하기에는 무리가 있어 조심해야 하며 주변에 내린천이 있어 래프팅등 모험관광을 동시에 즐길수 있으며 대부분의 코스가 당일 산행이 가능하다.인제군은 오래전부터 이곳에 스키장등 대단위 관광지로 개발하려고 하고 있으나 아직까지 가시적 성과없이 지지부진한 상태이다.한석산의 한모퉁이 내린천 변에는 6.25당시 이땅을 지키기 위한 우리 국군 용사들의 넋을 기리기위해 1990년 11월 매봉 한석산 전적비가 세워졌다.당시 한석산에서는 국군들이 치열한 전투끝에 8백95명의 적군을 사살하고 42명의 포로를 생포하였으며 3일간의 치열한 전투끝에 매봉과 한석산을 탈환하는 전과를 얻었으나 이과정에서 국군 72명이 전사하고 3백19명이 전사하여 이를 기리기위해 8백여평의 부지에 높이 8.1m의 화강암 석탑으로 6.25당시 참전부대인 9사단 30연대를 상징하기 위하여 탑을 9단으로 쌓았으며 탑의 원형도 30각도로 조성한 것이 특징이다", + "MNTN_HG_VL" : "1103", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", + "MNTN_NM" : "한석산" }, - "longitude" : 127.60196449999999, - "latitude" : 37.559491399999999 + "longitude" : 128.25588619999999, + "latitude" : 38.051582499999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "일명 `찌걱산'이라 불리는 지각산은 삼척시 하장면에 있는 오지의 산이다. 부근에 광동댐이 들어서면서 일부 훼손된 부분이 있으나 광동호와 인접해 있는 이 산의 경관은 지나가는 사람들의 발길을 붙잡기에 충분하다. 특히 광동댐 관리사무소가 들어선 능선부근은 남녀가 마주치면 그냥 지나치지 못하고 꼭 일이 생긴다는 말이 전해질 만큼 계곡 경관이 수려하다.지각산 동쪽 깎아지른 절벽에는 설패바위, 촛대바위,금강문 등 수많은 기암이 하늘을 찌를 듯이 솟아 선경을 이루는 별유천지이다. 건너편 미륵봉 밑에는 천연기념물 178호로 지정된 환선동굴이 있으며 황금색 종유석, 석순 폭포 등 기묘한 현상으로 감탄을 금치 못한다.", - "MNTN_HG_VL" : "904", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", - "MNTN_NM" : "지각산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "663", + "MNTN_LOCPLC_REGION_NM" : "경상남도 밀양시 청도면 구기리", + "MNTN_NM" : "열왕산" }, - "longitude" : 128.96111110000001, - "latitude" : 37.333055600000002 + "longitude" : 128.5953988, + "latitude" : 35.541475000000013 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "지등산은 충북 충주시 동량면에 위치한 산으로 천등산, 인등산과 함께 3등산의 하나이다. 정상 부근은 뾰족하고 높아 이름과는 어울리지 않는 형세를 하고 있다. 산세가 특별히 아름답거나 비경을 감추고 있지만 않지만 흙으로 된 육산으로 숲이 우거져 있어 나름대로의 매력을 지닌 산이다.그러나 산세가 특별히 내세울 것이 없다보니 사람들의 관심에서 잊혀진 산이었다. 그로인해 사람들의 발길이 뜸하다보니 지등산은 깨끗한 자연환경을 간직할 수 있었고 원시림과 같은 참신한 맛을 느낄 수 있다. 우거진 숲 사이로 불어오는 청량한 바람은 건강에도 많은 도움이 되어 산행의 값을 한층 높여준다. 산 아래에는 충주호와 충주댐이 있다.정상에 서면 북쪽으로 인등산, 남동쪽으로 충주호·계명산이 보이고, 동쪽으로 관모봉(641m)이 능선을 따라 이어져 있다.", - "MNTN_HG_VL" : "535", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 동량면 조동리", - "MNTN_NM" : "지등산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "441", + "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 상운면 문촌리", + "MNTN_NM" : "비봉산" }, - "longitude" : 127.9875262, - "latitude" : 37.017703300000001 + "longitude" : 128.79523180000001, + "latitude" : 36.839934399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "행정구역은 통영시지만 삼천포 앞 바다에 떠 있는 사량도에 있는 산으로 다도해 풍정이 물씬나는 한려해상국립공원에 자리잡고 있다. 우리 나라에서 대표적인 지리산과 이름이 같지만 원래 이름은 지이망산이다. 지리산이 바라보이는 산이란 뜻을 가졌다가 부르기 쉽게 줄여 육지의 지리산과 같은 이름으로 쓰이고 있다로 한다.3개의 유인도와 8개의 무인도로 이루어져 있는데, 주섬인 윗섬(상도)과 아랫섬(하도) 사이가 마주보고 그리 멀리 떨어져 있지 않아 호수처럼 잔잔하며, 윗섬의 중앙을 가로지르는 지리산, 불모산, 가마봉, 옥녀봉이 능선으로 연결되어 함께 산행을 할 수 있다. 지리산이나 옥녀봉만을 오를 수도 있고, 지리산부터 옥녀봉까지 종주할 수 있다. 옥녀봉의 암릉은 전설만큼이나 처절하리만치 빼어난 산세를 지니고 있어, 설악산의 용아릉을 연상케 할 만큼 기암괴봉과 경치가 뛰어난 곳이다. 바다와 산을 함께 즐길 수 있는 산행으로 재미를 더해 주지만 암봉, 고암릉으로 이어지는 능선길이 다소 험하다. 그러나 위험코스에는 우회코스가 있으며 등산로가 잘 정비되어 있고 안내표지가 잘되어있다. 초보자는 가급적 우회코스로 산행을 하고 세심한 주의가 필요하다.사량도의 8개 섬 중 상도(上島)에 동서로 길게 뻗은 산줄기 중 돈지리쪽의 제일 높은 봉우리로서, 한려수도의 빼어난 경관과 어우러져 '한반도 남단 최고의 비경'으로 꼽힌다. 산이름은 '지리산이 바라보이는 산'이란 뜻으로, 현지에서는 부르기 쉽게 줄여서 흔히 지리산이라고 한다. 바위산으로서 불모산(佛母山:399m)·가마봉(303m)·향봉(香峰)·옥녀봉(玉女峰:281m) 등과 연봉을 이루고 있어 함께 산행을 할 수 있는데, 높이는 낮아도 정상부의 바위산이 기암괴석을 형성하고 있으며 조망도 좋고 기묘한 바위능선으로 유명하다. 기암절벽과 경치가 뛰어난 옥녀봉에는 자기 딸에게 욕정을 품은 아버지와 그 딸 옥녀의 전설이 전해내려오고 있다. 사량도는 섬이 뱀처럼 생기고, 또 뱀이 많다고 해서 붙여진 이름이다.", - "MNTN_HG_VL" : "398", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면 (사량도)", - "MNTN_NM" : "지리산" + "DETAIL_INFO_DTCONT" : "흑석산은 해남과 영암을 남북으로 가르는 산으로 호남정맥이 땅끝으로 가기 전 월출산과 두륜산 사이에 솟아 있다. 인근의 월출산이 남성, 두륜산이 여성의 이미지를 풍기는 산이라면 흑석산은 중후한 중년 신사 같은 산이다.「동국여지승람」에서 가학산(駕鶴山)으로 표기되어 있으나 「대동여지도」에는 가학산과 흑석산(깃대봉)으로 표시되어 있다. ‘가학’은 학이 날지 못하도록 학 앞에 멍에 가를 씌운 풍수지리상 비보(裨補)의 의미를 담고 있다. 또 ‘흑석’은 바위의 색깔이 검어 유래된 것으로 비가 올 때 물을 머금은 흑석산의 모습은 실제로도 검다. 강진 성전면 제전마을에서 올려다 본 산은 ‘밤하늘의 별처럼 아름답다’고 해서 별뫼산으로 불리지만 혹은 별매산으로 종종 혼용되어 표기한다. 해남군이 세운 이정표에는 별뫼산으로 적고 있어 산이란 뜻의 ‘뫼’로 풀이하면 무리가 없을 듯하다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면, 학산면", + "MNTN_NM" : "흑석산" }, - "longitude" : 128.18587239999999, - "latitude" : 34.8472443 + "longitude" : 126.633217, + "latitude" : 34.675793599999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "\"환상의 섬\"사량도 그 중간에 우뚝솟은 또 다른\"지리산\"(399.3m) 힘겹게 오른 옥녀봉서 바라보는 한려수도와 하산후의 싱싱한 회맛 눈과 입이 즐겁다 환상의 섬! 사량도가 더욱 아름답게 새로이 태어났다.감추어졌던 사량도의 비경들이 이제 수많은 산꾼들과 여행자들에게 흐뭇하게 그 매혹적인 자태를 드러내게 된 것이다. 통영시에서 펼친 관광개발로 대항해수욕장이 조성되고 여객선 터미널이 새롭게 단장되고 위험했던 등산로가 야무지게 정비되는 등 찾는 이들의 안전과 편의를 개선하여 사량도는 수많은 관광객들로 붐비고 있다.사량도는 통영시 사량면에 해당하는 섬으로 우리나라 남단 다도해 한려해상공원에 둘러싸인 아름다운 섬이다. 사량도는 섬 자체가 뱀 모양으로 생겼고 뱀이 많다고 해서 붙인 이름이라 하는데, 한 남자가 이룰 수 없는 사랑에 괴로워하다 상사병으로 죽어뱀이 되었다는 이야기도 전해온다.삼천포시 앞바다의 잔잔한 물결을 가르고 사량도 상도에 도착하면 섬 가운데 우뚝 솟은 지리산을 볼 수 있다.본래는 우리에게 잘 알려져 있는 전라도와 경상도에 걸친 장대한 지리산이 바라다보여 「지이망산」이라 불리다가 그 말이 줄어 「지리산」이 된 것이다. 높이는 얼마되지 않지만 한려수도의 빼어난 경관과 어우러져 그 어느 명산 못지 않게 절묘한 경관을 간직하고 있다.산에 오르는 길은 여럿 있으나 돈지포구를 시발점으로 지리산 옥녀봉을 거치는 능선을 타고 진촌으로 빠지는 코스를 택하는 것이 이 산의 진면목을 가장 잘 즐길 수 있는 방법이다.돈지는 수려한 경관의 바위산과 푸른 물살이 넘실대는 바다를 배경으로한 한폭의 그림같은 순박한 섬마을이다. 마을을 빠져나와 산을 오르기 시작하면 돌밭길이 나오는데 시야에 들어오는 바다 풍경 덕에 돌길이 지루하지 않고 아기자기하기만 하다. 행여 주위 경관에 시선을 빼앗겨 발이라도 헛디딜까 걱정이 될 정도다.", - "MNTN_HG_VL" : "399", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량면", - "MNTN_NM" : "지리산(통영)" + "DETAIL_INFO_DTCONT" : "뛰어난 풍광으로 우암 송시열이 낙향하여 머물던 화양구곡 중앙부에 위치한 도명산은 국립공원 속리산에 속하여 있으며 태고의 신비와 자연의 오묘한 섭리를 안고 있는 산이다. 첨성대 바위, 흔들바위 등 자연이 빚어낸 기묘한 형태에 기암과 암릉(岩陵)이 곳곳에 산재해 있으며 특히 정상부를 차지하고 있는 기암 덩어리인 정상 바위는 가히 일품이라 할 수 있다.정상은 크고 작은 바위 다섯 개가 하나로 정상을 이루고 있다. 정상에서의 조망은 북쪽 아래로는 화양동 계곡과 군자산, 칠보산이 펼쳐지고, 동쪽으로는 대하산, 남쪽으로는 낙영산, 주봉산, 멀리 속리산 능선과 문장대가 들어온다. 주변에는 분재처럼 자란 소나무가 정취를 더한다. 화양동계곡은 기암괴석으로 이뤄진 절경이 아홉 곳이나 된다고 해서 '화양구곡'(華陽九曲) 또는 '화양동 소금강'으로 불린다. 이곳은 경치가 너무 아름답고 물이 맑아 조선시대의 조선조 대유학자였던 우암 송시열 선생이 조정을 물러나와 은거하던 곳으로도 유명하다.이곳에 반한 조선 후기의 유학자 우암 송시열은 화양동주(洞主)로서 은거하며 이곳이 중국의 무이구곡을 닮았다 하여 9곡의 이름을 짓고 경천벽·금사담\\·첨성대 등의 바위에 글씨를 새겼다.제1곡 경천벽은 깎아지른 층암절벽이 하늘을 떠받치고 있으며, 화양2교 옆의 2곡 운영담은 구름이 비치는 담 주변에 넓은 모래사장이 있다. 3곡은 우암이 새벽에 올라 효종의 승하를 통곡했다는 읍궁암으로 민박집과 식당이 많다. 서원철폐의 빌미가 된 화양서원을 거쳐 하마소와 채운사 등의 명소가 있다.제일 수려한 4곡 금사담은 금모래가 반짝이며 넓은 암반 위에 우암의 암서재가 노송 사이에 있다. 화양3교 직전 바른쪽 낙영산 정상의 기암절벽인 5곡 첨성대는 별을 관측하던 곳이다. 더 가면 심곡에 큰 2층바위인 6곡 능운대가 나오며 7곡 와룡암, 8곡 학소대, 9곡 파천이 있다.", + "MNTN_HG_VL" : "642", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 청천면", + "MNTN_NM" : "도명산" }, - "longitude" : 128.18587239999999, - "latitude" : 34.8472443 + "longitude" : 127.8167474, + "latitude" : 36.652938800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "정선의 지억산은 민둥산에 가려진 산이다. 민둥산이 가을 억새로 워낙 유명하다 보니 지척의 지억산은 민둥산 산행 중 지나치는 산 정도로 알려져 있다. 산 족보로 따지면 지억산은 백두대간 금대봉에서 뻗어 나온 산줄기다. 이 산줄기를 산꾼들은 소위 ‘정선지맥’이라 부르며 지맥 주능선상에 지억산이 있다. 민둥산은 지억산에서 갈래 쳐진 산이니 지억산이 모산이다.지억산에서 민둥산은 2.6킬로미터 거리로, 1시간 10분 정도 밖에 걸리지 않아 당일 코스로 연결해도 무리가 없다. 높이는 거의 비슷한 편이며 민둥산이 1117.8미터로 1.1미터 높다. 그러나 지억산 정상에는 억새지대가 없으며 등산인들의 발길도 뜸한 편이다. 정상에는 철망에 둘러쳐진 태양열 전지가 있으며 표지석에는 ‘몰운산’이라 적혀있다. 인근 몰운대와 몰운리라는 지명에서 온 산 이름인 듯하다. 국토지리정보원 지형도를 보면 유명한 민둥산조차 이름이 없지만 지억산만큼은 선명히 표기되어 있다. 지억산의 한문 표기를 해석해 보면 영지와 같은 평평한 버섯으로 추정되는데 산행길 역시 평탄하고 정상부의 모양새도 봉긋하다.", - "MNTN_HG_VL" : "1117", - "MNTN_LOCPLC_REGION_NM" : "강원도 정선군 동면ㆍ남면", - "MNTN_NM" : "지억산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "295", + "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", + "MNTN_NM" : "와룡산" }, - "longitude" : 128.78374719999999, - "latitude" : 37.290074300000001 + "longitude" : 128.51053659999999, + "latitude" : 35.869378900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "189", - "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", - "MNTN_NM" : "지적산" + "DETAIL_INFO_DTCONT" : "두타산은 진천군 초평면, 괴산군 도안면과 증평읍의 경계를 이루고 있으며, 능선이 마치 부처가 누워있는 모습을 하고 있다. 진천의 상산8경 중 하나인 고찰 영수사를 산자락에 품고 있으며 은은한 종소리와 함께 아름다움을 간직한 명산으로 손꼽힌다.두타산 정상엔 삼국시대에 축조된 것으로 추정되는 석성이 자리하고 있는데, 길이 1킬로미터, 높이 1.2미터의 규모로 성내에는 두 개의 우물터가 있으며, 이따금 통일신라시대의 토기편과 기와 조각 등이 발견 되고 있으며 고려 시대의 유물도 출토된 적이 있다.두타산이란 산 지명은 단군이 팽우에게 높은 산과 냇물 등 산천을 다스리게 했는데, 그때 하루도 빠짐없이 비가 내려 온 산천이 모두 물에 잠기게 되자 사람들이 높은 곳으로 피난을 가야했다. 이때 팽우는 이 산에 머물게 되었고 산꼭대기가 섬처럼 조금 남아 있었다고 하여 두타산이라 이름 지었다고 한다.두타산의 산행기점은 진천 쪽 초평저수지에서 영수사를 거쳐 오르는 길과 대평주유소 전 동잠교에서 계곡을 따라 큰재로 오른 후 북동쪽 능선을 타고 정상에 오르는 길이 자주 이용된다. 이외에 증평읍 자양마을에서 오르는 길이 있지만 접근이 어렵고 능선을 넘어 다시 계곡으로 떨어져야하므로 거의 이용되지 않고 있다.", + "MNTN_HG_VL" : "599", + "MNTN_LOCPLC_REGION_NM" : "충북 진천군 초평면, 괴산군 도안면, 증평읍", + "MNTN_NM" : "두타산" }, - "longitude" : 126.41, - "latitude" : 34.828888900000003 + "longitude" : 127.5661554, + "latitude" : 36.830412799999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "금산읍 시내에서 남서쪽을 가로 막고 솟아 있다. 서대산, 계룡산에 이어 충청남도에서 세번째로 높은 산으로 주능선에 기암괴봉이 많고 숲이 무성하다.산자락에는 고찰 영천암과 영천약수·보석사·선공암·원효암·봉화대·관음암·관음굴·원효폭포 등 명소가 많고, 보석사 입구에는 전나무 숲과 수령 약 1000년의 은행나무(천연기념물 365)가 있다. 남이면에는 인삼시장이 서고, 금성면에서는 임진왜란 당시 왜적과 싸우다 옥쇄한 7백인의 충혼이 깃들인\"\"칠백의총(사적 제105호)을 찾아 선열들의 깊은 뜻을 새겨볼 수 있어 가족동반 코스로도 적당하다.산행은 금산읍 계진리 마을회관 앞에서 시작한다.계곡길을 따라 선공암과 빈대바위 옆을 지나 능선길을 오르면 정상이 나온다.정상에서 동쪽을 내려다 보면 수십길 깎아지른 절벽이 아찔하다. 서북쪽으로는 대둔산이 하얀 구름띠를 허리에 감고 다가오고 서대산의 기암절벽도 위용을 자랑하며 자태를 뽐낸다. 남쪽으로는 운장산과 구봉산이 마치 형제인양 맞붙은 모습으로 시야에 들어온다.", - "MNTN_HG_VL" : "732", - "MNTN_LOCPLC_REGION_NM" : "충청남도 금산군 금산읍", - "MNTN_NM" : "진락산" + "DETAIL_INFO_DTCONT" : "장안산은 장수군과 함양군의 경계선에 있는 백두대간상의 영취산에서 서쪽으로 갈라진 호남정맥의 첫머리에 솟아 있는 기봉이다. 기봉인 장안산에서 섬진강과 금강을 경계로 호남지방과 호서지방까지 뻣어 국토의 약 25%를 점유하고 풍요로운 강산을 이루고 있는 조산, 영산이기에 더욱 아름답게 가꾸어 나가야 한다. 장안산은 이 산맥에 솟아 있는 산중에서도 제일 높고 호남,지방에서는 지리산 덕유산 남덕유산에 이어 4번째로 높은 산이다.이 산은 1986년에 군립공원으로 지정되었다. 기암괴석과 울창한 원시수림을 자랑하는 장안산은 덕산용소와 방화동, 지지계곡 지구로 나뉘어져 아름다운 절경을 이루는 관광지다.", + "MNTN_HG_VL" : "1237", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 장수읍, 계남면", + "MNTN_NM" : "장안산" }, - "longitude" : 127.45882520000001, - "latitude" : 36.077696000000003 + "longitude" : 127.5959075, + "latitude" : 35.629946500000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "진악산은 해발 737미터로 충남에서 네 번째로 높은 산이다. 주릉에 펼쳐지는 기암괴석의 경관이 아름다우며 금산 쪽으로 깎아지른 듯한 낭떠러지는 장엄하기까지 하다. 진악산을 감싸고 있는 숲도 무성하며 영천암과 원효암 골짜기의 개울도 좋다. 특히 진악산 북편 관음봉 일대의 암애와 암봉들, 원효암 일대의 기암괴석과 폭포는 일품이다. 명물, 명소로는 보석사 입구에 전나무숲과 천연기념물 365호인 1100년 수령의 은행나무가 있고, 천년사찰 보석사와 영천암, 원효암이 있으며 이밖에 영천암의 영천약수, 도구통바위, 봉화대, 관음암과 관음굴, 원효폭포, 물골의 바위굴은 명소로써 훌륭한 가치를 지니고 있다.진악사 정상에서는 속리산과 서대산, 천태산, 민주지산, 덕유산의 장쾌한 산줄기를 모두 볼 수 있으며, 운장산의 특이한 모습도 보이고 계룡산도 눈에 띈다. 옛날부터 나라의 안위를 봉화로 알리는 봉화대가 있었으며, 조선시대 임진년 8월(1592년) 금산벌 싸움에서 중봉 조헌 선생과 함께 싸우다 순국하신 기허당 영규대사는 진악산 남쪽 기슭에 있는 보석사에서 수도를 했고 그 인연으로 보석사내의 의선각에 영규대사의 영정이 모셔져 있으며 보석사 들머리에 영규대사의 충혼을 기리는 위병 승장비가 세워져 있다.", - "MNTN_HG_VL" : "732", - "MNTN_LOCPLC_REGION_NM" : "충남 금산군 금산읍", - "MNTN_NM" : "진악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군", + "MNTN_NM" : "백마산" }, - "longitude" : 127.45882520000001, - "latitude" : 36.077696000000003 + "longitude" : 127.96885260000001, + "latitude" : 35.322628600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "질운산 산행은 대체적으로 힘들지 않다. 직동리 큰 터 삼거리, 직동만물슈퍼와 담배집이 산행들머리이다. 한밭골 자동차 길을 따라 40분에 효자각에 이르고, 오른쪽으로 효자각이 있는 골로 들어, 계속 광산길로 천천히 1시간 40분쯤에 새비재가 있다. 중간중간 샛길이 있으나 자동차 바퀴자국을 유심히 살피고 따르면 실수없을 것이다.새비재 고랭지 밭에는 10비터 높이의 전주만 있는데 정상으로 가는 주능선 앞에 20미터 높이의 전주가 있다. 정상은 40분 소요. 하산은 동쪽 주능으로 30분에 넓은 자운동 안부이다. 이곳에서 남쪽 광산길로 15분에 삼거리 왼쪽 길로 계속 구불구불 광산터, 붉은절벽, 폐광굴(폐쇄)를 지나며 오른쪽을 유심히 살피면 삼지창 같은 소나무를 발견할 수 있다. 여기서 오른쪽 상막골로 내려선다. 자운동 안부에서 삼지창 소나무까지 약 1시간 20분 걸린다. 총 산행시간은 6시간 30분에서 7시간 소요된다.", - "MNTN_HG_VL" : "1172", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 중동면, 정선군 신동읍", - "MNTN_NM" : "질운산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "775", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "계명산" }, - "longitude" : 128.71722220000001, - "latitude" : 37.196111100000003 + "longitude" : 128.93972220000001, + "latitude" : 36.420833299999998 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "578", - "MNTN_LOCPLC_REGION_NM" : "경상남도 진주시", - "MNTN_NM" : "집현산" + "MNTN_HG_VL" : "353", + "MNTN_LOCPLC_REGION_NM" : "경상남도 김해시", + "MNTN_NM" : "백두산" }, - "longitude" : 128.03420779999999, - "latitude" : 35.3133531 + "longitude" : 128.96777779999999, + "latitude" : 35.254444399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "쫓비산은 광양 다압면 매화마을을 둘러싸고 있는 산이다. 이름이 특이한 쫓비산은 인근 주민들에게 그 뜻을 물어도 명확한 답을 아는 이가 없다. 다만 형태가 뾰족해 사투리 ‘쪼삣’에서 유래했다는 설도 있고 섬진강의 푸른 물줄기에 빗대어 맑은 하늘이란 뜻의 ‘쪽빛’에서 유래된 이름이라는 설도 있다.쫓비산은 광양 매화마을을 둘러싸고 있는 산으로, 호남정맥 백운산에서 갈래 쳐진 산이며 섬진강을 끼고 앉은 산이다. 섬진강 550리 유장한 먼 굽이를 돌아나와 전라도와 경상도의 경계를 지으며 남해로 흘러드는 곳, 호남정맥이 끝나는 백운산 동편 산줄기에 솟은 것이 갈미봉 쫓비산 자락이다.쫓비산 하면 단연 매화꽃이 유명하다. 산 입구의 청매실농원은 매화꽃 만발해 축제가 열리는 봄이면 관광객들과 등산객으로 메워진다. 매화꽃이 유명하지만 능선으로 들면 진달래와 철쭉이 지천이다. 꽃의 개화 시기는 차이가 있어 산기슭의 매화꽃이 지면 바통을 이어받아 산등성이의 진달래와 철쭉이 핀다.", - "MNTN_HG_VL" : "537", - "MNTN_LOCPLC_REGION_NM" : "전남 광양시 진상면", - "MNTN_NM" : "쫓비산" + "DETAIL_INFO_DTCONT" : "삿갓봉은 백두대간의 주맥이 갈라져 나와 백적산을 세우고 청옥산을 일구며 강원도 평창 남서쪽으로 산세를 뻗쳐 솟아오른 산이다. 삿갓모양으로 우뚝 서 있어 삿갓봉이라 불리는데, 백운산, 응봉, 매봉 등과 마찬가지로 전국에 똑같은 이름의 산들이 곳곳에 산재해 있어 우리에게 친근하게 느껴지는 산이기도 하다.강원도 평창군의 삿갓봉은 강원도의 산들이 대개 그렇듯이 첩첩산중 오지 중에 오지로, 산세가 험하고 골이 깊기로 유명하다. 사람의 발길이 얼마 닿지 않아 울창한 산림이 그대로 보존되어 있고, 작은 벌레가 바스락거리는 소리까지 들릴 정도로 주변이 조용하여, 쾌적하고 여유로운 산행을 즐기기에는 안성맞춤인 산이다. 1천미터 이상의 기암괴석들이 봉우리를 이룬 정상에 오르면 북쪽으로 남병산, 남쪽으로 삼방산, 동쪽으로 청옥산, 그리고 서쪽으로는 장암산 등이 손에 잡힐 듯 조망되어 산행의 즐거움을 한껏 느낄 수 있는 산이다.", + "MNTN_HG_VL" : "400", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍, 미탄면", + "MNTN_NM" : "삿갓봉" }, - "longitude" : 127.6977778, - "latitude" : 35.07 + "longitude" : 128.53, + "latitude" : 37.343333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "542", - "MNTN_LOCPLC_REGION_NM" : "강원도 화천", - "MNTN_NM" : "창안산" + "DETAIL_INFO_DTCONT" : "정읍에서 약 12킬로미터 떨어진 곳으로 갑오동학혁명의 진원지인 고부면 신중리 죽산마을에 동학혁명모의탑이 세워져 있다. 정읍시는 동학농민운동의 시발 지이자 주요무대다. 특히 고부면은 동학농민운동의 진원지로 모의탑이 세워져 있다. 덕천면의 황토현 전적지(사적 295)를 중심으로 고부관아터, 만석보터, 전봉준 고택지(사적 293) 등 많은 관련 유적이 있다.이 산은 정읍시와 고창군 일대는 물론 내장산, 방장산, 입암산 등 명산이 한눈에 들어오는 확 트인 전망이 유명한 산이다. 정상에는 넓은 공간에 큰 바위와 나무와 초지가 서로 어우러져 휴식을 취하기에 좋다.두승산 이름의 유래는 옛날 고부관아에서 도량형의 기준이 되는 말(斗)과 되(升)를 돌로 만들어 고부군의 진산인 이 산의 남쪽 봉우리(말봉) 바위 위에 설치해 놓았다. 이후 사람들은 이 산을 ‘말과 되가 있는 산’ 이라 하여 두승산이라 부르게 되었다.정상부에는 작은 봉우리가 몇 개 있는데, 세 번째 봉우리가 정상이고 네 번째 봉우리가 말봉이다. 두승산 주위로는 동학혁명에 관한 역사 유적지가 많다. 특히 고부면은 동학농민운동에 앞장선 전봉준 고택지(사적 293) 등 많은 관련 유적이 있어 산행 후 역사 공부를 겸해 둘러봄직 하다.", + "MNTN_HG_VL" : "444", + "MNTN_LOCPLC_REGION_NM" : "전라북도 정읍시 고부면ㆍ덕천면ㆍ소성면", + "MNTN_NM" : "두승산" }, - "longitude" : 127.5457596, - "latitude" : 38.103257200000002 + "longitude" : 126.7980117, + "latitude" : 35.606852199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "죽산현감(竹山縣監)을 지낸 채씨(蔡氏)의 묘가 있는 산이라는 데서 유래하였다. 채죽산의 서쪽으로는 유구천이 흐르고 있는 넓은 충적 평야인 우성농조들이 위치해 있다.남쪽의 산등성이가 끝나는 곳에 부엉산이 있으며, 바로 금강으로 이어진다.", - "MNTN_HG_VL" : "177", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", - "MNTN_NM" : "채죽산" + "DETAIL_INFO_DTCONT" : "한남정맥과 갈라진 산줄기가 북쪽으로 태화산(645m) 백마산(530m) 줄기를 떨구고 동북진하여 광주와 이천을 잇는 넓고개를 건너 솟구친 산이 바로 원적산이다. 무적산(無寂山)이라고도 한다. 동쪽 원적봉(563.5m) 기슭에 638년(선덕여왕 7년)에 창건했다는 영원사(靈源寺)라는 사찰이 있으며, 주봉인 천덕봉 기슭에는 율수폭이라는 폭포가 있다. 고려말 공민왕이 난을 피해 이곳에 머물렀다는 전설이 전한다. 신둔면 장동리 쪽에는 군사훈련장이 있어 입산이 제한되므로 산행은 백사면 경사리 쪽에서 시작한다.전체적인 능선이 부드럽고 완만해 보이지만 산 천덕봉 안쪽으로 암벽이 있으며 이 산의 최고봉인 천덕봉은 높이 635m로 이천군내에서 제일 높다. 산행기점인 송곡마을은 전국 제일의 산수유 산지로 봄이면 농가울타리와 논밭두렁이 산수유의 노란 물결로 일렁이고 가을이 되면 들 곳곳에서 열매를 따는 풍요로운 풍경이 등반객들의 마음을 넉넉하게 채워준다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.", + "MNTN_HG_VL" : "564", + "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 백사면, 광주군 실촌면", + "MNTN_NM" : "원적산" }, - "longitude" : 127.0961111, - "latitude" : 36.474444400000003 + "longitude" : 127.4489854, + "latitude" : 37.351347400000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산이 바위로 이루어져 봉우리마다 하늘을 찌를 듯 솟아있는 천관산은 지리산, 월출산, 내장산, 내변산과 함께 호남의 5대 명산중 하나다.아기바위, 사자바위, 종봉, 천주봉, 관음봉, 선재봉, 대세봉, 석선봉, 돛대봉, 구룡, 갈대봉, 독성암, 아육탑 등을 비롯 수십개의 기암괴석과 기봉이 꼭대기 부분에 비죽비죽 솟아 있는데, 그 모습이 주옥으로 장식된 천자의 면류관 같다하여 천관산이라 불렀다고 한다.", - "MNTN_HG_VL" : "724", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장흥군 관산읍, 대덕읍", - "MNTN_NM" : "천관산" + "DETAIL_INFO_DTCONT" : "양평군 단월면의 가장 북쪽에 위치한 소리산은 강원도 홍천군과 접경을 이루는 경기도의 오지이다. 소리산은 주변의 산에 비해 큰 산은 아니지만 깎아지른 듯한 바위절벽과 기암괴석, 맑은 계곡이 어울려 예로부터 산음리 소금강이라 일컬어질 만큼 빼어난 경관을 지니고 있다. 예부터 산 속에 바위벼랑에 수리가 서식했다고 하여 수리산으로 부르다가 소리산으로 바뀌었다는 이야기가 전해진다. 인근 봉미산과 종자산이 육산인 것과 달리 소리산 정상부는 바위로 이루어져 있다.특히 산음리와 석산리 사이에 있는 용소계곡은 기암절벽과 울창한 나무들이 어우러져 한폭의 풍경화를 연상케 한다. 산 전체가 오염되지 않은 신선함과 전형적인 시골 마을의 평화로운 정취로 인해 휴식공간으로 인기가 높다. 가파른 산길을 올라 수리봉에 서면 서쪽 낭떠러지 아래로 펼쳐지는 S라인 산음천의 모습이 가히 소금강다운 아름다움을 보여주고 있다. 매년 3월에는 소리산 고로쇠축제가 열린다.", + "MNTN_HG_VL" : "480", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 단월면", + "MNTN_NM" : "소리산" }, - "longitude" : 126.91597160000001, - "latitude" : 34.532343099999999 + "longitude" : 127.61368330000001, + "latitude" : 37.637732100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 이천군 실촌면과 신둔면을 가르고 선 천덕봉은 마을 뒷산처럼 큰 특징이 없는 평범한 산이다. 남서쪽의 오르막길을 향하다보면 드넓은 이천평야가 시야에 들어오는데 가을녁에 보면 황금색 벌판이 장관을 이룬다.고려말 공민왕이 홍건적의 난을 피해 이곳에 왔다고 하여 공민왕봉이라고도 한다. 원적산에서 가장 높은 봉우리이며 항상 구름과 안개에 싸여 있다. 산속에 신라 선덕여왕 때 혜법선사가 세운 영원사가 있고, 계곡에는 산간 오지마을인 실촌면의 외선리·내선리가 있다. 정상에 오르면 북으로 앵자봉(667m)과 양자산(704m)이 보이고 남으로는 설봉산과 도드람산이 사야에 들어온다.산행길은 대체로 완만한 편이나 천덕봉 정상에서 원적봉까지 육군 사격장지대기 때문에 산행을 하려면 다시 돌아서 남서쪽의 오르막길을 올라야 한다.", - "MNTN_HG_VL" : "630", - "MNTN_LOCPLC_REGION_NM" : "경기도 이천시 실촌면, 신둔면", - "MNTN_NM" : "천덕봉" + "DETAIL_INFO_DTCONT" : "충북 중원 상모면과 괴산 연풍면 그리고 문경읍과 경계를 이루는 마역봉(馬驛峰)은 임진왜란때 신립장군의 한이서린 조령삼관문을 안고 있는 산이다.주말 산행 코스로 인기를 누리고 있는 신선봉(967m) 동쪽 1.5km 거리에 독립봉으로 우뚝 솟은 마역봉은 927m 의 높이에 비해 의외로 쉽게 오를수가 있다. 출발지점인 지릅재가 표고가 해발 650m 이기때문이다.산행의 들머리는 조령삼관문에서 오르거나 신선봉을 경유해도 되고 또 다른 코스는 소조령 3번 국도에서 고사리 마을을 지나 조령산 휴양림 매표소에 도착한 후 매표소에서 삼관문쪽 길을 따라 50m쯤 가면 급커브를 돌면서 왼쪽으로 훤히 뚫린 산길이 보이는데 여기가 신선봉과 마패봉의 중간능선으로 오르는 등산로다.산길을 접어들면 200여미터 거리에 비닐포장 가건물을 지어 놓고 밤낮없이 정성을 드리는 장소가 있는데, 바위 위로는 10여미터 폭포가 흘러내려 장관을 이룬다. 길은 폭포의 오른쪽 반석을 타고 올라 계류를 건너 물길을 따라 오르게 되는데 계곡이 v자 모양의 협곡으로 물이 흐를 때는 장관을 이룬다. 계류 옆으로 난 바위를 따라 조금 더 오르면 왼쪽으로 거대한 바위가 나타나는데 이것이 바로 치마바위이다.바위의 동쪽끝에서 바라보고 있노라면 그 끝자락은 분명히 곱디고운 여인이 치마가 땅에 닿을까봐 조심스레 치마폭을 추스리고 있는 것 같은 모습처럼 느껴진다. 혹시나 여인의 속살이라도 보일 것 같아 겸연쩍어진다. 마역봉은 뚜렷한 정상이 없이 50여미터 더 가면 전망대가 나오는데 월악산을 중심으로 한 북바위, 수리봉, 덕주봉, 만수봉, 포암산등 바위산의 진면목을 보여준다. 단순히 마역봉을 등산하기보다는 신선봉과 함께 등산하는 것이 일반적이다.소요 시간 :약 2시간 20분 소요최적 탐방 시기 : 9월 \/ 가을(단풍)볼거리 : 문경새재, 용유담, 신선봉, 각연사, 고산구곡, 화양동구곡숲길 명소 : 치마바위, 남쪽 계곡의 오솔길", + "MNTN_HG_VL" : "940", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 충주시 상모면", + "MNTN_NM" : "마역봉" }, - "longitude" : 127.4425, - "latitude" : 37.358333299999998 + "longitude" : 128.03113740000001, + "latitude" : 36.753807299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고흥반도 최남단에 솟아 있는 천등산은 겉에서 보면 그냥 커다란 바위산 같지만 오르면서 보면 암릉들이 골고루 세밀하게 나뉜 것이 산행의 재미를 더해준다. 능선에는 상여바위, 암릉지대, 염소바위, 뭉치바위 등이 있고, 능선 곳곳에는 억새 밭이 장관을 이루고 정상 서편 천동마을 위쪽에는 철꾹동산이 잘 조성되어 있다.정상에는 조선조 때의 봉수대 축성이 흐트러져 있고 기우단으로서도 유명한 곳이며, 고흥 반도에서 팔영산에 이어 두 번째로 높은 산이라 남해의 조망이 특히 뛰어나다.정상 동쪽 금사에는 전남 유형 문화재로 지정된 고찰 금탑사의 극락전이 있다. 이 극락전은 삼국시대에 창건된 후로 여러 번 중수되었으나, 조선시대 말기적인 건축 모습을 잘 보여주는 건물로 알려 있다. 절 주변에는 천연기념물 제 2399호로 지정된 비자나무 숲이 유명하고, 이 나무는 신라 선덕여왕 6년에 처음 심어진 것이라 전해오고 있으며 동백나무 거목 군락지도 있다.", - "MNTN_HG_VL" : "550", - "MNTN_LOCPLC_REGION_NM" : "전라남도 고흥군 풍양면, 포두면, 도화면", - "MNTN_NM" : "천등산" + "DETAIL_INFO_DTCONT" : "황조리에서 올라가는 코스는 산 중턱 까지 경사가 심하고 임도구간을 만나면 그길로 임도를 따라 등산로 길이 있다. 마교리에서 올라가는 코스도 산중턱까지는 경사가 심하고 첫번째 봉우리를 지나면 완만한 등산로길이 나온다. 숲길주변을 정비해서 인지 깔끔히 되어 있고 가는길 중간중간 마다 이정표가 설치 되어 있다. 삼척시 도계읍 신리와 항조리 사이에 위치하고 있으며 태백산맥에 속한다. 산정에는 육백산면 이라는 고위 평탄면이 있어 한국의 지형발달을 연구하는데 중요한 지표가 된다.둘레에는 해발 1000m가 넘는 봉우리 십여개가 이 산을 호위하고 있으며 이 산줄기는 근산,응봉산으로 이어져 낙동정맥과 만나 부산 금정산까지 뻗어간다.", + "MNTN_HG_VL" : "1251", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 도계읍 황조리", + "MNTN_NM" : "육백산" }, - "longitude" : 127.2780763, - "latitude" : 34.541848000000002 + "longitude" : 129.1083333, + "latitude" : 37.2233333 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고흥반도 최남단에 솟은 천등산은 봉우리가 하늘에 닿는다고 해서 천등이라고도 하고, 스님들이 정상에 올라 천개의 등불을 켜놓아 천등이라고 불렀다는 이야기가 전해진다.해발 554미터의 낮은 산이지만 바다 근처에 있어 어느 곳에 올라도 다도해의 아름다운 모습을 볼 수 있고, 사방으로 등산로가 나 있어 골라 오르는 재미가 있다. 정상에는 봉수대가 있었는데, 동쪽으로 마복산 서쪽으로 장기산 봉수와 서로 응했다고 한다. 정상 맞은편으로 월각산(딸각산)이 위치하는데, 바위를 밟고 오르노라면 “딸각딸각”하는 소리가 난다고 해서 그렇게 부른다고 한다.천등산 중턱에는 철쭉공원이 조성되어 있어 5월 초순 꽃이 만개하면 등산객을 비롯해 가족단위 관광객이 많이 찾고 있으며, 동쪽 능선 아래에는 신라시대 원효대사가 창건했다는 금탑사와 이 사찰을 중심으로 형성된 비자나무 숲(천연기념물 239호)이 자리하고 있다.", - "MNTN_HG_VL" : "550", - "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 풍양면, 도화면, 포두면", - "MNTN_NM" : "천등산" + "DETAIL_INFO_DTCONT" : "죽산현감(竹山縣監)을 지낸 채씨(蔡氏)의 묘가 있는 산이라는 데서 유래하였다. 채죽산의 서쪽으로는 유구천이 흐르고 있는 넓은 충적 평야인 우성농조들이 위치해 있다.남쪽의 산등성이가 끝나는 곳에 부엉산이 있으며, 바로 금강으로 이어진다.", + "MNTN_HG_VL" : "177", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 우성면", + "MNTN_NM" : "채죽산" }, - "longitude" : 127.2780763, - "latitude" : 34.541848000000002 + "longitude" : 127.0961111, + "latitude" : 36.474444400000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전북 완주군 운주면에 위치한 천등산은 대둔산의 명성에 가려져 있었다. 그러나 천등산은 금남정맥의 주맥인 대둔산(878m)과 함께 도립공원으로 지정되면서 주말이면 대전과 전주에서 산을 찾는 사람들로 붐빈다.능선은 암릉지대가 많고 곳곳에 기암이 산재하며 절벽은 층층을 이루면서 노송과 어우러져 절경이다. 특히 521봉에서 감투봉으로 오르는 등선에는 거북등 같은 모양의 바위가 넓게 깔려 이색적이며 암봉도 빼어나다.빈덕바위 남쪽 절벽 밑에 있는 신망 터에는 동굴 속에 샘과 제단이 설치된 명소가 있는데 식수는 이곳에서 준비하는 것이 좋다. 정상 서편 골짜기에는 돌탑이 많고 무당의 기도 터인 움막과 석굴이 있다. 정상 북쪽 갈림능선에서 북동으로 꼬부라져 내려가는 구간은 암벽지대의 험로이므로 노약자는 서쪽 지능선길을 택하는 게 안전할 것이다.", - "MNTN_HG_VL" : "707", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 운주면", - "MNTN_NM" : "천등산" + "DETAIL_INFO_DTCONT" : "경기도 용인의 구봉산은 속리산에서 뻗어 나온 한남금북정맥 선상에 위치하고 있다. 산명에서도 알 수 있듯이 많은 봉우리로 이루어진 구봉산에는 재미있는 전설이 전해오고 있다.예전 구봉산 자락인 용인군 원삼면 일대가 도읍지가 될 자리였는데 당시 1백개의 봉우리로 이루어진 구봉산이 어느날 큰 홍수로 끝봉우리가 떨어져 나갔고 이로 인해 이곳이 도읍지가 되지 못했다고 한다.구봉산 산행은 산의 동북쪽 끝인 외사면 근창리 창동에서 시작된다. 등산로는 인적이 적은 만큼 호젓한 산행의 재미를 느낄 수 있다. 이러한 소로길을 따라가다 보면 만나는 뾰족한 봉우리는 414봉이다. 정상은 여기에서 건너편 산줄기를 1시간 30분 정도를 더 걸어야 만날 수 있다. 정상에서는 고삼저수지와 주변의 너른 평야가 한눈에 들어온다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "경기도 용인시 원삼면, 외사면", + "MNTN_NM" : "구봉산" }, - "longitude" : 127.3088889, - "latitude" : 36.085555599999999 + "longitude" : 127.3269444, + "latitude" : 37.120555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "대중가요 `울고 넘는 박달재'의 배경인 박달재로부터 6km 떨어진 곳에 위치한 천등산은 수도권과 가까운데다 교통편이 좋아 등산인 들의 발길이 끊이지 않은 산이다. 천등산의 남쪽으로 5km거리에 인등산이 있고, 다시 남쪽으로 지등산이 나란히 있어, 천지조화설을 담고 있는 「천부경」의 천지인을 뜻하는 것으로도 본다.지등산, 인등산, 천등산을 옛 사람들은 삼등산이라 불렀으며, 임진왜란 때는 정감록의 예언에 따라 많은 사람들이 이 산으로 피난을 했다고 한다. 천등산에는 조선조 세조 때 황규라는 지사가 명당을 찾아 전국을 돌아다니다가 이 곳 천등산에서 신선을 보고 명당을 찾아 산세도를 그렸다는 전설이 전해지고 있다. 산행들머리는 해발 453m인 다리재 고개마루턱으로 산행이 힘들지 않은 편이다.", - "MNTN_HG_VL" : "554", - "MNTN_LOCPLC_REGION_NM" : "충청북도 충주시 산척면, 제천시 백운면", - "MNTN_NM" : "천등산" + "DETAIL_INFO_DTCONT" : "경북 청송군에 위치한 태양산은 주왕산국립공원 북부지역의 비경지대인 너구골 북쪽에 병풍을 두른 듯 솟아 있다. 5만분의 1지도에는 태행산으로 잘못 표기되어 있으나 태양산이 바른 명칭이다. 태양산은 댕댕이산 또는 부덕골로 불리기도 한다.경북 청송은 산악지대로 곳곳에 비경이 살아있고 동해가 가까워 인파가 사계절 끊일 날이 없는 관광명소이다. 동해와 내륙지방을 가르는 산맥을 형성하고 있는 태양산 산자락에는 마치 조각가가 심혈을 기울여 빚어놓은 듯한 단애를 이룬 기암괴석과 아름다운 계곡, 폭포 등이 어우러져 빼어난 산세를 자랑한다. 이 일대는 어디를 가나 심산유곡의 청정함을 자랑한다. 산행을 통해 비경을 만끽하는 것 만큼이나 오고가는 여정 또한 경치가 뛰어나 일상에 지친 마음을 맑게 해 준다.", + "MNTN_HG_VL" : "933", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군", + "MNTN_NM" : "태양산" }, - "longitude" : 128.00324459999999, - "latitude" : 37.097721700000001 + "longitude" : 129.1299612, + "latitude" : 36.456375800000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "마석에서 서북쪽으로 4.5km 떨어져 있는 산으로 1983년 군립공원으로 지정되어 휴일이면 많은 사람이 몰리고 있다.특히 이 곳은 스키장과 청소년 심신수련장 등이 있으며, 산의 형세가 험하지 않고 나무가 울창하여 당일 등산코스로 알맞다. 1990년 11월 1일부터 야영장외 지역에서는 취사가 금지됐다.", - "MNTN_HG_VL" : "810", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 오남읍, 화도읍", - "MNTN_NM" : "천마산" + "DETAIL_INFO_DTCONT" : "수인산은 강진과 장흥의 경계를 이루고 있으며 그 높이와는 어울리지 않게 웅장하고 오묘한 산세를 이룬다. 산성으로 둘러싸인 정상부는 고려 말부터 조선말까지 전라 병영성의 전략 요충지로서 왜구가 침략할 때마다 주민들의 피난처로 이용되었고 병영면의 지명은 조선 태종 때 왜구를 막을 목적으로 병영을 설치한 데서 유래한 것이다. 실제 수인산은 병영면 소재지에서 바라보면 알을 품은 듯한 형상인 노적봉을 가운데로 주위가 온통 암벽으로 둘러 싸여 있어 천혜의 요새로 손색이 없는 철옹성 같은 산세를 보여준다.수인산은 억새로도 유명한데 정상부 천평 규모의 조릿대와 어우러져 황금벌판이 압권이다. 수인산의 대표적인 등산 코스는 강진 병영면의 수인사, 홈골에서 시작하는 것과 장흥 유치면 대리의 수덕목장에서 올라가는 길이다.무등산, 지리산, 두륜산, 천관산, 흑석산, 월출산에 둘러싸인 지점이 이곳으로 정상에서의 조망은 일품이다. 가까이는 장흥벌과 병영벌이 훤하게 내려다보인다. 장흥벌을 흐르는 탐진강이 길게 꼬리를 늘어뜨리며 다도해로 빠지고 있으며 병영면은 너른 평야를 감싸 안은 듯 산세가 이루어져 비옥한 곡창지대를 형성하고 있다.", + "MNTN_HG_VL" : "561", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 병영면·장흥군 유치면", + "MNTN_NM" : "수인산" }, - "longitude" : 127.272778, - "latitude" : 37.680556000000003 + "longitude" : 126.8516667, + "latitude" : 34.720555599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천봉산은 상주 삼악의 하나인 석악으로 상주의 명산이다. 천년에 한 번 봉황이 나타난다고 해서 천봉산(千峰山)이라는 설과 정상에 서면 주변의 천개의 산봉우리를 볼 수 있다고 하여 천봉산(千峰山)이라는 주장하는 사람도 있다. 산경표는 천봉산(天峰山)으로 표기되어 있다.천봉산에는 일찍부터 민속 문화가 발생하여, 성황사를 비롯해 산신제단이 현재도 남아 있고, 암석 신앙에서 비롯된 영암각이 있다. 성황사는 만민이 평안하고 풍요하며 신공으로 우순풍조하여 풍년이 들 것을 기원하던 자리다. 조선 후기까지도 고지기를 두어 지키게 하고 매년 제사를 지냈다 한다. 한마디로 천봉산은 민속 문화의 보고라 일컬을 만하다.정상은 황악산, 속리산, 주흘산 그리고 굽이쳐 흐르는 낙동강 등 산이 낮으면서도 주변 경치를 한 눈에 볼 수 있는 천연전망대다.최근 신년 일출산행지로 각광받고 있다.", - "MNTN_HG_VL" : "609", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 만산동, 부원동", - "MNTN_NM" : "천봉산" + "DETAIL_INFO_DTCONT" : "좌구산은 미원면 대덕리와 증평군 증평읍 율리의 경계를 이루는 산으로 청원군에서 가장 높은 산이다. 계곡을 따라 이어진 숲길에는 사람이 다닌 자취는 거의 없고 멧돼지가 헤집은 흔적만이 곳곳에 있다.잘 뻗은 낙엽송 군락을 비록하여 다양한 활엽수가 산행을 즐기게 한다. 풀숲에는 으아리 참취가 곳곳에 군락을 이루고 대표적인 독초로 꼽히는 천남성과 부자도 자주 눈에 띄이며, 이산은 한남금북정맥 종주 구간에 포함되어 있는 산이다.", + "MNTN_HG_VL" : "659", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군, 청원군", + "MNTN_NM" : "좌구산" }, - "longitude" : 128.1429444, - "latitude" : 36.442608999999997 + "longitude" : 127.636263, + "latitude" : 36.717288799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천봉산은 전라남도 보성군의 문덕면과 복내면의 경계에 자리한 해발 609m의 아담한 산이다. 무등산을 지나 남으로 달려가던 호남정맥이 화순군의 두봉산(631m)을 지나며 북동쪽으로 한 줄기 곁가지를 일으킨다. 이 곁가지는 장재봉과 알아리재를 지나 보성군과의 경계를 이루는 말봉산(584m)에 이르러 왼쪽으로는 까치봉을, 오른쪽으로는 천봉산을 지나 드넓은 주암호 푸른물에 스르르 내려앉게 된다.또한 이 산은 보성군을 비롯해 화순과 순천에까지 걸쳐 있는 주암호변에서 그 물기운으로 솟구쳐오른 듯한 형상이며 산세가 깊으면서도 전망이 빼어나며 깊은 계곡도 거느리고 있다. 또한 천봉산은 말봉산, 까치봉과 힘을 모아 대원사 계곡을 보호하고 있으며, 봉황에 관한 전설을 가지고 있다.들머리에 자리한 대원사는 1550년 전 백제 무령왕 3년, 아도화상에 의해 창건되었다고 전하며 6.25 동란으로 극락전만 남기고 소실되었으나 십여 년 전부터 중창불사가 시작된 규모있는 사찰이다. 문화유산으로는 지방유형문화재 제 35호인 자진원오국사 부도와 제87호인 극락전이 있다. 연못에 놓인 돌다리를 지나 경내에 들러 극락전과 부모공덕불, 500년 고목 등을 둘러보고 일주문을 나서 위쪽에 자리한 티벳박물관 앞을 지나 산행을 시작한다.", - "MNTN_HG_VL" : "436", - "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군 문덕면", - "MNTN_NM" : "천봉산" + "DETAIL_INFO_DTCONT" : "해발 878m의 용화산은 간동면 유촌리, 하남면 삼화리와 거레리, 춘천시 사북면 고탄리에 걸쳐있다. 북쪽으로는 파로호를, 서쪽으로는 춘천호를, 남쪽으로는 소양호의 중심에 위치한 산이다.용화산 준령과 오봉산 사이에 성불령이라는 고개가 있고 여기에 성불사 터가 있다. 옛부터 성불사 저녁 종소리와 용화산 안개와 구름, 기괴한 돌, 원천리 계곡의 맑은 물, 부용산의 밝은 달, 죽엽산의 단풍, 구운소의 물고기 등을 옛부터 팔경이라 불렀다. 산에는 광바위, 심바위, 꼭지바위, 주전자바위, 마귀할미바위, 바둑바위 등 실물을 방불케하는 기암괴석이 있다.", + "MNTN_HG_VL" : "878", + "MNTN_LOCPLC_REGION_NM" : "강원도 화천군 간동면ㆍ하남면, 춘천시 사북면", + "MNTN_NM" : "용화산" }, - "longitude" : 127.1333333, - "latitude" : 34.946666700000002 + "longitude" : 127.74382540000001, + "latitude" : 38.039407599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천삼산은 치악산(1288m)의 남대봉에서 뻗어 내려 온 능선이 감악봉을 조금 못미쳐 남서쪽으로 흘러내리는 곳에 위치한 산이다. 옛부터 약초가 많고 위장병에 효험 있는 천수암 약수터가 있어 영험한 산으로 알려진 이 산에는 사찰이 세 개나 있으며 한때 새마을 운동의 일환으로 많은 사람들이 교육받았던 가나안농군학교가 터를 잡고 있다.또한 20여리에 달하는 능선 자락에 시루봉, 상봉, 중봉, 동굴, 천수암터, 흔들바위등 기기묘묘한 바위의 천국이다. 용암 3리 선터골 상단부에 철철바위가 있는데 늦가을철 비가 내리면 이 바위 위로 산삼씨앗이 흘러내려와서 하늘에서 산삼씨앗을 준다는 전설이 있는 산이다. 그래서 하늘이 산삼을 내리는 산, 천삼산으로 부르게 되었다고한다.", - "MNTN_HG_VL" : "819", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 충청북도 제천시", - "MNTN_NM" : "천삼산" + "DETAIL_INFO_DTCONT" : "경기도 가평군과 양평군의 경계를 이루고 있는 어비산은 유명산 계곡을 사이에 두고 유명산의 동쪽에 솟아 있는 산이다. 어비산이란 이름은 옛부터 홍수 때 물고기가 산을 뛰어 넘는다고 하여 붙여진 이름이라 하는데, 주민들은 건너편의 유명산과 더불어 설악면과 옥천면을 경계한 산이라하여 대부산이라고도 부른다 한다.용문산에서 서쪽으로 뻗어내린 능선이 어비산을 이루고, 어비산에서 북쪽으로 뻗어내린 능선과 동쪽으로 평행선을 이룬 계곡이 어비계곡이다. 이 어비계곡 또한 유명계곡에 못지 않을 정도로 아름다운 계곡이다. 큰 바위와 이따금 나타는 청정한 푸른소는 어비계곡의 자랑거리라고 할 수 있다. 계곡까지 급사면을 이룬 산록은 울창한 숲으로 뒤덮이고 숲아래 바위들은 푸른이끼옷을 입고 있고 그 아래로 흐르는 계류는 때로는 비취빛으로 바뀐다.길을 버리고 계곡을 따라 내려가는 맛이 또한 시원하다. 그러나 유명계곡처럼 완연한 협곡을 이룬 것은 아니고 길이도 유명계곡 보다는 짧은 편이어서 아쉽기는 하지만 경기도내의 아름다운 계곡중의 하나임은 분명하다. 산행은 유명산 입구인 가일리에서 오르는 코스와 대일마을에서 시작하는 방법이 있다.", + "MNTN_HG_VL" : "726", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 양평군 옥천면", + "MNTN_NM" : "어비산" }, - "longitude" : 128.1018985, - "latitude" : 37.209571099999998 + "longitude" : 127.5186384, + "latitude" : 37.589764000000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "\"김새 때문에 여러 가지 이름으로 불린다. 동쪽에서 보면 하늘 천(天)자로 보이고 정상이 일자봉으로 생김새가 특이하여 하늘이 내놓은 산이라 해서 천생산이라고도 하고, 함지박을 엎어 놓은 것 같다 하여 방티산, 한일자로 보인다 해서 일자봉, 병풍을 둘러친 것 같다 해서 병풍바위라고도 부르며, 장천면 일대에서는 천생산성을 박혁거세가 처음 쌓았다는 전설 때문에 혁거산이라고 부른다.천생산성은 경상북도 기념물 제12호로 지정되었다. 그런가하면 금오산성과 낙동강을 동서로 끼고 있어 오히려 전략적 가치가 높은 산이다. 선조 29년(1596년) 임진왜란 때 홍의장군 곽재우가 이 산에 의지하여 왜적을 대파한 것도 산이 위치하고 있는 전략적 가치를 말해준다. 그가 활약했던 천생산성이 있고, 군기를 굽던 자리가 지금도 남아있다. 구미시를 내려다보고 있다.산행은 무지개 마을에서 시작해 천룡사와 미득암을 지나 정상에 오른 뒤 통신 바위를 지나 신장리의 자골로 내려온다.", - "MNTN_HG_VL" : "407", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 산동, 장천면", - "MNTN_NM" : "천생산" + "DETAIL_INFO_DTCONT" : "월방산(月芳山)은 운달산의 한줄기가 길게 뻗어 영순면으로 산줄기를 뻗으면서 산북면과 호계면, 산양면 경계에 솟은 산으로 높이는 낮지만 울창한 소나무와 주변에 유적이 많아 볼거리가 많은 산이다.산행은 산양면 봉정리에서 시작하여 산신제단을 거쳐 정상에 오른 뒤 호계면 봉서리로 내려선다. 산행 시간은 2시간 정도 걸린다. 산기슭에 봉정리 탑동의 삼층석탑 부재, 마애보살입상, 마애여래상, 봉서리삼층석탑 등의 불교유적이 많이 남아 있다.정상 바로 밑에 있는 작은 산신당에 다음과 같은 전설이 전한다. 옛날에 마음씨 고운 아낙네가 산에 나물을 캐러 갔다가 미끄러져 정신을 잃었다. 이 때 꿈에 산신당의 백발노인이 나타나서 벼랑 사이에 흐르는 물을 먹고 바르라고 말하였다. 여인이 꿈에서 깨어 노인이 시키는대로 하였더니 과연 상처가 씻은 듯이 나앗다. 여인의 이야기를 들은 심술궂은 사내가 산신당 벽에 걸린 산신의 눈을 솔가지로 찌르고 벼랑 사이에 흐르는 우물을 파헤쳤다. 그러자 밤마다 귀신이 나타나 3일만에 사내가 죽고 우물물이 흙탕물로 변했으며 호랑이가 나타나 마을의 가축들을 물어갔다. 이에 주민들은 산신의 노여움을 가라앉히기 위해 매년 정월 대보름에 제사를 드리기 시작하였고, 이 제사는 지금도 이어지고 있다.", + "MNTN_HG_VL" : "360", + "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 산양면 봉정리", + "MNTN_NM" : "월방산" }, - "longitude" : 128.458507, - "latitude" : 36.1107935 + "longitude" : 128.2333333, + "latitude" : 36.633333299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 구미시 신동, 인의동, 금전동과 장천면 경계에 솟은 천생산은 많은 이름을 가졌다. 동쪽에서 볼 때 생김새가 ‘하늘 천’자를 닮아 하늘이 빚은 산 천생산, 함지박을 엎어놓은 것 같아 함지박의 경상도 사투리 ‘방티’를 붙인 방티산, 능선이 ‘한 일’자로 보인다고 해서 일자봉이라고도 한다. 장천면 일대에서는 정상에 있는 산성을 박혁거세가 처음 쌓았다는 전설 때문에 혁거산으로 통한다.이처럼 다양한 이름을 가진 천생산은 썩 높지 않으며 산마루가 길고 평탄해 산행하는 데 힘들지 않다. 숲도 울창한데 구미시에서 삼림욕장을 조성해 시민들이 쉽게 자연을 접할 수 있도록 했다.정상 서쪽에는 불쑥 튀어나온 큰 바위 미득암(米得岩)이 있다. 사자가 하늘을 우러러 포효하는 형상이다. 천생산을 앙천산(仰天山)이라고도 부르는 이유는 바로 이것 때문.임진왜란 당시 난공불락이던 천생산성을 공략하기 위해 왜군이 산기슭에 큰 연못을 파 성 안의 물을 마르게 했다. 이에 의병장 곽재우는 미득암 바위에 말을 세워두고 쌀을 주르르 부어 말을 씻는 시늉을 했다. 이를 본 왜군은 산성에 물이 많은 것으로 생각하고 물러갔다고 한다. 그래서 쌀의 덕을 보았다고 하여 ‘미덕암(米德岩)’으로도 부른다.", - "MNTN_HG_VL" : "407", - "MNTN_LOCPLC_REGION_NM" : "경북 구미시 신동ㆍ인의동ㆍ황상동ㆍ금전동, 장천면", - "MNTN_NM" : "천생산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "474", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군 예산읍 수철리 449", + "MNTN_NM" : "덕봉산" }, - "longitude" : 128.458507, - "latitude" : 36.1107935 + "longitude" : 126.8822222, + "latitude" : 36.713611100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "통도사 인터체인지에서 부산쪽으로 7km 떨어진 곳에 있는 산으로, 경부고속도로 위로 가설된 용연 육교를 지나 3km쯤 가면 내원사로 가는 골짜기에 다다르게 된다. 여기서부터 기암괴석과 울창한 숲이 우거져 금강산의 계곡을 방불케하는 천성산이 시작된다.", - "MNTN_HG_VL" : "920", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산시 하북면, 상북면, 웅상읍", - "MNTN_NM" : "천성산" + "DETAIL_INFO_DTCONT" : "모산동과 송학면 경계에 위치한 해발 871미터의 용두산은 삼한시대 축조된 의림지와 제2 의림지, 솔밭공원을 남녘 자락에 펼치고 있는 제천의 진산이다. 산기슭에서 흘러내린 물이 용두천을 이루며 의림지로 흘러든다. 북서쪽으로는 석기암산(906m)과 감악산(920m)이 이어진다. 제천 시내의 산이어서 교통이 편리하고 찾기가 수월해 주말이면 제천 시민들이 즐겨 찾는다.용두산 산행 코스는 크게 세 군데로 나눌 수 있다. 피재, 물안이골, 석기암봉 코스 중에서 사람들이 가장 많이 찾는 코스는 피재 방면이다. 산행은 솔밭공원 앞 주차장에서 시작한다. 수령 수백년을 헤아리는 노송 백여 그루가 숲을 이룬 솔향기 가득한 공원에는 여러 점의 조각이 놓여 있어 운치가 있다. 의림지 북쪽으로 약 5백미터 지점에 자리한 이 솔밭공원을 지나면 진초록 못물이 더욱 맑은 제2 의림지가 있다. 용두산 등산로는 그 위편에 위치한 청소년수련원 오른쪽으로 나 있다. 의림지와 용두산산림욕장 등을 연계해 산행하면 다양한 볼거리와 편안한 휴식을 즐길 수 있다.용두산 정상은 매우 널찍한 헬기장으로, 주위에 벤치가 10여개 설치돼 있다. 헬기장 한쪽 끄트머리에는 ‘용두산 해발 873m’라 새긴 아담한 정성석이 있다. 정상에서 바라보는 조망은남동쪽을 제외하고는 나무가 우거져 좋지 않다. 서북쪽으로 석기암(906m)과 감악산(920m) 산줄기가 이어진다.", + "MNTN_HG_VL" : "871", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 송학면", + "MNTN_NM" : "용두산" }, - "longitude" : 129.11215920000001, - "latitude" : 35.420248999999998 + "longitude" : 128.2108604, + "latitude" : 37.203046100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "619", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", - "MNTN_NM" : "천왕산" + "DETAIL_INFO_DTCONT" : "지형적으로는 공주시 유구읍, 아산시 송악면, 천안시 광덕면이 광덕산을 끼고있다. 산세가 높으며 나무들이 오래되어 경관이 보기가 좋은곳이다. 특히 노약자도 많이 이용하는데산림과에서 만든 소방도로로 이용을 많이 한다.", + "MNTN_HG_VL" : "638", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 천안시 광덕리", + "MNTN_NM" : "광덕산" }, - "longitude" : 128.59414770000001, - "latitude" : 35.5852754 + "longitude" : 127.034266, + "latitude" : 36.693891999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;화왕산과 관룡산 조망이 일품gt;천왕산(619m)은 낙동정맥 사룡산에서 비슬산을 지나 밀양 종남산 오우진나루까지 146킬로미터의 산줄기로 뻗은 비슬지맥의 한 봉우리다. 묘봉산(514m)에서 배바위산(608m)으로 이어지는 비슬지맥에서 약간 벗어나 있지만 비슬지맥을 종주하는 등산인들이 꼭 들리는 곳이다. 남쪽 밀양시 청도면의 소태리에서 죽바위산-호암산을 거쳐 건티재로 갔다가 배바위산-천왕산에 오른 후 천왕재로 내려오는 긴 코스의 산행을 할 수 있다. 또 북동쪽의 풍각면 덕양리(가양)에서 임도를 따라 대산사까지 가거나 각남면 상옥산에서 대산사에 오른 후 족금당-천왕산-배바위산으로 산행을 이어갈 수도 있다. 비슬지맥이 지나는 천왕산-배바위산-건티재 능선은 길이 뚜렷하지만 족금당과 대산사로 이어지는 능선은 길이 다소 희미하다. 능선에 툭 튀어나온 큰 바위인 배바위에 오르면 화왕산과 관룡산 조망이 일품이다. 능선에 샘이 없어서 식수는 미리 준비한다.", - "MNTN_HG_VL" : "619", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", - "MNTN_NM" : "천왕산" + "DETAIL_INFO_DTCONT" : "국내 최대의 면적을 자랑하는 자연휴양림을 거느리고 있는 방태산은 강원도 인제군과 홍천군의 경계를 이루는 산으로, 교통이 불편한 관계로 아직도 오염되지 않은 깨끗한 계곡을 간직하고 있다.청정한 자연림에 들어서면 도심에서 불과 몇시간 거리밖에 떨어져 있지 않다는 사실이 믿어지지 않는다. 빽빽한 나무들 사이에 누워 하늘을 올려다보면 한줄기의 햇살도 허용하지 않는 수림의 깊이가 느껴진다.", + "MNTN_HG_VL" : "1446", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면, 상남면", + "MNTN_NM" : "방태산" }, - "longitude" : 128.59414770000001, - "latitude" : 35.5852754 + "longitude" : 128.35604789999999, + "latitude" : 37.894853599999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "해발 158m의 비교적 낮은 지역인 전주대 뒷산으로 일반 등산객들은 아주 드물게 이동하는 지역이며 주로 전주대 학생들이 즐겨 찾는 지역임", - "MNTN_HG_VL" : "158", - "MNTN_LOCPLC_REGION_NM" : "전라북도 전주시 상림동", - "MNTN_NM" : "천장봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "175", + "MNTN_LOCPLC_REGION_NM" : "제주도 제주시 애월읍 고내리", + "MNTN_NM" : "고내봉" }, - "longitude" : 127.0819444, - "latitude" : 35.808333300000001 + "longitude" : 126.3418004, + "latitude" : 33.459126500000004 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "332", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", - "MNTN_NM" : "천재산" + "DETAIL_INFO_DTCONT" : "다락산은 발왕산(1458m)의 산줄기가 남으로 뻗어 내리다 자개천과 송천에 이르러 더 나아가지 못하고 동서로 길게 누우며 솟아오른 형상이다.발왕산에서 뻗어내린 능선상의 마지막 봉우리이다. 송천을 사이에 두고 노추산을 마주 보고 있다. 산 남쪽의 구절리는 오지마을로 남아 있다가 1960년 대 산업철도 구절선이 생기면서 탄광촌으로 흥청거리기도 했으나 광맥이 끊기고 몰려들었던 사람도 다 떠난 지금은 다시 고즈넉한 옛 모습이다.등산로마다 숲이 우거졌고 야생란을 위시한 자생식물이 남아있으며, 자개천의 푸른 물빛이 오염되지 않은 비경을 이루는 깨끗한 산이다. 원시의 냄새를 풍기는 다락산의 초본류는 그 무성하고 수수한 모양새로 그런 것을 좋아하게 마련인 등산객을 유혹한다. 산 꽃 촬영에 적당한 산이다.", + "MNTN_HG_VL" : "1018", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 정선 북면", + "MNTN_NM" : "다락산" }, - "longitude" : 127.7422222, - "latitude" : 34.763611099999999 + "longitude" : 128.7613806, + "latitude" : 37.5412933 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "천주산은 자체로도 녹록치 않은 높이를 자랑하지만 주변에 버금갈 만한 산이 없어서 더욱 뛰어난 상승감을 준다. 분지로 둘러싸인 창원을 굽어보는 진달래 명산으로, 지리산 영신봉(1652m)에서 김해 신어산(631m)을 지나 낙동강 하구에 그 꼬리를 담그는 232킬로미터의 낙남정맥에 솟은 수많은 산 가운데서도 단연 돋보이는 명산이다.천주산의 주봉은 용지봉으로 주변 일대에 진달래가 군락을 이루어 있다. 조망이 시원한 정상에서는 무학산에서 정병산 지나 비음산, 용지봉까지 이어지는 낙남정맥이 마산과 창원을 감싸며 꿈틀거리듯 뻗어가는 장쾌한 모습을 감상할 수 있으며, 웅장한 산세에 둘러싸인 아름다운 도시 마산과 창원, 진해도 한눈에 볼 수 있다. 무학산과 마산 앞바다, 북쪽으로 철새들의 낙원인 주남저수지와 그 일대 들판도 그림처럼 펼쳐진다.", - "MNTN_HG_VL" : "640", - "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 마산회원구 구암동, 의창구 북면", - "MNTN_NM" : "천주산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "73", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "삼학도" }, - "longitude" : 128.59073989999999, - "latitude" : 35.271812500000003 + "longitude" : 126.3914317, + "latitude" : 34.782971400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 원주시 소초면과 횡성군 안흥면의 경계를 이루는 천지봉은 치악산과 매화산 중간에 우뚝 솟은 봉으로 치악산 정상인 비로봉의 유명도에 밀려 아직도 깨끗함을 간직하고 있다.남쪽 능선길은 부드럽고 많은 산악인으로 붐비는 구간인 반면, 북쪽 천지봉으로 이어지는 능선은 굴곡이 심하고 전망 좋은 암봉이 곳곳에 있으며 섬뜩한 기운이 감돌기조차 하는 한적한 산길이라 대조적이다.영말골과 세렴골계곡은 울창한 수림이 하늘을 가리고 군데군데의 폭포와 옥 같은 계류가 어우러져 매우 아름답고 산길은 원시림을 방불케 해서 더욱 좋다. 정상에는 삼각점이 있고 밋밋하기는 하나 비로봉,백덕산,매화산,삼봉 등 사방을 바라보는 전망이 일품이다.", - "MNTN_HG_VL" : "1087", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면, 횡성군 안흥면", - "MNTN_NM" : "천지봉" + "DETAIL_INFO_DTCONT" : "수촌이라는 마을의 `자연숲' 뒤에 솟았다고 해서 숲뒤산이라 부르는 이 산은 고양이와 개에 관한 전설이 얽혀있는 광동굴, 층층나무와 잣나무가 그득한 숲, 하늘말나리와 더덕의 향기가 은은히 퍼지는 산길, 냉기가 솟는 샘물 때문에 오지를 찾는 사람들이 저절로 발길을 멈추게 된다.비라도 내리면 광동굴에 들어앉아 비오는 풍경도 감상할 수 있어 특히 여름 산행이 즐거운 산이다. 또한 숲뒤산은 강원도 삼척시 하장면 장전리에 있는 골로 마을이 있어 볼품없는 골짜기나 계곡 중간에 식수원으로 쓰는 광동굴 입구가 여름에 시원하고 멋지다. 골지천에서 휴식을 하고 한번쯤 둘러 보는 것도 좋다.", + "MNTN_HG_VL" : "1065", + "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 하장면", + "MNTN_NM" : "숲뒤산" }, - "longitude" : 128.09777779999999, - "latitude" : 37.405833299999998 + "longitude" : 128.9251209, + "latitude" : 37.3435427 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북 영동군 양산면과 충남 금산군 제원면의 경계를 이루는 천태산은 기암절벽과 수림이 조화를 이루고 있어 일명 '충북의 설악'이라 불리고 있는 산이다. 등산로는 바위지대에다 안내표지와 로프가 설치되어 있어 아기자기한 바위산행을 만끽할 수 있는 묘미가 있는 산이며 뛰어난 자연경관을 자랑하는 산이기도 하다.이름난 명소가 산재해 있어 가족동반 등산지로도 좋다. 계곡은 비록 짧으나 시원하게 쏟아지는 용추폭포와 진주폭포가 있고, 봄에는 진달래, 벚꽂이 온 산을 뒤덮고 가을에는 단풍 또한 좋다.천태산에는 양산 8경 중 제1경인 영국사가 있으며, 10km 떨어진 곳에 여의정, 강선대, 용암 등이 있어 볼거리가 많은 곳이다. 영국사 앞 등산로 입구에는 천연기념물 제233호로 지정된 수령 천년이 넘는 은행나무가 서 있다.이 나무는 높이 18m, 둘레가 6m에 달하는 거목이다. 나라를 평안하게 하는 뜻을 가진 영국사는 고려 31대 공민왕이 홍건적의 난을 피해 이 근처에 와서 천일기도를 드린 끝에 난을 평정한 것을 기념하여 절을 짓고 이름을 영국사라 붙였다고 전해지고 있다.", - "MNTN_HG_VL" : "715", - "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군 양산면, 충청남도 금산면 제원면", - "MNTN_NM" : "천태산" + "DETAIL_INFO_DTCONT" : "완택산은 연하리와 동강변인 삼옥리 사이에 위치하고 있다. 산세는 동고서저, 즉 주능선을 경계로 동쪽 연하리 방면은 급경사에 절벽이 많고, 서쪽 동강 방면은 완만한 산세를 이루고 있다. 산세가 이렇듯 그 옛날 완택산은 천혜의 요새였다는 전설이 전해지고 있다.주능선 동쪽은 수직절벽이 대부분이어서 자연성곽을 이루고 서쪽은 동강 물줄기가 자연적인 방어선을 이루고 있다. 그래서 완택산은 옛날 예맥의 땅이었다는 얘기가 전해지며, 퉁구스식 방법으로 축성한 산성흔적이 산자락 곳곳에 조금씩 남아있다.완택산 등산로는 급경사를 이룬 동쪽 연하리 방면에서 오르내리는 코스가 일반적이다. 그러나 요즘은 동강변 삼옥리에서 완만한 경사를 이룬 능선과 계곡 코스가 인기 있다.", + "MNTN_HG_VL" : "918", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "완택산" }, - "longitude" : 127.6135306, - "latitude" : 36.157161500000001 + "longitude" : 128.55202180000001, + "latitude" : 37.2109405 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "289", - "MNTN_LOCPLC_REGION_NM" : "전라남도 강진", - "MNTN_NM" : "천태산" + "DETAIL_INFO_DTCONT" : "발교산은 강원도 홍천군 동면과 횡성군 청일면 사이에 남북으로 길게 드러누운 산이다. 발교산은 6·25의 전화도 피해갈 만큼 주위가 온통 산으로 둘러싸여 있는 오지의 한가운데 자리하고 있다. 그런 만큼 아직까지 자연 그대로의 모습을 유지하고 있다. 산행은 봉명2리에서 시작된다.봉명리는 구접이라는 이름으로도 불리는데 산이 아홉 겹이나 둘러싸고 있다 해서 그리 불렸다고 한다. 마을을 낀 계곡길을 따라 오르다 보면 소나무숲이 나오고 곧이어 가파른 오르막이 시작된다.정상까지는 오르막이 계속되어 오르는 발걸음을 무겁게 하지만 정상에 서면 공작산, 대화산이 지척에 보이고 멀리 치악산의 줄기가 시야에 와 닿는다. 철분이 많이 섞였다는 계곡의 물소리가 산행 내내 귀를 즐겁게 해준다.", + "MNTN_HG_VL" : "998", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 동면, 횡성군 청일면", + "MNTN_NM" : "발교산" }, - "longitude" : 126.91666669999999, - "latitude" : 34.899999999999999 + "longitude" : 128.11388890000001, + "latitude" : 37.654722199999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "401", - "MNTN_LOCPLC_REGION_NM" : "충청남도 논산", - "MNTN_NM" : "천호봉" + "DETAIL_INFO_DTCONT" : "강원도 원주시 귀래면과 충북 제천시 백운면의 경계를 이루는 십자봉은 원주에서 남쪽으로 15㎞ 지점에 숨어있는 명산이다.겨울에는 설경, 가을에는 단풍과 낙엽, 그리고 여름에는 시원한 계곡으로 사시사철 산행지로 각광을 받고 있는데, 특히 산으로 들어서면 등산로마다 잡목수림이 터널을 이루고 있어, 여름철에 더위를 피하기 위한 장소로 그만이다. 빽빽히 들어찬 나무사이로 4㎞ 길이의 천은계곡이 쭉 뻗어 있으며 곳곳에 소와 담, 암반이 펼쳐져 계곡미가 뛰어나다. 계곡입구에서 10분 거리에 천은사라는 아담한 절이 있다.십자봉이라는 산이름은 일제가 붙인 이름이고, 덕동리 주민들은 촉새봉이라 부른다. 산 서쪽 자락인 귀래리에 있는 천은사 절이름도 '십자봉 천은사'가 아닌 '백운산 천은사'로 부르고 있다. 촉새봉이라는 산 이름은 이곳 주민들이 예전부터 조상 대대로 불러온 이름이다.", + "MNTN_HG_VL" : "985", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 귀래면, 충청북도 제천시 백운면", + "MNTN_NM" : "십자봉" }, - "longitude" : 127.2411111, - "latitude" : 36.204166700000002 + "longitude" : 127.93055560000001, + "latitude" : 37.211111099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경상남도 밀양시 단장면·산내면과 울산광역시 울주군 상북면(上北面)의 경계에 있는 산이다. 주봉(主峰)은 사자봉이다. 남쪽 5km 부근에 솟아 있는 재약산(載藥山:주봉은 수미봉 1,018m)과 맥이 이어져, 천황산을 재약산으로 일컫기도 하는데, 이러한 혼동은 천황산이 일제강점기 때 붙은 이름이라 하여 '우리 이름 되찾기' 운동의 일환으로 사자봉을 재약산 주봉으로, 재약산을 수미봉으로 부르면서 생겨났다.산세가 수려하여 삼남금강(三南金剛)이라 부르며, 인근 일대의 해발고도 1,000m 이상의 준봉들로 이루어진 영남알프스 산군(山郡)에 속하는 산이다. 산세는 부드러운 편이나 정상 일대에는 거대한 암벽을 갖추고 있다. 수미봉·사자봉·능동산·신불산·취서산으로 이어지는 능선은 드넓은 억새평원으로서 사자평 고원지대라고 부르는데, 일대는 해발고도가 800m에 달해 목장으로 개발되어 있다.서쪽 산기슭에 있는 유명한 대찰(大刹)인 표충사(表忠寺)를 비롯하여 부근에 내원암(內院庵)·서상암(西上庵) 등의 절과, 높이 20m의 폭포 2개가 연이어 있는 칭칭폭포[層層瀑布:毘盧瀑布], 무지개가 걸리는 높이 25m의 금강폭포 등 명소가 있다. 천황산의 북쪽 사면에는 가마볼·호박소[臼淵] 등의 명소 외에 단열냉각에 의한 물리적 현상으로 여름에도 골짜기에 얼음이 어는 얼음골(천연기념물 224)이 있다.", - "MNTN_HG_VL" : "1189", - "MNTN_LOCPLC_REGION_NM" : "울산광역시, 경상남도 밀양시", - "MNTN_NM" : "천황산" + "DETAIL_INFO_DTCONT" : "만덕산은 강진읍 남쪽에 위치한 높이 412미터의 야트막한 산으로 마을 뒷산처럼 보잘것 없지만, 산 안으로 파고들면 앙팡지고 아기자기한데다 능선에는 상당한 크기의 암석들이 많으며, 그윽한 정취마저 넘치는 산이다. 산기슭에는 천년고찰 백련사와 조선 말기의 실학자 다산선생의 실학정신이 깃들어 있는 다산초당 등 역사적 자취를 더듬어 볼만한 곳이 있어 등산과 유적지 답사를 겸한 산행으로 제격이다.산세 또한 부드러워 가족산행지로도 권장할 만하다. 바람재에서 석문사에 이르는 등산로는 사람들의 발길이 닿지 않아 잡목과 잡초가 등산로를 뒤덮고 있으나 이정표가 군데군데 설치되어 있어 산행하는 데는 큰 어려움이 없다. 백련사 주변으로는 천연기념물 제151호로 지정된 1500여 그루 동백나무가 1.3헥타르에 걸쳐 자라고 있으며, 특히 절 앞에 많이 모여 자란다.", + "MNTN_HG_VL" : "412", + "MNTN_LOCPLC_REGION_NM" : "전라남도 강진군 강진읍, 도암면", + "MNTN_NM" : "만덕산" }, - "longitude" : 128.97150189999999, - "latitude" : 35.557452300000001 + "longitude" : 126.7438889, + "latitude" : 34.592222200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "철마산은 쇠말산, 샛말, 소멀미 등 비슷한 속명이 있다. 옛날 이곳은 큰홍수와 해일로 인하여 오랫동안 물속에 잠겨 있었는데, 미역바위의 용굴에서 동해 용왕의 명을 받은 용마가 나와서 물을 다스리고 나서부터는 물이 없어 용마는 환궁하지 못한 채 햇볕에 말려져 점차 굳어져서 작은 쇠말이 되어 최근까지도 그 흔적이 남아 있었기 때문에 쇠로 된 말이 있는 산이라 하여 쇠(鐵), 말(馬), 뫼(山)로 철마산이라 하였다고 한다.쇠는 소, 새와 같은 말로 샛바람이라 하는동쪽을 뜻이고, 말은 마라, 말, 머리와 동계어로서 마루라는 말로서 산마루 로 산등성이를 뜻하는 말이다.", - "MNTN_HG_VL" : "605", - "MNTN_LOCPLC_REGION_NM" : "부산광역시 기장군 철마면", - "MNTN_NM" : "철마산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "482", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시 북구", + "MNTN_NM" : "운제산" }, - "longitude" : 129.13749999999999, - "latitude" : 35.310000000000002 + "longitude" : 129.35138889999999, + "latitude" : 35.934444399999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "음지 마을의 주산으로 옛날에 장군이 암굴에서 철마를 타고 나왔다는 전설이 있어 불려진 산으로 화악산 줄기의 대표적인 명산이다. 정상에는 아직도 성터(철마산성)가 남아 있고 주위에는 높고 험한 산줄기가 이어져 천혜의 요새를 이루고 있다.남북으로 뻗은 산줄기를 기준으로 서쪽은 산세가 급경사를 이루어 이렇다 할 계곡도 없지만, 상대적으로 경사가 완만한 동쪽 일원에는 비금계곡이라는 남양주시 최고의 계곡과 지계곡들이 여럿 있어 여름 피서철 산행지로 이름 높다.또한 동남서 방향에 돌을 쌓았으며 불암이라는 절벽에는 장군이 나왔다는 바위굴이 있다. 그 바위굴은 장군이 말을 매어 두고 사육했던 곳으로 암반의 곳곳에 장군의 흔적이 역력히 남아 잇다. 또한 전설에 의하면 바위굴은 신라의 선인 옥단춘의 출생지로서 고려 초 보조국사가 그 자리에 한선사를 건립했다는 기록이 남아 있다.", - "MNTN_HG_VL" : "627", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "철마산" + "DETAIL_INFO_DTCONT" : "정상에서 서남쪽으로 능선이 이어지면서 치악산과 합해지고, 동쪽으로는 백악산과 마주보는 큰 산이다. 그 동안은 이웃한 치악산의 명성에 가려 세상에 알려지지 않았다.그러나 봄철이면 철쭉과 진달래가 붉게 물들어 여성적인 아름다움을 간직하고 있어 산행을 권할 만하다.옛날 신선이 살았다는 전설을 간직한 신선봉이 있다.(연중 입산 및 등산 불가 지역입니다.) 치악산 국립공원 내에 속하는데 치악산에 비해 찾는 이가 거의 없으니 의외로 호젓한 산행을 즐길 수 있다.", + "MNTN_HG_VL" : "954", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 소초면", + "MNTN_NM" : "매화산" }, - "longitude" : 128.69147169999999, - "latitude" : 35.593220600000002 + "longitude" : 128.09777779999999, + "latitude" : 37.405833299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "청계산이란 이름을 가진 산이 경기도에만 세 곳이 있다. 양평군 양서면의 청계산(658m)과 과천시와 성남시의 경계를 이루는 청계산(618m), 그리고 포천군 일동면과 가평군 하면의 경계를 이루는 청계산(849m)으로 이 중에서 포천 청계산이 가장 높고, 산세가 커 산행코스도 다양하다.수도권 지역에서 등산인들이 즐겨찾는 산들 중 하나인 청계산은, 관악산과 마주한 과천의 청계산(618m)과 양평군 양서면에 있는 청계산(658m)보다 그 규모나 아름다움에 있어 으뜸으로 꼽힐 만한 곳이다.이 청계산(849.1n)의 일반적으로 잘 알려진 등산 코스는 청계저수지를 기점으로 해서 길매고개를 거쳐 정상에 오른 뒤 동북쪽으로 뻗은 계곡을 통해 다시 청계저수지로 하산하는 것이다. 상판리 방면에서 갈매재로 올라가는 길은 1990년부터 입산금지 구역으로 지정되어 있다.실제 정상은 서북쪽에 솟은 육산의 모습을 지닌 봉우리다.정상에서 북쪽으로 내려설 때 바위지대를 지나야 하므로 안전에 유의하도록 한다.", - "MNTN_HG_VL" : "618", - "MNTN_LOCPLC_REGION_NM" : "경기도 포천시 일동면, 가평군 하면", - "MNTN_NM" : "청계산" + "DETAIL_INFO_DTCONT" : "줄줄이 산릉과 산등이 융기되어 있는 선의산은 명당이 많다고 하여 지관들이 구석구석을 누비면서 지금도 찾아다니고 있다. 신라시대 사찰이 있었고 암자가 있다 하여 암자골이라 하며 그 위에 있는 선의산은 청도군과 경산시의 경계를 이루고 있다. 또한 말과 닮은 산의 형세라 하여 말안쪽산 즉 마암산이라고 부르기도 한다.", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "선의산" }, - "longitude" : 127.3701707, - "latitude" : 37.933052600000003 + "longitude" : 128.77348799999999, + "latitude" : 35.727622799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서울시 서초구 양재동과 경기도 과천, 의왕, 성남시에 걸치고 있으며 서울 주변에서 숲과 계곡, 절, 공원 등을 한꺼번에 만날 수 있는 청계산은 청룡이 승천했던 곳이라 과거에는 청룡산으로도 불렸다. 남북으로 흐르는 능선을 중심으로 펼쳐진 산세가 수려하며 숲 또한 울창하고 계곡이 깊고 아늑하다.과천의 서울대공원에서 바라보면 대공원 뒤에 병풍처럼 둘러있으며 바위로 되어 있는 정상인 망경대가 우뚝 솟아 보인다. 정상에 서면 북서쪽으로 펼쳐진 계곡 아래 과천시와 동물원, 식물원이 있는 서울대공원, 각종 놀이기구가 있는 서울랜드, 국립현대미술관, 과천 경마장이 한눈에 내려다보인다.청계사에는 갖가지 명물이 많은데 그중 대표되는 것이 계단길이다. 시민의 손으로 산을 꾸미겠다는 취지로 얼마의 돈을 지불하면 계단 한 칸 마다 사연을 적어 꾸밀 수 있게 했다. 자신들의 소망, 기업이나 가게 홍보, 성경 구절 등으로 계단을 빼곡이 채우고 있어, 계단을 오를 때마다 읽어 가는 재미가 쏠쏠하다. 또 청계산은 역사적으로도 절의 곧은 선비들이 난세를 피해 은거한 충절의 산이라 할 수 있다. 대표적인 인물은 고려의 충신 이색과 조윤, 조선 중기의 김종직의 문하로 활동하던 일두 정여창이다. 망경대, 금수샘, 이수봉 등은 모두 그들과 관계되어 있다.", - "MNTN_HG_VL" : "873", - "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 신원동, 경기도 과천시 막계동, 의왕시 청계동, 성남시 수정구", - "MNTN_NM" : "청계산" + "DETAIL_INFO_DTCONT" : "삼봉약수에 있는 가칠봉(1,240m)에서 직선거리로 약 14km 북쪽에 위치한 가칠봉은 곰배령으로 더 유명하다. 곰배령 일대의 넓은 초원지대는 봄부터 가을까지 온갖 야생화가 피어나 지나는 이의 눈길을 끌고 놓지 않는다.<><>가칠봉 산자락에 사는 주민들은 일년 내내 산골 곳곳을 누비며 약초와 나물을 캐러 다니고 있다. 그래서 99년 5월부터 곰배령,가칠봉 일대를 입산 금지하고 있어, 입산코자 할 경우 인제 군청에 미리 확인해 봐야 한다.<><>가칠봉에서 북쪽으로 이어지는 주능선을 따라가면 곰배령을 지나 작은 점봉산(1,295m)으로 이어지고 이어서 점봉산(1,424m)으로 연결되어 한계령으로 능선이 뻗어 나가면서 설악의 품으로 들어간다. 가칠봉 일대는 교통이 불편한 관계로 접근이 어려워 아직도 깨끗한 계곡과 경관을 유지하고 있다.", + "MNTN_HG_VL" : "1242", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 기린면 진동리", + "MNTN_NM" : "가칠봉" }, - "longitude" : 127.0415787, - "latitude" : 37.414165699999998 + "longitude" : 128.42111109999999, + "latitude" : 38.0038889 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "동쪽으로 용문산과 북쪽으로 중미산을 건너다보고 있으며 남서쪽으로는 남한강이 유유히 흘러나가고 있다. 교통이 그렇게 나쁜편은 않은데도 그냥 지나쳐 버리기 쉬운 산중 하나이다. 목왕리 못 미쳐에는 조선중엽의 문신인 한음 이덕형 선생의 묘와 신도비가 있어 산행길에 들러봄직 하고 정상에 서면 북한강과 발아래 펼쳐지고 두물머리인 양수리 일대가 잡힐 듯 내려다 보인다.양평에 위치한 이 청계산은 수도권 일대의 세 개의 청계산 중 가장 알려지지 않은 산이다. 호젓한 산행을 즐기고 싶다면 한 번쯤 찾아 볼 만하다.", - "MNTN_HG_VL" : "849", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평 서종면, 양서면", - "MNTN_NM" : "청계산" + "DETAIL_INFO_DTCONT" : "\"김새 때문에 여러 가지 이름으로 불린다. 동쪽에서 보면 하늘 천(天)자로 보이고 정상이 일자봉으로 생김새가 특이하여 하늘이 내놓은 산이라 해서 천생산이라고도 하고, 함지박을 엎어 놓은 것 같다 하여 방티산, 한일자로 보인다 해서 일자봉, 병풍을 둘러친 것 같다 해서 병풍바위라고도 부르며, 장천면 일대에서는 천생산성을 박혁거세가 처음 쌓았다는 전설 때문에 혁거산이라고 부른다.천생산성은 경상북도 기념물 제12호로 지정되었다. 그런가하면 금오산성과 낙동강을 동서로 끼고 있어 오히려 전략적 가치가 높은 산이다. 선조 29년(1596년) 임진왜란 때 홍의장군 곽재우가 이 산에 의지하여 왜적을 대파한 것도 산이 위치하고 있는 전략적 가치를 말해준다. 그가 활약했던 천생산성이 있고, 군기를 굽던 자리가 지금도 남아있다. 구미시를 내려다보고 있다.산행은 무지개 마을에서 시작해 천룡사와 미득암을 지나 정상에 오른 뒤 통신 바위를 지나 신장리의 자골로 내려온다.", + "MNTN_HG_VL" : "407", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 산동, 장천면", + "MNTN_NM" : "천생산" }, - "longitude" : 127.4027778, - "latitude" : 37.553611099999998 + "longitude" : 128.458507, + "latitude" : 36.1107935 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "230", - "MNTN_LOCPLC_REGION_NM" : "강원도 속초", - "MNTN_NM" : "청대산" + "DETAIL_INFO_DTCONT" : "우두산은 고래산과 능선으로 이어져 있으며 신라때 대사찰 이었던 곳에 최근에 지은 고달사가 있다. 고달사는 764년(신라 경덕왕 23)에 창건되었다고 하며, 신라 이래의 유명한 삼원(三院), 즉 도봉원(道峰院)·희양원(曦陽院)·고달원(高達院) 중 하나로 고려시대에는 국가가 관장하는 대찰이었다. 고달사지부도(국보 4)를 비롯하여 고달사원종대사혜진탑비 귀부 및 이수(보물 6), 고달사지석불좌(보물 8), 고달사원종대사혜진탑(보물 7) 등의 문화재가 남아 있다. 불교유적도 찾아볼 수 있어 문화유적 탐방코스로도 인기가 높은 산이다.산행 기점은 곡수리이다. 고래산의 등산로는 동쪽의 쪽다리나 금동 마을에서 오르는 길과 서쪽의 곡수리를 기점으로 하는 코스가 있다. 구둔역에서 남쪽 도로를 따라가다 쪽다리에서 440봉에 올라 정상까지는 육산의 완만한 길이며 정상에는 큰바위로 구성되어 있다.", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평, 여주", + "MNTN_NM" : "우두산" }, - "longitude" : 128.56960169999999, - "latitude" : 38.1778786 + "longitude" : 127.6441667, + "latitude" : 37.4052778 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "청도읍에서 남서쪽으로, 밀양시에서는 북서쪽으로 솟은 화악산은 이 일대에서는 가장 높은 산이다. 이 산은 화악산의 북쪽, 같은 능선에서 솟은 산으로 산 북쪽에는 신둔사가 있고 동쪽에는 적천사가 있다.먼 옛날 청도에는 이서국(伊西國)이란 부족국가의 도읍지가 있었다고 한다. 그래서 한 나라의 수도였던 곳에만 있는 남산이 이곳 청도에도 있다.삼국사기와삼국유사에서 전하는 이서국은 한때 신라를 공격해 위기에 빠뜨릴 정도의 강국이었으나 결국 신라에 합병되었다. 그래서 남산에는 신라군사에 쫓긴 이서국의 왕이 숨어들었다는 전설을 갖고 있는 은왕봉이 있다. 서울과 경주, 개성의 남산이 300m 정도인데 비해 청도 남산은 800m 대의 높이를 자랑하는데 등산로가 여럿 있어 그 위용을 알 만하다. 산 곳곳에 뛰어난 암릉 전망대를 품고 있으며 정상 북쪽에는 비구니 사찰인 죽림사가 자리잡고 있다. 이곳 명소 가운데 하나인 약수폭포는 상부의 저수지에 물을 저장하고 있다가 여름에 풀어내 절경의 극치를 보여준다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", - "MNTN_NM" : "청도남산" + "DETAIL_INFO_DTCONT" : "승학산은 부산의 억새명산이다. 승학산은 부산에서 가장 서쪽에 있으며, 구덕산과 시약산의 서쪽, 엄광산의 남쪽으로 사하구 당리동의 뒷산이다. 승학산 동쪽 제석골 안부에 억새군락이 있는데, 이는 수만 평에 이르는 부산 제1의 억새밭이다. 바람 따라 일렁이는 대장관은 전국의 어느 억새명산 못지않다. 더불어 부산의 다양한 풍경을 한눈에 조망할 수 있다.승학산의 동쪽에는 영도, 감천, 송도 등의 항구와 바다가 펼쳐지며, 서쪽에는 서서히 강폭을 넓히는 낙동강과 드넓은 김해벌이 그 규모를 자랑하고 남쪽에는 연대봉이 우뚝 솟았고 북쪽에는 발아래 펼쳐진 억새밭이 눈길을 사로잡는다. 승학산은 높지 않으나 그 이름처럼, 도시 속의 고고한 학과도 같은 화려함으로 등산인들의 마음을 사로잡는 산이다. 고려말 무학대사가 전국을 두루 돌아다니며 산세를 살폈는데 이곳에 오니 산세가 준엄하고 기세가 높아 마치 학이 나는 듯 하여 승학산이란 이름을 붙였다는 전설이 전해 오며 흔히 동아대 뒷산이라고도 한다.", + "MNTN_HG_VL" : "497", + "MNTN_LOCPLC_REGION_NM" : "부산광역시 사하구 당리동", + "MNTN_NM" : "승학산" }, - "longitude" : 128.70460869999999, - "latitude" : 35.614273900000001 + "longitude" : 128.97999999999999, + "latitude" : 35.116666700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉화읍에서 동남쪽으로 26km 떨어진 청량산(869.7m)에는 금탑봉을 비롯하여 아름다운 봉우리 12개와 8개의 동굴이 있다.자연경관이 수려하여 옛부터 소금강이라 전하여지는 명산으로써 태백산에서부터 시작되는 낙동강 줄기가 절벽을 감아돌아 절경을 빚어내고 있으며, 신선이 내려와 바둑을 두었다는 신선대와 선녀가 가무유희를 즐겼다는 선녀봉을 비롯하여 12봉의 기암괴석으로 이루어져 있고, 신라때부터 근세에 이르기까지 김생, 퇴계이황등 선현들이 수도를 하던 유불선교 발상지로 널리 알려져 있을뿐만 아니라 고려 공민왕 10년에 제2차 홍건적의 난을 피하여 왕이 이곳에 와 마지막요새로써 산성을 축조하였고, 난이 끝난후 왕이 이곳을 떠나자 주민들이 왕을 추모하기 위하여 공민왕당을 세우고 봄, 가을로 공을 드리자 대란이 있을때 마다 소리가 울려 재난을 피할수 있었다는 전설이 있으며, 이곳 공민왕당을 오르는 등산로는 말 다섯 마리가 한꺼번에 지나다녔다는 五馬道가 있다.", - "MNTN_HG_VL" : "870", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 명호면", - "MNTN_NM" : "청량산" + "DETAIL_INFO_DTCONT" : "오도산은 도선국사가 깨달음을 얻었던 곳으로 숙성산 정상에서 이 산을 보면서 산의 기운과 형상에 도취되어 꼬박 일주일을 움직이지 않았다고 한다. 이를 본 주민들이 도선이 잠든 것으라 여겨 숙성산 정상을 성수단(聖睡壇)이 된 것이라고 전해진다.도선국사가 도취될 만큼 이 산에는 지실골, 한시골, 폭포골, 두오골 등 맑고 깊은 계곡이 포진해 있어 안으로 들어가면 갈수록 깊이를 더하는 산이다. 골짜기는 오도산,미녀산,숙성산에서 흘러내리는 물들을 모아 수량이 풍부하다. 다래나무가 계곡을 가릴 정도로 많고 그 열매가 계곡 암반에 떨어져 소복히 쌓여 있고 더러는 계곡의 와폭을 따라 흐르기도 한다.정상은 통신시설 때문에 일반인의 출입은 금지하고 있다. 정상 일대의 도로에서 사방을 조망하는 맛이 그만이다. 덕유산을 비롯해 수도산, 가야산 그리고 자굴산, 황매산,지리산, 백운산, 계관산, 황석산, 기백산이 병풍을 친 듯 장관이고 남으로 합천호도 보인다.", + "MNTN_HG_VL" : "1134", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가조면, 합천군 묘산면", + "MNTN_NM" : "오도산" }, - "longitude" : 128.90838890000001, - "latitude" : 36.7964974 + "longitude" : 128.07499999999999, + "latitude" : 35.673888900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 인천", - "MNTN_NM" : "청량산" + "DETAIL_INFO_DTCONT" : "합천호 푸른물속에 산자락을 담그고 하봉, 중봉, 상봉 등 세 봉우리로 정상을 이루어 수중매로 불리는 황매산(1,108m)은 합천읍에서 서남쪽으로 20km 지점에 위치해 있다.산아래의 황매 평전은 목장 지대와 고산 철쭉 자생지가 있으며, 통일 신라시대의 고찰인 염암사지(사적 131호)가 있다. 황매산은 군리 공원으로 1983년 지정되어, 가회면 둔내리에서 영암사지에 이르는 등산로를 개설하였다. 대병면 하금리 하금천에는 야영장을 개설하여 합천호와 이 지역을 찾는 관광객의 편의를 도모하고 있다.", + "MNTN_HG_VL" : "1113", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면, 가회면, 산청군 차황면.", + "MNTN_NM" : "황매산" }, - "longitude" : 126.67919689999999, - "latitude" : 37.431407100000001 + "longitude" : 127.9744444, + "latitude" : 35.495833300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "155", - "MNTN_LOCPLC_REGION_NM" : "경기도 화성시", - "MNTN_NM" : "청명산" + "DETAIL_INFO_DTCONT" : "자굴산은 얼핏 보기에는 단순한 봉우리같지만 들어서서 보면 제법 다양한 경관을 갖추고 있는 산이다. 합천이나 산청으로 이어지는 20번 국도가 이 산 밑을 지나기 때문에 이 지역 사람들에게는 매우 친숙한 곳이다.자굴산은 남명 조식선생의 싯귀에 `도굴산( 堀山)'이라 기록되어 있고 저굴산, 지굴산, 사굴산이라고 불리는 등 산 이름의 유래가 명확치 않다. 그러다가 일제말기에 지방 유지들로 구성된 등산 친목단체 `운악회'에서 고향 진산의 이름을 통일하자고 의견을 모아 빼어난 산세를 강조하기 위해 글자마다 뫼산자를 넣어 표기했다고 한다.정상에서면 지리산 천황봉이 손에 잡힐 듯 가깝게 보인다. 그리고 절터샘과 명경대, 신비로운 금지샘 등 명소가 있다. 샘에는 억새가 무성하고 조망이 좋다.", + "MNTN_HG_VL" : "897", + "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군 칠곡면, 가례면, 대의면", + "MNTN_NM" : "자굴산" }, - "longitude" : 126.7261111, - "latitude" : 37.175555600000003 + "longitude" : 128.20224590000001, + "latitude" : 35.374487700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "가리왕산에서 뻗어 내려간 주능선이 서쪽으로 중왕산을 일으키고 여기서 남쪽으로 다리를 놓은 듯 가로질러 내려가는 능선 끝에 일으킨 산이 바로 청옥산이다, 산세는 가리왕산과 흡사한 점이 있고, 중후한 육산의 형태를 띠고 있다.청옥산은 '곤드레' 나물과 더불어 '청옥' 이란 산채가 많이 자생하여 이름 붙여진 산이다. 능선이 비교적 평탄한 지형으로 그 면적이 볍씨 6백두락이나 된다는 뜻에서 지어진 '육백마지기'가 산 정상에 위치하고 있으며 고랭지 채소를 주로 재배하고 있다.산행은 백일동에서 동남계곡을 따라 밸패재에 올라 남쪽 능선으로 정상에 올랐다가 서쪽 능선을 따라 삿갓봉(1,055m)으로 이어지는 능선 중간에서 지동리를 지나 창선탄광 입구 고길리로 하산할 수 있다.", - "MNTN_HG_VL" : "1256", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 평창읍", - "MNTN_NM" : "청옥산" + "DETAIL_INFO_DTCONT" : "경원선 철도가 휴전선에 막혀 더 이상 달리지 못하고 멈추는 곳에 고대산이 솟아 있다. 고대산은 등산객들이 자유롭게 산행을 할 수 있는 산 중에서 휴전선에 가장 가깝게 위치해 있는 산이다. 경기도 최북단인 연천군 신서면 신탄리와 강원도 철원군 사이에 있는 고대산 정상에서는 북녘의 철원평야와 6·25 때 격전지인 백마고지, 금학산과 지장봉, 북대산, 향로봉은 물론 한탄강 기슭의 종자산까지 한눈에 들어온다. 분단의 한, 망향의 한이 굽이쳐 북녘이 그리울 때, 멀리서나마 북녘땅을 바라볼 수 있는 3대 명산으로 고대산, 복계산, 지장봉을 꼽는데 해마다 6월이면 분단 상황을 체험해 보려는 많은 등산인들이 고대산을 찾는다. 수려한 전망과 적당한 코스 등 최적의 산행코스를 갖췄음에도 전략적 요충지라는 이유로 웬만한 지도에는 감춰진 산이다. 휴전선과 가장 가까운 곳에 있기 때문에 여태껏 사람들에게 잘 알려지지 않았다는 것이 이 산이 간직한 매력이기도 하다.", + "MNTN_HG_VL" : "832", + "MNTN_LOCPLC_REGION_NM" : "경기도 연천군 신서면·강원도 철원군 철원읍", + "MNTN_NM" : "고대산" }, - "longitude" : 128.50805560000001, - "latitude" : 37.410277800000003 + "longitude" : 127.1549062, + "latitude" : 38.198599399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "청옥산은 백두대간이 금강산, 설악산, 오대산 등을 빚으며 동해안을 따라 남동쪽으로 내려가다가 동해지방 해안가에 이르러 솟아 오른 명산이다. 두타산과 함께 사방에 드리운 능선과 고개를 끼고 있으며, 짙푸른 동해를 손아래로 굽어 보고 있다. 이 산은 여러 등산로와 유적지가 있어 아름다운 절경을 감상하는 등산객의 발길이 끊이지 않는 곳이기도 하다. 두타산과의 거리는 약4km정도여서 일찍 서두른다면 두타산과 청옥산을 함께 오를수도 있다. 청옥산과 두타산 산아래 펼쳐진 국민관광지 1호 무릉계곡은 100여명을 수용할 수 있는 무릉반석과 학소대, 선녀탕 그리고 계곡 양편에 깎아지른 듯한 병풍바위 등 웅장한 절경을 안고 있다.두타산 북릉에는 두타산성이 있고, 바위가 좋아서 오르기엔 안성마춤인 코스이다. 상대적으로 두타산에서 청옥산에 이르는 코스는 부드럽고 완만하여 하산로로 이용하는것이 좋다. 청옥산까지 종주한후 연칠성령이나 학등을 이용하여 하산할경우 거리도 약 20km나 되고 소요시간도 대략 9시간정도가 소요될걸로 생각된다. 산이 워낙 크고 깊기때문에 눈이나 비가 많이 올때는 삼가하는편이 좋다.", - "MNTN_HG_VL" : "1403", - "MNTN_LOCPLC_REGION_NM" : "강원도 동해시 삼화동, 삼척시 정선군", - "MNTN_NM" : "청옥산" + "DETAIL_INFO_DTCONT" : "구룡령은 옛부터 큰 고개인 원구룡령의 남동쪽 1㎞지점에 위치해 있다. 옛 구룡령은 현고개에서 서북쪽의 1100고지를 넘어가야 있는 것이다. 약수산이란 이름은 흔히 명개리 약수라 불리는 이 산 남쪽 골짜기의 약수에서 유래한 것이라고 한다.약수산은 백두대간이 오대산에 이르기 직전 산세를 일으키고 있는 산 들 중의 하나다. 구룡령 너머 서쪽엔 갈전곡봉이, 동남으로는 응복산(1360m), 만월봉(1279m)이 한 어깨로 나란히 솟아있다. 그래서 이 산들을 연결해서 종주하는 산악인들도 여럿 있다. 홍천군 내면 목맥동 일대는 수림이 울창하고 각종 희귀 동식물과 열대어 등 어류가 서식하고 있어 자연훼손을 최소화하는 산행을 해야 겠다.약수산 북쪽으로 이어진 암산 동북으로 깊고 길게 패여진 미천골은 아직 사람들이 많이 드나들지 않아 옛날 그대로의 숲과 자연경치를 간직 한 곳이다. 양옆으로 늘어선 나무들이 시원스럽고, 계곡 안의 물속에는 물고기들이 많다.울창한 숲, 맑은 물, 기암괴석, 야생동식물, 약수터, 신라고적, 토종꿀, 각종 산림부산물 등 휴양원이 풍부하고, 또한 이곳의 미천골 자연휴양림은 5,652천㎡의 시설 구역내에 평균수명 50년 이상의 활엽수 천연림으로 삼림욕을 즐길 수 있다. 미천골 초입에는 신라 법흥왕 때 창건했다가 고려 말에 폐사되었다는 선림원터가 있다. 석등, 3층석탑, 홍각선사탑비, 부도 등의 보물급 문화재가 남아 있다.공지(空地)로 된 정상에서는 남쪽의 백두대간길과 소황병산 및 오대산 구간이 잘 바라보인다.", + "MNTN_HG_VL" : "1306", + "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 내면", + "MNTN_NM" : "약수산" }, - "longitude" : 128.9735857, - "latitude" : 37.433949400000003 + "longitude" : 128.5261151, + "latitude" : 37.882913799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태백산 망경대 정상에서 남동편에 위치한 산이다. 소천면 늦재에서 능선 따라 망경대로 이어지는 등산로가 있다. 이 산에는 세계최남단의 열목어 서식으로 유명한 백천계곡이 있고, 산 기슭 중턱에는 사명대사가 수도했다는 홍제사가 있다.태백산을 중심으로 이 산을 비롯해 일대에 1,000m가 넘는 산들만도 9개 봉이나 되어 심산유곡의 자연미를 만끽할 수 있다. 백두대간 갓대배기봉에서 동남으로 갈래친 능선 위에 있고, 소천면 늦재에서 능선을 따라 망경대로 이어지는 등산로가 있다.일대 1억 53만㎡가 청옥산 자연휴양림으로 지정되었는데, 한국의 휴양림 가운데 가장 넓고 물놀이장, 체력단련장, 산막, 야영장, 캠프파이어장 등의 편의시설이 완비되어 있다. 산기슭 중턱에는 유정(惟政)이 수도했다는 홍제사가 있고 산 옆으로 흐르는 고선계곡은 길이 100리에 이르는 깊은 원시림계곡을 이룬다.태백산 문수봉과 청옥산 사이에서 시작되어 조록바위봉까지 이르는 12㎞의 백천계곡은 낙동강의 상류이며 세계 최남단의 열목어(천연기념물 74) 서식지로 유명하다. 일대는 천연기념물 및 천연림 보호지역이므로 출입을 제한한다.그밖에 주변에는 5만 영령위로탑이 세워져 있는 현불사와 오전약수, 우곡약수터, 불영사, 다덕약수관광지, 두내약수관광지, 청량산 도립공원, 사미정(四未亭) 등의 관광지가 있다. 또한 겨울철에는 적설량이 많아 늦은 봄까지 눈을 볼 수 있고, 임도가 넓어 산악스키를 즐기기에 적당하다.", - "MNTN_HG_VL" : "1256", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 석포면, 소천면", - "MNTN_NM" : "청옥산" + "DETAIL_INFO_DTCONT" : "완주군 동북부에 있는 요지인 고산은 고려시대에는 봉성형이었으며 조선시대에는 고산군이었다. 금남정맥에서 뻗쳐와 원등산 위봉산 되실봉을 거쳐 북쪽으로 달려가 안수산을 솟구친다. 북쪽으로 나아가던 500m대의 산세가 고산을 눈앞에 두고 갑자기 멈추며 산줄기는 동쪽으로 틀어진다.북쪽으로의 진행을 멈춘 산줄기는 자연스럽게 높은 턱을 이루고 그 끝에 크나큰 암봉을 빚어놓았다. 특히 이 암봉(일명 달걀봉)은 고산천이 휘돌아 흐르는 고산마을을 굽어보고 있다. 고산에서는 물론 봉동 삼레 일대 들녘에서도 눈에 잘 띄는 특이한 산세다. 달걀봉 아래 제법 널찍한 터에 안수암이 있고 수 백년 된 느티나무가 그 연륜을 자랑하고 있다. 느티나무로 미루어 볼 때 적어도 수 백년 전부터 있었으리라 믿어지는 안수암은 모악산 금산사의 말사로 지금은 젊은 범운스님이 홀로 다스리고 있다.안수산을 고산 사람들은 고산의 지킴이로 믿고 있다. 고산천을 중심으로 펼쳐진 고산 일대의 지형이 풍수지리적으로 '지네'의 형국이라 한다. 지내의 독기를 누릴 수 있는 것은 지네와 상극인 '닭'으로 알려져 있는데이 안수산이 닭벼슬을 닮아 일명 '계봉산'으로 불린다. 또 멀찍이서 바라보면 거대한 바위로 이뤄진 주봉이 듬직한 자태로 서 있어 오르기 전부터 보는 이의 마음이 한결 뿌듯해진다.안수산 정상에서 되실봉 정상까지 약 2시간 30분 소요되는 암릉코스가 산행의 재미를 더해준다. 산행기점은 주로 청동마을이나 성재동마을로 잡는 것이 일반적인데, 안수산 서쪽 계곡 저수지로 하산하거나 안수산에서 되실봉을 거쳐 오성리로 하산할 수 있다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 고산면", + "MNTN_NM" : "안수산" }, - "longitude" : 128.96222220000001, - "latitude" : 37.0433333 + "longitude" : 127.22648959999999, + "latitude" : 35.954262300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "1277", - "MNTN_LOCPLC_REGION_NM" : "경상북도 봉화군 석포면, 소천면", - "MNTN_NM" : "청옥산" + "DETAIL_INFO_DTCONT" : "마니산에는 거대한 바위성 같은 바위절벽을 안고 선 향로봉이 있다. 수려한 산세를 가졌지만, 아직도 이 산을 찾는 이가 그리 많지 않다. 바로 서쪽에 영동의 명산 천태산의 명성에 가려져 있기 때문이다.향로봉의 동면 아래에 있는 중심이 마을쪽은 좌우가 모두 깍아지른 바위벼랑이며 향로봉 둘레 575봉과 564봉의 남면 모두가 엄청난 높이의 낭떠러지를 이루고 있어 장관이다. 전체적인 마니산의 지형은 한 마리의 문어가 금강을 향해 발을 뻗친 모양이다. 그 발 끝에는 어류산, 시루봉, 노고산, 봉화산, 동골산이 있다. 동면에는 마니산 성터와 공민왕의 거처였다는 절터가 있다. 마니산 능선에서 고려 공민왕때 홍건적의 난을 피해 들어 왔을 때 쌓은 산성벽이 지금도 남아있다.", + "MNTN_HG_VL" : "469", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동군, 옥천군", + "MNTN_NM" : "마니산" }, - "longitude" : 128.96222220000001, - "latitude" : 37.0433333 + "longitude" : 127.6519444, + "latitude" : 36.171666700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "청우산(해발 619.3m)은 46번 경춘국도를 따라 가평 춘천 방면으로 진행하다가 청평 건문소에서 현리 포천방면 37번국도로 옮겨 오다보면 가평 사계절 썰매장을 막지나 광성교회수련원앞에광진교를 건너면서 산행이 시작된다.청우산은 명지산에서 시작하여 매봉, 대봉, 대금산이 가평을 동서로 가루는 산줄기의 끝 지점에 위치해 있다. 그리 높지 않은 산임에도 정상에 경치가 매우 아름답다 동쪽으로 경춘국도를 사이에 두고 호명산과 주발봉으로 이어지는 산맥이 옆으로 길게 누운 모습이 한눈에 들어온다.#65517;소요 시간 : 정상까지 2시간#65517;볼거리 : 아침고요수목원#65517;최적 탐방 시기 :4월 \/봄 잣나무숲을 끼고 청오사를 지나 능선마루에 오르면 봄이면 능선마다 진달래와 철쭉이 만발하고 참나무숲이 우거져 있다.#65517;숲길 명소 : 정상에서 조망#65517;문화재 : 경기 가평군 하면 대보리 산176-1번지 기념물 제28호 조종암(朝宗巖)이 바위는 조선(朝鮮) 숙종(肅宗) 10년(1684)에 가평군수(加平郡守) 이제두(李齊杜)와 허격(許格) 백해명(白海明) 등이 명(明)나라가 임진왜란(壬辰倭亂) 때 베푼 은혜와 청(淸)나라로부터 당한 굴욕을 잊지 말자는 뜻을 새긴 숭명배청사상(崇明排淸思想)의 기념물이다.#65517;산이 험하지 않아 청우산만 오른다면 하루거리로 적당한 산행이 될수 있고 주변 산장국민관광지는 가족과 즐길수 있는 야영캠프장과 어린이 놀이터, 다목적운동시설 등이 있다.", - "MNTN_HG_VL" : "619", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 상면, 외서면", - "MNTN_NM" : "청우산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "481", + "MNTN_LOCPLC_REGION_NM" : "충청남도 예산군", + "MNTN_NM" : "서원산" }, - "longitude" : 127.4138889, - "latitude" : 37.780833299999998 + "longitude" : 126.63341490000001, + "latitude" : 36.7292141 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간 마루금상의 청화산(984m)은 정상은 경상북도 상주와 문경시, 충청북도의 괴산군과 경계를 이루고 있다. 북쪽 대야산에서 남진하여 조항산을 지나온 백두대간이 청화산에 이르면 방향을 남서쪽으로 틀어 눌재로 떨어진 다음 속리산으로 이어져 나간다.lt;택리지gt;에서 이중환은 “청화산은 뒤에 내외의 선유동을 두고 앞에는 용유동에 임해 있어 경치가 지극히 좋음은 속리산보다 낫다”고 표현할 만큼 이름다운 산이다. 육산의 웅장함과 바위산의 아기자기한 맛을 함께 맛볼 수 있을 뿐만 아니라 백악산, 군자산 등 속리산국립공원 일원의 산봉들을 조망할 수 있다. 청화산 오름길은 크게 세 코스다. 오래전부터 많이 이용돼온 입석1리나 심송2리에서 송면지~갓바위재를 경유하는 코스와 사계절 인기 있는 백두대간상의 눌재 기점, 그리고 쌍룡계곡 병천에서 화산마을로 들어가 정상 접근이 가장 ª은 원적사를 경유하는 코스가 있다.", - "MNTN_HG_VL" : "984", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 상주시, 충청북도 괴산군", - "MNTN_NM" : "청화산" + "DETAIL_INFO_DTCONT" : "미륵산은 넓디넓은 호남평야 한가운데 위치한 작은 산이만 그 무게는 결코 가볍지 않다. 백제의 무왕이 된 서동과 선화공주 이야기를 간직한 미륵사가 있던 곳이고, 정상에는 마한시대 것으로 추정하는 마륵산성이 남아있기도 하다. 산 구경하기 어려운 익산땅에서 미륵산은 등산인들의 유일한 휴식처가 되기 때문에 사람들의 발길이 끊이질 않는다.정상은 주변의 넓은 평야지대로 인해 초록의 바다 위에 우뚝 솟은 섬처럼 거칠 것 없는 조망이 일품이다. 동남북 대둔산을 잇는 금남정맥 줄기가 부드럽게 이어져 있고 익산시가지가 훤히 내려다보인다. 다만 아쉬운 것은 정상에 위치한 두 개의 무덤에 훼손 방지를 위해 날카로운 철조망이 처져 있어 절대 들어오지 말라는 듯 위협한다.정상에서 동쪽으로 내려서면 미륵산성을 만난다. 일부 복원된 산성의 규모만으로도 그 크기를 짐작할 정도로 아주 크며 주변으로 높은 산이 없어 멀리까지 관찰할 수 있는 이점이 있는 곳이다.미륵산을 중심으로 금마, 삼기면 일대에는 마한 선인들이 남긴 민속놀이와 미륵산록에 찬란하게 꽃피웠던 백제문화를 보존 전승하기 위하여 매년 10월 8일에 축제를 벌인다. 축제에는 마한 때 유래된 것으로 보여지는, 깃대를 앞으로 숙여 세배를 하는 금마기세배(金馬旗歲拜)놀이를 비롯한 많은 민속놀이가 벌어진다. 특히 ‘콩 깍자, 콩 깍자’로 시작되는 ‘지게 목발 노래’는 지방무형문화재 1호로 지정된 농요(農謠)이다.", + "MNTN_HG_VL" : "430", + "MNTN_LOCPLC_REGION_NM" : "전북 익산시 금마면ㆍ낭산면ㆍ삼기면", + "MNTN_NM" : "미륵산" }, - "longitude" : 127.91937729999999, - "latitude" : 36.624444099999998 + "longitude" : 127.03903339999999, + "latitude" : 36.0250561 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충북과 경북의 경계인 청화산은 멀리 소백산으로부터 조령산, 주흘산, 대야산 등과 함께 속리산을 솟구치게 하는 교두보 역할을 한다. 청화산은 울창한 숲과 험준한 바위가 잘 어우러져 산행의 재미를 두배로 맛볼 수 있는 산이다.의상저수지에서 누런 문양처럼 보이는 갓바위재까지 가는 길은 송림이 무성하며 산죽도 군락을 이루고 서 있다. 겨울철에도 푸르름을 간직하고 있는 비경과 그 드넓은 산죽군락은 보는 사람의 가슴을 깨끗이 정화 해 줄 듯 하다. 갓바위재에서 871봉을 거쳐 정상에 오르는 길에는 수많은 기암이 대기하고 서 있는데 특히 871봉에서 정상까지는 중간에 세미클라이밍을 해야 할만큼 험준하다.한편 등산 기점인 옥양동에서 의상저수지로 가다보면 둘레가 5미터, 폭이 20미터, 높이가 15미터인 소나무가 서 있는데 이는 천연기념물 제 290호로 지정되어 있는 용송이다.", - "MNTN_HG_VL" : "984", - "MNTN_LOCPLC_REGION_NM" : "경상북도 상주시 화북면, 문경시 농암면, 충청북도 괴산군 청천면", - "MNTN_NM" : "청화산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "경상남도 거창", + "MNTN_NM" : "수도산" }, - "longitude" : 127.91937729999999, - "latitude" : 36.624444099999998 + "longitude" : 127.98164250000001, + "latitude" : 35.859287100000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "701", - "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 도개면 다곡리", - "MNTN_NM" : "청화산" + "DETAIL_INFO_DTCONT" : "도비산은 서산시에서 연암산(441m)과 팔봉산(362m)에 이어 3번째로 높다. 정상에 올라서면 서해 조망이 뛰어나다. 주변에는 안면도 간월암 수덕사 등 관광명소가 산재해 있어 여름철 가족 산행지로 적격이다.산행 들머리는 추평리 부석사 입구에서 시작된다. 이곳서 시멘트로 포장된 농로를 따라 30여분을 올라가면 부석사에 닿는다. 급경사길을 20여분 오르면 능선에 닿는다. 능선길을 따라 15분 정도 걸으면 바로 정상. 그만큼 산행을 하기에 어려움이 없다. 정상에 오르면 천수만 간척지를 비롯해 너른 들판과 그 너머로 서해바다가 손짓한다. 도심에서는 느낄 수 없는 포근함이 다가온다. 또 겨울이면 간월호와 부남호의 철새를 볼 수 있다.일설에 의하면 산 대부분이 나무로 덮여 있어 봄이면 복숭아꽃으로 산을 장식하고, 주위에 낙화가 소복이 쌓이는 데서 연유되어 [복숭아 도]자 와 [살찔 비]자를 써서 도비산이라 이름 붙였다고 한다.", + "MNTN_HG_VL" : "352", + "MNTN_LOCPLC_REGION_NM" : "충청남도 서산시 인지면", + "MNTN_NM" : "도비산" }, - "longitude" : 128.4005908, - "latitude" : 36.289798699999999 + "longitude" : 126.41607550000001, + "latitude" : 36.702880200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "636", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 대구", - "MNTN_NM" : "초례봉" + "DETAIL_INFO_DTCONT" : "\"보령 시가지를 동남쪽으로 둘러서 있는 산이 성주산과 옥마산이다. 성주터널이 생기기 전 성주와 부여 쪽으로 가려면 옥마산을 통과하는 구절양장을 고갯길을 넘어야 했다. 비포장도로인 옛길을 가쁜 숨을 몰아쉬고 오르다보면 보령시가지가 한눈에 내려다보이는 정자가 옥마정이다.옥마정에서 성주로 향하는 내리막길에서 다시 산을 타고 오르면 보령 행패러글라이딩 활공장과 만난다. 이곳은 항공 스포츠를 즐기는 이들에게 새로운 메카 구실을 하는 곳이다. 행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하여 자세한 안내를 받을 수 있다.소요 시간 :180분 (구간별, 코스별로 다름)최적 탐방 시기 :4 ~ 5월 \/봄볼거리 : 옥마정에서 보는 시내전망, 활공장(행글라이딩과 패러글라이딩을 즐기기 위해 전국에서 몰려드는 사람들의 발길이 잦은 곳이며, 활공장 옆 솔숲에는 휴식공간이 마련돼 있다.보령시에서는 매년 전국 규모의 활공 대회를 개최하고 있다. 대천항공클럽(041-936-1797)에 문의하면 자세한 안내를 받을 수 있다)", + "MNTN_HG_VL" : "602", + "MNTN_LOCPLC_REGION_NM" : "충청남도 보령시", + "MNTN_NM" : "옥마산" }, - "longitude" : 128.75, - "latitude" : 35.899999999999999 + "longitude" : 126.6350923, + "latitude" : 36.317708400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "초록봉은 백두대간의 연봉 청옥산의 한 봉우리로 수목이 울창하고 계곡과 자연경관이 아름다운 등산로이며 정상에서 동해시 전체가 바로 보여 동해 8경 중 제8경으로 선정되었다. 최근들어 시민들의 휴식공간 및 소원을 빌기 위한 장소로도 많은 사람들이 찾고 있다.초록봉에는 ‘칠성바위’라고 불리는 바위가 있다. 이 바위에는 전설이 전해져 오는데, 옛날 인간세상이 너무 어지러워 하느님이 세상을 바로잡기 위해 한 장수를 보냈다. 이 장수는 세상을 바로잡고 자기 일을 다 한 후 승천하기 위해 힘차게 바위를 밟고 지나갔는데 그 장수의 오른쪽 발자국은 초록봉 벼락바위에, 왼쪽 발자국은 초록봉 아래 바위에 길이 15미터, 높이 3미터의 큰 흔적으로 남았다. 후세 사람들은 그 바위에 소원을 빌면 소원성취 있다해 칠성바위라 불렀다.옛적에는 초로의 산, 비나리의 산으로 명성이 있었으나 대형 산불로 잿더미가 되는 바람에 현재는 오히려 조망 좋은 일출, 일몰 산행지로 각광받고 있다. 초록봉은 산세가 부드럽고 키 큰 나무가 적어 산행 내내 바다를 볼 수 있으며 등산로도 유추하기 쉬워 길을 잃을 염려가 없다. 중식시간을 포함하더라도 느긋하게 5시간이면 충분히 산행을 즐길 수 있다.", - "MNTN_HG_VL" : "529", - "MNTN_LOCPLC_REGION_NM" : "강원도 동해시", - "MNTN_NM" : "초록봉" + "DETAIL_INFO_DTCONT" : "경상남도 거창군 북상면(北上面)과 함양군 서상면(西上面)의 경계에 있는 산. 덕유산국립공원 남쪽에 위치한다. 북쪽 능선을 따라 덕유산(1,614m)에 이르고, 남쪽으로는 거망산擧網山:1,184m)에 이른다.동쪽 비탈면은 남강(南江)의 상류인 지우천(智雨川)의 수원이 되고, 동쪽에 위치한 기백산(箕白山:1,331m)과의 사이에 계곡을 이룬다.서쪽 비탈면은 완만하고 남강의 상류 하곡(河谷)을 이룬다. 서쪽의 장수군 장계면(長溪面)과의 사이에 육십령(六十嶺)이 있는데, 영남과 호남지방의 중요한 통로이다. 남강 하곡분지를 둘러싸고 있으며 덕유산에 이어져서 자연경관이 아름답다. 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나다.소요 시간 :1코스 (3시간정도)서상 - 영각사 - 남녕재(기점) - 능선 - 정상2코스 (4시간정도)안의 - 용추계곡 - 수망령 - 큰목재 - 정상 - 남녕재최적 탐방 시기 :5, 9월 \/ 봄, 가을볼거리 : 육산인 듯하면서도 암봉과 암벽이 적절히 배치되어 절경이 뛰어나며 남릉과 서북릉의 중턱위로 진달래가 군락을 이루어 천상의 화원을 걷는 기분이 든다.숲길 명소 : 남릉과 서북릉의 중턱위로 진달래 군락월봉산은 덕유산의 명성에 가려 많이 알려지지 않았다가 최근 들어 찾는 이가 늘고있는 산이다. 단독코스로도 다녀올 수 있고 금원산과 연계하여 종주하기도 하고 거망산과 연계하여 종주하기도 한다.함양군에서 안내판과 이정표를 적절히 설치해놓았다. 내계에서 가는 길은 임도길을 많이 걸어야해 산길오르기전에 지치기 쉽다. 남령 안내판에는 식수대가 그려져있지만 찾아보니 없다. 식수대가 있으면 좋을 듯하다.", + "MNTN_HG_VL" : "1294", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군 서상면, 거창군 북상면", + "MNTN_NM" : "월봉산" }, - "longitude" : 129.0714347, - "latitude" : 37.522134999999999 + "longitude" : 127.72486480000001, + "latitude" : 35.729298100000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "전남 보성은 차 다음으로 철쭉이 유명한 고장이다. 이에 제암산과 일림산은 5월이면 사람들이 줄 지어 찾아 오른다. 반면 같은 보성임에도 불구하고 여유롭게 철쭉을 즐길 수 있는 산이 있으니 바로 겸백면에 위치한 초암산이다.제암산, 일림산이 산 정상에 오르면 푸른 바다와 어우러진 철쭉을 볼 수 있다는 장점이 있는 반면 초암산은 철쭉 하나로 승부한다. 단출하게 느껴지지만 그만큼 색이 분산되지 않는 단정한 미학이 살아 있는 산이다. 또한 초암산은 철쭉이라는 핵심만을 즐기고 내려올 수도 있다는 간편함이 두드러진다. 최근 너무 힘든 산행보다는 간편하게 즐기면서 오를 수 있는 산을 찾는 사람들이 증가한 만큼 초암산은 앞으로 많은 사람들이 찾기에 매력적이다. 북쪽 임도를 이용해 철쭉밭 바로 아래까지 차량으로 올라간 다음 정상 철쭉밭을 구경한 후 되내려오는 거의 관광에 가까운 탐방이 가능하다.너무 간단하게 느껴진다면 호남정맥 일부를 이루고 있는 광대코재~주월산~방장산~오도재 능선을 포함한 원점회귀형의 사뭇 긴 당일산행 코스를 잡을 수도 있다. 겸백면은 이 원점회귀형 등산로의 출발지인 수암리에 널쩍한 주차장도 새로 만들었다.더불어 보성군은 ‘녹차와 철쭉이 어우러진 보성’이라는 모토로 작년부터는 초암산에서도 철쭉제를 열고 있다.", - "MNTN_HG_VL" : "576", - "MNTN_LOCPLC_REGION_NM" : "전남 보성군 겸백면", - "MNTN_NM" : "초암산" + "DETAIL_INFO_DTCONT" : "봉화산이란 이름에서 알수 있듯 이산은 연기나 불을 피워 통신을 하던 봉화대가 있는 산으로 사방이 트인 전망이 일품이다.장수군 천천면과 계남면을 가르고 있는 봉화산 정상에 서면 북동쪽으로 파도처럼 일렁이는 덕유산 능선이 보이고 12대 종산중의 하나인 장안산이 시야에 들어온다. 봉화산 산행의 맛을 음미하자면 정북 방향의 능선을 타고 방아재쪽으로 올라야 한다. 다른 봉우리에 비해 방아재는 여러 골짜기 물을 받아 흘러가는 천천의 물줄기를 한눈에 바라볼 수 있기 때문이다.평범하기 이를 데 없는 이 봉화산에 최근 남원을 기점으로 등산인들의 발길이 잦아지고 있다. 그 이유는 몰론 철쭉 군락이 발견되었기 때문이다. 철쭉 군락이 산사면 곳곳에 널려 있는 데다가 장수와 함양 땅으로 뻗은 암릉길이 온통 철쭉꽃길이다.", + "MNTN_HG_VL" : "338", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군 천천면, 계남면", + "MNTN_NM" : "봉화산" }, - "longitude" : 127.1822171, - "latitude" : 34.828257000000001 + "longitude" : 127.5485212, + "latitude" : 35.701548299999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평에는 한북정맥의 주를 이루는 1000미터급 고봉이 밀집되어 있다. 촉대봉은 경기도에서 제일 높은 화악산에서 동쪽으로 뻗어 내린 능선이 응봉(1436m)에서 동남쪽 홍적이고개로 이어지는 능선에 솟아 있는 산이다. 이름은 정상 부분이 봉우리 세 개로 되어 있고 끝이 뾰족한 데서 유래하였으며 촉대봉(燭臺峰)이라 한다. 화악산이 북쪽에서 남쪽을 바라보며 버티고 서 있는 형상이라면 촉대봉은 왼쪽 어깨에 해당하는 것으로 거대한 바위와 나무가 우거진 능선이 웅장하고 정상에서의 경치가 장관이다. 특히 겨울 설경과 가을 단풍이 아름답다.강원도 춘천시 사북면과 경기도 가평군 북면의 경계를 이루고 있는 촉대봉에는 동쪽 산자락인 강원도 춘천시 사북면 지암리에 집다리골자연휴양림이 조성되어 있다. 능선 끝의 멱골, 싸리재마을은 의병운동와 독립만세운동의 중심지였다.", - "MNTN_HG_VL" : "1125", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면·강원도 춘천시 사북면", - "MNTN_NM" : "촉대봉" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "151", + "MNTN_LOCPLC_REGION_NM" : "전라남도 목포", + "MNTN_NM" : "양을산" }, - "longitude" : 127.5444444, - "latitude" : 37.975833299999998 + "longitude" : 126.40777780000001, + "latitude" : 34.812500000000007 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "비슬산의 주봉에서 동쪽으로 이어지는 능선이 북으로 방향을 바꾸어 올라가다 솟구쳐서 이루어진 산(900m)이다. 비슬산 주봉우리의 동쪽 능선이 북쪽으로 이어져 솟은 산이다. 비슬산과 산세가 비슷하며, 700m 부근부터는 경사가 완만한 고위평탄면 지형을 이룬다. 침엽수림과 활엽수림이 섞여 자라 혼합림을 이루고, 1천여 종의 자생식물이 자라며, 봄에는 진달래 천국을 이루고 가을에는 단풍이 온산을 물들여 대구 근교 지방의 주민들에게는 매우 친근한 산이다.정상 일대 능선에는 억새풀과 진달래가 군락을 이루어 자란다. 주암산과는 능선으로 이어져 있으며 두 산을 연결하여 산행하면 좋다.", - "MNTN_HG_VL" : "905", - "MNTN_LOCPLC_REGION_NM" : "대구광역시 달성군 가창면", - "MNTN_NM" : "최정산" + "DETAIL_INFO_DTCONT" : "무릉산은 칠북면의 중심산역으로 작대산의 북쪽에 위치하면서 둥그스럼한 산릉에 부드러움을 더하고 있다. 낙동강에 산자락을 내밀고 있는 북릉은 북면 온천이 있는 마금산역에 손을 내밀면서 느긋하게 산세를 일으키고 있다.", + "MNTN_HG_VL" : "556", + "MNTN_LOCPLC_REGION_NM" : "경상남도 창원시 북면, 함안군 칠북면", + "MNTN_NM" : "무릉산" }, - "longitude" : 128.60083330000001, - "latitude" : 35.763888899999998 + "longitude" : 128.56579629999999, + "latitude" : 35.328721999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "담양읍에서 13km 정도 떨어진 높이 731.2m의 추월산은 전라남도 기념물 4호이자 전라남도 5대 명산중의 하나로 손꼽힌다.담양군의 최북단인 용면 월계리와 전라북도 순창 북흥면과 도경계를 이룬다. 많은 수림과 기암괴석, 깎아세운 듯한 석벽이 마치 성을 쌓은 듯이 둘러있고 서쪽에 겨우 사람 하나 통행 할 정도의 길이 트여 있다.", - "MNTN_HG_VL" : "731", - "MNTN_LOCPLC_REGION_NM" : "전라남도 담양군 용면, 전라북도 순창군 복흥면", - "MNTN_NM" : "추월산" + "DETAIL_INFO_DTCONT" : "마석에서 서북쪽으로 4.5km 떨어져 있는 산으로 1983년 군립공원으로 지정되어 휴일이면 많은 사람이 몰리고 있다.특히 이 곳은 스키장과 청소년 심신수련장 등이 있으며, 산의 형세가 험하지 않고 나무가 울창하여 당일 등산코스로 알맞다. 1990년 11월 1일부터 야영장외 지역에서는 취사가 금지됐다.", + "MNTN_HG_VL" : "810", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 오남읍, 화도읍", + "MNTN_NM" : "천마산" }, - "longitude" : 126.9756112, - "latitude" : 35.3992133 + "longitude" : 127.272778, + "latitude" : 37.680556000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "화도읍(마석)에서 북동쪽으로 12km 거리에 있는 축령산(887.1m)은 조종천과 수동천의 사이에 솟아 있다. 이 산에는 일명 '남이바위'라고 하는 바위가 있는데, 이는 조선시대 때 남이장이 이 곳에서 심신을 수련하였다 하여 붙여진 이름이라고 한다.축령산의 울창한 수림과 계곡을 이용하여 자연 휴양림을 조성, 삼림욕장, 휴계소, 체육시설, 놀이시설, 야영장 등 편의 시설이 두루 갖추어 진 곳이다.", - "MNTN_HG_VL" : "887", - "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시 수동면, 가평군 상면", - "MNTN_NM" : "축령산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "890", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "계족산" }, - "longitude" : 127.3330406, - "latitude" : 37.752879499999999 + "longitude" : 128.5200261, + "latitude" : 37.169667099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "축령산은 전남 장성과 전북 고창의 경계를 이루는 산으로 노령 지맥 위에 솟아 있다. 장성에서는 편박나무숲 기슭을 축령산이라 부르고 문수사에서는 청량산이라고도 부른다. 축령산은 6.25 전쟁 등 민족적 수난기에 깊은 상처를 받기도 한 산이지만 현재 축령산 남서쪽 산록은 유럽풍의 잘 조림된 침엽수림 지대를 연상케 한다.삼나무, 편백, 낙엽송, 리기다소나무 등 수령 5~50년생의 숲이 널찍하게 바다를 이루고 있으며 주변엔 천연림인 상수리, 졸참나무, 떡갈나무 등이 둘러싸고 있다.이렇듯 축령산이 세상에 알려진 것은 산을 두르고 있는 숲 덕분이다. 숲을 배경으로 영화 ‘태백산맥’, ‘내마음의 풍금’과 드라마 ‘왕초’도 촬영됐다. 하지만 축령산의 숲은 사람에 의해 인공적으로 만들어졌다. 일제시대를 겪으면서 완전히 헐벗었던 산이 지금의 모습이 되기까지 애쓴 분은 춘원 임종국 선생이다. 1956년부터 시작된 육림의지는 선생이 세상을 떠난 1987년까지 계속됐다.편백과 삼나무가 주를 이루는 축령산휴양림은 오후 1시부터 3시 사이에 산책하는 것이 좋다. 나무별로 피톤치드가 활발히 생성되는 시간이 다른데 편백과 삼나무의 피톤치드 활성 시간이 오후 1~3시 사이다.", - "MNTN_HG_VL" : "622", - "MNTN_LOCPLC_REGION_NM" : "전북 고창군 고수면, 전남 장성군 서삼면", - "MNTN_NM" : "축령산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "756", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남천면, 청도군 매전면", + "MNTN_NM" : "선의산" }, - "longitude" : 126.7291354, - "latitude" : 35.368435099999999 + "longitude" : 128.77333329999999, + "latitude" : 35.726388900000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "치마산은 구이면과 신덕면의 경계선상에 완만하게 솟아있는 육산으로 구이저수지 동쪽의 경각산을 바라보고 있다.이 산은 산세가 말이 달려나가는 형상이라 하여 달릴 치(馳) 자와 말 마(馬) 자를 붙여 이름을 지었다고 한다. 망산 마을이름은 마을 뒷산(치마산 북릉)이 옥토망월형이라 하여 생긴 이름이라는 설과, 모악산을 마주보는 형국이라 지어진 것이라는 설이 전해진다. 이 마을은 실와우와 돔바우 2개 마을로 이뤄져 있다.이 산을 가운데 두고 주변에 높고 너른 산과 들이 시원스럽게 펼쳐져 있어 전망이 뛰어나며 겨울이 되면 정상 헬기장 부근에 눈이 많이 쌓여 눈 등산하기에 좋다. 치마산은 겉으로 보기에는 펑퍼짐한 육산 정도로 보인다. 평범하게 보이는 이 산 속에 진안 마이산 석탑을 보는 듯한 석탑군이 형성돼 있는 용광사를 비롯해서 장군바위, 장군굴, 마애불상 등 볼거리가 적지 않아 앞으로 근교산행 대상코스로 자리매김할 수 있는 내용이 알찬 산이다.", - "MNTN_HG_VL" : "567", - "MNTN_LOCPLC_REGION_NM" : "전라북도 완주군 구이면, 임실군 신덕면", - "MNTN_NM" : "치마산" + "DETAIL_INFO_DTCONT" : "부귀산은 전북 진안군 부귀면과 진압읍을 가로지르며 금남정맥과 호남정맥의 마루금을 긋고 있다. 등산 코스 가운데 특별히 시선을 끌만한 장소는 없으나 수풀이 우거져 있어 한적한 분위기를 만끽할 수 있으며 전체적으로 무난한 등산로를 갖추고 있다.부귀산의 북쪽인 부귀면 대곡마을이나 손실골에서 오르면 육산, 진안읍 원정곡 마을에서 오르면 암봉으로 이루어진 산이고, 이 두 방향에서 산의 조망이 잘된다. 부귀면 대곡마을은 원래 한실골(韓室谷)인데 일본인들이 고쳤으며, 마을 뒷산인 부귀산은 사지앙천(蛇之仰天) 즉 뱀이 하늘을 우러러보는 형상인 명당이 있고, 가뭄이 들면 진안지역의 사람들이 모여서 기우제를 지내는 곳이며, 산삼을 캔 적이 있는 곳이고 한다. 결국 부귀의 이름이 말해주듯이 이 지역은 산수(山水)가 좋아 천하명당자리에 터를 잡은 부귀한 곳이라는 의미이라고 한다.대곡마을 주민들은 부귀산을 '배택산'이라고도 하는데, 말세가 되면 이산에 올라서 배를 타고 나가야 살수 있다고 하는 속설을 간직한 산이다.", + "MNTN_HG_VL" : "806", + "MNTN_LOCPLC_REGION_NM" : "전라북도 진안군 진안읍, 부귀면", + "MNTN_NM" : "부귀산" }, - "longitude" : 127.1461111, - "latitude" : 35.695833299999997 + "longitude" : 127.3927778, + "latitude" : 35.809166699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강원도 삼척시 가곡면에 자리한 치바위산은 사금산에서 남향으로 뻗어나간 지능선상의 최고봉이다. 산을 올려다보면 산꼭대기의 바위들이 `키'처럼 보이는데 `키'의 방언이 `치'이기 때문에 치바위산이라 불리게 되었다. 서쪽으로 낙동정맥 마루금에 솟아 있는 백병산(1259m)과 복두산(978m)을 마주보고 있어 신리에서 풍곡으로 이어진 도화천협곡의 장관을 감상할 수 있다. 남서쪽으로 토산과 면산자락에 가곡자연휴양림이 조성되어 있고, 남쪽으로는 유명한 용소골이 길게 패여있으며 주위로 벼락바위봉과 범바위봉, 중봉산이 자리잡고 있다.치바위산은 크게 두 개의 봉우리로 나누어진다. 하나는 동활리쪽 835m봉으로 `동활 치바위'라 부르고 이곳에서 동쪽 오저리 방면으로 분기한 780m봉을 `오저 치바위'라 부른다.", - "MNTN_HG_VL" : "835", - "MNTN_LOCPLC_REGION_NM" : "강원도 삼척시 가곡면", - "MNTN_NM" : "치바위산" + "DETAIL_INFO_DTCONT" : "만덕산은 완주군 소양면 화심에서 진안으로 가는 구 도로에 우뚝 솟아 있다. 그리고 임진왜란 당시 왜군을 맞아 치열한 전투를 벌였던 역사적 전적지이며 6·25 때 공비 출몰이 심했던 곳 중 하나로 곰티재를 지키고 있는 수문장과 같은 곳이다. 만덕산은 한자로 일만 만(萬)과 큰 덕(德)을 써서 만인에게 덕을 베푸는 산이라는 뜻이다. 그 이름 덕분인지 주민들의 말에 따르면 수많은 전란을 겪으면서도 지역 주민들은 큰 화를 입지 않았다고 한다. 암봉과 육산으로 조화를 이루어 가을 단풍, 겨울 설경의 풍치가 한 폭의 그림과도 같다. 특히 이 산의 동남쪽 기슭에 자리 잡고 있는 미륵사 일대의 경관은 일품이며 바로 아래 높이 50미터의 만덕폭포와 그 주변의 풍광은 등산객들의 발길을 사로잡는데 부족함이 없다. 겨울철의 빙폭은 젊은 산악인들의 빙벽 훈련장으로 사랑을 받고 있다. 전주에서 가깝고 교통이 편리한데다 등산 코스가 다양하여 모악산 다음으로 전주시민이 즐겨 찾는 곳이다.", + "MNTN_HG_VL" : "766", + "MNTN_LOCPLC_REGION_NM" : "전북 완주군 상관면, 소양면", + "MNTN_NM" : "만덕산" }, - "longitude" : 129.17500000000001, - "latitude" : 37.154166699999998 + "longitude" : 127.2724339, + "latitude" : 35.791643800000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "치악산은 강원도 원주시와 횡성군의 경계를 이루는 산으로, 산세가 뛰어난 데다 영동고속국도와 중앙고속국도에 인접해 있어 교통이 편리해 중부권 산행지로 인기가 높다.", - "MNTN_HG_VL" : "1282", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시, 횡성군, 영월군", - "MNTN_NM" : "치악산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "476", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "봉화산" }, - "longitude" : 128.05050990000001, - "latitude" : 37.3716893 + "longitude" : 127.6119444, + "latitude" : 34.652500000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "칠보산은 충북 괴산군 칠성면과 장연면의 경계를 이루는 산으로, 쌍곡계곡을 사이에 두고 군자산과 마주보고 있다. 칠보는 불교의 무량수경이나 법화경에 나오는 일곱가지 보배인 금, 은, 파리, 마노, 기거, 유리, 산호를 뜻한다고 한다.산의 규모는 작지만 기암괴석이 곳곳에 널려 있고, 고사목과 노송이 암봉과 조화를 이루어 한폭의 동양화를 보는 듯 하다. 이 산은 송이버섯 산지로 유명하며, 또한 칠보산에 오르는 길목에는 신라시대에 창건하였다는 고찰 각연사가 자리잡고 있다. 이 사찰에는 보물 제 433호인 석조비로 사나불좌상, 통일대사탑비 등이 있어 관광 코스로도 손색이 없는 곳이다. 정상에 서면 북쪽 아래로 각연사와 청석골 계곡이 보이고, 동북쪽으로는 덕가산과 희양산이, 서북쪽으로는 쌍곡계곡과 군자산이 가깝게 보인다.", - "MNTN_HG_VL" : "778", - "MNTN_LOCPLC_REGION_NM" : "충북 괴산군 청안면", - "MNTN_NM" : "칠보산" + "DETAIL_INFO_DTCONT" : "자연경관이 좋고 등산로가 원만하여 누구나 쉽게 오를수 있고, 산림욕 하기 좋다. 산을 오르면서 동식물들을 접할수 있어 자연학습에 도움이 많이 된다. 정상에 올라가면 비봉산과 인제읍 시가지가 한눈에 내려다 보이며 경관이 좋다.", + "MNTN_HG_VL" : "662", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 인제읍 상동리", + "MNTN_NM" : "기룡산" }, - "longitude" : 127.67984060000001, - "latitude" : 36.771560800000003 + "longitude" : 128.1527778, + "latitude" : 38.0816667 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "수원시의 서쪽에 있는 산으로 수원시와 화성군의 경계지점을 이루고 있으며 예로부터 일곱 가지 보물 (산삼, 맷돌, 잣나무, 황계수닭, 절, 장사, 금)이 많았다고 하여 칠보산이라 한다. 해발 234m로 2개의 등산코스는 완만하고 수림이 울창하여 노약자와 주부들의 산행으로 매우 적당하다.", - "MNTN_HG_VL" : "234", - "MNTN_LOCPLC_REGION_NM" : "경기도 수원, 화성", - "MNTN_NM" : "칠보산" + "DETAIL_INFO_DTCONT" : "통방산의 서쪽에 위치한 매곡산은 호젓한 맛이 일품이다. 주위에 통방산이 자리하며 청평가도를 따라가면 우측으로 고동산, 화야산, 뽀루봉의 줄기가 이어서 바로 바라다 보인다.산이 높지는 않지만 일반인들이 이 산의 존재를 잘 모르기 때문이다. 또한 사람들의 발길이 적어 나무들과 산을 흘러내리는 물이 별 방해를 받지 않고 살고 있다. 그래서 이 산을 오르다 보면 다른 산들에 비해 유난히 숲이 울창하고 계곡의 물소리 또한 나무들의 사색을 방해하지 않으려는 듯 조용조용 흐르는 것을 알게 된다. 요즘은 산을 즐기는 사람들에 의해 조금씩 알려지고 있다.", + "MNTN_HG_VL" : "507", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면", + "MNTN_NM" : "매곡산" }, - "longitude" : 126.9333333, - "latitude" : 37.25 + "longitude" : 127.39749999999999, + "latitude" : 37.6211111 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "봉우리가 7개인 데서 칠봉산이라 유래되었다. 동쪽으로 임천고개를 넘어 선바위산과 운암산으로 이어지고, 서쪽에 십리산, 남쪽에 평안산, 북쪽에는 백운산이 있다.", - "MNTN_HG_VL" : "234", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 대학리", - "MNTN_NM" : "칠봉산" + "DETAIL_INFO_DTCONT" : "강원도 평창군 방림면, 횡성군 안흥면 태백산맥에서 갈라져 나간 차령산맥의 원두에 있는 명산 백덕산(1,350m) 과 북쪽으로 연이은 능선 위에 솟아오른 산이다. 지도상에는 1,136봉이 무명으로 되어 있으나 주민들은 봉우리가 다섯개 있다고 하여 오봉산으로 부르고 있다. 소양댐 위에 있는 오봉산(779m)과 자칫 혼돈하기 쉬우니 이 점 착오없기 바란다. 문재를 가운데 두고 북쪽이오봉산, 남쪽이 백덕산인데 그래서 그런지 두 개의 산이 산세나 식물상도 매우 흡사하다.잡목이 무성한 산길을 따라가다 1126고지에 이르면 참나무 울창한 숲길을 만날 수 있다. 이곳에서 조금만 올라가면 정상이다. 사람의 흔적을 찾아보기 어려워 복잡한 도심속의 소음을 등지고 한적한 산행을 즐기기에 안성맞춤이다.", + "MNTN_HG_VL" : "1136", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 평창군", + "MNTN_NM" : "오봉산" }, - "longitude" : 127.0130546, - "latitude" : 36.3687921 + "longitude" : 128.28561920000001, + "latitude" : 37.601998999999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "높이 506m로천보산 지맥이 북쪽으로 이어져 솟은 산이다. 발치봉,응봉,석봉,기대봉,투구봉,솔치봉,돌봉 등 7개 봉우리가 솟아 있어 칠봉이라는 이름이 붙었다. 주변에 삼봉산,오봉산,구봉산 등 홀수로 된 이름을 가진 산들이 많다. 조선시대 세조가 말년에 과거의 잘못을 뉘우치며 이곳에 올랐다 하여 어등산(御登山) 이라고도 하고,가을 단풍이 아름다워 비단 병풍에 비유하여 금병산(錦屛山)이라고도 한다. 인근에 목행선 선생 선묘와 탑동석불이 자리잡고 있다.", - "MNTN_HG_VL" : "506", - "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시 송내동, 불현동", - "MNTN_NM" : "칠봉산" + "DETAIL_INFO_DTCONT" : "구름을 다리 삼아 다녀야 하는 절벽산인 운교산은 아래로 옥동천이 구비치는 모습을 내려다 보고 위로 높은 하늘을 우러르는 형상이다. 옥동천에 발을 담그려 다리를 뻗은 채 구름다리를 건너 하늘로 오르고 싶어하는 산의 마음이 전해진다. 산과 산이 연이어지고 그 산들 또한 키를 다투는 영월에서도 오지에 속하는 이 산은 암벽으로 이루어진 능선이 절경이다. 바위마다 석이버섯이 많아 주민들은 석이산으로 부르기도 한다.산행은 중동면사무소에서 시작하며 4봉·3봉·2봉으로 이어지는 암릉길이 등산의 묘미를 더해 준다. 오르막과 내리막이 모두 무척 가파르며 정상에서 동남쪽으로 옥동천을 굽어보는 조망이 아름답다.주변에 청령포와 고씨동굴 등의 명승지가 있다. 이 중 청령포는 단종이 귀양살이를 하던 곳으로, 삼면으로 깊은 강물이 흐르고 한쪽은 깎아지른 절벽으로 되어 있는 천혜의 유형지이다. 고씨동굴은 수억년 전에 생긴 전형적인 석회동굴인데, 길이가 6.3km에 이르며 굴 내부에 호수를 비롯하여 3개의 폭포와 6개의 광장이 있다. 임진왜란 때 고씨 일가가 이 동굴에 숨어 살았다 해서 고씨동굴이라 부르게 되었다는 전설이 전한다. 천연기념물 219호로 지정되었다.", + "MNTN_HG_VL" : "925", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 하동면, 중동면", + "MNTN_NM" : "운교산" }, - "longitude" : 127.093144, - "latitude" : 37.871221800000001 + "longitude" : 128.65333330000001, + "latitude" : 37.137500000000003 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "330", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "칠봉산" + "MNTN_HG_VL" : "701", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 도개면 다곡리", + "MNTN_NM" : "청화산" }, - "longitude" : 128.8485613, - "latitude" : 37.714190700000003 + "longitude" : 128.4005908, + "latitude" : 36.289798699999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "981", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 구정면, 옥계면", - "MNTN_NM" : "칠성산" + "DETAIL_INFO_DTCONT" : "수리산은 안양, 군포, 안산시 경계에 자리한 산이다. 관악산, 삼성산, 모락산과 이웃하고 있으며 낮으면서도 암릉과 숲, 계곡의 경관이 좋아 조선시대에는 안산의 명산으로 불리기도 했다. 수리산 산세는 북쪽으로 터진 말발굽 모양을 하고 있다. 말발굽 북동쪽 끝줄기에 관모봉(426m)이 있으며 상봉인 태을봉(489m)은 관모봉 남서쪽에 있다. 태을봉에서 반 바퀴 돌아서면 서편 줄기 중간에 독수리바위인 수암봉(395m)이 있으며 산줄기가 휘돌아가는 슬기봉과 고깔봉 일대에 공공시설물이 있다.수리산 산행에서 가장 경관이 뛰어나고 산행의 맛이 좋은 곳은 태을봉에서 슬기봉까지 이어지는 암릉 구간과 수암봉이다. 산행은 안양 창박골 쪽에서 관모봉으로 올라 태을봉을 거쳐 병목안 골짜기를 끼고 반 바퀴 돌아 수암봉까지 가거나 거꾸로 수암봉에서 시작하여 관모봉으로 돌면 된다. 태을봉 바로 아래의 거대한 산본 아파트 단지에서도 등산로가 여럿 있다.", + "MNTN_HG_VL" : "489", + "MNTN_LOCPLC_REGION_NM" : "경기도 안양시·군포시·안산시", + "MNTN_NM" : "수리산" }, - "longitude" : 128.87542120000001, - "latitude" : 37.669779900000002 + "longitude" : 126.9027047, + "latitude" : 37.366196799999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "981", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉", - "MNTN_NM" : "칠성산" + "DETAIL_INFO_DTCONT" : "경기도 양평군 서종면과 가평군 설악면이 경계를 이루는 지점에 위치한 통방산은 북동쪽으로는 청다락골이 있고, 서쪽으로는 사기막천이, 서남쪽으로는 소(沼)와 탕(湯)이 즐비한 삼각골이 있어 띠를 두른 듯 세 방면으로 큰 계곡이 흐르고 있어 여름철 산행지로 적당한 곳이다.지형적으로 남쪽으로만 시계가 트여 남한강이 조망되며, 좌우로 중미산(834), 화야산(755), 용문산(1,157)이 자리하고 있어 첩첩산중에 들어선 느낌을 주는 산이다. 산행기점이 계곡을 건너게 되어 있으므로 수량이 늘어나는 장마철에는 각별한 주의를 해야한다. 수입리쪽에 자리한 사기막천은 계곡미가 수려하여 벽계구곡으로 불리어 왔다.", + "MNTN_HG_VL" : "650", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면, 가평군 설악면", + "MNTN_NM" : "통방산" }, - "longitude" : 128.87542120000001, - "latitude" : 37.669779900000002 + "longitude" : 127.4560599, + "latitude" : 37.633368599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "lt;땅 위에 드리운 북두칠성gt;칠성산(981m)은 백두대간상의 석병산(1055m)과 삽당령(680m) 사이에 위치한 두리봉(1033m)에서 강릉을 바라보며 북으로 뻗은 지맥 상의 약 9km쯤에 솟은 봉우리다. 이 산은 머리에 바위를 이고 길게 드리운 품새가 하늘의 북두칠성과 흡사하다. 칠성산은 옛 고을 원님이 기거하던 칠사당자리(강릉의료원)에서 올려다보면 여러개의 바위 봉들이 별과 같은 형상으로 빛을 토하고 있어 칠성산이라 불렀다고 한다. 또한 활활 타오르는 불꽃 모양의 칠성산 때문에 강릉시에 화재가 자주 일어난다는 설도 있다. 국립지리원 발행 지형도에는 칠성산이란 지명은 없다. 다만 주봉(981m) 남쪽에 칠성대(954m)라 표기되어 있을 뿐이다. 「대동여지도」에는 ‘담정산’ 이라 하였지만 언제 이름을 잃었는지 모르며 다만 산자락 아래 담산동이란 마을 이름이 남아 있다. 칠성산은 도심에 인접한 산이면서도 강릉 사람들이 바다를 좋아하는 탓인지 원시림의 모습을 간직하고 있다. 이 칠성산은 1996년 강릉 앞바다에 난데없이 나타난 북한 잠수함으로 인해 전국의 이목을 집중시켰다.", - "MNTN_HG_VL" : "981", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면, 구정면, 옥계면", - "MNTN_NM" : "칠성산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "128", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 강서구", + "MNTN_NM" : "개화산" }, - "longitude" : 128.87542120000001, - "latitude" : 37.669779900000002 + "longitude" : 126.8038889, + "latitude" : 37.582777800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 안성군 삼죽면, 죽산면, 금광면에 위치한\"\"칠장산군\"\"(덕성산-칠현산-칠장산)은 백두대간 중 속리산에서 가지쳐 나온 정맥인 금북정맥에 속한 산이다. 높이는 높지 않지만 산의 폭이 크고 숲이 울창하여 그 일부는 안성시와 진천군의 경계를 이루고 있으며, 산 기슭에 칠장사란 고찰이 있어 유명해진 산이다.636년(신라 선덕여왕 5) 자장율사가 창건한 칠장사는 조선 명종 때 임꺽정이 승려인 병해와 함께 10여 년 머물던 사찰이다. 칠장사오불회괘불탱(국보 296), 칠장사혜소국사비(보물 488), 봉업사석불입상(보물 983), 조선 후기에 진흙으로 빚은 사천왕상(경기유형문화재 11)을 비롯하여 대웅전(경기유형문화재 114), 인목대비친필족자(경기유형문화재 34), 철당간(경기유형문화재 39) 등 많은 문화재를 보유하고 있다.국보와 보물이 있는 한적한 고찰 칠장사를 둘러 보고, 숲이 울창한 칠장산에 올라 시원한 공기를 마시고 내려와 칠장사 혜소국사비 아래쪽 골짜기 약수터를 둘러보면 칠장산과 칠장산 순례는 끝난다.", - "MNTN_HG_VL" : "492", - "MNTN_LOCPLC_REGION_NM" : "경기도 안성시 죽산면, 금광면, 삼죽면", - "MNTN_NM" : "칠장산" + "DETAIL_INFO_DTCONT" : "희리산은 해발 327미터로 그리 높지 않아 어린 자녀와 함께 삼림욕을 즐기기에 안성맞춤이다. 최고봉인 문수봉에 올라서면 사방이 탁 트여 조망 또한 훌륭하다. 산 전체는 사계절 내내 푸른 해송으로 둘러싸여 있어 언제든지 녹색의 신선함을 느낄 수 있다.희리산은 자연휴양림으로 유명하다. 휴양림의 휴양관은 총 15개실로 대회의실과 소회의실을 갖추고 있어 단체 이용객이 사용하기에 적합하고 숲속의 집은 7개 수종(소나무, 잣나무, 낙엽송, 삼나무, 해송, 층층나무, 참나무)의 판재로 내부 인테리어를 꾸며 특유의 향기를 느낄 수 있다.휴양림의 북서쪽에는 네명의 장사가 놀던 자리라는 사인대가 있고 사인대 밑에는 이 장사들이 턱걸이한 장소라 하여 턱걸이장이라 불리고 있는 140미터 정도의 절벽도 있다.문수봉 밑으로는 이 장사들이 살았다는 큰 산봉우리 4개가 있고 그 아래로 이 장사들의 졸병들이 살았다 하여 이름 붙여진 여러 모양의 작은 졸병바위가 100여 개 정도 있으며 빈대가 너무 많아 절을 헐었다는 문수사 절터도 있어 희리산을 오르는 동안 많은 볼거리를 제공하고 있다.", + "MNTN_HG_VL" : "327", + "MNTN_LOCPLC_REGION_NM" : "충남 서천군 종천면", + "MNTN_NM" : "희리산" }, - "longitude" : 127.3912223, - "latitude" : 37.030774200000003 + "longitude" : 126.66426149999999, + "latitude" : 36.112400299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "통영시 사량면 아랫섬(하도)에 위치한 해발 349m의 산으로서 남쪽으로 뻗은 산줄기를 따라 7개의 봉우리가 솟아 있어 칠현봉(七絃峰)이라 하는데 이 가운데 망산(공수산, 해발 310m)에는 옛 사량진의 봉수지(烽燧址)가 있다. 칠현봉에는 등산로와 안내판이 잘 정비되어 있고 일곱 봉우리를 오르내리는 능선길이 재미있을 뿐아니라 사방으로 탁 트인 전망 또한 좋아 근래 가장 각광받는 등산코스이다.산기슭에 칠장사가 있다. 고려 때 혜소국사가 일곱 도적을 제도하여 도를 깨치게 했다 하여 칠현산이라 불리게 되었다. 칠장산과 붙어 있어 함께 산행할 수도 있다. 산행은 걸미고개에서 시작하여 극락마을을 통해 정상에 오른 뒤 다시 극락마을로 내려와 걸미고개로 하산한다. 칠장산과 이어서 등반하려면 걸미삼거리에서 신대마을로 들어가 원효암을 지나 정상에 오른 뒤 갈림길에서 칠장사를 거쳐 칠장산에 올랐다가 사거리 갈림길에서 신미창교로 내려와 미장리 정류장으로 하산한다.", - "MNTN_HG_VL" : "349", - "MNTN_LOCPLC_REGION_NM" : "경상남도 통영시 사량도", - "MNTN_NM" : "칠현산" + "DETAIL_INFO_DTCONT" : "팔공산하면 대구의 팔공산을 떠올리지만 이 산은 전북 진안과 장수에 걸쳐있는 팔공산으로 제법 높은 산인데도 인적이 드문 산이다. 무진장,무주,진안,장수는 오지중에서도 오지로 꼽혀 사람들의 접근이 쉽지 않았으나 최근에는 깨끗한 산천을 찾는 이들이 늘어가면서 하나씩 이름이 알려져가고 있다.팔공산 역시 사람들의 발길이 닿지 않아 원시림과 같은 청정함을 느낄 수 있는 곳이다. 이 산만이 갖는 뚜렷한 특징은 없으나 정상에서 북으로 내려가는 능선에 키를 넘는 억새군락이 인상적이다.정상에는 송신탑이 있고 사방으로 끝없이 펼쳐지는 산의 파노라마가 장관이며, 동쪽 장안산과의 사이에는 논개의 충절이 소리 없이 깔려 군민과 함께 숨쉬고 친절한 도시 장수가 내려다 보인다. 정상에서 북쪽으로 이어진 능선에는 억새가 장관이며 와룡자연휴양림이 조성되어 더더욱 좋다.", + "MNTN_HG_VL" : "1151", + "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군", + "MNTN_NM" : "팔공산" }, - "longitude" : 128.2317299, - "latitude" : 34.8234979 + "longitude" : 127.46611110000001, + "latitude" : 35.620555600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 가평군 가평읍 승안리와 경반리의 경계를 이루는 칼봉산은 수락폭포와 용추폭포로 유명한 산이다. 가평읍에서 경반리 골짜기 안으로 12km 거리에 있는 수락폭포는 높이 30m쯤 되는 비교적 큰 폭포이다. 칼봉산의 물안골계곡은 옥계구곡이라는 이름이 있을 정도로 폭포와 소, 아름다운 물구비가 있어서 산행을 하지 않더라도 서울에서 하루 쉬어 오기에 아주 적당한 곳이다. 계곡 초입에 있는 용추폭폭포와 소는 관광지도에는 빠지지 않을 정도의 명소이다.칼봉산이란 이름은 주능선이 마치 칼날처럼 날카로운 암릉으로 이루어져 있어 붙여졌다고 한다. 경반리 방면은 버스가 다니지않아 교통이 불편하여 교통이 편리한 승안리 방면으로 등산을 하고 있다. 이 산도 더덕 등 산나물이 많이 서식하고 있는 곳이다.산행은 우무동 입구에서 서쪽 길을 따라 들어가면 양아터 마을의 맨 위에 있는 민가에 닿게되고, 이곳에서 서쪽 지능선을 가로질러 나가면 큰 소나무가 한그루 있는 십자로에 닿는다. 십자로에서 서쪽 계류를 건너 능선을 하나 넘어 북쪽길을 따라 수목이 울창한 주능선에 올라 서쪽으로 약간 올라가면 정상이다.", - "MNTN_HG_VL" : "900", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍", - "MNTN_NM" : "칼봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "396", + "MNTN_LOCPLC_REGION_NM" : "제주도 서귀포시 서호동", + "MNTN_NM" : "고근산" }, - "longitude" : 127.436694, - "latitude" : 37.862840200000001 + "longitude" : 126.51384419999999, + "latitude" : 33.266262900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태기산은 횡성군의 최고봉으로 치악산과 인접해 있다. 일명 덕고산(또는 대기산)이라고도 불리는 태기산은 삼한시대 말기 진한의 마지막 왕인 태기왕이 신라군에게 쫓기어 이곳에 성을 쌓고 군사를 길러 신라와 싸웠다는 전설이 전해지고 있어 태기산이라 이름붙었다 한다.산 정상에는 삼한시대의 진한의 마지막 왕인 태기왕이 신라에 대항하던 태기산성(약1km)이 있다. 태기산성은 삼한시대, 진한의 마지막 왕인 태기왕이 신라에 대항하던 곳으로 그 안에 태기산성비가 세워져 있다.주변에는 신라 선덕여왕 16년에 자장율사가 창건한 봉복사라는 절과 심산유곡의 약수터가 있다. 양구두미재 정상에서 비포장 도로를 따라 정상에 오르던가 봉복사 계곡을 따라 잡목이 우거진 능선길을 헤치고 올라가면 정상에 이른다. 정상은 한국방송공사 송신소가 있어 입산 통제 구역이다.", - "MNTN_HG_VL" : "1261", - "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군 둔내면, 청일면, 평창군 봉평면, 홍춘군 서석면", - "MNTN_NM" : "태기산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "359", + "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", + "MNTN_NM" : "대미산" }, - "longitude" : 128.28561920000001, - "latitude" : 37.601998999999999 + "longitude" : 127.77444439999999, + "latitude" : 34.674166700000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간 오대산에서 서쪽으로 가지를 뻗어 내린 유장한 산줄기 가운데 가장 깊숙한 곳, 신대리를 중심으로 봉복, 덕고, 태기산 줄기가 부챗살을 펼치며 솟아있다. 아직 시로 승격되지 못한 홍천, 평창, 횡성의 3개 군의 경계를 이루는 오지다. 높이 1261미터로 횡성군에서 가장 높다. 본래는 덕고산(德高山)이었는데 삼한시대 진한의 마지막 왕인 태기왕이 산성을 쌓고 신라에 대항하던 곳이라 하여 이름을 고쳐 부르게 되었다.정상아래 1000미터 고원에는 1970년대 초만 해도 이 산에 150여 호, 근 천여 명이나 살던 마을 태기리가 있었다. 화전민과 고랭지 채소밭, 초등학교까지 거느릴 정도로 품이 너른 산이다. 현재는 돌담과 잡목만 무성한 집터들뿐이다.이 산 아래 주변에는 볼거리가 많다. 신대리 초입에 있는 신라시대 창건한 봉복사와 삼층석탑을 비롯해서, 동쪽에는 효석문화마을, 동남쪽에는 휘닉스 파크, 또 청태산으로 이어지는 남쪽 산줄기 아래는 청태산자연휴양림이 자리하고 있다.", - "MNTN_HG_VL" : "1261", - "MNTN_LOCPLC_REGION_NM" : "횡성군 둔내면, 평창군 봉평면, 홍천군 서석면", - "MNTN_NM" : "태기산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "947", + "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", + "MNTN_NM" : "금학산" }, - "longitude" : 128.28561920000001, - "latitude" : 37.601998999999999 + "longitude" : 128.91777780000001, + "latitude" : 36.377499999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "태백산은 경상북도 봉화군 석포면 대현리와 태백시 문곡소도동 그리고 강원도 영월군 상동면 천평리와 접경을 이루며 동경 128。56\"북위 37。05\"에 자리잡은 해발 1,566.7m의 명산이다. 이 산에서 발원하는 물이 영남평야의 젖줄인 낙동강과 우리민족의 역사와 함께한 한강, 삼척의 오십천을 이루니 국토의 종산이자 반도 이남의 모든 산의 모태가 되는 뿌리산이다.태백산은 천제단이 있는 영봉을 중심으로 북쪽에 장군봉(1567m) 동쪽에 문수봉(1,514.9m), 영봉과 문수봉사이의 부쇠봉(1,549.4m)로 이루어져 있다. 암벽이 적고 경사가 완만하여 남녀노소 누구나 쉽게 오를 수 있는 산으로 정상에는 고산식물이 자생하고 봄이면 산철쭉, 진달래의 군락지가 등산객을 맞이하고 여름에는 울창한 수목과 차고 깨끗한 계곡물이 한여름 더위를 잊기에 충분하며 가을은 형형색색의 단풍으로 수놓으며 겨울은 흰 눈으로 뒤덮인 주목군락의 설경을 보여 주는 곳으로 남성다운 중후한 웅장함과 포용력을 지닌 육산으로 이루어져 있다.또한 정상에서 바라보는 일출과 낙조는 장엄하여 세속을 떠난 천상계를 연상케 하고 맑은 날 멀리 동해 바다를 볼 수 있는 것도 태백산이 가지고있는 자랑거리이다. 이 밖에도 최고높은 곳에 위치한 한국명수중 으뜸수 용정, 용담이 있다.1989년 5월 13일 17.44㎢의 면적이 도립공원으로 지정되었으며 소도집단시설지구에 콘도형인 태백산 민박촌을 비롯하여 숙박시설,음식점,야영장 등이 마련되어 있으며 석탄의 역사를 한 눈에 볼 수 있는 석탄박물관이 있고, 겨울철에는 대규모의 눈썰매장이 개장된다.", - "MNTN_HG_VL" : "1567", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", - "MNTN_NM" : "태백산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "235", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", + "MNTN_NM" : "오봉산" }, - "longitude" : 128.91524039999999, - "latitude" : 37.095739199999997 + "longitude" : 128.8075, + "latitude" : 37.704722199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "숙종의 태를 묻었던 곳으로, 태봉동이라 하였다. 비석 중 하나는 1661년(현종 2)에 고종의 태(胎)를 처음 이곳에 안치할 때 세운 것이며, 다른 하나는 숙종이 임금에 즉위한 후 9년 후인 1683년에 건립한 것이다. 1869년(고종 2) 태와 태실은 경기도 양주로 옮겨가고 지금은 비석만 남아 있다. 관리가 잘 되어있어 남녀노소 누구나 건강증진에 좋다.", - "MNTN_HG_VL" : "133", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 태봉동", - "MNTN_NM" : "태수산" + "DETAIL_INFO_DTCONT" : "산자락에 천년고찰 봉복사를 안고 있는 덕고산은 사찰 안에 덕고산 봉복사(德高山 鳳腹寺)라는 현판이 걸려 있어 그렇게 불리는데, 강원도 횡성군 청일면과 홍천군 서석면의 사이에 서서 경계를 이룬다.태기산과 성골계곡을 사이에 두고 마주보고 있는 덕고산은 삼한시대 말 진한의 마지막 왕인 태기왕이 새로 일어나는 신라군에 쫓기어 이곳에 성을 쌓고 군사를 길러 신라군과 싸웠다는 전설을 안고 있다. 그래서 이 산의 성골 골짜기에서는 태기왕 때의 것으로 보이는 허물어진 성벽 일부와 기와조각, 샘터 등이 발견되고 있다.산기슭에는 복조리의 재료인 산죽(山竹:시누대)이 많이 자란다.수림이 빽빽하여 정상에서의 조망이 시원하지는 않지만 깊고 조용한 산이다. 산행 들머리에는 신라시대의 것으로 6·25전쟁 때 총탄에 맞은 흔적이 여러 군데 있는 것을 빼고는 비교적 원형이 잘 보존되어 있는 삼층석탑(강원유형문화재 60)이 있다.", + "MNTN_HG_VL" : "1125", + "MNTN_LOCPLC_REGION_NM" : "강원도 횡성군, 홍천군", + "MNTN_NM" : "덕고산" }, - "longitude" : 127.09657319999999, - "latitude" : 36.410788500000002 + "longitude" : 128.16441259999999, + "latitude" : 37.471818200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 청송군에 위치한 태양산은 주왕산국립공원 북부지역의 비경지대인 너구골 북쪽에 병풍을 두른 듯 솟아 있다. 5만분의 1지도에는 태행산으로 잘못 표기되어 있으나 태양산이 바른 명칭이다. 태양산은 댕댕이산 또는 부덕골로 불리기도 한다.경북 청송은 산악지대로 곳곳에 비경이 살아있고 동해가 가까워 인파가 사계절 끊일 날이 없는 관광명소이다. 동해와 내륙지방을 가르는 산맥을 형성하고 있는 태양산 산자락에는 마치 조각가가 심혈을 기울여 빚어놓은 듯한 단애를 이룬 기암괴석과 아름다운 계곡, 폭포 등이 어우러져 빼어난 산세를 자랑한다. 이 일대는 어디를 가나 심산유곡의 청정함을 자랑한다. 산행을 통해 비경을 만끽하는 것 만큼이나 오고가는 여정 또한 경치가 뛰어나 일상에 지친 마음을 맑게 해 준다.", - "MNTN_HG_VL" : "933", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청송군", - "MNTN_NM" : "태양산" + "DETAIL_INFO_DTCONT" : "경기도 가평군 가평읍 승안리와 경반리의 경계를 이루는 칼봉산은 수락폭포와 용추폭포로 유명한 산이다. 가평읍에서 경반리 골짜기 안으로 12km 거리에 있는 수락폭포는 높이 30m쯤 되는 비교적 큰 폭포이다. 칼봉산의 물안골계곡은 옥계구곡이라는 이름이 있을 정도로 폭포와 소, 아름다운 물구비가 있어서 산행을 하지 않더라도 서울에서 하루 쉬어 오기에 아주 적당한 곳이다. 계곡 초입에 있는 용추폭폭포와 소는 관광지도에는 빠지지 않을 정도의 명소이다.칼봉산이란 이름은 주능선이 마치 칼날처럼 날카로운 암릉으로 이루어져 있어 붙여졌다고 한다. 경반리 방면은 버스가 다니지않아 교통이 불편하여 교통이 편리한 승안리 방면으로 등산을 하고 있다. 이 산도 더덕 등 산나물이 많이 서식하고 있는 곳이다.산행은 우무동 입구에서 서쪽 길을 따라 들어가면 양아터 마을의 맨 위에 있는 민가에 닿게되고, 이곳에서 서쪽 지능선을 가로질러 나가면 큰 소나무가 한그루 있는 십자로에 닿는다. 십자로에서 서쪽 계류를 건너 능선을 하나 넘어 북쪽길을 따라 수목이 울창한 주능선에 올라 서쪽으로 약간 올라가면 정상이다.", + "MNTN_HG_VL" : "900", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍", + "MNTN_NM" : "칼봉산" }, - "longitude" : 129.1299612, - "latitude" : 36.456375800000004 + "longitude" : 127.436694, + "latitude" : 37.862840200000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "신증동국여지승람에 대화산이라 지칭한 태화산은 강원 영월군 영월읍 남쪽에 자리해 있다. 정상에서 북서쪽으로 뻗은 능선 끝에는 남한강이 굽이쳐 흐르고 정상으로 향하는 길에 영월읍을 두루 굽어볼 수 있는 태화산성터가 남아 있다.고구려 시대에 쌓았던 토성, 태화산성에서는 간혹 당시의 기와 파편이 발견되기도 한다. 태화산 정상에서는 멀리 남으로 소백산과 백두대간 줄기가 조망된다.", - "MNTN_HG_VL" : "1028", - "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍, 충청북도 단양군 영춘면", - "MNTN_NM" : "태화산" + "DETAIL_INFO_DTCONT" : "도갑산, 월각산, 주지봉등은 호남의 명산인 월출산의 한 봉우리를 이루고 있는 산으로 천황봉(809m)을 최고봉으로 하여 기암괴석으로 장엄하게 우뚝 솟은 산이다. 그리하여 예로부터 문사들이 탐내는 명산이었고 영암의 지명을 “靈巖”으로 부르게 한 산이기도 하다.이곳 골짜기마다 이 같은 영험함을 기대는 민간신앙의 자취들이 오늘날까지 이어지고 있다. 더욱이 월출산은 선사시대 이래 발달된 해로와 비옥한 영산강 주변의 농경지를 배경으로 하는 이 지역의 문화와 역사를 상징하고 있다. 또한 기슭에는 고찰 도갑사(道岬寺)가 있고 이곳에는 국보로 지정된 해탈문, 보물로 지정된 석조여래좌상 등이 있다. 특히, 도갑산을 포함한 월출산이 국립공원으로 지정된 후 관광지로서 각광을 받고 있다.", + "MNTN_HG_VL" : "376", + "MNTN_LOCPLC_REGION_NM" : "전라남도 영암군 군서면", + "MNTN_NM" : "도갑산" }, - "longitude" : 128.48475329999999, - "latitude" : 37.117061700000001 + "longitude" : 126.6725, + "latitude" : 34.744444399999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 광주시 남쪽 끝에 자리한 도척면은 백제 온조왕이 한강유역에 도읍을 정하려고 이곳을 탐사할 때 자로 재고 또 쟀다고 해서 도척(都尺)이란 이름이 붙었다고 한다. 이러한 도척면 북서쪽을 병풍처럼 에워싸고 있는 산이 바로 태화산이다. 조선 영조 때의 고지도와 광주부읍지에는 대해산(大海山), 해동지도에는 대화산(大華山)으로 기록되어 있다.경기 남부에서 아름답기로 이름 난 태화산은 관바위, 수리바위, 병풍바위, 상사바위, 조춤바위 등 멋진 다섯 개의 바위들이 늘어선 바우산골과 조망 좋은 정상 그리고 그 바로 아래쪽의 백련암, 김병기 대감이 대화약수를 마시고 병이 나은 기념으로 썼다는 ‘大華水石’ 암각 등 볼거리 또한 풍성하다.태화산은 봄이 다 가도록 흐드러지게 피어나는 진달래와 철쭉이 특징이다. 내세울 만한 높이는 아니지만 전망 좋은 바위가 곳곳에 자리하고, 울창하게 우거진 숲은 산림욕을 즐기기에 그만이다.", - "MNTN_HG_VL" : "641", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주시 도척면", - "MNTN_NM" : "태화산" + "DETAIL_INFO_DTCONT" : "월출산에서 남으로 뻗은 능선이 강진군 성전면과 영암군 학산면을 잇는 회랑에서 2번국도에 길을 내주는등 잠시 바닥에 깔렸다가 고도를 높여 별매산을 만들고 서쪽으로 진행하며 영암군과 해남군사이의 장벽을 이룬다. 이 산줄기는 동으로부터 별매산, 가학산, 흑석산, 두억봉, 418봉등으로 이어지며 계속 서진한뒤 영암호에 이른다.봄철 철쭉철이면 철쭉군락지가 산재한 이 산줄기의 곳곳이 붉게 물들어 장관을 연출한다. 높지 않으면서도 수려한 봉우리들이 중첩되고 조망도 시원한 산들이 가학산, 흑석산이다. 별매산(465m)에서 흑석산(黑石山,650m)으로 이어지는 능선에 우뚝 솟아 있는 가학산의 정상부는 거대한 돔형의 바위 봉으로 되어 있어 해발에 비해 웅장함을 자랑하고 있다.가학산 정상은 평평하고 넓은 공터를 이루고 있으나 양쪽이 절벽으로 이루어져 있어 주의해야 하는 곳이다. 정상에서 북동쪽으로 월출산이 손에 잡힐 듯 가까이 보이고, 남쪽으로는 두륜산이 아스라히 보인다. 가학산 주능선은 온통 바위능선으로 되어 있어 등산로 이외 탈출로가 많지 않은 산이다.", + "MNTN_HG_VL" : "575", + "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면 당산리", + "MNTN_NM" : "가학산" }, - "longitude" : 127.2886111, - "latitude" : 37.291944399999998 + "longitude" : 126.6408333, + "latitude" : 34.680277799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "토함산은 호국의 진산으로 예로부터 신성시 되어온 산이다. 신라의 영산으로 일명 동악이라 불리었으며, 서악 선도산, 남악 금오산, 북악 금강산, 중악 남산과 더불어 신라 5악이다. 신라의 4대 임금인 석탈해왕이 죽은 후 동악의 산이 되었다고 한다. 석탈해왕은 토해왕이라고도 했는데 토함산의 이름은 동악의 산이 된 데에서 유래된 듯하다.경주에서 가장 큰 산으로서 울산광역시와 경계를 이루며 동쪽으로는 추령재를 지나 기림사와 죽어서 동해의 큰 용이 되어 왜적으로부터 동해를 지키겠다는 문무대왕의 수중릉이 있는 동해바로 이어진다. 서쪽으로는 대덕산과 노천박물관으로 불리는 남산과 마주하고 있다. 북쪽으로는 만호봉을 지나 보문관광단지에 이른다.토함산 기슭에 위치한 불국사와 석굴암 이외에도 무덤에 물이 괴어 널을 걸어 묻었다는 전설로 유명한 괘능, 아사달과 아사녀의 애절한 전설이 담긴 영지못 등 주변에는 많은 문화재가 있다. 일출이 일품인 정상은 신년일출산행지로 손꼽히는 곳이다.", - "MNTN_HG_VL" : "746", - "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 불국동", - "MNTN_NM" : "토함산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "619", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 풍각면, 각남면. 경상남도 밀양시 청도면, 성산면", + "MNTN_NM" : "천왕산" }, - "longitude" : 129.345, - "latitude" : 35.801666599999997 + "longitude" : 128.59414770000001, + "latitude" : 35.5852754 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한국의 계곡을 대표하는 불영계곡과 인적이 끊긴 내천인 와피천을 가슴에 품고 있는 산이다. 낙동정맥의 주맥으로 울창한 원시림과 맑은 물은 가히 선경(仙境)을 방불케한다. 단지 교통이 불편해서 찾기 어렵다는 단점이 있지만, 마음먹고 찾아간 사람들에게는 자연이 줄 수 있는 최상의 선물을 분명 안겨주는 곳이다.이 산은 왕피천과 한국토종 소나무 자생군락지로 유명한 불영계곡을 품은 낙동정맥의 산이다 주위에 왕궁목재로 이용되던 황장목 보호구역이었던 곳도 있으며 울창한 산림을 이용개발한 통고산 자연휴양림이 있는 곳이다. 각종 나무마다 팻말이 붙어있는 등 가족단위로 나들이 하기엔 안성맞춤이고 산장들은 통나무로 지어져 있고 이름도\"\"머루랑\"\",\"\"다래랑\"\"등 자연그대로의 분위기를 살린 곳이며 삼림욕장 개장과 동시 임산 도로의 개설로 접근이 쉬워진 산이기도 하다. 또한 신라 진덕여왕 5년에 의상대사가 창건한 불영사가 자리잡고 있다.정상에 서면 50평 남짓한 헬기장으로 울진 원자력 발전소에서 세운 둥근 정상 표지판이 반긴다. 시야가 탁 트이면서 조망도 매우 좋다 . 동해 바다의 넘실대는 파도가 손에 잡힐듯 하며 불영계곡과 왕피천계곡이 펼쳐진다. 북쪽으로는 낙동정맥이 굽이 굽이 물결치는 가운데 응봉산이 올려다 보이고 남으로는 저 멀리 아련히 일월산 장군봉이 눈에 들어온다.", - "MNTN_HG_VL" : "1067", - "MNTN_LOCPLC_REGION_NM" : "경상북도 울진군 서면", - "MNTN_NM" : "통고산" + "DETAIL_INFO_DTCONT" : "봉황산은 경북 영주와 봉화군의 경계를 이루는 산이다. 산의 모양이 봉황을 닮았다고 해서 봉황산이라 불리는 이 산은 태백산(1567m)을 거친 백두대간이 소백산(1439m)으로 뻗어 내리다가 중간에 위치한 선달산에서 남쪽으로 가지친 지맥 선상에 자리하고 있다.사람들에게는 별로 알려지지 못한 산이지만 산자락에 자리잡은 부석사는 매우 유명하다. 부석사 무량수전은 한국에서 가장 오래된 목조건물이며, 국보 제18호로 지정되어 있다. 이 외에도 석탑, 석종 등 보물이 많고, 규모가 웅장해서 이 절을 찾는 관광객이 많다 부석사만 둘러보고 가는 관광객이 많아 한적한 산행을 즐길 수 있다. 특히 소백산 도립공원에 속해 있으면서도 주변의 영봉들에 가려 그 진가가 제대로 알려지지 않았지만 그만큼 사람들의 발길을 덜타 깨끗하고 아름다운 자연미를 그대로 간직하고 있다.부석사 무량수전 뒤편의 오솔길을 따라 능선에 오르면 정상까지 이를 수 있다. 정상까지의 길은 울창한 소나무 숲과 진달래가 군락을 이룬 숲길이 등산의 피곤함을 잊게 해준다.", + "MNTN_HG_VL" : "259", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영주시 부석면, 봉화군 물야면", + "MNTN_NM" : "봉황산" }, - "longitude" : 129.19194440000001, - "latitude" : 36.898611099999997 + "longitude" : 128.6937088, + "latitude" : 37.004579300000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "섬진강과 보성강을 가르고 있는 통명산은 그리 높은 산은 아니지만 지리상으로 중요한 위치를 점하고 있다. 통명산을 주산으로 주부산과 곤명산 산줄기가 섬진강과 보성강을 가르고 있기 때문이다. 일반적으로 곡성하면 동악산을 생각하지만 최고봉은 분명 통명산이다. 4개 면의 경계가 되는 지리적인 요충지 외에도 이름조차도 하늘의 옥황상제가 기거한다는 통명전을 뜻하니 말이다. 또한 곡성이 배출한 명장 신숭겸과 마천목은 각각 고려초와 조선초기에 주군을 도와 나라의 기초를 다지는데 기여한 인물들인데 바로 통명산 자락에서 태어났다.제단을 쌓은 듯 평평한 정수리의 조망은 시원하기 이를 데 없다. 북쪽으로 동악산과 곡성읍이, 동쪽으로는 주부산과 지리산의 위용이, 남쪽으로는 조계산을 이어 달리는 호남정맥과 주암호를 지나온 보성강 물줄기가 섬진강을 향하여 굽어드는 절경이 펼쳐진다.", - "MNTN_HG_VL" : "764", - "MNTN_LOCPLC_REGION_NM" : "전남 곡성군 죽곡면", - "MNTN_NM" : "통명산" + "DETAIL_INFO_DTCONT" : "서울에서 44km, 동두천시청에서 동북쪽으로 약 5km의 거리에 있는 소요산은 경치가 뛰어나 경기도의 '소금강'이라 불린다.", + "MNTN_HG_VL" : "588", + "MNTN_LOCPLC_REGION_NM" : "경기도 동두천시, 포천시 신북면", + "MNTN_NM" : "소요산" }, - "longitude" : 127.2616723, - "latitude" : 35.208018799999998 + "longitude" : 127.0878091, + "latitude" : 37.942629599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 양평군 서종면과 가평군 설악면이 경계를 이루는 지점에 위치한 통방산은 북동쪽으로는 청다락골이 있고, 서쪽으로는 사기막천이, 서남쪽으로는 소(沼)와 탕(湯)이 즐비한 삼각골이 있어 띠를 두른 듯 세 방면으로 큰 계곡이 흐르고 있어 여름철 산행지로 적당한 곳이다.지형적으로 남쪽으로만 시계가 트여 남한강이 조망되며, 좌우로 중미산(834), 화야산(755), 용문산(1,157)이 자리하고 있어 첩첩산중에 들어선 느낌을 주는 산이다. 산행기점이 계곡을 건너게 되어 있으므로 수량이 늘어나는 장마철에는 각별한 주의를 해야한다. 수입리쪽에 자리한 사기막천은 계곡미가 수려하여 벽계구곡으로 불리어 왔다.", - "MNTN_HG_VL" : "650", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 서종면, 가평군 설악면", - "MNTN_NM" : "통방산" + "DETAIL_INFO_DTCONT" : "덕갈산은 산청,거창,함양군을 경계 짓는 위치에 있으며 덕유산에서 내려온 줄기가 이곳에서 양분 되어 한줄기는 갈전, 철마, 소룡, 바랑산을 거쳐 황매산으로 뻗어있고 또하나가 바로 덕갈산 줄 기를 이루며 그 끝은 태봉산까지 길게 이어져 있다. 마치 떡가래처럼 널어져 있는 형세를 하고 있으며 그 줄기위에서는 지리산을 정면으로 바라볼수 있어 주변의 1000m 내외의 산들과 구별되어 산중에 제왕임을 한눈에 알 수 있게한다. 또한 덕유산에서 지리산으로 흐르다 출렁이면서 솟아 오 른 고봉들도 조망이 가능하여 덕갈산을 방문한 등산객에게만 산행의 참맛을 선사한다. 덕갈산은 가슴을 확트이게하고 눈을 즐겁게 하는 산으로 자신을 자랑하기보다는 주변 산들의 기상 과 기세를 칭찬하는 겸손한 산이다.", + "MNTN_HG_VL" : "669", + "MNTN_LOCPLC_REGION_NM" : "경상남도 산청군,거창군,함양군", + "MNTN_NM" : "덕갈산" }, - "longitude" : 127.4560599, - "latitude" : 37.633368599999997 + "longitude" : 127.86333329999999, + "latitude" : 35.576111099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "팔각산은 계곡을 끼고 뾰족한 암봉 8개가 이어져 있는 데에서 유래했으며 ‘옥계팔봉’이라고도 부른다. 높은 산은 아니지만 각종 기암괴석과 급경사, 암벽 등으로 인해 산세가 험한 편이다. 산 중턱에는 200여 명이 앉을 수 있을 만큼 넓고 편평한 푸른색 암반이 있다.2000년 이전엔 등산로 4.5킬러미터만 개방되었으나 이후 6.1킬로미터 등산로가 추가로 정비되었으며, 곳곳에 로프와 철봉이 설치되었다. 8개의 연이은 봉우리에 다다를 때마다 동해와 삼사해상공원, 주왕산 줄기, 옥계계곡의 물줄기가 차례로 내려다보인다. 산 북쪽에 있는 산성계곡 일대에는 삼림욕장이 조성되어 있으며, 운동시설과 삼림욕 의자, 야외탁자, 평상 등 편의시설과 음수대, 간이화장실, 안내소, 종합안내소가 있다.팔각산과 동대산에서 흘러내린 물이 합류해 이루어진 옥계계곡도 팔각산에서 빼놓을 수 없다. 1607년 손성을이 광해군의 학정을 피해 은거하며 지은 침수정(枕漱亭)이 있으며 이 계곡 일원은 경상북도기념물 45호로 지정되어 있다. 손성을은 계곡 가운데 꽃봉오리 모양으로 앉은 진주암(眞珠岩) 외에 병풍바위, 향로봉, 촛대바위 등 주변의 아름다운 곳을 골라 ‘팔각산 37경’이라는 이름을 붙였다.", - "MNTN_HG_VL" : "633", - "MNTN_LOCPLC_REGION_NM" : "경북 영덕군 달산면 주응리", - "MNTN_NM" : "팔각산" + "DETAIL_INFO_DTCONT" : "강원도 영월군의 진산인 봉래산은 영월읍내를 굽어보는 자리에 우뚝 솟아있다. 영월8경의 하나이기도 한 봉래산은 `봉래채운'이라는 예전의 명성 그대로 많은 관광명소를 끼고 있다.산행도 낙화암, 민충사 등 유명한 관광지를 안고 있는 체육공원에서부터 시작된다. 체육공원에서 절터를 지나 동북쪽 능선길을 따라 오르면 정상에 다다를 수 있다. 중간에 조망되는 남한강 물줄기와 영월읍내의 모습이 보는 이의 눈을 시원하게 해준다. 정상은 참나무가 빽빽이 들어서 있는 펑퍼짐한 둔덕으로 이루어져 있다.주위에 천연기념물인 고씨동굴과 어라연 등이 자리하고 있다. 또한 영월로 들어서는 길목인 소나기재 북쪽에 단종의 능이 위치해 있으며, 천문대와 동강등 주변 관광자원과 연계해 이제 영월은 새로운 산행과 관광을 겸할 수 있다.", + "MNTN_HG_VL" : "856", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 영월읍", + "MNTN_NM" : "봉래산" }, - "longitude" : 129.2583333, - "latitude" : 36.344999999999999 + "longitude" : 128.4858619, + "latitude" : 37.197774199999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경북 경산시의 북쪽에 위치한 해발1,192.3m 산이고. 관봉은 852m 봉우리로써 아주 험준한 산은 아니고 보통인은 등산하기에 알맞고 능선부위에 암반이 많은 곳으며, 자연경관이 좋고 관봉에서는 전망도 좋으며. 일년내내 불자신도와 등산객이 가장많은 장소이다.", - "MNTN_HG_VL" : "1192", - "MNTN_LOCPLC_REGION_NM" : "경상북도 군위군 부계면, 영천시 신녕면, 대구광역시 동구", - "MNTN_NM" : "팔공산" + "DETAIL_INFO_DTCONT" : "대성산은 충북 옥천군과 충남 금산군을 가르며 남북으로 뻗쳐있는 산줄기 가운데 있는 산이다. 천태산과 장룡산 외 새봉, 마성산, 용봉 등도 이 산줄기를 따라 이어져있다. 이 줄기는 백제와 신라의 경계였으며 모두가 아름답다. 천태산은 그 아름다움이 널리 알려진지 오래며 기암괴석이 많은 장룡산은 물론 대성산도 폭포가 많은 산으로 유명하다. 이 지역 주민들은 대성산 품안에 열 개의 폭포가 있다고 자랑한다.하지만 폭포만이 매력의 전부가 아니다. 폭포가 아니어도 여기저기 솟아 있는 바위봉우리에서 바라보는 조망이 좋다. 이 봉우리들은 천길 낭떠러지를 이루며 좁고 깊은 골짜기 위에 우뚝 솟아있기 때문에 조망이 좋고 무척 시원하다.대성산은 열 개의 폭포와 함께 열 개의 조망이 있는 산이라 할 수 있다. 그 가운데 유난히 뾰족해 멀리서 눈에 잘 띄는 국사봉 위의 조망대는 아예 ‘전망대’라는 정식 이름까지 붙여져 있다. 천길 벼랑 위에 있는 이 전망대에서는 옥천 일대가 발아래 펼쳐지고 멀리 속리산, 덕유산, 민주지산, 백화산, 포성봉과 함께 주행봉, 황악산 등을 조망할 수 있어 좋다.", + "MNTN_HG_VL" : "706", + "MNTN_LOCPLC_REGION_NM" : "충북 옥천군 이원면, 충남 금산군 군북면", + "MNTN_NM" : "대성산" }, - "longitude" : 128.69499999999999, - "latitude" : 36.016944000000002 + "longitude" : 127.6154454, + "latitude" : 36.217931999999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "팔공산하면 대구의 팔공산을 떠올리지만 이 산은 전북 진안과 장수에 걸쳐있는 팔공산으로 제법 높은 산인데도 인적이 드문 산이다. 무진장,무주,진안,장수는 오지중에서도 오지로 꼽혀 사람들의 접근이 쉽지 않았으나 최근에는 깨끗한 산천을 찾는 이들이 늘어가면서 하나씩 이름이 알려져가고 있다.팔공산 역시 사람들의 발길이 닿지 않아 원시림과 같은 청정함을 느낄 수 있는 곳이다. 이 산만이 갖는 뚜렷한 특징은 없으나 정상에서 북으로 내려가는 능선에 키를 넘는 억새군락이 인상적이다.정상에는 송신탑이 있고 사방으로 끝없이 펼쳐지는 산의 파노라마가 장관이며, 동쪽 장안산과의 사이에는 논개의 충절이 소리 없이 깔려 군민과 함께 숨쉬고 친절한 도시 장수가 내려다 보인다. 정상에서 북쪽으로 이어진 능선에는 억새가 장관이며 와룡자연휴양림이 조성되어 더더욱 좋다.", - "MNTN_HG_VL" : "1151", - "MNTN_LOCPLC_REGION_NM" : "전라북도 장수군", - "MNTN_NM" : "팔공산" + "DETAIL_INFO_DTCONT" : "남양주군에 있는 예봉산은 경기도 하남시의 검단산을 바라보고 있는 산이다. 예봉산은 남북의 두 줄기가 팔당댐에서 합쳐졌다가 서울로 흘러드는 한강의 물결 파노라마를 지켜볼 수 있는 산으로 인접해 있는 예빈산(禮賓山 589m)을 거치는 것이 일반적이다.옛날에 배를 타고 영월, 정선, 충주, 단양, 춘천을 오가는 길손들이 한양을 떠나며 삼각산이 보이는 이곳에서 임금에게 예를 갖추었다 해서 예빈산이라 부르기도 했다. 그런 연유에서인지 이 산자락에서는 실학의 선구자 정약용, 건국 운동을 선동했던 몽양 여운형 선생, 가나안 농군학교를 설립해 농촌지도자를 양성하는 데 앞장섰던 김용기 장로 등 이름 있는 인물들이 많이 배출되었다.예봉산의 능선이나 정상에 올라가면 어디서나 북한강과 팔당댐이 산을 끼고 굽이쳐 흐르는 아름다운 모습을 볼 수 있다. 능선길의 단풍은 특히 좋다. 정상 주변은 옛 성터 같은 돌무더기가 있다. 예전에는 산령단이 있었다고 하나 지금은 헬기장으로 변했고, 삼각점(양수 26)과 예봉산악회가 세운 정상표지석이 있다.", + "MNTN_HG_VL" : "683", + "MNTN_LOCPLC_REGION_NM" : "경기도 남양주시", + "MNTN_NM" : "예봉산" }, - "longitude" : 127.46611110000001, - "latitude" : 35.620555600000003 + "longitude" : 127.2611921, + "latitude" : 37.559263000000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "주능선이 마치 병풍을 펼친 듯한 산세로, 예부터 '소금강' 이라 불리어질 만큼 아름답다. 게다가 주능선 좌우로 홍천강이 흐르고 있어 정상에 올라서 바라보는 전망이 더 없이 좋으며, 물놀이도 겸할 수 있는 곳이다.팔봉산은 흔히 두 번 놀라게 하는 산으로 알려져 있다. 낮은 산이지만, 산세가 아름다워 놀라고 일단 산에 올라 보면 암릉이 줄지어 있어 산행이 만만치 않아 놀란다는 것이다.", - "MNTN_HG_VL" : "328", - "MNTN_LOCPLC_REGION_NM" : "강원도 홍천군 서면 팔봉리", - "MNTN_NM" : "팔봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "748", + "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", + "MNTN_NM" : "포도산" }, - "longitude" : 127.6954236, - "latitude" : 37.6974485 + "longitude" : 129.22692240000001, + "latitude" : 36.519314600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "서산 팔봉산(361.5m)은 금북정맥의 금강산(361.1m)에서 분기한 지능선의 한 줄기로 금강산 서북쪽 바로 건너편에 천혜의 절경을 자랑하며 8개의 봉우리로 솟아있다. 400미터도 되지 않는 낮은 산이지만 아기자기한 암릉과 조망이 일품이다. 능선에 오르면 북쪽으로 오밀조밀한 해변이 한눈에 들어오고 차분하게 가라앉은 주변의 정취가 한 폭의 멋들어진 수채화 같다. 서해안에 접한 이곳은 특히 바위에 노을이 물드는 저녁 시간의 풍경이 장관이다.산의 위치도 바다를 조망하기 좋은 위치이며, 아담한 암릉이 주는 고즈넉한 산세는 백제인의 미소처럼 소탈하다.팔봉산 산행 가운데는 제1봉에서 제3봉 사이에 펼쳐진 암릉 구간이 백미다. 암릉을 오르내리며 걷다보면 수석처럼 현란한 바위의 조화에 절로 탄성이 터져 나온다. 예전에는 아슬아슬한 바위타기가 재미를 더했지만, 지금은 서산시에서 위험한 곳에 철계단을 설치하여 가족산행을 하기에 무리없다. 남녀노소 누구나 안전하게 팔봉산의 바위 능선을 감상할 수 있다.팔봉산만 돌아보고 내려오는데는 3시간 정도면 충분하다. 산행이ordf;다고 느껴지는 사람들은 제8봉에서 산이고개를 거쳐 금강산과 장군산으로 산행을 이어가며 구간을 늘일 수도 있다.", - "MNTN_HG_VL" : "362", - "MNTN_LOCPLC_REGION_NM" : "충남 서산시 팔봉면", - "MNTN_NM" : "팔봉산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "", + "MNTN_LOCPLC_REGION_NM" : "전라남도 화순", + "MNTN_NM" : "용암산" }, - "longitude" : 126.3708271, - "latitude" : 36.810449699999999 + "longitude" : 127.0052778, + "latitude" : 34.957500000000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "395", - "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군", - "MNTN_NM" : "팔암산" + "DETAIL_INFO_DTCONT" : "지리산 왕시리봉에서 섬진강을 내려다보면 굽이쳐 가던 섬진강 끝자락에 삼각형 실루엣으로 우뚝 솟은 산이 눈길을 사로잡는데, 하동의 진산인 금오산(849m)이다. 금오산 정상은 남해 조망이 일품이다. 오른쪽으로 광양제철소와 화력발전소, 정면으로 다도해의 수많은 섬들이 점점이 떠 있고, 왼쪽 사천만 뒤로 우뚝한 와룡산의 멋진 자태 또한 일품이다. 정상에 선 중계탑으로 인해 실제로 오를 수 있는 정상부가 한쪽으로 밀려나 있는 게 아쉽다.남해를 비추며 떠오르는 달맞이와 해맞이, 아름다움을 간직한 해넘이는 금오산이 자랑하는 최고의 볼거리다. 달맞이 전망대로는 금오산 남쪽의 너덜지대에 위치한 석굴암이 최고로 꼽힌다. 달이 없는 밤이라도 불야성을 이룬 광양제철소의 야경 또한 황홀한 볼거리를 제공한다.석굴암과 봉수대, 비구니도량 금성암 등 산행하면서 둘러볼 수 있는 볼거리 외에도 1973년 완공된 남해대교와 충무공의 얼을 기리는 충렬사, 그 앞 노량 앞바다에 떠 있는 거북선 등 많은 명소가 있다.", + "MNTN_HG_VL" : "849", + "MNTN_LOCPLC_REGION_NM" : "경남 하동군 금남면ㆍ진교면", + "MNTN_NM" : "금오산" }, - "longitude" : 126.82715090000001, - "latitude" : 35.4843118 + "longitude" : 127.8692594, + "latitude" : 34.993499200000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "고흥읍에서 동쪽으로 25km 떨어진 소백산맥의 맨 끝부분에 위치한 산으로 8개의 봉우리가 남쪽을 향해 일직선으로 솟아 있다.", - "MNTN_HG_VL" : "607", - "MNTN_LOCPLC_REGION_NM" : "전남 고흥군 영남면 우천리", - "MNTN_NM" : "팔영산" + "DETAIL_INFO_DTCONT" : "부암산(傅岩山)은 스승 부(傅)자를 쓰며 일명 스승바위산이라고도 하는데 사실 부암산 자락은 너무 많은 역사를 간직한 산이다. 악(岳, 嶽)이나 암(岩)자가 들어가는 산은 거의 바위산인데 이 곳 역시 예외는 아니다. 부암산은 멀리서 쳐다보아도 암반 투성이고 정상에서 주위를 둘러보아도 역시나 북쪽 산들은 모두 바위산이다. 거대한 바위들이 누룩이 포개져 있는 것처럼 층층이 포개져 있다.한적한 마을 뒤에 있으면서도 그 산세가 빼어나다. 가까이 있으면서 소문이 자자한 황매산과 모산재에 조금도 뒤지지 않는 멋진 산이다. 산길로 들어서면 우람한 낙락장송이 산을 채우며 잔가지가 많은 소나무들이 마치 담 하나를 사이에 둔 이웃처럼 함께 어울려 골짜기를 메웠다. 특히 단계천 가운데 자리잡고 있는 기암이라는 바위는 그 풍채가 당당하면서도 멋스럽다. 바위에는 많은 구멍이 뚫려있는데 옛날에 일산을 꽂았던 자리이다. 단계현 시절에 놀이가 있을 때에 이곳에서 풍악을 울리고 기생을 불러서 놀이를 하던 곳으로 전한다.", + "MNTN_HG_VL" : "696", + "MNTN_LOCPLC_REGION_NM" : "경남 합천군 가회면, 산청군 차황면ㆍ산등면", + "MNTN_NM" : "부암산" }, - "longitude" : 127.4341153, - "latitude" : 34.618202699999998 + "longitude" : 127.9902359, + "latitude" : 35.457224099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "등산을 즐기는 사람이라도 경기도 양평에 편전산이 있다는 것을 아는 사람은 그다지 많지 않다. 널리 알려지지 않은 산들이 그렇듯이 편전산은 호젓한 산행을 즐기기 좋으며 수풀이 우거져 덮수룩한 산길을 걷는 묘미가 있는 산행지이다. 이 산에는 특히 소나무와 참나무가 많으며 곳곳에 억새풀 수풀림이 형성되어 있다. 정상에 서면 북쪽 건너편에 동그마니 들어앉은 마유산이 보이고 동쪽으로 용문산 주봉과 그 연릉이 남으로 길게 뻗어 나가다 솟구친 백운봉이 가깝게 눈에 든다.정상에 오르면 북쪽 건너편에 커다란 무덤처럼 둥근 산세를 지닌 마유산이 보이고 동쪽으로는 용문산의 주봉과 그 연릉이 남으로 길게 뻗어가다가 솟은 백운봉이 가깝게 조망된다.", - "MNTN_HG_VL" : "376", - "MNTN_LOCPLC_REGION_NM" : "경기도 양평군", - "MNTN_NM" : "편전산" + "DETAIL_INFO_DTCONT" : "삼방산 산행은 태백시를 기점으로 한다. 시내버스를 타고 철암 방터골 입구 버스정차장에서 하차하여 동쪽으로 깊게 패인 방터골을 걸으면 넓은 길이 점점 좁아지며 계류도 맑아져 갑자기 깊은 산 속에 들은 기분이 든다. 실제 이곳은 태백시의 오지이다.징검다리 건너기를 여러번, 여유 있는 걸음으로 1시간 10여분 후면 원심이골 입구다. 입구에는 쌍소나무와 태백여성산악회 표지기가 있다. 원심이골에서 20분가면 합수점인데 합수점 사이 능선 대밭고리를 40분 올라 주능선 안부 전개목에 닿아 오른쪽으로 15분 능선을 따르면 늪지가 나타난다. 여기서 남쪽으로 방향을 꺾어 늪지를 내려서면 지르뫼어이 안부다. 지르뫼어이 바로 남쪽 둥그런 봉이 정상이다.하산 30분 후 돌탑에 이르러서부터는 독도에 신경을 써야 한다. 돌탑에서 육송정까지 약 2 시간 걸린다. 방터골에서 원심이골 정상을 거쳐 태백시계를 따라 육송정에 이르는 총산행 시간은 5시간 이상 소요된다.", + "MNTN_HG_VL" : "1175", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "삼방산" }, - "longitude" : 127.4802778, - "latitude" : 37.541111099999988 + "longitude" : 129.07030929999999, + "latitude" : 37.084382499999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "p class=\"bonmun\"토정비결을 지은이지함이 올라가서 편하게 자리잡아 앉았다 해서 평안산이라 하기도 하며, 옛 성 터가 있어 이곳에 피난한 사람은 모두 무사하였다 하여 평안산이라 불리운다고 한다. 공주시가지로부터 남서쪽에 위치해 있으며, 북쪽으로는 금강과 칠봉산이, 남쪽으로는 장군봉이 위치해 있다.", - "MNTN_HG_VL" : "168", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 탄천면 운곡리", - "MNTN_NM" : "평안산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "427", + "MNTN_LOCPLC_REGION_NM" : "경상남도 고성", + "MNTN_NM" : "선유산" }, - "longitude" : 127.0177778, - "latitude" : 36.3541667 + "longitude" : 128.27611110000001, + "latitude" : 35.1175 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "748", - "MNTN_LOCPLC_REGION_NM" : "경상북도 영양군", - "MNTN_NM" : "포도산" + "DETAIL_INFO_DTCONT" : "전라북도 부안의 변산반도는 아름다운 해안선을 따라 수많은 절경이 이어지는데 이 일대가 국립공원으로 지정되어 있다. 변산은 바다를 끼고 도는 외변산과 남서부 산악지의 내변산으로 구분한다. 변산반도 국립공원의 내륙은 첩첩산중으로 이루어져 있다. 최고봉인 의상봉의 높이가 해발 509m에 불과하지만 400m급 준봉들이 겹겹이 이어진다. 내륙쪽 변산반도를 가리키는 내변산의 명소로는 최고봉인 의상봉(509m)을 비롯해 쌍선봉(459.1m), 옥녀봉, 관음봉(433m 일명 가인봉), 선인봉 등 기암봉들이 여럿 솟아 있고, 직소폭포, 분옥담, 선녀당, 가마소, 와룡소, 내소사, 개암사, 우금산성, 울금바위 등이 있다. 직소폭포 골짜기는 쌍선봉 자락에서 흘러내려 부안호로 흘러 내려간다.산에 얽힌 전설이 전해지는데, 이성계가 청년시절에 부안군 보안면 우반동 굴바위 옆 저수지 안쪽의 선계안(또는 성계골)에서 영험한 두 노인에게 각각 문(文)과 무(武)를 익혀 훌륭한 청년이 된 뒤 스승들과 헤어질 때가 되었다고 한다. 스승과 제자 모두 이를 서로 아쉬워하다가 선계안으로부터 북쪽으로 삼천보나 떨어진 이곳까지 왔고, 이성계가 두 스승에게 하직 인사를 하고 보니 두 스승은 사라지고 그 앞에 높은 봉우리 두 개만 우뚝 솟아 있었다고 한다.산중턱의 월명암에서 내려다보이는 안개 낀 아침 바다의 신비로움을 일컫는 월명무애와 직소폭포는 웅연조대, 소사모종, 채석범주, 지포신경, 개암고적, 서해낙조와 함께 변산팔경(邊山八景)으로 꼽힌다.", + "MNTN_HG_VL" : "459", + "MNTN_LOCPLC_REGION_NM" : "전라북도 부안군 변산면", + "MNTN_NM" : "쌍선봉" }, - "longitude" : 129.22692240000001, - "latitude" : 36.519314600000001 + "longitude" : 126.558978, + "latitude" : 35.643399299999999 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "754", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시", - "MNTN_NM" : "피래산" + "MNTN_HG_VL" : "630", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군", + "MNTN_NM" : "곡달산" }, - "longitude" : 128.9761111, - "latitude" : 37.646111099999999 + "longitude" : 127.4664193, + "latitude" : 37.657477 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "하설산은 충북 제천에 자리잡은 산이다. 백두대간이 대미산 부근에서 북으로 갈라져 솟은 봉우리가 문수봉이고 이곳에서 북서로 뻗어 우뚝 솟은 봉우리가 바로 하설산이다. 이 산은 대미산에서 갈린 산줄기이며 문수봉과 매두막에서 이어지며 월악산국립공원 안에 있다. 여름에도 눈이 온다는 뜻을 지닌 산 이름은 실제로 눈이 오지는 않지만 그만큼 시원하다는 의미를 담고 있다. 특히 산 아래 자리잡은 용하구곡은 경치가 아름답고 계곡물이 차기로 이름 나 있다. 계곡의 물은 대미산에서 발원한 광천에서 흘러들어온다.정상에서의 조망은 월악산국립공원 일대가 한눈에 들어오고 북쪽으로 충주호와 금수산이, 동쪽으로는 도락산 줄기 너머로 소백산 연화봉과 죽령이 보인다. 정상 주변에는 참나무 수림이 빽빽하고 산딸기나무 군락이 1천 평 남짓 형성되어 있다.", - "MNTN_HG_VL" : "1028", - "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시 덕산면", - "MNTN_NM" : "하설산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "440", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", + "MNTN_NM" : "구봉산" }, - "longitude" : 128.1758734, - "latitude" : 36.874696399999998 + "longitude" : 127.7820761, + "latitude" : 37.891676400000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한라산은 우리나라 최남단에 위치해 있으면서 남한에서 가장 높은 산이다. 해발 1950m, 면적 151.35㎢ 로 1970년 3월 24일 국립공원으로 지정된 이 산은 3대 영산중의 하나로 다양한 식생분포를 이뤄 학술적 가치가 높은 동식물의 보고이기도 하다.", - "MNTN_HG_VL" : "1947", - "MNTN_LOCPLC_REGION_NM" : "제주도 제주시, 서귀포시", - "MNTN_NM" : "한라산" + "DETAIL_INFO_DTCONT" : "백두대간 주능선에 위치한 문수봉은 태백산 천제단을 마주하고 있으며 풍수 지리적으로 영험한 기(氣)가 있다 하여 무속 신앙인들과 이와 유사한 사람들의 기도처가 많은 산이다.산 정상부가 돌무더기로 되어 있어 이색적인 느낌을 주는 산이고 정상에는 태고때부터 하늘에 제사를 지내던 천제단이 있다. 삼국사기에 왕이 친히 천제를 올렸다는 기록이 있고 세종실록지리지에는 신라에서 오악 가운데 태백산을 북악으로 받들어 봄,가을에 제사를 지냈다고 한다. 천제단을 중심으로 북쪽지점에 태백산의 주봉인 가장 높은 장군봉, 남동쪽으로 능선을 타고 가면 멀리 수만개의 바위로 이루어진 문수봉이 있다. 서울에서 내려온 한 처사가 쌓고 있는 조그마한 돌탑이 있다.신라 진평왕때 자장율사가 이 봉우리에 문수보살을 모시기 위해 망경사를 지었다고 하며, 그 외 사찰로도 백단사, 유일사, 만덕사, 청원사등이 있다.태백산은 겨울의 눈과 설화가 환상적이다. 주목과 어우러진 설화는 동화속의 설경이다. 적설량이 많고 바람이 세차기로 유명하여 눈이 잘 녹지 않고 쌓인다. 세차게 몰아치는 바람이 눈을 달려 설화를 만든다.", + "MNTN_HG_VL" : "1162", + "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 경상북도 봉화군 석포면", + "MNTN_NM" : "문수봉" }, - "longitude" : 126.5291666, - "latitude" : 33.3616666 + "longitude" : 128.94, + "latitude" : 37.0944444 }, { - "mountain" : { - "DETAIL_INFO_DTCONT" : "한산이라는 명칭은 산 아래에 한씨의 묘가 있어 한산소라 불리는 마을 이름에서 유래된 것으로 추정된다. 출구쪽은 밤나무 단지와 연결되어 있으며 경사가 심하다.", - "MNTN_HG_VL" : "121", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 웅진동", - "MNTN_NM" : "한산" + "mountain" : { + "DETAIL_INFO_DTCONT" : "가야산은 경남 합천군 가야면과 거창군 가북면, 경북 성주군 가천면 수륜면을 한몸에 품고있다. 우리나라 12대 명산중의 하나로 산세가 천하에서 으뜸이고, 지덕은 해동에서 제일이라 하여, 대한 8경에 속하는 명산이다. 가야산 지역이 옛날 가야국이 있었던 곳이고 이 산이 가야국에서 가장 높고 훌륭한 산이었기 때문에 자연스럽게 가야의 산이라 불렀다고 한다.가야산은 소머리 같다 해서 우두산(산 머리의 큰 바위 아래에 소의 코라는 뜻의 우비정이란 샘도 있다) 이라는 이름외에 상왕산, 설산, 중향산 등으로도 불리워졌다. '택리지'에 기암괴봉을 불꽃에 비유하여 석화성(石火星)이라고 하였는데, 가야산은 보는 방향에 따라서 한송이 연꽃으로도 보였다가 서쪽으로 겹겹이 솟은 산봉우리 사이사이 또는 골짜기에 하얀구름이 잠기면 많은 섬이 떠 있는 바다가 된다.해발 1천m가 넘는 고봉들이 불꽃처럼 솟아 있는 자태하며, 북에서 남으로 이르는 장쾌한 대덕유의 줄기와 아스라히 떠오른 구름위로 지리산을 볼 수 있는 조망, 홍류동천의 아름다운 계곡 등 장중하고 덕성스러운 모습을 곳곳에서 볼 수 있다.가야산 고스락에 서면 금오산, 팔공산, 비슬산이 보이고 화왕산, 자굴산이 보이는가 하면 가까이에 두무산, 오도산, 비계산, 조금 멀리에 백운산, 수도산, 대덕산 등이 보인다.여기에 우리나라 3보 사찰중 하나인 해인사가 들어서고, 조선시대 때 강화도에서 팔만대장경을 옮겨온 이후 불교의 성지로 자리메김하였다. 근래에는 백련암에서 수도했던 성철 스님으로 인하여 더욱 유명해졌다.", + "MNTN_HG_VL" : "1433", + "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군ㆍ거창군, 경상북도 성주군", + "MNTN_NM" : "가야산" }, - "longitude" : 127.0999884, - "latitude" : 36.452894499999999 + "longitude" : 128.1179362, + "latitude" : 35.822099600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "한석산(1,103)은 내설악 인근의 삼형제봉,가리봉,으로 연결되는 산으로 등산객에게는 많이 알려지지 않은 미지의 산이다. 삼형제봉,가리봉은 험준한 바위들로 이루어져 일반등산객들이 사전지식없이 산행하기에는 무리가 있어 조심해야 하며 주변에 내린천이 있어 래프팅등 모험관광을 동시에 즐길수 있으며 대부분의 코스가 당일 산행이 가능하다.인제군은 오래전부터 이곳에 스키장등 대단위 관광지로 개발하려고 하고 있으나 아직까지 가시적 성과없이 지지부진한 상태이다.한석산의 한모퉁이 내린천 변에는 6.25당시 이땅을 지키기 위한 우리 국군 용사들의 넋을 기리기위해 1990년 11월 매봉 한석산 전적비가 세워졌다.당시 한석산에서는 국군들이 치열한 전투끝에 8백95명의 적군을 사살하고 42명의 포로를 생포하였으며 3일간의 치열한 전투끝에 매봉과 한석산을 탈환하는 전과를 얻었으나 이과정에서 국군 72명이 전사하고 3백19명이 전사하여 이를 기리기위해 8백여평의 부지에 높이 8.1m의 화강암 석탑으로 6.25당시 참전부대인 9사단 30연대를 상징하기 위하여 탑을 9단으로 쌓았으며 탑의 원형도 30각도로 조성한 것이 특징이다", - "MNTN_HG_VL" : "1103", - "MNTN_LOCPLC_REGION_NM" : "강원도 인제군", - "MNTN_NM" : "한석산" + "DETAIL_INFO_DTCONT" : "보현산은 경북 영천시 화북면과 청송군 현서면, 포항시 죽장면의 경계를 이루며 솟은 육산이다. 정상 부근에는 국내 최대 규모의 보현산천문대가 있으며 천문대까지 차량으로 오를 수 있다. 참나무, 당단풍나무, 고로쇠나무 등이 숲을 이루고 있으며 야생화 천국이라 할 만큼 다양한 식물들이 자라고 있다.주능선은 이웃한 면봉산과 더불어 고산다운 산세를 지닌다. 시루봉(1124m)과 보현산(1126m), 두 봉우리가 나란히 정상군을 이루고 있다. 정상에서 동쪽 능선을 따라 3킬로미터 지점에는 826.5미터의 ‘작은 보현산’도 있다.보현산은 이 일대에서 가장 높은 산이기에 일출과 낙조를 잘 볼 수 있는 곳이다. 일출과 일몰의 아름다움이 알려지기 시작하면서 해마다 연말연시면 해돋이와 함께 새롭게 한 해를 시작하려는 이들로 인산인해를 이룬다. 이른 봄에는 고로쇠축제, 5월에는 산나물축제, 8월 중순에는 별빛축제가 열리는 들머리 정각리 별빛마을은 최근에 청정미나리로도 널리 알려져 찾는 이가 늘고 있다.", + "MNTN_HG_VL" : "1126", + "MNTN_LOCPLC_REGION_NM" : "경북 영천시 화북면, 청송군 현서면, 포항시 죽장면", + "MNTN_NM" : "보현산" }, - "longitude" : 128.25588619999999, - "latitude" : 38.051582499999988 + "longitude" : 128.97476230000001, + "latitude" : 36.1616304 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "원래 차가운 비가 내리는 산이란 뜻의 찰비산이라 불리다가 나중에 찰 한(寒), 비 우(雨) 자를 쓴 한우산으로 이름이 바뀐 이 산은 의령의 명산인 자굴산과 이어져 있다.비록 지리산이나 자굴산에 비해 알려지지는 않았지만, 한우산에서 산성산까지 연결하여 산행을 하다보면 풀밭이 널찍하게 자리잡은 곳이 있어 신나게 달리다가도 수직의 빳빳한 암벽이 늘어선 암봉지대를 만나면 힘겹게 오르는 맛이 있어 숨겨진 산의 보물을 찾아내는 기분이다.산 정상에서 내려다보는 마을은 포근한 느낌이 드는 전형적인 산간마을이어서 그곳에서 하룻밤을 지내면 노곤한 몸이 생기를 되찾을 것이다. 또한 한우산은 철쭉군락지로 유명하고 아름다운 찰비골 계곡에는 민속촌이 조성되어 있다.", - "MNTN_HG_VL" : "764", - "MNTN_LOCPLC_REGION_NM" : "경상남도 의령군", - "MNTN_NM" : "한우산" + "DETAIL_INFO_DTCONT" : "문수산(일명 천호산)의 한 지맥이 서쪽으로 뻗어 형성된 해발 342m의 높지 않은 산이다.미륵산 동쪽의 왕궁면,여산면에 걸쳐있는 네 봉우리(옥녀봉,선인봉,노승봉,성태봉)를 통틀어 봉화산이라 말한다.서동공원에서 시작해 용화산의 정상부에 오르면 서쪽으로 익산의 진산인 미륵산이 보이고 여산 방면으로 가다가 우측으로 내려가면 서동요의 전설로 잘 알려진 선화공주사가가 나온다.미륵산과 용화산을 합하며모두 용화산이라 불러왔으나 지금은 미륵사가 있는곳이 미륵산이고 나머지를 용화산이라 한다. 일명 군입산(軍入山)이라고 하는데 고려 태조가 후백제를 정벌할때 군대를 주둔시켰던 곳이기 때문에 붙여진 이름이라고 신증동국여지승람은 기록하고 있다.", + "MNTN_HG_VL" : "342", + "MNTN_LOCPLC_REGION_NM" : "전라북도 익산시", + "MNTN_NM" : "용화산" }, - "longitude" : 128.20174539999999, - "latitude" : 35.393346600000008 + "longitude" : 127.0655587, + "latitude" : 36.0244456 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "신라와 백제의 격전지로 알려진 한우산은 봄이면 철쭉제가 열리는 철쭉 명산이다. 한자로 찰 한(寒)자와 비 우(雨)자를 쓰는 이 산은 한여름에 내리는 비도 한겨울에 내리는 비처럼 차다고 해서 붙여진 이름이다. 산자락에는 망대실골, 찰비골, 백학계곡이 흐르고 있고 골짜기마다 사시사철 맑은 물이 흐르고 곳곳에 폭포와 소를 만들어 장관을 이룬다.산길은 모나지 않고 완만하고 부드럽다. 한우산은 패러글라이딩 활공장으로도 유명하며 766미터봉 주변으로는 철쭉이 군락을 이루고 있어 봄이면 철쭉을 만끽할 수 있다. 찰비골을 따라 자굴산(897.1m)으로 이어지는 임도를 따르면 산행을 굳이 하지 않아도 차량으로 정상에 다다를 수 있다. 이 임도는 안성기 주연의 영화 ‘아름다운 시절’을 촬영한 곳이기도 하다.국토지리정보원 지형도에는 한우산 정상을 766미터봉으로 표기하고 있으나 의령군청 정보와 실제 산행을 해보면 835미터 봉우리가 정상에 걸맞다는 것을 알 수 있다. 정상석 역시 835봉에 세워져 있지만 높이가 764미터로 표기되어 있으므로 수정이 필요하다.", - "MNTN_HG_VL" : "835", - "MNTN_LOCPLC_REGION_NM" : "경남 의령군 가례면", - "MNTN_NM" : "한우산" + "DETAIL_INFO_DTCONT" : "양천산은 진천군 문백면 평산리, 은티리, 사양리에 걸쳐 있는 산으로 말이 달리고 있는 분마형(奔馬形)을 하고 있다. 봉우리가 평원하여 반석과 같고 산중턱에는 석지(石池)가 있어 찬물이 그치지 않는 산이라 하여 냉천산(冷川山)이라 불리기도 한다.옥성교에서 그럭재마을을 지나 정상에 오르면 사양저수지가 내려다 보인다. 사미마을 쪽으로 내려오는 하산길은 경사가 급해 조심해야 한다. 임진왜란 때 주민들을 피신시킨 양천산성이 있다.", + "MNTN_HG_VL" : "350", + "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면", + "MNTN_NM" : "양천산" }, - "longitude" : 128.20174539999999, - "latitude" : 35.393346600000008 + "longitude" : 127.4608339, + "latitude" : 36.770334800000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "315", - "MNTN_LOCPLC_REGION_NM" : "대전 동구 효평동,마산동", - "MNTN_NM" : "함각산" + "MNTN_HG_VL" : "368", + "MNTN_LOCPLC_REGION_NM" : "경상북도 포항시", + "MNTN_NM" : "봉화봉" }, - "longitude" : 127.47583330000001, - "latitude" : 36.395555600000002 + "longitude" : 129.09805560000001, + "latitude" : 36.146666699999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "함박산은 최악의 조건을 갖추고 있는 악산이다. 암릉은 대단히 험난하고, 식수는 처음부터 하산 지점까지 전혀 구할 수 없고, 경사도는 매우 심하고 자갈 너덜지대로 되어 있다.암릉식수경사도의 3대 최악의 조건을 구비한 산이라 하겠다. 일부 공룡능선만큼이나 험난한 암릉 코스로 중간중간 위험이 도사리는 만큼, 눈비가 오는 날이나 단독 산행은 절대 금물이다.", - "MNTN_HG_VL" : "588", - "MNTN_LOCPLC_REGION_NM" : "경상남도 양산", - "MNTN_NM" : "함박산" + "DETAIL_INFO_DTCONT" : "면적 72평방 킬로미터에 둘레가 44.12킬로미터인 울릉도는 포항에서 뱃길로 188킬로미터 떨어진 섬으로 독도를 포함해서 본토에서 가장 멀리 있는 섬이다. 섬 주변은 대부분 화산암의 해안절벽으로 되어 있는데 바로 이 섬 중심부에 성인봉이 자리해 있다.작은 땅, 울릉도 위에 하나의 봉우리가 솟아 있으니 성인봉이 곧 울릉도인 셈이다. 울릉도는 오래전부터 왕조들의 정책에 의해 백성들을 살 수 없게 하였던 곳이나 백성들이 몰래 숨어 들어 끝끝내 우리 땅으로 지켜낸 우리 민족의 기상이라고 할 수 있다. 울릉도에 관한 기록은 신라시대로 거슬러 올라간다.〈삼국사기〉와 〈삼국유사〉에 신라 22대 지증왕 때 울릉도에 관한 기록이 있다. 〈삼국사기〉에는 지증왕 13년에 우산국(于山國)이 항복했고, 하실라 군주 이사부(異斯夫)가 나무로 만든 사자를 싣고 가서 항복을 받았다고 기록되어 있는데 〈삼국유사〉의 기록은 조금 다르다. 〈삼국 유사〉에 따르면 아슬라주 동쪽 바다에서 순풍으로 이틀 걸리는 곳에 우릉도(于陵島)가 있고 이 섬에 사는 오랑캐들은 교만하게 바닷물이 깊은 것을 믿고 조공을 바치지 않아 이창 박이종(朴伊宗)이 나무사자로 위협해 항복시켰다고 한다.울릉도는 겨울에는 따뜻하고 여름에는 시원해서 누구라도 살기 좋고 모든 것이 풍요롭다. 특히 '3무'라고 해서 도둑,거지,뱀이 없고 '5다'라고 하여 향(香),풍(風),미(美),수(水),석(石))이 많기로 이름나 있다. 해안가로 나가면 구멍바위(공암), 거북바위, 사자바위, 곰바위, 말바위, 국수를 널어놓은 듯한 국수바위 등 기암괴석을 쉽게 볼 수 있다. 성인봉 북쪽 하산 길에 있는 이십 여만 평의 나리분지에는 억새 밭과 나리꽃 군락이 서쪽으로 솟아 있는 알봉(538)과 어우러져 비경을 자아낸다.울릉도 서쪽 끝 태화동에는 울릉도의 대표적 사당인 성하신당이 자리잡고 있다. 이곳 주민들은 매년 음력 2월에 농사와 어업의 풍년,풍어를 빌고 있다.전설에 의하면 성하신당은 조선 태종 때 안무사로 왔던 김인우가 세웠다고 한다. 안무사 김인우가 심한 풍랑으로 본토에 돌아가지 못하고 있을 때 신의 지시를 받고 젊은 남녀 한 쌍 태하동에 억지로 떼어놓고 본토로 돌아갈 수 있었는데 몇 년 뒤 울릉도에 다시 와 보니 두 사람이 껴안은 채 백골이 되어 있어 그들의 원혼을 달래기 위해 세운 사당이라 한다. 저동에서 봉래폭포로 이어지는 등산로에는 바위틈에서 찬바람이 나오는 〈천연에어컨〉이 땀을 시켜 준다.천연에어컨에서 정상으로 이어지는 등산로를 따라 약 40분 오르면 세 갈래 물줄기가 원시림을 뚫고 쏟아지는 봉래폭포를 만나게 된다. 나리분지에서 산행이 끝나는 지점인 천부선착장을 따라 서쪽으로 2백미터정도 걷다보면 바위굴 속에서 찬바람이 나오는 풍혈(風穴)이 있다. 봉래폭포쪽 천연에어컨보다 못하지만 여름 땀을 씻어내기에는 충분하다.", + "MNTN_HG_VL" : "987", + "MNTN_LOCPLC_REGION_NM" : "경상북도 울릉군 울릉읍 서면ㆍ북면", + "MNTN_NM" : "성인봉" }, - "longitude" : 129.1802778, - "latitude" : 35.306111100000003 + "longitude" : 130.86615280000001, + "latitude" : 37.503257099999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "산경표에서는 ‘크고 밝은 뫼’의 뜻으로 대박산(大朴山), 삼국유사에서는 묘범산(妙梵山)이라 불린 함백산(1572.9m)은 5대 적멸보궁인 정암사를 품고 있으며 지하에는 무진장의 석탄을 간직한 남한 제6위의 산이다. 함백산이 품고 있는 정암사는 1300여년 전 자장율사가 문수보살의 계시에 따라 갈반지(葛盤地)를 찾아 큰 구렁이를 찾은 후 그 자리에 적멸보궁과 수마노탑을 짓고 석가모니의 진신사리를 모셨다고 한다. 적멸보궁 옆 주목은 자장율사가 꽂아둔 지팡이가 살아난 것이라 해 ‘선장단’이라 부른다.함백산 정상 부근은 주목이 군락을 이루며, 두문동재에서 만항재까지의 고원 지역에는 참나물, 누리대, 취나물 등 산나물이 많다. 특히 겨울산행을 하다보면 주목과 고사목에 핀 눈꽃이나 상고대가 추위조차 잊게 해 줄 만큼 아름답다. 함백산의 대표 등산로 중 하나인 만항재는 해발 1330미터로 남한에서 가장 높은 도로며 두문동재는 1268미터로 만항재와 버금가는 높이다.", - "MNTN_HG_VL" : "1573", - "MNTN_LOCPLC_REGION_NM" : "강원도 태백시, 영월군 상동읍, 정선군 고한읍", - "MNTN_NM" : "함백산" + "DETAIL_INFO_DTCONT" : "무안군을 동서로 가르고 청계면과 몽탄면을 경계로 하는 해발 318m의승달산은 노령산맥 4대 명혈중의 하나이며 목포의 유달산과 쌍벽을 이루는 명산으로 총지사지, 목우암 등 불교사적이 많다. 3백미터가 조금 넘는 이 산이 명혈로 꼽히는 이유는 고승이 제자를 모아 놓고 불공을 드리는 형상이기 때문으로 예전에는 영축산이라 불렸다고 한다.고려 인종때 원나라 승원명이 제자 500명과 함께 도를 득달한 후 이 산을 승달산이라 명하셨고 산세가 수려하고 주변경관이 아름다워 휴일이면 가족단위 피크닉 장으로 널리 알려져 있다.현재는 이 혈아래에 목포대학교가 터를 잡고 있다. 승달산은 신안군과 서해를 내려다 볼 수 있으며 반나절이면 원점회귀가 가능해 평일에도 등반이 가능한 곳이다.들머리는 국립목포대학교 농과대 실습장이 있는 도림리 천지골과 월산리 수월동, 몽탄면 목우암인데, 교통이 편한 천지골이 자주 이용되고 있다. 특히 천지골 오름은 노승봉과 318봉으로 이어지는 능선 위 하루재까지 임도가 뚫려 쉽게 접근할 수 있으며 이 임도가 하루재 건너의 법천사나 목우암 아래까지 이어져 있다. 백제 성왕 때 덕이조사가 창건했다는 법천사는 조선시대 들어서 무수히 많은 고승이 수도하던 곳으로 우리나라 불교의 4대 성지중 하나로 불린다. 조선 후기에 폐사되었지만 퇴락한 요사채가 역사를 증명해 주고 있다. 법천사 맞은편에 위치한 목우암은 승달산 제일의 명당에 자리잡았다고 한다. 목우암에는 2미터가 넘는 목조불과 산신각이 있으며 새로지은 대웅전이 번듯하기만 하다.또한 남도의 바닷가에 위치하고 있어서 해발고도에 비해 월등히 뛰어난 조망을 즐길 수 있을 뿐 아니라 겨울에도 훈훈한 훈풍을 느낄 수 있는 명산이다. 그리고 토양이나 기후 조건이 야생난이 자라기에 최적의 조건을 지니고 있어 '난(蘭)'자생지로도 이름 난 곳이다.", + "MNTN_HG_VL" : "318", + "MNTN_LOCPLC_REGION_NM" : "전라남도 무안군 청계면, 몽탄면", + "MNTN_NM" : "승달산" }, - "longitude" : 128.9176271, - "latitude" : 37.1615368 + "longitude" : 126.4569444, + "latitude" : 34.908888900000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "해남 금강산은 한반도 서남쪽 끝머리에 자리잡은 해남읍을 병풍처럼 두르고 있다. 한양과 멀다는 이유로 이곳은 귀양지로 이름을 날린 고장이다. 그러나 귀양 온 양반들이 심어놓은 문화와 유적은 오랫동안 이어져 유배문화의 본산이 된다.그 때문일까. 해남의 산들에는 독특한 정서가 스며있어 산을 찾는 이들마저 시 한 수 읊지 않고는 견딜 수 없게 만든다. 비록 작은 산이지만 기암과 괴석으로 된 암장들이 포진해 있는 금강산 정상에서는 해남읍내와 인근의 목포, 강진, 진도, 완도, 장흥, 영암일대를 조망할 수 있다.", - "MNTN_HG_VL" : "481", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군", - "MNTN_NM" : "해남 금강산" + "DETAIL_INFO_DTCONT" : "중미산은 청평과 양평을 잇는 37번 도로에서 가장 높은 곳인 선어치(서너치)고개를 사이에 두고 유명산과 마주보고 있다. 중미산 남쪽의 고개를 서너치(3-4寸)라고 부르게 된 데에는 재미있는 연유가 있다.호랑이가 있다는 고개를 넘어 온 선비에게 호랑이를 못 보았느냐고 묻자\"\"호랑이는 못 보고 어찌나 나무가 울창한지 하늘만 서너치 보았오` 라고 얘기한 것에서 비롯되었다고도 하고 가마 타고 시집가는 색시가 고개를 넘으면서 지루한 나머지 하인에게\"\"길이 얼마나 남았느냐\"\"고 물을 때마다 하인이\"\"이제 서너치 남았소\"\"라고 대답했다는데서 붙여진 지명이라고 한다. 이 산 자락 아래 양현 마을이 국민휴양지로 개발되면서부터 등산객들이 늘고 있다. 인근의 산 중에서 제법 높은 산이라 정상에서의 조망이 시원스럽다.", + "MNTN_HG_VL" : "833", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 옥천면, 가평군 설악면", + "MNTN_NM" : "중미산" }, - "longitude" : 126.5997222, - "latitude" : 34.591666699999998 + "longitude" : 127.4716706, + "latitude" : 37.594901399999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "해명산은 인천시 삼산면 석모도에 위치한 산으로 서해에서 불어오는 해풍을 받으며 산과 바다의 정취를 동시에 즐길 수 있는 곳이다. 서해에서 불어오는 해풍을 듬뿍 받으며 산행을 할 수 있는 해명산의 정상에서면 낙가산과 상봉산의 모습이 한눈에 들어오고 서쪽바다에는 이름모를 섬들이 아른거리고, 정상을 떠나 주변 바다를 보면서 군데군데 피어있는 진달래 능선을 따라 낙가산으로 갈 때면 마치 바다 위를 걷는 기분이 든다.산세가 아기자기해 가족동반 산행지로 적합하며 산행이 수월하므로 인접한 낙가산 산행을 곁들이는 것이 좋다.", - "MNTN_HG_VL" : "309", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 석모도", - "MNTN_NM" : "해명산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 임실군", + "MNTN_NM" : "고덕산" }, - "longitude" : 126.3494724, - "latitude" : 37.676399099999998 + "longitude" : 127.3434029, + "latitude" : 35.659716299999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기도 광주군 퇴촌면과 남종면의 경계에 솟은 해협산은 북으로 정암산(403m)과 한강을 끼고, 남쪽의 관산(555m), 양자산(704m)과 함께 나지막한 산이다. 비록 산은 작으나 산세가 험하지 않고 강과 연접해 있어 가족단위 산행과 물놀이를 즐기기 적당한 곳이다.천지개벽 당시에 온 천지가 물바다가 되어 많은 사람들이 배를 타고 피난을 하던 중 정상에 있는\"군두바위\"에 말뚝을 박고 배를 잡아매었다 하며 바위가 있는 곳이 골짜기라 하여 해협산이라 불렀다 한다.", - "MNTN_HG_VL" : "531", - "MNTN_LOCPLC_REGION_NM" : "경기도 광주군 퇴촌면, 남종면", - "MNTN_NM" : "해협산" + "DETAIL_INFO_DTCONT" : "계족산은 말 그대로 닭의 발처럼 산줄기가 사방으로 뻗어있다. 대전시 동북쪽에 울타리를 이룬 시민의 산인지라 온 산이 공원화 되어 있다. 등산로만 해도 입구가 20여 군데에 달할 정도다. 산 남서쪽에는 경부고속도로가 시내와 경계를 지으며 산줄기와 나란히 달리고, 그 맞은편인 동쪽 산자락에는 푸른 대청호가 넘실거린다.산 자락에는 각종 유적과 문화재 등이 즐비하다. 들머리인 용화사에는 석불입상, 날머리인 비래사에는 동춘당이 지은 정자인 옥류각, 그 아랫마을인 송촌동에는 동춘당이 있다. 우암 송시열 선생이 학문을 닦고 제자를 가르쳤던 곳에는 우암사적 공원이 들어섰다. 과거와 현재, 미래가 공존하는 도시인 대전답게 계족산 역시 그 모습을 고스란히 반영하고 있다.계족산에는 계족산성이 북에서 남으로 길게 산정을 형성하고 있다. 삼국시대 백제 부흥군이 활동했던 옹산성으로 추정되는 이 성은 둘레만 해도 1037미터로 이 고장 최대의 산성이다. 성벽은 안쪽의 흙을 깎아내고 바깥쪽에만 돌을 쌓는 수법으로 만들어졌다.", + "MNTN_HG_VL" : "424", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 대덕구, 동구", + "MNTN_NM" : "계족산" }, - "longitude" : 127.3559904, - "latitude" : 37.491495200000003 + "longitude" : 127.43934659999999, + "latitude" : 36.385547600000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "치악산 정상인 비로봉에서 남쪽으로 5km 지점에 솟아 있는 향로봉은 강원도 원주시와 횡성군의 경계를 이루는 산으로 교통이 편리하여 당일 산행지로 적합하다. 등산객으로 붐비는 구룡사계곡에 비해 호젓한 산행을 즐길 수 있는 곳이다.원주역에서 산행기점인 행구동까지는 버스로 20분 정도로 가까운 거리인 향로봉을 오른 후, 북쪽 비로봉이나 남쪽 남대봉 등 어느 방향으로나 산행이 가능하다. 치악산 일대의 억새군락은 단연 고둔치를 최고로 친다. 향로봉 남쪽 능선에 위치한 치악평전은 일명 '금두고원'이라고 부르는데, '금두' 라는 말은 억새밭이 햇빛을 받아 금빛 찬란하게 빛나기 때문에 붙여진 이름이다.", - "MNTN_HG_VL" : "579", - "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 행구동, 판부면, 신림면, 횡성군 강림면", - "MNTN_NM" : "향로봉" + "DETAIL_INFO_DTCONT" : "청평사라는 명찰을 품은 오봉산의 남쪽에 자리한 산이다. 북쪽으로 오봉산(779m)과 연결되어 있고, 동쪽으로는 봉화산(736m)과 맞대고 있다. 마적산은 오봉산의 주능선이 서남쪽으로 나가다가 정남 방향으로 꺾이면서 최고봉인 785고지를 만들고 일직선으로 뻗어 내려가면서 크고 작은 여러 개의 봉우리를 일구고 있다. 마적산 산행의 백미라 하면 하산을 하면서 소양호를 감상 할 수 있다는 것이다.능선에는 주로 떡갈나무, 상수리나무 같은 참나무류가 숲을 이루고 있으며 도중에 무수한 칡덩쿨과 드룹나무 군락이 있다. 정상에서는 춘천시와 시가지를 가로지르는 소양강이 눈에 들어온다.", + "MNTN_HG_VL" : "610", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 신북읍, 북산면", + "MNTN_NM" : "마적산" }, - "longitude" : 128.03416669999999, - "latitude" : 37.330833300000002 + "longitude" : 127.79229549999999, + "latitude" : 37.952335800000007 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "574", - "MNTN_LOCPLC_REGION_NM" : "충청남도 계룡시 향한리, 논산시 상월면", - "MNTN_NM" : "향적산" + "MNTN_HG_VL" : "338", + "MNTN_LOCPLC_REGION_NM" : "강원도 속초시", + "MNTN_NM" : "주봉산" }, - "longitude" : 127.20184399999999, - "latitude" : 36.292887800000003 + "longitude" : 128.54221570000001, + "latitude" : 38.172462099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "남북으로 길게 누워 계룡산 천왕봉을 올려다보고 있는 향적산은 동서 양편이 높은 바위벼랑으로 되어 있어 아름답다.백두대간에서 금남호남정맥이 갈라져 나와 계룡산 어림에 다다른 금남정맥이 산태극을 이루며 금강을 따라 서남향으로 돌아 나아간다. 여기서 계룡산은 손가락으로 남쪽을 가리키듯 한 가닥 산줄기를 남으로 뻗친다. 계룡산에서 거의 일직선으로 연산까지 뻗은 이 산줄기의 중간쯤에 향적산이 자리 잡고 있다.이 향적산 줄기의 동서 비탈은 지도의 등고선이 보여주는 것처럼 거의 절벽에 가까운 급경사를 이루고 있다. 이 가운데 향적산 주봉 일대의 서면과 농바위 일대의 동서 양면은 깎아지른 바위벼랑으로 장관을 이루어 경관이 좋다.향적산에서는 계룡산을 바로 턱 밑에서 올려다 볼 수 있고 산줄기 너머로 대전시가지가 보인다. 뿐만 아니라 서대산, 진악산, 대둔산, 덕유산, 운장산, 오서산 등이 보인다.", - "MNTN_HG_VL" : "574", - "MNTN_LOCPLC_REGION_NM" : "충청남도 계룡시 향한리, 논산시 상월면", - "MNTN_NM" : "향적산" + "DETAIL_INFO_DTCONT" : "영동군 학산면과 무주읍에 걸쳐 있는 백하산은 하얀 노을, 하얀 이내라는 뜻으로 노을이 아름다운 산이다. 백하산 줄기는 영동에서 학산을 거쳐 무주로 이어지는 19번 국도와 나란히 뻗쳐있어 차를 타고 가며 계속 그 모습을 올려다 볼 수 있다.백하산은 북쪽에서 보면 그저 거하고 짙푸른 산이지만 산에 들어서면 곳곳에 까마득한 바위 낭떠러지가 많다.동쪽 끝 여의재 남쪽에는 여의 저수지가 있으며 서쪽 끝 압재 북쪽에는 봉황저수지가 있다. 19번 국도가 백하산 아래를 지나 돌아가기 때문에 백하산 산행을 위한 교통은 편리한 편이다.백하산 아래의 안삼마을은 큰 길가 삼정마을의 일부로 산골짜기 안에 있는 삼정이라 해서 안삼이라 한다. 마을 들머리에는 명절 때 풍년과 마을의 무고를 기원하는 도랑제를 모시는 반신 석상이 있다.", + "MNTN_HG_VL" : "634", + "MNTN_LOCPLC_REGION_NM" : "충청북도 영동 학산면,전라북도 무주", + "MNTN_NM" : "백하산" }, - "longitude" : 127.20184399999999, - "latitude" : 36.292887800000003 + "longitude" : 127.6891667, + "latitude" : 36.062777799999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "강화군 내가면 고천리에 위치한 해발 466m의 혈구산은 강화도의 중심에 위치한 산이다. 고려산과 고비고개를 사이에 두고 남북으로 이어져있으나 혈구산이 더 높고 산세도 부드러운 고려산에 비해 뾰족하면서 굴곡이 있어 힘이 넘친다. 고비고개에서 정상에 이르는 능선길은 4개의 봉우리로 이루어져있으며 첫 번째 봉우리를 지나면서 방향이 우측으로 심하게 휘면서 2봉을 만나고 남쪽으로 진행하다 3봉이 된 후 다시 왼쪽으로 휘어지며 4봉인 혈구산 정상부를 만들어 낸다.각 봉우리 오름길은 매우 가파라서 숨이 가쁘지만 봉우리에 올라서면 시원한 조망을 제공해주며 다음 봉우리 사이 안부까지 내리막길이 있어 강약이 조화를 이루는 코스라 할 수 있다. 그러면서도 쉬는 시간을 포함해 2시간밖에 걸리지 않는 짧은 거리여서 가족산행지로도 적격이다. 정상부에 올라서면 사방으로 전망이 트이며 강화도의 전모가 드러난다.", - "MNTN_HG_VL" : "466", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 강화군 내가면 고천리", - "MNTN_NM" : "혈구산" + "DETAIL_INFO_DTCONT" : "크게 화려하거나 요란하지 않지만 그런 대로 쏠쏠하게 볼거리가 있고 전망도 좋은 산이다.해발 500여 미터정도의 나지막한 산이지만 정상에 오르면 멀리 영광쪽 바다에 배가 떠다니는 모습이 보이고 무등산을 물론 광주시내까지도 조명할 수 있는 산이다. 광주에서 거리도 그리 멀지 않아 당일치기로 다녀와도 무리가 없다. 작은 규모에 비해 등산로는 꽤 가파른 편이며 아기자기한 암벽미도 그만이다.", + "MNTN_HG_VL" : "98", + "MNTN_LOCPLC_REGION_NM" : "전라북도 고창군 성송면\/전라남도 장성군 삼계면 부성리", + "MNTN_NM" : "고성산" }, - "longitude" : 126.4405556, - "latitude" : 37.720277799999998 + "longitude" : 126.6333333, + "latitude" : 35.299999999999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "충청북도 단양군 영춘면과 경상북도 영주시 단산면에 걸쳐 있는 형제봉은 동·북 비탈면에서 남한강 지류 남대천이 발원한다. 소백의 남서쪽 끝자락에 이름 그대로 두 봉우리가 우뜩 솟은 형제봉(1,177.5m)은 소벡산 중에서도 찾는 이가 거의 없는 곳이다. 소백산의 주능선과 이어져 있지만 거의 독립된 봉우리라 해도 과언이 아니다.소백산 끝자락에 온화하게 솟은 산. 비로봉에서 북동쪽으로 직선거리 11.5Km 지점에 솟은 형제봉은 이름 그대로 두 봉우리가 사이좋게 솟아 소백의 남서쪽 끝자락에 자리잡고 있다. 죽령에서 시작하여 비로봉을 지나 국망봉에서 내려오면 형제봉을 바로 앞두고 칼바위에서 서쪽으로 백두대간이 갈려나가고 형제봉을 지나 의풍리로 빠져 나오면 총 39km로 소백산의 가장 긴 종주코스에 해당한다.", - "MNTN_HG_VL" : "1115", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 영춘면", - "MNTN_NM" : "형제봉" + "DETAIL_INFO_DTCONT" : "경주 남산은 곧 신라라해도 과언이 아니다. 그만큼 신라 건국에서부터 멸망에 이르는 동안의 수많은 유적과 신라를 지탱해 온 불교유적의 보고이다.신라의 건국설화에 나오는 나정(羅井)에서부터 종말기의 포석정이 남산 기슭에 자리잡았다. 그 사이의 시간 간격이 900년이다.", + "MNTN_HG_VL" : "495", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경주시 남산동ㆍ내남면", + "MNTN_NM" : "남산" }, - "longitude" : 128.56805560000001, - "latitude" : 37.036111099999999 + "longitude" : 129.22555600000001, + "latitude" : 35.768056000000001 }, { "mountain" : { "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "490", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수", - "MNTN_NM" : "호랑산" + "MNTN_HG_VL" : "476", + "MNTN_LOCPLC_REGION_NM" : "전라남도 보성군", + "MNTN_NM" : "봉화산" }, - "longitude" : 127.7008915, - "latitude" : 34.791603500000001 + "longitude" : 127.1086111, + "latitude" : 34.732777800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "245", - "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", - "MNTN_NM" : "호룡곡산" + "DETAIL_INFO_DTCONT" : "조령산은 경북 문경시와 충북 괴산군을 나누는 백두대간 마루능선을 이루는 산의 하나다. 충북과 경북에 걸쳐 있는 이화령과 조령3관문 사이에 위치하고, 산림이 울창하며 대암벽지대가 많아 기암괴봉이 노송과 어울려 한폭의 그림을 보는 것과도 같이 아름답다. 문경새재를 허리춤에 안고 있는 조령산은 산보다 재가 더 유명하다.이화령(큰세재)에는 휴게소와 대형 주차장이 있고, 북쪽 구새재는 조령 제 3관문(조령관)이 있으며 관문 서편에는 조령산 자연 휴양림이 조성되어 있어 여러사람이 찾아와도 부담이 없다. 주능선 상에는 정상 북쪽으로 신선봉과 치마바위봉을 비롯 대소 암봉과 암벽 지대가 많아 산의 웅장한 면모를 느낄 수 있고, 능선 서편으로는 수옥 폭포와 용송골, 절골, 심기골등 아름다운 계곡이 있어 여름철 산행으로 그만이다.", + "MNTN_HG_VL" : "1025", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 연풍면, 경상북도 문경시 문경읍", + "MNTN_NM" : "조령산" }, - "longitude" : 126.4214736, - "latitude" : 37.378381300000001 + "longitude" : 128.04363900000001, + "latitude" : 36.770401 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "인otilde;시 중구 무의도에 있는 호룡곡산은 사계절 바다의 정취를 즐기며 산행을 즐길 수 있는 산이다. 수도권에서 1~2시간이면 닿을 수 있고, 섬 산행과 낙조산행을 즐기기에 제격이다.무의동~호랑바위~신선약수~정상~마당바위~부oacute;바위~환상의길~하나개해수욕장으로 이어지는 등산코스는 2시간이면 누구나 완주할 수 있다. 약 6킬로미터에 달하는 등산코스에는 옹달샘, 약수터, 나무계단 등이 잘 정비되어 있다.정상에서는 용유도, 팔미도, 자월도, 영흥도 등 섬과 바다가 어우러진 풍광이 일품이다. 산행 후 들리게 되는 무의도 서쪽 하나개 해변에서는 동죽, 바지락 등 조개도 잡을 수 있다. 이 해변은 영화 공포의 외인구단 촬영장소였다.호룡곡산 산행의 또 다른 매력은 산릉에 있는 고려바위, 마당바위, 부oacute;바위 등 기암괴석을 감상하는 것이다. ‘서해의 알프스’ 라 불릴 만큼 산세가 수려하다. 생태관찰로, 산림uuml;험로(4km), 전망대 등을 갖춘 삼림욕장도 있다.", - "MNTN_HG_VL" : "245", + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "255", "MNTN_LOCPLC_REGION_NM" : "인천광역시 중구", - "MNTN_NM" : "호룡곡산" + "MNTN_NM" : "백운산" }, - "longitude" : 126.4214736, - "latitude" : 37.378381300000001 + "longitude" : 126.5169444, + "latitude" : 37.493888900000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "북한강변에 자리 잡은 호명산은 한북정맥상의 귀목봉에서 남으로 뻗은 산줄기 끝자락에 있는 산으로 청평댐 뒤로 병풍처럼 솟아 있다. 이 산은 지난 79년 산 위에 양수발전용 저수지인 호명 저수지가 생긴 다음부터 등산객들의 발길이 잦아지는 산이다.‘호랑이가 우는 산’이란 뜻의 호명산은 옛날 산림이 우거지고 사람들의 왕래가 적었을 때 호랑이 울음소리가 많이 들려오곤 했다는 데서 유래되었다. 때문에 범이 우는 마을의 호명리와 범이 입을 벌리고 있는 모습과 흡사하다는 아갈바위봉, 아갈바위골 등 호랑이와 관련된 지명이 산 곳곳에 남아있다. 남쪽으로는 청평호반과 조종천이 지척이며, 북쪽으로는 북한강과 함께 인공댐인 청평 양수발전소가 있는 천지연이 자리 잡고 있다.정상에서는 남으로 화야산 뽀루봉과 용문산이 줄지어 서있고 서북으로는 깃대봉과 축령산, 서리산 등이 조망된다. 북으로 청우산과 대금산 매봉이 뚜렷하게 보이고 명지산, 화악산, 국망봉 등이 파노라마의 장관을 연출하며 산 아래로는 청평호와 북한강, 조종천, 천지연의 물줄기가 반짝인다.", - "MNTN_HG_VL" : "632", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 청평면", - "MNTN_NM" : "호명산" + "DETAIL_INFO_DTCONT" : "부용산(882m)에서 남쪽으로 능선이 뻗어 있는데, 이 능선상에서 가장 높은 봉우리이다. 부용산 외에 오봉산(779m)과도 능선이 이어져 있어, 종주 등반도 가능하다. 산의 북쪽을 제외하고는 소양호로 둘러싸여 있어, 정상에서의 조망이 시원하고 아름답다.청평사 선착장에서 서쪽길은 청평사로 이어지고 동쪽길 따라 작은 고개를 넘어가면 청평골 입구에 농막집이 있다. 농막에서 계곡 왼쪽 길을 따라 올라가서 계곡이 갈라지기 직전에 왼쪽길 따라 들어가면 동굴이 있는 기도터에 닿게 된다. 계곡을 건너서는 조금 가파른 길을 거쳐 하우고개에 이르게 된다. 하우고개 십자로에서 남쪽 길로 들어가면 봉화산에 오르게 되는데 이 길은 사람이 별로 다니지 않는 완만한 능선에 억새와 칡넝쿨이 무성하여 길바닥이 보이지 않는 상태이다.", + "MNTN_HG_VL" : "734", + "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시 북산면", + "MNTN_NM" : "봉화산" }, - "longitude" : 127.4460303, - "latitude" : 37.729328899999999 + "longitude" : 127.8413889, + "latitude" : 37.967222199999988 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "280", - "MNTN_LOCPLC_REGION_NM" : "전라남도 여수시", - "MNTN_NM" : "호암산" + "DETAIL_INFO_DTCONT" : "보문산은 대전시 남쪽 중심부에 근접해 있어 대전시민들에게는 매우 친근한 휴식처이다. 이 산에는 보문산성, 보문사지, 야외음악당, 전망대 유희시설, 케이블카가 있으며 시루봉길 등 10여개의 등산로와 20여개소의 약수터가 있다. 특히, 보문산성은 시 기념물 제 10호로 1991년 12월 백제산성중 최초로 복원되었다.정상에 있는 장대루에 오르면 광활한 대전 시가지의 발전상을 한 눈에 볼 수 있는 곳이다. 본래 이 산은 보물이 많다하여 보물산이라 부르다가 후에 보문산으로 고쳐 부르게 되었다거나, 나무꾼이 죽어가는 물고기를 살려줘서 얻은 '은혜를 갚는 보물주머니'에서 이름이 유래되었다는 전설도 전해진다. 보문산 녹음(綠陰)은 대전팔경의 하나로 꼽힌다.대전광역시의 대표적인 녹음공원이자 도시자연공원으로,사정공원지구에는 스포츠와 피크닉을 위한 넓은 잔디광장과 체육시설 등이 조성되어 있다. 평일 2천명, 성수기에는 1일 평균 2만여명이 즐겨 찾는 4계절 행락지이다.", + "MNTN_HG_VL" : "457", + "MNTN_LOCPLC_REGION_NM" : "대전광역시 중구", + "MNTN_NM" : "보문산" }, - "longitude" : 127.71566850000001, - "latitude" : 34.768495399999999 + "longitude" : 127.42154499999999, + "latitude" : 36.301724 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "930", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군", - "MNTN_NM" : "호음산" + "DETAIL_INFO_DTCONT" : "충북 단양군 어상천면과 영춘면 사이에 솟아있는 삼태산은 마치 삼태기 세 개를 엎어놓은 듯한 산세를 하고 있어 이와 같은 이름이 붙었다. 그러나 서쪽인 대전리나 남쪽인 임현리에서 바라보면 누에가 기어가고 있는 듯한 형상과 흡사하여 누에머리산이라고 불리기도 한다. 삼태산은 단양팔경과 인근 유명산들의 명성에 가려 산악인들에게 그리 잘 알려진 산은 아니다. 일반에게 잘 알려지지 않아 자연이 잘 보존되어 있다.어상천면과 영춘면 사이에 있는 농우재고개가 삼태산과 오기산을 이어주는데, 예로부터 주민들은 하늘 높이 솟아오른 삼태산을 남자산, 산세가 부드러운 오기산은 여자산으로 불러왔으며 두 산이 서로 바라보면서 항상 그리워한다고 여겼다.산허리의 단양팔경 중 2경인 일광굴의 신비한 풍광과, 산 구비구비 계곡 곳곳에 스며있는 애틋하고도 재미난 전설들은, 이 곳을 찾는 사람들의 발길을 즐겁게 해주고 있다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군 어상천면", + "MNTN_NM" : "삼태산" }, - "longitude" : 127.83861109999999, - "latitude" : 35.797499999999999 + "longitude" : 128.37006980000001, + "latitude" : 37.120670199999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "화란봉은 이름 그대로 꽃모양을 하고 있는 산으로 부채살처럼 펼쳐진 화관이 화란봉을 중심으로 겹겹이 에워싼 형상이다.산행기점인 벌마을에는 용수골이 있는데 이곳은 옛날에 이무기가 하늘로 오르다 힘이 부쳐 떨어진 곳이라 한다. 지금도 그때 자국이 용수골 너럭바위에 남아있다.화란봉에선 닭목재가 한눈에 들어온다.화란봉 주위에는 기암괴석과 몇 아름 되는 노송들이 바위 틈새에서 우람하게 자라는 모습을 보면 마치 한 폭의 동양화를 연상하게 된다.", - "MNTN_HG_VL" : "1069", - "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 왕산면", - "MNTN_NM" : "화란봉" + "DETAIL_INFO_DTCONT" : "연인산은 경기도 제2의 고봉 명지산의 남녘 능선을 잇는 산이다. 가평군 제1의 휴양지인 용추계곡 최상류에 자리하고 있다.연인산은 우목봉과 월출산으로 불리어왔으나 가평군이 지명을 공모하여 1999년 3월 ‘사랑이 이루어지는 곳’이란 뜻에서 이 산 이름을 연인산으로 바꾸었다. 그리고 연인산 서남쪽의 전패봉(906봉)은 우정봉, 전패고개는 우정고개, 동남쪽의 879봉은 장수봉으로 고쳤다. 또한 연인산에서 뻗은 각 능선에 우정, 연인, 장수, 청풍 등의 이름을 붙였다.연인산은 수도권에서 승용차로 2시간 이내 거리이면서 아름다운 비경과 명소들이 많은 산이다. 그중 제일비경은 용추구곡으로 연인산의 발원지이다. 용추구곡은 연인산의 부드럽고 완만한 지능선을 ‘ㄷ자’ 형태로 감싸고 있다. 연인상 정상에 오르면 사방의 조망이 막힘 없이 시원하다.가평군은 1995년 연인산 능선에 철쭉이 자생하는 것이 확인한 후 이곳을 관광지로 보존하기 위하여 1999년 5월 철쭉제를 개최하고 해마다 열고 있다. 연인산 철쭉은 5월 중순경에 만개한다.", + "MNTN_HG_VL" : "1068", + "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 가평읍ㆍ북면ㆍ하면", + "MNTN_NM" : "연인산" }, - "longitude" : 128.78916670000001, - "latitude" : 37.626388899999988 + "longitude" : 127.4186114, + "latitude" : 37.898696600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "화부산은 길안면 대사리와 고란리를 경계로 남북으로 길게 자리잡고 있는 산이다. 비교적 낮은 산이지만 치솟는 경사와 아기자기한 능선, 그리고 촛대바위, 문살바위 등이매우 아름답게 어우러져 있다. 정상부근에는 잡목이 무성하여 어디가 정상인지 분간조차 할 수 없으며 정상에서는조망이 불가능하다.", - "MNTN_HG_VL" : "626", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시 길안면 대사리,고란리", - "MNTN_NM" : "화부산" + "DETAIL_INFO_DTCONT" : "계방서정맥(桂芳西正脈)이라 불리는 산줄기 도미(掉尾)를 장식하며, 경기의 곡창지대인 여주 들녁에 우뚝 서 한 바다에 고래 등처럼 떠 있는 이산은 '고달산(高達山)'으로 불리기도 하며, 예로부터 고려장을 하던 '고려산'으로 불리었다.서남쪽으로 위치한 우두산(牛頭山) 남쪽에 사적 제382호로 지정된 '고달사지(高達寺址)'라는 사적지를 가지고 있으며, 금동마을 뒤쪽으로는 고려장 굴이 있어 옛 고려장 관습에 흔적을 가지고 있는 산이다.산세는 육산으로 가파른 경사를 이루고 있으며, 지제면 대평리쪽은 골프장 개발공사로 자연이 훼손되고 등산로가 없어졌으므로 여주 북내면쪽으로만 산행이 가능하다. 고달사지는 국보 제4호로 지정된 고달사부도를 위시해, 보물 3점, 향토유적지등이 있어, 산행과 문화재 탐방을 함께 할 수 있는 산이다.", + "MNTN_HG_VL" : "543", + "MNTN_LOCPLC_REGION_NM" : "경기도 여주군 북내면, 양평군 지제면", + "MNTN_NM" : "고래산" }, - "longitude" : 128.9526189, - "latitude" : 36.387769600000013 + "longitude" : 127.658602, + "latitude" : 37.417704200000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "화악산은 경북 청도군 경남 밀양시의 도경계를 이루고 있다. 비슬산에서 남쪽으로 이어져 한 줄기는 창녕 화왕산으로 갈라지고, 화악산을 지나 철마산으로 뻗어내려 물길을 만나면서 멈춘다.화악산은 부드러운 육산과 곳곳에 바윗길을 드러낸 골산이 합쳐진 형태의 산으로 청도에서 손꼽을 만큼 아름다운 산이다. 정상은 세 봉우리가 주봉을 중심으로 나란히 솟아 있고 그 등성이가 황소의 등을 방불케 하며, 두 봉우리의 중간쯤에서 남쪽으로 또 한 봉우리가 솟아 있는데 이를 속칭 작은 화악산이라고 한다.화악이란 이름은 정상의 세개 봉우리 형상이 중국 오악의 하나인 서악, 즉 화악의 삼봉과 비슷하다고 하여 붙여진 것이다. 또 산의 생김새가 덕성스러워 덕기에 둔취되어 있다는 뜻에서 둔덕산이라고도 한다. 화악산은 영남알프스까지 이어지는 만만찮은 높이에 시원스런 조망과 아기자기한 암릉 그리고 봄철에는 철쭉이 피어 가족산행지로 적합하다.", - "MNTN_HG_VL" : "932", - "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군 청도읍ㆍ경상남도 밀양시 청도면", - "MNTN_NM" : "화악산" + "DETAIL_INFO_DTCONT" : "치악산 국립공원의 최고봉인 비로봉(1,288m)에서 남쪽 치악재 방향으로 뻗어 내린 능선 상에 우뚝 솟은 남대봉은 강원도 원주시 판부면과 신림면의 경계를 이루는 산이다.남대봉에서는 상원사, 영원사 등 치악산의 이름난 절 3개곳중 둘이 보이고 절이 있는 상원골과 영원골등 2개의 긴 계곡도 보인다. 둘다 구룡사가 있는구룡계곡에 못지 않는 계곡이다. 또한 4계절마다 그 모습을 달리하며 호젓한 등산로 때문에 많은 산악인과 관광객의 발길이 끊이지 않고 있다.정상 동남쪽 아래에 있는 상원사 대웅전 앞에는 꿩과 구렁이의 보은의 전설을 간직한 삼층석탑 2기가 눈길을 끈다. 정상에 서면 북쪽으로 고둔치와 치악산맥의 연릉과 치악산 정상인 비로봉이 아스라히 보인다.", + "MNTN_HG_VL" : "1182", + "MNTN_LOCPLC_REGION_NM" : "강원도 원주시 판부면, 신림면", + "MNTN_NM" : "남대봉" }, - "longitude" : 128.69147169999999, - "latitude" : 35.593220600000002 + "longitude" : 128.0519444, + "latitude" : 37.308333300000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "경기 5악 중의 으뜸인 화악산(1,468m)은 강원도와 경기도를 가르는 분기점에 우뚝 솟아 있는 산이다. 경기도의 최고봉이다. 화악산을 중심으로 동쪽에 매봉, 서쪽에 중봉이 위치하며 이들을 삼형제봉이라고도 한다. 여기서 발원하는 물은 화악천을 이루며 가평천의 주천이 되어 북한강으로 흘러든다.정상 주변은 군사지역으로 출입이 금지되어 있어 가까운 곳에서 보는 것으로 만족해야 하는 점이 아쉽다. 지금은 정상 서남쪽 1km 거리에 있는 중봉 산행으로 화악산 정상을 대신하고 있다. 화악산 주능선에 오르면 가평, 춘천 일원을 굽어볼 수 있어 산행의 재미를 더해 준다.", - "MNTN_HG_VL" : "1468", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 북면, 강원도 화천군 사내면", - "MNTN_NM" : "화악산(중봉)" + "DETAIL_INFO_DTCONT" : "서울시 서초구 양재동과 경기도 과천, 의왕, 성남시에 걸치고 있으며 서울 주변에서 숲과 계곡, 절, 공원 등을 한꺼번에 만날 수 있는 청계산은 청룡이 승천했던 곳이라 과거에는 청룡산으로도 불렸다. 남북으로 흐르는 능선을 중심으로 펼쳐진 산세가 수려하며 숲 또한 울창하고 계곡이 깊고 아늑하다.과천의 서울대공원에서 바라보면 대공원 뒤에 병풍처럼 둘러있으며 바위로 되어 있는 정상인 망경대가 우뚝 솟아 보인다. 정상에 서면 북서쪽으로 펼쳐진 계곡 아래 과천시와 동물원, 식물원이 있는 서울대공원, 각종 놀이기구가 있는 서울랜드, 국립현대미술관, 과천 경마장이 한눈에 내려다보인다.청계사에는 갖가지 명물이 많은데 그중 대표되는 것이 계단길이다. 시민의 손으로 산을 꾸미겠다는 취지로 얼마의 돈을 지불하면 계단 한 칸 마다 사연을 적어 꾸밀 수 있게 했다. 자신들의 소망, 기업이나 가게 홍보, 성경 구절 등으로 계단을 빼곡이 채우고 있어, 계단을 오를 때마다 읽어 가는 재미가 쏠쏠하다. 또 청계산은 역사적으로도 절의 곧은 선비들이 난세를 피해 은거한 충절의 산이라 할 수 있다. 대표적인 인물은 고려의 충신 이색과 조윤, 조선 중기의 김종직의 문하로 활동하던 일두 정여창이다. 망경대, 금수샘, 이수봉 등은 모두 그들과 관계되어 있다.", + "MNTN_HG_VL" : "873", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 서초구 신원동, 경기도 과천시 막계동, 의왕시 청계동, 성남시 수정구", + "MNTN_NM" : "청계산" }, - "longitude" : 127.5031003, - "latitude" : 37.9950197 + "longitude" : 127.0415787, + "latitude" : 37.414165699999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "높이 755m의 화야산은 북한강이 북에서 서쪽으로 감싸고 흘러내리는 가운데 위치해 있다. 산위에서의 전망이 좋고 강물을 내려다보며 산을 오르는 이색적인 기분을 맛 볼 수 있다. 화야산은 가평군 외서면과 양평군 서정면에 걸쳐 있는 해발755m의 산으로 북한강이 산 북쪽으로 청평호를 이루면서 감싸고 돌아 남쪽으로 행해 나란히 흘러나가는 가운데 있으므로 산행중에 내려다 보이는 경치가 아름답다.청평에서 멀지않은곳에 있으므로 접근이 용이하고 정상 북쪽끝에 위치한 뾰루봉(709m)과 서쪽능선위에 일구어진 고동산(600m)이 모두 화야산에 딸린 봉우리라 할수 있다. 동서로 갈라져 내려간 능선에는 수림이 울창하고 계곡이깊어서 어느때 찾아도 만족한 산행을 할수 있다. 산행에 있어서 어느코스를 택하건 4시간 이상 소요되므로 만만히 보아서는 않된다.또 겨울철에는 적설량이 많아 겨울산행의 맛을 제 대로 느껴 볼수 있는 산이기도 하다. 북쪽의 청평 호반과 서쪽 큰골 또한 대성리 유원지와 함께 여름철 피서지로서 유명하다. 주능성에 올라서면 강물을 끼고 산행하는 기분이 좋다.", - "MNTN_HG_VL" : "755", - "MNTN_LOCPLC_REGION_NM" : "경기도 가평군 설악면, 외서면", - "MNTN_NM" : "화야산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "231", + "MNTN_LOCPLC_REGION_NM" : "인천광역시 옹진군", + "MNTN_NM" : "비조봉" }, - "longitude" : 127.4279782, - "latitude" : 37.671530099999998 + "longitude" : 126.1304785, + "latitude" : 37.219784599999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "장흥과 가깝고 험한 능선이 있어 전란의 소용돌이에 끊임없이 휘말려들었던 화학산은 오르다보면 실제로는 그리 험하지 않다. 나무도 거의 잡목이고 육산인데다가 주능선도 바위지대가 없이 길게 남북으로 늘어져 있다.정상은 좁은 데다가 꺽다리 억새들이 무성해서 주위경관을 감상하기는 쉽지 않다. 하지만 남쪽으로 조금 내려와 헬기장에 서면 천태산과 금성산, 용암산과 국사봉을 모두 볼 수 있다.", - "MNTN_HG_VL" : "614", - "MNTN_LOCPLC_REGION_NM" : "전라남도 화순군 청풍면, 도암면", - "MNTN_NM" : "화학산" + "DETAIL_INFO_DTCONT" : "두산동과 입압동 경계지역에 있는 강릉시내에서 가장 해발고가 높은 산으로 꼭대기에 옛날 봉화를 올렸던 봉수대가 있었다. 지금은 강릉 봉수대비가 있어 유적의 자취를 찾아 볼수 있다. 월대산은 강릉 사주산의 하나이며 봉 서쪽 낙맥에 일제시대에 일본인들이 한국인의 기를 말살시키기 위해 철주 (쇠말뚝)을 박았던 바위가 있다. 월대산 동쪽 마을은 뻗어내린 산줄기가 곡식을 담는 말처럼 생겼다 하여 말산이라 한다. 남쪽면은 경사가 완만하고 북쪽면은 경사가 급한 편으로 거리가 짧은 편이어서 힘든 코스는 아니다. 정상에 오르는 코스가 여러갈래로 갈라져 있어 모든 코스를 등산하면 운동량이 꽤 많은 코스이다. 조망점에서 강릉시내가 한눈에 들어오는 조망권이 좋은 특징이 있다.", + "MNTN_HG_VL" : "75", + "MNTN_LOCPLC_REGION_NM" : "강원도 강릉시 성덕동", + "MNTN_NM" : "월대산" }, - "longitude" : 126.9208333, - "latitude" : 34.863333300000001 + "longitude" : 128.9252778, + "latitude" : 37.756111099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "환성산은 팔공산과 무학산이 서로 연결되는 중앙산록으로 예부터 이 산의 생김새가 서로 고리를 걸어 당기는 형상이라 해 환성산이라 불렀다. 하양 명산으로 산 아래에는 신라 헌덕왕의 왕자인 심지왕사가 창건했다는 환성사가 있다.안심에서 산행을 시작해 뾰족한 봉우리를 오르면 초래봉이다. 태조 왕건 촬영지로 알려져 많은 등산인들이 찾고 있다. 뒤로는 대구시가지와 금호강 줄기가, 동쪽으로는 카톨릭대학과 하양읍내가 보인다. 초래봉은 바위로 이루어져있는데 정상표석은 대안산악회에서 설치했다. 이 산은 고려 태조 왕건이 후백제 견훤이 패하여 이곳에 이르렀다가 후에 여기서 제를 올렸다는 이야기가 전한다.정상을 지나면 불굴사에 닿는다. 경내에는 갓바위약사여래불과 동시대 것으로 추정되는 약사여래입상과 보물 429호인 불굴사 삼층석탑이 있다. 불굴사 주방 뒤로 가면 절벽 위에 자연석굴이 있는데 지금은 홍주암이라는 암자로 쓰인다. ‘불굴’, ‘원효굴’, ‘관음굴’로도 불리며 굴 속에 ‘아동제일약수(我東第一藥水)’가 있다. 원효굴은 김유신 장군이 이 물을 마시면서 삼국통일의 염원을 기도했던 장소로도 알려져 있다.", - "MNTN_HG_VL" : "811", - "MNTN_LOCPLC_REGION_NM" : "대구시 동구, 경북 경산시 하양읍ㆍ와촌읍", - "MNTN_NM" : "환성산" + "DETAIL_INFO_DTCONT" : "오대산에서 시작되는 백두대간의 줄기가 운두령을 넘어 서진하다가 1212m봉에서 남서쪽으로 가지를 친 능선위에 솟아 있는 산이 흥정산이다. 흥정산의 전체 산새는 육산이고, 능선길은 산죽이 깔려 있으며 숲이 앞을 가려 조망은 좋지 않은 편이다.흥정산 골짜기 계곡주변은 이름모를 잡목, 단풍나무, 물푸레나무, 싸리나무, 두릅나무 등 울창한 수림지대를 이루고 냉수성어류 인 열목어와 송어 등이 다량 서식하고 있으며, 기암괴석과 울창한 숲속으로 조화롭게 이루어진 게곡이다.", + "MNTN_HG_VL" : "1279", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면 흥정리", + "MNTN_NM" : "흥정산" }, - "longitude" : 128.74083329999999, - "latitude" : 35.936944400000002 + "longitude" : 128.31444440000001, + "latitude" : 37.676944399999996 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "환희산은 진천군 문백면과 충청남도 천안군 동면을 경계로 위치해 있다. 환희산이란 이름은 말그대로 기쁨을 안겨주는 산이라는 뜻에서 그렇게 불려진다.야트막한 산을 산책 삼아 오르내리며 환희산이 안겨주는 기쁨으로 몸도 마음도 건강해질 수 있을 것이다. 환희산은 등산시간이 짧아 등산으로 인한 피로감은 전혀 느껴지지 않는다. 삼림욕을 하듯 천천히 산을 즐긴다면 맑은 공기가 가슴을 탁 트이게 한다.", - "MNTN_HG_VL" : "402", - "MNTN_LOCPLC_REGION_NM" : "충청북도 진천군 문백면 봉죽리", - "MNTN_NM" : "환희산" + "DETAIL_INFO_DTCONT" : "주월산은 괴산의 명산 중 가장 짧은 코스이다. 산행에 필요한 시간은 불과 1시간 정도면 충분하기 때문이다. 그렇다고 볼거리가 없다거나 시시한 산은 절대 아니다. 느릅재 정상에서 충주 쪽으로 19번 국도를 따라 가면서 가까이 보이는 까닭에 누구든 빼어난 산의 모습에 취하면 쉽게 내려오지 못하는 산이기도 하다.바위능선이 병풍처럼 둘러쳐져 있어 산세가 빼어나고 정상에 오르면 남쪽으로 박달산을 비롯한 여러 산이 보인다. 주변에 공림사와 망개나무자생지·수안보온천 등의 명소가 있다.산행은 감나무골에서 시작한다. 능선을 타고 5분 오르면 작은 봉우리가 나오는데 이곳에서 서쪽으로 이담저수지와 마을이 보인다. 동쪽으로 10분 정도 올라가 첫번째 바위봉우리를 지나면 정상이다. 두 봉우리 주위는 마치 성곽처럼 평평한 바위로 둘러싸여 있고 그 모습이 절구의 확돌처럼 보인다 하여 산 아랫마을을 화학골이라 부르기도 한다.", + "MNTN_HG_VL" : "470", + "MNTN_LOCPLC_REGION_NM" : "충청북도 괴산군 장연면", + "MNTN_NM" : "주월산" }, - "longitude" : 127.402422, - "latitude" : 36.800996699999999 + "longitude" : 127.9037335, + "latitude" : 36.849944299999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "합천호 푸른물속에 산자락을 담그고 하봉, 중봉, 상봉 등 세 봉우리로 정상을 이루어 수중매로 불리는 황매산(1,108m)은 합천읍에서 서남쪽으로 20km 지점에 위치해 있다.산아래의 황매 평전은 목장 지대와 고산 철쭉 자생지가 있으며, 통일 신라시대의 고찰인 염암사지(사적 131호)가 있다. 황매산은 군리 공원으로 1983년 지정되어, 가회면 둔내리에서 영암사지에 이르는 등산로를 개설하였다. 대병면 하금리 하금천에는 야영장을 개설하여 합천호와 이 지역을 찾는 관광객의 편의를 도모하고 있다.", - "MNTN_HG_VL" : "1113", - "MNTN_LOCPLC_REGION_NM" : "경상남도 합천군 대병면, 가회면, 산청군 차황면.", - "MNTN_NM" : "황매산" + "DETAIL_INFO_DTCONT" : "강원도 평창군과 영월군에 걸쳐 있는 절개산은 아직 일반인들에게는 덜 알려진 곳으로 산행의 발걸음이 잦지않다. 에머랄드빛 평창강이 휘감아도는 청정지역으로 산세 또한 깨끗함을 자랑한다. 정상에 노송한그루가 자리하고 있어 절개산의 최고지임을 증명한다. 동남쪽으로 영월 봉래산과 태화산등이 조망되고 날씨가 좋은 날은 멀리 소백산까지도 시야에 들어온다. 호젖한 오르막길과 갖가지 산나물이 지천으로 생명력을 자랑하는 능선길을 걷다보면 시원한 강바람이 내내 산행길을 함께 했음을 느낄 수 있다.절개산은 이름 그대로 신념이나 신의를 굽힘이 없고 변하지 않는 절개를 대표하는 산이다. 이 산 서쪽 평창강이 에돌아 깎아 세운 뼝대 위에 관굴과 민굴이라 하는 응암동굴이 있다. 임진왜란 때 여기에 배수진을 치고, 권두문 군수는 휘하 장졸, 백성들과 함께 단기 3925년, 서기 1592년 8월7일부터 5일간 응암동굴을 본부로 삼아 왜적과 혈전을 벌였던 유적지다. 또한 군수의 부인 강소사는 왜병의 포로가 될 때 절벽에서 투신, 초개와 같이 목숨을 버려 절개를 지켰다.", + "MNTN_HG_VL" : "876", + "MNTN_LOCPLC_REGION_NM" : "강원도 평창군, 영월군", + "MNTN_NM" : "절개산" }, - "longitude" : 127.9744444, - "latitude" : 35.495833300000001 + "longitude" : 128.40283840000001, + "latitude" : 37.324562800000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황병산은 높이 1,407m의 명산으로 청학동 소금강의 절경을 끼고 구룡폭포, 만물상, 금강사, 십자소 등 수많은 명승 고적을 품고 있다.75년 오대산이 국립공원으로 지정되면서 황병산 또한 국립공원으로 편입됐지만, 사람들 사이에서는 잘 알려지지 않은 편이다. 잘 알려지지 않은 까닭에 황병산은 자연 그대로의 아름다움을 간직할 수 있었다. 골골이 깊은 산중의 계곡 하며, 희귀식물, 원시림 등은 황병산의 또 다른 자랑이다.육산이라 산행도 수월한 편이며 부드러운 흙을 밟으며 산행 할 수 있어 좋다. 특히 여름이면 계곡을 끼고 가는 코스가 인기다. 정상은 입산금지 구역이다.", - "MNTN_HG_VL" : "1407", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 도암면 병내리", - "MNTN_NM" : "황병산" + "DETAIL_INFO_DTCONT" : "백두대간이 동로면 벌재를 지나 대미산을 빚어놓고 대미산 정상에 못 미친 1,045m고지에서 북으로 한줄기 뻗어 문수봉을 솟아 놓았다. 충북 제천시 덕산면과 경북 문경시 동로면의 경계를 이룬 문수봉은 월악산 국립공원에 속해 있으며 육산으로 이루어져 있어 등반하기 수월한 산이다. 폭포, 탕, 소 등이 사방 곳곳에 흩어져 있어 여름철 가족 피서지로 적합한 이 산의 자랑은 단연 용하구곡이다. 용하구곡이란 이름 자체가 `여름을 갖고 논다'는 뜻에서 비롯된만큼 더위를 씻어내는 야영지로서의 조건을 다 갖추고 있다.옛날 시인 묵객들이 시문을 겨뤘던 청벽대에서부터 선미대, 가학정, 석운대, 수룡대, 우화굴,세심폭, 활래담 마지막 9경인 강서대에 이르기까지 편편한 반석과 깨끗한 물줄기가 절경을 이룬다. 능선 안부에서 곰취, 취나물, 신선초 등 무공해 산나물을 채취하는 재미도 솔솔하며 봄에는 능선안부께에 철쭉나무 군락이 터널을 이루어 산행의 묘미를 더해준다.", + "MNTN_HG_VL" : "1517", + "MNTN_LOCPLC_REGION_NM" : "충청북도 제천시, 경상북도 문경시", + "MNTN_NM" : "문수봉" }, - "longitude" : 128.66333330000001, - "latitude" : 37.7577778 + "longitude" : 128.21333329999999, + "latitude" : 36.850277800000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황석산이 위치해 있는 함양은 '썩은 갈치가 다 모이는 곳' 이라 할만큼 상대적으로 교통이 불편한 곳으로 사람의 발길을 덜 타는 오지이다. 그래서 이 산은 손때 묻지 않은 자연미를 그대로 보존하고 있는 곳이다.황석산 정상부로 가는 길은 억새능선이 장관을 이루고 정상부에 이르면 쌍립한 암봉의 멋스러움이 등산의 피로를 어루만져준다. 인접한 거망산 종주길도 경관이 일품인데 그 사이사이에 위험한 암릉길이 있으므로 20m정도의 보조자일을 준비하는 것이 안전하다.", - "MNTN_HG_VL" : "1193", - "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", - "MNTN_NM" : "황석산" + "DETAIL_INFO_DTCONT" : "백운봉은 양평읍에서 북동쪽으로 약 10km 떨어진 용문산 남쪽끝의 바위 봉우리이다. 높이가 940m로 주변의 용문산, 도일봉, 중원산 등과 함께 경기도 안에서는 비교적 높은 산으로 알려져 있으며 함왕봉과 능선으로 이어져 있다. 서쪽에는 함왕골, 동쪽에는 연수리계곡이 있으며 정상과 주능선에는 암봉이 많다. 함왕골에는 923년(경명왕 7)에 승려 대경이 창건한 사나사(舍那寺)가 있으며, 3층석탑, 대적광전, 원증국사비, 부도 등이 있다.능선은 골이 깊고 다향하여 매혹적이고 사적지가 많다. 잘 알려지지 않아 오염이 덜 되어 있고 호젓한 산행을 즐길 수 있다. 겨울철 하산길에 즐길 수 있는 자연 눈썰매코스가 매력적이다. 정상에서 남북으로 이은 주능선과 지능선마다 소나무와 암봉들이 조화를 이루고 있고 높은 암봉으로 이루어져 있으며, 앞이 탁 트이고 멀리 운악산, 용문산이 보이며 남쪽으로는 남한강 줄기가 보인다. 능선에는 철쭉, 단풍나무, 고목들이 우거져 있고 비좁고 험한 급경사길이 있다.", + "MNTN_HG_VL" : "936", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평군 양평읍, 옥천면, 용문면", + "MNTN_NM" : "백운봉" }, - "longitude" : 127.7574192, - "latitude" : 35.656779499999999 + "longitude" : 127.52611109999999, + "latitude" : 37.533611100000002 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황악산은 김천시에서 서쪽으로 12km 떨어진 곳에 위치한 산이다.옛부터 학이 많이 찾아와 황학산이라 불리었으나, 직지사의 현판 및 택리지에 황악산으로 되어있다. 울창한 소나무 숲과 깊은 계곡에 옥같이 맑은 물, 가을의 단풍과 겨울의 설화가 아름답다. 일대는 국민관광지로 지정되어 더욱 개발되고 있다.전체적인 산세는 특징없이 완만한 편이나 온 산에 수림이 울창하고 산 동쪽으로 흘러내리는 계곡은 곳곳에 폭포와 소를 이뤄 그윽한 계곡미를 이루고 있다. 특히 직지사 서쪽200m 지점에 있는 천룡대에서부터 펼쳐지는 능여계곡은 이산의 대표적인 계곡으로 봄철에는 진달래, 벚꽃, 산목련이 볼만하고 가을철 단풍 또한 절경을 이룬다.황악산 정상에서 직지사를 내려다 보면 무수한 지능선이 하나씩 계곡안에서 소멸된 뒤 마지막 남은 두가닥 능선이 좌우에서 직지사를 크게 싸안으면서 산과 절의 화합은 완성된다. 1111m에 이르는 황악산의 높은 봉우리와 그 아래 학의 날개처럼 펼쳐지는 계곡이 좁은 수로를 통하여 동으로 빠져나가고 그 길목에 직지사는 자리잡고 있는 것이다.직지사는 어떻게 보면 황악산 정기가 맺은 전혀 다른 종류의 꽃봉오리 같아 보인다. 직지사는 새로 세운 대형 일주문에 동국제일가람이라는 커다란 편액을 붙여놓은 대로 국중의 사찰 가운데서도 열손가락에 들만한 거찰이다.", - "MNTN_HG_VL" : "1111", - "MNTN_LOCPLC_REGION_NM" : "경상북도 김천시 대항면 운수리", - "MNTN_NM" : "황악산" + "DETAIL_INFO_DTCONT" : "순창군과 담양군의 경계를 이루며 강천산(584m)과 형제처럼 솟아있는 산성산은 비록 그 높이는 낮지만 공룡등처럼 이어져있는 능선길을 따라 곳곳에 널린 유적과 절경을 감상하는 것만으로 산행의 즐거움을 충분히 챙겨갈 수 있는 그런 산이다. 이 산에 축조된 산성 때문에 산성산이라 이름 붙여졌다 하며, 일명 금성산이라고 불리는데 이는 금성면에 위치해 있기 때문이다.산성산은 해발 600m에 가까운 철마봉의 절벽에서 시작된, 연대봉, 운대봉, 시리봉 등 사방 계곡의 능선을 이용하여 축조한\"\"금성산성\"\"으로서 강천산 줄기가 서남으로 뻗어 담양군과 순창군의 경계를 이루고 각 봉우리마다 웅장한 암봉으로 이루어져 있다. 철마봉에서 서쪽으로 조망되는 담양호, 추워란의 위용 석양의 노을진 경관이 볼 만하다.", + "MNTN_HG_VL" : "603", + "MNTN_LOCPLC_REGION_NM" : "전라북도 순창군, 전라남도 담양군", + "MNTN_NM" : "산성산" }, - "longitude" : 127.966111, - "latitude" : 36.119166999999997 + "longitude" : 127.0391056, + "latitude" : 35.379716700000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "백두대간의 한 뼈대를 이루며 높이 솟아있는 이 산은 이름이 여럿 있다. 황정산(黃庭山)이라고도 하고 작성산(鵲城山), 또는 황장봉산 등으로 표기되고 있으나 황장목이 많아 황장산으로 통칭되고 있다.소나무의 한 종류인 황장목은 균열이 적고 단단해 임금의 관(棺)이나 대궐을 만드는데 많이 쓰인 귀한 나무이다. 이 때문에 조선조 숙종 때인 1680년에 이 산에서의 벌목과 개간을 금지하는 봉산(封山) 표석이 동로면 명전리 벌천계곡 하류에 세워졌다. 또 산 깊숙한 문안골 계곡에는 우람한 석문이 있는 작성산성이 있는데 축조방식으로 보아 고구려 시대 것으로 추정된다. 산 아래 금천에는 버들치 등 1급수 어류가 살고 있다.", - "MNTN_HG_VL" : "1079", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 동로면", - "MNTN_NM" : "황장산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "329", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시", + "MNTN_NM" : "명덕산" }, - "longitude" : 128.27611099999999, - "latitude" : 36.813056000000003 + "longitude" : 127.1847222, + "latitude" : 36.426944399999996 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황적봉은 계룡산의 봉우리중 하나이다. 계룡산은 충청남도 공주군과 논산군에 걸쳐있으며 주봉인 천왕봉(845m)아래로 쌀개봉(828m), 황적봉(664m),수창봉(662m) 도덕봉(524m)등 거대한 산혼을 횡성하고 산세는 대체로 경사가 완만한 편이며 정상 부근은 경사가 급하다. 이들 봉우리 사이에는 7개의 계곡과 3개의 폭포가 있어 운치를 더해주며, 골짜기에는 동학사갑사신원사 그리고 구룡사의 대가람을 배치한 불교의 명지이며, 다양한 식, 생물분포의 학술적 자원이 풍부하며 자연경관이 빼어난 국립공원으로 이름이 높다.출입이 금지되어 있는 황적봉-쌀개봉 능선은 계룡산 산행의 또 하나의 모험이자, 신선한 충격이다. 황적봉-쌀개봉능선을 잇는 산행은 때로는 한가할 정도로 평탄한 산행길이지만 변화 많은 봉우리로 점철 돼 있어 잔재미가 많으며 때로는 위험한 바윗길이 숨어있는 호방한 산행의 기분도 만끽할 수 있는 아름다운 코스이다. 특히 쌀개능선의 호방한 바위암릉위에서 바라보는 연천봉에서 관음봉을 거쳐 자연성능, 삼불봉으로 이어지는 이 산의 이른바\"\"주코스\"\"의 능선과 봉우리들을 바라보는 경관은 전혀 다른 매력으로 다가온다.", - "MNTN_HG_VL" : "664", - "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 반포면, 논산시 두마", - "MNTN_NM" : "황적봉" + "DETAIL_INFO_DTCONT" : "동쪽으로 용문산과 북쪽으로 중미산을 건너다보고 있으며 남서쪽으로는 남한강이 유유히 흘러나가고 있다. 교통이 그렇게 나쁜편은 않은데도 그냥 지나쳐 버리기 쉬운 산중 하나이다. 목왕리 못 미쳐에는 조선중엽의 문신인 한음 이덕형 선생의 묘와 신도비가 있어 산행길에 들러봄직 하고 정상에 서면 북한강과 발아래 펼쳐지고 두물머리인 양수리 일대가 잡힐 듯 내려다 보인다.양평에 위치한 이 청계산은 수도권 일대의 세 개의 청계산 중 가장 알려지지 않은 산이다. 호젓한 산행을 즐기고 싶다면 한 번쯤 찾아 볼 만하다.", + "MNTN_HG_VL" : "849", + "MNTN_LOCPLC_REGION_NM" : "경기도 양평 서종면, 양서면", + "MNTN_NM" : "청계산" }, - "longitude" : 127.2319444, - "latitude" : 36.348611099999999 + "longitude" : 127.4027778, + "latitude" : 37.553611099999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "황정산은 충북 단양군 대강면에 위치한 산으로, 도로를 사이에 두고 유명한 도락산과 마주보고 있다. 백두대간이 소백산을 지나 죽령에서 가라앉았다가 남쪽으로 다시 치솟으며 도솔봉(1,314m)과 묘적봉(1,148m)을 빚어낸다.백두대간이 묘적봉에서 서쪽으로 방향을 틀어 황장봉산(1,077m)으로 뻗어나가기 직전인 저수재와 벌재 사이 1,076m봉에서 북으로 가지를 쳐 나간 지능선은 1,080m봉과 수리봉(1,019m)을 일으키고 이어서 빚어 놓은 것이 황정산이다. 황정산을 일으킨 능선은 서북쪽으로 방향을 틀어 직치에서 가라앉았다가 다시 고도를 높이며 도락산(964m)을 빚어 놓고 북으로 금수산을 향하여 뻗어 나간 능선이 덕절산(780m)과 두악산(732m)을 마지막으로 빚어놓고 그 여맥을 충주호에 가라앉힌다.이 산에는 천년고찰인 원통암(圓通庵)을 비롯해서 기암괴석으로 이루어진 신단양8경의 하나인 칠성암,남근석,모자(母子)바위, 손가락바위, 누에바위 등 볼거리가 산 곳곳에 널려있다. 황정산 북동쪽 산자락에 자리잡은 원통암은 고려 공민왕(1351-1374)때 나옹화상이 개창했다고 전해진다. 원통암 옆에는 대석 높이 7m 위에 높이 15m의 7개 암석이 있다. 4개의 수직 균열이 있어 부처님 손바닥을 닮았다는 칠성암(七星巖)이 있는 꼭대기에는 수령이 3백년은 됨직한 노송이 한 그루 서 있다.", - "MNTN_HG_VL" : "959", - "MNTN_LOCPLC_REGION_NM" : "충청북도 단양군", - "MNTN_NM" : "황정산" + "DETAIL_INFO_DTCONT" : "수원시의 서쪽에 있는 산으로 수원시와 화성군의 경계지점을 이루고 있으며 예로부터 일곱 가지 보물 (산삼, 맷돌, 잣나무, 황계수닭, 절, 장사, 금)이 많았다고 하여 칠보산이라 한다. 해발 234m로 2개의 등산코스는 완만하고 수림이 울창하여 노약자와 주부들의 산행으로 매우 적당하다.", + "MNTN_HG_VL" : "234", + "MNTN_LOCPLC_REGION_NM" : "경기도 수원, 화성", + "MNTN_NM" : "칠보산" }, - "longitude" : 128.33677549999999, - "latitude" : 36.845008499999999 + "longitude" : 126.9333333, + "latitude" : 37.25 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "769", - "MNTN_LOCPLC_REGION_NM" : "경상북도 안동시", - "MNTN_NM" : "황학산" + "DETAIL_INFO_DTCONT" : "냉산은 구미 해평면, 도개면, 군위군 소보면의 경계에 위치하고 있는 아담한 산으로 잘 알려지지 않은 산이다.낙동강 동쪽에 위치하며, 팔공산맥(八公山脈)에 속한다. 일명 `태조봉(太祖峰)'이라고도 한다. 고려 태조가 견훤을 정벌하기 위해 축성한 숭신산성이 있고, 산 초입에 신라에 불교를 처음 전한 아도화상이 창건한 것으로 전해진 도리사가 유명하다.도리사는 신라에 최초로 불교를 전한 아도화상(阿道和尙)이 세웠다고 전해지며, 경내에 있는 극락전(極樂殿)과 5층석탑(五層石塔)은 보물로 지정되어 있다.", + "MNTN_HG_VL" : "693", + "MNTN_LOCPLC_REGION_NM" : "경상북도 구미시 해평면, 도개리", + "MNTN_NM" : "냉산" }, - "longitude" : 128.87916670000001, - "latitude" : 36.375833299999996 + "longitude" : 128.4007306, + "latitude" : 36.258746899999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "회령봉은 강원도 평창군 봉평면에 위치한 준봉으로써, 육산이며 숲이 울창하고 산록엔 더덕이 많다. 멀지 않은 곳에 솟아 있는 흥정산과 산세와 규모가 비슷한 산이다.산길은 대체로 또렷하나 숲이 짙으므로 길 찾기가 쉽지 않다. 능선엔 진달래와 철쭉나무가 군락을 이룬다.사람들이 거의 찾지 않는 강원도의 오지 산 중의 하나이다.", - "MNTN_HG_VL" : "1309", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면", - "MNTN_NM" : "회령봉" + "DETAIL_INFO_DTCONT" : "주로 군진지와 훈련용으로 많이 쓰이고 있는 구간이다. 경사는 있지만 대부분 완만하므로 일반 등산화로도 충분히 등산이 가능하다. 정상까지 헬기장 두곳이 있으며, 그곳에 올라서면 내설악과 외설악이 한눈에 들어와 장관을 이루어 한폭의 그림을 연상케 한다.", + "MNTN_HG_VL" : "590", + "MNTN_LOCPLC_REGION_NM" : "강원도 인제군 북면 원통리", + "MNTN_NM" : "봉화봉" }, - "longitude" : 128.3663889, - "latitude" : 37.686111099999998 + "longitude" : 128.22194440000001, + "latitude" : 38.138055600000001 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "575", - "MNTN_LOCPLC_REGION_NM" : "강원도 춘천시", - "MNTN_NM" : "후봉" + "DETAIL_INFO_DTCONT" : "강원도 영월군 수주면과 횡성군 안흥면이 경계를 이루는 사자산은 지능인 연화봉 석굴에 많이 있었다는 꿀과 먹을 수 있는 흙인 전단포, 칠기의 도장 재료인 옻나무와 산삼등 네가지 재보가 많이 나기 때문에 일명 사재산(四財山)이라고 불리었다 한다. 일설에는 금.은.동이 많이 채굴되어 그렇게 부른다고도 한다.절골을 사이에 두고 백덕산(1,350m)과 마주한 이산은 남쪽 능선 끝자락으로 그림처럼 수려한 구봉대산(870)을 위시해 곳곳에 기암과 폭포를 가지고 있으며, 골이 깊어 많은 수량과 청정함을 유지하고 있어 고찰 법흥사와 조화를 이룬 산이다. 특히 겨울이면 많은 적설량에다 곳곳에 설화가 만발해 사자산을 찾는 등산객들에게 풍부한 아름다움을 선사한다.또한 등산로 경사가 완만해 가족단위 등산로로는 일품이다. 정상에 서면 가리왕산과 오대산의 산군이 물결치듯 보인다. 남쪽으로는 소백산의 고운 산줄기와 서쪽으로는 치악산맥이 한눈에 들어 온다.", + "MNTN_HG_VL" : "1181", + "MNTN_LOCPLC_REGION_NM" : "강원도 영월군 수주면, 횡성군 안흥면", + "MNTN_NM" : "사자산" }, - "longitude" : 127.8288889, - "latitude" : 37.923333300000003 + "longitude" : 128.2825, + "latitude" : 37.406111099999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "흑석산은 해남과 영암을 남북으로 가르는 산으로 호남정맥이 땅끝으로 가기 전 월출산과 두륜산 사이에 솟아 있다. 인근의 월출산이 남성, 두륜산이 여성의 이미지를 풍기는 산이라면 흑석산은 중후한 중년 신사 같은 산이다.「동국여지승람」에서 가학산(駕鶴山)으로 표기되어 있으나 「대동여지도」에는 가학산과 흑석산(깃대봉)으로 표시되어 있다. ‘가학’은 학이 날지 못하도록 학 앞에 멍에 가를 씌운 풍수지리상 비보(裨補)의 의미를 담고 있다. 또 ‘흑석’은 바위의 색깔이 검어 유래된 것으로 비가 올 때 물을 머금은 흑석산의 모습은 실제로도 검다. 강진 성전면 제전마을에서 올려다 본 산은 ‘밤하늘의 별처럼 아름답다’고 해서 별뫼산으로 불리지만 혹은 별매산으로 종종 혼용되어 표기한다. 해남군이 세운 이정표에는 별뫼산으로 적고 있어 산이란 뜻의 ‘뫼’로 풀이하면 무리가 없을 듯하다.", - "MNTN_HG_VL" : "650", - "MNTN_LOCPLC_REGION_NM" : "전라남도 해남군 계곡면, 학산면", - "MNTN_NM" : "흑석산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1184", + "MNTN_LOCPLC_REGION_NM" : "경상남도 함양군", + "MNTN_NM" : "거망산" }, - "longitude" : 126.633217, - "latitude" : 34.675793599999999 + "longitude" : 127.7369444, + "latitude" : 35.683055600000003 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "", - "MNTN_HG_VL" : "495", - "MNTN_LOCPLC_REGION_NM" : "충청남도 천안시", - "MNTN_NM" : "흑성산" + "DETAIL_INFO_DTCONT" : "금북정맥 구간에 해당", + "MNTN_HG_VL" : "381", + "MNTN_LOCPLC_REGION_NM" : "충청남도 공주시 유구읍, 예산군", + "MNTN_NM" : "장학산" }, - "longitude" : 127.208302, - "latitude" : 36.796827100000002 + "longitude" : 126.88777779999999, + "latitude" : 36.561388899999997 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "오대산에서 시작되는 백두대간의 줄기가 운두령을 넘어 서진하다가 1212m봉에서 남서쪽으로 가지를 친 능선위에 솟아 있는 산이 흥정산이다. 흥정산의 전체 산새는 육산이고, 능선길은 산죽이 깔려 있으며 숲이 앞을 가려 조망은 좋지 않은 편이다.흥정산 골짜기 계곡주변은 이름모를 잡목, 단풍나무, 물푸레나무, 싸리나무, 두릅나무 등 울창한 수림지대를 이루고 냉수성어류 인 열목어와 송어 등이 다량 서식하고 있으며, 기암괴석과 울창한 숲속으로 조화롭게 이루어진 게곡이다.", - "MNTN_HG_VL" : "1279", - "MNTN_LOCPLC_REGION_NM" : "강원도 평창군 봉평면 흥정리", - "MNTN_NM" : "흥정산" + "DETAIL_INFO_DTCONT" : "서울과 경기도 의정부시, 남양주시의 경계에 솟은 그리 높지 않은 산이다. 이 산은 덕릉고개를 사이에 두고 수락산(637.7m)과 마주하며 남북으로 우뚝한, 서울 동북쪽 공원녹지의 근간을 이룬다.불암산 주봉은 그 형상이 마치 송낙(소나무 겨우살이로 만든 여승이 쓰는 모자)을 쓴 부처의 모습과 같다 하여 불암산이라 불리게 되었으며 천보산(天寶山), 필암산(筆岩山) 이라는 이름도 가지고 있다.불암산은 사암으로 된 산이라 수목이 울창하지는 않으나 능선은 기암으로 이어지고 서울 근교의 수많은 등산학교들의 암벽교장으로 애용되기도 한다. 바위로 된 정상에서는 수락산, 도봉산, 북한산을 비롯한 서울과 남양주 쪽 조망이 아주 좋다.불암산 산행 코스 중 수락산과 북한산, 도봉산 능선을 잇는 종주코스가 최근 인기가 높다. 불암산 - 수락산 - 사패산 - 도봉산 - 북한산을 무박 2일로 이어 종주하는 ‘서울 5개산 종주산행’의 첫 출발지로 보통 불암산 자락의 불암동을 잡는다.", + "MNTN_HG_VL" : "510", + "MNTN_LOCPLC_REGION_NM" : "서울특별시 노원구 상계동, 중계동ㆍ경기도 남양주시 별내면", + "MNTN_NM" : "불암산" }, - "longitude" : 128.31444440000001, - "latitude" : 37.676944399999996 + "longitude" : 127.095, + "latitude" : 37.663333299999998 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "희리산은 해발 327미터로 그리 높지 않아 어린 자녀와 함께 삼림욕을 즐기기에 안성맞춤이다. 최고봉인 문수봉에 올라서면 사방이 탁 트여 조망 또한 훌륭하다. 산 전체는 사계절 내내 푸른 해송으로 둘러싸여 있어 언제든지 녹색의 신선함을 느낄 수 있다.희리산은 자연휴양림으로 유명하다. 휴양림의 휴양관은 총 15개실로 대회의실과 소회의실을 갖추고 있어 단체 이용객이 사용하기에 적합하고 숲속의 집은 7개 수종(소나무, 잣나무, 낙엽송, 삼나무, 해송, 층층나무, 참나무)의 판재로 내부 인테리어를 꾸며 특유의 향기를 느낄 수 있다.휴양림의 북서쪽에는 네명의 장사가 놀던 자리라는 사인대가 있고 사인대 밑에는 이 장사들이 턱걸이한 장소라 하여 턱걸이장이라 불리고 있는 140미터 정도의 절벽도 있다.문수봉 밑으로는 이 장사들이 살았다는 큰 산봉우리 4개가 있고 그 아래로 이 장사들의 졸병들이 살았다 하여 이름 붙여진 여러 모양의 작은 졸병바위가 100여 개 정도 있으며 빈대가 너무 많아 절을 헐었다는 문수사 절터도 있어 희리산을 오르는 동안 많은 볼거리를 제공하고 있다.", - "MNTN_HG_VL" : "327", - "MNTN_LOCPLC_REGION_NM" : "충남 서천군 종천면", - "MNTN_NM" : "희리산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "395", + "MNTN_LOCPLC_REGION_NM" : "전라남도 장성군", + "MNTN_NM" : "팔암산" }, - "longitude" : 126.66426149999999, - "latitude" : 36.112400299999997 + "longitude" : 126.82715090000001, + "latitude" : 35.4843118 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "희양산은 충북의 괴산과 경북의 문경에 걸쳐 거대한 하나의 바위덩이로 이루어진 듯 당당한 위세를 뽐내고 있는 산이다. 정상에서 북쪽은 시루봉, 서쪽으로는 구왕봉으로 이어져 나가며 기세를 진정시키지만, 동남서쪽으로 노출된 암장능 곡클라이밍 코스로 다시 없이 좋아 이미 여러개의 코스가 개발되어 있다.병풍처럼 둘러쌓인 거대한 화강암벽은 설악산 울산바위에 필적할 만 하며, 암벽 하단부인 2백여m의 슬랩과 암벽은 위압감을 느끼기에 충분하다. 정상 남쪽 아래 유서깊은 봉암사가 있고, 옥석대와 그 주변 일대에 펼쳐진 옥석계곡의 뛰어난 정경은 등산의 또 다른 맛을 준다.", - "MNTN_HG_VL" : "996", - "MNTN_LOCPLC_REGION_NM" : "경상북도 문경시 가은읍, 충청북도 괴산군 연풍면,", - "MNTN_NM" : "희양산" + "DETAIL_INFO_DTCONT" : "lt;세 성인 상징하는 경산의 대표 산gt;경북 경산은 흔히 삼성현(三聖賢)의 고장으로 불린다. 세 성인, 즉 원효대사와 설총, 삼국유사를 저술한 일연이 태어난 곳이기 때문이다. 이 삼성현을 상징하는 산이 바로 삼성산이다. 경산시 남산면에 위치한 삼성산 가는 길은 대구·경북 일원에서는 물 좋기로 정평이 난 상대온천 가는 길, 상대온천이 산행의 들머리이자 날머리이기 때문이다. 그래서 삼성산은 이곳을 기점으로 온천과 연계한 산행 대상지로 제법 알려져 있다. 산의 높이가 말해주듯 산세는 크지 않은데 정상에서는 남산면과 자인면 일대의 벌판이 보이는 정도다. 그러나 이 산자락에 삼성현의 얼이 서려있는 성지곡, 성제지, 성참사, 불당지 등이 자리하고 있다. 정상 언저리에는 원효가 창건한 성지암이라는 절간이 있었던 것으로 추정되며, 현재는 외면상 그 흔적은 없고 기왓장만 간혹 출토되고 있다고 전한다. 주능선은 북서쪽으로 백화산(486m), 남서쪽으로 청도군 학일산(693m)으로 이어진다. 한편, 경산시는 2012년 완공 목표로 삼성산 진입 길목인 인흥리에 수백억 원을 들여 이른바 ‘삼성현역사문화공원’을 조성 중에 있다. 삼성현의 업적과 정신문화를 계승, 발전시키기고 위한 것으로, 공원이 들어서고 나면 삼성산은 그야말로 경산의 진산으로 거듭날 것이다.", + "MNTN_HG_VL" : "554", + "MNTN_LOCPLC_REGION_NM" : "경상북도 경산시 남산면", + "MNTN_NM" : "삼성산" }, - "longitude" : 128.0027001, - "latitude" : 36.715962300000001 + "longitude" : 128.7943459, + "latitude" : 35.771673499999999 }, { "mountain" : { - "DETAIL_INFO_DTCONT" : "본래 이름은흰돌더미산이다. 흰덤이가 흰대미로 불리기도 하고 희대미로 불리기도 한다. 산 정상에 높이 약 1.5m 둘레 6m 쯤되는 흰 화강암이 놓여있는데 산이름은 여기서 유래되었다고 본다. 정상에서 북쪽으로 2km 거리에 양각산이 있고 더가면 수도산이 있다. 남쪽으로는 회남령과 이어져 보해산과 금귀봉이 자리하고 있고 서쪽으로는 웅양댐이 안겨있고거말산에서 국사봉으로 이어지는 길이 된다.", - "MNTN_HG_VL" : "1018", - "MNTN_LOCPLC_REGION_NM" : "경상남도 거창군 가북면, 웅양면", - "MNTN_NM" : "흰대미산" + "DETAIL_INFO_DTCONT" : "", + "MNTN_HG_VL" : "1013", + "MNTN_LOCPLC_REGION_NM" : "경상북도 청도군", + "MNTN_NM" : "문복산" }, - "longitude" : 127.9561111, - "latitude" : 35.825277799999988 + "longitude" : 129.03833330000001, + "latitude" : 35.679166700000003 } ] \ No newline at end of file From c3438abd7de329dbf7b11250e5942b91e8542a72 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 15 Nov 2021 14:46:45 +0900 Subject: [PATCH 184/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=84=A4=EB=AA=85?= =?UTF-8?q?=20=EC=97=86=EC=9D=84=EC=8B=9C=20=EB=9D=BC=EB=B2=A8=20=EC=88=A8?= =?UTF-8?q?=EA=B9=80,=20=EC=82=B0=20JSON=20=EC=A4=91=EB=B3=B5=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0,=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20padding=20=EC=A6=9D?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailScene/MountainDetailTableViewCell.swift | 5 +++-- .../SanTa/MountainDetailScene/MountainDetailTitleView.swift | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index f82db85..3e59a1c 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -41,13 +41,13 @@ class MountainDetailTableViewCell: UITableViewCell { self.addSubview(contentLabel) let categoryLabelConstraints = [ - categoryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + categoryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), categoryLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20) ] NSLayoutConstraint.activate(categoryLabelConstraints) let contentLabelConstraints = [ - contentLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + contentLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), contentLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10), contentLabel.topAnchor.constraint(equalTo: categoryLabel.bottomAnchor, constant: 10), contentLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) @@ -56,6 +56,7 @@ class MountainDetailTableViewCell: UITableViewCell { } func configure(category: String, content: String) { + categoryLabel.isHidden = content.isEmpty categoryLabel.text = category contentLabel.text = content } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift index 69d1f4e..68cafa7 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift @@ -23,7 +23,6 @@ class MountainDetailTitleView: UIView { self.layer.shadowRadius = 1 self.layer.shadowColor = UIColor.lightGray.cgColor self.layer.shadowOffset = CGSize(width: 0, height: 1) - print("add shadow") } private func layoutTitleView() { @@ -37,13 +36,13 @@ class MountainDetailTitleView: UIView { let titleConstraints = [ titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), - titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20) + titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25) ] NSLayoutConstraint.activate(titleConstraints) let distanceLabelConstraints = [ distanceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), - distanceLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20) + distanceLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25) ] NSLayoutConstraint.activate(distanceLabelConstraints) } From 014993b5fb72fa31e9dcf8963d2c4ee468815575 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 15:31:20 +0900 Subject: [PATCH 185/465] =?UTF-8?q?[Feat]=20#160=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EB=8F=99=EC=9D=98=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?present=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingViewController.swift | 10 ++++++++++ .../RecordingScene/RecordingViewCoordinator.swift | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 9ba7e6f..ee092af 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -100,6 +100,12 @@ class RecordingViewController: UIViewController { self.configureTarget() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + self.presentRecordingPhotoView() + } + private func configureBindings() { self.recordingViewModel?.$currentTime .receive(on: DispatchQueue.main) @@ -136,6 +142,10 @@ class RecordingViewController: UIViewController { self.locationButton.addTarget(self, action: #selector(locationButtonAction), for: .touchUpInside) } + private func presentRecordingPhotoView() { + self.coordinator?.presentRecordingPhotoViewController() + } + @objc private func pauseButtonAction(_ sender: UIResponder) { if currentState { self.view.backgroundColor = .black diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 3528332..6b514b2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -65,4 +65,12 @@ extension RecordingViewCoordinator { recordingTitleViewCoordinator.start() } + + func presentRecordingPhotoViewController() { + let recordingPhotoViewCoordinator = RecordingPhotoViewCoordinator(delegate: self.recordingViewController) + self.childCoordinators.append(recordingPhotoViewCoordinator) + recordingPhotoViewCoordinator.parentCoordinator = self + + recordingPhotoViewCoordinator.start() + } } From 5b0559eb8b2e0ff2e0cb368c61348dbd562b8a8b Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 16:12:44 +0900 Subject: [PATCH 186/465] =?UTF-8?q?[Feat]=20#158=20=EC=A0=9C=EC=96=B4=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index 769318b..71e0a1a 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -22,6 +22,7 @@ class RecordingPhotoViewController: UIViewController { private let recordingPhotoImage: UIImageView = { let image = UIImageView() image.image = UIImage(systemName: "camera.fill") + image.tintColor = .systemBlue image.translatesAutoresizingMaskIntoConstraints = false return image }() @@ -29,7 +30,8 @@ class RecordingPhotoViewController: UIViewController { private let recordingPhotoTitle: UILabel = { let label = UILabel() label.text = "사진 기록하기" - label.font = .preferredFont(forTextStyle: .headline) + label.font = .preferredFont(forTextStyle: .title1) + label.textAlignment = .center label.textColor = .systemGray label.translatesAutoresizingMaskIntoConstraints = false return label @@ -38,7 +40,9 @@ class RecordingPhotoViewController: UIViewController { private let recordingPhotoDescription: UILabel = { let label = UILabel() label.text = "사진을 찍으면 지도에 표시됩니다." - label.font = .preferredFont(forTextStyle: .body) + label.font = .preferredFont(forTextStyle: .title2) + label.numberOfLines = 2 + label.textAlignment = .center label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -56,9 +60,9 @@ class RecordingPhotoViewController: UIViewController { private let photoStackView: UIStackView = { let stackView = UIStackView() - stackView.spacing = 12 + stackView.spacing = 8 stackView.axis = .vertical - stackView.distribution = .fillEqually + stackView.distribution = .fillProportionally stackView.alignment = .center stackView.translatesAutoresizingMaskIntoConstraints = false return stackView @@ -74,7 +78,7 @@ class RecordingPhotoViewController: UIViewController { let frameWidth = view.frame.width let frameHeight = view.frame.height - self.displayView.frame = CGRect(x: 6, y: frameHeight - frameHeight/2, width: frameWidth - 12, height: frameHeight/3) + self.displayView.frame = CGRect(x: 6, y: frameWidth, width: frameWidth - 12, height: frameHeight/2 - 64) [self.recordingPhotoTitle, self.recordingPhotoImage, self.recordingPhotoDescription, self.agreeButton].forEach { self.photoStackView.addArrangedSubview($0) @@ -86,15 +90,16 @@ class RecordingPhotoViewController: UIViewController { let recordingPhotoTitleConstraints = [ self.recordingPhotoTitle.widthAnchor.constraint(equalToConstant: frameWidth - 12) ] - + let recordingPhotoImageConstraints = [ - self.recordingPhotoImage.widthAnchor.constraint(equalToConstant: frameWidth - 12) + self.recordingPhotoImage.widthAnchor.constraint(equalToConstant: frameWidth/3), + self.recordingPhotoImage.heightAnchor.constraint(equalTo: self.recordingPhotoImage.widthAnchor, constant: -16) ] - + let recordingPhotoDescriptionText = [ self.recordingPhotoDescription.widthAnchor.constraint(equalToConstant: frameWidth - 12) ] - + let agreeButtonConstraints = [ self.agreeButton.widthAnchor.constraint(equalToConstant: frameWidth - 12) ] From 17811ab43b95c45d865693a8e24ab23321041b67 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 16:18:55 +0900 Subject: [PATCH 187/465] =?UTF-8?q?[Feat]=20#159=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B6=8C=ED=95=9C=20=ED=97=88=EC=9A=A9=20?= =?UTF-8?q?Delegate=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 11 +++++++++++ .../RecordingScene/RecordingViewController.swift | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index 71e0a1a..d000472 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -31,6 +31,7 @@ class RecordingPhotoViewController: UIViewController { let label = UILabel() label.text = "사진 기록하기" label.font = .preferredFont(forTextStyle: .title1) + label.adjustsFontForContentSizeCategory = true label.textAlignment = .center label.textColor = .systemGray label.translatesAutoresizingMaskIntoConstraints = false @@ -41,6 +42,7 @@ class RecordingPhotoViewController: UIViewController { let label = UILabel() label.text = "사진을 찍으면 지도에 표시됩니다." label.font = .preferredFont(forTextStyle: .title2) + label.adjustsFontForContentSizeCategory = true label.numberOfLines = 2 label.textAlignment = .center label.translatesAutoresizingMaskIntoConstraints = false @@ -72,6 +74,7 @@ class RecordingPhotoViewController: UIViewController { super.viewDidLoad() self.configureConstraints() + self.configureTarget() } private func configureConstraints() { @@ -117,4 +120,12 @@ class RecordingPhotoViewController: UIViewController { NSLayoutConstraint.activate(agreeButtonConstraints) NSLayoutConstraint.activate(titleStackViewConstraints) } + + private func configureTarget() { + self.agreeButton.addTarget(self, action: #selector(agreeButtonAction), for: .touchUpInside) + } + + @objc private func agreeButtonAction(_ sender: UIButton) { + self.delegate?.didAgreeButtonTouchDone() + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index ee092af..b8e3238 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -10,6 +10,7 @@ import Combine protocol RecordingViewDelegate: AnyObject { func didTitleWriteDone(title: String) + func didAgreeButtonTouchDone() } class RecordingViewController: UIViewController { @@ -214,4 +215,8 @@ extension RecordingViewController: RecordingViewDelegate { } } } + + func didAgreeButtonTouchDone() { + + } } From ec4a3f335942884baa5d3a72baf26833a7f77147 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 17:06:02 +0900 Subject: [PATCH 188/465] =?UTF-8?q?[Feat]=20#159=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B6=8C=ED=95=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 1 + .../RecordingViewController.swift | 20 +++++++++++++++---- SanTa/SanTa/Resources/Info.plist | 2 ++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index d000472..eed21eb 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -127,5 +127,6 @@ class RecordingPhotoViewController: UIViewController { @objc private func agreeButtonAction(_ sender: UIButton) { self.delegate?.didAgreeButtonTouchDone() + self.coordinator?.dismiss() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b8e3238..5f7d87a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -7,6 +7,7 @@ import UIKit import Combine +import Photos protocol RecordingViewDelegate: AnyObject { func didTitleWriteDone(title: String) @@ -104,7 +105,7 @@ class RecordingViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - self.presentRecordingPhotoView() + self.configureAlbumPermission() } private func configureBindings() { @@ -143,8 +144,19 @@ class RecordingViewController: UIViewController { self.locationButton.addTarget(self, action: #selector(locationButtonAction), for: .touchUpInside) } - private func presentRecordingPhotoView() { - self.coordinator?.presentRecordingPhotoViewController() + private func configureAlbumPermission() { + let status = PHPhotoLibrary.authorizationStatus(for: .readWrite) + + switch status{ + case .authorized: + break + case .denied: + self.coordinator?.presentRecordingPhotoViewController() + case .restricted, .notDetermined: + self.coordinator?.presentRecordingPhotoViewController() + default: + break + } } @objc private func pauseButtonAction(_ sender: UIResponder) { @@ -217,6 +229,6 @@ extension RecordingViewController: RecordingViewDelegate { } func didAgreeButtonTouchDone() { - + PHPhotoLibrary.requestAuthorization { _ in } } } diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index bf8c508..65bc8e2 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,6 +2,8 @@ + NSPhotoLibraryUsageDescription + 사진 저장을 위해 사진 접근을 허용해주세요. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes From 5c9bf1317e675a2a7c0882db8d0f311e19cac62a Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 15 Nov 2021 17:44:40 +0900 Subject: [PATCH 189/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=84=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 8935e57..3105ac6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -12,8 +12,7 @@ class MountainDetailViewController: UIViewController { weak var coordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? private var mutatingTopConstraint: NSLayoutConstraint? - private var mutatingBottomConstraint: NSLayoutConstraint? - private let maxRollUpDistance: CGFloat = 100 + private let maxRollUpDistance: CGFloat = 50 convenience init(viewModel: MountainDetailViewModel) { self.init() @@ -74,16 +73,14 @@ extension MountainDetailViewController { NSLayoutConstraint.activate(mapConstraints) self.mutatingTopConstraint = titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor) - self.mutatingBottomConstraint = titleView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor) var titleViewConstraints = [ titleView.leftAnchor.constraint(equalTo: headerView.leftAnchor), titleView.rightAnchor.constraint(equalTo: headerView.rightAnchor), + titleView.heightAnchor.constraint(equalToConstant: self.view.bounds.height * 0.07) ] - if let upperConstraint = self.mutatingTopConstraint, - let lowerConstraint = self.mutatingBottomConstraint { + if let upperConstraint = self.mutatingTopConstraint { titleViewConstraints.append(upperConstraint) - titleViewConstraints.append(lowerConstraint) } NSLayoutConstraint.activate(titleViewConstraints) @@ -117,7 +114,15 @@ extension MountainDetailViewController { snapShotter.start { snapShot, error in if let snapShot = snapShot { let mapImage = snapShot.image - + /* + func imageWith(newSize: CGSize) -> UIImage { + let image = UIGraphicsImageRenderer(size: newSize).image { _ in + draw(in: CGRect(origin: .zero, size: newSize)) + } + + return image.withRenderingMode(renderingMode) + } + */ UIGraphicsBeginImageContext(mapImage.size) mapImage.draw(in: CGRect(origin: CGPoint.zero, size: mapImage.size)) UIImage(systemName: "heart.fill")?.draw(at: snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) @@ -137,7 +142,7 @@ extension MountainDetailViewController { private func lowerMountainTitleView(mountainDetail: MountainDetailModel) -> UIView { let titleView = MountainDetailTitleView() titleView.configure(with: mountainDetail.moutainName, distance: mountainDetail.distance) - titleView.backgroundColor = .white + titleView.backgroundColor = .systemBackground return titleView } } @@ -187,11 +192,8 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour extension MountainDetailViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { - let remainingScroll = scrollView.contentSize.height - scrollView.bounds.size.height - let rollUp = min(remainingScroll, self.maxRollUpDistance) - if scrollView.contentOffset.y < rollUp && scrollView.contentOffset.y > 0 { + if scrollView.contentOffset.y > 0 && scrollView.contentOffset.y < self.maxRollUpDistance { self.mutatingTopConstraint?.constant = -scrollView.contentOffset.y - self.mutatingBottomConstraint?.constant = -scrollView.contentOffset.y } } } From e4b127787fc39bb9c3f59f356516a2584bea5926 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 15 Nov 2021 17:55:39 +0900 Subject: [PATCH 190/465] =?UTF-8?q?[Feat]=20=EC=82=B0=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=A7=80=EB=8F=84=EC=97=90=20=EB=A7=88?= =?UTF-8?q?=EC=BB=A4=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailScene/MountainDetailViewController.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 3105ac6..7e814b8 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -123,9 +123,14 @@ extension MountainDetailViewController { return image.withRenderingMode(renderingMode) } */ + UIGraphicsBeginImageContext(CGSize(width: 20, height: 20)) + UIImage(named: "SantaImage")?.draw(in: CGRect(x: 0, y: 0, width: 20, height: 20)) + let markerImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + UIGraphicsBeginImageContext(mapImage.size) mapImage.draw(in: CGRect(origin: CGPoint.zero, size: mapImage.size)) - UIImage(systemName: "heart.fill")?.draw(at: snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) + markerImage?.draw(at: snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() From 7b778002b56e956539a8854a615d8c746c5baa28 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 17:55:51 +0900 Subject: [PATCH 191/465] =?UTF-8?q?[Feat]=20#161=20UseCase=20PhotoModel=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20fetchAssets=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++++ .../RecordingScene/RecordingPhotoModel.swift | 17 +++++++++++++++++ .../SanTa/RecordingScene/RecordingUseCase.swift | 10 +++++++++- .../RecordingViewCoordinator.swift | 3 ++- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a62fcdf..e0d5efa 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; + DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -156,6 +157,7 @@ DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; + DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -184,6 +186,7 @@ 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */, + DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */, 984DDEC427325FB9003BE56B /* RecordRepository.swift */, 984DDEC027325D67003BE56B /* Record.swift */, DAB37D4F273256B900EC523F /* RecordingModel.swift */, @@ -502,6 +505,7 @@ 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, + DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift new file mode 100644 index 0000000..55b2963 --- /dev/null +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -0,0 +1,17 @@ +// +// RecordingPhotoModel.swift +// SanTa +// +// Created by 김민창 on 2021/11/15. +// + +import Foundation +import Photos + +final class RecordingPhotoModel { + + func fetchPhotos() { + let allMedia = PHAsset.fetchAssets(with: .image, options: nil) + print(allMedia) + } +} diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 66b1daf..9be6235 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,18 +11,21 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) + func fetchPhotos() func pause() func resume() } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { var recording: RecordingModel + var recordingPhoto: RecordingPhotoModel private let recordRepository: RecordRepository - init(recordRepository: RecordRepository, recordingModel: RecordingModel) { + init(recordRepository: RecordRepository, recordingModel: RecordingModel, recordingPhoto: RecordingPhotoModel) { self.recordRepository = recordRepository self.recording = recordingModel + self.recordingPhoto = recordingPhoto } func pause() { @@ -39,6 +42,11 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { return } records.configureTitle(title: title) + self.fetchPhotos() // 임시 self.recordRepository.save(records: records, completion: completion) } + + func fetchPhotos() { + self.recordingPhoto.fetchPhotos() + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 6b514b2..1ac80fc 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -27,7 +27,8 @@ class RecordingViewCoordinator: Coordinator { coreDataStorage: self.coreDataStorage ) ), - recordingModel: RecordingModel() + recordingModel: RecordingModel(), + recordingPhoto: RecordingPhotoModel() ) ) ) From c731e7a89cad1a44317882b2a5ccccf1ea16d234 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 18:40:27 +0900 Subject: [PATCH 192/465] =?UTF-8?q?[Feat]=20#161=20UseCase=20Data=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=EA=B0=92=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20fetchPhotos=20=EC=9D=BC=EB=B6=80=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingPhotoModel.swift | 33 +++++++++++++++++-- .../RecordingScene/RecordingUseCase.swift | 14 +++++--- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 55b2963..dc99d53 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -6,12 +6,41 @@ // import Foundation +import UIKit import Photos final class RecordingPhotoModel { - func fetchPhotos() { + private let imageManager = PHImageManager() + private let thumbnailSize = CGSize(width: 1024, height: 1024) + + var representedAssetIdentifier: String? + + func fetchPhotos(startDate: Date, endDate: Date) -> [Date]? { let allMedia = PHAsset.fetchAssets(with: .image, options: nil) - print(allMedia) + + for i in 0.. Void) { + guard let asset = asset, + let date = asset.creationDate else { + completion(nil) + return + } + print(date) + self.representedAssetIdentifier = asset.localIdentifier + +// self.imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, str, orientation, info in +// if self.representedAssetIdentifier == asset.localIdentifier { +// +// } +// }) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 9be6235..8373be7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,7 +11,7 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) - func fetchPhotos() + func fetchPhotos(startDate: Date?, endDate: Date?) -> [Date]? func pause() func resume() } @@ -42,11 +42,17 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { return } records.configureTitle(title: title) - self.fetchPhotos() // 임시 + self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) self.recordRepository.save(records: records, completion: completion) } - func fetchPhotos() { - self.recordingPhoto.fetchPhotos() + func fetchPhotos(startDate: Date?, endDate: Date?) -> [Date]? { + guard let startDate = startDate, + let endDate = endDate else { + return nil + } + + self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) + return nil } } From f3d0c59af9d8d49ed6d1a87288196231607b15a6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 23:15:45 +0900 Subject: [PATCH 193/465] =?UTF-8?q?[Feat]=20#161,=20#162=20Photo=20Struct?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20Fetch=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=9D=BC=EB=B6=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 6 +++++ .../RecordingScene/RecordingPhotoModel.swift | 17 +++++++++----- .../RecordingScene/RecordingUseCase.swift | 23 ++++++++++++------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 30cbcd6..d55803d 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -143,3 +143,9 @@ struct Location { let longitude: Double let altitude: Double } + +struct Photo { + let latitude: Double + let longitude: Double + let date: Date +} diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index dc99d53..14ead6a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -12,23 +12,28 @@ import Photos final class RecordingPhotoModel { private let imageManager = PHImageManager() - private let thumbnailSize = CGSize(width: 1024, height: 1024) var representedAssetIdentifier: String? - func fetchPhotos(startDate: Date, endDate: Date) -> [Date]? { + func fetchPhotos(startDate: Date, endDate: Date, completion: @escaping ([Data]?) -> Void){ let allMedia = PHAsset.fetchAssets(with: .image, options: nil) for i in 0.. Void) { + func requestIamge(with asset: PHAsset?, completion: @escaping (Data?) -> Void) { guard let asset = asset, let date = asset.creationDate else { completion(nil) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 8373be7..bc3234f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,7 +11,7 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) - func fetchPhotos(startDate: Date?, endDate: Date?) -> [Date]? + func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Date]?) -> Void) func pause() func resume() } @@ -42,17 +42,24 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { return } records.configureTitle(title: title) - self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) - self.recordRepository.save(records: records, completion: completion) + self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) { [weak self] images in + self?.recordRepository.save(records: records, completion: completion) + } } - func fetchPhotos(startDate: Date?, endDate: Date?) -> [Date]? { + func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Date]?) -> Void) { guard let startDate = startDate, let endDate = endDate else { - return nil + completionFetchImages(nil) + return + } + + self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) { images in + guard let images = images as? [Date] else { + completionFetchImages(nil) + return + } + completionFetchImages(images) } - - self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) - return nil } } From ada578a69f7ba8ff0ec4f1bfea184d9811047757 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 15 Nov 2021 23:36:31 +0900 Subject: [PATCH 194/465] =?UTF-8?q?[Refactor]=20#163=20Record=20=EB=A6=AC?= =?UTF-8?q?=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 38 ++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 30cbcd6..7861d08 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -16,11 +16,15 @@ class TotalRecords { return totalRecords.reduce(0) { $0 + $1.distances } } - var count: Int { + var sectionCount: Int { return totalRecords.count } - var totalTimes: Double { + var totalCount: Int { + return totalRecords.reduce(0) { $0 + $1.count } + } + + var totalTimes: TimeInterval { return totalRecords.reduce(0) { $0 + $1.times } } @@ -28,14 +32,15 @@ class TotalRecords { return totalRecords.reduce(0) { $0 + $1.steps } } - subscript(section: Int, item: Int) -> Records? { - guard self.count > section && totalRecords[section].count > item else { return nil } - return totalRecords[section].dateSeperateRecords[item] + subscript(section: Int) -> DateSeperateRecords? { + guard self.totalCount > section else { return nil } + return totalRecords[section] } - + func add(records: Records) { - guard let year = records.year else { return } - guard let month = records.month else { return } + guard let date = records.date else { return } + let year = Calendar.current.component(.year, from: date) + let month = Calendar.current.component(.month, from: date) let key = "\(year)\(month)" if let seperateDateRecords = self.mappingDateSeperateRecords[key] { @@ -55,6 +60,11 @@ class DateSeperateRecords { private(set) var dateSeperateRecords: [Records] = [] + subscript(item: Int) -> Records? { + guard self.count > item else { return nil } + return dateSeperateRecords[item] + } + init(year: Int, month: Int) { self.year = year self.month = month @@ -68,7 +78,7 @@ class DateSeperateRecords { return dateSeperateRecords.count } - var times: Double { + var times: TimeInterval { return dateSeperateRecords.reduce(0) { $0 + $1.times } } @@ -86,19 +96,15 @@ struct Records { private(set) var title: String private(set) var records: [Record] - var year: Int? { - return records.isEmpty ? nil : Calendar.current.component(.year, from: records[0].startTime) - } - - var month: Int? { - return records.isEmpty ? nil : Calendar.current.component(.month, from: records[0].startTime) + var date: Date? { + return records.last?.endTime } var distances: Double { return records.reduce(0) { $0 + $1.distance } } - var times: Double { + var times: TimeInterval { return records.reduce(0) { $0 + $1.time } } From 72296809ee88f24d9c2cdbf348010829309a8bae Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 23:40:31 +0900 Subject: [PATCH 195/465] =?UTF-8?q?[Feat]=20#161,=20#162=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=20=EB=82=A0=EC=A7=9C,=20=EC=8B=9C=EA=B0=84=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=9D=BC=20=EC=82=AC=EC=A7=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 +- .../RecordingScene/RecordingPhotoModel.swift | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index d55803d..d9b1bc7 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -147,5 +147,5 @@ struct Location { struct Photo { let latitude: Double let longitude: Double - let date: Date + let date: Data } diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 14ead6a..8d10a9b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -17,8 +17,9 @@ final class RecordingPhotoModel { func fetchPhotos(startDate: Date, endDate: Date, completion: @escaping ([Data]?) -> Void){ let allMedia = PHAsset.fetchAssets(with: .image, options: nil) + var photos = [Photo]() - for i in 0.. Void) { - guard let asset = asset, - let date = asset.creationDate else { + guard let asset = asset else { completion(nil) return } - print(date) + self.representedAssetIdentifier = asset.localIdentifier // self.imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, str, orientation, info in From e38b657a9b6053b5a1443d6410fac4fb1f331be7 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Mon, 15 Nov 2021 23:43:35 +0900 Subject: [PATCH 196/465] =?UTF-8?q?[Feat]=20=EC=82=B0=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=A7=90=ED=92=8D=EC=84=A0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 +++ SanTa/SanTa/MapScene/MountainAnnotation.swift | 6 ++-- .../MountainDetailAnnotationView.swift | 32 +++++++++++++++++++ .../MountainDetailViewController.swift | 30 ++++++++++++++++- 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 2d76ef5..3e6a8c9 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; 49450A4D274205040062CD51 /* MountainDetailCategoryLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */; }; + 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; @@ -92,6 +93,7 @@ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailCategoryLabel.swift; sourceTree = ""; }; + 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; @@ -236,6 +238,7 @@ 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */, + 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -523,6 +526,7 @@ 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */, 49D5A94D2738C71700937821 /* MountainDetailViewModel.swift in Sources */, + 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */, 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */, 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index c85116b..a604514 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -28,11 +28,11 @@ class MountainAnnotation: NSObject, MKAnnotation { self.region = region } - init(title: String, subtitle: String) { + init(title: String, subtitle: String, latitude: Double, longitude: Double) { self.title = title self.subtitle = subtitle - self.latitude = 0 - self.longitude = 0 + self.latitude = latitude + self.longitude = longitude self.mountainDescription = "" self.region = "" } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift new file mode 100644 index 0000000..aa861ce --- /dev/null +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift @@ -0,0 +1,32 @@ +// +// MountainDetailAnnotationView.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/15. +// + +import UIKit +import MapKit + + +class MountainnDetailAnnotationView: MKAnnotationView { + static let ReuseID = "MountainDetailAnnotationView" + let imageSideLength: CGFloat = 30 + + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + self.canShowCallout = true + self.calloutOffset = CGPoint(x: imageSideLength / 2, y: -imageSideLength / 4) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForDisplay() { + super.prepareForDisplay() + displayPriority = .defaultHigh + self.image = UIImage(named: "SantaImage") + self.frame = CGRect(x: 0, y: 0, width: imageSideLength, height: imageSideLength) + } +} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 7e814b8..5fd7300 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -40,7 +40,7 @@ class MountainDetailViewController: UIViewController { extension MountainDetailViewController { private func layoutMountainDetailView(mountainDetail: MountainDetailModel) { let headerView = UIView() - let mapSnapShot = upperMapHeaderView(mountainDetail: mountainDetail) + let mapSnapShot = upperMapView(mountainDetail: mountainDetail) let titleView = lowerMountainTitleView(mountainDetail: mountainDetail) let tableView = configuredTableView(mountainDetail: mountainDetail) @@ -104,6 +104,22 @@ extension MountainDetailViewController { return tableView } + private func upperMapView(mountainDetail: MountainDetailModel) -> MKMapView { + let mapView = MKMapView() + mapView.delegate = self + mapView.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) + + mapView.mapType = .satellite + mapView.isUserInteractionEnabled = false + let annotation = MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude) +// let annotation = MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: "") + mapView.register(MountainAnnotationView.self, forAnnotationViewWithReuseIdentifier: MountainAnnotationView.ReuseID) + mapView.addAnnotation(annotation) + mapView.selectAnnotation(annotation, animated: true) + + return mapView + } + private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { let mapOptions = MKMapSnapshotter.Options.init() mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) @@ -197,8 +213,20 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour extension MountainDetailViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { + let isBottom = scrollView.contentSize.height <= scrollView.bounds.height + scrollView.contentOffset.y + guard !isBottom else { return } if scrollView.contentOffset.y > 0 && scrollView.contentOffset.y < self.maxRollUpDistance { self.mutatingTopConstraint?.constant = -scrollView.contentOffset.y } } } + +extension MountainDetailViewController: MKMapViewDelegate { + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + guard let annotation = annotation as? MountainAnnotation else { return nil } + return MountainnDetailAnnotationView( + annotation: annotation, + reuseIdentifier: MountainnDetailAnnotationView.ReuseID + ) + } +} From cc8a00c9db329f2d9a4b961f0179185b5f18cad6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 15 Nov 2021 23:44:53 +0900 Subject: [PATCH 197/465] =?UTF-8?q?[Feat]=20#161=20=EC=B8=A1=EC=A0=95=20?= =?UTF-8?q?=EC=A4=91=20=EC=B4=AC=EC=98=81=20=EC=82=AC=EC=A7=84=20Fetch=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingPhotoModel.swift | 21 ++++++++++++------- .../RecordingScene/RecordingUseCase.swift | 6 +++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 8d10a9b..7f44dee 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -15,8 +15,9 @@ final class RecordingPhotoModel { var representedAssetIdentifier: String? - func fetchPhotos(startDate: Date, endDate: Date, completion: @escaping ([Data]?) -> Void){ + func fetchPhotos(startDate: Date, endDate: Date, completion: @escaping ([Photo]?) -> Void){ let allMedia = PHAsset.fetchAssets(with: .image, options: nil) + let dispatchGroup = DispatchGroup() var photos = [Photo]() for i in stride(from: allMedia.count - 1, through: 0, by: -1) { @@ -32,11 +33,12 @@ final class RecordingPhotoModel { case .orderedDescending, .orderedSame: switch endDate.compare(creationDate) { case .orderedAscending, .orderedSame: - + dispatchGroup.enter() requestIamge(with: asset) { (image) in guard let image = image else { return } let photo = Photo(latitude: Double(location.coordinate.latitude), longitude: Double(location.coordinate.longitude), date: image) photos.append(photo) + dispatchGroup.leave() } case .orderedDescending: break @@ -44,7 +46,10 @@ final class RecordingPhotoModel { case .orderedAscending: break } - + } + + dispatchGroup.notify(queue: .global()) { + completion(photos) } } @@ -56,10 +61,10 @@ final class RecordingPhotoModel { self.representedAssetIdentifier = asset.localIdentifier -// self.imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, str, orientation, info in -// if self.representedAssetIdentifier == asset.localIdentifier { -// -// } -// }) + self.imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, str, orientation, info in + if self.representedAssetIdentifier == asset.localIdentifier { + completion(data) + } + }) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index bc3234f..816430e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,7 +11,7 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) - func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Date]?) -> Void) + func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Photo]?) -> Void) func pause() func resume() } @@ -47,7 +47,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } } - func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Date]?) -> Void) { + func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Photo]?) -> Void) { guard let startDate = startDate, let endDate = endDate else { completionFetchImages(nil) @@ -55,7 +55,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) { images in - guard let images = images as? [Date] else { + guard let images = images else { completionFetchImages(nil) return } From c466b990d0c23d13b51818b6e72f351e532a37b5 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 15 Nov 2021 23:57:34 +0900 Subject: [PATCH 198/465] =?UTF-8?q?[REFACTOR]=20#166=20Coordinator=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 2 +- .../ResultScene/ResultViewCoordinator.swift | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index ff541fd..5b0dfdc 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -51,7 +51,7 @@ class AppCoordinator: Coordinator { mapViewController.tabBarItem = firstItem mapViewController.tabBarItem.image = .init(systemName: "play.fill") - let resultViewCoordinator = ResultViewCoordinator() + let resultViewCoordinator = ResultViewCoordinator(coreDataStorage: self.coreDataStorage) resultViewCoordinator.parentCoordinator = self childCoordinators.append(resultViewCoordinator) let resultViewController = resultViewCoordinator.startPush() diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index b526b6a..2b1e880 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -11,19 +11,35 @@ class ResultViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController + private let coreDataStorage: CoreDataStorage - init() { + init(coreDataStorage: CoreDataStorage) { self.navigationController = UINavigationController() + self.coreDataStorage = coreDataStorage } func start() { } func startPush() -> UINavigationController { - let resultViewController = ResultViewController() + let resultViewController = ResultViewController(viewModel: injectDependencies()) resultViewController.coordinator = self navigationController.setViewControllers([resultViewController], animated: true) return navigationController } } + +extension ResultViewCoordinator { + private func injectDependencies() -> ResultViewModel { + return ResultViewModel( + useCase: ResultUseCase( + resultRepository: DefaultResultRepository( + recordStorage: CoreDataRecordStorage( + coreDataStorage: self.coreDataStorage + ) + ) + ) + ) + } +} From a5cbb3c93e1fb4d93af4530d39929590f77bf5f0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 00:09:55 +0900 Subject: [PATCH 199/465] =?UTF-8?q?[Feat]=20#158=20RecordingPhotoView=20Dy?= =?UTF-8?q?namic=20View=20Layout=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoViewController.swift | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index eed21eb..4d78872 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -16,6 +16,7 @@ class RecordingPhotoViewController: UIViewController { view.backgroundColor = UIColor(named: "RecordingSubViewBackgroundColor") view.layer.masksToBounds = true view.layer.cornerRadius = 12 + view.translatesAutoresizingMaskIntoConstraints = false return view }() @@ -62,9 +63,9 @@ class RecordingPhotoViewController: UIViewController { private let photoStackView: UIStackView = { let stackView = UIStackView() - stackView.spacing = 8 + stackView.spacing = 16 stackView.axis = .vertical - stackView.distribution = .fillProportionally + stackView.distribution = .fill stackView.alignment = .center stackView.translatesAutoresizingMaskIntoConstraints = false return stackView @@ -79,9 +80,6 @@ class RecordingPhotoViewController: UIViewController { private func configureConstraints() { let frameWidth = view.frame.width - let frameHeight = view.frame.height - - self.displayView.frame = CGRect(x: 6, y: frameWidth, width: frameWidth - 12, height: frameHeight/2 - 64) [self.recordingPhotoTitle, self.recordingPhotoImage, self.recordingPhotoDescription, self.agreeButton].forEach { self.photoStackView.addArrangedSubview($0) @@ -90,6 +88,12 @@ class RecordingPhotoViewController: UIViewController { self.view.addSubview(displayView) self.displayView.addSubview(photoStackView) + let displayViweConstraints = [ + self.displayView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 6), + self.displayView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -6), + self.displayView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -64) + ] + let recordingPhotoTitleConstraints = [ self.recordingPhotoTitle.widthAnchor.constraint(equalToConstant: frameWidth - 12) ] @@ -104,7 +108,8 @@ class RecordingPhotoViewController: UIViewController { ] let agreeButtonConstraints = [ - self.agreeButton.widthAnchor.constraint(equalToConstant: frameWidth - 12) + self.agreeButton.widthAnchor.constraint(equalToConstant: frameWidth - 12), + self.agreeButton.heightAnchor.constraint(equalToConstant: frameWidth/8) ] let titleStackViewConstraints = [ @@ -114,6 +119,7 @@ class RecordingPhotoViewController: UIViewController { self.photoStackView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -16) ] + NSLayoutConstraint.activate(displayViweConstraints) NSLayoutConstraint.activate(recordingPhotoTitleConstraints) NSLayoutConstraint.activate(recordingPhotoImageConstraints) NSLayoutConstraint.activate(recordingPhotoDescriptionText) From 06ee542a0d0a21306b11f248296bb7e31a660558 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 00:29:54 +0900 Subject: [PATCH 200/465] [Feature] #168, #169, #170 ResultScene MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Custom ViewCell, Header 생성, Data 흐름 구현, DarkMode 대응 --- SanTa/SanTa.xcodeproj/project.pbxproj | 18 +- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 104 ++++++ SanTa/SanTa/ResultScene/ResultUseCase.swift | 18 +- .../ResultScene/ResultViewController.swift | 308 +++--------------- SanTa/SanTa/ResultScene/ResultViewModel.swift | 131 ++++++++ .../SanTa/ResultScene/SectionHeaderView.swift | 65 ++++ .../ResultScene/TotalRecordsViewCell.swift | 98 ++++++ 7 files changed, 462 insertions(+), 280 deletions(-) create mode 100644 SanTa/SanTa/ResultScene/RecordsViewCell.swift create mode 100644 SanTa/SanTa/ResultScene/ResultViewModel.swift create mode 100644 SanTa/SanTa/ResultScene/SectionHeaderView.swift create mode 100644 SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 5ce02fb..7df885e 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */; }; 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695A273026B10070B362 /* MountainAnnotationView.swift */; }; 5429695D27302B1D0070B362 /* ClusterAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */; }; + 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5465237C2741F997007B2692 /* ResultViewModel.swift */; }; 54731B65272F84D300534097 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54731B64272F84D300534097 /* MapViewModel.swift */; }; 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */ = {isa = PBXBuildFile; fileRef = 547CDD9927392474007CCA29 /* walkingManAnimation.gif */; }; 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */; }; @@ -43,6 +44,9 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; + 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */; }; + 54F88EB9274256FE0004EAFD /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */; }; + 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EBA274259950004EAFD /* RecordsViewCell.swift */; }; 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821C273CB45D006A847A /* ResultRepository.swift */; }; 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821E273CE16E006A847A /* ResultUseCase.swift */; }; 9826F3DD2739035E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; @@ -115,6 +119,7 @@ 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewCoordinator.swift; sourceTree = ""; }; 5429695A273026B10070B362 /* MountainAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotationView.swift; sourceTree = ""; }; 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterAnnotationView.swift; sourceTree = ""; }; + 5465237C2741F997007B2692 /* ResultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultViewModel.swift; sourceTree = ""; }; 54731B64272F84D300534097 /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = ""; }; 547CDD9927392474007CCA29 /* walkingManAnimation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = walkingManAnimation.gif; sourceTree = ""; }; 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Gif.swift"; sourceTree = ""; }; @@ -126,6 +131,9 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalRecordsViewCell.swift; sourceTree = ""; }; + 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = ""; }; + 54F88EBA274259950004EAFD /* RecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsViewCell.swift; sourceTree = ""; }; 9800821C273CB45D006A847A /* ResultRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultRepository.swift; sourceTree = ""; }; 9800821E273CE16E006A847A /* ResultUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultUseCase.swift; sourceTree = ""; }; 9826F3DC2739035E0064FA85 /* Option.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = ""; }; @@ -192,10 +200,14 @@ 5428FDB6272F8B2B002F9D40 /* ResultScene */ = { isa = PBXGroup; children = ( - 5429694C272FC1390070B362 /* ResultViewController.swift */, 5429694E272FC1740070B362 /* ResultViewCoordinator.swift */, + 5429694C272FC1390070B362 /* ResultViewController.swift */, + 5465237C2741F997007B2692 /* ResultViewModel.swift */, 9800821E273CE16E006A847A /* ResultUseCase.swift */, 9800821C273CB45D006A847A /* ResultRepository.swift */, + 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */, + 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */, + 54F88EBA274259950004EAFD /* RecordsViewCell.swift */, ); path = ResultScene; sourceTree = ""; @@ -468,6 +480,7 @@ buildActionMask = 2147483647; files = ( 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, + 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */, 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, @@ -498,8 +511,10 @@ 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */, 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, + 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, + 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */, @@ -523,6 +538,7 @@ 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */, + 54F88EB9274256FE0004EAFD /* SectionHeaderView.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */, ); diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift new file mode 100644 index 0000000..539e51e --- /dev/null +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -0,0 +1,104 @@ +// +// RecordsViewCell.swift +// SanTa +// +// Created by shin jae ung on 2021/11/15. +// + +import UIKit + +extension UILabel { + fileprivate convenience init(text: String, normalFontWithSize: CGFloat) { + self.init() + self.text = text + self.textColor = .black + } + + fileprivate convenience init(boldFontWithSize: CGFloat) { + self.init() + self.font = .boldSystemFont(ofSize: boldFontWithSize) + self.textColor = .black + } +} + +class RecordsViewCell: UICollectionViewCell { + static let identifier = "RecordsViewCell" + var date: PaddingLabel = { + let paddingLabel = PaddingLabel() + paddingLabel.padding(top: 2, bottom: 2, left: 3, right: 3) + paddingLabel.backgroundColor = UIColor(named: "SantaColor") + paddingLabel.layer.cornerRadius = 3 + paddingLabel.textColor = .white + paddingLabel.font = .boldSystemFont(ofSize: 13) + paddingLabel.clipsToBounds = true + return paddingLabel + }() + let horizontalStackView = UIStackView() + let distanceStackView = UIStackView() + let distance = UILabel(boldFontWithSize: 20) + let distanceLabel = UILabel(text: "거리", normalFontWithSize: 15) + let timeStackView = UIStackView() + let time = UILabel(boldFontWithSize: 20) + let timeLabel = UILabel(text: "시간", normalFontWithSize: 15) + let altitudeStackView = UIStackView() + let altitude = UILabel(boldFontWithSize: 20) + let altitudeLabel = UILabel(text: "고도차", normalFontWithSize: 15) + let stepsStackView = UIStackView() + let steps = UILabel(boldFontWithSize: 20) + let stepsLabel = UILabel(text: "걸음", normalFontWithSize: 15) + + func configure(date: String, distance: String, time: String, altitude: String, steps: String) { + self.date.text = date + self.distance.text = distance + self.time.text = time + self.altitude.text = altitude + self.steps.text = steps + + self.configureSubviews() + self.configureLayout() + } + + private func configureSubviews() { + self.addSubview(date) + self.addSubview(horizontalStackView) + self.horizontalStackView.distribution = .fillEqually + self.horizontalStackView.axis = .horizontal + self.distanceStackView.axis = .vertical + self.distanceStackView.alignment = .center + self.timeStackView.axis = .vertical + self.timeStackView.alignment = .center + self.altitudeStackView.axis = .vertical + self.altitudeStackView.alignment = .center + self.stepsStackView.axis = .vertical + self.stepsStackView.alignment = .center + self.horizontalStackView.addArrangedSubview(distanceStackView) + self.horizontalStackView.addArrangedSubview(timeStackView) + self.horizontalStackView.addArrangedSubview(altitudeStackView) + self.horizontalStackView.addArrangedSubview(stepsStackView) + self.distanceStackView.spacing = 5 + self.distanceStackView.addArrangedSubview(distance) + self.distanceStackView.addArrangedSubview(distanceLabel) + self.timeStackView.spacing = 5 + self.timeStackView.addArrangedSubview(time) + self.timeStackView.addArrangedSubview(timeLabel) + self.altitudeStackView.spacing = 5 + self.altitudeStackView.addArrangedSubview(altitude) + self.altitudeStackView.addArrangedSubview(altitudeLabel) + self.stepsStackView.spacing = 5 + self.stepsStackView.addArrangedSubview(steps) + self.stepsStackView.addArrangedSubview(stepsLabel) + } + + private func configureLayout() { + self.date.translatesAutoresizingMaskIntoConstraints = false + self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.date.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.date.topAnchor.constraint(equalTo: self.topAnchor, constant: 15), + self.horizontalStackView.topAnchor.constraint(greaterThanOrEqualTo: self.date.bottomAnchor, constant: 10), + self.horizontalStackView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -15), + self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) + ]) + } +} diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index 3f7bc99..2ddb75c 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -8,27 +8,23 @@ import Foundation import OSLog -protocol ResultUseCase { - func fetch(completion: @escaping (TotalRecords?) -> Void) -} - - -final class DefaultResultUseCase { - +final class ResultUseCase { private let resultRepository: ResultRepository + private(set) var totalRecords: TotalRecords? init(resultRepository: ResultRepository) { self.resultRepository = resultRepository } - func fetch(completion: @escaping (TotalRecords?) -> Void) { - self.resultRepository.fetch { result in + func fetch(completion: @escaping (Void?) -> Void) { + self.resultRepository.fetch { [weak self] result in switch result { case .success(let objects): - let totalRecords = self.makeTotalRecords(objects: objects) - completion(totalRecords) + self?.totalRecords = self?.makeTotalRecords(objects: objects) + completion(Void()) case .failure(let error): os_log(.error, log: .default, "\(error.localizedDescription)") + self?.totalRecords = nil completion(nil) } } diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index a673db9..663b40c 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -7,263 +7,36 @@ import UIKit -struct TopMain { - let distance = "42.195" - let count = "1" - let time = "02:30" - let steps = "99999" -} - -struct HeaderInfo { - let month = "2021. 11" - let count = "6회" - let distance = "31.084" - let time = "01:45" -} - -struct CellInfo { - let date = "어제(목) 오후 3시 46분" - let distance = "2.56" - let time = "03.01" - let altitude = "20" - let steps = "512" -} - -class TopMainCell: UICollectionViewCell { - static let identifier = "TopMainCell" - let kilometerNumber = UILabel() - let kilometer = UILabel() - let countNumber = UILabel() - let count = UILabel() - let timeNumber = UILabel() - let time = UILabel() - let stepsNumber = UILabel() - let steps = UILabel() - let horizontalStackView = UIStackView() - let countVerticalStackView = UIStackView() - let timeVerticalStackView = UIStackView() - let stepsVerticalStackView = UIStackView() - - func configure(distance: String, count: String, time: String, steps: String) { - self.configureSubviews() - self.configureLayout() - self.kilometerNumber.text = distance - self.kilometerNumber.font = .systemFont(ofSize: 60) - self.kilometer.text = "킬로미터" - self.kilometer.font = .systemFont(ofSize: 15) - self.countNumber.text = count - self.countNumber.font = .systemFont(ofSize: 25) - self.count.text = "횟수" - self.count.font = .systemFont(ofSize: 15) - self.timeNumber.text = time - self.timeNumber.font = .systemFont(ofSize: 25) - self.time.text = "시간" - self.time.font = .systemFont(ofSize: 15) - self.stepsNumber.text = steps - self.stepsNumber.font = .systemFont(ofSize: 25) - self.steps.text = "걸음" - self.steps.font = .systemFont(ofSize: 15) - self.backgroundColor = .systemGray6 - let border = CALayer() - border.frame = CGRect.init(x: 0, y: self.frame.height, width: self.frame.width, height: -1) - border.backgroundColor = UIColor.systemGray4.cgColor - self.layer.addSublayer(border) - } - - private func configureSubviews() { - self.addSubview(self.kilometerNumber) - self.addSubview(self.kilometer) - self.addSubview(self.horizontalStackView) - self.horizontalStackView.addArrangedSubview(countVerticalStackView) - self.horizontalStackView.addArrangedSubview(timeVerticalStackView) - self.horizontalStackView.addArrangedSubview(stepsVerticalStackView) - self.horizontalStackView.axis = .horizontal - self.horizontalStackView.distribution = .fillEqually - self.countVerticalStackView.axis = .vertical - self.countVerticalStackView.alignment = .center - self.countVerticalStackView.spacing = 5 - self.timeVerticalStackView.axis = .vertical - self.timeVerticalStackView.alignment = .center - self.timeVerticalStackView.spacing = 5 - self.stepsVerticalStackView.axis = .vertical - self.stepsVerticalStackView.alignment = .center - self.stepsVerticalStackView.spacing = 5 - self.countVerticalStackView.addArrangedSubview(countNumber) - self.countVerticalStackView.addArrangedSubview(count) - self.timeVerticalStackView.addArrangedSubview(timeNumber) - self.timeVerticalStackView.addArrangedSubview(time) - self.stepsVerticalStackView.addArrangedSubview(stepsNumber) - self.stepsVerticalStackView.addArrangedSubview(steps) - } - - private func configureLayout() { - self.kilometerNumber.translatesAutoresizingMaskIntoConstraints = false - self.kilometer.translatesAutoresizingMaskIntoConstraints = false - self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - self.kilometerNumber.centerXAnchor.constraint(equalTo: self.centerXAnchor), - self.kilometerNumber.topAnchor.constraint(equalTo: self.topAnchor, constant: 60), - self.kilometer.centerXAnchor.constraint(equalTo: self.centerXAnchor), - self.kilometer.topAnchor.constraint(equalTo: self.kilometerNumber.bottomAnchor, constant: 0), - self.horizontalStackView.topAnchor.constraint(equalTo: self.kilometer.bottomAnchor, constant: 50), - self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), - self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), - self.horizontalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) - ]) - } -} - -class Header: UICollectionReusableView { - static let identifier = "header" - let monthLabel = UILabel() - let countLabel = UILabel() - let distanceLabel = UILabel() - let timeLabel = UILabel() - - func configure(month: String, count: String, distance: String, time: String){ - self.backgroundColor = .white - self.monthLabel.text = month - self.monthLabel.font = .boldSystemFont(ofSize: 17) - self.countLabel.text = count - self.countLabel.font = .systemFont(ofSize: 15) - self.countLabel.textColor = .systemGray - self.distanceLabel.text = distance - self.distanceLabel.font = .systemFont(ofSize: 15) - self.distanceLabel.textColor = .systemGray - self.timeLabel.text = time - self.timeLabel.font = .systemFont(ofSize: 15) - self.timeLabel.textColor = .systemGray - self.configureSubviews() - self.configureLayout() - } - - private func configureSubviews(){ - self.addSubview(monthLabel) - self.addSubview(countLabel) - self.addSubview(distanceLabel) - self.addSubview(timeLabel) - self.monthLabel.translatesAutoresizingMaskIntoConstraints = false - self.countLabel.translatesAutoresizingMaskIntoConstraints = false - self.distanceLabel.translatesAutoresizingMaskIntoConstraints = false - self.timeLabel.translatesAutoresizingMaskIntoConstraints = false - } +class ResultViewController: UIViewController { + weak var coordinator: ResultViewCoordinator? + private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: ResultViewController.createCompositionalLayout()) + private var viewModel: ResultViewModel? - private func configureLayout() { - NSLayoutConstraint.activate([ - self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), - self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), - self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.distanceLabel.rightAnchor.constraint(equalTo: self.timeLabel.leftAnchor, constant: -10), - self.countLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10) - ]) + convenience init(viewModel: ResultViewModel) { + self.init() + self.viewModel = viewModel } -} -class MyCollectionViewCell: UICollectionViewCell { - static let identifier = "MyCollectionViewCell" - let date = PaddingLabel() - let horizontalStackView = UIStackView() - let distanceStackView = UIStackView() - let distance = UILabel() - let distanceLabel = UILabel() - let timeStackView = UIStackView() - let time = UILabel() - let timeLabel = UILabel() - let altitudeStackView = UIStackView() - let altitude = UILabel() - let altitudeLabel = UILabel() - let stepsStackView = UIStackView() - let steps = UILabel() - let stepsLabel = UILabel() - - func configure(date: String, distance: String, time: String, altitude: String, steps: String) { - self.date.padding(top: 2, bottom: 2, left: 2, right: 2) - self.date.text = date - self.date.backgroundColor = UIColor.init(red: 0.50, green: 0.8, blue: 0.37, alpha: 1) - self.date.layer.cornerRadius = 3 - self.date.clipsToBounds = true - self.date.textColor = .white - self.date.font = .boldSystemFont(ofSize: 13) - self.distance.text = distance - self.distance.font = .boldSystemFont(ofSize: 20) - self.distanceLabel.text = "거리" - self.time.text = time - self.time.font = .boldSystemFont(ofSize: 20) - self.timeLabel.text = "시간" - self.altitude.text = altitude - self.altitude.font = .boldSystemFont(ofSize: 20) - self.altitudeLabel.text = "고도차" - self.steps.text = steps - self.steps.font = .boldSystemFont(ofSize: 20) - self.stepsLabel.text = "걸음" - self.configureSubviews() - self.configureLayout() + override func viewDidLoad() { + super.viewDidLoad() + self.configureCollectionView() } - private func configureSubviews() { - self.addSubview(date) - self.addSubview(horizontalStackView) - self.horizontalStackView.distribution = .fillEqually - self.horizontalStackView.axis = .horizontal - self.distanceStackView.axis = .vertical - self.distanceStackView.alignment = .center - self.timeStackView.axis = .vertical - self.timeStackView.alignment = .center - self.altitudeStackView.axis = .vertical - self.altitudeStackView.alignment = .center - self.stepsStackView.axis = .vertical - self.stepsStackView.alignment = .center - self.horizontalStackView.addArrangedSubview(distanceStackView) - self.horizontalStackView.addArrangedSubview(timeStackView) - self.horizontalStackView.addArrangedSubview(altitudeStackView) - self.horizontalStackView.addArrangedSubview(stepsStackView) - self.distanceStackView.spacing = 5 - self.distanceStackView.addArrangedSubview(distance) - self.distanceStackView.addArrangedSubview(distanceLabel) - self.timeStackView.spacing = 5 - self.timeStackView.addArrangedSubview(time) - self.timeStackView.addArrangedSubview(timeLabel) - self.altitudeStackView.spacing = 5 - self.altitudeStackView.addArrangedSubview(altitude) - self.altitudeStackView.addArrangedSubview(altitudeLabel) - self.stepsStackView.spacing = 5 - self.stepsStackView.addArrangedSubview(steps) - self.stepsStackView.addArrangedSubview(stepsLabel) + override func viewWillAppear(_ animated: Bool) { + self.navigationController?.navigationBar.isHidden = true + viewModel?.viewWillAppear() { [weak self] in + DispatchQueue.main.async { + self?.navigationController?.navigationBar.topItem?.title = self?.viewModel?.totalDistance + self?.collectionView.reloadData() + } + } } - private func configureLayout() { - self.date.translatesAutoresizingMaskIntoConstraints = false - self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - self.date.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), - self.date.topAnchor.constraint(equalTo: self.topAnchor, constant: 15), - self.horizontalStackView.topAnchor.constraint(greaterThanOrEqualTo: self.date.bottomAnchor, constant: 10), - self.horizontalStackView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -15), - self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), - self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) - ]) - } -} - -class ResultViewController: UIViewController { - weak var coordinator: ResultViewCoordinator? - - private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: ResultViewController.createCompositionalLayout()) - private let topMain = TopMain() - private let headerInfo = HeaderInfo() - private let cellInfo = CellInfo() - - override func viewDidLoad() { - super.viewDidLoad() + private func configureCollectionView() { view.addSubview(collectionView) - self.navigationController?.navigationBar.isHidden = true - self.navigationController?.navigationBar.topItem?.title = topMain.distance + "km" - collectionView.register(TopMainCell.self, forCellWithReuseIdentifier: TopMainCell.identifier) - collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: MyCollectionViewCell.identifier) - collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: Header.identifier) + collectionView.register(TotalRecordsViewCell.self, forCellWithReuseIdentifier: TotalRecordsViewCell.identifier) + collectionView.register(RecordsViewCell.self, forCellWithReuseIdentifier: RecordsViewCell.identifier) + collectionView.register(SectionHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: SectionHeaderView.identifier) collectionView.frame = view.bounds collectionView.delegate = self collectionView.dataSource = self @@ -311,15 +84,14 @@ class ResultViewController: UIViewController { extension ResultViewController: UICollectionViewDataSource { func numberOfSections(in collectionView: UICollectionView) -> Int { - return 3 + guard let viewModel = viewModel else { return 0} + return viewModel.totalSections + 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return 1 - case 1: return 6 - case 2: return 6 - default : return 0 + default : return viewModel?.itemsInSection(section: section - 1) ?? 0 } } @@ -327,37 +99,37 @@ extension ResultViewController: UICollectionViewDataSource { switch indexPath.section { case 0: guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: TopMainCell.identifier, + withReuseIdentifier: TotalRecordsViewCell.identifier, for: indexPath - ) as? TopMainCell else { - return UICollectionViewCell() - } - cell.configure(distance: topMain.distance, count: topMain.count, time: topMain.time, steps: topMain.steps) + ) as? TotalRecordsViewCell, + let totalInfo = viewModel?.totalInfo() + else { return UICollectionViewCell() } + cell.configure(distance: totalInfo.distance, count: totalInfo.count, time: totalInfo.time, steps: totalInfo.steps) return cell default: guard let cell = collectionView.dequeueReusableCell( - withReuseIdentifier: MyCollectionViewCell.identifier, + withReuseIdentifier: RecordsViewCell.identifier, for: indexPath - ) as? MyCollectionViewCell else { - return UICollectionViewCell() - } + ) as? RecordsViewCell, + let cellInfo = viewModel?.cellInfo(indexPath: IndexPath(item: indexPath.item, section: indexPath.section - 1)) + else { return UICollectionViewCell() } cell.layer.cornerRadius = 10 cell.backgroundColor = .white cell.layer.shadowColor = UIColor.gray.cgColor cell.layer.shadowRadius = 2 cell.layer.shadowOpacity = 0.8 cell.layer.shadowOffset = CGSize(width: 0, height: 0.5) - cell.configure(date: cellInfo.date, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitude, steps: cellInfo.steps) + cell.configure(date: cellInfo.date, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitudeDifference, steps: cellInfo.steps) return cell } } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { - guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Header.identifier, for: indexPath) as? Header else { - return UICollectionReusableView() - } - header.configure(month: headerInfo.month, count: headerInfo.count, distance: headerInfo.distance, time: headerInfo.time) - return header + guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.identifier, for: indexPath) as? SectionHeaderView, + let sectionInfo = viewModel?.sectionInfo(section: indexPath.section - 1) + else { return UICollectionReusableView() } + sectionHeader.configure(month: sectionInfo.date, count: sectionInfo.count, distance: sectionInfo.distance, time: sectionInfo.time) + return sectionHeader } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift new file mode 100644 index 0000000..8225c9d --- /dev/null +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -0,0 +1,131 @@ +// +// ResultViewModel.swift +// SanTa +// +// Created by shin jae ung on 2021/11/15. +// + +import Foundation + +class ResultViewModel { + private let useCase: ResultUseCase + var cellShouldUpdate: () -> Void + var totalDistance: String { + guard let totalRecords = useCase.totalRecords else { return "" } + return self.doubleFormatter(totalRecords.totalDistances) + " km" + } + var totalSections: Int { + guard let totalRecords = useCase.totalRecords else { return 0 } + return totalRecords.sectionCount + } + + init(useCase: ResultUseCase) { + self.useCase = useCase + self.cellShouldUpdate = {} + } + + func viewWillAppear(completion: @escaping () -> Void) { + self.useCase.fetch { [weak self] void in + guard void != nil else { return } + self?.cellShouldUpdate() + completion() + } + } + + func itemsInSection(section: Int) -> Int { + useCase.totalRecords?[section]?.count ?? 0 + } + + func totalInfo() -> (distance: String, count: String, time: String, steps: String) { + guard let totalRecords = useCase.totalRecords else { + return ("", "", "", "") + } + let distanceString = self.doubleFormatter(totalRecords.totalDistances) + let countString = self.intFormatter(totalRecords.totalCount) + let timeString = self.timeFormatter(totalRecords.totalTimes) + let stepsString = self.stepsFormatter(totalRecords.totalSteps) + return (distanceString, countString, timeString, stepsString) + } + + func sectionInfo(section: Int) -> (date: String, count: String, distance: String, time: String) { + guard let totalRecords = useCase.totalRecords, + let dateSeperateRecords = totalRecords[section] + else { + return ("", "", "", "") + } + let dateString = self.headerDateFormatter( + year: dateSeperateRecords.year, + month: dateSeperateRecords.month + ) + let countString = "\(dateSeperateRecords.count)회" + let distanceString = self.doubleFormatter(dateSeperateRecords.distances) + "km" + let timeString = self.timeFormatter(dateSeperateRecords.times) + return (dateString, countString, distanceString, timeString) + } + + func cellInfo(indexPath: IndexPath) + -> (date: String, distance: String, time: String, altitudeDifference: String, steps: String, title: String) { + guard let totalRecords = useCase.totalRecords, + let records = totalRecords[indexPath.section]?[indexPath.item] + else { + return ("", "", "", "", "", "") + } + let dateString = self.cellDateFormatter(records.date) + let distanceString = self.doubleFormatter(records.distances) + let timeString = self.timeFormatter(records.times) + let altitudeDifferenceString = self.cellAltitudeDifferenceFormatter(records.maxAltitudeDifference) + let stepsString = self.stepsFormatter(records.steps) + let title = records.title + return (dateString, distanceString, timeString, altitudeDifferenceString, stepsString, title) + } +} + +extension ResultViewModel { + private func headerDateFormatter(year: Int, month: Int) -> String { + return "\(year). \(month)." + } + + private func cellDateFormatter(_ date: Date?) -> String { + guard let date = date else { return "알 수 없는 날짜" } + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier:"ko_KR") + dateFormatter.dateFormat = "M. d. (E) a h시 m분" + return dateFormatter.string(from:date) + } + + private func timeFormatter(_ time: TimeInterval) -> String { + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + formatter.zeroFormattingBehavior = .pad + return formatter.string(from: time) ?? "00:00" + } + + private func cellAltitudeDifferenceFormatter(_ number: Double) -> String { + guard number < 10000 else { return "9,999+" } + guard number < 1 else { return "-" } + return self.intFormatter(Int(number)) + } + + private func stepsFormatter(_ number: Int) -> String { + if number < 10000 { + return self.intFormatter(number) + } else { + let number = Double(number)/10000.0 + return self.doubleFormatter(number) + "만" + } + } + + private func intFormatter(_ number: Int) -> String { + let numberFormatter = NumberFormatter() + numberFormatter.numberStyle = .decimal + return numberFormatter.string(from: NSNumber(value: number)) ?? "Error" + } + + private func doubleFormatter(_ number: Double) -> String { + let numberFormatter = NumberFormatter() + numberFormatter.minimumFractionDigits = 2 + numberFormatter.maximumFractionDigits = 2 + numberFormatter.numberStyle = .decimal + return numberFormatter.string(from: NSNumber(value: number)) ?? "Error" + } +} diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift new file mode 100644 index 0000000..3375aa6 --- /dev/null +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -0,0 +1,65 @@ +// +// SectionHeaderView.swift +// SanTa +// +// Created by shin jae ung on 2021/11/15. +// + +import UIKit + +extension UILabel { + fileprivate convenience init(normalFontWithSize: CGFloat, withTextColor: UIColor) { + self.init() + self.font = .systemFont(ofSize: normalFontWithSize) + self.textColor = withTextColor + } + + fileprivate convenience init(boldFontWithSize: CGFloat, withTextColor: UIColor) { + self.init() + self.font = .boldSystemFont(ofSize: boldFontWithSize) + self.textColor = withTextColor + } +} + +class SectionHeaderView: UICollectionReusableView { + static let identifier = "SectionHeaderView" + let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .black) + let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + + func configure(month: String, count: String, distance: String, time: String){ + self.backgroundColor = .white + self.monthLabel.text = month + self.countLabel.text = count + self.distanceLabel.text = distance + self.timeLabel.text = time + + self.configureSubviews() + self.configureLayout() + } + + private func configureSubviews(){ + self.addSubview(monthLabel) + self.addSubview(countLabel) + self.addSubview(distanceLabel) + self.addSubview(timeLabel) + } + + private func configureLayout() { + self.monthLabel.translatesAutoresizingMaskIntoConstraints = false + self.countLabel.translatesAutoresizingMaskIntoConstraints = false + self.distanceLabel.translatesAutoresizingMaskIntoConstraints = false + self.timeLabel.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), + self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.distanceLabel.rightAnchor.constraint(equalTo: self.timeLabel.leftAnchor, constant: -10), + self.countLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), + self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10) + ]) + } +} diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift new file mode 100644 index 0000000..46955bf --- /dev/null +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -0,0 +1,98 @@ +// +// TotalRecordsViewCell.swift +// SanTa +// +// Created by shin jae ung on 2021/11/15. +// + +import UIKit + +extension UILabel { + fileprivate convenience init(normalFontWithSize: CGFloat) { + self.init() + self.font = .systemFont(ofSize: normalFontWithSize) + } + + fileprivate convenience init(text: String, normalFontWithSize: CGFloat) { + self.init() + self.text = text + self.font = .systemFont(ofSize: normalFontWithSize) + } +} + +class TotalRecordsViewCell: UICollectionViewCell { + static let identifier = "TotalRecordsInfoCell" + let kilometerNumber = UILabel(normalFontWithSize: 60) + let kilometer = UILabel(text: "킬로미터", normalFontWithSize: 25) + let countNumber = UILabel(normalFontWithSize: 25) + let count = UILabel(text: "횟수", normalFontWithSize: 15) + let timeNumber = UILabel(normalFontWithSize: 25) + let time = UILabel(text: "시간", normalFontWithSize: 15) + let stepsNumber = UILabel(normalFontWithSize: 25) + let steps = UILabel(text: "걸음", normalFontWithSize: 15) + let horizontalStackView = UIStackView() + let countVerticalStackView = UIStackView() + let timeVerticalStackView = UIStackView() + let stepsVerticalStackView = UIStackView() + + func configure(distance: String, count: String, time: String, steps: String) { + self.kilometerNumber.text = distance + self.countNumber.text = count + self.timeNumber.text = time + self.stepsNumber.text = steps + self.backgroundColor = .systemGray6 + + self.configureSubviews() + self.configureLayout() + self.configureShadow() + } + + private func configureSubviews() { + self.addSubview(self.kilometerNumber) + self.addSubview(self.kilometer) + self.addSubview(self.horizontalStackView) + self.horizontalStackView.addArrangedSubview(countVerticalStackView) + self.horizontalStackView.addArrangedSubview(timeVerticalStackView) + self.horizontalStackView.addArrangedSubview(stepsVerticalStackView) + self.horizontalStackView.axis = .horizontal + self.horizontalStackView.distribution = .fillEqually + self.countVerticalStackView.axis = .vertical + self.countVerticalStackView.alignment = .center + self.countVerticalStackView.spacing = 5 + self.timeVerticalStackView.axis = .vertical + self.timeVerticalStackView.alignment = .center + self.timeVerticalStackView.spacing = 5 + self.stepsVerticalStackView.axis = .vertical + self.stepsVerticalStackView.alignment = .center + self.stepsVerticalStackView.spacing = 5 + self.countVerticalStackView.addArrangedSubview(countNumber) + self.countVerticalStackView.addArrangedSubview(count) + self.timeVerticalStackView.addArrangedSubview(timeNumber) + self.timeVerticalStackView.addArrangedSubview(time) + self.stepsVerticalStackView.addArrangedSubview(stepsNumber) + self.stepsVerticalStackView.addArrangedSubview(steps) + } + + private func configureLayout() { + self.kilometerNumber.translatesAutoresizingMaskIntoConstraints = false + self.kilometer.translatesAutoresizingMaskIntoConstraints = false + self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.kilometerNumber.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.kilometerNumber.topAnchor.constraint(equalTo: self.topAnchor, constant: 60), + self.kilometer.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.kilometer.topAnchor.constraint(equalTo: self.kilometerNumber.bottomAnchor, constant: 0), + self.horizontalStackView.topAnchor.constraint(equalTo: self.kilometer.bottomAnchor, constant: 50), + self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.horizontalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.horizontalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) + ]) + } + + private func configureShadow() { + let border = CALayer() + border.frame = CGRect.init(x: 0, y: self.frame.height, width: self.frame.width, height: -1) + border.backgroundColor = UIColor.systemGray4.cgColor + self.layer.addSublayer(border) + } +} From 608c9ae41da65d48ec6bebcbb96a07b51229f28e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 00:41:57 +0900 Subject: [PATCH 201/465] =?UTF-8?q?[Feat]=20=EB=8B=AB=EA=B8=B0=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 5fd7300..46ffdd6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -92,6 +92,27 @@ extension MountainDetailViewController { tableView.rightAnchor.constraint(equalTo: view.rightAnchor) ] NSLayoutConstraint.activate(tableViewConstraints) + +// let backButton = UIButton() +// backButton.setImage(.init(systemName: "xmark"), for: .normal) +// backButton.tintColor = .white + let backButton = UIImageView(image: .init(systemName: "xmark")?.withTintColor(.white)) + self.view.addSubview(backButton) + backButton.translatesAutoresizingMaskIntoConstraints = false + backButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(close))) + backButton.isUserInteractionEnabled = true + + let backButtonConstraints = [ + backButton.topAnchor.constraint(equalTo: self.view.topAnchor), + backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor), + backButton.widthAnchor.constraint(equalToConstant: 40), + backButton.heightAnchor.constraint(equalToConstant: 40), + + ] + NSLayoutConstraint.activate(backButtonConstraints) + } + @objc private func close() { + self.dismiss(animated: true, completion: nil) } private func configuredTableView(mountainDetail: MountainDetailModel) -> UITableView { From 9a66782d73052357f25f9355044b1e589df6e491 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 11:17:52 +0900 Subject: [PATCH 202/465] =?UTF-8?q?[Feat]=20=EB=8B=AB=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=8B=B4=ED=8A=B8=20=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 46ffdd6..8647302 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -96,17 +96,20 @@ extension MountainDetailViewController { // let backButton = UIButton() // backButton.setImage(.init(systemName: "xmark"), for: .normal) // backButton.tintColor = .white - let backButton = UIImageView(image: .init(systemName: "xmark")?.withTintColor(.white)) + let backButton = UIImageView(image: .init(systemName: "xmark")) + backButton.tintColor = .white +// backButton.image?.withTintColor(.white) + backButton.tintColorDidChange() self.view.addSubview(backButton) backButton.translatesAutoresizingMaskIntoConstraints = false backButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(close))) backButton.isUserInteractionEnabled = true let backButtonConstraints = [ - backButton.topAnchor.constraint(equalTo: self.view.topAnchor), - backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor), - backButton.widthAnchor.constraint(equalToConstant: 40), - backButton.heightAnchor.constraint(equalToConstant: 40), + backButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10), + backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10), + backButton.widthAnchor.constraint(equalToConstant: 30), + backButton.heightAnchor.constraint(equalToConstant: 30), ] NSLayoutConstraint.activate(backButtonConstraints) From d3b859b32ab72a2b8e16d8f38c27bb1c10100f44 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 16 Nov 2021 13:11:27 +0900 Subject: [PATCH 203/465] =?UTF-8?q?[Feat]=20#177=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Cell=EC=95=88=EC=9D=98=20content=EB=93=A4?= =?UTF-8?q?=20stackView=EB=A1=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 28 +++++++++++-------- .../SettingsScene/ToggleOptionCell.swift | 26 +++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 7d125ca..046eb44 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -11,6 +11,15 @@ class MapOptionCell: UITableViewCell { static let identifier = "MapOptionCell" + private var stackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.alignment = .center + stackView.distribution = .equalCentering + return stackView + }() + private(set) var title: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .caption1) @@ -63,20 +72,17 @@ class MapOptionCell: UITableViewCell { } private func configureView() { - self.contentView.addSubview(self.title) + self.stackView.addArrangedSubview(self.title) + self.stackView.addArrangedSubview(self.map) + + self.contentView.addSubview(self.stackView) let locationConstrain = [ - self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), - self.title.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), + self.stackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -15), + self.stackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), ] NSLayoutConstraint.activate(locationConstrain) - - self.contentView.addSubview(self.map) - let mapConstrain = [ - self.map.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), - self.map.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), - self.map.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 10), - ] - NSLayoutConstraint.activate(mapConstrain) } func update(option: MapOption) { diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index eebd4bb..42726e7 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -17,6 +17,14 @@ class ToggleOptionCell: UITableViewCell { weak var delegate: ToggleOptionCellDelegate? + private var stackView: UIStackView = { + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.alignment = .center + return stackView + }() + private var title: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .caption1) @@ -70,21 +78,17 @@ class ToggleOptionCell: UITableViewCell { } private func configureView() { + self.stackView.addArrangedSubview(self.title) + self.stackView.addArrangedSubview(self.controlSwitch) - self.contentView.addSubview(self.title) + self.contentView.addSubview(self.stackView) let locationConstrain = [ - self.title.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), - self.title.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), + self.stackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -15), + self.stackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), + self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), ] NSLayoutConstraint.activate(locationConstrain) - - self.contentView.addSubview(self.controlSwitch) - let switchConstrain = [ - self.controlSwitch.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), - self.controlSwitch.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), - self.controlSwitch.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 10), - ] - NSLayoutConstraint.activate(switchConstrain) } func update(option: ToggleOption) { From ca193437637d1c64599020dbaa6a60a7e14c3a2b Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 16 Nov 2021 13:12:43 +0900 Subject: [PATCH 204/465] =?UTF-8?q?[Feat]=20#177=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Cell=EC=95=88=EC=9D=98=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=ED=81=AC=EA=B8=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 4 ++-- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 046eb44..ff16185 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -22,7 +22,7 @@ class MapOptionCell: UITableViewCell { private(set) var title: UILabel = { let label = UILabel() - label.font = UIFont.preferredFont(forTextStyle: .caption1) + label.font = UIFont.preferredFont(forTextStyle: .body) label.adjustsFontForContentSizeCategory = true label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 @@ -35,7 +35,7 @@ class MapOptionCell: UITableViewCell { private var map: UILabel = { let label = PaddingLabel() label.padding(top: 5, bottom: 5, left: 10, right: 10) - label.font = UIFont.preferredFont(forTextStyle: .caption2) + label.font = UIFont.preferredFont(forTextStyle: .caption1) label.adjustsFontForContentSizeCategory = true label.textColor = .white label.backgroundColor = .darkGray diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 42726e7..5e58f45 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -27,7 +27,7 @@ class ToggleOptionCell: UITableViewCell { private var title: UILabel = { let label = UILabel() - label.font = UIFont.preferredFont(forTextStyle: .caption1) + label.font = UIFont.preferredFont(forTextStyle: .body) label.adjustsFontForContentSizeCategory = true label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 From 3b00dfb2c4a30718b6996291d0ec6f9da3295ec5 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 16 Nov 2021 13:22:52 +0900 Subject: [PATCH 205/465] =?UTF-8?q?[Feat]=20#177=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Cell=20=EB=82=B4=EC=9A=A9=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 2 +- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index ff16185..829b0d4 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -38,7 +38,7 @@ class MapOptionCell: UITableViewCell { label.font = UIFont.preferredFont(forTextStyle: .caption1) label.adjustsFontForContentSizeCategory = true label.textColor = .white - label.backgroundColor = .darkGray + label.backgroundColor = UIColor(named: "SantaColor") label.translatesAutoresizingMaskIntoConstraints = false label.clipsToBounds = true label.layer.cornerRadius = 5 diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 5e58f45..a9a2ff0 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -41,7 +41,7 @@ class ToggleOptionCell: UITableViewCell { let controlSwitch = UISwitch() controlSwitch.translatesAutoresizingMaskIntoConstraints = false controlSwitch.addTarget(self, action: #selector(onClickSwitch(sender:)), for: .valueChanged) - controlSwitch.onTintColor = .systemBlue + controlSwitch.onTintColor = UIColor(named: "SantaColor") controlSwitch.setContentCompressionResistancePriority(.init(rawValue: 1000), for: .horizontal) return controlSwitch }() From 82810256696f3ac454b5706cd805b2cd794237bc Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 13:49:15 +0900 Subject: [PATCH 206/465] =?UTF-8?q?[Feat]=20#178=20DispatchGroup=20enter,?= =?UTF-8?q?=20leave=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 7f44dee..89a65fe 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -20,6 +20,7 @@ final class RecordingPhotoModel { let dispatchGroup = DispatchGroup() var photos = [Photo]() + dispatchGroup.enter() for i in stride(from: allMedia.count - 1, through: 0, by: -1) { let asset = allMedia[i] if asset.creationDate == nil || asset.location == nil { @@ -48,6 +49,7 @@ final class RecordingPhotoModel { } } + dispatchGroup.leave() dispatchGroup.notify(queue: .global()) { completion(photos) } From f6a27e118ef46214648cdad090a56c858cf2f49b Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 14:07:32 +0900 Subject: [PATCH 207/465] =?UTF-8?q?[Feat]=20=ED=8C=A8=EB=94=A9=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=82=B0?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=ED=8C=A8=EB=94=A9=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 --- .../MountainDetailCategoryLabel.swift | 29 ------------------- .../MountainDetailTableViewCell.swift | 2 +- SanTa/SanTa/SettingsScene/PaddingLabel.swift | 5 ++++ 4 files changed, 6 insertions(+), 34 deletions(-) delete mode 100644 SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 0b58224..edd320d 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; - 49450A4D274205040062CD51 /* MountainDetailCategoryLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */; }; 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; @@ -99,7 +98,6 @@ /* Begin PBXFileReference section */ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; - 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailCategoryLabel.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; @@ -256,7 +254,6 @@ 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, - 49450A4C274205040062CD51 /* MountainDetailCategoryLabel.swift */, 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */, ); path = MountainDetailScene; @@ -515,7 +512,6 @@ 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, - 49450A4D274205040062CD51 /* MountainDetailCategoryLabel.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */, diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift deleted file mode 100644 index f7edea7..0000000 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailCategoryLabel.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// MountainDetailCategoryLabel.swift -// SanTa -// -// Created by Jiwon Yoon on 2021/11/15. -// 출처: https://ios-development.tistory.com/698 - -import UIKit - -class MountainDetailCategoryLabel: UILabel { - private var defaultPadding = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3) - - convenience init(padding: UIEdgeInsets) { - self.init() - self.defaultPadding = padding - } - - override func drawText(in rect: CGRect) { - super.drawText(in: rect.inset(by: defaultPadding)) - } - - override var intrinsicContentSize: CGSize { - var contentSize = super.intrinsicContentSize - contentSize.height += defaultPadding.top + defaultPadding.bottom - contentSize.width += defaultPadding.left + defaultPadding.right - - return contentSize - } -} diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index 3e59a1c..fc069af 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -10,7 +10,7 @@ import UIKit class MountainDetailTableViewCell: UITableViewCell { static let identifier = "MountainDetailTableViewCellID" - let categoryLabel = MountainDetailCategoryLabel() + let categoryLabel = PaddingLabel(insets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) let contentLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { diff --git a/SanTa/SanTa/SettingsScene/PaddingLabel.swift b/SanTa/SanTa/SettingsScene/PaddingLabel.swift index 7304f09..aec34d3 100644 --- a/SanTa/SanTa/SettingsScene/PaddingLabel.swift +++ b/SanTa/SanTa/SettingsScene/PaddingLabel.swift @@ -10,6 +10,11 @@ import UIKit class PaddingLabel: UILabel { var insets = UIEdgeInsets.zero + + convenience init(insets: UIEdgeInsets) { + self.init() + self.padding(top: insets.top, bottom: insets.bottom, left: insets.left, right: insets.right) + } override func drawText(in rect: CGRect) { super.drawText(in: rect.inset(by: self.insets)) From 026f28839272d4a062b9e58503638687ffe9d7c5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 14:14:13 +0900 Subject: [PATCH 208/465] =?UTF-8?q?[Feat]=20#178=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=EB=A5=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4?= =?UTF-8?q?=EB=8A=94=20=EA=B5=AC=EC=A1=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 11 +++--- .../SanTa/RecordingScene/RecordingModel.swift | 2 +- .../RecordingScene/RecordingPhotoModel.swift | 37 +++---------------- .../RecordingScene/RecordingUseCase.swift | 26 ++++++------- SanTa/SanTa/ResultScene/ResultUseCase.swift | 2 +- 5 files changed, 25 insertions(+), 53 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index ef0f9ff..76be554 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -95,6 +95,7 @@ class DateSeperateRecords { struct Records { private(set) var title: String private(set) var records: [Record] + private(set) var assetIdentifiers: [String] var date: Date? { return records.last?.endTime @@ -121,6 +122,10 @@ struct Records { self.title = title } + mutating func configurePhoto(assetIdentifiers: [String]) { + self.assetIdentifiers = assetIdentifiers + } + mutating func add(record: Record) { self.records.append(record) } @@ -149,9 +154,3 @@ struct Location { let longitude: Double let altitude: Double } - -struct Photo { - let latitude: Double - let longitude: Double - let date: Data -} diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 39ffcf1..a8e639b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -150,7 +150,7 @@ final class RecordingModel: NSObject, ObservableObject { locations: self.location) guard self.records != nil else { - self.records = Records(title: "", records: [record]) + self.records = Records(title: "", records: [record], assetIdentifiers: [String]()) return } diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 89a65fe..dc8d253 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -15,32 +15,23 @@ final class RecordingPhotoModel { var representedAssetIdentifier: String? - func fetchPhotos(startDate: Date, endDate: Date, completion: @escaping ([Photo]?) -> Void){ + func fetchPhotos(startDate: Date, endDate: Date) -> [String]? { let allMedia = PHAsset.fetchAssets(with: .image, options: nil) - let dispatchGroup = DispatchGroup() - var photos = [Photo]() + var assetIdentifiers = [String]() - dispatchGroup.enter() for i in stride(from: allMedia.count - 1, through: 0, by: -1) { let asset = allMedia[i] if asset.creationDate == nil || asset.location == nil { continue } - guard let creationDate = asset.creationDate, - let location = asset.location else { return } + guard let creationDate = asset.creationDate else { return nil } switch startDate.compare(creationDate) { case .orderedDescending, .orderedSame: switch endDate.compare(creationDate) { case .orderedAscending, .orderedSame: - dispatchGroup.enter() - requestIamge(with: asset) { (image) in - guard let image = image else { return } - let photo = Photo(latitude: Double(location.coordinate.latitude), longitude: Double(location.coordinate.longitude), date: image) - photos.append(photo) - dispatchGroup.leave() - } + assetIdentifiers.append(asset.localIdentifier) case .orderedDescending: break } @@ -49,24 +40,6 @@ final class RecordingPhotoModel { } } - dispatchGroup.leave() - dispatchGroup.notify(queue: .global()) { - completion(photos) - } - } - - func requestIamge(with asset: PHAsset?, completion: @escaping (Data?) -> Void) { - guard let asset = asset else { - completion(nil) - return - } - - self.representedAssetIdentifier = asset.localIdentifier - - self.imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, str, orientation, info in - if self.representedAssetIdentifier == asset.localIdentifier { - completion(data) - } - }) + return assetIdentifiers } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 816430e..8420b84 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -11,7 +11,7 @@ protocol RecordingUseCase { var recording: RecordingModel { get set } func save(title: String, completion: @escaping (Result) -> Void) - func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Photo]?) -> Void) + func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] func pause() func resume() } @@ -41,25 +41,25 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { completion(.failure(CoreDataError.coreDataError)) return } + + let asset = self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) + records.configureTitle(title: title) - self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) { [weak self] images in - self?.recordRepository.save(records: records, completion: completion) - } + records.configurePhoto(assetIdentifiers: asset) + + self.recordRepository.save(records: records, completion: completion) } - func fetchPhotos(startDate: Date?, endDate: Date?, completionFetchImages: @escaping ([Photo]?) -> Void) { + func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] { guard let startDate = startDate, let endDate = endDate else { - completionFetchImages(nil) - return + return [String]() } - self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) { images in - guard let images = images else { - completionFetchImages(nil) - return - } - completionFetchImages(images) + guard let assets = self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) else { + return [String]() } + + return assets } } diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index 2ddb75c..9e6c5b1 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -47,7 +47,7 @@ final class ResultUseCase { guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } records.append(record) } - return Records(title: title, records: records) + return Records(title: title, records: records, assetIdentifiers: [String]()) } private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { From 165ea4d439102909a7d19a6d856436bfe4b47fba Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 14:30:07 +0900 Subject: [PATCH 209/465] =?UTF-8?q?[Feat]=20#162=20CoreData=20Record=20Ent?= =?UTF-8?q?ity=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 5209325..328f708 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -7,6 +7,7 @@ + @@ -20,7 +21,7 @@ - + \ No newline at end of file From 4bc38c5d588e60920009a24feae08092d71f8990 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 14:38:12 +0900 Subject: [PATCH 210/465] =?UTF-8?q?[Feat]=20#162=20=EC=95=A8=EB=B2=94?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B0=80=EC=A0=B8=EC=98=A8=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=EC=9D=84=20CoreData=EC=97=90=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Persistences/CoreDataRecordStorage.swift | 8 ++++++++ .../SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index d777f82..5134b5c 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -29,6 +29,14 @@ final class CoreDataRecordStorage: RecordsStorage { recordsObject.setValue(records.title, forKey: "title") + do { + let assetIdentifiers = try NSKeyedArchiver.archivedData(withRootObject: records.assetIdentifiers, requiringSecureCoding: true) + + recordsObject.setValue(assetIdentifiers, forKey: "assetIdentifiers") + } catch { + completion(.failure(CoreDataError.coreDataError)) + } + records.records.forEach { let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", into: context) as? RecordEntityMO diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 328f708..15ce1ec 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -7,7 +7,6 @@ - @@ -16,12 +15,13 @@ + - - + + \ No newline at end of file From 27aada226272a2aee90f4c2a4fd29da3069049f6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 14:48:50 +0900 Subject: [PATCH 211/465] =?UTF-8?q?[Feat]=20#179=20=ED=98=84=EC=9E=AC=20GP?= =?UTF-8?q?S=20=EC=83=81=ED=83=9C=20ViewModel=20Model=20Binding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index a8e639b..145e8f5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -15,6 +15,7 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @Published private(set) var walk = "" + @Published private(set) var gpsStatus = true private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() @@ -203,7 +204,6 @@ extension RecordingModel: CLLocationManagerDelegate { } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - // GPS를 켜지 않았을 경우 - print(error) + self.gpsStatus = false } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index e1aa200..d230a50 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -13,6 +13,7 @@ final class RecordingViewModel: ObservableObject { @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @Published private(set) var walk = "" + @Published private(set) var gpsStatus = true private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() @@ -50,6 +51,13 @@ final class RecordingViewModel: ObservableObject { self?.walk = walk }) .store(in: &self.subscriptions) + + self.recordingUseCase?.recording.$gpsStatus + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] gpsStatus in + self?.gpsStatus = gpsStatus + }) + .store(in: &self.subscriptions) } func pause() { From 3712bab3e1f699f323348ce9a38d535b6c5303e7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 14:57:23 +0900 Subject: [PATCH 212/465] [Feat] #181 Controller ViewModel Binding --- .../RecordingViewController.swift | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 5f7d87a..951eacd 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -136,6 +136,19 @@ class RecordingViewController: UIViewController { self?.walkLabel.text = walk }) .store(in: &self.subscriptions) + + self.recordingViewModel?.$gpsStatus + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] gpsStatus in + if gpsStatus != self?.currentState { + if gpsStatus == false { + self?.changeRecordingStatus() + } else { + self?.changeRecordingStatus() + } + } + }) + .store(in: &self.subscriptions) } private func configureTarget() { @@ -159,7 +172,7 @@ class RecordingViewController: UIViewController { } } - @objc private func pauseButtonAction(_ sender: UIResponder) { + private func changeRecordingStatus() { if currentState { self.view.backgroundColor = .black var pauseConfiguration = UIButton.Configuration.plain() @@ -179,6 +192,10 @@ class RecordingViewController: UIViewController { } } + @objc private func pauseButtonAction(_ sender: UIResponder) { + changeRecordingStatus() + } + @objc private func stopButtonAction(_ sender: UIResponder) { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) From 6e363faf7da60d91a7035af1b4a36482439f6590 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 15:17:08 +0900 Subject: [PATCH 213/465] =?UTF-8?q?[Refactor]=20checkPedoMeter=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 48 +++++++------------ .../RecordingViewController.swift | 20 +++++--- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 145e8f5..25c60b2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -16,6 +16,7 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" @Published private(set) var gpsStatus = true + @Published private(set) var gpsAuth = true private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() @@ -87,42 +88,18 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkPedoMeter() { - guard let date = self.startDate else { return } + guard let date = self.startDate, + let records = records else { return } + var dates = records.records + dates.append(Record(startTime: date, endTime: self.currentTime, step: 0, distance: 0, locations: [Location]())) + let dispatchGroup = DispatchGroup() self.currentWalk = 0 self.currentKilo = 0 dispatchGroup.enter() - self.pedoMeter.queryPedometerData(from: date, to: self.currentTime) { [weak self] data, error in - guard let activityData = data, - error == nil else { return } - - let walk = "\(activityData.numberOfSteps)" - - guard let walkNumber = Int(walk) else { return } - - self?.currentWalk += walkNumber - - guard let distance = activityData.distance else { return } - let transformatKilometer = Double(truncating: distance) / 1000 - self?.currentKilo += transformatKilometer - dispatchGroup.leave() - } - - dispatchGroup.notify(queue: .main) { [weak self] in - guard let walk = self?.currentWalk else { return } - - self?.walk = "\(walk)" - guard let currentKile = self?.currentKilo else { return } - let distanceString = String(format: "%.2f", currentKile) - - self?.kilometer = "\(distanceString)" - } - - guard let records = records else { return } - - records.records.forEach { + dates.forEach { dispatchGroup.enter() self.pedoMeter.queryPedometerData(from: $0.startTime, to: $0.endTime) { [weak self] data, error in guard let activityData = data, @@ -140,6 +117,17 @@ final class RecordingModel: NSObject, ObservableObject { dispatchGroup.leave() } } + dispatchGroup.leave() + + dispatchGroup.notify(queue: .main) { [weak self] in + guard let walk = self?.currentWalk else { return } + + self?.walk = "\(walk)" + guard let currentKile = self?.currentKilo else { return } + let distanceString = String(format: "%.2f", currentKile) + + self?.kilometer = "\(distanceString)" + } } private func appendRecord() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 951eacd..bd5905d 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -141,11 +141,7 @@ class RecordingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] gpsStatus in if gpsStatus != self?.currentState { - if gpsStatus == false { - self?.changeRecordingStatus() - } else { - self?.changeRecordingStatus() - } + self?.changeRecordingStatus() } }) .store(in: &self.subscriptions) @@ -192,8 +188,20 @@ class RecordingViewController: UIViewController { } } + private func authAlert() -> UIAlertController { + let alert = UIAlertController(title: "위치정보 활성화", message: "측정을 다시 시작할 수 있도록 위치정보를 활성화해주세요.", preferredStyle: .alert) + let cancel = UIAlertAction(title: "아니요", style: .cancel) + let confirm = UIAlertAction(title: "활성화", style: .default) { _ in + guard let url = URL(string: UIApplication.openSettingsURLString) else { return } + UIApplication.shared.open(url) + } + alert.addAction(cancel) + alert.addAction(confirm) + return alert + } + @objc private func pauseButtonAction(_ sender: UIResponder) { - changeRecordingStatus() + } @objc private func stopButtonAction(_ sender: UIResponder) { From e53105c00f501ad169986e74679fd4ba4d036531 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 15:18:44 +0900 Subject: [PATCH 214/465] =?UTF-8?q?[Refactor]=20main=20->=20global=20?= =?UTF-8?q?=EC=8A=A4=EB=A0=88=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 25c60b2..759085b 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -43,7 +43,7 @@ final class RecordingModel: NSObject, ObservableObject { } private func configureTimer() { - self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main) + self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global()) self.timer?.schedule(deadline: .now(), repeating: 1) self.timer?.setEventHandler(handler: { [weak self] in self?.currentTime = Date() @@ -119,7 +119,7 @@ final class RecordingModel: NSObject, ObservableObject { } dispatchGroup.leave() - dispatchGroup.notify(queue: .main) { [weak self] in + dispatchGroup.notify(queue: .global()) { [weak self] in guard let walk = self?.currentWalk else { return } self?.walk = "\(walk)" From 62cede5124e56bce4a068ce8cd52facacee4f3b6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 15:27:31 +0900 Subject: [PATCH 215/465] =?UTF-8?q?[Feat]=20#180,=20#181=20Current=20Statu?= =?UTF-8?q?s=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20ViewModel=20Model=20?= =?UTF-8?q?Binding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 759085b..bf5d51e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -11,6 +11,7 @@ import CoreMotion import Combine final class RecordingModel: NSObject, ObservableObject { + @Published private(set) var currentStatus = true @Published private(set) var time = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index bd5905d..37da423 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -201,7 +201,7 @@ class RecordingViewController: UIViewController { } @objc private func pauseButtonAction(_ sender: UIResponder) { - + changeRecordingStatus() } @objc private func stopButtonAction(_ sender: UIResponder) { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index d230a50..c758320 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -9,6 +9,7 @@ import Foundation import Combine final class RecordingViewModel: ObservableObject { + @Published private(set) var currentStatus = true @Published private(set) var currentTime = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @@ -24,6 +25,13 @@ final class RecordingViewModel: ObservableObject { } private func configureBindings() { + self.recordingUseCase?.recording.currentStatus + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] currentStatus in + self?.currentStatus = currentStatus + }) + .store(in: &self.subscriptions) + self.recordingUseCase?.recording.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in From 556814ac46e4e9a96c9afc13efa8df67822cfcee Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 16 Nov 2021 15:29:17 +0900 Subject: [PATCH 216/465] =?UTF-8?q?[Refacter]=20#177=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Cell=20=EB=A6=AC=ED=8E=99=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 38 ++++++------------- .../SettingsScene/ToggleOptionCell.swift | 35 +++++------------ 2 files changed, 20 insertions(+), 53 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 829b0d4..93862a9 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -10,16 +10,7 @@ import UIKit class MapOptionCell: UITableViewCell { static let identifier = "MapOptionCell" - - private var stackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .horizontal - stackView.alignment = .center - stackView.distribution = .equalCentering - return stackView - }() - + private(set) var title: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body) @@ -48,6 +39,16 @@ class MapOptionCell: UITableViewCell { return label }() + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.title, self.map]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.alignment = .center + stackView.distribution = .equalCentering + return stackView + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.configureView() @@ -56,25 +57,8 @@ class MapOptionCell: UITableViewCell { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - - override var frame: CGRect { - get { - return super.frame - } - set (newFrame) { - var frame = newFrame - let newWidth = frame.width * 0.90 - let space = (frame.width - newWidth) / 2 - frame.size.width = newWidth - frame.origin.x += space - super.frame = frame - } - } private func configureView() { - self.stackView.addArrangedSubview(self.title) - self.stackView.addArrangedSubview(self.map) - self.contentView.addSubview(self.stackView) let locationConstrain = [ self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index a9a2ff0..878f87d 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -17,14 +17,6 @@ class ToggleOptionCell: UITableViewCell { weak var delegate: ToggleOptionCellDelegate? - private var stackView: UIStackView = { - let stackView = UIStackView() - stackView.translatesAutoresizingMaskIntoConstraints = false - stackView.axis = .horizontal - stackView.alignment = .center - return stackView - }() - private var title: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body) @@ -46,6 +38,14 @@ class ToggleOptionCell: UITableViewCell { return controlSwitch }() + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.title, self.controlSwitch]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .horizontal + stackView.alignment = .center + return stackView + }() + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none @@ -55,21 +55,7 @@ class ToggleOptionCell: UITableViewCell { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - - override var frame: CGRect { - get { - return super.frame - } - set (newFrame) { - var frame = newFrame - let newWidth = frame.width * 0.90 - let space = (frame.width - newWidth) / 2 - frame.size.width = newWidth - frame.origin.x += space - super.frame = frame - } - } - + @objc func onClickSwitch(sender: UISwitch) { guard let title = self.title.text else { return } self.delegate?.toggleOptionCellSwitchChanged(self, @@ -78,9 +64,6 @@ class ToggleOptionCell: UITableViewCell { } private func configureView() { - self.stackView.addArrangedSubview(self.title) - self.stackView.addArrangedSubview(self.controlSwitch) - self.contentView.addSubview(self.stackView) let locationConstrain = [ self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), From 62c1344cde54c00afa06e3c35040f4afc05b8edb Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 15:40:34 +0900 Subject: [PATCH 217/465] =?UTF-8?q?[Feat]=20#179,=20#180,=20#181=20Alert?= =?UTF-8?q?=20=EB=9D=84=EC=9A=B0=EA=B8=B0=20GPS=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=84=98=EC=96=B4=EA=B0=80=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 3 +-- .../RecordingScene/RecordingViewController.swift | 6 ++++++ .../RecordingScene/RecordingViewModel.swift | 16 ++++++++-------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index bf5d51e..df51360 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -11,7 +11,6 @@ import CoreMotion import Combine final class RecordingModel: NSObject, ObservableObject { - @Published private(set) var currentStatus = true @Published private(set) var time = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @@ -118,8 +117,8 @@ final class RecordingModel: NSObject, ObservableObject { dispatchGroup.leave() } } - dispatchGroup.leave() + dispatchGroup.leave() dispatchGroup.notify(queue: .global()) { [weak self] in guard let walk = self?.currentWalk else { return } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 37da423..482aa67 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -141,6 +141,12 @@ class RecordingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] gpsStatus in if gpsStatus != self?.currentState { + if !gpsStatus { + guard let alert = self?.authAlert() else { return } + DispatchQueue.main.async { + self?.present(alert, animated: false) + } + } self?.changeRecordingStatus() } }) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index c758320..6b65b37 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -9,12 +9,12 @@ import Foundation import Combine final class RecordingViewModel: ObservableObject { - @Published private(set) var currentStatus = true @Published private(set) var currentTime = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @Published private(set) var walk = "" @Published private(set) var gpsStatus = true + private(set) var gpsAuth = true private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() @@ -25,13 +25,6 @@ final class RecordingViewModel: ObservableObject { } private func configureBindings() { - self.recordingUseCase?.recording.currentStatus - .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] currentStatus in - self?.currentStatus = currentStatus - }) - .store(in: &self.subscriptions) - self.recordingUseCase?.recording.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in @@ -66,6 +59,13 @@ final class RecordingViewModel: ObservableObject { self?.gpsStatus = gpsStatus }) .store(in: &self.subscriptions) + + self.recordingUseCase?.recording.$gpsAuth + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] gpsAuth in + self?.gpsAuth = gpsAuth + }) + .store(in: &self.subscriptions) } func pause() { From 70ecdd2ccfdde94a0cff25c694c298840f5e39ed Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 15:42:00 +0900 Subject: [PATCH 218/465] =?UTF-8?q?[Refactor]=20#182=20=EA=B3=A0=EB=8F=84?= =?UTF-8?q?=EC=B0=A8=20=EA=B3=84=EC=82=B0=20=EB=A6=AC=ED=8E=99=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index ef0f9ff..6c4cef8 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -113,8 +113,12 @@ struct Records { } var maxAltitudeDifference: Double { - let max = records.max { $0.altitudeDifference < $1.altitudeDifference } - return (max?.altitudeDifference ?? 0) + guard let max = records.compactMap({ $0.maxAltitude }).max(), + let min = records.compactMap({ $0.minAltitude }).min() + else { + return 0 + } + return max - min } mutating func configureTitle(title: String) { @@ -137,10 +141,12 @@ struct Record { return endTime.timeIntervalSinceReferenceDate - startTime.timeIntervalSinceReferenceDate } - var altitudeDifference: Double { - let min = locations.min { $0.altitude < $1.altitude } - let max = locations.max { $0.altitude < $1.altitude } - return (max?.altitude ?? 0) - (min?.altitude ?? 0) + var minAltitude: Double? { + return locations.map{ $0.altitude }.min() + } + + var maxAltitude: Double? { + return locations.map{ $0.altitude }.max() } } From f12c7777efab034cf0cfd5cb75836b154db6498c Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 16:03:29 +0900 Subject: [PATCH 219/465] =?UTF-8?q?[Fix]=20PedoMeter=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 24 +++++++++++++++---- .../RecordingScene/RecordingViewModel.swift | 8 ------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index df51360..35f61a2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -16,7 +16,6 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" @Published private(set) var gpsStatus = true - @Published private(set) var gpsAuth = true private let pedoMeter = CMPedometer() private var locationManager = CLLocationManager() @@ -88,9 +87,13 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkPedoMeter() { - guard let date = self.startDate, - let records = records else { return } - var dates = records.records + guard let date = self.startDate else { return } + var dates = [Record]() + if records != nil { + guard let records = records else { return } + dates = records.records + } + dates.append(Record(startTime: date, endTime: self.currentTime, step: 0, distance: 0, locations: [Location]())) let dispatchGroup = DispatchGroup() @@ -146,6 +149,15 @@ final class RecordingModel: NSObject, ObservableObject { self.records?.add(record: record) } + private func checkAuthorizationStatus() { + switch self.locationManager.authorizationStatus{ + case .authorizedWhenInUse, .authorizedAlways: + self.gpsStatus = true + default: + self.gpsStatus = false + } + } + func pause() { guard self.timerIsRunning == true else { return } @@ -159,6 +171,10 @@ final class RecordingModel: NSObject, ObservableObject { func resume() { guard self.timerIsRunning == false else { return } + self.checkAuthorizationStatus() + + guard self.gpsStatus == true else { return } + self.timerIsRunning = true self.timer?.resume() self.locationManager.startUpdatingLocation() diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 6b65b37..d230a50 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -14,7 +14,6 @@ final class RecordingViewModel: ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" @Published private(set) var gpsStatus = true - private(set) var gpsAuth = true private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() @@ -59,13 +58,6 @@ final class RecordingViewModel: ObservableObject { self?.gpsStatus = gpsStatus }) .store(in: &self.subscriptions) - - self.recordingUseCase?.recording.$gpsAuth - .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] gpsAuth in - self?.gpsAuth = gpsAuth - }) - .store(in: &self.subscriptions) } func pause() { From 24e406121273a4ab58f9e7914eab03a49a2aa2e1 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 16:07:30 +0900 Subject: [PATCH 220/465] =?UTF-8?q?[Refactor]=20#184=20=EB=B0=98=EB=B3=B5?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EB=A6=AC=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 35 ++++++++----------- .../ResultScene/TotalRecordsViewCell.swift | 14 +++----- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index 539e51e..6f6579a 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -23,7 +23,7 @@ extension UILabel { class RecordsViewCell: UICollectionViewCell { static let identifier = "RecordsViewCell" - var date: PaddingLabel = { + let date: PaddingLabel = { let paddingLabel = PaddingLabel() paddingLabel.padding(top: 2, bottom: 2, left: 3, right: 3) paddingLabel.backgroundColor = UIColor(named: "SantaColor") @@ -33,19 +33,19 @@ class RecordsViewCell: UICollectionViewCell { paddingLabel.clipsToBounds = true return paddingLabel }() - let horizontalStackView = UIStackView() - let distanceStackView = UIStackView() let distance = UILabel(boldFontWithSize: 20) - let distanceLabel = UILabel(text: "거리", normalFontWithSize: 15) - let timeStackView = UIStackView() let time = UILabel(boldFontWithSize: 20) - let timeLabel = UILabel(text: "시간", normalFontWithSize: 15) - let altitudeStackView = UIStackView() let altitude = UILabel(boldFontWithSize: 20) - let altitudeLabel = UILabel(text: "고도차", normalFontWithSize: 15) - let stepsStackView = UIStackView() let steps = UILabel(boldFontWithSize: 20) + let distanceLabel = UILabel(text: "거리", normalFontWithSize: 15) + let timeLabel = UILabel(text: "시간", normalFontWithSize: 15) + let altitudeLabel = UILabel(text: "고도차", normalFontWithSize: 15) let stepsLabel = UILabel(text: "걸음", normalFontWithSize: 15) + let horizontalStackView = UIStackView() + let distanceStackView = UIStackView() + let timeStackView = UIStackView() + let altitudeStackView = UIStackView() + let stepsStackView = UIStackView() func configure(date: String, distance: String, time: String, altitude: String, steps: String) { self.date.text = date @@ -63,30 +63,23 @@ class RecordsViewCell: UICollectionViewCell { self.addSubview(horizontalStackView) self.horizontalStackView.distribution = .fillEqually self.horizontalStackView.axis = .horizontal - self.distanceStackView.axis = .vertical - self.distanceStackView.alignment = .center - self.timeStackView.axis = .vertical - self.timeStackView.alignment = .center - self.altitudeStackView.axis = .vertical - self.altitudeStackView.alignment = .center - self.stepsStackView.axis = .vertical - self.stepsStackView.alignment = .center self.horizontalStackView.addArrangedSubview(distanceStackView) self.horizontalStackView.addArrangedSubview(timeStackView) self.horizontalStackView.addArrangedSubview(altitudeStackView) self.horizontalStackView.addArrangedSubview(stepsStackView) - self.distanceStackView.spacing = 5 self.distanceStackView.addArrangedSubview(distance) self.distanceStackView.addArrangedSubview(distanceLabel) - self.timeStackView.spacing = 5 self.timeStackView.addArrangedSubview(time) self.timeStackView.addArrangedSubview(timeLabel) - self.altitudeStackView.spacing = 5 self.altitudeStackView.addArrangedSubview(altitude) self.altitudeStackView.addArrangedSubview(altitudeLabel) - self.stepsStackView.spacing = 5 self.stepsStackView.addArrangedSubview(steps) self.stepsStackView.addArrangedSubview(stepsLabel) + [self.distanceStackView, self.timeStackView, self.altitudeStackView, self.stepsStackView].forEach { + $0.axis = .vertical + $0.alignment = .center + $0.spacing = 5 + } } private func configureLayout() { diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index 46955bf..f9fee05 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -56,21 +56,17 @@ class TotalRecordsViewCell: UICollectionViewCell { self.horizontalStackView.addArrangedSubview(stepsVerticalStackView) self.horizontalStackView.axis = .horizontal self.horizontalStackView.distribution = .fillEqually - self.countVerticalStackView.axis = .vertical - self.countVerticalStackView.alignment = .center - self.countVerticalStackView.spacing = 5 - self.timeVerticalStackView.axis = .vertical - self.timeVerticalStackView.alignment = .center - self.timeVerticalStackView.spacing = 5 - self.stepsVerticalStackView.axis = .vertical - self.stepsVerticalStackView.alignment = .center - self.stepsVerticalStackView.spacing = 5 self.countVerticalStackView.addArrangedSubview(countNumber) self.countVerticalStackView.addArrangedSubview(count) self.timeVerticalStackView.addArrangedSubview(timeNumber) self.timeVerticalStackView.addArrangedSubview(time) self.stepsVerticalStackView.addArrangedSubview(stepsNumber) self.stepsVerticalStackView.addArrangedSubview(steps) + [self.countVerticalStackView, self.timeVerticalStackView, self.stepsVerticalStackView].forEach { + $0.axis = .vertical + $0.alignment = .center + $0.spacing = 5 + } } private func configureLayout() { From 6dd248b8f04bbc6528ffc35edd9faacb2f040e6a Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 16:18:36 +0900 Subject: [PATCH 221/465] =?UTF-8?q?[Feature]=20#186=20=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=83=89=EC=83=81,=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=84=B0=EC=B9=98=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 4 ++-- SanTa/SanTa/MapScene/UIImage+Gif.swift | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 1b0f875..22815c8 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -104,7 +104,7 @@ class MapViewController: UIViewController { ] NSLayoutConstraint.activate(startButtonConstraints) - self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchUpInside) + self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) self.userTrackingButton = .init(mapView: mapView) self.view.addSubview(self.userTrackingButton) @@ -206,7 +206,7 @@ class MapViewController: UIViewController { extension MapViewController: Animatable { func shouldAnimate() { - let image = UIImage.gifImage(named: "walkingManAnimation") + let image = UIImage.gifImage(named: "walkingManAnimation", withTintColor: .white) self.startButton.setImage(image, for: .normal) } diff --git a/SanTa/SanTa/MapScene/UIImage+Gif.swift b/SanTa/SanTa/MapScene/UIImage+Gif.swift index 633f7d4..8c95402 100644 --- a/SanTa/SanTa/MapScene/UIImage+Gif.swift +++ b/SanTa/SanTa/MapScene/UIImage+Gif.swift @@ -7,23 +7,26 @@ // 참고: https://github.com/kiritmodi2702/GIF-Swift/blob/master/GIF-Swift/iOSDevCenters%2BGIF.swift import UIKit -import ImageIO extension UIImage { - class func gifImage(named: String) -> UIImage? { + class func gifImage(named: String, withTintColor: UIColor? = nil) -> UIImage? { guard let bundleURL = Bundle.main.url(forResource: named, withExtension: "gif"), let imageData = try? Data(contentsOf: bundleURL), let source = CGImageSourceCreateWithData(imageData as CFData, nil) else { return nil } - return UIImage.animatedImageWithSource(source) + return UIImage.animatedImageWithSource(source, withTintColor: withTintColor) } - private class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? { + private class func animatedImageWithSource(_ source: CGImageSource, withTintColor: UIColor?) -> UIImage? { let count: Int = CGImageSourceGetCount(source) let images: [UIImage] = (0.. Date: Tue, 16 Nov 2021 16:20:54 +0900 Subject: [PATCH 222/465] =?UTF-8?q?[Fix]=20=EC=95=A8=EB=B2=94=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=20=ED=97=88=EC=9A=A9=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordingViewController.swift | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 482aa67..f3846b1 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -142,7 +142,9 @@ class RecordingViewController: UIViewController { .sink (receiveValue: { [weak self] gpsStatus in if gpsStatus != self?.currentState { if !gpsStatus { - guard let alert = self?.authAlert() else { return } + let title = "위치정보 활성화" + let message = "측정을 다시 시작할 수 있도록 위치정보를 활성화해주세요." + guard let alert = self?.authAlert(title: title, message: message) else { return } DispatchQueue.main.async { self?.present(alert, animated: false) } @@ -163,11 +165,7 @@ class RecordingViewController: UIViewController { let status = PHPhotoLibrary.authorizationStatus(for: .readWrite) switch status{ - case .authorized: - break - case .denied: - self.coordinator?.presentRecordingPhotoViewController() - case .restricted, .notDetermined: + case .notDetermined: self.coordinator?.presentRecordingPhotoViewController() default: break @@ -194,8 +192,8 @@ class RecordingViewController: UIViewController { } } - private func authAlert() -> UIAlertController { - let alert = UIAlertController(title: "위치정보 활성화", message: "측정을 다시 시작할 수 있도록 위치정보를 활성화해주세요.", preferredStyle: .alert) + private func authAlert(title: String, message: String) -> UIAlertController { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) let cancel = UIAlertAction(title: "아니요", style: .cancel) let confirm = UIAlertAction(title: "활성화", style: .default) { _ in guard let url = URL(string: UIApplication.openSettingsURLString) else { return } From 407a21912933c7c8eb834297f450c98d589ce596 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 16 Nov 2021 16:55:18 +0900 Subject: [PATCH 223/465] =?UTF-8?q?[Refacter]=20#177=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=83=9D=EB=B7=B0=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=ED=81=AC=EA=B8=B0=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EB=B3=80=ED=98=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 11 +++++++++++ SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 93862a9..040c368 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -52,6 +52,7 @@ class MapOptionCell: UITableViewCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.configureView() + self.configureStackViewAccessibility() } required init?(coder: NSCoder) { @@ -74,3 +75,13 @@ class MapOptionCell: UITableViewCell { self.map.text = option.map.name } } + +// MARK: - Accessibility + +extension MapOptionCell { + private func configureStackViewAccessibility() { + self.stackView.axis = + self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? + .horizontal : .vertical + } +} diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 878f87d..62e9c83 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -50,6 +50,7 @@ class ToggleOptionCell: UITableViewCell { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none self.configureView() + self.configureStackViewAccessibility() } required init?(coder: NSCoder) { @@ -80,4 +81,12 @@ class ToggleOptionCell: UITableViewCell { } } +// MARK: - Accessibility +extension ToggleOptionCell { + private func configureStackViewAccessibility() { + self.stackView.axis = + self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? + .horizontal : .vertical + } +} From 8d99619273d99e5f75ea33680e5a753dcc3e81f4 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 16:58:23 +0900 Subject: [PATCH 224/465] =?UTF-8?q?[Feat]=20UseCase,=20ViewModel=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=BD=9C?= =?UTF-8?q?=EB=A0=89=EC=85=98=EB=B7=B0=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 12 +++++ .../CollectionViewCell.swift | 14 ++++++ .../ResultDetailLargerInfoView.swift | 44 ++++++++++++++----- .../ResultDetailUseCase.swift | 12 +++++ .../ResultDetailViewModel.swift | 8 ++++ 5 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index edd320d..21b8c64 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -9,6 +9,9 @@ /* Begin PBXBuildFile section */ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; + 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B32743992400B5FB88 /* CollectionViewCell.swift */; }; + 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494803812743748D002854B1 /* ResultDetailViewModel.swift */; }; + 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; @@ -98,6 +101,9 @@ /* Begin PBXFileReference section */ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; + 493178B32743992400B5FB88 /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; + 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; + 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; @@ -227,6 +233,9 @@ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, + 494803812743748D002854B1 /* ResultDetailViewModel.swift */, + 4948038327437499002854B1 /* ResultDetailUseCase.swift */, + 493178B32743992400B5FB88 /* CollectionViewCell.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -502,6 +511,7 @@ 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */, 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, + 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */, 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */, 5429694D272FC1390070B362 /* ResultViewController.swift in Sources */, 49D5A957273A62F800937821 /* MountainDetailTableViewCell.swift in Sources */, @@ -527,6 +537,7 @@ 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, + 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, @@ -537,6 +548,7 @@ 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, + 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */, 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift b/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift new file mode 100644 index 0000000..cdd3854 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift @@ -0,0 +1,14 @@ +// +// CollectionViewCell.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/16. +// + +import UIKit + +class CollectionViewCell: UICollectionViewCell { + convenience init() { + + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 4b6d069..918df72 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -8,26 +8,48 @@ import UIKit class ResultDetailLargerInfoView: UIView { + private var collectionView: UICollectionView override init(frame: CGRect) { super.init(frame: frame) + self.collectionView = UICollectionView(frame: frame) self.backgroundColor = .green } - init() { - super.init(frame: .zero) - self.backgroundColor = .red - } - required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - /* - // Only override draw() if you perform custom drawing. - // An empty implementation adversely affects performance during animation. - override func draw(_ rect: CGRect) { - // Drawing code +} + +extension ResultDetailLargerInfoView { + private func configureDownArrow() { + //chevron.compact.down + let downArrow:UIImageView = .init(image: UIImage(systemName: "chevron.compact.down")?.withTintColor(.black)) + downArrow.translatesAutoresizingMaskIntoConstraints = false + let downArrowConstraints = [ + downArrow.topAnchor.constraint(equalTo: self.topAnchor), + downArrow.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ] + NSLayoutConstraint.activate(downArrowConstraints) + } + + private func configure(collectionView: UICollectionView) { + self.addSubview(collectionView) + collectionView.delegate = self + collectionView.dataSource = self + let layout = UICollectionViewFlowLayout() + collectionView.collectionViewLayout = layout + } +} + +extension ResultDetailLargerInfoView: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + 4 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + <#code#> } - */ + } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift new file mode 100644 index 0000000..770d141 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -0,0 +1,12 @@ +// +// ResultDetailUseCase.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/16. +// + +import Foundation + +class ResultDetailUseCase { + +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift new file mode 100644 index 0000000..0205af6 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -0,0 +1,8 @@ +// +// ResultDetailViewModel.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/16. +// + +import Foundation From 5bcfa6ab96b8f42cdfb7e014358dd4b604e485b1 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 18:23:36 +0900 Subject: [PATCH 225/465] =?UTF-8?q?[Feat]=20#192,=20#193=20=EC=A7=84?= =?UTF-8?q?=EB=8F=99=20=ED=94=BC=EB=93=9C=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 9 ++++++++- SanTa/SanTa/MapScene/MapViewController.swift | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 5b0dfdc..ee507b5 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -13,7 +13,7 @@ protocol Coordinator: AnyObject { func start () } -class AppCoordinator: Coordinator { +class AppCoordinator: NSObject, Coordinator { var childCoordinators: [Coordinator] = [] let window: UIWindow? @@ -35,6 +35,7 @@ class AppCoordinator: Coordinator { func setTabBarController() -> UITabBarController { let tabBarController = UITabBarController() + tabBarController.delegate = self tabBarController.tabBar.backgroundColor = UIColor.white let firstItem = UITabBarItem(title: "시작", image: nil, tag: 0) @@ -78,3 +79,9 @@ class AppCoordinator: Coordinator { return tabBarController } } + +extension AppCoordinator: UITabBarControllerDelegate { + func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { + UISelectionFeedbackGenerator().selectionChanged() + } +} diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 1b0f875..12239d5 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -195,6 +195,7 @@ class MapViewController: UIViewController { } @objc private func presentRecordingViewController() { + UINotificationFeedbackGenerator().notificationOccurred(.success) switch self.manager.authorizationStatus{ case .authorizedWhenInUse, .authorizedAlways: self.coordinator?.presentRecordingViewController() From 43e25d286d4e7e7b8f2d42261d6b91a1112b40aa Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 19:11:22 +0900 Subject: [PATCH 226/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EC=9E=90=EB=A3=8C=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 + .../CollectionViewCell.swift | 6 +- .../ResultDetailLargerInfoView.swift | 15 ++- .../ResultDetailScene/ResultDetailModel.swift | 112 ++++++++++++++++++ .../ResultDetailUseCase.swift | 4 + .../ResultDetailViewModel.swift | 21 ++++ 6 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 21b8c64..a79661c 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B32743992400B5FB88 /* CollectionViewCell.swift */; }; + 493178B627439D0000B5FB88 /* ResultDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B527439D0000B5FB88 /* ResultDetailModel.swift */; }; 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494803812743748D002854B1 /* ResultDetailViewModel.swift */; }; 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; @@ -102,6 +103,7 @@ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; 493178B32743992400B5FB88 /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; + 493178B527439D0000B5FB88 /* ResultDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailModel.swift; sourceTree = ""; }; 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; @@ -236,6 +238,7 @@ 494803812743748D002854B1 /* ResultDetailViewModel.swift */, 4948038327437499002854B1 /* ResultDetailUseCase.swift */, 493178B32743992400B5FB88 /* CollectionViewCell.swift */, + 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -529,6 +532,7 @@ 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */, + 493178B627439D0000B5FB88 /* ResultDetailModel.swift in Sources */, 54296947272FBD4B0070B362 /* MapViewCoordinator.swift in Sources */, 54296953272FC3530070B362 /* MountainListViewCoordinator.swift in Sources */, DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift b/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift index cdd3854..cd5ee74 100644 --- a/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift +++ b/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift @@ -8,7 +8,7 @@ import UIKit class CollectionViewCell: UICollectionViewCell { - convenience init() { - - } +// convenience init() { +// +// } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 918df72..7ec5b3e 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -11,8 +11,8 @@ class ResultDetailLargerInfoView: UIView { private var collectionView: UICollectionView override init(frame: CGRect) { - super.init(frame: frame) self.collectionView = UICollectionView(frame: frame) + super.init(frame: frame) self.backgroundColor = .green } @@ -39,6 +39,15 @@ extension ResultDetailLargerInfoView { collectionView.dataSource = self let layout = UICollectionViewFlowLayout() collectionView.collectionViewLayout = layout + + collectionView.translatesAutoresizingMaskIntoConstraints = false + let constraints = [ + collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), + collectionView.leftAnchor.constraint(equalTo: self.leftAnchor), + collectionView.rightAnchor.constraint(equalTo: self.rightAnchor), + collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ] + NSLayoutConstraint.activate(constraints) } } @@ -48,8 +57,6 @@ extension ResultDetailLargerInfoView: UICollectionViewDelegate, UICollectionView } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - <#code#> + return UICollectionViewCell() } - - } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift new file mode 100644 index 0000000..3a79497 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -0,0 +1,112 @@ +// +// ResultDetailModel.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/16. +// + +import Foundation +import CoreLocation + +struct ResultDetailData { + let record: ResultRecordInformation + let distance: ResultDistance + +} + +struct ResultRecordInformation { + let startTime: Date + let endTime: Date + let startLocation: CLLocation + let endLocation: CLLocation +} + +struct ResultDistance { + let total: Double + let exercise: Double + let steps: Int + + init(records: Records) { + self.total = records.distances + self.exercise = records.distances + self.steps = records.steps + } +} + +struct ResultTime { + let spent: TimeInterval + let exercise: TimeInterval + let rest: TimeInterval + +// init(records: Records) { +// self.spent = records.times +// } +} + +struct ResultPace { + let timePerKilometer: TimeInterval + let fastestPace: TimeInterval + let slowestPace: TimeInterval +} + +struct ResultAltitude { + let total: Int + let highest: Int + let lowest: Int + let starting: Int + let ending: Int + + init(records: Records) { + let maxAltitude:Int = Int(records.records.flatMap{$0.locations}.max{ $0.altitude < $1.altitude }?.altitude ?? 0) + let minAltitude = Int(records.records.flatMap{$0.locations}.min{ $0.altitude < $1.altitude }?.altitude ?? 0) + let total = Int(maxAltitude - minAltitude) + let startAltitude = Int(records.records.first?.locations.first?.altitude ?? 0) + let endAltitude = Int(records.records.last?.locations.last?.altitude ?? 0) + + self.total = total + self.highest = maxAltitude + self.lowest = minAltitude + self.starting = startAltitude + self.ending = endAltitude + } +} + +struct ResultIncline { + let average: Int + let highest: Int + let uphillKilometer: Double + let downhillKilometer: Double + let plainKilometer: Double + + init(records: Records) { + var totalIncline: Double = 0 + var steepest: Double = 0 + var uphillDistance: Double = 0 + var downHillDistance: Double = 0 + var plainDistance: Double = 0 + + var locations: [Location] = [] + for record in records.records { + locations.append(contentsOf: record.locations) + } + + for index in 0.. 0 ? abs(distanceDelta) : 0 + downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 + plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 + } + + self.average = Int(totalIncline / Double(locations.count - 1)) + self.highest = Int(steepest) + self.uphillKilometer = uphillDistance / 1000 + self.downhillKilometer = downHillDistance / 1000 + self.plainKilometer = plainDistance / 1000 + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index 770d141..d8e6c30 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -8,5 +8,9 @@ import Foundation class ResultDetailUseCase { + private var records: Records + init(records: Records) { + self.records = records + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 0205af6..5fe7db0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -6,3 +6,24 @@ // import Foundation + +enum ResultDataType: String, CaseIterable { + case start = "시작" + case end = "종료" + case distance = "거리" + case time = "시간" + case pace = "페이스(1km당 소요시간)" + case altitude = "고도" + case incline = "경사도" +} + +struct CellContentEntity { + let content: String + let subContent: String? + let contentTitle: String? +} + +protocol CellRepresentableData { + var type: ResultDataType { get } + var contents: [CellContentEntity] { get } +} From b1856f1e9c8988a50ecdc47232c381815a95f5a9 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 19:19:24 +0900 Subject: [PATCH 227/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailModel.swift | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 3a79497..f767a60 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -9,16 +9,28 @@ import Foundation import CoreLocation struct ResultDetailData { - let record: ResultRecordInformation + let timeStamp: ResultTimeStamp let distance: ResultDistance - + /* + let time: ResultTime + let pace: ResultPace + */ + let altitude: ResultAltitude + let incline: ResultIncline } -struct ResultRecordInformation { +struct ResultTimeStamp { let startTime: Date let endTime: Date - let startLocation: CLLocation - let endLocation: CLLocation + let startLocation: Location? + let endLocation: Location? + + init(records: Records) { + self.startTime = records.records.first?.startTime ?? Date.distantPast + self.endTime = records.records.last?.endTime ?? Date.distantFuture + self.startLocation = records.records.first?.locations.first + self.endLocation = records.records.last?.locations.last + } } struct ResultDistance { @@ -28,7 +40,7 @@ struct ResultDistance { init(records: Records) { self.total = records.distances - self.exercise = records.distances + self.exercise = records.distances //?? self.steps = records.steps } } From 3d21161ec2ac88613a9754de14703a95056862da Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Tue, 16 Nov 2021 22:39:16 +0900 Subject: [PATCH 228/465] =?UTF-8?q?[Feat]=20ResultTime=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailModel.swift | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index f767a60..3ee8148 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -11,10 +11,8 @@ import CoreLocation struct ResultDetailData { let timeStamp: ResultTimeStamp let distance: ResultDistance - /* - let time: ResultTime - let pace: ResultPace - */ + let time: ResultTime +// let pace: ResultPace let altitude: ResultAltitude let incline: ResultIncline } @@ -47,12 +45,23 @@ struct ResultDistance { struct ResultTime { let spent: TimeInterval - let exercise: TimeInterval - let rest: TimeInterval + let active: TimeInterval + let inactive: TimeInterval -// init(records: Records) { -// self.spent = records.times -// } + init(records: Records) { + var active: TimeInterval = 0 + var inactive: TimeInterval = 0 + for index in 0.. Date: Tue, 16 Nov 2021 23:21:11 +0900 Subject: [PATCH 229/465] =?UTF-8?q?[Fix]=20#198=20TabBar=20DarkMode=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91=20=EB=B0=8F=20Personal=20Color=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppCoordinator.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 5b0dfdc..7154dff 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -35,7 +35,9 @@ class AppCoordinator: Coordinator { func setTabBarController() -> UITabBarController { let tabBarController = UITabBarController() - tabBarController.tabBar.backgroundColor = UIColor.white + tabBarController.tabBar.backgroundColor = .systemBackground + tabBarController.tabBar.tintColor = UIColor(named: "SantaColor") + tabBarController.tabBar.unselectedItemTintColor = .systemGray2 let firstItem = UITabBarItem(title: "시작", image: nil, tag: 0) let secondItem = UITabBarItem(title: "기록", image: nil, tag: 1) From edb97e4f037382911c1024f9d6fa1c70a2a6bc68 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 23:26:47 +0900 Subject: [PATCH 230/465] =?UTF-8?q?[Refactor]=20#200=20ResultViewControlle?= =?UTF-8?q?r=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultScene/ResultViewController.swift | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 663b40c..4a59749 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -9,7 +9,7 @@ import UIKit class ResultViewController: UIViewController { weak var coordinator: ResultViewCoordinator? - private let collectionView = UICollectionView(frame: .zero, collectionViewLayout: ResultViewController.createCompositionalLayout()) + private var collectionView: UICollectionView? private var viewModel: ResultViewModel? convenience init(viewModel: ResultViewModel) { @@ -27,49 +27,49 @@ class ResultViewController: UIViewController { viewModel?.viewWillAppear() { [weak self] in DispatchQueue.main.async { self?.navigationController?.navigationBar.topItem?.title = self?.viewModel?.totalDistance - self?.collectionView.reloadData() + self?.collectionView?.reloadData() } } } private func configureCollectionView() { + self.collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout()) + guard let collectionView = collectionView else { return } view.addSubview(collectionView) collectionView.register(TotalRecordsViewCell.self, forCellWithReuseIdentifier: TotalRecordsViewCell.identifier) collectionView.register(RecordsViewCell.self, forCellWithReuseIdentifier: RecordsViewCell.identifier) collectionView.register(SectionHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: SectionHeaderView.identifier) - collectionView.frame = view.bounds collectionView.delegate = self collectionView.dataSource = self } - private static func createCompositionalLayout() -> UICollectionViewCompositionalLayout { + private func createCompositionalLayout() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in switch sectionNumber { - case 0: return ResultViewController.firstLayoutSection() - default: return ResultViewController.secondLayoutSection() + case 0: return self.firstLayoutSection() + default: return self.secondLayoutSection() } } } - private static func firstLayoutSection() -> NSCollectionLayoutSection { - let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(300)) + private func firstLayoutSection() -> NSCollectionLayoutSection { + let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) - let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(300)) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.35)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1) let section = NSCollectionLayoutSection(group: group) return section } - private static func secondLayoutSection() -> NSCollectionLayoutSection { - let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(130)) + private func secondLayoutSection() -> NSCollectionLayoutSection { + let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = .init(top: 3, leading: 10, bottom: 13, trailing: 10) - let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(130)) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.16)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1) group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let section = NSCollectionLayoutSection(group: group) - - let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)) + let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.06)) let header = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, @@ -77,7 +77,6 @@ class ResultViewController: UIViewController { ) header.pinToVisibleBounds = true section.boundarySupplementaryItems = [header] - return section } } From f8d95663c58642ce596d095dfa7e3604fdb6ecb3 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 23:32:42 +0900 Subject: [PATCH 231/465] =?UTF-8?q?[Fix]=20#176=20Sticky=20Header=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/ResultViewController.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 4a59749..de586d0 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -137,10 +137,16 @@ extension ResultViewController: UICollectionViewDelegate { guard let navigationBar = self.navigationController?.navigationBar else { return } let navigationBarChangePointY = 100.0 if scrollView.contentOffset.y > navigationBarChangePointY { - navigationBar.isHidden = false + if navigationBar.isHidden { + navigationBar.isHidden = false + self.view.setNeedsLayout() + } navigationBar.layer.opacity = Float(0.05 * (scrollView.contentOffset.y - navigationBarChangePointY)) } else { - navigationBar.isHidden = true + if !navigationBar.isHidden { + navigationBar.isHidden = true + self.view.setNeedsLayout() + } } } } From f32e398f4f1b6b52a262706672cdd95543a4c449 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 16 Nov 2021 23:39:20 +0900 Subject: [PATCH 232/465] =?UTF-8?q?[Refactor]=20#203=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20DarkMode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contents.json | 33 +++++++++++++++++++ SanTa/SanTa/ResultScene/RecordsViewCell.swift | 5 +-- .../SanTa/ResultScene/SectionHeaderView.swift | 4 +-- 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 SanTa/SanTa/Resources/Assets.xcassets/RecodingResultCellColor.colorset/Contents.json diff --git a/SanTa/SanTa/Resources/Assets.xcassets/RecodingResultCellColor.colorset/Contents.json b/SanTa/SanTa/Resources/Assets.xcassets/RecodingResultCellColor.colorset/Contents.json new file mode 100644 index 0000000..b645929 --- /dev/null +++ b/SanTa/SanTa/Resources/Assets.xcassets/RecodingResultCellColor.colorset/Contents.json @@ -0,0 +1,33 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "platform" : "ios", + "reference" : "systemGray5Color" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index 539e51e..864e20c 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -11,13 +11,13 @@ extension UILabel { fileprivate convenience init(text: String, normalFontWithSize: CGFloat) { self.init() self.text = text - self.textColor = .black + self.textColor = .label } fileprivate convenience init(boldFontWithSize: CGFloat) { self.init() self.font = .boldSystemFont(ofSize: boldFontWithSize) - self.textColor = .black + self.textColor = .label } } @@ -53,6 +53,7 @@ class RecordsViewCell: UICollectionViewCell { self.time.text = time self.altitude.text = altitude self.steps.text = steps + self.backgroundColor = UIColor(named: "RecodingResultCellColor") self.configureSubviews() self.configureLayout() diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 3375aa6..5e5d31d 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -23,13 +23,13 @@ extension UILabel { class SectionHeaderView: UICollectionReusableView { static let identifier = "SectionHeaderView" - let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .black) + let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .label) let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) func configure(month: String, count: String, distance: String, time: String){ - self.backgroundColor = .white + self.backgroundColor = .systemBackground self.monthLabel.text = month self.countLabel.text = count self.distanceLabel.text = distance From a8ea7f035f19180cf1cd17ab3f54915b7f8ef598 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 16 Nov 2021 16:48:17 +0900 Subject: [PATCH 233/465] =?UTF-8?q?[Feat]=20#189=20UserDefaultsStorage=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 3 ++- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 +++- SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 4984bf5..8fa597d 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -42,6 +42,7 @@ extension MapViewCoordinator { if self.childCoordinators.isEmpty { let recordingViewCoordinator = RecordingViewCoordinator( navigationController: self.navigationController, + userDefaultsStorage: self.userDefaultsStorage, coreDataStorage: self.coreDataStorage) self.childCoordinators.append(recordingViewCoordinator) recordingViewCoordinator.parentCoordinator = self @@ -71,7 +72,7 @@ extension MapViewCoordinator { return MapViewModel( useCase: MapViewUseCase( repository: DefaultMapViewRespository( - mountainExtractor: mountainExtractor, + mountainExtractor: self.mountainExtractor, userDefaultsStorage: self.userDefaultsStorage ) ) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index a661e62..325b4e9 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -14,9 +14,11 @@ protocol RecordRepository { final class DefaultRecordRepository: RecordRepository { + private let settingsStorage: UserDefaultsStorage private let recordStorage: CoreDataRecordStorage - init(recordStorage: CoreDataRecordStorage) { + init(settingsStorage: UserDefaultsStorage, recordStorage: CoreDataRecordStorage) { + self.settingsStorage = settingsStorage self.recordStorage = recordStorage } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 1ac80fc..067d138 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -16,13 +16,14 @@ class RecordingViewCoordinator: Coordinator { private let coreDataStorage: CoreDataStorage - init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage) { + init(navigationController: UINavigationController, userDefaultsStorage: UserDefaultsStorage, coreDataStorage: CoreDataStorage) { self.navigationController = navigationController self.coreDataStorage = coreDataStorage self.recordingViewController = RecordingViewController( viewModel: RecordingViewModel( recordingUseCase: DefaultRecordingUseCase( recordRepository: DefaultRecordRepository( + settingsStorage: userDefaultsStorage, recordStorage: CoreDataRecordStorage( coreDataStorage: self.coreDataStorage ) From 15a2b69a5e31b651090718b2dc767f4ff0813ca5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 14:23:46 +0900 Subject: [PATCH 234/465] =?UTF-8?q?[Fix]=20PhotoModel=20UIKit=20Import=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index dc8d253..500b8d9 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -6,7 +6,6 @@ // import Foundation -import UIKit import Photos final class RecordingPhotoModel { From 0a6ea6368fe621554543a93d316478eb8d678368 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 17 Nov 2021 14:36:39 +0900 Subject: [PATCH 235/465] =?UTF-8?q?[Feat]=20#205=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 21 ++++++++++++++++--- .../ResultScene/ResultViewController.swift | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index f36b560..42915a8 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -24,8 +24,7 @@ extension UILabel { class RecordsViewCell: UICollectionViewCell { static let identifier = "RecordsViewCell" let date: PaddingLabel = { - let paddingLabel = PaddingLabel() - paddingLabel.padding(top: 2, bottom: 2, left: 3, right: 3) + let paddingLabel = PaddingLabel(insets: UIEdgeInsets(top: 2, left: 3, bottom: 2, right: 3)) paddingLabel.backgroundColor = UIColor(named: "SantaColor") paddingLabel.layer.cornerRadius = 3 paddingLabel.textColor = .white @@ -33,6 +32,15 @@ class RecordsViewCell: UICollectionViewCell { paddingLabel.clipsToBounds = true return paddingLabel }() + let title: PaddingLabel = { + let paddingLabel = PaddingLabel(insets: UIEdgeInsets(top: 2, left: 3, bottom: 2, right: 3)) + paddingLabel.backgroundColor = .label + paddingLabel.layer.cornerRadius = 3 + paddingLabel.textColor = .systemBackground + paddingLabel.font = .boldSystemFont(ofSize: 13) + paddingLabel.clipsToBounds = true + return paddingLabel + }() let distance = UILabel(boldFontWithSize: 20) let time = UILabel(boldFontWithSize: 20) let altitude = UILabel(boldFontWithSize: 20) @@ -47,13 +55,15 @@ class RecordsViewCell: UICollectionViewCell { let altitudeStackView = UIStackView() let stepsStackView = UIStackView() - func configure(date: String, distance: String, time: String, altitude: String, steps: String) { + func configure(date: String, title: String, distance: String, time: String, altitude: String, steps: String) { self.date.text = date + self.title.text = title self.distance.text = distance self.time.text = time self.altitude.text = altitude self.steps.text = steps self.backgroundColor = UIColor(named: "RecodingResultCellColor") + self.title.text?.count == 0 ? (self.title.isHidden = true) : (self.title.isHidden = false) self.configureSubviews() self.configureLayout() @@ -61,6 +71,7 @@ class RecordsViewCell: UICollectionViewCell { private func configureSubviews() { self.addSubview(date) + self.addSubview(title) self.addSubview(horizontalStackView) self.horizontalStackView.distribution = .fillEqually self.horizontalStackView.axis = .horizontal @@ -85,10 +96,14 @@ class RecordsViewCell: UICollectionViewCell { private func configureLayout() { self.date.translatesAutoresizingMaskIntoConstraints = false + self.title.translatesAutoresizingMaskIntoConstraints = false self.horizontalStackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ self.date.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), self.date.topAnchor.constraint(equalTo: self.topAnchor, constant: 15), + self.title.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), + self.title.topAnchor.constraint(equalTo: self.topAnchor, constant: 15), + self.title.leftAnchor.constraint(greaterThanOrEqualTo: self.date.rightAnchor, constant: 10), self.horizontalStackView.topAnchor.constraint(greaterThanOrEqualTo: self.date.bottomAnchor, constant: 10), self.horizontalStackView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -15), self.horizontalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index de586d0..b8c46a1 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -118,7 +118,7 @@ extension ResultViewController: UICollectionViewDataSource { cell.layer.shadowRadius = 2 cell.layer.shadowOpacity = 0.8 cell.layer.shadowOffset = CGSize(width: 0, height: 0.5) - cell.configure(date: cellInfo.date, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitudeDifference, steps: cellInfo.steps) + cell.configure(date: cellInfo.date, title: cellInfo.title, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitudeDifference, steps: cellInfo.steps) return cell } } From 560b91fc970b0f15566833389e9ff5d5ed7520f2 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 14:51:42 +0900 Subject: [PATCH 236/465] =?UTF-8?q?[Feat]=20#206=20m/m=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=EB=A1=9C=20=EC=B5=9C=EA=B3=A0=20=EC=88=9C=EA=B0=84=20?= =?UTF-8?q?=EC=86=8D=EB=8F=84=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 35f61a2..82c4339 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -23,20 +23,25 @@ final class RecordingModel: NSObject, ObservableObject { private var timerIsRunning = false private var records: Records? private var startDate: Date? + private var oneKileDate: Date? private var currentWalk = 0 private var currentKilo: Double = 0 + private var maxSpeed: Double = 0 + private var minSpeed: Double = 0 + private var sliceDistance: Double = 1 private var location = [Location]() private var currentTime = Date() { didSet { self.timeCalculation() - self.checkPedoMeter() +// self.checkPedoMeter() } } override init() { super.init() self.startDate = Date() + self.oneKileDate = self.startDate self.configureTimer() self.configureLocationManager() } @@ -133,6 +138,22 @@ final class RecordingModel: NSObject, ObservableObject { } } + private func calculateSpeed() { + if self.sliceDistance <= self.currentKilo { + guard let oneKileDate = self.oneKileDate else { + self.oneKileDate = self.currentTime + return + } + let elapsedTimeMinutes = Double(self.currentTime.timeIntervalSince(oneKileDate))/60 + let speed: Double = 1000/elapsedTimeMinutes + + if speed > self.maxSpeed { + self.maxSpeed = speed + self.oneKileDate = self.currentTime + } + } + } + private func appendRecord() { guard let startdate = self.startDate else { return } let record = Record(startTime: startdate, @@ -203,6 +224,7 @@ extension RecordingModel: CLLocationManagerDelegate { location.append(Location(latitude: Double(lastLocation.coordinate.latitude), longitude: Double(lastLocation.coordinate.longitude), altitude: Double(lastLocation.altitude))) + self.checkPedoMeter() altitude = "\(Int(lastLocation.altitude))" } } From f6b32e2ae8923e2b1abf7790fbd438b9b25ed6e9 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 14:52:14 +0900 Subject: [PATCH 237/465] =?UTF-8?q?[Feat]=20#207=20m/m=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=EB=A1=9C=20=EC=B5=9C=EC=A0=80=20=EC=88=9C=EA=B0=84=20?= =?UTF-8?q?=EC=86=8D=EB=8F=84=20=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 82c4339..769ab2e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -151,6 +151,11 @@ final class RecordingModel: NSObject, ObservableObject { self.maxSpeed = speed self.oneKileDate = self.currentTime } + + if speed < self.minSpeed { + self.minSpeed = speed + self.oneKileDate = self.currentTime + } } } From 9d0268660e9bfac53e6326cb5db7fc0a508964ed Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 14:55:04 +0900 Subject: [PATCH 238/465] =?UTF-8?q?[Feat]=20RecordingModel=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EB=AC=B8=EC=9E=90=EC=97=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 769ab2e..510cd5c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -12,9 +12,9 @@ import Combine final class RecordingModel: NSObject, ObservableObject { @Published private(set) var time = "" - @Published private(set) var kilometer = "" - @Published private(set) var altitude = "" - @Published private(set) var walk = "" + @Published private(set) var kilometer = "0.00" + @Published private(set) var altitude = "0" + @Published private(set) var walk = "0" @Published private(set) var gpsStatus = true private let pedoMeter = CMPedometer() From 5c53d36fecbfdb5ca5eca495c97924d963585e43 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 17 Nov 2021 14:55:11 +0900 Subject: [PATCH 239/465] =?UTF-8?q?[Feat]=20#209=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=EC=9D=98=20=EB=82=A0=EC=A7=9C=EB=A5=BC=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=ED=91=9C=EA=B8=B0=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/ResultViewModel.swift | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 8225c9d..64b1f1e 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -86,10 +86,19 @@ extension ResultViewModel { } private func cellDateFormatter(_ date: Date?) -> String { - guard let date = date else { return "알 수 없는 날짜" } + guard let date = date, + let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: .now) + else { return "알 수 없는 날짜" } + let calender = Calendar.current let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier:"ko_KR") - dateFormatter.dateFormat = "M. d. (E) a h시 m분" + if calender.compare(date, to: .now, toGranularity: .day) == .orderedSame { + dateFormatter.dateFormat = "a h시 m분" + } else if calender.compare(date, to: yesterday, toGranularity: .day) == .orderedSame { + dateFormatter.dateFormat = "어제(E) a h시 m분" + } else { + dateFormatter.dateFormat = "M. d. (E) a h시 m분" + } return dateFormatter.string(from:date) } From 9fb09000cc249fcc333725b091d798ead2314bd6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 14:59:05 +0900 Subject: [PATCH 240/465] =?UTF-8?q?[Feat]=20#206,=20#207=20sliceDistance?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 510cd5c..879167a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -150,11 +150,13 @@ final class RecordingModel: NSObject, ObservableObject { if speed > self.maxSpeed { self.maxSpeed = speed self.oneKileDate = self.currentTime + self.sliceDistance += 1 } if speed < self.minSpeed { self.minSpeed = speed self.oneKileDate = self.currentTime + self.sliceDistance += 1 } } } From 33d7409658c0f3e9c30262f18509f84ac048435b Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 15:02:24 +0900 Subject: [PATCH 241/465] =?UTF-8?q?[Fix]=20RecordingModel=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=ED=94=BC=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 879167a..42314bc 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -34,7 +34,6 @@ final class RecordingModel: NSObject, ObservableObject { private var currentTime = Date() { didSet { self.timeCalculation() -// self.checkPedoMeter() } } @@ -94,8 +93,7 @@ final class RecordingModel: NSObject, ObservableObject { private func checkPedoMeter() { guard let date = self.startDate else { return } var dates = [Record]() - if records != nil { - guard let records = records else { return } + if let records = self.records { dates = records.records } @@ -128,10 +126,10 @@ final class RecordingModel: NSObject, ObservableObject { dispatchGroup.leave() dispatchGroup.notify(queue: .global()) { [weak self] in - guard let walk = self?.currentWalk else { return } + guard let walk = self?.currentWalk, + let currentKile = self?.currentKilo else { return } self?.walk = "\(walk)" - guard let currentKile = self?.currentKilo else { return } let distanceString = String(format: "%.2f", currentKile) self?.kilometer = "\(distanceString)" From 75c2267ebf006842c61d043f8eed4e0f108cdd2b Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 15:03:25 +0900 Subject: [PATCH 242/465] =?UTF-8?q?[Fix]=20RecordingModel=20CurrentKilo=20?= =?UTF-8?q?->=20CurrentDistance=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 42314bc..ff081ad 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -25,7 +25,7 @@ final class RecordingModel: NSObject, ObservableObject { private var startDate: Date? private var oneKileDate: Date? private var currentWalk = 0 - private var currentKilo: Double = 0 + private var currentDistance: Double = 0 private var maxSpeed: Double = 0 private var minSpeed: Double = 0 private var sliceDistance: Double = 1 @@ -102,7 +102,7 @@ final class RecordingModel: NSObject, ObservableObject { let dispatchGroup = DispatchGroup() self.currentWalk = 0 - self.currentKilo = 0 + self.currentDistance = 0 dispatchGroup.enter() dates.forEach { @@ -119,7 +119,7 @@ final class RecordingModel: NSObject, ObservableObject { guard let distance = activityData.distance else { return } let transformatKilometer = Double(truncating: distance) / 1000 - self?.currentKilo += transformatKilometer + self?.currentDistance += transformatKilometer dispatchGroup.leave() } } @@ -127,7 +127,7 @@ final class RecordingModel: NSObject, ObservableObject { dispatchGroup.leave() dispatchGroup.notify(queue: .global()) { [weak self] in guard let walk = self?.currentWalk, - let currentKile = self?.currentKilo else { return } + let currentKile = self?.currentDistance else { return } self?.walk = "\(walk)" let distanceString = String(format: "%.2f", currentKile) @@ -137,7 +137,7 @@ final class RecordingModel: NSObject, ObservableObject { } private func calculateSpeed() { - if self.sliceDistance <= self.currentKilo { + if self.sliceDistance <= self.currentDistance { guard let oneKileDate = self.oneKileDate else { self.oneKileDate = self.currentTime return @@ -164,7 +164,7 @@ final class RecordingModel: NSObject, ObservableObject { let record = Record(startTime: startdate, endTime: self.currentTime, step: self.currentWalk, - distance: self.currentKilo, + distance: self.currentDistance, locations: self.location) guard self.records != nil else { From 1eb7aab8d2f19e08d3e85b519bee265a3adb289d Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 15:19:40 +0900 Subject: [PATCH 243/465] =?UTF-8?q?[Feat]=20#206,=20#207=20=EC=88=9C?= =?UTF-8?q?=EA=B0=84=20=EC=86=8D=EB=8F=84=20=EC=8B=9C=EA=B0=84=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EC=9C=BC=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index ff081ad..f2a8901 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -8,6 +8,7 @@ import Foundation import CoreLocation import CoreMotion +import AVFoundation import Combine final class RecordingModel: NSObject, ObservableObject { @@ -26,8 +27,8 @@ final class RecordingModel: NSObject, ObservableObject { private var oneKileDate: Date? private var currentWalk = 0 private var currentDistance: Double = 0 - private var maxSpeed: Double = 0 - private var minSpeed: Double = 0 + private var maxOneKiloTime = 0 + private var minOneKiloTime = 0 private var sliceDistance: Double = 1 private var location = [Location]() @@ -142,17 +143,16 @@ final class RecordingModel: NSObject, ObservableObject { self.oneKileDate = self.currentTime return } - let elapsedTimeMinutes = Double(self.currentTime.timeIntervalSince(oneKileDate))/60 - let speed: Double = 1000/elapsedTimeMinutes + let elapsedTimeMinutes = Int(self.currentTime.timeIntervalSince(oneKileDate)) - if speed > self.maxSpeed { - self.maxSpeed = speed + if elapsedTimeMinutes > self.maxOneKiloTime { + self.maxOneKiloTime = elapsedTimeMinutes self.oneKileDate = self.currentTime self.sliceDistance += 1 } - if speed < self.minSpeed { - self.minSpeed = speed + if elapsedTimeMinutes < self.minOneKiloTime { + self.minOneKiloTime = elapsedTimeMinutes self.oneKileDate = self.currentTime self.sliceDistance += 1 } From 1ef9842ded543f08058a32d9855526b1cbadad38 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 17 Nov 2021 15:24:44 +0900 Subject: [PATCH 244/465] =?UTF-8?q?[Fix]=20#211=20=EA=B0=80=EB=A1=9C?= =?UTF-8?q?=EB=AA=A8=EB=93=9C=20=ED=86=B5=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppDelegate.swift | 32 +++-------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index a909cf7..0d32030 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -10,51 +10,29 @@ import CoreData @main class AppDelegate: UIResponder, UIApplicationDelegate { - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. return true } // MARK: UISceneSession Lifecycle func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { + return UIInterfaceOrientationMask.portrait } // MARK: - Core Data stack lazy var persistentContainer: NSPersistentContainer = { - /* - The persistent container for the application. This implementation - creates and returns a container, having loaded the store for the - application to it. This property is optional since there are legitimate - error conditions that could cause the creation of the store to fail. - */ let container = NSPersistentContainer(name: "SanTa") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. - - /* - Typical reasons for an error here include: - * The parent directory does not exist, cannot be created, or disallows writing. - * The persistent store is not accessible, due to permissions or data protection when the device is locked. - * The device is out of space. - * The store could not be migrated to the current model version. - Check the error message to determine what the actual problem was. - */ fatalError("Unresolved error \(error), \(error.userInfo)") } }) @@ -69,8 +47,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { do { try context.save() } catch { - // Replace this implementation with code to handle the error appropriately. - // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } From fa390541da4819a2efa04354734c23a27eb0d391 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 15:25:46 +0900 Subject: [PATCH 245/465] =?UTF-8?q?[Feat]=20#190=201km=20=EA=B0=84?= =?UTF-8?q?=EA=B2=A9=EC=9C=BC=EB=A1=9C=20=EC=B4=9D=20=EA=B1=B0=EB=A6=AC,?= =?UTF-8?q?=20=EC=86=8C=EC=9A=94=20=EC=8B=9C=EA=B0=84,=20=ED=98=84?= =?UTF-8?q?=EC=9E=AC=20=EA=B3=A0=EB=8F=84=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=9D=8C=EC=84=B1=20=EC=95=8C=EB=A6=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index f2a8901..e1e8638 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -144,6 +144,7 @@ final class RecordingModel: NSObject, ObservableObject { return } let elapsedTimeMinutes = Int(self.currentTime.timeIntervalSince(oneKileDate)) + self.willSpeechCurrentStatus() if elapsedTimeMinutes > self.maxOneKiloTime { self.maxOneKiloTime = elapsedTimeMinutes @@ -159,6 +160,15 @@ final class RecordingModel: NSObject, ObservableObject { } } + private func willSpeechCurrentStatus() { + let synthesizer = AVSpeechSynthesizer() + let speech = "현재 총 거리는 \(kilometer)킬로미터 소요 시간은 \(time)초 현재 고도는 \(altitude)입니다." + let utterance = AVSpeechUtterance(string: speech) + utterance.voice = AVSpeechSynthesisVoice(language: "ko-KR") + utterance.rate = 0.4 + synthesizer.speak(utterance) + } + private func appendRecord() { guard let startdate = self.startDate else { return } let record = Record(startTime: startdate, From 6ef9c937438a36b2614395d66e110853df64887f Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 17 Nov 2021 15:29:37 +0900 Subject: [PATCH 246/465] =?UTF-8?q?[Feat]=20#213=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20VoiceOver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa.xcdatamodel/contents | 2 ++ SanTa/SanTa/SettingsScene/MapOptionCell.swift | 16 ++++++++++++-- .../SettingsViewController.swift | 8 +++++++ .../SettingsScene/ToggleOptionCell.swift | 22 +++++++++++++++++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 15ce1ec..24a8c5f 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -15,6 +15,7 @@ + @@ -23,5 +24,6 @@ + \ No newline at end of file diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 040c368..d60dd6c 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -52,7 +52,6 @@ class MapOptionCell: UITableViewCell { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.configureView() - self.configureStackViewAccessibility() } required init?(coder: NSCoder) { @@ -79,9 +78,22 @@ class MapOptionCell: UITableViewCell { // MARK: - Accessibility extension MapOptionCell { - private func configureStackViewAccessibility() { + func configureAccessibility() { + self.configureDynamicTypeAccessibility() + self.configureVoiceOverAccessibility() + } + + private func configureDynamicTypeAccessibility() { self.stackView.axis = self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? .horizontal : .vertical } + + private func configureVoiceOverAccessibility() { + self.map.isAccessibilityElement = false + self.accessibilityLabel = "\(title.text ?? "")" + self.accessibilityValue = "\(map.text ?? "")" + self.accessibilityHint = "지도형식을 바꾸려면 이중탭 하십시오" + self.accessibilityIdentifier = "\(title.text ?? "") Cell" + } } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 2523b7e..4515983 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -22,6 +22,7 @@ class SettingsViewController: UIViewController { let headerTitle = UILabel() headerTitle.translatesAutoresizingMaskIntoConstraints = false headerTitle.text = "설정" + headerTitle.accessibilityLabel = "설정 머리말" headerTitle.font = UIFont.systemFont(ofSize: 20, weight: .bold) return headerTitle }() @@ -129,6 +130,7 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { } cell.update(option: option) cell.delegate = self + cell.configureAccessibility() return cell case let option as MapOption: guard let cell = self.tableView.dequeueReusableCell(withIdentifier: MapOptionCell.identifier, @@ -137,6 +139,7 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { return UITableViewCell() } cell.update(option: option) + cell.configureAccessibility() return cell default: return UITableViewCell() @@ -144,6 +147,11 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if UIAccessibility.isVoiceOverRunning { + guard let cell = tableView.cellForRow(at: indexPath) as? ToggleOptionCell else { return } + cell.changeSwitch() + } + guard let cell = tableView.cellForRow(at: indexPath) as? MapOptionCell else { return } guard let title = cell.title.text else { return } self.showMapActionSheet(cellTitle: title) diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 62e9c83..d8056e3 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -50,7 +50,6 @@ class ToggleOptionCell: UITableViewCell { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none self.configureView() - self.configureStackViewAccessibility() } required init?(coder: NSCoder) { @@ -79,14 +78,33 @@ class ToggleOptionCell: UITableViewCell { self.title.text = option.text self.controlSwitch.isOn = option.toggle } + + func changeSwitch() { + self.controlSwitch.isOn.toggle() + self.onClickSwitch(sender: self.controlSwitch) + self.accessibilityValue = self.controlSwitch.isOn ? "켜짐" : "꺼짐" + } } // MARK: - Accessibility extension ToggleOptionCell { - private func configureStackViewAccessibility() { + func configureAccessibility() { + self.configureDynamicTypeAccessibility() + self.configureVoiceOverAccessibility() + } + + private func configureDynamicTypeAccessibility() { self.stackView.axis = self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? .horizontal : .vertical } + + private func configureVoiceOverAccessibility() { + self.controlSwitch.isAccessibilityElement = false + self.accessibilityLabel = "\(title.text ?? "")" + self.accessibilityValue = self.controlSwitch.isOn ? "켜짐" : "꺼짐" + self.accessibilityHint = "설정을 끄거나 켜려면 이중탭 하십시오" + self.accessibilityIdentifier = "\(title.text ?? "") Cell" + } } From 4368c6f1b7da821e6cd0a6968e5aa125b1d81c84 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 17 Nov 2021 15:43:48 +0900 Subject: [PATCH 247/465] =?UTF-8?q?[Fix]=20=EC=84=A4=EC=A0=95=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20Cell=20=EC=96=B8=EB=9E=98=ED=95=91=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 7 ++++--- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index d60dd6c..1fd8ee6 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -91,9 +91,10 @@ extension MapOptionCell { private func configureVoiceOverAccessibility() { self.map.isAccessibilityElement = false - self.accessibilityLabel = "\(title.text ?? "")" - self.accessibilityValue = "\(map.text ?? "")" + guard let title = title.text, let map = map.text else { return } + self.accessibilityLabel = "\(title)" + self.accessibilityValue = "\(map)" self.accessibilityHint = "지도형식을 바꾸려면 이중탭 하십시오" - self.accessibilityIdentifier = "\(title.text ?? "") Cell" + self.accessibilityIdentifier = "\(title) Cell" } } diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index d8056e3..5f3af96 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -102,9 +102,10 @@ extension ToggleOptionCell { private func configureVoiceOverAccessibility() { self.controlSwitch.isAccessibilityElement = false - self.accessibilityLabel = "\(title.text ?? "")" + guard let title = title.text else { return } + self.accessibilityLabel = "\(title)" self.accessibilityValue = self.controlSwitch.isOn ? "켜짐" : "꺼짐" self.accessibilityHint = "설정을 끄거나 켜려면 이중탭 하십시오" - self.accessibilityIdentifier = "\(title.text ?? "") Cell" + self.accessibilityIdentifier = "\(title) Cell" } } From cd508b4b132726c4d2c0ab2846c2c6d23188974e Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 15:56:12 +0900 Subject: [PATCH 248/465] =?UTF-8?q?[Feat]=20#189=20=EC=9D=8C=EC=84=B1=20?= =?UTF-8?q?=EC=95=88=EB=82=B4=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingScene/RecordRepository.swift | 20 +++++++++++++++++++ .../RecordingScene/RecordingUseCase.swift | 13 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 325b4e9..1dd0d3b 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -10,10 +10,19 @@ import Foundation protocol RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) + func fetchVoiceOption(key: Settings, completion: @escaping (Result) -> Void) } final class DefaultRecordRepository: RecordRepository { + enum userDefaultsError: Error { + case notExists + } + + enum optionError: Error { + case notExists + } + private let settingsStorage: UserDefaultsStorage private let recordStorage: CoreDataRecordStorage @@ -25,4 +34,15 @@ final class DefaultRecordRepository: RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) { self.recordStorage.save(records: records, completion: completion) } + + func fetchVoiceOption(key: Settings, completion: @escaping (Result) -> Void) { + self.settingsStorage.string(key: key) { value in + guard let value = value else { + completion(.failure(userDefaultsError.notExists)) + return + } + + print(value) + } + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 8420b84..3d89935 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -14,6 +14,7 @@ protocol RecordingUseCase { func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] func pause() func resume() + func fetchOptions() } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { @@ -62,4 +63,16 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { return assets } + + func fetchOptions() { + self.recordRepository.fetchVoiceOption(key: Settings.voiceGuidanceEveryOnekm) { result in + switch result { + case .failure(let error): + print(error) + return + case .success(let status): + print(status) + } + } + } } From 8b5c3ff87ea8956d637de276cdbcf3db2c4793d9 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:00:00 +0900 Subject: [PATCH 249/465] =?UTF-8?q?[Feat]=20#189=20Controller,=20ViewModel?= =?UTF-8?q?=20Option=20Fetch=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 1 + SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index f3846b1..b78e1c3 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -106,6 +106,7 @@ class RecordingViewController: UIViewController { super.viewDidAppear(animated) self.configureAlbumPermission() + self.recordingViewModel?.fetchOptions() } private func configureBindings() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index d230a50..e1c8f43 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -71,4 +71,8 @@ final class RecordingViewModel: ObservableObject { func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } + + func fetchOptions() { + self.recordingUseCase?.fetchOptions() + } } From e0079e0a0744d25493232b6fce6859b747291d83 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:04:15 +0900 Subject: [PATCH 250/465] =?UTF-8?q?[Feat]=20#189=20Repository=20completion?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordRepository.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 1dd0d3b..262efda 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -42,7 +42,12 @@ final class DefaultRecordRepository: RecordRepository { return } - print(value) + guard value == "1" else { + completion(.success(false)) + return + } + + completion(.success(true)) } } } From 225dca4e6ceab7468ce90bb4459fa1b04e717b13 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:10:51 +0900 Subject: [PATCH 251/465] =?UTF-8?q?[Feat]=20#189=20UseCase,=20Model=20will?= =?UTF-8?q?Speech=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 9 ++++++++- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 5 ++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index e1e8638..9470ec0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -32,6 +32,8 @@ final class RecordingModel: NSObject, ObservableObject { private var sliceDistance: Double = 1 private var location = [Location]() + private var willSpeech = false + private var currentTime = Date() { didSet { self.timeCalculation() @@ -144,7 +146,8 @@ final class RecordingModel: NSObject, ObservableObject { return } let elapsedTimeMinutes = Int(self.currentTime.timeIntervalSince(oneKileDate)) - self.willSpeechCurrentStatus() + + if willSpeech { self.willSpeechCurrentStatus() } if elapsedTimeMinutes > self.maxOneKiloTime { self.maxOneKiloTime = elapsedTimeMinutes @@ -194,6 +197,10 @@ final class RecordingModel: NSObject, ObservableObject { } } + func changedWillSpeechStatus(status: Bool) { + self.willSpeech = status + } + func pause() { guard self.timerIsRunning == true else { return } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 3d89935..f98128d 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -67,11 +67,10 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { func fetchOptions() { self.recordRepository.fetchVoiceOption(key: Settings.voiceGuidanceEveryOnekm) { result in switch result { - case .failure(let error): - print(error) + case .failure(_): return case .success(let status): - print(status) + self.recording.changedWillSpeechStatus(status: status) } } } From c149a15be061bee9e3de40590d39c1dca426cc79 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:16:47 +0900 Subject: [PATCH 252/465] =?UTF-8?q?[Feat]=20#214=20UseCase=EC=97=90=20Fetc?= =?UTF-8?q?h=20Record=20Photo=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index f98128d..9bf3d88 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -73,5 +73,14 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording.changedWillSpeechStatus(status: status) } } + + self.recordRepository.fetchVoiceOption(key: Settings.recordPhoto) { result in + switch result { + case .failure(_): + return + case .success(let status): + print(status) + } + } } } From 09d3703b54dd9b732f96a26d7024b14de0e8554c Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:17:34 +0900 Subject: [PATCH 253/465] =?UTF-8?q?[Fix]=20Repository=20Fetch=20Option=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 262efda..5561dc2 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -10,7 +10,7 @@ import Foundation protocol RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) - func fetchVoiceOption(key: Settings, completion: @escaping (Result) -> Void) + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) } final class DefaultRecordRepository: RecordRepository { @@ -35,7 +35,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage.save(records: records, completion: completion) } - func fetchVoiceOption(key: Settings, completion: @escaping (Result) -> Void) { + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { self.settingsStorage.string(key: key) { value in guard let value = value else { completion(.failure(userDefaultsError.notExists)) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 9bf3d88..78d4675 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -65,7 +65,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func fetchOptions() { - self.recordRepository.fetchVoiceOption(key: Settings.voiceGuidanceEveryOnekm) { result in + self.recordRepository.fetchRecordOption(key: Settings.voiceGuidanceEveryOnekm) { result in switch result { case .failure(_): return @@ -74,7 +74,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } } - self.recordRepository.fetchVoiceOption(key: Settings.recordPhoto) { result in + self.recordRepository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { case .failure(_): return From 9dcfbd0c69fb9ab66d6b7757cf6812b102056027 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:20:44 +0900 Subject: [PATCH 254/465] =?UTF-8?q?[Feat]=20#214=20UseCase,=20PhotoModel?= =?UTF-8?q?=20Will=20Record=20Photo=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift | 11 +++++++++-- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index 500b8d9..c1d5037 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -11,10 +11,13 @@ import Photos final class RecordingPhotoModel { private let imageManager = PHImageManager() - - var representedAssetIdentifier: String? + private var willRecordPhoto = false func fetchPhotos(startDate: Date, endDate: Date) -> [String]? { + guard self.willRecordPhoto == true else { + return nil + } + let allMedia = PHAsset.fetchAssets(with: .image, options: nil) var assetIdentifiers = [String]() @@ -41,4 +44,8 @@ final class RecordingPhotoModel { return assetIdentifiers } + + func changedWillRecordPhotoStatus(status: Bool) { + self.willRecordPhoto = status + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 78d4675..b4c94fc 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -79,7 +79,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { case .failure(_): return case .success(let status): - print(status) + self.recordingPhoto.changedWillRecordPhotoStatus(status: status) } } } From 6570a271d410621e7bf93e098d1d317550631ee5 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Wed, 17 Nov 2021 16:22:27 +0900 Subject: [PATCH 255/465] =?UTF-8?q?[Feat]=20=EC=BD=94=EB=94=94=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B7=B0?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8,=20=EB=B7=B0=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=ED=9D=90=EB=A6=84=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 6 +++- .../ResultDetailCoordinator.swift | 34 +++++++++++++++++++ .../ResultDetailLargerInfoView.swift | 3 +- .../ResultDetailScene/ResultDetailModel.swift | 8 +++++ .../ResultDetailUseCase.swift | 10 ++++-- .../ResultDetailViewController.swift | 14 ++++++-- .../ResultDetailViewModel.swift | 32 +++++++++++++++++ 7 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a79661c..32918aa 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */; }; 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */; }; 49D5A957273A62F800937821 /* MountainDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */; }; + 49FC97682744E105008CE73A /* ResultDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -116,6 +117,7 @@ 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailModel.swift; sourceTree = ""; }; 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTitleView.swift; sourceTree = ""; }; 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTableViewCell.swift; sourceTree = ""; }; + 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailCoordinator.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -237,8 +239,9 @@ 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, 494803812743748D002854B1 /* ResultDetailViewModel.swift */, 4948038327437499002854B1 /* ResultDetailUseCase.swift */, - 493178B32743992400B5FB88 /* CollectionViewCell.swift */, 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, + 493178B32743992400B5FB88 /* CollectionViewCell.swift */, + 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -539,6 +542,7 @@ 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, + 49FC97682744E105008CE73A /* ResultDetailCoordinator.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift new file mode 100644 index 0000000..cbbf58d --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift @@ -0,0 +1,34 @@ +// +// ResultDetailCoordinator.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/17. +// +import UIKit +import CoreLocation + +class ResultDetailCoordinator: Coordinator { + var childCoordinators: [Coordinator] = [] + + weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController + var viewController: ResultDetailViewController + + func start() { + self.navigationController.present(viewController, animated: true, completion: nil) + } + + func dismiss() { + self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinators.removeLast() + } + + + init(navigationController: UINavigationController, records: Records) { + self.navigationController = navigationController + let viewModel = ResultDetailViewModel(useCase: ResultDetailUseCase(model: ResultDetailData(records: records))) + self.viewController = ResultDetailViewController(viewModel: viewModel) + self.viewController.coordinator = self + } + +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 7ec5b3e..77a1107 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -37,8 +37,7 @@ extension ResultDetailLargerInfoView { self.addSubview(collectionView) collectionView.delegate = self collectionView.dataSource = self - let layout = UICollectionViewFlowLayout() - collectionView.collectionViewLayout = layout + collectionView.collectionViewLayout = UICollectionViewFlowLayout() collectionView.translatesAutoresizingMaskIntoConstraints = false let constraints = [ diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 3ee8148..08f9472 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -15,6 +15,14 @@ struct ResultDetailData { // let pace: ResultPace let altitude: ResultAltitude let incline: ResultIncline + + init(records: Records) { + self.timeStamp = ResultTimeStamp(records: records) + self.distance = ResultDistance(records: records) + self.time = ResultTime(records: records) + self.altitude = ResultAltitude(records: records) + self.incline = ResultIncline(records: records) + } } struct ResultTimeStamp { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index d8e6c30..8ebeee0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -8,9 +8,13 @@ import Foundation class ResultDetailUseCase { - private var records: Records + private let model: ResultDetailData - init(records: Records) { - self.records = records + init(model: ResultDetailData) { + self.model = model + } + + func transferResultDetailData(completion: (ResultDetailData) -> Void) { + completion(self.model) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 5875b06..da3c2b9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -9,13 +9,23 @@ import UIKit import MapKit class ResultDetailViewController: UIViewController { + weak var coordinator: ResultDetailCoordinator? + private var viewModel: ResultDetailViewModel? private var mapView: MKMapView? private var infoView: UIView? + convenience init(viewModel: ResultDetailViewModel) { + self.init() + self.viewModel = viewModel + } + override func viewDidLoad() { super.viewDidLoad() - self.layoutInitialRecordDetailView() - self.registerRecognizers() + self.viewModel?.resultDetailDataReceived = { detailData in + self.layoutInitialRecordDetailView() + self.registerRecognizers() + } + viewModel?.setUp() } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 5fe7db0..664af53 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -27,3 +27,35 @@ protocol CellRepresentableData { var type: ResultDataType { get } var contents: [CellContentEntity] { get } } + +class ResultDetailViewModel { + private let useCase: ResultDetailUseCase + var resultDetailData: ResultDetailData? + var resultDetailDataReceived: (ResultDetailData) -> Void = { info in } + + init(useCase: ResultDetailUseCase) { + self.useCase = useCase + } + + func setUp() { + self.useCase.transferResultDetailData { [weak self] dataModel in + self?.resultDetailData = dataModel + self?.resultDetailDataReceived(dataModel) + } + } +} + +//private let useCase: MountainDetailUseCase +//var mountainDetail: MountainDetailModel? +//var mountainInfoReceived: (MountainDetailModel) -> Void = { info in } +// +//init(useCase: MountainDetailUseCase) { +// self.useCase = useCase +//} +// +//func setUpViewModel() { +// useCase.transferMountainInformation { [weak self] mountainInfo in +// self?.mountainDetail = mountainInfo +// self?.mountainInfoReceived(mountainInfo) +// } +//} From 73d5fa25202d90cf6e69b31de6c23754a37cb5ab Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 16:55:56 +0900 Subject: [PATCH 256/465] =?UTF-8?q?[Feat]=20#144=20Coordinator=20push=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewCoordinator.swift | 4 ++++ .../MountainListScene/MountainListViewCoordinator.swift | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 0b53972..26577c7 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -21,6 +21,10 @@ class MountainDetailViewCoordinator: Coordinator { } } + func startPush() { + self.navigationController.pushViewController(self.mountainDetailViewController, animated: true) + } + func dismiss() { self.navigationController.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index d5ebba2..b0c55dd 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -6,6 +6,7 @@ // import UIKit +import CoreLocation class MountainListViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? @@ -44,5 +45,12 @@ extension MountainListViewCoordinator { userDefaultsStorage: self.userDefaultsStorage))) } + + func pushMountainDetailViewController(mountainAnnotation: MountainAnnotation, location: CLLocation?) { + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: location) + mountainDetailViewCoordinator.parentCoordinator = self + self.childCoordinators.append(mountainDetailViewCoordinator) + mountainDetailViewCoordinator.startPush() + } } From 95f0e72b1e6e951b2000dd84fca1bca4ddc09098 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 17:06:57 +0900 Subject: [PATCH 257/465] =?UTF-8?q?[Feat]=20#144=20Controller=20Push=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewController.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 029f882..25658ae 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -7,6 +7,7 @@ import UIKit import Combine +import CoreLocation class MountainListViewController: UIViewController { enum MountainListSection: Int, CaseIterable { @@ -129,7 +130,15 @@ class MountainListViewController: UIViewController { extension MountainListViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - collectionView.deselectItem(at: indexPath, animated: true) + guard let mountains = self.viewModel?.mountains else { return } + let location = CLLocation(latitude: CLLocationDegrees(mountains[indexPath.item].latitude), + longitude: mountains[indexPath.item].longitude) + self.coordinator?.pushMountainDetailViewController(mountainAnnotation: MountainAnnotation( + title: mountains[indexPath.item].mountain.mountainName, + subtitle: mountains[indexPath.item].mountain.mountainHeight, + latitude: mountains[indexPath.item].latitude, + longitude: mountains[indexPath.item].longitude), + location: location) } } From b3154423b86462f0effe9a1c09996469aeba5e43 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 17:22:29 +0900 Subject: [PATCH 258/465] =?UTF-8?q?[Refactor]=20#218=20CollectionView=20Ce?= =?UTF-8?q?ll=20Font=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 067875a..76e4b91 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -13,13 +13,13 @@ final class MountainCell: UICollectionViewCell { private var name: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 17, weight: .bold) + label.font = .preferredFont(forTextStyle: .headline) return label }() private var height: UILabel = { let label = UILabel() - label.font = UIFont.systemFont(ofSize: 12, weight: .bold) + label.font = .preferredFont(forTextStyle: .subheadline) label.textColor = .systemGray2 return label }() @@ -27,7 +27,8 @@ final class MountainCell: UICollectionViewCell { private var location: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false - label.font = UIFont.systemFont(ofSize: 12, weight: .light) + label.font = .preferredFont(forTextStyle: .caption1) + label.numberOfLines = 2 label.textColor = .systemGray2 return label }() From c820b795f1f100a1fea2109d056eabb742912091 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 17 Nov 2021 16:26:36 +0900 Subject: [PATCH 259/465] =?UTF-8?q?[Refactor]=20#219=20MapScene=20?= =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 235 ++++++++---------- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 4 +- SanTa/SanTa/MapScene/MapViewModel.swift | 15 ++ SanTa/SanTa/MapScene/MapViewUseCase.swift | 37 ++- 4 files changed, 154 insertions(+), 137 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index e8ae984..12e9ead 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -13,12 +13,53 @@ protocol Animatable: AnyObject { class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? - private var mapView: MKMapView? - private var startButton = UIButton() - private var addAnnotationButton = UIButton() - private var manager = CLLocationManager() - private var userTrackingButton = MKUserTrackingButton() private var viewModel: MapViewModel? + private lazy var mapView: MKMapView = { + let mapView = MKMapView(frame: view.bounds) + mapView.showsUserLocation = true + mapView.showsScale = true + mapView.showsCompass = true + mapView.delegate = self + return mapView + }() + private lazy var startButton: UIButton = { + let button = UIButton() + button.backgroundColor = UIColor(named: "SantaColor") + button.translatesAutoresizingMaskIntoConstraints = false + button.setTitle("시작", for: .normal) + button.setTitleColor(.white, for: .normal) + button.titleLabel?.font = .boldSystemFont(ofSize: 25) + button.layer.cornerRadius = 50 + button.layer.shadowColor = UIColor.gray.cgColor + button.layer.shadowOpacity = 1 + button.layer.shadowRadius = 3 + button.layer.shadowOffset = CGSize(width: 0, height: 3) + return button + }() + private lazy var addAnnotationButton: UIButton = { + let button = UIButton() + button.isHidden = true + button.translatesAutoresizingMaskIntoConstraints = false + button.backgroundColor = UIColor(named: "SantaColor") + button.setTitle("이곳을 알고 계시나요?", for: .normal) + button.setTitleColor(.white, for: .normal) + button.titleLabel?.font = .boldSystemFont(ofSize: 15) + button.layer.cornerRadius = 15 + button.layer.shadowColor = UIColor.gray.cgColor + button.layer.shadowOpacity = 1 + button.layer.shadowRadius = 3 + button.layer.shadowOffset = CGSize(width: 0, height: 2) + return button + }() + private lazy var userTrackingButton: MKUserTrackingButton = { + let button = MKUserTrackingButton(mapView: self.mapView) + button.isHidden = true + button.backgroundColor = .white + button.translatesAutoresizingMaskIntoConstraints = false + button.layer.cornerRadius = 10 + button.clipsToBounds = true + return button + }() convenience init(viewModel: MapViewModel) { self.init() @@ -29,23 +70,57 @@ class MapViewController: UIViewController { super.viewDidLoad() self.configureViews() self.registerAnnotationView() - self.configureCoreLocationManager() self.configureViewModel() } override func viewWillAppear(_ animated: Bool) { viewModel?.viewWillAppear() - switch self.manager.authorizationStatus { - case .authorizedAlways, .authorizedWhenInUse: - self.userTrackingButton.isHidden = false - default: - self.userTrackingButton.isHidden = true - } + self.configureUserTrackingButton() + } + + private func configureViews() { + self.view.addSubview(self.mapView) + self.view.addSubview(self.startButton) + self.view.addSubview(self.addAnnotationButton) + self.view.addSubview(self.userTrackingButton) + self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) + + NSLayoutConstraint.activate([ + self.startButton.widthAnchor.constraint(equalToConstant: 100), + self.startButton.heightAnchor.constraint(equalToConstant: 100), + self.startButton.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -mapView.frame.height/6), + self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) + ]) + NSLayoutConstraint.activate([ + self.userTrackingButton.widthAnchor.constraint(equalToConstant: 50), + self.userTrackingButton.heightAnchor.constraint(equalToConstant: 50), + self.userTrackingButton.leftAnchor.constraint(equalTo: mapView.rightAnchor, constant: -100), + self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) + ]) + NSLayoutConstraint.activate([ + self.addAnnotationButton.widthAnchor.constraint(equalToConstant: 150), + self.addAnnotationButton.heightAnchor.constraint(equalToConstant: 30), + self.addAnnotationButton.bottomAnchor.constraint(equalTo: startButton.topAnchor, constant: -10), + self.addAnnotationButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) + ]) + } + + private func registerAnnotationView() { + self.mapView.register( + MountainAnnotationView.self, + forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier + ) + self.mapView.register( + ClusterAnnotationView.self, + forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier + ) } private func configureViewModel() { self.viewModel?.markersShouldUpdate = { self.configureMarkers() } self.viewModel?.mapShouldUpdate = { self.configureMap() } + self.viewModel?.initialLocationShouldUpdate = { self.configureLocation() } + self.viewModel?.locationPermissionDidChange = { self.configureUserTrackingButton() } self.viewModel?.viewDidLoad() } @@ -59,7 +134,7 @@ class MapViewController: UIViewController { mountainDescription: mountainEntity.mountain.mountainShortDescription, region: mountainEntity.mountain.mountainRegion ) - self.mapView?.addAnnotation(mountainAnnotation) + self.mapView.addAnnotation(mountainAnnotation) } } @@ -67,109 +142,16 @@ class MapViewController: UIViewController { guard let map = viewModel?.map else { return } switch map { case .infomation: - mapView?.mapType = .mutedStandard + self.mapView.mapType = .mutedStandard case .normal: - mapView?.mapType = .standard + self.mapView.mapType = .standard case .satellite: - mapView?.mapType = .satellite + self.mapView.mapType = .hybrid } } - private func configureViews() { - self.mapView = MKMapView(frame: view.bounds) - guard let mapView = mapView else { return } - self.view.addSubview(mapView) - mapView.showsUserLocation = true - mapView.showsScale = true - mapView.showsCompass = true - mapView.delegate = self - - self.view.addSubview(self.startButton) - self.startButton.backgroundColor = UIColor(named: "SantaColor") - self.startButton.translatesAutoresizingMaskIntoConstraints = false - self.startButton.setTitle("시작", for: .normal) - self.startButton.setTitleColor(.white, for: .normal) - self.startButton.titleLabel?.font = .boldSystemFont(ofSize: 25) - self.startButton.layer.cornerRadius = 50 - self.startButton.layer.shadowColor = UIColor.gray.cgColor - self.startButton.layer.shadowOpacity = 1 - self.startButton.layer.shadowRadius = 3 - self.startButton.layer.shadowOffset = CGSize(width: 0, height: 3) - - let startButtonConstraints = [ - self.startButton.widthAnchor.constraint(equalToConstant: 100), - self.startButton.heightAnchor.constraint(equalToConstant: 100), - self.startButton.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -150), - self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) - ] - NSLayoutConstraint.activate(startButtonConstraints) - - self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) - - self.userTrackingButton = .init(mapView: mapView) - self.view.addSubview(self.userTrackingButton) - self.userTrackingButton.isHidden = true - self.userTrackingButton.backgroundColor = .white - self.userTrackingButton.translatesAutoresizingMaskIntoConstraints = false - self.userTrackingButton.layer.cornerRadius = 10 - self.userTrackingButton.clipsToBounds = true - let userTrackingButtonConstraints = [ - self.userTrackingButton.widthAnchor.constraint(equalToConstant: 50), - self.userTrackingButton.heightAnchor.constraint(equalToConstant: 50), - self.userTrackingButton.leftAnchor.constraint( - equalTo: mapView.rightAnchor, - constant: -100 - ), - self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) - ] - NSLayoutConstraint.activate(userTrackingButtonConstraints) - - self.view.addSubview(self.addAnnotationButton) - self.addAnnotationButton.isHidden = true - self.addAnnotationButton.translatesAutoresizingMaskIntoConstraints = false - self.addAnnotationButton.backgroundColor = UIColor(named: "SantaColor") - self.addAnnotationButton.setTitle("이곳을 알고 계시나요?", for: .normal) - self.addAnnotationButton.setTitleColor(.white, for: .normal) - self.addAnnotationButton.titleLabel?.font = .boldSystemFont(ofSize: 15) - self.addAnnotationButton.layer.cornerRadius = 15 - self.addAnnotationButton.layer.shadowColor = UIColor.gray.cgColor - self.addAnnotationButton.layer.shadowOpacity = 1 - self.addAnnotationButton.layer.shadowRadius = 3 - self.addAnnotationButton.layer.shadowOffset = CGSize(width: 0, height: 2) - let addAnnotationButtonConstraints = [ - self.addAnnotationButton.widthAnchor.constraint(equalToConstant: 150), - self.addAnnotationButton.heightAnchor.constraint(equalToConstant: 30), - self.addAnnotationButton.bottomAnchor.constraint( - equalTo: startButton.topAnchor, - constant: -10 - ), - self.addAnnotationButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) - ] - NSLayoutConstraint.activate(addAnnotationButtonConstraints) - } - - private func registerAnnotationView() { - guard let mapView = mapView else { return } - mapView.register( - MountainAnnotationView.self, - forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier - ) - mapView.register( - ClusterAnnotationView.self, - forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier - ) - } - - private func configureCoreLocationManager() { - self.manager.requestWhenInUseAuthorization() - self.manager.requestAlwaysAuthorization() - self.manager.delegate = self - self.manager.desiredAccuracy = kCLLocationAccuracyBest - self.manager.startUpdatingLocation() - } - - private func render(_ location: CLLocation) { - guard let mapView = mapView else { return } + private func configureLocation() { + guard let location = viewModel?.initialLocation else { return } let coordinate = CLLocationCoordinate2D( latitude: location.coordinate.latitude, longitude: location.coordinate.longitude @@ -182,6 +164,11 @@ class MapViewController: UIViewController { mapView.setRegion(region, animated: true) } + private func configureUserTrackingButton() { + guard let permission = viewModel?.locationPermission else { return } + self.userTrackingButton.isHidden = !permission + } + private func authAlert() -> UIAlertController { let alert = UIAlertController(title: "위치정보 활성화", message: "지도에 현재 위치를 표시할 수 있도록 위치정보를 활성화해주세요", preferredStyle: .alert) let cancel = UIAlertAction(title: "아니요", style: .cancel) @@ -196,10 +183,9 @@ class MapViewController: UIViewController { @objc private func presentRecordingViewController() { UINotificationFeedbackGenerator().notificationOccurred(.success) - switch self.manager.authorizationStatus{ - case .authorizedWhenInUse, .authorizedAlways: + if let viewModel = self.viewModel, viewModel.locationPermission { self.coordinator?.presentRecordingViewController() - default: + } else { self.present(authAlert(), animated: false) } } @@ -256,25 +242,6 @@ extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { guard let annotation = view.annotation as? MountainAnnotation else { return } - - coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation, location: self.manager.location) - } -} - -extension MapViewController: CLLocationManagerDelegate { - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - if let location = locations.first { - manager.stopUpdatingLocation() - self.render(location) - } - } - - func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - switch manager.authorizationStatus { - case .authorizedAlways, .authorizedWhenInUse: - self.userTrackingButton.isHidden = false - default: - self.userTrackingButton.isHidden = true - } + coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation) } } diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 4984bf5..704fda3 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -49,8 +49,8 @@ extension MapViewCoordinator { childCoordinators.first?.start() } - func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation, location: CLLocation?) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: location) + func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation) { + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index d033518..98c1f9f 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -6,18 +6,25 @@ // import Foundation +import CoreLocation class MapViewModel { private let useCase: MapViewUseCase private(set) var mountains: [MountainEntity]? private(set) var map: Map? + private(set) var initialLocation: CLLocation? + var locationPermission: Bool { self.useCase.locationPermission } var markersShouldUpdate: () -> Void var mapShouldUpdate: () -> Void + var initialLocationShouldUpdate: () -> Void + var locationPermissionDidChange: () -> Void init(useCase: MapViewUseCase) { self.useCase = useCase self.markersShouldUpdate = {} self.mapShouldUpdate = {} + self.initialLocationShouldUpdate = {} + self.locationPermissionDidChange = {} } func viewDidLoad() { @@ -25,6 +32,14 @@ class MapViewModel { self?.mountains = mountains self?.markersShouldUpdate() } + self.useCase.initialLocation = { [weak self] initialLocation in + self?.initialLocation = initialLocation + self?.initialLocationShouldUpdate() + } + self.useCase.locationPermissionDidChanged = { [weak self] in + self?.locationPermissionDidChange() + } + self.useCase.prepareLocacationManager() } func viewWillAppear() { diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index 73764ae..ba92daa 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -7,12 +7,26 @@ import Foundation import OSLog +import CoreLocation -class MapViewUseCase { +class MapViewUseCase: NSObject { private let repository: MapViewRepository + private let manager = CLLocationManager() + var initialLocation: (CLLocation) -> Void + var locationPermissionDidChanged: () -> Void + var locationPermission: Bool { + switch self.manager.authorizationStatus { + case .authorizedAlways, .authorizedWhenInUse: + return true + default: + return false + } + } init(repository: MapViewRepository) { self.repository = repository + self.initialLocation = { _ in } + self.locationPermissionDidChanged = {} } func prepareMountainMarkers(completion: @escaping ([MountainEntity]?) -> Void) { @@ -38,4 +52,25 @@ class MapViewUseCase { } } } + + func prepareLocacationManager() { + self.manager.requestWhenInUseAuthorization() + self.manager.requestAlwaysAuthorization() + self.manager.delegate = self + self.manager.desiredAccuracy = kCLLocationAccuracyBest + self.manager.startUpdatingLocation() + } +} + +extension MapViewUseCase: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let location = locations.first { + manager.stopUpdatingLocation() + self.initialLocation(location) + } + } + + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + self.locationPermissionDidChanged() + } } From d6681fb8d29f61c117bf7f811db301eea2e4f7ca Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 17 Nov 2021 17:52:42 +0900 Subject: [PATCH 260/465] =?UTF-8?q?[Refactor]=20#220=20MountainDetailScene?= =?UTF-8?q?=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/MountainDetailScene/MountainDetailUseCase.swift | 7 +++---- .../MountainDetailViewCoordinator.swift | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 14c5c2e..01ff2cc 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -10,16 +10,15 @@ import CoreLocation class MountainDetailUseCase { private let mountainAnnotation: MountainAnnotation - private let location: CLLocation? + private let manager = CLLocationManager() - init(mountainAnnotation: MountainAnnotation, location: CLLocation?) { + init(mountainAnnotation: MountainAnnotation) { self.mountainAnnotation = mountainAnnotation - self.location = location } private func calculateDistance() -> Double? { let mountainLocation = CLLocation(latitude: self.mountainAnnotation.latitude, longitude: self.mountainAnnotation.longitude) - guard let distance = location?.distance(from: mountainLocation) else { + guard let distance = manager.location?.distance(from: mountainLocation) else { return nil } return distance / 1000 diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 0b53972..31045e8 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -27,9 +27,9 @@ class MountainDetailViewCoordinator: Coordinator { } - init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation, location: CLLocation?) { + init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation) { self.navigationController = navigationController - let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation, location: location)) + let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation)) self.mountainDetailViewController = MountainDetailViewController(viewModel: viewModel) self.mountainDetailViewController.coordinator = self } From 624dc34f1985cf983463c77b2f094209fc98c74e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Wed, 17 Nov 2021 19:34:15 +0900 Subject: [PATCH 261/465] =?UTF-8?q?[Feat]=20=EA=B0=9C=EB=B3=84=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=ED=99=94=EB=A9=B4=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewModel.swift | 171 +++++++++++++++--- 1 file changed, 142 insertions(+), 29 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 664af53..0b3b0fd 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -6,28 +6,105 @@ // import Foundation - -enum ResultDataType: String, CaseIterable { - case start = "시작" - case end = "종료" - case distance = "거리" - case time = "시간" - case pace = "페이스(1km당 소요시간)" - case altitude = "고도" - case incline = "경사도" -} +import CoreLocation struct CellContentEntity { let content: String - let subContent: String? - let contentTitle: String? + let contentTitle: String } -protocol CellRepresentableData { - var type: ResultDataType { get } +protocol ResultDetailCellRepresentable { + var title: String { get } var contents: [CellContentEntity] { get } } +struct DistanceViewModel: ResultDetailCellRepresentable { + let title: String = "거리" + let contents: [CellContentEntity] + + init(distanceData: ResultDistance) { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + guard let total = formatter.string(from: NSNumber(value: distanceData.total)), + let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: total, contentTitle: "전체"), + CellContentEntity(content: steps, contentTitle: "걸음수") + ] + } +} + +struct TimeViewModel: ResultDetailCellRepresentable { + var title: String = "시간" + var contents: [CellContentEntity] + + init(timeData: ResultTime) { + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + guard let spent = formatter.string(from: timeData.spent), + let active = formatter.string(from: timeData.active), + let inactive = formatter.string(from: timeData.inactive) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: spent, contentTitle: "소요"), + CellContentEntity(content: active, contentTitle: "운동"), + CellContentEntity(content: inactive, contentTitle: "휴식"), + ] + } +} + +struct PaceViewModel: ResultDetailCellRepresentable { + var title: String = "페이스(1km당 소요시간)" + var contents: [CellContentEntity] + + +} + +struct AltitudeViewModel: ResultDetailCellRepresentable { + var title: String = "고도" + var contents: [CellContentEntity] + + init(altitudeData: ResultAltitude) { + self.contents = [ + CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), + CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), + CellContentEntity(content: String(altitudeData.lowest), contentTitle: "최저"), + CellContentEntity(content: String(altitudeData.starting), contentTitle: "시작"), + CellContentEntity(content: String(altitudeData.ending), contentTitle: "종료"), + ] + } +} + +struct InclineViewModel: ResultDetailCellRepresentable { + var title: String = "경사도" + var contents: [CellContentEntity] + + init(inclineData: ResultIncline) { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + guard let uphill = formatter.string(from: NSNumber(value: inclineData.uphillKilometer)), + let downhill = formatter.string(from: NSNumber(value: inclineData.downhillKilometer)), + let plain = formatter.string(from: NSNumber(value: inclineData.plainKilometer)) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: String(inclineData.average), contentTitle: "평균"), + CellContentEntity(content: String(inclineData.highest), contentTitle: "최고"), + CellContentEntity(content: uphill, contentTitle: "오르막(km)"), + CellContentEntity(content: downhill, contentTitle: "내리막(km)"), + CellContentEntity(content: plain, contentTitle: "평지(km)"), + ] + } +} + class ResultDetailViewModel { private let useCase: ResultDetailUseCase var resultDetailData: ResultDetailData? @@ -43,19 +120,55 @@ class ResultDetailViewModel { self?.resultDetailDataReceived(dataModel) } } + + var recordDate: String { + guard let endTime = self.resultDetailData?.timeStamp.endTime else { + return "" + } + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier: "ko-KR") + dateFormatter.dateFormat = "yyyy. MM. dd. (E)" + return dateFormatter.string(from: endTime) + } + + var startDate: String { + guard let startTime = self.resultDetailData?.timeStamp.startTime else { + return "" + } + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier: "ko-KR") + dateFormatter.dateFormat = "a h시 m분" + return dateFormatter.string(from: startTime) + } + + var endDate: String { + guard let endTime = self.resultDetailData?.timeStamp.endTime else { + return "" + } + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier: "ko-KR") + dateFormatter.dateFormat = "a h시 m분" + return dateFormatter.string(from: endTime) + } + + var startLocation: String { + guard let location = self.resultDetailData?.timeStamp.startLocation else { + return "" + } + var si: String? + var gu: String? + var dong: String? + + let geoCoder = CLGeocoder() + let CLLocation = CLLocation(latitude: location.latitude, longitude: location.longitude) + geoCoder.reverseGeocodeLocation(CLLocation, preferredLocale: Locale(identifier: "ko-KR")) { place, error in + guard error != nil, let place = place?.first else { + return + } + si = place.administrativeArea + gu = place.locality + dong = place.thoroughfare + } + return "\(si ?? "") \(gu ?? "") \(dong ?? "")" + } } - -//private let useCase: MountainDetailUseCase -//var mountainDetail: MountainDetailModel? -//var mountainInfoReceived: (MountainDetailModel) -> Void = { info in } -// -//init(useCase: MountainDetailUseCase) { -// self.useCase = useCase -//} -// -//func setUpViewModel() { -// useCase.transferMountainInformation { [weak self] mountainInfo in -// self?.mountainDetail = mountainInfo -// self?.mountainInfoReceived(mountainInfo) -// } -//} From 452d96cece8f835e2fb4bb893a180266d754c25f Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 21:54:27 +0900 Subject: [PATCH 262/465] =?UTF-8?q?[Feat]=20#223=20Background=20=EC=9D=8C?= =?UTF-8?q?=EC=84=B1=20=EC=95=88=EB=82=B4=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppDelegate.swift | 4 +++- SanTa/SanTa/RecordingScene/RecordingModel.swift | 9 +++++---- SanTa/SanTa/Resources/Info.plist | 3 +-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index a909cf7..dd30bf4 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -7,6 +7,7 @@ import UIKit import CoreData +import AVFoundation @main class AppDelegate: UIResponder, UIApplicationDelegate { @@ -14,7 +15,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. + try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default) + try? AVAudioSession.sharedInstance().setActive(true) return true } diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 9470ec0..00de96a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,7 +19,9 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var gpsStatus = true private let pedoMeter = CMPedometer() + private let synthesizer = AVSpeechSynthesizer() private var locationManager = CLLocationManager() + private var timer: DispatchSourceTimer? private var timerIsRunning = false private var records: Records? @@ -131,7 +133,7 @@ final class RecordingModel: NSObject, ObservableObject { dispatchGroup.notify(queue: .global()) { [weak self] in guard let walk = self?.currentWalk, let currentKile = self?.currentDistance else { return } - + self?.calculateSpeed() self?.walk = "\(walk)" let distanceString = String(format: "%.2f", currentKile) @@ -164,12 +166,11 @@ final class RecordingModel: NSObject, ObservableObject { } private func willSpeechCurrentStatus() { - let synthesizer = AVSpeechSynthesizer() - let speech = "현재 총 거리는 \(kilometer)킬로미터 소요 시간은 \(time)초 현재 고도는 \(altitude)입니다." + let speech = "현재 총 거리는 \(self.kilometer)킬로미터 소요 시간은 \(self.time)초 현재 고도는 \(self.altitude)입니다." let utterance = AVSpeechUtterance(string: speech) utterance.voice = AVSpeechSynthesisVoice(language: "ko-KR") utterance.rate = 0.4 - synthesizer.speak(utterance) + self.synthesizer.speak(utterance) } private func appendRecord() { diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index 65bc8e2..4f942fa 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,8 +2,6 @@ - NSPhotoLibraryUsageDescription - 사진 저장을 위해 사진 접근을 허용해주세요. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -23,6 +21,7 @@ UIBackgroundModes + audio location From 7828f7d2ab7283c65ea1ccc35f7af4cfacc38d3f Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 22:03:02 +0900 Subject: [PATCH 263/465] =?UTF-8?q?[Feat]=20#207,=20#208=20Records=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=EC=B2=B4=EC=97=90=20=EC=B5=9C=EA=B3=A0,=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=80=20=EC=86=8D=EB=8F=84=20=EB=8B=B9=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 2 ++ SanTa/SanTa/RecordingScene/RecordingModel.swift | 6 +++++- SanTa/SanTa/ResultScene/ResultUseCase.swift | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 053bad5..b6f3520 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -96,6 +96,8 @@ struct Records { private(set) var title: String private(set) var records: [Record] private(set) var assetIdentifiers: [String] + private(set) var secondPerHighestSpeed: Int + private(set) var secondPerMinimumSpeed: Int var date: Date? { return records.last?.endTime diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 00de96a..7b0105f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -182,7 +182,11 @@ final class RecordingModel: NSObject, ObservableObject { locations: self.location) guard self.records != nil else { - self.records = Records(title: "", records: [record], assetIdentifiers: [String]()) + self.records = Records(title: "", + records: [record], + assetIdentifiers: [String](), + secondPerHighestSpeed: minOneKiloTime, + secondPerMinimumSpeed: maxOneKiloTime) return } diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index 9e6c5b1..b264a46 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -47,7 +47,7 @@ final class ResultUseCase { guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } records.append(record) } - return Records(title: title, records: records, assetIdentifiers: [String]()) + return Records(title: title, records: records, assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int()) } private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { From ff755aa21279b6f6fa0e0514c07b8395a39dc499 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 22:07:18 +0900 Subject: [PATCH 264/465] =?UTF-8?q?[Feat]=20#206=20=EC=B5=9C=EA=B3=A0=20?= =?UTF-8?q?=EC=88=9C=EA=B0=84=20=EC=86=8D=EB=8F=84=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 7b0105f..e2bd8c5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -30,7 +30,7 @@ final class RecordingModel: NSObject, ObservableObject { private var currentWalk = 0 private var currentDistance: Double = 0 private var maxOneKiloTime = 0 - private var minOneKiloTime = 0 + private var minOneKiloTime = Int.max private var sliceDistance: Double = 1 private var location = [Location]() @@ -182,11 +182,15 @@ final class RecordingModel: NSObject, ObservableObject { locations: self.location) guard self.records != nil else { + var minTime = 0 + if minOneKiloTime != Int.max { + minTime = self.minOneKiloTime + } self.records = Records(title: "", records: [record], assetIdentifiers: [String](), - secondPerHighestSpeed: minOneKiloTime, - secondPerMinimumSpeed: maxOneKiloTime) + secondPerHighestSpeed: minTime, + secondPerMinimumSpeed: self.maxOneKiloTime) return } From 03420f14a171233c8086a02a7a974d73fe439cc2 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 22:09:46 +0900 Subject: [PATCH 265/465] =?UTF-8?q?[Feat]=20#206,=20#207=20=EC=B5=9C?= =?UTF-8?q?=EA=B3=A0,=20=EC=B5=9C=EC=A0=80=20=EC=86=8D=EB=8F=84=20?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=EA=B0=84=20CoreData=20Attribute=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 15ce1ec..dbec890 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -16,12 +16,14 @@ + + - + \ No newline at end of file From 96362f716a6507b59175f1c8c269c3919c739304 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 22:12:54 +0900 Subject: [PATCH 266/465] =?UTF-8?q?[Feat]=20#206,=20#207=20=EC=B5=9C?= =?UTF-8?q?=EA=B3=A0,=20=EC=B5=9C=EC=A0=80=20=EC=86=8D=EB=8F=84=20?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=EA=B0=84=20CoreData=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Persistences/CoreDataRecordStorage.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 5134b5c..95a1abd 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -28,6 +28,8 @@ final class CoreDataRecordStorage: RecordsStorage { into: context) recordsObject.setValue(records.title, forKey: "title") + recordsObject.setValue(records.secondPerHighestSpeed, forKey: "secondPerHighestSpeed") + recordsObject.setValue(records.secondPerMinimumSpeed, forKey: "secondPerMinimumSpeed") do { let assetIdentifiers = try NSKeyedArchiver.archivedData(withRootObject: records.assetIdentifiers, requiringSecureCoding: true) From 55b609b5153ae1bd826f8818ea99193f4560e3d0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 22:26:47 +0900 Subject: [PATCH 267/465] =?UTF-8?q?[Refactor]=20#218=20Cell=20Label=20Dyna?= =?UTF-8?q?mic=20Text=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 8 ++++++-- .../MountainListScene/MountainListViewController.swift | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 76e4b91..9ef70fb 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -14,12 +14,14 @@ final class MountainCell: UICollectionViewCell { private var name: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .headline) + label.adjustsFontForContentSizeCategory = true return label }() private var height: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .subheadline) + label.adjustsFontForContentSizeCategory = true label.textColor = .systemGray2 return label }() @@ -27,8 +29,9 @@ final class MountainCell: UICollectionViewCell { private var location: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false - label.font = .preferredFont(forTextStyle: .caption1) - label.numberOfLines = 2 + label.adjustsFontForContentSizeCategory = true + label.font = .preferredFont(forTextStyle: .callout) + label.numberOfLines = 5 label.textColor = .systemGray2 return label }() @@ -64,6 +67,7 @@ final class MountainCell: UICollectionViewCell { let locationConstrain = [ self.location.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10), self.location.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), + self.location.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -30), self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), ] NSLayoutConstraint.activate(locationConstrain) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 25658ae..3d82b3d 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -100,12 +100,12 @@ class MountainListViewController: UIViewController { ] NSLayoutConstraint.activate(collectionViewConstrain) } - + //fractionalWidth(0.25) private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in - let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(0.25))) + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) - let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(180)),subitems: [item]) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)),subitems: [item]) let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) From 65acf58c598c4602d8586d99ed65f7425b3848d3 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 23:19:50 +0900 Subject: [PATCH 268/465] [Feat] #218 CollectionView Footer Register --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ .../MountainListScene/MountainCell.swift | 4 +- .../MountainFooterView.swift | 39 +++++++++++++++++++ .../MountainListViewController.swift | 9 ++++- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTa/MountainListScene/MountainFooterView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a79661c..0289db4 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + DA854FBE274545FA00E51E4B /* MountainFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FBD274545FA00E51E4B /* MountainFooterView.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; @@ -167,6 +168,7 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; + DA854FBD274545FA00E51E4B /* MountainFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainFooterView.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; @@ -252,6 +254,7 @@ DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */, DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */, 985EEF62272FDA98002413D9 /* MountainCell.swift */, + DA854FBD274545FA00E51E4B /* MountainFooterView.swift */, ); path = MountainListScene; sourceTree = ""; @@ -524,6 +527,7 @@ 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, + DA854FBE274545FA00E51E4B /* MountainFooterView.swift in Sources */, DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 9ef70fb..bd72a8b 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -58,7 +58,7 @@ final class MountainCell: UICollectionViewCell { func configureView() { self.addSubview(self.stackView) let stackViewConstrain = [ - self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), + self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), self.stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), ] NSLayoutConstraint.activate(stackViewConstrain) @@ -68,7 +68,7 @@ final class MountainCell: UICollectionViewCell { self.location.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10), self.location.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), self.location.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -30), - self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), + self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20), ] NSLayoutConstraint.activate(locationConstrain) } diff --git a/SanTa/SanTa/MountainListScene/MountainFooterView.swift b/SanTa/SanTa/MountainListScene/MountainFooterView.swift new file mode 100644 index 0000000..252eaa8 --- /dev/null +++ b/SanTa/SanTa/MountainListScene/MountainFooterView.swift @@ -0,0 +1,39 @@ +// +// MountainFooterView.swift +// SanTa +// +// Created by 김민창 on 2021/11/17. +// + +import UIKit + +final class MountainFooterView: UIView { + + static let identifier = "MountainFooterView" + + private var footerView: UIView = { + let view = UIView() + view.backgroundColor = .systemGray4 + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + configureView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configureView() { + self.addSubview(self.footerView) + let footerViewConstraint = [ + self.footerView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10), + self.footerView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10), + ] + NSLayoutConstraint.activate(footerViewConstraint) + + } +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 3d82b3d..07cb409 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -88,6 +88,7 @@ class MountainListViewController: UIViewController { self.mountainListCollectionView.delegate = self self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() self.mountainListCollectionView.register(MountainCell.self, forCellWithReuseIdentifier: MountainCell.identifier) + self.mountainListCollectionView.register(MountainFooterView.self, forSupplementaryViewOfKind: "footer", withReuseIdentifier: MountainFooterView.identifier) } private func configureView() { @@ -100,7 +101,7 @@ class MountainListViewController: UIViewController { ] NSLayoutConstraint.activate(collectionViewConstrain) } - //fractionalWidth(0.25) + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500))) @@ -109,6 +110,12 @@ class MountainListViewController: UIViewController { let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + + let footerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(1)) + let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: footerSize, elementKind: "footer", alignment: .bottom) + + section.boundarySupplementaryItems = [footer] + return section } } From ec1ad3e417884c109e18ba7889c4c3f2bff2cf1d Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 17 Nov 2021 23:29:56 +0900 Subject: [PATCH 269/465] =?UTF-8?q?[Fix]=20#218=20CollectionView=20Footer?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 -- .../MountainFooterView.swift | 39 ------------------- .../MountainListViewController.swift | 6 --- 3 files changed, 49 deletions(-) delete mode 100644 SanTa/SanTa/MountainListScene/MountainFooterView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 0289db4..a79661c 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -76,7 +76,6 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; - DA854FBE274545FA00E51E4B /* MountainFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FBD274545FA00E51E4B /* MountainFooterView.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; @@ -168,7 +167,6 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; - DA854FBD274545FA00E51E4B /* MountainFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainFooterView.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; @@ -254,7 +252,6 @@ DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */, DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */, 985EEF62272FDA98002413D9 /* MountainCell.swift */, - DA854FBD274545FA00E51E4B /* MountainFooterView.swift */, ); path = MountainListScene; sourceTree = ""; @@ -527,7 +524,6 @@ 54851286272A6AD500407F28 /* MapViewController.swift in Sources */, 984DDEC9273271EC003BE56B /* CoreDataStorage.swift in Sources */, 9826F3DD2739035E0064FA85 /* Option.swift in Sources */, - DA854FBE274545FA00E51E4B /* MountainFooterView.swift in Sources */, DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */, 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, diff --git a/SanTa/SanTa/MountainListScene/MountainFooterView.swift b/SanTa/SanTa/MountainListScene/MountainFooterView.swift deleted file mode 100644 index 252eaa8..0000000 --- a/SanTa/SanTa/MountainListScene/MountainFooterView.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// MountainFooterView.swift -// SanTa -// -// Created by 김민창 on 2021/11/17. -// - -import UIKit - -final class MountainFooterView: UIView { - - static let identifier = "MountainFooterView" - - private var footerView: UIView = { - let view = UIView() - view.backgroundColor = .systemGray4 - return view - }() - - override init(frame: CGRect) { - super.init(frame: frame) - - configureView() - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - func configureView() { - self.addSubview(self.footerView) - let footerViewConstraint = [ - self.footerView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10), - self.footerView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10), - ] - NSLayoutConstraint.activate(footerViewConstraint) - - } -} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 07cb409..ee4c24d 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -88,7 +88,6 @@ class MountainListViewController: UIViewController { self.mountainListCollectionView.delegate = self self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() self.mountainListCollectionView.register(MountainCell.self, forCellWithReuseIdentifier: MountainCell.identifier) - self.mountainListCollectionView.register(MountainFooterView.self, forSupplementaryViewOfKind: "footer", withReuseIdentifier: MountainFooterView.identifier) } private func configureView() { @@ -111,11 +110,6 @@ class MountainListViewController: UIViewController { section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) - let footerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(1)) - let footer = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: footerSize, elementKind: "footer", alignment: .bottom) - - section.boundarySupplementaryItems = [footer] - return section } } From 0a2484947336c3359ea25eb3707cf404a37cf0a2 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Wed, 17 Nov 2021 23:54:30 +0900 Subject: [PATCH 270/465] =?UTF-8?q?[Feat]=20BezierPath=20=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A0=20=EA=B7=B8=EB=A6=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 10 +- SanTa/SanTa/RecordingScene/Record.swift | 14 ++ .../CollectionViewCell.swift | 14 -- .../SanTa/ResultDetailScene/DetailCell.swift | 39 ++++ .../ResultDetailCoordinator.swift | 1 - .../ResultDetailLargerInfoView.swift | 3 +- .../ResultDetailViewModel.swift | 209 ++++++++---------- .../ResultScene/ResultViewController.swift | 4 + .../ResultScene/ResultViewCoordinator.swift | 6 + 9 files changed, 165 insertions(+), 135 deletions(-) delete mode 100644 SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift create mode 100644 SanTa/SanTa/ResultDetailScene/DetailCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 32918aa..d323416 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */; }; 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */; }; - 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B32743992400B5FB88 /* CollectionViewCell.swift */; }; + 493178B42743992400B5FB88 /* DetailCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B32743992400B5FB88 /* DetailCell.swift */; }; 493178B627439D0000B5FB88 /* ResultDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B527439D0000B5FB88 /* ResultDetailModel.swift */; }; 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494803812743748D002854B1 /* ResultDetailViewModel.swift */; }; 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; @@ -103,7 +103,7 @@ /* Begin PBXFileReference section */ 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewController.swift; sourceTree = ""; }; 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailSmallerInfoView.swift; sourceTree = ""; }; - 493178B32743992400B5FB88 /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; + 493178B32743992400B5FB88 /* DetailCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailCell.swift; sourceTree = ""; }; 493178B527439D0000B5FB88 /* ResultDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailModel.swift; sourceTree = ""; }; 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; @@ -234,14 +234,14 @@ 5428FDB7272F8B34002F9D40 /* ResultDetailScene */ = { isa = PBXGroup; children = ( + 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */, 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, 494803812743748D002854B1 /* ResultDetailViewModel.swift */, 4948038327437499002854B1 /* ResultDetailUseCase.swift */, 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, - 493178B32743992400B5FB88 /* CollectionViewCell.swift */, - 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */, + 493178B32743992400B5FB88 /* DetailCell.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -545,7 +545,7 @@ 49FC97682744E105008CE73A /* ResultDetailCoordinator.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, - 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */, + 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 053bad5..e95d372 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -113,6 +113,20 @@ struct Records { return records.reduce(0) { $0 + $1.step } } + var maxAltitude: Double { + guard let max = records.compactMap({ $0.maxAltitude }).max() else { + return 0 + } + return max + } + + var minAltitude: Double { + guard let min = records.compactMap({ $0.minAltitude }).min() else { + return 0 + } + return min + } + var maxAltitudeDifference: Double { guard let max = records.compactMap({ $0.maxAltitude }).max(), let min = records.compactMap({ $0.minAltitude }).min() diff --git a/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift b/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift deleted file mode 100644 index cd5ee74..0000000 --- a/SanTa/SanTa/ResultDetailScene/CollectionViewCell.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// CollectionViewCell.swift -// SanTa -// -// Created by Jiwon Yoon on 2021/11/16. -// - -import UIKit - -class CollectionViewCell: UICollectionViewCell { -// convenience init() { -// -// } -} diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift new file mode 100644 index 0000000..343946c --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -0,0 +1,39 @@ +// +// CollectionViewCell.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/16. +// + +import UIKit + +class DetailCell: UICollectionViewCell { + var data: ResultDetailCellRepresentable? + let title: UILabel = UILabel() + + func configure(with cellData: ResultDetailCellRepresentable) { + self.data = cellData + + + } +} + +extension DetailCell { + private func layout(data: ResultDetailCellRepresentable) { + let title = UILabel() + title.text = data.title + } + + override func draw(_ rect: CGRect) { + let path = UIBezierPath() + path.lineWidth = 1 + path.lineJoinStyle = .round + let startingX: CGFloat = title.frame.origin.x + title.frame.width + let startingY: CGFloat = title.frame.origin.y + title.frame.height / 2 + path.move(to: CGPoint(x: startingX, y: startingY)) + path.addLine(to: CGPoint(x: self.bounds.width, y: startingY)) + path.close() + UIColor(named: "SantaColor")?.set() + path.stroke() + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift index cbbf58d..03c50a1 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift @@ -23,7 +23,6 @@ class ResultDetailCoordinator: Coordinator { self.parentCoordinator?.childCoordinators.removeLast() } - init(navigationController: UINavigationController, records: Records) { self.navigationController = navigationController let viewModel = ResultDetailViewModel(useCase: ResultDetailUseCase(model: ResultDetailData(records: records))) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 77a1107..16cc2ca 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -23,7 +23,6 @@ class ResultDetailLargerInfoView: UIView { extension ResultDetailLargerInfoView { private func configureDownArrow() { - //chevron.compact.down let downArrow:UIImageView = .init(image: UIImage(systemName: "chevron.compact.down")?.withTintColor(.black)) downArrow.translatesAutoresizingMaskIntoConstraints = false let downArrowConstraints = [ @@ -52,7 +51,7 @@ extension ResultDetailLargerInfoView { extension ResultDetailLargerInfoView: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - 4 + section == 0 ? 3 : 2 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 0b3b0fd..e5b3532 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -8,103 +8,6 @@ import Foundation import CoreLocation -struct CellContentEntity { - let content: String - let contentTitle: String -} - -protocol ResultDetailCellRepresentable { - var title: String { get } - var contents: [CellContentEntity] { get } -} - -struct DistanceViewModel: ResultDetailCellRepresentable { - let title: String = "거리" - let contents: [CellContentEntity] - - init(distanceData: ResultDistance) { - let formatter = NumberFormatter() - formatter.numberStyle = .decimal - formatter.maximumFractionDigits = 2 - guard let total = formatter.string(from: NSNumber(value: distanceData.total)), - let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { - self.contents = [] - return - } - self.contents = [ - CellContentEntity(content: total, contentTitle: "전체"), - CellContentEntity(content: steps, contentTitle: "걸음수") - ] - } -} - -struct TimeViewModel: ResultDetailCellRepresentable { - var title: String = "시간" - var contents: [CellContentEntity] - - init(timeData: ResultTime) { - let formatter = DateComponentsFormatter() - formatter.allowedUnits = [.hour, .minute] - guard let spent = formatter.string(from: timeData.spent), - let active = formatter.string(from: timeData.active), - let inactive = formatter.string(from: timeData.inactive) else { - self.contents = [] - return - } - self.contents = [ - CellContentEntity(content: spent, contentTitle: "소요"), - CellContentEntity(content: active, contentTitle: "운동"), - CellContentEntity(content: inactive, contentTitle: "휴식"), - ] - } -} - -struct PaceViewModel: ResultDetailCellRepresentable { - var title: String = "페이스(1km당 소요시간)" - var contents: [CellContentEntity] - - -} - -struct AltitudeViewModel: ResultDetailCellRepresentable { - var title: String = "고도" - var contents: [CellContentEntity] - - init(altitudeData: ResultAltitude) { - self.contents = [ - CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), - CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), - CellContentEntity(content: String(altitudeData.lowest), contentTitle: "최저"), - CellContentEntity(content: String(altitudeData.starting), contentTitle: "시작"), - CellContentEntity(content: String(altitudeData.ending), contentTitle: "종료"), - ] - } -} - -struct InclineViewModel: ResultDetailCellRepresentable { - var title: String = "경사도" - var contents: [CellContentEntity] - - init(inclineData: ResultIncline) { - let formatter = NumberFormatter() - formatter.numberStyle = .decimal - formatter.maximumFractionDigits = 2 - guard let uphill = formatter.string(from: NSNumber(value: inclineData.uphillKilometer)), - let downhill = formatter.string(from: NSNumber(value: inclineData.downhillKilometer)), - let plain = formatter.string(from: NSNumber(value: inclineData.plainKilometer)) else { - self.contents = [] - return - } - self.contents = [ - CellContentEntity(content: String(inclineData.average), contentTitle: "평균"), - CellContentEntity(content: String(inclineData.highest), contentTitle: "최고"), - CellContentEntity(content: uphill, contentTitle: "오르막(km)"), - CellContentEntity(content: downhill, contentTitle: "내리막(km)"), - CellContentEntity(content: plain, contentTitle: "평지(km)"), - ] - } -} - class ResultDetailViewModel { private let useCase: ResultDetailUseCase var resultDetailData: ResultDetailData? @@ -150,25 +53,105 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: endTime) } +} + +struct CellContentEntity { + let content: String + let contentTitle: String +} + +protocol ResultDetailCellRepresentable { + var title: String { get } + var contents: [CellContentEntity] { get } +} + +extension ResultDetailViewModel { - var startLocation: String { - guard let location = self.resultDetailData?.timeStamp.startLocation else { - return "" + + struct DistanceViewModel: ResultDetailCellRepresentable { + let title: String = "거리" + let contents: [CellContentEntity] + + init(distanceData: ResultDistance) { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + guard let total = formatter.string(from: NSNumber(value: distanceData.total)), + let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: total, contentTitle: "전체"), + CellContentEntity(content: steps, contentTitle: "걸음수") + ] } - var si: String? - var gu: String? - var dong: String? + } + + struct TimeViewModel: ResultDetailCellRepresentable { + var title: String = "시간" + var contents: [CellContentEntity] + + init(timeData: ResultTime) { + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + guard let spent = formatter.string(from: timeData.spent), + let active = formatter.string(from: timeData.active), + let inactive = formatter.string(from: timeData.inactive) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: spent, contentTitle: "소요"), + CellContentEntity(content: active, contentTitle: "운동"), + CellContentEntity(content: inactive, contentTitle: "휴식"), + ] + } + } + + struct PaceViewModel: ResultDetailCellRepresentable { + var title: String = "페이스(1km당 소요시간)" + var contents: [CellContentEntity] + + + } + + struct AltitudeViewModel: ResultDetailCellRepresentable { + var title: String = "고도" + var contents: [CellContentEntity] + + init(altitudeData: ResultAltitude) { + self.contents = [ + CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), + CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), + CellContentEntity(content: String(altitudeData.lowest), contentTitle: "최저"), + CellContentEntity(content: String(altitudeData.starting), contentTitle: "시작"), + CellContentEntity(content: String(altitudeData.ending), contentTitle: "종료"), + ] + } + } + + struct InclineViewModel: ResultDetailCellRepresentable { + var title: String = "경사도" + var contents: [CellContentEntity] - let geoCoder = CLGeocoder() - let CLLocation = CLLocation(latitude: location.latitude, longitude: location.longitude) - geoCoder.reverseGeocodeLocation(CLLocation, preferredLocale: Locale(identifier: "ko-KR")) { place, error in - guard error != nil, let place = place?.first else { - return - } - si = place.administrativeArea - gu = place.locality - dong = place.thoroughfare + init(inclineData: ResultIncline) { + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + guard let uphill = formatter.string(from: NSNumber(value: inclineData.uphillKilometer)), + let downhill = formatter.string(from: NSNumber(value: inclineData.downhillKilometer)), + let plain = formatter.string(from: NSNumber(value: inclineData.plainKilometer)) else { + self.contents = [] + return + } + self.contents = [ + CellContentEntity(content: String(inclineData.average), contentTitle: "평균"), + CellContentEntity(content: String(inclineData.highest), contentTitle: "최고"), + CellContentEntity(content: uphill, contentTitle: "오르막(km)"), + CellContentEntity(content: downhill, contentTitle: "내리막(km)"), + CellContentEntity(content: plain, contentTitle: "평지(km)"), + ] } - return "\(si ?? "") \(gu ?? "") \(dong ?? "")" } } diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index de586d0..17bb694 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -130,6 +130,10 @@ extension ResultViewController: UICollectionViewDataSource { sectionHeader.configure(month: sectionInfo.date, count: sectionInfo.count, distance: sectionInfo.distance, time: sectionInfo.time) return sectionHeader } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + + } } extension ResultViewController: UICollectionViewDelegate { diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index 2b1e880..23cbf23 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -28,6 +28,12 @@ class ResultViewCoordinator: Coordinator { return navigationController } + +// func pushDetailViewController(records: Records) { +// let storage = CoreDataRecordStorage(coreDataStorage: self.coreDataStorage) +// storage. +// let resultDetailCoordinator = ResultDetailCoordinator(navigationController: self.navigationController, records: <#T##Records#>) +// } } extension ResultViewCoordinator { From 9078699a8852e6e54f446f31158143aaaf6a3ac3 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon <> Date: Thu, 18 Nov 2021 00:12:43 +0900 Subject: [PATCH 271/465] =?UTF-8?q?[Feat]=20=EA=B8=B0=EB=A1=9D=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=A0=95=EB=B3=B4=20=EC=85=80=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 5 -- .../SanTa/ResultDetailScene/DetailCell.swift | 50 +++++++++++++++---- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 8647302..7166dc6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -93,12 +93,8 @@ extension MountainDetailViewController { ] NSLayoutConstraint.activate(tableViewConstraints) -// let backButton = UIButton() -// backButton.setImage(.init(systemName: "xmark"), for: .normal) -// backButton.tintColor = .white let backButton = UIImageView(image: .init(systemName: "xmark")) backButton.tintColor = .white -// backButton.image?.withTintColor(.white) backButton.tintColorDidChange() self.view.addSubview(backButton) backButton.translatesAutoresizingMaskIntoConstraints = false @@ -136,7 +132,6 @@ extension MountainDetailViewController { mapView.mapType = .satellite mapView.isUserInteractionEnabled = false let annotation = MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude) -// let annotation = MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude, mountainDescription: mountainDetail.mountainDescription, region: "") mapView.register(MountainAnnotationView.self, forAnnotationViewWithReuseIdentifier: MountainAnnotationView.ReuseID) mapView.addAnnotation(annotation) mapView.selectAnnotation(annotation, animated: true) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index 343946c..a9d498f 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -8,22 +8,54 @@ import UIKit class DetailCell: UICollectionViewCell { - var data: ResultDetailCellRepresentable? - let title: UILabel = UILabel() + private let title: UILabel = UILabel() - func configure(with cellData: ResultDetailCellRepresentable) { - self.data = cellData + func layout(data: ResultDetailCellRepresentable) { + self.title.text = data.title + self.title.textColor = .init(named: "SantaColor") + self.title.translatesAutoresizingMaskIntoConstraints = false + let titleConstraints = [ + self.title.topAnchor.constraint(equalTo: self.topAnchor), + self.title.leftAnchor.constraint(equalTo: self.leftAnchor) + ] + NSLayoutConstraint.activate(titleConstraints) + var contentLabels: [UILabel] = [] + var contentTitleLabels: [UILabel] = [] + + for content in data.contents { + let contentLabel = UILabel() + contentLabel.text = content.content + let contentTitleLabel = UILabel() + contentTitleLabel.text = content.contentTitle + contentLabels.append(contentLabel) + contentTitleLabels.append(contentTitleLabel) + } + + let stack = UIStackView() + stack.axis = .vertical + + for index in 0.. Date: Thu, 18 Nov 2021 00:23:01 +0900 Subject: [PATCH 272/465] =?UTF-8?q?[Feat]=20#226,=20#227,=20#228,=20#229?= =?UTF-8?q?=20=EC=9E=A5=EC=86=8C=20=EB=93=B1=EB=A1=9D=20=ED=99=94=EB=A9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 지도 Layout, Present, Dismiss, Annotation 구현 --- SanTa/SanTa.xcodeproj/project.pbxproj | 28 ++++++ SanTa/SanTa/MapScene/MapViewController.swift | 5 + SanTa/SanTa/MapScene/MapViewCoordinator.swift | 10 +- SanTa/SanTa/MapScene/MountainAnnotation.swift | 7 ++ .../MountainAddingViewController.swift | 93 +++++++++++++++++++ ...AddingViewController.swift~Stashed changes | 31 +++++++ .../MountainAddingViewCoordinator.swift | 38 ++++++++ .../MountainAddingViewModel.swift | 22 +++++ .../MountainAddingViewRepository.swift | 16 ++++ .../MountainAddingViewUseCase.swift | 12 +++ 10 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a79661c..e169361 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -49,6 +49,11 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; + 54B32065274510D8002232BD /* MountainAddingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32064274510D8002232BD /* MountainAddingViewController.swift */; }; + 54B3206727451169002232BD /* MountainAddingViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */; }; + 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32068274536D1002232BD /* MountainAddingViewModel.swift */; }; + 54B3206B274536E3002232BD /* MountainAddingViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */; }; + 54B3206D27453725002232BD /* MountainAddingViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */; }; 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */; }; 54F88EB9274256FE0004EAFD /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */; }; 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EBA274259950004EAFD /* RecordsViewCell.swift */; }; @@ -144,6 +149,11 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 54B32064274510D8002232BD /* MountainAddingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewController.swift; sourceTree = ""; }; + 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewCoordinator.swift; sourceTree = ""; }; + 54B32068274536D1002232BD /* MountainAddingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewModel.swift; sourceTree = ""; }; + 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewUseCase.swift; sourceTree = ""; }; + 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewRepository.swift; sourceTree = ""; }; 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalRecordsViewCell.swift; sourceTree = ""; }; 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = ""; }; 54F88EBA274259950004EAFD /* RecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsViewCell.swift; sourceTree = ""; }; @@ -371,6 +381,7 @@ 5428FDBE272F8D43002F9D40 /* Entities */, 54731B62272F808300534097 /* Application */, 54731B61272F7F7600534097 /* MapScene */, + 54B32063274510B7002232BD /* MountainAddingScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, @@ -383,6 +394,18 @@ path = SanTa; sourceTree = ""; }; + 54B32063274510B7002232BD /* MountainAddingScene */ = { + isa = PBXGroup; + children = ( + 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */, + 54B32064274510D8002232BD /* MountainAddingViewController.swift */, + 54B32068274536D1002232BD /* MountainAddingViewModel.swift */, + 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */, + 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */, + ); + path = MountainAddingScene; + sourceTree = ""; + }; 9826F42E273953FB0064FA85 /* SettingsSceneTests */ = { isa = PBXGroup; children = ( @@ -528,6 +551,7 @@ 985EEF63272FDA98002413D9 /* MountainCell.swift in Sources */, 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */, DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */, + 54B3206B274536E3002232BD /* MountainAddingViewUseCase.swift in Sources */, 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */, 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */, 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */, @@ -544,12 +568,15 @@ 493178B42743992400B5FB88 /* CollectionViewCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, + 54B3206D27453725002232BD /* MountainAddingViewRepository.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */, 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, + 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */, 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, + 54B3206727451169002232BD /* MountainAddingViewCoordinator.swift in Sources */, 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */, @@ -568,6 +595,7 @@ 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */, DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, + 54B32065274510D8002232BD /* MountainAddingViewController.swift in Sources */, 54296951272FC3290070B362 /* MountainListViewController.swift in Sources */, 9826F3DF273904010064FA85 /* Settings.swift in Sources */, 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */, diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 12e9ead..5130f87 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -84,6 +84,7 @@ class MapViewController: UIViewController { self.view.addSubview(self.addAnnotationButton) self.view.addSubview(self.userTrackingButton) self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) + self.addAnnotationButton.addTarget(self, action: #selector(presentMountainAddingViewController), for: .touchUpInside) NSLayoutConstraint.activate([ self.startButton.widthAnchor.constraint(equalToConstant: 100), @@ -189,6 +190,10 @@ class MapViewController: UIViewController { self.present(authAlert(), animated: false) } } + + @objc private func presentMountainAddingViewController() { + self.coordinator?.presentMountainAddingViewController() + } } extension MapViewController: Animatable { diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 704fda3..79f30c8 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -50,13 +50,21 @@ extension MapViewCoordinator { } func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: nil) // we should change this shit mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) mountainDetailViewCoordinator.start() } + func presentMountainAddingViewController() { + let mountainAddingViewCoordinator = MountainAddingViewCoordinator(navigationController: self.navigationController) + mountainAddingViewCoordinator.parentCoordinator = self + self.childCoordinators.append(mountainAddingViewCoordinator) + + mountainAddingViewCoordinator.start() + } + func recordingViewDidHide(){ guard let animatableViewController = navigationController.viewControllers.first as? Animatable else { return } animatableViewController.shouldAnimate() diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index a604514..5f57008 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -36,4 +36,11 @@ class MountainAnnotation: NSObject, MKAnnotation { self.mountainDescription = "" self.region = "" } + + init(latitude: Double, longitude: Double) { + self.latitude = latitude + self.longitude = longitude + self.mountainDescription = "" + self.region = "" + } } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift new file mode 100644 index 0000000..a5db068 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -0,0 +1,93 @@ +// +// MountainAddingViewController.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import MapKit + +class MountainAddingViewController: UIViewController { + weak var coordinator: MountainAddingViewCoordinator? + private var viewModel: MountainAddingViewModel? + private lazy var mapView: MKMapView = { + let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 2/5)) + mapView.delegate = self + mapView.mapType = .mutedStandard + mapView.isUserInteractionEnabled = false + return mapView + }() + private lazy var backButton: UIButton = { + let button = UIButton(frame: .zero) + button.setImage(.init(systemName: "xmark"), for: .normal) + button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) + button.tintColor = .label + button.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + convenience init(viewModel: MountainAddingViewModel) { + self.init() + self.viewModel = viewModel + } + + override func viewDidLoad() { + super.viewDidLoad() + self.configureViews() + self.configureViewModel() + } + + private func configureViews() { + self.view.addSubview(mapView) + self.view.addSubview(backButton) + NSLayoutConstraint.activate([ + self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), + self.backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + self.backButton.widthAnchor.constraint(equalToConstant: 30), + self.backButton.heightAnchor.constraint(equalToConstant: 30) + ]) + } + + private func configureViewModel() { + self.viewModel?.locationDidUpdate = { [weak self] in + self?.mapView.showsUserLocation = false + self?.configureLocation() + self?.configureAnnotation() + } + mapView.showsUserLocation = true + } + + private func configureLocation() { + guard let userLocation = self.viewModel?.userLocation else { return } + let location = CLLocationCoordinate2D(latitude: userLocation.latitude, longitude: userLocation.longitude) + let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01) + let region = MKCoordinateRegion(center: location, span: span) + self.mapView.setRegion(region, animated: false) + } + + private func configureAnnotation() { + guard let userLocation = self.viewModel?.userLocation else { return } + let mountainAnnotation = MountainAnnotation(latitude: userLocation.latitude, longitude: userLocation.longitude) + self.mapView.addAnnotation(mountainAnnotation) + } + + @objc func dismissViewController() { + self.coordinator?.dismiss() + } +} + +extension MountainAddingViewController: MKMapViewDelegate { + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + guard let annotation = annotation as? MountainAnnotation else { return nil } + return MountainAnnotationView( + annotation: annotation, + reuseIdentifier: MountainAnnotationView.ReuseID + ) + } + + func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { + self.viewModel?.userLocation = (userLocation.coordinate.latitude, userLocation.coordinate.longitude) + } +} + diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes new file mode 100644 index 0000000..d4ff9d4 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes @@ -0,0 +1,31 @@ +// +// MountainAddingViewController.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import MapKit + +class MountainAddingViewController: UIViewController { + weak var coordinator: MountainAddingViewCoordinator? + private lazy var mapView: MKMapView = { + let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 2/5)) + mapView.delegate = self + return mapView + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.configureViews() + } + + private func configureViews() { + self.view.addSubview(mapView) + } +} + +extension MountainAddingViewController: MKMapViewDelegate { + +} + diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift new file mode 100644 index 0000000..5fcaf53 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift @@ -0,0 +1,38 @@ +// +// MountainAddingViewCoordinator.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import UIKit + +class MountainAddingViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var navigationController: UINavigationController + var childCoordinators: [Coordinator] = [] + + init(navigationController: UINavigationController) { + self.navigationController = navigationController + } + + func start() { + let mountainAddingViewController = MountainAddingViewController(viewModel: injectDependencies()) + mountainAddingViewController.coordinator = self + mountainAddingViewController.modalPresentationStyle = .fullScreen + self.navigationController.present(mountainAddingViewController, animated: true) + } +} + +extension MountainAddingViewCoordinator { + private func injectDependencies() -> MountainAddingViewModel { + return MountainAddingViewModel( + useCase: MountainAddingViewUseCase() + ) + } + + func dismiss() { + self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinators.removeLast() + } +} diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift new file mode 100644 index 0000000..35a42f3 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -0,0 +1,22 @@ +// +// MountainAddingViewModel.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import Foundation + +class MountainAddingViewModel { + private var useCase: MountainAddingViewUseCase? + var locationDidUpdate: () -> Void + var userLocation: (latitude: Double, longitude: Double)? { + didSet { self.locationDidUpdate() } + } + + init(useCase: MountainAddingViewUseCase) { + self.useCase = useCase + self.locationDidUpdate = {} + } + +} diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift new file mode 100644 index 0000000..d255c6b --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift @@ -0,0 +1,16 @@ +// +// MountainAddingViewRepository.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import Foundation + +protocol MountainAddingRepository { + +} + +class DefaultMountainAddingRepository: MountainAddingRepository { + +} diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift new file mode 100644 index 0000000..05820e0 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -0,0 +1,12 @@ +// +// MountainAddingViewUseCase.swift +// SanTa +// +// Created by shin jae ung on 2021/11/17. +// + +import Foundation + +class MountainAddingViewUseCase { + +} From 896094dc1fcc6ef385a918c3f45b3a84e2215308 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Thu, 18 Nov 2021 11:08:07 +0900 Subject: [PATCH 273/465] =?UTF-8?q?[Fix]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...AddingViewController.swift~Stashed changes | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes deleted file mode 100644 index d4ff9d4..0000000 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift~Stashed changes +++ /dev/null @@ -1,31 +0,0 @@ -// -// MountainAddingViewController.swift -// SanTa -// -// Created by shin jae ung on 2021/11/17. -// - -import MapKit - -class MountainAddingViewController: UIViewController { - weak var coordinator: MountainAddingViewCoordinator? - private lazy var mapView: MKMapView = { - let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 2/5)) - mapView.delegate = self - return mapView - }() - - override func viewDidLoad() { - super.viewDidLoad() - self.configureViews() - } - - private func configureViews() { - self.view.addSubview(mapView) - } -} - -extension MountainAddingViewController: MKMapViewDelegate { - -} - From f17c49e8ab65a575e1310c041d77491ba0d1c132 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 11:30:28 +0900 Subject: [PATCH 274/465] =?UTF-8?q?[Fix]=20MountainDetailCoordinator=20Loc?= =?UTF-8?q?ation=20=EB=A7=A4=EA=B0=9C=EB=B3=80=EC=88=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index c8da4b9..faff4da 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -51,7 +51,7 @@ extension MapViewCoordinator { } func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: nil) // we should change this shit + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) // we should change this shit mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index b0c55dd..55587b8 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -47,7 +47,7 @@ extension MountainListViewCoordinator { } func pushMountainDetailViewController(mountainAnnotation: MountainAnnotation, location: CLLocation?) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation, location: location) + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) mountainDetailViewCoordinator.startPush() From 0f812255c9f500008c40f5dbe9604013d8291f33 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 18 Nov 2021 11:51:46 +0900 Subject: [PATCH 275/465] Remove Comment --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index faff4da..9fab5b9 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -51,7 +51,7 @@ extension MapViewCoordinator { } func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation) { - let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) // we should change this shit + let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) From 798a21e609bb5af3e1fe295db261e1e1bb0f2b08 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 18 Nov 2021 11:49:25 +0900 Subject: [PATCH 276/465] =?UTF-8?q?[Refactor]=20#236=20#224=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=EB=B0=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/SettingsViewController.swift | 2 +- SanTa/SanTa/SettingsScene/SettingsViewModel.swift | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 4515983..667c564 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -121,7 +121,7 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch self.viewModel?.settings[indexPath.section][indexPath.item] { + switch self.viewModel?.option(indexPath: indexPath) { case let option as ToggleOption: guard let cell = self.tableView.dequeueReusableCell(withIdentifier: ToggleOptionCell.identifier, for: indexPath) as? ToggleOptionCell diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift index 37ff192..0fa7762 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -26,6 +26,10 @@ final class SettingsViewModel { self.reloadSettings() } + func option(indexPath: IndexPath) -> Option { + return settings[indexPath.section][indexPath.item] + } + func change(value: T, key: Settings) { self.settingsUseCase.save(value: value, key: key) if value is String { From 80756ddf3f30a098206a97204dd3a121877c9ca2 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 18 Nov 2021 11:55:33 +0900 Subject: [PATCH 277/465] =?UTF-8?q?[Refactor]=20#236=20=EB=93=B1=EC=82=B0?= =?UTF-8?q?=EB=A1=9C=20=ED=91=9C=EC=8B=9C=ED=95=AD=EB=AA=A9=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Persistences/UserDefaultsStorage.swift | 4 ---- SanTa/SanTa/SettingsScene/Settings.swift | 3 --- SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 3 --- 3 files changed, 10 deletions(-) diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index 806f4e6..dced7af 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -63,9 +63,5 @@ final class DefaultUserDefaultsStorage: UserDefaultsStorage { self.save(value: Settings.mapFormat.initValue as? String, key: .mapFormat) } - if !self.exist(key: .markHikingTrailsOnTheMap) { - self.save(value: Settings.markHikingTrailsOnTheMap.initValue as? Bool, - key: .markHikingTrailsOnTheMap) - } } } diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/SettingsScene/Settings.swift index 3d210ca..13c5327 100644 --- a/SanTa/SanTa/SettingsScene/Settings.swift +++ b/SanTa/SanTa/SettingsScene/Settings.swift @@ -14,7 +14,6 @@ enum Settings: String, CaseIterable { case autoPauseResumeVoiceGuidance = "자동 일시정지, 재시작 음성 안내" case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" case mapFormat = "지도 형식" - case markHikingTrailsOnTheMap = "지도에 등산로 표시" var title: String { return self.rawValue @@ -34,8 +33,6 @@ enum Settings: String, CaseIterable { return true case .mapFormat: return "정보지도" - case .markHikingTrailsOnTheMap: - return true } } } diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index a4977c2..3f330d4 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -49,9 +49,6 @@ final class DefaultSettingsUsecase: SettingsUsecase { self.settingsRepository.makeMapOption(key: Settings.mapFormat) { value in mapSetting.append(value) } - self.settingsRepository.makeToggleOption(key: Settings.markHikingTrailsOnTheMap) { value in - mapSetting.append(value) - } options.append(photoSettings) options.append(autoSettins) From 6407e553286b744f4288edc20321e22ab9737699 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 18 Nov 2021 14:07:52 +0900 Subject: [PATCH 278/465] =?UTF-8?q?[Feat]=20#240=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 10 ++--- .../ResultDetailCoordinator.swift | 33 -------------- .../ResultDetailViewController.swift | 2 +- .../ResultDetailViewCoordinator.swift | 44 +++++++++++++++++++ .../ResultScene/ResultViewController.swift | 4 +- .../ResultScene/ResultViewCoordinator.swift | 15 ++++--- SanTa/SanTa/ResultScene/ResultViewModel.swift | 4 ++ 7 files changed, 65 insertions(+), 47 deletions(-) delete mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 9c79b04..bd5b02d 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -23,7 +23,7 @@ 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */; }; 49D5A955273A5A5C00937821 /* MountainDetailTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */; }; 49D5A957273A62F800937821 /* MountainDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */; }; - 49FC97682744E105008CE73A /* ResultDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */; }; + 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; @@ -122,7 +122,7 @@ 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailModel.swift; sourceTree = ""; }; 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTitleView.swift; sourceTree = ""; }; 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailTableViewCell.swift; sourceTree = ""; }; - 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailCoordinator.swift; sourceTree = ""; }; + 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewCoordinator.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; @@ -244,7 +244,7 @@ 5428FDB7272F8B34002F9D40 /* ResultDetailScene */ = { isa = PBXGroup; children = ( - 49FC97672744E105008CE73A /* ResultDetailCoordinator.swift */, + 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */, 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, @@ -386,10 +386,10 @@ 54731B61272F7F7600534097 /* MapScene */, 54B32063274510B7002232BD /* MountainAddingScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, + 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, DAFA9B55274112AB00BF168C /* RecordingPhotoScene */, - 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB9272F8BD9002F9D40 /* MountainListScene */, 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, 5428FDBB272F8C32002F9D40 /* SettingsScene */, @@ -566,7 +566,7 @@ 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */, 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */, 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, - 49FC97682744E105008CE73A /* ResultDetailCoordinator.swift in Sources */, + 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift deleted file mode 100644 index 03c50a1..0000000 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailCoordinator.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// ResultDetailCoordinator.swift -// SanTa -// -// Created by Jiwon Yoon on 2021/11/17. -// -import UIKit -import CoreLocation - -class ResultDetailCoordinator: Coordinator { - var childCoordinators: [Coordinator] = [] - - weak var parentCoordinator: Coordinator? - var navigationController: UINavigationController - var viewController: ResultDetailViewController - - func start() { - self.navigationController.present(viewController, animated: true, completion: nil) - } - - func dismiss() { - self.navigationController.dismiss(animated: true) - self.parentCoordinator?.childCoordinators.removeLast() - } - - init(navigationController: UINavigationController, records: Records) { - self.navigationController = navigationController - let viewModel = ResultDetailViewModel(useCase: ResultDetailUseCase(model: ResultDetailData(records: records))) - self.viewController = ResultDetailViewController(viewModel: viewModel) - self.viewController.coordinator = self - } - -} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index da3c2b9..5af57a7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -9,7 +9,7 @@ import UIKit import MapKit class ResultDetailViewController: UIViewController { - weak var coordinator: ResultDetailCoordinator? + weak var coordinator: ResultDetailViewCoordinator? private var viewModel: ResultDetailViewModel? private var mapView: MKMapView? private var infoView: UIView? diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift new file mode 100644 index 0000000..1bf6635 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -0,0 +1,44 @@ +// +// ResultDetailViewCoordinator.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/17. +// +import UIKit + +class ResultDetailViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var childCoordinators: [Coordinator] = [] + var navigationController: UINavigationController + var coreDataStorage: CoreDataStorage + var records: Records + + func start() { + let resultDetailViewController = ResultDetailViewController(viewModel: injectDependencies()) + resultDetailViewController.coordinator = self + self.navigationController.pushViewController(resultDetailViewController, animated: true) + } + + func dismiss() { + self.navigationController.dismiss(animated: true) + self.parentCoordinator?.childCoordinators.removeLast() + } + + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage, records: Records) { + self.navigationController = navigationController + self.coreDataStorage = coreDataStorage + self.records = records + } +} + +extension ResultDetailViewCoordinator { + private func injectDependencies() -> ResultDetailViewModel { + return ResultDetailViewModel( + useCase: ResultDetailUseCase( + model: ResultDetailData( + records: self.records + ) + ) + ) + } +} diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 49e3f53..f8b1d17 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -132,7 +132,9 @@ extension ResultViewController: UICollectionViewDataSource { } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - + let indexPath = IndexPath(item: indexPath.item, section: indexPath.section - 1) + guard let records = viewModel?.selectedRecords(indexPath: indexPath) else { return } + coordinator?.presentResultDetailViewController(records: records) } } diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index 23cbf23..892882c 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -25,15 +25,8 @@ class ResultViewCoordinator: Coordinator { let resultViewController = ResultViewController(viewModel: injectDependencies()) resultViewController.coordinator = self navigationController.setViewControllers([resultViewController], animated: true) - return navigationController } - -// func pushDetailViewController(records: Records) { -// let storage = CoreDataRecordStorage(coreDataStorage: self.coreDataStorage) -// storage. -// let resultDetailCoordinator = ResultDetailCoordinator(navigationController: self.navigationController, records: <#T##Records#>) -// } } extension ResultViewCoordinator { @@ -48,4 +41,12 @@ extension ResultViewCoordinator { ) ) } + + func presentResultDetailViewController(records: Records) { + let resultDetailViewCoordinator = ResultDetailViewCoordinator(navigationController: self.navigationController, coreDataStorage: self.coreDataStorage, records: records) + resultDetailViewCoordinator.parentCoordinator = self + self.childCoordinators.append(resultDetailViewCoordinator) + + resultDetailViewCoordinator.start() + } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 64b1f1e..685f28e 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -78,6 +78,10 @@ class ResultViewModel { let title = records.title return (dateString, distanceString, timeString, altitudeDifferenceString, stepsString, title) } + + func selectedRecords(indexPath: IndexPath) -> Records? { + return useCase.totalRecords?[indexPath.section]?[indexPath.item] + } } extension ResultViewModel { From 41a4e2993b74f3a540ac8c8887d5dd1d2a7f116e Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 14:19:27 +0900 Subject: [PATCH 279/465] =?UTF-8?q?[Refactor]=20RecordingUseCaseTest=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTest.swift | 23 +++ SanTa/SanTa.xcodeproj/project.pbxproj | 136 ++++++++++++++++++ .../xcshareddata/xcschemes/SanTa.xcscheme | 10 ++ 3 files changed, 169 insertions(+) create mode 100644 SanTa/RecordingSceneTest/RecordingUseCaseTest.swift diff --git a/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift b/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift new file mode 100644 index 0000000..288d36a --- /dev/null +++ b/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift @@ -0,0 +1,23 @@ +// +// RecordingSceneTest.swift +// RecordingSceneTest +// +// Created by 김민창 on 2021/11/18. +// + +import XCTest + +class RecordingUseCaseTest: XCTestCase { + + private var useCase: DefaultRecordingUseCase! + private var repository: RecordRepository! + + override func setUpWithError() throws { + repository = DefaultRecordRepository() + useCase = DefaultRecordingUseCase(settingsRepository: repository) + } + + func test() { + + } +} diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 9c79b04..105a3af 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -82,6 +82,12 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + DA854FC62746176A00E51E4B /* RecordingUseCaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */; }; + DA854FCE2746186A00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; + DA854FCF2746190F00E51E4B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; + DA854FD02746191A00E51E4B /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; + DA854FD12746191F00E51E4B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + DA854FD22746199E00E51E4B /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; @@ -103,6 +109,13 @@ remoteGlobalIDString = 5485127D272A6AD500407F28; remoteInfo = SanTa; }; + DA854FCC2746185400E51E4B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -179,6 +192,8 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; + DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTest.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; @@ -207,6 +222,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA854FC02746176A00E51E4B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -363,6 +385,7 @@ children = ( 54851280272A6AD500407F28 /* SanTa */, 9826F42E273953FB0064FA85 /* SettingsSceneTests */, + DA854FC42746176A00E51E4B /* RecordingSceneTest */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -372,6 +395,7 @@ children = ( 5485127E272A6AD500407F28 /* SanTa.app */, 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, + DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */, ); name = Products; sourceTree = ""; @@ -418,6 +442,14 @@ path = SettingsSceneTests; sourceTree = ""; }; + DA854FC42746176A00E51E4B /* RecordingSceneTest */ = { + isa = PBXGroup; + children = ( + DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */, + ); + path = RecordingSceneTest; + sourceTree = ""; + }; DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */ = { isa = PBXGroup; children = ( @@ -474,6 +506,24 @@ productReference = 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + DA854FC22746176A00E51E4B /* RecordingSceneTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA854FCB2746176A00E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTest" */; + buildPhases = ( + DA854FBF2746176A00E51E4B /* Sources */, + DA854FC02746176A00E51E4B /* Frameworks */, + DA854FC12746176A00E51E4B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DA854FCD2746185400E51E4B /* PBXTargetDependency */, + ); + name = RecordingSceneTest; + productName = RecordingSceneTest; + productReference = DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -491,6 +541,10 @@ CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; }; + DA854FC22746176A00E51E4B = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; }; }; buildConfigurationList = 54851279272A6AD500407F28 /* Build configuration list for PBXProject "SanTa" */; @@ -508,6 +562,7 @@ targets = ( 5485127D272A6AD500407F28 /* SanTa */, 9826F42C273953FB0064FA85 /* SettingsSceneTests */, + DA854FC22746176A00E51E4B /* RecordingSceneTest */, ); }; /* End PBXProject section */ @@ -530,6 +585,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA854FC12746176A00E51E4B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -630,6 +692,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA854FBF2746176A00E51E4B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DA854FD22746199E00E51E4B /* Settings.swift in Sources */, + DA854FD12746191F00E51E4B /* Record.swift in Sources */, + DA854FD02746191A00E51E4B /* RecordingModel.swift in Sources */, + DA854FCF2746190F00E51E4B /* RecordRepository.swift in Sources */, + DA854FCE2746186A00E51E4B /* RecordingUseCase.swift in Sources */, + DA854FC62746176A00E51E4B /* RecordingUseCaseTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -638,6 +713,11 @@ target = 5485127D272A6AD500407F28 /* SanTa */; targetProxy = 9826F431273953FB0064FA85 /* PBXContainerItemProxy */; }; + DA854FCD2746185400E51E4B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = DA854FCC2746185400E51E4B /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -876,6 +956,53 @@ }; name = Release; }; + DA854FC92746176A00E51E4B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + DA854FCA2746176A00E51E4B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -906,6 +1033,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DA854FCB2746176A00E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA854FC92746176A00E51E4B /* Debug */, + DA854FCA2746176A00E51E4B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index 18d624d..6688b84 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -48,6 +48,16 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + Date: Thu, 18 Nov 2021 14:22:23 +0900 Subject: [PATCH 280/465] =?UTF-8?q?[Feat]=20#242=20=EC=82=B0=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=99=94=EB=A9=B4=20VoiceOver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 15 +++++++++++++++ .../MountainListViewController.swift | 1 + .../SettingsScene/SettingsViewController.swift | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index bd72a8b..b765420 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -79,3 +79,18 @@ final class MountainCell: UICollectionViewCell { self.location.text = mountain.mountain.mountainRegion } } + +// MARK: - Accessibility + +extension MountainCell { + func configureVoiceOverAccessibility() { + guard let name = name.text else { return } + guard let height = height.text else { return } + guard let location = location.text else { return } + self.isAccessibilityElement = true + self.accessibilityLabel = "\(name) \(height) \(location)" + self.accessibilityTraits = .button + self.accessibilityHint = "상세화면으로 이동하려면 이중탭 하십시오" + self.accessibilityIdentifier = "\(name) \(height) \(location) Cell" + } +} diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index ee4c24d..b1a9dbc 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -121,6 +121,7 @@ class MountainListViewController: UIViewController { return UICollectionViewCell() } guard let item = item as? MountainEntity else { return cell } cell.update(mountain: item) + cell.configureVoiceOverAccessibility() return cell }) diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index 667c564..e6a7f13 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -22,7 +22,7 @@ class SettingsViewController: UIViewController { let headerTitle = UILabel() headerTitle.translatesAutoresizingMaskIntoConstraints = false headerTitle.text = "설정" - headerTitle.accessibilityLabel = "설정 머리말" + headerTitle.accessibilityTraits = .header headerTitle.font = UIFont.systemFont(ofSize: 20, weight: .bold) return headerTitle }() From b03a363cc38c85543110419110e7b426b2f7ba93 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 14:29:52 +0900 Subject: [PATCH 281/465] =?UTF-8?q?[Refactor]=20Recording=20Error=EB=A5=BC?= =?UTF-8?q?=20Generic=ED=95=98=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/RecordingSceneTest/RecordingUseCaseTest.swift | 13 ++++++++++++- .../SanTa/Persistences/CoreDataRecordStorage.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 5 +++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift b/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift index 288d36a..ee80229 100644 --- a/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift +++ b/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift @@ -12,8 +12,19 @@ class RecordingUseCaseTest: XCTestCase { private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! + class TestRecordingRepository : RecordRepository { + func save(records: Records, + completion: @escaping (Result) -> Void) { + + } + + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { + + } + } + override func setUpWithError() throws { - repository = DefaultRecordRepository() + repository = TestRecordingRepository() useCase = DefaultRecordingUseCase(settingsRepository: repository) } diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 95a1abd..637bf6f 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -10,7 +10,7 @@ import CoreData protocol RecordsStorage { func save(records: Records, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) } @@ -22,7 +22,7 @@ final class CoreDataRecordStorage: RecordsStorage { self.coreDataStorage = coreDataStorage } - func save(records: Records, completion: @escaping (Result) -> Void) { + func save(records: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordsObject = NSEntityDescription.insertNewObject(forEntityName: "RecordsEntity", into: context) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 5561dc2..d844f0e 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -9,7 +9,7 @@ import Foundation protocol RecordRepository { func save(records: Records, - completion: @escaping (Result) -> Void) + completion: @escaping (Result) -> Void) func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) } @@ -31,7 +31,7 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage = recordStorage } - func save(records: Records, completion: @escaping (Result) -> Void) { + func save(records: Records, completion: @escaping (Result) -> Void) { self.recordStorage.save(records: records, completion: completion) } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index b4c94fc..d2f5c46 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -10,7 +10,7 @@ import Foundation protocol RecordingUseCase { var recording: RecordingModel { get set } - func save(title: String, completion: @escaping (Result) -> Void) + func save(title: String, completion: @escaping (Result) -> Void) func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] func pause() func resume() @@ -37,8 +37,9 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recording.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording.cancel() else { + completion(.failure(CoreDataError.coreDataError)) return } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index e1c8f43..7d03e63 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -68,7 +68,7 @@ final class RecordingViewModel: ObservableObject { self.recordingUseCase?.resume() } - func save(title: String, completion: @escaping (Result) -> Void) { + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } From f131a6615644497c571cd0c201312a93c6326115 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 15:26:48 +0900 Subject: [PATCH 282/465] =?UTF-8?q?[Refactor]=20RecordingUseCase=EB=A5=BC?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=95=98=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTests.swift} | 15 +-- SanTa/SanTa.xcodeproj/project.pbxproj | 109 ++++++++---------- .../xcshareddata/xcschemes/SanTa.xcscheme | 24 ++-- .../RecordingScene/RecordRepository.swift | 6 - .../RecordingScene/RecordingUseCase.swift | 18 +-- .../RecordingScene/RecordingViewModel.swift | 10 ++ 6 files changed, 88 insertions(+), 94 deletions(-) rename SanTa/{RecordingSceneTest/RecordingUseCaseTest.swift => RecordingSceneTests/RecordingUseCaseTests.swift} (68%) diff --git a/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift similarity index 68% rename from SanTa/RecordingSceneTest/RecordingUseCaseTest.swift rename to SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index ee80229..1fb1a54 100644 --- a/SanTa/RecordingSceneTest/RecordingUseCaseTest.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -1,34 +1,35 @@ // -// RecordingSceneTest.swift -// RecordingSceneTest +// RecordingSceneTests.swift +// RecordingSceneTests // // Created by 김민창 on 2021/11/18. // import XCTest -class RecordingUseCaseTest: XCTestCase { - +class RecordingUseCaseTests: XCTestCase { + private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! class TestRecordingRepository : RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) { - + return } func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { - + return } } override func setUpWithError() throws { repository = TestRecordingRepository() - useCase = DefaultRecordingUseCase(settingsRepository: repository) + useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: RecordingModel(), recordingPhoto: RecordingPhotoModel()) } func test() { } + } diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 105a3af..1b3d511 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -82,12 +82,14 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; - DA854FC62746176A00E51E4B /* RecordingUseCaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */; }; - DA854FCE2746186A00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; - DA854FCF2746190F00E51E4B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; - DA854FD02746191A00E51E4B /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; - DA854FD12746191F00E51E4B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; - DA854FD22746199E00E51E4B /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; + DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */; }; + DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; + DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; + DA854FE2274627B000E51E4B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + DA854FE4274627D500E51E4B /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; + DA854FE92746292300E51E4B /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; DA9D7C9F273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */; }; DAAF2716272FF73700F8A115 /* RecordingViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */; }; @@ -109,13 +111,6 @@ remoteGlobalIDString = 5485127D272A6AD500407F28; remoteInfo = SanTa; }; - DA854FCC2746185400E51E4B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 54851276272A6AD500407F28 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5485127D272A6AD500407F28; - remoteInfo = SanTa; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -192,8 +187,8 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; - DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTest.swift; sourceTree = ""; }; + DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTests.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewCoordinator.swift; sourceTree = ""; }; DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecordingViewController+Extension.swift"; sourceTree = ""; }; @@ -222,7 +217,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DA854FC02746176A00E51E4B /* Frameworks */ = { + DA854FD62746273300E51E4B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -385,7 +380,7 @@ children = ( 54851280272A6AD500407F28 /* SanTa */, 9826F42E273953FB0064FA85 /* SettingsSceneTests */, - DA854FC42746176A00E51E4B /* RecordingSceneTest */, + DA854FDA2746273300E51E4B /* RecordingSceneTests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -395,7 +390,7 @@ children = ( 5485127E272A6AD500407F28 /* SanTa.app */, 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, - DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */, + DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */, ); name = Products; sourceTree = ""; @@ -442,12 +437,12 @@ path = SettingsSceneTests; sourceTree = ""; }; - DA854FC42746176A00E51E4B /* RecordingSceneTest */ = { + DA854FDA2746273300E51E4B /* RecordingSceneTests */ = { isa = PBXGroup; children = ( - DA854FC52746176A00E51E4B /* RecordingUseCaseTest.swift */, + DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */, ); - path = RecordingSceneTest; + path = RecordingSceneTests; sourceTree = ""; }; DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */ = { @@ -506,22 +501,21 @@ productReference = 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - DA854FC22746176A00E51E4B /* RecordingSceneTest */ = { + DA854FD82746273300E51E4B /* RecordingSceneTests */ = { isa = PBXNativeTarget; - buildConfigurationList = DA854FCB2746176A00E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTest" */; + buildConfigurationList = DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */; buildPhases = ( - DA854FBF2746176A00E51E4B /* Sources */, - DA854FC02746176A00E51E4B /* Frameworks */, - DA854FC12746176A00E51E4B /* Resources */, + DA854FD52746273300E51E4B /* Sources */, + DA854FD62746273300E51E4B /* Frameworks */, + DA854FD72746273300E51E4B /* Resources */, ); buildRules = ( ); dependencies = ( - DA854FCD2746185400E51E4B /* PBXTargetDependency */, ); - name = RecordingSceneTest; - productName = RecordingSceneTest; - productReference = DA854FC32746176A00E51E4B /* RecordingSceneTest.xctest */; + name = RecordingSceneTests; + productName = RecordingSceneTests; + productReference = DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -541,9 +535,8 @@ CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; }; - DA854FC22746176A00E51E4B = { + DA854FD82746273300E51E4B = { CreatedOnToolsVersion = 13.0; - TestTargetID = 5485127D272A6AD500407F28; }; }; }; @@ -562,7 +555,7 @@ targets = ( 5485127D272A6AD500407F28 /* SanTa */, 9826F42C273953FB0064FA85 /* SettingsSceneTests */, - DA854FC22746176A00E51E4B /* RecordingSceneTest */, + DA854FD82746273300E51E4B /* RecordingSceneTests */, ); }; /* End PBXProject section */ @@ -585,7 +578,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DA854FC12746176A00E51E4B /* Resources */ = { + DA854FD72746273300E51E4B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -682,6 +675,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */, 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */, 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */, 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, @@ -692,16 +686,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DA854FBF2746176A00E51E4B /* Sources */ = { + DA854FD52746273300E51E4B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA854FD22746199E00E51E4B /* Settings.swift in Sources */, - DA854FD12746191F00E51E4B /* Record.swift in Sources */, - DA854FD02746191A00E51E4B /* RecordingModel.swift in Sources */, - DA854FCF2746190F00E51E4B /* RecordRepository.swift in Sources */, - DA854FCE2746186A00E51E4B /* RecordingUseCase.swift in Sources */, - DA854FC62746176A00E51E4B /* RecordingUseCaseTest.swift in Sources */, + DA854FE92746292300E51E4B /* RecordingViewModel.swift in Sources */, + DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */, + DA854FE4274627D500E51E4B /* Settings.swift in Sources */, + DA854FE2274627B000E51E4B /* Record.swift in Sources */, + DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */, + DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */, + DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -713,11 +708,6 @@ target = 5485127D272A6AD500407F28 /* SanTa */; targetProxy = 9826F431273953FB0064FA85 /* PBXContainerItemProxy */; }; - DA854FCD2746185400E51E4B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5485127D272A6AD500407F28 /* SanTa */; - targetProxy = DA854FCC2746185400E51E4B /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -916,7 +906,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 5X25M942H6; + DEVELOPMENT_TEAM = B3PWYBKFUK; GENERATE_INFOPLIST_FILE = YES; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -939,7 +929,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 5X25M942H6; + DEVELOPMENT_TEAM = B3PWYBKFUK; GENERATE_INFOPLIST_FILE = YES; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -956,13 +946,12 @@ }; name = Release; }; - DA854FC92746176A00E51E4B /* Debug */ = { + DA854FDE2746273300E51E4B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = B3PWYBKFUK; + DEVELOPMENT_TEAM = GQ4HM48H8H; GENERATE_INFOPLIST_FILE = YES; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -970,23 +959,20 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTest; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; }; name = Debug; }; - DA854FCA2746176A00E51E4B /* Release */ = { + DA854FDF2746273300E51E4B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = B3PWYBKFUK; + DEVELOPMENT_TEAM = GQ4HM48H8H; GENERATE_INFOPLIST_FILE = YES; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -994,12 +980,11 @@ "@loader_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTest; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.RecordingSceneTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; }; name = Release; }; @@ -1033,11 +1018,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DA854FCB2746176A00E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTest" */ = { + DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - DA854FC92746176A00E51E4B /* Debug */, - DA854FCA2746176A00E51E4B /* Release */, + DA854FDE2746273300E51E4B /* Debug */, + DA854FDF2746273300E51E4B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index 6688b84..f1b1e28 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -20,6 +20,20 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + - - - - ) -> Void) - func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) -} - final class DefaultRecordRepository: RecordRepository { enum userDefaultsError: Error { diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index d2f5c46..6a8bd3f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -7,14 +7,14 @@ import Foundation -protocol RecordingUseCase { - var recording: RecordingModel { get set } - - func save(title: String, completion: @escaping (Result) -> Void) - func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] - func pause() - func resume() - func fetchOptions() +protocol RecordRepository { + func save(records: Records, + completion: @escaping (Result) -> Void) + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) +} + +enum RecordingViewModelError: Error { + case FetchError } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { @@ -40,7 +40,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording.cancel() else { - completion(.failure(CoreDataError.coreDataError)) + completion(.failure(RecordingViewModelError.FetchError)) return } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 7d03e63..ebdf4b5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -8,6 +8,16 @@ import Foundation import Combine +protocol RecordingUseCase { + var recording: RecordingModel { get set } + + func save(title: String, completion: @escaping (Result) -> Void) + func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] + func pause() + func resume() + func fetchOptions() +} + final class RecordingViewModel: ObservableObject { @Published private(set) var currentTime = "" @Published private(set) var kilometer = "" From cc73a056a83a8c9651723c3cff4b6458191156b5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 15:53:52 +0900 Subject: [PATCH 283/465] =?UTF-8?q?[Refactor]=20RecordingModel=20=EA=B0=92?= =?UTF-8?q?=20=EC=98=B5=EC=85=94=EB=84=90=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTests.swift | 14 +++++++++++--- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 12 ++++++------ .../SanTa/RecordingScene/RecordingViewModel.swift | 12 ++++++------ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index 1fb1a54..a10d7e7 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -19,7 +19,7 @@ class RecordingUseCaseTests: XCTestCase { } func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { - return + completion(.success(true)) } } @@ -28,8 +28,16 @@ class RecordingUseCaseTests: XCTestCase { useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: RecordingModel(), recordingPhoto: RecordingPhotoModel()) } - func test() { - + func test_음성안내_옵션_True_값_가져오기_성공() { + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) + self.repository.fetchRecordOption(key: Settings.voiceGuidanceEveryOnekm) { result in + switch result { + case .failure(_): + return + case .success(let status): + XCTAssertTrue(status) + } + } } } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 6a8bd3f..582dba0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -18,27 +18,27 @@ enum RecordingViewModelError: Error { } final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { - var recording: RecordingModel + var recording: RecordingModel? var recordingPhoto: RecordingPhotoModel private let recordRepository: RecordRepository - init(recordRepository: RecordRepository, recordingModel: RecordingModel, recordingPhoto: RecordingPhotoModel) { + init(recordRepository: RecordRepository, recordingModel: RecordingModel?, recordingPhoto: RecordingPhotoModel) { self.recordRepository = recordRepository self.recording = recordingModel self.recordingPhoto = recordingPhoto } func pause() { - self.recording.pause() + self.recording?.pause() } func resume() { - self.recording.resume() + self.recording?.resume() } func save(title: String, completion: @escaping (Result) -> Void) { - guard var records = recording.cancel() else { + guard var records = recording?.cancel() else { completion(.failure(RecordingViewModelError.FetchError)) return @@ -71,7 +71,7 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { case .failure(_): return case .success(let status): - self.recording.changedWillSpeechStatus(status: status) + self.recording?.changedWillSpeechStatus(status: status) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index ebdf4b5..12e9be6 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -9,7 +9,7 @@ import Foundation import Combine protocol RecordingUseCase { - var recording: RecordingModel { get set } + var recording: RecordingModel? { get set } func save(title: String, completion: @escaping (Result) -> Void) func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] @@ -34,35 +34,35 @@ final class RecordingViewModel: ObservableObject { } private func configureBindings() { - self.recordingUseCase?.recording.$time + self.recordingUseCase?.recording?.$time .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in self?.currentTime = time }) .store(in: &self.subscriptions) - self.recordingUseCase?.recording.$kilometer + self.recordingUseCase?.recording?.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) .store(in: &self.subscriptions) - self.recordingUseCase?.recording.$altitude + self.recordingUseCase?.recording?.$altitude .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitude = altitude }) .store(in: &self.subscriptions) - self.recordingUseCase?.recording.$walk + self.recordingUseCase?.recording?.$walk .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walk = walk }) .store(in: &self.subscriptions) - self.recordingUseCase?.recording.$gpsStatus + self.recordingUseCase?.recording?.$gpsStatus .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] gpsStatus in self?.gpsStatus = gpsStatus From ba8c19e5e38bd143b7942f3f42ab67007c8aa0b2 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 16:08:56 +0900 Subject: [PATCH 284/465] =?UTF-8?q?[Refactor]=20#237=20RecordingUseCase=20?= =?UTF-8?q?TestCode=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTests.swift | 70 +++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index a10d7e7..9423f0a 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -12,20 +12,32 @@ class RecordingUseCaseTests: XCTestCase { private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! + enum testError: Error { + case StoreError + } + class TestRecordingRepository : RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) { - return + + completion(.success(records)) } func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { - completion(.success(true)) + switch key { + case .voiceGuidanceEveryOnekm: + completion(.success(true)) + case .recordPhoto: + completion(.success(true)) + default: + completion(.success(false)) + } } } override func setUpWithError() throws { repository = TestRecordingRepository() - useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: RecordingModel(), recordingPhoto: RecordingPhotoModel()) + useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: nil, recordingPhoto: RecordingPhotoModel()) } func test_음성안내_옵션_True_값_가져오기_성공() { @@ -39,5 +51,55 @@ class RecordingUseCaseTests: XCTestCase { } } } - + + func test_음성안내_옵션_False_값_가져오기_성공() { + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) + self.repository.fetchRecordOption(key: Settings.photosOnMap) { result in + switch result { + case .failure(_): + return + case .success(let status): + XCTAssertFalse(status) + } + } + } + + func test_사진저장_옵션_True_값_가져오기_성공() { + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) + self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in + switch result { + case .failure(_): + return + case .success(let status): + XCTAssertTrue(status) + } + } + } + + func test_사진저장_옵션_False_값_가져오기_성공() { + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) + self.repository.fetchRecordOption(key: Settings.photosOnMap) { result in + switch result { + case .failure(_): + return + case .success(let status): + XCTAssertFalse(status) + } + } + } + + func test_Records_저장_성공() { + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) + let records = Records(title: "테스트", records: [Record](), assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int()) + + self.repository.save(records: records) { result in + switch result { + case .failure(_): + return + case .success(let records): + XCTAssertEqual(records.title, records.title) + } + + } + } } From 5d9e76b581a3e4923f5422883ec0a362a15ec2d7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 16:17:54 +0900 Subject: [PATCH 285/465] =?UTF-8?q?[Feat]=20#144=20MountainList=20Cell=20T?= =?UTF-8?q?ouch=EC=8B=9C=20Push=20=EB=8F=99=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListScene/MountainListViewController.swift | 7 +++---- .../MountainListScene/MountainListViewCoordinator.swift | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index ee4c24d..284fe3d 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -132,14 +132,13 @@ class MountainListViewController: UIViewController { extension MountainListViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { guard let mountains = self.viewModel?.mountains else { return } - let location = CLLocation(latitude: CLLocationDegrees(mountains[indexPath.item].latitude), - longitude: mountains[indexPath.item].longitude) self.coordinator?.pushMountainDetailViewController(mountainAnnotation: MountainAnnotation( title: mountains[indexPath.item].mountain.mountainName, subtitle: mountains[indexPath.item].mountain.mountainHeight, latitude: mountains[indexPath.item].latitude, - longitude: mountains[indexPath.item].longitude), - location: location) + longitude: mountains[indexPath.item].longitude, + mountainDescription: mountains[indexPath.item].mountain.mountainShortDescription, + region: mountains[indexPath.item].mountain.mountainRegion)) } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 55587b8..e861fef 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -46,7 +46,7 @@ extension MountainListViewCoordinator { } - func pushMountainDetailViewController(mountainAnnotation: MountainAnnotation, location: CLLocation?) { + func pushMountainDetailViewController(mountainAnnotation: MountainAnnotation) { let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) From 35d20eb4af74a6b2822226e6c4bc15b3dc31835e Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 18 Nov 2021 17:13:54 +0900 Subject: [PATCH 286/465] =?UTF-8?q?[Feat]=20#144=20MountainDetail=20Xmark?= =?UTF-8?q?=20Push=EC=8B=9C=20Hidden=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 12 ++++++++---- .../MountainDetailViewCoordinator.swift | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 7166dc6..bcbf125 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -14,6 +14,14 @@ class MountainDetailViewController: UIViewController { private var mutatingTopConstraint: NSLayoutConstraint? private let maxRollUpDistance: CGFloat = 50 + lazy var backButton: UIImageView = { + let uiImage = UIImageView(image: .init(systemName: "xmark")) + uiImage.tintColor = .white + uiImage.translatesAutoresizingMaskIntoConstraints = false + uiImage.isUserInteractionEnabled = true + return uiImage + }() + convenience init(viewModel: MountainDetailViewModel) { self.init() self.viewModel = viewModel @@ -93,13 +101,9 @@ extension MountainDetailViewController { ] NSLayoutConstraint.activate(tableViewConstraints) - let backButton = UIImageView(image: .init(systemName: "xmark")) - backButton.tintColor = .white backButton.tintColorDidChange() self.view.addSubview(backButton) - backButton.translatesAutoresizingMaskIntoConstraints = false backButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(close))) - backButton.isUserInteractionEnabled = true let backButtonConstraints = [ backButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10), diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 56b8f71..ab231bd 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -17,11 +17,13 @@ class MountainDetailViewCoordinator: Coordinator { func start() { if self.parentCoordinator is MapViewCoordinator { + self.mountainDetailViewController.backButton.isHidden = false self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) } } func startPush() { + self.mountainDetailViewController.backButton.isHidden = true self.navigationController.pushViewController(self.mountainDetailViewController, animated: true) } From 7833d9a203264bc4e78a52a45c6bd372c566e01e Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 18 Nov 2021 14:47:14 +0900 Subject: [PATCH 287/465] =?UTF-8?q?[Feat]=20Dismiss=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 37 ++++++++++++++++--- .../ResultDetailViewCoordinator.swift | 2 +- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 5af57a7..00f307c 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -13,6 +13,15 @@ class ResultDetailViewController: UIViewController { private var viewModel: ResultDetailViewModel? private var mapView: MKMapView? private var infoView: UIView? + private var backButton: UIButton = { + let button = UIButton() + button.setImage(.init(systemName: "chevron.backward"), for: .normal) + button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) + button.tintColor = .label + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) + return button + }() convenience init(viewModel: ResultDetailViewModel) { self.init() @@ -21,14 +30,32 @@ class ResultDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - self.viewModel?.resultDetailDataReceived = { detailData in - self.layoutInitialRecordDetailView() - self.registerRecognizers() - } - viewModel?.setUp() + self.configureViews() +// +// self.viewModel?.resultDetailDataReceived = { detailData in +// self.layoutInitialRecordDetailView() +// self.registerRecognizers() +// } +// viewModel?.setUp() + } + + private func configureViews() { + self.view.addSubview(backButton) + NSLayoutConstraint.activate([ + backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), + backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + backButton.widthAnchor.constraint(equalToConstant: 40), + backButton.heightAnchor.constraint(equalToConstant: 40), + ]) + } + + @objc func dismissViewController() { + coordinator?.dismiss() } } + + extension ResultDetailViewController { private func registerRecognizers() { let swipeDownRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showSmallInfoView)) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 1bf6635..7fc149a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -20,7 +20,7 @@ class ResultDetailViewCoordinator: Coordinator { } func dismiss() { - self.navigationController.dismiss(animated: true) + self.navigationController.popViewController(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } From bbf7cd92d15081f7985203a46bf606b85c215aa4 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 18 Nov 2021 17:32:00 +0900 Subject: [PATCH 288/465] =?UTF-8?q?[Feat]=20#246=20=EA=B0=9C=EB=B3=84=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20=ED=99=94=EB=A9=B4=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit present, dismiss, 레이아웃 추가 수정 --- .../ResultDetailScene/ResultDetailModel.swift | 2 +- .../ResultDetailSmallerInfoView.swift | 243 +++++++++--------- .../ResultDetailViewController.swift | 115 ++++++--- .../ResultDetailViewCoordinator.swift | 1 + .../ResultDetailViewModel.swift | 6 +- 5 files changed, 203 insertions(+), 164 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 08f9472..a5ec904 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -132,7 +132,7 @@ struct ResultIncline { plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 } - self.average = Int(totalIncline / Double(locations.count - 1)) + self.average = Int(totalIncline) self.highest = Int(steepest) self.uphillKilometer = uphillDistance / 1000 self.downhillKilometer = downHillDistance / 1000 diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 6652566..52cf59e 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -9,77 +9,134 @@ import UIKit class ResultDetailSmallerInfoView: UIView { - private let kilo = UILabel() + private let distance = UILabel() private let time = UILabel() private let steps = UILabel() private let maxAltitude = UILabel() private let minAltitude = UILabel() - private let avgSpeed = UILabel() + private let averageSpeed = UILabel() - private let kiloStackView = UIStackView() - private let timeStackView = UIStackView() - private let stepStackView = UIStackView() - private let maxAltStackView = UIStackView() - private let minAltStackView = UIStackView() - private let avgSpdStackView = UIStackView() + private let distanceLabel: UILabel = { + let label = UILabel() + label.text = "킬로미터" + return label + }() - private let leftInset: CGFloat = 20 - private let rightInset: CGFloat = 20 - private let topInset: CGFloat = 20 + private let timeLabel: UILabel = { + let label = UILabel() + label.text = "시간" + return label + }() + private let stepsLabel: UILabel = { + let label = UILabel() + label.text = "걸음" + return label + }() - init() { - super.init(frame: .zero) - self.layout() - } + private let maxAltitudeLabel: UILabel = { + let label = UILabel() + label.text = "최고 고도" + return label + }() - override init(frame: CGRect) { - super.init(frame: frame) - self.layout() - } + private let minAltitudeLabel: UILabel = { + let label = UILabel() + label.text = "최저 고도" + return label + }() - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } + private let averageSpeedLabel: UILabel = { + let label = UILabel() + label.text = "평균 속도" + return label + }() - private func layout() { - displayArrowImage() - self.configureKilometerStackView(with: "3.14") - self.configureTimeStackView(time: "00:18") - self.configureStepStackView(with: "1,456") - self.configureMaxAltStackView(with: "48") - self.configureMinAltStackView(with: "19") - self.configureAvgSpeedStackView(with: "3.34") - - let upperStack = UIStackView() - upperStack.axis = .horizontal - upperStack.distribution = .fillEqually - upperStack.spacing = 50 - upperStack.addArrangedSubview(kiloStackView) - upperStack.addArrangedSubview(timeStackView) - upperStack.addArrangedSubview(stepStackView) - - let lowerStack = UIStackView() - lowerStack.axis = .horizontal - lowerStack.distribution = .fillEqually - lowerStack.spacing = 50 - lowerStack.addArrangedSubview(maxAltStackView) - lowerStack.addArrangedSubview(minAltStackView) - lowerStack.addArrangedSubview(avgSpdStackView) - - let totalStack = UIStackView() - totalStack.axis = .vertical - totalStack.spacing = 30 - totalStack.addArrangedSubview(upperStack) - totalStack.addArrangedSubview(lowerStack) - self.addSubview(totalStack) - - totalStack.translatesAutoresizingMaskIntoConstraints = false - let constraints = [ - totalStack.centerXAnchor.constraint(equalTo: self.centerXAnchor), - totalStack.centerYAnchor.constraint(equalTo: self.centerYAnchor) - ] - NSLayoutConstraint.activate(constraints) + private lazy var distanceStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.distance, self.distanceLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var timeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.time, self.timeLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var stepsStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.steps, self.stepsLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var maxAltitudeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.maxAltitude, self.maxAltitudeLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var minAltitudeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.minAltitude, self.minAltitudeLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var averageSpeedStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.averageSpeed, self.averageSpeedLabel]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var firstHorizontalStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.distanceStackView, self.timeStackView, self.stepsStackView]) + stackView.axis = .horizontal + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var secondHorizontalStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.maxAltitudeStackView, self.minAltitudeStackView, self.averageSpeedStackView]) + stackView.axis = .horizontal + stackView.distribution = .fillEqually + return stackView + }() + + private lazy var compositionalStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [self.firstHorizontalStackView, self.secondHorizontalStackView]) + stackView.axis = .vertical + stackView.distribution = .fillEqually + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + func configureLayout(distance: String, time: String, steps: String, maxAltitude: String, minAltitude: String, averageSpeed: String) { + self.backgroundColor = .systemBackground + self.distance.text = distance + self.time.text = time + self.steps.text = steps + self.maxAltitude.text = maxAltitude + self.minAltitude.text = minAltitude + self.averageSpeed.text = averageSpeed + self.addSubview(self.compositionalStackView) + NSLayoutConstraint.activate([ + self.compositionalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor), + self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.compositionalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) } private func displayArrowImage() { @@ -95,70 +152,4 @@ class ResultDetailSmallerInfoView: UIView { ] NSLayoutConstraint.activate(arrowConstraints) } - - private func configureKilometerStackView(with kilometer: String) { - self.addSubview(kiloStackView) - self.kilo.text = kilometer - let kiloDescription = UILabel() - kiloDescription.text = "킬로미터" - self.kiloStackView.axis = .vertical - self.kiloStackView.alignment = .center - self.kiloStackView.addArrangedSubview(kilo) - self.kiloStackView.addArrangedSubview(kiloDescription) - } - - private func configureTimeStackView(time: String) { - self.addSubview(timeStackView) - self.time.text = time - let timeDescription = UILabel() - timeDescription.text = "시간" - self.timeStackView.axis = .vertical - self.timeStackView.alignment = .center - self.timeStackView.addArrangedSubview(self.time) - self.timeStackView.addArrangedSubview(timeDescription) - } - - private func configureStepStackView(with steps: String) { - self.addSubview(stepStackView) - self.steps.text = steps - let stepDescription = UILabel() - stepDescription.text = "걸음" - self.stepStackView.axis = .vertical - self.stepStackView.alignment = .center - self.stepStackView.addArrangedSubview(self.steps) - self.stepStackView.addArrangedSubview(stepDescription) - } - - private func configureMaxAltStackView(with maxAltitude: String) { - self.addSubview(maxAltStackView) - self.maxAltitude.text = maxAltitude - let maxAltDescription = UILabel() - maxAltDescription.text = "최고 고도" - self.maxAltStackView.axis = .vertical - self.maxAltStackView.alignment = .center - self.maxAltStackView.addArrangedSubview(self.maxAltitude) - self.maxAltStackView.addArrangedSubview(maxAltDescription) - } - - private func configureMinAltStackView(with minAltitude: String) { - self.addSubview(minAltStackView) - self.minAltitude.text = minAltitude - let minAltDescription = UILabel() - minAltDescription.text = "최저 고도" - self.minAltStackView.axis = .vertical - self.minAltStackView.alignment = .center - self.minAltStackView.addArrangedSubview(self.minAltitude) - self.minAltStackView.addArrangedSubview(minAltDescription) - } - - private func configureAvgSpeedStackView(with speed: String) { - self.addSubview(avgSpdStackView) - self.avgSpeed.text = speed - let avgSpeedDescription = UILabel() - avgSpeedDescription.text = "평균 속도" - self.avgSpdStackView.axis = .vertical - self.avgSpdStackView.alignment = .center - self.avgSpdStackView.addArrangedSubview(self.avgSpeed) - self.avgSpdStackView.addArrangedSubview(avgSpeedDescription) - } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 00f307c..d5eeb28 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -9,10 +9,24 @@ import UIKit import MapKit class ResultDetailViewController: UIViewController { + weak var coordinator: ResultDetailViewCoordinator? + private var viewModel: ResultDetailViewModel? - private var mapView: MKMapView? - private var infoView: UIView? + + private lazy var mapView: MKMapView = { + let mapView = MKMapView() + mapView.mapType = .mutedStandard + mapView.translatesAutoresizingMaskIntoConstraints = false + return mapView + }() + + private var informationView: ResultDetailSmallerInfoView = { + let view = ResultDetailSmallerInfoView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + private var backButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "chevron.backward"), for: .normal) @@ -23,6 +37,15 @@ class ResultDetailViewController: UIViewController { return button }() + private var changeButton: UIButton = { + let button = UIButton() + button.setImage(.init(systemName: "ellipsis.circle"), for: .normal) + button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) + button.tintColor = .label + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + convenience init(viewModel: ResultDetailViewModel) { self.init() self.viewModel = viewModel @@ -31,21 +54,55 @@ class ResultDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.configureViews() -// -// self.viewModel?.resultDetailDataReceived = { detailData in -// self.layoutInitialRecordDetailView() -// self.registerRecognizers() -// } -// viewModel?.setUp() + self.viewModel?.recordDidFetch = { [weak self] in + guard let data = self?.viewModel?.resultDetailData else { return } + self?.informationView.configureLayout( + distance: "\(data.distance.total)", + time: "\(data.time.spent)", + steps: "\(data.distance.steps)", + maxAltitude: "\(data.altitude.highest)", + minAltitude: "\(data.altitude.lowest)", + averageSpeed: "0" + ) + } + viewModel?.setUp() + } + + private func configureSmallerView() { + + print(informationView.bounds) + self.informationView = ResultDetailSmallerInfoView(frame: self.informationView.bounds) + print(view.subviews) } private func configureViews() { - self.view.addSubview(backButton) + self.view.addSubview(self.mapView) + self.view.addSubview(self.backButton) + self.view.addSubview(self.changeButton) + self.view.addSubview(self.informationView) + NSLayoutConstraint.activate([ + self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), + self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -self.view.frame.height * 0.25) + ]) + NSLayoutConstraint.activate([ + self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), + self.backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + self.backButton.widthAnchor.constraint(equalToConstant: 40), + self.backButton.heightAnchor.constraint(equalToConstant: 40), + ]) + NSLayoutConstraint.activate([ + self.changeButton.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor, constant: -10), + self.changeButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + self.changeButton.widthAnchor.constraint(equalToConstant: 40), + self.changeButton.heightAnchor.constraint(equalToConstant: 40), + ]) NSLayoutConstraint.activate([ - backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), - backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), - backButton.widthAnchor.constraint(equalToConstant: 40), - backButton.heightAnchor.constraint(equalToConstant: 40), + self.informationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), + self.informationView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.informationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) } @@ -60,47 +117,35 @@ extension ResultDetailViewController { private func registerRecognizers() { let swipeDownRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showSmallInfoView)) swipeDownRecognizer.direction = .down - self.infoView?.addGestureRecognizer(swipeDownRecognizer) + self.informationView.addGestureRecognizer(swipeDownRecognizer) let swipeUpRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showLargeInfoView)) swipeUpRecognizer.direction = .up - self.infoView?.addGestureRecognizer(swipeUpRecognizer) - } - - private func layoutInitialRecordDetailView() { - let mapFrame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height * 0.75) - self.mapView = MKMapView(frame: mapFrame) - if let mapView = self.mapView { self.view.addSubview(mapView) } - - self.infoView = UIView(frame: CGRect(x: 0, y: self.view.bounds.height * 0.75, width: self.view.bounds.width, height: self.view.bounds.height * 0.25)) - if let infoView = self.infoView { - self.view.addSubview(infoView) - infoView.addSubview(ResultDetailSmallerInfoView(frame: infoView.bounds)) - } + self.informationView.addGestureRecognizer(swipeUpRecognizer) } } extension ResultDetailViewController { @objc private func showLargeInfoView() { - self.infoView?.subviews.forEach { $0.removeFromSuperview() } + self.informationView.subviews.forEach { $0.removeFromSuperview() } let newY = self.view.bounds.height * 0.1 let newHeight = self.view.bounds.height * 0.9 - self.mapView?.isUserInteractionEnabled = false + self.mapView.isUserInteractionEnabled = false UIView.animate(withDuration: 0.25) { - self.infoView?.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) + self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) } - self.infoView?.addSubview(ResultDetailLargerInfoView(frame: self.infoView?.bounds ?? CGRect.zero)) +// self.informationView.addSubview(ResultDetailLargerInfoView(frame: self.informationView.bounds CGRect.zero)) } @objc private func showSmallInfoView() { - self.infoView?.subviews.forEach { $0.removeFromSuperview() } + self.informationView.subviews.forEach { $0.removeFromSuperview() } let newY = self.view.bounds.height * 0.75 let newHeight = self.view.bounds.height * 0.25 - self.mapView?.isUserInteractionEnabled = true + self.mapView.isUserInteractionEnabled = true UIView.animate(withDuration: 0.25) { - self.infoView?.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) + self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) } - self.infoView?.addSubview(ResultDetailSmallerInfoView(frame: self.infoView?.bounds ?? CGRect.zero)) +// self.informationView.addSubview(ResultDetailSmallerInfoView(frame: self.informationView.bounds CGRect.zero)) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 7fc149a..d27c1a0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -16,6 +16,7 @@ class ResultDetailViewCoordinator: Coordinator { func start() { let resultDetailViewController = ResultDetailViewController(viewModel: injectDependencies()) resultDetailViewController.coordinator = self + self.navigationController.setNavigationBarHidden(true, animated: false) self.navigationController.pushViewController(resultDetailViewController, animated: true) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index e5b3532..97450d7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -11,16 +11,17 @@ import CoreLocation class ResultDetailViewModel { private let useCase: ResultDetailUseCase var resultDetailData: ResultDetailData? - var resultDetailDataReceived: (ResultDetailData) -> Void = { info in } + var recordDidFetch: () -> Void init(useCase: ResultDetailUseCase) { self.useCase = useCase + self.recordDidFetch = {} } func setUp() { self.useCase.transferResultDetailData { [weak self] dataModel in self?.resultDetailData = dataModel - self?.resultDetailDataReceived(dataModel) + self?.recordDidFetch() } } @@ -75,6 +76,7 @@ extension ResultDetailViewModel { init(distanceData: ResultDistance) { let formatter = NumberFormatter() formatter.numberStyle = .decimal + formatter.minimumFractionDigits = 2 formatter.maximumFractionDigits = 2 guard let total = formatter.string(from: NSNumber(value: distanceData.total)), let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { From 659e47610a690a25dad95942703b2e45a3ec8c52 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 18 Nov 2021 21:12:20 +0900 Subject: [PATCH 289/465] =?UTF-8?q?[Fix]=20#248=20=EC=95=B1=EC=9D=B4=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=81=AC=EB=9E=98=EC=8B=9C=EA=B0=80=20=EB=82=98=EB=8A=94=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Resources/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/Resources/Info.plist b/SanTa/SanTa/Resources/Info.plist index 4f942fa..4d75803 100644 --- a/SanTa/SanTa/Resources/Info.plist +++ b/SanTa/SanTa/Resources/Info.plist @@ -2,6 +2,8 @@ + NSPhotoLibraryUsageDescription + 사진 저장을 위해 사진 접근을 허용해주세요. UIApplicationSceneManifest UIApplicationSupportsMultipleScenes From 4007be87f4381d8303b9b81f8ba0f1832d06d7b0 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 21 Nov 2021 01:17:56 +0900 Subject: [PATCH 290/465] =?UTF-8?q?[Feat]=20=EA=B0=9C=EB=B3=84=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=84=B1=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailModel.swift | 11 +--- .../ResultDetailViewController.swift | 14 ++--- .../ResultDetailViewModel.swift | 62 ++++++++++++++++--- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index a5ec904..98f9bb7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -57,18 +57,13 @@ struct ResultTime { let inactive: TimeInterval init(records: Records) { - var active: TimeInterval = 0 var inactive: TimeInterval = 0 for index in 0.. Void - + var distanceViewModel: DistanceViewModel { + return DistanceViewModel(distanceData: self.resultDetailData?.distance) + } + var timeViewModel: TimeViewModel { + print(self.resultDetailData?.time.spent, self.resultDetailData?.time.active, self.resultDetailData?.time.inactive) + return TimeViewModel(timeData: self.resultDetailData?.time) + } + var altitudeViewModel: AltitudeViewModel { + return AltitudeViewModel(altitudeData: self.resultDetailData?.altitude) + } init(useCase: ResultDetailUseCase) { self.useCase = useCase self.recordDidFetch = {} @@ -25,6 +34,16 @@ class ResultDetailViewModel { } } + func averageSpeed() -> String { + let formatter = NumberFormatter() + formatter.minimumFractionDigits = 2 + formatter.maximumFractionDigits = 2 + let totalDistance = self.resultDetailData?.distance.total ?? 0 + let totalTimeSpent = self.resultDetailData?.time.spent ?? 1 + print(totalTimeSpent) + return formatter.string(from: NSNumber(value: totalDistance / totalTimeSpent)) ?? "" + } + var recordDate: String { guard let endTime = self.resultDetailData?.timeStamp.endTime else { return "" @@ -67,22 +86,32 @@ protocol ResultDetailCellRepresentable { } extension ResultDetailViewModel { - - struct DistanceViewModel: ResultDetailCellRepresentable { let title: String = "거리" + let totalDistance: String + let steps: String let contents: [CellContentEntity] - init(distanceData: ResultDistance) { + init(distanceData: ResultDistance?) { + guard let distanceData = distanceData else { + self.totalDistance = "" + self.steps = "" + self.contents = [] + return + } let formatter = NumberFormatter() formatter.numberStyle = .decimal - formatter.minimumFractionDigits = 2 + formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 2 guard let total = formatter.string(from: NSNumber(value: distanceData.total)), let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { self.contents = [] + self.totalDistance = "" + self.steps = "" return } + self.totalDistance = total + self.steps = steps self.contents = [ CellContentEntity(content: total, contentTitle: "전체"), CellContentEntity(content: steps, contentTitle: "걸음수") @@ -92,17 +121,26 @@ extension ResultDetailViewModel { struct TimeViewModel: ResultDetailCellRepresentable { var title: String = "시간" + let totalTimeSpent: String var contents: [CellContentEntity] - init(timeData: ResultTime) { + init(timeData: ResultTime?) { + guard let timeData = timeData else { + self.totalTimeSpent = "" + self.contents = [] + return + } let formatter = DateComponentsFormatter() formatter.allowedUnits = [.hour, .minute] + formatter.zeroFormattingBehavior = .pad guard let spent = formatter.string(from: timeData.spent), let active = formatter.string(from: timeData.active), let inactive = formatter.string(from: timeData.inactive) else { self.contents = [] + self.totalTimeSpent = "" return } + self.totalTimeSpent = spent self.contents = [ CellContentEntity(content: spent, contentTitle: "소요"), CellContentEntity(content: active, contentTitle: "운동"), @@ -120,9 +158,17 @@ extension ResultDetailViewModel { struct AltitudeViewModel: ResultDetailCellRepresentable { var title: String = "고도" + let highest: String + let lowest: String var contents: [CellContentEntity] - init(altitudeData: ResultAltitude) { + init(altitudeData: ResultAltitude?) { + guard let altitudeData = altitudeData else { + self.highest = "" + self.lowest = "" + self.contents = [] + return + } self.contents = [ CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), @@ -130,6 +176,8 @@ extension ResultDetailViewModel { CellContentEntity(content: String(altitudeData.starting), contentTitle: "시작"), CellContentEntity(content: String(altitudeData.ending), contentTitle: "종료"), ] + self.highest = String(altitudeData.highest) + self.lowest = String(altitudeData.lowest) } } From b02b6946d39dfa302753082fd5346f2b348cfc59 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 21 Nov 2021 01:20:46 +0900 Subject: [PATCH 291/465] =?UTF-8?q?[Fix]=20=ED=94=84=EB=A6=B0=ED=8A=B8?= =?UTF-8?q?=EB=AC=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 778a0ba..0b9993b 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -16,7 +16,6 @@ class ResultDetailViewModel { return DistanceViewModel(distanceData: self.resultDetailData?.distance) } var timeViewModel: TimeViewModel { - print(self.resultDetailData?.time.spent, self.resultDetailData?.time.active, self.resultDetailData?.time.inactive) return TimeViewModel(timeData: self.resultDetailData?.time) } var altitudeViewModel: AltitudeViewModel { From fb0d759a0ea63b3bdc333fd7ca4c14749d589dc4 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 21 Nov 2021 16:40:19 +0900 Subject: [PATCH 292/465] =?UTF-8?q?[Feat]=20=EA=B0=9C=EB=B3=84=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=EC=A0=95=EB=B3=B4=20=EB=B3=BC=EB=93=9C=EC=B2=B4,?= =?UTF-8?q?=20=EC=8A=A4=ED=83=9D=EB=B7=B0=20=EB=A0=88=EC=9D=B4=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailSmallerInfoView.swift | 65 ++++++++++++++----- .../ResultDetailViewController.swift | 5 -- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 52cf59e..904a616 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -9,12 +9,36 @@ import UIKit class ResultDetailSmallerInfoView: UIView { - private let distance = UILabel() - private let time = UILabel() - private let steps = UILabel() - private let maxAltitude = UILabel() - private let minAltitude = UILabel() - private let averageSpeed = UILabel() + private let distance: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() + private let time: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() + private let steps: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() + private let maxAltitude: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() + private let minAltitude: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() + private let averageSpeed: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + return label + }() private let distanceLabel: UILabel = { let label = UILabel() @@ -56,7 +80,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.distance, self.distanceLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -64,7 +89,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.time, self.timeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -72,7 +98,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.steps, self.stepsLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -80,7 +107,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.maxAltitude, self.maxAltitudeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -88,7 +116,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.minAltitude, self.minAltitudeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -96,7 +125,8 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.averageSpeed, self.averageSpeedLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.distribution = .fillEqually + stackView.spacing = 0 +// stackView.distribution = .fillEqually return stackView }() @@ -117,7 +147,7 @@ class ResultDetailSmallerInfoView: UIView { private lazy var compositionalStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.firstHorizontalStackView, self.secondHorizontalStackView]) stackView.axis = .vertical - stackView.distribution = .fillEqually + stackView.distribution = .equalCentering stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -125,6 +155,7 @@ class ResultDetailSmallerInfoView: UIView { func configureLayout(distance: String, time: String, steps: String, maxAltitude: String, minAltitude: String, averageSpeed: String) { self.backgroundColor = .systemBackground self.distance.text = distance + self.distance.font = .systemFont(ofSize: self.distance.font.pointSize, weight: .bold) self.time.text = time self.steps.text = steps self.maxAltitude.text = maxAltitude @@ -133,15 +164,17 @@ class ResultDetailSmallerInfoView: UIView { self.addSubview(self.compositionalStackView) NSLayoutConstraint.activate([ self.compositionalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), - self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor), + self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), - self.compositionalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + self.compositionalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) ]) + self.displayArrowImage() } private func displayArrowImage() { - let arrow = UIImage(systemName: "chevron.compact.up")?.withTintColor(.black) + let arrow = UIImage(systemName: "chevron.compact.up") let imageView = UIImageView(image: arrow) + imageView.tintColor = .black self.addSubview(imageView) imageView.translatesAutoresizingMaskIntoConstraints = false diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index b2e4820..8611262 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -69,10 +69,7 @@ class ResultDetailViewController: UIViewController { } private func configureSmallerView() { - - print(informationView.bounds) self.informationView = ResultDetailSmallerInfoView(frame: self.informationView.bounds) - print(view.subviews) } private func configureViews() { @@ -134,7 +131,6 @@ extension ResultDetailViewController { UIView.animate(withDuration: 0.25) { self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) } -// self.informationView.addSubview(ResultDetailLargerInfoView(frame: self.informationView.bounds CGRect.zero)) } @objc private func showSmallInfoView() { @@ -145,7 +141,6 @@ extension ResultDetailViewController { UIView.animate(withDuration: 0.25) { self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) } -// self.informationView.addSubview(ResultDetailSmallerInfoView(frame: self.informationView.bounds CGRect.zero)) } } From d683b5575a711fd4df95b206909f2ba82e37e4e0 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 21 Nov 2021 16:58:42 +0900 Subject: [PATCH 293/465] =?UTF-8?q?[Feat]=20=EB=B3=80=EA=B2=BD=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=95=A1=EC=85=98(=EC=96=BC=EB=9F=BF=EB=A7=8C)=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 8611262..4464aa9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -43,6 +43,7 @@ class ResultDetailViewController: UIViewController { button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) button.tintColor = .label button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(presentModifyResultAlert), for: .touchUpInside) return button }() @@ -103,14 +104,6 @@ class ResultDetailViewController: UIViewController { ]) } - @objc func dismissViewController() { - coordinator?.dismiss() - } -} - - - -extension ResultDetailViewController { private func registerRecognizers() { let swipeDownRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showSmallInfoView)) swipeDownRecognizer.direction = .down @@ -142,6 +135,25 @@ extension ResultDetailViewController { self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) } } + + @objc func dismissViewController() { + coordinator?.dismiss() + } + + @objc func presentModifyResultAlert() { + let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in + + } + let delete = UIAlertAction(title: "삭제", style: .destructive) { action in + + } + let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil) + alert.addAction(changeTitle) + alert.addAction(delete) + alert.addAction(cancel) + self.present(alert, animated: true, completion: nil) + } } From eb35f5f6a124413731b0ea8bf5298a73572e3a0c Mon Sep 17 00:00:00 2001 From: Shin Date: Sun, 21 Nov 2021 20:48:43 +0900 Subject: [PATCH 294/465] =?UTF-8?q?[Refactor]=20#250=20MapScene=20?= =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Combine, Dictionary, Convention, Layout --- SanTa/SanTa/MapScene/MapViewController.swift | 97 ++++++++++++-------- SanTa/SanTa/MapScene/MapViewModel.swift | 31 +++---- SanTa/SanTa/MapScene/MapViewUseCase.swift | 10 +- 3 files changed, 75 insertions(+), 63 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 5130f87..5f5e209 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -5,6 +5,7 @@ // Created by shin jae ung on 2021/10/28. // import MapKit +import Combine protocol Animatable: AnyObject { func shouldAnimate() @@ -14,6 +15,9 @@ protocol Animatable: AnyObject { class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var viewModel: MapViewModel? + private var observers: [AnyCancellable] = [] + private let mapDictionary: [Map:MKMapType] = [.infomation:.mutedStandard, .normal: .standard, .satellite: .hybrid] + private lazy var mapView: MKMapView = { let mapView = MKMapView(frame: view.bounds) mapView.showsUserLocation = true @@ -22,6 +26,7 @@ class MapViewController: UIViewController { mapView.delegate = self return mapView }() + private lazy var startButton: UIButton = { let button = UIButton() button.backgroundColor = UIColor(named: "SantaColor") @@ -34,9 +39,11 @@ class MapViewController: UIViewController { button.layer.shadowOpacity = 1 button.layer.shadowRadius = 3 button.layer.shadowOffset = CGSize(width: 0, height: 3) + button.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) return button }() - private lazy var addAnnotationButton: UIButton = { + + private lazy var newPlaceButton: UIButton = { let button = UIButton() button.isHidden = true button.translatesAutoresizingMaskIntoConstraints = false @@ -49,8 +56,10 @@ class MapViewController: UIViewController { button.layer.shadowOpacity = 1 button.layer.shadowRadius = 3 button.layer.shadowOffset = CGSize(width: 0, height: 2) + button.addTarget(self, action: #selector(presentMountainAddingViewController), for: .touchUpInside) return button }() + private lazy var userTrackingButton: MKUserTrackingButton = { let button = MKUserTrackingButton(mapView: self.mapView) button.isHidden = true @@ -75,21 +84,18 @@ class MapViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { viewModel?.viewWillAppear() - self.configureUserTrackingButton() } private func configureViews() { self.view.addSubview(self.mapView) self.view.addSubview(self.startButton) - self.view.addSubview(self.addAnnotationButton) + self.view.addSubview(self.newPlaceButton) self.view.addSubview(self.userTrackingButton) - self.startButton.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) - self.addAnnotationButton.addTarget(self, action: #selector(presentMountainAddingViewController), for: .touchUpInside) NSLayoutConstraint.activate([ self.startButton.widthAnchor.constraint(equalToConstant: 100), self.startButton.heightAnchor.constraint(equalToConstant: 100), - self.startButton.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -mapView.frame.height/6), + self.startButton.bottomAnchor.constraint(equalTo: mapView.safeAreaLayoutGuide.bottomAnchor, constant: -mapView.frame.height/15), self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) ]) NSLayoutConstraint.activate([ @@ -99,10 +105,10 @@ class MapViewController: UIViewController { self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) ]) NSLayoutConstraint.activate([ - self.addAnnotationButton.widthAnchor.constraint(equalToConstant: 150), - self.addAnnotationButton.heightAnchor.constraint(equalToConstant: 30), - self.addAnnotationButton.bottomAnchor.constraint(equalTo: startButton.topAnchor, constant: -10), - self.addAnnotationButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) + self.newPlaceButton.widthAnchor.constraint(equalToConstant: 150), + self.newPlaceButton.heightAnchor.constraint(equalToConstant: 30), + self.newPlaceButton.bottomAnchor.constraint(equalTo: startButton.topAnchor, constant: -10), + self.newPlaceButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) ]) } @@ -118,15 +124,32 @@ class MapViewController: UIViewController { } private func configureViewModel() { - self.viewModel?.markersShouldUpdate = { self.configureMarkers() } - self.viewModel?.mapShouldUpdate = { self.configureMap() } - self.viewModel?.initialLocationShouldUpdate = { self.configureLocation() } - self.viewModel?.locationPermissionDidChange = { self.configureUserTrackingButton() } - self.viewModel?.viewDidLoad() + self.viewModel?.configureBindings() + self.viewModel?.$mountains + .sink(receiveValue: { [weak self] mountains in + self?.configureMarkers(mountains) + }) + .store(in: &self.observers) + self.viewModel?.$map + .sink(receiveValue: { [weak self] map in + self?.configureMap(map) + }) + .store(in: &self.observers) + self.viewModel?.$initialLocation + .sink(receiveValue: { [weak self] location in + self?.configureLocation(location) + }) + .store(in: &self.observers) + self.viewModel?.$locationPermission + .sink(receiveValue: { [weak self] bool in + self?.configureUserTrackingButton(bool) + }) + .store(in: &self.observers) } - private func configureMarkers() { - self.viewModel?.mountains?.forEach{ mountainEntity in + private func configureMarkers(_ mountains: [MountainEntity]?) { + guard let mountains = mountains else { return } + mountains.forEach{ mountainEntity in let mountainAnnotation = MountainAnnotation( title: mountainEntity.mountain.mountainName, subtitle: mountainEntity.mountain.mountainHeight + "m", @@ -139,20 +162,14 @@ class MapViewController: UIViewController { } } - private func configureMap() { - guard let map = viewModel?.map else { return } - switch map { - case .infomation: - self.mapView.mapType = .mutedStandard - case .normal: - self.mapView.mapType = .standard - case .satellite: - self.mapView.mapType = .hybrid - } + private func configureMap(_ map: Map?) { + guard let map = map, + let mapType = mapDictionary[map] else { return } + self.mapView.mapType = mapType } - private func configureLocation() { - guard let location = viewModel?.initialLocation else { return } + private func configureLocation(_ location: CLLocation?) { + guard let location = location else { return } let coordinate = CLLocationCoordinate2D( latitude: location.coordinate.latitude, longitude: location.coordinate.longitude @@ -165,8 +182,8 @@ class MapViewController: UIViewController { mapView.setRegion(region, animated: true) } - private func configureUserTrackingButton() { - guard let permission = viewModel?.locationPermission else { return } + private func configureUserTrackingButton(_ permission: Bool?) { + guard let permission = permission else { return } self.userTrackingButton.isHidden = !permission } @@ -184,7 +201,7 @@ class MapViewController: UIViewController { @objc private func presentRecordingViewController() { UINotificationFeedbackGenerator().notificationOccurred(.success) - if let viewModel = self.viewModel, viewModel.locationPermission { + if let viewModel = self.viewModel, viewModel.locationPermission == true { self.coordinator?.presentRecordingViewController() } else { self.present(authAlert(), animated: false) @@ -219,27 +236,27 @@ extension MapViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) { switch mode { case .follow, .followWithHeading: - if addAnnotationButton.isHidden { - self.addAnnotationButton.isHidden = false - self.addAnnotationButton.alpha = 0 + if newPlaceButton.isHidden { + self.newPlaceButton.isHidden = false + self.newPlaceButton.alpha = 0 UIView.transition( - with: addAnnotationButton, + with: newPlaceButton, duration: 0.5, options: [], animations: { [weak self] in - self?.addAnnotationButton.alpha = 1 + self?.newPlaceButton.alpha = 1 } ) } default: UIView.transition( - with: addAnnotationButton, + with: newPlaceButton, duration: 0.5, options: [], animations: { [weak self] in - self?.addAnnotationButton.alpha = 0 + self?.newPlaceButton.alpha = 0 }, completion: { [weak self] _ in - self?.addAnnotationButton.isHidden = true + self?.newPlaceButton.isHidden = true } ) } diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index 98c1f9f..11f98b0 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -5,40 +5,32 @@ // Created by shin jae ung on 2021/11/01. // -import Foundation +import Combine import CoreLocation -class MapViewModel { +final class MapViewModel { private let useCase: MapViewUseCase - private(set) var mountains: [MountainEntity]? - private(set) var map: Map? - private(set) var initialLocation: CLLocation? - var locationPermission: Bool { self.useCase.locationPermission } - var markersShouldUpdate: () -> Void - var mapShouldUpdate: () -> Void - var initialLocationShouldUpdate: () -> Void - var locationPermissionDidChange: () -> Void + @Published private(set) var mountains: [MountainEntity]? + @Published private(set) var map: Map? + @Published private(set) var initialLocation: CLLocation? + @Published private(set) var locationPermission: Bool? init(useCase: MapViewUseCase) { self.useCase = useCase - self.markersShouldUpdate = {} - self.mapShouldUpdate = {} - self.initialLocationShouldUpdate = {} - self.locationPermissionDidChange = {} } - func viewDidLoad() { + func configureBindings() { self.useCase.prepareMountainMarkers { [weak self] mountains in self?.mountains = mountains - self?.markersShouldUpdate() } self.useCase.initialLocation = { [weak self] initialLocation in self?.initialLocation = initialLocation - self?.initialLocationShouldUpdate() } - self.useCase.locationPermissionDidChanged = { [weak self] in - self?.locationPermissionDidChange() + self.useCase.locationPermissionDidChangeTo = { [weak self] bool in + self?.locationPermission = bool } + + self.useCase.preparePermission() self.useCase.prepareLocacationManager() } @@ -46,7 +38,6 @@ class MapViewModel { self.useCase.prepareMap{ [weak self] map in guard let map = map else { return } self?.map = map - self?.mapShouldUpdate() } } } diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index ba92daa..5045769 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -13,7 +13,7 @@ class MapViewUseCase: NSObject { private let repository: MapViewRepository private let manager = CLLocationManager() var initialLocation: (CLLocation) -> Void - var locationPermissionDidChanged: () -> Void + var locationPermissionDidChangeTo: (Bool) -> Void var locationPermission: Bool { switch self.manager.authorizationStatus { case .authorizedAlways, .authorizedWhenInUse: @@ -26,7 +26,7 @@ class MapViewUseCase: NSObject { init(repository: MapViewRepository) { self.repository = repository self.initialLocation = { _ in } - self.locationPermissionDidChanged = {} + self.locationPermissionDidChangeTo = { _ in } } func prepareMountainMarkers(completion: @escaping ([MountainEntity]?) -> Void) { @@ -53,6 +53,10 @@ class MapViewUseCase: NSObject { } } + func preparePermission() { + self.locationPermissionDidChangeTo(self.locationPermission) + } + func prepareLocacationManager() { self.manager.requestWhenInUseAuthorization() self.manager.requestAlwaysAuthorization() @@ -71,6 +75,6 @@ extension MapViewUseCase: CLLocationManagerDelegate { } func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - self.locationPermissionDidChanged() + self.locationPermissionDidChangeTo(self.locationPermission) } } From 97314fd045e632d74e86aa1aa13ca7749d8821f1 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 22 Nov 2021 14:59:03 +0900 Subject: [PATCH 295/465] =?UTF-8?q?[Feat]=20#255=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 +++ SanTa/SanTa/MapScene/MapViewController.swift | 1 + .../Persistences/CoreDataRecordStorage.swift | 33 +++++++++++++++++++ SanTa/SanTa/RecordingScene/Record.swift | 3 ++ .../SanTa/RecordingScene/RecordingModel.swift | 3 +- .../SanTa.xcdatamodel/contents | 6 ++-- .../ResultDetailScene/ResultDetailModel.swift | 2 ++ .../ResultDetailRepository.swift | 25 ++++++++++++++ .../ResultDetailUseCase.swift | 16 ++++++++- .../ResultDetailViewController.swift | 6 +++- .../ResultDetailViewCoordinator.swift | 5 +++ .../ResultDetailViewModel.swift | 7 ++++ SanTa/SanTa/ResultScene/ResultUseCase.swift | 5 +-- 13 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f983fe0..0a4e62e 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; + 49921D89274B3B440091112C /* ResultDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49921D88274B3B440091112C /* ResultDetailRepository.swift */; }; 49A3E61D2732756C0020CAC1 /* MountainAnnotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */; }; 49D5A9492738C31600937821 /* MountainDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */; }; 49D5A94B2738C3AB00937821 /* MountainDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */; }; @@ -122,6 +123,7 @@ 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; + 49921D88274B3B440091112C /* ResultDetailRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailRepository.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewCoordinator.swift; sourceTree = ""; }; 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailViewController.swift; sourceTree = ""; }; @@ -269,6 +271,7 @@ 4948038327437499002854B1 /* ResultDetailUseCase.swift */, 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, 493178B32743992400B5FB88 /* DetailCell.swift */, + 49921D88274B3B440091112C /* ResultDetailRepository.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -632,6 +635,7 @@ 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, 984DDEC727327064003BE56B /* CoreDataRecordStorage.swift in Sources */, 49225C60273CDB680021AD79 /* ResultDetailSmallerInfoView.swift in Sources */, + 49921D89274B3B440091112C /* ResultDetailRepository.swift in Sources */, 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */, 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */, 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 5130f87..8df23e9 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -71,6 +71,7 @@ class MapViewController: UIViewController { self.configureViews() self.registerAnnotationView() self.configureViewModel() + print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!") } override func viewWillAppear(_ animated: Bool) { diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 637bf6f..7223ce5 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -28,6 +28,8 @@ final class CoreDataRecordStorage: RecordsStorage { into: context) recordsObject.setValue(records.title, forKey: "title") + recordsObject.setValue(records.id, forKey: "id") + print(records.id) recordsObject.setValue(records.secondPerHighestSpeed, forKey: "secondPerHighestSpeed") recordsObject.setValue(records.secondPerMinimumSpeed, forKey: "secondPerMinimumSpeed") @@ -83,4 +85,35 @@ final class CoreDataRecordStorage: RecordsStorage { } } } + + func delete(id: String, completion: @escaping (Result) -> Void) { + let request = NSFetchRequest(entityName: "RecordsEntity") + request.predicate = NSPredicate(format: "id = %@", id) + self.coreDataStorage.performBackgroundTask { context in + do { + let result = try context.fetch(request) + print(result) + context.delete(result[0]) + try context.save() + completion(.success(Void())) + } catch { + print(error) + completion(.failure(error)) + } + } + } + + func update(id: String, title: String) { + let request = NSFetchRequest(entityName: "RecordsEntity") + request.predicate = NSPredicate(format: "id = %@", id) + self.coreDataStorage.performBackgroundTask { context in + do { + let result = try context.fetch(request) + result[0].setValue(title, forKey: "title") + try context.save() + } catch { + print(error) + } + } + } } diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 2aa7d06..927b157 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -98,6 +98,9 @@ struct Records { private(set) var assetIdentifiers: [String] private(set) var secondPerHighestSpeed: Int private(set) var secondPerMinimumSpeed: Int + private(set) var id: String + + var date: Date? { return records.last?.endTime diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index e2bd8c5..d91be43 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -190,7 +190,8 @@ final class RecordingModel: NSObject, ObservableObject { records: [record], assetIdentifiers: [String](), secondPerHighestSpeed: minTime, - secondPerMinimumSpeed: self.maxOneKiloTime) + secondPerMinimumSpeed: self.maxOneKiloTime, + id: UUID().uuidString) return } diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 3275a97..6919375 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -15,8 +15,8 @@ - + @@ -25,6 +25,6 @@ - + \ No newline at end of file diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 98f9bb7..4a778c0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -15,6 +15,7 @@ struct ResultDetailData { // let pace: ResultPace let altitude: ResultAltitude let incline: ResultIncline + let id: String init(records: Records) { self.timeStamp = ResultTimeStamp(records: records) @@ -22,6 +23,7 @@ struct ResultDetailData { self.time = ResultTime(records: records) self.altitude = ResultAltitude(records: records) self.incline = ResultIncline(records: records) + self.id = records.id } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift new file mode 100644 index 0000000..37f1083 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift @@ -0,0 +1,25 @@ +// +// ResultDetailRepository.swift +// SanTa +// +// Created by Jiwon Yoon on 2021/11/22. +// + +import Foundation + +protocol ResultDetailRepository { +// func update(id: UUID, title: String, completion: @escaping (Result<>)) + func delete(id: String, completion: @escaping (Result) -> Void) +} + +class DefaultResultDetailRepository: ResultDetailRepository { + private let recordStorage: CoreDataRecordStorage + + init(recordStorage: CoreDataRecordStorage) { + self.recordStorage = recordStorage + } + func delete(id: String, completion: @escaping (Result) -> Void) { + self.recordStorage.delete(id: id, completion: completion) + + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index 8ebeee0..b39a015 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -9,12 +9,26 @@ import Foundation class ResultDetailUseCase { private let model: ResultDetailData + private let repository: ResultDetailRepository - init(model: ResultDetailData) { + init(model: ResultDetailData, repository: ResultDetailRepository) { self.model = model + self.repository = repository } func transferResultDetailData(completion: (ResultDetailData) -> Void) { completion(self.model) } + + func delete(id: String, completion: @escaping () -> Void) { + self.repository.delete(id: id) { result in + switch result { + case .success(): + completion() + case .failure(let error): + print(error) + + } + } + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 4464aa9..2e548fc 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -146,7 +146,11 @@ extension ResultDetailViewController { } let delete = UIAlertAction(title: "삭제", style: .destructive) { action in - + self.viewModel?.delete { + DispatchQueue.main.async { + self.coordinator?.dismiss() + } + } } let cancel = UIAlertAction(title: "취소", style: .cancel, handler: nil) alert.addAction(changeTitle) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index d27c1a0..7f0a6c3 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -38,6 +38,11 @@ extension ResultDetailViewCoordinator { useCase: ResultDetailUseCase( model: ResultDetailData( records: self.records + ), + repository: DefaultResultDetailRepository( + recordStorage: CoreDataRecordStorage( + coreDataStorage: self.coreDataStorage + ) ) ) ) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 0b9993b..89aab1e 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -33,6 +33,13 @@ class ResultDetailViewModel { } } + func delete(completion: @escaping () -> Void) { + guard let id = self.resultDetailData?.id else { + return + } + self.useCase.delete(id: id, completion: completion) + } + func averageSpeed() -> String { let formatter = NumberFormatter() formatter.minimumFractionDigits = 2 diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index b264a46..5f666c2 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -40,14 +40,15 @@ final class ResultUseCase { } private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { - guard let title = recordsEntityMO.title else { return nil } + guard let title = recordsEntityMO.title, + let id = recordsEntityMO.id else { return nil } var records: [Record] = [] recordsEntityMO.records?.forEach { guard let recordEntityMO = $0 as? RecordEntityMO else { return } guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } records.append(record) } - return Records(title: title, records: records, assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int()) + return Records(title: title, records: records, assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int(), id: id) } private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { From 0334d24dc71871a93920a7873116b6db973afe39 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 15:08:57 +0900 Subject: [PATCH 296/465] [Feat] #149 InformationView Pan Gesture Configure --- .../ResultDetailViewController.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 4464aa9..3fc256a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -55,6 +55,7 @@ class ResultDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.configureViews() + self.configurePanGesture() self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } self?.informationView.configureLayout( @@ -73,6 +74,14 @@ class ResultDetailViewController: UIViewController { self.informationView = ResultDetailSmallerInfoView(frame: self.informationView.bounds) } + private func configurePanGesture() { + let informationViewPan = UIPanGestureRecognizer(target: self, action: #selector(informationViewPanPanned(_:))) + + informationViewPan.delaysTouchesBegan = false + informationViewPan.delaysTouchesEnded = false + view.addGestureRecognizer(informationViewPan) + } + private func configureViews() { self.view.addSubview(self.mapView) self.view.addSubview(self.backButton) @@ -113,6 +122,12 @@ class ResultDetailViewController: UIViewController { swipeUpRecognizer.direction = .up self.informationView.addGestureRecognizer(swipeUpRecognizer) } + + @objc private func informationViewPanPanned(_ panGestureRecognizer: UIPanGestureRecognizer) { + let translation = panGestureRecognizer.translation(in: self.view) + + print("유저가 위아래로 \(translation.y)만큼 드래그하였습니다.") + } } extension ResultDetailViewController { From 37d6afa43c9e2adcc749983299b545863218af31 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 16:01:14 +0900 Subject: [PATCH 297/465] [Feat] #149 InformationView Scroll Up --- .../ResultDetailViewController.swift | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 3fc256a..3ec5f93 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -124,9 +124,54 @@ class ResultDetailViewController: UIViewController { } @objc private func informationViewPanPanned(_ panGestureRecognizer: UIPanGestureRecognizer) { - let translation = panGestureRecognizer.translation(in: self.view) + let translation = panGestureRecognizer.translation(in: self.informationView) - print("유저가 위아래로 \(translation.y)만큼 드래그하였습니다.") + let informationViewHeight = self.informationView.frame.height + + switch panGestureRecognizer.state { + case .began: + let blackView = UIView() +// blackView.backgroundColor = .black +// blackView.alpha = 0.5 +// +// self.mapView.addSubview(blackView) +// +// NSLayoutConstraint.activate([ +// blackView.leftAnchor.constraint(equalTo: self.mapView.leftAnchor), +// blackView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), +// blackView.rightAnchor.constraint(equalTo: self.mapView.rightAnchor), +// blackView.bottomAnchor.constraint(equalTo: self.mapView.bottomAnchor) +// ]) +// +// UIView.animate(withDuration: 0.2, animations: { +// self.view.layoutIfNeeded() +// }) + case .changed: + guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10) else { + return + } + + NSLayoutConstraint.activate([ + self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: translation.y) + ]) + + case .ended: + UIView.animate(withDuration: 1.2, delay: 0.3, options: .curveEaseInOut, animations: { + if self.informationView.frame.minY <= self.view.frame.height/2 { + NSLayoutConstraint.activate([ + self.informationView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: self.backButton.frame.height + 10) + ]) + } else { + NSLayoutConstraint.activate([ + self.informationView.topAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor) + ]) + } + self.view.setNeedsLayout() + }, completion: nil) + + default: + break + } } } From 44a28a2372d309b0d30899b35daaceb6a9a05168 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 16:03:51 +0900 Subject: [PATCH 298/465] [Feat] #149 InformationView Scroll Up Animate --- .../ResultDetailViewController.swift | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 3ec5f93..cb62a4b 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -156,17 +156,17 @@ class ResultDetailViewController: UIViewController { ]) case .ended: - UIView.animate(withDuration: 1.2, delay: 0.3, options: .curveEaseInOut, animations: { - if self.informationView.frame.minY <= self.view.frame.height/2 { - NSLayoutConstraint.activate([ - self.informationView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: self.backButton.frame.height + 10) - ]) - } else { - NSLayoutConstraint.activate([ - self.informationView.topAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor) - ]) - } - self.view.setNeedsLayout() + if self.informationView.frame.minY <= self.view.frame.height/2 { + NSLayoutConstraint.activate([ + self.informationView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: self.backButton.frame.height + 10) + ]) + } else { + NSLayoutConstraint.activate([ + self.informationView.topAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor) + ]) + } + UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut, animations: { + self.view.layoutIfNeeded() }, completion: nil) default: From 434943eaf89722742114e8cfcacfc3e154f69fe6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 16:07:16 +0900 Subject: [PATCH 299/465] =?UTF-8?q?[Feat]=20#149=20MapView=20Alpha=20?= =?UTF-8?q?=EA=B0=92=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index cb62a4b..96a13d6 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -17,6 +17,7 @@ class ResultDetailViewController: UIViewController { private lazy var mapView: MKMapView = { let mapView = MKMapView() mapView.mapType = .mutedStandard + mapView.backgroundColor = .black mapView.translatesAutoresizingMaskIntoConstraints = false return mapView }() @@ -130,22 +131,9 @@ class ResultDetailViewController: UIViewController { switch panGestureRecognizer.state { case .began: - let blackView = UIView() -// blackView.backgroundColor = .black -// blackView.alpha = 0.5 -// -// self.mapView.addSubview(blackView) -// -// NSLayoutConstraint.activate([ -// blackView.leftAnchor.constraint(equalTo: self.mapView.leftAnchor), -// blackView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), -// blackView.rightAnchor.constraint(equalTo: self.mapView.rightAnchor), -// blackView.bottomAnchor.constraint(equalTo: self.mapView.bottomAnchor) -// ]) -// -// UIView.animate(withDuration: 0.2, animations: { -// self.view.layoutIfNeeded() -// }) + UIView.animate(withDuration: 0.2, animations: { + self.mapView.alpha = 0.8 + }) case .changed: guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10) else { return @@ -161,11 +149,12 @@ class ResultDetailViewController: UIViewController { self.informationView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: self.backButton.frame.height + 10) ]) } else { + self.mapView.alpha = 1 NSLayoutConstraint.activate([ self.informationView.topAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor) ]) } - UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut, animations: { + UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { self.view.layoutIfNeeded() }, completion: nil) From e00e421e8be57d782c300a5815a59dae0f4ce6ad Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 22 Nov 2021 16:26:03 +0900 Subject: [PATCH 300/465] =?UTF-8?q?[Feat]=20#256=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=A0=9C=EB=AA=A9=20=EB=B3=80=EA=B2=BD=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Persistences/CoreDataRecordStorage.swift | 6 +-- .../RecordingViewController.swift | 5 ++- .../RecordingTitleViewController.swift | 2 +- .../RecordingTitleViewCoordinator.swift | 22 +++++++--- .../ResultDetailScene/ResultDetailModel.swift | 6 +++ .../ResultDetailRepository.swift | 8 +++- .../ResultDetailUseCase.swift | 16 +++---- .../ResultDetailViewController.swift | 43 +++++++++++++++++-- .../ResultDetailViewCoordinator.swift | 13 ++++++ .../ResultDetailViewModel.swift | 17 +++++++- 10 files changed, 111 insertions(+), 27 deletions(-) diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 7223ce5..0d63181 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -29,7 +29,6 @@ final class CoreDataRecordStorage: RecordsStorage { recordsObject.setValue(records.title, forKey: "title") recordsObject.setValue(records.id, forKey: "id") - print(records.id) recordsObject.setValue(records.secondPerHighestSpeed, forKey: "secondPerHighestSpeed") recordsObject.setValue(records.secondPerMinimumSpeed, forKey: "secondPerMinimumSpeed") @@ -103,7 +102,7 @@ final class CoreDataRecordStorage: RecordsStorage { } } - func update(id: String, title: String) { + func update(title: String, id: String, completion: @escaping (Result) -> Void) { let request = NSFetchRequest(entityName: "RecordsEntity") request.predicate = NSPredicate(format: "id = %@", id) self.coreDataStorage.performBackgroundTask { context in @@ -111,8 +110,9 @@ final class CoreDataRecordStorage: RecordsStorage { let result = try context.fetch(request) result[0].setValue(title, forKey: "title") try context.save() + completion(.success(Void())) } catch { - print(error) + completion(.failure(error)) } } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b78e1c3..144cb2f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -9,8 +9,11 @@ import UIKit import Combine import Photos -protocol RecordingViewDelegate: AnyObject { +protocol SetTitleDelegate: AnyObject { func didTitleWriteDone(title: String) +} + +protocol RecordingViewDelegate: SetTitleDelegate { func didAgreeButtonTouchDone() } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 13de1aa..db1191c 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -9,7 +9,7 @@ import UIKit class RecordingTitleViewController: UIViewController { weak var coordinator: RecordingTitleViewCoordinator? - weak var delegate: RecordingViewDelegate? + weak var delegate: SetTitleDelegate? private var displayView: UIView = { let view = UIView() diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index cf44fca..82f421c 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -12,22 +12,34 @@ class RecordingTitleViewCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController - init(delegate: RecordingViewDelegate) { + init(delegate: SetTitleDelegate) { self.recordingTitleViewController = RecordingTitleViewController() self.recordingTitleViewController.delegate = delegate self.recordingTitleViewController.coordinator = self } func start() { - guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + if let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator { + recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) + } else if let resultDetailCoordinator = parentCoordinator as? ResultDetailViewCoordinator { + resultDetailCoordinator.navigationController.viewControllers.last?.present(recordingTitleViewController, animated: true) + } +// guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else {return} - recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) +// recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) } func dismiss() { - guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } + if let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator { + recordingCoordinator.recordingViewController.dismiss(animated: true, completion: nil) + + } else if let resultDetailViewCoordinator = parentCoordinator as? ResultDetailViewCoordinator { + resultDetailViewCoordinator.navigationController.viewControllers.last?.dismiss(animated: true, completion: nil) + } + +// guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } +// recordingCoordinator.recordingViewController.dismiss(animated: true) - recordingCoordinator.recordingViewController.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 4a778c0..7dadec8 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -16,6 +16,7 @@ struct ResultDetailData { let altitude: ResultAltitude let incline: ResultIncline let id: String + private(set) var title: String init(records: Records) { self.timeStamp = ResultTimeStamp(records: records) @@ -24,6 +25,11 @@ struct ResultDetailData { self.altitude = ResultAltitude(records: records) self.incline = ResultIncline(records: records) self.id = records.id + self.title = records.title + } + + mutating func change(title: String) { + self.title = title } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift index 37f1083..469d9a9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift @@ -8,7 +8,7 @@ import Foundation protocol ResultDetailRepository { -// func update(id: UUID, title: String, completion: @escaping (Result<>)) + func update(title: String, id: String, completion: @escaping (Result) -> Void) func delete(id: String, completion: @escaping (Result) -> Void) } @@ -18,8 +18,12 @@ class DefaultResultDetailRepository: ResultDetailRepository { init(recordStorage: CoreDataRecordStorage) { self.recordStorage = recordStorage } + func delete(id: String, completion: @escaping (Result) -> Void) { self.recordStorage.delete(id: id, completion: completion) - + } + + func update(title: String, id: String, completion: @escaping (Result) -> Void) { + self.recordStorage.update(title: title, id: id, completion: completion) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index b39a015..c8fc709 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -20,15 +20,11 @@ class ResultDetailUseCase { completion(self.model) } - func delete(id: String, completion: @escaping () -> Void) { - self.repository.delete(id: id) { result in - switch result { - case .success(): - completion() - case .failure(let error): - print(error) - - } - } + func delete(id: String, completion: @escaping (Result) -> Void) { + self.repository.delete(id: id, completion: completion) + } + + func update(title: String, id: String, completion: @escaping (Result) -> Void) { + self.repository.update(title: title, id: id, completion: completion) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2e548fc..58588b4 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -47,6 +47,13 @@ class ResultDetailViewController: UIViewController { return button }() + private var titleLabel: UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + convenience init(viewModel: ResultDetailViewModel) { self.init() self.viewModel = viewModel @@ -57,6 +64,7 @@ class ResultDetailViewController: UIViewController { self.configureViews() self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } + self?.titleLabel.text = viewModel.resultDetailData?.title self?.informationView.configureLayout( distance: viewModel.distanceViewModel.totalDistance, time: viewModel.timeViewModel.totalTimeSpent, @@ -77,6 +85,7 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.mapView) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) + self.view.addSubview(self.titleLabel) self.view.addSubview(self.informationView) NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), @@ -96,6 +105,10 @@ class ResultDetailViewController: UIViewController { self.changeButton.widthAnchor.constraint(equalToConstant: 40), self.changeButton.heightAnchor.constraint(equalToConstant: 40), ]) + NSLayoutConstraint.activate([ + self.titleLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), + self.titleLabel.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + ]) NSLayoutConstraint.activate([ self.informationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), @@ -143,12 +156,23 @@ extension ResultDetailViewController { @objc func presentModifyResultAlert() { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in - + // TODO: 입력창 띄우고 텍스트 입력 받아서 update 호출 + self.coordinator?.presentRecordingTitleViewController() +// self.viewModel?.update(title: "타이트을", completion: { title in +// DispatchQueue.main.async { +// self.titleLabel.text = title +// } +// }) } let delete = UIAlertAction(title: "삭제", style: .destructive) { action in - self.viewModel?.delete { - DispatchQueue.main.async { - self.coordinator?.dismiss() + self.viewModel?.delete { result in + switch result { + case .success(): + DispatchQueue.main.async { + self.coordinator?.dismiss() + } + case .failure(let error): + print(error) } } } @@ -160,4 +184,15 @@ extension ResultDetailViewController { } } +extension ResultDetailViewController: SetTitleDelegate { + func didTitleWriteDone(title: String) { + self.viewModel?.update(title: title, completion: { title in + DispatchQueue.main.async { + self.titleLabel.text = title + } + }) + } + + +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 7f0a6c3..47d4ad2 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -12,6 +12,7 @@ class ResultDetailViewCoordinator: Coordinator { var navigationController: UINavigationController var coreDataStorage: CoreDataStorage var records: Records +// let viewController: ResultDetailViewController = .init(viewModel: self.injectDependencies()) func start() { let resultDetailViewController = ResultDetailViewController(viewModel: injectDependencies()) @@ -47,4 +48,16 @@ extension ResultDetailViewCoordinator { ) ) } + + func presentRecordingTitleViewController() { + guard let viewController = self.navigationController.viewControllers.last as? ResultDetailViewController else { + print("뷰컨 없음") + return + } + let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(delegate: viewController) + self.childCoordinators.append(recordingTitleViewCoordinator) + recordingTitleViewCoordinator.parentCoordinator = self + + recordingTitleViewCoordinator.start() + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 89aab1e..394c482 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -33,13 +33,28 @@ class ResultDetailViewModel { } } - func delete(completion: @escaping () -> Void) { + func delete(completion: @escaping (Result) -> Void) { guard let id = self.resultDetailData?.id else { return } self.useCase.delete(id: id, completion: completion) } + func update(title: String, completion: @escaping (String) -> Void) { + guard let id = self.resultDetailData?.id else { + return + } + self.useCase.update(title: title, id: id) { result in + switch result { + case .success(): + self.resultDetailData?.change(title: title) + completion(title) + case .failure(let error): + print(error) + } + } + } + func averageSpeed() -> String { let formatter = NumberFormatter() formatter.minimumFractionDigits = 2 From f6a6009cbfa6fc9372814e41f60bbad4626e6224 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 17:09:42 +0900 Subject: [PATCH 301/465] =?UTF-8?q?[Feat]=20#149=20InfoView=20Bottom=20Con?= =?UTF-8?q?straint=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 96a13d6..3a71b50 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -14,6 +14,8 @@ class ResultDetailViewController: UIViewController { private var viewModel: ResultDetailViewModel? + private var infoViewBottomConstraint: NSLayoutConstraint? + private lazy var mapView: MKMapView = { let mapView = MKMapView() mapView.mapType = .mutedStandard @@ -106,12 +108,17 @@ class ResultDetailViewController: UIViewController { self.changeButton.widthAnchor.constraint(equalToConstant: 40), self.changeButton.heightAnchor.constraint(equalToConstant: 40), ]) + NSLayoutConstraint.activate([ self.informationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), self.informationView.rightAnchor.constraint(equalTo: self.view.rightAnchor), self.informationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) + + infoViewBottomConstraint = + self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) + guard let infoViewConstraint = infoViewBottomConstraint else { return } + NSLayoutConstraint.activate([infoViewConstraint]) } private func registerRecognizers() { @@ -124,9 +131,23 @@ class ResultDetailViewController: UIViewController { self.informationView.addGestureRecognizer(swipeUpRecognizer) } + private func findInfoViewBottomConstraints(traslation: CGFloat) { + var bottomConstraint: NSLayoutConstraint? + self.informationView.constraints.forEach { + if $0.firstAttribute == .bottom { + bottomConstraint = $0 + } + } + bottomConstraint?.constant = traslation + } + + private func changeInfoViewBottomConstraints(traslation: CGFloat) { + guard let infoViewConstraint = self.infoViewBottomConstraint else { return } + infoViewConstraint.constant = traslation + } + @objc private func informationViewPanPanned(_ panGestureRecognizer: UIPanGestureRecognizer) { let translation = panGestureRecognizer.translation(in: self.informationView) - let informationViewHeight = self.informationView.frame.height switch panGestureRecognizer.state { @@ -134,26 +155,24 @@ class ResultDetailViewController: UIViewController { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 0.8 }) + case .changed: guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10) else { return } - - NSLayoutConstraint.activate([ - self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: translation.y) - ]) + + changeInfoViewBottomConstraints(traslation: translation.y) case .ended: if self.informationView.frame.minY <= self.view.frame.height/2 { - NSLayoutConstraint.activate([ - self.informationView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: self.backButton.frame.height + 10) - ]) + changeInfoViewBottomConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) } else { - self.mapView.alpha = 1 - NSLayoutConstraint.activate([ - self.informationView.topAnchor.constraint(equalTo: self.mapView.safeAreaLayoutGuide.bottomAnchor) - ]) + UIView.animate(withDuration: 0.2, animations: { + self.mapView.alpha = 1 + }) + changeInfoViewBottomConstraints(traslation: 0) } + UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { self.view.layoutIfNeeded() }, completion: nil) From e90ceb92bb1d5bcb63e7d1cd3902cfe4e03fc3a5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 17:24:25 +0900 Subject: [PATCH 302/465] =?UTF-8?q?[Feat]=20#149=20InfoView=20Up=20Down=20?= =?UTF-8?q?Scroll=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 3a71b50..56507a1 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -15,6 +15,8 @@ class ResultDetailViewController: UIViewController { private var viewModel: ResultDetailViewModel? private var infoViewBottomConstraint: NSLayoutConstraint? + private var infoViewHight: CGFloat? + private var largeInfoView = false private lazy var mapView: MKMapView = { let mapView = MKMapView() @@ -119,6 +121,9 @@ class ResultDetailViewController: UIViewController { self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewBottomConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) + + self.view.layoutIfNeeded() + self.infoViewHight = self.informationView.frame.height } private func registerRecognizers() { @@ -157,19 +162,28 @@ class ResultDetailViewController: UIViewController { }) case .changed: - guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10) else { + var offset: CGFloat = 0 + if largeInfoView { + offset = self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY + } + + guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10), + let infoViewHight = self.infoViewHight, + infoViewHight < (informationViewHeight - (translation.y + offset)) else { return } - changeInfoViewBottomConstraints(traslation: translation.y) + changeInfoViewBottomConstraints(traslation: translation.y + offset) case .ended: if self.informationView.frame.minY <= self.view.frame.height/2 { changeInfoViewBottomConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) + largeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 1 }) + largeInfoView = false changeInfoViewBottomConstraints(traslation: 0) } From 6a4d7958431bddc926126b8e46ec0d64fc5b338a Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 17:37:56 +0900 Subject: [PATCH 303/465] =?UTF-8?q?[Refactor]=20#149=20StackView=20spacing?= =?UTF-8?q?,=20mapView=20Height=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailSmallerInfoView.swift | 12 ++++++------ .../ResultDetailViewController.swift | 12 +----------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 904a616..564eff9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -80,7 +80,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.distance, self.distanceLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() @@ -89,7 +89,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.time, self.timeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() @@ -98,7 +98,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.steps, self.stepsLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() @@ -107,7 +107,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.maxAltitude, self.maxAltitudeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() @@ -116,7 +116,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.minAltitude, self.minAltitudeLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() @@ -125,7 +125,7 @@ class ResultDetailSmallerInfoView: UIView { let stackView = UIStackView(arrangedSubviews: [self.averageSpeed, self.averageSpeedLabel]) stackView.axis = .vertical stackView.alignment = .center - stackView.spacing = 0 + stackView.spacing = 5 // stackView.distribution = .fillEqually return stackView }() diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 56507a1..0c508fd 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -96,7 +96,7 @@ class ResultDetailViewController: UIViewController { self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -self.view.frame.height * 0.25) + self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -self.view.frame.height * 0.2) ]) NSLayoutConstraint.activate([ self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), @@ -126,16 +126,6 @@ class ResultDetailViewController: UIViewController { self.infoViewHight = self.informationView.frame.height } - private func registerRecognizers() { - let swipeDownRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showSmallInfoView)) - swipeDownRecognizer.direction = .down - self.informationView.addGestureRecognizer(swipeDownRecognizer) - - let swipeUpRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(showLargeInfoView)) - swipeUpRecognizer.direction = .up - self.informationView.addGestureRecognizer(swipeUpRecognizer) - } - private func findInfoViewBottomConstraints(traslation: CGFloat) { var bottomConstraint: NSLayoutConstraint? self.informationView.constraints.forEach { From b978bc4252656db6c52ca00d6201fe7bcbdbe987 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 17:52:54 +0900 Subject: [PATCH 304/465] =?UTF-8?q?[Feat]=20#149=20InfoView=20=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppDelegate.swift | 1 + .../ResultDetailSmallerInfoView.swift | 6 +++--- .../ResultDetailViewController.swift | 11 ++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index d14fffd..4513e31 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -9,6 +9,7 @@ import UIKit import CoreData import AVFoundation + @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 564eff9..5d65371 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -144,10 +144,11 @@ class ResultDetailSmallerInfoView: UIView { return stackView }() - private lazy var compositionalStackView: UIStackView = { + lazy var compositionalStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.firstHorizontalStackView, self.secondHorizontalStackView]) stackView.axis = .vertical stackView.distribution = .equalCentering + stackView.spacing = 10 stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -165,8 +166,7 @@ class ResultDetailSmallerInfoView: UIView { NSLayoutConstraint.activate([ self.compositionalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), - self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor), - self.compositionalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) + self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) ]) self.displayArrowImage() } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 0c508fd..2da3420 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -59,8 +59,6 @@ class ResultDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - self.configureViews() - self.configurePanGesture() self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } self?.informationView.configureLayout( @@ -71,6 +69,9 @@ class ResultDetailViewController: UIViewController { minAltitude: viewModel.altitudeViewModel.lowest, averageSpeed: viewModel.averageSpeed() ) + self?.informationView.layoutIfNeeded() + self?.configureViews() + self?.configurePanGesture() } viewModel?.setUp() } @@ -88,22 +89,26 @@ class ResultDetailViewController: UIViewController { } private func configureViews() { + guard let tabBar = self.navigationController?.tabBarController?.tabBar else { return } self.view.addSubview(self.mapView) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) self.view.addSubview(self.informationView) + NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -self.view.frame.height * 0.2) + self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -(self.informationView.compositionalStackView.frame.height + tabBar.frame.height)) ]) + NSLayoutConstraint.activate([ self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), self.backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), self.backButton.widthAnchor.constraint(equalToConstant: 40), self.backButton.heightAnchor.constraint(equalToConstant: 40), ]) + NSLayoutConstraint.activate([ self.changeButton.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor, constant: -10), self.changeButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), From 965593e16c748f2c048aa1a306a4bd5f9691dbfa Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 22 Nov 2021 18:10:50 +0900 Subject: [PATCH 305/465] =?UTF-8?q?[Feat]=20#258=20=EC=82=B0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EB=B3=B4=EC=9D=B4=EC=8A=A4?= =?UTF-8?q?=EC=98=A4=EB=B2=84=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/MountainDetailScene/MountainDetailViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index bcbf125..fe45e99 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -139,6 +139,7 @@ extension MountainDetailViewController { mapView.register(MountainAnnotationView.self, forAnnotationViewWithReuseIdentifier: MountainAnnotationView.ReuseID) mapView.addAnnotation(annotation) mapView.selectAnnotation(annotation, animated: true) + mapView.accessibilityElementsHidden = true return mapView } From 9b64d954f0e91d0ebbf3736a898c0a65ae69bbd5 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 22 Nov 2021 18:12:26 +0900 Subject: [PATCH 306/465] =?UTF-8?q?[Feat]=20#259=20=EC=8B=9C=EC=9E=91?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=B3=B4=EC=9D=B4=EC=8A=A4=EC=98=A4?= =?UTF-8?q?=EB=B2=84=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 5f5e209..9c1eb1c 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -24,6 +24,7 @@ class MapViewController: UIViewController { mapView.showsScale = true mapView.showsCompass = true mapView.delegate = self + mapView.accessibilityElementsHidden = true return mapView }() @@ -40,6 +41,7 @@ class MapViewController: UIViewController { button.layer.shadowRadius = 3 button.layer.shadowOffset = CGSize(width: 0, height: 3) button.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) + button.accessibilityHint = "측정을 시작하려면 이중탭 하십시오" return button }() From 99a69f11e054225b6e2c3c70c40655f2dbad282f Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 19:51:01 +0900 Subject: [PATCH 307/465] [Feat] #149 Rename Property --- .../ResultDetailViewController.swift | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2da3420..f71831f 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -14,9 +14,9 @@ class ResultDetailViewController: UIViewController { private var viewModel: ResultDetailViewModel? - private var infoViewBottomConstraint: NSLayoutConstraint? + private var infoViewTopConstraint: NSLayoutConstraint? private var infoViewHight: CGFloat? - private var largeInfoView = false + private var isLargeInfoView = false private lazy var mapView: MKMapView = { let mapView = MKMapView() @@ -122,9 +122,9 @@ class ResultDetailViewController: UIViewController { self.informationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) - infoViewBottomConstraint = + infoViewTopConstraint = self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) - guard let infoViewConstraint = infoViewBottomConstraint else { return } + guard let infoViewConstraint = infoViewTopConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) self.view.layoutIfNeeded() @@ -141,8 +141,8 @@ class ResultDetailViewController: UIViewController { bottomConstraint?.constant = traslation } - private func changeInfoViewBottomConstraints(traslation: CGFloat) { - guard let infoViewConstraint = self.infoViewBottomConstraint else { return } + private func changeInfoViewTopConstraints(traslation: CGFloat) { + guard let infoViewConstraint = self.infoViewTopConstraint else { return } infoViewConstraint.constant = traslation } @@ -158,7 +158,7 @@ class ResultDetailViewController: UIViewController { case .changed: var offset: CGFloat = 0 - if largeInfoView { + if isLargeInfoView { offset = self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY } @@ -168,18 +168,18 @@ class ResultDetailViewController: UIViewController { return } - changeInfoViewBottomConstraints(traslation: translation.y + offset) + changeInfoViewTopConstraints(traslation: translation.y + offset) case .ended: if self.informationView.frame.minY <= self.view.frame.height/2 { - changeInfoViewBottomConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) - largeInfoView = true + changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) + isLargeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 1 }) - largeInfoView = false - changeInfoViewBottomConstraints(traslation: 0) + isLargeInfoView = false + changeInfoViewTopConstraints(traslation: 0) } UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { From 772a95ac130e21e5669a77144f247c260fc702c7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 20:03:04 +0900 Subject: [PATCH 308/465] [Feat] #149 Display Up Down Mark --- .../ResultDetailSmallerInfoView.swift | 27 ++++++++++--------- .../ResultDetailViewController.swift | 1 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 5d65371..a6972f9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -168,21 +168,24 @@ class ResultDetailSmallerInfoView: UIView { self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) ]) - self.displayArrowImage() + self.layoutIfNeeded() + self.displayUpDownMark() } - private func displayArrowImage() { - let arrow = UIImage(systemName: "chevron.compact.up") - let imageView = UIImageView(image: arrow) - imageView.tintColor = .black - self.addSubview(imageView) - imageView.translatesAutoresizingMaskIntoConstraints = false + private func displayUpDownMark() { + let upDownView = UIView() + upDownView.backgroundColor = .label + upDownView.translatesAutoresizingMaskIntoConstraints = false + upDownView.layer.cornerRadius = 2 + upDownView.layer.masksToBounds = true - let arrowConstraints = [ - imageView.topAnchor.constraint(equalTo: self.topAnchor), - imageView.centerXAnchor.constraint(equalTo: self.centerXAnchor), - imageView.heightAnchor.constraint(equalToConstant: 20) + self.addSubview(upDownView) + let upDownConstraints = [ + upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), + upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + upDownView.heightAnchor.constraint(equalToConstant: 4), + upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/2) ] - NSLayoutConstraint.activate(arrowConstraints) + NSLayoutConstraint.activate(upDownConstraints) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index f71831f..3368370 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -69,7 +69,6 @@ class ResultDetailViewController: UIViewController { minAltitude: viewModel.altitudeViewModel.lowest, averageSpeed: viewModel.averageSpeed() ) - self?.informationView.layoutIfNeeded() self?.configureViews() self?.configurePanGesture() } From b81f344b6228153909c594dfed72eb5769ccd229 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 20:06:09 +0900 Subject: [PATCH 309/465] =?UTF-8?q?[Feat]=20#149=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 3368370..59d1d09 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -192,26 +192,6 @@ class ResultDetailViewController: UIViewController { } extension ResultDetailViewController { - @objc private func showLargeInfoView() { - self.informationView.subviews.forEach { $0.removeFromSuperview() } - let newY = self.view.bounds.height * 0.1 - let newHeight = self.view.bounds.height * 0.9 - self.mapView.isUserInteractionEnabled = false - UIView.animate(withDuration: 0.25) { - self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) - } - } - - @objc private func showSmallInfoView() { - self.informationView.subviews.forEach { $0.removeFromSuperview() } - let newY = self.view.bounds.height * 0.75 - let newHeight = self.view.bounds.height * 0.25 - self.mapView.isUserInteractionEnabled = true - UIView.animate(withDuration: 0.25) { - self.informationView.frame = CGRect(x: 0, y: newY, width: self.view.bounds.width, height: newHeight) - } - } - @objc func dismissViewController() { coordinator?.dismiss() } From dcba3ef22064d10cbd39b51f1728ab8b3b0b4e90 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 20:25:52 +0900 Subject: [PATCH 310/465] [Feat] #149 InfoView cornerRadius --- SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift | 1 + SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 2 ++ 2 files changed, 3 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index a6972f9..44a28a0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -162,6 +162,7 @@ class ResultDetailSmallerInfoView: UIView { self.maxAltitude.text = maxAltitude self.minAltitude.text = minAltitude self.averageSpeed.text = averageSpeed + self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] self.addSubview(self.compositionalStackView) NSLayoutConstraint.activate([ self.compositionalStackView.leftAnchor.constraint(equalTo: self.leftAnchor), diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 59d1d09..be01c8a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -172,11 +172,13 @@ class ResultDetailViewController: UIViewController { case .ended: if self.informationView.frame.minY <= self.view.frame.height/2 { changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) + self.informationView.layer.cornerRadius = 10 isLargeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 1 }) + self.informationView.layer.cornerRadius = 0 isLargeInfoView = false changeInfoViewTopConstraints(traslation: 0) } From c85f7ecb0024327f9ab29e5cd2898a42f0f907c5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 20:26:52 +0900 Subject: [PATCH 311/465] =?UTF-8?q?[Feat]=20#149=20InfoView=20CornerRadius?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index be01c8a..5f94870 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -166,13 +166,12 @@ class ResultDetailViewController: UIViewController { infoViewHight < (informationViewHeight - (translation.y + offset)) else { return } - + self.informationView.layer.cornerRadius = 10 changeInfoViewTopConstraints(traslation: translation.y + offset) case .ended: if self.informationView.frame.minY <= self.view.frame.height/2 { changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) - self.informationView.layer.cornerRadius = 10 isLargeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { From 97d58aac2c87becc9c3e6228cc4b00f789d6dad5 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 20:46:36 +0900 Subject: [PATCH 312/465] [Feat] #128 secondPerHighestSpeed, secondPerMinimumSpeed, archiveAssetIdentifiers unarchivedObject --- .../SanTa.xcdatamodeld/SanTa.xcdatamodel/contents | 1 - SanTa/SanTa/ResultScene/ResultUseCase.swift | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 3275a97..dbec890 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -15,7 +15,6 @@ - diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index b264a46..0239f2d 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -40,14 +40,19 @@ final class ResultUseCase { } private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { - guard let title = recordsEntityMO.title else { return nil } + guard let title = recordsEntityMO.title, + let archiveAssetIdentifiers = recordsEntityMO.assetIdentifiers, + let assetIdentifiers = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self], from: archiveAssetIdentifiers) as? [String] else { return nil } + let secondPerHighestSpeed = Int(recordsEntityMO.secondPerHighestSpeed) + let secondPerMinimumSpeed = Int(recordsEntityMO.secondPerMinimumSpeed) + var records: [Record] = [] recordsEntityMO.records?.forEach { guard let recordEntityMO = $0 as? RecordEntityMO else { return } guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } records.append(record) } - return Records(title: title, records: records, assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int()) + return Records(title: title, records: records, assetIdentifiers: assetIdentifiers, secondPerHighestSpeed: secondPerHighestSpeed, secondPerMinimumSpeed: secondPerMinimumSpeed) } private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { From 5eef45ff8c6308d49723121bc364be72c6597430 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:09:04 +0900 Subject: [PATCH 313/465] =?UTF-8?q?[Feat]=20#260=20ResultDetailLargerInfoV?= =?UTF-8?q?iew=20displayUpDownMark=20func=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 16cc2ca..bf38935 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -22,14 +22,21 @@ class ResultDetailLargerInfoView: UIView { } extension ResultDetailLargerInfoView { - private func configureDownArrow() { - let downArrow:UIImageView = .init(image: UIImage(systemName: "chevron.compact.down")?.withTintColor(.black)) - downArrow.translatesAutoresizingMaskIntoConstraints = false - let downArrowConstraints = [ - downArrow.topAnchor.constraint(equalTo: self.topAnchor), - downArrow.centerXAnchor.constraint(equalTo: self.centerXAnchor), + private func displayUpDownMark() { + let upDownView = UIView() + upDownView.backgroundColor = .label + upDownView.translatesAutoresizingMaskIntoConstraints = false + upDownView.layer.cornerRadius = 2 + upDownView.layer.masksToBounds = true + + self.addSubview(upDownView) + let upDownConstraints = [ + upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), + upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + upDownView.heightAnchor.constraint(equalToConstant: 4), + upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/2) ] - NSLayoutConstraint.activate(downArrowConstraints) + NSLayoutConstraint.activate(upDownConstraints) } private func configure(collectionView: UICollectionView) { From f811f581ea5b67c34eb84bc8ea001e38d3410dbf Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 22 Nov 2021 21:17:17 +0900 Subject: [PATCH 314/465] =?UTF-8?q?[Feat]=20#261=20=EC=B8=A1=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=93=B1=EC=82=B0=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=B3=B4=EC=9D=B4=EC=8A=A4=EC=98=A4=EB=B2=84=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 2 ++ .../RecordingViewController.swift | 20 +++++++++++++++++++ .../RecordingScene/RecordingViewModel.swift | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index e2bd8c5..3cce7e0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -13,6 +13,7 @@ import Combine final class RecordingModel: NSObject, ObservableObject { @Published private(set) var time = "" + @Published private(set) var accessibilityTime = "" @Published private(set) var kilometer = "0.00" @Published private(set) var altitude = "0" @Published private(set) var walk = "0" @@ -93,6 +94,7 @@ final class RecordingModel: NSObject, ObservableObject { let hours = (elapsedTimeSeconds / 3600) self.time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) + self.accessibilityTime = String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds) } private func checkPedoMeter() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index b78e1c3..894eadd 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -29,6 +29,7 @@ class RecordingViewController: UIViewController { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) label.text = "킬로미터" + label.isAccessibilityElement = false return label }() @@ -57,6 +58,7 @@ class RecordingViewController: UIViewController { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) label.text = "시간" + label.isAccessibilityElement = false return label }() @@ -64,6 +66,7 @@ class RecordingViewController: UIViewController { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) label.text = "고도" + label.isAccessibilityElement = false return label }() @@ -71,6 +74,7 @@ class RecordingViewController: UIViewController { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) label.text = "걸음" + label.isAccessibilityElement = false return label }() @@ -100,6 +104,7 @@ class RecordingViewController: UIViewController { self.configureButton() self.configureBindings() self.configureTarget() + setAccessibility() } override func viewDidAppear(_ animated: Bool) { @@ -117,10 +122,18 @@ class RecordingViewController: UIViewController { }) .store(in: &self.subscriptions) + self.recordingViewModel?.$accessibilityCurrentTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] time in + self?.timeLabel.accessibilityLabel = "현재시간 \(time)" + }) + .store(in: &self.subscriptions) + self.recordingViewModel?.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer + self?.kilometerLabel.accessibilityLabel = "현재 \(kilometer) 킬로미터" }) .store(in: &self.subscriptions) @@ -128,6 +141,7 @@ class RecordingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] altitude in self?.altitudeLabel.text = altitude + self?.altitudeLabel.accessibilityLabel = "현재 고도 \(altitude)" }) .store(in: &self.subscriptions) @@ -135,6 +149,7 @@ class RecordingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] walk in self?.walkLabel.text = walk + self?.walkLabel.accessibilityLabel = "현재 \(walk) 걸음" }) .store(in: &self.subscriptions) @@ -229,6 +244,11 @@ class RecordingViewController: UIViewController { deinit { print("😇RecordingViewController is deinit \(Date())!!😇") } + + func setAccessibility() { + + } + } extension RecordingViewController: RecordingViewDelegate { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 12e9be6..77e08d0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -20,6 +20,7 @@ protocol RecordingUseCase { final class RecordingViewModel: ObservableObject { @Published private(set) var currentTime = "" + @Published private(set) var accessibilityCurrentTime = "" @Published private(set) var kilometer = "" @Published private(set) var altitude = "" @Published private(set) var walk = "" @@ -41,6 +42,13 @@ final class RecordingViewModel: ObservableObject { }) .store(in: &self.subscriptions) + self.recordingUseCase?.recording?.$accessibilityTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] time in + self?.accessibilityCurrentTime = time + }) + .store(in: &self.subscriptions) + self.recordingUseCase?.recording?.$kilometer .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in From e33e38af6a6c94ed8032b6f6c51a6361e07d21f0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:17:37 +0900 Subject: [PATCH 315/465] [Feat] #260 LargerInfoView CollectionView Init --- .../ResultDetailScene/ResultDetailLargerInfoView.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index bf38935..6e97808 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -8,10 +8,15 @@ import UIKit class ResultDetailLargerInfoView: UIView { - private var collectionView: UICollectionView + private lazy var collectionView: UICollectionView = { + let flowLayout = UICollectionViewFlowLayout() + let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + + return collectionView + } override init(frame: CGRect) { - self.collectionView = UICollectionView(frame: frame) super.init(frame: frame) self.backgroundColor = .green } From bab281aba25ff00757d304073b4c3d1f346c555c Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:27:15 +0900 Subject: [PATCH 316/465] =?UTF-8?q?[Feat]=20#260=20LargerInfo=20Collection?= =?UTF-8?q?View=20typealias=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 6e97808..a413757 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -8,13 +8,20 @@ import UIKit class ResultDetailLargerInfoView: UIView { + enum DetailLargerInfoSection: Int, CaseIterable { + case main + } + + typealias DetailLargerInfoDataSource = UICollectionViewDiffableDataSource + typealias DetailLargerInfoSnapshot = NSDiffableDataSourceSnapshot + private lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView - } + }() override init(frame: CGRect) { super.init(frame: frame) @@ -46,9 +53,6 @@ extension ResultDetailLargerInfoView { private func configure(collectionView: UICollectionView) { self.addSubview(collectionView) - collectionView.delegate = self - collectionView.dataSource = self - collectionView.collectionViewLayout = UICollectionViewFlowLayout() collectionView.translatesAutoresizingMaskIntoConstraints = false let constraints = [ @@ -60,13 +64,3 @@ extension ResultDetailLargerInfoView { NSLayoutConstraint.activate(constraints) } } - -extension ResultDetailLargerInfoView: UICollectionViewDelegate, UICollectionViewDataSource { - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - section == 0 ? 3 : 2 - } - - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - return UICollectionViewCell() - } -} From 2abfdb46ae1335363a904a5162326038596e26fb Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:35:09 +0900 Subject: [PATCH 317/465] =?UTF-8?q?[Feat]=20#260=20LargerInfo=20Collection?= =?UTF-8?q?View=20CompositionalLayout=20func=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/DetailCell.swift | 2 ++ .../ResultDetailLargerInfoView.swift | 20 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index a9d498f..3216695 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -8,6 +8,8 @@ import UIKit class DetailCell: UICollectionViewCell { + static let identifier = "DetailCell" + private let title: UILabel = UILabel() func layout(data: ResultDetailCellRepresentable) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index a413757..490c3f6 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -51,7 +51,7 @@ extension ResultDetailLargerInfoView { NSLayoutConstraint.activate(upDownConstraints) } - private func configure(collectionView: UICollectionView) { + private func configureViews(collectionView: UICollectionView) { self.addSubview(collectionView) collectionView.translatesAutoresizingMaskIntoConstraints = false @@ -63,4 +63,22 @@ extension ResultDetailLargerInfoView { ] NSLayoutConstraint.activate(constraints) } + + private func configureCollectionView() { + self.collectionView.collectionViewLayout = configureCompositionalLayout() + self.collectionView.register(DetailCell.self, forCellWithReuseIdentifier: DetailCell.identifier) + } + + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { + return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(500))) + item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) + let section = NSCollectionLayoutSection(group: group) + section.orthogonalScrollingBehavior = .none + section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + + return section + } + } } From 3175702b9b2bd0b20eb20934bfed52a745970d8a Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:42:09 +0900 Subject: [PATCH 318/465] =?UTF-8?q?[Feat]=20#260=20LargerInfoView=20Label?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 490c3f6..1dbfcba 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -22,6 +22,52 @@ class ResultDetailLargerInfoView: UIView { return collectionView }() + + private lazy var dateLabel: UILabel = { + let label = UILabel() + label.backgroundColor = .label + label.textColor = .systemBackground + label.text = "2021. 11. 16(화)" + label.font = .preferredFont(forTextStyle: .caption1) + label.adjustsFontForContentSizeCategory = true + return label + }() + + private lazy var startLabel: UILabel = { + let label = UILabel() + label.textColor = UIColor(named: "SanTaColor") + label.text = "시작" + label.font = .preferredFont(forTextStyle: .title2) + label.adjustsFontForContentSizeCategory = true + return label + }() + + private lazy var endLabel: UILabel = { + let label = UILabel() + label.textColor = UIColor(named: "SanTaColor") + label.text = "종료" + label.font = .preferredFont(forTextStyle: .title2) + label.adjustsFontForContentSizeCategory = true + return label + }() + + private lazy var startTime: UILabel = { + let label = UILabel() + label.textColor = .label + label.text = "오후 6시 0분" + label.font = .preferredFont(forTextStyle: .title1) + label.adjustsFontForContentSizeCategory = true + return label + }() + + private lazy var endTime: UILabel = { + let label = UILabel() + label.textColor = .label + label.text = "오후 7시 38분" + label.font = .preferredFont(forTextStyle: .title1) + label.adjustsFontForContentSizeCategory = true + return label + }() override init(frame: CGRect) { super.init(frame: frame) From 99c502f77013a4ce8026a9762f816745f1469771 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 22 Nov 2021 21:46:07 +0900 Subject: [PATCH 319/465] =?UTF-8?q?[Feat]=20#259=20=EC=8B=9C=EC=9E=91?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=8B=9C=EC=9E=91=EB=B2=84=ED=8A=BC=20hin?= =?UTF-8?q?t=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 9c1eb1c..0efab61 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -219,10 +219,12 @@ extension MapViewController: Animatable { func shouldAnimate() { let image = UIImage.gifImage(named: "walkingManAnimation", withTintColor: .white) self.startButton.setImage(image, for: .normal) + self.startButton.accessibilityHint = "현재 측정 중입니다. 측정화면으로 돌아가려면 이중탭 하십시오" } func shouldStopAnimate() { self.startButton.setImage(nil, for: .normal) + self.startButton.accessibilityHint = "측정을 시작하려면 이중탭 하십시오" } } From 997c6ad8695ff3194407dd35c5142762a2ccf381 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 21:57:14 +0900 Subject: [PATCH 320/465] =?UTF-8?q?[Feat]=20#260=20LargerInfoView=20StackV?= =?UTF-8?q?iew=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 67 ++++++++++++++++--- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 1dbfcba..5cc87df 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -30,6 +30,7 @@ class ResultDetailLargerInfoView: UIView { label.text = "2021. 11. 16(화)" label.font = .preferredFont(forTextStyle: .caption1) label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -39,6 +40,7 @@ class ResultDetailLargerInfoView: UIView { label.text = "시작" label.font = .preferredFont(forTextStyle: .title2) label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -48,6 +50,7 @@ class ResultDetailLargerInfoView: UIView { label.text = "종료" label.font = .preferredFont(forTextStyle: .title2) label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -57,6 +60,7 @@ class ResultDetailLargerInfoView: UIView { label.text = "오후 6시 0분" label.font = .preferredFont(forTextStyle: .title1) label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -66,8 +70,27 @@ class ResultDetailLargerInfoView: UIView { label.text = "오후 7시 38분" label.font = .preferredFont(forTextStyle: .title1) label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false return label }() + + private lazy var labelStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 20 + stackView.alignment = .center + stackView.axis = .horizontal + stackView.distribution = .fill + return stackView + }() + + private lazy var timeStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 20 + stackView.alignment = .center + stackView.axis = .horizontal + stackView.distribution = .fill + return stackView + }() override init(frame: CGRect) { super.init(frame: frame) @@ -98,16 +121,40 @@ extension ResultDetailLargerInfoView { } private func configureViews(collectionView: UICollectionView) { - self.addSubview(collectionView) + configureStackView() + self.addSubview(self.dateLabel) + self.addSubview(self.startLabel) + self.addSubview(self.endLabel) + self.addSubview(self.startTime) + self.addSubview(self.endTime) + self.addSubview(self.collectionView) - collectionView.translatesAutoresizingMaskIntoConstraints = false - let constraints = [ - collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), - collectionView.leftAnchor.constraint(equalTo: self.leftAnchor), - collectionView.rightAnchor.constraint(equalTo: self.rightAnchor), - collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) - ] - NSLayoutConstraint.activate(constraints) + NSLayoutConstraint.activate([ + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + + NSLayoutConstraint.activate([ + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + + NSLayoutConstraint.activate([ + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + + NSLayoutConstraint.activate([ + self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), + self.collectionView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.collectionView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) + } + + private func configureStackView() { + [self.startLabel, self.endLabel].forEach { self.labelStackView.addArrangedSubview($0) } + [self.startTime, self.endTime].forEach { self.timeStackView.addArrangedSubview($0) } } private func configureCollectionView() { @@ -120,7 +167,7 @@ extension ResultDetailLargerInfoView { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) - let section = NSCollectionLayoutSection(group: group) + let section = NSCogllectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) From af975b9c2c5bdd7c903dbba6dca52a423a7a5bc1 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 22 Nov 2021 22:06:31 +0900 Subject: [PATCH 321/465] =?UTF-8?q?[Feat]=20#261=20=EC=B8=A1=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=B2=84=ED=8A=BC=20VoiceOver=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController+Extension.swift | 9 +++++++++ .../RecordingScene/RecordingViewController.swift | 11 +++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index 7f6f785..3cb198e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -133,4 +133,13 @@ extension RecordingViewController { self.view.layoutIfNeeded() } + + func configureAccessibilty() { + self.pauseButton.accessibilityLabel = "일시정지" + self.pauseButton.accessibilityHint = "측정을 일시정지 하시려면 이중탭하십시오" + self.stopButton.accessibilityLabel = "종료" + self.stopButton.accessibilityHint = "측정을 종료 하시려면 이중탭하십시오" + self.locationButton.accessibilityLabel = "현재위치" + self.locationButton.accessibilityHint = "시작화면에서 현재위치를 보시려면 이중탭하십시오" + } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 894eadd..960c619 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -104,7 +104,7 @@ class RecordingViewController: UIViewController { self.configureButton() self.configureBindings() self.configureTarget() - setAccessibility() + self.configureAccessibilty() } override func viewDidAppear(_ animated: Bool) { @@ -195,6 +195,8 @@ class RecordingViewController: UIViewController { pauseConfiguration.image = UIImage(systemName: "play.fill") pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) self.pauseButton.configuration = pauseConfiguration + self.pauseButton.accessibilityLabel = "재시작" + self.pauseButton.accessibilityHint = "측정을 재시작 하시려면 이중탭하십시오" self.recordingViewModel?.pause() self.currentState = false } else { @@ -203,6 +205,8 @@ class RecordingViewController: UIViewController { pauseConfiguration.image = UIImage(systemName: "pause.fill") pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) self.pauseButton.configuration = pauseConfiguration + self.pauseButton.accessibilityLabel = "일시정지" + self.pauseButton.accessibilityHint = "측정을 일시정지 하시려면 이중탭하십시오" self.recordingViewModel?.resume() self.currentState = true } @@ -244,11 +248,6 @@ class RecordingViewController: UIViewController { deinit { print("😇RecordingViewController is deinit \(Date())!!😇") } - - func setAccessibility() { - - } - } extension RecordingViewController: RecordingViewDelegate { From 5c426ef14876670ff32c724536b1f5e301b4d56e Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 22:16:13 +0900 Subject: [PATCH 322/465] =?UTF-8?q?[Feat]=20#260=20LargerInfoView=20StackV?= =?UTF-8?q?iew=20=EC=A0=9C=EC=96=B4=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 5cc87df..74f7d07 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -123,10 +123,8 @@ extension ResultDetailLargerInfoView { private func configureViews(collectionView: UICollectionView) { configureStackView() self.addSubview(self.dateLabel) - self.addSubview(self.startLabel) - self.addSubview(self.endLabel) - self.addSubview(self.startTime) - self.addSubview(self.endTime) + self.addSubview(self.labelStackView) + self.addSubview(self.timeStackView) self.addSubview(self.collectionView) NSLayoutConstraint.activate([ @@ -135,17 +133,17 @@ extension ResultDetailLargerInfoView { ]) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), - self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), + self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), - self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), + self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ - self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), + self.collectionView.topAnchor.constraint(equalTo: self.timeStackView.bottomAnchor, constant: 50), self.collectionView.leftAnchor.constraint(equalTo: self.leftAnchor), self.collectionView.rightAnchor.constraint(equalTo: self.rightAnchor), self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) @@ -167,7 +165,7 @@ extension ResultDetailLargerInfoView { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) - let section = NSCogllectionLayoutSection(group: group) + let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) From 0a89ae63a3788a9f867ed9cc459436ea8caf753d Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 22:17:08 +0900 Subject: [PATCH 323/465] =?UTF-8?q?[Feat]=20#260=20largerInformationView?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 5f94870..0919c1a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -26,12 +26,18 @@ class ResultDetailViewController: UIViewController { return mapView }() - private var informationView: ResultDetailSmallerInfoView = { + private var smallerInformationView: ResultDetailSmallerInfoView = { let view = ResultDetailSmallerInfoView() view.translatesAutoresizingMaskIntoConstraints = false return view }() + private var largerInformationView: ResultDetailLargerInfoView = { + let view = ResultDetailLargerInfoView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + private var backButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "chevron.backward"), for: .normal) @@ -61,7 +67,7 @@ class ResultDetailViewController: UIViewController { super.viewDidLoad() self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } - self?.informationView.configureLayout( + self?.smallerInformationView.configureLayout( distance: viewModel.distanceViewModel.totalDistance, time: viewModel.timeViewModel.totalTimeSpent, steps: viewModel.distanceViewModel.steps, @@ -76,7 +82,7 @@ class ResultDetailViewController: UIViewController { } private func configureSmallerView() { - self.informationView = ResultDetailSmallerInfoView(frame: self.informationView.bounds) + self.smallerInformationView = ResultDetailSmallerInfoView(frame: self.smallerInformationView.bounds) } private func configurePanGesture() { @@ -92,13 +98,13 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.mapView) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) - self.view.addSubview(self.informationView) + self.view.addSubview(self.smallerInformationView) NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -(self.informationView.compositionalStackView.frame.height + tabBar.frame.height)) + self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -(self.smallerInformationView.compositionalStackView.frame.height + tabBar.frame.height)) ]) NSLayoutConstraint.activate([ @@ -116,23 +122,23 @@ class ResultDetailViewController: UIViewController { ]) NSLayoutConstraint.activate([ - self.informationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.informationView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.informationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) + self.smallerInformationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.smallerInformationView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.smallerInformationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) infoViewTopConstraint = - self.informationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) + self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewTopConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) self.view.layoutIfNeeded() - self.infoViewHight = self.informationView.frame.height + self.infoViewHight = self.smallerInformationView.frame.height } private func findInfoViewBottomConstraints(traslation: CGFloat) { var bottomConstraint: NSLayoutConstraint? - self.informationView.constraints.forEach { + self.smallerInformationView.constraints.forEach { if $0.firstAttribute == .bottom { bottomConstraint = $0 } @@ -146,8 +152,8 @@ class ResultDetailViewController: UIViewController { } @objc private func informationViewPanPanned(_ panGestureRecognizer: UIPanGestureRecognizer) { - let translation = panGestureRecognizer.translation(in: self.informationView) - let informationViewHeight = self.informationView.frame.height + let translation = panGestureRecognizer.translation(in: self.smallerInformationView) + let informationViewHeight = self.smallerInformationView.frame.height switch panGestureRecognizer.state { case .began: @@ -166,18 +172,18 @@ class ResultDetailViewController: UIViewController { infoViewHight < (informationViewHeight - (translation.y + offset)) else { return } - self.informationView.layer.cornerRadius = 10 + self.smallerInformationView.layer.cornerRadius = 10 changeInfoViewTopConstraints(traslation: translation.y + offset) case .ended: - if self.informationView.frame.minY <= self.view.frame.height/2 { + if self.smallerInformationView.frame.minY <= self.view.frame.height/2 { changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) isLargeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 1 }) - self.informationView.layer.cornerRadius = 0 + self.smallerInformationView.layer.cornerRadius = 0 isLargeInfoView = false changeInfoViewTopConstraints(traslation: 0) } From dba446b00476d8dcb532729a34e58dfa4c6ddff3 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 22 Nov 2021 22:31:24 +0900 Subject: [PATCH 324/465] =?UTF-8?q?[Feat]=20=EC=A0=9C=EB=AA=A9=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9D=B4=EB=8F=99=20=EA=B2=BD=EB=A1=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 11 ++++++ .../ResultDetailScene/ResultDetailModel.swift | 6 ++-- .../ResultDetailViewController.swift | 34 +++++++++++++++++-- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 927b157..bff49b3 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -6,6 +6,7 @@ // import Foundation +import CoreLocation class TotalRecords { private(set) var totalRecords: [DateSeperateRecords] = [] @@ -141,6 +142,12 @@ struct Records { return max - min } + var coordinates: [[CLLocationCoordinate2D]] { + var coordinates: [[Location]] = [] + self.records.forEach{coordinates.append($0.locations)} + return coordinates.map{$0.map{$0.inCoordinates()}} + } + mutating func configureTitle(title: String) { self.title = title } @@ -178,4 +185,8 @@ struct Location { let latitude: Double let longitude: Double let altitude: Double + + func inCoordinates() -> CLLocationCoordinate2D { + return CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude) + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 7dadec8..fdf5cdf 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -16,6 +16,7 @@ struct ResultDetailData { let altitude: ResultAltitude let incline: ResultIncline let id: String + let coordinates: [[CLLocationCoordinate2D]] private(set) var title: String init(records: Records) { @@ -26,6 +27,7 @@ struct ResultDetailData { self.incline = ResultIncline(records: records) self.id = records.id self.title = records.title + self.coordinates = records.coordinates } mutating func change(title: String) { @@ -128,14 +130,14 @@ struct ResultIncline { let distanceDelta = current.distance(from: next) let altitudeDelta = next.altitude - current.altitude let incline = atan(altitudeDelta / distanceDelta) - totalIncline += incline + totalIncline += incline == .nan || incline == .infinity ? 0 : incline steepest = steepest < incline ? incline : steepest uphillDistance += altitudeDelta > 0 ? abs(distanceDelta) : 0 downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 } - self.average = Int(totalIncline) + self.average = 0 self.highest = Int(steepest) self.uphillKilometer = uphillDistance / 1000 self.downhillKilometer = downHillDistance / 1000 diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 58588b4..700a079 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -18,6 +18,7 @@ class ResultDetailViewController: UIViewController { let mapView = MKMapView() mapView.mapType = .mutedStandard mapView.translatesAutoresizingMaskIntoConstraints = false + return mapView }() @@ -62,6 +63,7 @@ class ResultDetailViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.configureViews() + self.mapView.delegate = self self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } self?.titleLabel.text = viewModel.resultDetailData?.title @@ -75,6 +77,21 @@ class ResultDetailViewController: UIViewController { ) } viewModel?.setUp() + + guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { + return + } + for pointSet in pointSets { + mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) + } + guard let initial = mapView.overlays.first?.boundingMapRect else { return } + + let mapRect = mapView.overlays + .dropFirst() + .reduce(initial) { $0.union($1.boundingMapRect) } + + mapView.setVisibleMapRect(mapRect, animated: true) + print(pointSets.count) } private func configureSmallerView() { @@ -107,7 +124,7 @@ class ResultDetailViewController: UIViewController { ]) NSLayoutConstraint.activate([ self.titleLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), - self.titleLabel.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), + self.titleLabel.centerYAnchor.constraint(equalTo: self.changeButton.centerYAnchor), ]) NSLayoutConstraint.activate([ self.informationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), @@ -192,7 +209,18 @@ extension ResultDetailViewController: SetTitleDelegate { } }) } - - } +extension ResultDetailViewController: MKMapViewDelegate { + func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { + if let polyline = overlay as? MKPolyline { + print("is polyline") + let renderer = MKPolylineRenderer(overlay: polyline) + renderer.lineWidth = 5 + renderer.alpha = 1 + renderer.strokeColor = .init(named: "SantaColor") + return renderer + } + return MKOverlayRenderer() + } +} From 4be0607386e1a949f156f17e5185899c8eedeb10 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 22:48:18 +0900 Subject: [PATCH 325/465] =?UTF-8?q?[Feat]=20#260=20LargerInfoView=20Collec?= =?UTF-8?q?tionView=20Header=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 + .../ResultDetailScene/DetailHeader.swift | 116 ++++++++++++++++++ .../ResultDetailLargerInfoView.swift | 110 ++--------------- .../ResultDetailViewController.swift | 25 +++- 4 files changed, 151 insertions(+), 104 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/DetailHeader.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f983fe0..526553b 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -101,6 +101,7 @@ DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; + DAFF214E274BD6460061A555 /* DetailHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFF214D274BD6460061A555 /* DetailHeader.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -200,6 +201,7 @@ DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoModel.swift; sourceTree = ""; }; + DAFF214D274BD6460061A555 /* DetailHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailHeader.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -269,6 +271,7 @@ 4948038327437499002854B1 /* ResultDetailUseCase.swift */, 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, 493178B32743992400B5FB88 /* DetailCell.swift */, + DAFF214D274BD6460061A555 /* DetailHeader.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -652,6 +655,7 @@ 54296955272FC3EC0070B362 /* SettingsViewController.swift in Sources */, 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */, 5429695B273026B10070B362 /* MountainAnnotationView.swift in Sources */, + DAFF214E274BD6460061A555 /* DetailHeader.swift in Sources */, DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */, DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */, 54B32065274510D8002232BD /* MountainAddingViewController.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift new file mode 100644 index 0000000..fac2b97 --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -0,0 +1,116 @@ +// +// DetailHeader.swift +// SanTa +// +// Created by 김민창 on 2021/11/22. +// + +import UIKit + +class DetailHeader: UICollectionReusableView { + static let identifier = "DetailHeader" + + private lazy var dateLabel: UILabel = { + let label = UILabel() + label.backgroundColor = .label + label.textColor = .systemBackground + label.text = "2021. 11. 16(화)" + label.font = .preferredFont(forTextStyle: .caption1) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var startLabel: UILabel = { + let label = UILabel() + label.textColor = UIColor(named: "SanTaColor") + label.text = "시작" + label.font = .preferredFont(forTextStyle: .title2) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var endLabel: UILabel = { + let label = UILabel() + label.textColor = UIColor(named: "SanTaColor") + label.text = "종료" + label.font = .preferredFont(forTextStyle: .title2) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var startTime: UILabel = { + let label = UILabel() + label.textColor = .label + label.text = "오후 6시 0분" + label.font = .preferredFont(forTextStyle: .title1) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var endTime: UILabel = { + let label = UILabel() + label.textColor = .label + label.text = "오후 7시 38분" + label.font = .preferredFont(forTextStyle: .title1) + label.adjustsFontForContentSizeCategory = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var labelStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 20 + stackView.alignment = .center + stackView.axis = .horizontal + stackView.distribution = .fill + return stackView + }() + + private lazy var timeStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 20 + stackView.alignment = .center + stackView.axis = .horizontal + stackView.distribution = .fill + return stackView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + } + + private func configureViews() { + self.addSubview(self.dateLabel) + self.addSubview(self.labelStackView) + self.addSubview(self.timeStackView) + + NSLayoutConstraint.activate([ + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + + NSLayoutConstraint.activate([ + self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), + self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + + NSLayoutConstraint.activate([ + self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), + self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + ]) + } + + private func configureStackView() { + [self.startLabel, self.endLabel].forEach { self.labelStackView.addArrangedSubview($0) } + [self.startTime, self.endTime].forEach { self.timeStackView.addArrangedSubview($0) } + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 74f7d07..a1103d5 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -22,79 +22,9 @@ class ResultDetailLargerInfoView: UIView { return collectionView }() - - private lazy var dateLabel: UILabel = { - let label = UILabel() - label.backgroundColor = .label - label.textColor = .systemBackground - label.text = "2021. 11. 16(화)" - label.font = .preferredFont(forTextStyle: .caption1) - label.adjustsFontForContentSizeCategory = true - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - private lazy var startLabel: UILabel = { - let label = UILabel() - label.textColor = UIColor(named: "SanTaColor") - label.text = "시작" - label.font = .preferredFont(forTextStyle: .title2) - label.adjustsFontForContentSizeCategory = true - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - private lazy var endLabel: UILabel = { - let label = UILabel() - label.textColor = UIColor(named: "SanTaColor") - label.text = "종료" - label.font = .preferredFont(forTextStyle: .title2) - label.adjustsFontForContentSizeCategory = true - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - private lazy var startTime: UILabel = { - let label = UILabel() - label.textColor = .label - label.text = "오후 6시 0분" - label.font = .preferredFont(forTextStyle: .title1) - label.adjustsFontForContentSizeCategory = true - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - private lazy var endTime: UILabel = { - let label = UILabel() - label.textColor = .label - label.text = "오후 7시 38분" - label.font = .preferredFont(forTextStyle: .title1) - label.adjustsFontForContentSizeCategory = true - label.translatesAutoresizingMaskIntoConstraints = false - return label - }() - - private lazy var labelStackView: UIStackView = { - let stackView = UIStackView() - stackView.spacing = 20 - stackView.alignment = .center - stackView.axis = .horizontal - stackView.distribution = .fill - return stackView - }() - - private lazy var timeStackView: UIStackView = { - let stackView = UIStackView() - stackView.spacing = 20 - stackView.alignment = .center - stackView.axis = .horizontal - stackView.distribution = .fill - return stackView - }() override init(frame: CGRect) { super.init(frame: frame) - self.backgroundColor = .green } required init?(coder: NSCoder) { @@ -120,39 +50,23 @@ extension ResultDetailLargerInfoView { NSLayoutConstraint.activate(upDownConstraints) } - private func configureViews(collectionView: UICollectionView) { - configureStackView() - self.addSubview(self.dateLabel) - self.addSubview(self.labelStackView) - self.addSubview(self.timeStackView) + func configure() { + self.configureCollectionView() + self.configureViews() + self.displayUpDownMark() + } + + private func configureViews() { + self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] self.addSubview(self.collectionView) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), - self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), - ]) - - NSLayoutConstraint.activate([ - self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), - self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), - ]) - - NSLayoutConstraint.activate([ - self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), - self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), - ]) - - NSLayoutConstraint.activate([ - self.collectionView.topAnchor.constraint(equalTo: self.timeStackView.bottomAnchor, constant: 50), - self.collectionView.leftAnchor.constraint(equalTo: self.leftAnchor), - self.collectionView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.collectionView.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 5), + self.collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + self.collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) - } - - private func configureStackView() { - [self.startLabel, self.endLabel].forEach { self.labelStackView.addArrangedSubview($0) } - [self.startTime, self.endTime].forEach { self.timeStackView.addArrangedSubview($0) } + self.layoutIfNeeded() } private func configureCollectionView() { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 0919c1a..b750416 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -75,6 +75,7 @@ class ResultDetailViewController: UIViewController { minAltitude: viewModel.altitudeViewModel.lowest, averageSpeed: viewModel.averageSpeed() ) + self?.largerInformationView.configure() self?.configureViews() self?.configurePanGesture() } @@ -98,6 +99,7 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.mapView) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) + self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) NSLayoutConstraint.activate([ @@ -127,6 +129,13 @@ class ResultDetailViewController: UIViewController { self.smallerInformationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) + NSLayoutConstraint.activate([ + self.largerInformationView.topAnchor.constraint(equalTo: self.smallerInformationView.topAnchor), + self.largerInformationView.leadingAnchor.constraint(equalTo: self.smallerInformationView.leadingAnchor), + self.largerInformationView.trailingAnchor.constraint(equalTo: self.smallerInformationView.trailingAnchor), + self.largerInformationView.bottomAnchor.constraint(equalTo: self.smallerInformationView.bottomAnchor) + ]) + infoViewTopConstraint = self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewTopConstraint else { return } @@ -172,20 +181,24 @@ class ResultDetailViewController: UIViewController { infoViewHight < (informationViewHeight - (translation.y + offset)) else { return } - self.smallerInformationView.layer.cornerRadius = 10 - changeInfoViewTopConstraints(traslation: translation.y + offset) + self.smallerInformationView.layer.cornerRadius = 13 + self.largerInformationView.layer.cornerRadius = 13 + self.changeInfoViewTopConstraints(traslation: translation.y + offset) case .ended: if self.smallerInformationView.frame.minY <= self.view.frame.height/2 { - changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) - isLargeInfoView = true + self.smallerInformationView.alpha = 0 + self.changeInfoViewTopConstraints(traslation: self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY) + self.isLargeInfoView = true } else { UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 1 }) self.smallerInformationView.layer.cornerRadius = 0 - isLargeInfoView = false - changeInfoViewTopConstraints(traslation: 0) + self.largerInformationView.layer.cornerRadius = 0 + self.isLargeInfoView = false + self.smallerInformationView.alpha = 1 + self.changeInfoViewTopConstraints(traslation: 0) } UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { From 20581bd0eb803c63ad9b8afc0722377848689138 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 22 Nov 2021 22:55:52 +0900 Subject: [PATCH 326/465] =?UTF-8?q?[Feat]=20=EA=B2=BD=EB=A1=9C=EC=97=90=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91/=EC=A2=85=EB=A3=8C=20=EB=A7=88=EC=BB=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 700a079..b087901 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -92,6 +92,17 @@ class ResultDetailViewController: UIViewController { mapView.setVisibleMapRect(mapRect, animated: true) print(pointSets.count) + let startAnnotation = MKPointAnnotation() + let endAnnotation = MKPointAnnotation() + guard let startPoint = pointSets.first?.first, + let endPoint = pointSets.last?.last else { + return + } + startAnnotation.coordinate = startPoint + startAnnotation.title = "start" + endAnnotation.coordinate = endPoint + endAnnotation.title = "end" + self.mapView.addAnnotations([startAnnotation, endAnnotation]) } private func configureSmallerView() { @@ -223,4 +234,20 @@ extension ResultDetailViewController: MKMapViewDelegate { } return MKOverlayRenderer() } + + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + guard annotation is MKPointAnnotation else { + return nil + } + + let identifier = "PointAnnotation" + let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier) + if annotation.title == "start" { + annotationView.markerTintColor = .init(named: "SantaColor") + } else { + annotationView.markerTintColor = .red + } + annotationView.animatesWhenAdded = true + return annotationView + } } From faf4e18d006c8ce5ac16b5f9e70a199f10efcf21 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 23:28:47 +0900 Subject: [PATCH 327/465] [Feat] #260 Configure DataSource, Snapshot --- .../ResultDetailScene/DetailHeader.swift | 2 + .../ResultDetailLargerInfoView.swift | 56 ++++++++++++++++++- .../ResultDetailViewController.swift | 1 + 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index fac2b97..4f9e5f3 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -81,6 +81,8 @@ class DetailHeader: UICollectionReusableView { override init(frame: CGRect) { super.init(frame: frame) + self.configureStackView() + self.configureViews() } required init?(coder aDecoder: NSCoder) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index a1103d5..4850228 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -12,10 +12,12 @@ class ResultDetailLargerInfoView: UIView { case main } - typealias DetailLargerInfoDataSource = UICollectionViewDiffableDataSource - typealias DetailLargerInfoSnapshot = NSDiffableDataSourceSnapshot + typealias DetailLargerInfoDataSource = UICollectionViewDiffableDataSource + typealias DetailLargerInfoSnapshot = NSDiffableDataSourceSnapshot - private lazy var collectionView: UICollectionView = { + private var dataSource: DetailLargerInfoDataSource? + + lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) collectionView.translatesAutoresizingMaskIntoConstraints = false @@ -53,11 +55,23 @@ extension ResultDetailLargerInfoView { func configure() { self.configureCollectionView() self.configureViews() + self.configuareDataSource() self.displayUpDownMark() + self.bindSnapShotApply(section: .main, item: ["test"]) + } + + private func bindSnapShotApply(section: DetailLargerInfoSection, item: [AnyHashable]) { + var snapshot = DetailLargerInfoSnapshot() + snapshot.appendSections([.main]) + item.forEach { + snapshot.appendItems([$0], toSection: section) + } + self.dataSource?.apply(snapshot, animatingDifferences: true) } private func configureViews() { self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + self.backgroundColor = .systemBackground self.addSubview(self.collectionView) NSLayoutConstraint.activate([ @@ -69,9 +83,26 @@ extension ResultDetailLargerInfoView { self.layoutIfNeeded() } + private func configuareDataSource() { + let datasource = DetailLargerInfoDataSource (collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell else { + return UICollectionViewCell() } + + return cell + }) + + self.dataSource = datasource + self.collectionView.dataSource = dataSource + } + private func configureCollectionView() { + self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailCell.self, forCellWithReuseIdentifier: DetailCell.identifier) + self.collectionView.register(DetailHeader.self, + forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, + withReuseIdentifier: DetailHeader.identifier) } private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { @@ -83,7 +114,26 @@ extension ResultDetailLargerInfoView { section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + let headerSize = NSCollectionLayoutSize( + widthDimension: .fractionalWidth(1.0), + heightDimension: .estimated(500)) + let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem( + layoutSize: headerSize, + elementKind: UICollectionView.elementKindSectionHeader, + alignment: .top) + + section.boundarySupplementaryItems = [sectionHeader] return section } } } + +extension ResultDetailLargerInfoView: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { + guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: DetailHeader.identifier, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { + return DetailHeader() + } + + return header + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index b750416..46564d2 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -203,6 +203,7 @@ class ResultDetailViewController: UIViewController { UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { self.view.layoutIfNeeded() + self.largerInformationView.collectionView.setNeedsLayout() }, completion: nil) default: From 5672bfde755d5a580fe98302d3ef758d717be46e Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 22 Nov 2021 23:40:08 +0900 Subject: [PATCH 328/465] =?UTF-8?q?[Feat]=20#260=20Display=20Up=20Down=20M?= =?UTF-8?q?ark=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailLargerInfoView.swift | 3 +-- .../ResultDetailSmallerInfoView.swift | 4 ++-- .../ResultDetailViewController.swift | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 4850228..8f09daf 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -47,7 +47,7 @@ extension ResultDetailLargerInfoView { upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), upDownView.heightAnchor.constraint(equalToConstant: 4), - upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/2) + upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/3) ] NSLayoutConstraint.activate(upDownConstraints) } @@ -80,7 +80,6 @@ extension ResultDetailLargerInfoView { self.collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) - self.layoutIfNeeded() } private func configuareDataSource() { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 44a28a0..7037752 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -169,8 +169,8 @@ class ResultDetailSmallerInfoView: UIView { self.compositionalStackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), self.compositionalStackView.rightAnchor.constraint(equalTo: self.rightAnchor) ]) - self.layoutIfNeeded() self.displayUpDownMark() + self.layoutIfNeeded() } private func displayUpDownMark() { @@ -185,7 +185,7 @@ class ResultDetailSmallerInfoView: UIView { upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), upDownView.heightAnchor.constraint(equalToConstant: 4), - upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/2) + upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/3) ] NSLayoutConstraint.activate(upDownConstraints) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 46564d2..885ecc3 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -26,19 +26,25 @@ class ResultDetailViewController: UIViewController { return mapView }() - private var smallerInformationView: ResultDetailSmallerInfoView = { - let view = ResultDetailSmallerInfoView() + private lazy var smallerInformationView: ResultDetailSmallerInfoView = { + let view = ResultDetailSmallerInfoView(frame: CGRect(x: 0, + y: 0, + width: self.view.frame.width, + height: self.view.frame.height)) view.translatesAutoresizingMaskIntoConstraints = false return view }() - private var largerInformationView: ResultDetailLargerInfoView = { - let view = ResultDetailLargerInfoView() + private lazy var largerInformationView: ResultDetailLargerInfoView = { + let view = ResultDetailLargerInfoView(frame: CGRect(x: 0, + y: 0, + width: self.view.frame.width, + height: self.view.frame.height)) view.translatesAutoresizingMaskIntoConstraints = false return view }() - private var backButton: UIButton = { + private lazy var backButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "chevron.backward"), for: .normal) button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) @@ -48,7 +54,7 @@ class ResultDetailViewController: UIViewController { return button }() - private var changeButton: UIButton = { + private lazy var changeButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "ellipsis.circle"), for: .normal) button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) From f6752eda92e5e00bb0607300da2a35fb546e1ca9 Mon Sep 17 00:00:00 2001 From: Shin Date: Mon, 22 Nov 2021 23:39:13 +0900 Subject: [PATCH 329/465] =?UTF-8?q?[Feat]=20#264,=20#265,=20#266,=20#267?= =?UTF-8?q?=20=EC=9E=A5=EC=86=8C=20=EB=93=B1=EB=A1=9D=20=ED=99=94=EB=A9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 레이아웃, 산 이름, 설명, 저장소에 저장하기 --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 + .../MountainAddingView.swift | 177 ++++++++++++++++++ .../MountainAddingViewController.swift | 57 ++++-- .../MountainAddingViewCoordinator.swift | 8 +- .../MountainAddingViewModel.swift | 35 +++- .../MountainAddingViewRepository.swift | 17 +- .../MountainAddingViewUseCase.swift | 25 +++ .../CoreDataMountainStorage.swift | 58 ++++++ .../SanTa.xcdatamodel/contents | 14 +- 9 files changed, 375 insertions(+), 24 deletions(-) create mode 100644 SanTa/SanTa/MountainAddingScene/MountainAddingView.swift create mode 100644 SanTa/SanTa/Persistences/CoreDataMountainStorage.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f983fe0..a1475bd 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -55,6 +55,8 @@ 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32068274536D1002232BD /* MountainAddingViewModel.swift */; }; 54B3206B274536E3002232BD /* MountainAddingViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */; }; 54B3206D27453725002232BD /* MountainAddingViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */; }; + 54B32073274B7E09002232BD /* MountainAddingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32072274B7E09002232BD /* MountainAddingView.swift */; }; + 54B32075274BCCA2002232BD /* CoreDataMountainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32074274BCCA2002232BD /* CoreDataMountainStorage.swift */; }; 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */; }; 54F88EB9274256FE0004EAFD /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */; }; 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F88EBA274259950004EAFD /* RecordsViewCell.swift */; }; @@ -164,6 +166,8 @@ 54B32068274536D1002232BD /* MountainAddingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewModel.swift; sourceTree = ""; }; 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewUseCase.swift; sourceTree = ""; }; 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewRepository.swift; sourceTree = ""; }; + 54B32072274B7E09002232BD /* MountainAddingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingView.swift; sourceTree = ""; }; + 54B32074274BCCA2002232BD /* CoreDataMountainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataMountainStorage.swift; sourceTree = ""; }; 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalRecordsViewCell.swift; sourceTree = ""; }; 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = ""; }; 54F88EBA274259950004EAFD /* RecordsViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsViewCell.swift; sourceTree = ""; }; @@ -333,6 +337,7 @@ 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */, 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */, 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */, + 54B32074274BCCA2002232BD /* CoreDataMountainStorage.swift */, ); path = Persistences; sourceTree = ""; @@ -421,6 +426,7 @@ children = ( 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */, 54B32064274510D8002232BD /* MountainAddingViewController.swift */, + 54B32072274B7E09002232BD /* MountainAddingView.swift */, 54B32068274536D1002232BD /* MountainAddingViewModel.swift */, 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */, 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */, @@ -593,6 +599,7 @@ buildActionMask = 2147483647; files = ( 54296957272FC4380070B362 /* SettingsViewCoordinator.swift in Sources */, + 54B32075274BCCA2002232BD /* CoreDataMountainStorage.swift in Sources */, 54F88EBB274259950004EAFD /* RecordsViewCell.swift in Sources */, 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */, 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */, @@ -637,6 +644,7 @@ 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, 54B3206727451169002232BD /* MountainAddingViewCoordinator.swift in Sources */, 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, + 54B32073274B7E09002232BD /* MountainAddingView.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */, 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift new file mode 100644 index 0000000..4fa4bf7 --- /dev/null +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift @@ -0,0 +1,177 @@ +// +// MountainAddingView.swift +// SanTa +// +// Created by shin jae ung on 2021/11/22. +// + +import UIKit + +protocol NewPlaceAddable { + func userDidTypeWrong() + func newPlaceShouldAdd(title: String, description: String) +} + +class MountainAddingView: UIScrollView { + + private let titleLabel: UILabel = { + let label = UILabel() + label.text = "장소 등록하기" + label.font = .boldSystemFont(ofSize: 25) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let nameLabel: PaddingLabel = { + let label = PaddingLabel(insets: UIEdgeInsets(top: 2, left: 3, bottom: 2, right: 3)) + label.text = "산 이름" + label.backgroundColor = UIColor(named: "SantaColor") + label.layer.cornerRadius = 3 + label.textColor = .white + label.font = .boldSystemFont(ofSize: 13) + label.clipsToBounds = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let nameTextField: UITextField = { + let textField = UITextField() + textField.placeholder = "산 이름(10글자 제한)" + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + private let descriptionLabel: PaddingLabel = { + let label = PaddingLabel(insets: UIEdgeInsets(top: 2, left: 3, bottom: 2, right: 3)) + label.text = "산 설명" + label.backgroundColor = UIColor(named: "SantaColor") + label.layer.cornerRadius = 3 + label.textColor = .white + label.font = .boldSystemFont(ofSize: 13) + label.clipsToBounds = true + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let descriptionTextView: UITextView = { + let textView = UITextView() + textView.text = "정상, 봉우리, 사찰, 공원 등(10줄, 100자 이내)" + textView.textColor = UIColor.systemGray3 + textView.font = .systemFont(ofSize: 17) + textView.translatesAutoresizingMaskIntoConstraints = false + textView.layer.cornerRadius = 5 + textView.layer.borderWidth = 1 + textView.layer.borderColor = UIColor.systemGray3.cgColor + return textView + }() + + private let registerButton: UIButton = { + let button = UIButton() + button.setTitle("장소 등록", for: .normal) + button.backgroundColor = UIColor.init(named: "SantaColor") + button.layer.cornerRadius = 5 + button.titleLabel?.font = .boldSystemFont(ofSize: 17) + button.clipsToBounds = true + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(registerTouched), for: .touchUpInside) + return button + }() + + var newPlaceDelegate: NewPlaceAddable? + + func configure() { + self.isScrollEnabled = true + self.backgroundColor = .systemBackground + self.translatesAutoresizingMaskIntoConstraints = false + self.configureSubViews() + self.configureLayout() + } + + + private func configureSubViews() { + self.addSubview(titleLabel) + self.addSubview(nameLabel) + self.addSubview(nameTextField) + self.addSubview(descriptionLabel) + self.addSubview(descriptionTextView) + self.addSubview(registerButton) + self.nameTextField.delegate = self + self.descriptionTextView.delegate = self + } + + private func configureLayout() { + NSLayoutConstraint.activate([ + self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + ]) + + NSLayoutConstraint.activate([ + self.nameLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 20), + self.nameLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + ]) + + NSLayoutConstraint.activate([ + self.nameTextField.topAnchor.constraint(equalTo: self.nameLabel.bottomAnchor, constant: 10), + self.nameTextField.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.nameTextField.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20), + ]) + + NSLayoutConstraint.activate([ + self.descriptionLabel.topAnchor.constraint(equalTo: self.nameTextField.bottomAnchor, constant: 20), + self.descriptionLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + ]) + + NSLayoutConstraint.activate([ + self.descriptionTextView.topAnchor.constraint(equalTo: self.descriptionLabel.bottomAnchor, constant: 10), + self.descriptionTextView.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.descriptionTextView.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20), + self.descriptionTextView.heightAnchor.constraint(equalToConstant: 100) + ]) + + NSLayoutConstraint.activate([ + self.registerButton.topAnchor.constraint(equalTo: self.descriptionTextView.bottomAnchor, constant: 20), + self.registerButton.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.registerButton.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20), + self.registerButton.bottomAnchor.constraint(lessThanOrEqualTo: self.contentLayoutGuide.bottomAnchor, constant: -20) + ]) + } + + @objc private func registerTouched() { + guard let title = nameTextField.text, !title.isEmpty, + let description = descriptionTextView.text, descriptionTextView.textColor != .systemGray3, !description.isEmpty + else { + self.newPlaceDelegate?.userDidTypeWrong() + return + } + self.newPlaceDelegate?.newPlaceShouldAdd(title: title, description: description) + } +} + +extension MountainAddingView: UITextFieldDelegate, UITextViewDelegate { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + guard let text = textField.text else { return true } + let newLength = text.count + string.count + return newLength <= 10 + } + + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + guard let string = textView.text else { return true } + let newLength = string.count + text.count + let newLines = string.filter{$0 == "\n"}.count + text.filter{$0 == "\n"}.count + return newLength <= 100 && newLines + 1 <= 10 + } + + func textViewDidBeginEditing(_ textView: UITextView) { + if textView.textColor == UIColor.systemGray3 { + textView.text = nil + textView.textColor = .label + } + } + + func textViewDidEndEditing(_ textView: UITextView) { + if textView.text.isEmpty { + textView.text = "정상, 봉우리, 사찰, 공원 등(10줄, 100자 이내)" + textView.textColor = UIColor.systemGray3 + } + } +} diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index a5db068..a3dd02b 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -6,10 +6,13 @@ // import MapKit +import Combine class MountainAddingViewController: UIViewController { weak var coordinator: MountainAddingViewCoordinator? private var viewModel: MountainAddingViewModel? + private var observers: [AnyCancellable] = [] + private lazy var mapView: MKMapView = { let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 2/5)) mapView.delegate = self @@ -17,6 +20,7 @@ class MountainAddingViewController: UIViewController { mapView.isUserInteractionEnabled = false return mapView }() + private lazy var backButton: UIButton = { let button = UIButton(frame: .zero) button.setImage(.init(systemName: "xmark"), for: .normal) @@ -27,6 +31,12 @@ class MountainAddingViewController: UIViewController { return button }() + private lazy var mountainAddingView: MountainAddingView = { + let view = MountainAddingView() + view.configure() + return view + }() + convenience init(viewModel: MountainAddingViewModel) { self.init() self.viewModel = viewModel @@ -34,6 +44,7 @@ class MountainAddingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.mountainAddingView.newPlaceDelegate = self self.configureViews() self.configureViewModel() } @@ -41,34 +52,42 @@ class MountainAddingViewController: UIViewController { private func configureViews() { self.view.addSubview(mapView) self.view.addSubview(backButton) + self.view.addSubview(mountainAddingView) NSLayoutConstraint.activate([ self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), self.backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), self.backButton.widthAnchor.constraint(equalToConstant: 30), self.backButton.heightAnchor.constraint(equalToConstant: 30) ]) + NSLayoutConstraint.activate([ + self.mountainAddingView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor), + self.mountainAddingView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + self.mountainAddingView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + self.mountainAddingView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) + ]) } private func configureViewModel() { - self.viewModel?.locationDidUpdate = { [weak self] in - self?.mapView.showsUserLocation = false - self?.configureLocation() - self?.configureAnnotation() - } + self.viewModel?.$coordinate + .sink(receiveValue: { [weak self] coordinate in + self?.mapView.showsUserLocation = false + self?.configureLocation(coordinate) + self?.configureAnnotation(coordinate) + }) + .store(in: &observers) mapView.showsUserLocation = true } - private func configureLocation() { - guard let userLocation = self.viewModel?.userLocation else { return } - let location = CLLocationCoordinate2D(latitude: userLocation.latitude, longitude: userLocation.longitude) + private func configureLocation(_ coordinate: CLLocationCoordinate2D?) { + guard let coordinate = coordinate else { return } let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01) - let region = MKCoordinateRegion(center: location, span: span) + let region = MKCoordinateRegion(center: coordinate, span: span) self.mapView.setRegion(region, animated: false) } - private func configureAnnotation() { - guard let userLocation = self.viewModel?.userLocation else { return } - let mountainAnnotation = MountainAnnotation(latitude: userLocation.latitude, longitude: userLocation.longitude) + private func configureAnnotation(_ coordinate: CLLocationCoordinate2D?) { + guard let coordinate = coordinate else { return } + let mountainAnnotation = MountainAnnotation(latitude: coordinate.latitude, longitude: coordinate.longitude) self.mapView.addAnnotation(mountainAnnotation) } @@ -87,7 +106,19 @@ extension MountainAddingViewController: MKMapViewDelegate { } func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { - self.viewModel?.userLocation = (userLocation.coordinate.latitude, userLocation.coordinate.longitude) + self.viewModel?.updateUserLocation(coordinate: userLocation.coordinate, altitude: userLocation.location?.altitude) } } +extension MountainAddingViewController: NewPlaceAddable { + func userDidTypeWrong() { + let alert = UIAlertController(title: "올바르지 않은 입력", message: "산 이름과 설명이 입력되지 않았습니다", preferredStyle: .alert) + let confirm = UIAlertAction(title: "확인", style: .default) + alert.addAction(confirm) + self.present(alert, animated: true) + } + + func newPlaceShouldAdd(title: String, description: String) { + viewModel?.addMountain(title: title, description: description) + } +} diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift index 5fcaf53..e362d48 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift @@ -27,7 +27,13 @@ class MountainAddingViewCoordinator: Coordinator { extension MountainAddingViewCoordinator { private func injectDependencies() -> MountainAddingViewModel { return MountainAddingViewModel( - useCase: MountainAddingViewUseCase() + useCase: MountainAddingViewUseCase( + repository: DefaultMountainAddingRepository( + coreDataMountainStorage: CoreDataMountainStorage( + coreDataStorage: CoreDataStorage() // TODO - 변경필요 + ) + ) + ) ) } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index 35a42f3..cb94381 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -5,18 +5,41 @@ // Created by shin jae ung on 2021/11/17. // -import Foundation +import Combine +import CoreLocation +import AVFoundation class MountainAddingViewModel { private var useCase: MountainAddingViewUseCase? - var locationDidUpdate: () -> Void - var userLocation: (latitude: Double, longitude: Double)? { - didSet { self.locationDidUpdate() } - } + @Published private(set) var coordinate: CLLocationCoordinate2D? + private(set) var altitude: CLLocationDistance? init(useCase: MountainAddingViewUseCase) { self.useCase = useCase - self.locationDidUpdate = {} } + func updateUserLocation(coordinate: CLLocationCoordinate2D?, altitude: CLLocationDistance?) { + self.coordinate = coordinate + self.altitude = altitude + } + + func addMountain(title: String, description: String) { + guard let coordinate = coordinate, + let altitude = altitude + else { return } + self.useCase?.saveMountain( + name: title, + altitude: altitude, + latitude: coordinate.latitude, + longitude: coordinate.longitude, + description: description, + completion: { result in + guard result != nil else { + print("저장안됨") + return + } + print("저장됨") + } + ) + } } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift index d255c6b..bcbcc92 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift @@ -8,9 +8,24 @@ import Foundation protocol MountainAddingRepository { - + func save(_ mountainEntity: MountainEntity, completion: @escaping(Result) -> Void) } class DefaultMountainAddingRepository: MountainAddingRepository { + private let coreDataMountainStorage: CoreDataMountainStorage + + init(coreDataMountainStorage: CoreDataMountainStorage) { + self.coreDataMountainStorage = coreDataMountainStorage + } + func save(_ mountainEntity: MountainEntity, completion: @escaping(Result) -> Void) { + coreDataMountainStorage.save(mountainEntity: mountainEntity) { result in + switch result { + case .success(): + completion(.success(Void())) + case .failure(let error): + completion(.failure(error)) + } + } + } } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift index 05820e0..4b063ba 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -6,7 +6,32 @@ // import Foundation +import OSLog class MountainAddingViewUseCase { + private let repository: MountainAddingRepository + init(repository: MountainAddingRepository) { + self.repository = repository + } + + + func saveMountain(name: String, altitude: Double, latitude: Double, longitude: Double, description: String, completion: @escaping (Void?) -> Void) { + let mountainDetail = MountainEntity.MountainDetail( + mountainName: name, + mountainRegion: "", + mountainHeight: String(altitude), + mountainShortDescription: description + ) + let mountainEntity = MountainEntity(mountain: mountainDetail, latitude: latitude, longitude: longitude) + self.repository.save(mountainEntity) { result in + switch result { + case .success(): + completion(Void()) + case .failure(let error): + completion(nil) + os_log(.error, log: .default, "\(error.localizedDescription)") + } + } + } } diff --git a/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift new file mode 100644 index 0000000..6ca9d9d --- /dev/null +++ b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift @@ -0,0 +1,58 @@ +// +// CoreDataMountainStorage.swift +// SanTa +// +// Created by shin jae ung on 2021/11/22. +// + +import Foundation +import CoreData + +protocol MountainStorage { + func save(mountainEntity: MountainEntity, completion: @escaping (Result) -> Void) + func fetch(completion: @escaping (Result<[MountainEntityMO], Error>) -> Void) +} + +final class CoreDataMountainStorage: MountainStorage { + enum coreDataMountainStorageError: Error { + case saveError + case fetchError + } + + private let coreDataStroage: CoreDataStorage + + init(coreDataStorage: CoreDataStorage) { + self.coreDataStroage = coreDataStorage + } + + func save(mountainEntity: MountainEntity, completion: @escaping (Result) -> Void) { + self.coreDataStroage.performBackgroundTask { context in + let object = NSEntityDescription.insertNewObject(forEntityName: "MountainEntity", into: context) + object.setValue(mountainEntity.id, forKey: "id") + object.setValue(mountainEntity.mountain.mountainName, forKey: "name") + object.setValue(mountainEntity.mountain.mountainHeight, forKey: "altitude") + object.setValue(mountainEntity.latitude, forKey: "latitude") + object.setValue(mountainEntity.longitude, forKey: "longitude") + object.setValue(mountainEntity.mountain.mountainShortDescription, forKey: "descript") + + do { + try context.save() + completion(.success(Void())) + } catch { + completion(.failure(coreDataMountainStorageError.saveError)) + } + } + } + + func fetch(completion: @escaping (Result<[MountainEntityMO], Error>) -> Void) { + self.coreDataStroage.performBackgroundTask { context in + do { + let request = NSFetchRequest(entityName: "MountainEntity") + let result = try context.fetch(request) + completion(.success(result)) + } catch { + completion(.failure(coreDataMountainStorageError.fetchError)) + } + } + } +} diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 3275a97..c903062 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,11 +1,19 @@ - + + + + + + + + + @@ -15,7 +23,6 @@ - @@ -25,6 +32,7 @@ - + + \ No newline at end of file From 02eea9b2f5ffb50237d469d3a03213154c6cef43 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 00:22:22 +0900 Subject: [PATCH 330/465] =?UTF-8?q?[Feat]=20#260=20LargerInfoView=20Header?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/DetailHeader.swift | 16 ++++++---- .../ResultDetailLargerInfoView.swift | 32 ++++++++++--------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index 4f9e5f3..a39c0f3 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -81,8 +81,7 @@ class DetailHeader: UICollectionReusableView { override init(frame: CGRect) { super.init(frame: frame) - self.configureStackView() - self.configureViews() + self.configure() } required init?(coder aDecoder: NSCoder) { @@ -90,24 +89,29 @@ class DetailHeader: UICollectionReusableView { } + private func configure() { + self.configureStackView() + self.configureViews() + } + private func configureViews() { self.addSubview(self.dateLabel) self.addSubview(self.labelStackView) self.addSubview(self.timeStackView) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), - self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.dateLabel.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), ]) NSLayoutConstraint.activate([ self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), - self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.labelStackView.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), ]) NSLayoutConstraint.activate([ self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), - self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.timeStackView.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), ]) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 8f09daf..962e605 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -16,6 +16,7 @@ class ResultDetailLargerInfoView: UIView { typealias DetailLargerInfoSnapshot = NSDiffableDataSourceSnapshot private var dataSource: DetailLargerInfoDataSource? + private var currentSnapshot: DetailLargerInfoSnapshot? lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() @@ -57,7 +58,7 @@ extension ResultDetailLargerInfoView { self.configureViews() self.configuareDataSource() self.displayUpDownMark() - self.bindSnapShotApply(section: .main, item: ["test"]) + self.bindSnapShotApply(section: .main, item: [AnyHashable]()) } private func bindSnapShotApply(section: DetailLargerInfoSection, item: [AnyHashable]) { @@ -67,6 +68,8 @@ extension ResultDetailLargerInfoView { snapshot.appendItems([$0], toSection: section) } self.dataSource?.apply(snapshot, animatingDifferences: true) + self.currentSnapshot = snapshot + self.configureHeader() } private func configureViews() { @@ -75,7 +78,7 @@ extension ResultDetailLargerInfoView { self.addSubview(self.collectionView) NSLayoutConstraint.activate([ - self.collectionView.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 5), + self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), self.collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor), self.collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) @@ -87,7 +90,6 @@ extension ResultDetailLargerInfoView { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell else { return UICollectionViewCell() } - return cell }) @@ -96,7 +98,6 @@ extension ResultDetailLargerInfoView { } private func configureCollectionView() { - self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailCell.self, forCellWithReuseIdentifier: DetailCell.identifier) self.collectionView.register(DetailHeader.self, @@ -104,6 +105,17 @@ extension ResultDetailLargerInfoView { withReuseIdentifier: DetailHeader.identifier) } + private func configureHeader() { + self.dataSource?.supplementaryViewProvider = { ( + collectionView: UICollectionView, + kind: String, + indexPath: IndexPath) -> UICollectionReusableView? in + guard let header: DetailHeader = self.collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { return DetailHeader() } + + return header + } + } + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(500))) @@ -115,7 +127,7 @@ extension ResultDetailLargerInfoView { let headerSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), - heightDimension: .estimated(500)) + heightDimension: .estimated(200)) let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, @@ -126,13 +138,3 @@ extension ResultDetailLargerInfoView { } } } - -extension ResultDetailLargerInfoView: UICollectionViewDelegate { - func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { - guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: DetailHeader.identifier, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { - return DetailHeader() - } - - return header - } -} From 18c3e97df61f575530670b2f62d06aef1a7e5f69 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 11:23:36 +0900 Subject: [PATCH 331/465] =?UTF-8?q?[Feat]=20#260=20CollectionView=20Header?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/DetailHeader.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index a39c0f3..213258e 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -67,6 +67,7 @@ class DetailHeader: UICollectionReusableView { stackView.alignment = .center stackView.axis = .horizontal stackView.distribution = .fill + stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -76,6 +77,7 @@ class DetailHeader: UICollectionReusableView { stackView.alignment = .center stackView.axis = .horizontal stackView.distribution = .fill + stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -100,18 +102,18 @@ class DetailHeader: UICollectionReusableView { self.addSubview(self.timeStackView) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor, constant: 20), - self.dateLabel.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), - self.labelStackView.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), + self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), - self.timeStackView.centerXAnchor.constraint(equalTo: self.layoutMarginsGuide.centerXAnchor), + self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) } From 08637f2668f1f52727d0934322d5c7fa723f1bbd Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 11:36:38 +0900 Subject: [PATCH 332/465] =?UTF-8?q?[HotFix]=20=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=ED=9B=84=20=EC=BB=A8=ED=94=8C=EB=A6=AC=ED=8A=B8=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 3 +-- SanTa/SanTa/ResultScene/ResultUseCase.swift | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 28f46cc..7599b53 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -84,7 +84,7 @@ class ResultDetailViewController: UIViewController { self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } self?.titleLabel.text = viewModel.resultDetailData?.title - self?.informationView.configureLayout( + self?.smallerInformationView.configureLayout( distance: viewModel.distanceViewModel.totalDistance, time: viewModel.timeViewModel.totalTimeSpent, steps: viewModel.distanceViewModel.steps, @@ -145,7 +145,6 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) self.view.addSubview(self.titleLabel) - self.view.addSubview(self.informationView) NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index c272ee7..e4230b9 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -42,12 +42,11 @@ final class ResultUseCase { private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { guard let title = recordsEntityMO.title, let archiveAssetIdentifiers = recordsEntityMO.assetIdentifiers, + let id = recordsEntityMO.id, let assetIdentifiers = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self], from: archiveAssetIdentifiers) as? [String] else { return nil } let secondPerHighestSpeed = Int(recordsEntityMO.secondPerHighestSpeed) let secondPerMinimumSpeed = Int(recordsEntityMO.secondPerMinimumSpeed) - let id = recordsEntityMO.id else { return nil } - var records: [Record] = [] recordsEntityMO.records?.forEach { guard let recordEntityMO = $0 as? RecordEntityMO else { return } From f00e80371a2857c25d0c107d45f554746901dc38 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 13:25:26 +0900 Subject: [PATCH 333/465] =?UTF-8?q?[Feat]=20#271=20=EC=9E=A5=EC=86=8C?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=99=94=EB=A9=B4=20VoiceOver=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainAddingScene/MountainAddingView.swift | 6 ++++++ .../MountainAddingScene/MountainAddingViewController.swift | 3 +++ 2 files changed, 9 insertions(+) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift index 4fa4bf7..c566761 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift @@ -19,6 +19,7 @@ class MountainAddingView: UIScrollView { label.text = "장소 등록하기" label.font = .boldSystemFont(ofSize: 25) label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityTraits = .header return label }() @@ -31,6 +32,7 @@ class MountainAddingView: UIScrollView { label.font = .boldSystemFont(ofSize: 13) label.clipsToBounds = true label.translatesAutoresizingMaskIntoConstraints = false + label.isAccessibilityElement = false return label }() @@ -38,6 +40,7 @@ class MountainAddingView: UIScrollView { let textField = UITextField() textField.placeholder = "산 이름(10글자 제한)" textField.translatesAutoresizingMaskIntoConstraints = false + textField.accessibilityHint = "산 이름을 입력하십시오" return textField }() @@ -50,6 +53,7 @@ class MountainAddingView: UIScrollView { label.font = .boldSystemFont(ofSize: 13) label.clipsToBounds = true label.translatesAutoresizingMaskIntoConstraints = false + label.isAccessibilityElement = false return label }() @@ -62,6 +66,7 @@ class MountainAddingView: UIScrollView { textView.layer.cornerRadius = 5 textView.layer.borderWidth = 1 textView.layer.borderColor = UIColor.systemGray3.cgColor + textView.accessibilityHint = "산 설명을 입력하십시오" return textView }() @@ -74,6 +79,7 @@ class MountainAddingView: UIScrollView { button.clipsToBounds = true button.translatesAutoresizingMaskIntoConstraints = false button.addTarget(self, action: #selector(registerTouched), for: .touchUpInside) + button.accessibilityHint = "장소 등록을 하려면 이중 탭 하십시오" return button }() diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index a3dd02b..d3d2156 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -18,6 +18,7 @@ class MountainAddingViewController: UIViewController { mapView.delegate = self mapView.mapType = .mutedStandard mapView.isUserInteractionEnabled = false + mapView.accessibilityElementsHidden = true return mapView }() @@ -28,6 +29,8 @@ class MountainAddingViewController: UIViewController { button.tintColor = .label button.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityLabel = "닫기" + button.accessibilityHint = "장소등록을 종료하려면 이중 탭 하십시오" return button }() From 3bdac773ff478a9d58494c159648d9579e78ae53 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 13:29:18 +0900 Subject: [PATCH 334/465] =?UTF-8?q?[Feat]=20#262=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 6 +++--- .../RecordingViewController+Extension.swift | 10 +++++----- .../SanTa/RecordingScene/RecordingViewController.swift | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index aef856c..b7168c1 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -41,7 +41,7 @@ class MapViewController: UIViewController { button.layer.shadowRadius = 3 button.layer.shadowOffset = CGSize(width: 0, height: 3) button.addTarget(self, action: #selector(presentRecordingViewController), for: .touchDown) - button.accessibilityHint = "측정을 시작하려면 이중탭 하십시오" + button.accessibilityHint = "측정을 시작하려면 이중 탭 하십시오" return button }() @@ -220,12 +220,12 @@ extension MapViewController: Animatable { func shouldAnimate() { let image = UIImage.gifImage(named: "walkingManAnimation", withTintColor: .white) self.startButton.setImage(image, for: .normal) - self.startButton.accessibilityHint = "현재 측정 중입니다. 측정화면으로 돌아가려면 이중탭 하십시오" + self.startButton.accessibilityHint = "현재 측정 중입니다. 측정화면으로 돌아가려면 이중 탭 하십시오" } func shouldStopAnimate() { self.startButton.setImage(nil, for: .normal) - self.startButton.accessibilityHint = "측정을 시작하려면 이중탭 하십시오" + self.startButton.accessibilityHint = "측정을 시작하려면 이중 탭 하십시오" } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index 3cb198e..bedcdcf 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -135,11 +135,11 @@ extension RecordingViewController { } func configureAccessibilty() { - self.pauseButton.accessibilityLabel = "일시정지" - self.pauseButton.accessibilityHint = "측정을 일시정지 하시려면 이중탭하십시오" + self.pauseButton.accessibilityLabel = "일시 정지" + self.pauseButton.accessibilityHint = "측정을 일시정지 하려면 이중 탭 하십시오" self.stopButton.accessibilityLabel = "종료" - self.stopButton.accessibilityHint = "측정을 종료 하시려면 이중탭하십시오" - self.locationButton.accessibilityLabel = "현재위치" - self.locationButton.accessibilityHint = "시작화면에서 현재위치를 보시려면 이중탭하십시오" + self.stopButton.accessibilityHint = "측정을 종료 하려면 이중 탭 하십시오" + self.locationButton.accessibilityLabel = "현재 위치" + self.locationButton.accessibilityHint = "시작화면에서 현재 위치를 보려면 이중 탭 하십시오" } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 3857ad5..ec2c4d2 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -128,7 +128,7 @@ class RecordingViewController: UIViewController { self.recordingViewModel?.$accessibilityCurrentTime .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] time in - self?.timeLabel.accessibilityLabel = "현재시간 \(time)" + self?.timeLabel.accessibilityLabel = "현재 시간 \(time)" }) .store(in: &self.subscriptions) @@ -199,7 +199,7 @@ class RecordingViewController: UIViewController { pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) self.pauseButton.configuration = pauseConfiguration self.pauseButton.accessibilityLabel = "재시작" - self.pauseButton.accessibilityHint = "측정을 재시작 하시려면 이중탭하십시오" + self.pauseButton.accessibilityHint = "측정을 재시작 하려면 이중 탭 하십시오" self.recordingViewModel?.pause() self.currentState = false } else { @@ -209,7 +209,7 @@ class RecordingViewController: UIViewController { pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) self.pauseButton.configuration = pauseConfiguration self.pauseButton.accessibilityLabel = "일시정지" - self.pauseButton.accessibilityHint = "측정을 일시정지 하시려면 이중탭하십시오" + self.pauseButton.accessibilityHint = "측정을 일시정지 하려면 이중 탭 하십시오" self.recordingViewModel?.resume() self.currentState = true } From 747228ac2efad8e4697b4b8933f8e3499f6eee1a Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 13:57:38 +0900 Subject: [PATCH 335/465] =?UTF-8?q?[Feat]=20#261=20=EC=82=AC=EC=A7=84?= =?UTF-8?q?=ED=97=88=EC=9A=A9=20=ED=99=94=EB=A9=B4=20VoiceOver=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingPhotoScene/RecordingPhotoViewController.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index 4d78872..b4a889b 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -36,6 +36,7 @@ class RecordingPhotoViewController: UIViewController { label.textAlignment = .center label.textColor = .systemGray label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityTraits = .header return label }() @@ -58,6 +59,7 @@ class RecordingPhotoViewController: UIViewController { button.layer.masksToBounds = true button.layer.cornerRadius = 6 button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityHint = "사진 기록하기를 허용하려면 이중 탭 하십시오" return button }() From 34c2b22ceeaec3af2dacfa3e8ef52ce5256fbdfd Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 14:45:23 +0900 Subject: [PATCH 336/465] =?UTF-8?q?[Feat]=20#272=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=A2=85=ED=95=A9=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?VoiceOver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultScene/ResultViewController.swift | 27 +++++++++++-------- SanTa/SanTa/ResultScene/ResultViewModel.swift | 18 ++++++++++--- .../SanTa/ResultScene/SectionHeaderView.swift | 17 +++++++++++- .../ResultScene/TotalRecordsViewCell.swift | 15 +++++++++++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index f8b1d17..7ce7470 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -24,7 +24,7 @@ class ResultViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { self.navigationController?.navigationBar.isHidden = true - viewModel?.viewWillAppear() { [weak self] in + self.viewModel?.viewWillAppear() { [weak self] in DispatchQueue.main.async { self?.navigationController?.navigationBar.topItem?.title = self?.viewModel?.totalDistance self?.collectionView?.reloadData() @@ -33,8 +33,8 @@ class ResultViewController: UIViewController { } private func configureCollectionView() { - self.collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createCompositionalLayout()) - guard let collectionView = collectionView else { return } + self.collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: self.createCompositionalLayout()) + guard let collectionView = self.collectionView else { return } view.addSubview(collectionView) collectionView.register(TotalRecordsViewCell.self, forCellWithReuseIdentifier: TotalRecordsViewCell.identifier) collectionView.register(RecordsViewCell.self, forCellWithReuseIdentifier: RecordsViewCell.identifier) @@ -83,14 +83,14 @@ class ResultViewController: UIViewController { extension ResultViewController: UICollectionViewDataSource { func numberOfSections(in collectionView: UICollectionView) -> Int { - guard let viewModel = viewModel else { return 0} + guard let viewModel = self.viewModel else { return 0} return viewModel.totalSections + 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return 1 - default : return viewModel?.itemsInSection(section: section - 1) ?? 0 + default : return self.viewModel?.itemsInSection(section: section - 1) ?? 0 } } @@ -101,16 +101,17 @@ extension ResultViewController: UICollectionViewDataSource { withReuseIdentifier: TotalRecordsViewCell.identifier, for: indexPath ) as? TotalRecordsViewCell, - let totalInfo = viewModel?.totalInfo() + let totalInfo = self.viewModel?.totalInfo() else { return UICollectionViewCell() } cell.configure(distance: totalInfo.distance, count: totalInfo.count, time: totalInfo.time, steps: totalInfo.steps) + cell.configureVoiceOverAccessibility() return cell default: guard let cell = collectionView.dequeueReusableCell( withReuseIdentifier: RecordsViewCell.identifier, for: indexPath ) as? RecordsViewCell, - let cellInfo = viewModel?.cellInfo(indexPath: IndexPath(item: indexPath.item, section: indexPath.section - 1)) + let cellInfo = self.viewModel?.cellInfo(indexPath: IndexPath(item: indexPath.item, section: indexPath.section - 1)) else { return UICollectionViewCell() } cell.layer.cornerRadius = 10 cell.backgroundColor = .white @@ -125,16 +126,20 @@ extension ResultViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.identifier, for: indexPath) as? SectionHeaderView, - let sectionInfo = viewModel?.sectionInfo(section: indexPath.section - 1) + let sectionInfo = self.viewModel?.sectionInfo(section: indexPath.section - 1) else { return UICollectionReusableView() } - sectionHeader.configure(month: sectionInfo.date, count: sectionInfo.count, distance: sectionInfo.distance, time: sectionInfo.time) + sectionHeader.configure(month: sectionInfo.date, + count: sectionInfo.count, + distance: sectionInfo.distance, + time: sectionInfo.time) + sectionHeader.configureVoiceOverAccessibility(date: sectionInfo.accessibiltyDate) return sectionHeader } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let indexPath = IndexPath(item: indexPath.item, section: indexPath.section - 1) - guard let records = viewModel?.selectedRecords(indexPath: indexPath) else { return } - coordinator?.presentResultDetailViewController(records: records) + guard let records = self.viewModel?.selectedRecords(indexPath: indexPath) else { return } + self.coordinator?.presentResultDetailViewController(records: records) } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 685f28e..7106042 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -47,20 +47,28 @@ class ResultViewModel { return (distanceString, countString, timeString, stepsString) } - func sectionInfo(section: Int) -> (date: String, count: String, distance: String, time: String) { + func sectionInfo(section: Int) -> (date: String, + accessibiltyDate: String, + count: String, + distance: String, + time: String) { guard let totalRecords = useCase.totalRecords, let dateSeperateRecords = totalRecords[section] else { - return ("", "", "", "") + return ("", "", "", "", "") } let dateString = self.headerDateFormatter( year: dateSeperateRecords.year, month: dateSeperateRecords.month ) + let accessibiltyDateString = self.headerAccessibiltyDateFormatter( + year: dateSeperateRecords.year, + month: dateSeperateRecords.month + ) let countString = "\(dateSeperateRecords.count)회" let distanceString = self.doubleFormatter(dateSeperateRecords.distances) + "km" let timeString = self.timeFormatter(dateSeperateRecords.times) - return (dateString, countString, distanceString, timeString) + return (dateString, accessibiltyDateString, countString, distanceString, timeString) } func cellInfo(indexPath: IndexPath) @@ -89,6 +97,10 @@ extension ResultViewModel { return "\(year). \(month)." } + private func headerAccessibiltyDateFormatter(year: Int, month: Int) -> String { + return "\(year)년 \(month)월" + } + private func cellDateFormatter(_ date: Date?) -> String { guard let date = date, let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: .now) diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 5e5d31d..4c826a7 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -28,7 +28,7 @@ class SectionHeaderView: UICollectionReusableView { let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) - func configure(month: String, count: String, distance: String, time: String){ + func configure(month: String, count: String, distance: String, time: String) { self.backgroundColor = .systemBackground self.monthLabel.text = month self.countLabel.text = count @@ -63,3 +63,18 @@ class SectionHeaderView: UICollectionReusableView { ]) } } + +// MARK: - Accessibility + +extension SectionHeaderView { + + func configureVoiceOverAccessibility(date: String) { + guard let countLabel = countLabel.text else { return } + guard let distanceLabel = distanceLabel.text else { return } + guard let timeLabel = timeLabel.text else { return } + self.isAccessibilityElement = true + self.accessibilityLabel = "\(date) 등산기록 정보" + self.accessibilityTraits = .none + self.accessibilityHint = "총 등산횟수: \(countLabel), 총 거리: \(distanceLabel), 총 시간: \(timeLabel)" + } +} diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index f9fee05..a2e5736 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -92,3 +92,18 @@ class TotalRecordsViewCell: UICollectionViewCell { self.layer.addSublayer(border) } } + +// MARK: - Accessibility + +extension TotalRecordsViewCell { + + func configureVoiceOverAccessibility() { + guard let kilometerNumber = kilometerNumber.text else { return } + guard let countNumber = countNumber.text else { return } + guard let timeNumber = timeNumber.text else { return } + guard let stepsNumber = stepsNumber.text else { return } + self.isAccessibilityElement = true + self.accessibilityLabel = "전체 등산기록 정보" + self.accessibilityHint = "총 거리: \(kilometerNumber) 킬로미터, 총 등산횟수: \(countNumber), 총 시간: \(timeNumber), 총 걸음: \(stepsNumber) 걸음" + } +} From dff2d39bc8c1d30b95b46d3704c48d968900a82a Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Tue, 23 Nov 2021 14:48:24 +0900 Subject: [PATCH 337/465] =?UTF-8?q?[Feat]=20=EC=83=81=EC=84=B8=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=B0=BD=20=EC=A0=95=EB=B3=B4=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/DetailCell.swift | 58 +++++----- .../ResultDetailLargerInfoView.swift | 7 +- .../ResultDetailScene/ResultDetailModel.swift | 9 +- .../ResultDetailViewController.swift | 18 +-- .../ResultDetailViewModel.swift | 103 +++++++++++------- 5 files changed, 115 insertions(+), 80 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index 3216695..ad41d9e 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -10,18 +10,16 @@ import UIKit class DetailCell: UICollectionViewCell { static let identifier = "DetailCell" - private let title: UILabel = UILabel() - - func layout(data: ResultDetailCellRepresentable) { - self.title.text = data.title - self.title.textColor = .init(named: "SantaColor") - - self.title.translatesAutoresizingMaskIntoConstraints = false - let titleConstraints = [ - self.title.topAnchor.constraint(equalTo: self.topAnchor), - self.title.leftAnchor.constraint(equalTo: self.leftAnchor) - ] - NSLayoutConstraint.activate(titleConstraints) + func layout(data: LargeViewModel) { + let title: UILabel = UILabel() + self.addSubview(title) + title.text = data.title + title.textColor = .init(named: "SantaColor") + title.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + title.topAnchor.constraint(equalTo: self.topAnchor), + title.leftAnchor.constraint(equalTo: self.leftAnchor) + ]) var contentLabels: [UILabel] = [] var contentTitleLabels: [UILabel] = [] @@ -36,6 +34,7 @@ class DetailCell: UICollectionViewCell { } let stack = UIStackView() + self.addSubview(stack) stack.axis = .vertical for index in 0.. UICollectionViewCell in - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell else { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell, + let item = item as? LargeViewModel else { return UICollectionViewCell() } + cell.layout(data: item) return cell }) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index fdf5cdf..5379fe6 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -12,7 +12,7 @@ struct ResultDetailData { let timeStamp: ResultTimeStamp let distance: ResultDistance let time: ResultTime -// let pace: ResultPace + let pace: ResultPace let altitude: ResultAltitude let incline: ResultIncline let id: String @@ -23,6 +23,7 @@ struct ResultDetailData { self.timeStamp = ResultTimeStamp(records: records) self.distance = ResultDistance(records: records) self.time = ResultTime(records: records) + self.pace = ResultPace(records: records) self.altitude = ResultAltitude(records: records) self.incline = ResultIncline(records: records) self.id = records.id @@ -81,6 +82,12 @@ struct ResultPace { let timePerKilometer: TimeInterval let fastestPace: TimeInterval let slowestPace: TimeInterval + + init(records: Records) { + self.timePerKilometer = records.distances / records.times / 1000 + self.fastestPace = TimeInterval(records.secondPerHighestSpeed) + self.slowestPace = TimeInterval(records.secondPerMinimumSpeed) + } } struct ResultAltitude { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 7599b53..2d28e07 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -93,6 +93,17 @@ class ResultDetailViewController: UIViewController { averageSpeed: viewModel.averageSpeed() ) self?.largerInformationView.configure() + guard let distanceViewModel = self?.viewModel?.distanceViewModel, + let timeViewModel = self?.viewModel?.timeViewModel, + let paceViewModel = self?.viewModel?.paceViewModel, + let altitudeViewModel = self?.viewModel?.altitudeViewModel, + let inclineViewModel = self?.viewModel?.inclineViewMedel else { + return + } + let largeInfoModel: [LargeViewModel] = [ + distanceViewModel, timeViewModel, paceViewModel, altitudeViewModel, inclineViewModel + ] + self?.largerInformationView.bindSnapShotApply(section: .main, item: largeInfoModel) self?.configureViews() self?.configurePanGesture() } @@ -266,13 +277,7 @@ extension ResultDetailViewController { @objc func presentModifyResultAlert() { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in - // TODO: 입력창 띄우고 텍스트 입력 받아서 update 호출 self.coordinator?.presentRecordingTitleViewController() -// self.viewModel?.update(title: "타이트을", completion: { title in -// DispatchQueue.main.async { -// self.titleLabel.text = title -// } -// }) } let delete = UIAlertAction(title: "삭제", style: .destructive) { action in self.viewModel?.delete { result in @@ -307,7 +312,6 @@ extension ResultDetailViewController: SetTitleDelegate { extension ResultDetailViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { if let polyline = overlay as? MKPolyline { - print("is polyline") let renderer = MKPolylineRenderer(overlay: polyline) renderer.lineWidth = 5 renderer.alpha = 1 diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 394c482..e1035e0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -21,6 +21,13 @@ class ResultDetailViewModel { var altitudeViewModel: AltitudeViewModel { return AltitudeViewModel(altitudeData: self.resultDetailData?.altitude) } + var paceViewModel: PaceViewModel { + return PaceViewModel(paceData: self.resultDetailData?.pace) + } + var inclineViewMedel: InclineViewModel { + return InclineViewModel(inclineData: self.resultDetailData?.incline) + } + init(useCase: ResultDetailUseCase) { self.useCase = useCase self.recordDidFetch = {} @@ -101,34 +108,42 @@ struct CellContentEntity { let contentTitle: String } -protocol ResultDetailCellRepresentable { +protocol ResultDetailCellRepresentable: Hashable { var title: String { get } var contents: [CellContentEntity] { get } } +class LargeViewModel: Hashable { + var id: UUID = UUID() + var title: String = "" + var contents: [CellContentEntity] = [] + + func hash(into hasher: inout Hasher) { + hasher.combine(id) + } + + static func == (lhs: LargeViewModel, rhs: LargeViewModel) -> Bool { + lhs.id == rhs.id + } +} + extension ResultDetailViewModel { - struct DistanceViewModel: ResultDetailCellRepresentable { - let title: String = "거리" - let totalDistance: String - let steps: String - let contents: [CellContentEntity] + class DistanceViewModel: LargeViewModel { + var totalDistance: String = "" + var steps: String = "" init(distanceData: ResultDistance?) { + super.init() guard let distanceData = distanceData else { - self.totalDistance = "" - self.steps = "" - self.contents = [] return } + self.title = "거리" let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 2 guard let total = formatter.string(from: NSNumber(value: distanceData.total)), let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { - self.contents = [] - self.totalDistance = "" - self.steps = "" return } self.totalDistance = total @@ -140,25 +155,21 @@ extension ResultDetailViewModel { } } - struct TimeViewModel: ResultDetailCellRepresentable { - var title: String = "시간" - let totalTimeSpent: String - var contents: [CellContentEntity] + class TimeViewModel: LargeViewModel { + var totalTimeSpent: String = "" init(timeData: ResultTime?) { + super.init() guard let timeData = timeData else { - self.totalTimeSpent = "" - self.contents = [] return } + self.title = "시간" let formatter = DateComponentsFormatter() formatter.allowedUnits = [.hour, .minute] formatter.zeroFormattingBehavior = .pad guard let spent = formatter.string(from: timeData.spent), let active = formatter.string(from: timeData.active), let inactive = formatter.string(from: timeData.inactive) else { - self.contents = [] - self.totalTimeSpent = "" return } self.totalTimeSpent = spent @@ -170,26 +181,39 @@ extension ResultDetailViewModel { } } - struct PaceViewModel: ResultDetailCellRepresentable { - var title: String = "페이스(1km당 소요시간)" - var contents: [CellContentEntity] - - + class PaceViewModel: LargeViewModel { + init(paceData: ResultPace?) { + super.init() + guard let pace = paceData else { + return + } + self.title = "페이스(1km당 소요시간)" + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + formatter.zeroFormattingBehavior = .pad + guard let averagePace = formatter.string(from: pace.timePerKilometer), + let fastest = formatter.string(from: pace.fastestPace), + let slowest = formatter.string(from: pace.slowestPace) else { + return + } + self.contents = [ + CellContentEntity(content: averagePace, contentTitle: "평균"), + CellContentEntity(content: fastest, contentTitle: "최고"), + CellContentEntity(content: slowest, contentTitle: "최저"), + ] + } } - struct AltitudeViewModel: ResultDetailCellRepresentable { - var title: String = "고도" - let highest: String - let lowest: String - var contents: [CellContentEntity] + class AltitudeViewModel: LargeViewModel { + var highest: String = "" + var lowest: String = "" init(altitudeData: ResultAltitude?) { + super.init() guard let altitudeData = altitudeData else { - self.highest = "" - self.lowest = "" - self.contents = [] return } + self.title = "고도" self.contents = [ CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), @@ -202,18 +226,19 @@ extension ResultDetailViewModel { } } - struct InclineViewModel: ResultDetailCellRepresentable { - var title: String = "경사도" - var contents: [CellContentEntity] - - init(inclineData: ResultIncline) { + class InclineViewModel: LargeViewModel { + init(inclineData: ResultIncline?) { + super.init() + guard let inclineData = inclineData else { + return + } + self.title = "경사도" let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.maximumFractionDigits = 2 guard let uphill = formatter.string(from: NSNumber(value: inclineData.uphillKilometer)), let downhill = formatter.string(from: NSNumber(value: inclineData.downhillKilometer)), let plain = formatter.string(from: NSNumber(value: inclineData.plainKilometer)) else { - self.contents = [] return } self.contents = [ From 3cf163a88e59945eb462338f63ce9d1529250dae Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 15:08:28 +0900 Subject: [PATCH 338/465] =?UTF-8?q?[Feat]=20#272=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20RecordsViewCell=20VoiceOver=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController.swift | 2 +- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 23 +++++++++++++++++++ .../ResultScene/ResultViewController.swift | 1 + SanTa/SanTa/ResultScene/ResultViewModel.swift | 2 +- .../SanTa/ResultScene/SectionHeaderView.swift | 14 +++++------ .../ResultScene/TotalRecordsViewCell.swift | 2 +- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index ec2c4d2..670f64f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -136,7 +136,7 @@ class RecordingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer - self?.kilometerLabel.accessibilityLabel = "현재 \(kilometer) 킬로미터" + self?.kilometerLabel.accessibilityLabel = "현재 \(kilometer)km" }) .store(in: &self.subscriptions) diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index 42915a8..7f14572 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -111,3 +111,26 @@ class RecordsViewCell: UICollectionViewCell { ]) } } + +// MARK: - Accessibility + +extension RecordsViewCell { + + func configureVoiceOverAccessibility() { + guard let date = self.date.text else { return } + guard var title = self.title.text else { return } + guard let distance = self.distance.text else { return } + guard let time = self.time.text else { return } + guard let altitude = self.altitude.text else { return } + guard let steps = self.steps.text else { return } + if title.isEmpty { + title = "없음" + } + + self.isAccessibilityElement = true + self.accessibilityLabel = "\(date) 등산기록 정보" + self.accessibilityTraits = .none + self.accessibilityHint = "제목: \(title), 거리: \(distance)km, 시간: \(time), 고도차: \(altitude), 걸음: \(steps)" + } +} + diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 7ce7470..3d3a2ca 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -120,6 +120,7 @@ extension ResultViewController: UICollectionViewDataSource { cell.layer.shadowOpacity = 0.8 cell.layer.shadowOffset = CGSize(width: 0, height: 0.5) cell.configure(date: cellInfo.date, title: cellInfo.title, distance: cellInfo.distance, time: cellInfo.time, altitude: cellInfo.altitudeDifference, steps: cellInfo.steps) + cell.configureVoiceOverAccessibility() return cell } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 7106042..93a9996 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -109,7 +109,7 @@ extension ResultViewModel { let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier:"ko_KR") if calender.compare(date, to: .now, toGranularity: .day) == .orderedSame { - dateFormatter.dateFormat = "a h시 m분" + dateFormatter.dateFormat = "오늘(E) a h시 m분" } else if calender.compare(date, to: yesterday, toGranularity: .day) == .orderedSame { dateFormatter.dateFormat = "어제(E) a h시 m분" } else { diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 4c826a7..c337f1e 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -40,10 +40,10 @@ class SectionHeaderView: UICollectionReusableView { } private func configureSubviews(){ - self.addSubview(monthLabel) - self.addSubview(countLabel) - self.addSubview(distanceLabel) - self.addSubview(timeLabel) + self.addSubview(self.monthLabel) + self.addSubview(self.countLabel) + self.addSubview(self.distanceLabel) + self.addSubview(self.timeLabel) } private func configureLayout() { @@ -69,9 +69,9 @@ class SectionHeaderView: UICollectionReusableView { extension SectionHeaderView { func configureVoiceOverAccessibility(date: String) { - guard let countLabel = countLabel.text else { return } - guard let distanceLabel = distanceLabel.text else { return } - guard let timeLabel = timeLabel.text else { return } + guard let countLabel = self.countLabel.text else { return } + guard let distanceLabel = self.distanceLabel.text else { return } + guard let timeLabel = self.timeLabel.text else { return } self.isAccessibilityElement = true self.accessibilityLabel = "\(date) 등산기록 정보" self.accessibilityTraits = .none diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index a2e5736..11db3ec 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -104,6 +104,6 @@ extension TotalRecordsViewCell { guard let stepsNumber = stepsNumber.text else { return } self.isAccessibilityElement = true self.accessibilityLabel = "전체 등산기록 정보" - self.accessibilityHint = "총 거리: \(kilometerNumber) 킬로미터, 총 등산횟수: \(countNumber), 총 시간: \(timeNumber), 총 걸음: \(stepsNumber) 걸음" + self.accessibilityHint = "총 거리: \(kilometerNumber)km, 총 등산횟수: \(countNumber), 총 시간: \(timeNumber), 총 걸음: \(stepsNumber)" } } From 80333cc3aa124a5ece57d721429309c651cda678 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 15:28:41 +0900 Subject: [PATCH 339/465] =?UTF-8?q?[Fix]=20#272=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20VoiceOver=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 4 ++-- SanTa/SanTa/ResultScene/SectionHeaderView.swift | 3 +-- SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index 7f14572..033b6a1 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -128,9 +128,9 @@ extension RecordsViewCell { } self.isAccessibilityElement = true - self.accessibilityLabel = "\(date) 등산기록 정보" + self.accessibilityLabel = "\(date) 등산기록 정보, 제목: \(title), 거리: \(distance)km, 시간: \(time), 고도차: \(altitude), 걸음: \(steps)" self.accessibilityTraits = .none - self.accessibilityHint = "제목: \(title), 거리: \(distance)km, 시간: \(time), 고도차: \(altitude), 걸음: \(steps)" + self.accessibilityHint = "등산기록 상세화면으로 넘어가려면 이중 탭 하십시오" } } diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index c337f1e..628e0c6 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -73,8 +73,7 @@ extension SectionHeaderView { guard let distanceLabel = self.distanceLabel.text else { return } guard let timeLabel = self.timeLabel.text else { return } self.isAccessibilityElement = true - self.accessibilityLabel = "\(date) 등산기록 정보" + self.accessibilityLabel = "\(date) 등산기록 정보, 총 등산횟수: \(countLabel), 총 거리: \(distanceLabel), 총 시간: \(timeLabel)" self.accessibilityTraits = .none - self.accessibilityHint = "총 등산횟수: \(countLabel), 총 거리: \(distanceLabel), 총 시간: \(timeLabel)" } } diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index 11db3ec..17f93ec 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -103,7 +103,6 @@ extension TotalRecordsViewCell { guard let timeNumber = timeNumber.text else { return } guard let stepsNumber = stepsNumber.text else { return } self.isAccessibilityElement = true - self.accessibilityLabel = "전체 등산기록 정보" - self.accessibilityHint = "총 거리: \(kilometerNumber)km, 총 등산횟수: \(countNumber), 총 시간: \(timeNumber), 총 걸음: \(stepsNumber)" + self.accessibilityLabel = "전체 등산기록 정보, 총 거리: \(kilometerNumber)km, 총 등산횟수: \(countNumber), 총 시간: \(timeNumber), 총 걸음: \(stepsNumber)" } } From dd9992a7ae77a7ac3fd920d524d7e44e65f00501 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 15:42:31 +0900 Subject: [PATCH 340/465] =?UTF-8?q?[Feat]=20#275,=20#276=20fetchAssetImage?= =?UTF-8?q?=20func=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift | 2 ++ .../ResultDetailScene/ResultDetailViewController.swift | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index fdf5cdf..89624bc 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -16,6 +16,7 @@ struct ResultDetailData { let altitude: ResultAltitude let incline: ResultIncline let id: String + let assetIdentifiers: [String] let coordinates: [[CLLocationCoordinate2D]] private(set) var title: String @@ -28,6 +29,7 @@ struct ResultDetailData { self.id = records.id self.title = records.title self.coordinates = records.coordinates + self.assetIdentifiers = records.assetIdentifiers } mutating func change(title: String) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 7599b53..fd0f47e 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -7,6 +7,7 @@ import UIKit import MapKit +import Photos class ResultDetailViewController: UIViewController { @@ -122,9 +123,17 @@ class ResultDetailViewController: UIViewController { startAnnotation.title = "start" endAnnotation.coordinate = endPoint endAnnotation.title = "end" + self.fetchAssetImage() self.mapView.addAnnotations([startAnnotation, endAnnotation]) } + private func fetchAssetImage() { + guard let reusltDetailData = self.viewModel?.resultDetailData else { return } + let allMedia = PHAsset.fetchAssets(with: .image, options: nil) + + let assetIdentifiers = reusltDetailData + } + private func configureSmallerView() { self.smallerInformationView = ResultDetailSmallerInfoView(frame: self.smallerInformationView.bounds) } From 4752d5fffc1f4ce97f75caafec81628909b7f62d Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 15:46:01 +0900 Subject: [PATCH 341/465] =?UTF-8?q?[Feat]=20#275,=20#276=20fetchAssetImage?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index fd0f47e..6a2aecd 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -128,10 +128,17 @@ class ResultDetailViewController: UIViewController { } private func fetchAssetImage() { - guard let reusltDetailData = self.viewModel?.resultDetailData else { return } + guard let assetIdentifiers = self.viewModel?.resultDetailData?.assetIdentifiers else { return } let allMedia = PHAsset.fetchAssets(with: .image, options: nil) - - let assetIdentifiers = reusltDetailData + var identifierIndex = 0 + for i in stride(from: allMedia.count - 1, through: 0, by: -1) { + if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { + + + identifierIndex += 1 + guard identifierIndex < assetIdentifiers.count else { return } + } + } } private func configureSmallerView() { From ae3b2e8d131ca2c63744f5a3e2682932b4727318 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 15:52:34 +0900 Subject: [PATCH 342/465] =?UTF-8?q?[Feat]=20#275,=20#276=20requestAssetIam?= =?UTF-8?q?ge=20func=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20ImageManager=20=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 6a2aecd..617cd26 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -19,6 +19,9 @@ class ResultDetailViewController: UIViewController { private var infoViewHight: CGFloat? private var isLargeInfoView = false + private let imageManager = PHCachingImageManager() + private var uiImages = [UIImage]() + private lazy var mapView: MKMapView = { let mapView = MKMapView() mapView.mapType = .mutedStandard @@ -133,14 +136,27 @@ class ResultDetailViewController: UIViewController { var identifierIndex = 0 for i in stride(from: allMedia.count - 1, through: 0, by: -1) { if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { - - + requestAssetIamge(with: allMedia[i]) { [weak self] image in + guard let image = image else { return } + self?.uiImages.append(image) + } identifierIndex += 1 guard identifierIndex < assetIdentifiers.count else { return } } } } + private func requestAssetIamge(with asset: PHAsset?, completion: @escaping (UIImage?) -> Void) { + guard let asset = asset else { + completion(nil) + return + } + let thumbnailSize = CGSize(width: 1000, height: 1000) + self.imageManager.requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil, resultHandler: { image, _ in + completion(image) + }) + } + private func configureSmallerView() { self.smallerInformationView = ResultDetailSmallerInfoView(frame: self.smallerInformationView.bounds) } From 823eb39f9ad573089875202cfe4a2c3c3b8dde79 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 16:10:30 +0900 Subject: [PATCH 343/465] =?UTF-8?q?[Feat]=20#275,=20276=20MapView=20Image?= =?UTF-8?q?=20Annotation=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 617cd26..2f0dba0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -139,6 +139,7 @@ class ResultDetailViewController: UIViewController { requestAssetIamge(with: allMedia[i]) { [weak self] image in guard let image = image else { return } self?.uiImages.append(image) + self?.appendAnnotationimage(image: image) } identifierIndex += 1 guard identifierIndex < assetIdentifiers.count else { return } @@ -157,6 +158,17 @@ class ResultDetailViewController: UIViewController { }) } + private func appendAnnotationimage(image: UIImage) { + let annotationView = MKAnnotationView() + + let annotationimageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)) + annotationimageView.image = image + + annotationView.addSubview(annotationimageView) + + mapView.addSubview(annotationView) + } + private func configureSmallerView() { self.smallerInformationView = ResultDetailSmallerInfoView(frame: self.smallerInformationView.bounds) } From 8ae4ac83ec9f930a2b840cb31d640811a6992656 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 16:14:40 +0900 Subject: [PATCH 344/465] =?UTF-8?q?[Feat]=20#276=20appendImageAnnotation?= =?UTF-8?q?=20func=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/ResultDetailViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2f0dba0..32f50ff 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -139,7 +139,7 @@ class ResultDetailViewController: UIViewController { requestAssetIamge(with: allMedia[i]) { [weak self] image in guard let image = image else { return } self?.uiImages.append(image) - self?.appendAnnotationimage(image: image) + self?.appendImageAnnotation(image: image) } identifierIndex += 1 guard identifierIndex < assetIdentifiers.count else { return } @@ -158,7 +158,7 @@ class ResultDetailViewController: UIViewController { }) } - private func appendAnnotationimage(image: UIImage) { + private func appendImageAnnotation(image: UIImage) { let annotationView = MKAnnotationView() let annotationimageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)) From 6d99b3fbd6bbebe8ad12ac671c1fceb1154d2306 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Tue, 23 Nov 2021 16:53:37 +0900 Subject: [PATCH 345/465] =?UTF-8?q?[Feat]=20=EC=83=81=EC=84=B8=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=ED=81=AC=EA=B8=B0=20=EB=B0=8F=20=EA=B0=84=EA=B2=A9?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/DetailCell.swift | 38 ++++++++++++++++--- .../ResultDetailScene/DetailHeader.swift | 4 +- .../ResultDetailViewController.swift | 1 - 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index ad41d9e..009ba74 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -14,21 +14,40 @@ class DetailCell: UICollectionViewCell { let title: UILabel = UILabel() self.addSubview(title) title.text = data.title + title.font = .preferredFont(for: .body, weight: .bold) + title.adjustsFontSizeToFitWidth = true title.textColor = .init(named: "SantaColor") title.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - title.topAnchor.constraint(equalTo: self.topAnchor), - title.leftAnchor.constraint(equalTo: self.leftAnchor) + title.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), + title.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10) ]) + let line = UIView() + self.addSubview(line) + + line.backgroundColor = .init(named: "SantaColor") + line.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + line.heightAnchor.constraint(equalToConstant: 1), + line.leftAnchor.constraint(equalTo: title.rightAnchor, constant: 5), + line.centerYAnchor.constraint(equalTo: title.centerYAnchor), + line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), + ]) + + + var contentLabels: [UILabel] = [] var contentTitleLabels: [UILabel] = [] for content in data.contents { let contentLabel = UILabel() contentLabel.text = content.content + contentLabel.font = .preferredFont(for: .title1, weight: .bold) + let contentTitleLabel = UILabel() contentTitleLabel.text = content.contentTitle + contentTitleLabel.font = .preferredFont(forTextStyle: .body) contentLabels.append(contentLabel) contentTitleLabels.append(contentTitleLabel) } @@ -40,6 +59,7 @@ class DetailCell: UICollectionViewCell { for index in 0.. UIFont { + let metrics = UIFontMetrics(forTextStyle: style) + let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style) + let font = UIFont.systemFont(ofSize: desc.pointSize, weight: weight) + return metrics.scaledFont(for: font) + } +} //extension DetailCell { // override func draw(_ rect: CGRect) { // let path = UIBezierPath() diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index 213258e..d35495c 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -10,8 +10,8 @@ import UIKit class DetailHeader: UICollectionReusableView { static let identifier = "DetailHeader" - private lazy var dateLabel: UILabel = { - let label = UILabel() + private lazy var dateLabel: PaddingLabel = { + let label = PaddingLabel(insets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) label.backgroundColor = .label label.textColor = .systemBackground label.text = "2021. 11. 16(화)" diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2d28e07..14b9267 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -122,7 +122,6 @@ class ResultDetailViewController: UIViewController { .reduce(initial) { $0.union($1.boundingMapRect) } mapView.setVisibleMapRect(mapRect, animated: true) - print(pointSets.count) let startAnnotation = MKPointAnnotation() let endAnnotation = MKPointAnnotation() guard let startPoint = pointSets.first?.first, From 1022105b4890fda4d5598b58cda07dad9adc871e Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 16:56:06 +0900 Subject: [PATCH 346/465] =?UTF-8?q?[Feat]=20DeatilHeader=20Dynamic=20Type?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/DetailHeader.swift | 40 +++++++++++++------ .../ResultDetailLargerInfoView.swift | 2 +- .../ResultDetailViewController.swift | 2 +- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index 213258e..dce990a 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -12,31 +12,37 @@ class DetailHeader: UICollectionReusableView { private lazy var dateLabel: UILabel = { let label = UILabel() - label.backgroundColor = .label label.textColor = .systemBackground + label.backgroundColor = .label + label.textAlignment = .center label.text = "2021. 11. 16(화)" label.font = .preferredFont(forTextStyle: .caption1) label.adjustsFontForContentSizeCategory = true + label.adjustsFontSizeToFitWidth = true label.translatesAutoresizingMaskIntoConstraints = false return label }() private lazy var startLabel: UILabel = { let label = UILabel() - label.textColor = UIColor(named: "SanTaColor") + label.textColor = UIColor(named: "SantaColor") label.text = "시작" - label.font = .preferredFont(forTextStyle: .title2) + label.textAlignment = .right + label.font = .preferredFont(forTextStyle: .title3) label.adjustsFontForContentSizeCategory = true + label.adjustsFontSizeToFitWidth = true label.translatesAutoresizingMaskIntoConstraints = false return label }() private lazy var endLabel: UILabel = { let label = UILabel() - label.textColor = UIColor(named: "SanTaColor") + label.textColor = UIColor(named: "SantaColor") label.text = "종료" - label.font = .preferredFont(forTextStyle: .title2) + label.textAlignment = .left + label.font = .preferredFont(forTextStyle: .title3) label.adjustsFontForContentSizeCategory = true + label.adjustsFontSizeToFitWidth = true label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -45,8 +51,11 @@ class DetailHeader: UICollectionReusableView { let label = UILabel() label.textColor = .label label.text = "오후 6시 0분" - label.font = .preferredFont(forTextStyle: .title1) + label.textAlignment = .right + label.numberOfLines = 2 + label.font = .preferredFont(forTextStyle: .title2) label.adjustsFontForContentSizeCategory = true + label.adjustsFontSizeToFitWidth = true label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -55,8 +64,11 @@ class DetailHeader: UICollectionReusableView { let label = UILabel() label.textColor = .label label.text = "오후 7시 38분" - label.font = .preferredFont(forTextStyle: .title1) + label.textAlignment = .left + label.numberOfLines = 2 + label.font = .preferredFont(forTextStyle: .title2) label.adjustsFontForContentSizeCategory = true + label.adjustsFontSizeToFitWidth = true label.translatesAutoresizingMaskIntoConstraints = false return label }() @@ -64,9 +76,8 @@ class DetailHeader: UICollectionReusableView { private lazy var labelStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 20 - stackView.alignment = .center stackView.axis = .horizontal - stackView.distribution = .fill + stackView.distribution = .fillEqually stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -74,9 +85,8 @@ class DetailHeader: UICollectionReusableView { private lazy var timeStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 20 - stackView.alignment = .center stackView.axis = .horizontal - stackView.distribution = .fill + stackView.distribution = .fillEqually stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() @@ -102,17 +112,21 @@ class DetailHeader: UICollectionReusableView { self.addSubview(self.timeStackView) NSLayoutConstraint.activate([ - self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), + self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor), self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), + self.labelStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + self.labelStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) NSLayoutConstraint.activate([ - self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 20), + self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 8), + self.timeStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + self.timeStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), ]) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 962e605..92dae9d 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -78,7 +78,7 @@ extension ResultDetailLargerInfoView { self.addSubview(self.collectionView) NSLayoutConstraint.activate([ - self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 30), + self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), self.collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor), self.collectionView.trailingAnchor.constraint(equalTo: self.trailingAnchor), self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 32f50ff..c239a33 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -135,6 +135,7 @@ class ResultDetailViewController: UIViewController { let allMedia = PHAsset.fetchAssets(with: .image, options: nil) var identifierIndex = 0 for i in stride(from: allMedia.count - 1, through: 0, by: -1) { + guard identifierIndex < assetIdentifiers.count else { return } if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { requestAssetIamge(with: allMedia[i]) { [weak self] image in guard let image = image else { return } @@ -142,7 +143,6 @@ class ResultDetailViewController: UIViewController { self?.appendImageAnnotation(image: image) } identifierIndex += 1 - guard identifierIndex < assetIdentifiers.count else { return } } } } From 55c58b4d982420c2ae3f57bfa928faaf302b2c5c Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Tue, 23 Nov 2021 17:11:12 +0900 Subject: [PATCH 347/465] =?UTF-8?q?[Refactor]=20Records=20=EC=97=90?= =?UTF-8?q?=EC=84=9C=20CoreLocation=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0,=20=EA=B0=9C=EB=B3=84=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EB=B7=B0=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 11 ----- .../ResultDetailScene/ResultDetailModel.swift | 4 +- .../ResultDetailViewController.swift | 46 +++++++++++-------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index bff49b3..927b157 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -6,7 +6,6 @@ // import Foundation -import CoreLocation class TotalRecords { private(set) var totalRecords: [DateSeperateRecords] = [] @@ -142,12 +141,6 @@ struct Records { return max - min } - var coordinates: [[CLLocationCoordinate2D]] { - var coordinates: [[Location]] = [] - self.records.forEach{coordinates.append($0.locations)} - return coordinates.map{$0.map{$0.inCoordinates()}} - } - mutating func configureTitle(title: String) { self.title = title } @@ -185,8 +178,4 @@ struct Location { let latitude: Double let longitude: Double let altitude: Double - - func inCoordinates() -> CLLocationCoordinate2D { - return CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude) - } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index 5379fe6..f48d985 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -28,7 +28,9 @@ struct ResultDetailData { self.incline = ResultIncline(records: records) self.id = records.id self.title = records.title - self.coordinates = records.coordinates + var locations: [[CLLocationCoordinate2D]] = [] + records.records.forEach { locations.append($0.locations.map {CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) }) } + self.coordinates = locations } mutating func change(title: String) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 14b9267..df5fcec 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -109,28 +109,36 @@ class ResultDetailViewController: UIViewController { } viewModel?.setUp() - guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { + self.drawPathOnMap() + self.markEndPoints() + } + + private func drawPathOnMap() { + guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates, + let initial = mapView.overlays.first?.boundingMapRect else { return } for pointSet in pointSets { mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) } - guard let initial = mapView.overlays.first?.boundingMapRect else { return } - - let mapRect = mapView.overlays - .dropFirst() - .reduce(initial) { $0.union($1.boundingMapRect) } - - mapView.setVisibleMapRect(mapRect, animated: true) - let startAnnotation = MKPointAnnotation() - let endAnnotation = MKPointAnnotation() - guard let startPoint = pointSets.first?.first, - let endPoint = pointSets.last?.last else { + + let mapRect = mapView.overlays.dropFirst().reduce(initial) { $0.union($1.boundingMapRect) } + mapView.setVisibleMapRect(mapRect, animated: true) + } + + private func markEndPoints() { + guard let startingLocation = self.viewModel?.resultDetailData?.timeStamp.startLocation, + let endingLocation = self.viewModel?.resultDetailData?.timeStamp.endLocation else { return } - startAnnotation.coordinate = startPoint + + let startAnnotation = MKPointAnnotation() + let endAnnotation = MKPointAnnotation() + let startingPoint = CLLocationCoordinate2D(latitude: startingLocation.latitude, longitude: startingLocation.longitude) + let endingPoint = CLLocationCoordinate2D(latitude: endingLocation.latitude, longitude: endingLocation.longitude) + startAnnotation.coordinate = startingPoint startAnnotation.title = "start" - endAnnotation.coordinate = endPoint + endAnnotation.coordinate = endingPoint endAnnotation.title = "end" self.mapView.addAnnotations([startAnnotation, endAnnotation]) } @@ -155,7 +163,7 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) self.view.addSubview(self.titleLabel) - + NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), @@ -193,7 +201,7 @@ class ResultDetailViewController: UIViewController { ]) infoViewTopConstraint = - self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) + self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewTopConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) @@ -235,12 +243,12 @@ class ResultDetailViewController: UIViewController { guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10), let infoViewHight = self.infoViewHight, infoViewHight < (informationViewHeight - (translation.y + offset)) else { - return - } + return + } self.smallerInformationView.layer.cornerRadius = 13 self.largerInformationView.layer.cornerRadius = 13 self.changeInfoViewTopConstraints(traslation: translation.y + offset) - + case .ended: if self.smallerInformationView.frame.minY <= self.view.frame.height/2 { self.smallerInformationView.alpha = 0 From c6ae28932735e7922fb75fcd9990d91df3ed6d7d Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Tue, 23 Nov 2021 17:18:00 +0900 Subject: [PATCH 348/465] =?UTF-8?q?[Fix]=20=EA=B0=9C=EB=B3=84=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=20=EC=A4=8C=EC=9D=B8=20=EB=90=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailViewController.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index df5fcec..17c102f 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -114,13 +114,15 @@ class ResultDetailViewController: UIViewController { } private func drawPathOnMap() { - guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates, - let initial = mapView.overlays.first?.boundingMapRect else { + guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { return } for pointSet in pointSets { mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) } + guard let initial = mapView.overlays.first?.boundingMapRect else { + return + } let mapRect = mapView.overlays.dropFirst().reduce(initial) { $0.union($1.boundingMapRect) } mapView.setVisibleMapRect(mapRect, animated: true) @@ -131,7 +133,7 @@ class ResultDetailViewController: UIViewController { let endingLocation = self.viewModel?.resultDetailData?.timeStamp.endLocation else { return } - + print(startingLocation, endingLocation) let startAnnotation = MKPointAnnotation() let endAnnotation = MKPointAnnotation() let startingPoint = CLLocationCoordinate2D(latitude: startingLocation.latitude, longitude: startingLocation.longitude) From 91525af73d806bbc3109dde544d7942176283e55 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 23 Nov 2021 17:21:07 +0900 Subject: [PATCH 349/465] =?UTF-8?q?[Refactor]=20#282=20=EC=9E=A5=EC=86=8C?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D=20=ED=99=94=EB=A9=B4=20=EB=A6=AC=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CoreData 주입, Alert, 컨벤션, 순환참조 제거 --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 8 ++++-- .../MountainAddingView.swift | 20 ++++++++------- .../MountainAddingViewController.swift | 19 ++++++++++++-- .../MountainAddingViewCoordinator.swift | 6 +++-- .../MountainAddingViewModel.swift | 25 +++++++++---------- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 9fab5b9..300cfbc 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -43,7 +43,8 @@ extension MapViewCoordinator { let recordingViewCoordinator = RecordingViewCoordinator( navigationController: self.navigationController, userDefaultsStorage: self.userDefaultsStorage, - coreDataStorage: self.coreDataStorage) + coreDataStorage: self.coreDataStorage + ) self.childCoordinators.append(recordingViewCoordinator) recordingViewCoordinator.parentCoordinator = self } @@ -59,7 +60,10 @@ extension MapViewCoordinator { } func presentMountainAddingViewController() { - let mountainAddingViewCoordinator = MountainAddingViewCoordinator(navigationController: self.navigationController) + let mountainAddingViewCoordinator = MountainAddingViewCoordinator( + navigationController: self.navigationController, + coreDataStorage: self.coreDataStorage + ) mountainAddingViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainAddingViewCoordinator) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift index 4fa4bf7..ec2c2c3 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift @@ -7,7 +7,7 @@ import UIKit -protocol NewPlaceAddable { +protocol NewPlaceAddable: AnyObject { func userDidTypeWrong() func newPlaceShouldAdd(title: String, description: String) } @@ -77,10 +77,9 @@ class MountainAddingView: UIScrollView { return button }() - var newPlaceDelegate: NewPlaceAddable? + weak var newPlaceDelegate: NewPlaceAddable? func configure() { - self.isScrollEnabled = true self.backgroundColor = .systemBackground self.translatesAutoresizingMaskIntoConstraints = false self.configureSubViews() @@ -101,13 +100,13 @@ class MountainAddingView: UIScrollView { private func configureLayout() { NSLayoutConstraint.activate([ - self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), - self.titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.titleLabel.topAnchor.constraint(equalTo: self.contentLayoutGuide.topAnchor, constant: 20), + self.titleLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), ]) NSLayoutConstraint.activate([ self.nameLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 20), - self.nameLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.nameLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), ]) NSLayoutConstraint.activate([ @@ -118,7 +117,7 @@ class MountainAddingView: UIScrollView { NSLayoutConstraint.activate([ self.descriptionLabel.topAnchor.constraint(equalTo: self.nameTextField.bottomAnchor, constant: 20), - self.descriptionLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.descriptionLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), ]) NSLayoutConstraint.activate([ @@ -137,8 +136,11 @@ class MountainAddingView: UIScrollView { } @objc private func registerTouched() { - guard let title = nameTextField.text, !title.isEmpty, - let description = descriptionTextView.text, descriptionTextView.textColor != .systemGray3, !description.isEmpty + guard let title = self.nameTextField.text, + let description = self.descriptionTextView.text, + descriptionTextView.textColor != .systemGray3, + !description.isEmpty, + !title.isEmpty else { self.newPlaceDelegate?.userDidTypeWrong() return diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index a3dd02b..55e40ea 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -75,7 +75,13 @@ class MountainAddingViewController: UIViewController { self?.configureAnnotation(coordinate) }) .store(in: &observers) - mapView.showsUserLocation = true + self.viewModel?.addMountainResult + .receive(on: DispatchQueue.main) + .sink(receiveValue: { [weak self] result in + self?.showResult(result) + }) + .store(in: &observers) + self.mapView.showsUserLocation = true } private func configureLocation(_ coordinate: CLLocationCoordinate2D?) { @@ -91,6 +97,15 @@ class MountainAddingViewController: UIViewController { self.mapView.addAnnotation(mountainAnnotation) } + private func showResult(_ result: MountainAddingViewModel.AddMountainResult) { + let alert = UIAlertController(title: "산 추가하기", message: result.rawValue, preferredStyle: .alert) + let confirm = UIAlertAction(title: "확인", style: .default) { [weak self] _ in + self?.dismissViewController() + } + alert.addAction(confirm) + self.present(alert, animated: true) + } + @objc func dismissViewController() { self.coordinator?.dismiss() } @@ -119,6 +134,6 @@ extension MountainAddingViewController: NewPlaceAddable { } func newPlaceShouldAdd(title: String, description: String) { - viewModel?.addMountain(title: title, description: description) + self.viewModel?.addMountain(title: title, description: description) } } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift index e362d48..eddc0fa 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift @@ -11,9 +11,11 @@ class MountainAddingViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] + var coreDataStorage: CoreDataStorage - init(navigationController: UINavigationController) { + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage) { self.navigationController = navigationController + self.coreDataStorage = coreDataStorage } func start() { @@ -30,7 +32,7 @@ extension MountainAddingViewCoordinator { useCase: MountainAddingViewUseCase( repository: DefaultMountainAddingRepository( coreDataMountainStorage: CoreDataMountainStorage( - coreDataStorage: CoreDataStorage() // TODO - 변경필요 + coreDataStorage: self.coreDataStorage ) ) ) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index cb94381..a61d8a5 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -13,6 +13,12 @@ class MountainAddingViewModel { private var useCase: MountainAddingViewUseCase? @Published private(set) var coordinate: CLLocationCoordinate2D? private(set) var altitude: CLLocationDistance? + let addMountainResult = PassthroughSubject() + + enum AddMountainResult: String { + case success = "저장에 성공하였습니다." + case failure = "저장에 실패하였습니다." + } init(useCase: MountainAddingViewUseCase) { self.useCase = useCase @@ -27,19 +33,12 @@ class MountainAddingViewModel { guard let coordinate = coordinate, let altitude = altitude else { return } - self.useCase?.saveMountain( - name: title, - altitude: altitude, - latitude: coordinate.latitude, - longitude: coordinate.longitude, - description: description, - completion: { result in - guard result != nil else { - print("저장안됨") - return - } - print("저장됨") + self.useCase?.saveMountain(name: title, altitude: altitude, latitude: coordinate.latitude, longitude: coordinate.longitude, description: description) { [weak self] result in + guard result != nil else { + self?.addMountainResult.send(.failure) + return } - ) + self?.addMountainResult.send(.success) + } } } From d499b33f4972f0480c2c90b19c23f0d266d0fd36 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 17:27:35 +0900 Subject: [PATCH 350/465] =?UTF-8?q?[Refactor]=20#284=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=9E=90=EB=8F=99=20=EC=9D=BC=EC=8B=9C?= =?UTF-8?q?=EC=A0=95=EC=A7=80/=EC=9E=AC=EC=8B=9C=EC=9E=91=20=ED=95=AD?= =?UTF-8?q?=EB=AA=A9=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Persistences/UserDefaultsStorage.swift | 8 -------- SanTa/SanTa/SettingsScene/Settings.swift | 6 ------ SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 8 -------- SanTa/SettingsSceneTests/SettingsUsecaseTests.swift | 2 -- 4 files changed, 24 deletions(-) diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index dced7af..6651dd8 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -47,14 +47,6 @@ final class DefaultUserDefaultsStorage: UserDefaultsStorage { self.save(value: Settings.photosOnMap.initValue as? Bool, key: .photosOnMap) } - if !self.exist(key: .autoPauseResume) { - self.save(value: Settings.autoPauseResume.initValue as? Bool, - key: .autoPauseResume) - } - if !self.exist(key: .autoPauseResumeVoiceGuidance) { - self.save(value: Settings.autoPauseResumeVoiceGuidance.initValue as? Bool, - key: .autoPauseResumeVoiceGuidance) - } if !self.exist(key: .voiceGuidanceEveryOnekm) { self.save(value: Settings.voiceGuidanceEveryOnekm.initValue as? Bool, key: .voiceGuidanceEveryOnekm) diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/SettingsScene/Settings.swift index 13c5327..e9717c1 100644 --- a/SanTa/SanTa/SettingsScene/Settings.swift +++ b/SanTa/SanTa/SettingsScene/Settings.swift @@ -10,8 +10,6 @@ import Foundation enum Settings: String, CaseIterable { case recordPhoto = "사진 기록하기" case photosOnMap = "지도에 사진표시" - case autoPauseResume = "자동 일시정지, 재시작" - case autoPauseResumeVoiceGuidance = "자동 일시정지, 재시작 음성 안내" case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" case mapFormat = "지도 형식" @@ -25,10 +23,6 @@ enum Settings: String, CaseIterable { return true case .photosOnMap: return true - case .autoPauseResume: - return false - case .autoPauseResumeVoiceGuidance: - return false case .voiceGuidanceEveryOnekm: return true case .mapFormat: diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 3f330d4..53992d6 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -27,7 +27,6 @@ final class DefaultSettingsUsecase: SettingsUsecase { func makeSettings() -> [[Option]] { var options: [[Option]] = [] var photoSettings: [Option] = [] - var autoSettins: [Option] = [] var voiceSettings: [Option] = [] var mapSetting: [Option] = [] @@ -37,12 +36,6 @@ final class DefaultSettingsUsecase: SettingsUsecase { self.settingsRepository.makeToggleOption(key: Settings.photosOnMap) { value in photoSettings.append(value) } - self.settingsRepository.makeToggleOption(key: Settings.autoPauseResume) { value in - autoSettins.append(value) - } - self.settingsRepository.makeToggleOption(key: Settings.autoPauseResumeVoiceGuidance) { value in - autoSettins.append(value) - } self.settingsRepository.makeToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in voiceSettings.append(value) } @@ -51,7 +44,6 @@ final class DefaultSettingsUsecase: SettingsUsecase { } options.append(photoSettings) - options.append(autoSettins) options.append(voiceSettings) options.append(mapSetting) diff --git a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift index b47b1a3..97428fa 100644 --- a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift +++ b/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift @@ -40,7 +40,6 @@ class SettingsUsecaseTests: XCTestCase { let option4 = options[1][1] as? ToggleOption let option5 = options[2][0] as? ToggleOption let option6 = options[3][0] as? MapOption - let option7 = options[3][1] as? ToggleOption XCTAssertNotNil(option1) XCTAssertNotNil(option2) @@ -48,7 +47,6 @@ class SettingsUsecaseTests: XCTestCase { XCTAssertNotNil(option4) XCTAssertNotNil(option5) XCTAssertNotNil(option6) - XCTAssertNotNil(option7) } } From def997ce588e3a38c0dcd882d8dff96ba6e59390 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 17:29:13 +0900 Subject: [PATCH 351/465] =?UTF-8?q?[Refactor]=20#284=20SettingsUseCase=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=86=A0=EC=BD=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 7 +------ SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 53992d6..2eaf011 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -7,12 +7,7 @@ import Foundation -protocol SettingsUsecase { - func save(value: T, key: Settings) - func makeSettings() -> [[Option]] -} - -final class DefaultSettingsUsecase: SettingsUsecase { +final class SettingsUsecase { let settingsRepository: SettingsRepository diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 50f9e92..4d70cd9 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -32,7 +32,7 @@ class SettingsViewCoordinator: Coordinator { extension SettingsViewCoordinator { private func injectDependencies() -> SettingsViewModel { return SettingsViewModel( - settingsUseCase: DefaultSettingsUsecase( + settingsUseCase: SettingsUsecase( settingsRepository: DefaultSettingsRepository( settingsStorage: self.userDefaultsStorage ) From 649311f9282ac8ffb6ccb682c0f6d2a6d6f7866e Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Tue, 23 Nov 2021 17:43:37 +0900 Subject: [PATCH 352/465] =?UTF-8?q?[Refactor]=20#284=20Settings=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=9C=A0=EB=8B=9B=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 12 ++--- ...seTests.swift => SettingsSceneTests.swift} | 36 +++++++------ .../SettingsViewModelTests.swift | 50 ------------------- 3 files changed, 26 insertions(+), 72 deletions(-) rename SanTa/SettingsSceneTests/{SettingsUsecaseTests.swift => SettingsSceneTests.swift} (53%) delete mode 100644 SanTa/SettingsSceneTests/SettingsViewModelTests.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index b7105a4..5b93ad4 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -65,8 +65,7 @@ 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821E273CE16E006A847A /* ResultUseCase.swift */; }; 9826F3DD2739035E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 9826F3DF273904010064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; - 9826F436273954020064FA85 /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */; }; - 9826F437273954030064FA85 /* SettingsUsecaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */; }; + 9826F436273954020064FA85 /* SettingsSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F425273925BF0064FA85 /* SettingsSceneTests.swift */; }; 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; @@ -178,8 +177,7 @@ 9800821E273CE16E006A847A /* ResultUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultUseCase.swift; sourceTree = ""; }; 9826F3DC2739035E0064FA85 /* Option.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Option.swift; sourceTree = ""; }; 9826F3DE273904010064FA85 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; - 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelTests.swift; sourceTree = ""; }; - 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecaseTests.swift; sourceTree = ""; }; + 9826F425273925BF0064FA85 /* SettingsSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSceneTests.swift; sourceTree = ""; }; 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SettingsSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 984DDEC027325D67003BE56B /* Record.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = ""; }; 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCase.swift; sourceTree = ""; }; @@ -443,8 +441,7 @@ 9826F42E273953FB0064FA85 /* SettingsSceneTests */ = { isa = PBXGroup; children = ( - 9826F425273925BF0064FA85 /* SettingsViewModelTests.swift */, - 9826F427273926720064FA85 /* SettingsUsecaseTests.swift */, + 9826F425273925BF0064FA85 /* SettingsSceneTests.swift */, ); path = SettingsSceneTests; sourceTree = ""; @@ -697,8 +694,7 @@ 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, 9826F43C2739546E0064FA85 /* Settings.swift in Sources */, 9826F43D2739546E0064FA85 /* Option.swift in Sources */, - 9826F437273954030064FA85 /* SettingsUsecaseTests.swift in Sources */, - 9826F436273954020064FA85 /* SettingsViewModelTests.swift in Sources */, + 9826F436273954020064FA85 /* SettingsSceneTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift b/SanTa/SettingsSceneTests/SettingsSceneTests.swift similarity index 53% rename from SanTa/SettingsSceneTests/SettingsUsecaseTests.swift rename to SanTa/SettingsSceneTests/SettingsSceneTests.swift index 97428fa..2a58718 100644 --- a/SanTa/SettingsSceneTests/SettingsUsecaseTests.swift +++ b/SanTa/SettingsSceneTests/SettingsSceneTests.swift @@ -1,5 +1,5 @@ // -// SettingsUseCaseTests.swift +// SettingsViewModelTests.swift // SettingsTests // // Created by CHANGMIN OH on 2021/11/08. @@ -7,7 +7,7 @@ import XCTest -class SettingsUsecaseTests: XCTestCase { +class SettingsViewModelTests: XCTestCase { class MockRepository: SettingsRepository { func save(value: T, key: Settings) where T : Decodable, T : Encodable { @@ -23,30 +23,38 @@ class SettingsUsecaseTests: XCTestCase { } } + private var viewModel: SettingsViewModel! private var useCase: SettingsUsecase! - private var repository: MockRepository! override func setUpWithError() throws { - repository = MockRepository() - useCase = DefaultSettingsUsecase(settingsRepository: repository) + useCase = SettingsUsecase(settingsRepository: MockRepository()) + viewModel = SettingsViewModel(settingsUseCase: useCase) } - func test_repository반환_값에_따른_배열생성() { - let options = useCase.makeSettings() + func test_ViewModel은_viewDidLoad시_UseCase의_반환값_settings프로퍼티에_세팅() throws { + viewModel.viewDidLoad() + XCTAssertEqual(viewModel.sectionCount, 3) + } + + func test_ViewModel은_change호출시_문자열이면_settings프로퍼티_업데이트() throws { + viewModel.change(value: 1, key: .mapFormat) + XCTAssertEqual(viewModel.sectionCount, 0) + viewModel.change(value: "string", key: .mapFormat) + XCTAssertEqual(viewModel.sectionCount, 3) + } + + func test_UseCase는_repository반환_값에_따른_배열생성() { + let options = useCase.makeSettings() + let option1 = options[0][0] as? ToggleOption let option2 = options[0][1] as? ToggleOption let option3 = options[1][0] as? ToggleOption - let option4 = options[1][1] as? ToggleOption - let option5 = options[2][0] as? ToggleOption - let option6 = options[3][0] as? MapOption - + let option4 = options[2][0] as? MapOption + XCTAssertNotNil(option1) XCTAssertNotNil(option2) XCTAssertNotNil(option3) XCTAssertNotNil(option4) - XCTAssertNotNil(option5) - XCTAssertNotNil(option6) } } - diff --git a/SanTa/SettingsSceneTests/SettingsViewModelTests.swift b/SanTa/SettingsSceneTests/SettingsViewModelTests.swift deleted file mode 100644 index c972c3d..0000000 --- a/SanTa/SettingsSceneTests/SettingsViewModelTests.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// SettingsViewModelTests.swift -// SettingsTests -// -// Created by CHANGMIN OH on 2021/11/08. -// - -import XCTest - -class SettingsViewModelTests: XCTestCase { - - class MockUseCase: SettingsUsecase { - - let options: [[Option]] = [[MapOption(text: "맵", map: .infomation)]] - - func save(value: T, key: Settings) { - - } - - func makeSettings() -> [[Option]] { - return options - } - } - - private var viewModel: SettingsViewModel! - private var useCase: MockUseCase! - - override func setUpWithError() throws { - useCase = MockUseCase() - viewModel = SettingsViewModel(settingsUseCase: useCase) - } - - func test_viewDidLoad시_UseCase의_반환값_settings프로퍼티에_세팅() throws { - viewModel.viewDidLoad() - guard let mapOption = viewModel.settings[0][0] as? MapOption else { return } - XCTAssertEqual(mapOption.text, "맵") - XCTAssertEqual(mapOption.map, .infomation) - } - - func test_change호출시_문자열이면_settings프로퍼티_업데이트() throws { - viewModel.change(value: 1, key: .mapFormat) - XCTAssertEqual(viewModel.sectionCount, 0) - - viewModel.change(value: "string", key: .mapFormat) - let mapOption = viewModel.settings[0][0] as? MapOption - XCTAssertNotNil(mapOption) - XCTAssertEqual(mapOption?.text, "맵") - XCTAssertEqual(mapOption?.map, .infomation) - } -} From d600e788d030143342d405255f0db57f68fcd57d Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 20:00:39 +0900 Subject: [PATCH 353/465] =?UTF-8?q?[Feat]=20#276=20Annotation=20Point?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index c239a33..acf9945 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -20,7 +20,7 @@ class ResultDetailViewController: UIViewController { private var isLargeInfoView = false private let imageManager = PHCachingImageManager() - private var uiImages = [UIImage]() + private var uiImages = [String: UIImage]() private lazy var mapView: MKMapView = { let mapView = MKMapView() @@ -137,36 +137,34 @@ class ResultDetailViewController: UIViewController { for i in stride(from: allMedia.count - 1, through: 0, by: -1) { guard identifierIndex < assetIdentifiers.count else { return } if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { - requestAssetIamge(with: allMedia[i]) { [weak self] image in - guard let image = image else { return } - self?.uiImages.append(image) - self?.appendImageAnnotation(image: image) + requestAssetIamge(with: allMedia[i]) { [weak self] (image, asset) in + guard let image = image, + let identifier = asset?.localIdentifier, + let coordinate = asset?.location?.coordinate else { return } + self?.uiImages[identifier] = image + self?.appendImageAnnotation(identifier: identifier, location: coordinate) } identifierIndex += 1 } } } - private func requestAssetIamge(with asset: PHAsset?, completion: @escaping (UIImage?) -> Void) { + private func requestAssetIamge(with asset: PHAsset?, completion: @escaping (UIImage?, PHAsset?) -> Void) { guard let asset = asset else { - completion(nil) + completion(nil, nil) return } let thumbnailSize = CGSize(width: 1000, height: 1000) self.imageManager.requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil, resultHandler: { image, _ in - completion(image) + completion(image, asset) }) } - private func appendImageAnnotation(image: UIImage) { - let annotationView = MKAnnotationView() - - let annotationimageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 25, height: 25)) - annotationimageView.image = image - - annotationView.addSubview(annotationimageView) - - mapView.addSubview(annotationView) + private func appendImageAnnotation(identifier: String, location: CLLocationCoordinate2D) { + let imageAnnotation = MKPointAnnotation() + imageAnnotation.coordinate = location + imageAnnotation.title = identifier + mapView.addAnnotation(imageAnnotation) } private func configureSmallerView() { @@ -367,10 +365,12 @@ extension ResultDetailViewController: MKMapViewDelegate { } let identifier = "PointAnnotation" + + let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier) if annotation.title == "start" { annotationView.markerTintColor = .init(named: "SantaColor") - } else { + } else if annotation.title = "end" { annotationView.markerTintColor = .red } annotationView.animatesWhenAdded = true From f727d24f3c4bd837cbb65a2dd51111e116e98730 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 20:02:57 +0900 Subject: [PATCH 354/465] =?UTF-8?q?[Feat]=20#276=20image=20Annotation=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailViewController.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index acf9945..2556785 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -370,8 +370,14 @@ extension ResultDetailViewController: MKMapViewDelegate { let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier) if annotation.title == "start" { annotationView.markerTintColor = .init(named: "SantaColor") - } else if annotation.title = "end" { + } else if annotation.title == "end" { annotationView.markerTintColor = .red + } else { + guard let identifider = annotation.title, + let image = self.uiImages[identifider] else { + return nil + } + annotationView.image = image } annotationView.animatesWhenAdded = true return annotationView From 519b427eb5eea955285d321b83a244c7490ad150 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 20:42:13 +0900 Subject: [PATCH 355/465] [Feat] #276 image resize --- .../ResultDetailViewController.swift | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2556785..3c04487 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -367,19 +367,25 @@ extension ResultDetailViewController: MKMapViewDelegate { let identifier = "PointAnnotation" - let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier) + let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier) if annotation.title == "start" { - annotationView.markerTintColor = .init(named: "SantaColor") + annotationView.tintColor = .init(named: "SantaColor") } else if annotation.title == "end" { - annotationView.markerTintColor = .red + annotationView.tintColor = .red } else { guard let identifider = annotation.title, - let image = self.uiImages[identifider] else { + let image = self.uiImages[identifider ?? "None"] else { return nil } - annotationView.image = image + + let size = CGSize(width: 30, height: 30) + UIGraphicsBeginImageContextWithOptions(size, false, 0.0) + image.draw(in: CGRect(origin: CGPoint.zero, size: size)) + let resizedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + annotationView.image = resizedImage } - annotationView.animatesWhenAdded = true return annotationView } } From c3ba304f8dd21dc88ea291f72799c85a55d015ab Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Tue, 23 Nov 2021 18:28:44 +0900 Subject: [PATCH 356/465] =?UTF-8?q?[Refactor]=20#286=20=EA=B0=9C=EB=B3=84?= =?UTF-8?q?=20=EA=B8=B0=EB=A1=9D=ED=99=94=EB=A9=B4=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/DetailCell.swift | 5 ++++- .../ResultDetailScene/ResultDetailViewController.swift | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index 009ba74..96f4a7a 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -15,6 +15,7 @@ class DetailCell: UICollectionViewCell { self.addSubview(title) title.text = data.title title.font = .preferredFont(for: .body, weight: .bold) + title.numberOfLines = 0 title.adjustsFontSizeToFitWidth = true title.textColor = .init(named: "SantaColor") title.translatesAutoresizingMaskIntoConstraints = false @@ -25,7 +26,7 @@ class DetailCell: UICollectionViewCell { let line = UIView() self.addSubview(line) - + line.backgroundColor = .init(named: "SantaColor") line.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ @@ -44,10 +45,12 @@ class DetailCell: UICollectionViewCell { let contentLabel = UILabel() contentLabel.text = content.content contentLabel.font = .preferredFont(for: .title1, weight: .bold) + contentLabel.numberOfLines = 0 let contentTitleLabel = UILabel() contentTitleLabel.text = content.contentTitle contentTitleLabel.font = .preferredFont(forTextStyle: .body) + contentTitleLabel.numberOfLines = 0 contentLabels.append(contentLabel) contentTitleLabels.append(contentTitleLabel) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 17c102f..942a0a3 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -81,6 +81,12 @@ class ResultDetailViewController: UIViewController { super.viewDidLoad() self.configureViews() self.mapView.delegate = self + self.configureViewModel() + self.drawPathOnMap() + self.markEndPoints() + } + + private func configureViewModel() { self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } self?.titleLabel.text = viewModel.resultDetailData?.title @@ -108,9 +114,6 @@ class ResultDetailViewController: UIViewController { self?.configurePanGesture() } viewModel?.setUp() - - self.drawPathOnMap() - self.markEndPoints() } private func drawPathOnMap() { @@ -133,7 +136,6 @@ class ResultDetailViewController: UIViewController { let endingLocation = self.viewModel?.resultDetailData?.timeStamp.endLocation else { return } - print(startingLocation, endingLocation) let startAnnotation = MKPointAnnotation() let endAnnotation = MKPointAnnotation() let startingPoint = CLLocationCoordinate2D(latitude: startingLocation.latitude, longitude: startingLocation.longitude) From 04834db09504d41a7d42a0d8e94db67624a02681 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 23 Nov 2021 22:26:51 +0900 Subject: [PATCH 357/465] =?UTF-8?q?[Feat]=20#288=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=9C=20=EC=82=B0=20=ED=99=95=EC=9D=B8=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 5 ++- SanTa/SanTa/MapScene/MapViewModel.swift | 4 +- SanTa/SanTa/MapScene/MapViewRepository.swift | 29 +++++++++++- .../MountainAddingViewModel.swift | 2 +- .../MountainAddingViewUseCase.swift | 44 ++++++++++++------- .../CoreDataMountainStorage.swift | 5 ++- .../SanTa.xcdatamodel/contents | 3 +- 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 300cfbc..dad41d4 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -85,7 +85,10 @@ extension MapViewCoordinator { useCase: MapViewUseCase( repository: DefaultMapViewRespository( mountainExtractor: self.mountainExtractor, - userDefaultsStorage: self.userDefaultsStorage + userDefaultsStorage: self.userDefaultsStorage, + coreDataMountainStorage: CoreDataMountainStorage( + coreDataStorage: self.coreDataStorage + ) ) ) ) diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index 11f98b0..b7d5a2b 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -17,11 +17,13 @@ final class MapViewModel { init(useCase: MapViewUseCase) { self.useCase = useCase + self.mountains = [] } func configureBindings() { self.useCase.prepareMountainMarkers { [weak self] mountains in - self?.mountains = mountains + guard let mountains = mountains else { return } + self?.mountains?.append(contentsOf: mountains) } self.useCase.initialLocation = { [weak self] initialLocation in self?.initialLocation = initialLocation diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index 1e9fa74..a4e9a53 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -27,10 +27,12 @@ class DefaultMapViewRespository { private let mountainExtractor: MountainExtractor private let settingsStorage: UserDefaultsStorage + private let coreDataMountainStorage: CoreDataMountainStorage - init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage) { + init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage, coreDataMountainStorage: CoreDataMountainStorage) { self.mountainExtractor = mountainExtractor self.settingsStorage = userDefaultsStorage + self.coreDataMountainStorage = coreDataMountainStorage } } @@ -47,6 +49,31 @@ extension DefaultMapViewRespository: MapViewRepository { completion(.success(decodedObjects)) } } + + self.coreDataMountainStorage.fetch { result in + switch result { + case .failure(let error): + return completion(.failure(error)) + case .success(let mountainEntityMOs): + var mountainEntities: [MountainEntity] = [] + mountainEntityMOs.forEach{ MO in + let mountain = MountainEntity.MountainDetail( + mountainName: MO.name ?? "", + mountainRegion: MO.region ?? "", + mountainHeight: MO.altitude ?? "", + mountainShortDescription: MO.descript ?? "" + ) + let mountainEntity = MountainEntity( + id: MO.id ?? UUID(), + mountain: mountain, + latitude: MO.latitude, + longitude: MO.longitude + ) + mountainEntities.append(mountainEntity) + } + completion(.success(mountainEntities)) + } + } } func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) { diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index a61d8a5..f3e4086 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -16,7 +16,7 @@ class MountainAddingViewModel { let addMountainResult = PassthroughSubject() enum AddMountainResult: String { - case success = "저장에 성공하였습니다." + case success = "저장에 성공하였습니다.\n앱 종료 및 재시작 시 적용됩니다." case failure = "저장에 실패하였습니다." } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift index 4b063ba..71dcd3c 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -6,6 +6,7 @@ // import Foundation +import CoreLocation import OSLog class MountainAddingViewUseCase { @@ -14,24 +15,37 @@ class MountainAddingViewUseCase { init(repository: MountainAddingRepository) { self.repository = repository } - func saveMountain(name: String, altitude: Double, latitude: Double, longitude: Double, description: String, completion: @escaping (Void?) -> Void) { - let mountainDetail = MountainEntity.MountainDetail( - mountainName: name, - mountainRegion: "", - mountainHeight: String(altitude), - mountainShortDescription: description - ) - let mountainEntity = MountainEntity(mountain: mountainDetail, latitude: latitude, longitude: longitude) - self.repository.save(mountainEntity) { result in - switch result { - case .success(): - completion(Void()) - case .failure(let error): - completion(nil) - os_log(.error, log: .default, "\(error.localizedDescription)") + self.userRegion(latitude: latitude, longitude: longitude) { [weak self] region in + let mountainDetail = MountainEntity.MountainDetail( + mountainName: name, + mountainRegion: region, + mountainHeight: String(altitude), + mountainShortDescription: description + ) + let mountainEntity = MountainEntity(mountain: mountainDetail, latitude: latitude, longitude: longitude) + self?.repository.save(mountainEntity) { result in + switch result { + case .success(): + completion(Void()) + case .failure(let error): + completion(nil) + os_log(.error, log: .default, "\(error.localizedDescription)") + } + } + } + } + + private func userRegion(latitude: Double, longitude: Double, completion: @escaping (String) -> Void) { + let location = CLLocation(latitude: latitude, longitude: longitude) + CLGeocoder().reverseGeocodeLocation(location) { placeMark, error in + guard error == nil else{ + completion("") + return } + let region = [placeMark?.first?.administrativeArea, placeMark?.first?.locality, placeMark?.first?.subLocality].compactMap{ $0 }.joined(separator: " ") + completion(region) } } } diff --git a/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift index 6ca9d9d..ee44673 100644 --- a/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift @@ -29,10 +29,11 @@ final class CoreDataMountainStorage: MountainStorage { self.coreDataStroage.performBackgroundTask { context in let object = NSEntityDescription.insertNewObject(forEntityName: "MountainEntity", into: context) object.setValue(mountainEntity.id, forKey: "id") - object.setValue(mountainEntity.mountain.mountainName, forKey: "name") - object.setValue(mountainEntity.mountain.mountainHeight, forKey: "altitude") object.setValue(mountainEntity.latitude, forKey: "latitude") object.setValue(mountainEntity.longitude, forKey: "longitude") + object.setValue(mountainEntity.mountain.mountainName, forKey: "name") + object.setValue(mountainEntity.mountain.mountainRegion, forKey: "region") + object.setValue(mountainEntity.mountain.mountainHeight, forKey: "altitude") object.setValue(mountainEntity.mountain.mountainShortDescription, forKey: "descript") do { diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index 305533f..ab8ada9 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -13,6 +13,7 @@ + @@ -32,8 +33,8 @@ + - \ No newline at end of file From dfbddfb6651b829ead73ca4b95932d7fe87345ff Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:03:51 +0900 Subject: [PATCH 358/465] =?UTF-8?q?[Feat]=20#278=20ResultDetailImagesViewC?= =?UTF-8?q?ontroller,=20ResultDetailImagesViewCoordinator=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 ++++++++++ .../ResultDetailImageViewCoordinator.swift | 30 +++++++++++++++++++ .../ResultDetailImagesViewController.swift | 16 ++++++++++ 3 files changed, 62 insertions(+) create mode 100644 SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift create mode 100644 SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index b7105a4..5138596 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -101,6 +101,8 @@ DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; + DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */; }; + DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */; }; DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; @@ -204,6 +206,8 @@ DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; + DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewController.swift; sourceTree = ""; }; + DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImageViewCoordinator.swift; sourceTree = ""; }; DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoModel.swift; sourceTree = ""; }; @@ -416,6 +420,7 @@ 54731B61272F7F7600534097 /* MapScene */, 54B32063274510B7002232BD /* MountainAddingScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, + DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */, 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, @@ -466,6 +471,15 @@ path = RecordingTitleScene; sourceTree = ""; }; + DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */ = { + isa = PBXGroup; + children = ( + DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */, + DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */, + ); + path = ResultDetailImagesScene; + sourceTree = ""; + }; DAFA9B55274112AB00BF168C /* RecordingPhotoScene */ = { isa = PBXGroup; children = ( @@ -640,6 +654,7 @@ 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, + DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */, 54B3206D27453725002232BD /* MountainAddingViewRepository.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, @@ -654,6 +669,7 @@ 54B32073274B7E09002232BD /* MountainAddingView.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */, + DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */, 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift new file mode 100644 index 0000000..69fab13 --- /dev/null +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift @@ -0,0 +1,30 @@ +// +// ResultDetailImageCoordinator.swift +// SanTa +// +// Created by 김민창 on 2021/11/23. +// + +import UIKit + +class ResultDetailImagesViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var childCoordinators: [Coordinator] = [] + var navigationController: UINavigationController + + func start() { + let resultDetailImagesViewController = ResultDetailImagesViewController() + resultDetailImagesViewController.coordinator = self + self.navigationController.setNavigationBarHidden(true, animated: false) + self.navigationController.pushViewController(resultDetailImagesViewController, animated: true) + } + + func dismiss() { + self.navigationController.popViewController(animated: true) + self.parentCoordinator?.childCoordinators.removeLast() + } + + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage, records: Records) { + self.navigationController = navigationController + } +} diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift new file mode 100644 index 0000000..ad89331 --- /dev/null +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -0,0 +1,16 @@ +// +// ResultDetailImagesViewController.swift +// SanTa +// +// Created by 김민창 on 2021/11/23. +// + +import UIKit + +class ResultDetailImagesViewController: UIViewController { + weak var coordinator: ResultDetailImagesViewCoordinator? + + override func viewDidLoad() { + super.viewDidLoad() + } +} From 77c350f0fd4a20368e0179e6883204aa52d06717 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:09:30 +0900 Subject: [PATCH 359/465] =?UTF-8?q?[Feat]=20#278=20pushResultDetailImagesV?= =?UTF-8?q?iewController=20func=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailImageViewCoordinator.swift | 2 +- .../ResultDetailImagesViewController.swift | 1 + .../ResultDetailScene/ResultDetailViewCoordinator.swift | 9 ++++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift index 69fab13..c2f9443 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift @@ -24,7 +24,7 @@ class ResultDetailImagesViewCoordinator: Coordinator { self.parentCoordinator?.childCoordinators.removeLast() } - init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage, records: Records) { + init(navigationController: UINavigationController) { self.navigationController = navigationController } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index ad89331..2a2f74a 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -12,5 +12,6 @@ class ResultDetailImagesViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + self.view.backgroundColor = .red } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 47d4ad2..72b2470 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -51,7 +51,6 @@ extension ResultDetailViewCoordinator { func presentRecordingTitleViewController() { guard let viewController = self.navigationController.viewControllers.last as? ResultDetailViewController else { - print("뷰컨 없음") return } let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(delegate: viewController) @@ -60,4 +59,12 @@ extension ResultDetailViewCoordinator { recordingTitleViewCoordinator.start() } + + func pushResultDetailImagesViewController() { + let resultDetailImagesViewCoordinator = ResultDetailImagesViewCoordinator(navigationController: navigationController) + self.childCoordinators.append(resultDetailImagesViewCoordinator) + resultDetailImagesViewCoordinator.parentCoordinator = self + + resultDetailImagesViewCoordinator.start() + } } From ccdf7a88242ffb20e2e88ef4579cf121f9060312 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:16:25 +0900 Subject: [PATCH 360/465] =?UTF-8?q?[Feat]=20#278=20DetailImagesViewControl?= =?UTF-8?q?ler=20push=20Button=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 3c04487..76637ed 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -69,6 +69,18 @@ class ResultDetailViewController: UIViewController { return button }() + private lazy var detailImagesButton: UIButton = { + let button = UIButton() + button.setImage(.init(systemName: "photo.on.rectangle.angled"), for: .normal) + button.imageView?.contentMode = .scaleAspectFit + button.titleLabel?.font = .boldSystemFont(ofSize: 12) + button.contentHorizontalAlignment = .center + button.semanticContentAttribute = .forceLeftToRight + button.imageEdgeInsets = .init(top: 0, left: 15, bottom: 0, right: 15) + button.addTarget(self, action: #selector(pushDetailImagesViewController), for: .touchUpInside) + return button + }()g + private var titleLabel: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) @@ -187,6 +199,7 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) self.view.addSubview(self.titleLabel) + self.view.addSubview(self.detailImagesButton) NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), @@ -305,6 +318,10 @@ extension ResultDetailViewController { coordinator?.dismiss() } + @objc func pushDetailImagesViewController() { + + } + @objc func presentModifyResultAlert() { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in From 18f7e8355e22aab80ff06fd86e4f600956b166da Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 23 Nov 2021 23:22:35 +0900 Subject: [PATCH 361/465] =?UTF-8?q?[Fix]=20#290=20=EC=9E=A5=EC=86=8C=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=99=94=EB=A9=B4=20=ED=82=A4=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainAddingView.swift | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift index ec2c2c3..99bedf5 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift @@ -79,13 +79,33 @@ class MountainAddingView: UIScrollView { weak var newPlaceDelegate: NewPlaceAddable? + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + super.touchesBegan(touches, with: event) + self.endEditing(true) + } + func configure() { self.backgroundColor = .systemBackground self.translatesAutoresizingMaskIntoConstraints = false self.configureSubViews() self.configureLayout() + self.configureNotification() } + private func configureNotification() { + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillShow), + name: UIResponder.keyboardDidShowNotification, + object: nil + ) + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillHide), + name: UIResponder.keyboardWillHideNotification, + object: nil + ) + } private func configureSubViews() { self.addSubview(titleLabel) @@ -94,6 +114,7 @@ class MountainAddingView: UIScrollView { self.addSubview(descriptionLabel) self.addSubview(descriptionTextView) self.addSubview(registerButton) + self.delegate = self self.nameTextField.delegate = self self.descriptionTextView.delegate = self } @@ -147,6 +168,21 @@ class MountainAddingView: UIScrollView { } self.newPlaceDelegate?.newPlaceShouldAdd(title: title, description: description) } + + @objc private func keyboardWillShow(_ notification: Notification) { + guard let userInfo = notification.userInfo, + let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect + else { return } + let contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardFrame.size.height, right: 0.0) + self.contentInset = contentInset + self.scrollIndicatorInsets = contentInset + } + + @objc private func keyboardWillHide(_ notification: Notification) { + let contentInset = UIEdgeInsets.zero + self.contentInset = contentInset + self.scrollIndicatorInsets = contentInset + } } extension MountainAddingView: UITextFieldDelegate, UITextViewDelegate { @@ -156,6 +192,11 @@ extension MountainAddingView: UITextFieldDelegate, UITextViewDelegate { return newLength <= 10 } + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.descriptionTextView.becomeFirstResponder() + return true + } + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let string = textView.text else { return true } let newLength = string.count + text.count From 53bac9b91bc1272712d82525616609d17514ca82 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:36:13 +0900 Subject: [PATCH 362/465] [Feat] #278 DetailImages Push Button --- .../ResultDetailViewController.swift | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 76637ed..87e08f6 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -72,14 +72,23 @@ class ResultDetailViewController: UIViewController { private lazy var detailImagesButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "photo.on.rectangle.angled"), for: .normal) - button.imageView?.contentMode = .scaleAspectFit - button.titleLabel?.font = .boldSystemFont(ofSize: 12) + button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) + button.titleLabel?.font = .boldSystemFont(ofSize: 15) + button.backgroundColor = .systemBackground + button.tintColor = .label + button.setTitleColor(.label, for: .normal) button.contentHorizontalAlignment = .center button.semanticContentAttribute = .forceLeftToRight - button.imageEdgeInsets = .init(top: 0, left: 15, bottom: 0, right: 15) button.addTarget(self, action: #selector(pushDetailImagesViewController), for: .touchUpInside) + button.layer.cornerRadius = 5 + button.layer.masksToBounds = false + button.layer.shadowColor = UIColor.black.cgColor + button.layer.shadowOpacity = 0.7 + button.layer.shadowOffset = CGSize.zero + button.layer.shadowRadius = 2 + button.translatesAutoresizingMaskIntoConstraints = false return button - }()g + }() private var titleLabel: UILabel = { let label = UILabel() @@ -146,6 +155,7 @@ class ResultDetailViewController: UIViewController { guard let assetIdentifiers = self.viewModel?.resultDetailData?.assetIdentifiers else { return } let allMedia = PHAsset.fetchAssets(with: .image, options: nil) var identifierIndex = 0 + self.detailImagesButton.setTitle("\(assetIdentifiers.count)", for: .normal) for i in stride(from: allMedia.count - 1, through: 0, by: -1) { guard identifierIndex < assetIdentifiers.count else { return } if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { @@ -194,12 +204,12 @@ class ResultDetailViewController: UIViewController { private func configureViews() { guard let tabBar = self.navigationController?.tabBarController?.tabBar else { return } self.view.addSubview(self.mapView) + self.view.addSubview(self.detailImagesButton) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) self.view.addSubview(self.titleLabel) - self.view.addSubview(self.detailImagesButton) NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), @@ -237,6 +247,13 @@ class ResultDetailViewController: UIViewController { self.titleLabel.centerYAnchor.constraint(equalTo: self.changeButton.centerYAnchor), ]) + NSLayoutConstraint.activate([ + self.detailImagesButton.topAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: -45), + self.detailImagesButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -15), + self.detailImagesButton.widthAnchor.constraint(equalToConstant: 55), + self.detailImagesButton.heightAnchor.constraint(equalToConstant: 30) + ]) + infoViewTopConstraint = self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewTopConstraint else { return } @@ -319,7 +336,7 @@ extension ResultDetailViewController { } @objc func pushDetailImagesViewController() { - + coordinator?.pushResultDetailImagesViewController() } @objc func presentModifyResultAlert() { From 0053b50c038ff2687b157bc65ce5292e6ef00629 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:41:35 +0900 Subject: [PATCH 363/465] =?UTF-8?q?[Feat]=20#277=20imagesVisibilityButton?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 87e08f6..055d135 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -79,7 +79,25 @@ class ResultDetailViewController: UIViewController { button.setTitleColor(.label, for: .normal) button.contentHorizontalAlignment = .center button.semanticContentAttribute = .forceLeftToRight + button.layer.cornerRadius = 5 + button.layer.masksToBounds = false + button.layer.shadowColor = UIColor.black.cgColor + button.layer.shadowOpacity = 0.7 + button.layer.shadowOffset = CGSize.zero + button.layer.shadowRadius = 2 + button.translatesAutoresizingMaskIntoConstraints = false button.addTarget(self, action: #selector(pushDetailImagesViewController), for: .touchUpInside) + return button + }() + + private lazy var imagesVisibilityButton: UIButton = { + let button = UIButton() + button.setImage(.init(systemName: "eye"), for: .normal) + //eye.slash + button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) + button.backgroundColor = .systemBackground + button.tintColor = .label + button.contentHorizontalAlignment = .center button.layer.cornerRadius = 5 button.layer.masksToBounds = false button.layer.shadowColor = UIColor.black.cgColor @@ -87,6 +105,7 @@ class ResultDetailViewController: UIViewController { button.layer.shadowOffset = CGSize.zero button.layer.shadowRadius = 2 button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(imagesVisibilityButtonAction), for: .touchUpInside) return button }() @@ -205,6 +224,7 @@ class ResultDetailViewController: UIViewController { guard let tabBar = self.navigationController?.tabBarController?.tabBar else { return } self.view.addSubview(self.mapView) self.view.addSubview(self.detailImagesButton) + self.view.addSubview(self.imagesVisibilityButton) self.view.addSubview(self.backButton) self.view.addSubview(self.changeButton) self.view.addSubview(self.largerInformationView) @@ -254,6 +274,13 @@ class ResultDetailViewController: UIViewController { self.detailImagesButton.heightAnchor.constraint(equalToConstant: 30) ]) + NSLayoutConstraint.activate([ + self.imagesVisibilityButton.topAnchor.constraint(equalTo: self.detailImagesButton.topAnchor), + self.imagesVisibilityButton.trailingAnchor.constraint(equalTo: self.detailImagesButton.leadingAnchor, constant: -15), + self.imagesVisibilityButton.widthAnchor.constraint(equalToConstant: 55), + self.imagesVisibilityButton.heightAnchor.constraint(equalToConstant: 30) + ]) + infoViewTopConstraint = self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = infoViewTopConstraint else { return } @@ -339,6 +366,10 @@ extension ResultDetailViewController { coordinator?.pushResultDetailImagesViewController() } + @objc func imagesVisibilityButtonAction() { + + } + @objc func presentModifyResultAlert() { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in From d4900b6bf6db05ebf883efda1296971eccca7916 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 23 Nov 2021 23:57:50 +0900 Subject: [PATCH 364/465] =?UTF-8?q?[Feat]=20#278=20UIImages=20=EC=A3=BC?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailImageViewCoordinator.swift | 7 ++++-- .../ResultDetailImagesViewController.swift | 25 ++++++++++++++++++- .../ResultDetailViewController.swift | 2 +- .../ResultDetailViewCoordinator.swift | 4 +-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift index c2f9443..e76ecf8 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift @@ -12,10 +12,12 @@ class ResultDetailImagesViewCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController + let uiImages: [String: UIImage] + func start() { let resultDetailImagesViewController = ResultDetailImagesViewController() + resultDetailImagesViewController.uiImages = self.uiImages resultDetailImagesViewController.coordinator = self - self.navigationController.setNavigationBarHidden(true, animated: false) self.navigationController.pushViewController(resultDetailImagesViewController, animated: true) } @@ -24,7 +26,8 @@ class ResultDetailImagesViewCoordinator: Coordinator { self.parentCoordinator?.childCoordinators.removeLast() } - init(navigationController: UINavigationController) { + init(navigationController: UINavigationController, uiImages: [String: UIImage]) { self.navigationController = navigationController + self.uiImages = uiImages } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index 2a2f74a..5e8e2ed 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -10,8 +10,31 @@ import UIKit class ResultDetailImagesViewController: UIViewController { weak var coordinator: ResultDetailImagesViewCoordinator? + var uiImages = [String: UIImage]() + override func viewDidLoad() { super.viewDidLoad() - self.view.backgroundColor = .red + self.configureViews() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: false) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + self.navigationController?.setNavigationBarHidden(true, animated: false) + } + + private func configureViews() { + self.view.backgroundColor = .systemBackground + self.navigationController?.navigationBar.tintColor = .label + } +} + +extension ResultDetailImagesViewController { + @objc func dismissViewController() { + coordinator?.dismiss() } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 055d135..844cf9d 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -363,7 +363,7 @@ extension ResultDetailViewController { } @objc func pushDetailImagesViewController() { - coordinator?.pushResultDetailImagesViewController() + coordinator?.pushResultDetailImagesViewController(uiImages: uiImages) } @objc func imagesVisibilityButtonAction() { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 72b2470..1607baa 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -60,8 +60,8 @@ extension ResultDetailViewCoordinator { recordingTitleViewCoordinator.start() } - func pushResultDetailImagesViewController() { - let resultDetailImagesViewCoordinator = ResultDetailImagesViewCoordinator(navigationController: navigationController) + func pushResultDetailImagesViewController(uiImages: [String: UIImage]) { + let resultDetailImagesViewCoordinator = ResultDetailImagesViewCoordinator(navigationController: navigationController, uiImages: uiImages) self.childCoordinators.append(resultDetailImagesViewCoordinator) resultDetailImagesViewCoordinator.parentCoordinator = self From 81010c46f0501bec0ac0fb01def717c07c9318b0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 00:11:56 +0900 Subject: [PATCH 365/465] [Feat] #278 Diffable CollectionView Configure --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ .../DetailImagesCell.swift | 27 ++++++++ .../ResultDetailImagesViewController.swift | 69 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 5138596..f65595a 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -103,6 +103,7 @@ DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */; }; DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */; }; + DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */; }; DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; @@ -208,6 +209,7 @@ DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewController.swift; sourceTree = ""; }; DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImageViewCoordinator.swift; sourceTree = ""; }; + DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailImagesCell.swift; sourceTree = ""; }; DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoModel.swift; sourceTree = ""; }; @@ -476,6 +478,7 @@ children = ( DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */, DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */, + DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */, ); path = ResultDetailImagesScene; sourceTree = ""; @@ -650,6 +653,7 @@ 49D5A9532738FBCD00937821 /* MountainDetailModel.swift in Sources */, 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, + DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift new file mode 100644 index 0000000..c6db90f --- /dev/null +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -0,0 +1,27 @@ +// +// DetailImagesCell.swift +// SanTa +// +// Created by 김민창 on 2021/11/24. +// + +import UIKit + +class DetailImagesCell: UICollectionViewCell { + static let identifier = "DetailImagesCell" + + private let imageView = UIImageView() + + func update(image: UIImage) { + self.addSubview(imageView) + + self.imageView.image = image + + NSLayoutConstraint.activate([ + self.imageView.topAnchor.constraint(equalTo: self.topAnchor), + self.imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor), + self.imageView.trailingAnchor.constraint(equalTo: self.trailingAnchor), + self.imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) + } +} diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index 5e8e2ed..ae578d6 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -10,11 +10,31 @@ import UIKit class ResultDetailImagesViewController: UIViewController { weak var coordinator: ResultDetailImagesViewCoordinator? + enum DetailImagesSection: Int, CaseIterable { + case main + } + + typealias DetailImagesDataSource = UICollectionViewDiffableDataSource + typealias DetailImagesSnapshot = NSDiffableDataSourceSnapshot + + private var dataSource: DetailImagesDataSource? + var uiImages = [String: UIImage]() + lazy var collectionView: UICollectionView = { + let flowLayout = UICollectionViewFlowLayout() + let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + + return collectionView + }() + override func viewDidLoad() { super.viewDidLoad() + self.configureCollectionView() self.configureViews() + self.configuareDataSource() + self.configureImages() } override func viewWillAppear(_ animated: Bool) { @@ -30,6 +50,55 @@ class ResultDetailImagesViewController: UIViewController { private func configureViews() { self.view.backgroundColor = .systemBackground self.navigationController?.navigationBar.tintColor = .label + self.view.addSubview(self.collectionView) + + NSLayoutConstraint.activate([ + self.collectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), + self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + self.collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) + ]) + } + + private func configureCollectionView() { + self.collectionView.collectionViewLayout = configureCompositionalLayout() + self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) + } + + private func bindSnapShotApply(section: DetailImagesSection, item: [AnyHashable]) { + var snapshot = DetailImagesSnapshot() + snapshot.appendSections([.main]) + item.forEach { + snapshot.appendItems([$0], toSection: section) + } + self.dataSource?.apply(snapshot, animatingDifferences: true) + } + + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { + return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalWidth(1/3))) + item.contentInsets = .init(top: 3, leading: 3, bottom: 3, trailing: 3) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1/3)), subitems: [item]) + let section = NSCollectionLayoutSection(group: group) + section.orthogonalScrollingBehavior = .none + section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + return section + } + } + + private func configuareDataSource() { + let datasource = DetailImagesDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell else { + return UICollectionViewCell() } + return cell + }) + + self.dataSource = datasource + self.collectionView.dataSource = dataSource + } + + private func configureImages() { } } From 97b67de4362009d7d79ec259ec9edde8d8035950 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 00:26:09 +0900 Subject: [PATCH 366/465] =?UTF-8?q?[Feat]=20#278=20CollectionView=20?= =?UTF-8?q?=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailImagesScene/DetailImagesCell.swift | 1 + .../ResultDetailImagesViewController.swift | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift index c6db90f..6029b81 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -13,6 +13,7 @@ class DetailImagesCell: UICollectionViewCell { private let imageView = UIImageView() func update(image: UIImage) { + self.imageView.translatesAutoresizingMaskIntoConstraints = false self.addSubview(imageView) self.imageView.image = image diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index ae578d6..c9b5cc5 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -50,6 +50,7 @@ class ResultDetailImagesViewController: UIViewController { private func configureViews() { self.view.backgroundColor = .systemBackground self.navigationController?.navigationBar.tintColor = .label + self.title = "사진 모아보기 (\(uiImages.count)장)" self.view.addSubview(self.collectionView) NSLayoutConstraint.activate([ @@ -89,8 +90,12 @@ class ResultDetailImagesViewController: UIViewController { private func configuareDataSource() { let datasource = DetailImagesDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell else { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell, + let item = item as? String, + let image = self.uiImages[item] else { return UICollectionViewCell() } + + cell.update(image: image) return cell }) @@ -99,6 +104,13 @@ class ResultDetailImagesViewController: UIViewController { } private func configureImages() { + var identifiers = [String]() + + for (key, _) in self.uiImages { + identifiers.append(key) + } + + self.bindSnapShotApply(section: .main, item: identifiers) } } From 706b12c4207f430a0df8a9e8061b8556c34e0abd Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 24 Nov 2021 00:49:16 +0900 Subject: [PATCH 367/465] =?UTF-8?q?[Fix]=20#293=20=EB=A7=88=EC=BB=A4=202?= =?UTF-8?q?=EA=B0=9C=EA=B0=80=20=EA=B2=B9=EC=B3=90=EC=A7=80=EB=8A=94=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 7 ++++--- SanTa/SanTa/MapScene/MapViewModel.swift | 4 +--- SanTa/SanTa/MapScene/MapViewRepository.swift | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index aef856c..aa9aae2 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -151,9 +151,10 @@ class MapViewController: UIViewController { } private func configureMarkers(_ mountains: [MountainEntity]?) { + self.mapView.removeAnnotations(self.mapView.annotations) guard let mountains = mountains else { return } - mountains.forEach{ mountainEntity in - let mountainAnnotation = MountainAnnotation( + let annotations = mountains.map{ mountainEntity in + return MountainAnnotation( title: mountainEntity.mountain.mountainName, subtitle: mountainEntity.mountain.mountainHeight + "m", latitude: mountainEntity.latitude, @@ -161,8 +162,8 @@ class MapViewController: UIViewController { mountainDescription: mountainEntity.mountain.mountainShortDescription, region: mountainEntity.mountain.mountainRegion ) - self.mapView.addAnnotation(mountainAnnotation) } + self.mapView.addAnnotations(annotations) } private func configureMap(_ map: Map?) { diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index b7d5a2b..69b6c15 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -22,8 +22,7 @@ final class MapViewModel { func configureBindings() { self.useCase.prepareMountainMarkers { [weak self] mountains in - guard let mountains = mountains else { return } - self?.mountains?.append(contentsOf: mountains) + self?.mountains = mountains } self.useCase.initialLocation = { [weak self] initialLocation in self?.initialLocation = initialLocation @@ -31,7 +30,6 @@ final class MapViewModel { self.useCase.locationPermissionDidChangeTo = { [weak self] bool in self?.locationPermission = bool } - self.useCase.preparePermission() self.useCase.prepareLocacationManager() } diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index a4e9a53..954784d 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -38,21 +38,30 @@ class DefaultMapViewRespository { extension DefaultMapViewRespository: MapViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + let group = DispatchGroup() + group.enter() + group.enter() + var jsonMountains = [MountainEntity]() + var coreMountains = [MountainEntity]() self.mountainExtractor.extract { result in switch result { case .failure(let error): + group.leave() return completion(.failure(error)) case .success(let dataAsset): guard let decodedObjects = try? JSONDecoder().decode([MountainEntity].self, from: dataAsset.data) else { + group.leave() return completion(.failure(JSONDecodeError.decodingFailed)) } - completion(.success(decodedObjects)) + jsonMountains = decodedObjects + group.leave() } } self.coreDataMountainStorage.fetch { result in switch result { case .failure(let error): + group.leave() return completion(.failure(error)) case .success(let mountainEntityMOs): var mountainEntities: [MountainEntity] = [] @@ -71,9 +80,13 @@ extension DefaultMapViewRespository: MapViewRepository { ) mountainEntities.append(mountainEntity) } - completion(.success(mountainEntities)) + coreMountains = mountainEntities + group.leave() } } + group.notify(queue: .main) { + completion(.success(jsonMountains + coreMountains)) + } } func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) { From 0633799dc2531cc3890f10c560267dfc6451b468 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 24 Nov 2021 01:09:53 +0900 Subject: [PATCH 368/465] =?UTF-8?q?[Feat]=20#295=20=EC=9E=A5=EC=86=8C=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EC=9D=B4=20=EC=A7=80=EB=8F=84=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=20=EC=A6=89=EC=8B=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 10 +++++++++- SanTa/SanTa/MapScene/MapViewModel.swift | 6 ++++++ .../MountainAddingViewController.swift | 1 + .../MountainAddingScene/MountainAddingViewModel.swift | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index aa9aae2..c1606a2 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -82,7 +82,7 @@ class MapViewController: UIViewController { self.configureViews() self.registerAnnotationView() self.configureViewModel() - print("Documents Directory: ", FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last ?? "Not Found!") + self.configureNotification() } override func viewWillAppear(_ animated: Bool) { @@ -150,6 +150,14 @@ class MapViewController: UIViewController { .store(in: &self.observers) } + private func configureNotification() { + NotificationCenter.default.addObserver(self, selector: #selector(shouldUpdateMarkers), name: NSNotification.Name.init(rawValue: "save"), object: nil) + } + + @objc func shouldUpdateMarkers() { + self.viewModel?.updateMarker() + } + private func configureMarkers(_ mountains: [MountainEntity]?) { self.mapView.removeAnnotations(self.mapView.annotations) guard let mountains = mountains else { return } diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index 69b6c15..6fbf3ec 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -40,4 +40,10 @@ final class MapViewModel { self?.map = map } } + + func updateMarker() { + self.useCase.prepareMountainMarkers { [weak self] mountains in + self?.mountains = mountains + } + } } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index 55e40ea..76e0db7 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -79,6 +79,7 @@ class MountainAddingViewController: UIViewController { .receive(on: DispatchQueue.main) .sink(receiveValue: { [weak self] result in self?.showResult(result) + NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "save"), object: nil) }) .store(in: &observers) self.mapView.showsUserLocation = true diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index f3e4086..a61d8a5 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -16,7 +16,7 @@ class MountainAddingViewModel { let addMountainResult = PassthroughSubject() enum AddMountainResult: String { - case success = "저장에 성공하였습니다.\n앱 종료 및 재시작 시 적용됩니다." + case success = "저장에 성공하였습니다." case failure = "저장에 실패하였습니다." } From 3f74a332c5aa2de0b25a10f177f7c39ba7373c1e Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 24 Nov 2021 18:22:40 +0900 Subject: [PATCH 369/465] =?UTF-8?q?[Fix]=20#297=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=ED=95=9C=20=EC=82=B0=EC=9D=98=20=EA=B3=A0=EB=8F=84=20=ED=91=9C?= =?UTF-8?q?=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift index 71dcd3c..c120573 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -21,7 +21,7 @@ class MountainAddingViewUseCase { let mountainDetail = MountainEntity.MountainDetail( mountainName: name, mountainRegion: region, - mountainHeight: String(altitude), + mountainHeight: String(format: "%.f", altitude), mountainShortDescription: description ) let mountainEntity = MountainEntity(mountain: mountainDetail, latitude: latitude, longitude: longitude) From f1bd047b76a08d4d46f1e9c305a125685e4b42d1 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 24 Nov 2021 18:37:36 +0900 Subject: [PATCH 370/465] =?UTF-8?q?[Feat]=20#299=20Tracking=20Button=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 212779e..518aa92 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -65,6 +65,7 @@ class MapViewController: UIViewController { private lazy var userTrackingButton: MKUserTrackingButton = { let button = MKUserTrackingButton(mapView: self.mapView) button.isHidden = true + button.tintColor = UIColor(named: "SantaColor") button.backgroundColor = .white button.translatesAutoresizingMaskIntoConstraints = false button.layer.cornerRadius = 10 From 1f4a34f2bb34eb5c123f2133355527eb7b0f1c33 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 22:18:25 +0900 Subject: [PATCH 371/465] =?UTF-8?q?[Refactor]=20ResultDetailImagesViewCoor?= =?UTF-8?q?dinator=20dismiss=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailImageViewCoordinator.swift | 1 - .../ResultDetailImagesViewController.swift | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift index e76ecf8..772212b 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift @@ -22,7 +22,6 @@ class ResultDetailImagesViewCoordinator: Coordinator { } func dismiss() { - self.navigationController.popViewController(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index c9b5cc5..c901c13 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -44,6 +44,7 @@ class ResultDetailImagesViewController: UIViewController { override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) + self.coordinator?.dismiss() self.navigationController?.setNavigationBarHidden(true, animated: false) } From 20c4df654b4b1ba4a4463d70bbe39efb5e888054 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 22:23:14 +0900 Subject: [PATCH 372/465] =?UTF-8?q?[Refactor]=20DetailImagesCell=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DetailImagesCell.swift | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift index 6029b81..a88c986 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -12,12 +12,19 @@ class DetailImagesCell: UICollectionViewCell { private let imageView = UIImageView() - func update(image: UIImage) { + override init(frame: CGRect) { + super.init(frame: frame) + self.configureView() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func configureView() { self.imageView.translatesAutoresizingMaskIntoConstraints = false self.addSubview(imageView) - self.imageView.image = image - NSLayoutConstraint.activate([ self.imageView.topAnchor.constraint(equalTo: self.topAnchor), self.imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor), @@ -25,4 +32,8 @@ class DetailImagesCell: UICollectionViewCell { self.imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } + + func update(image: UIImage) { + self.imageView.image = image + } } From 8498b49cb19218831368d79a2a997965d7152519 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 22:40:14 +0900 Subject: [PATCH 373/465] =?UTF-8?q?[Feat]=20#279,=20#277=20=EC=84=AC?= =?UTF-8?q?=EB=84=A4=EC=9D=BC=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=EB=B7=B0=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 ++ .../ResultDetailViewController.swift | 13 ++++ .../ResultDetailScene/ThumbnailView.swift | 68 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 SanTa/SanTa/ResultDetailScene/ThumbnailView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 8c91dbe..f3381f0 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -100,6 +100,7 @@ DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; + DAB751B7274E74E600C39266 /* ThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751B6274E74E600C39266 /* ThumbnailView.swift */; }; DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */; }; DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */; }; DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */; }; @@ -205,6 +206,7 @@ DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; + DAB751B6274E74E600C39266 /* ThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailView.swift; sourceTree = ""; }; DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewController.swift; sourceTree = ""; }; DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImageViewCoordinator.swift; sourceTree = ""; }; DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailImagesCell.swift; sourceTree = ""; }; @@ -275,6 +277,7 @@ children = ( 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */, 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, + DAB751B6274E74E600C39266 /* ThumbnailView.swift */, 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, 494803812743748D002854B1 /* ResultDetailViewModel.swift */, @@ -651,6 +654,7 @@ 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */, DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */, + DAB751B7274E74E600C39266 /* ThumbnailView.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 945d7a3..21c8cb2 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -128,6 +128,7 @@ class ResultDetailViewController: UIViewController { self.configureViewModel() self.drawPathOnMap() self.markEndPoints() + self.registerAnnotationView() } private func configureViewModel() { @@ -160,6 +161,13 @@ class ResultDetailViewController: UIViewController { viewModel?.setUp() } + private func registerAnnotationView() { + self.mapView.register( + ThumbnailView.self, + forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier + ) + } + private func drawPathOnMap() { guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { return @@ -468,4 +476,9 @@ extension ResultDetailViewController: MKMapViewDelegate { } return annotationView } + + func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { + guard let annotation = view.annotation as? MountainAnnotation else { return } + coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation) + } } diff --git a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift new file mode 100644 index 0000000..2a1f51d --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift @@ -0,0 +1,68 @@ +// +// ThumbnailView.swift +// SanTa +// +// Created by 김민창 on 2021/11/24. +// + +import UIKit +import MapKit + +final class ThumbnailView: MKAnnotationView { + static let ReuseID = "ThumbnailAnnotation" + + private lazy var displayView: UIView = { + let view = UIView() + view.backgroundColor = .systemBackground + view.layer.cornerRadius = 5 + view.layer.masksToBounds = false + view.layer.shadowColor = UIColor.black.cgColor + view.layer.shadowOpacity = 0.7 + view.layer.shadowOffset = CGSize.zero + view.layer.shadowRadius = 2 + return view + }() + + private lazy var imageView = UIImageView() + + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForDisplay() { + super.prepareForDisplay() + displayPriority = .defaultHigh + self.frame = CGRect(x: 33, y: 33, width: 33, height: 33) + self.configure() + } + + private func configure() { + displayView.translatesAutoresizingMaskIntoConstraints = false + imageView.translatesAutoresizingMaskIntoConstraints = false + + self.addSubview(displayView) + self.addSubview(imageView) + + NSLayoutConstraint.activate([ + self.displayView.leftAnchor.constraint(equalTo: self.leftAnchor), + self.displayView.topAnchor.constraint(equalTo: self.topAnchor), + self.displayView.rightAnchor.constraint(equalTo: self.rightAnchor), + self.displayView.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) + + NSLayoutConstraint.activate([ + self.imageView.leftAnchor.constraint(equalTo: self.displayView.leftAnchor, constant: 3), + self.imageView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 3), + self.imageView.rightAnchor.constraint(equalTo: self.displayView.rightAnchor, constant: -3), + self.imageView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -3) + ]) + } + + func configureImage(uiImage: UIImage) { + + } +} From c4bfefd5dc3a10a5e390faad264a42aad66a31b6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 22:47:00 +0900 Subject: [PATCH 374/465] =?UTF-8?q?[Feat]=20#279=20=EC=84=AC=EB=84=A4?= =?UTF-8?q?=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=A7=B5=EB=B7=B0?= =?UTF-8?q?=EC=97=90=20=EA=B7=B8=EB=A6=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 14 ++++++-------- .../SanTa/ResultDetailScene/ThumbnailView.swift | 16 +++++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 21c8cb2..d415a03 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -466,19 +466,17 @@ extension ResultDetailViewController: MKMapViewDelegate { return nil } - let size = CGSize(width: 30, height: 30) - UIGraphicsBeginImageContextWithOptions(size, false, 0.0) - image.draw(in: CGRect(origin: CGPoint.zero, size: size)) - let resizedImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() + let thumbnailView = ThumbnailView(annotation: annotation, reuseIdentifier: identifier) + thumbnailView.configureImage(uiImage: image, id: identifider ?? "") - annotationView.image = resizedImage + return thumbnailView } return annotationView } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { - guard let annotation = view.annotation as? MountainAnnotation else { return } - coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation) + guard let annotation = view as? ThumbnailView else { return } + + print(annotation.imageIdentifier) } } diff --git a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift index 2a1f51d..0741e31 100644 --- a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift +++ b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift @@ -13,7 +13,7 @@ final class ThumbnailView: MKAnnotationView { private lazy var displayView: UIView = { let view = UIView() - view.backgroundColor = .systemBackground + view.backgroundColor = .white view.layer.cornerRadius = 5 view.layer.masksToBounds = false view.layer.shadowColor = UIColor.black.cgColor @@ -24,6 +24,7 @@ final class ThumbnailView: MKAnnotationView { }() private lazy var imageView = UIImageView() + private(set) var imageIdentifier = String() override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) @@ -55,14 +56,15 @@ final class ThumbnailView: MKAnnotationView { ]) NSLayoutConstraint.activate([ - self.imageView.leftAnchor.constraint(equalTo: self.displayView.leftAnchor, constant: 3), - self.imageView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 3), - self.imageView.rightAnchor.constraint(equalTo: self.displayView.rightAnchor, constant: -3), - self.imageView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -3) + self.imageView.leftAnchor.constraint(equalTo: self.displayView.leftAnchor, constant: 2), + self.imageView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 2), + self.imageView.rightAnchor.constraint(equalTo: self.displayView.rightAnchor, constant: -2), + self.imageView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -2) ]) } - func configureImage(uiImage: UIImage) { - + func configureImage(uiImage: UIImage, id: String) { + self.imageView.image = uiImage + self.imageIdentifier = id } } From c7794466432edcece29e4387a50b760390acdf5e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Wed, 24 Nov 2021 22:53:02 +0900 Subject: [PATCH 375/465] =?UTF-8?q?[Refactor]=20#301=20=EA=B2=BD=EC=82=AC?= =?UTF-8?q?=EB=8F=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/DetailCell.swift | 1 + SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index 96f4a7a..b17501f 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -11,6 +11,7 @@ class DetailCell: UICollectionViewCell { static let identifier = "DetailCell" func layout(data: LargeViewModel) { + self.subviews.forEach{$0.removeFromSuperview()} let title: UILabel = UILabel() self.addSubview(title) title.text = data.title diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index de1348c..e0c8536 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -140,15 +140,17 @@ struct ResultIncline { let next = CLLocation(latitude: locations[index+1].latitude, longitude: locations[index+1].longitude) let distanceDelta = current.distance(from: next) let altitudeDelta = next.altitude - current.altitude - let incline = atan(altitudeDelta / distanceDelta) - totalIncline += incline == .nan || incline == .infinity ? 0 : incline - steepest = steepest < incline ? incline : steepest + if distanceDelta != 0 { + let incline = atan(altitudeDelta / distanceDelta) + totalIncline += incline + steepest = max(steepest, incline) + } uphillDistance += altitudeDelta > 0 ? abs(distanceDelta) : 0 downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 } - self.average = 0 + self.average = locations.count > 1 ? Int(totalIncline / Double(locations.count - 1)) : 0 self.highest = Int(steepest) self.uphillKilometer = uphillDistance / 1000 self.downhillKilometer = downHillDistance / 1000 From 86339bfabe710e8a13ea00591f318cb3d9477d8b Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 23:02:36 +0900 Subject: [PATCH 376/465] =?UTF-8?q?[Feat]=20#279=20=EC=84=AC=EB=84=A4?= =?UTF-8?q?=EC=9D=BC=20=EB=A7=88=EC=BB=A4=20touch=20delegate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 2 +- SanTa/SanTa/ResultDetailScene/ThumbnailView.swift | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index d415a03..ac14460 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -474,7 +474,7 @@ extension ResultDetailViewController: MKMapViewDelegate { return annotationView } - func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { + func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { guard let annotation = view as? ThumbnailView else { return } print(annotation.imageIdentifier) diff --git a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift index 0741e31..dc29edc 100644 --- a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift +++ b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift @@ -36,8 +36,7 @@ final class ThumbnailView: MKAnnotationView { override func prepareForDisplay() { super.prepareForDisplay() - displayPriority = .defaultHigh - self.frame = CGRect(x: 33, y: 33, width: 33, height: 33) + self.frame = CGRect(x: 0, y: 0, width: 38, height: 38) self.configure() } From b0ab49ad239cbafa84c6df5cff2fe94556e6f3ac Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 24 Nov 2021 23:10:12 +0900 Subject: [PATCH 377/465] =?UTF-8?q?[Fix]=20#304,=20#305=20=EC=82=B0=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=99=94=EB=A9=B4=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 네비게이션바가 보이던 버그 및 인스턴스가 사라지지 않던 버그 수정 --- .../MountainDetailViewController.swift | 38 ++++++++-------- .../MountainDetailViewCoordinator.swift | 43 +++++++++++-------- .../MountainListViewCoordinator.swift | 2 +- 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index fe45e99..1f7c985 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -14,12 +14,16 @@ class MountainDetailViewController: UIViewController { private var mutatingTopConstraint: NSLayoutConstraint? private let maxRollUpDistance: CGFloat = 50 - lazy var backButton: UIImageView = { - let uiImage = UIImageView(image: .init(systemName: "xmark")) - uiImage.tintColor = .white - uiImage.translatesAutoresizingMaskIntoConstraints = false - uiImage.isUserInteractionEnabled = true - return uiImage + private lazy var backButton: UIButton = { + let button = UIButton(frame: .zero) + button.setImage(.init(systemName: "xmark"), for: .normal) + button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) + button.tintColor = .white + button.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) + button.translatesAutoresizingMaskIntoConstraints = false + button.accessibilityLabel = "닫기" + button.accessibilityHint = "목록 화면으로 돌아가시려면 이중 탭 하십시오" + return button }() convenience init(viewModel: MountainDetailViewModel) { @@ -32,16 +36,11 @@ class MountainDetailViewController: UIViewController { self.configureViewModel() } - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - self.coordinator?.dismiss() - } - private func configureViewModel() { - self.viewModel?.mountainInfoReceived = { mountainDetail in - self.layoutMountainDetailView(mountainDetail: mountainDetail) + self.viewModel?.mountainInfoReceived = { [weak self] mountainDetail in + self?.layoutMountainDetailView(mountainDetail: mountainDetail) } - viewModel?.setUpViewModel() + self.viewModel?.setUpViewModel() } } @@ -103,19 +102,16 @@ extension MountainDetailViewController { backButton.tintColorDidChange() self.view.addSubview(backButton) - backButton.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(close))) let backButtonConstraints = [ - backButton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10), + backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10), - backButton.widthAnchor.constraint(equalToConstant: 30), - backButton.heightAnchor.constraint(equalToConstant: 30), - ] NSLayoutConstraint.activate(backButtonConstraints) } - @objc private func close() { - self.dismiss(animated: true, completion: nil) + + @objc private func dismissViewController() { + self.coordinator?.dismiss() } private func configuredTableView(mountainDetail: MountainDetailModel) -> UITableView { diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index ab231bd..f600c33 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -9,35 +9,44 @@ import UIKit import CoreLocation class MountainDetailViewCoordinator: Coordinator { - var childCoordinators: [Coordinator] = [] - weak var parentCoordinator: Coordinator? + var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController - var mountainDetailViewController: MountainDetailViewController + var mountainAnnotation: MountainAnnotation + + init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation) { + self.navigationController = navigationController + self.mountainAnnotation = mountainAnnotation + } func start() { + let mountainDetailViewController = MountainDetailViewController(viewModel: injectDependencies()) + mountainDetailViewController.coordinator = self if self.parentCoordinator is MapViewCoordinator { - self.mountainDetailViewController.backButton.isHidden = false self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) + } else { + self.navigationController.setNavigationBarHidden(true, animated: false) + self.navigationController.pushViewController(mountainDetailViewController, animated: true) } } - func startPush() { - self.mountainDetailViewController.backButton.isHidden = true - self.navigationController.pushViewController(self.mountainDetailViewController, animated: true) - } - func dismiss() { - self.navigationController.dismiss(animated: true) + if self.parentCoordinator is MapViewCoordinator { + self.navigationController.dismiss(animated: true) + } else { + self.navigationController.popViewController(animated: true) + } self.parentCoordinator?.childCoordinators.removeLast() } - - - init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation) { - self.navigationController = navigationController - let viewModel = MountainDetailViewModel(useCase: MountainDetailUseCase(mountainAnnotation: mountainAnnotation)) - self.mountainDetailViewController = MountainDetailViewController(viewModel: viewModel) - self.mountainDetailViewController.coordinator = self +} + +extension MountainDetailViewCoordinator { + private func injectDependencies() -> MountainDetailViewModel { + return MountainDetailViewModel( + useCase: MountainDetailUseCase( + mountainAnnotation: self.mountainAnnotation + ) + ) } } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index e861fef..e0d985f 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -50,7 +50,7 @@ extension MountainListViewCoordinator { let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) - mountainDetailViewCoordinator.startPush() + mountainDetailViewCoordinator.start() } } From c6022429c939408431cca42cb9f909f200d90b69 Mon Sep 17 00:00:00 2001 From: MinChang Date: Wed, 24 Nov 2021 23:13:04 +0900 Subject: [PATCH 378/465] =?UTF-8?q?[Feat]=20#279=20ThumbnailViewController?= =?UTF-8?q?,=20ThumbnailCoordinator=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 +++ .../ResultDetailImagesViewController.swift | 6 - .../ResultDetailThumbnailViewController.swift | 103 ++++++++++++++++++ ...ResultDetailThumbnailViewCoordinator.swift | 32 ++++++ 4 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift create mode 100644 SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f3381f0..fe812ba 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -101,6 +101,8 @@ DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; DAB751B7274E74E600C39266 /* ThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751B6274E74E600C39266 /* ThumbnailView.swift */; }; + DAB751BA274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */; }; + DAB751BC274E7DFB00C39266 /* ResultDetailThumbnailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */; }; DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */; }; DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */; }; DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */; }; @@ -207,6 +209,8 @@ DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; DAB751B6274E74E600C39266 /* ThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailView.swift; sourceTree = ""; }; + DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailThumbnailViewController.swift; sourceTree = ""; }; + DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailThumbnailViewCoordinator.swift; sourceTree = ""; }; DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewController.swift; sourceTree = ""; }; DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImageViewCoordinator.swift; sourceTree = ""; }; DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailImagesCell.swift; sourceTree = ""; }; @@ -424,6 +428,7 @@ 54B32063274510B7002232BD /* MountainAddingScene */, 5428FDB6272F8B2B002F9D40 /* ResultScene */, DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */, + DAB751B8274E7DAD00C39266 /* ResultDetailThumbnailScene */, 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, 5428FDB5272F89F0002F9D40 /* RecordingScene */, DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, @@ -473,6 +478,15 @@ path = RecordingTitleScene; sourceTree = ""; }; + DAB751B8274E7DAD00C39266 /* ResultDetailThumbnailScene */ = { + isa = PBXGroup; + children = ( + DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */, + DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */, + ); + path = ResultDetailThumbnailScene; + sourceTree = ""; + }; DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */ = { isa = PBXGroup; children = ( @@ -670,10 +684,12 @@ 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */, 54F88EB727424C210004EAFD /* TotalRecordsViewCell.swift in Sources */, 54B3206727451169002232BD /* MountainAddingViewCoordinator.swift in Sources */, + DAB751BC274E7DFB00C39266 /* ResultDetailThumbnailViewCoordinator.swift in Sources */, 9800821D273CB45D006A847A /* ResultRepository.swift in Sources */, 54B32073274B7E09002232BD /* MountainAddingView.swift in Sources */, DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */, 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */, + DAB751BA274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift in Sources */, DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */, 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index c901c13..88efe3a 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -114,9 +114,3 @@ class ResultDetailImagesViewController: UIViewController { self.bindSnapShotApply(section: .main, item: identifiers) } } - -extension ResultDetailImagesViewController { - @objc func dismissViewController() { - coordinator?.dismiss() - } -} diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift new file mode 100644 index 0000000..2ce570a --- /dev/null +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -0,0 +1,103 @@ +// +// ResultDetailThumbnailViewController.swift +// SanTa +// +// Created by 김민창 on 2021/11/24. +// + +import UIKit + +class ResultDetailThumbnailViewController: UIViewController { + weak var coordinator: ResultDetailThumbnailViewCoordinator? + + enum DetailThumbnailSection: Int, CaseIterable { + case main + } + + typealias DetailThumbnailDataSource = UICollectionViewDiffableDataSource + typealias DetailThumbnailSnapshot = NSDiffableDataSourceSnapshot + + private var dataSource: DetailThumbnailDataSource? + + var uiImages = [String: UIImage]() + + lazy var collectionView: UICollectionView = { + let flowLayout = UICollectionViewFlowLayout() + let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + + return collectionView + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.configureCollectionView() + self.configureViews() + self.configuareDataSource() + self.configureImages() + } + + private func configureViews() { + self.view.backgroundColor = .systemBackground + self.view.addSubview(self.collectionView) + + NSLayoutConstraint.activate([ + self.collectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), + self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + self.collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) + ]) + } + + private func configureCollectionView() { + self.collectionView.collectionViewLayout = configureCompositionalLayout() + self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) + } + + private func bindSnapShotApply(section: DetailThumbnailSection, item: [AnyHashable]) { + var snapshot = DetailThumbnailSnapshot() + snapshot.appendSections([.main]) + item.forEach { + snapshot.appendItems([$0], toSection: section) + } + self.dataSource?.apply(snapshot, animatingDifferences: true) + } + + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { + return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1))) + item.contentInsets = .init(top: 3, leading: 3, bottom: 3, trailing: 3) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1)), subitems: [item]) + let section = NSCollectionLayoutSection(group: group) + section.orthogonalScrollingBehavior = .paging + section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + return section + } + } + + private func configuareDataSource() { + let datasource = DetailThumbnailDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell, + let item = item as? String, + let image = self.uiImages[item] else { + return UICollectionViewCell() } + + cell.update(image: image) + return cell + }) + + self.dataSource = datasource + self.collectionView.dataSource = dataSource + } + + private func configureImages() { + var identifiers = [String]() + + for (key, _) in self.uiImages { + identifiers.append(key) + } + + self.bindSnapShotApply(section: .main, item: identifiers) + } +} diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift new file mode 100644 index 0000000..c77baf3 --- /dev/null +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift @@ -0,0 +1,32 @@ +// +// ResultDetailThumbnailCoordinator.swift +// SanTa +// +// Created by 김민창 on 2021/11/24. +// + +import UIKit + +class ResultDetailThumbnailViewCoordinator: Coordinator { + weak var parentCoordinator: Coordinator? + var childCoordinators: [Coordinator] = [] + var navigationController: UINavigationController + + let uiImages: [String: UIImage] + + func start() { + let resultDetailThumbnailViewController = ResultDetailThumbnailViewController() + resultDetailThumbnailViewController.uiImages = self.uiImages + resultDetailThumbnailViewController.coordinator = self + self.navigationController.pushViewController(resultDetailThumbnailViewController, animated: true) + } + + func dismiss() { + self.parentCoordinator?.childCoordinators.removeLast() + } + + init(navigationController: UINavigationController, uiImages: [String: UIImage]) { + self.navigationController = navigationController + self.uiImages = uiImages + } +} From 1402b5c6f16a9516044b1e2698377ccd240f3cde Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 00:12:56 +0900 Subject: [PATCH 379/465] =?UTF-8?q?[Feat]=20#279=20presentResultDetailThum?= =?UTF-8?q?bnailViewController=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailViewCoordinator.swift | 8 ++++++++ .../ResultDetailThumbnailViewController.swift | 1 + .../ResultDetailThumbnailViewCoordinator.swift | 8 ++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 1607baa..5259078 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -67,4 +67,12 @@ extension ResultDetailViewCoordinator { resultDetailImagesViewCoordinator.start() } + + func presentResultDetailThumbnailViewController(uiImages: [String: UIImage], id: String) { + let resultDetailThumbnailViewCoordinator = ResultDetailThumbnailViewCoordinator(navigationController: navigationController, uiImages: uiImages, id: id) + self.childCoordinators.append(resultDetailThumbnailViewCoordinator) + resultDetailThumbnailViewCoordinator.parentCoordinator = self + + resultDetailThumbnailViewCoordinator.start() + } } diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index 2ce570a..cba504e 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -20,6 +20,7 @@ class ResultDetailThumbnailViewController: UIViewController { private var dataSource: DetailThumbnailDataSource? var uiImages = [String: UIImage]() + var currentIdentifier = String() lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift index c77baf3..d503213 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift @@ -13,20 +13,24 @@ class ResultDetailThumbnailViewCoordinator: Coordinator { var navigationController: UINavigationController let uiImages: [String: UIImage] + let id: String func start() { let resultDetailThumbnailViewController = ResultDetailThumbnailViewController() resultDetailThumbnailViewController.uiImages = self.uiImages + resultDetailThumbnailViewController.currentIdentifier = self.id resultDetailThumbnailViewController.coordinator = self - self.navigationController.pushViewController(resultDetailThumbnailViewController, animated: true) + + self.navigationController.present(resultDetailThumbnailViewController, animated: true) } func dismiss() { self.parentCoordinator?.childCoordinators.removeLast() } - init(navigationController: UINavigationController, uiImages: [String: UIImage]) { + init(navigationController: UINavigationController, uiImages: [String: UIImage], id: String) { self.navigationController = navigationController self.uiImages = uiImages + self.id = id } } From fc5ba2128545ffdc2f171e85acc5fc6be40cb2b0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 00:17:53 +0900 Subject: [PATCH 380/465] [Feat] #279 present ThumbnailView --- .../ResultDetailScene/ResultDetailViewController.swift | 2 +- .../ResultDetailThumbnailViewController.swift | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index ac14460..d1acf5a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -477,6 +477,6 @@ extension ResultDetailViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { guard let annotation = view as? ThumbnailView else { return } - print(annotation.imageIdentifier) + self.coordinator?.presentResultDetailThumbnailViewController(uiImages: uiImages, id: annotation.imageIdentifier) } } diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index cba504e..8b75bf2 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -38,15 +38,20 @@ class ResultDetailThumbnailViewController: UIViewController { self.configureImages() } + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + self.coordinator?.dismiss() + } + private func configureViews() { self.view.backgroundColor = .systemBackground self.view.addSubview(self.collectionView) NSLayoutConstraint.activate([ - self.collectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), - self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) + self.collectionView.heightAnchor.constraint(equalTo: self.view.widthAnchor), + self.collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) ]) } From 067180e8fa19993cabf8a3f58ccba5e7772abe81 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 00:33:43 +0900 Subject: [PATCH 381/465] =?UTF-8?q?[Refactor]=20#302=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EC=85=80=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/DetailCell.swift | 99 +++++++++---------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index b17501f..6324822 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -10,25 +10,39 @@ import UIKit class DetailCell: UICollectionViewCell { static let identifier = "DetailCell" + let title: UILabel = { + let label = UILabel() + label.font = .preferredFont(for: .body, weight: .bold) + label.textColor = .init(named: "SantaColor") + label.adjustsFontSizeToFitWidth = true + + return label + }() + + let line: UIView = { + let view = UIView() + view.backgroundColor = .init(named: "SantaColor") + + return view + }() + + let stack: UIStackView = { + let stack = UIStackView() + stack.axis = .vertical + + return stack + }() + func layout(data: LargeViewModel) { - self.subviews.forEach{$0.removeFromSuperview()} - let title: UILabel = UILabel() self.addSubview(title) title.text = data.title - title.font = .preferredFont(for: .body, weight: .bold) - title.numberOfLines = 0 - title.adjustsFontSizeToFitWidth = true - title.textColor = .init(named: "SantaColor") title.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ title.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), title.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10) ]) - let line = UIView() self.addSubview(line) - - line.backgroundColor = .init(named: "SantaColor") line.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ line.heightAnchor.constraint(equalToConstant: 1), @@ -37,36 +51,10 @@ class DetailCell: UICollectionViewCell { line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), ]) - - - var contentLabels: [UILabel] = [] - var contentTitleLabels: [UILabel] = [] - - for content in data.contents { - let contentLabel = UILabel() - contentLabel.text = content.content - contentLabel.font = .preferredFont(for: .title1, weight: .bold) - contentLabel.numberOfLines = 0 - - let contentTitleLabel = UILabel() - contentTitleLabel.text = content.contentTitle - contentTitleLabel.font = .preferredFont(forTextStyle: .body) - contentTitleLabel.numberOfLines = 0 - contentLabels.append(contentLabel) - contentTitleLabels.append(contentTitleLabel) - } - - let stack = UIStackView() + stack.subviews.forEach{ $0.removeFromSuperview() } self.addSubview(stack) - stack.axis = .vertical - - for index in 0.. Date: Thu, 25 Nov 2021 00:50:35 +0900 Subject: [PATCH 382/465] =?UTF-8?q?[Feat]=20#279=20=EC=A7=80=EC=A0=95?= =?UTF-8?q?=EB=90=9C=20=EC=85=80=EB=A1=9C=20ColletionView=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailThumbnailViewController.swift | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index 8b75bf2..24266b7 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -18,11 +18,12 @@ class ResultDetailThumbnailViewController: UIViewController { typealias DetailThumbnailSnapshot = NSDiffableDataSourceSnapshot private var dataSource: DetailThumbnailDataSource? + private var showIndex = 0 var uiImages = [String: UIImage]() var currentIdentifier = String() - lazy var collectionView: UICollectionView = { + private lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) collectionView.translatesAutoresizingMaskIntoConstraints = false @@ -30,6 +31,16 @@ class ResultDetailThumbnailViewController: UIViewController { return collectionView }() + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.backgroundColor = .systemBackground + label.tintColor = .label + label.textAlignment = .center + label.font = .preferredFont(for: .body, weight: .bold) + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + override func viewDidLoad() { super.viewDidLoad() self.configureCollectionView() @@ -46,6 +57,7 @@ class ResultDetailThumbnailViewController: UIViewController { private func configureViews() { self.view.backgroundColor = .systemBackground self.view.addSubview(self.collectionView) + self.view.addSubview(self.titleLabel) NSLayoutConstraint.activate([ self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), @@ -53,9 +65,16 @@ class ResultDetailThumbnailViewController: UIViewController { self.collectionView.heightAnchor.constraint(equalTo: self.view.widthAnchor), self.collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) ]) + + NSLayoutConstraint.activate([ + self.titleLabel.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 15), + self.titleLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + self.titleLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + ]) } private func configureCollectionView() { + self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) } @@ -66,7 +85,10 @@ class ResultDetailThumbnailViewController: UIViewController { item.forEach { snapshot.appendItems([$0], toSection: section) } - self.dataSource?.apply(snapshot, animatingDifferences: true) + self.dataSource?.apply(snapshot, animatingDifferences: true) { [weak self] in + guard let index = self?.showIndex else { return } + self?.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: .right, animated: true) + } } private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { @@ -99,11 +121,27 @@ class ResultDetailThumbnailViewController: UIViewController { private func configureImages() { var identifiers = [String]() + var index = 0 + var findImage = false for (key, _) in self.uiImages { identifiers.append(key) + + if key == currentIdentifier { + findImage = true + self.showIndex = index + self.titleLabel.text = "\(index + 1) / \(self.uiImages.count)" + } + if !findImage { index += 1 } } self.bindSnapShotApply(section: .main, item: identifiers) } } + +extension ResultDetailThumbnailViewController: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt index: IndexPath) { + self.showIndex = index.row + self.titleLabel.text = "\(showIndex + 1) / \(self.uiImages.count)" + } +} From 8affa3213175197c0ae2559c5158c33d9529eff0 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 01:19:39 +0900 Subject: [PATCH 383/465] =?UTF-8?q?[Feat]=20#279=20=EC=84=AC=EB=84=A4?= =?UTF-8?q?=EC=9D=BC=20=EB=A7=88=EC=BB=A4=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 8 ++++---- .../DetailImagesCell.swift | 4 +++- .../ResultDetailImagesViewController.swift | 16 +++++++++++----- ...t => ResultDetailImagesViewCoordinator.swift} | 10 ++++++++++ .../ResultDetailThumbnailViewController.swift | 15 +++++++++------ 5 files changed, 37 insertions(+), 16 deletions(-) rename SanTa/SanTa/ResultDetailImagesScene/{ResultDetailImageViewCoordinator.swift => ResultDetailImagesViewCoordinator.swift} (65%) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index fe812ba..991e6cc 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -104,7 +104,7 @@ DAB751BA274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */; }; DAB751BC274E7DFB00C39266 /* ResultDetailThumbnailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */; }; DAE7540E274D2A25004A19C3 /* ResultDetailImagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */; }; - DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */; }; + DAE75410274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE7540F274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift */; }; DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */; }; DAFA9B59274112D800BF168C /* RecordingPhotoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */; }; DAFA9B5B2741131400BF168C /* RecordingPhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */; }; @@ -212,7 +212,7 @@ DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailThumbnailViewController.swift; sourceTree = ""; }; DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailThumbnailViewCoordinator.swift; sourceTree = ""; }; DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewController.swift; sourceTree = ""; }; - DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImageViewCoordinator.swift; sourceTree = ""; }; + DAE7540F274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailImagesViewCoordinator.swift; sourceTree = ""; }; DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailImagesCell.swift; sourceTree = ""; }; DAFA9B58274112D800BF168C /* RecordingPhotoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoCoordinator.swift; sourceTree = ""; }; DAFA9B5A2741131400BF168C /* RecordingPhotoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingPhotoViewController.swift; sourceTree = ""; }; @@ -491,7 +491,7 @@ isa = PBXGroup; children = ( DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */, - DAE7540F274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift */, + DAE7540F274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift */, DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */, ); path = ResultDetailImagesScene; @@ -673,7 +673,7 @@ 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, 54296949272FBFAB0070B362 /* RecordingViewController.swift in Sources */, - DAE75410274D2A32004A19C3 /* ResultDetailImageViewCoordinator.swift in Sources */, + DAE75410274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift in Sources */, 54B3206D27453725002232BD /* MountainAddingViewRepository.swift in Sources */, 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */, 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift index a88c986..41ef968 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -11,6 +11,7 @@ class DetailImagesCell: UICollectionViewCell { static let identifier = "DetailImagesCell" private let imageView = UIImageView() + var id = String() override init(frame: CGRect) { super.init(frame: frame) @@ -33,7 +34,8 @@ class DetailImagesCell: UICollectionViewCell { ]) } - func update(image: UIImage) { + func update(image: UIImage, id: String) { self.imageView.image = image + self.id = id } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index 88efe3a..5c2ece8 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -20,6 +20,7 @@ class ResultDetailImagesViewController: UIViewController { private var dataSource: DetailImagesDataSource? var uiImages = [String: UIImage]() + var identifiers = [String]() lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() @@ -63,6 +64,7 @@ class ResultDetailImagesViewController: UIViewController { } private func configureCollectionView() { + self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) } @@ -96,7 +98,7 @@ class ResultDetailImagesViewController: UIViewController { let image = self.uiImages[item] else { return UICollectionViewCell() } - cell.update(image: image) + cell.update(image: image, id: item) return cell }) @@ -105,12 +107,16 @@ class ResultDetailImagesViewController: UIViewController { } private func configureImages() { - var identifiers = [String]() - for (key, _) in self.uiImages { - identifiers.append(key) + self.identifiers.append(key) } - self.bindSnapShotApply(section: .main, item: identifiers) + self.bindSnapShotApply(section: .main, item: self.identifiers) + } +} + +extension ResultDetailImagesViewController: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, didSelectItemAt index: IndexPath) { + self.coordinator?.presentResultDetailThumbnailViewController(uiImages: self.uiImages, id: self.identifiers[index.item]) } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift similarity index 65% rename from SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift rename to SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift index 772212b..459e53e 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImageViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift @@ -30,3 +30,13 @@ class ResultDetailImagesViewCoordinator: Coordinator { self.uiImages = uiImages } } + +extension ResultDetailImagesViewCoordinator { + func presentResultDetailThumbnailViewController(uiImages: [String: UIImage], id: String) { + let resultDetailThumbnailViewCoordinator = ResultDetailThumbnailViewCoordinator(navigationController: navigationController, uiImages: uiImages, id: id) + self.childCoordinators.append(resultDetailThumbnailViewCoordinator) + resultDetailThumbnailViewCoordinator.parentCoordinator = self + + resultDetailThumbnailViewCoordinator.start() + } +} diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index 24266b7..0c8e674 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -18,6 +18,7 @@ class ResultDetailThumbnailViewController: UIViewController { typealias DetailThumbnailSnapshot = NSDiffableDataSourceSnapshot private var dataSource: DetailThumbnailDataSource? + private var firetShowIndex = 0 private var showIndex = 0 var uiImages = [String: UIImage]() @@ -54,6 +55,11 @@ class ResultDetailThumbnailViewController: UIViewController { self.coordinator?.dismiss() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + self.collectionView.scrollToItem(at: IndexPath(row: self.firetShowIndex, section: 0), at: .right, animated: true) + } + private func configureViews() { self.view.backgroundColor = .systemBackground self.view.addSubview(self.collectionView) @@ -85,10 +91,7 @@ class ResultDetailThumbnailViewController: UIViewController { item.forEach { snapshot.appendItems([$0], toSection: section) } - self.dataSource?.apply(snapshot, animatingDifferences: true) { [weak self] in - guard let index = self?.showIndex else { return } - self?.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: .right, animated: true) - } + self.dataSource?.apply(snapshot, animatingDifferences: true) } private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { @@ -111,7 +114,7 @@ class ResultDetailThumbnailViewController: UIViewController { let image = self.uiImages[item] else { return UICollectionViewCell() } - cell.update(image: image) + cell.update(image: image, id: item) return cell }) @@ -129,7 +132,7 @@ class ResultDetailThumbnailViewController: UIViewController { if key == currentIdentifier { findImage = true - self.showIndex = index + self.firetShowIndex = index self.titleLabel.text = "\(index + 1) / \(self.uiImages.count)" } if !findImage { index += 1 } From fb1993267e4ac81d54163385a2c35d464fc42905 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 01:44:29 +0900 Subject: [PATCH 384/465] =?UTF-8?q?[Feat]=20#308,=20#309=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=20=EA=B6=8C=ED=95=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사진 권한이 없으면 자동으로 스위치를 변경하고, 설정 앱으로 Transition --- .../SanTa/SettingsScene/SettingsUsecase.swift | 14 +++++++++-- .../SettingsViewController.swift | 24 +++++++++++++++++++ .../SettingsScene/SettingsViewModel.swift | 19 +++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 2eaf011..f9a3a2a 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -6,10 +6,10 @@ // import Foundation +import Photos final class SettingsUsecase { - - let settingsRepository: SettingsRepository + private let settingsRepository: SettingsRepository init(settingsRepository: SettingsRepository) { self.settingsRepository = settingsRepository @@ -19,6 +19,16 @@ final class SettingsUsecase { self.settingsRepository.save(value: value, key: key) } + func photoPermission(completion: @escaping (Bool) -> Void) { + let photoPermission = PHPhotoLibrary.authorizationStatus(for: .readWrite) + switch photoPermission { + case .authorized: + completion(true) + default: + completion(false) + } + } + func makeSettings() -> [[Option]] { var options: [[Option]] = [] var photoSettings: [Option] = [] diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index e6a7f13..ccb5ea4 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -51,6 +51,11 @@ class SettingsViewController: UIViewController { self.bind() self.viewModel?.viewDidLoad() } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.viewModel?.viewWillAppear() + } private func configureTableView() { self.tableView.dataSource = self @@ -89,6 +94,25 @@ class SettingsViewController: UIViewController { self.viewModel?.$settings.sink { [weak self] _ in self?.tableView.reloadData() }.store(in: &self.subscriptions) + self.viewModel?.isPhotoRecordAvailable.sink { [weak self] bool in + self?.configurePhotoPermission(bool) + }.store(in: &self.subscriptions) + } + + private func configurePhotoPermission(_ bool: Bool) { + if !bool { + let alert = UIAlertController(title: "사진 권한 활성화", message: "측정하는 동안 사진을 기록할 수 있도록 위치정보를 활성화해주세요", preferredStyle: .alert) + let confirm = UIAlertAction(title: "확인", style: .default) { _ in + guard let url = URL(string: UIApplication.openSettingsURLString) else { return } + UIApplication.shared.open(url) + } + alert.addAction(confirm) + self.present(alert, animated: true) { + guard let photoSwitchCell = self.tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? ToggleOptionCell + else { return } + photoSwitchCell.changeSwitch() + } + } } private func showMapActionSheet(cellTitle: String) { diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift index 0fa7762..bc65675 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -13,6 +13,7 @@ final class SettingsViewModel { @Published var settings: [[Option]] = [] let settingsUseCase: SettingsUsecase + let isPhotoRecordAvailable = PassthroughSubject() var sectionCount: Int { return settings.count @@ -26,6 +27,15 @@ final class SettingsViewModel { self.reloadSettings() } + func viewWillAppear() { + self.settingsUseCase.photoPermission { [weak self] bool in + if !bool { + self?.settingsUseCase.save(value: false, key: .recordPhoto) + self?.reloadSettings() + } + } + } + func option(indexPath: IndexPath) -> Option { return settings[indexPath.section][indexPath.item] } @@ -34,6 +44,15 @@ final class SettingsViewModel { self.settingsUseCase.save(value: value, key: key) if value is String { self.reloadSettings() + return + } + if key == Settings.recordPhoto { + self.settingsUseCase.photoPermission { bool in + self.isPhotoRecordAvailable.send(bool) + if !bool { + self.settingsUseCase.save(value: false, key: .recordPhoto) + } + } } } From d514810ca655eaeaadb3612dffcee40b9fae8b1c Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 10:56:24 +0900 Subject: [PATCH 385/465] =?UTF-8?q?[Refactor]=20=EC=8A=A4=ED=83=9D?= =?UTF-8?q?=EB=B7=B0=20=EC=83=9D=EC=84=B1=EC=9E=90=20fileprivate=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/DetailCell.swift | 7 ++----- .../ResultDetailLargerInfoView.swift | 2 +- .../ResultDetailViewController.swift | 2 +- .../ResultDetailScene/ResultDetailViewModel.swift | 14 +++++++------- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index 6324822..f5231ff 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -15,25 +15,22 @@ class DetailCell: UICollectionViewCell { label.font = .preferredFont(for: .body, weight: .bold) label.textColor = .init(named: "SantaColor") label.adjustsFontSizeToFitWidth = true - return label }() let line: UIView = { let view = UIView() view.backgroundColor = .init(named: "SantaColor") - return view }() let stack: UIStackView = { let stack = UIStackView() stack.axis = .vertical - return stack }() - func layout(data: LargeViewModel) { + func layout(data: DetailInformationModel) { self.addSubview(title) title.text = data.title title.translatesAutoresizingMaskIntoConstraints = false @@ -77,7 +74,7 @@ extension UIFont { } extension UIStackView { - convenience init(content: CellContentEntity) { + fileprivate convenience init(content: CellContentEntity) { self.init() self.axis = .horizontal self.distribution = .equalCentering diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index a5f07a6..35082b1 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -88,7 +88,7 @@ extension ResultDetailLargerInfoView { let datasource = DetailLargerInfoDataSource (collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell, - let item = item as? LargeViewModel else { + let item = item as? DetailInformationModel else { return UICollectionViewCell() } cell.layout(data: item) return cell diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 945d7a3..ba282a2 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -150,7 +150,7 @@ class ResultDetailViewController: UIViewController { let inclineViewModel = self?.viewModel?.inclineViewMedel else { return } - let largeInfoModel: [LargeViewModel] = [ + let largeInfoModel: [DetailInformationModel] = [ distanceViewModel, timeViewModel, paceViewModel, altitudeViewModel, inclineViewModel ] self?.largerInformationView.bindSnapShotApply(section: .main, item: largeInfoModel) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index e1035e0..942fe81 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -113,7 +113,7 @@ protocol ResultDetailCellRepresentable: Hashable { var contents: [CellContentEntity] { get } } -class LargeViewModel: Hashable { +class DetailInformationModel: Hashable { var id: UUID = UUID() var title: String = "" var contents: [CellContentEntity] = [] @@ -122,13 +122,13 @@ class LargeViewModel: Hashable { hasher.combine(id) } - static func == (lhs: LargeViewModel, rhs: LargeViewModel) -> Bool { + static func == (lhs: DetailInformationModel, rhs: DetailInformationModel) -> Bool { lhs.id == rhs.id } } extension ResultDetailViewModel { - class DistanceViewModel: LargeViewModel { + class DistanceViewModel: DetailInformationModel { var totalDistance: String = "" var steps: String = "" @@ -155,7 +155,7 @@ extension ResultDetailViewModel { } } - class TimeViewModel: LargeViewModel { + class TimeViewModel: DetailInformationModel { var totalTimeSpent: String = "" init(timeData: ResultTime?) { @@ -181,7 +181,7 @@ extension ResultDetailViewModel { } } - class PaceViewModel: LargeViewModel { + class PaceViewModel: DetailInformationModel { init(paceData: ResultPace?) { super.init() guard let pace = paceData else { @@ -204,7 +204,7 @@ extension ResultDetailViewModel { } } - class AltitudeViewModel: LargeViewModel { + class AltitudeViewModel: DetailInformationModel { var highest: String = "" var lowest: String = "" @@ -226,7 +226,7 @@ extension ResultDetailViewModel { } } - class InclineViewModel: LargeViewModel { + class InclineViewModel: DetailInformationModel { init(inclineData: ResultIncline?) { super.init() guard let inclineData = inclineData else { From 4cbbc87d43fbb68510e71782b2cf267c94382809 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 25 Nov 2021 11:28:47 +0900 Subject: [PATCH 386/465] =?UTF-8?q?[Feat]=20#312=20RecordingTitleViewCoord?= =?UTF-8?q?inator=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleViewCoordinator.swift | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 82f421c..103bbb2 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -19,27 +19,13 @@ class RecordingTitleViewCoordinator: Coordinator { } func start() { - if let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator { - recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) - } else if let resultDetailCoordinator = parentCoordinator as? ResultDetailViewCoordinator { - resultDetailCoordinator.navigationController.viewControllers.last?.present(recordingTitleViewController, animated: true) - } -// guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else {return} - -// recordingCoordinator.recordingViewController.present(recordingTitleViewController, animated: true) + guard let viewController = self.recordingTitleViewController.delegate as? UIViewController else { return } + viewController.present(recordingTitleViewController, animated: true) } func dismiss() { - if let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator { - recordingCoordinator.recordingViewController.dismiss(animated: true, completion: nil) - - } else if let resultDetailViewCoordinator = parentCoordinator as? ResultDetailViewCoordinator { - resultDetailViewCoordinator.navigationController.viewControllers.last?.dismiss(animated: true, completion: nil) - } - -// guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } -// recordingCoordinator.recordingViewController.dismiss(animated: true) - + guard let viewController = self.recordingTitleViewController.delegate as? UIViewController else { return } + viewController.dismiss(animated: true, completion: nil) self.parentCoordinator?.childCoordinators.removeLast() } From aebd7ada5b05cbc20c0964a9bdee4ecfce7e81a1 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 11:38:34 +0900 Subject: [PATCH 387/465] =?UTF-8?q?[BUG]=20=EC=95=84=EC=9D=B4=ED=8F=B0=20x?= =?UTF-8?q?s=20=EA=B8=B0=EB=A1=9D=20=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=ED=91=9C=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/DetailCell.swift | 2 -- SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index f5231ff..f1fe9c3 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -82,12 +82,10 @@ extension UIStackView { let contentLabel = UILabel() contentLabel.text = content.content contentLabel.font = .preferredFont(for: .title1, weight: .bold) - contentLabel.numberOfLines = 0 let contentTitleLabel = UILabel() contentTitleLabel.text = content.contentTitle contentTitleLabel.font = .preferredFont(forTextStyle: .body) - contentTitleLabel.numberOfLines = 0 self.addArrangedSubview(contentLabel) self.addArrangedSubview(contentTitleLabel) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 35082b1..5bb9967 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -119,7 +119,7 @@ extension ResultDetailLargerInfoView { private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in - let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.5), heightDimension: .estimated(500))) + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.495), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) let section = NSCollectionLayoutSection(group: group) From 49ad6214619902d1749919e7645080f9fa3721b6 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 13:50:31 +0900 Subject: [PATCH 388/465] =?UTF-8?q?[Feat]=20#314=20LocationManager=20Activ?= =?UTF-8?q?ityType=20Fitness=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 52bd390..b646aac 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -64,6 +64,7 @@ final class RecordingModel: NSObject, ObservableObject { private func configureLocationManager() { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() + self.locationManager.activityType = .fitness self.locationManager.allowsBackgroundLocationUpdates = true self.locationManager.pausesLocationUpdatesAutomatically = false self.locationManager.showsBackgroundLocationIndicator = true From d2342d3bff0c4b6f06fc7fd6bf1d0248771530d3 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 13:53:42 +0900 Subject: [PATCH 389/465] =?UTF-8?q?[Feat]=20#315=20LocationManager=20Dista?= =?UTF-8?q?nce=20Filter=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index b646aac..8fc7b67 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -65,6 +65,7 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.activityType = .fitness + self.locationManager.distanceFilter = 5 self.locationManager.allowsBackgroundLocationUpdates = true self.locationManager.pausesLocationUpdatesAutomatically = false self.locationManager.showsBackgroundLocationIndicator = true From a988b13ac2642b8650a6bc99b0d74011ae7cff85 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 14:48:03 +0900 Subject: [PATCH 390/465] =?UTF-8?q?[Feat]=20#277=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EC=8D=B8=EB=84=A4=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=86=A0=EA=B8=80=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailUseCase.swift | 7 ++++ .../ResultDetailViewController.swift | 37 +++++++++++++++++-- .../ResultDetailViewModel.swift | 12 +++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index c8fc709..39d927b 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -10,10 +10,12 @@ import Foundation class ResultDetailUseCase { private let model: ResultDetailData private let repository: ResultDetailRepository + private(set) var isImageVisibilityOn: Bool init(model: ResultDetailData, repository: ResultDetailRepository) { self.model = model self.repository = repository + self.isImageVisibilityOn = true } func transferResultDetailData(completion: (ResultDetailData) -> Void) { @@ -27,4 +29,9 @@ class ResultDetailUseCase { func update(title: String, id: String, completion: @escaping (Result) -> Void) { self.repository.update(title: title, id: id, completion: completion) } + + func toggleImageVisibility(completion: @escaping (Bool) -> Void) { + isImageVisibilityOn.toggle() + completion(isImageVisibilityOn) + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index fd7c2e9..e78ee03 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -8,6 +8,7 @@ import UIKit import MapKit import Photos +import Combine class ResultDetailViewController: UIViewController { @@ -21,6 +22,7 @@ class ResultDetailViewController: UIViewController { private let imageManager = PHCachingImageManager() private var uiImages = [String: UIImage]() + private var observers: [AnyCancellable] = [] private lazy var mapView: MKMapView = { let mapView = MKMapView() @@ -71,7 +73,6 @@ class ResultDetailViewController: UIViewController { private lazy var detailImagesButton: UIButton = { let button = UIButton() - button.setImage(.init(systemName: "photo.on.rectangle.angled"), for: .normal) button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) button.titleLabel?.font = .boldSystemFont(ofSize: 15) button.backgroundColor = .systemBackground @@ -92,8 +93,6 @@ class ResultDetailViewController: UIViewController { private lazy var imagesVisibilityButton: UIButton = { let button = UIButton() - button.setImage(.init(systemName: "eye"), for: .normal) - //eye.slash button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) button.backgroundColor = .systemBackground button.tintColor = .label @@ -158,6 +157,17 @@ class ResultDetailViewController: UIViewController { self?.configureViews() self?.configurePanGesture() } + self.viewModel?.$imageVisibilityIconName + .sink(receiveValue: { [weak self] string in + self?.configureImageVisibilityButton(string) + }) + .store(in: &observers) + self.viewModel?.imageVisibilityStatus + .sink(receiveValue: { [weak self] bool in + self?.configureImageVisibility(bool) + }) + .store(in: &observers) + viewModel?.setUp() } @@ -167,6 +177,25 @@ class ResultDetailViewController: UIViewController { forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier ) } + + private func configureImageVisibilityButton(_ imageName: String?) { + guard let imageName = imageName else { return } + self.imagesVisibilityButton.setImage(UIImage(systemName: imageName), for: .normal) + } + + private func configureImageVisibility(_ bool: Bool) { + let imageAnnotations = self.mapView.annotations.filter{$0.title != "start" && $0.title != "end"} + switch bool { + case true: + imageAnnotations.forEach{ + self.mapView.view(for: $0)?.isHidden = false + } + case false: + imageAnnotations.forEach{ + self.mapView.view(for: $0)?.isHidden = true + } + } + } private func drawPathOnMap() { guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { @@ -397,7 +426,7 @@ extension ResultDetailViewController { } @objc func imagesVisibilityButtonAction() { - + self.viewModel?.imageVisibilityButtonTouched() } @objc func presentModifyResultAlert() { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 942fe81..8c70127 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -5,8 +5,8 @@ // Created by Jiwon Yoon on 2021/11/16. // -import Foundation import CoreLocation +import Combine class ResultDetailViewModel { private let useCase: ResultDetailUseCase @@ -27,6 +27,8 @@ class ResultDetailViewModel { var inclineViewMedel: InclineViewModel { return InclineViewModel(inclineData: self.resultDetailData?.incline) } + @Published var imageVisibilityIconName: String? + let imageVisibilityStatus = PassthroughSubject() init(useCase: ResultDetailUseCase) { self.useCase = useCase @@ -38,6 +40,7 @@ class ResultDetailViewModel { self?.resultDetailData = dataModel self?.recordDidFetch() } + self.imageVisibilityIconName = useCase.isImageVisibilityOn ? "eye" : "eye.slash" } func delete(completion: @escaping (Result) -> Void) { @@ -101,6 +104,13 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: endTime) } + + func imageVisibilityButtonTouched() { + self.useCase.toggleImageVisibility { [weak self] bool in + bool ? (self?.imageVisibilityIconName = "eye") : (self?.imageVisibilityIconName = "eye.slash") + self?.imageVisibilityStatus.send(bool) + } + } } struct CellContentEntity { From 2a03c924b4acd1e090ae0277736a712f68d2ecdb Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 14:51:17 +0900 Subject: [PATCH 391/465] =?UTF-8?q?[Fix]=20#315=20=EA=B3=A0=EB=8F=84?= =?UTF-8?q?=EC=B0=A8=EA=B0=80=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20=ED=91=9C?= =?UTF-8?q?=EA=B8=B0=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/ResultViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 93a9996..84edaa7 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -127,7 +127,7 @@ extension ResultViewModel { private func cellAltitudeDifferenceFormatter(_ number: Double) -> String { guard number < 10000 else { return "9,999+" } - guard number < 1 else { return "-" } + guard number > 1 else { return "-" } return self.intFormatter(Int(number)) } From 0cdf814eedd8a11591303f50a28f069627378ab4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 15:24:46 +0900 Subject: [PATCH 392/465] =?UTF-8?q?[Feat]=20#315=20Location=20=EC=98=A4?= =?UTF-8?q?=EC=B0=A8=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 8fc7b67..a071202 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -65,7 +65,7 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.startUpdatingLocation() self.locationManager.activityType = .fitness - self.locationManager.distanceFilter = 5 + self.locationManager.distanceFilter = 3 self.locationManager.allowsBackgroundLocationUpdates = true self.locationManager.pausesLocationUpdatesAutomatically = false self.locationManager.showsBackgroundLocationIndicator = true @@ -257,15 +257,32 @@ final class RecordingModel: NSObject, ObservableObject { extension RecordingModel: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let lastLocation = locations.last { - location.append(Location(latitude: Double(lastLocation.coordinate.latitude), - longitude: Double(lastLocation.coordinate.longitude), - altitude: Double(lastLocation.altitude))) self.checkPedoMeter() - altitude = "\(Int(lastLocation.altitude))" + if filterBadLocation(lastLocation) { + altitude = "\(Int(lastLocation.altitude))" + location.append(Location(latitude: Double(lastLocation.coordinate.latitude), + longitude: Double(lastLocation.coordinate.longitude), + altitude: Double(lastLocation.altitude))) + } } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { self.gpsStatus = false } + + private func filterBadLocation(_ location: CLLocation) -> Bool{ + let age = -location.timestamp.timeIntervalSinceNow + + print(location.horizontalAccuracy) + print(location.verticalAccuracy) + + guard age < 5, + location.horizontalAccuracy > 0 && location.horizontalAccuracy < 30, + location.verticalAccuracy > 0 && location.verticalAccuracy < 6 else { + return false + } + + return true + } } From 099c24006eb6711c27b5dea320d64642dd87bb73 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 25 Nov 2021 15:29:47 +0900 Subject: [PATCH 393/465] =?UTF-8?q?[Feat]=20RecordingTitleView=20text=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index db1191c..9c5a7a6 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -22,7 +22,7 @@ class RecordingTitleViewController: UIViewController { private let recordingTitle: UILabel = { let label = UILabel() label.text = "기록 제목" - label.font = .boldSystemFont(ofSize: 24) + label.font = UIFont.preferredFont(forTextStyle: .title1) label.textColor = .systemGray label.translatesAutoresizingMaskIntoConstraints = false return label @@ -31,7 +31,7 @@ class RecordingTitleViewController: UIViewController { private let recordingTitleDescription: UILabel = { let label = UILabel() label.text = "이 기록에 대한 제목을 입력해주세요." - label.font = .systemFont(ofSize: 20) + label.font = UIFont.preferredFont(forTextStyle: .body) label.translatesAutoresizingMaskIntoConstraints = false return label }() From 45aaef03bea6ab5f97db12022c874836f304354e Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 15:34:10 +0900 Subject: [PATCH 394/465] =?UTF-8?q?[Feat]=20#319=20PHPhotoLibrary.requestA?= =?UTF-8?q?uthorization=20Handler=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 670f64f..9fb0c01 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -281,6 +281,13 @@ extension RecordingViewController: RecordingViewDelegate { } func didAgreeButtonTouchDone() { - PHPhotoLibrary.requestAuthorization { _ in } + PHPhotoLibrary.requestAuthorization { status in + switch status { + case .authorized: + break + case .notDetermined, .restricted, .denied, .limited: + break + } + } } } From 5db3328f6c2bfcb6c9fc01dba7b72e1d7af03524 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 25 Nov 2021 15:42:55 +0900 Subject: [PATCH 395/465] =?UTF-8?q?[Feat]=20#320=20=EC=A7=80=EB=8F=84?= =?UTF-8?q?=EC=97=90=20=EC=82=AC=EC=A7=84=ED=91=9C=EC=8B=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Persistences/UserDefaultsStorage.swift | 4 ---- SanTa/SanTa/SettingsScene/Settings.swift | 3 --- SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 3 --- 3 files changed, 10 deletions(-) diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index 6651dd8..f904a84 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -43,10 +43,6 @@ final class DefaultUserDefaultsStorage: UserDefaultsStorage { self.save(value: Settings.recordPhoto.initValue as? Bool, key: .recordPhoto) } - if !self.exist(key: .photosOnMap) { - self.save(value: Settings.photosOnMap.initValue as? Bool, - key: .photosOnMap) - } if !self.exist(key: .voiceGuidanceEveryOnekm) { self.save(value: Settings.voiceGuidanceEveryOnekm.initValue as? Bool, key: .voiceGuidanceEveryOnekm) diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/SettingsScene/Settings.swift index e9717c1..8f4737e 100644 --- a/SanTa/SanTa/SettingsScene/Settings.swift +++ b/SanTa/SanTa/SettingsScene/Settings.swift @@ -9,7 +9,6 @@ import Foundation enum Settings: String, CaseIterable { case recordPhoto = "사진 기록하기" - case photosOnMap = "지도에 사진표시" case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" case mapFormat = "지도 형식" @@ -21,8 +20,6 @@ enum Settings: String, CaseIterable { switch self { case .recordPhoto: return true - case .photosOnMap: - return true case .voiceGuidanceEveryOnekm: return true case .mapFormat: diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index f9a3a2a..282d10a 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -38,9 +38,6 @@ final class SettingsUsecase { self.settingsRepository.makeToggleOption(key: Settings.recordPhoto) { value in photoSettings.append(value) } - self.settingsRepository.makeToggleOption(key: Settings.photosOnMap) { value in - photoSettings.append(value) - } self.settingsRepository.makeToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in voiceSettings.append(value) } From 6c496e307eab3697402c47dd143a8dfe82f18d6e Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 15:45:13 +0900 Subject: [PATCH 396/465] =?UTF-8?q?[Feat]=20#318=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=ED=99=94=EB=A9=B4=20=ED=97=A4=EB=8D=94=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultDetailScene/DetailHeader.swift | 16 +++++++--------- .../ResultDetailLargerInfoView.swift | 18 ++++++++++++++++++ .../ResultDetailScene/ResultDetailModel.swift | 2 -- .../ResultDetailViewController.swift | 6 +++++- .../ResultDetailViewCoordinator.swift | 1 - .../ResultDetailViewModel.swift | 13 ++++++------- 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index 340e0d1..7a45915 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -15,7 +15,6 @@ class DetailHeader: UICollectionReusableView { label.backgroundColor = .label label.textColor = .systemBackground label.textAlignment = .center - label.text = "2021. 11. 16(화)" label.font = .preferredFont(forTextStyle: .caption1) label.adjustsFontForContentSizeCategory = true label.adjustsFontSizeToFitWidth = true @@ -50,7 +49,6 @@ class DetailHeader: UICollectionReusableView { private lazy var startTime: UILabel = { let label = UILabel() label.textColor = .label - label.text = "오후 6시 0분" label.textAlignment = .right label.numberOfLines = 2 label.font = .preferredFont(forTextStyle: .title2) @@ -63,7 +61,6 @@ class DetailHeader: UICollectionReusableView { private lazy var endTime: UILabel = { let label = UILabel() label.textColor = .label - label.text = "오후 7시 38분" label.textAlignment = .left label.numberOfLines = 2 label.font = .preferredFont(forTextStyle: .title2) @@ -93,20 +90,21 @@ class DetailHeader: UICollectionReusableView { override init(frame: CGRect) { super.init(frame: frame) - self.configure() } - + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - } - private func configure() { + func configure(date: String, startTime: String, endTime: String) { self.configureStackView() - self.configureViews() + self.configureViews(date: date, startTime: startTime, endTime: endTime) } - private func configureViews() { + private func configureViews(date: String, startTime: String, endTime: String) { + self.dateLabel.text = date + self.startTime.text = startTime + self.endTime.text = endTime self.addSubview(self.dateLabel) self.addSubview(self.labelStackView) self.addSubview(self.timeStackView) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 5bb9967..3933b0a 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -18,6 +18,10 @@ class ResultDetailLargerInfoView: UIView { private var dataSource: DetailLargerInfoDataSource? private var currentSnapshot: DetailLargerInfoSnapshot? + private var date: String = "" + private var startTime: String = "" + private var endTime: String = "" + lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -26,6 +30,13 @@ class ResultDetailLargerInfoView: UIView { return collectionView }() + init(frame: CGRect, date: String, start: String, end: String) { + super.init(frame: frame) + self.date = date + self.startTime = start + self.endTime = end + } + override init(frame: CGRect) { super.init(frame: frame) } @@ -60,6 +71,12 @@ extension ResultDetailLargerInfoView { self.displayUpDownMark() } + func configureHeaderInformation(date: String, startTime: String, endTime: String) { + self.date = date + self.startTime = startTime + self.endTime = endTime + } + func bindSnapShotApply(section: DetailLargerInfoSection, item: [AnyHashable]) { var snapshot = DetailLargerInfoSnapshot() snapshot.appendSections([.main]) @@ -113,6 +130,7 @@ extension ResultDetailLargerInfoView { indexPath: IndexPath) -> UICollectionReusableView? in guard let header: DetailHeader = self.collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { return DetailHeader() } + header.configure(date: self.date, startTime: self.startTime, endTime: self.endTime) return header } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index e0c8536..7a9f2f9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -56,12 +56,10 @@ struct ResultTimeStamp { struct ResultDistance { let total: Double - let exercise: Double let steps: Int init(records: Records) { self.total = records.distances - self.exercise = records.distances //?? self.steps = records.steps } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index fd7c2e9..6407b14 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -148,9 +148,13 @@ class ResultDetailViewController: UIViewController { let timeViewModel = self?.viewModel?.timeViewModel, let paceViewModel = self?.viewModel?.paceViewModel, let altitudeViewModel = self?.viewModel?.altitudeViewModel, - let inclineViewModel = self?.viewModel?.inclineViewMedel else { + let inclineViewModel = self?.viewModel?.inclineViewMedel, + let recordDate = self?.viewModel?.recordDate, + let startTime = self?.viewModel?.startTime, + let endTime = self?.viewModel?.endTime else { return } + self?.largerInformationView.configureHeaderInformation(date: recordDate, startTime: startTime, endTime: endTime) let largeInfoModel: [DetailInformationModel] = [ distanceViewModel, timeViewModel, paceViewModel, altitudeViewModel, inclineViewModel ] diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 5259078..fb7c09b 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -12,7 +12,6 @@ class ResultDetailViewCoordinator: Coordinator { var navigationController: UINavigationController var coreDataStorage: CoreDataStorage var records: Records -// let viewController: ResultDetailViewController = .init(viewModel: self.injectDependencies()) func start() { let resultDetailViewController = ResultDetailViewController(viewModel: injectDependencies()) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 942fe81..2f72ba7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -68,11 +68,10 @@ class ResultDetailViewModel { formatter.maximumFractionDigits = 2 let totalDistance = self.resultDetailData?.distance.total ?? 0 let totalTimeSpent = self.resultDetailData?.time.spent ?? 1 - print(totalTimeSpent) return formatter.string(from: NSNumber(value: totalDistance / totalTimeSpent)) ?? "" } - var recordDate: String { + lazy var recordDate: String = { guard let endTime = self.resultDetailData?.timeStamp.endTime else { return "" } @@ -80,9 +79,9 @@ class ResultDetailViewModel { dateFormatter.locale = Locale(identifier: "ko-KR") dateFormatter.dateFormat = "yyyy. MM. dd. (E)" return dateFormatter.string(from: endTime) - } + }() - var startDate: String { + lazy var startTime: String = { guard let startTime = self.resultDetailData?.timeStamp.startTime else { return "" } @@ -90,9 +89,9 @@ class ResultDetailViewModel { dateFormatter.locale = Locale(identifier: "ko-KR") dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: startTime) - } + }() - var endDate: String { + lazy var endTime: String = { guard let endTime = self.resultDetailData?.timeStamp.endTime else { return "" } @@ -100,7 +99,7 @@ class ResultDetailViewModel { dateFormatter.locale = Locale(identifier: "ko-KR") dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: endTime) - } + }() } struct CellContentEntity { From a7d4d576572abd72a8714b6997299d12b45b84a7 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 15:47:02 +0900 Subject: [PATCH 397/465] =?UTF-8?q?[Feat]=20#319=20saveRecordPhotoOption?= =?UTF-8?q?=20viewModel=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 ++++ SanTa/SanTa/RecordingScene/RecordingViewController.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index 582dba0..ea72d15 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -52,6 +52,10 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { self.recordRepository.save(records: records, completion: completion) } + func saveRecordPhotoOption(value: Bool) { + + } + func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] { guard let startDate = startDate, let endDate = endDate else { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 9fb0c01..e818c5c 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -284,9 +284,9 @@ extension RecordingViewController: RecordingViewDelegate { PHPhotoLibrary.requestAuthorization { status in switch status { case .authorized: - break + self.recordingViewModel?.saveRecordPhotoOption(value: true) case .notDetermined, .restricted, .denied, .limited: - break + self.recordingViewModel?.saveRecordPhotoOption(value: false) } } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 77e08d0..16730a5 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -15,6 +15,7 @@ protocol RecordingUseCase { func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] func pause() func resume() + func saveRecordPhotoOption(value: Bool) func fetchOptions() } @@ -90,6 +91,10 @@ final class RecordingViewModel: ObservableObject { self.recordingUseCase?.save(title: title, completion: completion) } + func saveRecordPhotoOption(value: Bool) { + self.recordingUseCase?.saveRecordPhotoOption(value: value) + } + func fetchOptions() { self.recordingUseCase?.fetchOptions() } From d7418b4076f5703894736d476968fff8eb820e3f Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 15:49:16 +0900 Subject: [PATCH 398/465] =?UTF-8?q?[Refactor]=20#286=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?=20=EB=B0=8F=20=ED=94=84=EB=A6=B0=ED=8A=B8=EB=AC=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailScene/ResultDetailLargerInfoView.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 3933b0a..9a41c14 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -29,13 +29,6 @@ class ResultDetailLargerInfoView: UIView { return collectionView }() - - init(frame: CGRect, date: String, start: String, end: String) { - super.init(frame: frame) - self.date = date - self.startTime = start - self.endTime = end - } override init(frame: CGRect) { super.init(frame: frame) From 3ca9d571fd612d167ef598f64e398a99da1f4f38 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 15:52:35 +0900 Subject: [PATCH 399/465] =?UTF-8?q?[Feat]=20#319=20saveRecordPhotoOption?= =?UTF-8?q?=20UseCase=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordRepository.swift | 4 ++++ SanTa/SanTa/RecordingScene/RecordingUseCase.swift | 4 +++- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 7ca3e74..4df478b 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -29,6 +29,10 @@ final class DefaultRecordRepository: RecordRepository { self.recordStorage.save(records: records, completion: completion) } + func saveRecordPhotoOption(value: Bool) { + + } + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { self.settingsStorage.string(key: key) { value in guard let value = value else { diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index ea72d15..f0dafae 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -10,6 +10,7 @@ import Foundation protocol RecordRepository { func save(records: Records, completion: @escaping (Result) -> Void) + func saveRecordPhotoOption(value: Bool) func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) } @@ -53,7 +54,8 @@ final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { } func saveRecordPhotoOption(value: Bool) { - + self.recording?.changedWillSpeechStatus(status: value) + self.recordRepository.saveRecordPhotoOption(value: value) } func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index e818c5c..19d60a4 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -287,6 +287,8 @@ extension RecordingViewController: RecordingViewDelegate { self.recordingViewModel?.saveRecordPhotoOption(value: true) case .notDetermined, .restricted, .denied, .limited: self.recordingViewModel?.saveRecordPhotoOption(value: false) + @unknown default: + self.recordingViewModel?.saveRecordPhotoOption(value: false) } } } From af029aa395ffb9115d52818eb24106e5b3834d3e Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 25 Nov 2021 15:54:01 +0900 Subject: [PATCH 400/465] =?UTF-8?q?[Feat]=20#320=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EB=B7=B0=20?= =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MapScene/MapViewController.swift | 2 +- SanTa/SanTa/SettingsScene/SettingsUsecase.swift | 17 +++++------------ .../SettingsScene/SettingsViewController.swift | 12 ++++-------- .../SanTa/SettingsScene/SettingsViewModel.swift | 8 ++------ 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 518aa92..a05ef1b 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -87,7 +87,7 @@ class MapViewController: UIViewController { } override func viewWillAppear(_ animated: Bool) { - viewModel?.viewWillAppear() + self.viewModel?.viewWillAppear() } private func configureViews() { diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 282d10a..74479df 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -29,26 +29,19 @@ final class SettingsUsecase { } } - func makeSettings() -> [[Option]] { - var options: [[Option]] = [] - var photoSettings: [Option] = [] - var voiceSettings: [Option] = [] - var mapSetting: [Option] = [] + func makeSettings() -> [Option] { + var options: [Option] = [] self.settingsRepository.makeToggleOption(key: Settings.recordPhoto) { value in - photoSettings.append(value) + options.append(value) } self.settingsRepository.makeToggleOption(key: Settings.voiceGuidanceEveryOnekm) { value in - voiceSettings.append(value) + options.append(value) } self.settingsRepository.makeMapOption(key: Settings.mapFormat) { value in - mapSetting.append(value) + options.append(value) } - options.append(photoSettings) - options.append(voiceSettings) - options.append(mapSetting) - return options } } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index ccb5ea4..fdb616d 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -132,20 +132,16 @@ class SettingsViewController: UIViewController { extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { func numberOfSections(in tableView: UITableView) -> Int { - return self.viewModel?.sectionCount ?? 0 - } - - func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return 10.0 + guard let itemCount = self.viewModel?.settingsCount else { return 0 } + return itemCount } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - guard let itemCount = self.viewModel?.settings[section].count else { return 0 } - return itemCount + return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch self.viewModel?.option(indexPath: indexPath) { + switch self.viewModel?.settings[indexPath.section] { case let option as ToggleOption: guard let cell = self.tableView.dequeueReusableCell(withIdentifier: ToggleOptionCell.identifier, for: indexPath) as? ToggleOptionCell diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift index bc65675..f3e5dc0 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -10,12 +10,12 @@ import Combine final class SettingsViewModel { - @Published var settings: [[Option]] = [] + @Published var settings: [Option] = [] let settingsUseCase: SettingsUsecase let isPhotoRecordAvailable = PassthroughSubject() - var sectionCount: Int { + var settingsCount: Int { return settings.count } @@ -36,10 +36,6 @@ final class SettingsViewModel { } } - func option(indexPath: IndexPath) -> Option { - return settings[indexPath.section][indexPath.item] - } - func change(value: T, key: Settings) { self.settingsUseCase.save(value: value, key: key) if value is String { From 092adf046bd50bf120ab7ba90699ddc0fd38f44f Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 25 Nov 2021 15:55:28 +0900 Subject: [PATCH 401/465] =?UTF-8?q?[Feat]=20#320=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SettingsSceneTests/SettingsSceneTests.swift | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/SanTa/SettingsSceneTests/SettingsSceneTests.swift b/SanTa/SettingsSceneTests/SettingsSceneTests.swift index 2a58718..1171cd1 100644 --- a/SanTa/SettingsSceneTests/SettingsSceneTests.swift +++ b/SanTa/SettingsSceneTests/SettingsSceneTests.swift @@ -33,28 +33,26 @@ class SettingsViewModelTests: XCTestCase { func test_ViewModel은_viewDidLoad시_UseCase의_반환값_settings프로퍼티에_세팅() throws { viewModel.viewDidLoad() - XCTAssertEqual(viewModel.sectionCount, 3) + XCTAssertEqual(viewModel.settingsCount, 3) } func test_ViewModel은_change호출시_문자열이면_settings프로퍼티_업데이트() throws { viewModel.change(value: 1, key: .mapFormat) - XCTAssertEqual(viewModel.sectionCount, 0) + XCTAssertEqual(viewModel.settingsCount, 0) viewModel.change(value: "string", key: .mapFormat) - XCTAssertEqual(viewModel.sectionCount, 3) + XCTAssertEqual(viewModel.settingsCount, 3) } func test_UseCase는_repository반환_값에_따른_배열생성() { let options = useCase.makeSettings() - let option1 = options[0][0] as? ToggleOption - let option2 = options[0][1] as? ToggleOption - let option3 = options[1][0] as? ToggleOption - let option4 = options[2][0] as? MapOption + let option1 = options[0] as? ToggleOption + let option2 = options[1] as? ToggleOption + let option3 = options[2] as? MapOption XCTAssertNotNil(option1) XCTAssertNotNil(option2) XCTAssertNotNil(option3) - XCTAssertNotNil(option4) } } From c15dd6c3983494e187a0a0f4165662265a92d013 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 15:56:14 +0900 Subject: [PATCH 402/465] =?UTF-8?q?[Feat]=20#319=20saveRecordPhotoOption?= =?UTF-8?q?=20Repository=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordRepository.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 4df478b..63374d5 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -30,7 +30,7 @@ final class DefaultRecordRepository: RecordRepository { } func saveRecordPhotoOption(value: Bool) { - + self.settingsStorage.save(value: value, key: Settings.recordPhoto) } func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { From 6024ba394871627a885799f4dfb5ad1cb894b2e4 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:08:25 +0900 Subject: [PATCH 403/465] =?UTF-8?q?[Refactor]=20current=20gps=20status=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 14 ++++++++++++-- .../RecordingScene/RecordingViewController.swift | 10 +++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index a071202..e1db49a 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -18,6 +18,7 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var altitude = "0" @Published private(set) var walk = "0" @Published private(set) var gpsStatus = true + @Published private(set) var motionAuth = true private let pedoMeter = CMPedometer() private let synthesizer = AVSpeechSynthesizer() @@ -202,7 +203,16 @@ final class RecordingModel: NSObject, ObservableObject { self.records?.add(record: record) } - private func checkAuthorizationStatus() { + private func checkLocationAuthorizationStatus() { + switch self.locationManager.authorizationStatus{ + case .authorizedWhenInUse, .authorizedAlways: + self.gpsStatus = true + default: + self.gpsStatus = false + } + } + + private func checkMotionAuthorizationStatus() { switch self.locationManager.authorizationStatus{ case .authorizedWhenInUse, .authorizedAlways: self.gpsStatus = true @@ -228,7 +238,7 @@ final class RecordingModel: NSObject, ObservableObject { func resume() { guard self.timerIsRunning == false else { return } - self.checkAuthorizationStatus() + self.checkLocationAuthorizationStatus() guard self.gpsStatus == true else { return } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 19d60a4..8d36ed7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -91,7 +91,7 @@ class RecordingViewController: UIViewController { private var recordingViewModel: RecordingViewModel? private var subscriptions = Set() - private var currentState = true + private var isCoreLocationStatus = true convenience init(viewModel: RecordingViewModel) { self.init() @@ -159,7 +159,7 @@ class RecordingViewController: UIViewController { self.recordingViewModel?.$gpsStatus .receive(on: DispatchQueue.main) .sink (receiveValue: { [weak self] gpsStatus in - if gpsStatus != self?.currentState { + if gpsStatus != self?.isCoreLocationStatus { if !gpsStatus { let title = "위치정보 활성화" let message = "측정을 다시 시작할 수 있도록 위치정보를 활성화해주세요." @@ -192,7 +192,7 @@ class RecordingViewController: UIViewController { } private func changeRecordingStatus() { - if currentState { + if isCoreLocationStatus { self.view.backgroundColor = .black var pauseConfiguration = UIButton.Configuration.plain() pauseConfiguration.image = UIImage(systemName: "play.fill") @@ -201,7 +201,7 @@ class RecordingViewController: UIViewController { self.pauseButton.accessibilityLabel = "재시작" self.pauseButton.accessibilityHint = "측정을 재시작 하려면 이중 탭 하십시오" self.recordingViewModel?.pause() - self.currentState = false + self.isCoreLocationStatus = false } else { self.view.backgroundColor = UIColor(named: "SantaColor") var pauseConfiguration = UIButton.Configuration.plain() @@ -211,7 +211,7 @@ class RecordingViewController: UIViewController { self.pauseButton.accessibilityLabel = "일시정지" self.pauseButton.accessibilityHint = "측정을 일시정지 하려면 이중 탭 하십시오" self.recordingViewModel?.resume() - self.currentState = true + self.isCoreLocationStatus = true } } From edbb9e129d1f7a56c1f06f973b7f82810c872bd8 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 16:11:49 +0900 Subject: [PATCH 404/465] =?UTF-8?q?[Docs]=20=EC=BB=A4=EB=A7=A8=EB=93=9C?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=ED=88=B4=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 991e6cc..ce2ab16 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -130,6 +130,10 @@ 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; + 4963B7A4274F6E6000636FF5 /* GeoCoderResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GeoCoderResponse.swift; path = ../../../../../MountainGenerator/MountainGenerator/GeoCoderResponse.swift; sourceTree = ""; }; + 4963B7A5274F6E6000636FF5 /* MountainModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MountainModel.swift; path = ../../../../../MountainGenerator/MountainGenerator/MountainModel.swift; sourceTree = ""; }; + 4963B7A6274F6E6000636FF5 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = main.swift; path = ../../../../../MountainGenerator/MountainGenerator/main.swift; sourceTree = ""; }; + 4963B7A7274F6E6000636FF5 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = ../../../../../MountainGenerator/MountainGenerator/Extensions.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49921D88274B3B440091112C /* ResultDetailRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailRepository.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; @@ -245,6 +249,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 4963B7A3274F6E2600636FF5 /* MountainGeoCodingTool */ = { + isa = PBXGroup; + children = ( + 4963B7A7274F6E6000636FF5 /* Extensions.swift */, + 4963B7A4274F6E6000636FF5 /* GeoCoderResponse.swift */, + 4963B7A6274F6E6000636FF5 /* main.swift */, + 4963B7A5274F6E6000636FF5 /* MountainModel.swift */, + ); + path = MountainGeoCodingTool; + sourceTree = ""; + }; 5428FDB5272F89F0002F9D40 /* RecordingScene */ = { isa = PBXGroup; children = ( @@ -388,6 +403,7 @@ 54731B63272F81B200534097 /* Resources */ = { isa = PBXGroup; children = ( + 4963B7A3274F6E2600636FF5 /* MountainGeoCodingTool */, 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */, 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */, 5485128D272A6AD600407F28 /* Assets.xcassets */, From d8fb3bcb116e7bf5a140b31781ac155b62632ea8 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:20:18 +0900 Subject: [PATCH 405/465] =?UTF-8?q?[Fix]=20RecordingDetailView=20locations?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=ED=81=AC=EB=9E=98=EC=89=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/RecordingScene/RecordingModel.swift | 11 ++------ .../ResultDetailScene/ResultDetailModel.swift | 27 ++++++++++--------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index e1db49a..a858a21 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -40,6 +40,7 @@ final class RecordingModel: NSObject, ObservableObject { private var currentTime = Date() { didSet { + self.checkMotionAuthorizationStatus() self.timeCalculation() } } @@ -213,12 +214,7 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkMotionAuthorizationStatus() { - switch self.locationManager.authorizationStatus{ - case .authorizedWhenInUse, .authorizedAlways: - self.gpsStatus = true - default: - self.gpsStatus = false - } + print(CMPedometer.authorizationStatus()) } func changedWillSpeechStatus(status: Bool) { @@ -284,9 +280,6 @@ extension RecordingModel: CLLocationManagerDelegate { private func filterBadLocation(_ location: CLLocation) -> Bool{ let age = -location.timestamp.timeIntervalSinceNow - print(location.horizontalAccuracy) - print(location.verticalAccuracy) - guard age < 5, location.horizontalAccuracy > 0 && location.horizontalAccuracy < 30, location.verticalAccuracy > 0 && location.verticalAccuracy < 6 else { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index e0c8536..e825f96 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -135,19 +135,22 @@ struct ResultIncline { locations.append(contentsOf: record.locations) } - for index in 0.. 0 ? abs(distanceDelta) : 0 + downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 + plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 } - uphillDistance += altitudeDelta > 0 ? abs(distanceDelta) : 0 - downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 - plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 } self.average = locations.count > 1 ? Int(totalIncline / Double(locations.count - 1)) : 0 From e4d6dbe1de3f65f15e87351a775af0dfa89faa68 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:28:45 +0900 Subject: [PATCH 406/465] =?UTF-8?q?[Refactor]=20#319=20checkMotionAuthoriz?= =?UTF-8?q?ationStatus=20RecordingModel=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index a858a21..f60fcb3 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -214,7 +214,14 @@ final class RecordingModel: NSObject, ObservableObject { } private func checkMotionAuthorizationStatus() { - print(CMPedometer.authorizationStatus()) + switch CMPedometer.authorizationStatus() { + case .authorized: + self.motionAuth = true + case .restricted, .denied, .notDetermined: + self.motionAuth = false + @unknown default: + break + } } func changedWillSpeechStatus(status: Bool) { From 18497790511bbac813179f80fbcdd868cd191a1b Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:31:03 +0900 Subject: [PATCH 407/465] [Refactor] #319 ViewModel MotionAuth Combine --- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 16730a5..a22c49f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -26,6 +26,7 @@ final class RecordingViewModel: ObservableObject { @Published private(set) var altitude = "" @Published private(set) var walk = "" @Published private(set) var gpsStatus = true + @Published private(set) var motionAuth = true private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() @@ -77,6 +78,13 @@ final class RecordingViewModel: ObservableObject { self?.gpsStatus = gpsStatus }) .store(in: &self.subscriptions) + + self.recordingUseCase?.recording?.$motionAuth + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] motionAuth in + self?.motionAuth = motionAuth + }) + .store(in: &self.subscriptions) } func pause() { From ce1ce5c9bacbdf0d539c1c1440dabd5990d1bb9c Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:39:29 +0900 Subject: [PATCH 408/465] =?UTF-8?q?[Refactor]=20#319=20requestMotionAuth?= =?UTF-8?q?=20RecordingViewController=20=EB=A1=9C=EC=A7=81=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingViewController.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 8d36ed7..054929f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -172,6 +172,13 @@ class RecordingViewController: UIViewController { } }) .store(in: &self.subscriptions) + + self.recordingViewModel?.$motionAuth + .receive(on: DispatchQueue.main) + .sink (receiveValue: { [weak self] motionAuth in + self?.requestMotionAuth(status: motionAuth) + }) + .store(in: &self.subscriptions) } private func configureTarget() { @@ -226,6 +233,16 @@ class RecordingViewController: UIViewController { alert.addAction(confirm) return alert } + + private func requestMotionAuth(status: Bool) { + if !status { + let title = "동작 및 피트니스 활성화" + let message = "측정을 시작할 수 있도록 동작 및 피트니스를 활성화해주세요." + DispatchQueue.main.async { + self.present(self.authAlert(title: title, message: message), animated: false) + } + } + } @objc private func pauseButtonAction(_ sender: UIResponder) { changeRecordingStatus() From 0d1e5e3ef5f1ae5e081835401bbd83f1758eef51 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 16:44:03 +0900 Subject: [PATCH 409/465] =?UTF-8?q?[Refactor]=20#319=20CoreMotion=20?= =?UTF-8?q?=EA=B6=8C=ED=99=98=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 +- SanTa/SanTa/RecordingScene/RecordingViewController.swift | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index f60fcb3..de398aa 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -40,7 +40,6 @@ final class RecordingModel: NSObject, ObservableObject { private var currentTime = Date() { didSet { - self.checkMotionAuthorizationStatus() self.timeCalculation() } } @@ -51,6 +50,7 @@ final class RecordingModel: NSObject, ObservableObject { self.oneKileDate = self.startDate self.configureTimer() self.configureLocationManager() + self.checkMotionAuthorizationStatus() } private func configureTimer() { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 054929f..e42b0d0 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -241,6 +241,7 @@ class RecordingViewController: UIViewController { DispatchQueue.main.async { self.present(self.authAlert(title: title, message: message), animated: false) } + changeRecordingStatus() } } From a3434a008cd3c7a3e3adcbda7a54edf5d819e3c6 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 16:45:18 +0900 Subject: [PATCH 410/465] =?UTF-8?q?[Feat]=20#325=20=EA=B8=B0=EB=A1=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=99=94=EB=A9=B4=20=EC=B6=9C=EB=B0=9C?= =?UTF-8?q?=EC=A0=90=20=EB=B0=8F=20=EC=A2=85=EB=A3=8C=EC=A0=90=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 4 +++ SanTa/SanTa/ResultDetailScene/PinView.swift | 29 ++++++++++++++++++ .../ResultDetailViewController.swift | 30 +++++++------------ 3 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 SanTa/SanTa/ResultDetailScene/PinView.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 991e6cc..7d3cb75 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -51,6 +51,7 @@ 5485128C272A6AD500407F28 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5485128D272A6AD600407F28 /* Assets.xcassets */; }; 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */; }; + 54953444274F6903005C0E60 /* PinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54953443274F6903005C0E60 /* PinView.swift */; }; 54B32065274510D8002232BD /* MountainAddingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32064274510D8002232BD /* MountainAddingViewController.swift */; }; 54B3206727451169002232BD /* MountainAddingViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */; }; 54B32069274536D1002232BD /* MountainAddingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32068274536D1002232BD /* MountainAddingViewModel.swift */; }; @@ -169,6 +170,7 @@ 5485128D272A6AD600407F28 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54851290272A6AD600407F28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 54851292272A6AD600407F28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 54953443274F6903005C0E60 /* PinView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinView.swift; sourceTree = ""; }; 54B32064274510D8002232BD /* MountainAddingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewController.swift; sourceTree = ""; }; 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewCoordinator.swift; sourceTree = ""; }; 54B32068274536D1002232BD /* MountainAddingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingViewModel.swift; sourceTree = ""; }; @@ -290,6 +292,7 @@ 493178B32743992400B5FB88 /* DetailCell.swift */, DAFF214D274BD6460061A555 /* DetailHeader.swift */, 49921D88274B3B440091112C /* ResultDetailRepository.swift */, + 54953443274F6903005C0E60 /* PinView.swift */, ); path = ResultDetailScene; sourceTree = ""; @@ -718,6 +721,7 @@ 5429694F272FC1740070B362 /* ResultViewCoordinator.swift in Sources */, 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */, 49225C5E273CDB4F0021AD79 /* ResultDetailViewController.swift in Sources */, + 54953444274F6903005C0E60 /* PinView.swift in Sources */, 54F88EB9274256FE0004EAFD /* SectionHeaderView.swift in Sources */, 54731B65272F84D300534097 /* MapViewModel.swift in Sources */, 49D5A94F2738C72E00937821 /* MountainDetailUseCase.swift in Sources */, diff --git a/SanTa/SanTa/ResultDetailScene/PinView.swift b/SanTa/SanTa/ResultDetailScene/PinView.swift new file mode 100644 index 0000000..b04ed0f --- /dev/null +++ b/SanTa/SanTa/ResultDetailScene/PinView.swift @@ -0,0 +1,29 @@ +// +// PinView.swift +// SanTa +// +// Created by shin jae ung on 2021/11/25. +// + +import MapKit + +class PinView: MKAnnotationView { + static let ReuseID = "PinView" + + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { + super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) + self.centerOffset = CGPoint(x: 0, y: -20) + self.canShowCallout = true + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func prepareForDisplay() { + super.prepareForDisplay() + displayPriority = .defaultHigh + self.image = UIImage(systemName: "mappin") + self.frame = CGRect(x: 0, y: 0, width: 15, height: 40) + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index e78ee03..0850360 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -176,6 +176,7 @@ class ResultDetailViewController: UIViewController { ThumbnailView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier ) + self.mapView.register(PinView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) } private func configureImageVisibilityButton(_ imageName: String?) { @@ -184,7 +185,7 @@ class ResultDetailViewController: UIViewController { } private func configureImageVisibility(_ bool: Bool) { - let imageAnnotations = self.mapView.annotations.filter{$0.title != "start" && $0.title != "end"} + let imageAnnotations = self.mapView.annotations.filter{$0.title != "시작점" && $0.title != "종료점"} switch bool { case true: imageAnnotations.forEach{ @@ -222,9 +223,9 @@ class ResultDetailViewController: UIViewController { let startingPoint = CLLocationCoordinate2D(latitude: startingLocation.latitude, longitude: startingLocation.longitude) let endingPoint = CLLocationCoordinate2D(latitude: endingLocation.latitude, longitude: endingLocation.longitude) startAnnotation.coordinate = startingPoint - startAnnotation.title = "start" + startAnnotation.title = "시작점" endAnnotation.coordinate = endingPoint - endAnnotation.title = "end" + endAnnotation.title = "종료점" self.fetchAssetImage() self.mapView.addAnnotations([startAnnotation, endAnnotation]) } @@ -477,30 +478,19 @@ extension ResultDetailViewController: MKMapViewDelegate { } func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - guard annotation is MKPointAnnotation else { - return nil - } - - let identifier = "PointAnnotation" - - - let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier) - if annotation.title == "start" { - annotationView.tintColor = .init(named: "SantaColor") - } else if annotation.title == "end" { - annotationView.tintColor = .red + if annotation.title == "시작점" || annotation.title == "종료점" { + let annotationView = PinView(annotation: annotation, reuseIdentifier: PinView.ReuseID) + return annotationView } else { guard let identifider = annotation.title, - let image = self.uiImages[identifider ?? "None"] else { - return nil - } + let image = self.uiImages[identifider ?? "None"] + else { return nil } - let thumbnailView = ThumbnailView(annotation: annotation, reuseIdentifier: identifier) + let thumbnailView = ThumbnailView(annotation: annotation, reuseIdentifier: ThumbnailView.ReuseID) thumbnailView.configureImage(uiImage: image, id: identifider ?? "") return thumbnailView } - return annotationView } func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { From 56a53559e3ddda00b392765e6af0fa8c9fe97197 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 18:04:38 +0900 Subject: [PATCH 411/465] =?UTF-8?q?[Fix]=20#329=20=EC=82=B0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EA=B3=A0?= =?UTF-8?q?=EB=8F=84=EC=97=90=20=EB=8B=A8=EC=9C=84=EA=B0=80=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainListViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index b0bca64..b938f87 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -135,7 +135,7 @@ extension MountainListViewController: UICollectionViewDelegate { guard let mountains = self.viewModel?.mountains else { return } self.coordinator?.pushMountainDetailViewController(mountainAnnotation: MountainAnnotation( title: mountains[indexPath.item].mountain.mountainName, - subtitle: mountains[indexPath.item].mountain.mountainHeight, + subtitle: mountains[indexPath.item].mountain.mountainHeight + "m", latitude: mountains[indexPath.item].latitude, longitude: mountains[indexPath.item].longitude, mountainDescription: mountains[indexPath.item].mountain.mountainShortDescription, From b4395a13678a131b4e3c0ecf56d6709d429830f2 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 18:13:00 +0900 Subject: [PATCH 412/465] =?UTF-8?q?[Fix]=20gps=20=EC=98=A4=EC=B0=A8=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index de398aa..7d2b668 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -217,8 +217,10 @@ final class RecordingModel: NSObject, ObservableObject { switch CMPedometer.authorizationStatus() { case .authorized: self.motionAuth = true - case .restricted, .denied, .notDetermined: + case .restricted, .denied: self.motionAuth = false + case .notDetermined: + break @unknown default: break } @@ -287,9 +289,9 @@ extension RecordingModel: CLLocationManagerDelegate { private func filterBadLocation(_ location: CLLocation) -> Bool{ let age = -location.timestamp.timeIntervalSinceNow - guard age < 5, - location.horizontalAccuracy > 0 && location.horizontalAccuracy < 30, - location.verticalAccuracy > 0 && location.verticalAccuracy < 6 else { + guard age < 8, + location.horizontalAccuracy > 0 && location.horizontalAccuracy < 50, + location.verticalAccuracy > 0 && location.verticalAccuracy < 30 else { return false } From e93f122fa4a3bd738a3214e3b5869f066f281096 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 19:37:10 +0900 Subject: [PATCH 413/465] =?UTF-8?q?[Fix]=20gps=20=EC=98=A4=EC=B0=A8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 7 ++++--- .../ResultDetailScene/ResultDetailViewController.swift | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 7d2b668..cb5ea01 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -65,7 +65,6 @@ final class RecordingModel: NSObject, ObservableObject { private func configureLocationManager() { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest - self.locationManager.startUpdatingLocation() self.locationManager.activityType = .fitness self.locationManager.distanceFilter = 3 self.locationManager.allowsBackgroundLocationUpdates = true @@ -290,8 +289,10 @@ extension RecordingModel: CLLocationManagerDelegate { let age = -location.timestamp.timeIntervalSinceNow guard age < 8, - location.horizontalAccuracy > 0 && location.horizontalAccuracy < 50, - location.verticalAccuracy > 0 && location.verticalAccuracy < 30 else { + location.horizontalAccuracy > 0 && location.horizontalAccuracy < 80, + location.verticalAccuracy > 0 && location.verticalAccuracy < 50, + location.coordinate.latitude != self.location.last?.latitude && + location.coordinate.longitude != self.location.last?.longitude else { return false } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index fd7c2e9..ee073a2 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -172,6 +172,7 @@ class ResultDetailViewController: UIViewController { guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { return } + print(pointSets) for pointSet in pointSets { mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) } From ac7052e0b0724f39d6396ac00b6dc04b955d1c6a Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 20:11:34 +0900 Subject: [PATCH 414/465] =?UTF-8?q?[Refactor]=20oneKiloDate=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index cb5ea01..18bcf40 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -28,7 +28,7 @@ final class RecordingModel: NSObject, ObservableObject { private var timerIsRunning = false private var records: Records? private var startDate: Date? - private var oneKileDate: Date? + private var g: Date? private var currentWalk = 0 private var currentDistance: Double = 0 private var maxOneKiloTime = 0 @@ -47,7 +47,7 @@ final class RecordingModel: NSObject, ObservableObject { override init() { super.init() self.startDate = Date() - self.oneKileDate = self.startDate + self.oneKiloDate = self.startDate self.configureTimer() self.configureLocationManager() self.checkMotionAuthorizationStatus() @@ -148,8 +148,8 @@ final class RecordingModel: NSObject, ObservableObject { private func calculateSpeed() { if self.sliceDistance <= self.currentDistance { - guard let oneKileDate = self.oneKileDate else { - self.oneKileDate = self.currentTime + guard let oneKileDate = self.oneKiloDate else { + self.oneKiloDate = self.currentTime return } let elapsedTimeMinutes = Int(self.currentTime.timeIntervalSince(oneKileDate)) @@ -158,13 +158,13 @@ final class RecordingModel: NSObject, ObservableObject { if elapsedTimeMinutes > self.maxOneKiloTime { self.maxOneKiloTime = elapsedTimeMinutes - self.oneKileDate = self.currentTime + self.oneKiloDate = self.currentTime self.sliceDistance += 1 } if elapsedTimeMinutes < self.minOneKiloTime { self.minOneKiloTime = elapsedTimeMinutes - self.oneKileDate = self.currentTime + self.oneKiloDate = self.currentTime self.sliceDistance += 1 } } From abf649efe714ecf9560d88066fba0e97882d7263 Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 20:12:16 +0900 Subject: [PATCH 415/465] =?UTF-8?q?[Refactor]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=8D=BC=ED=8B=B0=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/RecordingModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 18bcf40..4748b59 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -28,7 +28,7 @@ final class RecordingModel: NSObject, ObservableObject { private var timerIsRunning = false private var records: Records? private var startDate: Date? - private var g: Date? + private var oneKiloDate: Date? private var currentWalk = 0 private var currentDistance: Double = 0 private var maxOneKiloTime = 0 From 518691d49572a6b5e98618edb1fe52a4eae384ea Mon Sep 17 00:00:00 2001 From: MinChang Date: Thu, 25 Nov 2021 20:15:11 +0900 Subject: [PATCH 416/465] =?UTF-8?q?[Fix]=20ResultDetail=20Print=20?= =?UTF-8?q?=EB=AC=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index ee073a2..fd7c2e9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -172,7 +172,6 @@ class ResultDetailViewController: UIViewController { guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { return } - print(pointSets) for pointSet in pointSets { mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) } From 4a55421446abffa3701797f18b807a05587418db Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 20:24:58 +0900 Subject: [PATCH 417/465] =?UTF-8?q?[Fix]=20#331=20=EC=82=AC=EC=A7=84=20?= =?UTF-8?q?=EB=AA=A8=EC=95=84=EB=B3=B4=EA=B8=B0=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 6e8318b..2aacf38 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -73,6 +73,7 @@ class ResultDetailViewController: UIViewController { private lazy var detailImagesButton: UIButton = { let button = UIButton() + button.setImage(.init(systemName: "photo.on.rectangle.angled"), for: .normal) button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) button.titleLabel?.font = .boldSystemFont(ofSize: 15) button.backgroundColor = .systemBackground From 885772a6ae2710b7782e8625c5f0317c7ffd32a5 Mon Sep 17 00:00:00 2001 From: Shin Date: Thu, 25 Nov 2021 21:03:16 +0900 Subject: [PATCH 418/465] =?UTF-8?q?[Fix]=20#333=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EB=B0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index fb7c09b..9d37190 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -21,6 +21,7 @@ class ResultDetailViewCoordinator: Coordinator { } func dismiss() { + self.navigationController.setNavigationBarHidden(false, animated: false) self.navigationController.popViewController(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } From 588ff6a2bad03a220c61bca4ef9ae495a6885e62 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Thu, 25 Nov 2021 21:45:39 +0900 Subject: [PATCH 419/465] =?UTF-8?q?[HOTFIX]=20=ED=8F=89=EA=B7=A0=EC=86=8D?= =?UTF-8?q?=EB=8F=84=20=EC=9D=B4=EB=8F=99=EA=B1=B0=EB=A6=AC=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift | 6 +++++- SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index aaeeb5b..e673829 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -59,8 +59,12 @@ struct ResultDistance { let steps: Int init(records: Records) { - self.total = records.distances self.steps = records.steps + guard let totalDistance = records.records.last?.distance else { + self.total = 0 + return + } + self.total = totalDistance } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 2f5d60b..721003b 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -71,7 +71,7 @@ class ResultDetailViewModel { formatter.maximumFractionDigits = 2 let totalDistance = self.resultDetailData?.distance.total ?? 0 let totalTimeSpent = self.resultDetailData?.time.spent ?? 1 - return formatter.string(from: NSNumber(value: totalDistance / totalTimeSpent)) ?? "" + return formatter.string(from: NSNumber(value: totalDistance * 3600 / totalTimeSpent)) ?? "" } lazy var recordDate: String = { From 4e1f9fe2378ca9f31bddd4ad9c036954fb5a8005 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 28 Nov 2021 14:03:44 +0900 Subject: [PATCH 420/465] =?UTF-8?q?[Feat]=20#336=20Locations=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=EC=B2=B4=20=EC=B6=94=EA=B0=80,=20=EA=B2=BD=EC=82=AC?= =?UTF-8?q?=EB=8F=84=20=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 16 --- SanTa/SanTa/RecordingScene/Record.swift | 108 +++++++++++++++++- .../ResultDetailScene/ResultDetailModel.swift | 29 ++--- 3 files changed, 114 insertions(+), 39 deletions(-) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 4c0a603..7d3cb75 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -131,10 +131,6 @@ 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; - 4963B7A4274F6E6000636FF5 /* GeoCoderResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GeoCoderResponse.swift; path = ../../../../../MountainGenerator/MountainGenerator/GeoCoderResponse.swift; sourceTree = ""; }; - 4963B7A5274F6E6000636FF5 /* MountainModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MountainModel.swift; path = ../../../../../MountainGenerator/MountainGenerator/MountainModel.swift; sourceTree = ""; }; - 4963B7A6274F6E6000636FF5 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = main.swift; path = ../../../../../MountainGenerator/MountainGenerator/main.swift; sourceTree = ""; }; - 4963B7A7274F6E6000636FF5 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = ../../../../../MountainGenerator/MountainGenerator/Extensions.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49921D88274B3B440091112C /* ResultDetailRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailRepository.swift; sourceTree = ""; }; 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAnnotation.swift; sourceTree = ""; }; @@ -251,17 +247,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 4963B7A3274F6E2600636FF5 /* MountainGeoCodingTool */ = { - isa = PBXGroup; - children = ( - 4963B7A7274F6E6000636FF5 /* Extensions.swift */, - 4963B7A4274F6E6000636FF5 /* GeoCoderResponse.swift */, - 4963B7A6274F6E6000636FF5 /* main.swift */, - 4963B7A5274F6E6000636FF5 /* MountainModel.swift */, - ); - path = MountainGeoCodingTool; - sourceTree = ""; - }; 5428FDB5272F89F0002F9D40 /* RecordingScene */ = { isa = PBXGroup; children = ( @@ -406,7 +391,6 @@ 54731B63272F81B200534097 /* Resources */ = { isa = PBXGroup; children = ( - 4963B7A3274F6E2600636FF5 /* MountainGeoCodingTool */, 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */, 5485128F272A6AD600407F28 /* LaunchScreen.storyboard */, 5485128D272A6AD600407F28 /* Assets.xcassets */, diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 927b157..dd7b80e 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -6,6 +6,7 @@ // import Foundation +import CoreLocation class TotalRecords { private(set) var totalRecords: [DateSeperateRecords] = [] @@ -31,12 +32,12 @@ class TotalRecords { var totalSteps: Int { return totalRecords.reduce(0) { $0 + $1.steps } } - + subscript(section: Int) -> DateSeperateRecords? { guard self.totalCount > section else { return nil } return totalRecords[section] } - + func add(records: Records) { guard let date = records.date else { return } let year = Calendar.current.component(.year, from: date) @@ -160,11 +161,11 @@ struct Record { let step: Int let distance: Double let locations: [Location] - + var time: TimeInterval { return endTime.timeIntervalSinceReferenceDate - startTime.timeIntervalSinceReferenceDate } - + var minAltitude: Double? { return locations.map{ $0.altitude }.min() } @@ -178,4 +179,103 @@ struct Location { let latitude: Double let longitude: Double let altitude: Double + + func distance(to: Location) -> Double { + let current = CLLocation(latitude: self.latitude, longitude: self.longitude) + let destination = CLLocation(latitude: to.latitude, longitude: to.longitude) + + return abs(current.distance(from: destination)) + } +} + +struct Locations { + private(set) var locations: [Location] + + init(locations: [Location]) { + self.locations = locations + } + + func totalUphillDistance() -> Double { + var uphillDistance: Double = 0 + var prevLocation: Location? = nil + for location in locations { + if let prevLocation = prevLocation { + let distance = location.distance(to: prevLocation) + if location.altitude > prevLocation.altitude { + uphillDistance += distance + } + } + prevLocation = location + } + + return uphillDistance + } + + func totalDownhillDistance() -> Double { + var downhillDistance: Double = 0 + var prevLocation: Location? = nil + for location in locations { + if let prevLocation = prevLocation { + let distance = location.distance(to: prevLocation) + if location.altitude < prevLocation.altitude { + downhillDistance += distance + } + } + prevLocation = location + } + + return downhillDistance + } + + func totalPlainDistance() -> Double { + var plainDistance: Double = 0 + var prevLocation: Location? = nil + for location in locations { + if let prevLocation = prevLocation { + let distance = location.distance(to: prevLocation) + if location.altitude == prevLocation.altitude { + plainDistance += distance + } + } + prevLocation = location + } + + return plainDistance + } + + func totalIncline() -> Double { + var incline: Double = 0 + var prevLocation: Location? = nil + + for location in locations { + if let prevLocation = prevLocation { + let distanceDelta = location.distance(to: prevLocation) + let altitudeDelta = location.altitude > prevLocation.altitude ? location.altitude - prevLocation.altitude : 0 + if distanceDelta != 0 { + incline += atan(altitudeDelta / distanceDelta) + } + } + prevLocation = location + } + + return incline + } + + func steepestIncline() -> Double { + var steepest: Double = 0 + var prevLocation: Location? = nil + + for location in locations { + if let prevLocation = prevLocation { + let distanceDelta = location.distance(to: prevLocation) + let altitudeDelta = location.altitude > prevLocation.altitude ? location.altitude - prevLocation.altitude : 0 + if distanceDelta != 0 { + let incline = atan(altitudeDelta / distanceDelta) + steepest = max(incline, steepest) + } + } + prevLocation = location + } + return steepest + } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index e673829..c3a58fd 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -132,30 +132,21 @@ struct ResultIncline { var downHillDistance: Double = 0 var plainDistance: Double = 0 - var locations: [Location] = [] + var paths: [[Location]] = [] for record in records.records { - locations.append(contentsOf: record.locations) + paths.append(record.locations) } - - if !locations.isEmpty { - for index in 0.. 0 ? abs(distanceDelta) : 0 - downHillDistance += altitudeDelta < 0 ? abs(distanceDelta) : 0 - plainDistance += altitudeDelta == 0 ? abs(distanceDelta) : 0 - } + for path in paths { + let locations = Locations(locations: path) + totalIncline += locations.totalIncline() + steepest = locations.steepestIncline() + uphillDistance += locations.totalUphillDistance() + downHillDistance += locations.totalDownhillDistance() + plainDistance += locations.totalPlainDistance() } - self.average = locations.count > 1 ? Int(totalIncline / Double(locations.count - 1)) : 0 + self.average = paths.count > 1 ? Int(totalIncline / Double(paths.count - 1)) : 0 self.highest = Int(steepest) self.uphillKilometer = uphillDistance / 1000 self.downhillKilometer = downHillDistance / 1000 From 43ea191035f2ce1b6b6ac800e3e5432a7d372fc0 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Sun, 28 Nov 2021 14:42:11 +0900 Subject: [PATCH 421/465] =?UTF-8?q?[Refactor]=20#338=20=EA=B3=A0=EB=8F=84?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 28 ++++++++++++++++++ .../ResultDetailScene/ResultDetailModel.swift | 29 +++++++++++-------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index dd7b80e..e47329f 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -195,6 +195,34 @@ struct Locations { self.locations = locations } + var maxAltitude: Double { + guard let max = locations.map({$0.altitude}).max() else { + return 0 + } + return max + } + + var minAltitude: Double { + guard let min = locations.map({$0.altitude}).min() else { + return 0 + } + return min + } + + var firstAltitude: Double { + guard let first = locations.map({$0.altitude}).first else { + return 0 + } + return first + } + + var lastAltitude: Double { + guard let last = locations.map({$0.altitude}).last else { + return 0 + } + return last + } + func totalUphillDistance() -> Double { var uphillDistance: Double = 0 var prevLocation: Location? = nil diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index c3a58fd..f093d34 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -104,17 +104,22 @@ struct ResultAltitude { let ending: Int init(records: Records) { - let maxAltitude:Int = Int(records.records.flatMap{$0.locations}.max{ $0.altitude < $1.altitude }?.altitude ?? 0) - let minAltitude = Int(records.records.flatMap{$0.locations}.min{ $0.altitude < $1.altitude }?.altitude ?? 0) - let total = Int(maxAltitude - minAltitude) - let startAltitude = Int(records.records.first?.locations.first?.altitude ?? 0) - let endAltitude = Int(records.records.last?.locations.last?.altitude ?? 0) + var paths: [Locations] = [] + for record in records.records { + paths.append(Locations(locations: record.locations)) + } + var maxAltitude: Int = 0 + var minAltitude: Int = 0 + for path in paths { + maxAltitude = max(Int(round(path.maxAltitude)), Int(maxAltitude)) + minAltitude = min(Int(round(path.minAltitude)), Int(minAltitude)) + } - self.total = total + self.total = maxAltitude - minAltitude self.highest = maxAltitude self.lowest = minAltitude - self.starting = startAltitude - self.ending = endAltitude + self.starting = Int(round(paths.first?.firstAltitude ?? 0)) + self.ending = Int(round(paths.last?.lastAltitude ?? 0)) } } @@ -132,13 +137,13 @@ struct ResultIncline { var downHillDistance: Double = 0 var plainDistance: Double = 0 - var paths: [[Location]] = [] + var paths: [Locations] = [] for record in records.records { - paths.append(record.locations) + paths.append(Locations(locations: record.locations)) } - for path in paths { - let locations = Locations(locations: path) + for locations in paths { + totalIncline += locations.totalIncline() steepest = locations.steepestIncline() uphillDistance += locations.totalUphillDistance() From 0306d4c8a19a905f0462477d4e30fdd55ac18ed9 Mon Sep 17 00:00:00 2001 From: Shin Date: Sun, 28 Nov 2021 23:31:19 +0900 Subject: [PATCH 422/465] =?UTF-8?q?[Fix]=20#340,=20#341=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=ED=99=94=EB=A9=B4,=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=B2=84=EA=B7=B8=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기록 화면 상단의 요역을 터치하면 크래쉬, 목록 화면 검색창이 사라지는 버그 . --- .../MountainDetailScene/MountainDetailViewCoordinator.swift | 3 ++- SanTa/SanTa/ResultScene/ResultViewController.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index f600c33..2ff7428 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -25,7 +25,7 @@ class MountainDetailViewCoordinator: Coordinator { if self.parentCoordinator is MapViewCoordinator { self.navigationController.present(mountainDetailViewController, animated: true, completion: nil) } else { - self.navigationController.setNavigationBarHidden(true, animated: false) + self.navigationController.setNavigationBarHidden(true, animated: true) self.navigationController.pushViewController(mountainDetailViewController, animated: true) } } @@ -34,6 +34,7 @@ class MountainDetailViewCoordinator: Coordinator { if self.parentCoordinator is MapViewCoordinator { self.navigationController.dismiss(animated: true) } else { + self.navigationController.setNavigationBarHidden(false, animated: true) self.navigationController.popViewController(animated: true) } self.parentCoordinator?.childCoordinators.removeLast() diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 3d3a2ca..098c125 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -139,7 +139,8 @@ extension ResultViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let indexPath = IndexPath(item: indexPath.item, section: indexPath.section - 1) - guard let records = self.viewModel?.selectedRecords(indexPath: indexPath) else { return } + guard indexPath.section >= 0, + let records = self.viewModel?.selectedRecords(indexPath: indexPath) else { return } self.coordinator?.presentResultDetailViewController(records: records) } } From 03b235269701a7620377caa09202cb2052a6db9e Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 29 Nov 2021 11:11:21 +0900 Subject: [PATCH 423/465] =?UTF-8?q?[Refactor]=20#343=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20UseCase,=20Repository=20=EB=A6=AC=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/ResultScene/ResultRepository.swift | 51 ++++++++++++++++- SanTa/SanTa/ResultScene/ResultUseCase.swift | 55 ++----------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultRepository.swift b/SanTa/SanTa/ResultScene/ResultRepository.swift index e058cbf..6d88442 100644 --- a/SanTa/SanTa/ResultScene/ResultRepository.swift +++ b/SanTa/SanTa/ResultScene/ResultRepository.swift @@ -8,7 +8,7 @@ import Foundation protocol ResultRepository { - func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) + func fetch(completion: @escaping (Result<[Records], Error>) -> Void) } final class DefaultResultRepository: ResultRepository { @@ -19,14 +19,59 @@ final class DefaultResultRepository: ResultRepository { self.recordStorage = recordStorage } - func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) { + func fetch(completion: @escaping (Result<[Records], Error>) -> Void) { self.recordStorage.fetch { result in switch result { case .success(let objects): - completion(.success(objects)) + var allRecords: [Records] = [] + objects.reversed().forEach { + guard let records = self.makeRecords(recordsEntityMO: $0) else { return } + allRecords.append(records) + } + completion(.success(allRecords)) case .failure(let error): completion(.failure(error)) } } } + + private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { + guard let title = recordsEntityMO.title, + let archiveAssetIdentifiers = recordsEntityMO.assetIdentifiers, + let id = recordsEntityMO.id, + let assetIdentifiers = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self], from: archiveAssetIdentifiers) as? [String] else { return nil } + let secondPerHighestSpeed = Int(recordsEntityMO.secondPerHighestSpeed) + let secondPerMinimumSpeed = Int(recordsEntityMO.secondPerMinimumSpeed) + + var records: [Record] = [] + recordsEntityMO.records?.forEach { + guard let recordEntityMO = $0 as? RecordEntityMO else { return } + guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } + records.append(record) + } + return Records(title: title, records: records, assetIdentifiers: assetIdentifiers, secondPerHighestSpeed: secondPerHighestSpeed, secondPerMinimumSpeed: secondPerMinimumSpeed, id: id) + + } + + private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { + guard let startTime = recordEntityMO.startTime else { return nil } + guard let endTime = recordEntityMO.endTime else { return nil } + let step = Int(recordEntityMO.step) + let distance = recordEntityMO.distance + + var locations: [Location] = [] + recordEntityMO.locations?.forEach{ + guard let locationEntityMO = $0 as? LocationEntityMO else { return } + let location = Location(latitude: locationEntityMO.latitude, + longitude: locationEntityMO.longitude, + altitude: locationEntityMO.altitude) + locations.append(location) + } + return Record(startTime: startTime, + endTime: endTime, + step: step, + distance: distance, + locations: locations) + } + } diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index e4230b9..27d531b 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -19,8 +19,11 @@ final class ResultUseCase { func fetch(completion: @escaping (Void?) -> Void) { self.resultRepository.fetch { [weak self] result in switch result { - case .success(let objects): - self?.totalRecords = self?.makeTotalRecords(objects: objects) + case .success(let allRecords): + self?.totalRecords = TotalRecords() + allRecords.forEach { + self?.totalRecords?.add(records: $0) + } completion(Void()) case .failure(let error): os_log(.error, log: .default, "\(error.localizedDescription)") @@ -29,53 +32,5 @@ final class ResultUseCase { } } } - - private func makeTotalRecords(objects: [RecordsEntityMO]) -> TotalRecords { - let totalRecords = TotalRecords() - objects.reversed().forEach { - guard let records = self.makeRecords(recordsEntityMO: $0) else { return } - totalRecords.add(records: records) - } - return totalRecords - } - - private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { - guard let title = recordsEntityMO.title, - let archiveAssetIdentifiers = recordsEntityMO.assetIdentifiers, - let id = recordsEntityMO.id, - let assetIdentifiers = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self], from: archiveAssetIdentifiers) as? [String] else { return nil } - let secondPerHighestSpeed = Int(recordsEntityMO.secondPerHighestSpeed) - let secondPerMinimumSpeed = Int(recordsEntityMO.secondPerMinimumSpeed) - - var records: [Record] = [] - recordsEntityMO.records?.forEach { - guard let recordEntityMO = $0 as? RecordEntityMO else { return } - guard let record = self.makeRecord(recordEntityMO: recordEntityMO) else { return } - records.append(record) - } - return Records(title: title, records: records, assetIdentifiers: assetIdentifiers, secondPerHighestSpeed: secondPerHighestSpeed, secondPerMinimumSpeed: secondPerMinimumSpeed, id: id) - - } - - private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { - guard let startTime = recordEntityMO.startTime else { return nil } - guard let endTime = recordEntityMO.endTime else { return nil } - let step = Int(recordEntityMO.step) - let distance = recordEntityMO.distance - - var locations: [Location] = [] - recordEntityMO.locations?.forEach{ - guard let locationEntityMO = $0 as? LocationEntityMO else { return } - let location = Location(latitude: locationEntityMO.latitude, - longitude: locationEntityMO.longitude, - altitude: locationEntityMO.altitude) - locations.append(location) - } - return Record(startTime: startTime, - endTime: endTime, - step: step, - distance: distance, - locations: locations) - } } From d73c08244473a2dea240047a41354f6ff59d3587 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 13:37:01 +0900 Subject: [PATCH 424/465] =?UTF-8?q?[Refactor]=20#345=20ResultDetailViewCon?= =?UTF-8?q?troller=20fetchAssetImage=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2aacf38..d53eebd 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -238,11 +238,15 @@ class ResultDetailViewController: UIViewController { private func fetchAssetImage() { guard let assetIdentifiers = self.viewModel?.resultDetailData?.assetIdentifiers else { return } let allMedia = PHAsset.fetchAssets(with: .image, options: nil) - var identifierIndex = 0 - self.detailImagesButton.setTitle("\(assetIdentifiers.count)", for: .normal) + var assetMap = [String: Bool]() + var identifierCount = 0 + + for identifier in assetIdentifiers { assetMap[identifier] = true } + for i in stride(from: allMedia.count - 1, through: 0, by: -1) { - guard identifierIndex < assetIdentifiers.count else { return } - if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { + guard identifierCount < assetIdentifiers.count else { return } + if let value = assetMap[allMedia[i].localIdentifier] { + guard value == true else { return } requestAssetIamge(with: allMedia[i]) { [weak self] (image, asset) in guard let image = image, let identifier = asset?.localIdentifier, @@ -250,9 +254,11 @@ class ResultDetailViewController: UIViewController { self?.uiImages[identifier] = image self?.appendImageAnnotation(identifier: identifier, location: coordinate) } - identifierIndex += 1 + identifierCount += 1 } } + + self.detailImagesButton.setTitle("\(identifierCount)", for: .normal) } private func requestAssetIamge(with asset: PHAsset?, completion: @escaping (UIImage?, PHAsset?) -> Void) { From 6192510008a4e5a66adb5ddb1ac20e42f76650ef Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 14:51:38 +0900 Subject: [PATCH 425/465] =?UTF-8?q?[Refactor]=20#346=20ResultView=20second?= =?UTF-8?q?LayoutSection=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultScene/ResultViewController.swift | 2 +- .../SanTa/ResultScene/SectionHeaderView.swift | 37 +++++++++++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 098c125..7eaa143 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -69,7 +69,7 @@ class ResultViewController: UIViewController { let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1) group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let section = NSCollectionLayoutSection(group: group) - let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.06)) + let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(200)) let header = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 628e0c6..db96c9b 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -23,10 +23,37 @@ extension UILabel { class SectionHeaderView: UICollectionReusableView { static let identifier = "SectionHeaderView" - let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .label) - let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) - let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) - let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + let monthLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .body) + label.textColor = .label + label.adjustsFontSizeToFitWidth = true + return label + }() + + let countLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .caption1) + label.textColor = .systemGray + label.adjustsFontSizeToFitWidth = true + return label + }() + + let distanceLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .caption1) + label.textColor = .systemGray + label.adjustsFontSizeToFitWidth = true + return label + }() + + let timeLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .caption1) + label.textColor = .systemGray + label.adjustsFontSizeToFitWidth = true + return label + }() func configure(month: String, count: String, distance: String, time: String) { self.backgroundColor = .systemBackground @@ -52,8 +79,10 @@ class SectionHeaderView: UICollectionReusableView { self.distanceLabel.translatesAutoresizingMaskIntoConstraints = false self.timeLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ + self.monthLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), + self.monthLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), From e89308c6174c86da362b127b7a60cde91de6741f Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 15:16:03 +0900 Subject: [PATCH 426/465] =?UTF-8?q?[Refactor]=20#346=20ResultView=20firstL?= =?UTF-8?q?ayoutSection=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/ResultViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index 7eaa143..edd28c5 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -55,7 +55,7 @@ class ResultViewController: UIViewController { private func firstLayoutSection() -> NSCollectionLayoutSection { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) - let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.35)) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(300)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1) let section = NSCollectionLayoutSection(group: group) return section From 9ab2975560316526cebf0c78e58bb5ada09def88 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 15:36:26 +0900 Subject: [PATCH 427/465] =?UTF-8?q?[Refactor]=20#346=20ResultView=20second?= =?UTF-8?q?LayoutSection=20item=20Size=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/ResultScene/ResultViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index edd28c5..fef5352 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -65,7 +65,7 @@ class ResultViewController: UIViewController { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = .init(top: 3, leading: 10, bottom: 13, trailing: 10) - let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.16)) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(130)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1) group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let section = NSCollectionLayoutSection(group: group) From 0d0b7adad54d9228a054486d6cb3f22a88e88873 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 29 Nov 2021 16:16:04 +0900 Subject: [PATCH 428/465] =?UTF-8?q?[Test]=20#327=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20Unit=20Test=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/ResultSceneTests/ResultSceneTests.swift | 113 +++++++++++++++ SanTa/SanTa.xcodeproj/project.pbxproj | 131 ++++++++++++++++++ .../xcshareddata/xcschemes/SanTa.xcscheme | 10 ++ .../SanTa/ResultScene/ResultRepository.swift | 4 - SanTa/SanTa/ResultScene/ResultUseCase.swift | 4 + SanTa/SanTa/ResultScene/ResultViewModel.swift | 22 +-- 6 files changed, 271 insertions(+), 13 deletions(-) create mode 100644 SanTa/ResultSceneTests/ResultSceneTests.swift diff --git a/SanTa/ResultSceneTests/ResultSceneTests.swift b/SanTa/ResultSceneTests/ResultSceneTests.swift new file mode 100644 index 0000000..187bb3b --- /dev/null +++ b/SanTa/ResultSceneTests/ResultSceneTests.swift @@ -0,0 +1,113 @@ +// +// ResultSceneTests.swift +// ResultSceneTests +// +// Created by CHANGMIN OH on 2021/11/29. +// + +import XCTest + +class ResultSceneTests: XCTestCase { + + class MockRepository: ResultRepository { + func fetch(completion: @escaping (Result<[Records], Error>) -> Void) { + let location1 = Location(latitude: 10, longitude: 20, altitude: 30) + let location2 = Location(latitude: 20, longitude: 30, altitude: 40) + let location3 = Location(latitude: 30, longitude: 40, altitude: 50) + let location4 = Location(latitude: 40, longitude: 50, altitude: 60) + let location5 = Location(latitude: 50, longitude: 60, altitude: 70) + let location6 = Location(latitude: 60, longitude: 70, altitude: 80) + let location7 = Location(latitude: 70, longitude: 80, altitude: 90) + let location8 = Location(latitude: 80, longitude: 90, altitude: 10) + let record1 = Record(startTime: Date(timeIntervalSince1970: 1000), + endTime: Date(timeIntervalSince1970: 2000), + step: 10, + distance: 20, + locations: [location1, location2]) + let record2 = Record(startTime: Date(timeIntervalSince1970: 2000), + endTime: Date(timeIntervalSince1970: 3000), + step: 20, + distance: 30, + locations: [location3, location4]) + let record3 = Record(startTime: Date(timeIntervalSince1970: 4000), + endTime: Date(timeIntervalSince1970: 5000), + step: 30, + distance: 40, + locations: [location5, location6]) + let record4 = Record(startTime: Date(timeIntervalSince1970: 5000), + endTime: Date(timeIntervalSince1970: 6000), + step: 40, + distance: 50, + locations: [location7, location8]) + + let records1 = Records(title: "기록1", + records: [record1, record2], + assetIdentifiers: ["1", "11"], + secondPerHighestSpeed: 10, + secondPerMinimumSpeed: 20, + id: "1") + let records2 = Records(title: "기록2", + records: [record3, record4], + assetIdentifiers: ["2", "22"], + secondPerHighestSpeed: 30, + secondPerMinimumSpeed: 40, + id: "2") + completion(.success([records1, records2])) + } + } + + private var viewModel: ResultViewModel! + private var useCase: ResultUseCase! + + override func setUpWithError() throws { + useCase = ResultUseCase(resultRepository: MockRepository()) + viewModel = ResultViewModel(useCase: useCase) + } + + func test_ViewModel_viewWillAppear시_UseCase에_TotalRecords_세팅() throws { + viewModel.viewWillAppear { } + XCTAssertNotNil(useCase.totalRecords) + } + + func test_ViewModel_itemsInSection호출시_section넘버에_따라_Records갯수_반환() { + viewModel.viewWillAppear { } + XCTAssertEqual(viewModel.itemsInSection(section: 0), 2) + } + + func test_ViewModel_totalInfo호출시_총_Records를_View에_보여줄_문자열정보로_반환() { + viewModel.viewWillAppear { } + let infomation = viewModel.totalInfo() + XCTAssertEqual(infomation.distance, "140.00") + XCTAssertEqual(infomation.count, "2") + XCTAssertEqual(infomation.time, "01:06") + XCTAssertEqual(infomation.steps, "100") + } + + func test_ViewModel_sectionInfo호출시_섹션넘버에_맞는_Records를_View에_보여줄_문자열정보로_반환() { + viewModel.viewWillAppear { } + let infomation = viewModel.sectionInfo(section: 0) + XCTAssertEqual(infomation.date, "1970. 1.") + XCTAssertEqual(infomation.accessibiltyDate, "1970년 1월") + XCTAssertEqual(infomation.count, "2회") + XCTAssertEqual(infomation.distance, "140.00km") + XCTAssertEqual(infomation.time, "01:06") + } + + func test_ViewModel_cellInfo호출시_IndexPath에_맞는_Records를_View에_보여줄_문자열정보로_반환() { + viewModel.viewWillAppear { } + let infomation = viewModel.cellInfo(indexPath: IndexPath(item: 0, section: 0)) + XCTAssertEqual(infomation.date, "1. 1. (목) 오전 9시 50분") + XCTAssertEqual(infomation.distance, "50.00") + XCTAssertEqual(infomation.time, "00:33") + XCTAssertEqual(infomation.altitudeDifference, "30") + XCTAssertEqual(infomation.steps, "30") + XCTAssertEqual(infomation.title, "기록1") + } + + func test_ViewModel_selectedRecords호출시_IndexPath에_맞는_Records반환() { + viewModel.viewWillAppear { } + let record = viewModel.selectedRecords(indexPath: IndexPath(item: 0, section: 0)) + XCTAssertEqual(record?.id, "1") + } +} + diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 7d3cb75..7a326b9 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -82,6 +82,10 @@ 9889DA512730FFCD00F3C772 /* MapOptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */; }; 98A913012736844E008AAE39 /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; 98AEF1D727310759002E9C9A /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AEF1D627310759002E9C9A /* PaddingLabel.swift */; }; + 98BAABB4275479B0004505BB /* ResultSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BAABB3275479B0004505BB /* ResultSceneTests.swift */; }; + 98BAABBA27547A11004505BB /* ResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5465237C2741F997007B2692 /* ResultViewModel.swift */; }; + 98BAABBB27547A11004505BB /* ResultUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821E273CE16E006A847A /* ResultUseCase.swift */; }; + 98BAABBC27547A1B004505BB /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; @@ -121,6 +125,13 @@ remoteGlobalIDString = 5485127D272A6AD500407F28; remoteInfo = SanTa; }; + 98BAABB5275479B0004505BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -197,6 +208,8 @@ 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapOptionCell.swift; sourceTree = ""; }; 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsStorage.swift; sourceTree = ""; }; 98AEF1D627310759002E9C9A /* PaddingLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingLabel.swift; sourceTree = ""; }; + 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ResultSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 98BAABB3275479B0004505BB /* ResultSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultSceneTests.swift; sourceTree = ""; }; 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; @@ -237,6 +250,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98BAABAE275479B0004505BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD62746273300E51E4B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -406,6 +426,7 @@ 54851280272A6AD500407F28 /* SanTa */, 9826F42E273953FB0064FA85 /* SettingsSceneTests */, DA854FDA2746273300E51E4B /* RecordingSceneTests */, + 98BAABB2275479B0004505BB /* ResultSceneTests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -416,6 +437,7 @@ 5485127E272A6AD500407F28 /* SanTa.app */, 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */, + 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */, ); name = Products; sourceTree = ""; @@ -464,6 +486,14 @@ path = SettingsSceneTests; sourceTree = ""; }; + 98BAABB2275479B0004505BB /* ResultSceneTests */ = { + isa = PBXGroup; + children = ( + 98BAABB3275479B0004505BB /* ResultSceneTests.swift */, + ); + path = ResultSceneTests; + sourceTree = ""; + }; DA854FDA2746273300E51E4B /* RecordingSceneTests */ = { isa = PBXGroup; children = ( @@ -547,6 +577,24 @@ productReference = 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 98BAABB0275479B0004505BB /* ResultSceneTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 98BAABB9275479B0004505BB /* Build configuration list for PBXNativeTarget "ResultSceneTests" */; + buildPhases = ( + 98BAABAD275479B0004505BB /* Sources */, + 98BAABAE275479B0004505BB /* Frameworks */, + 98BAABAF275479B0004505BB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 98BAABB6275479B0004505BB /* PBXTargetDependency */, + ); + name = ResultSceneTests; + productName = ResultSceneTests; + productReference = 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; DA854FD82746273300E51E4B /* RecordingSceneTests */ = { isa = PBXNativeTarget; buildConfigurationList = DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */; @@ -581,6 +629,10 @@ CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; }; + 98BAABB0275479B0004505BB = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; DA854FD82746273300E51E4B = { CreatedOnToolsVersion = 13.0; }; @@ -602,6 +654,7 @@ 5485127D272A6AD500407F28 /* SanTa */, 9826F42C273953FB0064FA85 /* SettingsSceneTests */, DA854FD82746273300E51E4B /* RecordingSceneTests */, + 98BAABB0275479B0004505BB /* ResultSceneTests */, ); }; /* End PBXProject section */ @@ -624,6 +677,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98BAABAF275479B0004505BB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD72746273300E51E4B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -742,6 +802,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98BAABAD275479B0004505BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 98BAABBC27547A1B004505BB /* Record.swift in Sources */, + 98BAABBA27547A11004505BB /* ResultViewModel.swift in Sources */, + 98BAABBB27547A11004505BB /* ResultUseCase.swift in Sources */, + 98BAABB4275479B0004505BB /* ResultSceneTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD52746273300E51E4B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -764,6 +835,11 @@ target = 5485127D272A6AD500407F28 /* SanTa */; targetProxy = 9826F431273953FB0064FA85 /* PBXContainerItemProxy */; }; + 98BAABB6275479B0004505BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 98BAABB5275479B0004505BB /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1002,6 +1078,52 @@ }; name = Release; }; + 98BAABB7275479B0004505BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.ResultSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + 98BAABB8275479B0004505BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.ResultSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; DA854FDE2746273300E51E4B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1074,6 +1196,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 98BAABB9275479B0004505BB /* Build configuration list for PBXNativeTarget "ResultSceneTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 98BAABB7275479B0004505BB /* Debug */, + 98BAABB8275479B0004505BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index f1b1e28..ddb9ebb 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -62,6 +62,16 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + ) -> Void) -} - final class DefaultResultRepository: ResultRepository { private let recordStorage: CoreDataRecordStorage diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index 27d531b..d683ef2 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -8,6 +8,10 @@ import Foundation import OSLog +protocol ResultRepository { + func fetch(completion: @escaping (Result<[Records], Error>) -> Void) +} + final class ResultUseCase { private let resultRepository: ResultRepository private(set) var totalRecords: TotalRecords? diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 84edaa7..8871b69 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -11,11 +11,11 @@ class ResultViewModel { private let useCase: ResultUseCase var cellShouldUpdate: () -> Void var totalDistance: String { - guard let totalRecords = useCase.totalRecords else { return "" } + guard let totalRecords = self.useCase.totalRecords else { return "" } return self.doubleFormatter(totalRecords.totalDistances) + " km" } var totalSections: Int { - guard let totalRecords = useCase.totalRecords else { return 0 } + guard let totalRecords = self.useCase.totalRecords else { return 0 } return totalRecords.sectionCount } @@ -33,11 +33,11 @@ class ResultViewModel { } func itemsInSection(section: Int) -> Int { - useCase.totalRecords?[section]?.count ?? 0 + self.useCase.totalRecords?[section]?.count ?? 0 } func totalInfo() -> (distance: String, count: String, time: String, steps: String) { - guard let totalRecords = useCase.totalRecords else { + guard let totalRecords = self.useCase.totalRecords else { return ("", "", "", "") } let distanceString = self.doubleFormatter(totalRecords.totalDistances) @@ -52,7 +52,7 @@ class ResultViewModel { count: String, distance: String, time: String) { - guard let totalRecords = useCase.totalRecords, + guard let totalRecords = self.useCase.totalRecords, let dateSeperateRecords = totalRecords[section] else { return ("", "", "", "", "") @@ -71,9 +71,13 @@ class ResultViewModel { return (dateString, accessibiltyDateString, countString, distanceString, timeString) } - func cellInfo(indexPath: IndexPath) - -> (date: String, distance: String, time: String, altitudeDifference: String, steps: String, title: String) { - guard let totalRecords = useCase.totalRecords, + func cellInfo(indexPath: IndexPath) -> (date: String, + distance: String, + time: String, + altitudeDifference: String, + steps: String, + title: String) { + guard let totalRecords = self.useCase.totalRecords, let records = totalRecords[indexPath.section]?[indexPath.item] else { return ("", "", "", "", "", "") @@ -88,7 +92,7 @@ class ResultViewModel { } func selectedRecords(indexPath: IndexPath) -> Records? { - return useCase.totalRecords?[indexPath.section]?[indexPath.item] + return self.useCase.totalRecords?[indexPath.section]?[indexPath.item] } } From 54055210bc2de24f7b85cd16524b7f0902692490 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 29 Nov 2021 16:16:24 +0900 Subject: [PATCH 429/465] =?UTF-8?q?[Feat]=20#344=20Locations=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=EC=B2=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Persistences/CoreDataRecordStorage.swift | 3 ++- SanTa/SanTa/RecordingScene/Record.swift | 27 ++++++++++++++++--- .../SanTa.xcdatamodel/contents | 2 +- .../ResultDetailScene/ResultDetailModel.swift | 14 +++++----- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 0d63181..28d6e15 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -52,7 +52,8 @@ final class CoreDataRecordStorage: RecordsStorage { guard let recordObject = recordObject else { return } (recordsObject as? RecordsEntityMO)?.addToRecords(recordObject) - $0.locations.forEach { + + $0.locations.locations.forEach { let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", into: context) as? LocationEntityMO locationObject?.altitude = $0.altitude diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index e47329f..9bf9370 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -160,18 +160,26 @@ struct Record { let endTime: Date let step: Int let distance: Double - let locations: [Location] + let locations: Locations var time: TimeInterval { return endTime.timeIntervalSinceReferenceDate - startTime.timeIntervalSinceReferenceDate } var minAltitude: Double? { - return locations.map{ $0.altitude }.min() + return locations.minAltitude } var maxAltitude: Double? { - return locations.map{ $0.altitude }.max() + return locations.maxAltitude + } + + init(startTime: Date, endTime: Date, step: Int, distance: Double, locations: [Location]) { + self.startTime = startTime + self.endTime = endTime + self.step = step + self.distance = distance + self.locations = Locations(locations: locations) } } @@ -195,6 +203,10 @@ struct Locations { self.locations = locations } + var coordinates: [CLLocationCoordinate2D] { + return locations.map{CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)} + } + var maxAltitude: Double { guard let max = locations.map({$0.altitude}).max() else { return 0 @@ -223,6 +235,15 @@ struct Locations { return last } + var startLocation: Location? { + return locations.first + } + + var endLocation: Location? { + return locations.last + } + + func totalUphillDistance() -> Double { var uphillDistance: Double = 0 var prevLocation: Location? = nil diff --git a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents index ab8ada9..717fd10 100644 --- a/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents +++ b/SanTa/SanTa/Resources/SanTa.xcdatamodeld/SanTa.xcdatamodel/contents @@ -1,5 +1,5 @@ - + diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index f093d34..c9e98a9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -31,7 +31,7 @@ struct ResultDetailData { self.title = records.title self.assetIdentifiers = records.assetIdentifiers var locations: [[CLLocationCoordinate2D]] = [] - records.records.forEach { locations.append($0.locations.map {CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude) }) } + records.records.forEach{locations.append($0.locations.coordinates)} self.coordinates = locations } @@ -49,8 +49,8 @@ struct ResultTimeStamp { init(records: Records) { self.startTime = records.records.first?.startTime ?? Date.distantPast self.endTime = records.records.last?.endTime ?? Date.distantFuture - self.startLocation = records.records.first?.locations.first - self.endLocation = records.records.last?.locations.last + self.startLocation = records.records.first?.locations.startLocation + self.endLocation = records.records.last?.locations.endLocation } } @@ -106,10 +106,10 @@ struct ResultAltitude { init(records: Records) { var paths: [Locations] = [] for record in records.records { - paths.append(Locations(locations: record.locations)) + paths.append(record.locations) } - var maxAltitude: Int = 0 - var minAltitude: Int = 0 + var maxAltitude: Int = Int.min + var minAltitude: Int = Int.max for path in paths { maxAltitude = max(Int(round(path.maxAltitude)), Int(maxAltitude)) minAltitude = min(Int(round(path.minAltitude)), Int(minAltitude)) @@ -139,7 +139,7 @@ struct ResultIncline { var paths: [Locations] = [] for record in records.records { - paths.append(Locations(locations: record.locations)) + paths.append(record.locations) } for locations in paths { From 695d19985ae755979c0e52aad0184541561f9246 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 16:34:23 +0900 Subject: [PATCH 430/465] =?UTF-8?q?[Test]=20#238=20RecordingViewModel=20Te?= =?UTF-8?q?st=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTests.swift | 10 +- .../RecordingViewModelTests.swift | 257 ++++++++++++++++++ SanTa/SanTa.xcodeproj/project.pbxproj | 6 +- .../RecordingScene/RecordingViewModel.swift | 16 +- 4 files changed, 277 insertions(+), 12 deletions(-) create mode 100644 SanTa/RecordingSceneTests/RecordingViewModelTests.swift diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index 9423f0a..972ca38 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -17,6 +17,10 @@ class RecordingUseCaseTests: XCTestCase { } class TestRecordingRepository : RecordRepository { + func saveRecordPhotoOption(value: Bool) { + return + } + func save(records: Records, completion: @escaping (Result) -> Void) { @@ -54,7 +58,7 @@ class RecordingUseCaseTests: XCTestCase { func test_음성안내_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) - self.repository.fetchRecordOption(key: Settings.photosOnMap) { result in + self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { case .failure(_): return @@ -78,7 +82,7 @@ class RecordingUseCaseTests: XCTestCase { func test_사진저장_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) - self.repository.fetchRecordOption(key: Settings.photosOnMap) { result in + self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { case .failure(_): return @@ -90,7 +94,7 @@ class RecordingUseCaseTests: XCTestCase { func test_Records_저장_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) - let records = Records(title: "테스트", records: [Record](), assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int()) + let records = Records(title: "테스트", records: [Record](), assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int(), id: "") self.repository.save(records: records) { result in switch result { diff --git a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift new file mode 100644 index 0000000..f8d6c46 --- /dev/null +++ b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift @@ -0,0 +1,257 @@ +// +// RecordingViewModelTests.swift +// RecordingSceneTests +// +// Created by 김민창 on 2021/11/29. +// + +import XCTest +import Combine + +class RecordingViewModelTests: XCTestCase { + + private let recordingUseCase: RecordingUseCase? = nil + private var subscriptions = Set() + private var recordingViewModel = RecordingViewModel(recordingUseCase: nil) + + override func setUpWithError() throws { + } + + func test_시간_받기_성공() { + + var result = "" + self.recordingViewModel.$currentTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { time in + result = time + }) + .store(in: &self.subscriptions) + + let timeText = "0:00" + recordingViewModel.currentTime = timeText + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.5) + + XCTAssertTrue(timeText == result) + } + + func test_시간_받기_실패() { + + var result = "" + self.recordingViewModel.$currentTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { time in + result = time + }) + .store(in: &self.subscriptions) + + let timeText = "0:00" + recordingViewModel.currentTime = "0:01" + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(timeText == result) + } + + func test_접근성_현재_시간_받기_성공() { + + var result = "" + self.recordingViewModel.$accessibilityCurrentTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { time in + result = time + }) + .store(in: &self.subscriptions) + + let timeText = "0:00" + recordingViewModel.accessibilityCurrentTime = timeText + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(timeText == result) + } + + func test_접근성_현재_시간_받기_실패() { + + var result = "" + self.recordingViewModel.$accessibilityCurrentTime + .receive(on: DispatchQueue.main) + .sink (receiveValue: { time in + result = time + }) + .store(in: &self.subscriptions) + + let timeText = "0:00" + recordingViewModel.accessibilityCurrentTime = "0:01" + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(timeText == result) + } + + func test_킬로미터_받기_성공() { + + var result = "" + self.recordingViewModel.$kilometer + .receive(on: DispatchQueue.main) + .sink (receiveValue: { kilometer in + result = kilometer + }) + .store(in: &self.subscriptions) + + let kiloText = "5km" + recordingViewModel.kilometer = kiloText + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(kiloText == result) + } + + func test_킬로미터_받기_실패() { + + var result = "" + self.recordingViewModel.$kilometer + .receive(on: DispatchQueue.main) + .sink (receiveValue: { kilometer in + result = kilometer + }) + .store(in: &self.subscriptions) + + let kiloText = "5km" + recordingViewModel.kilometer = "4km" + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(kiloText == result) + } + + func test_고도_받기_성공() { + + var result = "" + self.recordingViewModel.$altitude + .receive(on: DispatchQueue.main) + .sink (receiveValue: { altitude in + result = altitude + }) + .store(in: &self.subscriptions) + + let altitudeText = "50" + recordingViewModel.altitude = altitudeText + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(altitudeText == result) + } + + func test_고도_받기_실패() { + + var result = "" + self.recordingViewModel.$altitude + .receive(on: DispatchQueue.main) + .sink (receiveValue: { altitude in + result = altitude + }) + .store(in: &self.subscriptions) + + let altitudeText = "5km" + recordingViewModel.altitude = "40" + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(altitudeText == result) + } + + func test_걸음_받기_성공() { + + var result = "" + self.recordingViewModel.$walk + .receive(on: DispatchQueue.main) + .sink (receiveValue: { walk in + result = walk + }) + .store(in: &self.subscriptions) + + let walkText = "300" + recordingViewModel.walk = walkText + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(walkText == result) + } + + func test_걸음_받기_실패() { + + var result = "" + self.recordingViewModel.$walk + .receive(on: DispatchQueue.main) + .sink (receiveValue: { walk in + result = walk + }) + .store(in: &self.subscriptions) + + let walkText = "300" + recordingViewModel.walk = "200" + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(walkText == result) + } + + func test_GPS상태_받기_성공() { + + var result = true + self.recordingViewModel.$gpsStatus + .receive(on: DispatchQueue.main) + .sink (receiveValue: { gps in + result = gps + }) + .store(in: &self.subscriptions) + + let gpsStatus = false + recordingViewModel.gpsStatus = gpsStatus + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(gpsStatus == result) + } + + func test_GPS상태_받기_실패() { + + var result = false + self.recordingViewModel.$gpsStatus + .receive(on: DispatchQueue.main) + .sink (receiveValue: { gps in + result = gps + }) + .store(in: &self.subscriptions) + + let gpsStatus = false + recordingViewModel.gpsStatus = true + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(gpsStatus == result) + } + + func test_motion권한_받기_성공() { + + var result = true + self.recordingViewModel.$motionAuth + .receive(on: DispatchQueue.main) + .sink (receiveValue: { motion in + result = motion + }) + .store(in: &self.subscriptions) + + let motionStatus = false + recordingViewModel.motionAuth = motionStatus + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertTrue(motionStatus == result) + } + + func test_motion권한_받기_실패() { + + var result = false + self.recordingViewModel.$motionAuth + .receive(on: DispatchQueue.main) + .sink (receiveValue: { motion in + result = motion + }) + .store(in: &self.subscriptions) + + let motionStatus = false + recordingViewModel.motionAuth = true + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) + + XCTAssertFalse(motionStatus == result) + } +} diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 7d3cb75..66d4b59 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ DAAF4D6C273CE02400780DC8 /* MountainListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */; }; DAAF4D6E273CE06A00780DC8 /* MountainListViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */; }; DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */; }; + DAB25F1B2754AF2D00F0BE75 /* RecordingViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB25F1A2754AF2D00F0BE75 /* RecordingViewModelTests.swift */; }; DAB37D4C2731166B00EC523F /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DAB37D50273256B900EC523F /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; DAB751B7274E74E600C39266 /* ThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB751B6274E74E600C39266 /* ThumbnailView.swift */; }; @@ -208,6 +209,7 @@ DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewModel.swift; sourceTree = ""; }; DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewUseCase.swift; sourceTree = ""; }; DAAF4D6F273CE08B00780DC8 /* MountainListViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListViewRepository.swift; sourceTree = ""; }; + DAB25F1A2754AF2D00F0BE75 /* RecordingViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModelTests.swift; sourceTree = ""; }; DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingViewModel.swift; sourceTree = ""; }; DAB37D4F273256B900EC523F /* RecordingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingModel.swift; sourceTree = ""; }; DAB751B6274E74E600C39266 /* ThumbnailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThumbnailView.swift; sourceTree = ""; }; @@ -255,10 +257,10 @@ 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */, + DAB37D4F273256B900EC523F /* RecordingModel.swift */, DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */, 984DDEC427325FB9003BE56B /* RecordRepository.swift */, 984DDEC027325D67003BE56B /* Record.swift */, - DAB37D4F273256B900EC523F /* RecordingModel.swift */, ); path = RecordingScene; sourceTree = ""; @@ -468,6 +470,7 @@ isa = PBXGroup; children = ( DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */, + DAB25F1A2754AF2D00F0BE75 /* RecordingViewModelTests.swift */, ); path = RecordingSceneTests; sourceTree = ""; @@ -750,6 +753,7 @@ DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */, DA854FE4274627D500E51E4B /* Settings.swift in Sources */, DA854FE2274627B000E51E4B /* Record.swift in Sources */, + DAB25F1B2754AF2D00F0BE75 /* RecordingViewModelTests.swift in Sources */, DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */, DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */, DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index a22c49f..5c0adb7 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -20,18 +20,18 @@ protocol RecordingUseCase { } final class RecordingViewModel: ObservableObject { - @Published private(set) var currentTime = "" - @Published private(set) var accessibilityCurrentTime = "" - @Published private(set) var kilometer = "" - @Published private(set) var altitude = "" - @Published private(set) var walk = "" - @Published private(set) var gpsStatus = true - @Published private(set) var motionAuth = true + @Published var currentTime = "" + @Published var accessibilityCurrentTime = "" + @Published var kilometer = "" + @Published var altitude = "" + @Published var walk = "" + @Published var gpsStatus = true + @Published var motionAuth = true private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() - init(recordingUseCase: RecordingUseCase) { + init(recordingUseCase: RecordingUseCase?) { self.recordingUseCase = recordingUseCase configureBindings() } From badbafe1d84a54bc9e324f739dff64aee13c8609 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 29 Nov 2021 17:15:53 +0900 Subject: [PATCH 431/465] =?UTF-8?q?[Refactor]=20=EA=B2=BD=EC=82=AC?= =?UTF-8?q?=EB=8F=84=20=ED=8F=89=EA=B7=A0,=20=EC=B5=9C=EA=B3=A0=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EA=B0=81?= =?UTF-8?q?=EB=8F=84=20=ED=91=9C=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 6 ++-- .../ResultDetailScene/ResultDetailModel.swift | 33 ++++++++++++------- .../ResultDetailViewModel.swift | 4 +-- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 9bf9370..8ac65ac 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -292,8 +292,8 @@ struct Locations { return plainDistance } - func totalIncline() -> Double { - var incline: Double = 0 + func totalIncline() -> [Double] { + var incline: [Double] = [] var prevLocation: Location? = nil for location in locations { @@ -301,7 +301,7 @@ struct Locations { let distanceDelta = location.distance(to: prevLocation) let altitudeDelta = location.altitude > prevLocation.altitude ? location.altitude - prevLocation.altitude : 0 if distanceDelta != 0 { - incline += atan(altitudeDelta / distanceDelta) + incline.append(atan(altitudeDelta / distanceDelta)) } } prevLocation = location diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index c9e98a9..b5628f9 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -108,8 +108,8 @@ struct ResultAltitude { for record in records.records { paths.append(record.locations) } - var maxAltitude: Int = Int.min - var minAltitude: Int = Int.max + var maxAltitude: Int = paths.isEmpty ? 0 : Int.min + var minAltitude: Int = paths.isEmpty ? 0 : Int.max for path in paths { maxAltitude = max(Int(round(path.maxAltitude)), Int(maxAltitude)) minAltitude = min(Int(round(path.minAltitude)), Int(minAltitude)) @@ -131,7 +131,7 @@ struct ResultIncline { let plainKilometer: Double init(records: Records) { - var totalIncline: Double = 0 + var inclines: [Double] = [] var steepest: Double = 0 var uphillDistance: Double = 0 var downHillDistance: Double = 0 @@ -142,19 +142,28 @@ struct ResultIncline { paths.append(record.locations) } - for locations in paths { - - totalIncline += locations.totalIncline() - steepest = locations.steepestIncline() - uphillDistance += locations.totalUphillDistance() - downHillDistance += locations.totalDownhillDistance() - plainDistance += locations.totalPlainDistance() + for path in paths { + inclines.append(contentsOf: path.totalIncline()) + steepest = max(path.steepestIncline(), steepest) + uphillDistance += path.totalUphillDistance() + downHillDistance += path.totalDownhillDistance() + plainDistance += path.totalPlainDistance() } + let averageInclineInRadian: Double = inclines.isEmpty ? 0 : inclines.reduce(0, +) / Double(inclines.count) + let averageInclineInDegrees: Int = Int(round(averageInclineInRadian.toDegrees())) - self.average = paths.count > 1 ? Int(totalIncline / Double(paths.count - 1)) : 0 - self.highest = Int(steepest) + self.average = averageInclineInDegrees + self.highest = Int(round(steepest.toDegrees())) self.uphillKilometer = uphillDistance / 1000 self.downhillKilometer = downHillDistance / 1000 self.plainKilometer = plainDistance / 1000 + + print("init: ", steepest) + } +} + +extension Double { + fileprivate func toDegrees() -> Double { + return self * 180 / Double.pi } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 721003b..287b227 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -251,8 +251,8 @@ extension ResultDetailViewModel { return } self.contents = [ - CellContentEntity(content: String(inclineData.average), contentTitle: "평균"), - CellContentEntity(content: String(inclineData.highest), contentTitle: "최고"), + CellContentEntity(content: String(inclineData.average)+"°", contentTitle: "평균"), + CellContentEntity(content: String(inclineData.highest)+"°", contentTitle: "최고"), CellContentEntity(content: uphill, contentTitle: "오르막(km)"), CellContentEntity(content: downhill, contentTitle: "내리막(km)"), CellContentEntity(content: plain, contentTitle: "평지(km)"), From 3409fb62a0fb34a5fe921c9149c43ad131ce6b51 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 17:16:49 +0900 Subject: [PATCH 432/465] =?UTF-8?q?[Refactor]=20#346=20SectionHeaderView?= =?UTF-8?q?=20=EC=A0=9C=EC=96=B4=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/MountainListScene/MountainCell.swift | 11 +++++++---- SanTa/SanTa/ResultScene/SectionHeaderView.swift | 10 +++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index b765420..004fd95 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -15,6 +15,7 @@ final class MountainCell: UICollectionViewCell { let label = UILabel() label.font = .preferredFont(forTextStyle: .headline) label.adjustsFontForContentSizeCategory = true + label.numberOfLines = 0 return label }() @@ -22,6 +23,7 @@ final class MountainCell: UICollectionViewCell { let label = UILabel() label.font = .preferredFont(forTextStyle: .subheadline) label.adjustsFontForContentSizeCategory = true + label.numberOfLines = 0 label.textColor = .systemGray2 return label }() @@ -31,20 +33,20 @@ final class MountainCell: UICollectionViewCell { label.translatesAutoresizingMaskIntoConstraints = false label.adjustsFontForContentSizeCategory = true label.font = .preferredFont(forTextStyle: .callout) - label.numberOfLines = 5 + label.numberOfLines = 0 label.textColor = .systemGray2 return label }() - + private lazy var stackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.name, self.height]) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.axis = .horizontal stackView.spacing = 10 - stackView.distribution = .fillEqually + stackView.distribution = .fill return stackView }() - + override init(frame: CGRect) { super.init(frame: frame) @@ -60,6 +62,7 @@ final class MountainCell: UICollectionViewCell { let stackViewConstrain = [ self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), self.stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), + self.stackView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -30), ] NSLayoutConstraint.activate(stackViewConstrain) diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index db96c9b..731bea7 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -28,6 +28,7 @@ class SectionHeaderView: UICollectionReusableView { label.font = .preferredFont(forTextStyle: .body) label.textColor = .label label.adjustsFontSizeToFitWidth = true + label.numberOfLines = 2 return label }() @@ -36,6 +37,7 @@ class SectionHeaderView: UICollectionReusableView { label.font = .preferredFont(forTextStyle: .caption1) label.textColor = .systemGray label.adjustsFontSizeToFitWidth = true + label.textAlignment = .right return label }() @@ -44,6 +46,8 @@ class SectionHeaderView: UICollectionReusableView { label.font = .preferredFont(forTextStyle: .caption1) label.textColor = .systemGray label.adjustsFontSizeToFitWidth = true + label.textAlignment = .right + label.numberOfLines = 2 return label }() @@ -52,6 +56,8 @@ class SectionHeaderView: UICollectionReusableView { label.font = .preferredFont(forTextStyle: .caption1) label.textColor = .systemGray label.adjustsFontSizeToFitWidth = true + label.textAlignment = .right + label.numberOfLines = 2 return label }() @@ -83,12 +89,14 @@ class SectionHeaderView: UICollectionReusableView { self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), self.monthLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), + self.monthLabel.trailingAnchor.constraint(equalTo: self.centerXAnchor, constant: -10), self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.distanceLabel.rightAnchor.constraint(equalTo: self.timeLabel.leftAnchor, constant: -10), self.countLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10) + self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10), + self.countLabel.leadingAnchor.constraint(equalTo: self.centerXAnchor, constant: 10), ]) } } From 6f37be94ba1c4febfe4493ec449d44c382fa23cd Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 29 Nov 2021 17:31:26 +0900 Subject: [PATCH 433/465] =?UTF-8?q?[Refactor]=20=EA=B1=B0=EB=A6=AC=20?= =?UTF-8?q?=EA=B3=84=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/RecordingScene/Record.swift | 3 +++ SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift | 6 +----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 8ac65ac..a299849 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -243,6 +243,9 @@ struct Locations { return locations.last } + func totalDistance() -> Double { + totalUphillDistance() + totalDownhillDistance() + totalPlainDistance() + } func totalUphillDistance() -> Double { var uphillDistance: Double = 0 diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index b5628f9..e7cdcba 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -60,11 +60,7 @@ struct ResultDistance { init(records: Records) { self.steps = records.steps - guard let totalDistance = records.records.last?.distance else { - self.total = 0 - return - } - self.total = totalDistance + self.total = records.records.map{$0.locations.totalDistance()}.reduce(0, +) / 1000 } } From 1ebf3dfc2917ec21b069d122a684102e19a595c6 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 29 Nov 2021 17:47:13 +0900 Subject: [PATCH 434/465] =?UTF-8?q?[Refactor]=20CoreDataRecordStorage=20?= =?UTF-8?q?=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Persistences/CoreDataRecordStorage.swift | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 0d63181..7e6fd59 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -25,17 +25,15 @@ final class CoreDataRecordStorage: RecordsStorage { func save(records: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordsObject = NSEntityDescription.insertNewObject(forEntityName: "RecordsEntity", - into: context) - - recordsObject.setValue(records.title, forKey: "title") - recordsObject.setValue(records.id, forKey: "id") - recordsObject.setValue(records.secondPerHighestSpeed, forKey: "secondPerHighestSpeed") - recordsObject.setValue(records.secondPerMinimumSpeed, forKey: "secondPerMinimumSpeed") + into: context) as? RecordsEntityMO + recordsObject?.title = records.title + recordsObject?.id = records.id + recordsObject?.secondPerHighestSpeed = Int16(records.secondPerHighestSpeed) + recordsObject?.secondPerMinimumSpeed = Int16(records.secondPerMinimumSpeed) do { let assetIdentifiers = try NSKeyedArchiver.archivedData(withRootObject: records.assetIdentifiers, requiringSecureCoding: true) - - recordsObject.setValue(assetIdentifiers, forKey: "assetIdentifiers") + recordsObject?.assetIdentifiers = assetIdentifiers } catch { completion(.failure(CoreDataError.coreDataError)) } @@ -43,14 +41,13 @@ final class CoreDataRecordStorage: RecordsStorage { records.records.forEach { let recordObject = NSEntityDescription.insertNewObject(forEntityName: "RecordEntity", into: context) as? RecordEntityMO - recordObject?.startTime = $0.startTime recordObject?.endTime = $0.endTime recordObject?.distance = $0.distance recordObject?.step = Int16($0.step) guard let recordObject = recordObject else { return } - (recordsObject as? RecordsEntityMO)?.addToRecords(recordObject) + recordsObject?.addToRecords(recordObject) $0.locations.forEach { let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", From 233e636d17e142149569794cce7d589f7a5c24a7 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 29 Nov 2021 18:15:55 +0900 Subject: [PATCH 435/465] =?UTF-8?q?[Feat]=20#349=20ResultDetailViewControl?= =?UTF-8?q?ler=20VoiceOver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailViewController.swift | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 2aacf38..02e7080 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -29,7 +29,7 @@ class ResultDetailViewController: UIViewController { mapView.mapType = .mutedStandard mapView.backgroundColor = .black mapView.translatesAutoresizingMaskIntoConstraints = false - + mapView.accessibilityElementsHidden = true return mapView }() @@ -57,7 +57,9 @@ class ResultDetailViewController: UIViewController { button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) button.tintColor = .label button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(dismissViewController), for: .touchUpInside) + button.addTarget(self, action: #selector(self.dismissViewController), for: .touchUpInside) + button.accessibilityLabel = "뒤로가기" + button.accessibilityHint = "이전 화면으로 돌아가려면 이중 탭 하십시오" return button }() @@ -67,7 +69,9 @@ class ResultDetailViewController: UIViewController { button.setPreferredSymbolConfiguration(.init(pointSize: 25), forImageIn: .normal) button.tintColor = .label button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(presentModifyResultAlert), for: .touchUpInside) + button.addTarget(self, action: #selector(self.presentModifyResultAlert), for: .touchUpInside) + button.accessibilityLabel = "수정하기" + button.accessibilityHint = "기록을 수정하거나 삭제하려면 이중 탭 하십시오" return button }() @@ -88,7 +92,9 @@ class ResultDetailViewController: UIViewController { button.layer.shadowOffset = CGSize.zero button.layer.shadowRadius = 2 button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(pushDetailImagesViewController), for: .touchUpInside) + button.addTarget(self, action: #selector(self.pushDetailImagesViewController), for: .touchUpInside) + button.accessibilityLabel = "앨범형식 모아보기" + button.accessibilityHint = "앨범형식으로 모아보려면 이중 탭 하십시오" return button }() @@ -105,7 +111,10 @@ class ResultDetailViewController: UIViewController { button.layer.shadowOffset = CGSize.zero button.layer.shadowRadius = 2 button.translatesAutoresizingMaskIntoConstraints = false - button.addTarget(self, action: #selector(imagesVisibilityButtonAction), for: .touchUpInside) + button.addTarget(self, action: #selector(self.imagesVisibilityButtonAction), for: .touchUpInside) + button.accessibilityLabel = "이미지 썸네일" + button.accessibilityValue = "켜짐" + button.accessibilityHint = "이미지 썸네일을 끄려면 이중 탭 하십시오" return button }() @@ -113,6 +122,7 @@ class ResultDetailViewController: UIViewController { let label = UILabel() label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) label.translatesAutoresizingMaskIntoConstraints = false + label.accessibilityTraits = .header return label }() @@ -173,7 +183,7 @@ class ResultDetailViewController: UIViewController { }) .store(in: &observers) - viewModel?.setUp() + self.viewModel?.setUp() } private func registerAnnotationView() { @@ -193,10 +203,14 @@ class ResultDetailViewController: UIViewController { let imageAnnotations = self.mapView.annotations.filter{$0.title != "시작점" && $0.title != "종료점"} switch bool { case true: + self.imagesVisibilityButton.accessibilityValue = "켜짐" + self.imagesVisibilityButton.accessibilityHint = "이미지 썸네일을 끄려면 이중 탭 하십시오" imageAnnotations.forEach{ self.mapView.view(for: $0)?.isHidden = false } case false: + self.imagesVisibilityButton.accessibilityValue = "꺼짐" + self.imagesVisibilityButton.accessibilityHint = "이미지 썸네일을 켜려면 이중 탭 하십시오" imageAnnotations.forEach{ self.mapView.view(for: $0)?.isHidden = true } @@ -208,14 +222,14 @@ class ResultDetailViewController: UIViewController { return } for pointSet in pointSets { - mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) + self.mapView.addOverlay(MKPolyline(coordinates: pointSet, count: pointSet.count)) } - guard let initial = mapView.overlays.first?.boundingMapRect else { + guard let initial = self.mapView.overlays.first?.boundingMapRect else { return } - let mapRect = mapView.overlays.dropFirst().reduce(initial) { $0.union($1.boundingMapRect) } - mapView.setVisibleMapRect(mapRect, animated: true) + let mapRect = self.mapView.overlays.dropFirst().reduce(initial) { $0.union($1.boundingMapRect) } + self.mapView.setVisibleMapRect(mapRect, animated: true) } private func markEndPoints() { @@ -243,7 +257,7 @@ class ResultDetailViewController: UIViewController { for i in stride(from: allMedia.count - 1, through: 0, by: -1) { guard identifierIndex < assetIdentifiers.count else { return } if allMedia[i].localIdentifier == assetIdentifiers[identifierIndex] { - requestAssetIamge(with: allMedia[i]) { [weak self] (image, asset) in + self.requestAssetIamge(with: allMedia[i]) { [weak self] (image, asset) in guard let image = image, let identifier = asset?.localIdentifier, let coordinate = asset?.location?.coordinate else { return } @@ -270,7 +284,7 @@ class ResultDetailViewController: UIViewController { let imageAnnotation = MKPointAnnotation() imageAnnotation.coordinate = location imageAnnotation.title = identifier - mapView.addAnnotation(imageAnnotation) + self.mapView.addAnnotation(imageAnnotation) } private func configureSmallerView() { @@ -278,7 +292,7 @@ class ResultDetailViewController: UIViewController { } private func configurePanGesture() { - let informationViewPan = UIPanGestureRecognizer(target: self, action: #selector(informationViewPanPanned(_:))) + let informationViewPan = UIPanGestureRecognizer(target: self, action: #selector(self.informationViewPanPanned(_:))) informationViewPan.delaysTouchesBegan = false informationViewPan.delaysTouchesEnded = false @@ -346,9 +360,9 @@ class ResultDetailViewController: UIViewController { self.imagesVisibilityButton.heightAnchor.constraint(equalToConstant: 30) ]) - infoViewTopConstraint = + self.infoViewTopConstraint = self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) - guard let infoViewConstraint = infoViewTopConstraint else { return } + guard let infoViewConstraint = self.infoViewTopConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) self.view.layoutIfNeeded() @@ -382,7 +396,7 @@ class ResultDetailViewController: UIViewController { case .changed: var offset: CGFloat = 0 - if isLargeInfoView { + if self.isLargeInfoView { offset = self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY } @@ -424,11 +438,11 @@ class ResultDetailViewController: UIViewController { extension ResultDetailViewController { @objc func dismissViewController() { - coordinator?.dismiss() + self.coordinator?.dismiss() } @objc func pushDetailImagesViewController() { - coordinator?.pushResultDetailImagesViewController(uiImages: uiImages) + self.coordinator?.pushResultDetailImagesViewController(uiImages: uiImages) } @objc func imagesVisibilityButtonAction() { From 5aa64c8cd373e37211b2fe23169c3722800975af Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 29 Nov 2021 20:53:16 +0900 Subject: [PATCH 436/465] =?UTF-8?q?[Fix]=20#350=20=EC=82=B0=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=EC=B0=BD=EC=9D=84=20=ED=84=B0=EC=B9=98=20=ED=9B=84=20?= =?UTF-8?q?=EC=82=B0=20=EC=83=81=EC=84=B8=ED=99=94=EB=A9=B4=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=EC=8B=9C=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=EB=B0=94=EA=B0=80=20=EC=82=AC=EB=9D=BC=EC=A7=80?= =?UTF-8?q?=EC=A7=80=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListViewController.swift | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index b938f87..9e1d120 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -39,7 +39,6 @@ class MountainListViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - self.configureSearchBar() self.configureCollectionView() self.configureView() self.configuareDataSource() @@ -47,6 +46,17 @@ class MountainListViewController: UIViewController { self.viewModel?.viewDidLoad() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.configureSearchBar() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + self.navigationItem.searchController = nil + self.view.setNeedsLayout() + } + private func configureSearchBar() { let searchController = UISearchController(searchResultsController: nil) searchController.searchBar.placeholder = "검색" From ccfac5d35233c872390161ec2259da24f97bd5ff Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 21:07:45 +0900 Subject: [PATCH 437/465] =?UTF-8?q?[Refactor]=20#347=20Mountain=20StackVie?= =?UTF-8?q?w=20AutoLayout=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppDelegate.swift | 2 +- SanTa/SanTa/MountainListScene/MountainCell.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index 4513e31..c9c4086 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -13,7 +13,7 @@ import AVFoundation @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default) + try? AVAudioSession.sharedInstance().setCategory(.multiRoute, mode: .spokenAudio) try? AVAudioSession.sharedInstance().setActive(true) return true } diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index 004fd95..dcbdd30 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -62,7 +62,7 @@ final class MountainCell: UICollectionViewCell { let stackViewConstrain = [ self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), self.stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), - self.stackView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -30), + self.stackView.rightAnchor.constraint(lessThanOrEqualTo: self.rightAnchor, constant: -30), ] NSLayoutConstraint.activate(stackViewConstrain) From 9452cd225caa212d040ed1db0f1f1e70e38e0217 Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Mon, 29 Nov 2021 21:42:03 +0900 Subject: [PATCH 438/465] =?UTF-8?q?[Feat]=20#349=20ResultDetailLargerInfoV?= =?UTF-8?q?iew,=20ResultDetailSmallerInfoView=20VoiceOver=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/ResultSceneTests/ResultSceneTests.swift | 1 - .../SanTa/ResultDetailScene/DetailCell.swift | 59 +++++++++++++------ .../ResultDetailScene/DetailHeader.swift | 15 +++++ .../ResultDetailLargerInfoView.swift | 5 +- .../ResultDetailSmallerInfoView.swift | 19 ++++++ .../ResultDetailViewController.swift | 20 +++++++ 6 files changed, 98 insertions(+), 21 deletions(-) diff --git a/SanTa/ResultSceneTests/ResultSceneTests.swift b/SanTa/ResultSceneTests/ResultSceneTests.swift index 187bb3b..b965ca3 100644 --- a/SanTa/ResultSceneTests/ResultSceneTests.swift +++ b/SanTa/ResultSceneTests/ResultSceneTests.swift @@ -39,7 +39,6 @@ class ResultSceneTests: XCTestCase { step: 40, distance: 50, locations: [location7, location8]) - let records1 = Records(title: "기록1", records: [record1, record2], assetIdentifiers: ["1", "11"], diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index f1fe9c3..e179d7d 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -31,35 +31,35 @@ class DetailCell: UICollectionViewCell { }() func layout(data: DetailInformationModel) { - self.addSubview(title) - title.text = data.title - title.translatesAutoresizingMaskIntoConstraints = false + self.addSubview(self.title) + self.title.text = data.title + self.title.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - title.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), - title.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10) + self.title.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), + self.title.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10) ]) - self.addSubview(line) - line.translatesAutoresizingMaskIntoConstraints = false + self.addSubview(self.line) + self.line.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - line.heightAnchor.constraint(equalToConstant: 1), - line.leftAnchor.constraint(equalTo: title.rightAnchor, constant: 5), - line.centerYAnchor.constraint(equalTo: title.centerYAnchor), - line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), + self.line.heightAnchor.constraint(equalToConstant: 1), + self.line.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 5), + self.line.centerYAnchor.constraint(equalTo: self.title.centerYAnchor), + self.line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), ]) - stack.subviews.forEach{ $0.removeFromSuperview() } - self.addSubview(stack) + self.stack.subviews.forEach{ $0.removeFromSuperview() } + self.addSubview(self.stack) for content in data.contents { - stack.addArrangedSubview(UIStackView(content: content)) + self.stack.addArrangedSubview(UIStackView(content: content)) } - stack.translatesAutoresizingMaskIntoConstraints = false + self.stack.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - stack.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 30), - stack.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10), - stack.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), - stack.bottomAnchor.constraint(equalTo: self.bottomAnchor) + self.stack.topAnchor.constraint(equalTo: self.title.bottomAnchor, constant: 30), + self.stack.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10), + self.stack.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), + self.stack.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } } @@ -91,3 +91,24 @@ extension UIStackView { self.addArrangedSubview(contentTitleLabel) } } + + +// MARK: - Accessibility + +extension DetailCell { + func configureVoiceOverAccessibility() { + self.isAccessibilityElement = true + guard let title = self.title.text else { return } + var label = "\(title)정보. " + self.stack.arrangedSubviews.forEach { + let stackView = $0 as? UIStackView + guard let contentLabel = (stackView?.arrangedSubviews[0] as? UILabel)?.text, + let contentTitleLabel = (stackView?.arrangedSubviews[1] as? UILabel)?.text + else { + return + } + label += "\(contentTitleLabel): \(contentLabel), " + } + self.accessibilityLabel = label + } +} diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index 7a45915..ee68bad 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -134,3 +134,18 @@ class DetailHeader: UICollectionReusableView { [self.startTime, self.endTime].forEach { self.timeStackView.addArrangedSubview($0) } } } + +// MARK: - Accessibility + +extension DetailHeader { + func configureVoiceOverAccessibility() { + self.isAccessibilityElement = true + guard let dateLabel = self.dateLabel.text, + let startTime = self.startTime.text, + let endTime = self.endTime.text + else { + return + } + self.accessibilityLabel = "날짜: \(dateLabel), 시작시간: \(startTime), 종료시간: \(endTime)" + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 9a41c14..154011d 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -95,12 +95,14 @@ extension ResultDetailLargerInfoView { } private func configuareDataSource() { - let datasource = DetailLargerInfoDataSource (collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + let datasource = DetailLargerInfoDataSource (collectionView: self.collectionView, + cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell, let item = item as? DetailInformationModel else { return UICollectionViewCell() } cell.layout(data: item) + cell.configureVoiceOverAccessibility() return cell }) @@ -124,6 +126,7 @@ extension ResultDetailLargerInfoView { guard let header: DetailHeader = self.collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { return DetailHeader() } header.configure(date: self.date, startTime: self.startTime, endTime: self.endTime) + header.configureVoiceOverAccessibility() return header } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 7037752..54e781d 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -190,3 +190,22 @@ class ResultDetailSmallerInfoView: UIView { NSLayoutConstraint.activate(upDownConstraints) } } + +// MARK: - Accessibility + +extension ResultDetailSmallerInfoView { + func configureVoiceOverAccessibility() { + self.isAccessibilityElement = true + guard let distance = self.distance.text, + let time = self.time.text, + let steps = self.steps.text, + let maxAltitude = self.maxAltitude.text, + let minAltitude = self.minAltitude.text, + let averageSpeed = self.averageSpeed.text + else { + return + } + self.accessibilityLabel = + "기록 정보 거리: \(distance)km, 시간: \(time), 걸음: \(steps), 최고고도: \(maxAltitude), 최저고도: \(minAltitude), 평균속도: \(averageSpeed)" + } +} diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 02e7080..71e7d4f 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -139,6 +139,7 @@ class ResultDetailViewController: UIViewController { self.drawPathOnMap() self.markEndPoints() self.registerAnnotationView() + self.configureVoiceOverAccessibility() } private func configureViewModel() { @@ -153,6 +154,7 @@ class ResultDetailViewController: UIViewController { minAltitude: viewModel.altitudeViewModel.lowest, averageSpeed: viewModel.averageSpeed() ) + self?.smallerInformationView.configureVoiceOverAccessibility() self?.largerInformationView.configure() guard let distanceViewModel = self?.viewModel?.distanceViewModel, let timeViewModel = self?.viewModel?.timeViewModel, @@ -430,6 +432,7 @@ class ResultDetailViewController: UIViewController { self.largerInformationView.collectionView.setNeedsLayout() }, completion: nil) + self.configureVoiceOverAccessibility() default: break } @@ -518,3 +521,20 @@ extension ResultDetailViewController: MKMapViewDelegate { self.coordinator?.presentResultDetailThumbnailViewController(uiImages: uiImages, id: annotation.imageIdentifier) } } + +// MARK: - Accessibility + +extension ResultDetailViewController { + private func configureVoiceOverAccessibility() { + switch isLargeInfoView { + case true: + self.view.accessibilityElements = [self.largerInformationView] + self.smallerInformationView.accessibilityElementsHidden = true + self.largerInformationView.accessibilityElementsHidden = false + case false: + self.view.accessibilityElements = nil + self.smallerInformationView.accessibilityElementsHidden = false + self.largerInformationView.accessibilityElementsHidden = true + } + } +} From 8fba859ac62ea15030e3f0df29bb8d55c33ef596 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 23:01:27 +0900 Subject: [PATCH 439/465] =?UTF-8?q?[Refactor]=20#352=20Background=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9D=8C=EC=95=85=EA=B3=BC=20=EC=9D=8C?= =?UTF-8?q?=EC=84=B1=20=EC=95=88=EB=82=B4=20=EB=8F=99=EC=8B=9C=EC=9E=AC?= =?UTF-8?q?=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Application/AppDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index c9c4086..3bd292c 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -13,7 +13,7 @@ import AVFoundation @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - try? AVAudioSession.sharedInstance().setCategory(.multiRoute, mode: .spokenAudio) + try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.duckOthers]) try? AVAudioSession.sharedInstance().setActive(true) return true } From cf2bac2f647e6acf768502e93cc1854d3f7d1fc9 Mon Sep 17 00:00:00 2001 From: MinChang Date: Mon, 29 Nov 2021 23:13:51 +0900 Subject: [PATCH 440/465] =?UTF-8?q?[Refactor]=20#346=20ResultView=20Second?= =?UTF-8?q?=20Header=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultScene/ResultViewController.swift | 2 +- .../SanTa/ResultScene/SectionHeaderView.swift | 48 ++----------------- 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index fef5352..c4897bd 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -69,7 +69,7 @@ class ResultViewController: UIViewController { let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitem: item, count: 1) group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let section = NSCollectionLayoutSection(group: group) - let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(200)) + let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(45)) let header = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 731bea7..08ebbf0 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -23,43 +23,10 @@ extension UILabel { class SectionHeaderView: UICollectionReusableView { static let identifier = "SectionHeaderView" - let monthLabel: UILabel = { - let label = UILabel() - label.font = .preferredFont(forTextStyle: .body) - label.textColor = .label - label.adjustsFontSizeToFitWidth = true - label.numberOfLines = 2 - return label - }() - - let countLabel: UILabel = { - let label = UILabel() - label.font = .preferredFont(forTextStyle: .caption1) - label.textColor = .systemGray - label.adjustsFontSizeToFitWidth = true - label.textAlignment = .right - return label - }() - - let distanceLabel: UILabel = { - let label = UILabel() - label.font = .preferredFont(forTextStyle: .caption1) - label.textColor = .systemGray - label.adjustsFontSizeToFitWidth = true - label.textAlignment = .right - label.numberOfLines = 2 - return label - }() - - let timeLabel: UILabel = { - let label = UILabel() - label.font = .preferredFont(forTextStyle: .caption1) - label.textColor = .systemGray - label.adjustsFontSizeToFitWidth = true - label.textAlignment = .right - label.numberOfLines = 2 - return label - }() + let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .label) + let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) + let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) func configure(month: String, count: String, distance: String, time: String) { self.backgroundColor = .systemBackground @@ -85,24 +52,19 @@ class SectionHeaderView: UICollectionReusableView { self.distanceLabel.translatesAutoresizingMaskIntoConstraints = false self.timeLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ - self.monthLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), self.monthLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.monthLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20), - self.monthLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10), - self.monthLabel.trailingAnchor.constraint(equalTo: self.centerXAnchor, constant: -10), self.timeLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20), self.distanceLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), self.distanceLabel.rightAnchor.constraint(equalTo: self.timeLabel.leftAnchor, constant: -10), self.countLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor), - self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10), - self.countLabel.leadingAnchor.constraint(equalTo: self.centerXAnchor, constant: 10), + self.countLabel.rightAnchor.constraint(equalTo: self.distanceLabel.leftAnchor, constant: -10) ]) } } // MARK: - Accessibility - extension SectionHeaderView { func configureVoiceOverAccessibility(date: String) { From be036424ad3a23ad0664c0a5fb5a233559be49da Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Mon, 29 Nov 2021 23:49:58 +0900 Subject: [PATCH 441/465] =?UTF-8?q?[Refactor]=20#354=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B0=80=20=EC=97=86=EC=9D=84=EC=8B=9C=20-=20?= =?UTF-8?q?=EB=A1=9C=20=ED=91=9C=EA=B8=B0=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=EB=A1=9C=EC=A7=81=EB=93=A4=20=EC=9D=BC=EB=B6=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainDetailViewController.swift | 9 -- SanTa/SanTa/RecordingScene/Record.swift | 20 +++-- .../ResultDetailScene/ResultDetailModel.swift | 37 +++++---- .../ResultDetailViewModel.swift | 83 +++++++++++++------ SanTa/SanTa/ResultScene/ResultViewModel.swift | 2 +- 5 files changed, 95 insertions(+), 56 deletions(-) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 1f7c985..007ef9e 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -150,15 +150,6 @@ extension MountainDetailViewController { snapShotter.start { snapShot, error in if let snapShot = snapShot { let mapImage = snapShot.image - /* - func imageWith(newSize: CGSize) -> UIImage { - let image = UIGraphicsImageRenderer(size: newSize).image { _ in - draw(in: CGRect(origin: .zero, size: newSize)) - } - - return image.withRenderingMode(renderingMode) - } - */ UIGraphicsBeginImageContext(CGSize(width: 20, height: 20)) UIImage(named: "SantaImage")?.draw(in: CGRect(x: 0, y: 0, width: 20, height: 20)) let markerImage = UIGraphicsGetImageFromCurrentImageContext() diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index a299849..3cdcd1c 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -80,7 +80,7 @@ class DateSeperateRecords { } var times: TimeInterval { - return dateSeperateRecords.reduce(0) { $0 + $1.times } + return dateSeperateRecords.reduce(0) { $0 + $1.totalTravelTime } } var steps: Int { @@ -111,8 +111,8 @@ struct Records { return records.reduce(0) { $0 + $1.distance } } - var times: TimeInterval { - return records.reduce(0) { $0 + $1.time } + var totalTravelTime: TimeInterval { + return records.reduce(0) { $0 + $1.travelTime } } var steps: Int { @@ -162,8 +162,8 @@ struct Record { let distance: Double let locations: Locations - var time: TimeInterval { - return endTime.timeIntervalSinceReferenceDate - startTime.timeIntervalSinceReferenceDate + var travelTime: TimeInterval { + return endTime.timeIntervalSince(startTime) } var minAltitude: Double? { @@ -244,7 +244,15 @@ struct Locations { } func totalDistance() -> Double { - totalUphillDistance() + totalDownhillDistance() + totalPlainDistance() + var distance: Double = 0 + var prevLocation: Location? = nil + for location in locations { + if let prevLocation = prevLocation { + distance += location.distance(to: prevLocation) + } + prevLocation = location + } + return distance } func totalUphillDistance() -> Double { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index e7cdcba..ba307db 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -55,7 +55,7 @@ struct ResultTimeStamp { } struct ResultDistance { - let total: Double + var total: Double? = nil let steps: Int init(records: Records) { @@ -71,12 +71,14 @@ struct ResultTime { init(records: Records) { var inactive: TimeInterval = 0 - for index in 0.. 1 { + for index in 0.. 0, + let speed = formatter.string(from: NSNumber(value: distance * 3600 / totalTime)) else { + return "-" + } + return speed } lazy var recordDate: String = { @@ -103,7 +106,7 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: endTime) }() - + func imageVisibilityButtonTouched() { self.useCase.toggleImageVisibility { [weak self] bool in bool ? (self?.imageVisibilityIconName = "eye") : (self?.imageVisibilityIconName = "eye.slash") @@ -128,18 +131,18 @@ class DetailInformationModel: Hashable { var contents: [CellContentEntity] = [] func hash(into hasher: inout Hasher) { - hasher.combine(id) + hasher.combine(id) } - + static func == (lhs: DetailInformationModel, rhs: DetailInformationModel) -> Bool { - lhs.id == rhs.id + lhs.id == rhs.id } } extension ResultDetailViewModel { class DistanceViewModel: DetailInformationModel { - var totalDistance: String = "" - var steps: String = "" + var totalDistance: String = "-" + var steps: String = "0" init(distanceData: ResultDistance?) { super.init() @@ -151,15 +154,17 @@ extension ResultDetailViewModel { formatter.numberStyle = .decimal formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 2 - guard let total = formatter.string(from: NSNumber(value: distanceData.total)), - let steps = formatter.string(from: NSNumber(value: distanceData.steps)) else { - return - } - self.totalDistance = total - self.steps = steps + if let steps = formatter.string(from: NSNumber(value: distanceData.steps)) { + self.steps = steps + } + + if let distance = distanceData.total, + let total = formatter.string(from: NSNumber(value: distance)) { + self.totalDistance = total + } self.contents = [ - CellContentEntity(content: total, contentTitle: "전체"), - CellContentEntity(content: steps, contentTitle: "걸음수") + CellContentEntity(content: self.totalDistance, contentTitle: "전체"), + CellContentEntity(content: self.steps, contentTitle: "걸음수") ] } } @@ -214,8 +219,8 @@ extension ResultDetailViewModel { } class AltitudeViewModel: DetailInformationModel { - var highest: String = "" - var lowest: String = "" + var highest: String = "-" + var lowest: String = "-" init(altitudeData: ResultAltitude?) { super.init() @@ -223,15 +228,41 @@ extension ResultDetailViewModel { return } self.title = "고도" + var totalString = "-" + var highestString = "-" + var lowestString = "-" + var startingString = "-" + var endingString = "-" + + if let total = altitudeData.total { + totalString = String(total) + } + + if let highest = altitudeData.highest { + highestString = String(highest) + self.highest = highestString + } + + if let lowest = altitudeData.lowest { + lowestString = String(lowest) + self.lowest = lowestString + } + + if let start = altitudeData.starting { + startingString = String(start) + } + + if let end = altitudeData.ending { + endingString = String(end) + } + self.contents = [ - CellContentEntity(content: String(altitudeData.total), contentTitle: "누적"), - CellContentEntity(content: String(altitudeData.highest), contentTitle: "최고"), - CellContentEntity(content: String(altitudeData.lowest), contentTitle: "최저"), - CellContentEntity(content: String(altitudeData.starting), contentTitle: "시작"), - CellContentEntity(content: String(altitudeData.ending), contentTitle: "종료"), + CellContentEntity(content: totalString, contentTitle: "누적"), + CellContentEntity(content: highestString, contentTitle: "최고"), + CellContentEntity(content: lowestString, contentTitle: "최저"), + CellContentEntity(content: startingString, contentTitle: "시작"), + CellContentEntity(content: endingString, contentTitle: "종료"), ] - self.highest = String(altitudeData.highest) - self.lowest = String(altitudeData.lowest) } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 84edaa7..f1ebb48 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -80,7 +80,7 @@ class ResultViewModel { } let dateString = self.cellDateFormatter(records.date) let distanceString = self.doubleFormatter(records.distances) - let timeString = self.timeFormatter(records.times) + let timeString = self.timeFormatter(records.totalTravelTime) let altitudeDifferenceString = self.cellAltitudeDifferenceFormatter(records.maxAltitudeDifference) let stepsString = self.stepsFormatter(records.steps) let title = records.title From e89a8e0cf817077f1d5d28da13642858bf679f55 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:28:45 +0900 Subject: [PATCH 442/465] =?UTF-8?q?[Docs]=20Test=20issue=20Template=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../refactor-request-template.md | 4 ++-- .../ISSUE_TEMPLATE/test-request-template.md | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/test-request-template.md diff --git a/.github/ISSUE_TEMPLATE/refactor-request-template.md b/.github/ISSUE_TEMPLATE/refactor-request-template.md index 4f2c772..609699d 100644 --- a/.github/ISSUE_TEMPLATE/refactor-request-template.md +++ b/.github/ISSUE_TEMPLATE/refactor-request-template.md @@ -1,7 +1,7 @@ --- name: Refactor Request Template about: Refactor 작업 필요시 사용하는 기본 템플릿 -title: '' +title: "[REFACTOR]" labels: Refactor assignees: '' @@ -14,7 +14,7 @@ assignees: '' 1. MVC 입니다 - 개선될 구조 - 2. MVVM 입니다 + 1. MVVM 입니다 ## 기대하는 결과 > 구체적으로 어떤 결과가 나오게 수정해야 하는지 작성합니다. diff --git a/.github/ISSUE_TEMPLATE/test-request-template.md b/.github/ISSUE_TEMPLATE/test-request-template.md new file mode 100644 index 0000000..6c58847 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/test-request-template.md @@ -0,0 +1,18 @@ +--- +name: Test Request Template +about: Test 추가 필요시 사용하는 기본 템플릿 +title: "[TEST]" +labels: Test +assignees: '' + +--- + +## 테스트를 추가할 Scene을 입력하세요 ex) MapScene +### 테스트를 추가할 파일을 입력하세요 ex) MapViewModel + +- 필요시 추가 설명 작성 + +## 🤔 완료 조건 + +- [ ] CheckPoint1 +- [ ] CheckPoint2 From a9d45825cf6b044cb9fde798e35bf2bf1d869010 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Tue, 30 Nov 2021 10:30:35 +0900 Subject: [PATCH 443/465] =?UTF-8?q?[Docs]=20Pull=20Request=20Template=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a6e344e..fae9d81 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,6 +14,7 @@ - [ ] 신규 기능 추가 - [ ] 버그 수정 - [ ] 리펙토링 +- [ ] 테스트 코드 작성 - [ ] 문서 업데이트 ### 체크리스트 From 2ae0a1ff3279e199835f1906c3ba0fde17efb8cd Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 10:53:23 +0900 Subject: [PATCH 444/465] =?UTF-8?q?[Refactor]=20#356=20swiftLint=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/.swiftlint.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 SanTa/.swiftlint.yml diff --git a/SanTa/.swiftlint.yml b/SanTa/.swiftlint.yml new file mode 100644 index 0000000..e69de29 From 0b8ad5cb86e56d69238713ee7e016302748c5980 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 11:29:18 +0900 Subject: [PATCH 445/465] =?UTF-8?q?[Refactor]=20#356=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NSLayout, self --- SanTa/.swiftlint.yml | 1 + .../RecordingUseCaseTests.swift | 38 ++--- .../RecordingViewModelTests.swift | 142 +++++++++--------- SanTa/ResultSceneTests/ResultSceneTests.swift | 19 ++- SanTa/SanTa.xcodeproj/project.pbxproj | 25 +++ SanTa/SanTa/Application/AppCoordinator.swift | 10 +- SanTa/SanTa/Application/AppDelegate.swift | 6 +- SanTa/SanTa/Application/SceneDelegate.swift | 1 - SanTa/SanTa/Entities/MountainEntity.swift | 10 +- .../MapScene/ClusterAnnotationView.swift | 10 +- SanTa/SanTa/MapScene/MapViewController.swift | 46 +++--- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 28 ++-- SanTa/SanTa/MapScene/MapViewModel.swift | 10 +- SanTa/SanTa/MapScene/MapViewRepository.swift | 14 +- SanTa/SanTa/MapScene/MapViewUseCase.swift | 12 +- SanTa/SanTa/MapScene/MountainAnnotation.swift | 8 +- .../MapScene/MountainAnnotationView.swift | 6 +- SanTa/SanTa/MapScene/UIImage+Gif.swift | 8 +- .../MountainAddingView.swift | 56 +++---- .../MountainAddingViewController.swift | 24 +-- .../MountainAddingViewCoordinator.swift | 6 +- .../MountainAddingViewModel.swift | 8 +- .../MountainAddingViewRepository.swift | 6 +- .../MountainAddingViewUseCase.swift | 12 +- .../MountainDetailAnnotationView.swift | 7 +- .../MountainDetailTableViewCell.swift | 72 +++++---- .../MountainDetailTitleView.swift | 23 ++- .../MountainDetailUseCase.swift | 15 +- .../MountainDetailViewController.swift | 114 +++++++------- .../MountainDetailViewCoordinator.swift | 8 +- .../MountainDetailViewModel.swift | 6 +- .../MountainListScene/MountainCell.swift | 33 ++-- .../MountainListViewController.swift | 59 ++++---- .../MountainListViewCoordinator.swift | 7 +- .../MountainListViewModel.swift | 8 +- .../MountainListViewRepository.swift | 6 +- .../MountainListViewUseCase.swift | 10 +- .../CoreDataMountainStorage.swift | 10 +- .../Persistences/CoreDataRecordStorage.swift | 23 ++- .../SanTa/Persistences/CoreDataStorage.swift | 2 +- .../Persistences/MountainExtractor.swift | 6 +- .../Persistences/UserDefaultsStorage.swift | 14 +- .../RecordingPhotoCoordinator.swift | 12 +- .../RecordingPhotoViewController.swift | 61 ++++---- SanTa/SanTa/RecordingScene/Record.swift | 125 ++++++++------- .../RecordingScene/RecordRepository.swift | 18 +-- .../SanTa/RecordingScene/RecordingModel.swift | 104 ++++++------- .../RecordingScene/RecordingPhotoModel.swift | 16 +- .../RecordingScene/RecordingUseCase.swift | 34 ++--- .../RecordingViewController+Extension.swift | 85 +++++------ .../RecordingViewController.swift | 94 ++++++------ .../RecordingViewCoordinator.swift | 19 +-- .../RecordingScene/RecordingViewModel.swift | 44 +++--- .../RecordingTitleViewController.swift | 78 +++++----- .../RecordingTitleViewCoordinator.swift | 8 +- .../DetailImagesCell.swift | 12 +- .../ResultDetailImagesViewController.swift | 42 +++--- .../ResultDetailImagesViewCoordinator.swift | 10 +- .../SanTa/ResultDetailScene/DetailCell.swift | 23 ++- .../ResultDetailScene/DetailHeader.swift | 34 ++--- SanTa/SanTa/ResultDetailScene/PinView.swift | 6 +- .../ResultDetailLargerInfoView.swift | 53 ++++--- .../ResultDetailScene/ResultDetailModel.swift | 34 ++--- .../ResultDetailRepository.swift | 6 +- .../ResultDetailSmallerInfoView.swift | 41 +++-- .../ResultDetailUseCase.swift | 10 +- .../ResultDetailViewController 2.swift | 4 +- .../ResultDetailViewController.swift | 140 +++++++++-------- .../ResultDetailViewCoordinator.swift | 18 +-- .../ResultDetailViewModel.swift | 60 ++++---- .../ResultDetailScene/ThumbnailView.swift | 20 +-- .../ResultDetailThumbnailViewController.swift | 52 +++---- ...ResultDetailThumbnailViewCoordinator.swift | 10 +- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 15 +- .../SanTa/ResultScene/ResultRepository.swift | 16 +- SanTa/SanTa/ResultScene/ResultUseCase.swift | 5 +- .../ResultScene/ResultViewController.swift | 24 +-- .../ResultScene/ResultViewCoordinator.swift | 6 +- SanTa/SanTa/ResultScene/ResultViewModel.swift | 30 ++-- .../SanTa/ResultScene/SectionHeaderView.swift | 14 +- .../ResultScene/TotalRecordsViewCell.swift | 14 +- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 24 ++- SanTa/SanTa/SettingsScene/Option.swift | 2 +- SanTa/SanTa/SettingsScene/PaddingLabel.swift | 6 +- SanTa/SanTa/SettingsScene/Settings.swift | 4 +- .../SettingsScene/SettingsRepository.swift | 10 +- .../SanTa/SettingsScene/SettingsUsecase.swift | 13 +- .../SettingsViewController.swift | 58 ++++--- .../SettingsViewCoordinator.swift | 8 +- .../SettingsScene/SettingsViewModel.swift | 16 +- .../SettingsScene/ToggleOptionCell.swift | 31 ++-- .../SettingsSceneTests.swift | 22 +-- 92 files changed, 1230 insertions(+), 1290 deletions(-) diff --git a/SanTa/.swiftlint.yml b/SanTa/.swiftlint.yml index e69de29..8b13789 100644 --- a/SanTa/.swiftlint.yml +++ b/SanTa/.swiftlint.yml @@ -0,0 +1 @@ + diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index 972ca38..a8e7240 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -11,22 +11,22 @@ class RecordingUseCaseTests: XCTestCase { private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! - + enum testError: Error { case StoreError } - - class TestRecordingRepository : RecordRepository { + + class TestRecordingRepository: RecordRepository { func saveRecordPhotoOption(value: Bool) { return } - + func save(records: Records, completion: @escaping (Result) -> Void) { - + completion(.success(records)) } - + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { switch key { case .voiceGuidanceEveryOnekm: @@ -38,72 +38,72 @@ class RecordingUseCaseTests: XCTestCase { } } } - + override func setUpWithError() throws { repository = TestRecordingRepository() useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: nil, recordingPhoto: RecordingPhotoModel()) } - + func test_음성안내_옵션_True_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) self.repository.fetchRecordOption(key: Settings.voiceGuidanceEveryOnekm) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): XCTAssertTrue(status) } } } - + func test_음성안내_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): XCTAssertFalse(status) } } } - + func test_사진저장_옵션_True_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): XCTAssertTrue(status) } } } - + func test_사진저장_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): XCTAssertFalse(status) } } } - + func test_Records_저장_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) let records = Records(title: "테스트", records: [Record](), assetIdentifiers: [String](), secondPerHighestSpeed: Int(), secondPerMinimumSpeed: Int(), id: "") - + self.repository.save(records: records) { result in switch result { - case .failure(_): + case .failure: return case .success(let records): XCTAssertEqual(records.title, records.title) } - + } } } diff --git a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift index f8d6c46..07c758a 100644 --- a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift +++ b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift @@ -13,245 +13,245 @@ class RecordingViewModelTests: XCTestCase { private let recordingUseCase: RecordingUseCase? = nil private var subscriptions = Set() private var recordingViewModel = RecordingViewModel(recordingUseCase: nil) - + override func setUpWithError() throws { } - + func test_시간_받기_성공() { - + var result = "" self.recordingViewModel.$currentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { time in + .sink(receiveValue: { time in result = time }) .store(in: &self.subscriptions) - + let timeText = "0:00" recordingViewModel.currentTime = timeText _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.5) - + XCTAssertTrue(timeText == result) } - + func test_시간_받기_실패() { - + var result = "" self.recordingViewModel.$currentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { time in + .sink(receiveValue: { time in result = time }) .store(in: &self.subscriptions) - + let timeText = "0:00" recordingViewModel.currentTime = "0:01" _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(timeText == result) } - + func test_접근성_현재_시간_받기_성공() { - + var result = "" self.recordingViewModel.$accessibilityCurrentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { time in + .sink(receiveValue: { time in result = time }) .store(in: &self.subscriptions) - + let timeText = "0:00" recordingViewModel.accessibilityCurrentTime = timeText _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(timeText == result) } - + func test_접근성_현재_시간_받기_실패() { - + var result = "" self.recordingViewModel.$accessibilityCurrentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { time in + .sink(receiveValue: { time in result = time }) .store(in: &self.subscriptions) - + let timeText = "0:00" recordingViewModel.accessibilityCurrentTime = "0:01" _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(timeText == result) } - + func test_킬로미터_받기_성공() { - + var result = "" self.recordingViewModel.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveValue: { kilometer in + .sink(receiveValue: { kilometer in result = kilometer }) .store(in: &self.subscriptions) - + let kiloText = "5km" recordingViewModel.kilometer = kiloText _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(kiloText == result) } - + func test_킬로미터_받기_실패() { - + var result = "" self.recordingViewModel.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveValue: { kilometer in + .sink(receiveValue: { kilometer in result = kilometer }) .store(in: &self.subscriptions) - + let kiloText = "5km" recordingViewModel.kilometer = "4km" _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(kiloText == result) } - + func test_고도_받기_성공() { - + var result = "" self.recordingViewModel.$altitude .receive(on: DispatchQueue.main) - .sink (receiveValue: { altitude in + .sink(receiveValue: { altitude in result = altitude }) .store(in: &self.subscriptions) - + let altitudeText = "50" recordingViewModel.altitude = altitudeText _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(altitudeText == result) } - + func test_고도_받기_실패() { - + var result = "" self.recordingViewModel.$altitude .receive(on: DispatchQueue.main) - .sink (receiveValue: { altitude in + .sink(receiveValue: { altitude in result = altitude }) .store(in: &self.subscriptions) - + let altitudeText = "5km" recordingViewModel.altitude = "40" _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(altitudeText == result) } - + func test_걸음_받기_성공() { - + var result = "" self.recordingViewModel.$walk .receive(on: DispatchQueue.main) - .sink (receiveValue: { walk in + .sink(receiveValue: { walk in result = walk }) .store(in: &self.subscriptions) - + let walkText = "300" recordingViewModel.walk = walkText _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(walkText == result) } - + func test_걸음_받기_실패() { - + var result = "" self.recordingViewModel.$walk .receive(on: DispatchQueue.main) - .sink (receiveValue: { walk in + .sink(receiveValue: { walk in result = walk }) .store(in: &self.subscriptions) - + let walkText = "300" recordingViewModel.walk = "200" _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(walkText == result) } - + func test_GPS상태_받기_성공() { - + var result = true self.recordingViewModel.$gpsStatus .receive(on: DispatchQueue.main) - .sink (receiveValue: { gps in + .sink(receiveValue: { gps in result = gps }) .store(in: &self.subscriptions) - + let gpsStatus = false recordingViewModel.gpsStatus = gpsStatus _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(gpsStatus == result) } - + func test_GPS상태_받기_실패() { - + var result = false self.recordingViewModel.$gpsStatus .receive(on: DispatchQueue.main) - .sink (receiveValue: { gps in + .sink(receiveValue: { gps in result = gps }) .store(in: &self.subscriptions) - + let gpsStatus = false recordingViewModel.gpsStatus = true _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(gpsStatus == result) } - + func test_motion권한_받기_성공() { - + var result = true self.recordingViewModel.$motionAuth .receive(on: DispatchQueue.main) - .sink (receiveValue: { motion in + .sink(receiveValue: { motion in result = motion }) .store(in: &self.subscriptions) - + let motionStatus = false recordingViewModel.motionAuth = motionStatus _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertTrue(motionStatus == result) } - + func test_motion권한_받기_실패() { - + var result = false self.recordingViewModel.$motionAuth .receive(on: DispatchQueue.main) - .sink (receiveValue: { motion in + .sink(receiveValue: { motion in result = motion }) .store(in: &self.subscriptions) - + let motionStatus = false recordingViewModel.motionAuth = true _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.2 seconds")], timeout: 0.2) - + XCTAssertFalse(motionStatus == result) } } diff --git a/SanTa/ResultSceneTests/ResultSceneTests.swift b/SanTa/ResultSceneTests/ResultSceneTests.swift index b965ca3..9ad711f 100644 --- a/SanTa/ResultSceneTests/ResultSceneTests.swift +++ b/SanTa/ResultSceneTests/ResultSceneTests.swift @@ -8,7 +8,7 @@ import XCTest class ResultSceneTests: XCTestCase { - + class MockRepository: ResultRepository { func fetch(completion: @escaping (Result<[Records], Error>) -> Void) { let location1 = Location(latitude: 10, longitude: 20, altitude: 30) @@ -54,25 +54,25 @@ class ResultSceneTests: XCTestCase { completion(.success([records1, records2])) } } - + private var viewModel: ResultViewModel! private var useCase: ResultUseCase! - + override func setUpWithError() throws { useCase = ResultUseCase(resultRepository: MockRepository()) viewModel = ResultViewModel(useCase: useCase) } - + func test_ViewModel_viewWillAppear시_UseCase에_TotalRecords_세팅() throws { viewModel.viewWillAppear { } XCTAssertNotNil(useCase.totalRecords) } - + func test_ViewModel_itemsInSection호출시_section넘버에_따라_Records갯수_반환() { viewModel.viewWillAppear { } XCTAssertEqual(viewModel.itemsInSection(section: 0), 2) } - + func test_ViewModel_totalInfo호출시_총_Records를_View에_보여줄_문자열정보로_반환() { viewModel.viewWillAppear { } let infomation = viewModel.totalInfo() @@ -81,7 +81,7 @@ class ResultSceneTests: XCTestCase { XCTAssertEqual(infomation.time, "01:06") XCTAssertEqual(infomation.steps, "100") } - + func test_ViewModel_sectionInfo호출시_섹션넘버에_맞는_Records를_View에_보여줄_문자열정보로_반환() { viewModel.viewWillAppear { } let infomation = viewModel.sectionInfo(section: 0) @@ -91,7 +91,7 @@ class ResultSceneTests: XCTestCase { XCTAssertEqual(infomation.distance, "140.00km") XCTAssertEqual(infomation.time, "01:06") } - + func test_ViewModel_cellInfo호출시_IndexPath에_맞는_Records를_View에_보여줄_문자열정보로_반환() { viewModel.viewWillAppear { } let infomation = viewModel.cellInfo(indexPath: IndexPath(item: 0, section: 0)) @@ -102,11 +102,10 @@ class ResultSceneTests: XCTestCase { XCTAssertEqual(infomation.steps, "30") XCTAssertEqual(infomation.title, "기록1") } - + func test_ViewModel_selectedRecords호출시_IndexPath에_맞는_Records반환() { viewModel.viewWillAppear { } let record = viewModel.selectedRecords(indexPath: IndexPath(item: 0, section: 0)) XCTAssertEqual(record?.id, "1") } } - diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index c9b688b..842e2d1 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; + 540F8EBA2755B8860082FA3B /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 540F8EB92755B8860082FA3B /* .swiftlint.yml */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */; }; 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296944272FBC6E0070B362 /* AppCoordinator.swift */; }; @@ -156,6 +157,7 @@ 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewCoordinator.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; + 540F8EB92755B8860082FA3B /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewUseCase.swift; sourceTree = ""; }; 54296944272FBC6E0070B362 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; @@ -425,6 +427,7 @@ 54851275272A6AD500407F28 = { isa = PBXGroup; children = ( + 540F8EB92755B8860082FA3B /* .swiftlint.yml */, 54851280272A6AD500407F28 /* SanTa */, 9826F42E273953FB0064FA85 /* SettingsSceneTests */, DA854FDA2746273300E51E4B /* RecordingSceneTests */, @@ -552,6 +555,7 @@ 5485127A272A6AD500407F28 /* Sources */, 5485127B272A6AD500407F28 /* Frameworks */, 5485127C272A6AD500407F28 /* Resources */, + 540F8EB82755B8080082FA3B /* ShellScript */, ); buildRules = ( ); @@ -667,6 +671,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 540F8EBA2755B8860082FA3B /* .swiftlint.yml in Resources */, 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */, 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */, 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */, @@ -696,6 +701,26 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 540F8EB82755B8080082FA3B /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\n\nif which swiftlint >/dev/null; then\n swiftlint autocorrect\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 5485127A272A6AD500407F28 /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 5d1cbee..37a3636 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -9,7 +9,7 @@ import UIKit protocol Coordinator: AnyObject { var childCoordinators: [Coordinator] { get set } - + func start () } @@ -44,7 +44,7 @@ class AppCoordinator: NSObject, Coordinator { let secondItem = UITabBarItem(title: "기록", image: nil, tag: 1) let thirdItem = UITabBarItem(title: "목록", image: nil, tag: 2) let fourthItem = UITabBarItem(title: "설정", image: nil, tag: 3) - + let mapViewCoordinator = MapViewCoordinator(userDefaultsStorage: self.userDefaultsStorage, mountainExtractor: self.mountainExtractor, coreDataStorage: self.coreDataStorage) @@ -53,14 +53,14 @@ class AppCoordinator: NSObject, Coordinator { let mapViewController = mapViewCoordinator.startPush() mapViewController.tabBarItem = firstItem mapViewController.tabBarItem.image = .init(systemName: "play.fill") - + let resultViewCoordinator = ResultViewCoordinator(coreDataStorage: self.coreDataStorage) resultViewCoordinator.parentCoordinator = self childCoordinators.append(resultViewCoordinator) let resultViewController = resultViewCoordinator.startPush() resultViewController.tabBarItem = secondItem resultViewController.tabBarItem.image = .init(systemName: "list.dash") - + let mountainListViewCoordinator = MountainListViewCoordinator(userDefaultsStorage: self.userDefaultsStorage, mountainExtractor: self.mountainExtractor) mountainListViewCoordinator.parentCoordinator = self @@ -68,7 +68,7 @@ class AppCoordinator: NSObject, Coordinator { let mountainListViewController = mountainListViewCoordinator.startPush() mountainListViewController.tabBarItem = thirdItem mountainListViewController.tabBarItem.image = .init(systemName: "text.below.photo") - + let settingsViewCoordinator = SettingsViewCoordinator(userDefaultsStorage: self.userDefaultsStorage) settingsViewCoordinator.parentCoordinator = self childCoordinators.append(settingsViewCoordinator) diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index 3bd292c..6005b27 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -9,7 +9,6 @@ import UIKit import CoreData import AVFoundation - @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { @@ -26,7 +25,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { } - + func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.portrait } @@ -35,7 +34,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "SanTa") - container.loadPersistentStores(completionHandler: { (storeDescription, error) in + container.loadPersistentStores(completionHandler: { (_, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } @@ -58,4 +57,3 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 0e4098a..5918a27 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -34,4 +34,3 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { (UIApplication.shared.delegate as? AppDelegate)?.saveContext() } } - diff --git a/SanTa/SanTa/Entities/MountainEntity.swift b/SanTa/SanTa/Entities/MountainEntity.swift index 63b2ff5..3a81498 100644 --- a/SanTa/SanTa/Entities/MountainEntity.swift +++ b/SanTa/SanTa/Entities/MountainEntity.swift @@ -9,10 +9,10 @@ import Foundation struct MountainEntity: Codable, Hashable { var id = UUID() - + struct MountainDetail: Codable { let mountainName, mountainRegion, mountainHeight, mountainShortDescription: String - + enum CodingKeys: String, CodingKey { case mountainName = "MNTN_NM" case mountainRegion = "MNTN_LOCPLC_REGION_NM" @@ -20,17 +20,17 @@ struct MountainEntity: Codable, Hashable { case mountainShortDescription = "DETAIL_INFO_DTCONT" } } - + let mountain: MountainDetail let latitude: Double let longitude: Double - + enum CodingKeys: String, CodingKey { case mountain = "mountain" case latitude = "latitude" case longitude = "longitude" } - + func hash(into hasher: inout Hasher) { hasher.combine(id) } diff --git a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift index 3d036a3..deb9abe 100644 --- a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift +++ b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift @@ -13,23 +13,23 @@ class ClusterAnnotationView: MKAnnotationView { collisionMode = .circle centerOffset = CGPoint(x: 0, y: -10) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForDisplay() { super.prepareForDisplay() - + if let cluster = annotation as? MKClusterAnnotation { let count = cluster.memberAnnotations.count - + image = UIGraphicsImageRenderer(size: CGSize(width: 30, height: 30)).image { _ in UIColor.white.setFill() UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 30, height: 30)).fill() UIColor(named: "SantaColor")?.setFill() UIBezierPath(ovalIn: CGRect(x: 3, y: 3, width: 24, height: 24)).fill() - + let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 11)] let text = count > 99 ? "99+" : "\(count)" diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index a05ef1b..4b781b7 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -16,8 +16,8 @@ class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var viewModel: MapViewModel? private var observers: [AnyCancellable] = [] - private let mapDictionary: [Map:MKMapType] = [.infomation:.mutedStandard, .normal: .standard, .satellite: .hybrid] - + private let mapDictionary: [Map: MKMapType] = [.infomation: .mutedStandard, .normal: .standard, .satellite: .hybrid] + private lazy var mapView: MKMapView = { let mapView = MKMapView(frame: view.bounds) mapView.showsUserLocation = true @@ -27,7 +27,7 @@ class MapViewController: UIViewController { mapView.accessibilityElementsHidden = true return mapView }() - + private lazy var startButton: UIButton = { let button = UIButton() button.backgroundColor = UIColor(named: "SantaColor") @@ -44,7 +44,7 @@ class MapViewController: UIViewController { button.accessibilityHint = "측정을 시작하려면 이중 탭 하십시오" return button }() - + private lazy var newPlaceButton: UIButton = { let button = UIButton() button.isHidden = true @@ -61,7 +61,7 @@ class MapViewController: UIViewController { button.addTarget(self, action: #selector(presentMountainAddingViewController), for: .touchUpInside) return button }() - + private lazy var userTrackingButton: MKUserTrackingButton = { let button = MKUserTrackingButton(mapView: self.mapView) button.isHidden = true @@ -72,12 +72,12 @@ class MapViewController: UIViewController { button.clipsToBounds = true return button }() - + convenience init(viewModel: MapViewModel) { self.init() self.viewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() self.configureViews() @@ -85,17 +85,17 @@ class MapViewController: UIViewController { self.configureViewModel() self.configureNotification() } - + override func viewWillAppear(_ animated: Bool) { self.viewModel?.viewWillAppear() } - + private func configureViews() { self.view.addSubview(self.mapView) self.view.addSubview(self.startButton) self.view.addSubview(self.newPlaceButton) self.view.addSubview(self.userTrackingButton) - + NSLayoutConstraint.activate([ self.startButton.widthAnchor.constraint(equalToConstant: 100), self.startButton.heightAnchor.constraint(equalToConstant: 100), @@ -115,7 +115,7 @@ class MapViewController: UIViewController { self.newPlaceButton.centerXAnchor.constraint(equalTo: self.startButton.centerXAnchor) ]) } - + private func registerAnnotationView() { self.mapView.register( MountainAnnotationView.self, @@ -126,7 +126,7 @@ class MapViewController: UIViewController { forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier ) } - + private func configureViewModel() { self.viewModel?.configureBindings() self.viewModel?.$mountains @@ -150,19 +150,19 @@ class MapViewController: UIViewController { }) .store(in: &self.observers) } - + private func configureNotification() { NotificationCenter.default.addObserver(self, selector: #selector(shouldUpdateMarkers), name: NSNotification.Name.init(rawValue: "save"), object: nil) } - + @objc func shouldUpdateMarkers() { self.viewModel?.updateMarker() } - + private func configureMarkers(_ mountains: [MountainEntity]?) { self.mapView.removeAnnotations(self.mapView.annotations) guard let mountains = mountains else { return } - let annotations = mountains.map{ mountainEntity in + let annotations = mountains.map { mountainEntity in return MountainAnnotation( title: mountainEntity.mountain.mountainName, subtitle: mountainEntity.mountain.mountainHeight + "m", @@ -174,13 +174,13 @@ class MapViewController: UIViewController { } self.mapView.addAnnotations(annotations) } - + private func configureMap(_ map: Map?) { guard let map = map, let mapType = mapDictionary[map] else { return } self.mapView.mapType = mapType } - + private func configureLocation(_ location: CLLocation?) { guard let location = location else { return } let coordinate = CLLocationCoordinate2D( @@ -194,12 +194,12 @@ class MapViewController: UIViewController { let region = MKCoordinateRegion(center: coordinate, span: span) mapView.setRegion(region, animated: true) } - + private func configureUserTrackingButton(_ permission: Bool?) { guard let permission = permission else { return } self.userTrackingButton.isHidden = !permission } - + private func authAlert() -> UIAlertController { let alert = UIAlertController(title: "위치정보 활성화", message: "지도에 현재 위치를 표시할 수 있도록 위치정보를 활성화해주세요", preferredStyle: .alert) let cancel = UIAlertAction(title: "아니요", style: .cancel) @@ -220,7 +220,7 @@ class MapViewController: UIViewController { self.present(authAlert(), animated: false) } } - + @objc private func presentMountainAddingViewController() { self.coordinator?.presentMountainAddingViewController() } @@ -232,7 +232,7 @@ extension MapViewController: Animatable { self.startButton.setImage(image, for: .normal) self.startButton.accessibilityHint = "현재 측정 중입니다. 측정화면으로 돌아가려면 이중 탭 하십시오" } - + func shouldStopAnimate() { self.startButton.setImage(nil, for: .normal) self.startButton.accessibilityHint = "측정을 시작하려면 이중 탭 하십시오" @@ -276,7 +276,7 @@ extension MapViewController: MKMapViewDelegate { ) } } - + func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { guard let annotation = view.annotation as? MountainAnnotation else { return } coordinator?.presentMountainDetailViewController(mountainAnnotation: annotation) diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index dad41d4..5ae4c34 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -12,11 +12,11 @@ class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController = UINavigationController() var childCoordinators: [Coordinator] = [] - + private let userDefaultsStorage: UserDefaultsStorage private let mountainExtractor: MountainExtractor private let coreDataStorage: CoreDataStorage - + init(userDefaultsStorage: UserDefaultsStorage, mountainExtractor: MountainExtractor, coreDataStorage: CoreDataStorage) { @@ -24,15 +24,15 @@ class MapViewCoordinator: Coordinator { self.mountainExtractor = mountainExtractor self.coreDataStorage = coreDataStorage } - + func start() { } - + func startPush() -> UINavigationController { let mapViewController = MapViewController(viewModel: injectDependencies()) mapViewController.coordinator = self self.navigationController.setViewControllers([mapViewController], animated: false) - + return navigationController } } @@ -50,15 +50,15 @@ extension MapViewCoordinator { } childCoordinators.first?.start() } - + func presentMountainDetailViewController(mountainAnnotation: MountainAnnotation) { let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainDetailViewCoordinator) - + mountainDetailViewCoordinator.start() } - + func presentMountainAddingViewController() { let mountainAddingViewCoordinator = MountainAddingViewCoordinator( navigationController: self.navigationController, @@ -66,20 +66,20 @@ extension MapViewCoordinator { ) mountainAddingViewCoordinator.parentCoordinator = self self.childCoordinators.append(mountainAddingViewCoordinator) - + mountainAddingViewCoordinator.start() } - - func recordingViewDidHide(){ + + func recordingViewDidHide() { guard let animatableViewController = navigationController.viewControllers.first as? Animatable else { return } animatableViewController.shouldAnimate() } - - func recordingViewDidDismiss(){ + + func recordingViewDidDismiss() { guard let animatableViewController = navigationController.viewControllers.first as? Animatable else { return } animatableViewController.shouldStopAnimate() } - + private func injectDependencies() -> MapViewModel { return MapViewModel( useCase: MapViewUseCase( diff --git a/SanTa/SanTa/MapScene/MapViewModel.swift b/SanTa/SanTa/MapScene/MapViewModel.swift index 6fbf3ec..c64ed8e 100644 --- a/SanTa/SanTa/MapScene/MapViewModel.swift +++ b/SanTa/SanTa/MapScene/MapViewModel.swift @@ -14,12 +14,12 @@ final class MapViewModel { @Published private(set) var map: Map? @Published private(set) var initialLocation: CLLocation? @Published private(set) var locationPermission: Bool? - + init(useCase: MapViewUseCase) { self.useCase = useCase self.mountains = [] } - + func configureBindings() { self.useCase.prepareMountainMarkers { [weak self] mountains in self?.mountains = mountains @@ -33,14 +33,14 @@ final class MapViewModel { self.useCase.preparePermission() self.useCase.prepareLocacationManager() } - + func viewWillAppear() { - self.useCase.prepareMap{ [weak self] map in + self.useCase.prepareMap { [weak self] map in guard let map = map else { return } self?.map = map } } - + func updateMarker() { self.useCase.prepareMountainMarkers { [weak self] mountains in self?.mountains = mountains diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index 954784d..47b98cd 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -16,19 +16,19 @@ class DefaultMapViewRespository { enum JSONDecodeError: Error { case decodingFailed } - + enum userDefaultsError: Error { case notExists } - + enum optionError: Error { case notExists } - + private let mountainExtractor: MountainExtractor private let settingsStorage: UserDefaultsStorage private let coreDataMountainStorage: CoreDataMountainStorage - + init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage, coreDataMountainStorage: CoreDataMountainStorage) { self.mountainExtractor = mountainExtractor self.settingsStorage = userDefaultsStorage @@ -57,7 +57,7 @@ extension DefaultMapViewRespository: MapViewRepository { group.leave() } } - + self.coreDataMountainStorage.fetch { result in switch result { case .failure(let error): @@ -65,7 +65,7 @@ extension DefaultMapViewRespository: MapViewRepository { return completion(.failure(error)) case .success(let mountainEntityMOs): var mountainEntities: [MountainEntity] = [] - mountainEntityMOs.forEach{ MO in + mountainEntityMOs.forEach { MO in let mountain = MountainEntity.MountainDetail( mountainName: MO.name ?? "", mountainRegion: MO.region ?? "", @@ -88,7 +88,7 @@ extension DefaultMapViewRespository: MapViewRepository { completion(.success(jsonMountains + coreMountains)) } } - + func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) { self.settingsStorage.string(key: key) { value in guard let value = value else { diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index 5045769..b845046 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -22,13 +22,13 @@ class MapViewUseCase: NSObject { return false } } - + init(repository: MapViewRepository) { self.repository = repository self.initialLocation = { _ in } self.locationPermissionDidChangeTo = { _ in } } - + func prepareMountainMarkers(completion: @escaping ([MountainEntity]?) -> Void) { self.repository.fetchMountains { result in switch result { @@ -40,7 +40,7 @@ class MapViewUseCase: NSObject { } } } - + func prepareMap(completion: @escaping (Map?) -> Void) { self.repository.fetchMapOption(key: Settings.mapFormat) { result in switch result { @@ -52,11 +52,11 @@ class MapViewUseCase: NSObject { } } } - + func preparePermission() { self.locationPermissionDidChangeTo(self.locationPermission) } - + func prepareLocacationManager() { self.manager.requestWhenInUseAuthorization() self.manager.requestAlwaysAuthorization() @@ -73,7 +73,7 @@ extension MapViewUseCase: CLLocationManagerDelegate { self.initialLocation(location) } } - + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { self.locationPermissionDidChangeTo(self.locationPermission) } diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index 5f57008..87fa569 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -14,11 +14,11 @@ class MountainAnnotation: NSObject, MKAnnotation { var longitude: Double var mountainDescription: String var region: String - + var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } - + init(title: String, subtitle: String, latitude: Double, longitude: Double, mountainDescription: String, region: String) { self.title = title self.subtitle = subtitle @@ -27,7 +27,7 @@ class MountainAnnotation: NSObject, MKAnnotation { self.mountainDescription = mountainDescription self.region = region } - + init(title: String, subtitle: String, latitude: Double, longitude: Double) { self.title = title self.subtitle = subtitle @@ -36,7 +36,7 @@ class MountainAnnotation: NSObject, MKAnnotation { self.mountainDescription = "" self.region = "" } - + init(latitude: Double, longitude: Double) { self.latitude = latitude self.longitude = longitude diff --git a/SanTa/SanTa/MapScene/MountainAnnotationView.swift b/SanTa/SanTa/MapScene/MountainAnnotationView.swift index bf04c8c..2038264 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotationView.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotationView.swift @@ -10,7 +10,7 @@ import MapKit class MountainAnnotationView: MKAnnotationView { static let ReuseID = "MountainAnnotation" - + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) self.clusteringIdentifier = "mountain" @@ -18,11 +18,11 @@ class MountainAnnotationView: MKAnnotationView { self.calloutOffset = CGPoint(x: 0, y: 5) self.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForDisplay() { super.prepareForDisplay() displayPriority = .defaultHigh diff --git a/SanTa/SanTa/MapScene/UIImage+Gif.swift b/SanTa/SanTa/MapScene/UIImage+Gif.swift index 8c95402..696feb6 100644 --- a/SanTa/SanTa/MapScene/UIImage+Gif.swift +++ b/SanTa/SanTa/MapScene/UIImage+Gif.swift @@ -16,12 +16,12 @@ extension UIImage { else { return nil } return UIImage.animatedImageWithSource(source, withTintColor: withTintColor) } - + private class func animatedImageWithSource(_ source: CGImageSource, withTintColor: UIColor?) -> UIImage? { let count: Int = CGImageSourceGetCount(source) - let images: [UIImage] = (0.., with event: UIEvent?) { super.touchesBegan(touches, with: event) self.endEditing(true) } - + func configure() { self.backgroundColor = .systemBackground self.translatesAutoresizingMaskIntoConstraints = false @@ -97,7 +97,7 @@ class MountainAddingView: UIScrollView { self.configureLayout() self.configureNotification() } - + private func configureNotification() { NotificationCenter.default.addObserver( self, @@ -112,7 +112,7 @@ class MountainAddingView: UIScrollView { object: nil ) } - + private func configureSubViews() { self.addSubview(titleLabel) self.addSubview(nameLabel) @@ -124,36 +124,36 @@ class MountainAddingView: UIScrollView { self.nameTextField.delegate = self self.descriptionTextView.delegate = self } - + private func configureLayout() { NSLayoutConstraint.activate([ self.titleLabel.topAnchor.constraint(equalTo: self.contentLayoutGuide.topAnchor, constant: 20), - self.titleLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.titleLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20) ]) - + NSLayoutConstraint.activate([ self.nameLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 20), - self.nameLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.nameLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20) ]) - + NSLayoutConstraint.activate([ self.nameTextField.topAnchor.constraint(equalTo: self.nameLabel.bottomAnchor, constant: 10), self.nameTextField.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), - self.nameTextField.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20), + self.nameTextField.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20) ]) - + NSLayoutConstraint.activate([ self.descriptionLabel.topAnchor.constraint(equalTo: self.nameTextField.bottomAnchor, constant: 20), - self.descriptionLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), + self.descriptionLabel.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20) ]) - + NSLayoutConstraint.activate([ self.descriptionTextView.topAnchor.constraint(equalTo: self.descriptionLabel.bottomAnchor, constant: 10), self.descriptionTextView.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), self.descriptionTextView.rightAnchor.constraint(equalTo: self.safeAreaLayoutGuide.rightAnchor, constant: -20), self.descriptionTextView.heightAnchor.constraint(equalToConstant: 100) ]) - + NSLayoutConstraint.activate([ self.registerButton.topAnchor.constraint(equalTo: self.descriptionTextView.bottomAnchor, constant: 20), self.registerButton.leftAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leftAnchor, constant: 20), @@ -161,7 +161,7 @@ class MountainAddingView: UIScrollView { self.registerButton.bottomAnchor.constraint(lessThanOrEqualTo: self.contentLayoutGuide.bottomAnchor, constant: -20) ]) } - + @objc private func registerTouched() { guard let title = self.nameTextField.text, let description = self.descriptionTextView.text, @@ -174,7 +174,7 @@ class MountainAddingView: UIScrollView { } self.newPlaceDelegate?.newPlaceShouldAdd(title: title, description: description) } - + @objc private func keyboardWillShow(_ notification: Notification) { guard let userInfo = notification.userInfo, let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect @@ -183,7 +183,7 @@ class MountainAddingView: UIScrollView { self.contentInset = contentInset self.scrollIndicatorInsets = contentInset } - + @objc private func keyboardWillHide(_ notification: Notification) { let contentInset = UIEdgeInsets.zero self.contentInset = contentInset @@ -197,26 +197,26 @@ extension MountainAddingView: UITextFieldDelegate, UITextViewDelegate { let newLength = text.count + string.count return newLength <= 10 } - + func textFieldShouldReturn(_ textField: UITextField) -> Bool { self.descriptionTextView.becomeFirstResponder() return true } - + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let string = textView.text else { return true } let newLength = string.count + text.count - let newLines = string.filter{$0 == "\n"}.count + text.filter{$0 == "\n"}.count + let newLines = string.filter {$0 == "\n"}.count + text.filter {$0 == "\n"}.count return newLength <= 100 && newLines + 1 <= 10 } - + func textViewDidBeginEditing(_ textView: UITextView) { if textView.textColor == UIColor.systemGray3 { textView.text = nil textView.textColor = .label } } - + func textViewDidEndEditing(_ textView: UITextView) { if textView.text.isEmpty { textView.text = "정상, 봉우리, 사찰, 공원 등(10줄, 100자 이내)" diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index d055445..cd11aae 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -12,7 +12,7 @@ class MountainAddingViewController: UIViewController { weak var coordinator: MountainAddingViewCoordinator? private var viewModel: MountainAddingViewModel? private var observers: [AnyCancellable] = [] - + private lazy var mapView: MKMapView = { let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 2/5)) mapView.delegate = self @@ -21,7 +21,7 @@ class MountainAddingViewController: UIViewController { mapView.accessibilityElementsHidden = true return mapView }() - + private lazy var backButton: UIButton = { let button = UIButton(frame: .zero) button.setImage(.init(systemName: "xmark"), for: .normal) @@ -33,13 +33,13 @@ class MountainAddingViewController: UIViewController { button.accessibilityHint = "장소등록을 종료하려면 이중 탭 하십시오" return button }() - + private lazy var mountainAddingView: MountainAddingView = { let view = MountainAddingView() view.configure() return view }() - + convenience init(viewModel: MountainAddingViewModel) { self.init() self.viewModel = viewModel @@ -51,7 +51,7 @@ class MountainAddingViewController: UIViewController { self.configureViews() self.configureViewModel() } - + private func configureViews() { self.view.addSubview(mapView) self.view.addSubview(backButton) @@ -69,7 +69,7 @@ class MountainAddingViewController: UIViewController { self.mountainAddingView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) } - + private func configureViewModel() { self.viewModel?.$coordinate .sink(receiveValue: { [weak self] coordinate in @@ -87,20 +87,20 @@ class MountainAddingViewController: UIViewController { .store(in: &observers) self.mapView.showsUserLocation = true } - + private func configureLocation(_ coordinate: CLLocationCoordinate2D?) { guard let coordinate = coordinate else { return } let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01) let region = MKCoordinateRegion(center: coordinate, span: span) self.mapView.setRegion(region, animated: false) } - + private func configureAnnotation(_ coordinate: CLLocationCoordinate2D?) { guard let coordinate = coordinate else { return } let mountainAnnotation = MountainAnnotation(latitude: coordinate.latitude, longitude: coordinate.longitude) self.mapView.addAnnotation(mountainAnnotation) } - + private func showResult(_ result: MountainAddingViewModel.AddMountainResult) { let alert = UIAlertController(title: "산 추가하기", message: result.rawValue, preferredStyle: .alert) let confirm = UIAlertAction(title: "확인", style: .default) { [weak self] _ in @@ -109,7 +109,7 @@ class MountainAddingViewController: UIViewController { alert.addAction(confirm) self.present(alert, animated: true) } - + @objc func dismissViewController() { self.coordinator?.dismiss() } @@ -123,7 +123,7 @@ extension MountainAddingViewController: MKMapViewDelegate { reuseIdentifier: MountainAnnotationView.ReuseID ) } - + func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) { self.viewModel?.updateUserLocation(coordinate: userLocation.coordinate, altitude: userLocation.location?.altitude) } @@ -136,7 +136,7 @@ extension MountainAddingViewController: NewPlaceAddable { alert.addAction(confirm) self.present(alert, animated: true) } - + func newPlaceShouldAdd(title: String, description: String) { self.viewModel?.addMountain(title: title, description: description) } diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift index eddc0fa..daa423b 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift @@ -12,12 +12,12 @@ class MountainAddingViewCoordinator: Coordinator { var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] var coreDataStorage: CoreDataStorage - + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage) { self.navigationController = navigationController self.coreDataStorage = coreDataStorage } - + func start() { let mountainAddingViewController = MountainAddingViewController(viewModel: injectDependencies()) mountainAddingViewController.coordinator = self @@ -38,7 +38,7 @@ extension MountainAddingViewCoordinator { ) ) } - + func dismiss() { self.navigationController.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index a61d8a5..5f58b5a 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -14,21 +14,21 @@ class MountainAddingViewModel { @Published private(set) var coordinate: CLLocationCoordinate2D? private(set) var altitude: CLLocationDistance? let addMountainResult = PassthroughSubject() - + enum AddMountainResult: String { case success = "저장에 성공하였습니다." case failure = "저장에 실패하였습니다." } - + init(useCase: MountainAddingViewUseCase) { self.useCase = useCase } - + func updateUserLocation(coordinate: CLLocationCoordinate2D?, altitude: CLLocationDistance?) { self.coordinate = coordinate self.altitude = altitude } - + func addMountain(title: String, description: String) { guard let coordinate = coordinate, let altitude = altitude diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift index bcbcc92..3ea6b4d 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift @@ -13,15 +13,15 @@ protocol MountainAddingRepository { class DefaultMountainAddingRepository: MountainAddingRepository { private let coreDataMountainStorage: CoreDataMountainStorage - + init(coreDataMountainStorage: CoreDataMountainStorage) { self.coreDataMountainStorage = coreDataMountainStorage } - + func save(_ mountainEntity: MountainEntity, completion: @escaping(Result) -> Void) { coreDataMountainStorage.save(mountainEntity: mountainEntity) { result in switch result { - case .success(): + case .success: completion(.success(Void())) case .failure(let error): completion(.failure(error)) diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift index c120573..c490a31 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -11,11 +11,11 @@ import OSLog class MountainAddingViewUseCase { private let repository: MountainAddingRepository - + init(repository: MountainAddingRepository) { self.repository = repository } - + func saveMountain(name: String, altitude: Double, latitude: Double, longitude: Double, description: String, completion: @escaping (Void?) -> Void) { self.userRegion(latitude: latitude, longitude: longitude) { [weak self] region in let mountainDetail = MountainEntity.MountainDetail( @@ -27,7 +27,7 @@ class MountainAddingViewUseCase { let mountainEntity = MountainEntity(mountain: mountainDetail, latitude: latitude, longitude: longitude) self?.repository.save(mountainEntity) { result in switch result { - case .success(): + case .success: completion(Void()) case .failure(let error): completion(nil) @@ -36,15 +36,15 @@ class MountainAddingViewUseCase { } } } - + private func userRegion(latitude: Double, longitude: Double, completion: @escaping (String) -> Void) { let location = CLLocation(latitude: latitude, longitude: longitude) CLGeocoder().reverseGeocodeLocation(location) { placeMark, error in - guard error == nil else{ + guard error == nil else { completion("") return } - let region = [placeMark?.first?.administrativeArea, placeMark?.first?.locality, placeMark?.first?.subLocality].compactMap{ $0 }.joined(separator: " ") + let region = [placeMark?.first?.administrativeArea, placeMark?.first?.locality, placeMark?.first?.subLocality].compactMap { $0 }.joined(separator: " ") completion(region) } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift index aa861ce..3505bc1 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift @@ -8,21 +8,20 @@ import UIKit import MapKit - class MountainnDetailAnnotationView: MKAnnotationView { static let ReuseID = "MountainDetailAnnotationView" let imageSideLength: CGFloat = 30 - + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) self.canShowCallout = true self.calloutOffset = CGPoint(x: imageSideLength / 2, y: -imageSideLength / 4) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForDisplay() { super.prepareForDisplay() displayPriority = .defaultHigh diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index fc069af..e49879b 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -9,55 +9,53 @@ import UIKit class MountainDetailTableViewCell: UITableViewCell { static let identifier = "MountainDetailTableViewCellID" - + let categoryLabel = PaddingLabel(insets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) let contentLabel = UILabel() - + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none self.setLayout() } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + private func setLayout() { - categoryLabel.backgroundColor = .init(named: "SantaColor") - categoryLabel.textColor = .white - categoryLabel.clipsToBounds = true - categoryLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold) - categoryLabel.layer.cornerRadius = 5 - - contentLabel.numberOfLines = 0 - contentLabel.lineBreakMode = .byCharWrapping - contentLabel.font = UIFont.systemFont(ofSize: 15, weight: .regular) - - categoryLabel.translatesAutoresizingMaskIntoConstraints = false - contentLabel.translatesAutoresizingMaskIntoConstraints = false - - self.addSubview(categoryLabel) - self.addSubview(contentLabel) - - let categoryLabelConstraints = [ - categoryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), - categoryLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20) - ] - NSLayoutConstraint.activate(categoryLabelConstraints) - - let contentLabelConstraints = [ - contentLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), - contentLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10), - contentLabel.topAnchor.constraint(equalTo: categoryLabel.bottomAnchor, constant: 10), - contentLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) - ] - NSLayoutConstraint.activate(contentLabelConstraints) + self.categoryLabel.backgroundColor = .init(named: "SantaColor") + self.categoryLabel.textColor = .white + self.categoryLabel.clipsToBounds = true + self.categoryLabel.font = UIFont.systemFont(ofSize: 15, weight: .bold) + self.categoryLabel.layer.cornerRadius = 5 + + self.contentLabel.numberOfLines = 0 + self.contentLabel.lineBreakMode = .byCharWrapping + self.contentLabel.font = UIFont.systemFont(ofSize: 15, weight: .regular) + + self.categoryLabel.translatesAutoresizingMaskIntoConstraints = false + self.contentLabel.translatesAutoresizingMaskIntoConstraints = false + + self.addSubview(self.categoryLabel) + self.addSubview(self.contentLabel) + + NSLayoutConstraint.activate([ + self.categoryLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), + self.categoryLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20) + ]) + + NSLayoutConstraint.activate([ + self.contentLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25), + self.contentLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10), + self.contentLabel.topAnchor.constraint(equalTo: self.categoryLabel.bottomAnchor, constant: 10), + self.contentLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) + ]) } - + func configure(category: String, content: String) { - categoryLabel.isHidden = content.isEmpty - categoryLabel.text = category - contentLabel.text = content + self.categoryLabel.isHidden = content.isEmpty + self.categoryLabel.text = category + self.contentLabel.text = content } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift index 68cafa7..b67f843 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift @@ -10,14 +10,13 @@ import UIKit class MountainDetailTitleView: UIView { private let titleLabel = UILabel() private let distanceLabel = UILabel() - - + override func draw(_ rect: CGRect) { super.draw(rect) self.layoutTitleView() self.addShadow() } - + private func addShadow() { self.layer.shadowOpacity = 0.5 self.layer.shadowRadius = 1 @@ -33,27 +32,25 @@ class MountainDetailTitleView: UIView { distanceLabel.textColor = .lightGray self.addSubview(titleLabel) self.addSubview(distanceLabel) - - let titleConstraints = [ + + NSLayoutConstraint.activate([ titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), titleLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25) - ] - NSLayoutConstraint.activate(titleConstraints) - - let distanceLabelConstraints = [ + ]) + + NSLayoutConstraint.activate([ distanceLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), distanceLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 25) - ] - NSLayoutConstraint.activate(distanceLabelConstraints) + ]) } - + func configure(with title: String, distance: Double?) { self.titleLabel.text = title guard let distance = distance else { self.distanceLabel.text = "현재 위치를 알 수 없어 산까지의 거리를 불러올 수 없습니다." return } - let distanceRepresentation = String(format:"%.2f", distance) + let distanceRepresentation = String(format: "%.2f", distance) self.distanceLabel.text = "현재 위치로부터 약 \(distanceRepresentation)km (직선거리)" } } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 01ff2cc..1a75ac3 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -11,28 +11,27 @@ import CoreLocation class MountainDetailUseCase { private let mountainAnnotation: MountainAnnotation private let manager = CLLocationManager() - + init(mountainAnnotation: MountainAnnotation) { self.mountainAnnotation = mountainAnnotation } - - private func calculateDistance() -> Double? { + + private func calculateDistance() -> Double? { let mountainLocation = CLLocation(latitude: self.mountainAnnotation.latitude, longitude: self.mountainAnnotation.longitude) - guard let distance = manager.location?.distance(from: mountainLocation) else { + guard let distance = manager.location?.distance(from: mountainLocation) else { return nil } return distance / 1000 } - + private func mountainRegions() -> [String] { return mountainAnnotation.region.components(separatedBy: ", ") } - + func transferMountainInformation(completion: @escaping (MountainDetailModel) -> Void) { guard let name = mountainAnnotation.title, let altitude = mountainAnnotation.subtitle else { return } - + completion(MountainDetailModel(moutainName: name, distance: calculateDistance(), regions: mountainRegions(), altitude: altitude, latitude: mountainAnnotation.latitude, longitude: mountainAnnotation.longitude, mountainDescription: mountainAnnotation.mountainDescription)) } } - diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 007ef9e..8150094 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -13,7 +13,7 @@ class MountainDetailViewController: UIViewController { private var viewModel: MountainDetailViewModel? private var mutatingTopConstraint: NSLayoutConstraint? private let maxRollUpDistance: CGFloat = 50 - + private lazy var backButton: UIButton = { let button = UIButton(frame: .zero) button.setImage(.init(systemName: "xmark"), for: .normal) @@ -25,17 +25,17 @@ class MountainDetailViewController: UIViewController { button.accessibilityHint = "목록 화면으로 돌아가시려면 이중 탭 하십시오" return button }() - + convenience init(viewModel: MountainDetailViewModel) { self.init() self.viewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() self.configureViewModel() } - + private func configureViewModel() { self.viewModel?.mountainInfoReceived = { [weak self] mountainDetail in self?.layoutMountainDetailView(mountainDetail: mountainDetail) @@ -50,85 +50,77 @@ extension MountainDetailViewController { let mapSnapShot = upperMapView(mountainDetail: mountainDetail) let titleView = lowerMountainTitleView(mountainDetail: mountainDetail) let tableView = configuredTableView(mountainDetail: mountainDetail) - + headerView.translatesAutoresizingMaskIntoConstraints = false mapSnapShot.translatesAutoresizingMaskIntoConstraints = false titleView.translatesAutoresizingMaskIntoConstraints = false tableView.translatesAutoresizingMaskIntoConstraints = false - - + headerView.addSubview(mapSnapShot) headerView.addSubview(titleView) - view.addSubview(tableView) - view.addSubview(headerView) - - let headerConstraints = [ - headerView.topAnchor.constraint(equalTo: view.topAnchor), - headerView.leftAnchor.constraint(equalTo: view.leftAnchor), - headerView.rightAnchor.constraint(equalTo: view.rightAnchor), - headerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5) - ] - NSLayoutConstraint.activate(headerConstraints) - - let mapConstraints = [ + self.view.addSubview(tableView) + self.view.addSubview(headerView) + self.view.addSubview(self.backButton) + + NSLayoutConstraint.activate([ + headerView.topAnchor.constraint(equalTo: self.view.topAnchor), + headerView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + headerView.rightAnchor.constraint(equalTo: self.view.rightAnchor), + headerView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5) + ]) + + NSLayoutConstraint.activate([ mapSnapShot.topAnchor.constraint(equalTo: headerView.topAnchor), mapSnapShot.leftAnchor.constraint(equalTo: headerView.leftAnchor), mapSnapShot.rightAnchor.constraint(equalTo: headerView.rightAnchor), mapSnapShot.heightAnchor.constraint(equalTo: headerView.heightAnchor, multiplier: 0.85) - - ] - NSLayoutConstraint.activate(mapConstraints) - + ]) + self.mutatingTopConstraint = titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor) - var titleViewConstraints = [ + NSLayoutConstraint.activate([ titleView.leftAnchor.constraint(equalTo: headerView.leftAnchor), titleView.rightAnchor.constraint(equalTo: headerView.rightAnchor), titleView.heightAnchor.constraint(equalToConstant: self.view.bounds.height * 0.07) - ] - + ]) + if let upperConstraint = self.mutatingTopConstraint { - titleViewConstraints.append(upperConstraint) + NSLayoutConstraint.activate([ + upperConstraint + ]) } - - NSLayoutConstraint.activate(titleViewConstraints) - - let tableViewConstraints = [ + + NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: titleView.bottomAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - tableView.leftAnchor.constraint(equalTo: view.leftAnchor), - tableView.rightAnchor.constraint(equalTo: view.rightAnchor) - ] - NSLayoutConstraint.activate(tableViewConstraints) - - backButton.tintColorDidChange() - self.view.addSubview(backButton) - - let backButtonConstraints = [ + tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), + tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor) + ]) + + NSLayoutConstraint.activate([ backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), - backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10), - ] - NSLayoutConstraint.activate(backButtonConstraints) + backButton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 10) + ]) } - + @objc private func dismissViewController() { self.coordinator?.dismiss() } - + private func configuredTableView(mountainDetail: MountainDetailModel) -> UITableView { let tableView = UITableView() - + tableView.register(MountainDetailTableViewCell.self, forCellReuseIdentifier: MountainDetailTableViewCell.identifier) tableView.separatorStyle = .none tableView.delegate = self tableView.dataSource = self return tableView } - + private func upperMapView(mountainDetail: MountainDetailModel) -> MKMapView { let mapView = MKMapView() mapView.delegate = self mapView.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) - + mapView.mapType = .satellite mapView.isUserInteractionEnabled = false let annotation = MountainAnnotation(title: mountainDetail.moutainName, subtitle: mountainDetail.altitude, latitude: mountainDetail.latitude, longitude: mountainDetail.longitude) @@ -136,15 +128,15 @@ extension MountainDetailViewController { mapView.addAnnotation(annotation) mapView.selectAnnotation(annotation, animated: true) mapView.accessibilityElementsHidden = true - + return mapView } - + private func upperMapHeaderView(mountainDetail: MountainDetailModel) -> UIImageView { let mapOptions = MKMapSnapshotter.Options.init() mapOptions.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude), span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)) mapOptions.mapType = .satellite - + let imgView = UIImageView() let snapShotter = MKMapSnapshotter(options: mapOptions) snapShotter.start { snapShot, error in @@ -154,15 +146,15 @@ extension MountainDetailViewController { UIImage(named: "SantaImage")?.draw(in: CGRect(x: 0, y: 0, width: 20, height: 20)) let markerImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - + UIGraphicsBeginImageContext(mapImage.size) mapImage.draw(in: CGRect(origin: CGPoint.zero, size: mapImage.size)) markerImage?.draw(at: snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - + imgView.image = image - + print(snapShot.image.size, snapShot.point(for: CLLocationCoordinate2D(latitude: mountainDetail.latitude, longitude: mountainDetail.longitude))) } else if let error = error { print(error.localizedDescription) @@ -170,7 +162,7 @@ extension MountainDetailViewController { } return imgView } - + private func lowerMountainTitleView(mountainDetail: MountainDetailModel) -> UIView { let titleView = MountainDetailTitleView() titleView.configure(with: mountainDetail.moutainName, distance: mountainDetail.distance) @@ -184,7 +176,7 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour case region = 0 case altitude = 1 case description = 2 - + var text: String { switch self { case .region: @@ -196,13 +188,13 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour } } } - + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: MountainDetailTableViewCell.identifier, for: indexPath) as? MountainDetailTableViewCell, let category = MountainDetailCategories(rawValue: indexPath.row) else { return UITableViewCell() } - + var content: String? = "" switch category { case .region: @@ -212,11 +204,11 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour case .description: content = self.viewModel?.mountainDetail?.mountainDescription } - + cell.configure(category: category.text, content: content ?? "") return cell } - + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return MountainDetailCategories.allCases.count } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 2ff7428..7220a99 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -13,12 +13,12 @@ class MountainDetailViewCoordinator: Coordinator { var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController var mountainAnnotation: MountainAnnotation - + init(navigationController: UINavigationController, mountainAnnotation: MountainAnnotation) { self.navigationController = navigationController self.mountainAnnotation = mountainAnnotation } - + func start() { let mountainDetailViewController = MountainDetailViewController(viewModel: injectDependencies()) mountainDetailViewController.coordinator = self @@ -29,7 +29,7 @@ class MountainDetailViewCoordinator: Coordinator { self.navigationController.pushViewController(mountainDetailViewController, animated: true) } } - + func dismiss() { if self.parentCoordinator is MapViewCoordinator { self.navigationController.dismiss(animated: true) @@ -49,5 +49,5 @@ extension MountainDetailViewCoordinator { ) ) } - + } diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift index 0fd1f70..1aaaa85 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift @@ -10,12 +10,12 @@ import Foundation class MountainDetailViewModel { private let useCase: MountainDetailUseCase var mountainDetail: MountainDetailModel? - var mountainInfoReceived: (MountainDetailModel) -> Void = { info in } - + var mountainInfoReceived: (MountainDetailModel) -> Void = { _ in } + init(useCase: MountainDetailUseCase) { self.useCase = useCase } - + func setUpViewModel() { useCase.transferMountainInformation { [weak self] mountainInfo in self?.mountainDetail = mountainInfo diff --git a/SanTa/SanTa/MountainListScene/MountainCell.swift b/SanTa/SanTa/MountainListScene/MountainCell.swift index dcbdd30..dce03a7 100644 --- a/SanTa/SanTa/MountainListScene/MountainCell.swift +++ b/SanTa/SanTa/MountainListScene/MountainCell.swift @@ -8,9 +8,9 @@ import UIKit final class MountainCell: UICollectionViewCell { - + static let identifier = "MountainCell" - + private var name: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .headline) @@ -18,7 +18,7 @@ final class MountainCell: UICollectionViewCell { label.numberOfLines = 0 return label }() - + private var height: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .subheadline) @@ -27,7 +27,7 @@ final class MountainCell: UICollectionViewCell { label.textColor = .systemGray2 return label }() - + private var location: UILabel = { let label = UILabel() label.translatesAutoresizingMaskIntoConstraints = false @@ -52,30 +52,29 @@ final class MountainCell: UICollectionViewCell { configureView() } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + func configureView() { self.addSubview(self.stackView) - let stackViewConstrain = [ + self.addSubview(self.location) + + NSLayoutConstraint.activate([ self.stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 20), self.stackView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), - self.stackView.rightAnchor.constraint(lessThanOrEqualTo: self.rightAnchor, constant: -30), - ] - NSLayoutConstraint.activate(stackViewConstrain) - - self.addSubview(self.location) - let locationConstrain = [ + self.stackView.rightAnchor.constraint(lessThanOrEqualTo: self.rightAnchor, constant: -30) + ]) + + NSLayoutConstraint.activate([ self.location.topAnchor.constraint(equalTo: self.stackView.bottomAnchor, constant: 10), self.location.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 30), self.location.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -30), - self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20), - ] - NSLayoutConstraint.activate(locationConstrain) + self.location.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20) + ]) } - + func update(mountain: MountainEntity) { self.name.text = mountain.mountain.mountainName self.height.text = mountain.mountain.mountainHeight + " m" diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index 9e1d120..e8aacbd 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -13,17 +13,17 @@ class MountainListViewController: UIViewController { enum MountainListSection: Int, CaseIterable { case main } - + typealias MountainListDataSource = UICollectionViewDiffableDataSource typealias MountainListSnapshot = NSDiffableDataSourceSnapshot - + weak var coordinator: MountainListViewCoordinator? - + var dataSource: MountainListDataSource? - + private var viewModel: MountainListViewModel? private var subscriptions = Set() - + let mountainListCollectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -31,12 +31,12 @@ class MountainListViewController: UIViewController { return collectionView }() - + convenience init(viewModel: MountainListViewModel) { self.init() self.viewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() self.configureCollectionView() @@ -45,27 +45,27 @@ class MountainListViewController: UIViewController { self.configureBinding() self.viewModel?.viewDidLoad() } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.configureSearchBar() } - + override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.navigationItem.searchController = nil self.view.setNeedsLayout() } - + private func configureSearchBar() { let searchController = UISearchController(searchResultsController: nil) searchController.searchBar.placeholder = "검색" searchController.searchResultsUpdater = self - + self.navigationItem.searchController = searchController self.navigationItem.hidesSearchBarWhenScrolling = false } - + private func bindSnapShotApply(section: MountainListSection, item: [AnyHashable]) { DispatchQueue.main.async { [weak self] in var snapshot = MountainListSnapshot() @@ -76,16 +76,16 @@ class MountainListViewController: UIViewController { self?.dataSource?.apply(snapshot, animatingDifferences: true) } } - + private func configureBinding() { self.viewModel?.$mountains .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] mountains in + .sink(receiveValue: { [weak self] mountains in guard let mountains = mountains else { return } self?.bindSnapShotApply(section: MountainListSection.main, item: mountains) }) .store(in: &self.subscriptions) - + self.viewModel?.$mountainName .debounce(for: 0.7, scheduler: RunLoop.main) .sink { [weak self] _ in @@ -93,48 +93,47 @@ class MountainListViewController: UIViewController { } .store(in: &subscriptions) } - + private func configureCollectionView() { self.mountainListCollectionView.delegate = self self.mountainListCollectionView.collectionViewLayout = configureCompositionalLayout() self.mountainListCollectionView.register(MountainCell.self, forCellWithReuseIdentifier: MountainCell.identifier) } - + private func configureView() { self.view.addSubview(self.mountainListCollectionView) - let collectionViewConstrain = [ + NSLayoutConstraint.activate([ self.mountainListCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor), self.mountainListCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), self.mountainListCollectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.mountainListCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - ] - NSLayoutConstraint.activate(collectionViewConstrain) + self.mountainListCollectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor) + ]) } - + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + return UICollectionViewCompositionalLayout { (_, _) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) - let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)),subitems: [item]) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) - + return section } } - + private func configuareDataSource() { - let datasource = MountainListDataSource (collectionView: self.mountainListCollectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in - - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MountainCell.identifier, for: indexPath) as? MountainCell else { + let datasource = MountainListDataSource(collectionView: self.mountainListCollectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MountainCell.identifier, for: indexPath) as? MountainCell else { return UICollectionViewCell() } guard let item = item as? MountainEntity else { return cell } cell.update(mountain: item) cell.configureVoiceOverAccessibility() return cell }) - + self.dataSource = datasource self.mountainListCollectionView.dataSource = dataSource } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index e0d985f..3bab7b0 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -15,13 +15,13 @@ class MountainListViewCoordinator: Coordinator { private let userDefaultsStorage: UserDefaultsStorage private let mountainExtractor: MountainExtractor - + init(userDefaultsStorage: UserDefaultsStorage, mountainExtractor: MountainExtractor) { self.userDefaultsStorage = userDefaultsStorage self.mountainExtractor = mountainExtractor } - + func start() { } @@ -45,7 +45,7 @@ extension MountainListViewCoordinator { userDefaultsStorage: self.userDefaultsStorage))) } - + func pushMountainDetailViewController(mountainAnnotation: MountainAnnotation) { let mountainDetailViewCoordinator = MountainDetailViewCoordinator(navigationController: self.navigationController, mountainAnnotation: mountainAnnotation) mountainDetailViewCoordinator.parentCoordinator = self @@ -53,4 +53,3 @@ extension MountainListViewCoordinator { mountainDetailViewCoordinator.start() } } - diff --git a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift index 7a140ab..a301ed8 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewModel.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewModel.swift @@ -10,20 +10,20 @@ import Combine final class MountainListViewModel { @Published private(set) var mountains: [MountainEntity]? @Published var mountainName: String? - + private let useCase: MountainListUseCase private var cancellables = Set() - + init(useCase: MountainListUseCase) { self.useCase = useCase } - + func viewDidLoad() { self.useCase.prepareMountainList { [weak self] mountains in self?.mountains = mountains } } - + func findMountains() { guard let name = mountainName else { return } self.useCase.findMountains(name: name) { [weak self] mountains in diff --git a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift index 049fb54..bc3920e 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift @@ -15,14 +15,14 @@ class DefaultMountainListViewReposiory { enum JSONDecodeError: Error { case decodingFailed } - + enum userDefaultsError: Error { case notExists } - + private let mountainExtractor: MountainExtractor private let settingsStorage: UserDefaultsStorage - + init(mountainExtractor: MountainExtractor, userDefaultsStorage: UserDefaultsStorage) { self.mountainExtractor = mountainExtractor self.settingsStorage = userDefaultsStorage diff --git a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift index e2b83e7..c08d1da 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewUseCase.swift @@ -11,17 +11,17 @@ import OSLog final class MountainListUseCase { private let repository: MountainListViewRepository private var entireMountains: [MountainEntity]? - + init(repository: MountainListViewRepository) { self.repository = repository } - + func prepareMountainList(completion: @escaping ([MountainEntity]?) -> Void) { guard self.entireMountains == nil else { completion(self.entireMountains) return } - + self.repository.fetchMountains { [weak self] result in switch result { case .failure(let error): @@ -33,14 +33,14 @@ final class MountainListUseCase { } } } - + func findMountains(name: String, completion: @escaping ([MountainEntity]?) -> Void) { guard self.entireMountains != nil else { return } guard name.isEmpty != true else { completion(self.entireMountains) return } - + completion(self.entireMountains?.filter { $0.mountain.mountainName == name }) } } diff --git a/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift index ee44673..8448e86 100644 --- a/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataMountainStorage.swift @@ -18,13 +18,13 @@ final class CoreDataMountainStorage: MountainStorage { case saveError case fetchError } - + private let coreDataStroage: CoreDataStorage - + init(coreDataStorage: CoreDataStorage) { self.coreDataStroage = coreDataStorage } - + func save(mountainEntity: MountainEntity, completion: @escaping (Result) -> Void) { self.coreDataStroage.performBackgroundTask { context in let object = NSEntityDescription.insertNewObject(forEntityName: "MountainEntity", into: context) @@ -35,7 +35,7 @@ final class CoreDataMountainStorage: MountainStorage { object.setValue(mountainEntity.mountain.mountainRegion, forKey: "region") object.setValue(mountainEntity.mountain.mountainHeight, forKey: "altitude") object.setValue(mountainEntity.mountain.mountainShortDescription, forKey: "descript") - + do { try context.save() completion(.success(Void())) @@ -44,7 +44,7 @@ final class CoreDataMountainStorage: MountainStorage { } } } - + func fetch(completion: @escaping (Result<[MountainEntityMO], Error>) -> Void) { self.coreDataStroage.performBackgroundTask { context in do { diff --git a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift index 06d5bb8..c3e81aa 100644 --- a/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataRecordStorage.swift @@ -15,13 +15,13 @@ protocol RecordsStorage { } final class CoreDataRecordStorage: RecordsStorage { - + private let coreDataStorage: CoreDataStorage init(coreDataStorage: CoreDataStorage) { self.coreDataStorage = coreDataStorage } - + func save(records: Records, completion: @escaping (Result) -> Void) { self.coreDataStorage.performBackgroundTask { context in let recordsObject = NSEntityDescription.insertNewObject(forEntityName: "RecordsEntity", @@ -30,7 +30,7 @@ final class CoreDataRecordStorage: RecordsStorage { recordsObject?.id = records.id recordsObject?.secondPerHighestSpeed = Int16(records.secondPerHighestSpeed) recordsObject?.secondPerMinimumSpeed = Int16(records.secondPerMinimumSpeed) - + do { let assetIdentifiers = try NSKeyedArchiver.archivedData(withRootObject: records.assetIdentifiers, requiringSecureCoding: true) recordsObject?.assetIdentifiers = assetIdentifiers @@ -45,23 +45,22 @@ final class CoreDataRecordStorage: RecordsStorage { recordObject?.endTime = $0.endTime recordObject?.distance = $0.distance recordObject?.step = Int16($0.step) - + guard let recordObject = recordObject else { return } recordsObject?.addToRecords(recordObject) - - + $0.locations.locations.forEach { let locationObject = NSEntityDescription.insertNewObject(forEntityName: "LocationEntity", into: context) as? LocationEntityMO locationObject?.altitude = $0.altitude locationObject?.latitude = $0.latitude locationObject?.longitude = $0.longitude - + guard let locationObject = locationObject else { return } recordObject.addToLocations(locationObject) } } - + do { try context.save() completion(.success(records)) @@ -70,7 +69,7 @@ final class CoreDataRecordStorage: RecordsStorage { } } } - + func fetch(completion: @escaping (Result<[RecordsEntityMO], Error>) -> Void) { self.coreDataStorage.performBackgroundTask { context in do { @@ -82,24 +81,22 @@ final class CoreDataRecordStorage: RecordsStorage { } } } - + func delete(id: String, completion: @escaping (Result) -> Void) { let request = NSFetchRequest(entityName: "RecordsEntity") request.predicate = NSPredicate(format: "id = %@", id) self.coreDataStorage.performBackgroundTask { context in do { let result = try context.fetch(request) - print(result) context.delete(result[0]) try context.save() completion(.success(Void())) } catch { - print(error) completion(.failure(error)) } } } - + func update(title: String, id: String, completion: @escaping (Result) -> Void) { let request = NSFetchRequest(entityName: "RecordsEntity") request.predicate = NSPredicate(format: "id = %@", id) diff --git a/SanTa/SanTa/Persistences/CoreDataStorage.swift b/SanTa/SanTa/Persistences/CoreDataStorage.swift index 2f88d43..22ce93f 100644 --- a/SanTa/SanTa/Persistences/CoreDataStorage.swift +++ b/SanTa/SanTa/Persistences/CoreDataStorage.swift @@ -33,7 +33,7 @@ final class CoreDataStorage { } } } - + func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) { self.persistentContainer.performBackgroundTask(block) } diff --git a/SanTa/SanTa/Persistences/MountainExtractor.swift b/SanTa/SanTa/Persistences/MountainExtractor.swift index edd397e..6ce6ce9 100644 --- a/SanTa/SanTa/Persistences/MountainExtractor.swift +++ b/SanTa/SanTa/Persistences/MountainExtractor.swift @@ -9,16 +9,16 @@ import Foundation import UIKit class MountainExtractor { - + enum ExtractError: Error { case extractionFailed } - + func extract(completion: @escaping (Result) -> Void) { guard let dataAsset = NSDataAsset(name: "MountainsWithLocation") else { return completion(.failure(ExtractError.extractionFailed)) } - + completion(.success(dataAsset)) } } diff --git a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift index f904a84..e30e6a8 100644 --- a/SanTa/SanTa/Persistences/UserDefaultsStorage.swift +++ b/SanTa/SanTa/Persistences/UserDefaultsStorage.swift @@ -15,29 +15,29 @@ protocol UserDefaultsStorage { } final class DefaultUserDefaultsStorage: UserDefaultsStorage { - + let userDefaults: UserDefaults - + init(useuserDefaults: UserDefaults = UserDefaults.standard) { self.userDefaults = useuserDefaults } - + func save(value: T, key: Settings) { self.userDefaults.set(value, forKey: key.title) } - + func exist(key: Settings) -> Bool { return self.userDefaults.object(forKey: key.title) != nil } - + func bool(key: Settings, completion: @escaping (Bool) -> Void) { completion(self.userDefaults.bool(forKey: key.title)) } - + func string(key: Settings, completion: @escaping (String?) -> Void) { completion(self.userDefaults.string(forKey: key.title)) } - + func makeFirstData() { if !self.exist(key: .recordPhoto) { self.save(value: Settings.recordPhoto.initValue as? Bool, diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift index 3a78394..07a9af2 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift @@ -11,7 +11,7 @@ class RecordingPhotoViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var recordingPhotoViewController: RecordingPhotoViewController - + init(delegate: RecordingViewDelegate) { self.recordingPhotoViewController = RecordingPhotoViewController() self.recordingPhotoViewController.delegate = delegate @@ -20,18 +20,14 @@ class RecordingPhotoViewCoordinator: Coordinator { func start() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - + recordingCoordinator.recordingViewController.present(recordingPhotoViewController, animated: true) } - + func dismiss() { guard let recordingCoordinator = parentCoordinator as? RecordingViewCoordinator else { return } - + recordingCoordinator.recordingViewController.dismiss(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } - - deinit { - print("😇RecordingPhotoViewCoordinator is deinit \(Date())!!😇") - } } diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index b4a889b..a528397 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -10,7 +10,7 @@ import UIKit class RecordingPhotoViewController: UIViewController { weak var coordinator: RecordingPhotoViewCoordinator? weak var delegate: RecordingViewDelegate? - + private var displayView: UIView = { let view = UIView() view.backgroundColor = UIColor(named: "RecordingSubViewBackgroundColor") @@ -19,7 +19,7 @@ class RecordingPhotoViewController: UIViewController { view.translatesAutoresizingMaskIntoConstraints = false return view }() - + private let recordingPhotoImage: UIImageView = { let image = UIImageView() image.image = UIImage(systemName: "camera.fill") @@ -27,7 +27,7 @@ class RecordingPhotoViewController: UIViewController { image.translatesAutoresizingMaskIntoConstraints = false return image }() - + private let recordingPhotoTitle: UILabel = { let label = UILabel() label.text = "사진 기록하기" @@ -39,7 +39,7 @@ class RecordingPhotoViewController: UIViewController { label.accessibilityTraits = .header return label }() - + private let recordingPhotoDescription: UILabel = { let label = UILabel() label.text = "사진을 찍으면 지도에 표시됩니다." @@ -50,7 +50,7 @@ class RecordingPhotoViewController: UIViewController { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private let agreeButton: UIButton = { let button = UIButton() button.backgroundColor = .systemBlue @@ -62,7 +62,7 @@ class RecordingPhotoViewController: UIViewController { button.accessibilityHint = "사진 기록하기를 허용하려면 이중 탭 하십시오" return button }() - + private let photoStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 16 @@ -75,64 +75,57 @@ class RecordingPhotoViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - + self.configureConstraints() self.configureTarget() } - + private func configureConstraints() { let frameWidth = view.frame.width - + [self.recordingPhotoTitle, self.recordingPhotoImage, self.recordingPhotoDescription, self.agreeButton].forEach { self.photoStackView.addArrangedSubview($0) } - + self.view.addSubview(displayView) self.displayView.addSubview(photoStackView) - - let displayViweConstraints = [ + + NSLayoutConstraint.activate([ self.displayView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 6), self.displayView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -6), self.displayView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -64) - ] - - let recordingPhotoTitleConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.recordingPhotoTitle.widthAnchor.constraint(equalToConstant: frameWidth - 12) - ] + ]) - let recordingPhotoImageConstraints = [ + NSLayoutConstraint.activate([ self.recordingPhotoImage.widthAnchor.constraint(equalToConstant: frameWidth/3), self.recordingPhotoImage.heightAnchor.constraint(equalTo: self.recordingPhotoImage.widthAnchor, constant: -16) - ] + ]) - let recordingPhotoDescriptionText = [ + NSLayoutConstraint.activate([ self.recordingPhotoDescription.widthAnchor.constraint(equalToConstant: frameWidth - 12) - ] + ]) - let agreeButtonConstraints = [ + NSLayoutConstraint.activate([ self.agreeButton.widthAnchor.constraint(equalToConstant: frameWidth - 12), self.agreeButton.heightAnchor.constraint(equalToConstant: frameWidth/8) - ] - - let titleStackViewConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.photoStackView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 16), self.photoStackView.leadingAnchor.constraint(equalTo: self.displayView.leadingAnchor, constant: 16), self.photoStackView.trailingAnchor.constraint(equalTo: self.displayView.trailingAnchor, constant: -16), self.photoStackView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -16) - ] - - NSLayoutConstraint.activate(displayViweConstraints) - NSLayoutConstraint.activate(recordingPhotoTitleConstraints) - NSLayoutConstraint.activate(recordingPhotoImageConstraints) - NSLayoutConstraint.activate(recordingPhotoDescriptionText) - NSLayoutConstraint.activate(agreeButtonConstraints) - NSLayoutConstraint.activate(titleStackViewConstraints) + ]) } - + private func configureTarget() { self.agreeButton.addTarget(self, action: #selector(agreeButtonAction), for: .touchUpInside) } - + @objc private func agreeButtonAction(_ sender: UIButton) { self.delegate?.didAgreeButtonTouchDone() self.coordinator?.dismiss() diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 3cdcd1c..617413f 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -10,40 +10,40 @@ import CoreLocation class TotalRecords { private(set) var totalRecords: [DateSeperateRecords] = [] - - private var mappingDateSeperateRecords: [String : DateSeperateRecords] = [:] - + + private var mappingDateSeperateRecords: [String: DateSeperateRecords] = [:] + var totalDistances: Double { return totalRecords.reduce(0) { $0 + $1.distances } } - + var sectionCount: Int { return totalRecords.count } - + var totalCount: Int { return totalRecords.reduce(0) { $0 + $1.count } } - + var totalTimes: TimeInterval { return totalRecords.reduce(0) { $0 + $1.times } } - + var totalSteps: Int { return totalRecords.reduce(0) { $0 + $1.steps } } - + subscript(section: Int) -> DateSeperateRecords? { guard self.totalCount > section else { return nil } return totalRecords[section] } - + func add(records: Records) { guard let date = records.date else { return } let year = Calendar.current.component(.year, from: date) let month = Calendar.current.component(.month, from: date) let key = "\(year)\(month)" - + if let seperateDateRecords = self.mappingDateSeperateRecords[key] { seperateDateRecords.add(records: records) } else { @@ -58,41 +58,40 @@ class TotalRecords { class DateSeperateRecords { let year: Int let month: Int - + private(set) var dateSeperateRecords: [Records] = [] - + subscript(item: Int) -> Records? { guard self.count > item else { return nil } return dateSeperateRecords[item] } - + init(year: Int, month: Int) { self.year = year self.month = month } - + var distances: Double { return dateSeperateRecords.reduce(0) { $0 + $1.distances } } - + var count: Int { return dateSeperateRecords.count } - + var times: TimeInterval { return dateSeperateRecords.reduce(0) { $0 + $1.totalTravelTime } } - + var steps: Int { return dateSeperateRecords.reduce(0) { $0 + $1.steps } } - + func add(records: Records) { self.dateSeperateRecords.append(records) } } - struct Records { private(set) var title: String private(set) var records: [Record] @@ -100,39 +99,37 @@ struct Records { private(set) var secondPerHighestSpeed: Int private(set) var secondPerMinimumSpeed: Int private(set) var id: String - - - + var date: Date? { return records.last?.endTime } - + var distances: Double { return records.reduce(0) { $0 + $1.distance } } - + var totalTravelTime: TimeInterval { return records.reduce(0) { $0 + $1.travelTime } } - + var steps: Int { return records.reduce(0) { $0 + $1.step } } - + var maxAltitude: Double { guard let max = records.compactMap({ $0.maxAltitude }).max() else { return 0 } return max } - + var minAltitude: Double { guard let min = records.compactMap({ $0.minAltitude }).min() else { return 0 } return min } - + var maxAltitudeDifference: Double { guard let max = records.compactMap({ $0.maxAltitude }).max(), let min = records.compactMap({ $0.minAltitude }).min() @@ -141,15 +138,15 @@ struct Records { } return max - min } - + mutating func configureTitle(title: String) { self.title = title } - + mutating func configurePhoto(assetIdentifiers: [String]) { self.assetIdentifiers = assetIdentifiers } - + mutating func add(record: Record) { self.records.append(record) } @@ -161,19 +158,19 @@ struct Record { let step: Int let distance: Double let locations: Locations - + var travelTime: TimeInterval { return endTime.timeIntervalSince(startTime) } - + var minAltitude: Double? { return locations.minAltitude } - + var maxAltitude: Double? { return locations.maxAltitude } - + init(startTime: Date, endTime: Date, step: Int, distance: Double, locations: [Location]) { self.startTime = startTime self.endTime = endTime @@ -187,65 +184,65 @@ struct Location { let latitude: Double let longitude: Double let altitude: Double - + func distance(to: Location) -> Double { let current = CLLocation(latitude: self.latitude, longitude: self.longitude) let destination = CLLocation(latitude: to.latitude, longitude: to.longitude) - + return abs(current.distance(from: destination)) } } struct Locations { private(set) var locations: [Location] - + init(locations: [Location]) { self.locations = locations } - + var coordinates: [CLLocationCoordinate2D] { - return locations.map{CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)} + return locations.map {CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude)} } - + var maxAltitude: Double { guard let max = locations.map({$0.altitude}).max() else { return 0 } return max } - + var minAltitude: Double { guard let min = locations.map({$0.altitude}).min() else { return 0 } return min } - + var firstAltitude: Double { guard let first = locations.map({$0.altitude}).first else { return 0 } return first } - + var lastAltitude: Double { guard let last = locations.map({$0.altitude}).last else { return 0 } return last } - + var startLocation: Location? { return locations.first } - + var endLocation: Location? { return locations.last } - + func totalDistance() -> Double { var distance: Double = 0 - var prevLocation: Location? = nil + var prevLocation: Location? for location in locations { if let prevLocation = prevLocation { distance += location.distance(to: prevLocation) @@ -254,10 +251,10 @@ struct Locations { } return distance } - + func totalUphillDistance() -> Double { var uphillDistance: Double = 0 - var prevLocation: Location? = nil + var prevLocation: Location? for location in locations { if let prevLocation = prevLocation { let distance = location.distance(to: prevLocation) @@ -267,13 +264,13 @@ struct Locations { } prevLocation = location } - + return uphillDistance } - + func totalDownhillDistance() -> Double { var downhillDistance: Double = 0 - var prevLocation: Location? = nil + var prevLocation: Location? for location in locations { if let prevLocation = prevLocation { let distance = location.distance(to: prevLocation) @@ -283,13 +280,13 @@ struct Locations { } prevLocation = location } - + return downhillDistance } - + func totalPlainDistance() -> Double { var plainDistance: Double = 0 - var prevLocation: Location? = nil + var prevLocation: Location? for location in locations { if let prevLocation = prevLocation { let distance = location.distance(to: prevLocation) @@ -299,14 +296,14 @@ struct Locations { } prevLocation = location } - + return plainDistance } - + func totalIncline() -> [Double] { var incline: [Double] = [] - var prevLocation: Location? = nil - + var prevLocation: Location? + for location in locations { if let prevLocation = prevLocation { let distanceDelta = location.distance(to: prevLocation) @@ -317,14 +314,14 @@ struct Locations { } prevLocation = location } - + return incline } - + func steepestIncline() -> Double { var steepest: Double = 0 - var prevLocation: Location? = nil - + var prevLocation: Location? + for location in locations { if let prevLocation = prevLocation { let distanceDelta = location.distance(to: prevLocation) diff --git a/SanTa/SanTa/RecordingScene/RecordRepository.swift b/SanTa/SanTa/RecordingScene/RecordRepository.swift index 63374d5..0e04a9a 100644 --- a/SanTa/SanTa/RecordingScene/RecordRepository.swift +++ b/SanTa/SanTa/RecordingScene/RecordRepository.swift @@ -8,43 +8,43 @@ import Foundation final class DefaultRecordRepository: RecordRepository { - + enum userDefaultsError: Error { case notExists } - + enum optionError: Error { case notExists } - + private let settingsStorage: UserDefaultsStorage private let recordStorage: CoreDataRecordStorage - + init(settingsStorage: UserDefaultsStorage, recordStorage: CoreDataRecordStorage) { self.settingsStorage = settingsStorage self.recordStorage = recordStorage } - + func save(records: Records, completion: @escaping (Result) -> Void) { self.recordStorage.save(records: records, completion: completion) } - + func saveRecordPhotoOption(value: Bool) { self.settingsStorage.save(value: value, key: Settings.recordPhoto) } - + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { self.settingsStorage.string(key: key) { value in guard let value = value else { completion(.failure(userDefaultsError.notExists)) return } - + guard value == "1" else { completion(.success(false)) return } - + completion(.success(true)) } } diff --git a/SanTa/SanTa/RecordingScene/RecordingModel.swift b/SanTa/SanTa/RecordingScene/RecordingModel.swift index 4748b59..206139f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingModel.swift @@ -19,11 +19,11 @@ final class RecordingModel: NSObject, ObservableObject { @Published private(set) var walk = "0" @Published private(set) var gpsStatus = true @Published private(set) var motionAuth = true - + private let pedoMeter = CMPedometer() private let synthesizer = AVSpeechSynthesizer() private var locationManager = CLLocationManager() - + private var timer: DispatchSourceTimer? private var timerIsRunning = false private var records: Records? @@ -35,15 +35,15 @@ final class RecordingModel: NSObject, ObservableObject { private var minOneKiloTime = Int.max private var sliceDistance: Double = 1 private var location = [Location]() - + private var willSpeech = false - + private var currentTime = Date() { didSet { self.timeCalculation() } } - + override init() { super.init() self.startDate = Date() @@ -52,17 +52,17 @@ final class RecordingModel: NSObject, ObservableObject { self.configureLocationManager() self.checkMotionAuthorizationStatus() } - + private func configureTimer() { self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global()) self.timer?.schedule(deadline: .now(), repeating: 1) self.timer?.setEventHandler(handler: { [weak self] in self?.currentTime = Date() }) - + self.resume() } - + private func configureLocationManager() { self.locationManager.desiredAccuracy = kCLLocationAccuracyBest self.locationManager.activityType = .fitness @@ -72,13 +72,13 @@ final class RecordingModel: NSObject, ObservableObject { self.locationManager.showsBackgroundLocationIndicator = true self.locationManager.delegate = self } - + private func timeCalculation() { guard let startDate = self.startDate else { return } var elapsedTimeSeconds = 0 - + elapsedTimeSeconds = Int(self.currentTime.timeIntervalSince(startDate)) - + guard let records = records else { self.timeConverter(elapsedTimeSeconds: elapsedTimeSeconds) return @@ -87,53 +87,53 @@ final class RecordingModel: NSObject, ObservableObject { records.records.forEach { elapsedTimeSeconds += Int($0.endTime.timeIntervalSince($0.startTime)) } - + self.timeConverter(elapsedTimeSeconds: elapsedTimeSeconds) } - + private func timeConverter(elapsedTimeSeconds: Int) { let seconds = elapsedTimeSeconds % 60 let minutes = (elapsedTimeSeconds / 60) % 60 let hours = (elapsedTimeSeconds / 3600) - + self.time = String(format: "%0.2d:%0.2d %0.2d\"", hours, minutes, seconds) self.accessibilityTime = String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds) } - + private func checkPedoMeter() { guard let date = self.startDate else { return } var dates = [Record]() if let records = self.records { dates = records.records } - + dates.append(Record(startTime: date, endTime: self.currentTime, step: 0, distance: 0, locations: [Location]())) - + let dispatchGroup = DispatchGroup() - + self.currentWalk = 0 self.currentDistance = 0 - + dispatchGroup.enter() dates.forEach { dispatchGroup.enter() self.pedoMeter.queryPedometerData(from: $0.startTime, to: $0.endTime) { [weak self] data, error in guard let activityData = data, error == nil else { return } - + let walk = "\(activityData.numberOfSteps)" - + guard let walkNumber = Int(walk) else { return } - + self?.currentWalk += walkNumber - + guard let distance = activityData.distance else { return } let transformatKilometer = Double(truncating: distance) / 1000 self?.currentDistance += transformatKilometer dispatchGroup.leave() } } - + dispatchGroup.leave() dispatchGroup.notify(queue: .global()) { [weak self] in guard let walk = self?.currentWalk, @@ -141,11 +141,11 @@ final class RecordingModel: NSObject, ObservableObject { self?.calculateSpeed() self?.walk = "\(walk)" let distanceString = String(format: "%.2f", currentKile) - + self?.kilometer = "\(distanceString)" } } - + private func calculateSpeed() { if self.sliceDistance <= self.currentDistance { guard let oneKileDate = self.oneKiloDate else { @@ -153,15 +153,15 @@ final class RecordingModel: NSObject, ObservableObject { return } let elapsedTimeMinutes = Int(self.currentTime.timeIntervalSince(oneKileDate)) - + if willSpeech { self.willSpeechCurrentStatus() } - + if elapsedTimeMinutes > self.maxOneKiloTime { self.maxOneKiloTime = elapsedTimeMinutes self.oneKiloDate = self.currentTime self.sliceDistance += 1 } - + if elapsedTimeMinutes < self.minOneKiloTime { self.minOneKiloTime = elapsedTimeMinutes self.oneKiloDate = self.currentTime @@ -169,7 +169,7 @@ final class RecordingModel: NSObject, ObservableObject { } } } - + private func willSpeechCurrentStatus() { let speech = "현재 총 거리는 \(self.kilometer)킬로미터 소요 시간은 \(self.time)초 현재 고도는 \(self.altitude)입니다." let utterance = AVSpeechUtterance(string: speech) @@ -177,7 +177,7 @@ final class RecordingModel: NSObject, ObservableObject { utterance.rate = 0.4 self.synthesizer.speak(utterance) } - + private func appendRecord() { guard let startdate = self.startDate else { return } let record = Record(startTime: startdate, @@ -185,7 +185,7 @@ final class RecordingModel: NSObject, ObservableObject { step: self.currentWalk, distance: self.currentDistance, locations: self.location) - + guard self.records != nil else { var minTime = 0 if minOneKiloTime != Int.max { @@ -199,19 +199,19 @@ final class RecordingModel: NSObject, ObservableObject { id: UUID().uuidString) return } - + self.records?.add(record: record) } - + private func checkLocationAuthorizationStatus() { - switch self.locationManager.authorizationStatus{ + switch self.locationManager.authorizationStatus { case .authorizedWhenInUse, .authorizedAlways: self.gpsStatus = true default: self.gpsStatus = false } } - + private func checkMotionAuthorizationStatus() { switch CMPedometer.authorizationStatus() { case .authorized: @@ -224,46 +224,46 @@ final class RecordingModel: NSObject, ObservableObject { break } } - + func changedWillSpeechStatus(status: Bool) { self.willSpeech = status } - + func pause() { guard self.timerIsRunning == true else { return } - + self.timerIsRunning = false self.appendRecord() self.timer?.suspend() self.locationManager.stopUpdatingLocation() self.startDate = nil } - + func resume() { guard self.timerIsRunning == false else { return } - + self.checkLocationAuthorizationStatus() - + guard self.gpsStatus == true else { return } - + self.timerIsRunning = true self.timer?.resume() self.locationManager.startUpdatingLocation() self.startDate = Date() self.location = [Location]() } - + func cancel() -> Records? { guard let records = self.records else { return nil } - + if !self.timerIsRunning { self.timer?.resume() } - + self.timer?.cancel() self.timer = nil self.locationManager.stopUpdatingLocation() - + return records } } @@ -280,14 +280,14 @@ extension RecordingModel: CLLocationManagerDelegate { } } } - + func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { self.gpsStatus = false } - - private func filterBadLocation(_ location: CLLocation) -> Bool{ + + private func filterBadLocation(_ location: CLLocation) -> Bool { let age = -location.timestamp.timeIntervalSinceNow - + guard age < 8, location.horizontalAccuracy > 0 && location.horizontalAccuracy < 80, location.verticalAccuracy > 0 && location.verticalAccuracy < 50, @@ -295,7 +295,7 @@ extension RecordingModel: CLLocationManagerDelegate { location.coordinate.longitude != self.location.last?.longitude else { return false } - + return true } } diff --git a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift index c1d5037..2175f2e 100644 --- a/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingPhotoModel.swift @@ -9,26 +9,26 @@ import Foundation import Photos final class RecordingPhotoModel { - + private let imageManager = PHImageManager() private var willRecordPhoto = false - + func fetchPhotos(startDate: Date, endDate: Date) -> [String]? { guard self.willRecordPhoto == true else { return nil } - + let allMedia = PHAsset.fetchAssets(with: .image, options: nil) var assetIdentifiers = [String]() - + for i in stride(from: allMedia.count - 1, through: 0, by: -1) { let asset = allMedia[i] if asset.creationDate == nil || asset.location == nil { continue } - + guard let creationDate = asset.creationDate else { return nil } - + switch startDate.compare(creationDate) { case .orderedDescending, .orderedSame: switch endDate.compare(creationDate) { @@ -41,10 +41,10 @@ final class RecordingPhotoModel { break } } - + return assetIdentifiers } - + func changedWillRecordPhotoStatus(status: Bool) { self.willRecordPhoto = status } diff --git a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift index f0dafae..4fc25af 100644 --- a/SanTa/SanTa/RecordingScene/RecordingUseCase.swift +++ b/SanTa/SanTa/RecordingScene/RecordingUseCase.swift @@ -21,69 +21,69 @@ enum RecordingViewModelError: Error { final class DefaultRecordingUseCase: RecordingUseCase, ObservableObject { var recording: RecordingModel? var recordingPhoto: RecordingPhotoModel - + private let recordRepository: RecordRepository - + init(recordRepository: RecordRepository, recordingModel: RecordingModel?, recordingPhoto: RecordingPhotoModel) { self.recordRepository = recordRepository self.recording = recordingModel self.recordingPhoto = recordingPhoto } - + func pause() { self.recording?.pause() } - + func resume() { self.recording?.resume() } - + func save(title: String, completion: @escaping (Result) -> Void) { guard var records = recording?.cancel() else { - + completion(.failure(RecordingViewModelError.FetchError)) return } - + let asset = self.fetchPhotos(startDate: records.records.last?.endTime, endDate: records.records.first?.startTime) - + records.configureTitle(title: title) records.configurePhoto(assetIdentifiers: asset) - + self.recordRepository.save(records: records, completion: completion) } - + func saveRecordPhotoOption(value: Bool) { self.recording?.changedWillSpeechStatus(status: value) self.recordRepository.saveRecordPhotoOption(value: value) } - + func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] { guard let startDate = startDate, let endDate = endDate else { return [String]() } - + guard let assets = self.recordingPhoto.fetchPhotos(startDate: startDate, endDate: endDate) else { return [String]() } - + return assets } - + func fetchOptions() { self.recordRepository.fetchRecordOption(key: Settings.voiceGuidanceEveryOnekm) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): self.recording?.changedWillSpeechStatus(status: status) } } - + self.recordRepository.fetchRecordOption(key: Settings.recordPhoto) { result in switch result { - case .failure(_): + case .failure: return case .success(let status): self.recordingPhoto.changedWillRecordPhotoStatus(status: status) diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift index bedcdcf..d1be247 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController+Extension.swift @@ -15,19 +15,19 @@ extension RecordingViewController { $0.layer.masksToBounds = true $0.layer.cornerRadius = $0.frame.width/2 } - + var pauseConfiguration = UIButton.Configuration.plain() pauseConfiguration.image = UIImage(systemName: "pause.fill") pauseConfiguration.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0) - + self.pauseButton.backgroundColor = .black self.pauseButton.configuration = pauseConfiguration - + self.stopButton.backgroundColor = .black self.stopButton.setImage(UIImage(systemName: "stop.fill"), for: .normal) self.locationButton.setImage(UIImage(systemName: "location.fill"), for: .normal) } - + func configureLabel() { [self.kilometerLabel, self.kilometerTextLabel, self.timeLabel, self.timeLabel, self.altitudeLabel, self.walkLabel, self.timeTextLabel, self.altitudeTextLabel, self.walkTextLabel].forEach { $0.textAlignment = .center @@ -36,104 +36,93 @@ extension RecordingViewController { $0.adjustsFontSizeToFitWidth = true } } - + func configureStackView() { [self.calculateStackView, self.calculateTextStackView, self.buttonStackView].forEach { $0.translatesAutoresizingMaskIntoConstraints = false $0.axis = .horizontal } - + self.calculateStackView.spacing = 10 self.calculateStackView.distribution = .fillEqually - + self.calculateTextStackView.spacing = 10 self.calculateTextStackView.distribution = .fillEqually - + self.buttonStackView.spacing = 18 self.buttonStackView.distribution = .fill self.buttonStackView.alignment = .center } - - + func configureConstraints() { self.view.backgroundColor = UIColor(named: "SantaColor") - + [self.timeLabel, self.altitudeLabel, self.walkLabel].forEach { self.calculateStackView.addArrangedSubview($0) } - + [self.timeTextLabel, self.altitudeTextLabel, self.walkTextLabel].forEach { self.calculateTextStackView.addArrangedSubview($0) } - + [self.stopButton, self.pauseButton, self.locationButton].forEach { self.buttonStackView.addArrangedSubview($0) } - + self.view.addSubview(kilometerLabel) self.view.addSubview(kilometerTextLabel) self.view.addSubview(calculateStackView) self.view.addSubview(calculateTextStackView) self.view.addSubview(buttonStackView) - - let kilometerLabelConstraints = [ + + NSLayoutConstraint.activate([ self.kilometerLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 80), self.kilometerLabel.widthAnchor.constraint(equalToConstant: self.view.frame.width/2 + 30), self.kilometerLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) - ] - - let kilometerTextLabelConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.kilometerTextLabel.topAnchor.constraint(equalTo: self.kilometerLabel.bottomAnchor, constant: 16), self.kilometerTextLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) - ] + ]) - let calculateStackViewConstraints = [ + NSLayoutConstraint.activate([ self.calculateStackView.topAnchor.constraint(equalTo: self.kilometerTextLabel.bottomAnchor, constant: 64), self.calculateStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), self.calculateStackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8), self.calculateStackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8) - ] + ]) - let calculateTextStackViewConstraints = [ + NSLayoutConstraint.activate([ self.calculateTextStackView.topAnchor.constraint(equalTo: self.calculateStackView.bottomAnchor, constant: 8), self.calculateTextStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), self.calculateTextStackView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8), self.calculateTextStackView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8) - ] - - let pauseButtonSizeConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.pauseButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/4), self.pauseButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/4) - ] - - let stopButtonSizeConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.stopButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/6), self.stopButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/6) - ] - - let locationButtonSizeConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.locationButton.heightAnchor.constraint(equalToConstant: self.view.frame.width/6), self.locationButton.widthAnchor.constraint(equalToConstant: self.view.frame.width/6) - ] - - NSLayoutConstraint.activate(pauseButtonSizeConstraints) - NSLayoutConstraint.activate(stopButtonSizeConstraints) - NSLayoutConstraint.activate(locationButtonSizeConstraints) - - let buttonStackViewConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.buttonStackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), self.buttonStackView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -80) - ] - - NSLayoutConstraint.activate(kilometerLabelConstraints) - NSLayoutConstraint.activate(kilometerTextLabelConstraints) - NSLayoutConstraint.activate(calculateStackViewConstraints) - NSLayoutConstraint.activate(calculateTextStackViewConstraints) - NSLayoutConstraint.activate(buttonStackViewConstraints) - + ]) + self.view.layoutIfNeeded() } - + func configureAccessibilty() { self.pauseButton.accessibilityLabel = "일시 정지" self.pauseButton.accessibilityHint = "측정을 일시정지 하려면 이중 탭 하십시오" diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index e42b0d0..8a1cdea 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -19,7 +19,7 @@ protocol RecordingViewDelegate: SetTitleDelegate { class RecordingViewController: UIViewController { weak var coordinator: RecordingViewCoordinator? - + let kilometerLabel: UILabel = { let label = UILabel() label.font = .boldSystemFont(ofSize: 110) @@ -27,7 +27,7 @@ class RecordingViewController: UIViewController { label.text = "0.00" return label }() - + let kilometerTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) @@ -35,28 +35,28 @@ class RecordingViewController: UIViewController { label.isAccessibilityElement = false return label }() - + let timeLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) label.text = "00:00 00\"" return label }() - + let altitudeLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) label.text = "0" return label }() - + let walkLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title2) label.text = "0" return label }() - + let timeTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) @@ -64,7 +64,7 @@ class RecordingViewController: UIViewController { label.isAccessibilityElement = false return label }() - + let altitudeTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) @@ -72,7 +72,7 @@ class RecordingViewController: UIViewController { label.isAccessibilityElement = false return label }() - + let walkTextLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) @@ -80,27 +80,27 @@ class RecordingViewController: UIViewController { label.isAccessibilityElement = false return label }() - + let pauseButton = UIButton() let stopButton = UIButton() let locationButton = UIButton() - + let calculateStackView = UIStackView() let calculateTextStackView = UIStackView() let buttonStackView = UIStackView() - + private var recordingViewModel: RecordingViewModel? private var subscriptions = Set() private var isCoreLocationStatus = true - + convenience init(viewModel: RecordingViewModel) { self.init() self.recordingViewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() - + self.configureLabel() self.configureStackView() self.configureConstraints() @@ -109,56 +109,56 @@ class RecordingViewController: UIViewController { self.configureTarget() self.configureAccessibilty() } - + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - + self.configureAlbumPermission() self.recordingViewModel?.fetchOptions() } - + private func configureBindings() { self.recordingViewModel?.$currentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] time in + .sink(receiveValue: { [weak self] time in self?.timeLabel.text = time }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$accessibilityCurrentTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] time in + .sink(receiveValue: { [weak self] time in self?.timeLabel.accessibilityLabel = "현재 시간 \(time)" }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] kilometer in + .sink(receiveValue: { [weak self] kilometer in self?.kilometerLabel.text = kilometer self?.kilometerLabel.accessibilityLabel = "현재 \(kilometer)km" }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$altitude .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] altitude in + .sink(receiveValue: { [weak self] altitude in self?.altitudeLabel.text = altitude self?.altitudeLabel.accessibilityLabel = "현재 고도 \(altitude)" }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$walk .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] walk in + .sink(receiveValue: { [weak self] walk in self?.walkLabel.text = walk self?.walkLabel.accessibilityLabel = "현재 \(walk) 걸음" }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$gpsStatus .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] gpsStatus in + .sink(receiveValue: { [weak self] gpsStatus in if gpsStatus != self?.isCoreLocationStatus { if !gpsStatus { let title = "위치정보 활성화" @@ -172,32 +172,32 @@ class RecordingViewController: UIViewController { } }) .store(in: &self.subscriptions) - + self.recordingViewModel?.$motionAuth .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] motionAuth in + .sink(receiveValue: { [weak self] motionAuth in self?.requestMotionAuth(status: motionAuth) }) .store(in: &self.subscriptions) } - + private func configureTarget() { self.pauseButton.addTarget(self, action: #selector(pauseButtonAction), for: .touchUpInside) self.stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside) self.locationButton.addTarget(self, action: #selector(locationButtonAction), for: .touchUpInside) } - + private func configureAlbumPermission() { let status = PHPhotoLibrary.authorizationStatus(for: .readWrite) - - switch status{ + + switch status { case .notDetermined: self.coordinator?.presentRecordingPhotoViewController() default: break } } - + private func changeRecordingStatus() { if isCoreLocationStatus { self.view.backgroundColor = .black @@ -221,7 +221,7 @@ class RecordingViewController: UIViewController { self.isCoreLocationStatus = true } } - + private func authAlert(title: String, message: String) -> UIAlertController { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) let cancel = UIAlertAction(title: "아니요", style: .cancel) @@ -233,7 +233,7 @@ class RecordingViewController: UIViewController { alert.addAction(confirm) return alert } - + private func requestMotionAuth(status: Bool) { if !status { let title = "동작 및 피트니스 활성화" @@ -248,11 +248,11 @@ class RecordingViewController: UIViewController { @objc private func pauseButtonAction(_ sender: UIResponder) { changeRecordingStatus() } - + @objc private func stopButtonAction(_ sender: UIResponder) { let stopAlert = UIAlertController(title: "기록 종료", message: "기록을 종료합니다.", preferredStyle: UIAlertController.Style.alert) let noneAction = UIAlertAction(title: "아니요", style: .default) - let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (action) in + let terminationAction = UIAlertAction(title: "종료", style: .default) { [weak self] (_) in self?.view.backgroundColor = .black self?.recordingViewModel?.pause() self?.coordinator?.presentRecordingTitleViewController() @@ -261,30 +261,26 @@ class RecordingViewController: UIViewController { stopAlert.addAction(terminationAction) present(stopAlert, animated: true, completion: nil) } - + @objc private func locationButtonAction(_ sender: UIResponder) { self.coordinator?.hide() } - - deinit { - print("😇RecordingViewController is deinit \(Date())!!😇") - } } extension RecordingViewController: RecordingViewDelegate { func didTitleWriteDone(title: String) { self.recordingViewModel?.save(title: title) { [weak self] completion in switch completion { - case .success(_): + case .success: DispatchQueue.main.async { self?.coordinator?.dismiss() } - case .failure(_): + case .failure: let resultAlert = UIAlertController(title: "저장 실패", message: "데이터 저장에 실패했습니다.", preferredStyle: UIAlertController.Style.alert) - let restoreAction = UIAlertAction(title: "다시 저장하기", style: .default) { [weak self] (action) in + let restoreAction = UIAlertAction(title: "다시 저장하기", style: .default) { [weak self] (_) in self?.didTitleWriteDone(title: title) } - let endAction = UIAlertAction(title: "저장하지 않기", style: .destructive) { [weak self] (action) in + let endAction = UIAlertAction(title: "저장하지 않기", style: .destructive) { [weak self] (_) in DispatchQueue.main.async { self?.coordinator?.dismiss() } @@ -297,7 +293,7 @@ extension RecordingViewController: RecordingViewDelegate { } } } - + func didAgreeButtonTouchDone() { PHPhotoLibrary.requestAuthorization { status in switch status { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 067d138..3be99ab 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -5,7 +5,6 @@ // Created by shin jae ung on 2021/11/01. // - import UIKit class RecordingViewCoordinator: Coordinator { @@ -13,9 +12,9 @@ class RecordingViewCoordinator: Coordinator { var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] var recordingViewController: RecordingViewController - + private let coreDataStorage: CoreDataStorage - + init(navigationController: UINavigationController, userDefaultsStorage: UserDefaultsStorage, coreDataStorage: CoreDataStorage) { self.navigationController = navigationController self.coreDataStorage = coreDataStorage @@ -40,23 +39,19 @@ class RecordingViewCoordinator: Coordinator { self.recordingViewController.modalPresentationStyle = .fullScreen self.navigationController.present(recordingViewController, animated: true) } - + func hide() { self.navigationController.dismiss(animated: true) guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } mapViewCoordinator.recordingViewDidHide() } - + func dismiss() { self.navigationController.dismiss(animated: true) guard let mapViewCoordinator = parentCoordinator as? MapViewCoordinator else { return } mapViewCoordinator.recordingViewDidDismiss() self.parentCoordinator?.childCoordinators.removeLast() } - - deinit { - print("😇RecordingViewCoordinator is deinit \(Date())!!😇") - } } extension RecordingViewCoordinator { @@ -64,15 +59,15 @@ extension RecordingViewCoordinator { let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(delegate: self.recordingViewController) self.childCoordinators.append(recordingTitleViewCoordinator) recordingTitleViewCoordinator.parentCoordinator = self - + recordingTitleViewCoordinator.start() } - + func presentRecordingPhotoViewController() { let recordingPhotoViewCoordinator = RecordingPhotoViewCoordinator(delegate: self.recordingViewController) self.childCoordinators.append(recordingPhotoViewCoordinator) recordingPhotoViewCoordinator.parentCoordinator = self - + recordingPhotoViewCoordinator.start() } } diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 5c0adb7..0518b66 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -10,7 +10,7 @@ import Combine protocol RecordingUseCase { var recording: RecordingModel? { get set } - + func save(title: String, completion: @escaping (Result) -> Void) func fetchPhotos(startDate: Date?, endDate: Date?) -> [String] func pause() @@ -27,82 +27,82 @@ final class RecordingViewModel: ObservableObject { @Published var walk = "" @Published var gpsStatus = true @Published var motionAuth = true - + private let recordingUseCase: RecordingUseCase? private var subscriptions = Set() - + init(recordingUseCase: RecordingUseCase?) { self.recordingUseCase = recordingUseCase configureBindings() } - + private func configureBindings() { self.recordingUseCase?.recording?.$time .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] time in + .sink(receiveValue: { [weak self] time in self?.currentTime = time }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$accessibilityTime .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] time in + .sink(receiveValue: { [weak self] time in self?.accessibilityCurrentTime = time }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$kilometer .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] kilometer in + .sink(receiveValue: { [weak self] kilometer in self?.kilometer = kilometer }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$altitude .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] altitude in + .sink(receiveValue: { [weak self] altitude in self?.altitude = altitude }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$walk .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] walk in + .sink(receiveValue: { [weak self] walk in self?.walk = walk }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$gpsStatus .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] gpsStatus in + .sink(receiveValue: { [weak self] gpsStatus in self?.gpsStatus = gpsStatus }) .store(in: &self.subscriptions) - + self.recordingUseCase?.recording?.$motionAuth .receive(on: DispatchQueue.main) - .sink (receiveValue: { [weak self] motionAuth in + .sink(receiveValue: { [weak self] motionAuth in self?.motionAuth = motionAuth }) .store(in: &self.subscriptions) } - + func pause() { self.recordingUseCase?.pause() } - + func resume() { self.recordingUseCase?.resume() } - + func save(title: String, completion: @escaping (Result) -> Void) { self.recordingUseCase?.save(title: title, completion: completion) } - + func saveRecordPhotoOption(value: Bool) { self.recordingUseCase?.saveRecordPhotoOption(value: value) } - + func fetchOptions() { self.recordingUseCase?.fetchOptions() } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index 9c5a7a6..a4b76dd 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -10,7 +10,7 @@ import UIKit class RecordingTitleViewController: UIViewController { weak var coordinator: RecordingTitleViewCoordinator? weak var delegate: SetTitleDelegate? - + private var displayView: UIView = { let view = UIView() view.backgroundColor = UIColor(named: "RecordingSubViewBackgroundColor") @@ -18,7 +18,7 @@ class RecordingTitleViewController: UIViewController { view.layer.cornerRadius = 12 return view }() - + private let recordingTitle: UILabel = { let label = UILabel() label.text = "기록 제목" @@ -27,7 +27,7 @@ class RecordingTitleViewController: UIViewController { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private let recordingTitleDescription: UILabel = { let label = UILabel() label.text = "이 기록에 대한 제목을 입력해주세요." @@ -35,7 +35,7 @@ class RecordingTitleViewController: UIViewController { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private let recordingTitleText: UITextField = { let textField = UITextField() textField.font = .systemFont(ofSize: 22) @@ -46,7 +46,7 @@ class RecordingTitleViewController: UIViewController { textField.translatesAutoresizingMaskIntoConstraints = false return textField }() - + private let inputButton: UIButton = { let button = UIButton() button.backgroundColor = .systemBlue @@ -65,7 +65,7 @@ class RecordingTitleViewController: UIViewController { button.translatesAutoresizingMaskIntoConstraints = false return button }() - + private let titleStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 12 @@ -75,68 +75,64 @@ class RecordingTitleViewController: UIViewController { stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() - + private var keyHeight: CGFloat? - + override func viewDidLoad() { super.viewDidLoad() - + self.configureDelegate() self.configureNotification() self.configureConstraints() self.configureTarget() self.titleTextFieldUnderLine() } - + private func configureDelegate() { self.recordingTitleText.delegate = self } - + private func configureNotification() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) } - + private func configureConstraints() { let frameWidth = view.frame.width let frameHeight = view.frame.height self.displayView.frame = CGRect(x: 6, y: frameHeight - frameHeight/2, width: frameWidth - 12, height: frameHeight/3) - + [self.recordingTitle, self.recordingTitleDescription, self.recordingTitleText, self.inputButton, self.notInputButton].forEach { self.titleStackView.addArrangedSubview($0) } - + self.view.addSubview(displayView) self.displayView.addSubview(titleStackView) - - let inputButtonConstraints = [ + + NSLayoutConstraint.activate([ self.inputButton.widthAnchor.constraint(equalToConstant: frameWidth - 12) - ] - - let recordingTitleText = [ + ]) + + NSLayoutConstraint.activate([ self.recordingTitleText.widthAnchor.constraint(equalToConstant: frameWidth - 12) - ] - - let titleStackViewConstraints = [ + ]) + + NSLayoutConstraint.activate([ self.titleStackView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 16), self.titleStackView.leadingAnchor.constraint(equalTo: self.displayView.leadingAnchor, constant: 16), self.titleStackView.trailingAnchor.constraint(equalTo: self.displayView.trailingAnchor, constant: -16), self.titleStackView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -16) - ] - - NSLayoutConstraint.activate(recordingTitleText) - NSLayoutConstraint.activate(inputButtonConstraints) - NSLayoutConstraint.activate(titleStackViewConstraints) - + ]) + self.view.layoutIfNeeded() } - + private func configureTarget() { self.inputButton.addTarget(self, action: #selector(inputButtonAction), for: .touchUpInside) self.notInputButton.addTarget(self, action: #selector(notInputButtonButtonAction), for: .touchUpInside) } - + private func titleTextFieldUnderLine() { let border = CALayer() border.frame = CGRect(x: 1, y: self.recordingTitleText.frame.size.height - 1, width: self.recordingTitleText.frame.width - 1, height: 1) @@ -144,26 +140,22 @@ class RecordingTitleViewController: UIViewController { border.backgroundColor = UIColor.systemGray2.cgColor self.recordingTitleText.layer.addSublayer(border) } - + @objc private func inputButtonAction(sender: UIButton) { guard let title = self.recordingTitleText.text else { self.coordinator?.dismiss() self.delegate?.didTitleWriteDone(title: "") return } - + self.coordinator?.dismiss() self.delegate?.didTitleWriteDone(title: title) } - + @objc private func notInputButtonButtonAction(sender: UIButton) { self.coordinator?.dismiss() self.delegate?.didTitleWriteDone(title: "") } - - deinit { - print("😇RecordingTitleViewController is deinit \(Date())!!😇") - } } extension RecordingTitleViewController: UITextFieldDelegate { @@ -172,7 +164,7 @@ extension RecordingTitleViewController: UITextFieldDelegate { if text.count >= 20 && range.length == 0 && range.location >= 20 { return false } - + return true } } @@ -180,18 +172,18 @@ extension RecordingTitleViewController: UITextFieldDelegate { extension RecordingTitleViewController { @objc func keyboardWillShow(_ sender: Notification) { guard self.keyHeight == nil else { return } - let userInfo:NSDictionary = sender.userInfo! as NSDictionary - let keyboardFrame:NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue + let userInfo: NSDictionary = sender.userInfo! as NSDictionary + let keyboardFrame: NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue let keyboardRectangle = keyboardFrame.cgRectValue let keyboardHeight = keyboardRectangle.height keyHeight = keyboardHeight - + self.displayView.frame.origin.y -= keyboardHeight } - + @objc func keyboardWillHide(_ sender: Notification) { guard let keyHeight = keyHeight else { return } - + self.displayView.frame.origin.y += keyHeight self.keyHeight = nil } diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 103bbb2..2c2b7fe 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -11,7 +11,7 @@ class RecordingTitleViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController - + init(delegate: SetTitleDelegate) { self.recordingTitleViewController = RecordingTitleViewController() self.recordingTitleViewController.delegate = delegate @@ -22,14 +22,10 @@ class RecordingTitleViewCoordinator: Coordinator { guard let viewController = self.recordingTitleViewController.delegate as? UIViewController else { return } viewController.present(recordingTitleViewController, animated: true) } - + func dismiss() { guard let viewController = self.recordingTitleViewController.delegate as? UIViewController else { return } viewController.dismiss(animated: true, completion: nil) self.parentCoordinator?.childCoordinators.removeLast() } - - deinit { - print("😇RecordingTitleViewCoordinator is deinit \(Date())!!😇") - } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift index 41ef968..7d2a32f 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -9,23 +9,23 @@ import UIKit class DetailImagesCell: UICollectionViewCell { static let identifier = "DetailImagesCell" - + private let imageView = UIImageView() var id = String() - + override init(frame: CGRect) { super.init(frame: frame) self.configureView() } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + private func configureView() { self.imageView.translatesAutoresizingMaskIntoConstraints = false self.addSubview(imageView) - + NSLayoutConstraint.activate([ self.imageView.topAnchor.constraint(equalTo: self.topAnchor), self.imageView.leadingAnchor.constraint(equalTo: self.leadingAnchor), @@ -33,7 +33,7 @@ class DetailImagesCell: UICollectionViewCell { self.imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } - + func update(image: UIImage, id: String) { self.imageView.image = image self.id = id diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index 5c2ece8..7cd106e 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -9,19 +9,19 @@ import UIKit class ResultDetailImagesViewController: UIViewController { weak var coordinator: ResultDetailImagesViewCoordinator? - + enum DetailImagesSection: Int, CaseIterable { case main } - + typealias DetailImagesDataSource = UICollectionViewDiffableDataSource typealias DetailImagesSnapshot = NSDiffableDataSourceSnapshot - + private var dataSource: DetailImagesDataSource? - + var uiImages = [String: UIImage]() var identifiers = [String]() - + lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -29,7 +29,7 @@ class ResultDetailImagesViewController: UIViewController { return collectionView }() - + override func viewDidLoad() { super.viewDidLoad() self.configureCollectionView() @@ -37,24 +37,24 @@ class ResultDetailImagesViewController: UIViewController { self.configuareDataSource() self.configureImages() } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(false, animated: false) } - + override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.coordinator?.dismiss() self.navigationController?.setNavigationBarHidden(true, animated: false) } - + private func configureViews() { self.view.backgroundColor = .systemBackground self.navigationController?.navigationBar.tintColor = .label self.title = "사진 모아보기 (\(uiImages.count)장)" self.view.addSubview(self.collectionView) - + NSLayoutConstraint.activate([ self.collectionView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), @@ -62,13 +62,13 @@ class ResultDetailImagesViewController: UIViewController { self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) } - + private func configureCollectionView() { self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) } - + private func bindSnapShotApply(section: DetailImagesSection, item: [AnyHashable]) { var snapshot = DetailImagesSnapshot() snapshot.appendSections([.main]) @@ -77,9 +77,9 @@ class ResultDetailImagesViewController: UIViewController { } self.dataSource?.apply(snapshot, animatingDifferences: true) } - + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + return UICollectionViewCompositionalLayout { (_, _) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalWidth(1/3))) item.contentInsets = .init(top: 3, leading: 3, bottom: 3, trailing: 3) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1/3)), subitems: [item]) @@ -89,28 +89,28 @@ class ResultDetailImagesViewController: UIViewController { return section } } - + private func configuareDataSource() { let datasource = DetailImagesDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in - + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell, let item = item as? String, - let image = self.uiImages[item] else { + let image = self.uiImages[item] else { return UICollectionViewCell() } - + cell.update(image: image, id: item) return cell }) - + self.dataSource = datasource self.collectionView.dataSource = dataSource } - + private func configureImages() { for (key, _) in self.uiImages { self.identifiers.append(key) } - + self.bindSnapShotApply(section: .main, item: self.identifiers) } } diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift index 459e53e..e2ab3ca 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift @@ -11,20 +11,20 @@ class ResultDetailImagesViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController - + let uiImages: [String: UIImage] - + func start() { let resultDetailImagesViewController = ResultDetailImagesViewController() resultDetailImagesViewController.uiImages = self.uiImages resultDetailImagesViewController.coordinator = self self.navigationController.pushViewController(resultDetailImagesViewController, animated: true) } - + func dismiss() { self.parentCoordinator?.childCoordinators.removeLast() } - + init(navigationController: UINavigationController, uiImages: [String: UIImage]) { self.navigationController = navigationController self.uiImages = uiImages @@ -36,7 +36,7 @@ extension ResultDetailImagesViewCoordinator { let resultDetailThumbnailViewCoordinator = ResultDetailThumbnailViewCoordinator(navigationController: navigationController, uiImages: uiImages, id: id) self.childCoordinators.append(resultDetailThumbnailViewCoordinator) resultDetailThumbnailViewCoordinator.parentCoordinator = self - + resultDetailThumbnailViewCoordinator.start() } } diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index e179d7d..c32e2aa 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -9,7 +9,7 @@ import UIKit class DetailCell: UICollectionViewCell { static let identifier = "DetailCell" - + let title: UILabel = { let label = UILabel() label.font = .preferredFont(for: .body, weight: .bold) @@ -17,19 +17,19 @@ class DetailCell: UICollectionViewCell { label.adjustsFontSizeToFitWidth = true return label }() - + let line: UIView = { let view = UIView() view.backgroundColor = .init(named: "SantaColor") return view }() - + let stack: UIStackView = { let stack = UIStackView() stack.axis = .vertical return stack }() - + func layout(data: DetailInformationModel) { self.addSubview(self.title) self.title.text = data.title @@ -38,22 +38,22 @@ class DetailCell: UICollectionViewCell { self.title.topAnchor.constraint(equalTo: self.topAnchor, constant: 10), self.title.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10) ]) - + self.addSubview(self.line) self.line.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ self.line.heightAnchor.constraint(equalToConstant: 1), self.line.leftAnchor.constraint(equalTo: self.title.rightAnchor, constant: 5), self.line.centerYAnchor.constraint(equalTo: self.title.centerYAnchor), - self.line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15), + self.line.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -15) ]) - - self.stack.subviews.forEach{ $0.removeFromSuperview() } + + self.stack.subviews.forEach { $0.removeFromSuperview() } self.addSubview(self.stack) for content in data.contents { self.stack.addArrangedSubview(UIStackView(content: content)) } - + self.stack.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ self.stack.topAnchor.constraint(equalTo: self.title.bottomAnchor, constant: 30), @@ -78,7 +78,7 @@ extension UIStackView { self.init() self.axis = .horizontal self.distribution = .equalCentering - + let contentLabel = UILabel() contentLabel.text = content.content contentLabel.font = .preferredFont(for: .title1, weight: .bold) @@ -86,13 +86,12 @@ extension UIStackView { let contentTitleLabel = UILabel() contentTitleLabel.text = content.contentTitle contentTitleLabel.font = .preferredFont(forTextStyle: .body) - + self.addArrangedSubview(contentLabel) self.addArrangedSubview(contentTitleLabel) } } - // MARK: - Accessibility extension DetailCell { diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index ee68bad..f77374f 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -9,7 +9,7 @@ import UIKit class DetailHeader: UICollectionReusableView { static let identifier = "DetailHeader" - + private lazy var dateLabel: PaddingLabel = { let label = PaddingLabel(insets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) label.backgroundColor = .label @@ -21,7 +21,7 @@ class DetailHeader: UICollectionReusableView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private lazy var startLabel: UILabel = { let label = UILabel() label.textColor = UIColor(named: "SantaColor") @@ -33,7 +33,7 @@ class DetailHeader: UICollectionReusableView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private lazy var endLabel: UILabel = { let label = UILabel() label.textColor = UIColor(named: "SantaColor") @@ -45,7 +45,7 @@ class DetailHeader: UICollectionReusableView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private lazy var startTime: UILabel = { let label = UILabel() label.textColor = .label @@ -57,7 +57,7 @@ class DetailHeader: UICollectionReusableView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private lazy var endTime: UILabel = { let label = UILabel() label.textColor = .label @@ -69,7 +69,7 @@ class DetailHeader: UICollectionReusableView { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + private lazy var labelStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 20 @@ -78,7 +78,7 @@ class DetailHeader: UICollectionReusableView { stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() - + private lazy var timeStackView: UIStackView = { let stackView = UIStackView() stackView.spacing = 20 @@ -87,7 +87,7 @@ class DetailHeader: UICollectionReusableView { stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() - + override init(frame: CGRect) { super.init(frame: frame) } @@ -95,12 +95,12 @@ class DetailHeader: UICollectionReusableView { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } - + func configure(date: String, startTime: String, endTime: String) { self.configureStackView() self.configureViews(date: date, startTime: startTime, endTime: endTime) } - + private func configureViews(date: String, startTime: String, endTime: String) { self.dateLabel.text = date self.startTime.text = startTime @@ -108,27 +108,27 @@ class DetailHeader: UICollectionReusableView { self.addSubview(self.dateLabel) self.addSubview(self.labelStackView) self.addSubview(self.timeStackView) - + NSLayoutConstraint.activate([ self.dateLabel.topAnchor.constraint(equalTo: self.topAnchor), - self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.dateLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor) ]) - + NSLayoutConstraint.activate([ self.labelStackView.topAnchor.constraint(equalTo: self.dateLabel.bottomAnchor, constant: 20), self.labelStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor), self.labelStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.labelStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor) ]) - + NSLayoutConstraint.activate([ self.timeStackView.topAnchor.constraint(equalTo: self.labelStackView.bottomAnchor, constant: 8), self.timeStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor), self.timeStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor), - self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor), + self.timeStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor) ]) } - + private func configureStackView() { [self.startLabel, self.endLabel].forEach { self.labelStackView.addArrangedSubview($0) } [self.startTime, self.endTime].forEach { self.timeStackView.addArrangedSubview($0) } diff --git a/SanTa/SanTa/ResultDetailScene/PinView.swift b/SanTa/SanTa/ResultDetailScene/PinView.swift index b04ed0f..48971f5 100644 --- a/SanTa/SanTa/ResultDetailScene/PinView.swift +++ b/SanTa/SanTa/ResultDetailScene/PinView.swift @@ -9,17 +9,17 @@ import MapKit class PinView: MKAnnotationView { static let ReuseID = "PinView" - + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) self.centerOffset = CGPoint(x: 0, y: -20) self.canShowCallout = true } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForDisplay() { super.prepareForDisplay() displayPriority = .defaultHigh diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 154011d..1f7292c 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -11,17 +11,17 @@ class ResultDetailLargerInfoView: UIView { enum DetailLargerInfoSection: Int, CaseIterable { case main } - + typealias DetailLargerInfoDataSource = UICollectionViewDiffableDataSource typealias DetailLargerInfoSnapshot = NSDiffableDataSourceSnapshot - + private var dataSource: DetailLargerInfoDataSource? private var currentSnapshot: DetailLargerInfoSnapshot? - + private var date: String = "" private var startTime: String = "" private var endTime: String = "" - + lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -29,11 +29,11 @@ class ResultDetailLargerInfoView: UIView { return collectionView }() - + override init(frame: CGRect) { super.init(frame: frame) } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -46,30 +46,29 @@ extension ResultDetailLargerInfoView { upDownView.translatesAutoresizingMaskIntoConstraints = false upDownView.layer.cornerRadius = 2 upDownView.layer.masksToBounds = true - + self.addSubview(upDownView) - let upDownConstraints = [ + NSLayoutConstraint.activate([ upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), upDownView.heightAnchor.constraint(equalToConstant: 4), upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/3) - ] - NSLayoutConstraint.activate(upDownConstraints) + ]) } - + func configure() { self.configureCollectionView() self.configureViews() self.configuareDataSource() self.displayUpDownMark() } - + func configureHeaderInformation(date: String, startTime: String, endTime: String) { self.date = date self.startTime = startTime self.endTime = endTime } - + func bindSnapShotApply(section: DetailLargerInfoSection, item: [AnyHashable]) { var snapshot = DetailLargerInfoSnapshot() snapshot.appendSections([.main]) @@ -80,12 +79,12 @@ extension ResultDetailLargerInfoView { self.currentSnapshot = snapshot self.configureHeader() } - + private func configureViews() { self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] self.backgroundColor = .systemBackground self.addSubview(self.collectionView) - + NSLayoutConstraint.activate([ self.collectionView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), self.collectionView.leadingAnchor.constraint(equalTo: self.leadingAnchor), @@ -93,23 +92,23 @@ extension ResultDetailLargerInfoView { self.collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) } - + private func configuareDataSource() { - let datasource = DetailLargerInfoDataSource (collectionView: self.collectionView, + let datasource = DetailLargerInfoDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in - + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailCell.identifier, for: indexPath) as? DetailCell, - let item = item as? DetailInformationModel else { + let item = item as? DetailInformationModel else { return UICollectionViewCell() } cell.layout(data: item) cell.configureVoiceOverAccessibility() return cell }) - + self.dataSource = datasource self.collectionView.dataSource = dataSource } - + private func configureCollectionView() { self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailCell.self, forCellWithReuseIdentifier: DetailCell.identifier) @@ -117,29 +116,29 @@ extension ResultDetailLargerInfoView { forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DetailHeader.identifier) } - + private func configureHeader() { self.dataSource?.supplementaryViewProvider = { ( collectionView: UICollectionView, - kind: String, + _: String, indexPath: IndexPath) -> UICollectionReusableView? in guard let header: DetailHeader = self.collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: DetailHeader.identifier, for: indexPath) as? DetailHeader else { return DetailHeader() } - + header.configure(date: self.date, startTime: self.startTime, endTime: self.endTime) header.configureVoiceOverAccessibility() return header } } - + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + return UICollectionViewCompositionalLayout { (_, _) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.495), heightDimension: .estimated(500))) item.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item]) let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior = .none section.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) - + let headerSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(200)) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift index ba307db..eb7e3c4 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailModel.swift @@ -19,7 +19,7 @@ struct ResultDetailData { let assetIdentifiers: [String] let coordinates: [[CLLocationCoordinate2D]] private(set) var title: String - + init(records: Records) { self.timeStamp = ResultTimeStamp(records: records) self.distance = ResultDistance(records: records) @@ -31,10 +31,10 @@ struct ResultDetailData { self.title = records.title self.assetIdentifiers = records.assetIdentifiers var locations: [[CLLocationCoordinate2D]] = [] - records.records.forEach{locations.append($0.locations.coordinates)} + records.records.forEach {locations.append($0.locations.coordinates)} self.coordinates = locations } - + mutating func change(title: String) { self.title = title } @@ -45,7 +45,7 @@ struct ResultTimeStamp { let endTime: Date let startLocation: Location? let endLocation: Location? - + init(records: Records) { self.startTime = records.records.first?.startTime ?? Date.distantPast self.endTime = records.records.last?.endTime ?? Date.distantFuture @@ -55,12 +55,12 @@ struct ResultTimeStamp { } struct ResultDistance { - var total: Double? = nil + var total: Double? let steps: Int - + init(records: Records) { self.steps = records.steps - self.total = records.records.map{$0.locations.totalDistance()}.reduce(0, +) / 1000 + self.total = records.records.map {$0.locations.totalDistance()}.reduce(0, +) / 1000 } } @@ -68,7 +68,7 @@ struct ResultTime { let spent: TimeInterval let active: TimeInterval let inactive: TimeInterval - + init(records: Records) { var inactive: TimeInterval = 0 if records.records.count > 1 { @@ -76,7 +76,7 @@ struct ResultTime { inactive += records.records[index + 1].startTime.timeIntervalSince(records.records[index].endTime) } } - self.active = records.records.map{$0.endTime.timeIntervalSince($0.startTime)}.reduce(0, +) + self.active = records.records.map {$0.endTime.timeIntervalSince($0.startTime)}.reduce(0, +) self.inactive = inactive self.spent = records.totalTravelTime } @@ -86,7 +86,7 @@ struct ResultPace { let timePerKilometer: TimeInterval let fastestPace: TimeInterval let slowestPace: TimeInterval - + init(records: Records) { self.timePerKilometer = records.distances / records.totalTravelTime / 1000 self.fastestPace = TimeInterval(records.secondPerHighestSpeed) @@ -100,7 +100,7 @@ struct ResultAltitude { let lowest: Int? let starting: Int? let ending: Int? - + init(records: Records) { var paths: [Locations] = [] for record in records.records { @@ -114,14 +114,14 @@ struct ResultAltitude { self.ending = nil return } - + var maxAltitude: Int = Int.min var minAltitude: Int = Int.max for path in paths { maxAltitude = max(Int(round(path.maxAltitude)), Int(maxAltitude)) minAltitude = min(Int(round(path.minAltitude)), Int(minAltitude)) } - + self.total = maxAltitude - minAltitude self.highest = maxAltitude self.lowest = minAltitude @@ -136,19 +136,19 @@ struct ResultIncline { let uphillKilometer: Double let downhillKilometer: Double let plainKilometer: Double - + init(records: Records) { var inclines: [Double] = [] var steepest: Double = 0 var uphillDistance: Double = 0 var downHillDistance: Double = 0 var plainDistance: Double = 0 - + var paths: [Locations] = [] for record in records.records { paths.append(record.locations) } - + for path in paths { inclines.append(contentsOf: path.totalIncline()) steepest = max(path.steepestIncline(), steepest) @@ -158,7 +158,7 @@ struct ResultIncline { } let averageInclineInRadian: Double = inclines.isEmpty ? 0 : inclines.reduce(0, +) / Double(inclines.count) let averageInclineInDegrees: Int = Int(round(averageInclineInRadian.toDegrees())) - + self.average = averageInclineInDegrees self.highest = Int(round(steepest.toDegrees())) self.uphillKilometer = uphillDistance / 1000 diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift index 469d9a9..22e8f64 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift @@ -14,15 +14,15 @@ protocol ResultDetailRepository { class DefaultResultDetailRepository: ResultDetailRepository { private let recordStorage: CoreDataRecordStorage - + init(recordStorage: CoreDataRecordStorage) { self.recordStorage = recordStorage } - + func delete(id: String, completion: @escaping (Result) -> Void) { self.recordStorage.delete(id: id, completion: completion) } - + func update(title: String, id: String, completion: @escaping (Result) -> Void) { self.recordStorage.update(title: title, id: id, completion: completion) } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index 54e781d..c41fe12 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -39,43 +39,43 @@ class ResultDetailSmallerInfoView: UIView { label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) return label }() - + private let distanceLabel: UILabel = { let label = UILabel() label.text = "킬로미터" return label }() - + private let timeLabel: UILabel = { let label = UILabel() label.text = "시간" return label }() - + private let stepsLabel: UILabel = { let label = UILabel() label.text = "걸음" return label }() - + private let maxAltitudeLabel: UILabel = { let label = UILabel() label.text = "최고 고도" return label }() - + private let minAltitudeLabel: UILabel = { let label = UILabel() label.text = "최저 고도" return label }() - + private let averageSpeedLabel: UILabel = { let label = UILabel() label.text = "평균 속도" return label }() - + private lazy var distanceStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.distance, self.distanceLabel]) stackView.axis = .vertical @@ -84,7 +84,7 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var timeStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.time, self.timeLabel]) stackView.axis = .vertical @@ -93,7 +93,7 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var stepsStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.steps, self.stepsLabel]) stackView.axis = .vertical @@ -102,7 +102,7 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var maxAltitudeStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.maxAltitude, self.maxAltitudeLabel]) stackView.axis = .vertical @@ -111,7 +111,7 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var minAltitudeStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.minAltitude, self.minAltitudeLabel]) stackView.axis = .vertical @@ -120,7 +120,7 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var averageSpeedStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.averageSpeed, self.averageSpeedLabel]) stackView.axis = .vertical @@ -129,21 +129,21 @@ class ResultDetailSmallerInfoView: UIView { // stackView.distribution = .fillEqually return stackView }() - + private lazy var firstHorizontalStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.distanceStackView, self.timeStackView, self.stepsStackView]) stackView.axis = .horizontal stackView.distribution = .fillEqually return stackView }() - + private lazy var secondHorizontalStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.maxAltitudeStackView, self.minAltitudeStackView, self.averageSpeedStackView]) stackView.axis = .horizontal stackView.distribution = .fillEqually return stackView }() - + lazy var compositionalStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.firstHorizontalStackView, self.secondHorizontalStackView]) stackView.axis = .vertical @@ -152,7 +152,7 @@ class ResultDetailSmallerInfoView: UIView { stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() - + func configureLayout(distance: String, time: String, steps: String, maxAltitude: String, minAltitude: String, averageSpeed: String) { self.backgroundColor = .systemBackground self.distance.text = distance @@ -172,22 +172,21 @@ class ResultDetailSmallerInfoView: UIView { self.displayUpDownMark() self.layoutIfNeeded() } - + private func displayUpDownMark() { let upDownView = UIView() upDownView.backgroundColor = .label upDownView.translatesAutoresizingMaskIntoConstraints = false upDownView.layer.cornerRadius = 2 upDownView.layer.masksToBounds = true - + self.addSubview(upDownView) - let upDownConstraints = [ + NSLayoutConstraint.activate([ upDownView.topAnchor.constraint(equalTo: self.topAnchor, constant: 5), upDownView.centerXAnchor.constraint(equalTo: self.centerXAnchor), upDownView.heightAnchor.constraint(equalToConstant: 4), upDownView.widthAnchor.constraint(equalToConstant: self.frame.width/3) - ] - NSLayoutConstraint.activate(upDownConstraints) + ]) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index 39d927b..7c0f72c 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -11,25 +11,25 @@ class ResultDetailUseCase { private let model: ResultDetailData private let repository: ResultDetailRepository private(set) var isImageVisibilityOn: Bool - + init(model: ResultDetailData, repository: ResultDetailRepository) { self.model = model self.repository = repository self.isImageVisibilityOn = true } - + func transferResultDetailData(completion: (ResultDetailData) -> Void) { completion(self.model) } - + func delete(id: String, completion: @escaping (Result) -> Void) { self.repository.delete(id: id, completion: completion) } - + func update(title: String, id: String, completion: @escaping (Result) -> Void) { self.repository.update(title: title, id: id, completion: completion) } - + func toggleImageVisibility(completion: @escaping (Bool) -> Void) { isImageVisibilityOn.toggle() completion(isImageVisibilityOn) diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift index aceade8..50b74e8 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController 2.swift @@ -19,7 +19,7 @@ import MapKit class ResultDetailViewController: UIViewController { private let mapView = MKMapView() - + override func viewDidLoad() { super.viewDidLoad() @@ -31,7 +31,7 @@ extension ResultDetailViewController { private func layoutResultDetailView() { self.view.addSubview(mapView) mapView.translatesAutoresizingMaskIntoConstraints = false - + let mapViewConstraints = [ mapView.topAnchor.constraint(equalTo: self.view.topAnchor), mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index e2afdf3..7800ee7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -11,19 +11,19 @@ import Photos import Combine class ResultDetailViewController: UIViewController { - + weak var coordinator: ResultDetailViewCoordinator? - + private var viewModel: ResultDetailViewModel? - + private var infoViewTopConstraint: NSLayoutConstraint? private var infoViewHight: CGFloat? private var isLargeInfoView = false - + private let imageManager = PHCachingImageManager() private var uiImages = [String: UIImage]() private var observers: [AnyCancellable] = [] - + private lazy var mapView: MKMapView = { let mapView = MKMapView() mapView.mapType = .mutedStandard @@ -32,7 +32,7 @@ class ResultDetailViewController: UIViewController { mapView.accessibilityElementsHidden = true return mapView }() - + private lazy var smallerInformationView: ResultDetailSmallerInfoView = { let view = ResultDetailSmallerInfoView(frame: CGRect(x: 0, y: 0, @@ -41,7 +41,7 @@ class ResultDetailViewController: UIViewController { view.translatesAutoresizingMaskIntoConstraints = false return view }() - + private lazy var largerInformationView: ResultDetailLargerInfoView = { let view = ResultDetailLargerInfoView(frame: CGRect(x: 0, y: 0, @@ -50,7 +50,7 @@ class ResultDetailViewController: UIViewController { view.translatesAutoresizingMaskIntoConstraints = false return view }() - + private lazy var backButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "chevron.backward"), for: .normal) @@ -62,7 +62,7 @@ class ResultDetailViewController: UIViewController { button.accessibilityHint = "이전 화면으로 돌아가려면 이중 탭 하십시오" return button }() - + private lazy var changeButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "ellipsis.circle"), for: .normal) @@ -74,7 +74,7 @@ class ResultDetailViewController: UIViewController { button.accessibilityHint = "기록을 수정하거나 삭제하려면 이중 탭 하십시오" return button }() - + private lazy var detailImagesButton: UIButton = { let button = UIButton() button.setImage(.init(systemName: "photo.on.rectangle.angled"), for: .normal) @@ -97,7 +97,7 @@ class ResultDetailViewController: UIViewController { button.accessibilityHint = "앨범형식으로 모아보려면 이중 탭 하십시오" return button }() - + private lazy var imagesVisibilityButton: UIButton = { let button = UIButton() button.setPreferredSymbolConfiguration(.init(pointSize: 14), forImageIn: .normal) @@ -117,7 +117,7 @@ class ResultDetailViewController: UIViewController { button.accessibilityHint = "이미지 썸네일을 끄려면 이중 탭 하십시오" return button }() - + private var titleLabel: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: label.font.pointSize, weight: .bold) @@ -125,12 +125,12 @@ class ResultDetailViewController: UIViewController { label.accessibilityTraits = .header return label }() - + convenience init(viewModel: ResultDetailViewModel) { self.init() self.viewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() self.configureViews() @@ -141,7 +141,7 @@ class ResultDetailViewController: UIViewController { self.registerAnnotationView() self.configureVoiceOverAccessibility() } - + private func configureViewModel() { self.viewModel?.recordDidFetch = { [weak self] in guard let viewModel = self?.viewModel else { return } @@ -184,10 +184,10 @@ class ResultDetailViewController: UIViewController { self?.configureImageVisibility(bool) }) .store(in: &observers) - + self.viewModel?.setUp() } - + private func registerAnnotationView() { self.mapView.register( ThumbnailView.self, @@ -200,25 +200,25 @@ class ResultDetailViewController: UIViewController { guard let imageName = imageName else { return } self.imagesVisibilityButton.setImage(UIImage(systemName: imageName), for: .normal) } - + private func configureImageVisibility(_ bool: Bool) { - let imageAnnotations = self.mapView.annotations.filter{$0.title != "시작점" && $0.title != "종료점"} + let imageAnnotations = self.mapView.annotations.filter {$0.title != "시작점" && $0.title != "종료점"} switch bool { case true: self.imagesVisibilityButton.accessibilityValue = "켜짐" self.imagesVisibilityButton.accessibilityHint = "이미지 썸네일을 끄려면 이중 탭 하십시오" - imageAnnotations.forEach{ + imageAnnotations.forEach { self.mapView.view(for: $0)?.isHidden = false } case false: self.imagesVisibilityButton.accessibilityValue = "꺼짐" self.imagesVisibilityButton.accessibilityHint = "이미지 썸네일을 켜려면 이중 탭 하십시오" - imageAnnotations.forEach{ + imageAnnotations.forEach { self.mapView.view(for: $0)?.isHidden = true } } } - + private func drawPathOnMap() { guard let pointSets: [[CLLocationCoordinate2D]] = self.viewModel?.resultDetailData?.coordinates else { return @@ -229,11 +229,11 @@ class ResultDetailViewController: UIViewController { guard let initial = self.mapView.overlays.first?.boundingMapRect else { return } - + let mapRect = self.mapView.overlays.dropFirst().reduce(initial) { $0.union($1.boundingMapRect) } self.mapView.setVisibleMapRect(mapRect, animated: true) } - + private func markEndPoints() { guard let startingLocation = self.viewModel?.resultDetailData?.timeStamp.startLocation, let endingLocation = self.viewModel?.resultDetailData?.timeStamp.endLocation else { @@ -250,15 +250,15 @@ class ResultDetailViewController: UIViewController { self.fetchAssetImage() self.mapView.addAnnotations([startAnnotation, endAnnotation]) } - + private func fetchAssetImage() { guard let assetIdentifiers = self.viewModel?.resultDetailData?.assetIdentifiers else { return } let allMedia = PHAsset.fetchAssets(with: .image, options: nil) var assetMap = [String: Bool]() var identifierCount = 0 - + for identifier in assetIdentifiers { assetMap[identifier] = true } - + for i in stride(from: allMedia.count - 1, through: 0, by: -1) { guard identifierCount < assetIdentifiers.count else { return } if let value = assetMap[allMedia[i].localIdentifier] { @@ -273,10 +273,10 @@ class ResultDetailViewController: UIViewController { identifierCount += 1 } } - + self.detailImagesButton.setTitle("\(identifierCount)", for: .normal) } - + private func requestAssetIamge(with asset: PHAsset?, completion: @escaping (UIImage?, PHAsset?) -> Void) { guard let asset = asset else { completion(nil, nil) @@ -287,26 +287,26 @@ class ResultDetailViewController: UIViewController { completion(image, asset) }) } - + private func appendImageAnnotation(identifier: String, location: CLLocationCoordinate2D) { let imageAnnotation = MKPointAnnotation() imageAnnotation.coordinate = location imageAnnotation.title = identifier self.mapView.addAnnotation(imageAnnotation) } - + private func configureSmallerView() { self.smallerInformationView = ResultDetailSmallerInfoView(frame: self.smallerInformationView.bounds) } - + private func configurePanGesture() { let informationViewPan = UIPanGestureRecognizer(target: self, action: #selector(self.informationViewPanPanned(_:))) - + informationViewPan.delaysTouchesBegan = false informationViewPan.delaysTouchesEnded = false view.addGestureRecognizer(informationViewPan) } - + private func configureViews() { guard let tabBar = self.navigationController?.tabBarController?.tabBar else { return } self.view.addSubview(self.mapView) @@ -317,66 +317,65 @@ class ResultDetailViewController: UIViewController { self.view.addSubview(self.largerInformationView) self.view.addSubview(self.smallerInformationView) self.view.addSubview(self.titleLabel) - + NSLayoutConstraint.activate([ self.mapView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.mapView.topAnchor.constraint(equalTo: self.view.topAnchor), self.mapView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -(self.smallerInformationView.compositionalStackView.frame.height + tabBar.frame.height)) + self.mapView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -(self.smallerInformationView.compositionalStackView.frame.height + tabBar.frame.height)) ]) - + NSLayoutConstraint.activate([ self.backButton.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10), self.backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), self.backButton.widthAnchor.constraint(equalToConstant: 40), - self.backButton.heightAnchor.constraint(equalToConstant: 40), + self.backButton.heightAnchor.constraint(equalToConstant: 40) ]) - + NSLayoutConstraint.activate([ self.changeButton.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor, constant: -10), self.changeButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10), self.changeButton.widthAnchor.constraint(equalToConstant: 40), - self.changeButton.heightAnchor.constraint(equalToConstant: 40), + self.changeButton.heightAnchor.constraint(equalToConstant: 40) ]) - + NSLayoutConstraint.activate([ self.smallerInformationView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.smallerInformationView.rightAnchor.constraint(equalTo: self.view.rightAnchor), self.smallerInformationView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) - + NSLayoutConstraint.activate([ self.largerInformationView.topAnchor.constraint(equalTo: self.smallerInformationView.topAnchor), self.largerInformationView.leadingAnchor.constraint(equalTo: self.smallerInformationView.leadingAnchor), self.largerInformationView.trailingAnchor.constraint(equalTo: self.smallerInformationView.trailingAnchor), self.largerInformationView.bottomAnchor.constraint(equalTo: self.smallerInformationView.bottomAnchor), self.titleLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), - self.titleLabel.centerYAnchor.constraint(equalTo: self.changeButton.centerYAnchor), + self.titleLabel.centerYAnchor.constraint(equalTo: self.changeButton.centerYAnchor) ]) - + NSLayoutConstraint.activate([ self.detailImagesButton.topAnchor.constraint(equalTo: self.mapView.bottomAnchor, constant: -45), self.detailImagesButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -15), self.detailImagesButton.widthAnchor.constraint(equalToConstant: 55), self.detailImagesButton.heightAnchor.constraint(equalToConstant: 30) ]) - + NSLayoutConstraint.activate([ self.imagesVisibilityButton.topAnchor.constraint(equalTo: self.detailImagesButton.topAnchor), self.imagesVisibilityButton.trailingAnchor.constraint(equalTo: self.detailImagesButton.leadingAnchor, constant: -15), self.imagesVisibilityButton.widthAnchor.constraint(equalToConstant: 55), self.imagesVisibilityButton.heightAnchor.constraint(equalToConstant: 30) ]) - - self.infoViewTopConstraint = - self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) + + self.infoViewTopConstraint = self.smallerInformationView.topAnchor.constraint(equalTo: self.mapView.bottomAnchor) guard let infoViewConstraint = self.infoViewTopConstraint else { return } NSLayoutConstraint.activate([infoViewConstraint]) - + self.view.layoutIfNeeded() self.infoViewHight = self.smallerInformationView.frame.height } - + private func findInfoViewBottomConstraints(traslation: CGFloat) { var bottomConstraint: NSLayoutConstraint? self.smallerInformationView.constraints.forEach { @@ -386,28 +385,28 @@ class ResultDetailViewController: UIViewController { } bottomConstraint?.constant = traslation } - + private func changeInfoViewTopConstraints(traslation: CGFloat) { guard let infoViewConstraint = self.infoViewTopConstraint else { return } infoViewConstraint.constant = traslation } - + @objc private func informationViewPanPanned(_ panGestureRecognizer: UIPanGestureRecognizer) { let translation = panGestureRecognizer.translation(in: self.smallerInformationView) let informationViewHeight = self.smallerInformationView.frame.height - + switch panGestureRecognizer.state { case .began: UIView.animate(withDuration: 0.2, animations: { self.mapView.alpha = 0.8 }) - + case .changed: var offset: CGFloat = 0 if self.isLargeInfoView { offset = self.backButton.frame.maxY - self.mapView.safeAreaLayoutGuide.layoutFrame.maxY } - + guard (self.view.frame.height - informationViewHeight) >= (self.backButton.frame.height + 10), let infoViewHight = self.infoViewHight, infoViewHight < (informationViewHeight - (translation.y + offset)) else { @@ -416,7 +415,7 @@ class ResultDetailViewController: UIViewController { self.smallerInformationView.layer.cornerRadius = 13 self.largerInformationView.layer.cornerRadius = 13 self.changeInfoViewTopConstraints(traslation: translation.y + offset) - + case .ended: if self.smallerInformationView.frame.minY <= self.view.frame.height/2 { self.smallerInformationView.alpha = 0 @@ -432,12 +431,12 @@ class ResultDetailViewController: UIViewController { self.smallerInformationView.alpha = 1 self.changeInfoViewTopConstraints(traslation: 0) } - + UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseInOut, animations: { self.view.layoutIfNeeded() self.largerInformationView.collectionView.setNeedsLayout() }, completion: nil) - + self.configureVoiceOverAccessibility() default: break @@ -449,29 +448,26 @@ extension ResultDetailViewController { @objc func dismissViewController() { self.coordinator?.dismiss() } - + @objc func pushDetailImagesViewController() { self.coordinator?.pushResultDetailImagesViewController(uiImages: uiImages) } - + @objc func imagesVisibilityButtonAction() { self.viewModel?.imageVisibilityButtonTouched() } - + @objc func presentModifyResultAlert() { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { action in + let changeTitle = UIAlertAction(title: "제목 변경", style: .default) { _ in self.coordinator?.presentRecordingTitleViewController() } - let delete = UIAlertAction(title: "삭제", style: .destructive) { action in + let delete = UIAlertAction(title: "삭제", style: .destructive) { _ in self.viewModel?.delete { result in - switch result { - case .success(): + if case .success = result { DispatchQueue.main.async { self.coordinator?.dismiss() } - case .failure(let error): - print(error) } } } @@ -504,7 +500,7 @@ extension ResultDetailViewController: MKMapViewDelegate { } return MKOverlayRenderer() } - + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if annotation.title == "시작점" || annotation.title == "종료점" { let annotationView = PinView(annotation: annotation, reuseIdentifier: PinView.ReuseID) @@ -513,17 +509,17 @@ extension ResultDetailViewController: MKMapViewDelegate { guard let identifider = annotation.title, let image = self.uiImages[identifider ?? "None"] else { return nil } - + let thumbnailView = ThumbnailView(annotation: annotation, reuseIdentifier: ThumbnailView.ReuseID) thumbnailView.configureImage(uiImage: image, id: identifider ?? "") - + return thumbnailView } } - + func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { guard let annotation = view as? ThumbnailView else { return } - + self.coordinator?.presentResultDetailThumbnailViewController(uiImages: uiImages, id: annotation.imageIdentifier) } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index 9d37190..af0fdd0 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -12,20 +12,20 @@ class ResultDetailViewCoordinator: Coordinator { var navigationController: UINavigationController var coreDataStorage: CoreDataStorage var records: Records - + func start() { let resultDetailViewController = ResultDetailViewController(viewModel: injectDependencies()) resultDetailViewController.coordinator = self self.navigationController.setNavigationBarHidden(true, animated: false) self.navigationController.pushViewController(resultDetailViewController, animated: true) } - + func dismiss() { self.navigationController.setNavigationBarHidden(false, animated: false) self.navigationController.popViewController(animated: true) self.parentCoordinator?.childCoordinators.removeLast() } - + init(navigationController: UINavigationController, coreDataStorage: CoreDataStorage, records: Records) { self.navigationController = navigationController self.coreDataStorage = coreDataStorage @@ -48,7 +48,7 @@ extension ResultDetailViewCoordinator { ) ) } - + func presentRecordingTitleViewController() { guard let viewController = self.navigationController.viewControllers.last as? ResultDetailViewController else { return @@ -56,23 +56,23 @@ extension ResultDetailViewCoordinator { let recordingTitleViewCoordinator = RecordingTitleViewCoordinator(delegate: viewController) self.childCoordinators.append(recordingTitleViewCoordinator) recordingTitleViewCoordinator.parentCoordinator = self - + recordingTitleViewCoordinator.start() } - + func pushResultDetailImagesViewController(uiImages: [String: UIImage]) { let resultDetailImagesViewCoordinator = ResultDetailImagesViewCoordinator(navigationController: navigationController, uiImages: uiImages) self.childCoordinators.append(resultDetailImagesViewCoordinator) resultDetailImagesViewCoordinator.parentCoordinator = self - + resultDetailImagesViewCoordinator.start() } - + func presentResultDetailThumbnailViewController(uiImages: [String: UIImage], id: String) { let resultDetailThumbnailViewCoordinator = ResultDetailThumbnailViewCoordinator(navigationController: navigationController, uiImages: uiImages, id: id) self.childCoordinators.append(resultDetailThumbnailViewCoordinator) resultDetailThumbnailViewCoordinator.parentCoordinator = self - + resultDetailThumbnailViewCoordinator.start() } } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 3afc404..31a1e5c 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -29,12 +29,12 @@ class ResultDetailViewModel { } @Published var imageVisibilityIconName: String? let imageVisibilityStatus = PassthroughSubject() - + init(useCase: ResultDetailUseCase) { self.useCase = useCase self.recordDidFetch = {} } - + func setUp() { self.useCase.transferResultDetailData { [weak self] dataModel in self?.resultDetailData = dataModel @@ -42,21 +42,21 @@ class ResultDetailViewModel { } self.imageVisibilityIconName = useCase.isImageVisibilityOn ? "eye" : "eye.slash" } - + func delete(completion: @escaping (Result) -> Void) { guard let id = self.resultDetailData?.id else { return } self.useCase.delete(id: id, completion: completion) } - + func update(title: String, completion: @escaping (String) -> Void) { guard let id = self.resultDetailData?.id else { return } self.useCase.update(title: title, id: id) { result in switch result { - case .success(): + case .success: self.resultDetailData?.change(title: title) completion(title) case .failure(let error): @@ -64,7 +64,7 @@ class ResultDetailViewModel { } } } - + func averageSpeed() -> String { let formatter = NumberFormatter() formatter.minimumFractionDigits = 2 @@ -76,7 +76,7 @@ class ResultDetailViewModel { } return speed } - + lazy var recordDate: String = { guard let endTime = self.resultDetailData?.timeStamp.endTime else { return "" @@ -86,7 +86,7 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "yyyy. MM. dd. (E)" return dateFormatter.string(from: endTime) }() - + lazy var startTime: String = { guard let startTime = self.resultDetailData?.timeStamp.startTime else { return "" @@ -96,7 +96,7 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: startTime) }() - + lazy var endTime: String = { guard let endTime = self.resultDetailData?.timeStamp.endTime else { return "" @@ -106,7 +106,7 @@ class ResultDetailViewModel { dateFormatter.dateFormat = "a h시 m분" return dateFormatter.string(from: endTime) }() - + func imageVisibilityButtonTouched() { self.useCase.toggleImageVisibility { [weak self] bool in bool ? (self?.imageVisibilityIconName = "eye") : (self?.imageVisibilityIconName = "eye.slash") @@ -129,11 +129,11 @@ class DetailInformationModel: Hashable { var id: UUID = UUID() var title: String = "" var contents: [CellContentEntity] = [] - + func hash(into hasher: inout Hasher) { hasher.combine(id) } - + static func == (lhs: DetailInformationModel, rhs: DetailInformationModel) -> Bool { lhs.id == rhs.id } @@ -143,7 +143,7 @@ extension ResultDetailViewModel { class DistanceViewModel: DetailInformationModel { var totalDistance: String = "-" var steps: String = "0" - + init(distanceData: ResultDistance?) { super.init() guard let distanceData = distanceData else { @@ -157,7 +157,7 @@ extension ResultDetailViewModel { if let steps = formatter.string(from: NSNumber(value: distanceData.steps)) { self.steps = steps } - + if let distance = distanceData.total, let total = formatter.string(from: NSNumber(value: distance)) { self.totalDistance = total @@ -168,10 +168,10 @@ extension ResultDetailViewModel { ] } } - + class TimeViewModel: DetailInformationModel { var totalTimeSpent: String = "" - + init(timeData: ResultTime?) { super.init() guard let timeData = timeData else { @@ -190,11 +190,11 @@ extension ResultDetailViewModel { self.contents = [ CellContentEntity(content: spent, contentTitle: "소요"), CellContentEntity(content: active, contentTitle: "운동"), - CellContentEntity(content: inactive, contentTitle: "휴식"), + CellContentEntity(content: inactive, contentTitle: "휴식") ] } } - + class PaceViewModel: DetailInformationModel { init(paceData: ResultPace?) { super.init() @@ -213,15 +213,15 @@ extension ResultDetailViewModel { self.contents = [ CellContentEntity(content: averagePace, contentTitle: "평균"), CellContentEntity(content: fastest, contentTitle: "최고"), - CellContentEntity(content: slowest, contentTitle: "최저"), + CellContentEntity(content: slowest, contentTitle: "최저") ] } } - + class AltitudeViewModel: DetailInformationModel { var highest: String = "-" var lowest: String = "-" - + init(altitudeData: ResultAltitude?) { super.init() guard let altitudeData = altitudeData else { @@ -233,39 +233,39 @@ extension ResultDetailViewModel { var lowestString = "-" var startingString = "-" var endingString = "-" - + if let total = altitudeData.total { totalString = String(total) } - + if let highest = altitudeData.highest { highestString = String(highest) self.highest = highestString } - + if let lowest = altitudeData.lowest { lowestString = String(lowest) self.lowest = lowestString } - + if let start = altitudeData.starting { startingString = String(start) } - + if let end = altitudeData.ending { endingString = String(end) } - + self.contents = [ CellContentEntity(content: totalString, contentTitle: "누적"), CellContentEntity(content: highestString, contentTitle: "최고"), CellContentEntity(content: lowestString, contentTitle: "최저"), CellContentEntity(content: startingString, contentTitle: "시작"), - CellContentEntity(content: endingString, contentTitle: "종료"), + CellContentEntity(content: endingString, contentTitle: "종료") ] } } - + class InclineViewModel: DetailInformationModel { init(inclineData: ResultIncline?) { super.init() @@ -286,7 +286,7 @@ extension ResultDetailViewModel { CellContentEntity(content: String(inclineData.highest)+"°", contentTitle: "최고"), CellContentEntity(content: uphill, contentTitle: "오르막(km)"), CellContentEntity(content: downhill, contentTitle: "내리막(km)"), - CellContentEntity(content: plain, contentTitle: "평지(km)"), + CellContentEntity(content: plain, contentTitle: "평지(km)") ] } } diff --git a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift index dc29edc..3543936 100644 --- a/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift +++ b/SanTa/SanTa/ResultDetailScene/ThumbnailView.swift @@ -10,7 +10,7 @@ import MapKit final class ThumbnailView: MKAnnotationView { static let ReuseID = "ThumbnailAnnotation" - + private lazy var displayView: UIView = { let view = UIView() view.backgroundColor = .white @@ -22,38 +22,38 @@ final class ThumbnailView: MKAnnotationView { view.layer.shadowRadius = 2 return view }() - + private lazy var imageView = UIImageView() private(set) var imageIdentifier = String() - + override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + override func prepareForDisplay() { super.prepareForDisplay() self.frame = CGRect(x: 0, y: 0, width: 38, height: 38) self.configure() } - + private func configure() { displayView.translatesAutoresizingMaskIntoConstraints = false imageView.translatesAutoresizingMaskIntoConstraints = false - + self.addSubview(displayView) self.addSubview(imageView) - + NSLayoutConstraint.activate([ self.displayView.leftAnchor.constraint(equalTo: self.leftAnchor), self.displayView.topAnchor.constraint(equalTo: self.topAnchor), self.displayView.rightAnchor.constraint(equalTo: self.rightAnchor), self.displayView.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) - + NSLayoutConstraint.activate([ self.imageView.leftAnchor.constraint(equalTo: self.displayView.leftAnchor, constant: 2), self.imageView.topAnchor.constraint(equalTo: self.displayView.topAnchor, constant: 2), @@ -61,7 +61,7 @@ final class ThumbnailView: MKAnnotationView { self.imageView.bottomAnchor.constraint(equalTo: self.displayView.bottomAnchor, constant: -2) ]) } - + func configureImage(uiImage: UIImage, id: String) { self.imageView.image = uiImage self.imageIdentifier = id diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index 0c8e674..f1cceae 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -9,21 +9,21 @@ import UIKit class ResultDetailThumbnailViewController: UIViewController { weak var coordinator: ResultDetailThumbnailViewCoordinator? - + enum DetailThumbnailSection: Int, CaseIterable { case main } - + typealias DetailThumbnailDataSource = UICollectionViewDiffableDataSource typealias DetailThumbnailSnapshot = NSDiffableDataSourceSnapshot - + private var dataSource: DetailThumbnailDataSource? private var firetShowIndex = 0 private var showIndex = 0 - + var uiImages = [String: UIImage]() var currentIdentifier = String() - + private lazy var collectionView: UICollectionView = { let flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: .init(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: flowLayout) @@ -31,7 +31,7 @@ class ResultDetailThumbnailViewController: UIViewController { return collectionView }() - + private lazy var titleLabel: UILabel = { let label = UILabel() label.backgroundColor = .systemBackground @@ -41,7 +41,7 @@ class ResultDetailThumbnailViewController: UIViewController { label.translatesAutoresizingMaskIntoConstraints = false return label }() - + override func viewDidLoad() { super.viewDidLoad() self.configureCollectionView() @@ -49,42 +49,42 @@ class ResultDetailThumbnailViewController: UIViewController { self.configuareDataSource() self.configureImages() } - + override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.coordinator?.dismiss() } - + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.collectionView.scrollToItem(at: IndexPath(row: self.firetShowIndex, section: 0), at: .right, animated: true) } - + private func configureViews() { self.view.backgroundColor = .systemBackground self.view.addSubview(self.collectionView) self.view.addSubview(self.titleLabel) - + NSLayoutConstraint.activate([ self.collectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.collectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), self.collectionView.heightAnchor.constraint(equalTo: self.view.widthAnchor), self.collectionView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor) ]) - + NSLayoutConstraint.activate([ self.titleLabel.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 15), self.titleLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), - self.titleLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + self.titleLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor) ]) } - + private func configureCollectionView() { self.collectionView.delegate = self self.collectionView.collectionViewLayout = configureCompositionalLayout() self.collectionView.register(DetailImagesCell.self, forCellWithReuseIdentifier: DetailImagesCell.identifier) } - + private func bindSnapShotApply(section: DetailThumbnailSection, item: [AnyHashable]) { var snapshot = DetailThumbnailSnapshot() snapshot.appendSections([.main]) @@ -93,9 +93,9 @@ class ResultDetailThumbnailViewController: UIViewController { } self.dataSource?.apply(snapshot, animatingDifferences: true) } - + private func configureCompositionalLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + return UICollectionViewCompositionalLayout { (_, _) -> NSCollectionLayoutSection? in let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1))) item.contentInsets = .init(top: 3, leading: 3, bottom: 3, trailing: 3) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1)), subitems: [item]) @@ -105,31 +105,31 @@ class ResultDetailThumbnailViewController: UIViewController { return section } } - + private func configuareDataSource() { let datasource = DetailThumbnailDataSource(collectionView: self.collectionView, cellProvider: { (collectionView, indexPath, item) -> UICollectionViewCell in - + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: DetailImagesCell.identifier, for: indexPath) as? DetailImagesCell, let item = item as? String, - let image = self.uiImages[item] else { + let image = self.uiImages[item] else { return UICollectionViewCell() } - + cell.update(image: image, id: item) return cell }) - + self.dataSource = datasource self.collectionView.dataSource = dataSource } - + private func configureImages() { var identifiers = [String]() var index = 0 var findImage = false - + for (key, _) in self.uiImages { identifiers.append(key) - + if key == currentIdentifier { findImage = true self.firetShowIndex = index @@ -137,7 +137,7 @@ class ResultDetailThumbnailViewController: UIViewController { } if !findImage { index += 1 } } - + self.bindSnapShotApply(section: .main, item: identifiers) } } diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift index d503213..0f6ef78 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift @@ -11,23 +11,23 @@ class ResultDetailThumbnailViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController - + let uiImages: [String: UIImage] let id: String - + func start() { let resultDetailThumbnailViewController = ResultDetailThumbnailViewController() resultDetailThumbnailViewController.uiImages = self.uiImages resultDetailThumbnailViewController.currentIdentifier = self.id resultDetailThumbnailViewController.coordinator = self - + self.navigationController.present(resultDetailThumbnailViewController, animated: true) } - + func dismiss() { self.parentCoordinator?.childCoordinators.removeLast() } - + init(navigationController: UINavigationController, uiImages: [String: UIImage], id: String) { self.navigationController = navigationController self.uiImages = uiImages diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index 033b6a1..aaa76dd 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -13,7 +13,7 @@ extension UILabel { self.text = text self.textColor = .label } - + fileprivate convenience init(boldFontWithSize: CGFloat) { self.init() self.font = .boldSystemFont(ofSize: boldFontWithSize) @@ -54,7 +54,7 @@ class RecordsViewCell: UICollectionViewCell { let timeStackView = UIStackView() let altitudeStackView = UIStackView() let stepsStackView = UIStackView() - + func configure(date: String, title: String, distance: String, time: String, altitude: String, steps: String) { self.date.text = date self.title.text = title @@ -64,11 +64,11 @@ class RecordsViewCell: UICollectionViewCell { self.steps.text = steps self.backgroundColor = UIColor(named: "RecodingResultCellColor") self.title.text?.count == 0 ? (self.title.isHidden = true) : (self.title.isHidden = false) - + self.configureSubviews() self.configureLayout() } - + private func configureSubviews() { self.addSubview(date) self.addSubview(title) @@ -93,7 +93,7 @@ class RecordsViewCell: UICollectionViewCell { $0.spacing = 5 } } - + private func configureLayout() { self.date.translatesAutoresizingMaskIntoConstraints = false self.title.translatesAutoresizingMaskIntoConstraints = false @@ -115,7 +115,7 @@ class RecordsViewCell: UICollectionViewCell { // MARK: - Accessibility extension RecordsViewCell { - + func configureVoiceOverAccessibility() { guard let date = self.date.text else { return } guard var title = self.title.text else { return } @@ -126,11 +126,10 @@ extension RecordsViewCell { if title.isEmpty { title = "없음" } - + self.isAccessibilityElement = true self.accessibilityLabel = "\(date) 등산기록 정보, 제목: \(title), 거리: \(distance)km, 시간: \(time), 고도차: \(altitude), 걸음: \(steps)" self.accessibilityTraits = .none self.accessibilityHint = "등산기록 상세화면으로 넘어가려면 이중 탭 하십시오" } } - diff --git a/SanTa/SanTa/ResultScene/ResultRepository.swift b/SanTa/SanTa/ResultScene/ResultRepository.swift index fc7a898..5f7917c 100644 --- a/SanTa/SanTa/ResultScene/ResultRepository.swift +++ b/SanTa/SanTa/ResultScene/ResultRepository.swift @@ -8,13 +8,13 @@ import Foundation final class DefaultResultRepository: ResultRepository { - + private let recordStorage: CoreDataRecordStorage - + init(recordStorage: CoreDataRecordStorage) { self.recordStorage = recordStorage } - + func fetch(completion: @escaping (Result<[Records], Error>) -> Void) { self.recordStorage.fetch { result in switch result { @@ -30,7 +30,7 @@ final class DefaultResultRepository: ResultRepository { } } } - + private func makeRecords(recordsEntityMO: RecordsEntityMO) -> Records? { guard let title = recordsEntityMO.title, let archiveAssetIdentifiers = recordsEntityMO.assetIdentifiers, @@ -48,15 +48,15 @@ final class DefaultResultRepository: ResultRepository { return Records(title: title, records: records, assetIdentifiers: assetIdentifiers, secondPerHighestSpeed: secondPerHighestSpeed, secondPerMinimumSpeed: secondPerMinimumSpeed, id: id) } - + private func makeRecord(recordEntityMO: RecordEntityMO) -> Record? { guard let startTime = recordEntityMO.startTime else { return nil } guard let endTime = recordEntityMO.endTime else { return nil } let step = Int(recordEntityMO.step) let distance = recordEntityMO.distance - + var locations: [Location] = [] - recordEntityMO.locations?.forEach{ + recordEntityMO.locations?.forEach { guard let locationEntityMO = $0 as? LocationEntityMO else { return } let location = Location(latitude: locationEntityMO.latitude, longitude: locationEntityMO.longitude, @@ -69,5 +69,5 @@ final class DefaultResultRepository: ResultRepository { distance: distance, locations: locations) } - + } diff --git a/SanTa/SanTa/ResultScene/ResultUseCase.swift b/SanTa/SanTa/ResultScene/ResultUseCase.swift index d683ef2..fd863fc 100644 --- a/SanTa/SanTa/ResultScene/ResultUseCase.swift +++ b/SanTa/SanTa/ResultScene/ResultUseCase.swift @@ -15,11 +15,11 @@ protocol ResultRepository { final class ResultUseCase { private let resultRepository: ResultRepository private(set) var totalRecords: TotalRecords? - + init(resultRepository: ResultRepository) { self.resultRepository = resultRepository } - + func fetch(completion: @escaping (Void?) -> Void) { self.resultRepository.fetch { [weak self] result in switch result { @@ -37,4 +37,3 @@ final class ResultUseCase { } } } - diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index c4897bd..d828684 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -11,7 +11,7 @@ class ResultViewController: UIViewController { weak var coordinator: ResultViewCoordinator? private var collectionView: UICollectionView? private var viewModel: ResultViewModel? - + convenience init(viewModel: ResultViewModel) { self.init() self.viewModel = viewModel @@ -21,17 +21,17 @@ class ResultViewController: UIViewController { super.viewDidLoad() self.configureCollectionView() } - + override func viewWillAppear(_ animated: Bool) { self.navigationController?.navigationBar.isHidden = true - self.viewModel?.viewWillAppear() { [weak self] in + self.viewModel?.viewWillAppear { [weak self] in DispatchQueue.main.async { self?.navigationController?.navigationBar.topItem?.title = self?.viewModel?.totalDistance self?.collectionView?.reloadData() } } } - + private func configureCollectionView() { self.collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: self.createCompositionalLayout()) guard let collectionView = self.collectionView else { return } @@ -42,9 +42,9 @@ class ResultViewController: UIViewController { collectionView.delegate = self collectionView.dataSource = self } - + private func createCompositionalLayout() -> UICollectionViewCompositionalLayout { - return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in + return UICollectionViewCompositionalLayout { (sectionNumber, _) -> NSCollectionLayoutSection? in switch sectionNumber { case 0: return self.firstLayoutSection() default: return self.secondLayoutSection() @@ -60,7 +60,7 @@ class ResultViewController: UIViewController { let section = NSCollectionLayoutSection(group: group) return section } - + private func secondLayoutSection() -> NSCollectionLayoutSection { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) @@ -81,19 +81,19 @@ class ResultViewController: UIViewController { } } -extension ResultViewController: UICollectionViewDataSource { +extension ResultViewController: UICollectionViewDataSource { func numberOfSections(in collectionView: UICollectionView) -> Int { guard let viewModel = self.viewModel else { return 0} return viewModel.totalSections + 1 } - + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch section { case 0: return 1 default : return self.viewModel?.itemsInSection(section: section - 1) ?? 0 } } - + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch indexPath.section { case 0: @@ -124,7 +124,7 @@ extension ResultViewController: UICollectionViewDataSource { return cell } } - + func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.identifier, for: indexPath) as? SectionHeaderView, let sectionInfo = self.viewModel?.sectionInfo(section: indexPath.section - 1) @@ -136,7 +136,7 @@ extension ResultViewController: UICollectionViewDataSource { sectionHeader.configureVoiceOverAccessibility(date: sectionInfo.accessibiltyDate) return sectionHeader } - + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let indexPath = IndexPath(item: indexPath.item, section: indexPath.section - 1) guard indexPath.section >= 0, diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index 892882c..70854c6 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -17,7 +17,7 @@ class ResultViewCoordinator: Coordinator { self.navigationController = UINavigationController() self.coreDataStorage = coreDataStorage } - + func start() { } @@ -41,12 +41,12 @@ extension ResultViewCoordinator { ) ) } - + func presentResultDetailViewController(records: Records) { let resultDetailViewCoordinator = ResultDetailViewCoordinator(navigationController: self.navigationController, coreDataStorage: self.coreDataStorage, records: records) resultDetailViewCoordinator.parentCoordinator = self self.childCoordinators.append(resultDetailViewCoordinator) - + resultDetailViewCoordinator.start() } } diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index 88e2abe..a6238c8 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -18,7 +18,7 @@ class ResultViewModel { guard let totalRecords = self.useCase.totalRecords else { return 0 } return totalRecords.sectionCount } - + init(useCase: ResultUseCase) { self.useCase = useCase self.cellShouldUpdate = {} @@ -31,11 +31,11 @@ class ResultViewModel { completion() } } - + func itemsInSection(section: Int) -> Int { self.useCase.totalRecords?[section]?.count ?? 0 } - + func totalInfo() -> (distance: String, count: String, time: String, steps: String) { guard let totalRecords = self.useCase.totalRecords else { return ("", "", "", "") @@ -46,7 +46,7 @@ class ResultViewModel { let stepsString = self.stepsFormatter(totalRecords.totalSteps) return (distanceString, countString, timeString, stepsString) } - + func sectionInfo(section: Int) -> (date: String, accessibiltyDate: String, count: String, @@ -70,7 +70,7 @@ class ResultViewModel { let timeString = self.timeFormatter(dateSeperateRecords.times) return (dateString, accessibiltyDateString, countString, distanceString, timeString) } - + func cellInfo(indexPath: IndexPath) -> (date: String, distance: String, time: String, @@ -90,7 +90,7 @@ class ResultViewModel { let title = records.title return (dateString, distanceString, timeString, altitudeDifferenceString, stepsString, title) } - + func selectedRecords(indexPath: IndexPath) -> Records? { return self.useCase.totalRecords?[indexPath.section]?[indexPath.item] } @@ -100,18 +100,18 @@ extension ResultViewModel { private func headerDateFormatter(year: Int, month: Int) -> String { return "\(year). \(month)." } - + private func headerAccessibiltyDateFormatter(year: Int, month: Int) -> String { return "\(year)년 \(month)월" } - + private func cellDateFormatter(_ date: Date?) -> String { guard let date = date, let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: .now) else { return "알 수 없는 날짜" } let calender = Calendar.current let dateFormatter = DateFormatter() - dateFormatter.locale = Locale(identifier:"ko_KR") + dateFormatter.locale = Locale(identifier: "ko_KR") if calender.compare(date, to: .now, toGranularity: .day) == .orderedSame { dateFormatter.dateFormat = "오늘(E) a h시 m분" } else if calender.compare(date, to: yesterday, toGranularity: .day) == .orderedSame { @@ -119,22 +119,22 @@ extension ResultViewModel { } else { dateFormatter.dateFormat = "M. d. (E) a h시 m분" } - return dateFormatter.string(from:date) + return dateFormatter.string(from: date) } - + private func timeFormatter(_ time: TimeInterval) -> String { let formatter = DateComponentsFormatter() formatter.allowedUnits = [.hour, .minute] formatter.zeroFormattingBehavior = .pad return formatter.string(from: time) ?? "00:00" } - + private func cellAltitudeDifferenceFormatter(_ number: Double) -> String { guard number < 10000 else { return "9,999+" } guard number > 1 else { return "-" } return self.intFormatter(Int(number)) } - + private func stepsFormatter(_ number: Int) -> String { if number < 10000 { return self.intFormatter(number) @@ -143,13 +143,13 @@ extension ResultViewModel { return self.doubleFormatter(number) + "만" } } - + private func intFormatter(_ number: Int) -> String { let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .decimal return numberFormatter.string(from: NSNumber(value: number)) ?? "Error" } - + private func doubleFormatter(_ number: Double) -> String { let numberFormatter = NumberFormatter() numberFormatter.minimumFractionDigits = 2 diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 08ebbf0..4710cd7 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -13,7 +13,7 @@ extension UILabel { self.font = .systemFont(ofSize: normalFontWithSize) self.textColor = withTextColor } - + fileprivate convenience init(boldFontWithSize: CGFloat, withTextColor: UIColor) { self.init() self.font = .boldSystemFont(ofSize: boldFontWithSize) @@ -27,25 +27,25 @@ class SectionHeaderView: UICollectionReusableView { let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) let distanceLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) let timeLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) - + func configure(month: String, count: String, distance: String, time: String) { self.backgroundColor = .systemBackground self.monthLabel.text = month self.countLabel.text = count self.distanceLabel.text = distance self.timeLabel.text = time - + self.configureSubviews() self.configureLayout() } - - private func configureSubviews(){ + + private func configureSubviews() { self.addSubview(self.monthLabel) self.addSubview(self.countLabel) self.addSubview(self.distanceLabel) self.addSubview(self.timeLabel) } - + private func configureLayout() { self.monthLabel.translatesAutoresizingMaskIntoConstraints = false self.countLabel.translatesAutoresizingMaskIntoConstraints = false @@ -66,7 +66,7 @@ class SectionHeaderView: UICollectionReusableView { // MARK: - Accessibility extension SectionHeaderView { - + func configureVoiceOverAccessibility(date: String) { guard let countLabel = self.countLabel.text else { return } guard let distanceLabel = self.distanceLabel.text else { return } diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index 17f93ec..2436ab3 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -12,7 +12,7 @@ extension UILabel { self.init() self.font = .systemFont(ofSize: normalFontWithSize) } - + fileprivate convenience init(text: String, normalFontWithSize: CGFloat) { self.init() self.text = text @@ -34,19 +34,19 @@ class TotalRecordsViewCell: UICollectionViewCell { let countVerticalStackView = UIStackView() let timeVerticalStackView = UIStackView() let stepsVerticalStackView = UIStackView() - + func configure(distance: String, count: String, time: String, steps: String) { self.kilometerNumber.text = distance self.countNumber.text = count self.timeNumber.text = time self.stepsNumber.text = steps self.backgroundColor = .systemGray6 - + self.configureSubviews() self.configureLayout() self.configureShadow() } - + private func configureSubviews() { self.addSubview(self.kilometerNumber) self.addSubview(self.kilometer) @@ -68,7 +68,7 @@ class TotalRecordsViewCell: UICollectionViewCell { $0.spacing = 5 } } - + private func configureLayout() { self.kilometerNumber.translatesAutoresizingMaskIntoConstraints = false self.kilometer.translatesAutoresizingMaskIntoConstraints = false @@ -84,7 +84,7 @@ class TotalRecordsViewCell: UICollectionViewCell { self.horizontalStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -30) ]) } - + private func configureShadow() { let border = CALayer() border.frame = CGRect.init(x: 0, y: self.frame.height, width: self.frame.width, height: -1) @@ -96,7 +96,7 @@ class TotalRecordsViewCell: UICollectionViewCell { // MARK: - Accessibility extension TotalRecordsViewCell { - + func configureVoiceOverAccessibility() { guard let kilometerNumber = kilometerNumber.text else { return } guard let countNumber = countNumber.text else { return } diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 1fd8ee6..4b748ce 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -8,7 +8,7 @@ import UIKit class MapOptionCell: UITableViewCell { - + static let identifier = "MapOptionCell" private(set) var title: UILabel = { @@ -22,7 +22,7 @@ class MapOptionCell: UITableViewCell { label.adjustsFontSizeToFitWidth = true return label }() - + private var map: UILabel = { let label = PaddingLabel() label.padding(top: 5, bottom: 5, left: 10, right: 10) @@ -38,7 +38,7 @@ class MapOptionCell: UITableViewCell { label.setContentCompressionResistancePriority(.init(rawValue: 1000), for: .horizontal) return label }() - + private lazy var stackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.title, self.map]) stackView.translatesAutoresizingMaskIntoConstraints = false @@ -47,28 +47,26 @@ class MapOptionCell: UITableViewCell { stackView.distribution = .equalCentering return stackView }() - - + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.configureView() } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func configureView() { self.contentView.addSubview(self.stackView) - let locationConstrain = [ + NSLayoutConstraint.activate([ self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), self.stackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -15), self.stackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), - self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), - ] - NSLayoutConstraint.activate(locationConstrain) + self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30) + ]) } - + func update(option: MapOption) { self.title.text = option.text self.map.text = option.map.name @@ -82,13 +80,13 @@ extension MapOptionCell { self.configureDynamicTypeAccessibility() self.configureVoiceOverAccessibility() } - + private func configureDynamicTypeAccessibility() { self.stackView.axis = self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? .horizontal : .vertical } - + private func configureVoiceOverAccessibility() { self.map.isAccessibilityElement = false guard let title = title.text, let map = map.text else { return } diff --git a/SanTa/SanTa/SettingsScene/Option.swift b/SanTa/SanTa/SettingsScene/Option.swift index 2b8a9f4..93376a8 100644 --- a/SanTa/SanTa/SettingsScene/Option.swift +++ b/SanTa/SanTa/SettingsScene/Option.swift @@ -12,7 +12,7 @@ enum Map: String, CaseIterable { case infomation = "정보지도" case normal = "일반지도" case satellite = "위성지도" - + var name: String { return self.rawValue } diff --git a/SanTa/SanTa/SettingsScene/PaddingLabel.swift b/SanTa/SanTa/SettingsScene/PaddingLabel.swift index aec34d3..4bb8753 100644 --- a/SanTa/SanTa/SettingsScene/PaddingLabel.swift +++ b/SanTa/SanTa/SettingsScene/PaddingLabel.swift @@ -8,9 +8,9 @@ import UIKit class PaddingLabel: UILabel { - + var insets = UIEdgeInsets.zero - + convenience init(insets: UIEdgeInsets) { self.init() self.padding(top: insets.top, bottom: insets.bottom, left: insets.left, right: insets.right) @@ -19,7 +19,7 @@ class PaddingLabel: UILabel { override func drawText(in rect: CGRect) { super.drawText(in: rect.inset(by: self.insets)) } - + override var intrinsicContentSize: CGSize { get { var contentSize = super.intrinsicContentSize diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/SettingsScene/Settings.swift index 8f4737e..d0b5fa8 100644 --- a/SanTa/SanTa/SettingsScene/Settings.swift +++ b/SanTa/SanTa/SettingsScene/Settings.swift @@ -11,11 +11,11 @@ enum Settings: String, CaseIterable { case recordPhoto = "사진 기록하기" case voiceGuidanceEveryOnekm = "1킬로미터 마다 음성 안내" case mapFormat = "지도 형식" - + var title: String { return self.rawValue } - + var initValue: Any { switch self { case .recordPhoto: diff --git a/SanTa/SanTa/SettingsScene/SettingsRepository.swift b/SanTa/SanTa/SettingsScene/SettingsRepository.swift index 356b2fd..1590573 100644 --- a/SanTa/SanTa/SettingsScene/SettingsRepository.swift +++ b/SanTa/SanTa/SettingsScene/SettingsRepository.swift @@ -14,24 +14,24 @@ protocol SettingsRepository { } final class DefaultSettingsRepository: SettingsRepository { - + let settingsStorage: UserDefaultsStorage - + init(settingsStorage: UserDefaultsStorage) { self.settingsStorage = settingsStorage } - + func save(value: T, key: Settings) { self.settingsStorage.save(value: value, key: key) } - + func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) { self.settingsStorage.bool(key: key) { value in let option = ToggleOption(text: key.title, toggle: value) completion(option) } } - + func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) { self.settingsStorage.string(key: key) { value in guard let value = value else { return } diff --git a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift index 74479df..749ac3b 100644 --- a/SanTa/SanTa/SettingsScene/SettingsUsecase.swift +++ b/SanTa/SanTa/SettingsScene/SettingsUsecase.swift @@ -10,15 +10,15 @@ import Photos final class SettingsUsecase { private let settingsRepository: SettingsRepository - + init(settingsRepository: SettingsRepository) { self.settingsRepository = settingsRepository } - + func save(value: T, key: Settings) { self.settingsRepository.save(value: value, key: key) } - + func photoPermission(completion: @escaping (Bool) -> Void) { let photoPermission = PHPhotoLibrary.authorizationStatus(for: .readWrite) switch photoPermission { @@ -28,10 +28,10 @@ final class SettingsUsecase { completion(false) } } - + func makeSettings() -> [Option] { var options: [Option] = [] - + self.settingsRepository.makeToggleOption(key: Settings.recordPhoto) { value in options.append(value) } @@ -41,8 +41,7 @@ final class SettingsUsecase { self.settingsRepository.makeMapOption(key: Settings.mapFormat) { value in options.append(value) } - + return options } } - diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index fdb616d..e495597 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -17,7 +17,7 @@ class SettingsViewController: UIViewController { headerView.backgroundColor = .systemBackground return headerView }() - + private var headerTitle: UILabel = { let headerTitle = UILabel() headerTitle.translatesAutoresizingMaskIntoConstraints = false @@ -35,15 +35,15 @@ class SettingsViewController: UIViewController { tableView.backgroundColor = .systemGray5 return tableView }() - + private var viewModel: SettingsViewModel? private var subscriptions = Set() - + convenience init(viewModel: SettingsViewModel) { self.init() self.viewModel = viewModel } - + override func viewDidLoad() { super.viewDidLoad() self.configureTableView() @@ -51,7 +51,7 @@ class SettingsViewController: UIViewController { self.bind() self.viewModel?.viewDidLoad() } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.viewModel?.viewWillAppear() @@ -61,35 +61,33 @@ class SettingsViewController: UIViewController { self.tableView.dataSource = self self.tableView.delegate = self } - + private func configureView() { self.view.backgroundColor = .systemBackground self.view.addSubview(self.headerView) - let headerViewConstrain = [ + self.view.addSubview(self.tableView) + self.headerView.addSubview(self.headerTitle) + + NSLayoutConstraint.activate([ self.headerView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), self.headerView.leftAnchor.constraint(equalTo: self.view.leftAnchor), self.headerView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - self.headerView.heightAnchor.constraint(equalToConstant: 50.0), - ] - NSLayoutConstraint.activate(headerViewConstrain) - - self.headerView.addSubview(self.headerTitle) - let headerTitleConstrain = [ + self.headerView.heightAnchor.constraint(equalToConstant: 50.0) + ]) + + NSLayoutConstraint.activate([ self.headerTitle.centerXAnchor.constraint(equalTo: self.headerView.centerXAnchor), - self.headerTitle.centerYAnchor.constraint(equalTo: self.headerView.centerYAnchor), - ] - NSLayoutConstraint.activate(headerTitleConstrain) - - self.view.addSubview(self.tableView) - let tableViewConstrain = [ + self.headerTitle.centerYAnchor.constraint(equalTo: self.headerView.centerYAnchor) + ]) + + NSLayoutConstraint.activate([ self.tableView.topAnchor.constraint(equalTo: self.headerView.bottomAnchor), self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), self.tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor), - self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor), - ] - NSLayoutConstraint.activate(tableViewConstrain) + self.tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor) + ]) } - + private func bind() { self.viewModel?.$settings.sink { [weak self] _ in self?.tableView.reloadData() @@ -98,7 +96,7 @@ class SettingsViewController: UIViewController { self?.configurePhotoPermission(bool) }.store(in: &self.subscriptions) } - + private func configurePhotoPermission(_ bool: Bool) { if !bool { let alert = UIAlertController(title: "사진 권한 활성화", message: "측정하는 동안 사진을 기록할 수 있도록 위치정보를 활성화해주세요", preferredStyle: .alert) @@ -114,7 +112,7 @@ class SettingsViewController: UIViewController { } } } - + private func showMapActionSheet(cellTitle: String) { let alert = UIAlertController(title: Settings.mapFormat.title, message: nil, preferredStyle: .actionSheet) Map.allCases.forEach { @@ -130,16 +128,16 @@ class SettingsViewController: UIViewController { } extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { - + func numberOfSections(in tableView: UITableView) -> Int { guard let itemCount = self.viewModel?.settingsCount else { return 0 } return itemCount } - + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } - + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { switch self.viewModel?.settings[indexPath.section] { case let option as ToggleOption: @@ -171,13 +169,13 @@ extension SettingsViewController: UITableViewDataSource, UITableViewDelegate { guard let cell = tableView.cellForRow(at: indexPath) as? ToggleOptionCell else { return } cell.changeSwitch() } - + guard let cell = tableView.cellForRow(at: indexPath) as? MapOptionCell else { return } guard let title = cell.title.text else { return } self.showMapActionSheet(cellTitle: title) self.tableView.deselectRow(at: indexPath, animated: true) } - + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension } diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 4d70cd9..89ae73a 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -10,15 +10,15 @@ import UIKit class SettingsViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] - + private var userDefaultsStorage: UserDefaultsStorage - + init(userDefaultsStorage: UserDefaultsStorage) { self.userDefaultsStorage = userDefaultsStorage } - + func start() { - + } func startPush() -> SettingsViewController { diff --git a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift index f3e5dc0..cc29657 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewModel.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewModel.swift @@ -9,24 +9,24 @@ import Foundation import Combine final class SettingsViewModel { - + @Published var settings: [Option] = [] - + let settingsUseCase: SettingsUsecase let isPhotoRecordAvailable = PassthroughSubject() - + var settingsCount: Int { return settings.count } - + init(settingsUseCase: SettingsUsecase) { self.settingsUseCase = settingsUseCase } - + func viewDidLoad() { self.reloadSettings() } - + func viewWillAppear() { self.settingsUseCase.photoPermission { [weak self] bool in if !bool { @@ -35,7 +35,7 @@ final class SettingsViewModel { } } } - + func change(value: T, key: Settings) { self.settingsUseCase.save(value: value, key: key) if value is String { @@ -51,7 +51,7 @@ final class SettingsViewModel { } } } - + private func reloadSettings() { self.settings = self.settingsUseCase.makeSettings() } diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 5f3af96..94e8db4 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -12,11 +12,11 @@ protocol ToggleOptionCellDelegate: AnyObject { } class ToggleOptionCell: UITableViewCell { - + static let identifier = "ToggleOptionCell" - + weak var delegate: ToggleOptionCellDelegate? - + private var title: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body) @@ -28,7 +28,7 @@ class ToggleOptionCell: UITableViewCell { label.adjustsFontSizeToFitWidth = true return label }() - + private var controlSwitch: UISwitch = { let controlSwitch = UISwitch() controlSwitch.translatesAutoresizingMaskIntoConstraints = false @@ -37,7 +37,7 @@ class ToggleOptionCell: UITableViewCell { controlSwitch.setContentCompressionResistancePriority(.init(rawValue: 1000), for: .horizontal) return controlSwitch }() - + private lazy var stackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [self.title, self.controlSwitch]) stackView.translatesAutoresizingMaskIntoConstraints = false @@ -45,13 +45,13 @@ class ToggleOptionCell: UITableViewCell { stackView.alignment = .center return stackView }() - + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.selectionStyle = .none self.configureView() } - + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -62,23 +62,22 @@ class ToggleOptionCell: UITableViewCell { title: title, switchOn: self.controlSwitch.isOn) } - + private func configureView() { self.contentView.addSubview(self.stackView) - let locationConstrain = [ + NSLayoutConstraint.activate([ self.stackView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 15), self.stackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -15), self.stackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 30), - self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30), - ] - NSLayoutConstraint.activate(locationConstrain) + self.stackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -30) + ]) } - + func update(option: ToggleOption) { self.title.text = option.text self.controlSwitch.isOn = option.toggle } - + func changeSwitch() { self.controlSwitch.isOn.toggle() self.onClickSwitch(sender: self.controlSwitch) @@ -93,13 +92,13 @@ extension ToggleOptionCell { self.configureDynamicTypeAccessibility() self.configureVoiceOverAccessibility() } - + private func configureDynamicTypeAccessibility() { self.stackView.axis = self.traitCollection.preferredContentSizeCategory < .accessibilityLarge ? .horizontal : .vertical } - + private func configureVoiceOverAccessibility() { self.controlSwitch.isAccessibilityElement = false guard let title = title.text else { return } diff --git a/SanTa/SettingsSceneTests/SettingsSceneTests.swift b/SanTa/SettingsSceneTests/SettingsSceneTests.swift index 1171cd1..54e3055 100644 --- a/SanTa/SettingsSceneTests/SettingsSceneTests.swift +++ b/SanTa/SettingsSceneTests/SettingsSceneTests.swift @@ -8,42 +8,42 @@ import XCTest class SettingsViewModelTests: XCTestCase { - + class MockRepository: SettingsRepository { - func save(value: T, key: Settings) where T : Decodable, T : Encodable { - + func save(value: T, key: Settings) where T: Decodable, T: Encodable { + } - + func makeToggleOption(key: Settings, completion: @escaping (Option) -> Void) { completion(ToggleOption(text: "토글", toggle: true)) } - + func makeMapOption(key: Settings, completion: @escaping (Option) -> Void) { completion(MapOption(text: "맵", map: .infomation)) } } - + private var viewModel: SettingsViewModel! private var useCase: SettingsUsecase! - + override func setUpWithError() throws { useCase = SettingsUsecase(settingsRepository: MockRepository()) viewModel = SettingsViewModel(settingsUseCase: useCase) } - + func test_ViewModel은_viewDidLoad시_UseCase의_반환값_settings프로퍼티에_세팅() throws { viewModel.viewDidLoad() XCTAssertEqual(viewModel.settingsCount, 3) } - + func test_ViewModel은_change호출시_문자열이면_settings프로퍼티_업데이트() throws { viewModel.change(value: 1, key: .mapFormat) XCTAssertEqual(viewModel.settingsCount, 0) - + viewModel.change(value: "string", key: .mapFormat) XCTAssertEqual(viewModel.settingsCount, 3) } - + func test_UseCase는_repository반환_값에_따른_배열생성() { let options = useCase.makeSettings() From 83337c68626a2c6d08bc2cfa741bcacdc82b9aea Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 11:38:29 +0900 Subject: [PATCH 446/465] =?UTF-8?q?[Refactor]=20#356=20=EC=83=81=EC=86=8D?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20class=EB=8A=94=20final=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingSceneTests/RecordingUseCaseTests.swift | 2 +- .../RecordingViewModelTests.swift | 2 +- SanTa/ResultSceneTests/ResultSceneTests.swift | 2 +- SanTa/SanTa/Application/AppCoordinator.swift | 2 +- SanTa/SanTa/Application/AppDelegate.swift | 2 +- SanTa/SanTa/Application/SceneDelegate.swift | 2 +- SanTa/SanTa/MapScene/ClusterAnnotationView.swift | 2 +- SanTa/SanTa/MapScene/MapViewController.swift | 2 +- SanTa/SanTa/MapScene/MapViewCoordinator.swift | 2 +- SanTa/SanTa/MapScene/MapViewRepository.swift | 2 +- SanTa/SanTa/MapScene/MapViewUseCase.swift | 2 +- SanTa/SanTa/MapScene/MountainAnnotation.swift | 2 +- SanTa/SanTa/MapScene/MountainAnnotationView.swift | 2 +- .../MountainAddingScene/MountainAddingView.swift | 2 +- .../MountainAddingViewController.swift | 2 +- .../MountainAddingViewCoordinator.swift | 2 +- .../MountainAddingViewModel.swift | 2 +- .../MountainAddingViewRepository.swift | 2 +- .../MountainAddingViewUseCase.swift | 2 +- .../MountainDetailAnnotationView.swift | 2 +- .../MountainDetailTableViewCell.swift | 2 +- .../MountainDetailTitleView.swift | 2 +- .../MountainDetailScene/MountainDetailUseCase.swift | 2 +- .../MountainDetailViewController.swift | 2 +- .../MountainDetailViewCoordinator.swift | 2 +- .../MountainDetailViewModel.swift | 2 +- .../MountainListViewController.swift | 2 +- .../MountainListViewCoordinator.swift | 2 +- .../MountainListViewRepository.swift | 2 +- SanTa/SanTa/Persistences/MountainExtractor.swift | 2 +- .../RecordingPhotoCoordinator.swift | 2 +- .../RecordingPhotoViewController.swift | 2 +- SanTa/SanTa/RecordingScene/Record.swift | 4 ++-- .../RecordingScene/RecordingViewController.swift | 2 +- .../RecordingScene/RecordingViewCoordinator.swift | 2 +- .../RecordingTitleViewController.swift | 2 +- .../RecordingTitleViewCoordinator.swift | 2 +- .../ResultDetailImagesScene/DetailImagesCell.swift | 2 +- .../ResultDetailImagesViewController.swift | 2 +- .../ResultDetailImagesViewCoordinator.swift | 2 +- SanTa/SanTa/ResultDetailScene/DetailCell.swift | 2 +- SanTa/SanTa/ResultDetailScene/DetailHeader.swift | 2 +- SanTa/SanTa/ResultDetailScene/PinView.swift | 2 +- .../ResultDetailLargerInfoView.swift | 2 +- .../ResultDetailScene/ResultDetailRepository.swift | 2 +- .../ResultDetailSmallerInfoView.swift | 2 +- .../ResultDetailScene/ResultDetailUseCase.swift | 2 +- .../ResultDetailViewController.swift | 2 +- .../ResultDetailViewCoordinator.swift | 2 +- .../ResultDetailScene/ResultDetailViewModel.swift | 12 ++++++------ .../ResultDetailThumbnailViewController.swift | 2 +- .../ResultDetailThumbnailViewCoordinator.swift | 2 +- SanTa/SanTa/ResultScene/RecordsViewCell.swift | 2 +- SanTa/SanTa/ResultScene/ResultViewController.swift | 2 +- SanTa/SanTa/ResultScene/ResultViewCoordinator.swift | 2 +- SanTa/SanTa/ResultScene/ResultViewModel.swift | 2 +- SanTa/SanTa/ResultScene/SectionHeaderView.swift | 2 +- SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift | 2 +- SanTa/SanTa/SettingsScene/MapOptionCell.swift | 2 +- SanTa/SanTa/SettingsScene/PaddingLabel.swift | 2 +- .../SanTa/SettingsScene/SettingsViewController.swift | 2 +- .../SettingsScene/SettingsViewCoordinator.swift | 2 +- SanTa/SanTa/SettingsScene/ToggleOptionCell.swift | 2 +- SanTa/SettingsSceneTests/SettingsSceneTests.swift | 2 +- 64 files changed, 70 insertions(+), 70 deletions(-) diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index a8e7240..c1e8de7 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -7,7 +7,7 @@ import XCTest -class RecordingUseCaseTests: XCTestCase { +final class RecordingUseCaseTests: XCTestCase { private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! diff --git a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift index 07c758a..16ba9bd 100644 --- a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift +++ b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift @@ -8,7 +8,7 @@ import XCTest import Combine -class RecordingViewModelTests: XCTestCase { +final class RecordingViewModelTests: XCTestCase { private let recordingUseCase: RecordingUseCase? = nil private var subscriptions = Set() diff --git a/SanTa/ResultSceneTests/ResultSceneTests.swift b/SanTa/ResultSceneTests/ResultSceneTests.swift index 9ad711f..bb62a1f 100644 --- a/SanTa/ResultSceneTests/ResultSceneTests.swift +++ b/SanTa/ResultSceneTests/ResultSceneTests.swift @@ -7,7 +7,7 @@ import XCTest -class ResultSceneTests: XCTestCase { +final class ResultSceneTests: XCTestCase { class MockRepository: ResultRepository { func fetch(completion: @escaping (Result<[Records], Error>) -> Void) { diff --git a/SanTa/SanTa/Application/AppCoordinator.swift b/SanTa/SanTa/Application/AppCoordinator.swift index 37a3636..d1b7ac3 100644 --- a/SanTa/SanTa/Application/AppCoordinator.swift +++ b/SanTa/SanTa/Application/AppCoordinator.swift @@ -13,7 +13,7 @@ protocol Coordinator: AnyObject { func start () } -class AppCoordinator: NSObject, Coordinator { +final class AppCoordinator: NSObject, Coordinator { var childCoordinators: [Coordinator] = [] let window: UIWindow? diff --git a/SanTa/SanTa/Application/AppDelegate.swift b/SanTa/SanTa/Application/AppDelegate.swift index 6005b27..f39dd00 100644 --- a/SanTa/SanTa/Application/AppDelegate.swift +++ b/SanTa/SanTa/Application/AppDelegate.swift @@ -10,7 +10,7 @@ import CoreData import AVFoundation @main -class AppDelegate: UIResponder, UIApplicationDelegate { +final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.duckOthers]) try? AVAudioSession.sharedInstance().setActive(true) diff --git a/SanTa/SanTa/Application/SceneDelegate.swift b/SanTa/SanTa/Application/SceneDelegate.swift index 5918a27..5bd3acc 100644 --- a/SanTa/SanTa/Application/SceneDelegate.swift +++ b/SanTa/SanTa/Application/SceneDelegate.swift @@ -7,7 +7,7 @@ import UIKit -class SceneDelegate: UIResponder, UIWindowSceneDelegate { +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? var appCoordinator: AppCoordinator? diff --git a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift index deb9abe..6d268dd 100644 --- a/SanTa/SanTa/MapScene/ClusterAnnotationView.swift +++ b/SanTa/SanTa/MapScene/ClusterAnnotationView.swift @@ -7,7 +7,7 @@ import MapKit -class ClusterAnnotationView: MKAnnotationView { +final class ClusterAnnotationView: MKAnnotationView { override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) collisionMode = .circle diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index 4b781b7..e7c2ab2 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -12,7 +12,7 @@ protocol Animatable: AnyObject { func shouldStopAnimate() } -class MapViewController: UIViewController { +final class MapViewController: UIViewController { weak var coordinator: MapViewCoordinator? private var viewModel: MapViewModel? private var observers: [AnyCancellable] = [] diff --git a/SanTa/SanTa/MapScene/MapViewCoordinator.swift b/SanTa/SanTa/MapScene/MapViewCoordinator.swift index 5ae4c34..ee79efd 100644 --- a/SanTa/SanTa/MapScene/MapViewCoordinator.swift +++ b/SanTa/SanTa/MapScene/MapViewCoordinator.swift @@ -8,7 +8,7 @@ import UIKit import CoreLocation -class MapViewCoordinator: Coordinator { +final class MapViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController = UINavigationController() var childCoordinators: [Coordinator] = [] diff --git a/SanTa/SanTa/MapScene/MapViewRepository.swift b/SanTa/SanTa/MapScene/MapViewRepository.swift index 47b98cd..a75dc5f 100644 --- a/SanTa/SanTa/MapScene/MapViewRepository.swift +++ b/SanTa/SanTa/MapScene/MapViewRepository.swift @@ -12,7 +12,7 @@ protocol MapViewRepository { func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) } -class DefaultMapViewRespository { +final class DefaultMapViewRespository { enum JSONDecodeError: Error { case decodingFailed } diff --git a/SanTa/SanTa/MapScene/MapViewUseCase.swift b/SanTa/SanTa/MapScene/MapViewUseCase.swift index b845046..34c8327 100644 --- a/SanTa/SanTa/MapScene/MapViewUseCase.swift +++ b/SanTa/SanTa/MapScene/MapViewUseCase.swift @@ -9,7 +9,7 @@ import Foundation import OSLog import CoreLocation -class MapViewUseCase: NSObject { +final class MapViewUseCase: NSObject { private let repository: MapViewRepository private let manager = CLLocationManager() var initialLocation: (CLLocation) -> Void diff --git a/SanTa/SanTa/MapScene/MountainAnnotation.swift b/SanTa/SanTa/MapScene/MountainAnnotation.swift index 87fa569..2bc5c66 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotation.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotation.swift @@ -7,7 +7,7 @@ import MapKit -class MountainAnnotation: NSObject, MKAnnotation { +final class MountainAnnotation: NSObject, MKAnnotation { var title: String? var subtitle: String? var latitude: Double diff --git a/SanTa/SanTa/MapScene/MountainAnnotationView.swift b/SanTa/SanTa/MapScene/MountainAnnotationView.swift index 2038264..992d32e 100644 --- a/SanTa/SanTa/MapScene/MountainAnnotationView.swift +++ b/SanTa/SanTa/MapScene/MountainAnnotationView.swift @@ -8,7 +8,7 @@ import UIKit import MapKit -class MountainAnnotationView: MKAnnotationView { +final class MountainAnnotationView: MKAnnotationView { static let ReuseID = "MountainAnnotation" override init(annotation: MKAnnotation?, reuseIdentifier: String?) { diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift index 378b992..3f684ac 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingView.swift @@ -12,7 +12,7 @@ protocol NewPlaceAddable: AnyObject { func newPlaceShouldAdd(title: String, description: String) } -class MountainAddingView: UIScrollView { +final class MountainAddingView: UIScrollView { private let titleLabel: UILabel = { let label = UILabel() diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index cd11aae..a2917bf 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -8,7 +8,7 @@ import MapKit import Combine -class MountainAddingViewController: UIViewController { +final class MountainAddingViewController: UIViewController { weak var coordinator: MountainAddingViewCoordinator? private var viewModel: MountainAddingViewModel? private var observers: [AnyCancellable] = [] diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift index daa423b..f7865be 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class MountainAddingViewCoordinator: Coordinator { +final class MountainAddingViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift index 5f58b5a..075a847 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewModel.swift @@ -9,7 +9,7 @@ import Combine import CoreLocation import AVFoundation -class MountainAddingViewModel { +final class MountainAddingViewModel { private var useCase: MountainAddingViewUseCase? @Published private(set) var coordinate: CLLocationCoordinate2D? private(set) var altitude: CLLocationDistance? diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift index 3ea6b4d..976f759 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewRepository.swift @@ -11,7 +11,7 @@ protocol MountainAddingRepository { func save(_ mountainEntity: MountainEntity, completion: @escaping(Result) -> Void) } -class DefaultMountainAddingRepository: MountainAddingRepository { +final class DefaultMountainAddingRepository: MountainAddingRepository { private let coreDataMountainStorage: CoreDataMountainStorage init(coreDataMountainStorage: CoreDataMountainStorage) { diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift index c490a31..cf3f93b 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewUseCase.swift @@ -9,7 +9,7 @@ import Foundation import CoreLocation import OSLog -class MountainAddingViewUseCase { +final class MountainAddingViewUseCase { private let repository: MountainAddingRepository init(repository: MountainAddingRepository) { diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift index 3505bc1..e390a97 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailAnnotationView.swift @@ -8,7 +8,7 @@ import UIKit import MapKit -class MountainnDetailAnnotationView: MKAnnotationView { +final class MountainnDetailAnnotationView: MKAnnotationView { static let ReuseID = "MountainDetailAnnotationView" let imageSideLength: CGFloat = 30 diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift index e49879b..b335844 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTableViewCell.swift @@ -7,7 +7,7 @@ import UIKit -class MountainDetailTableViewCell: UITableViewCell { +final class MountainDetailTableViewCell: UITableViewCell { static let identifier = "MountainDetailTableViewCellID" let categoryLabel = PaddingLabel(insets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift index b67f843..d5ae5ce 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailTitleView.swift @@ -7,7 +7,7 @@ import UIKit -class MountainDetailTitleView: UIView { +final class MountainDetailTitleView: UIView { private let titleLabel = UILabel() private let distanceLabel = UILabel() diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift index 1a75ac3..dad0d3c 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailUseCase.swift @@ -8,7 +8,7 @@ import Foundation import CoreLocation -class MountainDetailUseCase { +final class MountainDetailUseCase { private let mountainAnnotation: MountainAnnotation private let manager = CLLocationManager() diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift index 8150094..3d7f45e 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewController.swift @@ -8,7 +8,7 @@ import UIKit import MapKit -class MountainDetailViewController: UIViewController { +final class MountainDetailViewController: UIViewController { weak var coordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? private var mutatingTopConstraint: NSLayoutConstraint? diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift index 7220a99..04bfc61 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewCoordinator.swift @@ -8,7 +8,7 @@ import UIKit import CoreLocation -class MountainDetailViewCoordinator: Coordinator { +final class MountainDetailViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController diff --git a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift index 1aaaa85..df56fb6 100644 --- a/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift +++ b/SanTa/SanTa/MountainDetailScene/MountainDetailViewModel.swift @@ -7,7 +7,7 @@ import Foundation -class MountainDetailViewModel { +final class MountainDetailViewModel { private let useCase: MountainDetailUseCase var mountainDetail: MountainDetailModel? var mountainInfoReceived: (MountainDetailModel) -> Void = { _ in } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewController.swift b/SanTa/SanTa/MountainListScene/MountainListViewController.swift index e8aacbd..bf6d9ef 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewController.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewController.swift @@ -9,7 +9,7 @@ import UIKit import Combine import CoreLocation -class MountainListViewController: UIViewController { +final class MountainListViewController: UIViewController { enum MountainListSection: Int, CaseIterable { case main } diff --git a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift index 3bab7b0..ddf848c 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewCoordinator.swift @@ -8,7 +8,7 @@ import UIKit import CoreLocation -class MountainListViewCoordinator: Coordinator { +final class MountainListViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController = UINavigationController() diff --git a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift index bc3920e..a90cafa 100644 --- a/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift +++ b/SanTa/SanTa/MountainListScene/MountainListViewRepository.swift @@ -11,7 +11,7 @@ protocol MountainListViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) } -class DefaultMountainListViewReposiory { +final class DefaultMountainListViewReposiory { enum JSONDecodeError: Error { case decodingFailed } diff --git a/SanTa/SanTa/Persistences/MountainExtractor.swift b/SanTa/SanTa/Persistences/MountainExtractor.swift index 6ce6ce9..e809c7b 100644 --- a/SanTa/SanTa/Persistences/MountainExtractor.swift +++ b/SanTa/SanTa/Persistences/MountainExtractor.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -class MountainExtractor { +final class MountainExtractor { enum ExtractError: Error { case extractionFailed diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift index 07a9af2..117c711 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class RecordingPhotoViewCoordinator: Coordinator { +final class RecordingPhotoViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var recordingPhotoViewController: RecordingPhotoViewController diff --git a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift index a528397..a93352d 100644 --- a/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift +++ b/SanTa/SanTa/RecordingPhotoScene/RecordingPhotoViewController.swift @@ -7,7 +7,7 @@ import UIKit -class RecordingPhotoViewController: UIViewController { +final class RecordingPhotoViewController: UIViewController { weak var coordinator: RecordingPhotoViewCoordinator? weak var delegate: RecordingViewDelegate? diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/RecordingScene/Record.swift index 617413f..b99be4b 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/RecordingScene/Record.swift @@ -8,7 +8,7 @@ import Foundation import CoreLocation -class TotalRecords { +final class TotalRecords { private(set) var totalRecords: [DateSeperateRecords] = [] private var mappingDateSeperateRecords: [String: DateSeperateRecords] = [:] @@ -55,7 +55,7 @@ class TotalRecords { } } -class DateSeperateRecords { +final class DateSeperateRecords { let year: Int let month: Int diff --git a/SanTa/SanTa/RecordingScene/RecordingViewController.swift b/SanTa/SanTa/RecordingScene/RecordingViewController.swift index 8a1cdea..8277fef 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewController.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewController.swift @@ -17,7 +17,7 @@ protocol RecordingViewDelegate: SetTitleDelegate { func didAgreeButtonTouchDone() } -class RecordingViewController: UIViewController { +final class RecordingViewController: UIViewController { weak var coordinator: RecordingViewCoordinator? let kilometerLabel: UILabel = { diff --git a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift index 3be99ab..0ecef7f 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class RecordingViewCoordinator: Coordinator { +final class RecordingViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var navigationController: UINavigationController var childCoordinators: [Coordinator] = [] diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index a4b76dd..b157e51 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -7,7 +7,7 @@ import UIKit -class RecordingTitleViewController: UIViewController { +final class RecordingTitleViewController: UIViewController { weak var coordinator: RecordingTitleViewCoordinator? weak var delegate: SetTitleDelegate? diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift index 2c2b7fe..6837634 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class RecordingTitleViewCoordinator: Coordinator { +final class RecordingTitleViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var recordingTitleViewController: RecordingTitleViewController diff --git a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift index 7d2a32f..07e9e39 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/DetailImagesCell.swift @@ -7,7 +7,7 @@ import UIKit -class DetailImagesCell: UICollectionViewCell { +final class DetailImagesCell: UICollectionViewCell { static let identifier = "DetailImagesCell" private let imageView = UIImageView() diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift index 7cd106e..8cd39bb 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewController.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailImagesViewController: UIViewController { +final class ResultDetailImagesViewController: UIViewController { weak var coordinator: ResultDetailImagesViewCoordinator? enum DetailImagesSection: Int, CaseIterable { diff --git a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift index e2ab3ca..58582cc 100644 --- a/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailImagesViewCoordinator: Coordinator { +final class ResultDetailImagesViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController diff --git a/SanTa/SanTa/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/ResultDetailScene/DetailCell.swift index c32e2aa..d7a73a4 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailCell.swift @@ -7,7 +7,7 @@ import UIKit -class DetailCell: UICollectionViewCell { +final class DetailCell: UICollectionViewCell { static let identifier = "DetailCell" let title: UILabel = { diff --git a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift index f77374f..d82f5af 100644 --- a/SanTa/SanTa/ResultDetailScene/DetailHeader.swift +++ b/SanTa/SanTa/ResultDetailScene/DetailHeader.swift @@ -7,7 +7,7 @@ import UIKit -class DetailHeader: UICollectionReusableView { +final class DetailHeader: UICollectionReusableView { static let identifier = "DetailHeader" private lazy var dateLabel: PaddingLabel = { diff --git a/SanTa/SanTa/ResultDetailScene/PinView.swift b/SanTa/SanTa/ResultDetailScene/PinView.swift index 48971f5..a51c04d 100644 --- a/SanTa/SanTa/ResultDetailScene/PinView.swift +++ b/SanTa/SanTa/ResultDetailScene/PinView.swift @@ -7,7 +7,7 @@ import MapKit -class PinView: MKAnnotationView { +final class PinView: MKAnnotationView { static let ReuseID = "PinView" override init(annotation: MKAnnotation?, reuseIdentifier: String?) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift index 1f7292c..3f0b70f 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailLargerInfoView.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailLargerInfoView: UIView { +final class ResultDetailLargerInfoView: UIView { enum DetailLargerInfoSection: Int, CaseIterable { case main } diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift index 22e8f64..dedfe60 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailRepository.swift @@ -12,7 +12,7 @@ protocol ResultDetailRepository { func delete(id: String, completion: @escaping (Result) -> Void) } -class DefaultResultDetailRepository: ResultDetailRepository { +final class DefaultResultDetailRepository: ResultDetailRepository { private let recordStorage: CoreDataRecordStorage init(recordStorage: CoreDataRecordStorage) { diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift index c41fe12..c927af7 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailSmallerInfoView: UIView { +final class ResultDetailSmallerInfoView: UIView { private let distance: UILabel = { let label = UILabel() diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift index 7c0f72c..9e15ff5 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailUseCase.swift @@ -7,7 +7,7 @@ import Foundation -class ResultDetailUseCase { +final class ResultDetailUseCase { private let model: ResultDetailData private let repository: ResultDetailRepository private(set) var isImageVisibilityOn: Bool diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift index 7800ee7..cefab74 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewController.swift @@ -10,7 +10,7 @@ import MapKit import Photos import Combine -class ResultDetailViewController: UIViewController { +final class ResultDetailViewController: UIViewController { weak var coordinator: ResultDetailViewCoordinator? diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift index af0fdd0..cec1951 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewCoordinator.swift @@ -6,7 +6,7 @@ // import UIKit -class ResultDetailViewCoordinator: Coordinator { +final class ResultDetailViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController diff --git a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift index 31a1e5c..028eb11 100644 --- a/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/ResultDetailScene/ResultDetailViewModel.swift @@ -8,7 +8,7 @@ import CoreLocation import Combine -class ResultDetailViewModel { +final class ResultDetailViewModel { private let useCase: ResultDetailUseCase var resultDetailData: ResultDetailData? var recordDidFetch: () -> Void @@ -140,7 +140,7 @@ class DetailInformationModel: Hashable { } extension ResultDetailViewModel { - class DistanceViewModel: DetailInformationModel { + final class DistanceViewModel: DetailInformationModel { var totalDistance: String = "-" var steps: String = "0" @@ -169,7 +169,7 @@ extension ResultDetailViewModel { } } - class TimeViewModel: DetailInformationModel { + final class TimeViewModel: DetailInformationModel { var totalTimeSpent: String = "" init(timeData: ResultTime?) { @@ -195,7 +195,7 @@ extension ResultDetailViewModel { } } - class PaceViewModel: DetailInformationModel { + final class PaceViewModel: DetailInformationModel { init(paceData: ResultPace?) { super.init() guard let pace = paceData else { @@ -218,7 +218,7 @@ extension ResultDetailViewModel { } } - class AltitudeViewModel: DetailInformationModel { + final class AltitudeViewModel: DetailInformationModel { var highest: String = "-" var lowest: String = "-" @@ -266,7 +266,7 @@ extension ResultDetailViewModel { } } - class InclineViewModel: DetailInformationModel { + final class InclineViewModel: DetailInformationModel { init(inclineData: ResultIncline?) { super.init() guard let inclineData = inclineData else { diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift index f1cceae..8e5ac35 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailThumbnailViewController: UIViewController { +final class ResultDetailThumbnailViewController: UIViewController { weak var coordinator: ResultDetailThumbnailViewCoordinator? enum DetailThumbnailSection: Int, CaseIterable { diff --git a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift index 0f6ef78..ca782b8 100644 --- a/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift +++ b/SanTa/SanTa/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class ResultDetailThumbnailViewCoordinator: Coordinator { +final class ResultDetailThumbnailViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController diff --git a/SanTa/SanTa/ResultScene/RecordsViewCell.swift b/SanTa/SanTa/ResultScene/RecordsViewCell.swift index aaa76dd..e49b342 100644 --- a/SanTa/SanTa/ResultScene/RecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/RecordsViewCell.swift @@ -21,7 +21,7 @@ extension UILabel { } } -class RecordsViewCell: UICollectionViewCell { +final class RecordsViewCell: UICollectionViewCell { static let identifier = "RecordsViewCell" let date: PaddingLabel = { let paddingLabel = PaddingLabel(insets: UIEdgeInsets(top: 2, left: 3, bottom: 2, right: 3)) diff --git a/SanTa/SanTa/ResultScene/ResultViewController.swift b/SanTa/SanTa/ResultScene/ResultViewController.swift index d828684..8fea020 100644 --- a/SanTa/SanTa/ResultScene/ResultViewController.swift +++ b/SanTa/SanTa/ResultScene/ResultViewController.swift @@ -7,7 +7,7 @@ import UIKit -class ResultViewController: UIViewController { +final class ResultViewController: UIViewController { weak var coordinator: ResultViewCoordinator? private var collectionView: UICollectionView? private var viewModel: ResultViewModel? diff --git a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift index 70854c6..b7f7db3 100644 --- a/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift +++ b/SanTa/SanTa/ResultScene/ResultViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class ResultViewCoordinator: Coordinator { +final class ResultViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] var navigationController: UINavigationController diff --git a/SanTa/SanTa/ResultScene/ResultViewModel.swift b/SanTa/SanTa/ResultScene/ResultViewModel.swift index a6238c8..1f29f4e 100644 --- a/SanTa/SanTa/ResultScene/ResultViewModel.swift +++ b/SanTa/SanTa/ResultScene/ResultViewModel.swift @@ -7,7 +7,7 @@ import Foundation -class ResultViewModel { +final class ResultViewModel { private let useCase: ResultUseCase var cellShouldUpdate: () -> Void var totalDistance: String { diff --git a/SanTa/SanTa/ResultScene/SectionHeaderView.swift b/SanTa/SanTa/ResultScene/SectionHeaderView.swift index 4710cd7..ef47923 100644 --- a/SanTa/SanTa/ResultScene/SectionHeaderView.swift +++ b/SanTa/SanTa/ResultScene/SectionHeaderView.swift @@ -21,7 +21,7 @@ extension UILabel { } } -class SectionHeaderView: UICollectionReusableView { +final class SectionHeaderView: UICollectionReusableView { static let identifier = "SectionHeaderView" let monthLabel = UILabel(boldFontWithSize: 17, withTextColor: .label) let countLabel = UILabel(normalFontWithSize: 15, withTextColor: .systemGray) diff --git a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift index 2436ab3..8f339bc 100644 --- a/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift +++ b/SanTa/SanTa/ResultScene/TotalRecordsViewCell.swift @@ -20,7 +20,7 @@ extension UILabel { } } -class TotalRecordsViewCell: UICollectionViewCell { +final class TotalRecordsViewCell: UICollectionViewCell { static let identifier = "TotalRecordsInfoCell" let kilometerNumber = UILabel(normalFontWithSize: 60) let kilometer = UILabel(text: "킬로미터", normalFontWithSize: 25) diff --git a/SanTa/SanTa/SettingsScene/MapOptionCell.swift b/SanTa/SanTa/SettingsScene/MapOptionCell.swift index 4b748ce..10cfff4 100644 --- a/SanTa/SanTa/SettingsScene/MapOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/MapOptionCell.swift @@ -7,7 +7,7 @@ import UIKit -class MapOptionCell: UITableViewCell { +final class MapOptionCell: UITableViewCell { static let identifier = "MapOptionCell" diff --git a/SanTa/SanTa/SettingsScene/PaddingLabel.swift b/SanTa/SanTa/SettingsScene/PaddingLabel.swift index 4bb8753..571c37d 100644 --- a/SanTa/SanTa/SettingsScene/PaddingLabel.swift +++ b/SanTa/SanTa/SettingsScene/PaddingLabel.swift @@ -7,7 +7,7 @@ import UIKit -class PaddingLabel: UILabel { +final class PaddingLabel: UILabel { var insets = UIEdgeInsets.zero diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index e495597..a750abd 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -8,7 +8,7 @@ import UIKit import Combine -class SettingsViewController: UIViewController { +final class SettingsViewController: UIViewController { weak var coordinator: SettingsViewCoordinator? private var headerView: UIView = { diff --git a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift index 89ae73a..1f82b9e 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewCoordinator.swift @@ -7,7 +7,7 @@ import UIKit -class SettingsViewCoordinator: Coordinator { +final class SettingsViewCoordinator: Coordinator { weak var parentCoordinator: Coordinator? var childCoordinators: [Coordinator] = [] diff --git a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift index 94e8db4..e00e933 100644 --- a/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift +++ b/SanTa/SanTa/SettingsScene/ToggleOptionCell.swift @@ -11,7 +11,7 @@ protocol ToggleOptionCellDelegate: AnyObject { func toggleOptionCellSwitchChanged(_ cell: ToggleOptionCell, title: String, switchOn: Bool) } -class ToggleOptionCell: UITableViewCell { +final class ToggleOptionCell: UITableViewCell { static let identifier = "ToggleOptionCell" diff --git a/SanTa/SettingsSceneTests/SettingsSceneTests.swift b/SanTa/SettingsSceneTests/SettingsSceneTests.swift index 54e3055..126d1a7 100644 --- a/SanTa/SettingsSceneTests/SettingsSceneTests.swift +++ b/SanTa/SettingsSceneTests/SettingsSceneTests.swift @@ -7,7 +7,7 @@ import XCTest -class SettingsViewModelTests: XCTestCase { +final class SettingsViewModelTests: XCTestCase { class MockRepository: SettingsRepository { func save(value: T, key: Settings) where T: Decodable, T: Encodable { From 55e3081a4507d44c86e3f7c91981209aef638609 Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 11:57:21 +0900 Subject: [PATCH 447/465] =?UTF-8?q?[Refactor]=20#356=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConfigureBindings --- SanTa/SanTa/MapScene/MapViewController.swift | 6 ++++-- .../MountainAddingScene/MountainAddingViewController.swift | 4 ++-- SanTa/SanTa/RecordingScene/RecordingViewModel.swift | 2 +- SanTa/SanTa/SettingsScene/SettingsViewController.swift | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/SanTa/SanTa/MapScene/MapViewController.swift b/SanTa/SanTa/MapScene/MapViewController.swift index e7c2ab2..8399742 100644 --- a/SanTa/SanTa/MapScene/MapViewController.swift +++ b/SanTa/SanTa/MapScene/MapViewController.swift @@ -82,7 +82,7 @@ final class MapViewController: UIViewController { super.viewDidLoad() self.configureViews() self.registerAnnotationView() - self.configureViewModel() + self.configureBindings() self.configureNotification() } @@ -102,12 +102,14 @@ final class MapViewController: UIViewController { self.startButton.bottomAnchor.constraint(equalTo: mapView.safeAreaLayoutGuide.bottomAnchor, constant: -mapView.frame.height/15), self.startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) ]) + NSLayoutConstraint.activate([ self.userTrackingButton.widthAnchor.constraint(equalToConstant: 50), self.userTrackingButton.heightAnchor.constraint(equalToConstant: 50), self.userTrackingButton.leftAnchor.constraint(equalTo: mapView.rightAnchor, constant: -100), self.userTrackingButton.centerYAnchor.constraint(equalTo: self.startButton.centerYAnchor) ]) + NSLayoutConstraint.activate([ self.newPlaceButton.widthAnchor.constraint(equalToConstant: 150), self.newPlaceButton.heightAnchor.constraint(equalToConstant: 30), @@ -127,7 +129,7 @@ final class MapViewController: UIViewController { ) } - private func configureViewModel() { + private func configureBindings() { self.viewModel?.configureBindings() self.viewModel?.$mountains .sink(receiveValue: { [weak self] mountains in diff --git a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift index a2917bf..c597428 100644 --- a/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift +++ b/SanTa/SanTa/MountainAddingScene/MountainAddingViewController.swift @@ -49,7 +49,7 @@ final class MountainAddingViewController: UIViewController { super.viewDidLoad() self.mountainAddingView.newPlaceDelegate = self self.configureViews() - self.configureViewModel() + self.configureBindings() } private func configureViews() { @@ -70,7 +70,7 @@ final class MountainAddingViewController: UIViewController { ]) } - private func configureViewModel() { + private func configureBindings() { self.viewModel?.$coordinate .sink(receiveValue: { [weak self] coordinate in self?.mapView.showsUserLocation = false diff --git a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift index 0518b66..0e9ab89 100644 --- a/SanTa/SanTa/RecordingScene/RecordingViewModel.swift +++ b/SanTa/SanTa/RecordingScene/RecordingViewModel.swift @@ -33,7 +33,7 @@ final class RecordingViewModel: ObservableObject { init(recordingUseCase: RecordingUseCase?) { self.recordingUseCase = recordingUseCase - configureBindings() + self.configureBindings() } private func configureBindings() { diff --git a/SanTa/SanTa/SettingsScene/SettingsViewController.swift b/SanTa/SanTa/SettingsScene/SettingsViewController.swift index a750abd..dce9474 100644 --- a/SanTa/SanTa/SettingsScene/SettingsViewController.swift +++ b/SanTa/SanTa/SettingsScene/SettingsViewController.swift @@ -48,7 +48,7 @@ final class SettingsViewController: UIViewController { super.viewDidLoad() self.configureTableView() self.configureView() - self.bind() + self.configureBindings() self.viewModel?.viewDidLoad() } @@ -88,7 +88,7 @@ final class SettingsViewController: UIViewController { ]) } - private func bind() { + private func configureBindings() { self.viewModel?.$settings.sink { [weak self] _ in self?.tableView.reloadData() }.store(in: &self.subscriptions) From 84b7430e3aa328b227394d6afbb61b8157d7965c Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 11:58:03 +0900 Subject: [PATCH 448/465] =?UTF-8?q?[Refactor]=20#357=20=EB=93=B1=EC=82=B0?= =?UTF-8?q?=20=EC=A0=9C=EB=AA=A9=2010=EC=9E=90=20=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingTitleScene/RecordingTitleViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift index b157e51..0daed00 100644 --- a/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift +++ b/SanTa/SanTa/RecordingTitleScene/RecordingTitleViewController.swift @@ -161,7 +161,7 @@ final class RecordingTitleViewController: UIViewController { extension RecordingTitleViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { guard let text = textField.text else { return false } - if text.count >= 20 && range.length == 0 && range.location >= 20 { + if text.count >= 10 && range.length == 0 && range.location >= 10 { return false } From df43cf504544bcfc4b34b44396780aa798b2bdfc Mon Sep 17 00:00:00 2001 From: Shin Date: Tue, 30 Nov 2021 12:03:56 +0900 Subject: [PATCH 449/465] =?UTF-8?q?[Refactor]=20#356=20SwiftLint=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/.swiftlint.yml | 1 - SanTa/SanTa.xcodeproj/project.pbxproj | 25 ------------------------- 2 files changed, 26 deletions(-) delete mode 100644 SanTa/.swiftlint.yml diff --git a/SanTa/.swiftlint.yml b/SanTa/.swiftlint.yml deleted file mode 100644 index 8b13789..0000000 --- a/SanTa/.swiftlint.yml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index 842e2d1..c9b688b 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -27,7 +27,6 @@ 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; - 540F8EBA2755B8860082FA3B /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 540F8EB92755B8860082FA3B /* .swiftlint.yml */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */; }; 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296944272FBC6E0070B362 /* AppCoordinator.swift */; }; @@ -157,7 +156,6 @@ 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewCoordinator.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; - 540F8EB92755B8860082FA3B /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewUseCase.swift; sourceTree = ""; }; 54296944272FBC6E0070B362 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; @@ -427,7 +425,6 @@ 54851275272A6AD500407F28 = { isa = PBXGroup; children = ( - 540F8EB92755B8860082FA3B /* .swiftlint.yml */, 54851280272A6AD500407F28 /* SanTa */, 9826F42E273953FB0064FA85 /* SettingsSceneTests */, DA854FDA2746273300E51E4B /* RecordingSceneTests */, @@ -555,7 +552,6 @@ 5485127A272A6AD500407F28 /* Sources */, 5485127B272A6AD500407F28 /* Frameworks */, 5485127C272A6AD500407F28 /* Resources */, - 540F8EB82755B8080082FA3B /* ShellScript */, ); buildRules = ( ); @@ -671,7 +667,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 540F8EBA2755B8860082FA3B /* .swiftlint.yml in Resources */, 54851291272A6AD600407F28 /* LaunchScreen.storyboard in Resources */, 5485128E272A6AD600407F28 /* Assets.xcassets in Resources */, 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */, @@ -701,26 +696,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 540F8EB82755B8080082FA3B /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\n\nif which swiftlint >/dev/null; then\n swiftlint autocorrect\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 5485127A272A6AD500407F28 /* Sources */ = { isa = PBXSourcesBuildPhase; From 437795443db028267a3d658892d205821c307df3 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 30 Nov 2021 14:13:59 +0900 Subject: [PATCH 450/465] =?UTF-8?q?[Refactor]=20#359=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 100 +++++----- .../Record.swift => Entities/Location.swift} | 176 +---------------- .../{SettingsScene => Entities}/Option.swift | 0 SanTa/SanTa/Entities/Record.swift | 180 ++++++++++++++++++ .../Settings.swift | 0 SanTa/SanTa/MapScene/UIImage+Gif.swift | 35 ---- .../MapScene/ClusterAnnotationView.swift | 0 .../MapScene/MapViewController.swift | 26 +++ .../MapScene/MapViewCoordinator.swift | 0 .../{ => Scenes}/MapScene/MapViewModel.swift | 0 .../MapScene/MapViewRepository.swift | 0 .../MapScene/MapViewUseCase.swift | 0 .../MapScene/MountainAnnotation.swift | 0 .../MapScene/MountainAnnotationView.swift | 0 .../MountainAddingView.swift | 0 .../MountainAddingViewController.swift | 0 .../MountainAddingViewCoordinator.swift | 0 .../MountainAddingViewModel.swift | 0 .../MountainAddingViewRepository.swift | 0 .../MountainAddingViewUseCase.swift | 0 .../MountainDetailAnnotationView.swift | 0 .../MountainDetailModel.swift | 0 .../MountainDetailTableViewCell.swift | 0 .../MountainDetailTitleView.swift | 0 .../MountainDetailUseCase.swift | 0 .../MountainDetailViewController.swift | 0 .../MountainDetailViewCoordinator.swift | 0 .../MountainDetailViewModel.swift | 0 .../MountainListScene/MountainCell.swift | 0 .../MountainListViewController.swift | 0 .../MountainListViewCoordinator.swift | 0 .../MountainListViewModel.swift | 0 .../MountainListViewRepository.swift | 0 .../MountainListViewUseCase.swift | 0 .../RecordingPhotoCoordinator.swift | 0 .../RecordingPhotoViewController.swift | 0 .../RecordingScene/RecordRepository.swift | 0 .../RecordingScene/RecordingModel.swift | 0 .../RecordingScene/RecordingPhotoModel.swift | 0 .../RecordingScene/RecordingUseCase.swift | 0 .../RecordingViewController+Extension.swift | 0 .../RecordingViewController.swift | 0 .../RecordingViewCoordinator.swift | 0 .../RecordingScene/RecordingViewModel.swift | 0 .../RecordingTitleViewController.swift | 0 .../RecordingTitleViewCoordinator.swift | 0 .../DetailImagesCell.swift | 0 .../ResultDetailImagesViewController.swift | 0 .../ResultDetailImagesViewCoordinator.swift | 0 .../ResultDetailScene/DetailCell.swift | 0 .../ResultDetailScene/DetailHeader.swift | 0 .../ResultDetailScene/PinView.swift | 0 .../ResultDetailLargerInfoView.swift | 0 .../ResultDetailScene/ResultDetailModel.swift | 0 .../ResultDetailRepository.swift | 0 .../ResultDetailSmallerInfoView.swift | 0 .../ResultDetailUseCase.swift | 0 .../ResultDetailViewController 2.swift | 0 .../ResultDetailViewController.swift | 0 .../ResultDetailViewCoordinator.swift | 0 .../ResultDetailViewModel.swift | 0 .../ResultDetailScene/ThumbnailView.swift | 0 .../ResultDetailThumbnailViewController.swift | 0 ...ResultDetailThumbnailViewCoordinator.swift | 0 .../ResultScene/RecordsViewCell.swift | 0 .../ResultScene/ResultRepository.swift | 0 .../ResultScene/ResultUseCase.swift | 0 .../ResultScene/ResultViewController.swift | 0 .../ResultScene/ResultViewCoordinator.swift | 0 .../ResultScene/ResultViewModel.swift | 0 .../ResultScene/SectionHeaderView.swift | 0 .../ResultScene/TotalRecordsViewCell.swift | 0 .../SettingsScene/MapOptionCell.swift | 0 .../SettingsScene/SettingsRepository.swift | 0 .../SettingsScene/SettingsUsecase.swift | 0 .../SettingsViewController.swift | 0 .../SettingsViewCoordinator.swift | 0 .../SettingsScene/SettingsViewModel.swift | 0 .../SettingsScene/ToggleOptionCell.swift | 0 .../PaddingLabel.swift | 0 80 files changed, 261 insertions(+), 256 deletions(-) rename SanTa/SanTa/{RecordingScene/Record.swift => Entities/Location.swift} (50%) rename SanTa/SanTa/{SettingsScene => Entities}/Option.swift (100%) create mode 100644 SanTa/SanTa/Entities/Record.swift rename SanTa/SanTa/{SettingsScene => Entities}/Settings.swift (100%) delete mode 100644 SanTa/SanTa/MapScene/UIImage+Gif.swift rename SanTa/SanTa/{ => Scenes}/MapScene/ClusterAnnotationView.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MapViewController.swift (91%) rename SanTa/SanTa/{ => Scenes}/MapScene/MapViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MapViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MapViewRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MapViewUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MountainAnnotation.swift (100%) rename SanTa/SanTa/{ => Scenes}/MapScene/MountainAnnotationView.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingView.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingViewRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainAddingScene/MountainAddingViewUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailAnnotationView.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailTableViewCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailTitleView.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainDetailScene/MountainDetailViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainListViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainListViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainListViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainListViewRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/MountainListScene/MountainListViewUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingPhotoScene/RecordingPhotoCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingPhotoScene/RecordingPhotoViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingPhotoModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingViewController+Extension.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingScene/RecordingViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingTitleScene/RecordingTitleViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/RecordingTitleScene/RecordingTitleViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailImagesScene/DetailImagesCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailImagesScene/ResultDetailImagesViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailImagesScene/ResultDetailImagesViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/DetailCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/DetailHeader.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/PinView.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailLargerInfoView.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailSmallerInfoView.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailViewController 2.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ResultDetailViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailScene/ThumbnailView.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailThumbnailScene/ResultDetailThumbnailViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultDetailThumbnailScene/ResultDetailThumbnailViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/RecordsViewCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/ResultRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/ResultUseCase.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/ResultViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/ResultViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/ResultViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/SectionHeaderView.swift (100%) rename SanTa/SanTa/{ => Scenes}/ResultScene/TotalRecordsViewCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/MapOptionCell.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/SettingsRepository.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/SettingsUsecase.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/SettingsViewController.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/SettingsViewCoordinator.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/SettingsViewModel.swift (100%) rename SanTa/SanTa/{ => Scenes}/SettingsScene/ToggleOptionCell.swift (100%) rename SanTa/SanTa/{SettingsScene => Utility}/PaddingLabel.swift (100%) diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index c9b688b..a18abee 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -44,7 +44,6 @@ 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5465237C2741F997007B2692 /* ResultViewModel.swift */; }; 54731B65272F84D300534097 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54731B64272F84D300534097 /* MapViewModel.swift */; }; 547CDD9A27392474007CCA29 /* walkingManAnimation.gif in Resources */ = {isa = PBXBuildFile; fileRef = 547CDD9927392474007CCA29 /* walkingManAnimation.gif */; }; - 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */; }; 54851282272A6AD500407F28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851281272A6AD500407F28 /* AppDelegate.swift */; }; 54851284272A6AD500407F28 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851283272A6AD500407F28 /* SceneDelegate.swift */; }; 54851286272A6AD500407F28 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54851285272A6AD500407F28 /* MapViewController.swift */; }; @@ -70,8 +69,6 @@ 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; - 9826F43C2739546E0064FA85 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; - 9826F43D2739546E0064FA85 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; 984DDEC127325D67003BE56B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 984DDEC327325DFC003BE56B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; 984DDEC527325FB9003BE56B /* RecordRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC427325FB9003BE56B /* RecordRepository.swift */; }; @@ -85,16 +82,14 @@ 98BAABB4275479B0004505BB /* ResultSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BAABB3275479B0004505BB /* ResultSceneTests.swift */; }; 98BAABBA27547A11004505BB /* ResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5465237C2741F997007B2692 /* ResultViewModel.swift */; }; 98BAABBB27547A11004505BB /* ResultUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9800821E273CE16E006A847A /* ResultUseCase.swift */; }; - 98BAABBC27547A1B004505BB /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + DA4736D22755E39500841326 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */; }; DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4F273256B900EC523F /* RecordingModel.swift */; }; - DA854FE2274627B000E51E4B /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; - DA854FE4274627D500E51E4B /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */; }; DA854FE92746292300E51E4B /* RecordingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */; }; DA9D7C9D273A433E0018AD45 /* RecordingTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */; }; @@ -173,7 +168,6 @@ 5465237C2741F997007B2692 /* ResultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultViewModel.swift; sourceTree = ""; }; 54731B64272F84D300534097 /* MapViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewModel.swift; sourceTree = ""; }; 547CDD9927392474007CCA29 /* walkingManAnimation.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = walkingManAnimation.gif; sourceTree = ""; }; - 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Gif.swift"; sourceTree = ""; }; 5485127E272A6AD500407F28 /* SanTa.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SanTa.app; sourceTree = BUILT_PRODUCTS_DIR; }; 54851281272A6AD500407F28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 54851283272A6AD500407F28 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -214,6 +208,7 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; + DA4736D12755E39500841326 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTests.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; @@ -272,15 +267,14 @@ 5428FDB5272F89F0002F9D40 /* RecordingScene */ = { isa = PBXGroup; children = ( + 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, 54296948272FBFAB0070B362 /* RecordingViewController.swift */, DAAF2715272FF73700F8A115 /* RecordingViewController+Extension.swift */, - 5429694A272FBFCA0070B362 /* RecordingViewCoordinator.swift */, DAB37D4B2731166B00EC523F /* RecordingViewModel.swift */, 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */, DAB37D4F273256B900EC523F /* RecordingModel.swift */, DAFA9B5C27424C9A00BF168C /* RecordingPhotoModel.swift */, 984DDEC427325FB9003BE56B /* RecordRepository.swift */, - 984DDEC027325D67003BE56B /* Record.swift */, ); path = RecordingScene; sourceTree = ""; @@ -293,8 +287,8 @@ 5465237C2741F997007B2692 /* ResultViewModel.swift */, 9800821E273CE16E006A847A /* ResultUseCase.swift */, 9800821C273CB45D006A847A /* ResultRepository.swift */, - 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */, 54F88EB8274256FE0004EAFD /* SectionHeaderView.swift */, + 54F88EB627424C210004EAFD /* TotalRecordsViewCell.swift */, 54F88EBA274259950004EAFD /* RecordsViewCell.swift */, ); path = ResultScene; @@ -305,15 +299,15 @@ children = ( 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */, 49225C5D273CDB4F0021AD79 /* ResultDetailViewController.swift */, - DAB751B6274E74E600C39266 /* ThumbnailView.swift */, - 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, - 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, 494803812743748D002854B1 /* ResultDetailViewModel.swift */, 4948038327437499002854B1 /* ResultDetailUseCase.swift */, 493178B527439D0000B5FB88 /* ResultDetailModel.swift */, - 493178B32743992400B5FB88 /* DetailCell.swift */, - DAFF214D274BD6460061A555 /* DetailHeader.swift */, 49921D88274B3B440091112C /* ResultDetailRepository.swift */, + 49225C5F273CDB680021AD79 /* ResultDetailSmallerInfoView.swift */, + 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */, + DAB751B6274E74E600C39266 /* ThumbnailView.swift */, + DAFF214D274BD6460061A555 /* DetailHeader.swift */, + 493178B32743992400B5FB88 /* DetailCell.swift */, 54953443274F6903005C0E60 /* PinView.swift */, ); path = ResultDetailScene; @@ -335,14 +329,14 @@ 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */ = { isa = PBXGroup; children = ( - 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */, 49D5A9482738C31600937821 /* MountainDetailViewCoordinator.swift */, + 49D5A94A2738C3AB00937821 /* MountainDetailViewController.swift */, 49D5A94C2738C71700937821 /* MountainDetailViewModel.swift */, 49D5A94E2738C72E00937821 /* MountainDetailUseCase.swift */, 49D5A9522738FBCD00937821 /* MountainDetailModel.swift */, 49D5A954273A5A5C00937821 /* MountainDetailTitleView.swift */, - 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */, + 49D5A956273A62F800937821 /* MountainDetailTableViewCell.swift */, ); path = MountainDetailScene; sourceTree = ""; @@ -350,16 +344,13 @@ 5428FDBB272F8C32002F9D40 /* SettingsScene */ = { isa = PBXGroup; children = ( - 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, - 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */, - 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */, 54296956272FC4380070B362 /* SettingsViewCoordinator.swift */, 54296954272FC3EC0070B362 /* SettingsViewController.swift */, 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */, 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */, 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */, - 9826F3DE273904010064FA85 /* Settings.swift */, - 9826F3DC2739035E0064FA85 /* Option.swift */, + 985EEF64273010BD002413D9 /* ToggleOptionCell.swift */, + 9889DA502730FFCD00F3C772 /* MapOptionCell.swift */, ); path = SettingsScene; sourceTree = ""; @@ -368,6 +359,10 @@ isa = PBXGroup; children = ( 49FEEDB82732584000D37CCA /* MountainEntity.swift */, + 984DDEC027325D67003BE56B /* Record.swift */, + DA4736D12755E39500841326 /* Location.swift */, + 9826F3DC2739035E0064FA85 /* Option.swift */, + 9826F3DE273904010064FA85 /* Settings.swift */, ); path = Entities; sourceTree = ""; @@ -387,15 +382,14 @@ 54731B61272F7F7600534097 /* MapScene */ = { isa = PBXGroup; children = ( + 54296946272FBD4B0070B362 /* MapViewCoordinator.swift */, 54851285272A6AD500407F28 /* MapViewController.swift */, 54731B64272F84D300534097 /* MapViewModel.swift */, 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */, 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */, - 54296946272FBD4B0070B362 /* MapViewCoordinator.swift */, 5429695A273026B10070B362 /* MountainAnnotationView.swift */, 5429695C27302B1D0070B362 /* ClusterAnnotationView.swift */, 49A3E61C2732756C0020CAC1 /* MountainAnnotation.swift */, - 547CDD9B27392496007CCA29 /* UIImage+Gif.swift */, ); path = MapScene; sourceTree = ""; @@ -448,21 +442,11 @@ isa = PBXGroup; children = ( 54731B63272F81B200534097 /* Resources */, + 54731B62272F808300534097 /* Application */, 54296943272FB8410070B362 /* Persistences */, 5428FDBE272F8D43002F9D40 /* Entities */, - 54731B62272F808300534097 /* Application */, - 54731B61272F7F7600534097 /* MapScene */, - 54B32063274510B7002232BD /* MountainAddingScene */, - 5428FDB6272F8B2B002F9D40 /* ResultScene */, - DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */, - DAB751B8274E7DAD00C39266 /* ResultDetailThumbnailScene */, - 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, - 5428FDB5272F89F0002F9D40 /* RecordingScene */, - DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, - DAFA9B55274112AB00BF168C /* RecordingPhotoScene */, - 5428FDB9272F8BD9002F9D40 /* MountainListScene */, - 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, - 5428FDBB272F8C32002F9D40 /* SettingsScene */, + DA4736D32755E46800841326 /* Utility */, + DA4736D42755E56300841326 /* Scenes */, ); path = SanTa; sourceTree = ""; @@ -472,10 +456,10 @@ children = ( 54B3206627451169002232BD /* MountainAddingViewCoordinator.swift */, 54B32064274510D8002232BD /* MountainAddingViewController.swift */, - 54B32072274B7E09002232BD /* MountainAddingView.swift */, 54B32068274536D1002232BD /* MountainAddingViewModel.swift */, 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */, 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */, + 54B32072274B7E09002232BD /* MountainAddingView.swift */, ); path = MountainAddingScene; sourceTree = ""; @@ -496,6 +480,33 @@ path = ResultSceneTests; sourceTree = ""; }; + DA4736D32755E46800841326 /* Utility */ = { + isa = PBXGroup; + children = ( + 98AEF1D627310759002E9C9A /* PaddingLabel.swift */, + ); + path = Utility; + sourceTree = ""; + }; + DA4736D42755E56300841326 /* Scenes */ = { + isa = PBXGroup; + children = ( + 54731B61272F7F7600534097 /* MapScene */, + 54B32063274510B7002232BD /* MountainAddingScene */, + 5428FDB5272F89F0002F9D40 /* RecordingScene */, + DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */, + DAFA9B55274112AB00BF168C /* RecordingPhotoScene */, + 5428FDB6272F8B2B002F9D40 /* ResultScene */, + 5428FDB7272F8B34002F9D40 /* ResultDetailScene */, + DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */, + DAB751B8274E7DAD00C39266 /* ResultDetailThumbnailScene */, + 5428FDB9272F8BD9002F9D40 /* MountainListScene */, + 5428FDBA272F8BF6002F9D40 /* MountainDetailScene */, + 5428FDBB272F8C32002F9D40 /* SettingsScene */, + ); + path = Scenes; + sourceTree = ""; + }; DA854FDA2746273300E51E4B /* RecordingSceneTests */ = { isa = PBXGroup; children = ( @@ -508,8 +519,8 @@ DA9D7C9B273A42B90018AD45 /* RecordingTitleScene */ = { isa = PBXGroup; children = ( - DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */, DA9D7C9E273A45BE0018AD45 /* RecordingTitleViewCoordinator.swift */, + DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */, ); path = RecordingTitleScene; sourceTree = ""; @@ -517,8 +528,8 @@ DAB751B8274E7DAD00C39266 /* ResultDetailThumbnailScene */ = { isa = PBXGroup; children = ( - DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */, DAB751BB274E7DFA00C39266 /* ResultDetailThumbnailViewCoordinator.swift */, + DAB751B9274E7DEA00C39266 /* ResultDetailThumbnailViewController.swift */, ); path = ResultDetailThumbnailScene; sourceTree = ""; @@ -526,8 +537,8 @@ DAE7540C274D29E2004A19C3 /* ResultDetailImagesScene */ = { isa = PBXGroup; children = ( - DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */, DAE7540F274D2A32004A19C3 /* ResultDetailImagesViewCoordinator.swift */, + DAE7540D274D2A25004A19C3 /* ResultDetailImagesViewController.swift */, DAE75411274D3AFA004A19C3 /* DetailImagesCell.swift */, ); path = ResultDetailImagesScene; @@ -735,6 +746,7 @@ DAFA9B5D27424C9A00BF168C /* RecordingPhotoModel.swift in Sources */, DAE75412274D3AFA004A19C3 /* DetailImagesCell.swift in Sources */, DAB751B7274E74E600C39266 /* ThumbnailView.swift in Sources */, + DA4736D22755E39500841326 /* Location.swift in Sources */, 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */, 493178B42743992400B5FB88 /* DetailCell.swift in Sources */, 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */, @@ -760,7 +772,6 @@ 5465237D2741F997007B2692 /* ResultViewModel.swift in Sources */, 9800821F273CE16E006A847A /* ResultUseCase.swift in Sources */, 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */, - 547CDD9C27392496007CCA29 /* UIImage+Gif.swift in Sources */, 5429694B272FBFCA0070B362 /* RecordingViewCoordinator.swift in Sources */, DAAF4D70273CE08B00780DC8 /* MountainListViewRepository.swift in Sources */, DAAF4D6C273CE02400780DC8 /* MountainListViewModel.swift in Sources */, @@ -799,8 +810,6 @@ 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */, 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */, 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, - 9826F43C2739546E0064FA85 /* Settings.swift in Sources */, - 9826F43D2739546E0064FA85 /* Option.swift in Sources */, 9826F436273954020064FA85 /* SettingsSceneTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -809,7 +818,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 98BAABBC27547A1B004505BB /* Record.swift in Sources */, 98BAABBA27547A11004505BB /* ResultViewModel.swift in Sources */, 98BAABBB27547A11004505BB /* ResultUseCase.swift in Sources */, 98BAABB4275479B0004505BB /* ResultSceneTests.swift in Sources */, @@ -822,8 +830,6 @@ files = ( DA854FE92746292300E51E4B /* RecordingViewModel.swift in Sources */, DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */, - DA854FE4274627D500E51E4B /* Settings.swift in Sources */, - DA854FE2274627B000E51E4B /* Record.swift in Sources */, DAB25F1B2754AF2D00F0BE75 /* RecordingViewModelTests.swift in Sources */, DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */, DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */, diff --git a/SanTa/SanTa/RecordingScene/Record.swift b/SanTa/SanTa/Entities/Location.swift similarity index 50% rename from SanTa/SanTa/RecordingScene/Record.swift rename to SanTa/SanTa/Entities/Location.swift index b99be4b..18523b8 100644 --- a/SanTa/SanTa/RecordingScene/Record.swift +++ b/SanTa/SanTa/Entities/Location.swift @@ -1,185 +1,13 @@ // -// Recording.swift +// Location.swift // SanTa // -// Created by CHANGMIN OH on 2021/11/03. +// Created by 김민창 on 2021/11/30. // import Foundation import CoreLocation -final class TotalRecords { - private(set) var totalRecords: [DateSeperateRecords] = [] - - private var mappingDateSeperateRecords: [String: DateSeperateRecords] = [:] - - var totalDistances: Double { - return totalRecords.reduce(0) { $0 + $1.distances } - } - - var sectionCount: Int { - return totalRecords.count - } - - var totalCount: Int { - return totalRecords.reduce(0) { $0 + $1.count } - } - - var totalTimes: TimeInterval { - return totalRecords.reduce(0) { $0 + $1.times } - } - - var totalSteps: Int { - return totalRecords.reduce(0) { $0 + $1.steps } - } - - subscript(section: Int) -> DateSeperateRecords? { - guard self.totalCount > section else { return nil } - return totalRecords[section] - } - - func add(records: Records) { - guard let date = records.date else { return } - let year = Calendar.current.component(.year, from: date) - let month = Calendar.current.component(.month, from: date) - let key = "\(year)\(month)" - - if let seperateDateRecords = self.mappingDateSeperateRecords[key] { - seperateDateRecords.add(records: records) - } else { - let seperateDateRecords = DateSeperateRecords(year: year, month: month) - seperateDateRecords.add(records: records) - self.mappingDateSeperateRecords[key] = seperateDateRecords - self.totalRecords.append(seperateDateRecords) - } - } -} - -final class DateSeperateRecords { - let year: Int - let month: Int - - private(set) var dateSeperateRecords: [Records] = [] - - subscript(item: Int) -> Records? { - guard self.count > item else { return nil } - return dateSeperateRecords[item] - } - - init(year: Int, month: Int) { - self.year = year - self.month = month - } - - var distances: Double { - return dateSeperateRecords.reduce(0) { $0 + $1.distances } - } - - var count: Int { - return dateSeperateRecords.count - } - - var times: TimeInterval { - return dateSeperateRecords.reduce(0) { $0 + $1.totalTravelTime } - } - - var steps: Int { - return dateSeperateRecords.reduce(0) { $0 + $1.steps } - } - - func add(records: Records) { - self.dateSeperateRecords.append(records) - } -} - -struct Records { - private(set) var title: String - private(set) var records: [Record] - private(set) var assetIdentifiers: [String] - private(set) var secondPerHighestSpeed: Int - private(set) var secondPerMinimumSpeed: Int - private(set) var id: String - - var date: Date? { - return records.last?.endTime - } - - var distances: Double { - return records.reduce(0) { $0 + $1.distance } - } - - var totalTravelTime: TimeInterval { - return records.reduce(0) { $0 + $1.travelTime } - } - - var steps: Int { - return records.reduce(0) { $0 + $1.step } - } - - var maxAltitude: Double { - guard let max = records.compactMap({ $0.maxAltitude }).max() else { - return 0 - } - return max - } - - var minAltitude: Double { - guard let min = records.compactMap({ $0.minAltitude }).min() else { - return 0 - } - return min - } - - var maxAltitudeDifference: Double { - guard let max = records.compactMap({ $0.maxAltitude }).max(), - let min = records.compactMap({ $0.minAltitude }).min() - else { - return 0 - } - return max - min - } - - mutating func configureTitle(title: String) { - self.title = title - } - - mutating func configurePhoto(assetIdentifiers: [String]) { - self.assetIdentifiers = assetIdentifiers - } - - mutating func add(record: Record) { - self.records.append(record) - } -} - -struct Record { - let startTime: Date - let endTime: Date - let step: Int - let distance: Double - let locations: Locations - - var travelTime: TimeInterval { - return endTime.timeIntervalSince(startTime) - } - - var minAltitude: Double? { - return locations.minAltitude - } - - var maxAltitude: Double? { - return locations.maxAltitude - } - - init(startTime: Date, endTime: Date, step: Int, distance: Double, locations: [Location]) { - self.startTime = startTime - self.endTime = endTime - self.step = step - self.distance = distance - self.locations = Locations(locations: locations) - } -} - struct Location { let latitude: Double let longitude: Double diff --git a/SanTa/SanTa/SettingsScene/Option.swift b/SanTa/SanTa/Entities/Option.swift similarity index 100% rename from SanTa/SanTa/SettingsScene/Option.swift rename to SanTa/SanTa/Entities/Option.swift diff --git a/SanTa/SanTa/Entities/Record.swift b/SanTa/SanTa/Entities/Record.swift new file mode 100644 index 0000000..5ec4663 --- /dev/null +++ b/SanTa/SanTa/Entities/Record.swift @@ -0,0 +1,180 @@ +// +// Recording.swift +// SanTa +// +// Created by CHANGMIN OH on 2021/11/03. +// + +import Foundation + +final class TotalRecords { + private(set) var totalRecords: [DateSeperateRecords] = [] + + private var mappingDateSeperateRecords: [String: DateSeperateRecords] = [:] + + var totalDistances: Double { + return totalRecords.reduce(0) { $0 + $1.distances } + } + + var sectionCount: Int { + return totalRecords.count + } + + var totalCount: Int { + return totalRecords.reduce(0) { $0 + $1.count } + } + + var totalTimes: TimeInterval { + return totalRecords.reduce(0) { $0 + $1.times } + } + + var totalSteps: Int { + return totalRecords.reduce(0) { $0 + $1.steps } + } + + subscript(section: Int) -> DateSeperateRecords? { + guard self.totalCount > section else { return nil } + return totalRecords[section] + } + + func add(records: Records) { + guard let date = records.date else { return } + let year = Calendar.current.component(.year, from: date) + let month = Calendar.current.component(.month, from: date) + let key = "\(year)\(month)" + + if let seperateDateRecords = self.mappingDateSeperateRecords[key] { + seperateDateRecords.add(records: records) + } else { + let seperateDateRecords = DateSeperateRecords(year: year, month: month) + seperateDateRecords.add(records: records) + self.mappingDateSeperateRecords[key] = seperateDateRecords + self.totalRecords.append(seperateDateRecords) + } + } +} + +final class DateSeperateRecords { + let year: Int + let month: Int + + private(set) var dateSeperateRecords: [Records] = [] + + subscript(item: Int) -> Records? { + guard self.count > item else { return nil } + return dateSeperateRecords[item] + } + + init(year: Int, month: Int) { + self.year = year + self.month = month + } + + var distances: Double { + return dateSeperateRecords.reduce(0) { $0 + $1.distances } + } + + var count: Int { + return dateSeperateRecords.count + } + + var times: TimeInterval { + return dateSeperateRecords.reduce(0) { $0 + $1.totalTravelTime } + } + + var steps: Int { + return dateSeperateRecords.reduce(0) { $0 + $1.steps } + } + + func add(records: Records) { + self.dateSeperateRecords.append(records) + } +} + +struct Records { + private(set) var title: String + private(set) var records: [Record] + private(set) var assetIdentifiers: [String] + private(set) var secondPerHighestSpeed: Int + private(set) var secondPerMinimumSpeed: Int + private(set) var id: String + + var date: Date? { + return records.last?.endTime + } + + var distances: Double { + return records.reduce(0) { $0 + $1.distance } + } + + var totalTravelTime: TimeInterval { + return records.reduce(0) { $0 + $1.travelTime } + } + + var steps: Int { + return records.reduce(0) { $0 + $1.step } + } + + var maxAltitude: Double { + guard let max = records.compactMap({ $0.maxAltitude }).max() else { + return 0 + } + return max + } + + var minAltitude: Double { + guard let min = records.compactMap({ $0.minAltitude }).min() else { + return 0 + } + return min + } + + var maxAltitudeDifference: Double { + guard let max = records.compactMap({ $0.maxAltitude }).max(), + let min = records.compactMap({ $0.minAltitude }).min() + else { + return 0 + } + return max - min + } + + mutating func configureTitle(title: String) { + self.title = title + } + + mutating func configurePhoto(assetIdentifiers: [String]) { + self.assetIdentifiers = assetIdentifiers + } + + mutating func add(record: Record) { + self.records.append(record) + } +} + +struct Record { + let startTime: Date + let endTime: Date + let step: Int + let distance: Double + let locations: Locations + + var travelTime: TimeInterval { + return endTime.timeIntervalSince(startTime) + } + + var minAltitude: Double? { + return locations.minAltitude + } + + var maxAltitude: Double? { + return locations.maxAltitude + } + + init(startTime: Date, endTime: Date, step: Int, distance: Double, locations: [Location]) { + self.startTime = startTime + self.endTime = endTime + self.step = step + self.distance = distance + self.locations = Locations(locations: locations) + } +} diff --git a/SanTa/SanTa/SettingsScene/Settings.swift b/SanTa/SanTa/Entities/Settings.swift similarity index 100% rename from SanTa/SanTa/SettingsScene/Settings.swift rename to SanTa/SanTa/Entities/Settings.swift diff --git a/SanTa/SanTa/MapScene/UIImage+Gif.swift b/SanTa/SanTa/MapScene/UIImage+Gif.swift deleted file mode 100644 index 696feb6..0000000 --- a/SanTa/SanTa/MapScene/UIImage+Gif.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// UIImage+Gif.swift -// SanTa -// -// Created by shin jae ung on 2021/11/08. -// -// 참고: https://github.com/kiritmodi2702/GIF-Swift/blob/master/GIF-Swift/iOSDevCenters%2BGIF.swift - -import UIKit - -extension UIImage { - class func gifImage(named: String, withTintColor: UIColor? = nil) -> UIImage? { - guard let bundleURL = Bundle.main.url(forResource: named, withExtension: "gif"), - let imageData = try? Data(contentsOf: bundleURL), - let source = CGImageSourceCreateWithData(imageData as CFData, nil) - else { return nil } - return UIImage.animatedImageWithSource(source, withTintColor: withTintColor) - } - - private class func animatedImageWithSource(_ source: CGImageSource, withTintColor: UIColor?) -> UIImage? { - let count: Int = CGImageSourceGetCount(source) - let images: [UIImage] = (0.. UIImage? { + guard let bundleURL = Bundle.main.url(forResource: named, withExtension: "gif"), + let imageData = try? Data(contentsOf: bundleURL), + let source = CGImageSourceCreateWithData(imageData as CFData, nil) + else { return nil } + return UIImage.animatedImageWithSource(source, withTintColor: withTintColor) + } + + private class func animatedImageWithSource(_ source: CGImageSource, withTintColor: UIColor?) -> UIImage? { + let count: Int = CGImageSourceGetCount(source) + let images: [UIImage] = (0.. Date: Tue, 30 Nov 2021 16:43:27 +0900 Subject: [PATCH 451/465] =?UTF-8?q?[Test]=20#363,=20#364=20MapScene,=20Mou?= =?UTF-8?q?ntainAddingScene=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/MapSceneTests/MapSceneTests.swift | 74 +++++ .../MountainAddingSceneTests.swift | 66 ++++ SanTa/SanTa.xcodeproj/project.pbxproj | 294 ++++++++++++++++++ .../xcshareddata/xcschemes/SanTa.xcscheme | 20 ++ 4 files changed, 454 insertions(+) create mode 100644 SanTa/MapSceneTests/MapSceneTests.swift create mode 100644 SanTa/MountainAddingSceneTests/MountainAddingSceneTests.swift diff --git a/SanTa/MapSceneTests/MapSceneTests.swift b/SanTa/MapSceneTests/MapSceneTests.swift new file mode 100644 index 0000000..a53271f --- /dev/null +++ b/SanTa/MapSceneTests/MapSceneTests.swift @@ -0,0 +1,74 @@ +// +// MapSceneTests.swift +// MapSceneTests +// +// Created by shin jae ung on 2021/11/29. +// + +import XCTest +import Combine + +class MapSceneTests: XCTestCase { + var viewModel: MapViewModel! + var useCase: MapViewUseCase! + var expectation: XCTestExpectation! + var observers: [AnyCancellable] = [] + + class MockRepository: MapViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + let mountainDetail = MountainEntity.MountainDetail( + mountainName: "Name", + mountainRegion: "Region", + mountainHeight: "100", + mountainShortDescription: "Description" + ) + let mountainEntity = MountainEntity(id: UUID(), mountain: mountainDetail, latitude: 37.3591, longitude: 127.1051) + let mountainEntities = [mountainEntity] + completion(.success(mountainEntities)) + } + + func fetchMapOption(key: Settings, completion: @escaping (Result) -> Void) { + completion(.success(Map.infomation)) + } + } + + override func setUp() { + super.setUp() + self.useCase = MapViewUseCase(repository: MockRepository()) + self.viewModel = MapViewModel(useCase: self.useCase) + self.expectation = XCTestExpectation(description: "expectation") + } + + override func tearDown() { + self.viewModel = nil + self.useCase = nil + self.expectation = nil + super.tearDown() + } + + func test_ViewModel_configureBindings호출시_MountainEntity를_저장함() { + self.viewModel.$mountains + .dropFirst() + .sink(receiveValue: { [weak self] mountains in + XCTAssertNotNil(mountains, "reposiroty로 부터 [MountainEntity]가 nil로 반환됨") + XCTAssertTrue(mountains!.count == 1) + self?.expectation.fulfill() + }) + .store(in: &observers) + self.viewModel.configureBindings() + self.wait(for: [expectation], timeout: 1.0) + } + + func test_ViewModel_viewWillAppear호출시_Map을_저장함() { + self.viewModel.$map + .dropFirst() + .sink(receiveValue: { [weak self] map in + XCTAssertNotNil(map, "reposiroty로 부터 Map이 nil로 반환됨") + XCTAssertTrue(map == Map.infomation) + self?.expectation.fulfill() + }) + .store(in: &observers) + self.viewModel.viewWillAppear() + self.wait(for: [expectation], timeout: 1.0) + } +} diff --git a/SanTa/MountainAddingSceneTests/MountainAddingSceneTests.swift b/SanTa/MountainAddingSceneTests/MountainAddingSceneTests.swift new file mode 100644 index 0000000..65c8130 --- /dev/null +++ b/SanTa/MountainAddingSceneTests/MountainAddingSceneTests.swift @@ -0,0 +1,66 @@ +// +// MountainAddingSceneTests.swift +// MountainAddingSceneTests +// +// Created by shin jae ung on 2021/11/30. +// + +import XCTest +import Combine +import CoreLocation + +class MountainAddingSceneTests: XCTestCase { + var viewModel: MountainAddingViewModel! + var useCase: MountainAddingViewUseCase! + var expectation: XCTestExpectation! + var coordinate: CLLocationCoordinate2D! + var altitude: CLLocationDistance! + var observers: [AnyCancellable] = [] + + class MockRepository: MountainAddingRepository { + func save(_ mountainEntity: MountainEntity, completion: @escaping (Result) -> Void) { + completion(.success(Void())) + } + } + + override func setUp() { + super.setUp() + self.useCase = MountainAddingViewUseCase(repository: MockRepository()) + self.viewModel = MountainAddingViewModel(useCase: useCase) + self.expectation = XCTestExpectation(description: "expectation") + self.coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0) + self.altitude = 0 + } + + override func tearDown() { + self.viewModel = nil + self.useCase = nil + self.expectation = nil + super.tearDown() + } + + func test_ViewModel_updateUserLocation_호출시_위치를_저장함() { + self.viewModel.$coordinate + .dropFirst() + .sink(receiveValue: { [weak self] coordinate in + XCTAssertNotNil(coordinate, "updateUserLocation에서 coordinate가 올바르게 저장되지 않음") + self?.expectation.fulfill() + }) + .store(in: &observers) + self.viewModel.updateUserLocation(coordinate: self.coordinate, altitude: self.altitude) + self.wait(for: [expectation], timeout: 1.0) + } + + func test_ViewModel_addMountain_호출시_산을_추가함() { + self.viewModel.updateUserLocation(coordinate: self.coordinate, altitude: self.altitude) + self.viewModel.addMountainResult + .sink(receiveValue: { [weak self] result in + XCTAssertNotNil(result, "repository로 부터 AddingMountainResult가 nil로 반환됨") + XCTAssertEqual(result, .success, "산이 추가되지 않음") + self?.expectation.fulfill() + }) + .store(in: &self.observers) + self.viewModel.addMountain(title: "산", description: "설명") + self.wait(for: [expectation], timeout: 1.0) + } +} diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a18abee..8a776e2 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -27,6 +27,30 @@ 49FC97682744E105008CE73A /* ResultDetailViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */; }; 49FEEDB7273255DD00D37CCA /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; 49FEEDB92732584000D37CCA /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; + 5423CD662755FA4A00BAB338 /* MapSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5423CD652755FA4A00BAB338 /* MapSceneTests.swift */; }; + 5423CD6C2755FA6C00BAB338 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + 5423CD6D2755FA7400BAB338 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; + 5423CD6E2755FA8C00BAB338 /* MapViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54731B64272F84D300534097 /* MapViewModel.swift */; }; + 5423CD6F2755FA8E00BAB338 /* MapViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */; }; + 5423CD702755FA9100BAB338 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; + 5423CD712755FA9400BAB338 /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; + 5423CD722755FA9900BAB338 /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DC2739035E0064FA85 /* Option.swift */; }; + 5423CD732755FA9B00BAB338 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + 5423CD742755FA9F00BAB338 /* CoreDataMountainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32074274BCCA2002232BD /* CoreDataMountainStorage.swift */; }; + 5423CD752755FAA200BAB338 /* CoreDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */; }; + 5423CD762755FAA500BAB338 /* MountainExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */; }; + 5423CD772755FAA800BAB338 /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; + 5423CD782755FACE00BAB338 /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + 5423CD792755FAFA00BAB338 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; + 5423CD7A2755FB0500BAB338 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; + 5423CD822755FCEF00BAB338 /* MountainAddingSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5423CD812755FCEF00BAB338 /* MountainAddingSceneTests.swift */; }; + 5423CD882755FE0600BAB338 /* MountainAddingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32068274536D1002232BD /* MountainAddingViewModel.swift */; }; + 5423CD892755FE0900BAB338 /* MountainAddingViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206A274536E3002232BD /* MountainAddingViewUseCase.swift */; }; + 5423CD8A2755FE0E00BAB338 /* MountainAddingViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B3206C27453725002232BD /* MountainAddingViewRepository.swift */; }; + 5423CD8B2755FE1E00BAB338 /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; + 5423CD8C2756019000BAB338 /* CoreDataMountainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54B32074274BCCA2002232BD /* CoreDataMountainStorage.swift */; }; + 5423CD8D275601AD00BAB338 /* CoreDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */; }; + 5423CD8E275601B400BAB338 /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; 5428FDB4272F894D002F9D40 /* MapViewRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */; }; 5428FDBD272F8C5B002F9D40 /* MapViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */; }; 54296945272FBC6E0070B362 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54296944272FBC6E0070B362 /* AppCoordinator.swift */; }; @@ -114,6 +138,20 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 5423CD672755FA4A00BAB338 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; + 5423CD832755FCEF00BAB338 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; 9826F431273953FB0064FA85 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 54851276272A6AD500407F28 /* Project object */; @@ -151,6 +189,10 @@ 49FC97672744E105008CE73A /* ResultDetailViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewCoordinator.swift; sourceTree = ""; }; 49FEEDB6273255DD00D37CCA /* MountainExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainExtractor.swift; sourceTree = ""; }; 49FEEDB82732584000D37CCA /* MountainEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainEntity.swift; sourceTree = ""; }; + 5423CD632755FA4A00BAB338 /* MapSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5423CD652755FA4A00BAB338 /* MapSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapSceneTests.swift; sourceTree = ""; }; + 5423CD7F2755FCEF00BAB338 /* MountainAddingSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MountainAddingSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5423CD812755FCEF00BAB338 /* MountainAddingSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainAddingSceneTests.swift; sourceTree = ""; }; 5428FDB3272F894D002F9D40 /* MapViewRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewRepository.swift; sourceTree = ""; }; 5428FDBC272F8C5B002F9D40 /* MapViewUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewUseCase.swift; sourceTree = ""; }; 54296944272FBC6E0070B362 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; @@ -233,6 +275,20 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5423CD602755FA4A00BAB338 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5423CD7C2755FCEF00BAB338 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5485127B272A6AD500407F28 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -264,6 +320,22 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 5423CD642755FA4A00BAB338 /* MapSceneTests */ = { + isa = PBXGroup; + children = ( + 5423CD652755FA4A00BAB338 /* MapSceneTests.swift */, + ); + path = MapSceneTests; + sourceTree = ""; + }; + 5423CD802755FCEF00BAB338 /* MountainAddingSceneTests */ = { + isa = PBXGroup; + children = ( + 5423CD812755FCEF00BAB338 /* MountainAddingSceneTests.swift */, + ); + path = MountainAddingSceneTests; + sourceTree = ""; + }; 5428FDB5272F89F0002F9D40 /* RecordingScene */ = { isa = PBXGroup; children = ( @@ -423,6 +495,8 @@ 9826F42E273953FB0064FA85 /* SettingsSceneTests */, DA854FDA2746273300E51E4B /* RecordingSceneTests */, 98BAABB2275479B0004505BB /* ResultSceneTests */, + 5423CD642755FA4A00BAB338 /* MapSceneTests */, + 5423CD802755FCEF00BAB338 /* MountainAddingSceneTests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -434,6 +508,8 @@ 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */, 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */, + 5423CD632755FA4A00BAB338 /* MapSceneTests.xctest */, + 5423CD7F2755FCEF00BAB338 /* MountainAddingSceneTests.xctest */, ); name = Products; sourceTree = ""; @@ -556,6 +632,42 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5423CD622755FA4A00BAB338 /* MapSceneTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5423CD6B2755FA4A00BAB338 /* Build configuration list for PBXNativeTarget "MapSceneTests" */; + buildPhases = ( + 5423CD5F2755FA4A00BAB338 /* Sources */, + 5423CD602755FA4A00BAB338 /* Frameworks */, + 5423CD612755FA4A00BAB338 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5423CD682755FA4A00BAB338 /* PBXTargetDependency */, + ); + name = MapSceneTests; + productName = MapSceneTests; + productReference = 5423CD632755FA4A00BAB338 /* MapSceneTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5423CD7E2755FCEF00BAB338 /* MountainAddingSceneTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5423CD852755FCEF00BAB338 /* Build configuration list for PBXNativeTarget "MountainAddingSceneTests" */; + buildPhases = ( + 5423CD7B2755FCEF00BAB338 /* Sources */, + 5423CD7C2755FCEF00BAB338 /* Frameworks */, + 5423CD7D2755FCEF00BAB338 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5423CD842755FCEF00BAB338 /* PBXTargetDependency */, + ); + name = MountainAddingSceneTests; + productName = MountainAddingSceneTests; + productReference = 5423CD7F2755FCEF00BAB338 /* MountainAddingSceneTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5485127D272A6AD500407F28 /* SanTa */ = { isa = PBXNativeTarget; buildConfigurationList = 54851295272A6AD600407F28 /* Build configuration list for PBXNativeTarget "SanTa" */; @@ -636,6 +748,14 @@ LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 1300; TargetAttributes = { + 5423CD622755FA4A00BAB338 = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; + 5423CD7E2755FCEF00BAB338 = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; 5485127D272A6AD500407F28 = { CreatedOnToolsVersion = 13.0; }; @@ -669,11 +789,27 @@ 9826F42C273953FB0064FA85 /* SettingsSceneTests */, DA854FD82746273300E51E4B /* RecordingSceneTests */, 98BAABB0275479B0004505BB /* ResultSceneTests */, + 5423CD622755FA4A00BAB338 /* MapSceneTests */, + 5423CD7E2755FCEF00BAB338 /* MountainAddingSceneTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5423CD612755FA4A00BAB338 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5423CD7D2755FCEF00BAB338 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5485127C272A6AD500407F28 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -708,6 +844,40 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5423CD5F2755FA4A00BAB338 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5423CD662755FA4A00BAB338 /* MapSceneTests.swift in Sources */, + 5423CD6E2755FA8C00BAB338 /* MapViewModel.swift in Sources */, + 5423CD712755FA9400BAB338 /* MountainEntity.swift in Sources */, + 5423CD752755FAA200BAB338 /* CoreDataStorage.swift in Sources */, + 5423CD742755FA9F00BAB338 /* CoreDataMountainStorage.swift in Sources */, + 5423CD7A2755FB0500BAB338 /* SanTa.xcdatamodeld in Sources */, + 5423CD762755FAA500BAB338 /* MountainExtractor.swift in Sources */, + 5423CD6F2755FA8E00BAB338 /* MapViewUseCase.swift in Sources */, + 5423CD732755FA9B00BAB338 /* Settings.swift in Sources */, + 5423CD722755FA9900BAB338 /* Option.swift in Sources */, + 5423CD702755FA9100BAB338 /* MapViewRepository.swift in Sources */, + 5423CD772755FAA800BAB338 /* UserDefaultsStorage.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5423CD7B2755FCEF00BAB338 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5423CD882755FE0600BAB338 /* MountainAddingViewModel.swift in Sources */, + 5423CD8E275601B400BAB338 /* SanTa.xcdatamodeld in Sources */, + 5423CD8C2756019000BAB338 /* CoreDataMountainStorage.swift in Sources */, + 5423CD892755FE0900BAB338 /* MountainAddingViewUseCase.swift in Sources */, + 5423CD8B2755FE1E00BAB338 /* MountainEntity.swift in Sources */, + 5423CD8A2755FE0E00BAB338 /* MountainAddingViewRepository.swift in Sources */, + 5423CD8D275601AD00BAB338 /* CoreDataStorage.swift in Sources */, + 5423CD822755FCEF00BAB338 /* MountainAddingSceneTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5485127A272A6AD500407F28 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -806,7 +976,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5423CD6C2755FA6C00BAB338 /* Settings.swift in Sources */, DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */, + 5423CD6D2755FA7400BAB338 /* Option.swift in Sources */, 9826F4382739546E0064FA85 /* SettingsViewModel.swift in Sources */, 9826F4392739546E0064FA85 /* SettingsUsecase.swift in Sources */, 9826F43A2739546E0064FA85 /* SettingsRepository.swift in Sources */, @@ -820,6 +992,8 @@ files = ( 98BAABBA27547A11004505BB /* ResultViewModel.swift in Sources */, 98BAABBB27547A11004505BB /* ResultUseCase.swift in Sources */, + 5423CD792755FAFA00BAB338 /* Location.swift in Sources */, + 5423CD782755FACE00BAB338 /* Record.swift in Sources */, 98BAABB4275479B0004505BB /* ResultSceneTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -840,6 +1014,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5423CD682755FA4A00BAB338 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 5423CD672755FA4A00BAB338 /* PBXContainerItemProxy */; + }; + 5423CD842755FCEF00BAB338 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 5423CD832755FCEF00BAB338 /* PBXContainerItemProxy */; + }; 9826F432273953FB0064FA85 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5485127D272A6AD500407F28 /* SanTa */; @@ -864,6 +1048,98 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 5423CD692755FA4A00BAB338 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78F54XW75V; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.random.MapSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + 5423CD6A2755FA4A00BAB338 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78F54XW75V; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.random.MapSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; + 5423CD862755FCEF00BAB338 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78F54XW75V; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.random.MountainAddingSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + 5423CD872755FCEF00BAB338 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 78F54XW75V; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.random.MountainAddingSceneTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; 54851293272A6AD600407F28 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1179,6 +1455,24 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5423CD6B2755FA4A00BAB338 /* Build configuration list for PBXNativeTarget "MapSceneTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5423CD692755FA4A00BAB338 /* Debug */, + 5423CD6A2755FA4A00BAB338 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5423CD852755FCEF00BAB338 /* Build configuration list for PBXNativeTarget "MountainAddingSceneTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5423CD862755FCEF00BAB338 /* Debug */, + 5423CD872755FCEF00BAB338 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 54851279272A6AD500407F28 /* Build configuration list for PBXProject "SanTa" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index ddb9ebb..421e131 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -72,6 +72,26 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + + + + + Date: Tue, 30 Nov 2021 17:55:56 +0900 Subject: [PATCH 452/465] =?UTF-8?q?[Test]=20#362=20MountainList=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20Test=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListSceneTests.swift | 52 +++++++ .../RecordingUseCaseTests.swift | 4 +- SanTa/SanTa.xcodeproj/project.pbxproj | 137 ++++++++++++++++++ .../xcschemes/MountainListSceneTests.xcscheme | 52 +++++++ .../xcshareddata/xcschemes/SanTa.xcscheme | 12 +- .../MountainListViewRepository.swift | 4 - .../MountainListViewUseCase.swift | 4 + 7 files changed, 253 insertions(+), 12 deletions(-) create mode 100644 SanTa/MountainListSceneTests/MountainListSceneTests.swift create mode 100644 SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/MountainListSceneTests.xcscheme diff --git a/SanTa/MountainListSceneTests/MountainListSceneTests.swift b/SanTa/MountainListSceneTests/MountainListSceneTests.swift new file mode 100644 index 0000000..2b254b5 --- /dev/null +++ b/SanTa/MountainListSceneTests/MountainListSceneTests.swift @@ -0,0 +1,52 @@ +// +// MountainListSceneTestss.swift +// MountainListSceneTestss +// +// Created by 김민창 on 2021/11/30. +// + +import XCTest + +final class MountainListSceneTests: XCTestCase { + + private var successUseCase: MountainListUseCase! + private var failUseCase: MountainListUseCase! + private var successViewModel: MountainListViewModel! + private var failViewModel: MountainListViewModel! + + enum TestError: Error { + case error + } + + class SuccessMountainViewRepository: MountainListViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + let mountainList = [MountainEntity]() + completion(.success(mountainList)) + } + } + + class FailMountainViewRepository: MountainListViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { + completion(.failure(TestError.error)) + } + } + + override func setUp() { + self.successUseCase = MountainListUseCase(repository: SuccessMountainViewRepository()) + self.failUseCase = MountainListUseCase(repository: FailMountainViewRepository()) + self.successViewModel = MountainListViewModel(useCase: successUseCase) + self.failViewModel = MountainListViewModel(useCase: failUseCase) + } + + func test_MountainList_가져오기_성공 () { + successViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertNotNil(successViewModel.mountains) + } + + func test_MountainList_가져오기_실패 () { + failViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertNil(failViewModel.mountains) + } +} diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index c1e8de7..6fa2232 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -58,7 +58,7 @@ final class RecordingUseCaseTests: XCTestCase { func test_음성안내_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) - self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in + self.repository.fetchRecordOption(key: Settings.mapFormat) { result in switch result { case .failure: return @@ -82,7 +82,7 @@ final class RecordingUseCaseTests: XCTestCase { func test_사진저장_옵션_False_값_가져오기_성공() { _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.5 seconds")], timeout: 0.5) - self.repository.fetchRecordOption(key: Settings.recordPhoto) { result in + self.repository.fetchRecordOption(key: Settings.mapFormat) { result in switch result { case .failure: return diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index a18abee..da35a7e 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -86,6 +86,13 @@ 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; DA4736D22755E39500841326 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; + DA4736E6275610EE00841326 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; + DA4736E7275610F600841326 /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + DA4736E8275610FA00841326 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; + DA4736F327561C6200841326 /* MountainListSceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736F227561C6200841326 /* MountainListSceneTests.swift */; }; + DA4736F927561C9400841326 /* MountainListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */; }; + DA4736FA27561C9400841326 /* MountainListViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */; }; + DA4736FB27561C9A00841326 /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */; }; DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; @@ -128,6 +135,13 @@ remoteGlobalIDString = 5485127D272A6AD500407F28; remoteInfo = SanTa; }; + DA4736F427561C6200841326 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -209,6 +223,8 @@ 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; DA4736D12755E39500841326 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; + DA4736F027561C6200841326 /* MountainListSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MountainListSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DA4736F227561C6200841326 /* MountainListSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListSceneTests.swift; sourceTree = ""; }; DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTests.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; @@ -254,6 +270,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA4736ED27561C6200841326 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD62746273300E51E4B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -423,6 +446,7 @@ 9826F42E273953FB0064FA85 /* SettingsSceneTests */, DA854FDA2746273300E51E4B /* RecordingSceneTests */, 98BAABB2275479B0004505BB /* ResultSceneTests */, + DA4736F127561C6200841326 /* MountainListSceneTests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -434,6 +458,7 @@ 9826F42D273953FB0064FA85 /* SettingsSceneTests.xctest */, DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */, 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */, + DA4736F027561C6200841326 /* MountainListSceneTests.xctest */, ); name = Products; sourceTree = ""; @@ -507,6 +532,14 @@ path = Scenes; sourceTree = ""; }; + DA4736F127561C6200841326 /* MountainListSceneTests */ = { + isa = PBXGroup; + children = ( + DA4736F227561C6200841326 /* MountainListSceneTests.swift */, + ); + path = MountainListSceneTests; + sourceTree = ""; + }; DA854FDA2746273300E51E4B /* RecordingSceneTests */ = { isa = PBXGroup; children = ( @@ -609,6 +642,24 @@ productReference = 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + DA4736EF27561C6200841326 /* MountainListSceneTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA4736F627561C6200841326 /* Build configuration list for PBXNativeTarget "MountainListSceneTests" */; + buildPhases = ( + DA4736EC27561C6200841326 /* Sources */, + DA4736ED27561C6200841326 /* Frameworks */, + DA4736EE27561C6200841326 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DA4736F527561C6200841326 /* PBXTargetDependency */, + ); + name = MountainListSceneTests; + productName = MountainListSceneTestss; + productReference = DA4736F027561C6200841326 /* MountainListSceneTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; DA854FD82746273300E51E4B /* RecordingSceneTests */ = { isa = PBXNativeTarget; buildConfigurationList = DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */; @@ -647,6 +698,10 @@ CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; }; + DA4736EF27561C6200841326 = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; DA854FD82746273300E51E4B = { CreatedOnToolsVersion = 13.0; }; @@ -669,6 +724,7 @@ 9826F42C273953FB0064FA85 /* SettingsSceneTests */, DA854FD82746273300E51E4B /* RecordingSceneTests */, 98BAABB0275479B0004505BB /* ResultSceneTests */, + DA4736EF27561C6200841326 /* MountainListSceneTests */, ); }; /* End PBXProject section */ @@ -698,6 +754,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA4736EE27561C6200841326 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD72746273300E51E4B /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -824,10 +887,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA4736EC27561C6200841326 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DA4736FB27561C9A00841326 /* MountainEntity.swift in Sources */, + DA4736F927561C9400841326 /* MountainListViewModel.swift in Sources */, + DA4736FA27561C9400841326 /* MountainListViewUseCase.swift in Sources */, + DA4736F327561C6200841326 /* MountainListSceneTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA854FD52746273300E51E4B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DA4736E8275610FA00841326 /* Location.swift in Sources */, + DA4736E7275610F600841326 /* Record.swift in Sources */, + DA4736E6275610EE00841326 /* Settings.swift in Sources */, DA854FE92746292300E51E4B /* RecordingViewModel.swift in Sources */, DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */, DAB25F1B2754AF2D00F0BE75 /* RecordingViewModelTests.swift in Sources */, @@ -850,6 +927,11 @@ target = 5485127D272A6AD500407F28 /* SanTa */; targetProxy = 98BAABB5275479B0004505BB /* PBXContainerItemProxy */; }; + DA4736F527561C6200841326 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = DA4736F427561C6200841326 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1134,6 +1216,52 @@ }; name = Release; }; + DA4736F727561C6200841326 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = GQ4HM48H8H; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.MountainListSceneTestss; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + DA4736F827561C6200841326 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = GQ4HM48H8H; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = ajou.minryul.MountainListSceneTestss; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; DA854FDE2746273300E51E4B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1215,6 +1343,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DA4736F627561C6200841326 /* Build configuration list for PBXNativeTarget "MountainListSceneTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA4736F727561C6200841326 /* Debug */, + DA4736F827561C6200841326 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA854FDD2746273300E51E4B /* Build configuration list for PBXNativeTarget "RecordingSceneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/MountainListSceneTests.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/MountainListSceneTests.xcscheme new file mode 100644 index 0000000..bccc4db --- /dev/null +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/MountainListSceneTests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index ddb9ebb..fdefc98 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -56,9 +56,9 @@ skipped = "NO"> @@ -66,9 +66,9 @@ skipped = "NO"> diff --git a/SanTa/SanTa/Scenes/MountainListScene/MountainListViewRepository.swift b/SanTa/SanTa/Scenes/MountainListScene/MountainListViewRepository.swift index a90cafa..69913e0 100644 --- a/SanTa/SanTa/Scenes/MountainListScene/MountainListViewRepository.swift +++ b/SanTa/SanTa/Scenes/MountainListScene/MountainListViewRepository.swift @@ -7,10 +7,6 @@ import Foundation -protocol MountainListViewRepository { - func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) -} - final class DefaultMountainListViewReposiory { enum JSONDecodeError: Error { case decodingFailed diff --git a/SanTa/SanTa/Scenes/MountainListScene/MountainListViewUseCase.swift b/SanTa/SanTa/Scenes/MountainListScene/MountainListViewUseCase.swift index c08d1da..89474a5 100644 --- a/SanTa/SanTa/Scenes/MountainListScene/MountainListViewUseCase.swift +++ b/SanTa/SanTa/Scenes/MountainListScene/MountainListViewUseCase.swift @@ -8,6 +8,10 @@ import Foundation import OSLog +protocol MountainListViewRepository { + func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) +} + final class MountainListUseCase { private let repository: MountainListViewRepository private var entireMountains: [MountainEntity]? From 3b016fa24edc7bfcef082e077d602224d0ab21f8 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 30 Nov 2021 18:09:10 +0900 Subject: [PATCH 453/465] =?UTF-8?q?[Test]=20#362=20MountainList=20Unit=20T?= =?UTF-8?q?est=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MountainListSceneTests.swift | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/SanTa/MountainListSceneTests/MountainListSceneTests.swift b/SanTa/MountainListSceneTests/MountainListSceneTests.swift index 2b254b5..29f395d 100644 --- a/SanTa/MountainListSceneTests/MountainListSceneTests.swift +++ b/SanTa/MountainListSceneTests/MountainListSceneTests.swift @@ -20,7 +20,8 @@ final class MountainListSceneTests: XCTestCase { class SuccessMountainViewRepository: MountainListViewRepository { func fetchMountains(completion: @escaping (Result<[MountainEntity], Error>) -> Void) { - let mountainList = [MountainEntity]() + let mountainList = [MountainEntity(mountain: MountainEntity.MountainDetail(mountainName: "한라산", mountainRegion: "", mountainHeight: "", mountainShortDescription: "제주도에 있습니다."), latitude: 0, longitude: 0), + MountainEntity(mountain: MountainEntity.MountainDetail(mountainName: "토함산", mountainRegion: "", mountainHeight: "", mountainShortDescription: "경주에 있습니다."), latitude: 0, longitude: 0)] completion(.success(mountainList)) } } @@ -38,15 +39,64 @@ final class MountainListSceneTests: XCTestCase { self.failViewModel = MountainListViewModel(useCase: failUseCase) } - func test_MountainList_가져오기_성공 () { + func test_MountainList_가져오기_성공() { successViewModel.viewDidLoad() _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) XCTAssertNotNil(successViewModel.mountains) } - func test_MountainList_가져오기_실패 () { + func test_MountainList_가져오기_실패() { failViewModel.viewDidLoad() _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) XCTAssertNil(failViewModel.mountains) } + + func test_MountainList_산_개수_비교_성공() { + successViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertTrue(!successViewModel.mountains!.isEmpty) + } + + func test_MountainList_산_개수_비교_실패() { + successViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertFalse(successViewModel.mountains?.count == 0) + } + + func test_MountainList_첫번째_산_이름_비교_성공() { + successViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertTrue(successViewModel.mountains?[0].mountain.mountainName == "한라산") + } + + func test_MountainList_첫번째_산_이름_비교_실패() { + successViewModel.viewDidLoad() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + XCTAssertFalse(successViewModel.mountains?[0].mountain.mountainName == "") + } + + func test_MountainList_토함산_찾기_성공() { + successViewModel.viewDidLoad() + successViewModel.mountainName = "토함산" + + successViewModel.findMountains() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + + + XCTAssertTrue(successViewModel.mountains?[0].mountain.mountainName == "토함산") + XCTAssertTrue(successViewModel.mountains!.count == 1) + } + + func test_MountainList_산_찾기_실패() { + successViewModel.viewDidLoad() + successViewModel.mountainName = "" + + let mountainCount = successViewModel.mountains!.count + + successViewModel.findMountains() + _ = XCTWaiter.wait(for: [expectation(description: "Wait for 0.1 seconds")], timeout: 0.1) + + + XCTAssertTrue(successViewModel.mountains!.count == mountainCount) + } } From e35cc9294de7bc3d0b2c3d554881c22ce0cb6e71 Mon Sep 17 00:00:00 2001 From: MinChang Date: Tue, 30 Nov 2021 19:58:08 +0900 Subject: [PATCH 454/465] =?UTF-8?q?[Test]=20RecordingScene=20Test=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecordingUseCaseTests.swift | 29 +-------------- .../RecordingViewModelTests.swift | 6 ++-- .../TestRecordingRepository.swift | 35 +++++++++++++++++++ SanTa/SanTa.xcodeproj/project.pbxproj | 4 +++ 4 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 SanTa/RecordingSceneTests/TestRecordingRepository.swift diff --git a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift index 6fa2232..9672436 100644 --- a/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift +++ b/SanTa/RecordingSceneTests/RecordingUseCaseTests.swift @@ -12,34 +12,7 @@ final class RecordingUseCaseTests: XCTestCase { private var useCase: DefaultRecordingUseCase! private var repository: RecordRepository! - enum testError: Error { - case StoreError - } - - class TestRecordingRepository: RecordRepository { - func saveRecordPhotoOption(value: Bool) { - return - } - - func save(records: Records, - completion: @escaping (Result) -> Void) { - - completion(.success(records)) - } - - func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { - switch key { - case .voiceGuidanceEveryOnekm: - completion(.success(true)) - case .recordPhoto: - completion(.success(true)) - default: - completion(.success(false)) - } - } - } - - override func setUpWithError() throws { + override func setUp() { repository = TestRecordingRepository() useCase = DefaultRecordingUseCase(recordRepository: repository, recordingModel: nil, recordingPhoto: RecordingPhotoModel()) } diff --git a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift index 16ba9bd..2cf6124 100644 --- a/SanTa/RecordingSceneTests/RecordingViewModelTests.swift +++ b/SanTa/RecordingSceneTests/RecordingViewModelTests.swift @@ -13,10 +13,10 @@ final class RecordingViewModelTests: XCTestCase { private let recordingUseCase: RecordingUseCase? = nil private var subscriptions = Set() private var recordingViewModel = RecordingViewModel(recordingUseCase: nil) - - override func setUpWithError() throws { + + override func setUp() { } - + func test_시간_받기_성공() { var result = "" diff --git a/SanTa/RecordingSceneTests/TestRecordingRepository.swift b/SanTa/RecordingSceneTests/TestRecordingRepository.swift new file mode 100644 index 0000000..fc1acec --- /dev/null +++ b/SanTa/RecordingSceneTests/TestRecordingRepository.swift @@ -0,0 +1,35 @@ +// +// TestRecordingRepository.swift +// RecordingSceneTests +// +// Created by 김민창 on 2021/11/30. +// + +import Foundation + +enum testError: Error { + case StoreError +} + +class TestRecordingRepository: RecordRepository { + func saveRecordPhotoOption(value: Bool) { + return + } + + func save(records: Records, + completion: @escaping (Result) -> Void) { + + completion(.success(records)) + } + + func fetchRecordOption(key: Settings, completion: @escaping (Result) -> Void) { + switch key { + case .voiceGuidanceEveryOnekm: + completion(.success(true)) + case .recordPhoto: + completion(.success(true)) + default: + completion(.success(false)) + } + } +} diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index da35a7e..3cc7f84 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -93,6 +93,7 @@ DA4736F927561C9400841326 /* MountainListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6B273CE02400780DC8 /* MountainListViewModel.swift */; }; DA4736FA27561C9400841326 /* MountainListViewUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAAF4D6D273CE06A00780DC8 /* MountainListViewUseCase.swift */; }; DA4736FB27561C9A00841326 /* MountainEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FEEDB82732584000D37CCA /* MountainEntity.swift */; }; + DA4736FD2756383000841326 /* TestRecordingRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736FC2756383000841326 /* TestRecordingRepository.swift */; }; DA854FD42746270A00E51E4B /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A913002736844E008AAE39 /* UserDefaultsStorage.swift */; }; DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */; }; DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC227325DFC003BE56B /* RecordingUseCase.swift */; }; @@ -225,6 +226,7 @@ DA4736D12755E39500841326 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; DA4736F027561C6200841326 /* MountainListSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MountainListSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA4736F227561C6200841326 /* MountainListSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListSceneTests.swift; sourceTree = ""; }; + DA4736FC2756383000841326 /* TestRecordingRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestRecordingRepository.swift; sourceTree = ""; }; DA854FD92746273300E51E4B /* RecordingSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RecordingSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUseCaseTests.swift; sourceTree = ""; }; DA9D7C9C273A433E0018AD45 /* RecordingTitleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingTitleViewController.swift; sourceTree = ""; }; @@ -545,6 +547,7 @@ children = ( DA854FDB2746273300E51E4B /* RecordingUseCaseTests.swift */, DAB25F1A2754AF2D00F0BE75 /* RecordingViewModelTests.swift */, + DA4736FC2756383000841326 /* TestRecordingRepository.swift */, ); path = RecordingSceneTests; sourceTree = ""; @@ -909,6 +912,7 @@ DA854FE62746282600E51E4B /* RecordingPhotoModel.swift in Sources */, DAB25F1B2754AF2D00F0BE75 /* RecordingViewModelTests.swift in Sources */, DA854FE1274627AA00E51E4B /* RecordingModel.swift in Sources */, + DA4736FD2756383000841326 /* TestRecordingRepository.swift in Sources */, DA854FE02746279F00E51E4B /* RecordingUseCase.swift in Sources */, DA854FDC2746273300E51E4B /* RecordingUseCaseTests.swift in Sources */, ); From f851467ec069d2c235f05c5efa06c8b2517296d1 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Wed, 1 Dec 2021 10:45:19 +0900 Subject: [PATCH 455/465] =?UTF-8?q?[Test]=20=EA=B3=A0=EB=8F=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ResultDetailAltitudeTest.swift | 68 ++++++++ SanTa/SanTa.xcodeproj/project.pbxproj | 145 +++++++++++++++++- .../xcshareddata/xcschemes/SanTa.xcscheme | 12 +- .../ResultDetailScene/ResultDetailModel.swift | 3 + 4 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 SanTa/ResultDetailAltitudeTest/ResultDetailAltitudeTest.swift diff --git a/SanTa/ResultDetailAltitudeTest/ResultDetailAltitudeTest.swift b/SanTa/ResultDetailAltitudeTest/ResultDetailAltitudeTest.swift new file mode 100644 index 0000000..ca01354 --- /dev/null +++ b/SanTa/ResultDetailAltitudeTest/ResultDetailAltitudeTest.swift @@ -0,0 +1,68 @@ +// +// ResultDetailTest.swift +// ResultDetailTest +// +// Created by Jiwon Yoon on 2021/11/30. +// + +import XCTest + +class ResultDetailTest: XCTestCase { + let location1 = Location(latitude: 37.53456840060343, longitude: 127.1299119494656, altitude: 20) + let location2 = Location(latitude: 37.53456840060343, longitude: 127.1299119494656, altitude: 40) + let location3 = Location(latitude: 37.53456840060343, longitude: 127.1299119494656, altitude: 50) + let location4 = Location(latitude: 37.53456840060343, longitude: 127.1299119494656, altitude: 10) + + private var resultAltitude: ResultDetailViewModel.AltitudeViewModel! + + + func test_빈위치좌표배열받을시_고도가전부마이너스() throws { + let emptyRecord = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: []) + let records = Records(title: "기록제목", records: [emptyRecord], assetIdentifiers: [], secondPerHighestSpeed: 600, secondPerMinimumSpeed: 600, id: "id") + let altModel = ResultAltitude(records: records) + resultAltitude = .init(altitudeData: altModel) + XCTAssertEqual(resultAltitude.contents.filter{$0.content.contains("-")}.count, 5) + } + + func test_최저고도_최고고도_레코드한개() throws { + let record1 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location1, location2]) + let records = Records(title: "기록제목", records: [record1], assetIdentifiers: [], secondPerHighestSpeed: 600, secondPerMinimumSpeed: 600, id: "id") + let altModel = ResultAltitude(records: records) + resultAltitude = .init(altitudeData: altModel) + XCTAssertEqual(resultAltitude.lowest, "20") + XCTAssertEqual(resultAltitude.highest, "40") + } + + func test_최저고도_최고고도_레코드여러개() throws { + let record1 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location1, location2]) + let record2 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location3, location4]) + let records = Records(title: "기록제목", records: [record1, record2], assetIdentifiers: [], secondPerHighestSpeed: 600, secondPerMinimumSpeed: 600, id: "id") + let altModel = ResultAltitude(records: records) + resultAltitude = .init(altitudeData: altModel) + XCTAssertEqual(resultAltitude.lowest, "10") + XCTAssertEqual(resultAltitude.highest, "50") + } + + func test_시작고도_종료고도_레코드한개() throws { + let record1 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location1, location2]) + let records = Records(title: "기록제목", records: [record1], assetIdentifiers: [], secondPerHighestSpeed: 600, secondPerMinimumSpeed: 600, id: "id") + let altModel = ResultAltitude(records: records) + resultAltitude = .init(altitudeData: altModel) + let start = resultAltitude.contents.filter {$0.contentTitle == "시작"}.first?.content ?? "" + let end = resultAltitude.contents.filter {$0.contentTitle == "종료"}.first?.content ?? "" + XCTAssertEqual(start, "20") + XCTAssertEqual(end, "40") + } + + func test_시작고도_종료고도_레코드여러개() throws { + let record1 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location1, location2]) + let record2 = Record(startTime: Date.now, endTime: Date.now + 100, step: 7777, distance: 777, locations: [location3, location4]) + let records = Records(title: "기록제목", records: [record2, record1], assetIdentifiers: [], secondPerHighestSpeed: 600, secondPerMinimumSpeed: 600, id: "id") + let altModel = ResultAltitude(records: records) + resultAltitude = .init(altitudeData: altModel) + let start = resultAltitude.contents.filter {$0.contentTitle == "시작"}.first?.content ?? "" + let end = resultAltitude.contents.filter {$0.contentTitle == "종료"}.first?.content ?? "" + XCTAssertEqual(start, "50") + XCTAssertEqual(end, "40") + } +} diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index b6c2c79..f7fe7e9 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -13,6 +13,16 @@ 493178B627439D0000B5FB88 /* ResultDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B527439D0000B5FB88 /* ResultDetailModel.swift */; }; 494803822743748D002854B1 /* ResultDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494803812743748D002854B1 /* ResultDetailViewModel.swift */; }; 4948038427437499002854B1 /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; + 4953CB822757092D00A0106F /* ResultDetailAltitudeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4953CB812757092D00A0106F /* ResultDetailAltitudeTest.swift */; }; + 4953CB882757095C00A0106F /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; + 4953CB892757096000A0106F /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; + 4953CB8A2757096500A0106F /* CoreDataRecordStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC627327064003BE56B /* CoreDataRecordStorage.swift */; }; + 4953CB8B2757097700A0106F /* ResultDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494803812743748D002854B1 /* ResultDetailViewModel.swift */; }; + 4953CB8C2757098900A0106F /* ResultDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 493178B527439D0000B5FB88 /* ResultDetailModel.swift */; }; + 4953CB8D275709D700A0106F /* ResultDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4948038327437499002854B1 /* ResultDetailUseCase.swift */; }; + 4953CB8E27570A1300A0106F /* ResultDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49921D88274B3B440091112C /* ResultDetailRepository.swift */; }; + 4953CB8F27570A1E00A0106F /* SanTa.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5485128A272A6AD500407F28 /* SanTa.xcdatamodeld */; }; + 4953CB9027570A3000A0106F /* CoreDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC8273271EC003BE56B /* CoreDataStorage.swift */; }; 4955B8EB2742A65D00D90F94 /* MountainDetailAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */; }; 49742D562740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */; }; 49921D89274B3B440091112C /* ResultDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49921D88274B3B440091112C /* ResultDetailRepository.swift */; }; @@ -146,6 +156,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 4953CB832757092D00A0106F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; 5423CD672755FA4A00BAB338 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 54851276272A6AD500407F28 /* Project object */; @@ -190,6 +207,8 @@ 493178B527439D0000B5FB88 /* ResultDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailModel.swift; sourceTree = ""; }; 494803812743748D002854B1 /* ResultDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailViewModel.swift; sourceTree = ""; }; 4948038327437499002854B1 /* ResultDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailUseCase.swift; sourceTree = ""; }; + 4953CB7F2757092D00A0106F /* ResultDetailAltitudeTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ResultDetailAltitudeTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 4953CB812757092D00A0106F /* ResultDetailAltitudeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailAltitudeTest.swift; sourceTree = ""; }; 4955B8EA2742A65D00D90F94 /* MountainDetailAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainDetailAnnotationView.swift; sourceTree = ""; }; 49742D552740E1A0008F7DC2 /* ResultDetailLargerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailLargerInfoView.swift; sourceTree = ""; }; 49921D88274B3B440091112C /* ResultDetailRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultDetailRepository.swift; sourceTree = ""; }; @@ -293,6 +312,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 4953CB7C2757092D00A0106F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5423CD602755FA4A00BAB338 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -345,6 +371,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 4953CB802757092D00A0106F /* ResultDetailAltitudeTest */ = { + isa = PBXGroup; + children = ( + 4953CB812757092D00A0106F /* ResultDetailAltitudeTest.swift */, + ); + path = ResultDetailAltitudeTest; + sourceTree = ""; + }; 5423CD642755FA4A00BAB338 /* MapSceneTests */ = { isa = PBXGroup; children = ( @@ -523,6 +557,7 @@ DA4736F127561C6200841326 /* MountainListSceneTests */, 5423CD642755FA4A00BAB338 /* MapSceneTests */, 5423CD802755FCEF00BAB338 /* MountainAddingSceneTests */, + 4953CB802757092D00A0106F /* ResultDetailAltitudeTest */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -537,6 +572,7 @@ DA4736F027561C6200841326 /* MountainListSceneTests.xctest */, 5423CD632755FA4A00BAB338 /* MapSceneTests.xctest */, 5423CD7F2755FCEF00BAB338 /* MountainAddingSceneTests.xctest */, + 4953CB7F2757092D00A0106F /* ResultDetailAltitudeTest.xctest */, ); name = Products; sourceTree = ""; @@ -668,6 +704,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 4953CB7E2757092D00A0106F /* ResultDetailAltitudeTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4953CB872757092D00A0106F /* Build configuration list for PBXNativeTarget "ResultDetailAltitudeTest" */; + buildPhases = ( + 4953CB7B2757092D00A0106F /* Sources */, + 4953CB7C2757092D00A0106F /* Frameworks */, + 4953CB7D2757092D00A0106F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4953CB842757092D00A0106F /* PBXTargetDependency */, + ); + name = ResultDetailAltitudeTest; + productName = ResultDetailAltitudeTest; + productReference = 4953CB7F2757092D00A0106F /* ResultDetailAltitudeTest.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5423CD622755FA4A00BAB338 /* MapSceneTests */ = { isa = PBXNativeTarget; buildConfigurationList = 5423CD6B2755FA4A00BAB338 /* Build configuration list for PBXNativeTarget "MapSceneTests" */; @@ -799,9 +853,13 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1300; + LastSwiftUpdateCheck = 1310; LastUpgradeCheck = 1300; TargetAttributes = { + 4953CB7E2757092D00A0106F = { + CreatedOnToolsVersion = 13.1; + TestTargetID = 5485127D272A6AD500407F28; + }; 5423CD622755FA4A00BAB338 = { CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; @@ -850,11 +908,19 @@ DA4736EF27561C6200841326 /* MountainListSceneTests */, 5423CD622755FA4A00BAB338 /* MapSceneTests */, 5423CD7E2755FCEF00BAB338 /* MountainAddingSceneTests */, + 4953CB7E2757092D00A0106F /* ResultDetailAltitudeTest */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 4953CB7D2757092D00A0106F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5423CD612755FA4A00BAB338 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -910,6 +976,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 4953CB7B2757092D00A0106F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4953CB9027570A3000A0106F /* CoreDataStorage.swift in Sources */, + 4953CB882757095C00A0106F /* Record.swift in Sources */, + 4953CB8E27570A1300A0106F /* ResultDetailRepository.swift in Sources */, + 4953CB8A2757096500A0106F /* CoreDataRecordStorage.swift in Sources */, + 4953CB892757096000A0106F /* Location.swift in Sources */, + 4953CB8B2757097700A0106F /* ResultDetailViewModel.swift in Sources */, + 4953CB822757092D00A0106F /* ResultDetailAltitudeTest.swift in Sources */, + 4953CB8D275709D700A0106F /* ResultDetailUseCase.swift in Sources */, + 4953CB8C2757098900A0106F /* ResultDetailModel.swift in Sources */, + 4953CB8F27570A1E00A0106F /* SanTa.xcdatamodeld in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5423CD5F2755FA4A00BAB338 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1095,6 +1178,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 4953CB842757092D00A0106F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 4953CB832757092D00A0106F /* PBXContainerItemProxy */; + }; 5423CD682755FA4A00BAB338 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5485127D272A6AD500407F28 /* SanTa */; @@ -1134,6 +1222,52 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 4953CB852757092D00A0106F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = jw.ResultDetailAltitudeTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Debug; + }; + 4953CB862757092D00A0106F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = jw.ResultDetailAltitudeTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SanTa.app/SanTa"; + }; + name = Release; + }; 5423CD692755FA4A00BAB338 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1587,6 +1721,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 4953CB872757092D00A0106F /* Build configuration list for PBXNativeTarget "ResultDetailAltitudeTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4953CB852757092D00A0106F /* Debug */, + 4953CB862757092D00A0106F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5423CD6B2755FA4A00BAB338 /* Build configuration list for PBXNativeTarget "MapSceneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index ec66bd1..36e35ce 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -67,7 +67,7 @@ @@ -92,6 +92,16 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + Date: Wed, 1 Dec 2021 10:56:03 +0900 Subject: [PATCH 456/465] =?UTF-8?q?[Feat]=20#303=20=EC=82=B0=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=99=94=EB=A9=B4=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcshareddata/xcschemes/SanTa.xcscheme | 2 +- .../MountainDetailViewController.swift | 20 +------------------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index ec66bd1..cf1c07a 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -67,7 +67,7 @@ diff --git a/SanTa/SanTa/Scenes/MountainDetailScene/MountainDetailViewController.swift b/SanTa/SanTa/Scenes/MountainDetailScene/MountainDetailViewController.swift index 3d7f45e..b9ba22f 100644 --- a/SanTa/SanTa/Scenes/MountainDetailScene/MountainDetailViewController.swift +++ b/SanTa/SanTa/Scenes/MountainDetailScene/MountainDetailViewController.swift @@ -11,8 +11,6 @@ import MapKit final class MountainDetailViewController: UIViewController { weak var coordinator: MountainDetailViewCoordinator? private var viewModel: MountainDetailViewModel? - private var mutatingTopConstraint: NSLayoutConstraint? - private let maxRollUpDistance: CGFloat = 50 private lazy var backButton: UIButton = { let button = UIButton(frame: .zero) @@ -76,19 +74,13 @@ extension MountainDetailViewController { mapSnapShot.heightAnchor.constraint(equalTo: headerView.heightAnchor, multiplier: 0.85) ]) - self.mutatingTopConstraint = titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor) NSLayoutConstraint.activate([ + titleView.topAnchor.constraint(equalTo: mapSnapShot.bottomAnchor), titleView.leftAnchor.constraint(equalTo: headerView.leftAnchor), titleView.rightAnchor.constraint(equalTo: headerView.rightAnchor), titleView.heightAnchor.constraint(equalToConstant: self.view.bounds.height * 0.07) ]) - if let upperConstraint = self.mutatingTopConstraint { - NSLayoutConstraint.activate([ - upperConstraint - ]) - } - NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: titleView.bottomAnchor), tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), @@ -214,16 +206,6 @@ extension MountainDetailViewController: UITableViewDelegate, UITableViewDataSour } } -extension MountainDetailViewController: UIScrollViewDelegate { - func scrollViewDidScroll(_ scrollView: UIScrollView) { - let isBottom = scrollView.contentSize.height <= scrollView.bounds.height + scrollView.contentOffset.y - guard !isBottom else { return } - if scrollView.contentOffset.y > 0 && scrollView.contentOffset.y < self.maxRollUpDistance { - self.mutatingTopConstraint?.constant = -scrollView.contentOffset.y - } - } -} - extension MountainDetailViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { guard let annotation = annotation as? MountainAnnotation else { return nil } From 90ceea5da2ef93b105b3e5353be49dfa4f406881 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Wed, 1 Dec 2021 10:59:58 +0900 Subject: [PATCH 457/465] =?UTF-8?q?[Fix]=20#368=20pace=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift index eb7e3c4..644d984 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift @@ -88,7 +88,7 @@ struct ResultPace { let slowestPace: TimeInterval init(records: Records) { - self.timePerKilometer = records.distances / records.totalTravelTime / 1000 + self.timePerKilometer = records.totalTravelTime / records.distances self.fastestPace = TimeInterval(records.secondPerHighestSpeed) self.slowestPace = TimeInterval(records.secondPerMinimumSpeed) } From ff3002c481d24a397836cb1f3502f3b5d7d212e0 Mon Sep 17 00:00:00 2001 From: Shin Date: Wed, 1 Dec 2021 14:21:39 +0900 Subject: [PATCH 458/465] =?UTF-8?q?[Fix]=20#371=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=EC=9D=84=20=ED=84=B0=EC=B9=98=ED=95=98=EC=98=80=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=95=B1=EC=9D=B4=20=ED=81=AC=EB=9E=98=EC=8B=9C?= =?UTF-8?q?=EB=82=98=EB=8A=94=20=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift | 6 +++++- .../Scenes/ResultDetailScene/ResultDetailViewModel.swift | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift index 43dbf03..ebbf487 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift @@ -88,7 +88,11 @@ struct ResultPace { let slowestPace: TimeInterval init(records: Records) { - self.timePerKilometer = records.totalTravelTime / records.distances + if records.distances == 0 { + self.timePerKilometer = 0 + } else { + self.timePerKilometer = records.totalTravelTime / records.distances + } self.fastestPace = TimeInterval(records.secondPerHighestSpeed) self.slowestPace = TimeInterval(records.secondPerMinimumSpeed) } diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailViewModel.swift b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailViewModel.swift index 028eb11..401d276 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailViewModel.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailViewModel.swift @@ -72,8 +72,9 @@ final class ResultDetailViewModel { guard let distance = self.resultDetailData?.distance.total, let totalTime = self.resultDetailData?.time.spent, totalTime > 0, let speed = formatter.string(from: NSNumber(value: distance * 3600 / totalTime)) else { - return "-" + return "알 수 없음" } + if distance == 0 { return "-" } return speed } From 6d6b427dc5728f59dac3c617fcf36e9509681a82 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Wed, 1 Dec 2021 15:37:24 +0900 Subject: [PATCH 459/465] =?UTF-8?q?[Docs]=20README.md=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 157 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 142 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f535205..ef603ad 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # SanTa🏔🎅🏻

-
+
# 🎯 개발 환경 - Xcode 13.0+ - Swift 5.5+ -- iOS 14.5+ +- iOS 15.0+ -
+
# 📝 프로젝트 목표 + ``` -1. 기존 올라 앱보다 더 많은 산 데이터를 제공 -2. 기존 올라 앱보다 뛰어난 접근성 제공 -3. CoreData, CoreLocation, CoreMotion, MapKit을 활용한 앱 -4. 외부 라이브러리에 대한 의존성이 없는 앱 +1. 올라 앱보다 더 많은 산 데이터를 제공 +2. 뛰어난 접근성 제공 +3. Apple FrameWork를 활용하여 개발 +4. 스토리보드를 사용하지 않고 개발 ``` -
+
# 💬 프로젝트 소개 -산타는 등산 기록을 측정하고, 측정된 데이터를 사용자가 쉽게 파악할 수 있도록 해주는 iOS 어플리케이션 입니다. +### ✅ 대한민국 산의 정보를 확인해 보세요 + +지도, 산 목록 화면을 통해 산을 확인할 수 있으며 각각의 산에 대한 세부 정보도 확인할 수 있습니다. + +### ✅ 등산 기록을 측정해 보세요 + +등산 측정을 시작하면 등산에 대한 여러 정보를 측정할 수 있습니다. 또한 등산 중에 찍은 사진기록도 저장이 되며 1km를 걸을 때마다 음성 안내도 지원하고 있습니다. + +### ✅ 기록된 데이터를 확인해 보세요 + +등산 기록들을 한눈에 파악할 수 있습니다. 또한 기록된 등산 기록을 클릭하여 훨씬 더 세부적인 정보를 확인할 수 있습니다. -
+### ✅ 손쉬운 사용을 경험해 보세요 + +손쉬운 사용에서 더 큰 텍스트와 VoiceOver를 지원합니다. + + +
# 👀 미리 보기 +
+ +|||| +|:-:|:-:|:-:| +|`지도화면`|`측정화면`|`기록화면`| +|||| +|`개별기록화면`|`산 목록화면`|`설정화면`| + +
+
+ + # ⚙️ 기능 +``` +- 지도에서 산 위치 확인 +- 목록에서 산 이름으로 검색 +- 산 상세 정보 확인 +- 이동 기록 측정 +- 측정중 촬영한 사진 경로에 표시 +- 측정한 기록 상세 정보 확인 +- 보이스오버, 다이나믹 타입 적용으로 접근성 증가 +- 사용자가 임의로 장소(산) 추가 가능 +- 1km 마다 음성안내 기능 +``` + +
+ # 🏛 아키텍처 +![](https://i.imgur.com/cWt3FUh.png) + +
+ # 📂 폴더구조 +```swift + SanTa + ᄂ Resources + ᄂ Application + ᄂ Persistences + ᄂ Entities + ᄂ Utility + ᄂ Scenes + ᄂ MapScene + ᄂ MountainAddingScene + ᄂ RecordingScene + ᄂ RecordingTitleScene + ᄂ RecordingPhotoScene + ᄂ ResultScene + ᄂ ResultDetailScene + ᄂ ResultDetailImagesScene + ᄂ ResultDetailThumbnailScene + ᄂ MountainListScene + ᄂ MountainDetailScene + ᄂ SettingsScene +``` + +
+ # 🖼 프레임워크 + + +
+ # 🎖 도전 사항 + +``` +- StoryBoard 없이 코드로만 뷰 구성 +- MVVM-C 패턴 도입 +- Clean Architecture +- MapKit, CoreLocation, CoreMotion +- Combine +- DiffableDataSource, Compositional Layout +- CoreData +- GeoCoding +``` + + +# ➕ 기타 + +
+ 위키 + +- [기획서](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D%EC%84%9C) +- [백로그 v1.0](https://docs.google.com/spreadsheets/d/1knT2-uQZDPz_AqpKvzfX5WR0OSWgWKeMTkDxKiYlCSQ/edit#gid=0) +- [백로그 v2.0](https://docs.google.com/spreadsheets/d/1dg-yESySimbF7rKb7PhkNopBnSWy8--Ss5LfAvjjDHk/edit#gid=0) +- [그라운드 룰](https://github.com/boostcampwm-2021/iOS02/wiki/%EA%B7%B8%EB%9D%BC%EC%9A%B4%EB%93%9C-%EB%A3%B0) +- [컨벤션](https://github.com/boostcampwm-2021/iOS02/wiki/%EA%B7%9C%EC%B9%99) + +
+ +
+ +
+ 트러블 슈팅 + +- [트러블 슈팅](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/트러블-슈팅) +- [Controller 메모리 해제 문제](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/RecordingViewController-%EB%A9%94%EB%AA%A8%EB%A6%AC-%ED%95%B4%EC%A0%9C-%EB%AC%B8%EC%A0%9C) +- [Pull Request Strategy](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Pull-Request-Strategy) +- [산 목록 검색 문제](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/%EC%82%B0-%EB%AA%A9%EB%A1%9D-%EA%B2%80%EC%83%89) +- [권한 유도 중 Controller 오류](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/%EC%95%B1-%EA%B6%8C%ED%95%9C-%EC%9C%A0%EB%8F%84-%EC%A4%91-Controller-%EC%98%A4%EB%A5%98) +- [Sticky Header 버그 해결과정](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Navigation-Bar와-Sticky-Header) +- [Git으로 Bug 찾기](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Git으로-Bug-찾기) +- [Delegate와 순환참조](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Delegate와-순환참조) +
+ +
+ +
+ 학습 + +- [위치 정보 요청](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/위치-정보-요청하기) +- [GeoCoding](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Google-GeoCoding을-이용하여-산-이름으로-(위도,경도)-찾기) +- [Custom Push/Pop Transition](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/Custom-Push-Pop-Transition) +- [CoreData](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/CoreData) +- [UIFeedbackGenerator](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/UIFeedbackGenerator) +- [VoiceOver](https://github.com/boostcampwm-2021/iOS02-SanTa/wiki/VoiceOver) +
From 2d4739798da28a9a5b9818d246b8ff79eed4b4ac Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Wed, 1 Dec 2021 16:53:04 +0900 Subject: [PATCH 460/465] =?UTF-8?q?[Test]=20#373=20UITest=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa.xcodeproj/project.pbxproj | 129 +++++++++++++++++- .../xcshareddata/xcschemes/SanTa.xcscheme | 10 ++ .../Scenes/ResultScene/RecordsViewCell.swift | 3 +- .../ResultScene/ResultViewController.swift | 2 +- SanTa/SanTaUITests/SanTaUITests.swift | 63 +++++++++ .../SanTaUITestsLaunchTests.swift | 32 +++++ 6 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 SanTa/SanTaUITests/SanTaUITests.swift create mode 100644 SanTa/SanTaUITests/SanTaUITestsLaunchTests.swift diff --git a/SanTa/SanTa.xcodeproj/project.pbxproj b/SanTa/SanTa.xcodeproj/project.pbxproj index f7fe7e9..66c91e5 100644 --- a/SanTa/SanTa.xcodeproj/project.pbxproj +++ b/SanTa/SanTa.xcodeproj/project.pbxproj @@ -119,6 +119,8 @@ 98BCF4F52737A3480073E6FB /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */; }; 98BCF4F72737A66E0073E6FB /* SettingsUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */; }; 98BCF4F92737A7120073E6FB /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */; }; + 98C954A52757532B0058DD22 /* SanTaUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C954A42757532B0058DD22 /* SanTaUITests.swift */; }; + 98C954A72757532B0058DD22 /* SanTaUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C954A62757532B0058DD22 /* SanTaUITestsLaunchTests.swift */; }; DA4736D22755E39500841326 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA4736D12755E39500841326 /* Location.swift */; }; DA4736E6275610EE00841326 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826F3DE273904010064FA85 /* Settings.swift */; }; DA4736E7275610F600841326 /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984DDEC027325D67003BE56B /* Record.swift */; }; @@ -191,6 +193,13 @@ remoteGlobalIDString = 5485127D272A6AD500407F28; remoteInfo = SanTa; }; + 98C954A82757532B0058DD22 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 54851276272A6AD500407F28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5485127D272A6AD500407F28; + remoteInfo = SanTa; + }; DA4736F427561C6200841326 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 54851276272A6AD500407F28 /* Project object */; @@ -284,6 +293,9 @@ 98BCF4F42737A3480073E6FB /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 98BCF4F62737A66E0073E6FB /* SettingsUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUsecase.swift; sourceTree = ""; }; 98BCF4F82737A7120073E6FB /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; + 98C954A22757532B0058DD22 /* SanTaUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SanTaUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 98C954A42757532B0058DD22 /* SanTaUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SanTaUITests.swift; sourceTree = ""; }; + 98C954A62757532B0058DD22 /* SanTaUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SanTaUITestsLaunchTests.swift; sourceTree = ""; }; DA4736D12755E39500841326 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; DA4736F027561C6200841326 /* MountainListSceneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MountainListSceneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA4736F227561C6200841326 /* MountainListSceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MountainListSceneTests.swift; sourceTree = ""; }; @@ -354,6 +366,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98C9549F2757532B0058DD22 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4736ED27561C6200841326 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -558,6 +577,7 @@ 5423CD642755FA4A00BAB338 /* MapSceneTests */, 5423CD802755FCEF00BAB338 /* MountainAddingSceneTests */, 4953CB802757092D00A0106F /* ResultDetailAltitudeTest */, + 98C954A32757532B0058DD22 /* SanTaUITests */, 5485127F272A6AD500407F28 /* Products */, ); sourceTree = ""; @@ -573,6 +593,7 @@ 5423CD632755FA4A00BAB338 /* MapSceneTests.xctest */, 5423CD7F2755FCEF00BAB338 /* MountainAddingSceneTests.xctest */, 4953CB7F2757092D00A0106F /* ResultDetailAltitudeTest.xctest */, + 98C954A22757532B0058DD22 /* SanTaUITests.xctest */, ); name = Products; sourceTree = ""; @@ -619,6 +640,15 @@ path = ResultSceneTests; sourceTree = ""; }; + 98C954A32757532B0058DD22 /* SanTaUITests */ = { + isa = PBXGroup; + children = ( + 98C954A42757532B0058DD22 /* SanTaUITests.swift */, + 98C954A62757532B0058DD22 /* SanTaUITestsLaunchTests.swift */, + ); + path = SanTaUITests; + sourceTree = ""; + }; DA4736D32755E46800841326 /* Utility */ = { isa = PBXGroup; children = ( @@ -811,6 +841,24 @@ productReference = 98BAABB1275479B0004505BB /* ResultSceneTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 98C954A12757532B0058DD22 /* SanTaUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 98C954AC2757532B0058DD22 /* Build configuration list for PBXNativeTarget "SanTaUITests" */; + buildPhases = ( + 98C9549E2757532B0058DD22 /* Sources */, + 98C9549F2757532B0058DD22 /* Frameworks */, + 98C954A02757532B0058DD22 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 98C954A92757532B0058DD22 /* PBXTargetDependency */, + ); + name = SanTaUITests; + productName = SanTaUITests; + productReference = 98C954A22757532B0058DD22 /* SanTaUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; DA4736EF27561C6200841326 /* MountainListSceneTests */ = { isa = PBXNativeTarget; buildConfigurationList = DA4736F627561C6200841326 /* Build configuration list for PBXNativeTarget "MountainListSceneTests" */; @@ -853,7 +901,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1310; + LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 1300; TargetAttributes = { 4953CB7E2757092D00A0106F = { @@ -879,6 +927,10 @@ CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; }; + 98C954A12757532B0058DD22 = { + CreatedOnToolsVersion = 13.0; + TestTargetID = 5485127D272A6AD500407F28; + }; DA4736EF27561C6200841326 = { CreatedOnToolsVersion = 13.0; TestTargetID = 5485127D272A6AD500407F28; @@ -909,6 +961,7 @@ 5423CD622755FA4A00BAB338 /* MapSceneTests */, 5423CD7E2755FCEF00BAB338 /* MountainAddingSceneTests */, 4953CB7E2757092D00A0106F /* ResultDetailAltitudeTest */, + 98C954A12757532B0058DD22 /* SanTaUITests */, ); }; /* End PBXProject section */ @@ -959,6 +1012,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98C954A02757532B0058DD22 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4736EE27561C6200841326 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1147,6 +1207,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 98C9549E2757532B0058DD22 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 98C954A72757532B0058DD22 /* SanTaUITestsLaunchTests.swift in Sources */, + 98C954A52757532B0058DD22 /* SanTaUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA4736EC27561C6200841326 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1203,6 +1272,11 @@ target = 5485127D272A6AD500407F28 /* SanTa */; targetProxy = 98BAABB5275479B0004505BB /* PBXContainerItemProxy */; }; + 98C954A92757532B0058DD22 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5485127D272A6AD500407F28 /* SanTa */; + targetProxy = 98C954A82757532B0058DD22 /* PBXContainerItemProxy */; + }; DA4736F527561C6200841326 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5485127D272A6AD500407F28 /* SanTa */; @@ -1630,6 +1704,50 @@ }; name = Release; }; + 98C954AA2757532B0058DD22 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.SanTaUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SanTa; + }; + name = Debug; + }; + 98C954AB2757532B0058DD22 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = B3PWYBKFUK; + GENERATE_INFOPLIST_FILE = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.ohchangmin.SanTaUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SanTa; + }; + name = Release; + }; DA4736F727561C6200841326 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1784,6 +1902,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 98C954AC2757532B0058DD22 /* Build configuration list for PBXNativeTarget "SanTaUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 98C954AA2757532B0058DD22 /* Debug */, + 98C954AB2757532B0058DD22 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA4736F627561C6200841326 /* Build configuration list for PBXNativeTarget "MountainListSceneTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme index 36e35ce..564be1b 100644 --- a/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme +++ b/SanTa/SanTa.xcodeproj/xcshareddata/xcschemes/SanTa.xcscheme @@ -102,6 +102,16 @@ ReferencedContainer = "container:SanTa.xcodeproj"> + + + + Date: Wed, 1 Dec 2021 21:38:53 +0900 Subject: [PATCH 461/465] =?UTF-8?q?[Fix]=20#375=20=EC=9D=8C=EC=84=B1=20?= =?UTF-8?q?=EC=95=88=EB=82=B4=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Scenes/RecordingScene/RecordingModel.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/SanTa/SanTa/Scenes/RecordingScene/RecordingModel.swift b/SanTa/SanTa/Scenes/RecordingScene/RecordingModel.swift index 206139f..5b7b1e8 100644 --- a/SanTa/SanTa/Scenes/RecordingScene/RecordingModel.swift +++ b/SanTa/SanTa/Scenes/RecordingScene/RecordingModel.swift @@ -159,19 +159,18 @@ final class RecordingModel: NSObject, ObservableObject { if elapsedTimeMinutes > self.maxOneKiloTime { self.maxOneKiloTime = elapsedTimeMinutes self.oneKiloDate = self.currentTime - self.sliceDistance += 1 } if elapsedTimeMinutes < self.minOneKiloTime { self.minOneKiloTime = elapsedTimeMinutes self.oneKiloDate = self.currentTime - self.sliceDistance += 1 } + self.sliceDistance += 1 } } private func willSpeechCurrentStatus() { - let speech = "현재 총 거리는 \(self.kilometer)킬로미터 소요 시간은 \(self.time)초 현재 고도는 \(self.altitude)입니다." + let speech = "현재 총 거리는 \(self.sliceDistance)킬로미터 소요 시간은 \(self.time)초 현재 고도는 \(self.altitude)입니다." let utterance = AVSpeechUtterance(string: speech) utterance.voice = AVSpeechSynthesisVoice(language: "ko-KR") utterance.rate = 0.4 From 294b40494d72ee7559f361c42050382ea5d43e50 Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Wed, 1 Dec 2021 21:59:32 +0900 Subject: [PATCH 462/465] =?UTF-8?q?[Docs]=20#378=20=EC=82=B0=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EC=B6=9C=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MountainGenerator/Extensions.swift | 44 +++++++++++ MountainGenerator/GeoCoderResponse.swift | 82 ++++++++++++++++++++ MountainGenerator/MountainModel.swift | 40 ++++++++++ MountainGenerator/main.swift | 98 ++++++++++++++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 MountainGenerator/Extensions.swift create mode 100644 MountainGenerator/GeoCoderResponse.swift create mode 100644 MountainGenerator/MountainModel.swift create mode 100644 MountainGenerator/main.swift diff --git a/MountainGenerator/Extensions.swift b/MountainGenerator/Extensions.swift new file mode 100644 index 0000000..e2259ca --- /dev/null +++ b/MountainGenerator/Extensions.swift @@ -0,0 +1,44 @@ +// +// Extensions.swift +// MountainGenerator +// +// Created by Jiwon Yoon on 2021/11/25. +// + +import Foundation + +protocol URLQueryParameterStringConvertible { + var queryParameters: String {get} +} + +extension Dictionary : URLQueryParameterStringConvertible { + /** + This computed property returns a query parameters string from the given NSDictionary. For + example, if the input is @{@"day":@"Tuesday", @"month":@"January"}, the output + string will be @"day=Tuesday&month=January". + @return The computed parameters string. + */ + var queryParameters: String { + var parts: [String] = [] + for (key, value) in self { + let part = String(format: "%@=%@", + String(describing: key).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!, + String(describing: value).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!) + parts.append(part as String) + } + return parts.joined(separator: "&") + } + +} + +extension URL { + /** + Creates a new URL by adding the given query parameters. + @param parametersDictionary The query parameter dictionary to add. + @return A new URL. + */ + func appendingQueryParameters(_ parametersDictionary : Dictionary) -> URL { + let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters) + return URL(string: URLString)! + } +} diff --git a/MountainGenerator/GeoCoderResponse.swift b/MountainGenerator/GeoCoderResponse.swift new file mode 100644 index 0000000..0de1092 --- /dev/null +++ b/MountainGenerator/GeoCoderResponse.swift @@ -0,0 +1,82 @@ +// +// GeoCoderResponse.swift +// MountainGenerator +// +// Created by Jiwon Yoon on 2021/11/25. +// + +import Foundation + +struct GeoCodeDTO: Codable { + let results: [Result] + let status: String + + enum CodingKeys: String, CodingKey { + case results = "results" + case status = "status" + } +} + +// MARK: - Result +struct Result: Codable { + let addressComponents: [AddressComponent] + let formattedAddress: String + let geometry: Geometry + let placeID: String + let plusCode: PlusCode? + let types: [String] + + enum CodingKeys: String, CodingKey { + case addressComponents = "address_components" + case formattedAddress = "formatted_address" + case geometry + case placeID = "place_id" + case plusCode = "plus_code" + case types + } +} + +// MARK: - AddressComponent +struct AddressComponent: Codable { + let longName, shortName: String + let types: [String] + + enum CodingKeys: String, CodingKey { + case longName = "long_name" + case shortName = "short_name" + case types + } +} + +// MARK: - Geometry +struct Geometry: Codable { + let location: Location + let locationType: String + let viewport: Viewport + + enum CodingKeys: String, CodingKey { + case location + case locationType = "location_type" + case viewport + } +} + +// MARK: - Location +struct Location: Codable { + let lat, lng: Double +} + +// MARK: - Viewport +struct Viewport: Codable { + let northeast, southwest: Location +} + +// MARK: - PlusCode +struct PlusCode: Codable { + let compoundCode, globalCode: String + + enum CodingKeys: String, CodingKey { + case compoundCode = "compound_code" + case globalCode = "global_code" + } +} diff --git a/MountainGenerator/MountainModel.swift b/MountainGenerator/MountainModel.swift new file mode 100644 index 0000000..266843d --- /dev/null +++ b/MountainGenerator/MountainModel.swift @@ -0,0 +1,40 @@ +// +// MountainModel.swift +// MountainGenerator +// +// Created by Jiwon Yoon on 2021/11/25. +// + +import Foundation + +struct MountainInfo: Codable { + let mountainName, mountainRegion, mountainHeight, mountainShortDescription: String + + enum CodingKeys: String, CodingKey { + case mountainName = "MNTN_NM" + case mountainRegion = "MNTN_LOCPLC_REGION_NM" + case mountainHeight = "MNTN_HG_VL" + case mountainShortDescription = "DETAIL_INFO_DTCONT" + } +} + +struct MountainWithLocation: Codable, Hashable { + let mountain: MountainInfo + let latitude: Double + let longitude: Double + + enum CodingKeys: String, CodingKey { + case mountain = "mountain" + case latitude = "latitude" + case longitude = "longitude" + } + // 위도와 경도가 같을시 같은 데이터로 취급 + func hash(into hasher: inout Hasher) { + hasher.combine(latitude) + hasher.combine(longitude) + } + + static func ==(lhs: MountainWithLocation, rhs: MountainWithLocation) -> Bool { + return lhs.longitude == rhs.longitude && lhs.latitude == rhs.latitude + } +} diff --git a/MountainGenerator/main.swift b/MountainGenerator/main.swift new file mode 100644 index 0000000..93b86e5 --- /dev/null +++ b/MountainGenerator/main.swift @@ -0,0 +1,98 @@ +// +// main.swift +// MountainGenerator +// +// Created by Jiwon Yoon on 2021/11/25. +// +// Mac Command Line Tool + +import Foundation + +var processedMountains = Set() + +func readJSON() -> [MountainInfo] { + let data = try? Data(contentsOf: URL(fileURLWithPath: "/Users/jiwonyoon/Desktop/Mountains.json")) + let decoded = try? JSONDecoder().decode([MountainInfo].self, from: data!) + + return decoded ?? [] +} + +// 국내에 없거나, 자연 지형(natural feature)이 아니면 산 데이터로 인정 하지 않음 +func isValidMountain(response: GeoCodeDTO?) -> Bool { + guard let response = response, + let addressComponents = response.results.first?.addressComponents, + let types = response.results.first?.types else { + return false + } + var isInKorea = false + let isNaturalFeature = types.contains("natural_feature") + + for addressComponent in addressComponents { + if addressComponent.longName == "대한민국" || addressComponent.shortName == "KR" { + isInKorea = true + break + } + } + return isInKorea && isNaturalFeature +} + +func sendRequest(for mountain: MountainInfo) { + let sessionConfig = URLSessionConfiguration.default + let session = URLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil) + + guard var URL = URL(string: "https://maps.googleapis.com/maps/api/geocode/json") else { return } + let URLParams = [ + "address": "\(mountain.mountainRegion) \(mountain.mountainName)", + "key": "비밀임", + "language": "ko", + ] + URL = URL.appendingQueryParameters(URLParams) + var request = URLRequest(url: URL) + request.httpMethod = "GET" + + let task = session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in + if let data = data, (error == nil) { + let dto = try? JSONDecoder().decode(GeoCodeDTO.self, from: data) + // 검색해도 위치정보가 나오지 않을 경우. + guard let latitude = dto?.results.first?.geometry.location.lat, + let longitude = dto?.results.first?.geometry.location.lng, + isValidMountain(response: dto) else { + print("not a valid Mountain!") + return + } + + let mountainWithLocation = MountainWithLocation(mountain: mountain, latitude: latitude, longitude: longitude) + processedMountains.insert(mountainWithLocation) + print("\(mountainWithLocation.mountain.mountainName), \(mountainWithLocation.latitude), \(mountainWithLocation.longitude)") + + } + else { + // Failure + print("URL Session Task Failed: %@", error!.localizedDescription); + } + }) + task.resume() + session.finishTasksAndInvalidate() +} + + +let mountains = readJSON() +print(mountains.count) + +for mountain in mountains { + print("requesting: \(mountain.mountainName)") + sendRequest(for: mountain) + // 너무 리퀘스트를 동시에 보내면 구글 API가 응답하지 않음! + sleep(1) +} +let mountainsWithLocation = Array(processedMountains) +//이후 json 파일로 저장 + +let encoder = JSONEncoder() +encoder.outputFormatting = .prettyPrinted +if let jsonData = try? encoder.encode(mountainsWithLocation), + let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) { + + let pathWithFileName = URL(string: "/Users/jiwonyoon/Desktop/")?.appendingPathComponent("MountainsWithLocation.json") + try jsonString.write(to: pathWithFileName!, atomically: true, encoding: .utf8) +} From de244094dd1e9a1005082cf13b8e21df603de86c Mon Sep 17 00:00:00 2001 From: Jiwon Yoon Date: Wed, 1 Dec 2021 22:03:05 +0900 Subject: [PATCH 463/465] =?UTF-8?q?[BUG]=20#377=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EA=B1=B0=EB=A6=AC=20=EC=9D=BC=EC=B9=98=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift index ebbf487..3ce74b3 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailModel.swift @@ -60,7 +60,7 @@ struct ResultDistance { init(records: Records) { self.steps = records.steps - self.total = records.records.map {$0.locations.totalDistance()}.reduce(0, +) / 1000 + self.total = records.distances } } From fbdb1604366f644d17b803bd832309171287591d Mon Sep 17 00:00:00 2001 From: OHCHANGMIN Date: Thu, 2 Dec 2021 14:45:50 +0900 Subject: [PATCH 464/465] =?UTF-8?q?[Refactor]=20#381=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20-=EB=A1=9C=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=EC=9D=BC=20=EB=95=8C=20VoiceOver=20=EC=97=86?= =?UTF-8?q?=EC=9D=8C=20=EC=9C=BC=EB=A1=9C=20=EC=8B=A4=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scenes/ResultDetailScene/DetailCell.swift | 3 ++- .../ResultDetailSmallerInfoView.swift | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/DetailCell.swift b/SanTa/SanTa/Scenes/ResultDetailScene/DetailCell.swift index d7a73a4..ce3a1e6 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/DetailCell.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/DetailCell.swift @@ -101,11 +101,12 @@ extension DetailCell { var label = "\(title)정보. " self.stack.arrangedSubviews.forEach { let stackView = $0 as? UIStackView - guard let contentLabel = (stackView?.arrangedSubviews[0] as? UILabel)?.text, + guard var contentLabel = (stackView?.arrangedSubviews[0] as? UILabel)?.text, let contentTitleLabel = (stackView?.arrangedSubviews[1] as? UILabel)?.text else { return } + contentLabel = contentLabel == "-" ? "없음" : contentLabel label += "\(contentTitleLabel): \(contentLabel), " } self.accessibilityLabel = label diff --git a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailSmallerInfoView.swift b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailSmallerInfoView.swift index c927af7..3bc3d15 100644 --- a/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailSmallerInfoView.swift +++ b/SanTa/SanTa/Scenes/ResultDetailScene/ResultDetailSmallerInfoView.swift @@ -81,7 +81,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -90,7 +89,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -99,7 +97,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -108,7 +105,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -117,7 +113,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -126,7 +121,6 @@ final class ResultDetailSmallerInfoView: UIView { stackView.axis = .vertical stackView.alignment = .center stackView.spacing = 5 -// stackView.distribution = .fillEqually return stackView }() @@ -198,12 +192,15 @@ extension ResultDetailSmallerInfoView { guard let distance = self.distance.text, let time = self.time.text, let steps = self.steps.text, - let maxAltitude = self.maxAltitude.text, - let minAltitude = self.minAltitude.text, - let averageSpeed = self.averageSpeed.text + var maxAltitude = self.maxAltitude.text, + var minAltitude = self.minAltitude.text, + var averageSpeed = self.averageSpeed.text else { return } + maxAltitude = maxAltitude == "-" ? " 없음" : maxAltitude + minAltitude = minAltitude == "-" ? " 없음" : minAltitude + averageSpeed = averageSpeed == "-" ? " 없음" : averageSpeed self.accessibilityLabel = "기록 정보 거리: \(distance)km, 시간: \(time), 걸음: \(steps), 최고고도: \(maxAltitude), 최저고도: \(minAltitude), 평균속도: \(averageSpeed)" } From 7b0fe44f660a61130de2b9c67eda55f8a78b34a2 Mon Sep 17 00:00:00 2001 From: sustainable-git <81242125+sustainable-git@users.noreply.github.com> Date: Fri, 3 Dec 2021 17:09:16 +0900 Subject: [PATCH 465/465] =?UTF-8?q?[Docs]=20README.md=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 배포주소, 데모영상 추가 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef603ad..24c5880 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ [![GitHub Closed PR](https://img.shields.io/github/issues-pr-closed-raw/boostcampwm-2021/iOS02-SanTa?color=red)](https://github.com/boostcampwm-2021/iOS02-SanTa/pulls?q=is%3Apr+is%3Aclosed) -[[배포주소]]() +[[배포주소]](https://appho.st/d/UE8O6Cui) [[데모영상]](https://www.youtube.com/watch?v=Y6Lspfrv8Rw)