-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #383 from boostcampwm-2021/dev
[Branching] Merge to Main branch
- Loading branch information
Showing
155 changed files
with
19,752 additions
and
393 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
name: Refactor Request Template | ||
about: Refactor 작업 필요시 사용하는 기본 템플릿 | ||
title: "[REFACTOR]" | ||
labels: Refactor | ||
assignees: '' | ||
|
||
--- | ||
|
||
## 구조 설명 | ||
> 팀원이 이해할 수 있도록 자세하게 구체적으로 작성합니다. 담당자도 함께 할당해주세요. | ||
- 현재 구조 | ||
1. MVC 입니다 | ||
|
||
- 개선될 구조 | ||
1. MVVM 입니다 | ||
|
||
## 기대하는 결과 | ||
> 구체적으로 어떤 결과가 나오게 수정해야 하는지 작성합니다. | ||
## 참고자료 | ||
> 보여지는 뷰의 경우 스크린샷도 함께 첨부합니다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
name: Test Request Template | ||
about: Test 추가 필요시 사용하는 기본 템플릿 | ||
title: "[TEST]" | ||
labels: Test | ||
assignees: '' | ||
|
||
--- | ||
|
||
## 테스트를 추가할 Scene을 입력하세요 ex) MapScene | ||
### 테스트를 추가할 파일을 입력하세요 ex) MapViewModel | ||
|
||
- 필요시 추가 설명 작성 | ||
|
||
## 🤔 완료 조건 | ||
|
||
- [ ] CheckPoint1 | ||
- [ ] CheckPoint2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
- [ ] 신규 기능 추가 | ||
- [ ] 버그 수정 | ||
- [ ] 리펙토링 | ||
- [ ] 테스트 코드 작성 | ||
- [ ] 문서 업데이트 | ||
|
||
### 체크리스트 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<String, String>) -> URL { | ||
let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters) | ||
return URL(string: URLString)! | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// | ||
// main.swift | ||
// MountainGenerator | ||
// | ||
// Created by Jiwon Yoon on 2021/11/25. | ||
// | ||
// Mac Command Line Tool | ||
|
||
import Foundation | ||
|
||
var processedMountains = Set<MountainWithLocation>() | ||
|
||
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) | ||
} |
Oops, something went wrong.