Tech. Forum 개발자들을 위한 정보 공유의 장입니다
닫기

Tech.Forum

자동차 경로 안내 관련 질문 있습니다.

#1

package com.example.taxipath;

import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.skt.Tmap.TMapData;
import com.skt.Tmap.TMapMarkerItem;

import com.skt.Tmap.TMapPoint;
import com.skt.Tmap.TMapPolyLine;
import com.skt.Tmap.TMapView;

import java.io.IOException;
import java.util.List;

import static android.view.View.VISIBLE;

public class ShowMap extends AppCompatActivity {
ImageView warning;
Button checkCost, path1, path2;
RelativeLayout relativeLayout;
FrameLayout select_pathF_Layout, show_mapF_Layout;
LinearLayout show_mapL_Layout;
Bitmap startBitmap, endBitmap;
TMapView tMapView;
String address;
Intent intent1;
View view;
TextView textView;
TMapPoint myDestination, myPos;

private String APP_KEY = "94ae616c-9be2-4c2f-b111-3286a1358f11";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.show_map);
    tMapView = new TMapView(this);
    startBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.mypos);
    //입력된 목적지 값을 Intent 클래스를 통해 받고 문자열로 전환
    intent1 = getIntent();
    view = null;
    relativeLayout = (RelativeLayout) findViewById(R.id.tMapView);
    checkCost = (Button) findViewById(R.id.checkCost);
    textView = (TextView) findViewById(R.id.textView1);
    setTMapView();
    relativeLayout.addView(tMapView);
    onClickCheckCost();
}

final LocationListener gpsLocationListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        double myPosLon = location.getLongitude();
        double myPosLat = location.getLatitude();
        myPos = new TMapPoint(myPosLat, myPosLon);
        /*
        사용자의 위치를 실시간으로 갱신시킴
         */
        textView.setText("위도 : " + myPos.getLatitude() + "\n경도 : " + myPos.getLongitude());
        tMapView.setLocationPoint(myPosLon, myPosLat);
        tMapView.setIcon(startBitmap);
        tMapView.setIconVisibility(true);
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) { }
    @Override
    public void onProviderEnabled(String provider) { }
    @Override
    public void onProviderDisabled(String provider) { }
};

void myPosition(){
    /*
    onLocationChanged 메소드에 계속 사용자 위치를 갱신함
    GPS를 우선적으로 받으며, GPS 통신이 안될 경우 NETWORK로 받아옴
    갱신될때마다 사용자의 마커도 계속 바뀐다. (당연히 목적지의 마커는 변하지 않음)
    */
    final LocationManager locationManager =(LocationManager) getSystemService(Context.LOCATION_SERVICE);
    if(Build.VERSION.SDK_INT >= 23 &&
            ContextCompat.checkSelfPermission(
                    getApplicationContext(),
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
    {
        ActivityCompat.requestPermissions(ShowMap.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
    }
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, //GPS 우선
            100,
            1,
            gpsLocationListener);
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, //GPS 통신이 안되면 NETWORK로
            100,
            1,
            gpsLocationListener);
}

void selectPath(){
    /*
    '측정' 버튼을 누르면 레이아웃이 전환됨
     경로가 여러 개 나타나고, 사용자가 원하는 경로를 선택할 수 있음
     */
    select_pathF_Layout = (FrameLayout) findViewById(R.id.select_Path);
    show_mapL_Layout = (LinearLayout) findViewById(R.id.showMapLinearLayout);
    show_mapF_Layout = (FrameLayout) findViewById(R.id.showMapFrameLayout);
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = inflater.inflate(R.layout.select_path, show_mapF_Layout, true);
    show_mapL_Layout.setVisibility(View.GONE);//새 레이아웃이 나타나고 이전 레이아웃은 없어진다.
    path1= (Button) findViewById(R.id.path1);
    path2= (Button)findViewById(R.id.path2);
    warning = (ImageView) findViewById(R.id.warning);

    path1.setVisibility(VISIBLE);
    path2.setVisibility(VISIBLE);

    showPath();
    onClick_path1();
    onClick_path2();
}
void showPath(){ //자동차 경로를 그려줌

    try{
        TMapPolyLine tMapPolyLine = new TMapData().findPathData(myPos, myDestination);
        tMapPolyLine.setLineColor(Color.BLUE);
        tMapPolyLine.setLineWidth(2);
        tMapView.addTMapPolyLine("Line1", tMapPolyLine);
    }
    catch(Exception e){ e.printStackTrace();}
}



void onClick_path1(){
    //1번 경로 선택. "예"를 누를 시, 경로 변경 불가능
    path1.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(ShowMap.this);
            dialog.setTitle("1번 경로 선택");
            dialog.setMessage("1번 경로로 선택하시겠습니까? (재설정 불가능합니다)");
            dialog.setPositiveButton("예",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(getApplicationContext(), "1번 경로로 설정이 끝났습니다.", Toast.LENGTH_SHORT).show();
                            path2.setVisibility(View.GONE);
                            warning.setVisibility(VISIBLE);
                        }
                    });
            dialog.setNegativeButton("아니오", null);
            dialog.show();
        }
    });
}
void onClick_path2(){
    //2번 경로 선택. "예"를 누를 시, 경로 변경 불가능
    path2.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            AlertDialog.Builder dialog = new AlertDialog.Builder(ShowMap.this);
            dialog.setTitle("2번 경로 선택");
            dialog.setMessage("2번 경로로 선택하시겠습니까? (재설정 불가능합니다)");
            dialog.setPositiveButton("예",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(getApplicationContext(), "2번 경로로 설정이 끝났습니다.", Toast.LENGTH_SHORT).show();
                            path1.setVisibility(View.GONE);
                            warning.setVisibility(VISIBLE);
                        }
                    });
            dialog.setNegativeButton("아니오", null);
            dialog.show();
        }
    });
}
void onClickCheckCost(){
    /*
    "측정"버튼 누를 시, 미터기를 블루투스로 연동하여 미터기의 실제 금액을 받아옴
    사용자의 현재 위치가 표시되고, 목적지까지 경로를 제공
    아직 미완성...
     */
    checkCost.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            selectPath();

        }
    });
}
private void setTMapView(){
    /*
    지도를 띄움 여기서 사용자의 현재 위치가 표시됨
    목적지를 지도에 띄우며, 목적지 위치가 바로 나타남
     */
    tMapView.setMapType(TMapView.MAPTYPE_STANDARD);
    tMapView.setSKTMapApiKey(APP_KEY);
    tMapView.setZoomLevel(16);
    myPosition();
    convert_Geo_code();
}
private void convert_Geo_code(){
    /*
    사용자가 입력한 목적지를 좌표로 전환
     */
    address = intent1.getStringExtra("dest");
    Geocoder coder = new Geocoder(getApplicationContext());
    Address addr = null;
    List<Address> list = null;
    try {
        try {
            list = coder.getFromLocationName(address, 1);
        }
        catch (IOException e) { }
        try {
            addr = list.get(0);
        }
        catch (IndexOutOfBoundsException e) { }

        double lat = addr.getLatitude();//위도
        double lon = addr.getLongitude();//경도
        showDestination(lat, lon);
    }
    catch(NullPointerException e){
        Toast.makeText(getApplicationContext(), "잘못 입력하였습니다. 뒤로가기를 눌러 다시 설정해주시기 바랍니다.", Toast.LENGTH_LONG).show();
        show_mapL_Layout = (LinearLayout)findViewById(R.id.showMapLinearLayout);
        show_mapL_Layout.setVisibility(View.INVISIBLE);
    }
}

void showDestination(double lat, double lon) {
    /*
    사용자가 입력한 목적지를 보여주며, 목적지 마커가 어디에 찍히는지 알림
     */
    endBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.mymarker);
    myDestination = new TMapPoint(lat, lon); //목적지 좌표
    TMapMarkerItem marker = new TMapMarkerItem(); //마커 생성
    marker.setTMapPoint(myDestination);
    marker.setIcon(endBitmap);
    tMapView.setCenterPoint(lon, lat); //목적지 좌표로 이동
    tMapView.addMarkerItem("marker", marker);
}

}

코드를 이렇게 올려도 될지 모르곘습니다.
자동차 경로 안내 예제를 보고
예제를 이용해서 다른 출발지와 목적지에서도 경로가 나오나 해보니까 안되더군요.
코드에 문제가 있나요?

0 Likes

#2

안녕하세요.

T map API 운영담당자입니다.

문의주신 내용만으로는 정확한 원인을 알기 어렵습니다만 findPathData 메소드를 메인 쓰레드에서 수행하기 때문에 문제가 발생하는 것으로 추측됩니다.

find0PathData는 네트워크 데이터를 이용하므로 메인쓰레드에서 수행하는 경우 데이터를 받아올 때 까지 기다려야하므로 AsyncTask를 사용해 비동기 작업을 수행해야합니다.

문의주신 글에 API 키가 작성되어 있으므로 API키 내용을 지워주시고, 로그 메시지의 내용을 작성하여 문의주시면 검토 후 다시 답변드리겠습니다.

감사합니다.

0 Likes