Skip to content

Commit 1ff0c95

Browse files
authored
Merge pull request #1573 from lesserwhirls/gh-1519
Allow center longitude to be set without normalization
2 parents ac95229 + 7128226 commit 1ff0c95

3 files changed

Lines changed: 48 additions & 14 deletions

File tree

cdm/core/src/main/java/ucar/unidata/geoloc/projection/LatLonProjection.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
2-
* Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
5+
56
package ucar.unidata.geoloc.projection;
67

78
import ucar.nc2.constants.CF;
@@ -248,23 +249,59 @@ public double[][] latLonToProj(double[][] from, double[][] to, int latIndex, int
248249

249250

250251
/**
251-
* Set the center of the Longitude range. It is normalized to +/- 180.
252+
* Set the center longitude of this projection, normalizing it into the range [-180, 180].
253+
*
254+
* <p>
252255
* The cylinder is cut at the "seam" = centerLon +- 180.
253256
* Use this to keep the Longitude values kept in the range [centerLon +-180], which
254257
* makes seam handling easier.
258+
* {@link #latLonToProj} returns longitudes in the range
259+
* [{@code centerLon} - 180, {@code centerLon} + 180], so the center longitude controls where the
260+
* seam falls and therefore which longitude values are produced.
261+
*
262+
* <p>
263+
* This method always normalizes the supplied value to [-180, 180], which discards information
264+
* about grids whose longitude coordinates legitimately lie outside that range. To preserve
265+
* such information, use
266+
* {@link #setCenterLon(double, boolean)} with {@code normalize = false}.
255267
*
256-
* @param centerLon the center of the Longitude range.
257-
* @return centerLon normalized to +/- 180.
268+
* @param centerLon the center of the longitude range, in degrees east.
269+
* @return centerLon normalized to [-180, 180].
270+
* @deprecated use {@link #setCenterLon(double, boolean)} with {@code normalize = true}
258271
*/
272+
@Deprecated
259273
public double setCenterLon(double centerLon) {
260-
this.centerLon = LatLonPoints.lonNormal(centerLon);
274+
return setCenterLon(centerLon, true);
275+
}
276+
277+
/**
278+
* Set the center longitude of this projection, optionally normalizing it into the range [-180, 180].
279+
*
280+
* <p>
281+
* The center longitude controls the location of the projection "seam" (at {@code centerLon} +/- 180).
282+
* This also means it controls the range of longitudes returned by the projection. When {@code normalize}
283+
* is {@code false}, the supplied value is stored as given. This allows the projection to
284+
* reproduce grid longitudes that lie outside [-180, 180].
285+
*
286+
* @param centerLon the center of the longitude range, in degrees east.
287+
* @param normalize if {@code true}, normalize {@code centerLon} into [-180, 180]; if {@code false},
288+
* store it unchanged.
289+
* @return the center longitude that was stored.
290+
*/
291+
public double setCenterLon(double centerLon, boolean normalize) {
292+
this.centerLon = normalize ? LatLonPoints.lonNormal(centerLon) : centerLon;
261293
return this.centerLon;
262294
}
263295

264296
/**
265-
* Get the center of the Longitude range. It is normalized to +/- 180.
297+
* Get the center longitude of this projection, in degrees east.
298+
*
299+
* <p>
300+
* Note that this value is normalized to [-180, 180] only if it was set via
301+
* {@link #setCenterLon(double)} (or {@link #setCenterLon(double, boolean)} with
302+
* {@code normalize = true}).
266303
*
267-
* @return the center longitude
304+
* @return the center longitude.
268305
*/
269306
public double getCenterLon() {
270307
return centerLon;

grib/src/main/java/ucar/nc2/grib/grib1/Grib1Gds.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
55

@@ -557,9 +557,7 @@ public String toString() {
557557
public GdsHorizCoordSys makeHorizCoordSys() {
558558
LatLonProjection proj = new LatLonProjection(getEarth());
559559
double centerLon = ((int) ((lo2 - lo1 + deltaLon) / 2 / scale3)) * scale3;
560-
proj.setCenterLon(centerLon);
561-
562-
// ProjectionPoint startP = proj.latLonToProj(LatLonPoint.create(la1, lo1));
560+
proj.setCenterLon(centerLon, false);
563561
double startx = lo1; // startP.getX();
564562
double starty = la1; // startP.getY();
565563
return new GdsHorizCoordSys(getNameShort(), template, 0, scanMode, proj, startx, getDx(), starty, getDy(),

grib/src/main/java/ucar/nc2/grib/grib2/Grib2Gds.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998-2025 John Caron and University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
55

@@ -519,8 +519,7 @@ public int[] getOptionalPoints() {
519519
public GdsHorizCoordSys makeHorizCoordSys() {
520520
LatLonProjection proj = new LatLonProjection(getEarth());
521521
double centerLon = ((int) ((lo2 - lo1 + deltaLon) / 2 / getScale())) * getScale();
522-
proj.setCenterLon(centerLon);
523-
// ProjectionPoint startP = proj.latLonToProj(LatLonPoint.create(la1, lo1));
522+
proj.setCenterLon(centerLon, false);
524523
double startx = lo1; // startP.getX();
525524
double starty = la1; // startP.getY();
526525
return new GdsHorizCoordSys(getNameShort(), template, numberOfDataPoints, scanMode, proj, startx, deltaLon,

0 commit comments

Comments
 (0)