CRSUtility { public static CoordinateReferenceSystem getCRSFromGridCoordSystem(GridCoordSystem gcs) { ProjectionImpl projection = gcs.getProjection(); if (projection == null) { return DefaultGeographicCRS.WGS84; } Map<String, Parameter> parameterMap = new HashMap<String, Parameter>(); for (Parameter p : projection.getProjectionParameters()) { parameterMap.put(p.getName(), p); } GeodeticDatum datum = generateGeodeticDatum(parameterMap); Parameter gridMappingNameParameter = parameterMap.get("grid_mapping_name"); String gridMappingName = gridMappingNameParameter == null ? "LatLon" : gridMappingNameParameter.getStringValue(); GeographicCRS geographicCRS = (datum == DefaultGeodeticDatum.WGS84) ? DefaultGeographicCRS.WGS84 : new DefaultGeographicCRS( "CF-Derived Geographic CRS", datum, DefaultEllipsoidalCS.GEODETIC_2D); if ("LatLon".equals(gridMappingName) || "latitude_longitude".equals(gridMappingName)) { ProjectionRect projectionRect = gcs.getBoundingBox(); boolean longitude360 = projectionRect.getMaxX() > 180; if (longitude360) { Map<String, Object> crsPoperties = new HashMap<String, Object>(); crsPoperties.put(IdentifiedObject.NAME_KEY, "CRS LON [0,360]"); ExtentImpl extent = new ExtentImpl(); List<GeographicExtent> extentList = new ArrayList<GeographicExtent>(); extentList.add(new GeographicBoundingBoxImpl(0, 360, -90, 90)); extent.setGeographicElements(extentList); crsPoperties.put(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY, extent); return new DefaultDerivedCRS( "CF-Derived CRS LON [0,360]", geographicCRS, longitudeCenter180Modulo360Transform, DefaultEllipsoidalCS.GEODETIC_2D); } else { return geographicCRS; } } try { Unit<Length> axisLengthUnit = generateAxisLengthUnit(gcs); DefaultMathTransformFactory transformFactory = new DefaultMathTransformFactory(); ParameterValueGroup parameterGroup = null; if ("albers_conical_equal_area".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Albers_Conic_Equal_Area"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_central_meridian", "longitude_of_center"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_center"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferStandardParallels(); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("azimuthal_equidistant".equals(gridMappingName)) { throw new RuntimeException("azimuthal_equidistant projection is not supported"); } else if ("lambert_azimuthal_equal_area".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Lambert_Azimuthal_Equal_Area"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_projection_origin", "longitude_of_center"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_center"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("lambert_conformal_conic".equals(gridMappingName)) { boolean is2SP = ProjectionParameterAdapter.getStandardParallelCount(parameterMap) == 2; parameterGroup = is2SP ? transformFactory.getDefaultParameters("Lambert_Conformal_Conic_2SP") : transformFactory.getDefaultParameters("Lambert_Conformal_Conic_1SP"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_central_meridian", "central_meridian"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_origin"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); if (is2SP) { adapter.transferStandardParallels(); } adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("lambert_cylindrical_equal_area".equals(gridMappingName)) { throw new RuntimeException("lambert_cylindrical_equal_area projection is not supported"); } else if ("mercator".equals(gridMappingName)) { boolean is2SP = parameterMap.containsKey("standard_parallel"); parameterGroup = is2SP ? transformFactory.getDefaultParameters("Mercator_2SP") : transformFactory.getDefaultParameters("Mercator_1SP"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_projection_origin", "central_meridian"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); if (is2SP) { adapter.transferStandardParallels(); } else { adapter.transferUnitless("scale_factor_at_projection_origin", "scale_factor"); } adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("orthographic".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Orthographic"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_projection_origin", "central_meridian"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_origin"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("polar_stereographic".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Polar_Stereographic"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("straight_vertical_longitude_from_pole", "central_meridian"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_origin"); adapter.transferUnitless("scale_factor_at_projection_origin", "scale_factor"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferStandardParallels(); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("rotated_latitude_longitude".equals(gridMappingName)) { throw new RuntimeException("rotated_latitude_longitude projection is not supported"); } else if ("stereographic".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Stereographic"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferAngle("longitude_of_projection_origin", "central_meridian"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_origin"); adapter.transferUnitless("scale_factor_at_projection_origin", "scale_factor"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("transverse_mercator".equals(gridMappingName)) { parameterGroup = transformFactory.getDefaultParameters("Transverse_Mercator"); ProjectionParameterAdapter adapter = new ProjectionParameterAdapter(axisLengthUnit, parameterMap, parameterGroup); adapter.transferUnitless("scale_factor_at_central_meridian", "scale_factor"); adapter.transferAngle("longitude_of_central_meridian", "central_meridian"); adapter.transferAngle("latitude_of_projection_origin", "latitude_of_origin"); adapter.transferLength("false_easting", "false_easting"); adapter.transferLength("false_northing", "false_northing"); adapter.transferEllipsoid(datum.getEllipsoid()); } else if ("vertical_perspective".equals(gridMappingName)) { throw new RuntimeException("vertical_perspective projection is not supported"); } if (parameterGroup == null) { throw new RuntimeException("unknown grid_mapping_name"); } CartesianCS cartesianCS = DefaultCartesianCS.PROJECTED.usingUnit(axisLengthUnit); MathTransform transform = transformFactory.createBaseToDerived( geographicCRS, parameterGroup, cartesianCS); if (! (transform instanceof ConcatenatedTransform)) { throw new RuntimeException("Expected instance of ConcatenatedTransform"); } MathTransform wrapped = new ConcatenatedTransformAdapter((ConcatenatedTransform)transform); ProjectedCRS projectedCRS = new DefaultProjectedCRS( "CF-Derived Projected CRS", geographicCRS, wrapped, cartesianCS); return projectedCRS; } catch (NoSuchIdentifierException e) { throw new RuntimeException(e); } catch (FactoryException e) { throw new RuntimeException(e); } }  static CoordinateReferenceSystem getCRSFromGridDatatype(GridDatatype gd); static CoordinateReferenceSystem getCRSFromGridCoordSystem(GridCoordSystem gcs);  }
@Test public void testEllipsoidParametersHaveCorrectOrderOfMagnitude() throws IOException { FeatureDataset fd = FeatureDatasetFactoryManager.open( FeatureType.ANY, "src/test/resources/crs/sleuth.2010.ncml", null, new Formatter(System.err)); if (fd != null && fd instanceof GridDataset) { GridDataset gd = (GridDataset)fd; List<GridDatatype> gdts = gd.getGrids(); assertEquals(1, gdts.size()); CoordinateReferenceSystem crs = CRSUtility.getCRSFromGridCoordSystem(gdts.get(0).getCoordinateSystem()); assertTrue(crs instanceof ProjectedCRS); ProjectedCRS pcrs = (ProjectedCRS)crs; assertEquals(6378137., pcrs.getDatum().getEllipsoid().getSemiMajorAxis(), 0); assertEquals(298.257222101, pcrs.getDatum().getEllipsoid().getInverseFlattening(), 1e-7); assertEquals(SI.METER, pcrs.getDatum().getEllipsoid().getAxisUnit()); } else { fail("Unable to open test dataset."); } }
@Test public void testEarthRadiusIfMissingFromGridMapping() throws IOException { FeatureDataset fd = FeatureDatasetFactoryManager.open( FeatureType.ANY, "src/test/resources/crs/ACFclimBasins.ncml", null, new Formatter(System.err)); if (fd != null && fd instanceof GridDataset) { GridDataset gd = (GridDataset)fd; GridDatatype gdt = gd.findGridDatatype("xppt"); assertNotNull(gdt); GridCoordSystem gcs = gdt.getCoordinateSystem(); assertNotNull(gcs); CoordinateReferenceSystem crs = CRSUtility.getCRSFromGridCoordSystem(gcs); assertNotNull(crs); assertTrue(crs instanceof ProjectedCRS); ProjectedCRS pcrs = (ProjectedCRS)crs; assertEquals(6371229.0, pcrs.getDatum().getEllipsoid().getSemiMajorAxis(), 0); assertEquals(SI.METER, pcrs.getDatum().getEllipsoid().getAxisUnit()); } else { fail("Unable to open test dataset."); } }