# Detect route and map updates

Update detection requires a current catalog. Run `AUTO` on normal screen entry, _fetchRegionLists()_ again after synchronization completes, and use `FORCE` for an explicit user refresh.

For the route side, check `row.routeRegion?.updateAvailable == true`. It becomes true only when local detail exists, the route package is fully downloaded, and the latest catalog `version` or `timestampSec` differs from local detail. _catalogRemoved_ means the catalog removed the region and was not an update.

### Installed map item OfflineInstalledRegion

| Field | Meaning | Recommended use |
| --- | --- | --- |
| `regionId` | Installed map-region ID | Associate with `row.regionId` |
| `displayName` | Best local display name | Display only |
| `packageCount` | Number of packages installed for this region | The SDK imposes no fixed package-count limit |
| `totalBytes` | Installed database bytes recorded by the manifest | This is not the remaining download size |
| `regionVersion` | Map version from the most recent successful install | Compare with `mapRegion.version` |
| `allTarsOk` | Whether every map package completed successfully | When `false`, treat the install as incomplete and offer `Resume` |
| `dataSource` | Map data source that owns the installation | Use for diagnostics or multi-source handling |
| `dataSourceLabel` | Human-readable data-source name | Useful on settings or diagnostic screens |

_MapTileRegionListItem_ has no direct _updateAvailable_ property. Call _NBNavigation.listInstalledMapTileRegions()_ asynchronously and associate results by `regionId`. A `CURRENT` or `UPDATE_AVAILABLE` decision is valid only when the installed region is complete and both versions are non-blank. A missing version is `UNKNOWN` and should be assumed as current.

```kotlin
enum class MapUpdateState { NOT_INSTALLED, INCOMPLETE, CURRENT,
    UPDATE_AVAILABLE, UNKNOWN }

fun mapUpdateState(
    row: OfflineRegionListRow,
    installed: List<OfflineInstalledRegion>
): MapUpdateState {
    val catalog = row.mapRegion ?: return MapUpdateState.UNKNOWN
    val local = installed.firstOrNull { it.regionId.toLong() == row.regionId }
        ?: return MapUpdateState.NOT_INSTALLED
    if (!local.allTarsOk) return MapUpdateState.INCOMPLETE
    val latest = catalog.version
    val current = local.regionVersion
    if (latest.isNullOrBlank() || current.isNullOrBlank()) {
        return MapUpdateState.UNKNOWN
    }
    return if (latest == current) MapUpdateState.CURRENT
           else MapUpdateState.UPDATE_AVAILABLE
}
```

The SDK does not silently update regional data in the background. Show the version, estimated size, network policy, and storage result before the user confirms an update.

For a fully installed map package, calling _downloadRegion()_ again can return `ALREADY_COMPLETED`. If the product uses a full reinstall policy, obtain confirmation from user, call _deleteRegionAllData()_, then _call downloadRegion()_, and require both `routeNetwork` and `mapTile` to reach `COMPLETED`. The region temporarily loses offline capability during replacement, and route/map operations are not atomic across the two subsystems.
