use of org.opengis.util.FactoryException in project sis by apache.
the class MultiAuthoritiesFactoryTest method testCreateFromCombinedURNs.
/**
* Tests {@code MultiAuthoritiesFactory.createFoo(String)} from codes in the
* {@code "urn:ogc:def:type, type₁:authority₁:version₁:code₁, type₂:authority₂:version₂:code₂"} form.
*
* @throws FactoryException if an authority or a code is not recognized.
*
* @since 0.8
*/
@Test
@DependsOnMethod("testCreateFromURNs")
public void testCreateFromCombinedURNs() throws FactoryException {
final Set<AuthorityFactoryMock> mock = Collections.singleton(new AuthorityFactoryMock("MOCK", "2.3"));
final MultiAuthoritiesFactory factory = new MultiAuthoritiesFactory(mock, mock, mock, null);
testCreateFromCombinedURIs(factory, "urn:ogc:def:crs, crs:MOCK::4326, crs:MOCK::5714");
/*
* Following are more unusual combinations described in OGC 07-092r1 (2007)
* "Definition identifier URNs in OGC namespace".
*/
SingleCRS crs = factory.createGeographicCRS("urn:ogc:def:crs, datum:MOCK::6326, cs:MOCK::6424");
assertSame("datum", HardCodedDatum.WGS84, crs.getDatum());
assertSame("cs", HardCodedCS.GEODETIC_2D, crs.getCoordinateSystem());
/*
* Verify that invalid combined URIs are rejected.
*/
try {
factory.createObject("urn:ogc:def:cs, crs:MOCK::4326, crs:MOCK::5714");
fail("Shall not accept to create CoordinateSystem from combined URI.");
} catch (FactoryException e) {
String message = e.getMessage();
assertTrue(message, message.contains("CoordinateSystem"));
}
try {
factory.createObject("urn:ogc:def:crs, datum:MOCK::6326, cs:MOCK::6424, cs:MOCK::6422");
fail("Shall not accept to create combined URI with unexpected objects.");
} catch (FactoryException e) {
assertNotNull(e.getMessage());
}
}
use of org.opengis.util.FactoryException in project sis by apache.
the class CoordinateOperationMethods method computeUnionOfAllDomainOfValidity.
/**
* For each {@link OperationMethod} (identified by their name), computes the union of the domain of validity
* of all CRS using that operation method. The result is a map where keys are {@link OperationMethod} names,
* and values are the union of the domain of validity of all CRS using that {@code OperationMethod}.
*
* <p>This is a costly operation.</p>
*
* @todo This method is not yet used. This is pending the implementation of {@code CRSAuthorityFactory} is SIS.
*
* @param factory the factory to use for getting CRS.
* @return the union of domain of validity of all map projections using a method of the given name.
* @throws FactoryException if an error occurred while fetching the list of CRS.
*/
public static Map<String, DefaultGeographicBoundingBox> computeUnionOfAllDomainOfValidity(final CRSAuthorityFactory factory) throws FactoryException {
final Map<String, DefaultGeographicBoundingBox> domainOfValidity = new HashMap<>();
for (final String code : factory.getAuthorityCodes(GeneralDerivedCRS.class)) {
final CoordinateReferenceSystem crs;
try {
crs = factory.createCoordinateReferenceSystem(code);
} catch (FactoryException e) {
// Ignore and inspect the next element.
continue;
}
if (crs instanceof GeneralDerivedCRS) {
final GeographicBoundingBox candidate = CRS.getGeographicBoundingBox(crs);
if (candidate != null) {
final String name = ((GeneralDerivedCRS) crs).getConversionFromBase().getMethod().getName().getCode();
DefaultGeographicBoundingBox validity = domainOfValidity.get(name);
if (validity == null) {
validity = new DefaultGeographicBoundingBox(candidate);
domainOfValidity.put(name, validity);
} else {
validity.add(candidate);
}
}
}
}
return domainOfValidity;
}
use of org.opengis.util.FactoryException in project sis by apache.
the class FeatureTypeBuilder method build.
/**
* Builds the feature type from the information and properties specified to this builder.
* One of the {@code setName(…)} methods must have been invoked before this {@code build()} method (mandatory).
* All other methods are optional, but some calls to a {@code add} method are usually needed.
*
* <div class="warning"><b>Warning:</b> In a future SIS version, the return type may be changed to the
* {@code org.opengis.feature.FeatureType} interface. This change is pending GeoAPI revision.</div>
*
* <p>If a feature type has already been built and this builder state has not changed since the
* feature type creation, then the previously created {@code FeatureType} instance is returned.</p>
*
* @return the feature type.
* @throws IllegalStateException if the builder contains inconsistent information.
*
* @see #clear()
*/
@Override
public DefaultFeatureType build() throws IllegalStateException {
if (feature == null) {
/*
* Creates an initial array of property types with up to 3 slots reserved for sis:identifier, sis:geometry
* and sis:envelope operations. At first we presume that there is always an identifier. The identifier slot
* will be removed later if there is none.
*/
// Number of explicitely specified properties.
final int numSpecified = properties.size();
// Number of synthetic properties that may be generated.
int numSynthetic;
int envelopeIndex = -1;
int geometryIndex = -1;
final AbstractIdentifiedType[] identifierTypes;
if (identifierCount == 0) {
numSynthetic = 0;
identifierTypes = null;
} else {
numSynthetic = 1;
identifierTypes = new AbstractIdentifiedType[identifierCount];
}
if (defaultGeometry != null) {
envelopeIndex = numSynthetic++;
if (!AttributeConvention.GEOMETRY_PROPERTY.equals(defaultGeometry.getName())) {
geometryIndex = numSynthetic++;
}
}
final AbstractIdentifiedType[] propertyTypes = new AbstractIdentifiedType[numSynthetic + numSpecified];
int propertyCursor = numSynthetic;
int identifierCursor = 0;
for (int i = 0; i < numSpecified; i++) {
final PropertyTypeBuilder builder = properties.get(i);
final AbstractIdentifiedType instance = builder.build();
propertyTypes[propertyCursor] = instance;
/*
* Collect the attributes to use as identifier components while we loop over all properties.
* A NullPointerException or an ArrayIndexOutOfBoundsException in this block would mean that
* identifierCount field has not been updated correctly by an addRole(AttributeRole) method.
*/
if (builder.isIdentifier()) {
identifierTypes[identifierCursor++] = instance;
}
/*
* If there is a default geometry, add a link named "sis:geometry" to that geometry.
* It may happen that the property created by the user is already named "sis:geometry",
* in which case we will avoid to duplicate the property.
*/
if (builder == defaultGeometry && geometryIndex >= 0) {
if (propertyTypes[geometryIndex] != null) {
/*
* Assuming that there is no bug in our implementation, this error could happen if the user
* has modified this FeatureTypeBuilder in another thread during this build() execution.
*/
throw new CorruptedObjectException();
}
propertyTypes[geometryIndex] = FeatureOperations.link(name(AttributeConvention.GEOMETRY_PROPERTY), instance);
}
propertyCursor++;
}
/*
* Create the "envelope" operation only after we created all other properties.
* Actually it is okay if the 'propertyTypes' array still contains null elements not needed for envelope calculation
* like "sis:identifier", since FeatureOperations.envelope(…) constructor ignores any property which is not for a value.
*/
if (envelopeIndex >= 0)
try {
propertyTypes[envelopeIndex] = FeatureOperations.envelope(name(AttributeConvention.ENVELOPE_PROPERTY), null, propertyTypes);
} catch (FactoryException e) {
throw new IllegalStateException(e);
}
/*
* If a synthetic identifier need to be created, create it now as the first property.
* It may happen that the user provided a single identifier component already named
* "sis:identifier", in which case we avoid to duplicate the property.
*/
if (identifierTypes != null) {
if (identifierCursor != identifierTypes.length) {
/*
* Assuming that there is no bug in our implementation, this error could happen if the user
* has modified this FeatureTypeBuilder in another thread during this build() execution.
*/
throw new CorruptedObjectException();
}
if (AttributeConvention.IDENTIFIER_PROPERTY.equals(identifierTypes[0].getName())) {
if (identifierCursor > 1) {
throw new IllegalStateException(Resources.format(Resources.Keys.PropertyAlreadyExists_2, getDisplayName(), AttributeConvention.IDENTIFIER_PROPERTY));
}
System.arraycopy(propertyTypes, 1, propertyTypes, 0, --propertyCursor);
} else {
propertyTypes[0] = FeatureOperations.compound(name(AttributeConvention.IDENTIFIER_PROPERTY), idDelimiter, idPrefix, idSuffix, identifierTypes);
}
}
feature = new DefaultFeatureType(identification(), isAbstract(), superTypes.toArray(new DefaultFeatureType[superTypes.size()]), ArraysExt.resize(propertyTypes, propertyCursor));
}
return feature;
}
use of org.opengis.util.FactoryException in project sis by apache.
the class FranceGeocentricInterpolation method createMathTransform.
/**
* Creates a transform from the specified group of parameter values.
* This method creates the transform from <em>target</em> to <em>source</em>
* (which is the direction that use the interpolation grid directly without iteration),
* then inverts the transform.
*
* @param factory the factory to use if this constructor needs to create other math transforms.
* @param values the group of parameter values.
* @return the created math transform.
* @throws ParameterNotFoundException if a required parameter was not found.
* @throws FactoryException if an error occurred while loading the grid.
*/
@Override
public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup values) throws ParameterNotFoundException, FactoryException {
boolean withHeights = false;
final Parameters pg = Parameters.castOrWrap(values);
final Integer dim = pg.getValue(Molodensky.DIMENSION);
if (dim != null)
switch(dim) {
case 2:
break;
case 3:
withHeights = true;
break;
default:
throw new InvalidParameterValueException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "dim", dim), "dim", dim);
}
final Path file = pg.getMandatoryValue(FILE);
final DatumShiftGridFile<Angle, Length> grid = getOrLoad(file, isRecognized(file) ? new double[] { TX, TY, TZ } : null, PRECISION);
MathTransform tr = createGeodeticTransformation(factory, createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR, Molodensky.TGT_SEMI_MINOR, // GRS 1980 ellipsoid
CommonCRS.ETRS89.ellipsoid()), createEllipsoid(pg, Molodensky.SRC_SEMI_MAJOR, Molodensky.SRC_SEMI_MINOR, // Clarke 1880 (IGN) ellipsoid
null), withHeights, grid);
try {
tr = tr.inverse();
} catch (NoninvertibleTransformException e) {
// Should never happen.
throw new FactoryException(e);
}
return tr;
}
use of org.opengis.util.FactoryException in project sis by apache.
the class GeocentricAffineBetweenGeographic method createMathTransform.
/**
* Creates a math transform from the specified group of parameter values.
* This method wraps the affine operation into Geographic/Geocentric conversions.
*
* @param factory the factory to use for creating concatenated transforms.
* @param values the group of parameter values.
* @return the created math transform.
* @throws FactoryException if a transform can not be created.
*/
@Override
public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup values) throws FactoryException {
final Parameters pv = Parameters.castOrWrap(values);
final MathTransform affine = super.createMathTransform(factory, pv);
/*
* Create a "Geographic to Geocentric" conversion with ellipsoid axis length units converted to metres
* (the unit implied by SRC_SEMI_MAJOR) because it is the unit of Bursa-Wolf parameters that we created above.
*/
MathTransform toGeocentric = EllipsoidToCentricTransform.createGeodeticConversion(factory, pv.doubleValue(SRC_SEMI_MAJOR), pv.doubleValue(SRC_SEMI_MINOR), Units.METRE, getSourceDimensions() >= 3, EllipsoidToCentricTransform.TargetType.CARTESIAN);
/*
* Create a "Geocentric to Geographic" conversion with ellipsoid axis length units converted to metres
* because this is the unit of the Geocentric CRS used above.
*/
MathTransform toGeographic = EllipsoidToCentricTransform.createGeodeticConversion(factory, pv.doubleValue(TGT_SEMI_MAJOR), pv.doubleValue(TGT_SEMI_MINOR), Units.METRE, getTargetDimensions() >= 3, EllipsoidToCentricTransform.TargetType.CARTESIAN);
try {
toGeographic = toGeographic.inverse();
} catch (NoninvertibleTransformException e) {
// Should never happen with SIS implementation.
throw new FactoryException(e);
}
/*
* The Geocentric → Affine → Geographic chain.
*/
return factory.createConcatenatedTransform(toGeocentric, factory.createConcatenatedTransform(affine, toGeographic));
}
Aggregations