Issue #1279 change GridCoverage to choose more reasonable longitude ranges, use a 0 central meridian for huge grids to avoid normalization in geotools, fix intersections in GridGeometryProjections to work for unnormalized areas, fix data wrapper world wrap detection to work for any crs which doesn't normalize.
Former-commit-id:9bef14fdb1
[formerlyaac3144f51
] [formerly2f7a04f8ef
] [formerlye3cc30e8a8
[formerly2f7a04f8ef
[formerly 908b9ec666e5dfb50ef4fe3899bf2288bf4cecc5]]] Former-commit-id:e3cc30e8a8
Former-commit-id: f7f14001910f26e749c9069418cd703088ba92a9 [formerlya67d5e2b6c
] Former-commit-id:6748ebb4ec
This commit is contained in:
parent
2244937369
commit
b7f3492c1a
4 changed files with 50 additions and 11 deletions
|
@ -595,6 +595,20 @@ public abstract class GridCoverage extends PersistableDataObject implements
|
|||
maxLon -= 1.0E-12;
|
||||
minLon += 1.0E-12;
|
||||
}
|
||||
|
||||
// Normalize the range by shifting 360 degrees to bring the range
|
||||
// within +/-360 degree as much as possible. For example the
|
||||
// Canadian-NH model gets calculated as 179.7 to 540.3 but it
|
||||
// works better to use -180.3 to 180.3.
|
||||
while (minLon > 0 && maxLon > 360) {
|
||||
minLon -= 360;
|
||||
maxLon -= 360;
|
||||
}
|
||||
// Normalize the low end.
|
||||
while (minLon < -360 && maxLon < 0) {
|
||||
minLon += 360;
|
||||
maxLon += 360;
|
||||
}
|
||||
try {
|
||||
geometry = MapUtil.createGeometry(minLat, minLon, maxLat,
|
||||
maxLon);
|
||||
|
@ -743,7 +757,8 @@ public abstract class GridCoverage extends PersistableDataObject implements
|
|||
if (isSubGridded()) {
|
||||
String subGridName = getName();
|
||||
int index = subGridName.lastIndexOf(SUBGRID_TOKEN);
|
||||
if (index >= 0 && index + SUBGRID_TOKEN.length() < subGridName.length()) {
|
||||
if (index >= 0
|
||||
&& index + SUBGRID_TOKEN.length() < subGridName.length()) {
|
||||
model = subGridName.substring(index + SUBGRID_TOKEN.length());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,16 @@ public class LatLonGridCoverage extends GridCoverage {
|
|||
double maxLon = minLon + dx * nx;
|
||||
|
||||
double centralMeridian = (minLon + maxLon) / 2.0;
|
||||
if (dx * nx <= 360) {
|
||||
centralMeridian = MapUtil.correctLon(centralMeridian);
|
||||
} else {
|
||||
// For almost all map projections geotools will clip all math
|
||||
// transforms to be within +-180 of the central meridian. For grids
|
||||
// that wrap around the world more than once this is a problem. When
|
||||
// the central Meridian is 0.0 then geotools does not do this
|
||||
// clipping, which works much better.
|
||||
centralMeridian = 0.0;
|
||||
}
|
||||
crs = MapUtil.constructEquidistantCylindrical(
|
||||
MapUtil.AWIPS_EARTH_RADIUS, MapUtil.AWIPS_EARTH_RADIUS,
|
||||
centralMeridian, 0);
|
||||
|
|
|
@ -385,11 +385,28 @@ public class MapUtil {
|
|||
LATLON_PROJECTION, false);
|
||||
ReferencedEnvelope newTargetREnv = targetREnv.transform(
|
||||
LATLON_PROJECTION, false);
|
||||
|
||||
com.vividsolutions.jts.geom.Envelope intersection = newTargetREnv
|
||||
.intersection(newSourceEnv);
|
||||
// Its possible to get two envelopes that don't intersect in a common
|
||||
// space, for example one could have longitude from -200 to -160 and
|
||||
// another could have longitude from 160 to 200. Even though these are
|
||||
// the same range, they don't intersect. These two loops will shift the
|
||||
// data 360 degrees in the x direction until all intersections are
|
||||
// found.
|
||||
while (newSourceEnv.getMaxX() > newTargetREnv.getMinX()) {
|
||||
newSourceEnv.translate(-360, 0);
|
||||
intersection.expandToInclude(newTargetREnv
|
||||
.intersection(newSourceEnv));
|
||||
}
|
||||
while (newSourceEnv.getMinX() < newTargetREnv.getMaxX()) {
|
||||
newSourceEnv.translate(360, 0);
|
||||
intersection.expandToInclude(newTargetREnv
|
||||
.intersection(newSourceEnv));
|
||||
}
|
||||
// Get the newEnvelope
|
||||
ReferencedEnvelope newEnv = new ReferencedEnvelope(JTS.getEnvelope2D(
|
||||
newTargetREnv.intersection(newSourceEnv), LATLON_PROJECTION),
|
||||
LATLON_PROJECTION);
|
||||
intersection, LATLON_PROJECTION), LATLON_PROJECTION);
|
||||
|
||||
newEnv = newEnv.transform(targetCRS, false, 500);
|
||||
// Calculate nx and ny, start with the number of original grid
|
||||
// points in the intersection and then adjust to the new aspect
|
||||
|
|
|
@ -27,8 +27,6 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
|||
import org.opengis.referencing.datum.PixelInCell;
|
||||
import org.opengis.referencing.operation.MathTransform;
|
||||
|
||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* Abstract class for any data implementation that can act as both a source and
|
||||
|
@ -138,8 +136,8 @@ public abstract class AbstractDataWrapper implements DataSource,
|
|||
grid2crs.transform(corner2, corner2);
|
||||
crs2LatLon.transform(corner1, corner1);
|
||||
crs2LatLon.transform(corner2, corner2);
|
||||
corner1.x = MapUtil.correctLon(corner1.x);
|
||||
corner2.x = MapUtil.correctLon(corner2.x);
|
||||
corner1.x = corner1.x - 360;
|
||||
corner2.x = corner2.x - 360;
|
||||
crs2LatLon.inverse().transform(corner1, corner1);
|
||||
crs2LatLon.inverse().transform(corner2, corner2);
|
||||
grid2crs.inverse().transform(corner1, corner1);
|
||||
|
|
Loading…
Add table
Reference in a new issue