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

org.mapfish.print.map.image.wms.WmsUtilities Maven / Gradle / Ivy

package org.mapfish.print.map.image.wms;

import com.google.common.base.Strings;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

import org.geotools.data.wms.request.GetMapRequest;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.mapfish.print.URIUtils;
import org.mapfish.print.map.image.wms.WmsLayerParam.ServerType;
import org.opengis.referencing.FactoryException;

import java.awt.Dimension;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * A few methods to help make wms requests for all types of wms layers.
 */
public final class WmsUtilities {
    private WmsUtilities() {
        // intentionally empty
    }

    /**
     * Make a WMS getLayer request and return the image read from the server.
     * @param wmsLayerParam the wms request parameters
     * @param commonURI the uri to use for the requests (excepting parameters of course.)
     * @param imageSize the size of the image to request
     * @param dpi the dpi of the image to request
     * @param angle the angle of the image to request
     * @param bounds the area and projection of the request on the world.
     */
    public static URI makeWmsGetLayerRequest(
            final WmsLayerParam wmsLayerParam,
            final URI commonURI,
            final Dimension imageSize,
            final double dpi,
            final double angle,
            final ReferencedEnvelope bounds) throws FactoryException, URISyntaxException, IOException {
        final GetMapRequest getMapRequest = WmsVersion.lookup(wmsLayerParam.version).
                getGetMapRequest(commonURI.toURL());
        getMapRequest.setBBox(bounds);
        getMapRequest.setDimensions(imageSize.width, imageSize.height);
        getMapRequest.setFormat(wmsLayerParam.imageFormat);
        getMapRequest.setSRS(CRS.lookupIdentifier(bounds.getCoordinateReferenceSystem(), false));

        for (int i = wmsLayerParam.layers.length - 1; i > -1; i--) {
            String layer = wmsLayerParam.layers[i];
            String style = "";
            if (wmsLayerParam.styles != null) {
                style = wmsLayerParam.styles[i];
            }
            getMapRequest.addLayer(layer, style);
        }
        final URI getMapUri = getMapRequest.getFinalURL().toURI();

        Multimap extraParams = HashMultimap.create();
        extraParams.putAll(wmsLayerParam.getMergeableParams());
        extraParams.putAll(wmsLayerParam.getCustomParams());

        if (wmsLayerParam.serverType != null) {
            addDpiParam(extraParams, (int) Math.round(dpi), wmsLayerParam.serverType);
            if (wmsLayerParam.useNativeAngle && angle != 0.0) {
                addAngleParam(extraParams, angle, wmsLayerParam.serverType);
            }
        }
        return URIUtils.addParams(getMapUri, extraParams, Collections.emptySet());

    }

    private static void addDpiParam(final Multimap extraParams,
            final int dpi, final ServerType type) {
        switch (type) {
        case MAPSERVER:
            if (!contains(extraParams, "MAP_RESOLUTION")) {
                extraParams.put("MAP_RESOLUTION", Integer.toString(dpi));
            }
            break;
        case QGISSERVER:
            if (!contains(extraParams, "DPI")) {
                extraParams.put("DPI", Integer.toString(dpi));
            }
            break;
        case GEOSERVER:
            if (!contains(extraParams, "FORMAT_OPTIONS")) {
                extraParams.put("FORMAT_OPTIONS", "dpi:" + Integer.toString(dpi));
            } else if (!isDpiSet(extraParams)) {
                setDpiValue(extraParams, dpi);
            }
            break;
        default:
            break;
        }
    }

    private static void addAngleParam(
            final Multimap extraParams, final double angle, final ServerType type) {
        switch (type) {
            case MAPSERVER:
                if (!contains(extraParams, "MAP_ANGLE")) {
                    extraParams.put("MAP_ANGLE", Double.toString(Math.toDegrees(angle)));
                }
                break;
            case QGISSERVER:
                break;
            case GEOSERVER:
                if (!contains(extraParams, "ANGLE")) {
                    extraParams.put("ANGLE", Double.toString(Math.toDegrees(angle)));
                }
                break;
            default:
                break;
        }
    }

    /**
     * Checks if a map contains a key ignoring upper/lower case.
     */
    private static boolean contains(final Multimap map, final String searchKey) {
        for (String key : map.keys()) {
            if (key.equalsIgnoreCase(searchKey)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Checks if the DPI value is already set for GeoServer.
     */
    private static boolean isDpiSet(final Multimap extraParams) {
        String searchKey = "FORMAT_OPTIONS";
        for (String key : extraParams.keys()) {
            if (key.equalsIgnoreCase(searchKey)) {
                for (String value : extraParams.get(key)) {
                    if (value.toLowerCase().contains("dpi:")) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Set the DPI value for GeoServer if there are already FORMAT_OPTIONS.
     */
    private static void setDpiValue(final Multimap extraParams, final int dpi) {
        String searchKey = "FORMAT_OPTIONS";
        for (String key : extraParams.keys()) {
            if (key.equalsIgnoreCase(searchKey)) {
                Collection values = extraParams.removeAll(key);
                List newValues = new ArrayList();
                for (String value : values) {
                    if (!Strings.isNullOrEmpty(value)) {
                        value += ";dpi:" + Integer.toString(dpi);
                        newValues.add(value);
                    }
                }
                extraParams.putAll(key, newValues);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy