package au.org.aurin.wif.impl;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.geotools.metadata.iso.citation.Citations;
import org.geotools.referencing.CRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import au.org.aurin.wif.exception.io.DataStoreCreationException;
import au.org.aurin.wif.svc.WifKeys;
/**
* The Class AsyncProjectServiceImpl.
*/
@Service
@Qualifier("validatorCRS")
public class ValidatorCRS {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 213432423433L;
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(ValidatorCRS.class);
/**
* Inits the.
*/
@PostConstruct
public void init() {
LOGGER.trace("Initializing version: " + WifKeys.WIF_KEY_VERSION);
}
/**
* Cleanup.
*/
@PreDestroy
public void cleanup() {
LOGGER.trace("Service succesfully cleared! ");
}
/**
* Validate, if the metadata of the provided CRS differs from the ones in
* geotools, falls back to finding the one with the same code. // TODO Find
* out why in some instances instead of returning null, it will hang!
*
* @param crs
* the crs
* @param msg
* the msg
* @return the coordinate reference system
* @throws DataStoreCreationException
* the data store creation exception
*/
public CoordinateReferenceSystem validate(CoordinateReferenceSystem crs,
String msg) throws DataStoreCreationException {
final String declaredCode = CRS.toSRS(crs);
String geotoolsCode = "";
String parsedWKTcode = "";
LOGGER.info("spatial union crs WKT: {}", crs.toWKT());
LOGGER
.info(
"spatial union CRS id= \"{}\" checking for the validity of it in Geotools...",
declaredCode);
try {
try {
geotoolsCode = CRS.lookupIdentifier(crs, false);
} catch (final Exception e) {
LOGGER.error(e.getMessage());
LOGGER
.warn("Got an exception in lookup identifier of original code, defaulting to declared code...");
geotoolsCode = declaredCode;
}
if (geotoolsCode == null) {
LOGGER.debug("invalid original code, defaulting to declared code...");
geotoolsCode = declaredCode;
} else {
LOGGER.debug("geotools found the code of the original crs: {}",
geotoolsCode);
}
final CoordinateReferenceSystem parseWKT = CRS.parseWKT(crs.toWKT());
parsedWKTcode = CRS.lookupIdentifier(parseWKT, false);
LOGGER.debug(
"crs code of parsedWKT : {}, attempting to decode it in geotools...",
parsedWKTcode);
if (parsedWKTcode == null) {
LOGGER
.debug(" invalid WKT ccode found, defaulting to the original code...");
parsedWKTcode = declaredCode;
}
// Check that the provided CRS can be understood by Geotools
if (geotoolsCode.equals(parsedWKTcode)) {
final CoordinateReferenceSystem crsGeootools = CRS
.decode(parsedWKTcode);
crs = crsGeootools;
} else {
msg = msg
+ "Original crs doesn't have a valid code for geotools, most likely geoserver will fail...";
LOGGER.error(msg);
throw new DataStoreCreationException(msg);
}
LOGGER.debug("CRS has been validated!!...");
return crs;
} catch (final NoSuchAuthorityCodeException e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
} catch (final FactoryException e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
} catch (final Exception e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
}
}
/**
* Validate simple, it just doesn't accept invalid codes
*
* @param crs
* the crs
* @param msg
* the msg
* @return the coordinate reference system
* @throws DataStoreCreationException
* the data store creation exception
*/
public CoordinateReferenceSystem validateSimple(
final CoordinateReferenceSystem crs, String msg)
throws DataStoreCreationException {
final String declaredCode = CRS.toSRS(crs);
CoordinateReferenceSystem decodedCrs = null;
msg = msg + "The CRS provided is invalid in geotools";
LOGGER.info("spatial union crs WKT: {}", crs.toWKT());
LOGGER
.info(
"spatial union CRS id= \"{}\" checking for the validity of it in Geotools...",
declaredCode);
try {
final String wkt = crs.toWKT();
final CoordinateReferenceSystem parsedCRS = CRS.parseWKT(wkt);
LOGGER
.debug("CRS WKT has been parsed! Looking up the identifier, may take a while...");
String code = CRS.lookupIdentifier(parsedCRS, true);
if (code == null) {
code = CRS.lookupIdentifier(Citations.EPSG, parsedCRS, true);
if (code == null) {
final Integer codevalue = CRS.lookupEpsgCode(parsedCRS, true);
if (codevalue != null) {
final String str = "EPSG:" + String.valueOf(codevalue);
decodedCrs = CRS.decode(str);
LOGGER.warn("Code found is: {}", str);
} else {
decodedCrs = CRS.decode(WifKeys.CRS_DEFAULT);
LOGGER.warn("Code not found, defaulting to: {}",
WifKeys.CRS_DEFAULT);
}
}
} else {
LOGGER.info("Code found: {}", code);
decodedCrs = CRS.decode(code);
LOGGER.debug("CRS has been validated to {} : {} !!...", decodedCrs
.getName().getAuthority(), decodedCrs.getName().getCode());
}
return decodedCrs;
} catch (final NoSuchAuthorityCodeException e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
} catch (final FactoryException e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
} catch (final Exception e) {
LOGGER.error(msg);
throw new DataStoreCreationException(msg, e);
}
}
}