package com.revolsys.oracle.recordstore.esri; import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import com.revolsys.geometry.cs.CoordinateSystem; import com.revolsys.geometry.cs.WktCsParser; import com.revolsys.geometry.cs.esri.EsriCoordinateSystems; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.jdbc.io.AbstractJdbcRecordStore; import com.revolsys.record.schema.RecordStoreSchema; public class ArcSdeSpatialReferenceCache { public static ArcSdeSpatialReferenceCache get(final AbstractJdbcRecordStore recordStore) { ArcSdeSpatialReferenceCache spatialReferences = recordStore .getProperty("esriSpatialReferences"); if (spatialReferences == null) { spatialReferences = new ArcSdeSpatialReferenceCache(); recordStore.setProperty("esriSpatialReferences", spatialReferences); } return spatialReferences; } public static ArcSdeSpatialReferenceCache get(final RecordStoreSchema schema) { final AbstractJdbcRecordStore recordStore = (AbstractJdbcRecordStore)schema.getRecordStore(); return get(recordStore); } protected static ArcSdeSpatialReference getSpatialReference(final Connection connection, final RecordStoreSchema schema, final int esriSrid) { final ArcSdeSpatialReferenceCache cache = get(schema); return cache.getSpatialReference(connection, esriSrid); } private final Map<Integer, ArcSdeSpatialReference> spatialReferences = new HashMap<>(); public ArcSdeSpatialReferenceCache() { } protected synchronized ArcSdeSpatialReference getSpatialReference(final Connection connection, final int esriSrid) { ArcSdeSpatialReference spatialReference = this.spatialReferences.get(esriSrid); if (spatialReference == null) { spatialReference = getSpatialReference(connection, "SELECT SRID, SR_NAME, X_OFFSET, Y_OFFSET, Z_OFFSET, M_OFFSET, XYUNITS, Z_SCALE, M_SCALE, CS_ID, DEFINITION FROM SDE.ST_SPATIAL_REFERENCES WHERE SRID = ?", esriSrid); if (spatialReference == null) { spatialReference = getSpatialReference(connection, "SELECT SRID, DESCRIPTION, FALSEX, FALSEY, FALSEZ, FALSEM, XYUNITS, ZUNITS, MUNITS, AUTH_SRID, SRTEXT FROM SDE.SPATIAL_REFERENCES WHERE SRID = ?", esriSrid); } } return spatialReference; } protected ArcSdeSpatialReference getSpatialReference(final Connection connection, final String sql, final int esriSrid) { try ( PreparedStatement statement = connection.prepareStatement(sql);) { statement.setInt(1, esriSrid); try ( ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { final String name = resultSet.getString(2); final BigDecimal xOffset = resultSet.getBigDecimal(3); final BigDecimal yOffset = resultSet.getBigDecimal(4); final BigDecimal zOffset = resultSet.getBigDecimal(5); final BigDecimal mOffset = resultSet.getBigDecimal(6); final double scale = resultSet.getBigDecimal(7).doubleValue(); final double zScale = resultSet.getBigDecimal(8).doubleValue(); final double mScale = resultSet.getBigDecimal(9).doubleValue(); int srid = resultSet.getInt(10); final String wkt = resultSet.getString(11); final GeometryFactory geometryFactory; final double[] scales = { scale, scale, zScale }; if (srid <= 0) { final CoordinateSystem coordinateSystem = new WktCsParser(wkt).parse(); final CoordinateSystem esriCoordinateSystem = EsriCoordinateSystems .getCoordinateSystem(coordinateSystem); srid = esriCoordinateSystem.getCoordinateSystemId(); if (srid <= 0) { geometryFactory = GeometryFactory.fixed(coordinateSystem, 3, scales); } else { geometryFactory = GeometryFactory.fixed(srid, 3, scales); } } else { geometryFactory = GeometryFactory.fixed(srid, 3, scales); } final ArcSdeSpatialReference spatialReference = new ArcSdeSpatialReference( geometryFactory); spatialReference.setEsriSrid(esriSrid); spatialReference.setName(name); spatialReference.setXOffset(xOffset); spatialReference.setYOffset(yOffset); spatialReference.setZOffset(zOffset); spatialReference.setMOffset(mOffset); spatialReference.setXyScale(scale); spatialReference.setZScale(zScale); spatialReference.setMScale(mScale); spatialReference.setSrid(srid); spatialReference.setCsWkt(wkt); this.spatialReferences.put(esriSrid, spatialReference); return spatialReference; } } } catch (final SQLException e) { throw new RuntimeException("Unable to get srid " + esriSrid, e); } return null; } }