J2ME/Android/BlackBerry - 驾驶路线指引,两个位置之间的路径

91
在Android 1.0中,有一个用于驾驶路线的com.google.googlenav命名空间:
路线-改进的谷歌驾驶方向
但在更新的SDK中,由于某些原因被删除了...
Android:自API 1.0以来已删除DrivingDirections-如何在1.5 / 1.6中执行? 在BlackBerry上也缺乏此类API:
如何在Blackberry中找到两个地方之间的路线?

csie-tw提供了一种解决方法(查询gmaps以获取kml文件并解析它):
Android-驾驶方向(路线路径)
此外,Andrea为Android制作了DrivingDirections助手类
我为此功能编写了一个小助手,在j2me中,所以我想分享我的Android和BlackBerry示例。

更新
正如评论中所述,这不是官方允许的Google Maps APIs服务条款:

Google Maps/Google Earth APIs 服务条款
最近更新:2009年5月27日
...
10. 许可证限制。除非在条款下明确允许,或者您已经收到了来自Google(或适用的特定内容提供者)的事先书面授权,否则Google的上述许可受到以下所有限制的约束。除非在第7节或地图API文档中明确允许,否则您不得(也不得允许任何其他人):
...
10.9 使用服务或内容与任何产品、系统或应用程序相关联,包括但不限于实时导航或路线指引,其中包括与用户传感器启用设备位置同步的逐步路线指引;

并且可能会对某些应用程序进行禁用(至少在Android上)... 来自在.NET对Geocode进行抓取的交谈:

这不被API使用条款所允许。您不应该抓取Google Maps以生成地理代码。我们将阻止那些对我们的服务器进行自动查询的服务。

Bret Taylor
Google Maps 产品经理

将不胜感激任何替代方案和/或建议!
谢谢!


2
我想这样爬取谷歌地图的驾车路线可能会违反谷歌的使用条款。 - Christopher Orr
我正在获取mRoad中的所有点,但它们没有在地图上映射出来。地图上显示的路径仅从斋普尔到德里! - Vishal Khakhkhar
1
@Vishal:抱歉,我无法帮助你!请发布单独的问题! - Maksym Gontar
1个回答

115

J2ME地图路线提供者

maps.google.com有一个导航服务,可以提供KML格式的路线信息。

要获取kml文件,我们需要使用起点和终点位置组成URL:

public static String getUrl(double fromLat, double fromLon,
                            double toLat, double toLon) {// connect to map web service
    StringBuffer urlString = new StringBuffer();
    urlString.append("http://maps.google.com/maps?f=d&hl=en");
    urlString.append("&saddr=");// from
    urlString.append(Double.toString(fromLat));
    urlString.append(",");
    urlString.append(Double.toString(fromLon));
    urlString.append("&daddr=");// to
    urlString.append(Double.toString(toLat));
    urlString.append(",");
    urlString.append(Double.toString(toLon));
    urlString.append("&ie=UTF8&0&om=0&output=kml");
    return urlString.toString();
}

接下来,您需要解析XML(使用SAXParser实现),并填充数据结构:

public class Point {
    String mName;
    String mDescription;
    String mIconUrl;
    double mLatitude;
    double mLongitude;
}

public class Road {
    public String mName;
    public String mDescription;
    public int mColor;
    public int mWidth;
    public double[][] mRoute = new double[][] {};
    public Point[] mPoints = new Point[] {};
}

在Android和Blackberry上,网络连接的实现方式不同,因此您首先需要形成URL:

 public static String getUrl(double fromLat, double fromLon,
     double toLat, double toLon)

然后使用这个URL创建连接并获取InputStream。
接着将这个InputStream传递并获取解析后的数据结构:

 public static Road getRoute(InputStream is) 

完整源代码RoadProvider.java

黑莓(BlackBerry)

class MapPathScreen extends MainScreen {
    MapControl map;
    Road mRoad = new Road();
    public MapPathScreen() {
        double fromLat = 49.85, fromLon = 24.016667;
        double toLat = 50.45, toLon = 30.523333;
        String url = RoadProvider.getUrl(fromLat, fromLon, toLat, toLon);
        InputStream is = getConnection(url);
        mRoad = RoadProvider.getRoute(is);
        map = new MapControl();
        add(new LabelField(mRoad.mName));
        add(new LabelField(mRoad.mDescription));
        add(map);
    }
    protected void onUiEngineAttached(boolean attached) {
        super.onUiEngineAttached(attached);
        if (attached) {
            map.drawPath(mRoad);
        }
    }
    private InputStream getConnection(String url) {
        HttpConnection urlConnection = null;
        InputStream is = null;
        try {
            urlConnection = (HttpConnection) Connector.open(url);
            urlConnection.setRequestMethod("GET");
            is = urlConnection.openInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return is;
    }
}

在Google Code上查看完整代码,请参考J2MEMapRouteBlackBerryEx

Android

Android G1屏幕截图

public class MapRouteActivity extends MapActivity {
    LinearLayout linearLayout;
    MapView mapView;
    private Road mRoad;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        new Thread() {
            @Override
            public void run() {
                double fromLat = 49.85, fromLon = 24.016667;
                double toLat = 50.45, toLon = 30.523333;
                String url = RoadProvider
                        .getUrl(fromLat, fromLon, toLat, toLon);
                InputStream is = getConnection(url);
                mRoad = RoadProvider.getRoute(is);
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }

    Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            TextView textView = (TextView) findViewById(R.id.description);
            textView.setText(mRoad.mName + " " + mRoad.mDescription);
            MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
            List<Overlay> listOfOverlays = mapView.getOverlays();
            listOfOverlays.clear();
            listOfOverlays.add(mapOverlay);
            mapView.invalidate();
        };
    };

    private InputStream getConnection(String url) {
        InputStream is = null;
        try {
            URLConnection conn = new URL(url).openConnection();
            is = conn.getInputStream();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return is;
    }
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}

请在Google Code的J2MEMapRouteAndroidEx上查看完整代码。


2
http://code.google.com/intl/uk-UA/android/add-ons/google-apis/reference/com/google/android/maps/MapController.html#setZoom%28int%29 - Maksym Gontar
8
这段代码将不再起作用,因为谷歌已停止以KML格式提供响应。以下是解决方案的链接,回答了Stack Overflow问题[为什么使用KML数据检索Google Android方向不再起作用?](https://dev59.com/E2gt5IYBdhLWcg3w5hWr#11745316) - kendrelaxman
1
这是完整的文档:https://developers.google.com/maps/documentation/directions/ - Alexey
以上解决方案已经无法在API 2中使用。我成功地使用Google地图Android API v2在两个点之间绘制了路径。我在那个链接上发布了它的解决方案。答案:使用Google Maps Android API v2在两个点之间绘制路径。 - Zeeshan Mirza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接