/*
* JGrass - Free Open Source Java GIS http://www.jgrass.org
* (C) HydroloGIS - www.hydrologis.com
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option) any
* later version.
*
* This library 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 Library General Public License for more
* details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; if not, write to the Free Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jgrasstools.hortonmachine.modules.hydrogeomorphology.adige.core;
import java.util.Comparator;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.jgrasstools.hortonmachine.modules.network.PfafstetterNumber;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
/**
* @author Andrea Antonello (www.hydrologis.com)
*/
public abstract class MonitoringPoint
implements
Comparator<MonitoringPoint>,
MonitoringPointsConstants {
public static final int TYPE_HYDROMETER_DISCHARGE = 0;
public static final int TYPE_DAM_SCARICO = 1;
public static final int TYPE_DAM_TURBINATA = 2;
/**
* The identifier id of the data feed into the monitoring point. This identifier makes it
* possible to understand how to calculate the needed output. It is very different from the
* typeIdentifier parameter of the method
* {@link MonitoringPoint#getDataValueAt(Date, Double, int)}.
*/
protected int currentIdentifier = -1;
protected Coordinate position = null;
protected int ID = -1;
protected PfafstetterNumber pfafstetterNumber;
protected String name = " - "; //$NON-NLS-1$
protected String description = " - "; //$NON-NLS-1$
protected int type;
protected int relatedID;
protected Hashtable<String, MonitoringPoint> pfafRelatedMonitoringPointsTable = new Hashtable<String, MonitoringPoint>();
protected boolean isActive = false;
protected double dataTimeInterval = -1;
protected String dataTimeIntervalUnit = ""; //$NON-NLS-1$
protected String srsCode = ""; //$NON-NLS-1$
protected String quantityName = ""; //$NON-NLS-1$
protected String quantityUnit = ""; //$NON-NLS-1$
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public PfafstetterNumber getPfatstetterNumber() {
return pfafstetterNumber;
}
public int getID() {
return ID;
}
public int getRelatedID() {
return relatedID;
}
/**
* Tries to connect another monitoringpoint if that one has a related id equal to that of this
* object. That way it would be possible to add more than one point as related.
*
* @param monitoringPoint the point to connect
* @return true if the connection was successfull
*/
public boolean connectIfPossible( MonitoringPoint monitoringPoint ) {
// check if the other point has this as related id
if (ID == monitoringPoint.getRelatedID()) {
pfafRelatedMonitoringPointsTable.put(monitoringPoint.getPfatstetterNumber().toString(),
monitoringPoint);
return true;
}
return false;
}
/**
* Get the related monitoringpoint. If there are more than one, the pfafstetter number is used
* to chose.
*
* @param pfafStetter used to chose in the points table. Can be null, in which case the first
* found is taken (should be used only if there is only one point in the table)
* @return the related point
*/
public MonitoringPoint getRelatedMonitoringPoint( String pfafStetter ) {
if (pfafStetter != null) {
return pfafRelatedMonitoringPointsTable.get(pfafStetter);
} else {
Set<String> keySet = pfafRelatedMonitoringPointsTable.keySet();
for( String key : keySet ) {
return pfafRelatedMonitoringPointsTable.get(key);
}
return null;
}
}
public int getType() {
return type;
}
public Coordinate getPosition() {
return position;
}
public boolean isActive() {
return isActive;
}
public void setActive( boolean isActive ) {
this.isActive = isActive;
}
/**
* Add a date/value data record to a particular series
*
* @param date date of the record
* @param value value of the record
* @param identifier identifier of the recorded series
*/
public abstract void addDateValueRecord( Date date, Double value, int identifier );
/**
* Add a value/value data record to a particular series (could be level/volume or
* level/discharge)
*
* @param xValue the domain value for the record
* @param yValue the range value for the record
* @param identifier and identifier for the series
*/
public abstract void addValueValueRecord( Double xValue, Double yValue, int identifier );
/**
* Get a data record from a particular serie
*
* @param date the date for which teh value is requested ({@link MonitoringPoint#geodataNovalue} is
* returned, if no value present)
* @param value a value if a value is needed to calculate a result (for example in the case of a
* dam, if the output discharge is based on the input discharge)
* @param tyepIdentifier identifier of the type of output requested. <b>IMPORTANT:</b> this is
* very different from the identifiers used to define the datattypes that are feed into
* the monitoringpoint, which use the {@link MonitoringPoint#currentIdentifier}. <br>
* The typeIdentifier can be of type:<br>
* <ul>
* <li> {@link MonitoringPoint#TYPE_HYDROMETER_DISCHARGE} </li>
* <li> {@link MonitoringPoint#TYPE_DAM_SCARICO} </li>
* <li> {@link MonitoringPoint#TYPE_DAM_TURBINATA} </li>
* </ul>
* @return the value at the requested date
*/
public abstract Double getDataValueAt( Date date, Double value, int tyepIdentifier );
public int compare( MonitoringPoint o1, MonitoringPoint o2 ) {
PfafstetterNumber p1 = o1.getPfatstetterNumber();
PfafstetterNumber p2 = o2.getPfatstetterNumber();
if (p1 != null && p2 != null) {
List<Integer> p1OrdersList = o1.getPfatstetterNumber().getOrdersList();
List<Integer> p2OrdersList = o2.getPfatstetterNumber().getOrdersList();
int levels = p1OrdersList.size();
if (p2OrdersList.size() < levels) {
levels = p2OrdersList.size();
}
/*
* check the numbers to the minor level of the two
*/
for( int i = 0; i < levels; i++ ) {
int thisone = p1OrdersList.get(i);
int otherone = p2OrdersList.get(i);
if (thisone > otherone) {
/*
* if this has major number of the other, then this has to be sorted as minor of
* the other, following the pfafstetter logic that has major numbers towards
* valley
*/
return -1;
} else if (thisone < otherone) {
return 1;
} else {
// if they are equal, go on to the next level
continue;
}
}
return 0;
} else {
if (p1 == null)
System.out.println("Pstaett null for " + o1.getName());
if (p2 == null)
System.out.println("Pstaett null for " + o2.getName());
return -2;
}
}
/**
* Create a featurecollection from a list of monitoringpoints. Based on the position of the
* points and some of their attributes.
*
* @param monitoringPointsList
* @return the featurecollection
*/
public SimpleFeatureCollection toFeatureCollection(
List<MonitoringPoint> monitoringPointsList ) {
// create the feature type
SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
// set the name
b.setName("monitoringpoints");
// add a geometry property
b.add("the_geom", Point.class);
// add some properties
b.add("id", Integer.class);
b.add("relatedid", Integer.class);
b.add("pfaf", String.class);
// build the type
SimpleFeatureType type = b.buildFeatureType();
// create the feature
SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
GeometryFactory gF = new GeometryFactory();
/*
* insert them in inverse order to get them out of the collection in the same order as the
* list
*/
DefaultFeatureCollection newCollection = new DefaultFeatureCollection();
for( int i = 0; i < monitoringPointsList.size(); i++ ) {
MonitoringPoint mp = monitoringPointsList.get(monitoringPointsList.size() - i - 1);
Object[] values = new Object[]{gF.createPoint(mp.getPosition()), mp.getID(),
mp.getRelatedID(), mp.getPfatstetterNumber().toString()};
// add the values
builder.addAll(values);
// build the feature with provided ID
SimpleFeature feature = builder.buildFeature(type.getTypeName() + "." + i);
newCollection.add(feature);
}
return newCollection;
}
}