Search in sources :

Example 76 with InternationalString

use of org.opengis.util.InternationalString in project sis by apache.

the class MetadataReader method addCitation.

/**
 * Adds a {@code DataIdentification/Citation} element if at least one of the required attributes is non-null.
 * This method will initialize the {@link #pointOfContact} field, than reuse it if non-null and suitable.
 *
 * <p>This method opportunistically collects the name of all publishers.
 * Those names are useful to {@link #addIdentificationInfo(Set)}.</p>
 *
 * @return the name of all publishers, or {@code null} if none.
 */
private Set<InternationalString> addCitation() {
    String title = stringValue(TITLE);
    if (title == null) {
        // THREDDS attribute documented in TITLE javadoc.
        title = stringValue("full_name");
        if (title == null) {
            // THREDDS attribute documented in TITLE javadoc.
            title = stringValue("name");
            if (title == null) {
                title = decoder.getTitle();
            }
        }
    }
    addTitle(title);
    addEdition(stringValue(PRODUCT_VERSION));
    addOtherCitationDetails(stringValue(REFERENCES));
    addCitationDate(decoder.dateValue(METADATA_CREATION), DateType.CREATION, Scope.ALL);
    addCitationDate(decoder.dateValue(METADATA_MODIFIED), DateType.REVISION, Scope.ALL);
    addCitationDate(decoder.dateValue(DATE_CREATED), DateType.CREATION, Scope.RESOURCE);
    addCitationDate(decoder.dateValue(DATE_MODIFIED), DateType.REVISION, Scope.RESOURCE);
    addCitationDate(decoder.dateValue(DATE_ISSUED), DateType.PUBLICATION, Scope.RESOURCE);
    /*
         * Add the responsible party which is declared in global attributes, or in
         * the THREDDS attributes if no information was found in global attributes.
         * This responsible party is taken as the point of contact.
         */
    for (final String path : searchPath) {
        decoder.setSearchPath(path);
        final ResponsibleParty party = createResponsibleParty(CREATOR, true);
        if (party != pointOfContact) {
            addPointOfContact(party, Scope.ALL);
            if (pointOfContact == null) {
                pointOfContact = party;
            }
        }
    }
    /*
         * There is no distinction in netCDF files between "point of contact" and "creator".
         * We take the first one as the data originator.
         */
    addCitedResponsibleParty(pointOfContact, Role.ORIGINATOR);
    /*
         * Add the contributors only after we did one full pass over the creators. We keep those two
         * loops separated in order to increase the chances that pointOfContact has been initialized
         * (it may not have been initialized on the first pass).
         */
    Set<InternationalString> publisher = null;
    for (final String path : searchPath) {
        decoder.setSearchPath(path);
        final ResponsibleParty contributor = createResponsibleParty(CONTRIBUTOR, false);
        if (contributor != pointOfContact) {
            addCitedResponsibleParty(contributor, null);
        }
        final ResponsibleParty r = createResponsibleParty(PUBLISHER, false);
        if (r != null) {
            addDistributor(r);
            /*
                 * TODO: There is some transfert option, etc. that we could set there.
                 * See UnidataDD2MI.xsl for options for OPeNDAP, THREDDS, etc.
                 */
            publisher = addIfNonNull(publisher, r.getOrganisationName());
            publisher = addIfNonNull(publisher, toInternationalString(r.getIndividualName()));
        }
    }
    decoder.setSearchPath(searchPath);
    return publisher;
}
Also used : InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString)

Example 77 with InternationalString

use of org.opengis.util.InternationalString in project sis by apache.

the class EPSGDataAccess method createParameterDescriptor.

/**
 * Creates a definition of a single parameter used by an operation method.
 *
 * <div class="note"><b>Example:</b>
 * some EPSG codes for parameters are:
 *
 * <table class="sis" summary="EPSG codes examples">
 *   <tr><th>Code</th> <th>Description</th></tr>
 *   <tr><td>8801</td> <td>Latitude of natural origin</td></tr>
 *   <tr><td>8802</td> <td>Longitude of natural origin</td></tr>
 *   <tr><td>8805</td> <td>Scale factor at natural origin</td></tr>
 *   <tr><td>8806</td> <td>False easting</td></tr>
 *   <tr><td>8807</td> <td>False northing</td></tr>
 * </table></div>
 *
 * @param  code  value allocated by EPSG.
 * @return the parameter descriptor for the given code.
 * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
 * @throws FactoryException if the object creation failed for some other reason.
 *
 * @see org.apache.sis.parameter.DefaultParameterDescriptor
 */
@Override
public synchronized ParameterDescriptor<?> createParameterDescriptor(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    ParameterDescriptor<?> returnValue = null;
    try (ResultSet result = executeQuery("Coordinate_Operation Parameter", "PARAMETER_CODE", "PARAMETER_NAME", "SELECT PARAMETER_CODE," + " PARAMETER_NAME," + " DESCRIPTION," + " DEPRECATED" + " FROM [Coordinate_Operation Parameter]" + " WHERE PARAMETER_CODE = ?", code)) {
        while (result.next()) {
            final Integer epsg = getInteger(code, result, 1);
            final String name = getString(code, result, 2);
            final String description = getOptionalString(result, 3);
            final boolean deprecated = getOptionalBoolean(result, 4);
            Class<?> type = Double.class;
            /*
                 * If the parameter appears to have at least one non-null value in the "Parameter File Name" column,
                 * then the type is assumed to be URI as a string. Otherwise, the type is a floating point number.
                 */
            try (ResultSet r = executeQuery("ParameterType", "SELECT PARAM_VALUE_FILE_REF FROM [Coordinate_Operation Parameter Value]" + " WHERE (PARAMETER_CODE = ?) AND PARAM_VALUE_FILE_REF IS NOT NULL", epsg)) {
                while (r.next()) {
                    String element = getOptionalString(r, 1);
                    if (element != null && !element.isEmpty()) {
                        type = String.class;
                        break;
                    }
                }
            }
            /*
                 * Search for units.   We typically have many different units but all of the same dimension
                 * (for example metres, kilometres, feet, etc.). In such case, the units Set will have only
                 * one element and that element will be the most frequently used unit.  But some parameters
                 * accept units of different dimensions.   For example the "Ordinate 1 of evaluation point"
                 * (EPSG:8617) parameter value may be in metres or in degrees.   In such case the units Set
                 * will have two elements.
                 */
            final Set<Unit<?>> units = new LinkedHashSet<>();
            try (ResultSet r = executeQuery("ParameterUnit", "SELECT UOM_CODE FROM [Coordinate_Operation Parameter Value]" + " WHERE (PARAMETER_CODE = ?)" + " GROUP BY UOM_CODE" + " ORDER BY COUNT(UOM_CODE) DESC", epsg)) {
                next: while (r.next()) {
                    final String c = getOptionalString(r, 1);
                    if (c != null) {
                        final Unit<?> candidate = owner.createUnit(c);
                        for (final Unit<?> e : units) {
                            if (candidate.isCompatible(e)) {
                                continue next;
                            }
                        }
                        units.add(candidate);
                    }
                }
            }
            /*
                 * Determines if the inverse operation can be performed by reversing the parameter sign.
                 * The EPSG dataset uses "Yes" or "No" value, but SIS scripts use boolean type. We have
                 * to accept both. Note that if we do not recognize the string as a boolean value, then
                 * we need a SQLException, not a null value.  If the value is wrongly null, this method
                 * will succeed anyway and EPSGDataAccess will finish its work without apparent problem,
                 * but Apache SIS will fail later when it will try to compute the inverse operation, for
                 * example in a call to CRS.findOperation(…). The exception thrown at such later time is
                 * much more difficult to relate to the root cause than if we throw the exception here.
                 */
            InternationalString isReversible = null;
            try (ResultSet r = executeQuery("ParameterSign", "SELECT DISTINCT PARAM_SIGN_REVERSAL FROM [Coordinate_Operation Parameter Usage]" + " WHERE (PARAMETER_CODE = ?)", epsg)) {
                if (r.next()) {
                    Boolean b;
                    if (translator.useBoolean()) {
                        b = r.getBoolean(1);
                        if (r.wasNull())
                            b = null;
                    } else {
                        // May throw SQLException - see above comment.
                        b = SQLUtilities.toBoolean(r.getString(1));
                    }
                    if (b != null) {
                        isReversible = b ? SignReversalComment.OPPOSITE : SignReversalComment.SAME;
                    }
                }
            }
            /*
                 * Now creates the parameter descriptor.
                 */
            final NumberRange<?> valueDomain;
            switch(units.size()) {
                case 0:
                    valueDomain = null;
                    break;
                default:
                    valueDomain = new EPSGParameterDomain(units);
                    break;
                case 1:
                    valueDomain = MeasurementRange.create(Double.NEGATIVE_INFINITY, false, Double.POSITIVE_INFINITY, false, CollectionsExt.first(units));
                    break;
            }
            final Map<String, Object> properties = createProperties("Coordinate_Operation Parameter", name, epsg, isReversible, deprecated);
            properties.put(ImmutableIdentifier.DESCRIPTION_KEY, description);
            final ParameterDescriptor<?> descriptor = new DefaultParameterDescriptor<>(properties, 1, 1, type, valueDomain, null, null);
            returnValue = ensureSingleton(descriptor, returnValue, code);
        }
    } catch (SQLException exception) {
        throw databaseFailure(OperationMethod.class, code, exception);
    }
    if (returnValue == null) {
        throw noSuchAuthorityCode(OperationMethod.class, code);
    }
    return returnValue;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SQLException(java.sql.SQLException) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) Unit(javax.measure.Unit) DefaultOperationMethod(org.apache.sis.referencing.operation.DefaultOperationMethod) EPSGParameterDomain(org.apache.sis.internal.referencing.EPSGParameterDomain) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) ResultSet(java.sql.ResultSet) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) IdentifiedObject(org.opengis.referencing.IdentifiedObject) DefaultParameterDescriptor(org.apache.sis.parameter.DefaultParameterDescriptor)

Example 78 with InternationalString

use of org.opengis.util.InternationalString in project sis by apache.

the class EPSGDataAccess method getAuthority.

/**
 * Returns the authority for this EPSG dataset. The returned citation contains the database version
 * in the {@linkplain Citation#getEdition() edition} attribute, together with date of last update in
 * the {@linkplain Citation#getEditionDate() edition date}.
 * Example (the exact content will vary with Apache SIS versions, JDBC driver and EPSG dataset versions):
 *
 * {@preformat text
 *   Citation
 *   ├─ Title ……………………………………………………… EPSG Geodetic Parameter Dataset
 *   ├─ Identifier ………………………………………… EPSG
 *   ├─ Online resource (1 of 2)
 *   │  ├─ Linkage ………………………………………… http://epsg-registry.org/
 *   │  └─ Function ……………………………………… Browse
 *   └─ Online resource (2 of 2)
 *      ├─ Linkage ………………………………………… jdbc:derby:/my/path/to/SIS_DATA/Databases/SpatialMetadata
 *      ├─ Description ……………………………… EPSG dataset version 8.9 on “Apache Derby Embedded JDBC Driver” version 10.12.
 *      └─ Function ……………………………………… Connection
 * }
 */
@Override
public synchronized Citation getAuthority() {
    /*
         * We do not cache this citation because the caching service is already provided by ConcurrentAuthorityFactory.
         */
    final DefaultCitation c = new DefaultCitation("EPSG Geodetic Parameter Dataset");
    c.setIdentifiers(Collections.singleton(new ImmutableIdentifier(null, null, Constants.EPSG)));
    try {
        /*
             * Get the most recent version number from the history table. We get the date in local timezone
             * instead then UTC because the date is for information purpose only, and the local timezone is
             * more likely to be shown nicely (without artificial hours) to the user.
             */
        final String query = translator.apply("SELECT VERSION_NUMBER, VERSION_DATE FROM [Version History]" + " ORDER BY VERSION_DATE DESC, VERSION_HISTORY_CODE DESC");
        String version = null;
        try (Statement statement = connection.createStatement();
            ResultSet result = statement.executeQuery(query)) {
            while (result.next()) {
                version = getOptionalString(result, 1);
                // Local timezone.
                final Date date = result.getDate(2);
                if (version != null && date != null) {
                    // Paranoiac check.
                    c.setEdition(new SimpleInternationalString(version));
                    c.setEditionDate(date);
                    break;
                }
            }
        }
        /*
             * Add some hard-coded links to EPSG resources, and finally add the JDBC driver name and version number.
             * The list last OnlineResource looks like:
             *
             *    Linkage:      jdbc:derby:/my/path/to/SIS_DATA/Databases/SpatialMetadata
             *    Function:     Connection
             *    Description:  EPSG dataset version 8.9 on “Apache Derby Embedded JDBC Driver” version 10.12.
             *
             * TODO: A future version should use Citations.EPSG as a template.
             *       See the "EPSG" case in ServiceForUtility.createCitation(String).
             */
        final DatabaseMetaData metadata = connection.getMetaData();
        addURIs: for (int i = 0; ; i++) {
            String url;
            OnLineFunction function;
            InternationalString description = null;
            switch(i) {
                case 0:
                    url = "http://epsg-registry.org/";
                    function = OnLineFunction.SEARCH;
                    break;
                case 1:
                    url = "http://www.epsg.org/";
                    function = OnLineFunction.DOWNLOAD;
                    break;
                case 2:
                    {
                        url = SQLUtilities.getSimplifiedURL(metadata);
                        function = OnLineFunction.valueOf(CONNECTION);
                        description = Resources.formatInternational(Resources.Keys.GeodeticDataBase_4, Constants.EPSG, version, metadata.getDatabaseProductName(), Version.valueOf(metadata.getDatabaseMajorVersion(), metadata.getDatabaseMinorVersion()));
                        break;
                    }
                // Finished adding all URIs.
                default:
                    break addURIs;
            }
            final DefaultOnlineResource r = new DefaultOnlineResource();
            try {
                r.setLinkage(new URI(url));
            } catch (URISyntaxException exception) {
                unexpectedException("getAuthority", exception);
            }
            r.setFunction(function);
            r.setDescription(description);
            c.getOnlineResources().add(r);
        }
    } catch (SQLException exception) {
        unexpectedException("getAuthority", exception);
    } finally {
        c.freeze();
    }
    return c;
}
Also used : DefaultCitation(org.apache.sis.metadata.iso.citation.DefaultCitation) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) OnLineFunction(org.opengis.metadata.citation.OnLineFunction) URISyntaxException(java.net.URISyntaxException) DatabaseMetaData(java.sql.DatabaseMetaData) DefaultOnlineResource(org.apache.sis.metadata.iso.citation.DefaultOnlineResource) URI(java.net.URI) Date(java.util.Date) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) ResultSet(java.sql.ResultSet) ImmutableIdentifier(org.apache.sis.metadata.iso.ImmutableIdentifier)

Example 79 with InternationalString

use of org.opengis.util.InternationalString in project sis by apache.

the class CommonAuthorityFactory method getDescriptionText.

/**
 * Returns a description of the object corresponding to a code.
 * The description can be used for example in a combo box in a graphical user interface.
 *
 * <p>Codes in the {@code "AUTO(2)"} namespace do not need parameters for this method.
 * But if parameters are nevertheless specified, then they will be taken in account.</p>
 *
 * <table class="sis">
 *   <caption>Examples</caption>
 *   <tr><th>Argument value</th>                <th>Return value</th></tr>
 *   <tr><td>{@code CRS:84}</td>                <td>WGS 84</td></tr>
 *   <tr><td>{@code AUTO2:42001}</td>           <td>WGS 84 / Auto UTM</td></tr>
 *   <tr><td>{@code AUTO2:42001,1,-100,45}</td> <td>WGS 84 / UTM zone 47N</td></tr>
 * </table>
 *
 * @param  code  value in the CRS or AUTO(2) code space.
 * @return a description of the object.
 * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
 * @throws FactoryException if an error occurred while fetching the description.
 */
@Override
public InternationalString getDescriptionText(final String code) throws FactoryException {
    final int s = skipNamespace(code) & ~LEGACY_MASK;
    final String localCode = code.substring(s, CharSequences.skipTrailingWhitespaces(code, s, code.length()));
    if (localCode.indexOf(SEPARATOR) < 0) {
        /*
             * For codes in the "AUTO(2)" namespace without parameters, we can not rely on the default implementation
             * since it would fail to create the ProjectedCRS instance. Instead we return a generic description.
             * Note that we do not execute this block if parametes were specified. If there is parameters,
             * then we instead rely on the default implementation for a more accurate description text.
             */
        final int codeValue;
        try {
            codeValue = Integer.parseInt(localCode);
        } catch (NumberFormatException exception) {
            throw noSuchAuthorityCode(localCode, code, exception);
        }
        final int i = codeValue - FIRST_PROJECTION_CODE;
        if (i >= 0 && i < PROJECTION_NAMES.length) {
            return new SimpleInternationalString(PROJECTION_NAMES[i]);
        }
    }
    return new SimpleInternationalString(createCoordinateReferenceSystem(localCode).getName().getCode());
}
Also used : SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString)

Example 80 with InternationalString

use of org.opengis.util.InternationalString in project sis by apache.

the class InverseOperationMethod method properties.

/**
 * Infers the properties to give to an inverse coordinate operation.
 * The returned map will contains three kind of information:
 *
 * <ul>
 *   <li>Metadata (domain of validity, accuracy)</li>
 *   <li>Parameter values, if possible</li>
 * </ul>
 *
 * This method copies accuracy and domain of validity metadata from the given operation.
 * We presume that the inverse operation has the same accuracy than the direct operation.
 *
 * <div class="note"><b>Note:</b>
 * in many cases, the inverse operation is numerically less accurate than the direct operation because it
 * uses approximations like series expansions or iterative methods. However the numerical errors caused by
 * those approximations are not of interest here, because they are usually much smaller than the inaccuracy
 * due to the stochastic nature of coordinate transformations (not to be confused with coordinate conversions;
 * see ISO 19111 for more information).</div>
 *
 * If the inverse of the given operation can be represented by inverting the sign of all numerical
 * parameter values, then this method copies also those parameters in a {@code "parameters"} entry.
 *
 * @param source  the operation for which to get the inverse parameters.
 * @param target  where to store the inverse parameters.
 */
static void properties(final SingleOperation source, final Map<String, Object> target) {
    target.put(SingleOperation.DOMAIN_OF_VALIDITY_KEY, source.getDomainOfValidity());
    final Collection<PositionalAccuracy> accuracy = source.getCoordinateOperationAccuracy();
    if (!Containers.isNullOrEmpty(accuracy)) {
        target.put(SingleOperation.COORDINATE_OPERATION_ACCURACY_KEY, accuracy.toArray(new PositionalAccuracy[accuracy.size()]));
    }
    /*
         * If the inverse of the given operation can be represented by inverting the sign of all numerical
         * parameter values, copies those parameters in a "parameters" entry in the properties map.
         * Otherwise does nothing.
         */
    final ParameterValueGroup parameters = source.getParameterValues();
    final ParameterValueGroup copy = parameters.getDescriptor().createValue();
    for (final GeneralParameterValue gp : parameters.values()) {
        if (gp instanceof ParameterValue<?>) {
            final ParameterValue<?> src = (ParameterValue<?>) gp;
            final Object value = src.getValue();
            if (value instanceof Number) {
                final ParameterDescriptor<?> descriptor = src.getDescriptor();
                final InternationalString remarks = descriptor.getRemarks();
                if (remarks != SignReversalComment.SAME) {
                    if (remarks != SignReversalComment.OPPOSITE) {
                        /*
                             * The parameter descriptor does not specify whether the values for the inverse operation
                             * have the same sign or opposite sign. We could heuristically presume that we can invert
                             * the sign if the minimum value has the opposite sign than the maximum value  (as in the
                             * [-10 … 10] range), but such assumption is dangerous. For example the values in a matrix
                             * could be bounded to a range like [-1 … 1], which would mislead above heuristic rule.
                             *
                             * Note that abandoning here does not mean that we will never know the parameter values.
                             * As a fallback, AbstractCoordinateOperation will try to get the parameter values from
                             * the MathTransform. This is the appropriate thing to do at least for Affine operation.
                             */
                        return;
                    }
                    /*
                         * The parameter value of the inverse operation is (or is presumed to be) the negative of
                         * the parameter value of the source operation.  We need to preserve units of measurement
                         * if they were specified.
                         */
                    final ParameterValue<?> tgt = copy.parameter(descriptor.getName().getCode());
                    final Unit<?> unit = src.getUnit();
                    if (unit != null) {
                        tgt.setValue(-src.doubleValue(), unit);
                    } else if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
                        tgt.setValue(-src.intValue());
                    } else {
                        tgt.setValue(-src.doubleValue());
                    }
                    // No need to add 'tgt' to 'copy' since it was done by the call to copy.parameter(…).
                    continue;
                }
            }
        }
        copy.values().add(gp);
    }
    target.put(ReferencingServices.PARAMETERS_KEY, copy);
}
Also used : GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) PositionalAccuracy(org.opengis.metadata.quality.PositionalAccuracy) GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) ParameterValue(org.opengis.parameter.ParameterValue) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) InternationalString(org.opengis.util.InternationalString)

Aggregations

InternationalString (org.opengis.util.InternationalString)86 SimpleInternationalString (org.apache.sis.util.iso.SimpleInternationalString)20 Test (org.junit.Test)17 DefaultCitation (org.apache.sis.metadata.iso.citation.DefaultCitation)13 IdentifiedObject (org.opengis.referencing.IdentifiedObject)10 ArrayList (java.util.ArrayList)7 Locale (java.util.Locale)6 GenericName (org.opengis.util.GenericName)6 Extent (org.opengis.metadata.extent.Extent)5 DefaultDataIdentification (org.apache.sis.metadata.iso.identification.DefaultDataIdentification)4 DependsOnMethod (org.apache.sis.test.DependsOnMethod)4 Vocabulary (org.apache.sis.util.resources.Vocabulary)4 Citation (org.opengis.metadata.citation.Citation)4 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)3 ResultSet (java.sql.ResultSet)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 TableAppender (org.apache.sis.io.TableAppender)3 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)3 DataStoreException (org.apache.sis.storage.DataStoreException)3