Search in sources :

Example 6 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class ParameterFormat method formatSummary.

/**
 * Implementation of public {@code format(…)} methods for {@code NAME_SUMMARY} content level.
 *
 * @param  objects  the collection of objects to format.
 * @param  out      the stream or buffer where to write the summary.
 * @throws IOException if an error occurred will writing to the given appendable.
 */
private void formatSummary(final IdentifiedObject[] objects, final Appendable out) throws IOException {
    final Vocabulary resources = Vocabulary.getResources(displayLocale);
    /*
         * Prepares all rows before we write them to the output stream, because not all
         * identified objects may have names with the same scopes in the same order. We
         * also need to iterate over all rows in order to know the number of columns.
         *
         * The first column is reserved for the identifier. We put null as a sentinal key for
         * that column name, to be replaced later by "Identifier" in user locale. We can not
         * put the localized strings in the map right now because they could conflict with
         * the scope of some alias to be processed below.
         */
    boolean hasIdentifiers = false;
    final List<String[]> rows = new ArrayList<>();
    final Map<String, Integer> columnIndices = new LinkedHashMap<>();
    // See above comment for the meaning of "null" here.
    columnIndices.put(null, 0);
    if (preferredCodespaces != null) {
        for (final String codespace : preferredCodespaces) {
            columnIndices.put(codespace, columnIndices.size());
        }
    }
    for (final IdentifiedObject object : objects) {
        // Will growth later if needed.
        String[] row = new String[columnIndices.size()];
        /*
             * Put the first identifier in the first column. If no identifier has a codespace in the list
             * supplied by the user, then we will use the first identifier (any codespace) as a fallback.
             */
        final Set<ReferenceIdentifier> identifiers = object.getIdentifiers();
        if (identifiers != null) {
            // Paranoiac check.
            Identifier identifier = null;
            for (final ReferenceIdentifier candidate : identifiers) {
                if (candidate != null) {
                    // Paranoiac check.
                    if (isPreferredCodespace(candidate.getCodeSpace())) {
                        identifier = candidate;
                        // Format now.
                        break;
                    }
                    if (identifier == null) {
                        // To be used as a fallback if we find nothing better.
                        identifier = candidate;
                    }
                }
            }
            if (identifier != null) {
                row[0] = IdentifiedObjects.toString(identifier);
                hasIdentifiers = true;
            }
        }
        /*
             * If the name's codespace is in the list of codespaces asked by the user, add that name
             * in the current row and clear the 'name' locale variable. Otherwise, keep the 'name'
             * locale variable in case we found no alias to format.
             */
        ReferenceIdentifier name = object.getName();
        if (name != null) {
            // Paranoiac check.
            final String codespace = name.getCodeSpace();
            if (isPreferredCodespace(codespace)) {
                row = putIfAbsent(resources, row, columnIndices, codespace, name.getCode());
                name = null;
            }
        }
        /*
             * Put all aliases having a codespace in the list asked by the user.
             */
        final Collection<GenericName> aliases = object.getAlias();
        if (aliases != null) {
            // Paranoiac check.
            for (final GenericName alias : aliases) {
                if (alias != null) {
                    // Paranoiac check.
                    final String codespace = NameToIdentifier.getCodeSpace(alias, displayLocale);
                    if (isPreferredCodespace(codespace)) {
                        row = putIfAbsent(resources, row, columnIndices, codespace, alias.tip().toInternationalString().toString(displayLocale));
                        name = null;
                    }
                }
            }
        }
        /*
             * If no name and no alias have a codespace in the list of codespaces asked by the user,
             * force the addition of primary name regardless its codespace.
             */
        if (name != null) {
            row = putIfAbsent(resources, row, columnIndices, name.getCodeSpace(), name.getCode());
        }
        rows.add(row);
    }
    /*
         * Writes the table. The header will contain one column for each codespace in the order declared
         * by the user. If the user did not specified any codespace, or if we had to write codespace not
         * on the user list, then those codespaces will be written in the order we found them.
         */
    final boolean hasColors = (colors != null);
    final TableAppender table = new TableAppender(out, columnSeparator);
    table.setMultiLinesCells(true);
    table.appendHorizontalSeparator();
    for (String codespace : columnIndices.keySet()) {
        if (codespace == null) {
            // Skip empty column.
            if (!hasIdentifiers)
                continue;
            codespace = resources.getString(Vocabulary.Keys.Identifier);
        }
        if (hasColors) {
            codespace = X364.BOLD.sequence() + codespace + X364.NORMAL.sequence();
        }
        table.append(codespace);
        nextColumn(table);
    }
    table.appendHorizontalSeparator();
    /*
         * Writes row content.
         */
    final int numColumns = columnIndices.size();
    for (final String[] row : rows) {
        for (int i = hasIdentifiers ? 0 : 1; i < numColumns; i++) {
            if (i < row.length) {
                final String name = row[i];
                if (name != null) {
                    table.append(name);
                }
            }
            nextColumn(table);
        }
        table.nextLine();
    }
    table.appendHorizontalSeparator();
    table.flush();
}
Also used : Vocabulary(org.apache.sis.util.resources.Vocabulary) ArrayList(java.util.ArrayList) TableAppender(org.apache.sis.io.TableAppender) LinkedHashMap(java.util.LinkedHashMap) GenericName(org.opengis.util.GenericName) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) NameToIdentifier(org.apache.sis.internal.metadata.NameToIdentifier) Identifier(org.opengis.metadata.Identifier) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 7 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class ParameterFormat method format.

/**
 * Formats the given object to the given stream of buffer.
 * The object may be an instance of any of the following types:
 *
 * <ul>
 *   <li>{@link ParameterValueGroup}</li>
 *   <li>{@link ParameterDescriptorGroup}</li>
 *   <li>{@link OperationMethod}</li>
 *   <li><code>{@linkplain IdentifiedObject}[]</code> — accepted only for {@link ContentLevel#NAME_SUMMARY}.</li>
 * </ul>
 *
 * @throws IOException if an error occurred while writing to the given appendable.
 */
@Override
public void format(final Object object, final Appendable toAppendTo) throws IOException {
    ArgumentChecks.ensureNonNull("object", object);
    ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
    final boolean isSummary = contentLevel == ContentLevel.NAME_SUMMARY;
    final ParameterDescriptorGroup descriptor;
    final ParameterValueGroup values;
    final Identifier name;
    if (object instanceof ParameterValueGroup) {
        values = (ParameterValueGroup) object;
        descriptor = values.getDescriptor();
        name = descriptor.getName();
    } else if (object instanceof ParameterDescriptorGroup) {
        descriptor = (ParameterDescriptorGroup) object;
        values = null;
        name = descriptor.getName();
    } else if (object instanceof OperationMethod) {
        final OperationMethod operation = (OperationMethod) object;
        descriptor = operation.getParameters();
        values = null;
        name = operation.getName();
    } else if (isSummary && object instanceof IdentifiedObject[]) {
        formatSummary((IdentifiedObject[]) object, toAppendTo);
        return;
    } else {
        throw new IllegalArgumentException(Errors.getResources(displayLocale).getString(Errors.Keys.UnsupportedType_1, object.getClass()));
    }
    if (isSummary) {
        final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
        formatSummary(parameters.toArray(new IdentifiedObject[parameters.size()]), toAppendTo);
    } else {
        format(name.getCode(), descriptor, values, toAppendTo);
    }
}
Also used : NameToIdentifier(org.apache.sis.internal.metadata.NameToIdentifier) Identifier(org.opengis.metadata.Identifier) ReferenceIdentifier(org.opengis.referencing.ReferenceIdentifier) IdentifiedObject(org.opengis.referencing.IdentifiedObject) OperationMethod(org.opengis.referencing.operation.OperationMethod)

Example 8 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class EPSGFactoryTest method testFindGeographic.

/**
 * Tests {@link EPSGFactory#newIdentifiedObjectFinder()} method with a geographic CRS.
 *
 * @throws FactoryException if an error occurred while querying the factory.
 */
@Test
@DependsOnMethod("testWGS84")
public void testFindGeographic() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder();
    final DefaultGeographicCRS crs = (DefaultGeographicCRS) CRS.fromWKT("GEOGCS[“WGS 84”,\n" + // Use the alias instead than primary name for forcing a deeper search.
    "  DATUM[“WGS 84”,\n" + // Different name for forcing a deeper search.
    "    SPHEROID[“WGS 1984”, 6378137.0, 298.257223563]],\n" + "  PRIMEM[“Greenwich”, 0.0],\n" + "  UNIT[“degree”, 0.017453292519943295],\n" + "  AXIS[“Geodetic latitude”, NORTH],\n" + "  AXIS[“Geodetic longitude”, EAST]]");
    /*
         * First, search for a CRS with axis order that does not match the ones in the EPSG database.
         * IdentifiedObjectFinder should not accept EPSG:4326 as a match for the given CRS.
         */
    assertEquals("Full scan should be enabled by default.", IdentifiedObjectFinder.Domain.VALID_DATASET, finder.getSearchDomain());
    assertTrue("Should not find WGS84 because the axis order is not the same.", finder.find(crs.forConvention(AxesConvention.NORMALIZED)).isEmpty());
    /*
         * Ensure that the cache is empty.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.DECLARATION);
    assertTrue("Should not find without a full scan, because the WKT contains no identifier " + "and the CRS name is ambiguous (more than one EPSG object have this name).", finder.find(crs).isEmpty());
    /*
         * Scan the database for searching the CRS.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
    final IdentifiedObject found = finder.findSingleton(crs);
    assertNotNull("With full scan allowed, the CRS should be found.", found);
    assertEpsgNameAndIdentifierEqual("WGS 84", 4326, found);
    /*
         * Should find the CRS without the need of a full scan, because of the cache.
         */
    finder.setSearchDomain(IdentifiedObjectFinder.Domain.DECLARATION);
    assertSame("The CRS should still in the cache.", found, finder.findSingleton(crs));
}
Also used : IdentifiedObjectFinder(org.apache.sis.referencing.factory.IdentifiedObjectFinder) IdentifiedObject(org.opengis.referencing.IdentifiedObject) DefaultGeographicCRS(org.apache.sis.referencing.crs.DefaultGeographicCRS) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 9 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class FeatureFormat method formatValue.

/**
 * Appends the given attribute value, in a truncated form if it exceed the maximal value length.
 *
 * @param  value   the value to append.
 * @param  table   where to append the value.
 * @param  length  number of characters appended before this method call in the current table cell.
 * @return number of characters appended after this method call in the current table cell, or -1 if
 *         the length exceed the maximal length (in which case the caller should break iteration).
 */
private int formatValue(final Object value, final TableAppender table, final int length) {
    String text;
    if (value instanceof InternationalString) {
        text = ((InternationalString) value).toString(displayLocale);
    } else if (value instanceof GenericName) {
        text = toString((GenericName) value);
    } else if (value instanceof AbstractIdentifiedType) {
        text = toString(((AbstractIdentifiedType) value).getName());
    } else if (value instanceof IdentifiedObject) {
        text = IdentifiedObjects.getIdentifierOrName((IdentifiedObject) value);
    } else if ((text = Geometries.toString(value)) == null) {
        text = value.toString();
    }
    final int remaining = MAXIMAL_VALUE_LENGTH - length;
    if (remaining >= text.length()) {
        table.append(text);
        return length + text.length();
    } else {
        table.append(text, 0, Math.max(0, remaining - 1)).append('…');
        return -1;
    }
}
Also used : GenericName(org.opengis.util.GenericName) InternationalString(org.opengis.util.InternationalString) InternationalString(org.opengis.util.InternationalString) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 10 with IdentifiedObject

use of org.opengis.referencing.IdentifiedObject in project sis by apache.

the class Formatter method append.

/**
 * Appends the given {@code FormattableObject}.
 * This method performs the following steps:
 *
 * <ul>
 *   <li>Invoke <code>object.{@linkplain FormattableObject#formatTo(Formatter) formatTo}(this)</code>.</li>
 *   <li>Prepend the keyword returned by the above method call (e.g. {@code "GEOCS"}).</li>
 *   <li>If the given object is an instance of {@link IdentifiedObject}, then append complementary information:</li>
 * </ul>
 *
 * <blockquote><table class="sis">
 *   <caption>Complementary WKT elements</caption>
 *   <tr><th>WKT 2 element</th><th>WKT 1 element</th><th>For types</th></tr>
 *   <tr><td>{@code Anchor[…]}</td>        <td></td> <td>{@link Datum}</td></tr>
 *   <tr><td>{@code Scope[…]}</td>         <td></td> <td>{@link ReferenceSystem}, {@link Datum}, {@link CoordinateOperation}</td></tr>
 *   <tr><td>{@code Area[…]}</td>          <td></td> <td>{@link ReferenceSystem}, {@link Datum}, {@link CoordinateOperation}</td></tr>
 *   <tr><td>{@code BBox[…]}</td>          <td></td> <td>{@link ReferenceSystem}, {@link Datum}, {@link CoordinateOperation}</td></tr>
 *   <tr><td>{@code VerticalExtent[…]}</td><td></td> <td>{@link ReferenceSystem}, {@link Datum}, {@link CoordinateOperation}</td></tr>
 *   <tr><td>{@code TimeExtent[…]}</td>    <td></td> <td>{@link ReferenceSystem}, {@link Datum}, {@link CoordinateOperation}</td></tr>
 *   <tr><td>{@code Id[…]}</td><td>{@code Authority[…]}</td><td>{@link IdentifiedObject}</td></tr>
 *   <tr><td>{@code Remarks[…]}</td>       <td></td> <td>{@link ReferenceSystem}, {@link CoordinateOperation}</td></tr>
 * </table></blockquote>
 *
 * @param  object  the formattable object to append to the WKT, or {@code null} if none.
 */
public void append(final FormattableObject object) {
    if (object == null) {
        return;
    }
    /*
         * Safety check: ensure that we do not have circular dependencies (e.g. a ProjectedCRS contains
         * a Conversion which may contain the ProjectedCRS as its target CRS). Without this protection,
         * a circular dependency would cause an OutOfMemoryError.
         */
    final int stackDepth = enclosingElements.size();
    for (int i = stackDepth; --i >= 0; ) {
        if (enclosingElements.get(i) == object) {
            throw new IllegalStateException(Errors.getResources(locale).getString(Errors.Keys.CircularReference));
        }
    }
    enclosingElements.add(object);
    if (hasContextualUnit < 0) {
        // Test if leftmost bit is set to 1.
        throw new IllegalStateException(Errors.getResources(locale).getString(Errors.Keys.TreeDepthExceedsMaximum));
    }
    hasContextualUnit <<= 1;
    /*
         * Add a new line if it was requested, open the bracket and increase indentation in case the
         * element to format contains other FormattableObject elements.
         */
    appendSeparator();
    int base = buffer.length();
    elementStart = buffer.appendCodePoint(symbols.getOpeningBracket(0)).length();
    indent(+1);
    /*
         * Formats the inner part, then prepend the WKT keyword.
         * The result looks like the following:
         *
         *         <previous text>,
         *           PROJCS["NAD27 / Idaho Central",
         *             GEOGCS[...etc...],
         *             ...etc...
         */
    IdentifiedObject info = (object instanceof IdentifiedObject) ? (IdentifiedObject) object : null;
    String keyword = object.formatTo(this);
    if (keyword == null) {
        if (info != null) {
            setInvalidWKT(info, null);
        } else {
            setInvalidWKT(object.getClass(), null);
        }
        keyword = getName(object.getClass());
    } else if (toUpperCase != 0) {
        final Locale locale = symbols.getLocale();
        keyword = (toUpperCase >= 0) ? keyword.toUpperCase(locale) : keyword.toLowerCase(locale);
    }
    if (highlightError && colors != null) {
        final String color = colors.getAnsiSequence(ElementKind.ERROR);
        if (color != null) {
            buffer.insert(base, color + BACKGROUND_DEFAULT);
            base += color.length();
        }
    }
    highlightError = false;
    buffer.insert(base, keyword);
    /*
         * When formatting geometry coordinates, we may need to shift all numbers by the width
         * of the keyword inserted above in order to keep numbers properly aligned. Exemple:
         *
         *     BOX[ 4.000 -10.000
         *         50.000   2.000]
         */
    if (keywordSpaceAt != null) {
        final int length = keyword.length();
        final CharSequence additionalMargin = CharSequences.spaces(keyword.codePointCount(0, length));
        final int n = keywordSpaceAt.size();
        for (int i = 0; i < n; ) {
            int p = keywordSpaceAt.getInt(i);
            // Take in account spaces added previously.
            p += (++i * length);
            buffer.insert(p, additionalMargin);
        }
        keywordSpaceAt.clear();
    }
    /*
         * Format the SCOPE["…"], AREA["…"] and other elements. Some of those information
         * are available only for Datum, CoordinateOperation and ReferenceSystem objects.
         */
    if (info == null && convention.majorVersion() != 1 && object instanceof GeneralParameterValue) {
        info = ((GeneralParameterValue) object).getDescriptor();
    }
    if (info != null) {
        appendComplement(info, (stackDepth >= 1) ? enclosingElements.get(stackDepth - 1) : null, (stackDepth >= 2) ? enclosingElements.get(stackDepth - 2) : null);
    }
    /*
         * Close the bracket, then update the queue of enclosed elements by removing this element.
         */
    buffer.appendCodePoint(symbols.getClosingBracket(0));
    indent(-1);
    enclosingElements.remove(stackDepth);
    hasContextualUnit >>>= 1;
}
Also used : Locale(java.util.Locale) GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) InternationalString(org.opengis.util.InternationalString) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Aggregations

IdentifiedObject (org.opengis.referencing.IdentifiedObject)30 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)15 InternationalString (org.opengis.util.InternationalString)10 FactoryException (org.opengis.util.FactoryException)8 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)5 IdentifiedObjectFinder (org.apache.sis.referencing.factory.IdentifiedObjectFinder)5 DataStoreException (org.apache.sis.storage.DataStoreException)5 Identifier (org.opengis.metadata.Identifier)5 ReferenceIdentifier (org.opengis.referencing.ReferenceIdentifier)5 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)5 HashMap (java.util.HashMap)4 Cache (org.apache.sis.util.collection.Cache)3 Test (org.junit.Test)3 GenericName (org.opengis.util.GenericName)3 NameToIdentifier (org.apache.sis.internal.metadata.NameToIdentifier)2 FormattableObject (org.apache.sis.io.wkt.FormattableObject)2 NamedIdentifier (org.apache.sis.referencing.NamedIdentifier)2 DependsOnMethod (org.apache.sis.test.DependsOnMethod)2 SimpleInternationalString (org.apache.sis.util.iso.SimpleInternationalString)2 Extent (org.opengis.metadata.extent.Extent)2