-
Notifications
You must be signed in to change notification settings - Fork 1
[FEAT] 코스 그리기 / 출발지 설정 구현 (현위치, 사용자 지정) #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0bab7a3
5b9d210
1aea96d
8a198e6
fc479ee
fbe0e35
a37f3dd
2c8aab1
a238bf9
0b1f050
6e87132
57a8642
347c3a1
a69e2a9
8cf9bfc
973c9e8
f33f2e6
da75492
baf7e2f
927a1e7
1ad5a21
e7aee9b
6904b7d
876f3e8
169e2e5
1fe80ab
bcc473e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <shape xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <corners | ||
| android:radius="10dp"> | ||
| </corners> | ||
| <solid | ||
| android:color="@color/W1"> | ||
| </solid> | ||
| <stroke | ||
| android:color="@color/M1" | ||
| android:width="1dp" /> | ||
| </shape> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="16dp" | ||
| android:height="16dp" | ||
| android:viewportWidth="16" | ||
| android:viewportHeight="16"> | ||
| <path | ||
| android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" | ||
| android:fillColor="#C1C1C1"/> | ||
| <group> | ||
| <clip-path | ||
| android:pathData="M3.2,3.2h9.6v9.6h-9.6z"/> | ||
| <path | ||
| android:pathData="M8.668,12H8.644C8.556,11.995 8.472,11.961 8.406,11.903C8.339,11.845 8.294,11.767 8.276,11.68L7.66,8.652C7.644,8.575 7.607,8.505 7.551,8.449C7.496,8.394 7.425,8.356 7.348,8.34L4.32,7.724C4.234,7.707 4.155,7.662 4.097,7.595C4.039,7.529 4.004,7.445 3.999,7.357C3.993,7.269 4.017,7.181 4.067,7.108C4.116,7.035 4.188,6.98 4.272,6.952L10.672,4.82C10.744,4.791 10.823,4.783 10.899,4.797C10.976,4.812 11.046,4.848 11.102,4.902C11.158,4.956 11.197,5.025 11.215,5.1C11.232,5.176 11.227,5.255 11.2,5.328L9.068,11.728C9.04,11.811 8.986,11.882 8.914,11.932C8.842,11.981 8.755,12.005 8.668,12Z" | ||
| android:fillColor="#ffffff"/> | ||
| </group> | ||
| </vector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="16dp" | ||
| android:height="16dp" | ||
| android:viewportWidth="16" | ||
| android:viewportHeight="16"> | ||
| <path | ||
| android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" | ||
| android:fillColor="#C1C1C1"/> | ||
| <path | ||
| android:pathData="M9.2,11.6L6.8,10.76L4.94,11.48C4.807,11.534 4.684,11.519 4.57,11.435C4.457,11.352 4.4,11.24 4.4,11.1V5.5C4.4,5.414 4.425,5.337 4.476,5.27C4.526,5.204 4.594,5.154 4.68,5.12L6.8,4.4L9.2,5.24L11.06,4.52C11.194,4.467 11.317,4.482 11.43,4.566C11.544,4.649 11.6,4.761 11.6,4.9V10.5C11.6,10.587 11.575,10.664 11.525,10.73C11.475,10.797 11.407,10.847 11.32,10.88L9.2,11.6ZM8.8,10.62V5.94L7.2,5.38V10.06L8.8,10.62Z" | ||
| android:fillColor="#ffffff"/> | ||
| </vector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="46dp" | ||
| android:height="4dp" | ||
| android:viewportWidth="46" | ||
| android:viewportHeight="4"> | ||
| <path | ||
| android:pathData="M2,2H43.5" | ||
| android:strokeWidth="4" | ||
| android:fillColor="#00000000" | ||
| android:strokeColor="#ECECEC" | ||
| android:strokeLineCap="round"/> | ||
| </vector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="52dp" | ||
| android:height="30dp" | ||
| android:viewportWidth="52" | ||
| android:viewportHeight="30"> | ||
| <path | ||
| android:pathData="M26,30L21.521,22.323L30.48,22.323L26,30Z" | ||
| android:fillColor="#593EEC"/> | ||
| <path | ||
| android:pathData="M5.231,0.876L46.769,0.876A4.279,4.279 0,0 1,51.048 5.155L51.048,19.021A4.279,4.279 0,0 1,46.769 23.3L5.231,23.3A4.279,4.279 0,0 1,0.952 19.021L0.952,5.155A4.279,4.279 0,0 1,5.231 0.876z" | ||
| android:fillColor="#593EEC"/> | ||
| <path | ||
| android:pathData="M25.649,11.557V12.645H21.554V13.312H24.491V15.909H18.559V16.494H24.771V17.594H17.096V14.903H23.017V14.377H17.085V13.312H20.068V12.645H15.985V11.557H25.649ZM16.359,10.165C18.489,10.071 19.571,9.562 19.881,8.948H16.897V7.848H20.068V7.006H21.542V7.848H24.736V8.948H21.724C22.028,9.562 23.116,10.071 25.263,10.165L24.83,11.264C22.853,11.165 21.478,10.668 20.805,9.866C20.132,10.668 18.764,11.165 16.769,11.264L16.359,10.165ZM28.118,7.497V8.761H30.294V7.497H31.792V12.142H26.632V7.497H28.118ZM27.697,13.991V12.832H34.763V15.722H29.182V16.412H35.068V17.594H27.72V14.657H33.277V13.991H27.697ZM28.118,10.972H30.294V9.884H28.118V10.972ZM33.266,12.434V7.017H34.763V9.088H36.202V10.293H34.763V12.434H33.266Z" | ||
| android:fillColor="#ffffff"/> | ||
| </vector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package com.runnect.runnect.data.dto | ||
|
|
||
|
|
||
| import android.os.Parcelable | ||
| import kotlinx.android.parcel.Parcelize | ||
|
|
||
| @Parcelize | ||
| data class LocationData( | ||
| val buildingName: String, | ||
| val fullAddress: String, | ||
| ) : Parcelable |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| package com.runnect.runnect.data.dto.tmap.geocoding | ||
|
|
||
|
|
||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class ResponseReverseGeocodingDto( | ||
| @SerialName("addressInfo") | ||
| val addressInfo: AddressInfo | ||
| ) { | ||
| @Serializable | ||
| data class AddressInfo( | ||
| @SerialName("addressKey") | ||
| val addressKey: String? = null, | ||
| @SerialName("addressType") | ||
| val addressType: String, | ||
| @SerialName("adminDong") | ||
| val adminDong: String, | ||
| @SerialName("adminDongCode") | ||
| val adminDongCode: String, | ||
| @SerialName("adminDongCoord") | ||
| val adminDongCoord: AdminDongCoord? = null, | ||
| @SerialName("buildingIndex") | ||
| val buildingIndex: String, | ||
| @SerialName("buildingName") | ||
| val buildingName: String, | ||
| @SerialName("bunji") | ||
| val bunji: String, | ||
| @SerialName("city_do") | ||
| val cityDo: String, | ||
| @SerialName("eup_myun") | ||
| val eupMyun: String, | ||
| @SerialName("fullAddress") | ||
| val fullAddress: String, | ||
| @SerialName("gu_gun") | ||
| val guGun: String, | ||
| @SerialName("legalDong") | ||
| val legalDong: String, | ||
| @SerialName("legalDongCode") | ||
| val legalDongCode: String, | ||
| @SerialName("legalDongCoord") | ||
| val legalDongCoord: LegalDongCoord? = null, | ||
| @SerialName("mappingDistance") | ||
| val mappingDistance: String, | ||
| @SerialName("ri") | ||
| val ri: String, | ||
| @SerialName("roadAddressKey") | ||
| val roadAddressKey: String? = null, | ||
| @SerialName("roadCode") | ||
| val roadCode: String, | ||
| @SerialName("roadCoord") | ||
| val roadCoord: RoadCoord? = null, | ||
| @SerialName("roadName") | ||
| val roadName: String | ||
| ) { | ||
|
|
||
| @Serializable | ||
| data class AdminDongCoord( | ||
| @SerialName("lat") | ||
| val lat: String, | ||
| @SerialName("latEntr") | ||
| val latEntr: String, | ||
| @SerialName("lon") | ||
| val lon: String, | ||
| @SerialName("lonEntr") | ||
| val lonEntr: String | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class RoadCoord( | ||
| @SerialName("lat") | ||
| val lat: String, | ||
| @SerialName("latEntr") | ||
| val latEntr: String, | ||
| @SerialName("lon") | ||
| val lon: String, | ||
| @SerialName("lonEntr") | ||
| val lonEntr: String | ||
| ) | ||
|
|
||
| @Serializable | ||
| data class LegalDongCoord( | ||
| @SerialName("lat") | ||
| val lat: String, | ||
| @SerialName("latEntr") | ||
| val latEntr: String, | ||
| @SerialName("lon") | ||
| val lon: String, | ||
| @SerialName("lonEntr") | ||
| val lonEntr: String | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,8 @@ class DepartureSearchRepositoryImpl @Inject constructor(private val departureSou | |
| SearchResultEntity( | ||
| fullAddress = makeMainAdress(it), | ||
| name = it.name ?: "", | ||
| locationLatLng = LatLng(it.noorLat.toDouble(), it.noorLon.toDouble()) | ||
| locationLatLng = LatLng(it.noorLat.toDouble(), it.noorLon.toDouble()), | ||
| mode = "searchLocation" //현위치, 지도에서 출발과 구분하기 위한 식별자 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문자열은 하드코딩 하지 않고 const 로 상수화 시키는 것이 어떨까요??
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아래 코드에 리뷰를 추가했는데, 문자열 대신 enum class를 활용하는 것도 좋을 거 같아요 :)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋아요!! 매직 리터럴을 지양하는 방향이 좋다고 생각하고 기존의 코드들도 리팩토링 해오고 있었습니다! |
||
| ) | ||
| } | ||
| return changedData | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.runnect.runnect.data.repository | ||
|
|
||
| import com.runnect.runnect.data.dto.LocationData | ||
| import com.runnect.runnect.data.source.remote.RemoteReverseGeocodingDataSource | ||
| import com.runnect.runnect.domain.ReverseGeocodingRepository | ||
| import javax.inject.Inject | ||
|
|
||
| class ReverseGeocodingRepositoryImpl @Inject constructor(private val reverseGeocodingDataSource: RemoteReverseGeocodingDataSource) : | ||
| ReverseGeocodingRepository { | ||
| override suspend fun getLocationInfoUsingLatLng( | ||
| lat: Double, | ||
| lon: Double | ||
| ): LocationData { | ||
| val response = | ||
| reverseGeocodingDataSource.getLocationInfoUsingLatLng(lat = lat, lon = lon).body() | ||
| return LocationData( | ||
| buildingName = response?.addressInfo?.buildingName ?: "buildingName fail", | ||
| fullAddress = response?.addressInfo?.fullAddress ?: "fullAddress fail" | ||
| ) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 응답값 response 가 널이어도 LocationData에는 "buildingName fail" 같은 문자열이 들어가네요! interface ReverseGeocodingRepository {
suspend fun getLocationInfoUsingLatLng(lat: Double, lon: Double): LocationData?
}override suspend fun getLocationInfoUsingLatLng(
lat: Double,
lon: Double
): LocationData? {
val response = reverseGeocodingDataSource
.getLocationInfoUsingLatLng(lat = lat, lon = lon)
.body()
return if (response != null) {
LocationData(
buildingName = response.addressInfo.buildingName,
fullAddress = response.addressInfo.fullAddress
)
} else null
} fun getLocationInfoUsingLatLng(lat: Double, lon: Double) {
viewModelScope.launch {
runCatching {
reverseGeocodingRepository.getLocationInfoUsingLatLng(lat = lat, lon = lon)
}.onSuccess { response ->
if(response == null) {
Timber.e("getLocationInfoUsingLatLng response is null")
return@launch
}
Timber.tag(ContentValues.TAG).d("통신success")
reverseGeocodingResult.value = response
}.onFailure {
Timber.tag(ContentValues.TAG).d("통신failure : ${it}")
errorMessage.value = it.message
}
}
}이런 식으로 널 처리하는 걸 생각해봤는데, 더 나은 방식이 있다면 적극 추천해주세요!!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. response 자체가 null이 오는 건 생각 못했는데 좋다!! 날카로워서 베일 뻔.. 내가 짜놓은 코드는 하은이 네 말처럼 response부터 null이 오는 경우도 "buildingName fail"을 주기 때문에 적절한 null 처리라는 생각이 안 드네. api에서 buildingName, fullAddress 값으로 보내줄 게 없을 때 빈문자열("")로 보내주거든. 그래서 (api 측에 문제가 생기지 않는 이상) 사실 buildingName에 null이 뜰 가능성은 없어서 하은이 네가 짜준 코드처럼 그냥 크게 response의 null 여부만 체크하는 게 간단할 것 같아!! (만약 response는 null이 아닌데 이후 attribute 값들이 null을 가진다면 더 세부적인 처리가 필요하겠지만) |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package com.runnect.runnect.data.service | ||
|
|
||
| import com.runnect.runnect.BuildConfig | ||
| import com.runnect.runnect.data.dto.tmap.SearchResponseTmapDto | ||
| import com.runnect.runnect.data.dto.tmap.geocoding.ResponseReverseGeocodingDto | ||
| import retrofit2.Response | ||
| import retrofit2.http.GET | ||
| import retrofit2.http.Header | ||
| import retrofit2.http.Query | ||
|
|
||
| interface ReverseGeocodingService { | ||
|
|
||
| @GET("/tmap/geo/reversegeocoding?") | ||
| suspend fun getLocationUsingLatLng( | ||
| @Header("appKey") appKey: String = BuildConfig.TMAP_API_KEY, | ||
| @Query("version") version: Int = 1, | ||
| @Query("callback") callback: String? = null, | ||
| @Query("lat") lat: Double, | ||
| @Query("lon") lon: Double, | ||
| @Query("coordType") coordType: String? = "WGS84GEO", | ||
| @Query("addressType") addresstType: String? = "A04", | ||
| ): Response<ResponseReverseGeocodingDto> | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 문서 를 통해 각 속성이 어떤 것인지 알 수 있었어요! |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.runnect.runnect.data.source.remote | ||
|
|
||
| import com.runnect.runnect.data.dto.tmap.geocoding.ResponseReverseGeocodingDto | ||
| import com.runnect.runnect.data.service.ReverseGeocodingService | ||
| import retrofit2.Response | ||
| import javax.inject.Inject | ||
|
|
||
| class RemoteReverseGeocodingDataSource @Inject constructor(private val reverseGeocodingService: ReverseGeocodingService) { | ||
| suspend fun getLocationInfoUsingLatLng( | ||
| lat: Double, | ||
| lon: Double | ||
| ): Response<ResponseReverseGeocodingDto> = | ||
| reverseGeocodingService.getLocationUsingLatLng(lat = lat, lon = lon) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,11 @@ object ServiceModule { | |
| fun provideKSearchService(@RetrofitModule.Tmap tmapRetrofit: Retrofit) = | ||
| tmapRetrofit.create(SearchService::class.java) | ||
|
|
||
| @Singleton | ||
| @Provides | ||
| fun provideReverseGeocodingService(@RetrofitModule.Tmap tmapRetrofit: Retrofit) = | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Runnect, Tmap 이라는 한정자는 qualifier 라는 패키지로 별도 분리하여 정의하는 것이 더 좋을 거 같습니다 :)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그렇게 해본 적이 없어서 어떻게 해볼 수 있을지 모르겠는데 코어 타임 때 여쭤보겠습니다! |
||
| tmapRetrofit.create(ReverseGeocodingService::class.java) | ||
|
|
||
| @Singleton | ||
| @Provides | ||
| fun provideBannerService() = Firebase.firestore | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.runnect.runnect.domain | ||
|
|
||
| import com.runnect.runnect.data.dto.LocationData | ||
|
|
||
| interface ReverseGeocodingRepository { | ||
| suspend fun getLocationInfoUsingLatLng(lat: Double, lon: Double): LocationData | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
latEntr속성이 무엇인지 알 수 있을까요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
주소의 입구에 해당하는 위도 좌표입니다.
다른 attribute에 대한 설명은 아래 링크에 있습니다!
https://openapi.sk.com/products/detail?linkMenuSeq=23