org.integratedmodelling.engine.geospace.coverage.raster.WCS Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* Copyright (C) 2007, 2015:
*
* - Ferdinando Villa - integratedmodelling.org - any
* other authors listed in @author annotations
*
* All rights reserved. This file is part of the k.LAB software suite, meant to enable
* modular, collaborative, integrated development of interoperable data and model
* components. For details, see http://integratedmodelling.org.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the Affero General Public License Version 3 or any later version.
*
* This program is distributed in the hope that it will be useful, but without any
* warranty; without even the implied warranty of merchantability or fitness for a
* particular purpose. See the Affero General Public License for more details.
*
* You should have received a copy of the Affero General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite
* 330, Boston, MA 02111-1307, USA. The license is also available at:
* https://www.gnu.org/licenses/agpl.html
*******************************************************************************/
package org.integratedmodelling.engine.geospace.coverage.raster;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import org.integratedmodelling.api.configuration.IConfiguration;
import org.integratedmodelling.api.monitoring.IMonitor;
import org.integratedmodelling.api.network.API;
import org.integratedmodelling.collections.Path;
import org.integratedmodelling.common.configuration.KLAB;
import org.integratedmodelling.common.utils.NetUtilities;
import org.integratedmodelling.exceptions.KlabException;
import org.integratedmodelling.exceptions.KlabValidationException;
import nu.xom.Attribute;
import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Nodes;
import nu.xom.XPathContext;
public class WCS {
public static final String CRS = "CRS";
public static final String MINX = "MINX";
public static final String MAXX = "MAXX";
public static final String MINY = "MINY";
public static final String MAXY = "MAXY";
public static final String XCELLS = "XCELLS";
public static final String YCELLS = "YCELLS";
public static final String version = "2.0.0";
String service;
public WCS(String serviceUrl) {
this.service = serviceUrl;
}
public Map describeCoverage(String coverage, String authentication, IMonitor monitor)
throws KlabException {
String crs = null;
double maxx = 0, minx = 0, maxy = 0, miny = 0;
int xcells = 0, ycells = 0;
try {
Builder builder = new Builder();
URL url = new URL(service
+ "?service=WCS&version=" + version + "&request=DescribeCoverage&coverageId=" + coverage);
KLAB.info("reading WCS " + version + " coverage description: " + url);
URLConnection connection = url.openConnection();
/*
* set configured timeout
*/
if (KLAB.CONFIG.getProperties().containsKey(IConfiguration.KLAB_CONNECTION_TIMEOUT)) {
int timeout = 1000 * Integer.parseInt(KLAB.CONFIG.getProperties()
.getProperty(IConfiguration.KLAB_CONNECTION_TIMEOUT, "10"));
connection.setConnectTimeout(timeout);
connection.setReadTimeout(timeout);
}
if (authentication != null) {
connection.setRequestProperty(API.AUTHENTICATION_HEADER, authentication);
}
try (InputStream input = connection.getInputStream()) {
Document doc = builder.build(input);
XPathContext xc = XPathContext.makeNamespaceContext(doc.getRootElement());
Nodes nodes = doc.query("//gml:Envelope", xc);
if (nodes.size() > 0) {
Attribute attr = ((Element) nodes.get(0)).getAttribute("srsName");
if (attr != null) {
crs = attr.getValue();
if (!crs.contains("/EPSG/")) {
throw new KlabValidationException(coverage
+ ": projection code not EPSG: only EPSG codes are supported");
}
crs = "EPSG:" + Path.getLast(crs, '/');
}
} else {
throw new KlabValidationException("invalid response reading coverage properties for "
+ coverage);
}
nodes = doc.query("//gml:lowerCorner", xc);
if (nodes.size() > 0) {
double[] xy = splitDoubles(nodes.get(0).getValue());
minx = xy[0];
miny = xy[1];
}
nodes = doc.query("//gml:upperCorner", xc);
if (nodes.size() > 0) {
double[] xy = splitDoubles(nodes.get(0).getValue());
maxx = xy[0];
maxy = xy[1];
}
nodes = doc.query("//gml:GridEnvelope/gml:high", xc);
if (nodes.size() > 0) {
double[] xy = splitDoubles(nodes.get(0).getValue());
xcells = (int) xy[0];
ycells = (int) xy[1];
}
}
} catch (Exception e) {
// monitor.error(e);
throw new KlabValidationException("cannot parse coverage properties for " + coverage);
}
Map ret = new HashMap<>();
/*
* WCS will faithfully abide to the lat/lon bullshit.
*/
if (crs.equals("EPSG:4326")) {
double tmp = maxx;
maxx = maxy;
maxy = tmp;
tmp = minx;
minx = miny;
miny = tmp;
}
ret.put(CRS, crs);
ret.put(MINX, minx);
ret.put(MAXX, maxx);
ret.put(MINY, miny);
ret.put(MAXY, maxy);
ret.put(XCELLS, xcells);
ret.put(YCELLS, ycells);
return ret;
}
public boolean responds() {
return NetUtilities.urlResponds(getCapabilitiesURL());
}
public String getCapabilitiesURL() {
return service + "?service=WCS&version=2.0.0&request=GetCapabilities";
}
public static double[] splitDoubles(String s) {
String[] ss = s.split("\\s+");
double[] dd = new double[ss.length];
for (int i = 0; i < ss.length; i++) {
dd[i] = Double.parseDouble(ss[i]);
}
return dd;
}
}