Interactive world map widget for Flutter with pre-generated geometry, fast paint, and simple country hit-testing. Designed for quick selection, highlighting, and fit-to-region workflows without runtime SVG parsing.
- Pre-generated world map geometry (no SVG parsing at paint time)
InteractiveWorldMapwith pan/zoom viaInteractiveViewer- Country hit-testing by map ID (mostly ISO alpha-2, with
X_*specials) - UN Geoscheme helpers for region/subregion selection
- Remote-island presets for sane fit bounds
WorldIconfor fixed-size icons
Add the dependency:
dependencies:
interactive_world_map: ^0.1.0Import:
import 'package:interactive_world_map/interactive_world_map.dart';final controller = WorldMapController();
InteractiveWorldMap(
controller: controller,
selectOnTap: true,
toggleSelectionOnTap: true,
onCountryTap: (id) {
// Your app logic here.
},
style: const WorldMapStyle(),
)controller.fitToCountries(
{CountryCode.FR, CountryCode.DE}.toMapIds(),
options: const FitOptions(
excludeRemoteIslands: true,
remoteIslandLevel: RemoteIslandLevel.main,
),
);Remote islands can distort bounds (e.g. Norway/Spitsbergen, USA/Hawaii). Use presets to get stable fits.
Defaults are already included via kDefaultRemoteIslandPresetStore.
final options = FitOptions(
excludeRemoteIslands: true,
remoteIslandLevel: RemoteIslandLevel.main,
presetOverrides: {
// Norway (map id resolves to X_NOR)
'NO': {
RemoteIslandLevel.main: const RemoteIslandPreset(
linkFactor: 0.05,
minClusterDensityRatio: 0.45,
maxClustersToKeep: 1,
),
},
},
);final options = FitOptions(
excludeRemoteIslands: true,
remoteIslandLevel: RemoteIslandLevel.main,
presetOverrides: {
// Include all parts even when excludeRemoteIslands is true
'DK': {RemoteIslandLevel.allParts: const RemoteIslandPreset()},
},
);Render and hit-test only a subset of countries:
InteractiveWorldMap(
visibleCountryIds: UnRegion.europe.mapIds(),
)final europe = UnRegion.europe.mapIds();
final seAsia = UnSubregion.southEasternAsia.mapIds();
final caribbean = UnIntermediateRegion.caribbean.mapIds();WorldIcon(
ids: {CountryCode.DE}.toMapIds(),
size: 64,
style: const WorldIconStyle(),
)With remote-island filtering:
WorldIcon(
ids: {CountryCode.US}.toMapIds(),
size: 64,
islandOptions: const IslandFilterOptions(
excludeRemoteIslands: true,
remoteIslandLevel: RemoteIslandLevel.main,
),
)Most map IDs are ISO alpha-2, but some use X_* IDs. The default resolver
handles known overrides:
final id = defaultMapIdResolver('FR'); // -> X_FRAUse CountryCode enums and toMapIds() helpers to avoid manual mapping.
World map data is derived from Natural Earth and is in the public domain.
Attribution is not required but is appreciated (see NOTICE).
See /example for a working demo with:
- Interactive map selection
- Fit-to-selection
- World icon examples