예상 이동 시간 및 거리 검색

두 위치 간을 이동하는 데 걸리는 예상 시간 및 거리를 검색하는 프로그램을 만들 수 있습니다. 다음 절차에서는 BlackBerry 단말기 사용자가 도착지 주소를 입력하는 텍스트 필드 1개, 도착지에 이르는 데 걸리는 예상 시간 및 거리를 검색하기 위해 사용자가 클릭하는 버튼 1개, 결과를 표시하기 위한 필드 1개를 포함하는 UI 프로그램을 만듭니다.

시작하기 전에:

BlackBerry 단말기 또는 BlackBerry Smartphone Simulator에서 GPS를 사용할 수 있게 설정되어 있는지 확인합니다.

  1. 필요한 클래스와 인터페이스를 가져옵니다.
    import net.rim.device.api.lbs.Locator;
    import net.rim.device.api.lbs.travel.*;
    import net.rim.device.api.system.*;
    import net.rim.device.api.ui.*;
    import net.rim.device.api.ui.component.*;
    import net.rim.device.api.ui.container.*;
    import javax.microedition.location.*;
  2. UiApplication 클래스를 확장하여 프로그램 구조를 만듭니다. main()에서 새 클래스의 인스턴스를 만들고 enterEventDispatcher()를 호출하여 프로그램이 이벤트를 수신할 수 있도록 합니다. 프로그램 생성자에서 pushScreen()을 호출하여 프로그램의 사용자 정의 화면을 표시합니다. 3단계에서 설명한 TravelTimeScreen 클래스는 사용자 정의 화면을 나타냅니다.
    public final class MyTravelTimeDemo extends UiApplication
    {
        public static void main(String[] args)
        {
            MyTravelTimeDemo theApp = new MyTravelTimeDemo();
            theApp.enterEventDispatcher();
        }
        public MyTravelTimeDemo()
        {
            pushScreen(new TravelTimeScreen());
        }
    }
  3. MainScreen 클래스를 확장하여 사용자 정의 화면의 구조를 만듭니다.
    class TravelTimeScreen extends MainScreen
    {
        private BasicEditField _destinationField;
        private LabelField _timeLabel;
        private LabelField _distanceLabel;
  4. 생성자에서 super()를 호출하여 기본 메뉴를 만듭니다. setTitle()을 호출하여 화면 제목을 지정합니다. BasicEditField 클래스의 인스턴스를 만들어 사용자가 도착지를 입력할 수 있는 텍스트 필드를 만듭니다. add()를 호출하여 필드를 화면에 추가합니다. ButtonField 클래스의 인스턴스를 만들어 이동 시간 및 거리의 예상치를 검색하기 위한 버튼을 만듭니다. Field.setChangeListener()를 호출하여 이 버튼의 상태 변경을 수신합니다. 5단계에서 설명한 findTravelTime()을 호출하여 사용자가 버튼을 클릭하면 이동 시간 및 거리의 예상치를 검색합니다. add()를 호출하여 버튼을 화면에 추가합니다. 이동 시간 및 거리의 예상 결과를 표시하는 LabelField 클래스의 인스턴스를 만듭니다.
    public TravelTimeScreen()
    {
        super(DEFAULT_CLOSE | DEFAULT_MENU);
        setTitle(new LabelField("Travel Time Demo" , Field.USE_ALL_WIDTH | DrawStyle.HCENTER));
        this._destinationField = new BasicEditField("Destination: ", "", 500, TextField.NO_NEWLINE);
        add(this._destinationField);
        ButtonField travelButton = new ButtonField("Get Travel Estimate", ButtonField.CONSUME_CLICK);
        travelButton.setChangeListener(new FieldChangeListener() 
        {
            public void fieldChanged(Field field, int context)
            {
                findTravelTime();
            }
        });
        add(travelButton);
        this._timeLabel = new LabelField();
        add(this._timeLabel);
        this._distanceLabel = new LabelField();
        add(this._distanceLabel);
    }
  5. 여행 시간 예상치를 제공하는 메소드를 TravelTimeScreen 클래스에 만듭니다. 사용자가 입력한 도착지를 검색하기 위해 getText()를 호출하는 String 클래스의 인스턴스를 만듭니다. Null 값 또는 길이가 0인 값이 destination 필드에 들어 있는지 검사하여 해당 필드가 비어 있지 않은지 확인합니다. 이동 시간 및 거리 결과 필드에서 값을 지웁니다.
    private void findTravelTime() 
    {
        final String destination = this._destinationField.getText();
        if ((destination == null) || (destination.length() == 0))
        {
            Dialog.alert("Destination field cannot be empty");
            return;
        }
        this._timeLabel.setText("");
        this._distanceLabel.setText("");
  6. 시작과 종료 지점의 지리공간 좌표를 검색합니다. 이를 위해 먼저 findTravelTime 메소드에서 run()을 호출하는 Thread 클래스의 인스턴스를 만듭니다. run() 내부의 try/catch 블록에서 Locator.geocode()를 호출하고 매개 변수로 도착지에 해당하는 String을 전달하여 주소를 찾고 Landmark 객체의 배열을 반환합니다. Landmark.getQualifiedCoordinates()를 호출해 Geolocation 서비스를 사용하여 도착지의 지리공간 좌표를 검색합니다. 현재 위치를 요청하기 위해 LocationProvider.getInstance()를 호출하여 위치 공급자를 검색합니다. Location.getQualifiedCoordinates()를 호출해 GPS 서비스를 사용하여 현재 위치의 지리공간 좌표를 검색합니다. GPS를 사용할 수 없는 경우에는 Geolocation 서비스를 사용하여 현재 위치의 좌표를 검색할 수도 있습니다.
    Thread travelTimeThread = new Thread()
    {
        public void run()
        {
            try
            {
                final Landmark[] landmarks = Locator.geocode(destination.replace('\n', ' '), null);
                Coordinates endPoint = landmarks[0].getQualifiedCoordinates();
                LocationProvider provider = LocationProvider.getInstance(null);
                if (provider == null)
                {
                    throw new IllegalStateException("no LocationProvider available");
                }
                Coordinates startPoint = provider.getLocation(-1).getQualifiedCoordinates();
  7. TraveTimeEstimator.getInstance()를 호출하여 TravelTimeEstimator 클래스의 인스턴스를 만듭니다. requestArrivalEstimate()를 호출하여 예상 이동 시간과 거리를 요청합니다. 시작과 종료 지점에 대한 Coordinates 객체를 지정하고, 출발 시간을 지정합니다. 이 예에서는 지리공간 좌표를 검색하기 위해 별도의 단일 스레드가 만들어지기 때문에 동기 요청이 이루어집니다. TravelTime.START_NOW 상수를 사용하면 이동이 즉시 시작되는 것으로 지정할 수 있습니다. 8단계에서 설명하는 showResults()를 호출하여 결과를 표시합니다.
    TravelTimeEstimator estimator = TravelTimeEstimator.getInstance();
    final TravelTime travelTime = estimator.requestArrivalEstimate(startPoint, endPoint, TravelTime.START_NOW, null);
    showResults(travelTime);
  8. showResults 메소드에서 invokeLater()를 호출하여 이 코드 섹션을 프로그램의 이벤트 큐에 추가합니다. Runnable 클래스의 인스턴스를 만들고 이를 매개 변수로 invokeLater()에 전달합니다. Runnable의 정의에서 run()을 재정의합니다. getElapsedTime()을 호출하여 예상 이동 시간을 검색합니다. 반환된 이동 시간을 밀리초 형식에서 시:분:초 형식으로 변환합니다. getDistance()를 호출하여 예상 이동 시간을 검색합니다. 반환된 거리를 미터 단위에서 킬로미터 단위로 변환합니다. setText()를 호출하여 이동 시간 및 거리에 대한 결과를 표시합니다.
    private void showResults(final TravelTime travelTime)
    {
        Application.getApplication().invokeLater(new Runnable()
        {
            public void run()
            {
                long value = travelTime.getElapsedTime() / 1000;
                long seconds = value % 60;
                value /= 60;
                long minutes = value % 60;
                long hours = value / 60;
                StringBuffer buffer = new StringBuffer();
                buffer.append(hours);
                buffer.append(':');
                if (minutes < 10)
                {
                    buffer.append('0');
                }
                buffer.append(minutes);
                buffer.append(':');
                if (seconds < 10)
                {
                    buffer.append('0');
                }
                buffer.append(seconds);
                String msg = "Travel Time (h:m:s): " + buffer.toString();
                TravelTimeScreen.this._timeLabel.setText(msg);
                double distance = travelTime.getDistance() / 1000.0;
                msg = "Distance (km): " + Double.toString(distance);
                TravelTimeScreen.this._distanceLabel.setText(msg);
            }
        });
    }

이 정보가 도움이 되었습니까? 의견을 보내 주십시오.