@@ -494,6 +494,8 @@ def from_transform(
494494 height : int ,
495495 x_dim : str = "x" ,
496496 y_dim : str = "y" ,
497+ x_coord_name : str = "xc" ,
498+ y_coord_name : str = "yc" ,
497499 crs : CRS | Any | None = None ,
498500 ) -> RasterIndex :
499501 """Create a RasterIndex from an affine transform and raster dimensions.
@@ -507,10 +509,14 @@ def from_transform(
507509 Number of pixels in the x direction.
508510 height : int
509511 Number of pixels in the y direction.
510- x_dim : str, default "x"
512+ x_dim : str, optional
511513 Name for the x dimension.
512- y_dim : str, default "y"
514+ y_dim : str, optional
513515 Name for the y dimension.
516+ x_coord_name : str, optional
517+ Name for the x dimension. For non-rectilinear transforms only.
518+ y_coord_name : str, optional
519+ Name for the y dimension. For non-rectilinear transforms only.
514520 crs : :class:`pyproj.crs.CRS` or any, optional
515521 The coordinate reference system. Any value accepted by
516522 :meth:`pyproj.crs.CRS.from_user_input`.
@@ -533,21 +539,35 @@ def from_transform(
533539 >>> from affine import Affine
534540 >>> transform = Affine(1.0, 0.0, 0.0, 0.0, -1.0, 100.0)
535541 >>> index = RasterIndex.from_transform(transform, width=100, height=100)
542+
543+ Create a non-rectilinear index:
544+
545+ >>> index = RasterIndex.from_transform(
546+ ... Affine.rotation(45), width=100, height=100, x_coord_name="x1", y_coord_name="x2"
547+ ... )
536548 """
537549 index : WrappedIndex
538550
539551 # pixel centered coordinates
540552 affine = affine * Affine .translation (0.5 , 0.5 )
541553
542554 if affine .is_rectilinear and affine .b == affine .d == 0 :
543- x_transform = AxisAffineTransform (affine , width , "x" , x_dim , is_xaxis = True )
544- y_transform = AxisAffineTransform (affine , height , "y" , y_dim , is_xaxis = False )
555+ x_transform = AxisAffineTransform (affine , width , x_dim , x_dim , is_xaxis = True )
556+ y_transform = AxisAffineTransform (affine , height , y_dim , y_dim , is_xaxis = False )
545557 index = (
546558 AxisAffineTransformIndex (x_transform ),
547559 AxisAffineTransformIndex (y_transform ),
548560 )
549561 else :
550- xy_transform = AffineTransform (affine , width , height , x_dim = x_dim , y_dim = y_dim )
562+ xy_transform = AffineTransform (
563+ affine ,
564+ width ,
565+ height ,
566+ x_dim = x_dim ,
567+ y_dim = y_dim ,
568+ x_coord_name = x_coord_name ,
569+ y_coord_name = y_coord_name ,
570+ )
551571 index = CoordinateTransformIndex (xy_transform )
552572
553573 return cls (index , crs = crs )
@@ -568,6 +588,18 @@ def create_variables(self, variables: Mapping[Any, Variable] | None = None) -> d
568588 for index in self ._wrapped_indexes :
569589 new_variables .update (index .create_variables ())
570590
591+ if self .crs is not None :
592+ xname , yname = self .xy_coord_names
593+ xattrs , yattrs = self .crs .cs_to_cf ()
594+ if "axis" in xattrs and "axis" in yattrs :
595+ # The axis order is defined by the projection
596+ # So we have to figure which is which.
597+ # This is an ugly hack that works for common cases.
598+ if xattrs ["axis" ] == "Y" :
599+ xattrs , yattrs = yattrs , xattrs
600+ new_variables [xname ].attrs = xattrs
601+ new_variables [yname ].attrs = yattrs
602+
571603 return new_variables
572604
573605 @property
0 commit comments