blob: bcc21b7588493bce7366c59171e7001fda1c56c7 [file] [log] [blame]
/*
* 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.feature;
import java.util.Arrays;
import java.util.Map;
import java.util.Collections;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.internal.feature.AttributeConvention;
import org.apache.sis.referencing.crs.HardCodedCRS;
import org.apache.sis.geometry.GeneralEnvelope;
// Test dependencies
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.apache.sis.test.ReferencingAssert.*;
/**
* Tests {@link EnvelopeOperation}.
*
* @author Johann Sorel (Geomatys)
* @version 0.7
* @since 0.7
* @module
*/
@DependsOn(LinkOperationTest.class)
public final strictfp class EnvelopeOperationTest extends TestCase {
/**
* Creates a feature type with a bounds operation.
* The feature contains the following properties:
*
* <ul>
* <li>{@code name} as a {@link String}</li>
* <li>{@code classes} as a {@link Polygon}</li>
* <li>{@code climbing wall} as a {@link Point}</li>
* <li>{@code gymnasium} as a {@link Polygon}</li>
* <li>{@code sis:geometry} as a link to the default geometry</li>
* <li>{@code bounds} as the feature envelope attribute.</li>
* </ul>
*
* @param defaultGeometry 1 for using "classes" as the default geometry, or 3 for "gymnasium".
* @return the feature for a school.
*/
private static DefaultFeatureType school(final int defaultGeometry) throws FactoryException {
final DefaultAttributeType<?> standardCRS = new DefaultAttributeType<>(
name(AttributeConvention.CRS_CHARACTERISTIC), CoordinateReferenceSystem.class, 1, 1, HardCodedCRS.WGS84_φλ);
final DefaultAttributeType<?> normalizedCRS = new DefaultAttributeType<>(
name(AttributeConvention.CRS_CHARACTERISTIC), CoordinateReferenceSystem.class, 1, 1, HardCodedCRS.WGS84);
final AbstractIdentifiedType[] attributes = {
new DefaultAttributeType<>(name("name"), String.class, 1, 1, null),
new DefaultAttributeType<>(name("classes"), Polygon.class, 1, 1, null, standardCRS),
new DefaultAttributeType<>(name("climbing wall"), Point.class, 1, 1, null, standardCRS),
new DefaultAttributeType<>(name("gymnasium"), Polygon.class, 1, 1, null, normalizedCRS),
null,
null
};
attributes[4] = FeatureOperations.link(name(AttributeConvention.GEOMETRY_PROPERTY), attributes[defaultGeometry]);
attributes[5] = FeatureOperations.envelope(name("bounds"), null, attributes);
return new DefaultFeatureType(name("school"), false, null, attributes);
}
/**
* Creates a map of identification properties containing only an entry for the given name.
*/
private static Map<String,?> name(final Object name) {
return Collections.singletonMap(DefaultAttributeType.NAME_KEY, name);
}
/**
* Tests the constructor. The set of attributes on which the operation depends shall include
* "classes", "climbing wall" and "gymnasium" but not "name" since the later does not contain
* a geometry. Furthermore the default CRS shall be {@code HardCodedCRS.WGS84}, not
* {@code HardCodedCRS.WGS84_φλ}, because this test uses "gymnasium" as the default geometry.
*
* @throws FactoryException if an error occurred while searching for the coordinate operations.
*/
@Test
public void testConstruction() throws FactoryException {
final AbstractIdentifiedType property = school(3).getProperty("bounds");
assertInstanceOf("bounds", EnvelopeOperation.class, property);
final EnvelopeOperation op = (EnvelopeOperation) property;
assertSame("crs", HardCodedCRS.WGS84, op.crs);
assertSetEquals(Arrays.asList("classes", "climbing wall", "gymnasium"), op.getDependencies());
}
/**
* Implementation of the test methods.
*/
private static void run(final AbstractFeature feature) {
assertNull("Before a geometry is set", feature.getPropertyValue("bounds"));
GeneralEnvelope expected;
// Set one geometry
Polygon classes = new Polygon();
classes.startPath(10, 20);
classes.lineTo(10, 30);
classes.lineTo(15, 30);
classes.lineTo(15, 20);
feature.setPropertyValue("classes", classes);
expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
expected.setRange(0, 10, 15);
expected.setRange(1, 20, 30);
assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));
// Set second geometry
Point wall = new Point(18, 40);
feature.setPropertyValue("climbing wall", wall);
expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
expected.setRange(0, 10, 18);
expected.setRange(1, 20, 40);
assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));
// Set third geometry. This geometry has CRS axis order reversed.
Polygon gymnasium = new Polygon();
gymnasium.startPath(-5, -30);
gymnasium.lineTo(-6, -30);
gymnasium.lineTo(-6, -31);
gymnasium.lineTo(-5, -31);
feature.setPropertyValue("gymnasium", gymnasium);
expected = new GeneralEnvelope(HardCodedCRS.WGS84_φλ);
expected.setRange(0, -31, 18);
expected.setRange(1, -6, 40);
assertEnvelopeEquals(expected, (Envelope) feature.getPropertyValue("bounds"));
}
/**
* Tests a dense type with operations.
*
* @throws FactoryException if an error occurred while searching for the coordinate operations.
*/
@Test
@DependsOnMethod("testConstruction")
public void testDenseFeature() throws FactoryException {
run(new DenseFeature(school(1)));
}
/**
* Tests a sparse feature type with operations.
*
* @throws FactoryException if an error occurred while searching for the coordinate operations.
*/
@Test
@DependsOnMethod("testConstruction")
public void testSparseFeature() throws FactoryException {
run(new SparseFeature(school(2)));
}
}