001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2006-2024 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.feature; 019 020import java.util.Map; 021import java.util.Collections; 022import org.opengis.annotation.UML; 023import org.opengis.annotation.Stereotype; 024import org.opengis.annotation.Classifier; 025import org.opengis.util.GenericName; 026 027import static org.opengis.annotation.Obligation.*; 028import static org.opengis.annotation.Specification.ISO_19109; 029 030 031/** 032 * Definition of an attribute in a feature type. 033 * The name of attribute type is mandatory. The name {@linkplain org.opengis.util.GenericName#scope() scope} 034 * is typically the name of the {@linkplain FeatureType feature type} containing this attribute, but this is 035 * not mandatory. The scope could also be defined by the ontology for example. 036 * 037 * <div class="note"><b>Note:</b> 038 * compared to the Java language, {@code AttributeType} is equivalent to {@link java.lang.reflect.Field} 039 * while {@code FeatureType} is equivalent to {@link Class}.</div> 040 * 041 * <h2>Value type</h2> 042 * Attributes can be used for both spatial and non-spatial properties. 043 * Some examples are: 044 * 045 * <table class="ogc"> 046 * <caption>Attribute value type examples</caption> 047 * <tr><th>Attribute name</th> <th>Value type</th></tr> 048 * <tr><td>Building shape</td> <td>{@link org.opengis.geometry.Geometry}</td></tr> 049 * <tr><td>Building owner</td> <td>{@link org.opengis.metadata.citation.Responsibility}</td></tr> 050 * <tr><td>Horizontal accuracy</td> <td>{@link org.opengis.metadata.quality.PositionalAccuracy}</td></tr> 051 * </table> 052 * 053 * <h2>Attribute characterization</h2> 054 * An {@code Attribute} can be characterized by other attributes. For example, an attribute that carries a measurement 055 * (e.g. air temperature) may have another attribute that holds the measurement accuracy (e.g. ±0.1°C). 056 * Such accuracy can be stored as a <i>characteristic</i> of the measurement attribute. 057 * 058 * <p>The {@link #characteristics()} method in this {@code AttributeType} interface returns a description of all 059 * characteristics that attributes of this type may have. The actual characteristics values can be stored on a 060 * record-by-record basis in the {@link Attribute#characteristics()} map. 061 * However, in the common case of characteristics having a constant value for all records in a dataset, 062 * the constant can be given by the characteristic {@linkplain #getDefaultValue() default value} and 063 * {@code Attribute.characteristics()} may return an empty map (at implementation choice).</p> 064 * 065 * @param <V> the type of attribute values. If the attribute supports multi-occurrences, 066 * then this is the type of elements (not the collection type). 067 * 068 * @author Jody Garnett (Refractions Research) 069 * @author Justin Deoliveira (The Open Planning Project) 070 * @author Martin Desruisseaux (Geomatys) 071 * @version 3.1 072 * @since 3.1 073 * 074 * @see Attribute 075 * @see DynamicAttributeType 076 */ 077@Classifier(Stereotype.METACLASS) 078@UML(identifier="AttributeType", specification=ISO_19109) 079public interface AttributeType<V> extends PropertyType { 080 /** 081 * Returns the name of this attribute type. 082 * For {@code AttributeType}, the name is mandatory. 083 * 084 * @return the attribute type name. 085 */ 086 @Override 087 @UML(identifier="name", obligation=MANDATORY, specification=ISO_19109) 088 GenericName getName(); 089 090 /** 091 * Returns the type of attribute values. 092 * 093 * @return the type of attribute values. 094 */ 095 @UML(identifier="valueType", obligation=MANDATORY, specification=ISO_19109) 096 Class<V> getValueClass(); 097 098 /* 099 * ISO 19109 properties omitted for now: 100 * 101 * - valueDomain : CharacterString 102 * 103 * Rational: a CharacterString is hardly programmatically usable. A Range would be better but too specific. 104 * We could follow the GeoAPI path and define a "restrictions : Filter" property. That would be more generic, 105 * but we are probably better to wait for Filter to be made submitted to a GeoAPI release. 106 */ 107 108 /** 109 * Returns the minimum number of attribute values. 110 * The returned value is greater than or equal to zero. 111 * 112 * <p>To be valid, an {@code Attribute} instance of this {@code AttributeType} shall have at least 113 * this minimum number of elements in its {@link Attribute#getValues() collection of values}.</p> 114 * 115 * @return the minimum number of attribute values. 116 */ 117 @UML(identifier="cardinality", obligation=MANDATORY, specification=ISO_19109) 118 int getMinimumOccurs(); 119 120 /** 121 * Returns the maximum number of attribute values. 122 * The returned value is greater than or equal to the {@link #getMinimumOccurs()} value. 123 * If there is no maximum, then this method returns {@link Integer#MAX_VALUE}. 124 * 125 * <p>To be valid, an {@code Attribute} instance of this {@code AttributeType} shall have no more than 126 * this maximum number of elements in its {@link Attribute#getValues() collection of values}.</p> 127 * 128 * @return the maximum number of attribute values, or {@link Integer#MAX_VALUE} if none. 129 */ 130 @UML(identifier="cardinality", obligation=MANDATORY, specification=ISO_19109) 131 int getMaximumOccurs(); 132 133 /** 134 * Returns the default value for the attribute. 135 * This value is used when an attribute is created and no value for it is specified. 136 * 137 * @return the default value for the attribute, or {@code null} if none. 138 */ 139 V getDefaultValue(); 140 141 /** 142 * Other attribute types that describe this attribute type. 143 * See <cite>Attribute characterization</cite> in class Javadoc for more information. 144 * 145 * <div class="note"><b>Example:</b> 146 * an attribute that carries a measurement (e.g. air temperature) may have another attribute 147 * that holds the measurement accuracy.</div> 148 * 149 * The characteristics are enumerated in the {@linkplain Map#values() map values}. 150 * The {@linkplain Map#keySet() map keys} are the {@code String} representations of 151 * characteristics {@linkplain #getName() name}, for more convenient lookups. 152 * 153 * @return other attribute types that describe this attribute type, or an empty map if none. 154 * 155 * @see Attribute#characteristics() 156 */ 157 @UML(identifier="characterizeBy", obligation=OPTIONAL, specification=ISO_19109) 158 default Map<String,AttributeType<?>> characteristics() { 159 return Collections.emptyMap(); 160 } 161 /* 162 * Note: ISO 19109 also defines the following member 163 * for traversing the association in the opposite way: 164 * 165 * - characterize the attribute type that is described by this attribute type. 166 * 167 * This member has been omitted for now. 168 */ 169 170 /** 171 * Creates a new attribute instance of this type initialized to the {@linkplain #getDefaultValue() default value}. 172 * 173 * @return a new attribute instance. 174 * @throws UnsupportedOperationException if this type does not support new instance creation. 175 */ 176 Attribute<V> newInstance() throws UnsupportedOperationException; 177}