본문 바로가기
Kotlin/Kotlin 팁

구글 지도 Open API로 지도에 표시

by MonoSoft 2020. 10. 26.
728x90
반응형

이번에는 구글 지도API와 서울시에서 제공하는 API를 활용해 

도서관 위치 정보를 찍어보도록 하겠다!

 

우선 서울특별시 열린데이터광장에서 API 키를 발급 받아야된다!

다음과 같이 해보도록 하쟈!

 

 

메인 홈페이지 화면에서 [도서관위치정보] 를 검색하도록 하자!

 

 

 

리스트가 나열되고 그중에 [서울특별시 공공도서관현황정보] 를 클릭을 한다.

 

 

 

 

위와 같이 OpenAPI 탭을 클릭하고 인증키 신청을 클릭해준다~!

 

 

 

약관동의와 관련 내용을 입력한후 인증키신청을 눌러준다.

 

 

api키가 발급되었습니다 라는 메세지와 함께 키값이 나올것이다!

 

 

 

인증키가 발급되면 위와 같이 나온다.....

 

 

 

하단에 미리보기 보면 샘풀url 을 복사해둔다!

 

일단 웹브라우저에 복사한 인증키를 붙여놓고 괄호안에 발급받은 인증키를 붙여넣고 실행해준다

그럼 관련 데이터들이 제이슨 형태로 보인다.

 

 

 

MapsActivity.kr

package com.monosoft.seoulapitest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast

import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.LatLngBounds
import com.google.android.gms.maps.model.MarkerOptions
import com.monosoft.seoulapitest.data.Library
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory


class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

private lateinit var mMap: GoogleMap

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}

/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap

loadLibraries()
// Add a marker in Sydney and move the camera
//val sydney = LatLng(-34.0, 151.0)
//mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
//mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}

fun loadLibraries() {
val retrofit = Retrofit.Builder()
.baseUrl(SeoulOpenApi.DOMAIN)
.addConverterFactory(GsonConverterFactory.create())
.build()

val service = retrofit.create(SeoulOpenService::class.java)

service.getLibraries(SeoulOpenApi.API_KEY,200)
.enqueue(object : Callback<Library> {
override fun onResponse(call: Call<Library>, response: Response<Library>) {
val result = response.body()
showLibraries(result)
}

override fun onFailure(call: Call<Library>, t: Throwable) {
Toast.makeText(this@MapsActivity,"데이터를 가져올 수 없습니다",Toast.LENGTH_LONG).show()
}
})
}

fun showLibraries(result:Library?) {
result?.let {
val latlngbounds = LatLngBounds.Builder()
for(library in it.SeoulPublicLibraryInfo.row ) {
val position = LatLng(library.XCNTS.toDouble(),library.YDNTS.toDouble() )
val marker = MarkerOptions().position(position).title(library.LBRRY_NAME)
mMap.addMarker(marker)

latlngbounds.include(position)
}

val bounds = latlngbounds.build()
val padding = 0

val camera = CameraUpdateFactory.newLatLngBounds(bounds,padding)
mMap.moveCamera(camera)
}
}
}

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.monosoft.seoulapitest">

<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the "MyLocation" functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--인터넷에 데이터를 가져올때 꼭 추가-->
<uses-permission android:name="android.permission.INTERNET"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/Theme.SeoulAPITest">

<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />

<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

 

Library.kr

package com.monosoft.seoulapitest.data

data class Library(
val SeoulPublicLibraryInfo: SeoulPublicLibraryInfo
)

 

SeoulOpenApi.kr

package com.monosoft.seoulapitest

import com.monosoft.seoulapitest.data.Library
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path


class SeoulOpenApi {
companion object {
val DOMAIN = "http://openapi.seoul.go.kr:8088/"
val API_KEY = "684f6a6f696b696d3731765a416a48"
}
}

interface SeoulOpenService {
@GET("{api_key}/json/SeoulPublicLibraryInfo/1/{limit}")
fun getLibraries(@Path("api_key") key:String, @Path("end") limit :Int ) : Call<Library>
}

 

SeoulPublicLibraryInfo.kr

package com.monosoft.seoulapitest.data

data class SeoulPublicLibraryInfo(
val RESULT: RESULT,
val list_total_count: Int,
val row: List<Row>
)

 

build.gradle(.app)

plugins {
id 'com.android.application'
id 'kotlin-android'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "com.monosoft.seoulapitest"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

kotlinOptions {
jvmTarget = '1.8'
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

 

google_maps_api.xml

<resources>
<!--
TODO: Before you run your application, you need a Google Maps API key.

To get one, follow this link, follow the directions and press "Create" at the end:

https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=40:19:5E:1F:6F:6E:C9:C6:47:37:24:D9:FC:87:3A:75:FC:7F:0F:4B%3Bcom.monosoft.seoulapitest

You can also add your credentials to an existing key, using these values:

Package name:
com.monosoft.seoulapitest

SHA-1 certificate fingerprint:
40:19:5E:1F:6F:6E:C9:C6:47:37:24:D9:FC:87:3A:75:FC:7F:0F:4B

Alternatively, follow the directions here:
https://developers.google.com/maps/documentation/android/start#get-key

Once you have your key (it starts with "AIza"), replace the "google_maps_key"
string in this file.
-->
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">YOUR_KEY_HERE</string>
</resources>

728x90
반응형

댓글