Skip to content

Commit

Permalink
Merge pull request #1163 from lat-lon/implementPart2Crs-277-PR284
Browse files Browse the repository at this point in the history
Updates needed for implementation of OGC API Features Part 2 (CRS)
  • Loading branch information
copierrj authored Jul 13, 2022
2 parents e67a2ce + bd64493 commit 92ac14c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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, <code>null</code> if not known or the features of geometries are stored in different CRS.
*/
ICRS getStorageCrs();

}
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ public boolean isAvailable() {
*
* @return the CRS used for storing the geometries, can be <code>null</code> (keeps original CRS)
*/
public ICRS getStorageCRS() {
@Override
public ICRS getStorageCrs() {
return storageCRS;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ public List<String> 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 ) {
Expand Down Expand Up @@ -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 ) );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ public Pair<Date, Date> calcTemporalExtent( QName ftName, QName datetimeProperty
return null;
}

@Override
public ICRS getStorageCrs() {
return null;
}

@Override
public FeatureInputStream query( Query query )
throws FeatureStoreException, FilterEvaluationException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public class ShapeFeatureStore implements FeatureStore {

private String shpName;

private ICRS crs;
private ICRS storageCrs;

private Charset encoding;

Expand Down Expand Up @@ -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 <code>null</code
* @param crs
* @param storageCrs
* crs used by the shape file, must not be <code>null</code>
* @param encoding
* encoding used in the dbf file, can be <code>null</code> (encoding guess mode)
Expand All @@ -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<Mapping> mappings, ResourceMetadata<FeatureStore> metadata ) {
this.shpName = shpName;
this.crs = crs;
this.storageCrs = storageCrs;
this.encoding = encoding;
this.mappings = mappings;
this.metadata = metadata;
Expand Down Expand Up @@ -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 );
Expand All @@ -257,7 +257,7 @@ private SHPReader getSHP( boolean forceIndexRebuild )
try {
LOG.debug( "Loading RTree from disk." );
RTree<Long> 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..." );
Expand All @@ -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<RTree<Long>, 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;
}
Expand Down Expand Up @@ -613,8 +613,9 @@ public boolean isMaxFeaturesAndStartIndexApplicable( Query[] queries ) {
*
* @return the CRS used by the shape file, never <code>null</code>
*/
public ICRS getStorageCRS() {
return crs;
@Override
public ICRS getStorageCrs() {
return storageCrs;
}

private class FeatureIterator implements CloseableIterator<Feature> {
Expand Down Expand Up @@ -679,39 +680,39 @@ 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" );
}
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 ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public class SimpleSQLFeatureStore implements FeatureStore {

private boolean available = false;

ICRS crs;
ICRS storageCrs;

private AppSchema schema;

Expand All @@ -143,7 +143,7 @@ public class SimpleSQLFeatureStore implements FeatureStore {

/**
* @param connId
* @param crs
* @param storageCrs
* @param sql
* @param ftLocalName
* @param ftNamespace
Expand All @@ -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<Pair<Integer, String>> lods,
ResourceMetadata<FeatureStore> metadata ) {
this.connProvider = connProvider;
Expand All @@ -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<Integer, String>();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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: '{}'.",
Expand Down Expand Up @@ -426,8 +427,9 @@ public int[] queryHits( Query[] queries )
*
* @return the CRS of the geometry column, never <code>null</code>
*/
public ICRS getStorageCRS() {
return crs;
@Override
public ICRS getStorageCrs() {
return storageCrs;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 92ac14c

Please # to comment.