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

org.mapfish.print.map.readers.WMTSServiceInfo Maven / Gradle / Ivy

/*
 * Copyright (C) 2013  Camptocamp
 *
 * This file is part of MapFish Print
 *
 * MapFish Print is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MapFish Print 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
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MapFish Print.  If not, see .
 */

package org.mapfish.print.map.readers;

import com.vividsolutions.jts.geom.Envelope;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mapfish.print.RenderingContext;
import org.pvalsecc.misc.URIUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;

import static org.mapfish.print.map.readers.ServerInfoCache.ServiceInfoLoader.getTextContentOfChild;

/**
 * Use to get information about a WMS server. Caches the results.
 */
public class WMTSServiceInfo extends ServiceInfo {
    private static final Log LOGGER = LogFactory.getLog(WMTSServiceInfo.class);

    private static final ServerInfoCache cache = new ServerInfoCache(new WMSServiceInfoLoader());

    /**
     * Not null if we actually use a TileCache server.
     */
    final Map tileCacheLayers = new HashMap();

    public static synchronized void clearCache() {
        cache.clearCache();
    }

    public static WMTSServiceInfo getInfo(URI uri, RenderingContext context) {
        return cache.getInfo(uri, context);
    }

    public static WmtsCapabilitiesInfo getLayerInfo(URI uri, String layerId, RenderingContext context) {
        return getInfo(uri, context).tileCacheLayers.get(layerId);
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("WMTSServerInfo");
        sb.append("{tileCacheLayers=").append(tileCacheLayers);
        sb.append('}');
        return sb.toString();
    }

    static class WMSServiceInfoLoader extends ServerInfoCache.ServiceInfoLoader {

        @Override
        public Log logger() {
            return LOGGER;
        }

        @Override
        public WMTSServiceInfo createNewErrorResult() {
            return new WMTSServiceInfo();
        }

        @Override
        public URL createURL(URI baseUrl, RenderingContext context) throws UnsupportedEncodingException, URISyntaxException,
                MalformedURLException {
            Map> queryParams = new HashMap>();
            URIUtils.addParamOverride(queryParams, "SERVICE", "WMTS");
            URIUtils.addParamOverride(queryParams, "REQUEST", "GetCapabilities");
            URIUtils.addParamOverride(queryParams, "VERSION", "1.0.0");
            URL url = URIUtils.addParams(baseUrl, queryParams, HTTPMapReader.OVERRIDE_ALL).toURL();

            return url;
        }

        @Override
        public WMTSServiceInfo parseInfo(InputStream stream) throws ParserConfigurationException, IOException, SAXException {
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

            //we don't want the DTD to be checked and it's the only way I found
            documentBuilder.setEntityResolver(new EntityResolver() {
                public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                    return new InputSource(new StringReader(""));
                }
            });

            Document doc = documentBuilder.parse(stream);

            NodeList tileSets = doc.getElementsByTagName("Layer");

            final WMTSServiceInfo result = new WMTSServiceInfo();

            if (tileSets.getLength() > 0) {
                for (int i = 0; i < tileSets.getLength(); ++i) {
                    try {
                    final Element layer = (Element) tileSets.item(i);

                    String identifier = getTextContentOfChild(layer, "Identifier");
                    String title = getTextContentOfChild(layer, "Title", identifier);

                    ArrayList formats = getTextContentOfChildren(layer, "Format");
                    final String[] lowerCorner = getTextContextFromPath(layer, "WGS84BoundingBox/LowerCorner", "-180 -90").split(" ");
                    final String[] upperCorner = getTextContextFromPath(layer, "WGS84BoundingBox/UpperCorner", "180 90").split(" ");
                    final Envelope bounds = new Envelope(Double.parseDouble(lowerCorner[0]), Double.parseDouble(upperCorner[0]),
                            Double.parseDouble(lowerCorner[1]), Double.parseDouble(upperCorner[1]));

                    Map tileMatrices = new HashMap();
                    final NodeList matrixSetLink = layer.getElementsByTagName("TileMatrixSetLink");
                    for (int j = 0; j < matrixSetLink.getLength(); j++) {
                        Element element = (Element) matrixSetLink.item(j);
                        final TileMatrixSet tileMatrixSet = new TileMatrixSet(element);
                        tileMatrices.put(tileMatrixSet.id, tileMatrixSet);
                    }
                    result.tileCacheLayers.put(identifier, new WmtsCapabilitiesInfo(identifier, title, formats, bounds, tileMatrices));
                    } catch (NoSuchElementException e) {
                        LOGGER.warn(e.getMessage(), e);
                    }
                }
            }

            return result;
        }

    }

    static class TileMatrixSet {
        final String id;
        final Map limits;

        public TileMatrixSet(Element element) {
            id = getTextContentOfChild(element, "TileMatrixSet");
            Map tmpLimits = new HashMap();
            final NodeList tileMatrixLimits = element.getElementsByTagName("TileMatrixLimits");
            for (int j = 0; j < tileMatrixLimits.getLength(); j++) {
                Element el = (Element) tileMatrixLimits.item(j);
                TileMatrixLimit limit = new WMTSServiceInfo.TileMatrixLimit(el);
                tmpLimits.put(limit.id, limit);
            }
            this.limits = Collections.unmodifiableMap(tmpLimits);
        }
    }

    static class TileMatrixLimit {
        final String id;
        final int MinTileRow;
        final int MaxTileRow;
        final int MinTileCol;
        final int MaxTileCol;


        public TileMatrixLimit(Element el) {
            id = getTextContentOfChild(el, "TileMatrix");
            MinTileRow = Integer.parseInt(getTextContentOfChild(el, "MinTileRow"));
            MaxTileRow = Integer.parseInt(getTextContentOfChild(el, "MaxTileRow"));
            MinTileCol = Integer.parseInt(getTextContentOfChild(el, "MinTileCol"));
            MaxTileCol = Integer.parseInt(getTextContentOfChild(el, "MaxTileCol"));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy