001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2008-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.test.metadata; 019 020import org.opengis.metadata.*; 021import org.opengis.metadata.extent.*; 022import org.opengis.geometry.Geometry; 023import org.opengis.test.ValidatorContainer; 024 025import static org.junit.jupiter.api.Assertions.*; 026import static org.opengis.test.Assertions.assertBetween; 027 028 029/** 030 * Validates {@link Extent} and related objects from the {@code org.opengis.metadata.extent} package. 031 * 032 * <p>This class is provided for users wanting to override the validation methods. When the default 033 * behavior is sufficient, the {@link org.opengis.test.Validators} static methods provide a more 034 * convenient way to validate various kinds of objects.</p> 035 * 036 * @author Martin Desruisseaux (Geomatys) 037 * @version 3.1 038 * @since 2.2 039 */ 040public class ExtentValidator extends MetadataValidator { 041 /** 042 * Creates a new validator instance. 043 * 044 * @param container the set of validators to use for validating other kinds of objects 045 * (see {@linkplain #container field javadoc}). 046 */ 047 public ExtentValidator(final ValidatorContainer container) { 048 super(container, "org.opengis.metadata.extent"); 049 } 050 051 /** 052 * For each interface implemented by the given object, invokes the corresponding 053 * {@code validate(…)} method defined in this class (if any). 054 * 055 * @param object the object to dispatch to {@code validate(…)} methods, or {@code null}. 056 * @return number of {@code validate(…)} methods invoked in this class for the given object. 057 */ 058 public int dispatch(final GeographicExtent object) { 059 int n = 0; 060 if (object != null) { 061 if (object instanceof GeographicDescription) {validate((GeographicDescription) object); n++;} 062 if (object instanceof GeographicBoundingBox) {validate((GeographicBoundingBox) object); n++;} 063 if (object instanceof BoundingPolygon) {validate((BoundingPolygon) object); n++;} 064 } 065 return n; 066 } 067 068 /** 069 * Validates the geographic description. 070 * 071 * @param object the object to validate, or {@code null}. 072 */ 073 public void validate(final GeographicDescription object) { 074 if (object == null) { 075 return; 076 } 077 final Identifier identifier = object.getGeographicIdentifier(); 078 mandatory(identifier, "GeographicDescription: must have an identifier."); 079 } 080 081 /** 082 * Validates the bounding polygon. 083 * 084 * @param object the object to validate, or {@code null}. 085 * 086 * @todo Not yet implemented. 087 */ 088 public void validate(final BoundingPolygon object) { 089 if (object == null) { 090 return; 091 } 092 for (final Geometry e : toArray(Geometry.class, object.getPolygons())) { 093 // TODO 094 } 095 } 096 097 /** 098 * Validates the geographic bounding box. 099 * 100 * @param object the object to validate, or {@code null}. 101 */ 102 public void validate(final GeographicBoundingBox object) { 103 if (object == null) { 104 return; 105 } 106 final double west = object.getWestBoundLongitude(); 107 final double east = object.getEastBoundLongitude(); 108 final double south = object.getSouthBoundLatitude(); 109 final double north = object.getNorthBoundLatitude(); 110 assertBetween(-180, +180, west, "GeographicBoundingBox: illegal west bound."); 111 assertBetween(-180, +180, east, "GeographicBoundingBox: illegal east bound."); 112 assertBetween(-90, +90, south, "GeographicBoundingBox: illegal south bound."); 113 assertBetween(-90, +90, north, "GeographicBoundingBox: illegal north bound."); 114 assertFalse(south > north, "GeographicBoundingBox: invalid range of latitudes."); // Accept NaN. 115 /* 116 * Do not require west <= east, as this condition is not specified in ISO 19115. 117 * Some implementations may use west > east for box spanning the anti-meridian. 118 */ 119 } 120 121 /** 122 * Validates the vertical extent. 123 * 124 * @param object the object to validate, or {@code null}. 125 */ 126 public void validate(final VerticalExtent object) { 127 if (object == null) { 128 return; 129 } 130 final Double minimum = object.getMinimumValue(); 131 final Double maximum = object.getMaximumValue(); 132 mandatory(minimum, "VerticalExtent: must have a minimum value."); 133 mandatory(maximum, "VerticalExtent: must have a maximum value."); 134 if (minimum != null && maximum != null) { 135 assertTrue(minimum <= maximum, "VerticalExtent: invalid range."); 136 } 137 container.validate(object.getVerticalCRS()); 138 } 139 140 /** 141 * Validates the temporal extent. 142 * 143 * @param object the object to validate, or {@code null}. 144 * 145 * @todo Validation of temporal primitives not yet implemented. 146 */ 147 public void validate(final TemporalExtent object) { 148 if (object == null) { 149 return; 150 } 151 if (object instanceof SpatialTemporalExtent) { 152 for (final GeographicExtent e : toArray(GeographicExtent.class, ((SpatialTemporalExtent) object).getSpatialExtent())) { 153 dispatch(e); 154 } 155 } 156 } 157 158 /** 159 * Validates the given extent. 160 * 161 * @param object the object to validate, or {@code null}. 162 */ 163 public void validate(final Extent object) { 164 if (object == null) { 165 return; 166 } 167 validateOptional(object.getDescription()); 168 for (GeographicExtent e : toArray(GeographicExtent.class, object.getGeographicElements())) dispatch(e); 169 for (VerticalExtent e : toArray(VerticalExtent .class, object.getVerticalElements ())) validate(e); 170 for (TemporalExtent e : toArray(TemporalExtent .class, object.getTemporalElements ())) validate(e); 171 } 172}