view gnv-artifacts/src/main/java/de/intevation/gnv/state/CoordinateSelectionState.java @ 1062:58b4a07db856

Cach improvement: remove the cached elements of each visited state that is visited while stepping back to a previous state. gnv-artifacts/trunk@1147 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 02 Jun 2010 09:52:39 +0000
parents 05bf8534a35a
children f953c9a559d8
line wrap: on
line source
package de.intevation.gnv.state;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.vividsolutions.jts.geom.Point;

import de.intevation.artifactdatabase.Config;
import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData;
import de.intevation.gnv.state.describedata.KeyValueDescibeData;
import de.intevation.gnv.state.describedata.NamedArrayList;
import de.intevation.gnv.state.describedata.NamedCollection;
import de.intevation.gnv.utils.ArtifactXMLUtilities;
import de.intevation.gnv.utils.InputValidator;
import de.intevation.gnv.utils.WKTUtils;
import de.intevation.gnv.utils.exception.ValidationException;

/**
 * This state handles coordinate input by the user. It searches database results
 * for coordinates and turns them into a human readable form.
 *
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 *
 */
public class CoordinateSelectionState extends StateBase {

    /**
     * the logger, used to log exceptions and additonaly information
     */
    private static Logger log = Logger.getLogger(CoordinateSelectionState.class);

    /**
     * The UID of this Class
     */
    private static final long serialVersionUID = 6318923553625195063L;

    /**
     * XPATH Expressions for the setup.
     */

    private final static String MESH_WIDTH_XPATH = "mesh-width";
    private final static String XLINK_XPATH = "xlink:href";
    private final static String MESH_LIST_XPATH = "/mesh-widths/mesh";
    private final static String ID_XPATH = "id";
    private final static String WIDTH_VALUE_XPATH = "width";

    /**
     * Holds all given Widths between two MeshPoints for different Meshes.
     */
    private HashMap<String, Double> meshWidths = null;

    /**
     * Constructor
     */
    public CoordinateSelectionState() {
        super();
    }

    @Override
    protected List<Object> purifyResult(Collection<Result> result, String uuid) {
        log.debug("CoordinateSelectionState.purifyResult");
        List<Object> describeData = new ArrayList<Object>();

        NamedCollection<KeyValueDescibeData> keyValueDescibeData =
            extractKVP(result, "FEATUREID", "SHAPE");

        describeData.add(keyValueDescibeData);
        return describeData;
    }


    @Override
    protected String prepareInputData4RegionDBQuery(String value) {
        log.debug("CoordinateSelectionState.prepareInputData4RegionDBQuery");
        double distance=0.;
        String returnValue = null;
        try {
            Point center = InputValidator.getPointValue(value);
            String meshId = super.inputData.get("meshid").getValue();
            int segments = 97;
            if (meshWidths != null){
                Double distanceValue = this.meshWidths.get(meshId);
                if (distanceValue != null){
                    log.debug("User "+distanceValue+" as Buffer around given Point");
                    distance = distanceValue.doubleValue();
                }else{
                    log.warn("No distance is configured for Mesh with id"+ meshId);
                }
            }else{
                log.warn("No MeshWidth configured. Check if this is correct.");
            }
            returnValue = center.buffer(distance,segments).toText();
        } catch (NumberFormatException e) {
            log.error(e,e);
        } catch (ValidationException e) {
            log.error(e,e);
        }
        return returnValue;

    }


    @Override
    protected NamedCollection<KeyValueDescibeData> extractKVP(
            Collection<Result> result,
            String keyid,
            String valueid) {
        Iterator<Result> rit = result.iterator();
        NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>(
        this.dataName, result.size());
        keyValueDescibeData.setMultiSelect(this.dataMultiSelect);
        String prevKey = null;
        while (rit.hasNext()) {
            Result resultValue = rit.next();
            String key = resultValue.getString(keyid);
            if(prevKey == null || !prevKey.equals(key)){ // TODO: FIXME: We have to do that because the arcsde does not support a distinct Query on Layers
                String geomString = CoordinateSelectionState.convert2DisplayCoordinate(resultValue.getString(valueid));
                String value = geomString;
                if (resultValue.getResultDescriptor().getColumnIndex("VALUE") > 0){
                    value = resultValue.getString("VALUE") + " - "+value;
                }


                keyValueDescibeData.add(new DefaultKeyValueDescribeData(key,value ));
            }
            prevKey = key;
        }
        return keyValueDescibeData;
    }

    /**
     * Turn coordinate into a human readable format.
     *
     * @param wkt Coordinate as wkt string.
     * @return formatted coordinate.
     */
    protected static String convert2DisplayCoordinate(String wkt){
        return WKTUtils.toText(wkt);
    }


    @Override
    public void setup(Node configuration) {
        super.setup(configuration);
        Element widthElement = (Element)Config.getNodeXPath(configuration, MESH_WIDTH_XPATH);

        if (widthElement != null){
            String fileName = widthElement.getAttribute(XLINK_XPATH);
            fileName = Config.replaceConfigDir(fileName);
            Node configurationNode = new ArtifactXMLUtilities().readConfiguration(fileName);
            NodeList meshNodes = Config.getNodeSetXPath(configurationNode,MESH_LIST_XPATH );
            if (meshNodes != null){
                meshWidths = new HashMap<String, Double>(meshNodes.getLength());
                for (int i = 0; i < meshNodes.getLength(); i++){
                    Element meshNode = (Element)meshNodes.item(i);
                    String id = meshNode.getAttribute(ID_XPATH);
                    Double value = Double.parseDouble(meshNode.getAttribute(WIDTH_VALUE_XPATH));
                    meshWidths.put(id, value);
                }
            }
        }else{
            log.warn("No Mesh Width defined.");
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org