본문 바로가기
안드로이드 자바

[Java][Android] 네이버 지도 - 숫자 마커 만들기(롱클릭 이벤트)

by teamnova 2022. 12. 5.
728x90

 

안녕하세요. 이번 시간에는 지도 위에 숫자 마커를 찍어보도록 하겠습니다.

원하는 결과는 이렇습니다.

 

https://navermaps.github.io/android-map-sdk/guide-ko/

 

Home · 네이버 지도 안드로이드 SDK

No results matching ""

navermaps.github.io

마커를 만들기에 앞서 네이버 지도API를 사용할 수 있게 준비해주세요. 

네이버 지도 API를 사용하는 방법이 나와있습니다. 인증이 완료되어 지도를 사용할 수 있게 되면 OnMapReadyCallback을 등록하여 비동기로 NaverMap 객체를 얻습니다.

 

 

 

1. NaverMap 객체 얻기


public class Map2_stickodeTest extends AppCompatActivity implements OnMapReadyCallback { // implement꼭해주기(인터페이스구현)


    public String TAG = "Map2_stickodeTest";
    public MapView mapView; //지도 뷰(보이는 것)
    public NaverMap 네이버Map;

    // 마커
    private TextView tv_markerNum; // 마커에 삽입될 view
    private int route123 = 0; // view에 보일 숫자
    private int markerMaxCount = 5;

	// arraylist
    public ArrayList<Marker> 마커리스트 = new ArrayList<>(); 
    public ArrayList<Double> 마커위도리스트 = new ArrayList<>(); 
    public ArrayList<Double> 마커경도리스트 = new ArrayList<>(); 
    
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stickode_test);

        mapView = findViewById(R.id.map_stickode);
        tv_markerNum = (TextView)findViewById(R.id.tv_markerNum); // 마커에 삽입될 숫자뷰


        // 네이버 지도 초기화
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this); // 네이버지도에서 반환되는 콜백함수를 자신(this)으로 지정하는 역할
                                            // Async : 비동기(로 NaverMap객체를 얻는다)

    } //~onCreate()



    // NaverMap객체가 준비되면 콜백메소드를 호출한다.
    @Override
    public void onMapReady(@NonNull NaverMap naverMap) { Log.e(TAG, "onMapReady() 입장"); //지도의 작동을 다룸


    } //~oMapReady()

}

onMapReady메소드에서 지도의 작동을 다룹니다. 

설정과 권한, 위치, 리스너 등을 이 곳에 구현할 것입니다. 

 

 

 

2. XML (레이아웃)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/full"
    tools:context=".copy.Map2_stickodeTest">

    <com.naver.maps.map.MapView
        android:id="@+id/map_stickode"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">


            <TextView
                android:id="@+id/tv_markerNum"
                android:layout_width="27dp"
                android:layout_height="27dp"
                android:layout_marginTop="16dp"
                android:background="@drawable/round"
                android:gravity="center"
                android:text="1"
                android:textColor="@color/black"
                android:textSize="18sp"
                android:textStyle="bold"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.958"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />


            <TextView
                android:id="@+id/textView13"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:background="@drawable/text_round"
                android:gravity="center"
                android:padding="10dp"
                android:text="지도 위를 꾹 눌러보세요. \n최대 10개까지 경로지정이 가능합니다."
                android:textColor="@color/black"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.496"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />


        </androidx.constraintlayout.widget.ConstraintLayout>
    </com.naver.maps.map.MapView>
</androidx.constraintlayout.widget.ConstraintLayout>
android:background="@drawable/round"

 

 

 

3.  원형 리소스 (선택)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#FF8535" />
    <size
        android:height="60dp"
        android:width="60dp" />
</shape>

원형으로 보이고 싶어서 만들어 뒀습니다. 모양은 원하시는대로 하면 될 것 같습니다. 

지도가 적용된 레이아웃

저 오른쪽 위에 있는 오렌지색 '1'이 Textview입니다. 이 뷰 하나로 마커를 여러 개 찍을 것입니다. 안 쓸 때는 숨겨집니다.

흰배경은 지도가 들어갈 자리입니다. 이제 롱클릭리스너를 이용해 마커를 추가해보겠습니다. 

 

 

 

4. onMapReady() 구현

// NaverMap객체가 준비되면 콜백메소드를 호출한다.
@Override
public void onMapReady(@NonNull NaverMap naverMap) { //지도의 작동을 다룸

    Log.e(TAG, "onMapReady() 입장");
    네이버Map = naverMap; //전역변수에 대입(스레드에서 쓰려고)


    //런타임 권한
    Log.e(TAG, "런타임 권한을 맵에 지정");
    ActivityCompat.requestPermissions(Map2_stickodeTest.this, PERMISSIONS, LOCATION_PERMISSION_REQUEST_CODE); //현재위치 표시할 때 권한 확인(이미 M_main에서 통과됐기때문에 여기서는 런타임권한메소드 x)


    //위치 오버레이
    // (사용자의 위치를 나타내는 데 특화된 오버레이이로, 지도상에 단 하나만 존재)
    LocationOverlay locationOverlay = naverMap.getLocationOverlay(); //위치 인스턴스 생성x 왜냐면 유일무이..그래서 호출해옴
    locationOverlay.setPosition(new LatLng(위도, 경도)); //더 빠르게 위치잡으라고 set해줌
    locationOverlay.setVisible(true); //가시성 : 기본false


    //현재위치 GPS
    naverMap.setLocationSource(locationSource); //현재위치
    naverMap.setLocationTrackingMode(LocationTrackingMode.Follow); //트래킹모드를 선언해야 위치오버레이가 보임
    naverMap.setLayerGroupEnabled(NaverMap.LAYER_GROUP_MOUNTAIN, true); //레이어 : 등산로




    // 지도 롱 클릭 : 마커 생성
    tv_markerNum.setVisibility(View.GONE); //기존 뷰를 안 숨기니까 뷰가 제멋대로 이동해버림.
    naverMap.setOnMapLongClickListener(new NaverMap.OnMapLongClickListener() {
        @Override
        public void onMapLongClick(@NonNull PointF pointF, @NonNull LatLng latLng) {

            double 위도 = latLng.latitude;
            double 경도 = latLng.longitude;

                 Toast.makeText(getApplicationContext()
                , "lat : "+latLng.latitude+", \nLng : "+latLng.longitude
                , Toast.LENGTH_SHORT).show(); //퇴장알림을 해야 확신할 듯

                Log.e(TAG, "위도 : "+위도);
                Log.e(TAG, "경도 : "+경도);
                Log.e(TAG, "route123 : "+route123);


            if(route123 < markerMaxCount) { // 최대 n개까지만 마커 생성

                route123++;
                Log.e(TAG, "route123++ if문 안 : "+route123);
                tv_markerNum.setText(String.valueOf(route123)); //원형 마커에 숫자 대입 /int그대로넣으니 에러남

                // 마커 추가 : 끝수 + 1된 마커 추가
                Marker marker = new Marker(); //여러개 추가할거라 롱클릭 안에 위치
                marker.setPosition(new LatLng(위도, 경도)); //먼저(위치에러뜸)
                marker.setWidth(90);
                marker.setHeight(90);
                marker.setMap(네이버Map); //다시 대입한다 /해야 보임
                marker.setIcon(OverlayImage.fromView(tv_markerNum)); //숫자먼저 set하고 뷰를 삽입한다.

                마커리스트.add(route123 - 1, marker); // 배열[0]부터하려고 -1함
                마커위도리스트.add(위도); // 마커추가할 때 같이 위경도도 추가하고 삭제할 때도 동일하게
                마커경도리스트.add(경도);
                Log.e(TAG, "마커리스트[].size : "+ 마커리스트.size() +"마커위도리스트size :"+마커위도리스트.size()+"마커경도리스트size: "+마커경도리스트.size());
                Log.e(TAG, "마커위도리스트[] : "+ 마커위도리스트); //담긴 객체 확인용
                Log.e(TAG, "마커경도리스트[] : "+ 마커경도리스트);


            } else {
                Toast.makeText(getApplicationContext(), "최대 경로마커 갯수는 "+markerMaxCount+"개입니다.", Toast.LENGTH_SHORT).show(); 
            }
        }
    });
} //~oMapReady()

 

롱클릭했을 때 숫자가 늘어나면서 1번~5번까지 마커가 생성됩니다.