rlqja1107 / LocationService

Based on Location Service, We would put a electronic kick-board option on Finding Way
0 stars 0 forks source link

기존의 킥보드 대중교통 연동 기능에 지도 메모 기능 추가 #8

Open rlqja1107 opened 4 years ago

rlqja1107 commented 4 years ago

지도에 지도메모 기능 추가

기능

미팅이나 모임이 많은 사람들을 위해 지도 상에서 위치를 기록할 수 있게 한다. 현재까지는 모임 장소에 마커를 찍으면 거기에 제목내용을 기록할 수 있게 한다. 이를 통해 한 눈에 자신의 위치의 약속을 볼 수 있게 한다.
그리고 하나의 앱으로 대중교통 목록과 운전경로를 보여줄 수 있게 하는 것이 목적이다.

UI

memo_activity

코드 구현

Realm

realm 라이브러리를 이용하여 마커의 정보를 저장시켰다.
realm에 저장시킬 데이터 정보는 다음과 같다. 각각은 필드에 해당된다.

open class MemoData(@PrimaryKey var id:String= UUID.randomUUID().toString(), var latitude:Double=0.0, var longitude:Double=0.0, var contents:String="", var title:String="",
                    var year:Int=0, var month:Int=0, var day:Int=0, var hour:Int=0, var minute:Int=0):
    RealmObject()

처음에 realm에 새로운 class 데이터가 추가된다는 것을 알려줘야 한다. 이는 RealmConfiguration의 migration을 이용하여 새로운 class를 추가했다. 방법은 다음과 같다.

var config=RealmConfiguration.Builder().migration { realm, oldVersion, newVersion ->
            var schema=realm.schema
            schema.create("MemoData").addField("id",String::class.java,FieldAttribute.PRIMARY_KEY,FieldAttribute.REQUIRED)
                .addField("latitude",Double::class.java)
                .addField("longitude",Double::class.java)
                .addField("contents",String::class.java,FieldAttribute.REQUIRED)
                .addField("title",String::class.java,FieldAttribute.REQUIRED)
                .addField("year",Int::class.java)
                .addField("month",Int::class.java)
                .addField("day",Int::class.java)
                .addField("hour",Int::class.java)
                .addField("minute",Int::class.java)
        }.schemaVersion(1).build()
        Realm.setDefaultConfiguration(config)

addField를 통해 데이터를 저장시킬 field를 추가시킨다.

Realm의 저장

코드의 일부를 보면 다음과 같다.

  saveMarker.icon = MarkerIcons.GRAY
                    saveMarker.map = naverMap
                    memo.title=bottom_slide.titleText.text.toString()
                    memo.latitude=saveMarker.position.latitude
                    memo.longitude=saveMarker.position.longitude
                    memo.contents=bottom_slide.contentText.text.toString()
                    realm?.executeTransaction {
                    it.copyToRealm(memo)
                }
                    Toast.makeText(this, "Toyou 메모가 저장되었습니다.", Toast.LENGTH_SHORT).show()

해당 마커가 여기서 saveMarker다. MemoData의 인스턴스인 memo의 정보를 위의 코드를 통해 넣어주고 realm.copyToRealm(memo)를 통해 핸드폰 데이터베이스에 저장시킨다.

Realm에서 마커 정보와 같이 불러와서 지도에 표시하기

우선 핸드폰 데이터베이스로부터 Query를 통해 가져와야한다. 모든 정보를 가져와야하기 때문에 findAll()이용했다.

class MemoClass(private val realm: Realm) {
    fun getAllMemo(): RealmResults<MemoData>{
        return realm.where(MemoData::class.java)
            .findAll()
    }
}

위의 코드를 실행 시켜 정보를 저장시키고

 var memodata = MemoClass(realm!!).getAllMemo()

memoData에 있는 정보들을 이용해 지도상에 표시만 하면된다.
다음의 함수를 통해서 지도에 표시한다. 여기서 마커 모양을 기존의 찍는 마커의 모양과 다르게 하기위해 우선은 Gray로 정해놨다. 이후에 마커의 모양도 여러가지로 해서 한눈에 보기 쉽게 만들 것이다. 이 함수는 mapView.getSync{}안에서 비동기 객체를 가져오자마자 바로 실행하게 했다. 이는 initSetting이라는 함수 안에 있는데 초기 정보 설정단계에 해당한다.

private fun initMarkerSetting(data: MemoData) {
        var marker = Marker()
        marker.position = LatLng(data.latitude, data.longitude)
        marker.width = Marker.SIZE_AUTO
        marker.height = Marker.SIZE_AUTO
        marker.isCaptionPerspectiveEnabled = true
        marker.setOnClickListener {
            showPanel(data.latitude, data.longitude, true, data, marker)
            true
        }
        var info = InfoWindow()
        info.adapter = object : InfoWindow.DefaultTextAdapter(this) {
            override fun getText(p0: InfoWindow): CharSequence {
                return title
            }
        }
        info.open(marker)
        marker.icon = MarkerIcons.GRAY
        marker.map = naverMap
    }