use of org.opengis.util.GenericName in project sis by apache.
the class EPSGDataAccess method createProperties.
/**
* Returns the name and aliases for the {@link IdentifiedObject} to construct.
*
* @param table the table on which a query has been executed.
* @param name the name for the {@link IdentifiedObject} to construct.
* @param code the EPSG code of the object to construct.
* @param remarks remarks as a {@link String} or {@link InternationalString}, or {@code null} if none.
* @param deprecated {@code true} if the object to create is deprecated.
* @return the name together with a set of properties.
*/
@SuppressWarnings("ReturnOfCollectionOrArrayField")
private Map<String, Object> createProperties(final String table, String name, final Integer code, CharSequence remarks, final boolean deprecated) throws SQLException, FactoryDataException {
/*
* Search for aliases. Note that searching for the object code is not sufficient. We also need to check if the
* record is really from the table we are looking for since different tables may have objects with the same ID.
*
* Some aliases are identical to the name except that some letters are replaced by their accented letters.
* For example "Reseau Geodesique Francais" → "Réseau Géodésique Français". If we find such alias, replace
* the name by the alias so we have proper display in user interface. Notes:
*
* - WKT formatting will still be compliant with ISO 19162 because the WKT formatter replaces accented
* letters by ASCII ones.
* - We do not perform this replacement directly in our EPSG database because ASCII letters are more
* convenient for implementing accent-insensitive searches.
*/
final List<GenericName> aliases = new ArrayList<>();
try (ResultSet result = executeQuery("Alias", "SELECT OBJECT_TABLE_NAME, NAMING_SYSTEM_NAME, ALIAS" + " FROM [Alias] INNER JOIN [Naming System]" + " ON [Alias].NAMING_SYSTEM_CODE =" + " [Naming System].NAMING_SYSTEM_CODE" + " WHERE OBJECT_CODE = ?", code)) {
while (result.next()) {
if (tableMatches(table, result.getString(1))) {
final String naming = getOptionalString(result, 2);
final String alias = getString(code, result, 3);
NameSpace ns = null;
if (naming != null) {
ns = namingSystems.get(naming);
if (ns == null) {
ns = owner.nameFactory.createNameSpace(owner.nameFactory.createLocalName(null, naming), null);
namingSystems.put(naming, ns);
}
}
if (CharSequences.toASCII(alias).toString().equals(name)) {
name = alias;
} else {
aliases.add(owner.nameFactory.createLocalName(ns, alias));
}
}
}
}
/*
* At this point we can fill the properties map.
*/
properties.clear();
GenericName gn = null;
final Locale locale = getLocale();
final Citation authority = owner.getAuthority();
final InternationalString edition = authority.getEdition();
final String version = (edition != null) ? edition.toString() : null;
if (name != null) {
gn = owner.nameFactory.createGenericName(namespace, Constants.EPSG, name);
properties.put("name", gn);
properties.put(NamedIdentifier.CODE_KEY, name);
properties.put(NamedIdentifier.VERSION_KEY, version);
properties.put(NamedIdentifier.AUTHORITY_KEY, authority);
properties.put(AbstractIdentifiedObject.LOCALE_KEY, locale);
final NamedIdentifier id = new NamedIdentifier(properties);
properties.clear();
properties.put(IdentifiedObject.NAME_KEY, id);
}
if (!aliases.isEmpty()) {
properties.put(IdentifiedObject.ALIAS_KEY, aliases.toArray(new GenericName[aliases.size()]));
}
if (code != null) {
final String codeString = code.toString();
final ImmutableIdentifier identifier;
if (deprecated) {
final String replacedBy = getSupersession(table, code, locale);
identifier = new DeprecatedCode(authority, Constants.EPSG, codeString, version, Character.isDigit(replacedBy.charAt(0)) ? replacedBy : null, Vocabulary.formatInternational(Vocabulary.Keys.SupersededBy_1, replacedBy));
properties.put(AbstractIdentifiedObject.DEPRECATED_KEY, Boolean.TRUE);
} else {
identifier = new ImmutableIdentifier(authority, Constants.EPSG, codeString, version, (gn != null) ? gn.toInternationalString() : null);
}
properties.put(IdentifiedObject.IDENTIFIERS_KEY, identifier);
}
properties.put(IdentifiedObject.REMARKS_KEY, remarks);
properties.put(AbstractIdentifiedObject.LOCALE_KEY, locale);
properties.put(ReferencingServices.MT_FACTORY, owner.mtFactory);
return properties;
}
use of org.opengis.util.GenericName in project sis by apache.
the class IdentifiedObjectFinder method createFromNames.
/**
* Creates an object equals (optionally ignoring metadata), to the specified object using only the
* {@linkplain AbstractIdentifiedObject#getName name} and {@linkplain AbstractIdentifiedObject#getAlias aliases}.
* If no such object is found, returns {@code null}.
*
* <p>This method may be used with some {@linkplain GeodeticAuthorityFactory authority factory}
* implementations like the one backed by the EPSG database, which are capable to find an object
* from its name when the identifier is unknown.</p>
*
* @param object the object looked up.
* @return the identified object, or {@code null} if not found.
* @throws FactoryException if an error occurred while creating an object.
*
* @see #createFromCodes(IdentifiedObject)
* @see #createFromIdentifiers(IdentifiedObject)
*/
private IdentifiedObject createFromNames(final IdentifiedObject object) throws FactoryException {
String code = object.getName().getCode();
IdentifiedObject candidate;
try {
candidate = create(code);
} catch (FactoryException e) {
/*
* The identifier was not recognized. We will continue later with aliases.
* Note: we catch a more generic exception than NoSuchAuthorityCodeException because
* this attempt may fail for various reasons (character string not supported
* by the underlying database for primary key, duplicated name found, etc.).
*/
exceptionOccurred(e);
candidate = null;
}
if (match(candidate, object)) {
return candidate;
}
for (final GenericName id : object.getAlias()) {
code = id.toString();
try {
candidate = create(code);
} catch (FactoryException e) {
// The name was not recognized. No problem, let's go on.
exceptionOccurred(e);
continue;
}
if (match(candidate, object)) {
return candidate;
}
}
return null;
}
use of org.opengis.util.GenericName in project sis by apache.
the class DefaultNameFactory method toGenericNames.
/**
* Converts the given value to an array of generic names. If the given value is an instance of
* {@link GenericName}, {@link String} or any other type enumerated below, then it is converted
* and returned in an array of length 1. If the given value is an array or a collection, then an
* array of same length is returned where each element has been converted.
*
* <p>Allowed types or element types are:</p>
* <ul>
* <li>{@link GenericName}, to be casted and returned as-is.</li>
* <li>{@link CharSequence} (usually a {@link String} or an {@link InternationalString}),
* to be parsed as a generic name using the {@link DefaultNameSpace#DEFAULT_SEPARATOR ':'} separator.</li>
* <li>{@link Identifier}, its {@linkplain Identifier#getCode() code} to be parsed as a generic name
* using the {@link DefaultNameSpace#DEFAULT_SEPARATOR ':'} separator.</li>
* </ul>
*
* If {@code value} is an array or a collection containing {@code null} elements,
* then the corresponding element in the returned array will also be {@code null}.
*
* @param value the object to cast into an array of generic names, or {@code null}.
* @return the generic names, or {@code null} if the given {@code value} was null.
* Note that it may be the {@code value} reference itself casted to {@code GenericName[]}.
* @throws ClassCastException if {@code value} can't be casted.
*
* @since 0.5
*/
public GenericName[] toGenericNames(Object value) throws ClassCastException {
if (value == null) {
return null;
}
GenericName name = toGenericName(value);
if (name != null) {
return new GenericName[] { name };
}
/*
* Above code checked for a singleton. Now check for a collection or an array.
*/
final Object[] values;
if (value instanceof Object[]) {
values = (Object[]) value;
if (values instanceof GenericName[]) {
return (GenericName[]) values;
}
} else if (value instanceof Collection<?>) {
values = ((Collection<?>) value).toArray();
} else {
throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_2, "value", value.getClass()));
}
final GenericName[] names = new GenericName[values.length];
for (int i = 0; i < values.length; i++) {
value = values[i];
if (value != null) {
name = toGenericName(value);
if (name == null) {
throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_2, "value[" + i + ']', value.getClass()));
}
names[i] = name;
}
}
return names;
}
use of org.opengis.util.GenericName in project sis by apache.
the class DefaultNameSpace method name.
/**
* Represents the identifier of this namespace. Namespace identifiers shall be
* {@linkplain AbstractName#toFullyQualifiedName() fully-qualified names} where
* the following condition holds:
*
* {@preformat java
* assert name.scope().isGlobal() == true;
* }
*
* @return the identifier of this namespace.
*/
@Override
public GenericName name() {
final int depth;
synchronized (this) {
if (path != null) {
return path;
}
depth = depth(this);
final DefaultLocalName[] names = new DefaultLocalName[depth];
DefaultNameSpace scan = this;
for (int i = depth; --i >= 0; ) {
names[i] = new DefaultLocalName(scan.parent, scan.name);
scan = scan.parent;
}
assert depth(scan) == 0 || scan.isGlobal();
path = DefaultScopedName.create(UnmodifiableArrayList.wrap(names));
GenericName truncated = path;
for (int i = depth; --i >= 0; ) {
names[i].fullyQualified = truncated;
truncated = (truncated instanceof ScopedName) ? ((ScopedName) truncated).path() : null;
}
}
/*
* At this point the name is created and ready to be returned. As an optimization,
* defines the name of parents now in order to share subarea of the array we just
* created. The goal is to have less objects in memory.
*/
AbstractName truncated = path;
DefaultNameSpace scan = parent;
while (scan != null && !scan.isGlobal()) {
/*
* If we have a parent, then depth >= 2 and consequently the name is a ScopedName.
* Actually it should be an instance of DefaultScopedName - we known that since we
* created it ourself with the DefaultScopedName.create(...) method call - and we
* know that its tail() implementation creates instance of AbstractName. Given all
* the above, none of the casts on the line below should ever fails, unless there
* is bug in this package.
*/
truncated = (AbstractName) ((ScopedName) truncated).path();
synchronized (scan) {
if (scan.path == null || scan.path.arraySize() < depth) {
scan.path = truncated;
}
}
scan = scan.parent;
}
return path;
}
use of org.opengis.util.GenericName in project sis by apache.
the class BuilderTest method testAddNameWithScope.
/**
* Tests {@link Builder#addName(Citation, CharSequence)} and {@link Builder#addName(CharSequence)} with codespace.
*/
@Test
@DependsOnMethod({ "testAddName", "testSetCodeSpace" })
public void testAddNameWithScope() {
final NameFactory factory = DefaultFactories.forBuildin(NameFactory.class);
// Expected values to be used later in the test.
final String name = "Mercator (variant A)";
final GenericName alias1 = factory.createLocalName(scope(factory, "EPSG"), "Mercator (1SP)");
final GenericName alias2 = new NamedIdentifier(Citations.OGC, "Mercator_1SP");
final GenericName alias3 = new NamedIdentifier(Citations.GEOTIFF, "CT_Mercator");
assertTrue("That name should not have a scope.", alias3.scope().isGlobal());
assertTrue("That name should not have a scope.", alias2.scope().isGlobal());
assertFalse("That name should be in EPSG scope.", alias1.scope().isGlobal());
assertEquals("EPSG", alias1.scope().name().toString());
assertEquals("Mercator (1SP)", alias1.toString());
assertEquals("OGC:Mercator_1SP", alias2.toString());
assertEquals("GeoTIFF:CT_Mercator", alias3.toString());
// The test.
final BuilderMock builder = createMercator(true, false);
assertEquals(name, builder.getName());
assertArrayEquals(new GenericName[] { alias1, alias2, alias3 }, builder.getAliases());
}
Aggregations