/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.ui.crs.projdef; import org.esa.snap.core.util.math.MathUtils; import org.geotools.referencing.ReferencingFactoryFinder; import org.geotools.referencing.cs.DefaultCartesianCS; import org.geotools.referencing.cs.DefaultEllipsoidalCS; import org.geotools.referencing.operation.projection.MapProjection; import org.geotools.referencing.operation.projection.TransverseMercator; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CRSFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.datum.GeodeticDatum; import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.referencing.operation.OperationMethod; import java.util.HashMap; /** * @author Marco Peters * @since BEAM 4.7 */ abstract class AbstractUTMCrsProvider extends AbstractCrsProvider { static final int MIN_UTM_ZONE = 1; static final int MAX_UTM_ZONE = 60; AbstractUTMCrsProvider(String name, boolean hasParameters, boolean datumChangable, GeodeticDatum defaultDatum) { super(name, hasParameters, datumChangable, defaultDatum); } static String getProjectionName(int zoneIndex, boolean south) { return "UTM Zone " + zoneIndex + (south ? ", South" : ""); } static int getZoneIndex(double longitude) { final double zoneIndex = ((longitude + 180.0f) / 6.0f - 0.5f) + 1; return (int)MathUtils.roundAndCrop(zoneIndex, MIN_UTM_ZONE, MAX_UTM_ZONE); } private static void setValue(ParameterValueGroup values, ParameterDescriptor<Double> descriptor, double value) { values.parameter(descriptor.getName().getCode()).setValue(value); } protected static double getCentralMeridian(int zoneIndex) { return (zoneIndex - 0.5) * 6.0 - 180.0; } ParameterValueGroup createTransverseMercatorParameters(int zoneIndex, boolean south, GeodeticDatum datum) { ParameterDescriptorGroup tmParameters = new TransverseMercator.Provider().getParameters(); ParameterValueGroup tmValues = tmParameters.createValue(); setValue(tmValues, MapProjection.AbstractProvider.SEMI_MAJOR, datum.getEllipsoid().getSemiMajorAxis()); setValue(tmValues, MapProjection.AbstractProvider.SEMI_MINOR, datum.getEllipsoid().getSemiMinorAxis()); setValue(tmValues, MapProjection.AbstractProvider.LATITUDE_OF_ORIGIN, 0.0); setValue(tmValues, MapProjection.AbstractProvider.CENTRAL_MERIDIAN, getCentralMeridian(zoneIndex)); setValue(tmValues, MapProjection.AbstractProvider.SCALE_FACTOR, 0.9996); setValue(tmValues, MapProjection.AbstractProvider.FALSE_EASTING, 500000.0); setValue(tmValues, MapProjection.AbstractProvider.FALSE_NORTHING, south ? 10000000.0 : 0.0); return tmValues; } CoordinateReferenceSystem createCrs(String crsName, OperationMethod method, ParameterValueGroup parameters, GeodeticDatum datum) throws FactoryException { final CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null); final CoordinateOperationFactory coFactory = ReferencingFactoryFinder.getCoordinateOperationFactory(null); final HashMap<String, Object> projProperties = new HashMap<String, Object>(); projProperties.put("name", crsName + " / " + datum.getName().getCode()); final Conversion conversion = coFactory.createDefiningConversion(projProperties, method, parameters); final HashMap<String, Object> baseCrsProperties = new HashMap<String, Object>(); baseCrsProperties.put("name", datum.getName().getCode()); final GeographicCRS baseCrs = crsFactory.createGeographicCRS(baseCrsProperties, datum, DefaultEllipsoidalCS.GEODETIC_2D); return crsFactory.createProjectedCRS(projProperties, baseCrs, conversion, DefaultCartesianCS.PROJECTED); } }