diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-commons/src/main/java/org/deegree/feature/persistence/FeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-commons/src/main/java/org/deegree/feature/persistence/FeatureStore.java index a9fd82d80f..9db8e8617a 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-commons/src/main/java/org/deegree/feature/persistence/FeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-commons/src/main/java/org/deegree/feature/persistence/FeatureStore.java @@ -40,6 +40,7 @@ import org.deegree.commons.tom.gml.GMLObject; import org.deegree.commons.utils.Pair; +import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.feature.Feature; import org.deegree.feature.persistence.lock.LockManager; import org.deegree.feature.persistence.query.Query; @@ -258,4 +259,11 @@ FeatureStoreTransaction acquireTransaction() LockManager getLockManager() throws FeatureStoreException; + /** + * Returns the CRS of all stored features, if all features and geometries are in the same CRS. + * + * @return the CRS of all stored features, null if not known or the features of geometries are stored in different CRS. + */ + ICRS getStorageCrs(); + } diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStore.java index d418297964..cff005521e 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStore.java @@ -300,7 +300,8 @@ public boolean isAvailable() { * * @return the CRS used for storing the geometries, can be null (keeps original CRS) */ - public ICRS getStorageCRS() { + @Override + public ICRS getStorageCrs() { return storageCRS; } diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStoreTransaction.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStoreTransaction.java index 3d7d726595..40f9239e6f 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStoreTransaction.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-memory/src/main/java/org/deegree/feature/persistence/memory/MemoryFeatureStoreTransaction.java @@ -223,8 +223,8 @@ public List performInsert( FeatureCollection fc, IDGenMode mode ) throws FeatureStoreException { long begin = System.currentTimeMillis(); - if ( fs.getStorageCRS() != null ) { - LOG.debug( "Transforming incoming feature collection to '" + fs.getStorageCRS() + "'" ); + if ( fs.getStorageCrs() != null ) { + LOG.debug( "Transforming incoming feature collection to '" + fs.getStorageCrs() + "'" ); try { fc = transformGeometries( fc ); } catch ( Exception e ) { @@ -436,7 +436,7 @@ private FeatureCollection transformGeometries( FeatureCollection fc ) throws IllegalArgumentException, UnknownCRSException, TransformationException { FeatureCollection transformedFc = new GenericFeatureCollection(); - GeometryTransformer transformer = new GeometryTransformer( fs.getStorageCRS() ); + GeometryTransformer transformer = new GeometryTransformer( fs.getStorageCrs() ); for ( Feature feature : fc ) { transformedFc.add( transformGeometries( feature, transformer ) ); } diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-remotewfs/src/main/java/org/deegree/feature/persistence/remotewfs/RemoteWFSFeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-remotewfs/src/main/java/org/deegree/feature/persistence/remotewfs/RemoteWFSFeatureStore.java index 690d7178d0..114396f8cb 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-remotewfs/src/main/java/org/deegree/feature/persistence/remotewfs/RemoteWFSFeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-remotewfs/src/main/java/org/deegree/feature/persistence/remotewfs/RemoteWFSFeatureStore.java @@ -181,6 +181,11 @@ public Pair calcTemporalExtent( QName ftName, QName datetimeProperty return null; } + @Override + public ICRS getStorageCrs() { + return null; + } + @Override public FeatureInputStream query( Query query ) throws FeatureStoreException, FilterEvaluationException { diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-shape/src/main/java/org/deegree/feature/persistence/shape/ShapeFeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-shape/src/main/java/org/deegree/feature/persistence/shape/ShapeFeatureStore.java index 065abb1c2d..05097524d5 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-shape/src/main/java/org/deegree/feature/persistence/shape/ShapeFeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-shape/src/main/java/org/deegree/feature/persistence/shape/ShapeFeatureStore.java @@ -136,7 +136,7 @@ public class ShapeFeatureStore implements FeatureStore { private String shpName; - private ICRS crs; + private ICRS storageCrs; private Charset encoding; @@ -169,7 +169,7 @@ public class ShapeFeatureStore implements FeatureStore { * * @param shpName * name of the shape file to be loaded, may omit the ".shp" extension, must not be nullnull * @param encoding * encoding used in the dbf file, can be null (encoding guess mode) @@ -185,11 +185,11 @@ public class ShapeFeatureStore implements FeatureStore { * @param mappings * may be null, in which case the original DBF names and 'geometry' will be used */ - public ShapeFeatureStore( String shpName, ICRS crs, Charset encoding, String ftNamespace, String localFtName, + public ShapeFeatureStore( String shpName, ICRS storageCrs, Charset encoding, String ftNamespace, String localFtName, String ftPrefix, boolean generateAlphanumericIndexes, FeatureStoreCache cache, List mappings, ResourceMetadata metadata ) { this.shpName = shpName; - this.crs = crs; + this.storageCrs = storageCrs; this.encoding = encoding; this.mappings = mappings; this.metadata = metadata; @@ -223,14 +223,14 @@ private void getCRSFromFile( File prj ) { in = new BufferedReader( new FileReader( prj ) ); String c = in.readLine().trim(); try { - crs = CRSManager.lookup( c ); - LOG.debug( ".prj contained EPSG code '{}'", crs.getAlias() ); + storageCrs = CRSManager.lookup( c ); + LOG.debug( ".prj contained EPSG code '{}'", storageCrs.getAlias() ); } catch ( UnknownCRSException e2 ) { LOG.warn( "Could not parse the .prj projection file for {}, reason: {}.", shpName, e2.getLocalizedMessage() ); LOG.warn( "The file also does not contain a valid EPSG code, assuming CRS:84 (WGS84 with x/y axis order)." ); LOG.trace( "Stack trace of failed WKT parsing:", e2 ); - crs = CRSManager.lookup( "CRS:84" ); + storageCrs = CRSManager.lookup( "CRS:84" ); } } catch ( IOException e1 ) { LOG.debug( "Stack trace:", e1 ); @@ -257,7 +257,7 @@ private SHPReader getSHP( boolean forceIndexRebuild ) try { LOG.debug( "Loading RTree from disk." ); RTree rtree = RTree.loadFromDisk( shpName + ".rti" ); - shp = new SHPReader( raf, crs, rtree, rtree.getExtraFlag() ); + shp = new SHPReader( raf, storageCrs, rtree, rtree.getExtraFlag() ); } catch ( IOException e ) { LOG.debug( "Stack trace:", e ); LOG.warn( "Existing rtree index could not be read. Generating a new one..." ); @@ -267,13 +267,13 @@ private SHPReader getSHP( boolean forceIndexRebuild ) } } - shp = new SHPReader( raf, crs, null, false ); + shp = new SHPReader( raf, storageCrs, null, false ); LOG.debug( "Building rtree index in memory for '{}'", new File( shpName ).getName() ); Pair, Boolean> p = createIndex( shp ); LOG.debug( "done building index." ); - shp = new SHPReader( raf, crs, p.first, p.second ); + shp = new SHPReader( raf, storageCrs, p.first, p.second ); p.first.writeTreeToDisk( shpName + ".rti" ); return shp; } @@ -613,8 +613,9 @@ public boolean isMaxFeaturesAndStartIndexApplicable( Query[] queries ) { * * @return the CRS used by the shape file, never null */ - public ICRS getStorageCRS() { - return crs; + @Override + public ICRS getStorageCrs() { + return storageCrs; } private class FeatureIterator implements CloseableIterator { @@ -679,7 +680,7 @@ public void init() { LOG.debug( "Loading shape file '{}'", shpName ); - if ( crs == null ) { + if ( storageCrs == null ) { File prj = new File( shpName + ".PRJ" ); if ( !prj.exists() ) { prj = new File( shpName + ".prj" ); @@ -687,31 +688,31 @@ public void init() { if ( prj.exists() ) { try { try { - crs = new WKTParser( prj ).parseCoordinateSystem(); + storageCrs = new WKTParser( prj ).parseCoordinateSystem(); } catch ( IOException e ) { String msg = "The shape datastore for '" + shpName + "' could not be initialized, because no CRS was defined."; throw new ResourceInitException( msg ); } catch ( Exception e1 ) { getCRSFromFile( prj ); - if ( crs == null ) { + if ( storageCrs == null ) { return; } } } catch ( WKTParsingException e ) { getCRSFromFile( prj ); - if ( crs == null ) { + if ( storageCrs == null ) { return; } } } else { LOG.debug( "No crs configured, and no .prj found, assuming CRS:84 (WGS84 in x/y axis order)." ); - crs = CRSManager.getCRSRef( "CRS:84" ); + storageCrs = CRSManager.getCRSRef( "CRS:84" ); } } try { - transformer = new GeometryTransformer( crs ); + transformer = new GeometryTransformer( storageCrs ); } catch ( IllegalArgumentException e ) { LOG.error( "Unknown error", e ); // } catch ( UnknownCRSException e ) { diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-simplesql/src/main/java/org/deegree/feature/persistence/simplesql/SimpleSQLFeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-simplesql/src/main/java/org/deegree/feature/persistence/simplesql/SimpleSQLFeatureStore.java index 69ac46b49b..db5268f166 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-simplesql/src/main/java/org/deegree/feature/persistence/simplesql/SimpleSQLFeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-simplesql/src/main/java/org/deegree/feature/persistence/simplesql/SimpleSQLFeatureStore.java @@ -117,7 +117,7 @@ public class SimpleSQLFeatureStore implements FeatureStore { private boolean available = false; - ICRS crs; + ICRS storageCrs; private AppSchema schema; @@ -143,7 +143,7 @@ public class SimpleSQLFeatureStore implements FeatureStore { /** * @param connId - * @param crs + * @param storageCrs * @param sql * @param ftLocalName * @param ftNamespace @@ -152,7 +152,7 @@ public class SimpleSQLFeatureStore implements FeatureStore { * @param lods * @param metadata */ - public SimpleSQLFeatureStore( ConnectionProvider connProvider, String crs, String sql, String ftLocalName, + public SimpleSQLFeatureStore( ConnectionProvider connProvider, String storageCrs, String sql, String ftLocalName, String ftNamespace, String ftPrefix, String bbox, List> lods, ResourceMetadata metadata ) { this.connProvider = connProvider; @@ -172,13 +172,13 @@ public SimpleSQLFeatureStore( ConnectionProvider connProvider, String crs, Strin this.ftName = new QName( ftNamespace, ftLocalName, ftPrefix ); try { - this.crs = CRSManager.lookup( crs ); - transformer = new GeometryTransformer( this.crs ); + this.storageCrs = CRSManager.lookup( storageCrs ); + transformer = new GeometryTransformer( this.storageCrs ); } catch ( IllegalArgumentException e ) { - LOG.error( "The invalid crs '{}' was specified for the simple SQL data store.", crs ); + LOG.error( "The invalid crs '{}' was specified for the simple SQL data store.", storageCrs ); LOG.trace( "Stack trace:", e ); } catch ( UnknownCRSException e ) { - LOG.error( "The invalid crs '{}' was specified for the simple SQL data store.", crs ); + LOG.error( "The invalid crs '{}' was specified for the simple SQL data store.", storageCrs ); LOG.trace( "Stack trace:", e ); } this.lods = new TreeMap(); @@ -220,7 +220,7 @@ public Envelope calcEnvelope( QName ftName ) { LOG.info( "Could not determine envelope of database table, using world bbox instead." ); return fac.createEnvelope( -180, -90, 180, 90, CRSUtils.EPSG_4326 ); } - Geometry g = new WKTReader( crs ).read( bboxString ); + Geometry g = new WKTReader( storageCrs ).read( bboxString ); cachedEnvelope.first = current; cachedEnvelope.second = g.getEnvelope(); return cachedEnvelope.second; @@ -366,7 +366,8 @@ protected Feature createElement( ResultSet rs ) byte[] bs = rs.getBytes( pt.getName().getLocalPart() ); if ( bs != null ) { try { - Geometry geom = WKBReader.read( bs, crs ); + Geometry geom = WKBReader.read( bs, + storageCrs ); props.add( new GenericProperty( pt, geom ) ); } catch ( ParseException e ) { LOG.info( "WKB from the DB could not be parsed: '{}'.", @@ -426,8 +427,9 @@ public int[] queryHits( Query[] queries ) * * @return the CRS of the geometry column, never null */ - public ICRS getStorageCRS() { - return crs; + @Override + public ICRS getStorageCrs() { + return storageCrs; } @Override diff --git a/deegree-datastores/deegree-featurestores/deegree-featurestore-sql/src/main/java/org/deegree/feature/persistence/sql/SQLFeatureStore.java b/deegree-datastores/deegree-featurestores/deegree-featurestore-sql/src/main/java/org/deegree/feature/persistence/sql/SQLFeatureStore.java index 3418fd9917..ae9c3b0f6f 100644 --- a/deegree-datastores/deegree-featurestores/deegree-featurestore-sql/src/main/java/org/deegree/feature/persistence/sql/SQLFeatureStore.java +++ b/deegree-datastores/deegree-featurestores/deegree-featurestore-sql/src/main/java/org/deegree/feature/persistence/sql/SQLFeatureStore.java @@ -75,6 +75,8 @@ import org.deegree.commons.utils.Pair; import org.deegree.commons.utils.kvp.InvalidParameterValueException; import org.deegree.cs.coordinatesystems.ICRS; +import org.deegree.cs.persistence.CRSManager; +import org.deegree.cs.refs.coordinatesystem.CRSRef; import org.deegree.db.ConnectionProvider; import org.deegree.db.ConnectionProviderProvider; import org.deegree.feature.Feature; @@ -565,6 +567,15 @@ BBoxCache getBBoxCache() { return bboxCache; } + @Override + public ICRS getStorageCrs() { + if ( this.config.getStorageCRS() != null && this.config.getStorageCRS().getValue() != null ) { + String storageCrs = this.config.getStorageCRS().getValue(); + return CRSManager.getCRSRef( storageCrs ); + } + return null; + } + @Override public GMLObject getObjectById( String id ) throws FeatureStoreException {