Package org.geoserver.wms.dynamic.legendgraphic

Source Code of org.geoserver.wms.dynamic.legendgraphic.DynamicGetLegendGraphicDispatcherCallback

package org.geoserver.wms.dynamic.legendgraphic;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geoserver.ows.DispatcherCallback;
import org.geoserver.ows.Request;
import org.geoserver.ows.Response;
import org.geoserver.platform.Operation;
import org.geoserver.platform.Service;
import org.geoserver.platform.ServiceException;
import org.geoserver.wms.GetLegendGraphicRequest;
import org.geotools.process.function.ProcessFunction;
import org.geotools.process.raster.DynamicColorMapProcess;
import org.geotools.process.raster.FilterFunction_svgColorMap;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Style;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Function;

/**
* A {@link DispatcherCallback} which intercepts a getLegendGraphicRequest and check whether that request involve a dynamicColorRamp rendering
* transformation. In that case, it setup a legend based on the dynamic values coming from the request.
*
* @author Daniele Romagnoli, GeoSolutions SAS
*
*/
public class DynamicGetLegendGraphicDispatcherCallback implements DispatcherCallback {

    private static final Logger LOGGER = org.geotools.util.logging.Logging
            .getLogger(DynamicGetLegendGraphicDispatcherCallback.class.getPackage().getName());

    private DynamicColorMapBuilder dynamicColorMapBuilder;

    public DynamicGetLegendGraphicDispatcherCallback(DynamicColorMapBuilder dynamicColorMapBuilder) {
        this.dynamicColorMapBuilder = dynamicColorMapBuilder;
    }

    @Override
    public Request init(Request request) {
        return request;
    }

    @Override
    public Service serviceDispatched(Request request, Service service) throws ServiceException {
        return service;
    }

    @Override
    public Operation operationDispatched(Request request, Operation operation) {
        final String id = operation.getId();

        // only intercepting getLegendGraphic invokation
        if (id.equalsIgnoreCase("getLegendGraphic")) {
            final Object[] params = operation.getParameters();
            if (params != null && params.length > 0 && params[0] instanceof GetLegendGraphicRequest) {

                final GetLegendGraphicRequest getLegendRequest = (GetLegendGraphicRequest) params[0];
                final List<Style> styles = getLegendRequest.getStyles();

                // Retrieving the colorRamp definition
                final String colorRamp = getColorRampDefinition(styles);
                Map map = request.getRawKvp();
                if (colorRamp != null && map.containsKey("LAYER")) {

                    Method method;
                    try {
                        Service service = new Service(operation.getService().getId(),
                                dynamicColorMapBuilder, null, null);
                        method = DynamicColorMapBuilder.class.getMethod("execute", new Class[] {
                                GetLegendGraphicRequest.class, Map.class, String.class });
                        Operation op = new Operation(id, service, method, new Object[] {
                                getLegendRequest, map, colorRamp });
                        return op;
                    } catch (SecurityException e) {
                        if (LOGGER.isLoggable(Level.SEVERE)) {
                            LOGGER.log(
                                    Level.SEVERE,
                                    "Unable to prepare an operation for Dynamic "
                                            + "GetLegendGraphic due to the reported error. Proceeding with default operation");
                        }
                        return operation;
                    } catch (NoSuchMethodException e) {
                        if (LOGGER.isLoggable(Level.SEVERE)) {
                            LOGGER.log(
                                    Level.SEVERE,
                                    "Unable to prepare an operation for Dynamic "
                                            + "GetLegendGraphic due to the reported error. Proceeding with default operation");
                        }
                        return operation;

                    }
                }
            }
        }
        return operation;
    }

    /**
     * Look for a ColorRamp string definition used by a {@link FilterFunction_svgColorMap} if any.
     *
     * @param styles
     * @return
     */
    private String getColorRampDefinition(final List<Style> styles) {
        // Parsing the first style
        if (styles != null && styles.size() > 0) {
            final Style style = styles.get(0);
            final FeatureTypeStyle[] featureTypeStyles = style.featureTypeStyles().toArray(
                    new FeatureTypeStyle[0]);
            for (FeatureTypeStyle featureTypeStyle : featureTypeStyles) {

                // Getting the main transformation
                Expression transformation = featureTypeStyle.getTransformation();
                if (transformation instanceof ProcessFunction) {
                    final ProcessFunction processFunction = (ProcessFunction) transformation;
                    final String processName = processFunction.getName();

                    // Checking whether the processFunction is a DynamicColorMapProcess
                    if (processName.equalsIgnoreCase(DynamicColorMapProcess.NAME)) {
                        return getColorRampDefinition(processFunction);
                    }
                }
            }
        }
        return null;
    }

    /**
     * Look for a ColorRamp definition used by a {@link DynamicColorMapProcess} rendering transformation.
     *
     * @param processFunction
     * @return
     */
    private String getColorRampDefinition(final ProcessFunction processFunction) {
        List<Expression> functionParameters = processFunction.getParameters();
        if (functionParameters.size() == 2) { // 1 is the data, 2 is the colormap
            Expression param = functionParameters.get(1);
            if (param instanceof Function) {
                Function paramFunction = (Function) param;
                List<Expression> functionParams = paramFunction.getParameters();
                if (functionParams.size() == 2) {

                    // Getting the second parameter representing the colorRamp
                    param = functionParams.get(1);
                    if (param instanceof FilterFunction_svgColorMap) {
                        FilterFunction_svgColorMap colorMap = (FilterFunction_svgColorMap) param;
                        List<Expression> colorMapParams = colorMap.getParameters();
                        if (colorMapParams != null && colorMapParams.size() == 3) {
                            return colorMapParams.get(0).toString();
                        }
                    }
                }
            }
        }
        return null;
    }

    @Override
    public Object operationExecuted(Request request, Operation operation, Object result) {
        return result;
    }

    @Override
    public Response responseDispatched(Request request, Operation operation, Object result,
            Response response) {
        return response;
    }

    @Override
    public void finished(Request request) {
    }
}
TOP

Related Classes of org.geoserver.wms.dynamic.legendgraphic.DynamicGetLegendGraphicDispatcherCallback

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.