> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Transport Type Inference (do_not_know)

> How Dcycle automatically infers the transport mode and distance when transport_type is set to do_not_know

# Transport Type Inference

When a transport section is created with `transport_type: "do_not_know"`, Dcycle automatically infers the most appropriate transport mode and calculates the distance. This page explains the exact decision logic.

## Why use do\_not\_know?

Use `do_not_know` when you know the origin and destination of a shipment but not the transport mode — for example, when processing supplier invoices that don't specify how goods were shipped. Dcycle applies a standardized inference algorithm to ensure the most realistic emission factor is used.

<Note>
  `kms_manual` is **not allowed** for `do_not_know` sections. Because the emission factor depends on the inferred transport mode (which itself depends on geography), manual distances cannot be meaningfully combined with automatic mode selection.
</Note>

## Inference Algorithm

The inference runs at section creation time and follows this decision tree:

```
Given: origin address, destination address
         │
         ▼
1. Geocode both addresses → get coordinates + country codes
         │
         ▼
2. Check for sea crossing
   Same country AND different landmass?
   (e.g. mainland Spain → Canary Islands, mainland Italy → Sicily)
         │
   ┌─────┴──────┐
   YES          NO
   │             │
   ▼             ▼
Use maritime   Same country AND road-reachable via Google Maps?
distance       (status=OK, distance > 0 km, not a default fallback)
(haversine         │
 or searoute)  ┌───┴───┐
               YES     NO
               │        │
               ▼        ▼
           Use road  Use air distance
           distance  (haversine great-circle)
           (Google   Emission factor:
           Maps)     "aircraft, unspecified"
           travel_method → truck
```

## Decision Rules

### Rule 1 — Sea crossing (same country, different landmass)

**Condition:** Origin and destination share the same country code, but their coordinates resolve to different landmasses (e.g. a continental mainland vs. an island).

**Outcome:**

* **Distance:** maritime (navigable-water via searoute, or haversine fallback)
* **Emission factor:** air — specifically the "aircraft, unspecified" concept

This special case exists because island-to-mainland routes involve a sea crossing where ferry emission factors are unavailable in ecoinvent. Air unspecified provides the most conservative and available estimate.

**Examples:**

* Madrid, Spain → Las Palmas, Gran Canaria (Spain) → **maritime kms, air EF**
* Rome, Italy → Palermo, Sicily (Italy) → **maritime kms, air EF**
* Lisbon, Portugal → Funchal, Madeira (Portugal) → **maritime kms, air EF**

### Rule 2 — Same country, road-reachable

**Condition:** Origin and destination are in the same country, no sea crossing detected, and Google Maps returns a valid driving distance (status OK, distance > 0, not a hardcoded default).

**Outcome:**

* **Distance:** road (Google Maps Distance Matrix)
* **Emission factor:** road freight
* **travel\_method** is automatically set to `truck`

**Examples:**

* Madrid, Spain → Barcelona, Spain → **road, truck**
* Paris, France → Lyon, France → **road, truck**
* Berlin, Germany → Munich, Germany → **road, truck**

### Rule 3 — Different countries (or road unreachable)

**Condition:** Everything else — different countries, or same country where Google Maps cannot return a driving route.

**Outcome:**

* **Distance:** air (haversine great-circle between geocoded coordinates)
* **Emission factor:** air — "aircraft, unspecified"
* **travel\_method** stays `null`

**Examples:**

* Madrid, Spain → Paris, France → **air** (different countries)
* Madrid, Spain → Damascus, Syria → **air** (different countries)
* Copenhagen, Denmark → Reykjavik, Iceland → **air** (no road route available)

## What stays as do\_not\_know in the database

The `transport_type` field on the section **always remains `do_not_know`** in the database, regardless of which mode was inferred. The inferred mode only determines:

1. Which geographic distance record is used for `kms`
2. Which emission factor concept is matched during calculation

This means the `kms_source` field will be `null` for `do_not_know` sections in the current API response, since the distance was stored under the inferred transport type's geographic distance record, not under `do_not_know`.

## Emission factors used

| Inferred scenario                | Emission factor concept          |
| -------------------------------- | -------------------------------- |
| Same-country sea crossing        | aircraft, unspecified (air)      |
| Same-country, road-reachable     | road freight, lorry, unspecified |
| Cross-country / road unreachable | aircraft, unspecified (air)      |

The "aircraft, unspecified" factor covers all haul distances without requiring a distance band, making it the natural choice when the exact route characteristics are unknown.

## Comparison with explicit transport types

|                        | `do_not_know`                             | Explicit type (e.g. `maritime`)                      |
| ---------------------- | ----------------------------------------- | ---------------------------------------------------- |
| Distance calculation   | Automatic per inference rules             | Based on declared type                               |
| `kms_manual` allowed   | No                                        | Yes                                                  |
| `transport_type` in DB | Always `do_not_know`                      | The declared type                                    |
| `travel_method`        | Set automatically (truck if road) or null | Provided by user                                     |
| Emission factor        | Inferred from geography                   | Matched from declared type + travel\_method + detail |

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Why is air used for cross-country routes instead of maritime?">
    The inference algorithm prioritises the lowest-complexity mode that can be unambiguously determined from geography alone. For cross-country routes, air is the safest default because:

    * Maritime requires knowing the actual port-to-port routing, which is not available for all country pairs.
    * Rail is not universally available and depends on railway network connectivity.
    * Air operates between any two points on the globe.

    If you know the actual transport mode, you should always declare it explicitly rather than using `do_not_know`.
  </Accordion>

  <Accordion title="What counts as a 'sea crossing' within the same country?">
    Dcycle uses a landmass detection algorithm based on coordinates. A sea crossing is detected when origin and destination coordinates fall on different landmasses, even if they share the same ISO country code. This correctly identifies:

    * Mainland Spain → Canary Islands
    * Mainland Italy → Sicily or Sardinia
    * Mainland Portugal → Azores or Madeira
    * Mainland Denmark → Bornholm island

    It does **not** trigger for tunnels or bridges (e.g. Copenhagen ↔ Malmö via Øresund Bridge), because the road routing check passes first.
  </Accordion>

  <Accordion title="Can I override the inferred mode?">
    Yes — use an explicit `transport_type` instead of `do_not_know`. If you know the shipment was maritime, set `transport_type: "maritime"`. If it was road, set `transport_type: "road"` and optionally `travel_method: "truck"`. You can also set `kms_manual` to override the calculated distance for any explicit type.
  </Accordion>

  <Accordion title="Why is kms_source null for do_not_know sections?">
    The `kms` value for a `do_not_know` section is taken from a geographic distance record stored under the inferred type (road, air, or maritime). Because the join that populates `kms_source` matches on `transport_type`, it doesn't find the record stored under the inferred type. This is a known limitation — the distance was correctly calculated; only the source label is unavailable in the API response.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Transport Overview" icon="book" href="/api-reference/transport/overview">
    Full data model, transport types, and distance calculation methods
  </Card>

  <Card title="Create Transport Route" icon="plus" href="/api-reference/transport/create">
    How to create a route with do\_not\_know sections
  </Card>

  <Card title="Transport Combinations" icon="shuffle" href="/api-reference/transport/combinations">
    All valid transport type + method + detail combinations
  </Card>

  <Card title="Get Transport Route" icon="route" href="/api-reference/transport/get">
    Reading kms, kms\_source, and inferred transport fields from a route
  </Card>
</CardGroup>
