Package org.vfny.geoserver.wcs.responses

Source Code of org.vfny.geoserver.wcs.responses.DescribeResponse

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.vfny.geoserver.wcs.responses;

import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeSet;
import java.util.logging.Logger;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageDimensionInfo;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.MetadataLinkInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.config.ServiceInfo;
import org.geoserver.wcs.WCSInfo;
import org.geotools.factory.Hints;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.opengis.coverage.grid.GridGeometry;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.datum.DatumFactory;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.vfny.geoserver.Request;
import org.vfny.geoserver.Response;
import org.vfny.geoserver.wcs.WcsException;
import org.vfny.geoserver.wcs.requests.DescribeRequest;
import org.vfny.geoserver.wcs.requests.WCSRequest;


/**
* DOCUMENT ME!
*
* @author $Author: Alessio Fabiani (alessio.fabiani@gmail.com) $ (last
*         modification)
* @author $Author: Simone Giannecchini (simboss1@gmail.com) $ (last
*         modification)
*/
public class DescribeResponse implements Response {
    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.responses");
    private static final String CURR_VER = "\"1.0.0\"";
    private static final String WCS_URL = "http://www.opengis.net/wcs";
    private static final String WCS_NAMESPACE = new StringBuffer("\n  xmlns=\"").append(WCS_URL)
                                                                                .append("\"")
                                                                                .toString();
    private static final String XLINK_URL = "\"http://www.w3.org/1999/xlink\"";
    private static final String XLINK_NAMESPACE = new StringBuffer("\n  xmlns:xlink=").append(XLINK_URL)
                                                                                      .toString();
    private static final String OGC_URL = "\"http://www.opengis.net/ogc\"";
    private static final String OGC_NAMESPACE = new StringBuffer("\n  xmlns:ogc=").append(OGC_URL)
                                                                                  .toString();
    private static final String GML_URL = "\"http://www.opengis.net/gml\"";
    private static final String GML_NAMESPACE = new StringBuffer("\n  xmlns:gml=").append(GML_URL)
                                                                                  .toString();
    private static final String SCHEMA_URI = "\"http://www.w3.org/2001/XMLSchema-instance\"";
    private static final String XSI_NAMESPACE = new StringBuffer("\n  xmlns:xsi=").append(SCHEMA_URI)
                                                                                  .toString();

    /** Fixed return footer information */
    private static final String FOOTER = "\n</CoverageDescription>";

    /**
     *
     * @uml.property name="request"
     * @uml.associationEnd multiplicity="(0 1)"
     */
    private DescribeRequest request;

    /** Main XML class for interpretation and response. */
    private String xmlResponse = new String();

    /**
     * The default datum factory.
     *
     * @uml.property name="datumFactory"
     * @uml.associationEnd multiplicity="(1 1)"
     */
    protected final DatumFactory datumFactory = ReferencingFactoryFinder.getDatumFactory(null);

    /**
     * The service configuration bean this response works upon
     */
    private WCSInfo wcs;

    public DescribeResponse(final WCSInfo wcs) {
        this.wcs = wcs;
    }

    /**
     * Returns any extra headers that this service might want to set in the HTTP response object.
     * @see org.vfny.geoserver.Response#getResponseHeaders()
     */
    public HashMap getResponseHeaders() {
        return null;
    }

    /**
     * The default coordinate reference system factory.
     */

    // protected final static CRSFactory crsFactory =
    // FactoryFinder.getCRSFactory(new
    // Hints(Hints.CRS_AUTHORITY_FACTORY,EPSGCRSAuthorityFactory.class));
    protected final static CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(new Hints(
                Hints.CRS_AUTHORITY_FACTORY, CRSAuthorityFactory.class));

    /**
     * The default math transform factory.
     *
     * @uml.property name="mtFactory"
     * @uml.associationEnd multiplicity="(1 1)"
     */
    protected final MathTransformFactory mtFactory = ReferencingFactoryFinder
        .getMathTransformFactory(null);

    /**
     * The default transformations factory.
     */
    protected final static CoordinateOperationFactory opFactory = ReferencingFactoryFinder
        .getCoordinateOperationFactory(new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE));

    public void execute(Request req) throws WcsException {
        WCSRequest request = (WCSRequest) req;

        if (!(request instanceof DescribeRequest)) {
            throw new WcsException(new StringBuffer(
                    "illegal request type, expected DescribeRequest, got ").append(request)
                                                                                                           .toString());
        }

        DescribeRequest wcsRequest = (DescribeRequest) request;
        this.request = wcsRequest;
        LOGGER.finer("processing describe request" + wcsRequest);

        String outputFormat = wcsRequest.getOutputFormat();

        if (!outputFormat.equalsIgnoreCase("XMLSCHEMA")) {
            throw new WcsException(new StringBuffer("output format: ").append(outputFormat)
                                                                      .append(" not ")
                                                                      .append("supported by geoserver")
                                                                      .toString());
        }

        // generates response, using general function
        xmlResponse = generateCoverages(wcsRequest);

        if (!request.getWCS().getGeoServer().getGlobal().isVerbose()) {
            xmlResponse = xmlResponse.replaceAll(">\n[ \\t\\n]*", ">");
            xmlResponse = xmlResponse.replaceAll("\n[ \\t\\n]*", " ");
        }
    }

    public String getContentType(GeoServer gs) {
        return "text/xml; charset=" + gs.getGlobal().getCharset();
    }

    public String getContentEncoding() {
        return null;
    }

    public String getContentDisposition() {
        return null;
    }

    public void writeTo(OutputStream out) throws WcsException {
        try {
            final Charset encoding = Charset.forName(wcs.getGeoServer().getGlobal().getCharset());
            Writer writer = new OutputStreamWriter(out, encoding);
            writer.write(xmlResponse);
            writer.flush();
        } catch (IOException ex) {
            throw new WcsException(ex, "", getClass().getName());
        }
    }

    private final String generateCoverages(DescribeRequest wcsRequest)
        throws WcsException {
        List requestedTypes = wcsRequest.getCoverages();

        // Initialize return information and intermediate return objects
        StringBuffer tempResponse = new StringBuffer();

        // ComplexType table = new ComplexType();
        if (requestedTypes.size() == 0) {
            // if there are no specific requested types then get all.
          Catalog catalog = wcsRequest.getWCS().getGeoServer().getCatalog();
          requestedTypes = new ArrayList();
          for (CoverageInfo ci : catalog.getCoverages()) {
        requestedTypes.add(ci.getName());
      }
        }

        tempResponse.append("<?xml version=\"1.0\" encoding=\"")
                    .append(wcs.getGeoServer().getGlobal().getCharset()).append("\"?>")
                    .append("\n<CoverageDescription version=").append(CURR_VER).append(" ")
                    .toString();

        tempResponse.append(WCS_NAMESPACE);
        tempResponse.append(XLINK_NAMESPACE);
        tempResponse.append(OGC_NAMESPACE);
        tempResponse.append(GML_NAMESPACE);
        tempResponse.append(XSI_NAMESPACE);
        /*tempResponse.append(" xsi:schemaLocation=\"").append(WCS_URL).append(
                        " ").append(request.getSchemaBaseUrl()).append(
                        "wcs/1.0.0/describeCoverage.xsd\">\n\n");*/
        tempResponse.append(" xsi:schemaLocation=\"").append(WCS_URL).append(" ")
                    .append("http://schemas.opengis.net/wcs/1.0.0/")
                    .append("describeCoverage.xsd\">\n\n");

        tempResponse.append(generateSpecifiedCoverages(requestedTypes, wcsRequest.getWCS()));

        tempResponse.append(FOOTER);

        return tempResponse.toString();
    }

    private String generateSpecifiedCoverages(List requestedTypes, WCSInfo gs)
        throws WcsException {
        String tempResponse = new String();
        String curCoverageName = new String();

        final int length = requestedTypes.size();
        CoverageInfo meta;

        Catalog catalog = gs.getGeoServer().getCatalog();
        for (int i = 0; i < length; i++) {
            curCoverageName = requestedTypes.get(i).toString();

      meta = catalog.getCoverageByName(curCoverageName);

            if (meta == null) {
                throw new WcsException(new StringBuffer("Coverage ").append(curCoverageName)
                                                                    .append(" does ")
                                                                    .append("not exist on this server")
                                                                    .toString());
            }

            try {
              tempResponse = tempResponse + printElement(meta);
            } catch(Exception e) {
              throw new WcsException(e);
            }
        }

        tempResponse = tempResponse + "\n\n";

        return tempResponse;
    }

    private static String printElement(CoverageInfo cv) throws Exception {
        StringBuffer tempResponse = new StringBuffer();

        tempResponse.append("\n <CoverageOffering>");

        if(cv.getMetadataLinks() != null) {
          for (MetadataLinkInfo link : cv.getMetadataLinks()) {
            tempResponse.append("\n  <metadataLink about=\"").append(link.getAbout())
                .append("\" metadataType=\"").append(link.getMetadataType())
                .append("\"/>");
      }
        }

        String tmp = cv.getDescription();

        if ((tmp != null) && (tmp != "")) {
            tempResponse.append("\n  <description>").append(tmp).append("</description>");
        }

        tmp = cv.getName();

        if ((tmp != null) && (tmp != "")) {
            tempResponse.append("\n  <name>").append(tmp).append("</name>");
        }

        tmp = cv.getTitle();

        if ((tmp != null) && (tmp != "")) {
            tempResponse.append("\n  <label>").append(tmp).append("</label>");
        }

        final ReferencedEnvelope envelope = cv.getLatLonBoundingBox();

        tempResponse.append("\n  <lonLatEnvelope" + " srsName=\"WGS84(DD)\"") /*urn:ogc:def:crs:OGC:1.3:CRS84*/
                    .append(">");
        tempResponse.append("\n   <gml:pos>").append(envelope.getLowerCorner().getOrdinate(0))
                    .append(" ").append(envelope.getLowerCorner().getOrdinate(1))
                    .append("</gml:pos>");
        tempResponse.append("\n   <gml:pos>").append(envelope.getUpperCorner().getOrdinate(0))
                    .append(" ").append(envelope.getUpperCorner().getOrdinate(1))
                    .append("</gml:pos>");
        /*tempResponse.append("\n   <gml:timePosition></gml:timePosition>");
        tempResponse.append("\n   <gml:timePosition></gml:timePosition>");*/
        tempResponse.append("\n  </lonLatEnvelope>");

        if ((cv.getKeywords() != null) && (cv.getKeywords().size() > 0)) {
            tempResponse.append("\n  <keywords>");

            for (int i = 0; i < cv.getKeywords().size(); i++)
                tempResponse.append("\n   <keyword>" + cv.getKeywords().get(i) + "</keyword>");

            tempResponse.append("\n  </keywords>");
        }

        // TODO we need to signal somehow that something went wrong
        ReferencedEnvelope cvEnvelope = cv.boundingBox();
        tempResponse.append("\n  <domainSet>");
        tempResponse.append("\n   <spatialDomain>");
        // Envelope
        String userDefinedCrsIdentifier = cv.getSRS();
        tempResponse.append("\n    <gml:Envelope")
                    .append((((userDefinedCrsIdentifier != null) && (userDefinedCrsIdentifier != ""))
            ? new StringBuffer(" srsName=\"").append(userDefinedCrsIdentifier).append("\"").toString() : ""))
                    .append(">");
        tempResponse.append("\n       <gml:pos>")
                    .append((cvEnvelope != null)
            ? new StringBuffer(Double.toString(cvEnvelope.getLowerCorner().getOrdinate(0))).append(
                " ").append(cvEnvelope.getLowerCorner().getOrdinate(1)).toString() : "")
                    .append("</gml:pos>");
        tempResponse.append("\n       <gml:pos>")
                    .append((cvEnvelope != null)
            ? new StringBuffer(Double.toString(cvEnvelope.getUpperCorner().getOrdinate(0))).append(
                " ").append(cvEnvelope.getUpperCorner().getOrdinate(1)).toString() : "")
                    .append("</gml:pos>");
        tempResponse.append("\n    </gml:Envelope>");

        // Grid
    GridGeometry  grid      = cv.getGrid();
    MathTransform gridToCRS = grid.getGridToCRS();
    final int gridDimension = gridToCRS != null ? gridToCRS.getSourceDimensions() : 0;

    // RectifiedGrid
    tempResponse.append("\n    <gml:RectifiedGrid").append(
                   (gridToCRS != null) ? new StringBuffer(" dimension=\"").append(gridDimension).append("\"").toString() : "");
   
    if (userDefinedCrsIdentifier != null) {
        tempResponse.append(" srsName=\"").append(userDefinedCrsIdentifier).append("\"");
    }

    tempResponse.append(">");

    String lowers = "";
    String upers = "";

    for (int r = 0; r < gridDimension; r++) {
      lowers += (grid.getGridRange().getLow(r) + " ");
      upers += (grid.getGridRange().getHigh(r) + " ");
    }

    tempResponse.append("\n       <gml:limits>");
    tempResponse.append("\n         <gml:GridEnvelope>");
    tempResponse.append("\n         <gml:low>"
        + ((cvEnvelope != null) ? lowers : "") + "</gml:low>");
    tempResponse.append("\n         <gml:high>"
        + ((cvEnvelope != null) ? upers : "") + "</gml:high>");
    tempResponse.append("\n         </gml:GridEnvelope>");
    tempResponse.append("\n       </gml:limits>");

    for (CoverageDimensionInfo dimension : cv.getDimensions()) {
        tempResponse.append("\n       <gml:axisName>" + dimension.getName()
            + "</gml:axisName>");
    }

    tempResponse.append("\n       <gml:origin>");
    tempResponse.append("\n       <gml:pos>"
        + (gridToCRS != null ? ((AffineTransform) gridToCRS).getTranslateX() + " " + ((AffineTransform) gridToCRS).getTranslateY()
            : ((cvEnvelope != null) ? (cvEnvelope.getLowerCorner() .getOrdinate(0) + " " + cvEnvelope.getUpperCorner().getOrdinate(1)) : ""))
        + "</gml:pos>");
    tempResponse.append("\n       </gml:origin>");
    tempResponse.append("\n       <gml:offsetVector>"
        + (gridToCRS != null ? ((AffineTransform) gridToCRS).getScaleX() + " " + ((AffineTransform) gridToCRS).getShearX()
            : ((cvEnvelope != null) ? ((cvEnvelope.getUpperCorner().getOrdinate(0) - cvEnvelope.getLowerCorner().getOrdinate(0)) / (grid.getGridRange().getHigh(0) - grid.getGridRange().getLow(0))) : 0.0) + " 0.0")
        + "</gml:offsetVector>");
    tempResponse.append("\n       <gml:offsetVector>"
        + (gridToCRS != null ? ((AffineTransform) gridToCRS).getShearY() + " " + ((AffineTransform) gridToCRS).getScaleY()
            : "0.0 " + ((cvEnvelope != null) ? ((cvEnvelope.getLowerCorner().getOrdinate(1) - cvEnvelope.getUpperCorner().getOrdinate(1)) / (grid.getGridRange().getHigh(1) - grid.getGridRange().getLow(1))) : -0.0))
        + "</gml:offsetVector>");
    tempResponse.append("\n    </gml:RectifiedGrid>");
    tempResponse.append("\n   </spatialDomain>");
   
   
        tempResponse.append("\n  </domainSet>");

        // rangeSet
        TreeSet nodataValues = new TreeSet();

        try {
            if (cv.getDimensions().size() > 0) {
                int numSampleDimensions = cv.getDimensions().size();
                tempResponse.append("\n  <rangeSet>");
                tempResponse.append("\n   <RangeSet>");
                //tempResponse.append("\n    <!--  WARNING: Mandatory metadata '..._rangeset_name' was missing in this context.  --> ");
                tempResponse.append("\n    <name>" + cv.getName() + "</name>");
                tempResponse.append("\n    <label>" + cv.getTitle() + "</label>");
                tempResponse.append("\n      <axisDescription>");
                tempResponse.append("\n        <AxisDescription>");
                tempResponse.append("\n          <name>Band</name>");
                tempResponse.append("\n          <label>Band</label>");
                tempResponse.append("\n          <values>");

                if (numSampleDimensions == 1) {
                    tempResponse.append("\n            <singleValue>").append("1")
                                .append("</singleValue>");
                } else {
                    tempResponse.append("\n            <interval>");
                    tempResponse.append("\n              <min>1</min>");
                    tempResponse.append("\n              <max>" + numSampleDimensions + "</max>");
                    tempResponse.append("\n            </interval>");
                }

                tempResponse.append("\n          </values>");
                tempResponse.append("\n        </AxisDescription>");
                tempResponse.append("\n      </axisDescription>");

                for(CoverageDimensionInfo dim : cv.getDimensions())
                  for(Double nullValue : dim.getNullValues())
                        if (!nodataValues.contains(nullValue)) {
                            nodataValues.add(nullValue);
                        }

                tempResponse.append("\n      <nullValues>");

                if (nodataValues.size() > 0) {
                    if (nodataValues.size() == 1) {
                        tempResponse.append("\n        <singleValue>"
                            + (Double) nodataValues.first() + "</singleValue>");
                    } else {
                        tempResponse.append("\n        <interval>");
                        tempResponse.append("\n          <min>" + (Double) nodataValues.first()
                            + "</min>");
                        tempResponse.append("\n          <max>" + (Double) nodataValues.last()
                            + "</max>");
                        tempResponse.append("\n        <interval>");
                    }
                } else {
                    tempResponse.append("\n        <singleValue>0</singleValue>");
                }

                tempResponse.append("\n      </nullValues>");

                tempResponse.append("\n   </RangeSet>");
                tempResponse.append("\n  </rangeSet>");
            }
        } catch (Exception e) {
            // TODO Handle this exceptions ...
            e.printStackTrace();
        }

        if (((cv.getRequestSRS() != null) && (cv.getRequestSRS().size() > 0))
                || ((cv.getResponseSRS() != null) && (cv.getResponseSRS().size() > 0))) {
            tempResponse.append("\n  <supportedCRSs>");

            if ((cv.getResponseSRS() != null) && (cv.getResponseSRS().size() > 0)
                    && (cv.getRequestSRS() != null) && (cv.getRequestSRS().size() > 0)) {
                tempResponse.append("\n    <requestResponseCRSs>");

                ArrayList CRSs = new ArrayList();

                for (int i = 0; i < cv.getRequestSRS().size(); i++)
                    if (!CRSs.contains(cv.getRequestSRS().get(i))) {
                        CRSs.add(cv.getRequestSRS().get(i));
                    }

                for (int i = 0; i < cv.getResponseSRS().size(); i++)
                    if (!CRSs.contains(cv.getResponseSRS().get(i))) {
                        CRSs.add(cv.getResponseSRS().get(i));
                    }

                for (int i = 0; i < CRSs.size(); i++)
                    tempResponse.append(CRSs.get(i) + " ");
               
                tempResponse.setLength(tempResponse.length()-1);
                tempResponse.append("</requestResponseCRSs>");
            } else {
                if ((cv.getRequestSRS() != null) && (cv.getRequestSRS().size() > 0)) {
                    for (int i = 0; i < cv.getRequestSRS().size(); i++)
                        tempResponse.append("\n    <requestCRSs>" + cv.getRequestSRS().get(i)
                            + "</requestCRSs>");
                }

                if ((cv.getResponseSRS() != null) && (cv.getResponseSRS().size() > 0)) {
                    for (int i = 0; i < cv.getResponseSRS().size(); i++)
                        tempResponse.append("\n    <responseCRSs>" + cv.getResponseSRS().get(i)
                            + "</responseCRSs>");
                }
            }

            tempResponse.append("\n  </supportedCRSs>");
        }

        final String nativeFormat = (((cv.getNativeFormat() != null)
            && cv.getNativeFormat().equalsIgnoreCase("GEOTIFF")) ? "GeoTIFF" : cv.getNativeFormat());
        String supportedFormat = "";

        if (((cv.getSupportedFormats() != null) && (cv.getSupportedFormats().size() > 0))) {
            tempResponse.append("\n  <supportedFormats"
                + (((nativeFormat != null) && (nativeFormat != ""))
                ? (" nativeFormat=\"" + nativeFormat + "\"") : "") + ">");

            for (int i = 0; i < cv.getSupportedFormats().size(); i++) {
                supportedFormat = (String) cv.getSupportedFormats().get(i);
                supportedFormat = (supportedFormat.equalsIgnoreCase("GEOTIFF") ? "GeoTIFF"
                                                                               : supportedFormat);
                tempResponse.append("\n    <formats>" + supportedFormat + "</formats>");
            }

            tempResponse.append("\n  </supportedFormats>");
        }

        if (((cv.getInterpolationMethods() != null) && (cv.getInterpolationMethods().size() > 0))) {
            tempResponse.append("\n  <supportedInterpolations"
                + (((cv.getDefaultInterpolationMethod() != null)
                && (cv.getDefaultInterpolationMethod() != ""))
                ? (" default=\"" + cv.getDefaultInterpolationMethod() + "\"") : "") + ">");

            for (int i = 0; i < cv.getInterpolationMethods().size(); i++)
                tempResponse.append("\n    <interpolationMethod>"
                    + cv.getInterpolationMethods().get(i) + "</interpolationMethod>");

            tempResponse.append("\n  </supportedInterpolations>");
        }

        tempResponse.append("\n </CoverageOffering>");

        return tempResponse.toString();
    }
   
    /*
    * (non-Javadoc)
    *
    * @see org.vfny.geoserver.responses.Response#abort()
    */
    public void abort(ServiceInfo gs) {
        // nothing to undo
    }
}
TOP

Related Classes of org.vfny.geoserver.wcs.responses.DescribeResponse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.