Package org.geoserver.wcs2_0.eo.response

Source Code of org.geoserver.wcs2_0.eo.response.WCSEOCoverageMetadataProvider

package org.geoserver.wcs2_0.eo.response;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.DimensionInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.ows.URLMangler.URLType;
import org.geoserver.ows.util.ResponseUtils;
import org.geoserver.wcs.WCSInfo;
import org.geoserver.wcs2_0.GetCoverage;
import org.geoserver.wcs2_0.eo.WCSEOMetadata;
import org.geoserver.wcs2_0.response.WCS20CoverageMetadataProvider;
import org.geoserver.wcs2_0.response.WCSDimensionsHelper;
import org.geoserver.wcs2_0.util.NCNameResourceCodec;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.CRS.AxisOrder;
import org.geotools.util.logging.Logging;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.NamespaceSupport;

/**
* Encodes the minimal set of EO metadata for a given coverage:
*
* <pre>
*                 <wcseo:EOMetadata>
*                     <eop:EarthObservation gml:id="someEOCoverage1_metadata">
*                         <om:phenomenonTime>
*                             <gml:TimePeriod gml:id="someEOCoverage1_tp">
*                                 <gml:beginPosition>2008-03-13T10:00:06.000</gml:beginPosition>
*                                 <gml:endPosition>2008-03-13T10:20:26.000</gml:endPosition>
*                             </gml:TimePeriod>
*                         </om:phenomenonTime>
*                         <om:resultTime>
*                             <gml:TimeInstant gml:id="someEOCoverage1_archivingdate">
*                                 <gml:timePosition>2001-08-22T11:02:47.999</gml:timePosition>
*                             </gml:TimeInstant>
*                         </om:resultTime>
*                         <om:procedure/>
*                         <om:observedProperty/>
*                         <om:featureOfInterest>
*                             <eop:Footprint gml:id="someEOCoverage1_fp">
*                                 <eop:multiExtentOf>
*                                     <gml:MultiSurface gml:id="someEOCoverage1_ms" srsName="EPSG:4326">
*                                         <gml:surfaceMembers>
*                                             <gml:Polygon gml:id="someEOCoverage1_fppoly">
*                                                 <gml:exterior>
*                                                     <gml:LinearRing>
*                                                         <gml:posList>43.516667 2.1025 43.381667 2.861667 42.862778 2.65 42.996389 1.896944 43.516667 2.1025</gml:posList>
*                                                     </gml:LinearRing>
*                                                 </gml:exterior>
*                                             </gml:Polygon>
*                                         </gml:surfaceMembers>
*                                     </gml:MultiSurface>
*                                 </eop:multiExtentOf>
*                                 <eop:centerOf>
*                                     <gml:Point gml:id="someEOCoverage1_p" srsName="EPSG:4326">
*                                         <gml:pos>43.190833 2.374167</gml:pos>
*                                     </gml:Point>
*                                 </eop:centerOf>
*                             </eop:Footprint>
*                         </om:featureOfInterest>
*                         <om:result/>
*                         <eop:metaDataProperty>
*                             <eop:EarthObservationMetaData>
*                                 <eop:identifier>someEOCoverage1</eop:identifier>
*                                 <eop:acquisitionType>NOMINAL</eop:acquisitionType>
*                                 <eop:status>ARCHIVED</eop:status>
*                             </eop:EarthObservationMetaData>
*                         </eop:metaDataProperty>
*                     </eop:EarthObservation>
*                 </wcseo:EOMetadata>
* </pre>
*
* @author Andrea Aime - GeoSolutions
*/
public class WCSEOCoverageMetadataProvider implements WCS20CoverageMetadataProvider {
   
    static final Logger LOGGER = Logging.getLogger(WCSEOCoverageMetadataProvider.class);
    private GeoServer gs;

    public WCSEOCoverageMetadataProvider(GeoServer gs) {
        this.gs = gs;
    }
   
    private boolean isEarthObservationEnabled() {
        WCSInfo wcs = gs.getService(WCSInfo.class);
        Boolean enabled = wcs.getMetadata().get(WCSEOMetadata.ENABLED.key, Boolean.class);
        return Boolean.TRUE.equals(enabled);
    }
   
    @Override
    public String[] getSchemaLocations(String schemaBaseURL) {
        if(!isEarthObservationEnabled()) {
            return new String[0];
        }
        String schemaLocation = ResponseUtils.buildURL(schemaBaseURL, "schemas/wcseo/1.0/wcsEOCoverage.xsd",
                null, URLType.RESOURCE);
        return new String[] { WCSEOMetadata.NAMESPACE, schemaLocation };
    }

    @Override
    public void registerNamespaces(NamespaceSupport namespaces) {
        if(!isEarthObservationEnabled()) {
            return;
        }
        namespaces.declarePrefix("wcseo", WCSEOMetadata.NAMESPACE);
        namespaces.declarePrefix("eop", "http://www.opengis.net/eop/2.0");
        namespaces.declarePrefix("gml", "http://www.opengis.net/gml/3.2");
        namespaces.declarePrefix("om", "http://www.opengis.net/om/2.0");
    }

    @Override
    public void encode(Translator tx, Object context) throws IOException {
        if (!(context instanceof CoverageInfo) || !isEarthObservationEnabled()) {
            return;
        }

        CoverageInfo ci = (CoverageInfo) context;
        DimensionInfo time = ci.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class);
        if (time == null) {
            LOGGER.log(Level.FINE, "We received a coverage info that has no " +
                "associated time, cannot add EO metadata to it: "+ ci.prefixedName());
            return;
        }
        GridCoverage2DReader reader = (GridCoverage2DReader) ci.getGridCoverageReader(null, null);
        String coverageId = NCNameResourceCodec.encode(ci);
        WCSDimensionsHelper dimensionHelper = new WCSDimensionsHelper(time, reader, coverageId);
        tx.start("wcseo:EOMetadata");
        tx.start("eop:EarthObservation", atts("gml:id", coverageId + "_metadata"));
       
        // phenomenon time
        tx.start("om:phenomenonTime");
        tx.start("gml:TimePeriod", atts("gml:id", coverageId + "_tp"));
        element(tx, "gml:beginPosition", dimensionHelper.getBeginTime(), null);
        element(tx, "gml:endPosition", dimensionHelper.getEndTime(), null);
        tx.end("gml:TimePeriod");
        tx.end("om:phenomenonTime");
       
        // resultTime
        tx.start("om:resultTime");
        tx.start("gml:TimeInstant", atts("gml:id", coverageId + "_rt"));
        element(tx, "gml:timePosition", dimensionHelper.getEndTime(), null);
        tx.end("gml:TimeInstant");
        tx.end("om:resultTime");
       
        // some empty elements...
        element(tx, "om:procedure", null, null);
        element(tx, "om:observedProperty", null, null);

        // the footprint
        GeneralEnvelope ge = reader.getOriginalEnvelope();
        CoordinateReferenceSystem crs = reader.getCoordinateReferenceSystem();
        String srsName = getSRSName(crs);
        final boolean axisSwap = CRS.getAxisOrder(crs).equals(AxisOrder.EAST_NORTH);
        double minx = ge.getLowerCorner().getOrdinate(axisSwap ? 1 : 0);
        double miny = ge.getLowerCorner().getOrdinate(axisSwap ? 0 : 1);
        double maxx = ge.getUpperCorner().getOrdinate(axisSwap ? 1 : 0);
        double maxy = ge.getUpperCorner().getOrdinate(axisSwap ? 0 : 1);
        tx.start("om:FeatureOfInterest");
        tx.start("eop:Footprint", atts("gml:id", coverageId + "_fp"));
        tx.start("eop:multiExtentOf");
        tx.start("gml:MultiSurface", atts("gml:id", coverageId + "_ms", "srsName", srsName));
        tx.start("gml:surfaceMembers");
        tx.start("gml:Polygon", atts("gml:id", coverageId + "_msp"));
        tx.start("gml:exterior");
        tx.start("gml:LinearRing");
        String posList = posList(minx, miny, minx, maxy, maxx, maxy, maxx, miny, minx, miny);
        element(tx, "gml:posList", posList, null);
        tx.end("gml:LinearRing");
        tx.end("gml:exterior");
        tx.end("gml:Polygon");
        tx.end("gml:surfaceMembers");
        tx.end("gml:MultiSurface");
        tx.end("eop:multiExtentOf");
        double midx = (minx + maxx) / 2;
        double midy = (miny + maxy) / 2;
        tx.start("eop:centerOf");
        tx.start("gml:Point", atts("gml:id", coverageId + "_co", "srsName", srsName));
        element(tx, "gml:pos", midx + " " + midy, null);
        tx.end("gml:Point");
        tx.end("eop:centerOf");
        tx.end("eop:Footprint");
        tx.end("om:FeatureOfInterest");
       
        // fixed metadata properties (at least for the moment)
        tx.start("eop:metaDataProperty");
        tx.start("eop:EarthObservationMetaData");
        element(tx, "eop:identifier", coverageId, null);
        element(tx, "eop:acquisitionType", "NOMINAL", null);
        element(tx, "eop:status", "ARCHIVED", null);
        tx.end("eop:EarthObservationMetaData");
        tx.end("eop:metaDataProperty");
       
        tx.end("eop:EarthObservation");
        tx.end("wcseo:EOMetadata");

    }

    private String posList(double... ordinates) {
        StringBuilder sb = new StringBuilder();
        for (double ord : ordinates) {
            sb.append(ord).append(" ");
        }
        return sb.substring(0, sb.length() - 1);
    }

    private String getSRSName(CoordinateReferenceSystem crs) {
        Integer EPSGCode = null;
        try {
            EPSGCode = CRS.lookupEpsgCode(crs, false);
        } catch (FactoryException e) {
            throw new IllegalStateException("Unable to lookup epsg code for this CRS:"
                    + crs, e);
        }
        if (EPSGCode == null) {
            throw new IllegalStateException("Unable to lookup epsg code for this CRS:"
                    + crs);
        }
        return GetCoverage.SRS_STARTER + EPSGCode;
    }
   
    private void element(Translator tx, String element,
            String content, AttributesImpl attributes) {
        tx.start(element, attributes);
        if(content != null) {
            tx.chars(content);
        }
        tx.end(element);
    }
   
    Attributes atts(String... atts) {
        AttributesImpl attributes = new AttributesImpl();
        for (int i = 0; i < atts.length; i += 2) {
            attributes.addAttribute(null, atts[i], atts[i], null, atts[i + 1]);
        }
        return attributes;
    }

}
TOP

Related Classes of org.geoserver.wcs2_0.eo.response.WCSEOCoverageMetadataProvider

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.