All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy