package org.geotools.coverage.io.impl.range; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.measure.Measure; import javax.measure.converter.UnitConverter; import javax.measure.quantity.Length; import javax.measure.unit.SI; import javax.measure.unit.Unit; import org.geotools.coverage.io.range.Axis; import org.geotools.feature.NameImpl; import org.geotools.referencing.crs.DefaultEngineeringCRS; import org.geotools.referencing.cs.DefaultCoordinateSystemAxis; import org.geotools.referencing.cs.DefaultLinearCS; import org.geotools.referencing.datum.DefaultEngineeringDatum; import org.geotools.util.SimpleInternationalString; import org.opengis.feature.type.Name; import org.opengis.referencing.crs.SingleCRS; import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.cs.CoordinateSystemAxis; import org.opengis.referencing.datum.EngineeringDatum; import org.opengis.util.InternationalString; public class WavelengthAxis<V> implements Axis<V,Length>{ /** * A single band. */ public static class Band extends Measure<Double,Length>{ private static final long serialVersionUID = -4651829687224844766L; private String description; private double minValue; private double maxValue; private String name; Band( String band, double value, String description ){ this.name = band; this.minValue = value; this.maxValue = value; this.description = description; } Band( String band, double from, double to, String description ) { this.name = band; this.minValue = from; this.maxValue = to; this.description = description; } @Override public double doubleValue(Unit<Length> length) { UnitConverter converter = SI.MICRO(SI.METER).getConverterTo( length ); return converter.convert( getValue() ); } @Override public Unit<Length> getUnit() { return SI.NANO(SI.METER); } @Override public java.lang.Double getValue() { return (minValue + maxValue) / 2.0; } public String getName(){ return name; } public String getDescription(){ return description; } @Override public Measure<java.lang.Double, Length> to(Unit<Length> length) { return Measure.valueOf( doubleValue(length), length ); } } /** Violet light between 380-450 nm */ public static final Band COLOR_VIOLET = new Band( "Violet", 380, 450, "Visible light between 380-450 nm" ); /** Blue light between 450-495 nm */ public static final Band COLOR_BLUE = new Band( "Blue", 450, 495, "Visible light between 450-495 nm" ); /** Green light between 495-570 nm */ public static final Band COLOR_GREEN = new Band( "Green", 495, 570, "Visible light between 495-570 nm" ); /** Yellow between 570-590 nm */ public static final Band COLOR_YELLOW = new Band( "Yellow", 570,590, "Visible light between 570-590 nm" ); /** Orange light between 590-620 nm */ public static final Band COLOR_ORANGE = new Band( "Green", 590,620, "Visible light between 590-620 nm" ); /** Red between 620-750 nm */ public static final Band COLOR_RED = new Band( "Yellow", 620, 750, "Visible light between 620-750 nm" ); /** LANDSAT7 definition of BLUE */ public static final Band BLUE = new Band( "BLUE", 450, 520, "useful for soil/vegetation discrimination, forest type mapping, and identifying man-made features"); /** LANDSAT7 definition of GREEN */ public static final Band GREEN = new Band( "GREEN", 520, 610, "penetrates clear water fairly well, and gives excellent contrast between clear and turbid (muddy) water."); /** LANDSAT7 definition of RED */ public static final Band RED = new Band("RED", 630, 690, "useful for identifying vegetation types, soils, and urban (city and town) features"); /** LANDSAT7 definition of NIR */ public static final Band NIR = new Band("NIR", 750, 900, " good for mapping shorelines and biomass content"); /** LANDSAT7 definition of SWIR */ public static final Band SWIR = new Band("SWIR", 1550, 17560, "useful to measure the moisture content of soil and vegetation"); /** LANDSAT7 definition of TIR */ public static final Band TIR = new Band("TIR", 10400, 12500, "useful to observe temperature"); /** LANDSAT7 definition of SWIR2 */ public static final Band SWIR2 = new Band("SWIR2", 2080, 23500, "useful to measure the moisture content of soil and vegetation"); /** * Keys for this {@link Axis}. */ private ArrayList<Measure<V, Length>> keys; private NameImpl name; /** * Bands associated with RGB images. * <p> * Currently this is defined using COLOR_RED, COLOR_GREEN and COLOR_BLUE. * This definition should be updated to use the standard sRGB definitions. */ public static final WavelengthAxis<Double> RGB; static { final List<Band> RGB_BANDS = new ArrayList<Band>(); RGB_BANDS.add( COLOR_RED ); RGB_BANDS.add( COLOR_GREEN ); RGB_BANDS.add( COLOR_BLUE ); RGB = new WavelengthAxis<Double>("RGB-AXIS", RGB_BANDS ); } /** * Bands associated with LANDSAT8 readings. */ public static final WavelengthAxis<Double> LANDSAT7; static { final List<Band> LANDSAT_BANDS = new ArrayList<Band>(); LANDSAT_BANDS.add(WavelengthAxis.BLUE); LANDSAT_BANDS.add(WavelengthAxis.GREEN); LANDSAT_BANDS.add(WavelengthAxis.RED); LANDSAT_BANDS.add(WavelengthAxis.NIR); LANDSAT_BANDS.add(WavelengthAxis.SWIR); LANDSAT_BANDS.add(WavelengthAxis.TIR); LANDSAT_BANDS.add(WavelengthAxis.SWIR2); LANDSAT7 = new WavelengthAxis<Double>("LANDSAT7-AXIS", LANDSAT_BANDS); } private static final DefaultEngineeringCRS CRS; static { CoordinateSystemAxis csAxis = new DefaultCoordinateSystemAxis( new SimpleInternationalString("Light"), "\u03BB", // LAMBDA AxisDirection.OTHER, SI.MICRO(SI.METER)); DefaultLinearCS lightCS = new DefaultLinearCS("Light",csAxis); Map<String,Object> datumProperties = new HashMap<String,Object>(); datumProperties.put("name", "light"); EngineeringDatum lightDatum = new DefaultEngineeringDatum( datumProperties ); CRS = new DefaultEngineeringCRS("Wave Length", lightDatum, lightCS ); } public WavelengthAxis(String name, final List<? extends Measure<V, Length>> keys) { this.keys= new ArrayList<Measure<V, Length>>(keys); this.name= new NameImpl(name); } /** * These are units of length; as such the are * not restricted to a coordinate reference system. */ public SingleCRS getCoordinateReferenceSystem() { return CRS; } public InternationalString getDescription() { return new SimpleInternationalString("Spectral Information"); } public Measure<V, Length> getKey(int keyIndex) { return this.keys.get(keyIndex); } public List<Measure<V, Length>> getKeys() { return Collections.unmodifiableList(keys); } public Name getName() { return name; } public int getNumKeys() { return keys.size(); } public Unit<Length> getUnitOfMeasure() { return SI.MICRO(SI.METER); } }