CRS & Reprojection Helpers#
CRS-handling helpers in pyramids.base.crs — the single source of
truth for osr.SpatialReference construction, WKT/Proj4 → EPSG
resolution, and coordinate reprojection. The most-commonly-used
ones are also re-exposed as FeatureCollection static methods for
ergonomic continuity (e.g.
FeatureCollection.reproject_coordinates delegates to
pyramids.base.crs.reproject_coordinates).
Functions#
pyramids.base.crs.sr_from_epsg(epsg)
#
Build an :class:osr.SpatialReference from an EPSG code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
epsg
|
int
|
EPSG code; cast to |
required |
Returns:
| Type | Description |
|---|---|
SpatialReference
|
osr.SpatialReference: The constructed SRS. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If GDAL cannot resolve the EPSG code (the
non-zero return path from |
Source code in src/pyramids/base/crs.py
pyramids.base.crs.sr_from_wkt(wkt)
#
Build an :class:osr.SpatialReference from a WKT string.
Thin wrapper around osr.SpatialReference(wkt=wkt) that gives
the WKT path a consistent name alongside :func:sr_from_epsg and
:func:create_sr_from_proj. Use this when you have a WKT (the
most common case in the dataset stack — dataset.crs returns
WKT) and want a typed SRS without re-typing the constructor's
keyword argument every call site.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wkt
|
str
|
Well-Known Text representation of the spatial reference. |
required |
Returns:
| Type | Description |
|---|---|
SpatialReference
|
osr.SpatialReference: The constructed SRS. |
Examples:
- Round-trip an EPSG code through WKT:
Source code in src/pyramids/base/crs.py
pyramids.base.crs.create_sr_from_proj(prj, string_type=None)
#
Create an :class:osr.SpatialReference from a projection string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prj
|
str
|
The projection string (WKT, ESRI WKT, or Proj4). |
required |
string_type
|
str | None
|
One of |
None
|
Returns:
| Type | Description |
|---|---|
SpatialReference
|
osr.SpatialReference: The constructed spatial reference. |
Examples:
- Parse a standard EPSG:4326 WKT string and inspect the result:
- Parse a Proj4 string by passing
string_type="PROJ4": - Parse an EPSG:3857 WKT and confirm the axis order is projected:
Source code in src/pyramids/base/crs.py
pyramids.base.crs.get_epsg_from_prj(prj)
#
Return the EPSG code identified by a projection string.
Resolves the EPSG of the root CRS object in three steps:
:meth:osr.SpatialReference.AutoIdentifyEPSG (tags recognisable
CRSes), then the root AUTHORITY code, then a confident,
unambiguous :meth:osr.SpatialReference.FindMatches PROJ-database
lookup for well-known CRSes whose WKT lacks a root authority (e.g. a
UTM PROJCS from GDAL's AAIGrid driver). The code of a child
unit/datum node is never returned as if it were a CRS — that bug
(issue #403) made GRIB rasters resolve to the degree-unit EPSG:9122
and UTM ASCII grids to the WGS_1984 datum EPSG:6326.
An empty input string is no longer silently mapped to 4326; that
legacy default masked real configuration errors. Callers that
genuinely want a fallback should handle the CRSError themselves,
or use :func:epsg_from_wkt which accepts an explicit default.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
prj
|
str
|
Projection string. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
The resolved EPSG code. |
Raises:
| Type | Description |
|---|---|
CRSError
|
If |
Examples:
- Resolve EPSG:4326 from its standard WKT representation:
- Resolve EPSG:3857 (Web Mercator) from its WKT representation:
- A well-known CRS whose WKT carries no root authority still resolves, via a confident PROJ-database match (here a "WGS 84 / UTM zone 18N" PROJCS with its root authority stripped):
- A genuinely custom CRS that matches no database entry raises
CRSErrorrather than returning a child unit/datum code (here GDAL's spherical-earth GRIB GEOGCS, whose only authority node is the degree unit EPSG:9122):>>> grib_wkt = ( ... 'GEOGCS["Coordinate System imported from GRIB file",' ... 'DATUM["unnamed",SPHEROID["Sphere",6371229,0]],' ... 'PRIMEM["Greenwich",0],' ... 'UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],' ... 'AXIS["Latitude",NORTH],AXIS["Longitude",EAST]]' ... ) >>> get_epsg_from_prj(grib_wkt) Traceback (most recent call last): ... pyramids.base._errors.CRSError: get_epsg_from_prj could not resolve an EPSG code ... - An empty projection string raises
CRSError(aValueErrorsubclass):
Source code in src/pyramids/base/crs.py
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | |
pyramids.base.crs.epsg_from_wkt(wkt, default=4326)
#
Resolve an EPSG code from a WKT / Proj string with a fallback.
Wraps :func:get_epsg_from_prj to absorb the
get_epsg_from_prj(wkt) if wkt else default idiom that was
previously open-coded in four places across the dataset stack.
Returns default when wkt is empty (or None), and also when
get_epsg_from_prj cannot resolve an EPSG from a non-empty wkt
(it raises :class:CRSError for a custom CRS whose root carries no
EPSG authority — e.g. a spherical-earth GRIB GEOGCS); otherwise
delegates to :func:get_epsg_from_prj.
Use this in places where an empty projection should be treated as
a soft "unknown CRS, assume WGS84" rather than a hard error — for
example the Dataset.epsg property on a freshly-built
in-memory raster that has no projection metadata yet. Use
:func:get_epsg_from_prj directly when you want the strict
behaviour where an empty projection raises.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wkt
|
str
|
Projection string (WKT, ESRI WKT, or Proj4). An empty
string or |
required |
default
|
int
|
EPSG code to return when |
4326
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
EPSG code resolved from |
int
|
empty or its CRS carries no resolvable EPSG. |
Examples:
- Empty input falls back to the supplied default:
- Non-empty WKT delegates to :func:
get_epsg_from_prj: - An unresolvable custom CRS falls back to
defaultinstead of raising (here GDAL's spherical-earth GRIB GEOGCS):>>> from pyramids.base.crs import epsg_from_wkt >>> grib_wkt = ( ... 'GEOGCS["Coordinate System imported from GRIB file",' ... 'DATUM["unnamed",SPHEROID["Sphere",6371229,0]],' ... 'PRIMEM["Greenwich",0],' ... 'UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],' ... 'AXIS["Latitude",NORTH],AXIS["Longitude",EAST]]' ... ) >>> epsg_from_wkt(grib_wkt) 4326 >>> epsg_from_wkt(grib_wkt, default=3857) 3857
Source code in src/pyramids/base/crs.py
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | |
pyramids.base.crs.reproject_coordinates(x, y, *, from_crs=4326, to_crs=3857, precision=6)
#
Reproject parallel x / y coordinate lists between CRSes.
Argument and return order is (x, y) throughout; accepts any
CRS form :meth:pyproj.Transformer.from_crs understands (EPSG
int, EPSG string, WKT, Proj4, :class:pyproj.CRS).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
list[float]
|
X-coordinates in the source CRS (longitudes when
|
required |
y
|
list[float]
|
Y-coordinates in the source CRS (latitudes when
|
required |
from_crs
|
Any
|
Source CRS. Accepts anything
:meth: |
4326
|
to_crs
|
Any
|
Target CRS, same forms as |
3857
|
precision
|
int | None
|
Decimal places to round each returned coordinate to. Pass
|
6
|
Returns:
| Type | Description |
|---|---|
tuple[list[float], list[float]]
|
tuple[list[float], list[float]]: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
CRSError
|
If :meth: |
Examples:
- Reproject a WGS84 point into Web Mercator:
Source code in src/pyramids/base/crs.py
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | |