Changelog¶
2026.1.0 (2026-01-21)¶
This is a major release featuring comprehensive geodetic coordinate conversion support, a massive expansion of tile providers, and significant architectural improvements. The new geodesy module implements high-precision coordinate conversions between geographic (lat/lon), UTM, MGRS, and ECEF coordinate systems using Karney (2011) and Bowring (1985) algorithms. The tile provider ecosystem has grown from 20+ to over 100 providers, including OpenStreetMap variants, Stadia Maps, CartoDB, ESRI, NASA GIBS, and regional providers. The HTTP client has been modernized by migrating from requests to httpx, and tile downloads now gracefully handle failures by default. This release also drops support for Python 3.7-3.10 and adds support for Python 3.12-3.14.
Added¶
Added new
geodesymodule for comprehensive coordinate conversions between different coordinate systems:Geographic coordinates (latitude/longitude in WGS84)
UTM (Universal Transverse Mercator) coordinates
MGRS (Military Grid Reference System) coordinates
ECEF (Earth-Centered, Earth-Fixed) Cartesian coordinates
Added public API functions for coordinate conversions (exported from
papermappackage):latlon_to_utm()- Convert geographic coordinates to UTMutm_to_latlon()- Convert UTM coordinates to geographiclatlon_to_mgrs()- Convert geographic coordinates to MGRSmgrs_to_latlon()- Convert MGRS coordinates to geographiclatlon_to_ecef()- Convert geographic coordinates to ECEF Cartesianecef_to_latlon()- Convert ECEF Cartesian to geographicformat_latlon(),format_utm(),format_mgrs(),format_ecef()- Format coordinates as human-readable strings
Added coordinate type classes:
LatLonCoordinate,UTMCoordinate,MGRSCoordinate,ECEFCoordinate(NamedTuples)Added
Ellipsoiddataclass for reference ellipsoid parameters withWGS_84_ELLIPSOIDconstantAdded
PaperMap.from_utm()classmethod to create a PaperMap instance from UTM coordinatesAdded
PaperMap.from_mgrs()classmethod to create a PaperMap instance from MGRS coordinates (supports both MGRSCoordinate objects and MGRS strings)Added
PaperMap.from_ecef()classmethod to create a PaperMap instance from ECEF coordinatesAdded
mgrs, andecefCLI sub-commands to generate paper maps from MGRS and ECEF coordinates, respectivelyAdded
--strictflag to CLI andstrict_downloadparameter toPaperMapclass to control tile download failure behavior. By default (strict=False), PaperMap now allows graceful degradation when some tiles fail to download, rendering failed tiles as background color and issuing a warning. When strict=True, the previous behavior is maintained where any tile download failure raises an exception.Added new
tile_providerssubpackage with provider-based organization for improved maintainabilityAdded 100+ new tile providers from various providers including:
OpenStreetMap regional variants (DE, CH, France, HOT, BZH)
Stadia Maps (including Stamen styles: Toner, Terrain, Watercolor)
CartoDB/Carto (Positron, Dark Matter, Voyager)
Esri (WorldStreetMap, WorldImagery, WorldTopoMap, and more)
HERE Maps (requires API key)
USGS (USTopo, USImagery)
NASA GIBS (satellite imagery)
MapTiler (requires API key)
Jawg Maps (requires API key)
TomTom (requires API key)
CyclOSM (bicycle-oriented maps)
OpenSeaMap (nautical charts)
Waymarked Trails (hiking, cycling, MTB, slopes, riding, skating)
Regional providers: BasemapAT (Austria), NLMaps (Netherlands), SwissFederalGeoportal
And many more specialty maps
Added support for Python 3.12, 3.13 and 3.14.
Changed¶
Improved coordinate conversion accuracy by implementing Karney’s (2011) series expansion of the Transverse Mercator projection for UTM conversions, achieving sub-millimeter accuracy
Refactored coordinate conversion functions from
utils.pyinto the newgeodesymodule with improved implementations:Replaced
spherical_to_utm()andutm_to_spherical()withlatlon_to_utm()andutm_to_latlon()using high-accuracy Karney (2011) algorithmsReplaced
spherical_to_cartesian()andcartesian_to_spherical()withlatlon_to_ecef()andecef_to_latlon()using Bowring (1985) iterative methodConsolidated angle wrapping functions (
wrap(),wrap90(),wrap180(),wrap360()) intowrap_angle(),wrap_lat(), andwrap_lon()
Migrated from
requeststohttpxfor HTTP client functionality, utilizing modern features such as improved connection pooling and timeout handlingRefactored tests to use
pytest-httpxfor cleaner and more maintainable HTTP mockingReorganized package structure by consolidating
defaults.py,constants.py, andtyping.pyinto their logical homes:Tile provider configurations moved to new
tile_providerssubpackagePaper sizes and default values moved to
papermap.pyGeodetic coordinate conversion functions and constants moved to new
geodesymodule
Renamed
TileServerclass toTileProviderand enhanced it with new properties:Added
keyproperty for tile provider key (lowercase with dashes)Added
nameproperty for tile provider display nameAdded
html_attributionproperty for HTML-formatted attribution with hyperlinksAdded
boundsproperty for geographic bounds (optional)Renamed
mirrorstosubdomainsfor better clarityRenamed
mirrors_cycletosubdomains_cycleUpdated URL template placeholders:
{zoom}→{z},{mirror}→{s},{api_key}→{a}
Renamed some tile providers for consistency
Refactored
PaperMap.__init__method into smaller, focused private methods to improve readability and testability:Extracted coordinate validation into
_validate_coordinatesExtracted tile provider setup into
_validate_and_set_tile_providerExtracted paper size configuration into
_validate_and_set_paper_sizeExtracted zoom calculations into
_compute_zoom_and_resize_factorExtracted image dimension calculations into
_compute_image_dimensionsExtracted tile initialization into
_initialize_tilesExtracted PDF initialization into
_initialize_pdf
Renamed
PaperMaptopapermap(purely aesthetically, no changes in installation or usage required).
Removed¶
Removed support for Python 3.7, 3.8, 3.9 and 3.10.
Removed
papermap.defaults,papermap.constants, andpapermap.typingmodules (contents redistributed to other modules)
0.3.0 (2022-11-09)¶
This is a pretty big release with a completely overhauled codebase. For this, I used my new cookiecutter-python-package Python package template. As such, this release comes with much higher code quality, documentation, automation and some important changes to the core functionality of PaperMap.
Changes¶
Completely refactored codebase, with:
Added documentation via Read the Docs
Added CI/CD via GitHub Actions
Added pre-commit hooks w/ CI-integration
Switched to Click for the CLI
Switched to flit for building & releasing the package
0.2.2 (2020-11-26)¶
Changes¶
Added support for custom fonts
0.2.1 (2020-11-03)¶
Changes¶
Added GPX support
Added more tile servers
Added tests
Refactored the codebase
0.1.0 (2019-10-09)¶
Changes¶
Initial release of PaperMap