tim@335: /**
tim@335:  *
tim@335:  */
tim@335: package de.intevation.gnv.state;
tim@335: 
tim@335: import java.util.ArrayList;
tim@335: import java.util.Collection;
tim@511: import java.util.HashMap;
tim@335: import java.util.Iterator;
ingo@470: import java.util.List;
tim@335: 
tim@335: import org.apache.log4j.Logger;
tim@511: import org.w3c.dom.Element;
tim@511: import org.w3c.dom.Node;
tim@511: import org.w3c.dom.NodeList;
tim@335: 
tim@335: import com.vividsolutions.jts.geom.Point;
tim@335: 
tim@511: import de.intevation.artifactdatabase.Config;
tim@335: import de.intevation.gnv.geobackend.base.Result;
tim@335: import de.intevation.gnv.state.describedata.DefaultKeyValueDescribeData;
tim@335: import de.intevation.gnv.state.describedata.KeyValueDescibeData;
tim@335: import de.intevation.gnv.state.describedata.NamedArrayList;
tim@335: import de.intevation.gnv.state.describedata.NamedCollection;
tim@511: import de.intevation.gnv.utils.ArtifactXMLUtilities;
tim@335: import de.intevation.gnv.utils.InputValidator;
ingo@507: import de.intevation.gnv.utils.WKTUtils;
tim@335: import de.intevation.gnv.utils.exception.ValidationException;
tim@335: 
tim@335: /**
tim@335:  * @author Tim Englich <tim.englich@intevation.de>
tim@335:  *
tim@335:  */
tim@335: public class CoordinateSelectionState extends StateBase {
tim@335: 
tim@335:     /**
tim@335:      * the logger, used to log exceptions and additonaly information
tim@335:      */
tim@335:     private static Logger log = Logger.getLogger(CoordinateSelectionState.class);
tim@335:     
tim@335:     /**
tim@335:      * The UID of this Class
tim@335:      */
tim@335:     private static final long serialVersionUID = 6318923553625195063L;
tim@511:     
tim@511:     /**
tim@511:      * XPATH Expressions for the setup.
tim@511:      */
tim@511:     
tim@511:     private final static String MESH_WIDTH_XPATH = "mesh-width";
tim@511:     private final static String XLINK_XPATH = "xlink:href";
tim@511:     private final static String MESH_LIST_XPATH = "/mesh-widths/mesh";
tim@511:     private final static String ID_XPATH = "id";
tim@511:     private final static String WIDTH_VALUE_XPATH = "width";
tim@511:     
tim@511:     /**
tim@511:      * Holds all given Widths between two MeshPoints for different Meshes.
tim@511:      */
tim@511:     private HashMap<String, Double> meshWidths = null;
tim@335: 
tim@335:     /**
tim@335:      * Constructor
tim@335:      */
tim@335:     public CoordinateSelectionState() {
tim@335:         super();
tim@335:     }
tim@335: 
tim@335:     @Override
ingo@607:     protected List<Object> purifyResult(Collection<Result> result, String uuid) {
tim@335:         log.debug("CoordinateSelectionState.purifyResult");
ingo@607:         List<Object> describeData = new ArrayList<Object>();
ingo@607: 
ingo@607:         NamedCollection<KeyValueDescibeData> keyValueDescibeData =
ingo@607:             extractKVP(result, "FEATUREID", "SHAPE");
ingo@607: 
tim@335:         describeData.add(keyValueDescibeData);
ingo@607:         return describeData;
tim@335:     }
ingo@607: 
tim@511:     /**
tim@511:      * @see de.intevation.gnv.state.StateBase#prepareInputData4RegionDBQuery(java.lang.String)
tim@511:      */
tim@335:     @Override
tim@335:     protected String prepareInputData4RegionDBQuery(String value) {
tim@335:         log.debug("CoordinateSelectionState.prepareInputData4RegionDBQuery");
tim@335:         double distance=0.;
tim@335:         String returnValue = null;
tim@335:         try {
tim@335:             Point center = new InputValidator().getPointValue(value);
tim@511:             String meshId = super.inputData.get("meshid").getValue();
tim@335:             int segments = 97;
tim@511:             if (meshWidths != null){
tim@511:                 Double distanceValue = this.meshWidths.get(meshId);
tim@511:                 if (distanceValue != null){
tim@511:                     log.debug("User "+distanceValue+" as Buffer around given Point");
tim@511:                     distance = distanceValue.doubleValue();
tim@511:                 }else{
tim@511:                     log.warn("No distance is configured for Mesh with id"+ meshId);
tim@511:                 }
tim@511:             }else{
tim@511:                 log.warn("No MeshWidth configured. Check if this is correct.");
tim@335:             }
tim@335:             returnValue = center.buffer(distance,segments).toText();
tim@335:         } catch (NumberFormatException e) {
tim@335:             log.error(e,e);
tim@335:         } catch (ValidationException e) {
tim@335:             log.error(e,e);
tim@335:         }
tim@335:         return returnValue;
tim@335:         
tim@335:     }
tim@335:     
tim@335:     /**
tim@335:      * @see de.intevation.gnv.state.StateBase#extractKVP(java.util.Collection, java.lang.String, java.lang.String)
tim@335:      */
tim@335:     @Override
tim@335:     protected NamedCollection<KeyValueDescibeData> extractKVP(
tim@335:             Collection<Result> result,
tim@335:             String keyid,
tim@335:             String valueid) {
tim@335:         Iterator<Result> rit = result.iterator();
tim@335:         NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>(
tim@335:         this.dataName, result.size());
tim@335:         keyValueDescibeData.setMultiSelect(this.dataMultiSelect);
tim@335:         String prevKey = null;
tim@335:         while (rit.hasNext()) {
tim@335:             Result resultValue = rit.next();
tim@335:             String key = resultValue.getString(keyid);
tim@461:             if(prevKey == null || !prevKey.equals(key)){ // TODO: FIXME: We have to do that because the arcsde does not support a distinct Query on Layers
tim@335:                 String geomString = this.convert2DisplayCoordinate(resultValue.getString(valueid));
tim@335:                 String value = geomString;
tim@335:                 if (resultValue.getResultDescriptor().getColumnIndex("VALUE") > 0){
tim@335:                     value = resultValue.getString("VALUE") + " - "+value;
tim@335:                 }
tim@335:                 
tim@335:                 
tim@335:                 keyValueDescibeData.add(new DefaultKeyValueDescribeData(key,value ));
tim@335:             }
tim@335:             prevKey = key;
tim@335:         }
tim@335:         return keyValueDescibeData;
tim@335:     }
tim@335:     
ingo@507:     protected static String convert2DisplayCoordinate(String wkt){
ingo@507:         return WKTUtils.toText(wkt);
tim@335:     }
tim@511: 
tim@511:     /**
tim@511:      * @see de.intevation.gnv.state.StateBase#setup(org.w3c.dom.Node)
tim@511:      */
tim@511:     @Override
tim@511:     public void setup(Node configuration) {
tim@511:         super.setup(configuration);
tim@511:         Element widthElement = (Element)Config.getNodeXPath(configuration, MESH_WIDTH_XPATH);
tim@511:         
tim@511:         if (widthElement != null){
tim@511:             String fileName = widthElement.getAttribute(XLINK_XPATH);
tim@511:             fileName = Config.replaceConfigDir(fileName);
tim@511:             Node configurationNode = new ArtifactXMLUtilities().readConfiguration(fileName);
tim@511:             NodeList meshNodes = Config.getNodeSetXPath(configurationNode,MESH_LIST_XPATH );
tim@511:             if (meshNodes != null){
tim@511:                 meshWidths = new HashMap<String, Double>(meshNodes.getLength());
tim@511:                 for (int i = 0; i < meshNodes.getLength(); i++){
tim@511:                     Element meshNode = (Element)meshNodes.item(i);
tim@511:                     String id = meshNode.getAttribute(ID_XPATH);
tim@511:                     Double value = Double.parseDouble(meshNode.getAttribute(WIDTH_VALUE_XPATH));
tim@511:                     meshWidths.put(id, value);
tim@511:                 }
tim@511:             }
tim@511:         }else{
tim@511:             log.warn("No Mesh Width defined.");
tim@511:         }
tim@511:     }
tim@335: }