Geometry Registry

geo.map accepts a registry id, a URL, or geometry you pass directly. A registry id is the fastest path: nothing is fetched until you use a pack, and one pack is one request no matter how many aliases or maps on the page ask for it.

geo: { map: 'world/countries@110m' }   // canonical id
geo: { map: 'world/countries' }        // detail-free alias: the lightest pack
geo: { map: 'us' }                     // alias for us/states@10m
geo: { map: 'jp/prefectures' }         // alias, the country's own word for its tier
geo: { map: 'eu/nuts2@20m' }           // Eurostat regions

What travels with each pack

Finding, converting, and hosting boundary files is the tax on every map project. Each of the 26 packs carries four things so you do not have to work them out yourself.

A recommended join key. Data is keyed the way it is actually keyed: us/states joins on "CA", admin-1 packs join on ISO 3166-2 codes like "DE-BY". Generic key detection cannot get this right on its own, an admin-1 feature also carries a country-level code, and choosing that would give every Japanese prefecture the same key.

Repaired identifiers. Natural Earth publishes ISO_A3 as -99 for France and Norway, among others, because it splits their overseas parts into separate features. A join on iso_a3 against the raw file silently loses both countries. The pipeline repairs this once, at build time.

A recommended projection and view, for packs where the generic default is not just suboptimal but wrong. us gets albersUsa, because Alaska's Aleutians cross the antimeridian and the map would otherwise span the whole width of the world. The NUTS packs get an azimuthal equal-area projection centered on Europe with a mainland-only view, because the geometry reaches from French Guiana to Réunion and fitting all of it leaves Europe a few pixels across. An explicit geo.projection or geo.view always overrides the recommendation.

Provenance. Source, license, vintage, boundary policy, and detail level, available through ApexMaps.mapMeta(id) and ApexMaps.catalogue(). Required attribution renders automatically, so a NUTS map credits EuroGeographics whether or not anyone remembered to add it.

The 26 packs

World

Pack idAliasesCoversJoin key
world/countries@110mworld, world/countriesCountries, low detailiso_a3
world/countries@50mCountries, medium detailiso_a3
world/land@110mworld/landCoastline only, no datanone
world/land@50mCoastline only, no datanone

United States

Pack idAliasesCoversJoin key
us/states@10mus/states, us50 statesabbr (USPS)
us/counties@10mus/countiesAll 3,231 countiesfips
us/nation@10mOutline only, no datanone

Both US packs recommend albersUsa, which insets Alaska and Hawaii. County FIPS codes are five digits with a leading zero ("06037"); a numeric data key that lost it is repaired automatically, see Joins.

European Union (Eurostat NUTS)

Pack idAliasesCoversJoin key
eu/nuts0@20meuCountriesnuts_id
eu/nuts1@20meu/regionsMajor regionsnuts_id
eu/nuts2@20mBasic regionsnuts_id
eu/nuts3@20mSmall regionsnuts_id

All four recommend EPSG:3035-equivalent (azimuthal equal-area, rotated on Europe) with a mainland-only view, and credit EuroGeographics on screen.

Admin-1, 15 countries

Natural Earth's "admin-1" tier is not the same administrative level everywhere, so each alias uses the country's own term for what the pack actually contains.

Pack idAliasesLevelNotes
cn/admin1@10mcn/provinces, cnProvinces
in/admin1@10min/states, inStates
jp/admin1@10mjp/prefectures, jpPrefectures
de/admin1@10mde/states, deStates
gb/admin1@10mgb/districts, gbDistricts and unitary authoritiesNot the 4 countries or 12 regions; use eu/nuts1@20m for those
fr/admin1@10mfr/departments, frDepartmentsNot the 13 metropolitan regions; use eu/nuts1@20m. Default view is metropolitan France
it/admin1@10mit/provinces, itProvincesNot the 20 regions; use eu/nuts2@20m
ca/admin1@10mca/provinces, caProvinces and territories
br/admin1@10mbr/states, brStates
ru/admin1@10mru/regions, ruFederal subjectsCustom rotation, Chukotka crosses the antimeridian
mx/admin1@10mmx/states, mxStates
au/admin1@10mau/states, auStates and territoriesDefault view excludes Heard and McDonald Islands
kr/admin1@10mkr/provinces, krProvinces
es/admin1@10mes/provinces, esProvincesNot the 17 autonomous communities; use eu/nuts2@20m
id/admin1@10mid/provinces, idProvinces

All 15 join on iso_3166_2 (e.g. "DE-BY", "JP-13").

Checking provenance

ApexMaps.mapMeta('us/counties@10m')
// { source: 'US Census Bureau TIGER/Line via us-atlas 3.0', license: 'public domain',
//   vintage: '2023', detail: 'high', keyField: 'fips', levelName: 'Counties', ... }

ApexMaps.catalogue()   // every built-in pack, unfiltered, with provenance

ApexMaps.listMaps() lists every registered id and alias. A typo in geo.map throws with a suggestion computed the same way a failed join suggestion is, by edit distance against the registered ids.

Pointing at your own copy: setGeoSource

Packs are fetched from jsDelivr by default, so nothing needs installing to try one. Install the dataset separately, apexmaps-geo, when you want the files locally: offline work, air-gapped deployments, or build-time resolution.

npm install apexmaps-geo
// No network: resolve packs from the installed dataset
ApexMaps.setGeoSource((file) => import(`apexmaps-geo/${file}`).then((m) => m.default))

// Self-hosted: any base URL that serves the same files
ApexMaps.setGeoSource('https://cdn.example.com/apexmaps-geo/')

apexmaps-geo ships as its own package, versioned independently of apexmaps, because boundaries change on their own schedule: NUTS is revised every three years, US counties re-district on the census, and countries rename themselves. A boundary correction should not force a library upgrade.

Status: apexmaps-geo is prepared but has not had its first publish yet, so the default jsDelivr source 404s until it does. Until then, pass geometry directly to geo.map or call setGeoSource() with your own loader.

Registering your own geometry

ApexMaps.registerMap(id, geometry, meta) adds a pack under an id of your choosing, a floor plan, a custom region, anything with a GeoJSON or TopoJSON shape. This is a free, unlicensed feature:

ApexMaps.registerMap('office/floor-3', floorPlanGeoJson, {
  source: 'Internal facilities team',
  license: 'proprietary',
  keyField: 'roomId',
})

Registered geometry is looked up the same way as a built-in pack, so geo.map: 'office/floor-3' works exactly like geo.map: 'us/states'.