Search in sources :

Example 6 with FactoryDataException

use of org.apache.sis.referencing.factory.FactoryDataException in project sis by apache.

the class EPSGDataAccess method createObject.

/**
 * Returns an arbitrary object from a code. The default implementation delegates to more specific methods,
 * for example {@link #createCoordinateReferenceSystem(String)}, {@link #createDatum(String)}, <i>etc.</i>
 * until a successful one is found.
 *
 * <p><strong>Note that this method may be ambiguous</strong> since the same EPSG code can be used for different
 * kind of objects. This method throws an exception if it detects an ambiguity on a <em>best-effort</em> basis.
 * It is recommended to invoke the most specific {@code createFoo(String)} method when the desired type is known,
 * both for performance reason and for avoiding ambiguity.</p>
 *
 * @param  code  value allocated by EPSG.
 * @return the object 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 #createCoordinateReferenceSystem(String)
 * @see #createDatum(String)
 * @see #createCoordinateSystem(String)
 */
@Override
public synchronized IdentifiedObject createObject(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    final boolean isPrimaryKey = isPrimaryKey(code);
    final StringBuilder query = new StringBuilder("SELECT ");
    final int queryStart = query.length();
    int found = -1;
    try {
        final int pk = isPrimaryKey ? toPrimaryKeys(null, null, null, code)[0] : 0;
        for (int i = 0; i < TableInfo.EPSG.length; i++) {
            final TableInfo table = TableInfo.EPSG[i];
            final String column = isPrimaryKey ? table.codeColumn : table.nameColumn;
            if (column == null) {
                continue;
            }
            query.setLength(queryStart);
            query.append(table.codeColumn);
            if (!isPrimaryKey) {
                // Only for filterFalsePositive(…).
                query.append(", ").append(column);
            }
            query.append(" FROM ").append(table.table).append(" WHERE ").append(column).append(isPrimaryKey ? " = ?" : " LIKE ?");
            try (PreparedStatement stmt = connection.prepareStatement(translator.apply(query.toString()))) {
                /*
                     * Check if at least one record is found for the code or the name.
                     * Ensure that there is not two values for the same code or name.
                     */
                if (isPrimaryKey) {
                    stmt.setInt(1, pk);
                } else {
                    stmt.setString(1, toLikePattern(code));
                }
                Integer present = null;
                try (ResultSet result = stmt.executeQuery()) {
                    while (result.next()) {
                        if (isPrimaryKey || SQLUtilities.filterFalsePositive(code, result.getString(2))) {
                            present = ensureSingleton(getOptionalInteger(result, 1), present, code);
                        }
                    }
                }
                if (present != null) {
                    if (found >= 0) {
                        throw new FactoryDataException(error().getString(Errors.Keys.DuplicatedIdentifier_1, code));
                    }
                    found = i;
                }
            }
        }
    } catch (SQLException exception) {
        throw databaseFailure(IdentifiedObject.class, code, exception);
    }
    /*
         * If a record has been found in one table, then delegates to the appropriate method.
         */
    if (found >= 0) {
        switch(found) {
            case 0:
                return createCoordinateReferenceSystem(code);
            case 1:
                return createCoordinateSystem(code);
            case 2:
                return createCoordinateSystemAxis(code);
            case 3:
                return createDatum(code);
            case 4:
                return createEllipsoid(code);
            case 5:
                return createPrimeMeridian(code);
            case 6:
                return createCoordinateOperation(code);
            case 7:
                return createOperationMethod(code);
            case 8:
                return createParameterDescriptor(code);
            // Can not cast Unit to IdentifiedObject
            case 9:
                break;
            // Should not happen
            default:
                throw new AssertionError(found);
        }
    }
    throw noSuchAuthorityCode(IdentifiedObject.class, code);
}
Also used : FactoryDataException(org.apache.sis.referencing.factory.FactoryDataException) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 7 with FactoryDataException

use of org.apache.sis.referencing.factory.FactoryDataException in project sis by apache.

the class EPSGDataAccess method createCoordinateSystemAxes.

/**
 * Returns the coordinate system axis from an EPSG code for a {@link CoordinateSystem}.
 *
 * <p><strong>WARNING:</strong> The EPSG database uses "{@code ORDER}" as a column name.
 * This is tolerated by Access, but MySQL does not accept that name.</p>
 *
 * @param  cs         the EPSG code for the coordinate system.
 * @param  dimension  of the coordinate system, which is also the size of the returned array.
 * @return an array of coordinate system axis.
 * @throws SQLException if an error occurred during database access.
 * @throws FactoryException if the code has not been found.
 */
private CoordinateSystemAxis[] createCoordinateSystemAxes(final Integer cs, final int dimension) throws SQLException, FactoryException {
    int i = 0;
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[dimension];
    try (ResultSet result = executeQuery("AxisOrder", "SELECT COORD_AXIS_CODE" + " FROM [Coordinate Axis]" + " WHERE COORD_SYS_CODE = ?" + " ORDER BY [ORDER]", cs)) {
        while (result.next()) {
            final String axis = getString(cs, result, 1);
            if (i < axes.length) {
                /*
                     * If 'i' is out of bounds, an exception will be thrown after the loop.
                     * We do not want to thrown an ArrayIndexOutOfBoundsException here.
                     */
                axes[i] = owner.createCoordinateSystemAxis(axis);
            }
            ++i;
        }
    }
    if (i != axes.length) {
        throw new FactoryDataException(error().getString(Errors.Keys.MismatchedDimension_2, axes.length, i));
    }
    return axes;
}
Also used : FactoryDataException(org.apache.sis.referencing.factory.FactoryDataException) ResultSet(java.sql.ResultSet) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString)

Example 8 with FactoryDataException

use of org.apache.sis.referencing.factory.FactoryDataException in project sis by apache.

the class EPSGDataAccess method createCoordinateSystemAxis.

/**
 * Creates a coordinate system axis with name, direction, unit and range of values.
 *
 * <div class="note"><b>Example:</b>
 * some EPSG codes for axes are:
 *
 * <table class="sis" summary="EPSG codes examples">
 *   <tr><th>Code</th> <th>Description</th>   <th>Unit</th></tr>
 *   <tr><td>106</td>  <td>Latitude (φ)</td>  <td>degree</td></tr>
 *   <tr><td>107</td>  <td>Longitude (λ)</td> <td>degree</td></tr>
 *   <tr><td>1</td>    <td>Easting (E)</td>   <td>metre</td></tr>
 *   <tr><td>2</td>    <td>Northing (N)</td>  <td>metre</td></tr>
 * </table></div>
 *
 * @param  code  value allocated by EPSG.
 * @return the axis 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 #createCoordinateSystem(String)
 * @see org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis
 */
@Override
public synchronized CoordinateSystemAxis createCoordinateSystemAxis(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    CoordinateSystemAxis returnValue = null;
    try (ResultSet result = executeQuery("Coordinate Axis", "COORD_AXIS_CODE", null, "SELECT COORD_AXIS_CODE," + " COORD_AXIS_NAME_CODE," + " COORD_AXIS_ORIENTATION," + " COORD_AXIS_ABBREVIATION," + " UOM_CODE" + " FROM [Coordinate Axis]" + " WHERE COORD_AXIS_CODE = ?", code)) {
        while (result.next()) {
            final Integer epsg = getInteger(code, result, 1);
            final Integer nameCode = getInteger(code, result, 2);
            final String orientation = getString(code, result, 3);
            final String abbreviation = getString(code, result, 4);
            final String unit = getString(code, result, 5);
            final AxisDirection direction;
            try {
                direction = CoordinateSystems.parseAxisDirection(orientation);
            } catch (IllegalArgumentException exception) {
                throw new FactoryDataException(exception.getLocalizedMessage(), exception);
            }
            final AxisName an = getAxisName(nameCode);
            final CoordinateSystemAxis axis = owner.csFactory.createCoordinateSystemAxis(createProperties("Coordinate Axis", an.name, epsg, an.description, false), abbreviation, direction, owner.createUnit(unit));
            returnValue = ensureSingleton(axis, returnValue, code);
        }
    } catch (SQLException exception) {
        throw databaseFailure(CoordinateSystemAxis.class, code, exception);
    }
    if (returnValue == null) {
        throw noSuchAuthorityCode(CoordinateSystemAxis.class, code);
    }
    return returnValue;
}
Also used : FactoryDataException(org.apache.sis.referencing.factory.FactoryDataException) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString)

Example 9 with FactoryDataException

use of org.apache.sis.referencing.factory.FactoryDataException in project sis by apache.

the class EPSGDataAccess method createCoordinateReferenceSystem.

/**
 * Creates an arbitrary coordinate reference system from a code.
 * The returned object will typically be an instance of {@link GeographicCRS}, {@link ProjectedCRS},
 * {@link VerticalCRS} or {@link CompoundCRS}.
 *
 * <div class="note"><b>Example:</b>
 * some EPSG codes for coordinate reference systems are:
 *
 * <table class="sis" summary="EPSG codes examples">
 *   <tr><th>Code</th> <th>Type</th>          <th>Description</th></tr>
 *   <tr><td>4326</td> <td>Geographic</td>    <td>World Geodetic System 1984</td></tr>
 *   <tr><td>4979</td> <td>Geographic 3D</td> <td>World Geodetic System 1984</td></tr>
 *   <tr><td>4978</td> <td>Geocentric</td>    <td>World Geodetic System 1984</td></tr>
 *   <tr><td>3395</td> <td>Projected</td>     <td>WGS 84 / World Mercator</td></tr>
 *   <tr><td>5714</td> <td>Vertical</td>      <td>Mean Sea Level height</td></tr>
 *   <tr><td>6349</td> <td>Compound</td>      <td>NAD83(2011) + NAVD88 height</td></tr>
 *   <tr><td>5800</td> <td>Engineering</td>   <td>Astra Minas Grid</td></tr>
 * </table></div>
 *
 * @param  code  value allocated by EPSG.
 * @return the coordinate reference system 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.
 */
@Override
public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    CoordinateReferenceSystem returnValue = null;
    try (ResultSet result = executeQuery("Coordinate Reference System", "COORD_REF_SYS_CODE", "COORD_REF_SYS_NAME", // [ 1]
    "SELECT COORD_REF_SYS_CODE," + // [ 2]
    " COORD_REF_SYS_NAME," + // [ 3]
    " AREA_OF_USE_CODE," + // [ 4]
    " CRS_SCOPE," + // [ 5]
    " REMARKS," + // [ 6]
    " DEPRECATED," + // [ 7]
    " COORD_REF_SYS_KIND," + // [ 8] Null for CompoundCRS
    " COORD_SYS_CODE," + // [ 9] Null for ProjectedCRS
    " DATUM_CODE," + // [10] For ProjectedCRS
    " SOURCE_GEOGCRS_CODE," + // [11] For ProjectedCRS
    " PROJECTION_CONV_CODE," + // [12] For CompoundCRS only
    " CMPD_HORIZCRS_CODE," + // [13] For CompoundCRS only
    " CMPD_VERTCRS_CODE" + " FROM [Coordinate Reference System]" + " WHERE COORD_REF_SYS_CODE = ?", code)) {
        while (result.next()) {
            final Integer epsg = getInteger(code, result, 1);
            final String name = getString(code, result, 2);
            final String area = getOptionalString(result, 3);
            final String scope = getOptionalString(result, 4);
            final String remarks = getOptionalString(result, 5);
            final boolean deprecated = getOptionalBoolean(result, 6);
            final String type = getString(code, result, 7);
            /*
                 * Note: Do not invoke 'createProperties' now, even if we have all required informations,
                 *       because the 'properties' map is going to overwritten by calls to 'createDatum', etc.
                 *
                 * The following switch statement should have a case for all "epsg_crs_kind" values enumerated
                 * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases.
                 */
            final CRSFactory crsFactory = owner.crsFactory;
            final CoordinateReferenceSystem crs;
            switch(type.toLowerCase(Locale.US)) {
                /* ----------------------------------------------------------------------
                     *   GEOGRAPHIC CRS
                     *
                     *   NOTE: 'createProperties' MUST be invoked after any call to an other
                     *         'createFoo' method. Consequently, do not factor out.
                     * ---------------------------------------------------------------------- */
                case "geographic 2d":
                case "geographic 3d":
                    {
                        Integer csCode = getInteger(code, result, 8);
                        if (replaceDeprecatedCS) {
                            csCode = DEPRECATED_CS.getOrDefault(csCode, csCode);
                        }
                        final EllipsoidalCS cs = owner.createEllipsoidalCS(csCode.toString());
                        final String datumCode = getOptionalString(result, 9);
                        final GeodeticDatum datum;
                        if (datumCode != null) {
                            datum = owner.createGeodeticDatum(datumCode);
                        } else {
                            final String geoCode = getString(code, result, 10, 9);
                            // Must be closed before call to createGeographicCRS(String)
                            result.close();
                            ensureNoCycle(GeographicCRS.class, epsg);
                            try {
                                datum = owner.createGeographicCRS(geoCode).getDatum();
                            } finally {
                                endOfRecursivity(GeographicCRS.class, epsg);
                            }
                        }
                        crs = crsFactory.createGeographicCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   PROJECTED CRS
                     *
                     *   NOTE: This method invokes itself indirectly, through createGeographicCRS.
                     *         Consequently we can not use 'result' anymore after this block.
                     * ---------------------------------------------------------------------- */
                case "projected":
                    {
                        final String csCode = getString(code, result, 8);
                        final String geoCode = getString(code, result, 10);
                        final String opCode = getString(code, result, 11);
                        // Must be closed before call to createFoo(String)
                        result.close();
                        ensureNoCycle(ProjectedCRS.class, epsg);
                        try {
                            final CartesianCS cs = owner.createCartesianCS(csCode);
                            final Conversion op;
                            try {
                                op = (Conversion) owner.createCoordinateOperation(opCode);
                            } catch (ClassCastException e) {
                                // If happen anyway, the ClassCastException cause will give more hints than just the message.
                                throw (NoSuchAuthorityCodeException) noSuchAuthorityCode(Projection.class, opCode).initCause(e);
                            }
                            final CoordinateReferenceSystem baseCRS;
                            final boolean resumeParamChecks;
                            if (!deprecated) {
                                baseCRS = owner.createCoordinateReferenceSystem(geoCode);
                                resumeParamChecks = false;
                            } else {
                                /*
                                 * If the ProjectedCRS is deprecated, one reason among others may be that it uses one of
                                 * the deprecated coordinate systems. Those deprecated CS used non-linear units like DMS.
                                 * Apache SIS can not instantiate a ProjectedCRS when the baseCRS uses such units, so we
                                 * set a flag asking to replace the deprecated CS by a supported one. Since that baseCRS
                                 * would not be exactly as defined by EPSG, we must not cache it because we do not want
                                 * 'owner.createGeographicCRS(geoCode)' to return that modified CRS. Since the same CRS
                                 * may be recreated every time a deprecated ProjectedCRS is created, we temporarily
                                 * shutdown the loggings in order to avoid the same warning to be logged many time.
                                 */
                                final boolean old = quiet;
                                try {
                                    quiet = true;
                                    replaceDeprecatedCS = true;
                                    // Do not cache that CRS.
                                    baseCRS = createCoordinateReferenceSystem(geoCode);
                                } finally {
                                    replaceDeprecatedCS = false;
                                    quiet = old;
                                }
                                /*
                                 * The crsFactory method calls will indirectly create a parameterized MathTransform.
                                 * Their constructor will try to verify the parameter validity. But some deprecated
                                 * CRS had invalid parameter values (they were deprecated precisely for that reason).
                                 * If and only if we are creating a deprecated CRS, temporarily suspend the parameter
                                 * checks.
                                 */
                                resumeParamChecks = !Semaphores.queryAndSet(Semaphores.SUSPEND_PARAMETER_CHECK);
                            // Try block must be immediately after above line (do not insert any code between).
                            }
                            try {
                                /*
                                 * For a ProjectedCRS, the baseCRS is always geographic. So in theory we would not
                                 * need the 'instanceof' check. However the EPSG dataset version 8.9 also uses the
                                 * "projected" type for CRS that are actually derived CRS. See EPSG:5820 and 5821.
                                 */
                                final Map<String, Object> properties = createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated);
                                if (baseCRS instanceof GeographicCRS) {
                                    crs = crsFactory.createProjectedCRS(properties, (GeographicCRS) baseCRS, op, cs);
                                } else {
                                    crs = crsFactory.createDerivedCRS(properties, baseCRS, op, cs);
                                }
                            } finally {
                                if (resumeParamChecks) {
                                    Semaphores.clear(Semaphores.SUSPEND_PARAMETER_CHECK);
                                }
                            }
                        } finally {
                            endOfRecursivity(ProjectedCRS.class, epsg);
                        }
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   VERTICAL CRS
                     * ---------------------------------------------------------------------- */
                case "vertical":
                    {
                        final VerticalCS cs = owner.createVerticalCS(getString(code, result, 8));
                        final VerticalDatum datum = owner.createVerticalDatum(getString(code, result, 9));
                        crs = crsFactory.createVerticalCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   TEMPORAL CRS
                     *
                     *   NOTE : The original EPSG database does not define any temporal CRS.
                     *          This block is a SIS-specific extension.
                     * ---------------------------------------------------------------------- */
                case "time":
                case "temporal":
                    {
                        final TimeCS cs = owner.createTimeCS(getString(code, result, 8));
                        final TemporalDatum datum = owner.createTemporalDatum(getString(code, result, 9));
                        crs = crsFactory.createTemporalCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   COMPOUND CRS
                     *
                     *   NOTE: This method invokes itself recursively.
                     *         Consequently, we can not use 'result' anymore.
                     * ---------------------------------------------------------------------- */
                case "compound":
                    {
                        final String code1 = getString(code, result, 12);
                        final String code2 = getString(code, result, 13);
                        result.close();
                        final CoordinateReferenceSystem crs1, crs2;
                        ensureNoCycle(CompoundCRS.class, epsg);
                        try {
                            crs1 = owner.createCoordinateReferenceSystem(code1);
                            crs2 = owner.createCoordinateReferenceSystem(code2);
                        } finally {
                            endOfRecursivity(CompoundCRS.class, epsg);
                        }
                        // Note: Do not invoke 'createProperties' sooner.
                        crs = crsFactory.createCompoundCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), crs1, crs2);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   GEOCENTRIC CRS
                     * ---------------------------------------------------------------------- */
                case "geocentric":
                    {
                        final CoordinateSystem cs = owner.createCoordinateSystem(getString(code, result, 8));
                        final GeodeticDatum datum = owner.createGeodeticDatum(getString(code, result, 9));
                        final Map<String, Object> properties = createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated);
                        if (cs instanceof CartesianCS) {
                            crs = crsFactory.createGeocentricCRS(properties, datum, (CartesianCS) cs);
                        } else if (cs instanceof SphericalCS) {
                            crs = crsFactory.createGeocentricCRS(properties, datum, (SphericalCS) cs);
                        } else {
                            throw new FactoryDataException(error().getString(Errors.Keys.IllegalCoordinateSystem_1, cs.getName()));
                        }
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   ENGINEERING CRS
                     * ---------------------------------------------------------------------- */
                case "engineering":
                    {
                        final CoordinateSystem cs = owner.createCoordinateSystem(getString(code, result, 8));
                        final EngineeringDatum datum = owner.createEngineeringDatum(getString(code, result, 9));
                        crs = crsFactory.createEngineeringCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   PARAMETRIC CRS
                     * ---------------------------------------------------------------------- */
                case "parametric":
                    {
                        final DefaultParametricCS cs = owner.createParametricCS(getString(code, result, 8));
                        final DefaultParametricDatum datum = owner.createParametricDatum(getString(code, result, 9));
                        crs = ReferencingServices.getInstance().createParametricCRS(createProperties("Coordinate Reference System", name, epsg, area, scope, remarks, deprecated), datum, cs, crsFactory);
                        break;
                    }
                /* ----------------------------------------------------------------------
                     *   UNKNOWN CRS
                     * ---------------------------------------------------------------------- */
                default:
                    {
                        throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
                    }
            }
            returnValue = ensureSingleton(crs, returnValue, code);
            if (result.isClosed()) {
                return returnValue;
            }
        }
    } catch (SQLException exception) {
        throw databaseFailure(CoordinateReferenceSystem.class, code, exception);
    }
    if (returnValue == null) {
        throw noSuchAuthorityCode(CoordinateReferenceSystem.class, code);
    }
    return returnValue;
}
Also used : SQLException(java.sql.SQLException) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) ResultSet(java.sql.ResultSet) DefaultParametricDatum(org.apache.sis.referencing.datum.DefaultParametricDatum) NoSuchAuthorityCodeException(org.opengis.referencing.NoSuchAuthorityCodeException) DefaultParametricCS(org.apache.sis.referencing.cs.DefaultParametricCS) DefaultGeodeticDatum(org.apache.sis.referencing.datum.DefaultGeodeticDatum) FactoryDataException(org.apache.sis.referencing.factory.FactoryDataException) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap)

Example 10 with FactoryDataException

use of org.apache.sis.referencing.factory.FactoryDataException in project sis by apache.

the class EPSGDataAccess method createCoordinateSystem.

/**
 * Creates an arbitrary coordinate system from a code. The returned object will typically be an
 * instance of {@link EllipsoidalCS}, {@link CartesianCS} or {@link VerticalCS}.
 *
 * <div class="note"><b>Example:</b>
 * some EPSG codes for coordinate systems are:
 *
 * <table class="sis" summary="EPSG codes examples">
 *   <tr><th>Code</th> <th>Type</th>              <th>Axes</th>                                    <th>Orientations</th> <th>Unit</th></tr>
 *   <tr><td>4406</td> <td>Cartesian 2D CS</td>   <td>easting, northing (E,N)</td>                 <td>east, north</td>     <td>kilometre</td></tr>
 *   <tr><td>4496</td> <td>Cartesian 2D CS</td>   <td>easting, northing (E,N)</td>                 <td>east, north</td>     <td>metre</td></tr>
 *   <tr><td>4500</td> <td>Cartesian 2D CS</td>   <td>northing, easting (N,E)</td>                 <td>north, east</td>     <td>metre</td></tr>
 *   <tr><td>4491</td> <td>Cartesian 2D CS</td>   <td>westing, northing (W,N)</td>                 <td>west, north</td>     <td>metre</td></tr>
 *   <tr><td>6422</td> <td>Ellipsoidal 2D CS</td> <td>latitude, longitude</td>                     <td>north, east</td>     <td>degree</td></tr>
 *   <tr><td>6424</td> <td>Ellipsoidal 2D CS</td> <td>longitude, latitude</td>                     <td>east, north</td>     <td>degree</td></tr>
 *   <tr><td>6429</td> <td>Ellipsoidal 2D CS</td> <td>longitude, latitude</td>                     <td>east, north</td>     <td>radian</td></tr>
 *   <tr><td>6423</td> <td>Ellipsoidal 3D CS</td> <td>latitude, longitude, ellipsoidal height</td> <td>north, east, up</td> <td>degree, degree, metre</td></tr>
 *   <tr><td>6404</td> <td>Spherical 3D CS</td>   <td>latitude, longitude, radius</td>             <td>north, east, up</td> <td>degree, degree, metre</td></tr>
 *   <tr><td>6498</td> <td>Vertical CS</td>       <td>depth (D)</td>                               <td>down</td>            <td>metre</td></tr>
 *   <tr><td>6499</td> <td>Vertical CS</td>       <td>height (H)</td>                              <td>up</td>              <td>metre</td></tr>
 * </table></div>
 *
 * @param  code  value allocated by EPSG.
 * @return the coordinate system 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.
 */
@Override
public synchronized CoordinateSystem createCoordinateSystem(final String code) throws NoSuchAuthorityCodeException, FactoryException {
    ArgumentChecks.ensureNonNull("code", code);
    CoordinateSystem returnValue = null;
    try (ResultSet result = executeQuery("Coordinate System", "COORD_SYS_CODE", "COORD_SYS_NAME", "SELECT COORD_SYS_CODE," + " COORD_SYS_NAME," + " COORD_SYS_TYPE," + " DIMENSION," + " REMARKS," + " DEPRECATED" + " FROM [Coordinate System]" + " WHERE COORD_SYS_CODE = ?", code)) {
        while (result.next()) {
            final Integer epsg = getInteger(code, result, 1);
            final String name = getString(code, result, 2);
            final String type = getString(code, result, 3);
            final int dimension = getInteger(code, result, 4);
            final String remarks = getOptionalString(result, 5);
            final boolean deprecated = getOptionalBoolean(result, 6);
            final CoordinateSystemAxis[] axes = createCoordinateSystemAxes(epsg, dimension);
            // Must be after axes.
            final Map<String, Object> properties = createProperties("Coordinate System", name, epsg, remarks, deprecated);
            /*
                 * The following switch statement should have a case for all "epsg_cs_kind" values enumerated
                 * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases.
                 */
            final CSFactory csFactory = owner.csFactory;
            CoordinateSystem cs = null;
            switch(type.toLowerCase(Locale.US)) {
                case WKTKeywords.ellipsoidal:
                    {
                        switch(dimension) {
                            case 2:
                                cs = csFactory.createEllipsoidalCS(properties, axes[0], axes[1]);
                                break;
                            case 3:
                                cs = csFactory.createEllipsoidalCS(properties, axes[0], axes[1], axes[2]);
                                break;
                        }
                        break;
                    }
                case "cartesian":
                    {
                        // Need lower-case "c"
                        switch(dimension) {
                            case 2:
                                cs = csFactory.createCartesianCS(properties, axes[0], axes[1]);
                                break;
                            case 3:
                                cs = csFactory.createCartesianCS(properties, axes[0], axes[1], axes[2]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.spherical:
                    {
                        switch(dimension) {
                            case 3:
                                cs = csFactory.createSphericalCS(properties, axes[0], axes[1], axes[2]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.vertical:
                case "gravity-related":
                    {
                        switch(dimension) {
                            case 1:
                                cs = csFactory.createVerticalCS(properties, axes[0]);
                                break;
                        }
                        break;
                    }
                case "time":
                case WKTKeywords.temporal:
                    {
                        switch(dimension) {
                            case 1:
                                cs = csFactory.createTimeCS(properties, axes[0]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.parametric:
                    {
                        switch(dimension) {
                            case 1:
                                cs = ReferencingServices.getInstance().createParametricCS(properties, axes[0], csFactory);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.linear:
                    {
                        switch(dimension) {
                            case 1:
                                cs = csFactory.createLinearCS(properties, axes[0]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.polar:
                    {
                        switch(dimension) {
                            case 2:
                                cs = csFactory.createPolarCS(properties, axes[0], axes[1]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.cylindrical:
                    {
                        switch(dimension) {
                            case 3:
                                cs = csFactory.createCylindricalCS(properties, axes[0], axes[1], axes[2]);
                                break;
                        }
                        break;
                    }
                case WKTKeywords.affine:
                    {
                        switch(dimension) {
                            case 2:
                                cs = csFactory.createAffineCS(properties, axes[0], axes[1]);
                                break;
                            case 3:
                                cs = csFactory.createAffineCS(properties, axes[0], axes[1], axes[2]);
                                break;
                        }
                        break;
                    }
                default:
                    {
                        throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
                    }
            }
            if (cs == null) {
                throw new FactoryDataException(resources().getString(Resources.Keys.UnexpectedDimensionForCS_1, type));
            }
            returnValue = ensureSingleton(cs, returnValue, code);
        }
    } catch (SQLException exception) {
        throw databaseFailure(CoordinateSystem.class, code, exception);
    }
    if (returnValue == null) {
        throw noSuchAuthorityCode(CoordinateSystem.class, code);
    }
    return returnValue;
}
Also used : SQLException(java.sql.SQLException) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) FactoryDataException(org.apache.sis.referencing.factory.FactoryDataException) ResultSet(java.sql.ResultSet) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Aggregations

FactoryDataException (org.apache.sis.referencing.factory.FactoryDataException)10 ResultSet (java.sql.ResultSet)9 SimpleInternationalString (org.apache.sis.util.iso.SimpleInternationalString)8 InternationalString (org.opengis.util.InternationalString)8 SQLException (java.sql.SQLException)7 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)4 IdentifiedObject (org.opengis.referencing.IdentifiedObject)4 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 DefaultGeodeticDatum (org.apache.sis.referencing.datum.DefaultGeodeticDatum)2 DefaultParametricDatum (org.apache.sis.referencing.datum.DefaultParametricDatum)2 NoSuchIdentifierException (org.opengis.util.NoSuchIdentifierException)2 PreparedStatement (java.sql.PreparedStatement)1 ParseException (java.text.ParseException)1 Calendar (java.util.Calendar)1 Date (java.util.Date)1 Map (java.util.Map)1 LogRecord (java.util.logging.LogRecord)1 Unit (javax.measure.Unit)1 ParserException (javax.measure.format.ParserException)1