| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sis.style.se1; |
| |
| import java.util.Optional; |
| import jakarta.xml.bind.annotation.XmlType; |
| import jakarta.xml.bind.annotation.XmlElement; |
| |
| // Specific to the geoapi-3.1 and geoapi-4.0 branches: |
| import org.opengis.filter.Expression; |
| |
| |
| /** |
| * Information about a channel to use in a multi-spectral source. |
| * Channels are identified by data-dependent character identifiers. |
| * Commonly, channels will be labelled as "1", "2", <i>etc</i>. |
| * A set of selected channels is contained in {@link ChannelSelection}. |
| * |
| * <!-- Following list of authors contains credits to OGC GeoAPI 2 contributors. --> |
| * @author Ian Turton (CCG) |
| * @author Johann Sorel (Geomatys) |
| * @author Martin Desruisseaux (Geomatys) |
| * |
| * @param <R> the type of data to style, such as {@code Feature} or {@code Coverage}. |
| */ |
| @XmlType(name = "SelectedChannelType", propOrder = { |
| "sourceChannelName", |
| "contrastEnhancement" |
| }) |
| // No root element is specified in OGC 05-077r4. |
| public class SelectedChannel<R> extends StyleElement<R> { |
| /** |
| * The channel's name, or {@code null} if unspecified. |
| * |
| * @see #getSourceChannelName() |
| * @see #setSourceChannelName(Expression) |
| * |
| * @todo Needs an adapter from expression to plain string. |
| */ |
| @XmlElement(name = "SourceChannelName", required = true) |
| protected Expression<R,String> sourceChannelName; |
| |
| /** |
| * Contrast enhancement applied to the selected channel in isolation, or {@code null} if none. |
| * |
| * @see #getContrastEnhancement() |
| * @see #setContrastEnhancement(ContrastEnhancement) |
| */ |
| @XmlElement(name = "ContrastEnhancement") |
| protected ContrastEnhancement<R> contrastEnhancement; |
| |
| /** |
| * For JAXB unmarshalling only. |
| */ |
| private SelectedChannel() { |
| // Thread-local factory will be used. |
| } |
| |
| /** |
| * Creates an initially empty selected channel. |
| * |
| * @param factory the factory to use for creating expressions and child elements. |
| */ |
| public SelectedChannel(final StyleFactory<R> factory) { |
| super(factory); |
| } |
| |
| /** |
| * Creates a shallow copy of the given object. |
| * For a deep copy, see {@link #clone()} instead. |
| * |
| * @param source the object to copy. |
| */ |
| public SelectedChannel(final SelectedChannel<R> source) { |
| super(source); |
| sourceChannelName = source.sourceChannelName; |
| contrastEnhancement = source.contrastEnhancement; |
| } |
| |
| /** |
| * Returns the channel's name. |
| * |
| * @return the channel's name, or {@code null} if unspecified. |
| * |
| * @todo Shall never be {@code null}. We need to think about some default value. |
| */ |
| public Expression<R,String> getSourceChannelName() { |
| return sourceChannelName; |
| } |
| |
| /** |
| * Sets the channel's name. |
| * |
| * @param value the channel's name, or {@code null} if unspecified. |
| */ |
| public void setSourceChannelName(final Expression<R,String> value) { |
| sourceChannelName = value; |
| } |
| |
| /** |
| * Returns the contrast enhancement applied to the selected channel in isolation. |
| * The returned object is <em>live</em>: |
| * changes in the returned instance will be reflected in this stroke, and conversely. |
| * |
| * @return contrast enhancement for the selected channel. |
| * |
| * @see RasterSymbolizer#getContrastEnhancement() |
| */ |
| public Optional<ContrastEnhancement<R>> getContrastEnhancement() { |
| return Optional.ofNullable(contrastEnhancement); |
| } |
| |
| /** |
| * Sets the contrast enhancement applied to the selected channel in isolation. |
| * The given instance is stored by reference, it is not cloned. |
| * If this method is never invoked, then the default value is absence. |
| * |
| * @param value new contrast enhancement, or {@code null} if none. |
| * |
| * @see RasterSymbolizer#setContrastEnhancement(ContrastEnhancement) |
| */ |
| public void setContrastEnhancement(final ContrastEnhancement<R> value) { |
| contrastEnhancement = value; |
| } |
| |
| /** |
| * Returns all properties contained in this class. |
| * This is used for {@link #equals(Object)} and {@link #hashCode()} implementations. |
| */ |
| @Override |
| final Object[] properties() { |
| return new Object[] {sourceChannelName, contrastEnhancement}; |
| } |
| |
| /** |
| * Returns a deep clone of this object. All style elements are cloned, |
| * but expressions are not on the assumption that they are immutable. |
| * |
| * @return deep clone of all style elements. |
| */ |
| @Override |
| public SelectedChannel<R> clone() { |
| final var clone = (SelectedChannel<R>) super.clone(); |
| clone.selfClone(); |
| return clone; |
| } |
| |
| /** |
| * Clones the mutable style fields of this element. |
| */ |
| private void selfClone() { |
| if (contrastEnhancement != null) { |
| contrastEnhancement = contrastEnhancement.clone(); |
| } |
| } |
| } |