首页 文章

使用osmbonuspack库在osmdroid Map 上绘制路线

提问于
浏览
1

我创建了osmdroid Map 视图,我在其上显示自定义WMS,这是有效的 . 接下来,我需要在2点之间的 Map 路线上绘制dinamically,我从GeoJSON格式的自定义服务获得 . GeoJSON看起来像这样:http://pastebin.com/GJWYNkAq

通过OkHttp客户端调用服务:

Request request = new Request.Builder()
                .url("http://xxx.xxx.xxx.x:7915/GeoService.svc/GetRoute?" + "source=" + encodedSourceAddress + "&target=" + encodedTargetAddress)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful())
                    throw new IOException("Unexpected code " + response);

                String result = response.body().string();
                Log.d("RESULT", result);
                viewRoute(result); //json is received ok, I debugged it

            }

        });

我在这个方法中使用了这个Osmbonuspack库:

public void viewRoute(String geoJson) {
    KmlDocument kmlDocument = new KmlDocument();
    kmlDocument.parseGeoJSON(geoJson); //application is crashed here
    FolderOverlay myOverLay = (FolderOverlay) kmlDocument.mKmlRoot.buildOverlay(map, null, null, kmlDocument);
    map.getOverlays().add(myOverLay);
    map.invalidate();
}

当我运行app时,启动后崩溃时出现此错误:

03-09 13:01:51.521 3968-3992 / bachelor.vsb.martin.osmdroidclient E / AndroidRuntime:致命异常:OkHttp分派器进程:bachelor.vsb.martin.osmdroidclient,PID:3968 java.lang.ClassCastException:COM . google.gson.JsonNull不能被转换到在com.google.gson.JsonObject com.google.gson.JsonObject.getAsJsonObject(JsonObject.java:191)在org.osmdroid.bonuspack.kml.KmlPlacemark . (KmlPlacemark.java:89 )在org.osmdroid.bonuspack.kml.KmlFeature.parseGeoJSON(KmlFeature.java:237)在org.osmdroid.bonuspack.kml.KmlFolder . (KmlFolder.java:62)在org.osmdroid.bonuspack.kml.KmlFeature.parseGeoJSON (KmlFeature.java:235)在org.osmdroid.bonuspack.kml.KmlDocument.parseGeoJSON(KmlDocument.java:1097)在org.osmdroid.bonuspack.kml.KmlDocument.parseGeoJSON(KmlDocument.java:1112)在bachelor.vsb . martin.osmdroidclient.MainActivity.viewRoute(MainActivity.java:137)在bachelor.vsb.martin.osmdroidclient.MainActivity $ 1.onResponse(MainActivity.java:127)在okhttp3.RealCall $ AsyncCall.execute(RealCall.java:135)在okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:607 )在java.lang.Thread.run(Thread.java:761)

我使用的是osmdroid 5.6.4和osmbonuspack 6.2

1 回答

  • 1

    它看起来像是该库中的一个错误 . master分支的current实现如下所示:

    89: JsonObject geometry = json.getAsJsonObject("geometry");
    90: if (geometry != null) {
    

    是的,对于不存在的键, getAsJsonObject 可以返回 null ,但是如果已知给定的JSON路径值是 null ,则Gson使用 JsonNull 作为 null 值标记(并且它是有意义的) . JSON中唯一具有 null 的路径是 $.features[6].geometry ,所以我假设这是唯一的原因 . 你可以在这里做的是在他们的GitHub问题台提出一个新问题,添加一个适当的 JsonNull 检查,以免在类型转换中失败 . 模拟案例:

    final JsonObject geometry = (JsonObject) geoJsonObject.getAsJsonObject()
            .get("features")
            .getAsJsonArray()
            .get(6)
            .getAsJsonObject()
            .get("geometry"); // actually JsonNull for $.features[6].geometry
    

    到目前为止你能做的是:

    • 从树中删除该路径(我没有分析该库是否可以使用空/不完整的 geometry JsonPath 元素,因此可能只是替换该路径值将无效) .

    • 或者删除整个第7个 feature 对象(这可能更合适,但会导致一些数据丢失) .

    第一个选项的示例:

    final JsonObject geoJsonObject = gson.fromJson(geoJson, JsonObject.class);
    fixGeoJsonObject(geoJsonObject);
    kmlDocument.parseGeoJSON(geoJsonObject); // passing the "fixed" object
    

    其中 fixGeoJsonObject 如下:

    private static void fixGeoJsonObject(final JsonObject geoJsonObject) {
        final JsonArray features = geoJsonObject
                .get("features")
                .getAsJsonArray();
        final int length = features.size();
        for ( int i = 0; i < length; i++ ) {
            final JsonObject feature = features.get(i)
                    .getAsJsonObject();
            final JsonElement geometry = feature.get("geometry");
            if ( geometry.isJsonNull() ) {
                feature.remove("geometry"); // losing some data...
            }
        }
    }
    

    或者第二种选择:

    private static void fixGeoJsonObject(final JsonObject geoJsonObject) {
        final JsonArray features = geoJsonObject
                .get("features")
                .getAsJsonArray();
        for ( int i = 0; i < features.size(); i++ ) {
            final JsonObject feature = features.get(i)
                    .getAsJsonObject();
            final JsonElement geometry = feature.get("geometry");
            if ( geometry.isJsonNull() ) {
                features.remove(i); // losing even more data...
            }
        }
    }
    

    这应该会修复你使用的 ClassCastException .

    编辑1:

相关问题