001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2004-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.metadata.identification; 019 020import java.util.ArrayList; 021import java.util.Collection; 022import java.util.Collections; 023import java.util.Iterator; 024import java.time.temporal.TemporalAmount; 025import org.opengis.util.InternationalString; 026import org.opengis.metadata.Identifier; 027import org.opengis.metadata.MetadataScope; 028import org.opengis.metadata.citation.Citation; 029import org.opengis.metadata.citation.Responsibility; 030import org.opengis.metadata.citation.ResponsibleParty; 031import org.opengis.metadata.spatial.SpatialRepresentationType; 032import org.opengis.metadata.maintenance.MaintenanceInformation; 033import org.opengis.metadata.maintenance.ScopeCode; 034import org.opengis.metadata.constraint.Constraints; 035import org.opengis.metadata.distribution.Format; 036import org.opengis.metadata.extent.Extent; 037import org.opengis.annotation.UML; 038import org.opengis.annotation.Profile; 039import org.opengis.annotation.Classifier; 040import org.opengis.annotation.Stereotype; 041 042import static org.opengis.annotation.Obligation.*; 043import static org.opengis.annotation.Specification.*; 044import static org.opengis.annotation.ComplianceLevel.*; 045 046 047/** 048 * Basic information required to uniquely identify a resource or resources. 049 * 050 * @author Martin Desruisseaux (IRD) 051 * @author Cory Horner (Refractions Research) 052 * @version 3.1 053 * @since 2.0 054 */ 055@Classifier(Stereotype.ABSTRACT) 056@UML(identifier="MD_Identification", specification=ISO_19115) 057public interface Identification { 058 /** 059 * Citation for the resource. 060 * 061 * @return citation for the resource. 062 */ 063 @Profile(level=CORE) 064 @UML(identifier="citation", obligation=MANDATORY, specification=ISO_19115) 065 Citation getCitation(); 066 067 /** 068 * Brief narrative summary of the resource. 069 * 070 * @return brief narrative summary of the resource. 071 */ 072 @Profile(level=CORE) 073 @UML(identifier="abstract", obligation=MANDATORY, specification=ISO_19115) 074 InternationalString getAbstract(); 075 076 /** 077 * Summary of the intentions with which the resource was developed. 078 * 079 * @return the intentions with which the resource was developed, or {@code null}. 080 */ 081 @UML(identifier="purpose", obligation=OPTIONAL, specification=ISO_19115) 082 default InternationalString getPurpose() { 083 return null; 084 } 085 086 /** 087 * Recognition of those who contributed to the resource. 088 * 089 * <div class="warning"><b>Upcoming API change — internationalization</b><br> 090 * The return type will be changed to {@code Collection<? extends InternationalString>} in GeoAPI 4.0. 091 * </div> 092 * 093 * @return recognition of those who contributed to the resource. 094 */ 095 @UML(identifier="credit", obligation=OPTIONAL, specification=ISO_19115) 096 default Collection<String> getCredits() { 097 return Collections.emptyList(); 098 } 099 100 /** 101 * Status of the resource. 102 * 103 * @return status of the resource. 104 */ 105 @UML(identifier="status", obligation=OPTIONAL, specification=ISO_19115) 106 default Collection<Progress> getStatus() { 107 return Collections.emptySet(); // Use Set instead of List for hash-safe final classes. 108 } 109 110 /** 111 * Identification of, and means of communication with, person(s) and organisations 112 * associated with the resource(s). 113 * 114 * <div class="warning"><b>Upcoming API change — generalization</b><br> 115 * As of ISO 19115:2014, {@code ResponsibleParty} is replaced by the {@link Responsibility} parent interface. 116 * This change may be applied in GeoAPI 4.0. 117 * </div> 118 * 119 * @return means of communication with person(s) and organisations(s) associated with the resource. 120 * 121 * @see org.opengis.metadata.Metadata#getContacts() 122 */ 123 @Profile(level=CORE) 124 @UML(identifier="pointOfContact", obligation=OPTIONAL, specification=ISO_19115, version=2003) 125 default Collection<? extends ResponsibleParty> getPointOfContacts() { 126 return Collections.emptyList(); 127 } 128 129 /** 130 * Methods used to spatially represent geographic information. 131 * 132 * @return methods used to spatially represent geographic information. 133 * 134 * @since 3.1 135 */ 136 @UML(identifier="spatialRepresentationType", obligation=OPTIONAL, specification=ISO_19115) 137 default Collection<SpatialRepresentationType> getSpatialRepresentationTypes() { 138 return Collections.emptySet(); // Use Set instead of List for hash-safe final classes. 139 } 140 141 /** 142 * Factor which provides a general understanding of the density of spatial data in the resource. 143 * May also describe the range of resolutions in which a digital resource may be used. 144 * 145 * <div class="note"><b>Note:</b> 146 * this element should be repeated when describing upper and lower range. 147 * </div> 148 * 149 * @return factor which provides a general understanding of the density of spatial resource. 150 * 151 * @since 3.1 152 */ 153 @Profile(level=CORE) 154 @UML(identifier="spatialResolution", obligation=OPTIONAL, specification=ISO_19115) 155 default Collection<? extends Resolution> getSpatialResolutions() { 156 return Collections.emptyList(); 157 } 158 159 /** 160 * Smallest resolvable temporal period in a resource. 161 * 162 * @return smallest resolvable temporal period in a resource. 163 * 164 * @departure integration 165 * The type defined by ISO 19115 is {@code TM_Duration}, an interface defined by ISO 19108. 166 * That ISO type can be mapped to the {@link java.time.Period} or {@link java.time.Duration} 167 * classes from the standard Java library. 168 * 169 * @since 3.1 170 */ 171 @UML(identifier="temporalResolution", obligation=OPTIONAL, specification=ISO_19115) 172 default Collection<? extends TemporalAmount> getTemporalResolutions() { 173 return Collections.emptyList(); 174 } 175 176 /** 177 * Main theme(s) of the resource. 178 * 179 * @return main theme(s). 180 * 181 * @condition Mandatory if {@link MetadataScope#getResourceScope()} equals {@link ScopeCode#DATASET} 182 * or {@link ScopeCode#SERIES}. 183 * 184 * @since 3.1 185 */ 186 @Profile(level=CORE) 187 @UML(identifier="topicCategory", obligation=CONDITIONAL, specification=ISO_19115) 188 Collection<TopicCategory> getTopicCategories(); 189 190 /** 191 * Spatial and temporal extent of the resource. 192 * 193 * @return spatial and temporal extent of the resource. 194 * 195 * @condition Mandatory with either a 196 * {@linkplain org.opengis.metadata.extent.GeographicBoundingBox geographic bounding box} or a 197 * {@linkplain org.opengis.metadata.extent.GeographicDescription geographic description} if 198 * {@link MetadataScope#getResourceScope()} equals {@link ScopeCode#DATASET} or {@link ScopeCode#SERIES}. 199 * 200 * @since 3.1 201 */ 202 @Profile(level=CORE) 203 @UML(identifier="extent", obligation=CONDITIONAL, specification=ISO_19115) 204 Collection<? extends Extent> getExtents(); 205 206 /** 207 * Other documentation associated with the resource. 208 * 209 * <div class="note"><b>Example:</b> 210 * related articles, publications, user guides, data dictionaries. 211 * </div> 212 * 213 * @return other documentation associated with the resource. 214 * 215 * @since 3.1 216 */ 217 @UML(identifier="additionalDocumentation", obligation=OPTIONAL, specification=ISO_19115) 218 default Collection<? extends Citation> getAdditionalDocumentations() { 219 return Collections.emptyList(); 220 } 221 222 /** 223 * Code that identifies the level of processing in the producers coding system of a resource. 224 * 225 * <div class="note"><b>Example:</b> 226 * NOAA level 1B. 227 * </div> 228 * 229 * @return code that identifies the level of processing in the producers coding system of a resource. 230 * 231 * @since 3.1 232 * 233 * @see org.opengis.metadata.content.CoverageDescription#getProcessingLevelCode() 234 */ 235 @UML(identifier="processingLevel", obligation=OPTIONAL, specification=ISO_19115) 236 default Identifier getProcessingLevel() { 237 return null; 238 } 239 240 /** 241 * Information about the frequency of resource updates, and the scope of those updates. 242 * 243 * @return frequency and scope of resource updates. 244 */ 245 @UML(identifier="resourceMaintenance", obligation=OPTIONAL, specification=ISO_19115) 246 default Collection<? extends MaintenanceInformation> getResourceMaintenances() { 247 return Collections.emptyList(); 248 } 249 250 /** 251 * Graphic that illustrates the resource(s) (should include a legend for the graphic). 252 * 253 * @return a graphic that illustrates the resource(s). 254 */ 255 @UML(identifier="graphicOverview", obligation=OPTIONAL, specification=ISO_19115) 256 default Collection<? extends BrowseGraphic> getGraphicOverviews() { 257 return Collections.emptyList(); 258 } 259 260 /** 261 * Description of the format of the resource(s). 262 * 263 * @return description of the format. 264 * 265 * @see org.opengis.metadata.distribution.Distribution#getDistributionFormats() 266 */ 267 @UML(identifier="resourceFormat", obligation=OPTIONAL, specification=ISO_19115) 268 default Collection<? extends Format> getResourceFormats() { 269 return Collections.emptyList(); 270 } 271 272 /** 273 * Category keywords, their type, and reference source. 274 * 275 * @return category keywords, their type, and reference source. 276 */ 277 @UML(identifier="descriptiveKeywords", obligation=OPTIONAL, specification=ISO_19115) 278 default Collection<? extends Keywords> getDescriptiveKeywords() { 279 return Collections.emptyList(); 280 } 281 282 /** 283 * Basic information about specific application(s) for which the resource(s) 284 * has/have been or is being used by different users. 285 * 286 * @return information about specific application(s) for which the resource(s) 287 * has/have been or is being used. 288 */ 289 @UML(identifier="resourceSpecificUsage", obligation=OPTIONAL, specification=ISO_19115) 290 default Collection<? extends Usage> getResourceSpecificUsages() { 291 return Collections.emptyList(); 292 } 293 294 /** 295 * Information about constraints which apply to the resource(s). 296 * 297 * @return constraints which apply to the resource(s). 298 */ 299 @UML(identifier="resourceConstraints", obligation=OPTIONAL, specification=ISO_19115) 300 default Collection<? extends Constraints> getResourceConstraints() { 301 return Collections.emptyList(); 302 } 303 304 /** 305 * Associated resource information. 306 * 307 * @return associated resource information. 308 * 309 * @since 3.1 310 */ 311 @UML(identifier="associatedResource", obligation=OPTIONAL, specification=ISO_19115) 312 default Collection<? extends AssociatedResource> getAssociatedResources() { 313 return Collections.emptyList(); 314 } 315 316 /** 317 * Aggregate dataset information. 318 * 319 * @return aggregate dataset information. 320 * 321 * @deprecated As of ISO 19115:2014, replaced by {@link #getAssociatedResources()}. 322 */ 323 @Deprecated(since="3.1") 324 @UML(identifier="aggregationInfo", obligation=OPTIONAL, specification=ISO_19115, version=2003) 325 default Collection<? extends AggregateInformation> getAggregationInfo() { 326 ArrayList<AggregateInformation> info = new ArrayList<>(); 327 for (final AssociatedResource res : getAssociatedResources()) { 328 info.add(new AggregateInformation() { 329 @Override public Citation getName() {return res.getName();} 330 @Override public AssociationType getAssociationType() {return res.getAssociationType();} 331 @Override public InitiativeType getInitiativeType() {return res.getInitiativeType();} 332 @Override public Citation getMetadataReference() {return res.getMetadataReference();} 333 @Override public Citation getAggregateDataSetName() {return res.getName();} 334 @Override public Identifier getAggregateDataSetIdentifier() { 335 Citation name = res.getName(); 336 if (name != null) { 337 Iterator<? extends Identifier> it = name.getIdentifiers().iterator(); 338 if (it.hasNext()) return it.next(); 339 } 340 return null; 341 } 342 }); 343 } 344 return info; 345 } 346}