如何将 JSON 转换为 DirectionsRoute

How to convert JSON to DirectionsRoute

我正在为 Android 使用 mapbox API 开发一个简单的导航器。 我正在使用 https://docs.mapbox.com/playground/directions/ 游乐场创建一些路线,我想使用生成的 JSON 生成一个 DirectionsRoute 对象。 所以我调用 DirectionsRoute.fromJson() 但是当我这样做时,应用程序崩溃并出现此错误:

E/Mbgl-MapChangeReceiver: Exception in onDidFinishLoadingStyle
java.lang.NullPointerException: Null distance
    at com.mapbox.api.directions.v5.models.$AutoValue_DirectionsRoute.<init>($AutoValue_DirectionsRoute.java:45)
    at com.mapbox.api.directions.v5.models.AutoValue_DirectionsRoute.<init>(AutoValue_DirectionsRoute.java:27)
    at com.mapbox.api.directions.v5.models.AutoValue_DirectionsRoute$GsonTypeAdapter.read(AutoValue_DirectionsRoute.java:260)
    at com.mapbox.api.directions.v5.models.AutoValue_DirectionsRoute$GsonTypeAdapter.read(AutoValue_DirectionsRoute.java:30)
    at com.google.gson.Gson.fromJson(Gson.java:932)
    at com.google.gson.Gson.fromJson(Gson.java:897)
    at com.google.gson.Gson.fromJson(Gson.java:846)
    at com.google.gson.Gson.fromJson(Gson.java:817)
    at com.mapbox.api.directions.v5.models.DirectionsRoute.fromJson(DirectionsRoute.java:172)
    at eu.mediator.hmi.cluster2.navigator.Nav.getDirectionsRoute(Nav.kt:108)
    at eu.mediator.hmi.cluster2.navigator.Nav.access$getDirectionsRoute(Nav.kt:15)
    at eu.mediator.hmi.cluster2.navigator.Nav$route.invoke(Nav.kt:19)
    at eu.mediator.hmi.cluster2.navigator.Nav$route.invoke(Nav.kt:19)
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
    at eu.mediator.hmi.cluster2.navigator.Nav.getRoute(Nav.kt:19)
    at eu.mediator.hmi.cluster2.navigator.Nav.onNavigationReady(Nav.kt:83)
    at com.mapbox.navigation.ui.NavigationView.updateNavigationReadyListeners(NavigationView.java:701)
    at com.mapbox.navigation.ui.NavigationView.lambda$onMapReady[=11=]$NavigationView(NavigationView.java:261)
    at com.mapbox.navigation.ui.-$$Lambda$NavigationView$cQ4pEaxGsKIc0JZPsHECDoNZqgE.onStyleLoaded(Unknown Source:4)
    at com.mapbox.mapboxsdk.maps.MapboxMap.notifyStyleLoaded(MapboxMap.java:963)
    at com.mapbox.mapboxsdk.maps.MapboxMap.onFinishLoadingStyle(MapboxMap.java:225)
    at com.mapbox.mapboxsdk.maps.MapView$MapCallback.onDidFinishLoadingStyle(MapView.java:1383)
    at com.mapbox.mapboxsdk.maps.MapChangeReceiver.onDidFinishLoadingStyle(MapChangeReceiver.java:198)
    at com.mapbox.mapboxsdk.maps.NativeMapView.onDidFinishLoadingStyle(NativeMapView.java:1166)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:326)
    at android.os.Looper.loop(Looper.java:160)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

这是我要解析的 json 的示例:

{
  "routes": [
    {
      "weight_name": "auto",
      "weight": 296.434,
      "duration": 220.762,
      "distance": 706.383,
      "legs": [
        {
          "admins": [{"iso_3166_1_alpha3": "USA", "iso_3166_1": "US"}],
          "weight": 296.434,
          "duration": 220.762,
          "steps": [
            {
              "intersections": [
                {
                  "entry": [true],
                  "bearings": [299],
                  "duration": 1.309,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 1.539,
                  "geometry_index": 0,
                  "location": [-73.992199, 40.734505]
                },
                {
                  "entry": [false, true],
                  "in": 0,
                  "bearings": [119, 299],
                  "duration": 58.966,
                  "turn_weight": 2,
                  "turn_duration": 2.021,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "weight": 68.911,
                  "geometry_index": 1,
                  "location": [-73.992255, 40.734529]
                },
                {
                  "bearings": [119, 299],
                  "entry": [false, true],
                  "in": 0,
                  "turn_weight": 2,
                  "turn_duration": 0.021,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "geometry_index": 2,
                  "location": [-73.994055, 40.735287]
                }
              ],
              "maneuver": {
                "type": "depart",
                "instruction": "Drive northwest on East 13th Street.",
                "bearing_after": 299,
                "bearing_before": 0,
                "location": [-73.992199, 40.734505]
              },
              "name": "East 13th Street",
              "duration": 62.26,
              "distance": 185.82,
              "driving_side": "right",
              "weight": 74.757,
              "mode": "driving",
              "geometry": "qqfulAl_cclCo@nBkn@noBs@|B"
            },
            {
              "intersections": [
                {
                  "entry": [false, true],
                  "in": 0,
                  "bearings": [119, 210],
                  "duration": 8.377,
                  "turn_weight": 22.5,
                  "turn_duration": 7.395,
                  "mapbox_streets_v8": {"class": "secondary"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "weight": 23.654,
                  "geometry_index": 3,
                  "location": [-73.994118, 40.735313]
                },
                {
                  "entry": [false, true],
                  "in": 0,
                  "bearings": [30, 210],
                  "duration": 11.134,
                  "turn_weight": 2,
                  "turn_duration": 0.007,
                  "mapbox_streets_v8": {"class": "secondary"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "weight": 15.075,
                  "geometry_index": 4,
                  "location": [-73.994156, 40.735263]
                },
                {
                  "bearings": [30, 210],
                  "entry": [false, true],
                  "in": 0,
                  "turn_weight": 2,
                  "turn_duration": 0.007,
                  "mapbox_streets_v8": {"class": "secondary"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "geometry_index": 5,
                  "location": [-73.994562, 40.734732]
                }
              ],
              "maneuver": {
                "type": "turn",
                "instruction": "Turn left onto 5th Avenue.",
                "modifier": "left",
                "bearing_after": 210,
                "bearing_before": 299,
                "location": [-73.994118, 40.735313]
              },
              "name": "5th Avenue",
              "duration": 20.663,
              "distance": 81,
              "driving_side": "right",
              "weight": 42.074,
              "mode": "driving",
              "geometry": "adhulAjwfclCbBjAd`@jXdBlA"
            },
            {
              "intersections": [
                {
                  "entry": [false, true],
                  "in": 0,
                  "bearings": [30, 121],
                  "duration": 9.332,
                  "turn_weight": 12.5,
                  "turn_duration": 7.275,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 1,
                  "weight": 14.917,
                  "geometry_index": 6,
                  "location": [-73.994601, 40.734681]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [118, 301],
                  "duration": 1.051,
                  "turn_weight": 2,
                  "turn_duration": 0.022,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 3.209,
                  "geometry_index": 7,
                  "location": [-73.994524, 40.734646]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 298],
                  "duration": 39.865,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 48.832,
                  "geometry_index": 8,
                  "location": [-73.994484, 40.73463]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 2.065,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 4.417,
                  "geometry_index": 9,
                  "location": [-73.992878, 40.733958]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 4.626,
                  "turn_weight": 2,
                  "turn_duration": 2.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 5.076,
                  "geometry_index": 10,
                  "location": [-73.992792, 40.733922]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 47.135,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 57.375,
                  "geometry_index": 11,
                  "location": [-73.992714, 40.733889]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 3.608,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 6.23,
                  "geometry_index": 12,
                  "location": [-73.991224, 40.73326]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 4.5,
                  "turn_weight": 2,
                  "turn_duration": 2.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 4.928,
                  "geometry_index": 13,
                  "location": [-73.991114, 40.733214]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 14.962,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 19.571,
                  "geometry_index": 14,
                  "location": [-73.991019, 40.733174]
                },
                {
                  "entry": [true, false],
                  "in": 1,
                  "bearings": [119, 299],
                  "duration": 7.762,
                  "turn_weight": 0.5,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "weight": 9.611,
                  "geometry_index": 15,
                  "location": [-73.990465, 40.732939]
                },
                {
                  "bearings": [119, 299],
                  "entry": [true, false],
                  "in": 1,
                  "turn_weight": 2,
                  "turn_duration": 0.008,
                  "mapbox_streets_v8": {"class": "street"},
                  "is_urban": true,
                  "admin_index": 0,
                  "out": 0,
                  "geometry_index": 16,
                  "location": [-73.990173, 40.732817]
                }
              ],
              "maneuver": {
                "type": "turn",
                "instruction": "Turn left onto East 12th Street.",
                "modifier": "left",
                "bearing_after": 121,
                "bearing_before": 210,
                "location": [-73.994601, 40.734681]
              },
              "name": "East 12th Street",
              "duration": 137.839,
              "distance": 439.563,
              "driving_side": "right",
              "weight": 179.603,
              "mode": "driving",
              "geometry": "q|fulApugclCdAyC^oA~h@kcBfAkD`A{Chf@c|AzA{EnA}DtMsa@rFgQ`@oAx@kC"
            },
            {
              "intersections": [
                {
                  "bearings": [299],
                  "entry": [true],
                  "in": 0,
                  "admin_index": 0,
                  "geometry_index": 18,
                  "location": [-73.990063, 40.732771]
                }
              ],
              "maneuver": {
                "type": "arrive",
                "instruction": "Your destination is on the right.",
                "modifier": "right",
                "bearing_after": 0,
                "bearing_before": 119,
                "location": [-73.990063, 40.732771]
              },
              "name": "East 12th Street",
              "duration": 0,
              "distance": 0,
              "driving_side": "right",
              "weight": 0,
              "mode": "driving",
              "geometry": "eeculA|y~blC??"
            }
          ],
          "distance": 706.383,
          "summary": "East 13th Street, East 12th Street"
        }
      ],
      "geometry": "qqfulAl_cclCoq@|vBnf@d]jvBszG"
    }
  ],
  "waypoints": [
    {
      "distance": 2.275,
      "name": "East 13th Street",
      "location": [-73.992199, 40.734505]
    },
    {
      "distance": 4.846,
      "name": "East 12th Street",
      "location": [-73.990063, 40.732771]
    }
  ],
  "code": "Ok",
  "uuid": "iN7DOXpeBlZLl3bHqiFcXZinCTs9_4miufia3aF9gVodZF3QZ-c0lQ=="
}

mapbox API 的响应不是 DirectionsRoute。它是 DirectionsResponse,一个看起来像这样的结构:

{
    "routes":[ ... ],
    "waypoints":[ ... ],
    "code":"Ok",
    "uuid":"iN7DOXpeBlZLl3bHqiFcXZinCTs9_4miufia3aF9gVodZF3QZ-c0lQ=="
}

所以你不能用DirectionsRoute.fromJson()

解析这个

响应包含 DirectionsRoute 的列表,在 "routes" 属性 中。通常第一个是被使用的那个。解析这个使用

directionsResponse = DirectionsResponse.fromJson();

然后你可以像这样在响应中得到第一条路线:

DirectionsRoute route = directionsResponse.routes().get(0);