|
377 | 377 | let sourceNameProj = "source_matched_proj"; |
378 | 378 | let sourceNameEdges = "source_matched_edges"; |
379 | 379 | let sourceNameEdgesCuts = "source_matched_edges_cuts"; |
| 380 | + let sourceNameGaps = "source_submatch_gaps"; |
380 | 381 | let layerName = "layer_matched_route"; |
381 | 382 | let layerNameVertices = "layer_matched_vertices"; |
382 | 383 | let layerNameProj = "layer_matched_proj"; |
383 | 384 | let layerNameEdges = "layer_matched_edges"; |
384 | 385 | let layerNameEdgesCuts = "layer_matched_edges_cuts"; |
| 386 | + let layerNameGaps = "layer_submatch_gaps"; |
385 | 387 | fetch("/api/v0.1.0/mapmatch", { |
386 | 388 | method: "post", |
387 | 389 | headers: { |
|
411 | 413 | features: data.map(obs => { return {...obs.matched_edge_cut, id: obs.edge_id, properties: {obs_idx: obs.obs_idx}} }) |
412 | 414 | }; |
413 | 415 | const matchedVertices = { |
414 | | - type: 'FeatureCollection', |
| 416 | + type: 'FeatureCollection', |
415 | 417 | features: data.map(obs => { return {...obs.matched_vertex, id: obs.vertex_id, properties: {obs_idx: obs.obs_idx}} }) |
416 | 418 | }; |
417 | 419 | const projectedPoints = { |
418 | 420 | type: 'FeatureCollection', |
419 | 421 | features: data.map(obs => { return {...obs.projected_point, properties: {obs_idx: obs.obs_idx}} }) |
| 422 | + }; |
| 423 | + |
| 424 | + // Create gap lines between sub-matches |
| 425 | + const gapLines = { |
| 426 | + type: 'FeatureCollection', |
| 427 | + features: [] |
| 428 | + }; |
| 429 | + const subMatches = jsoned.sub_matches; |
| 430 | + for (let i = 0; i < subMatches.length - 1; i++) { |
| 431 | + const currentSubMatch = subMatches[i]; |
| 432 | + const nextSubMatch = subMatches[i + 1]; |
| 433 | + if (currentSubMatch.observations.length > 0 && nextSubMatch.observations.length > 0) { |
| 434 | + const lastObs = currentSubMatch.observations[currentSubMatch.observations.length - 1]; |
| 435 | + const firstObs = nextSubMatch.observations[0]; |
| 436 | + if (lastObs.projected_point && firstObs.projected_point) { |
| 437 | + gapLines.features.push({ |
| 438 | + type: 'Feature', |
| 439 | + properties: { |
| 440 | + from_submatch: i, |
| 441 | + to_submatch: i + 1, |
| 442 | + from_obs: lastObs.obs_idx, |
| 443 | + to_obs: firstObs.obs_idx |
| 444 | + }, |
| 445 | + geometry: { |
| 446 | + type: 'LineString', |
| 447 | + coordinates: [ |
| 448 | + lastObs.projected_point.geometry.coordinates, |
| 449 | + firstObs.projected_point.geometry.coordinates |
| 450 | + ] |
| 451 | + } |
| 452 | + }); |
| 453 | + } |
| 454 | + } |
420 | 455 | } |
421 | 456 |
|
422 | 457 | // Add all sources |
|
460 | 495 | "data": matchedEdgesCuts |
461 | 496 | }); |
462 | 497 | } |
| 498 | + if (map.getSource(sourceNameGaps)) { |
| 499 | + map.getSource(sourceNameGaps).setData(gapLines); |
| 500 | + } else { |
| 501 | + map.addSource(sourceNameGaps, { |
| 502 | + "type": "geojson", |
| 503 | + "data": gapLines |
| 504 | + }); |
| 505 | + } |
463 | 506 |
|
464 | 507 | // Add all layers |
| 508 | + // Gap lines between sub-matches (orange dashed) |
| 509 | + if (!map.getLayer(layerNameGaps)) { |
| 510 | + map.addLayer({ |
| 511 | + "id": layerNameGaps, |
| 512 | + "type": "line", |
| 513 | + "source": sourceNameGaps, |
| 514 | + "layout": { |
| 515 | + "line-join": "round", |
| 516 | + "line-cap": "round" |
| 517 | + }, |
| 518 | + "paint": { |
| 519 | + "line-color": "#556832", |
| 520 | + "line-opacity": 0.9, |
| 521 | + "line-width": 4, |
| 522 | + "line-dasharray": [2, 4] |
| 523 | + } |
| 524 | + }); |
| 525 | + } |
465 | 526 | if (!map.getLayer(layerNameEdges)) { |
466 | 527 | map.addLayer({ |
467 | 528 | "id": layerNameEdges, |
|
0 commit comments