[Schmitzm-commits] r751 - in trunk/src/schmitzm/jfree/feature: . style
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Mar 3 15:26:40 CET 2010
Author: mojays
Date: 2010-03-03 15:26:40 +0100 (Wed, 03 Mar 2010)
New Revision: 751
Modified:
trunk/src/schmitzm/jfree/feature/AggregationFunction.java
trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java
Log:
Normalization of aggregated (and weighted) attributes.
Modified: trunk/src/schmitzm/jfree/feature/AggregationFunction.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/AggregationFunction.java 2010-03-03 12:48:23 UTC (rev 750)
+++ trunk/src/schmitzm/jfree/feature/AggregationFunction.java 2010-03-03 14:26:40 UTC (rev 751)
@@ -84,7 +84,6 @@
public Double getResult(QuantileBin1D statistics) {
switch (this) {
case AVG:
- case AVG_WEIGHTED:
return statistics.mean();
case MEDIAN:
return statistics.median();
@@ -95,6 +94,7 @@
// case SUM_ABS: // SK: Man müsste beim
// "packen der daten in die Statistik" schon abs() auf die werte
// anwenden und dann diese zeile einkommentieren
+ case AVG_WEIGHTED:
case SUM:
return statistics.sum();
case COUNT:
Modified: trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java
===================================================================
--- trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java 2010-03-03 12:48:23 UTC (rev 750)
+++ trunk/src/schmitzm/jfree/feature/style/FeatureChartUtil.java 2010-03-03 14:26:40 UTC (rev 751)
@@ -59,6 +59,8 @@
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.Name;
+import com.sun.org.apache.xml.internal.security.encryption.AgreementMethod;
+
import schmitzm.geotools.feature.FeatureUtil;
import schmitzm.geotools.feature.PipedFeatureIterator;
import schmitzm.jfree.JFreeChartUtil;
@@ -77,767 +79,732 @@
/**
* This class contains static utility methods related to chart styles based on
* {@link FeatureCollection}.
- *
* @author <a href="mailto:Martin.Schmitz at koeln.de">Martin Schmitz</a>
* @version 1.0
*/
public class FeatureChartUtil {
- final static Logger LOGGER = Logger.getLogger(FeatureChartUtil.class);
+ final static Logger LOGGER = Logger.getLogger(FeatureChartUtil.class);
- /** Instance of {@link ChartStyleXMLFactory}. */
- public static final FeatureChartStyleXMLFactory FEATURE_CHART_STYLE_FACTORY = new FeatureChartStyleXMLFactory();
+ /** Instance of {@link ChartStyleXMLFactory}. */
+ public static final FeatureChartStyleXMLFactory FEATURE_CHART_STYLE_FACTORY = new FeatureChartStyleXMLFactory();
- /**
- * Returns all {@link DatasetSelectionModel DatasetSelectionModels} that can
- * be reached via the renderers of a chart.
- *
- * @param chart
- * a chart
- */
- public static List<FeatureDatasetSelectionModel<?, ?, ?>> getFeatureDatasetSelectionModelFor(
- JFreeChart chart) {
- ArrayList<FeatureDatasetSelectionModel<?, ?, ?>> renderers = new ArrayList<FeatureDatasetSelectionModel<?, ?, ?>>();
+ /**
+ * Returns all {@link DatasetSelectionModel DatasetSelectionModels} that can
+ * be reached via the renderers of a chart.
+ * @param chart a chart
+ */
+ public static List<FeatureDatasetSelectionModel<?, ?, ?>> getFeatureDatasetSelectionModelFor(
+ JFreeChart chart) {
+ ArrayList<FeatureDatasetSelectionModel<?, ?, ?>> renderers = new ArrayList<FeatureDatasetSelectionModel<?, ?, ?>>();
- Plot plot = chart.getPlot();
+ Plot plot = chart.getPlot();
- /** Collect renderers from XYPlot */
- if (plot instanceof XYPlot) {
- XYPlot xyplot = (XYPlot) plot;
+ /** Collect renderers from XYPlot */
+ if (plot instanceof XYPlot) {
+ XYPlot xyplot = (XYPlot) plot;
- for (int i = 0; i < xyplot.getRendererCount(); i++) {
- XYItemRenderer renderer = xyplot.getRenderer(i);
- if (renderer instanceof DatasetSelectionModelProvider
- && ((DatasetSelectionModelProvider) renderer)
- .getSelectionModel() instanceof FeatureDatasetSelectionModel) {
- renderers
- .add((FeatureDatasetSelectionModel) ((DatasetSelectionModelProvider) renderer)
- .getSelectionModel());
- }
- }
- }
- /** Collect renderers from CategoryPlot */
- if (plot instanceof CategoryPlot) {
- CategoryPlot catPlot = (CategoryPlot) plot;
+ for (int i = 0; i < xyplot.getRendererCount(); i++) {
+ XYItemRenderer renderer = xyplot.getRenderer(i);
+ if (renderer instanceof DatasetSelectionModelProvider &&
+ ((DatasetSelectionModelProvider) renderer).getSelectionModel() instanceof FeatureDatasetSelectionModel) {
+ renderers.add((FeatureDatasetSelectionModel) ((DatasetSelectionModelProvider) renderer).getSelectionModel());
+ }
+ }
+ }
+ /** Collect renderers from CategoryPlot */
+ if (plot instanceof CategoryPlot) {
+ CategoryPlot catPlot = (CategoryPlot) plot;
- for (int i = 0; i < catPlot.getRendererCount(); i++) {
- CategoryItemRenderer renderer = catPlot.getRenderer(i);
- if (renderer instanceof DatasetSelectionModelProvider
- && ((DatasetSelectionModelProvider) renderer)
- .getSelectionModel() instanceof FeatureDatasetSelectionModel) {
- renderers
- .add((FeatureDatasetSelectionModel) ((DatasetSelectionModelProvider) renderer)
- .getSelectionModel());
- }
- }
- }
+ for (int i = 0; i < catPlot.getRendererCount(); i++) {
+ CategoryItemRenderer renderer = catPlot.getRenderer(i);
+ if (renderer instanceof DatasetSelectionModelProvider &&
+ ((DatasetSelectionModelProvider) renderer).getSelectionModel() instanceof FeatureDatasetSelectionModel) {
+ renderers.add((FeatureDatasetSelectionModel) ((DatasetSelectionModelProvider) renderer).getSelectionModel());
+ }
+ }
+ }
- return renderers;
- }
+ return renderers;
+ }
- /**
- * Creates a {@link Dataset} for 1 or more attributes of a
- * {@link FeatureCollection}. According to the feature attribute type the
- * method decides whether a {@link XYDataset} or a {@link CategoryDataset}
- * is created:<br>
- * In case of an non-numeric X attribute a {@link CategoryDataset} is
- * created always. Otherwise the default is to create a {@link XYDataset}.
- * The flag {@code forceCat} can be used to create {@link CategoryDataset}
- * for numeric X attributes.
- *
- * @param fc
- * a {@link FeatureCollection}
- * @param forceCat
- * forces a {@link CategoryDataset} also for numeric X attributes
- * @param sort
- * sorts the features according to {@code xAttr} before creating
- * the dataset
- * @param xAttr
- * feature attribute used for the X-value
- * @param yAttr
- * feature attribute(s) used for the Y-value (at least one; for
- * each a series is created in the dataset)
- */
- public static Dataset createDataset(
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- FeatureChartStyle style) {
- String xAttr = style.getAttributeName(0);
- // Check the X attribute to differ between XY- and CategoryDataset
- AttributeDescriptor xDesc = fc.getSchema().getDescriptor(xAttr);
- if (xDesc == null)
- throw new UnsupportedOperationException("Unknown attribute: "
- + xAttr);
+ /**
+ * Creates a {@link Dataset} for 1 or more attributes of a
+ * {@link FeatureCollection}. According to the feature attribute type the
+ * method decides whether a {@link XYDataset} or a {@link CategoryDataset} is
+ * created:<br>
+ * In case of an non-numeric X attribute a {@link CategoryDataset} is created
+ * always. Otherwise the default is to create a {@link XYDataset}. The flag
+ * {@code forceCat} can be used to create {@link CategoryDataset} for numeric
+ * X attributes.
+ * @param fc a {@link FeatureCollection}
+ * @param forceCat forces a {@link CategoryDataset} also for numeric X
+ * attributes
+ * @param sort sorts the features according to {@code xAttr} before creating
+ * the dataset
+ * @param xAttr feature attribute used for the X-value
+ * @param yAttr feature attribute(s) used for the Y-value (at least one; for
+ * each a series is created in the dataset)
+ */
+ public static Dataset createDataset(
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ FeatureChartStyle style) {
+ String xAttr = style.getAttributeName(0);
+ // Check the X attribute to differ between XY- and CategoryDataset
+ AttributeDescriptor xDesc = fc.getSchema().getDescriptor(xAttr);
+ if (xDesc == null)
+ throw new UnsupportedOperationException("Unknown attribute: " + xAttr);
- // If domain attribute is numeric (and category not forced) create
- // a XYDataset
- if (!style.isForceCategories()
- && Number.class.isAssignableFrom(xDesc.getType().getBinding()))
- return createXYDataset(fc, style);
- else
- return createCategoryDataset(fc, style);
- }
+ // If domain attribute is numeric (and category not forced) create
+ // a XYDataset
+ if (!style.isForceCategories() &&
+ Number.class.isAssignableFrom(xDesc.getType().getBinding()))
+ return createXYDataset(fc, style);
+ else
+ return createCategoryDataset(fc, style);
+ }
- /**
- * Checks whether an attribute exists and whether it is of a specific type.
- * Otherwise an {@link IllegalArgumentException} is thrown.
- *
- * @param fType
- * a feature type
- * @param aName
- * the attribute name checked for numeric type
- * @param typeToCheck
- * the type the attribute must support (if {@code null} only the
- * attribute existing is checked!)
- */
- private static void checkAttributeType(SimpleFeatureType fType,
- String aName, Class<?> typeToCheck, String... errDesc) {
- AttributeDescriptor aDesc = fType.getDescriptor(aName);
- if (aDesc == null)
- throw new UnsupportedOperationException("Unknown attribute: "
- + aName);
+ /**
+ * Checks whether an attribute exists and whether it is of a specific type.
+ * Otherwise an {@link IllegalArgumentException} is thrown.
+ * @param fType a feature type
+ * @param aName the attribute name checked for numeric type
+ * @param typeToCheck the type the attribute must support (if {@code null}
+ * only the attribute existing is checked!)
+ */
+ private static void checkAttributeType(SimpleFeatureType fType, String aName,
+ Class<?> typeToCheck, String... errDesc) {
+ AttributeDescriptor aDesc = fType.getDescriptor(aName);
+ if (aDesc == null)
+ throw new UnsupportedOperationException("Unknown attribute: " + aName);
- String attrDesc = errDesc.length > 0 ? errDesc[0] : "Attribute";
- String datasetDesc = errDesc.length > 1 ? errDesc[1] : "Dataset";
+ String attrDesc = errDesc.length > 0 ? errDesc[0] : "Attribute";
+ String datasetDesc = errDesc.length > 1 ? errDesc[1] : "Dataset";
- if (typeToCheck != null
- && !typeToCheck.isAssignableFrom(aDesc.getType().getBinding()))
- throw new UnsupportedOperationException(attrDesc + " must be "
- + typeToCheck.getSimpleName() + " for " + datasetDesc
- + ": " + aName);
- }
+ if (typeToCheck != null &&
+ !typeToCheck.isAssignableFrom(aDesc.getType().getBinding()))
+ throw new UnsupportedOperationException(attrDesc + " must be " +
+ typeToCheck.getSimpleName() +
+ " for " + datasetDesc + ": " +
+ aName);
+ }
- /**
- * Creates a {@link XYDataset} for 2 (or more) attributes of a
- * {@link FeatureCollection}. XYDateset can only be created for
- * <b>numeric</b> attributes.
- *
- * @param fc
- * a {@link FeatureCollection}
- * @param style
- * defines the attributes used to create the dataset from, as
- * well as the sorting and normalization properties
- * @throws IllegalArgumentException
- * if less then 2 attributes are specified
- * @throws UnsupportedOperationException
- * if attributes are not numeric
- */
- public static XYSeriesCollection createXYDataset(
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- FeatureChartStyle chartStyle) {
- int attrCount = chartStyle.getAttributeCount();
- if (attrCount < 2)
- throw new IllegalArgumentException(
- "FeatureChartStyle must define at least 2 attributes to create XYDataset: "
- + attrCount);
- String xAttrName = chartStyle.getAttributeName(ChartStyle.DOMAIN_AXIS);
- // check data types of X attribute
- checkAttributeType(fc.getSchema(), xAttrName, Number.class,
- "Domain attribute", "XYDataset");
- // check data types of Y attribute
- for (int i = 1; i < attrCount; i++)
- checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i),
- Number.class, "Range attribute", "XYDataset");
+ /**
+ * Creates a {@link XYDataset} for 2 (or more) attributes of a
+ * {@link FeatureCollection}. XYDateset can only be created for <b>numeric</b>
+ * attributes.
+ * @param fc a {@link FeatureCollection}
+ * @param style defines the attributes used to create the dataset from, as
+ * well as the sorting and normalization properties
+ * @throws IllegalArgumentException if less then 2 attributes are specified
+ * @throws UnsupportedOperationException if attributes are not numeric
+ */
+ public static XYSeriesCollection createXYDataset(
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ FeatureChartStyle chartStyle) {
+ int attrCount = chartStyle.getAttributeCount();
+ if (attrCount < 2)
+ throw new IllegalArgumentException(
+ "FeatureChartStyle must define at least 2 attributes to create XYDataset: " +
+ attrCount);
+ String xAttrName = chartStyle.getAttributeName(ChartStyle.DOMAIN_AXIS);
+ // check data types of X attribute
+ checkAttributeType(fc.getSchema(), xAttrName, Number.class,
+ "Domain attribute", "XYDataset");
+ // check data types of Y attribute
+ for (int i = 1; i < attrCount; i++)
+ checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i),
+ Number.class, "Range attribute", "XYDataset");
- // Create a series for each range attribute (note: the 0
- // array element useless, but it is more comfortable to
- // use an array of the same size as "attributes"
- XYSeries[] xySeries = new XYSeries[attrCount];
- for (int i = 1; i < xySeries.length; i++)
- xySeries[i] = new XYSeries(chartStyle.getAttributeName(i), false,
- true); // IMPORTANT: Do not use autosort!!
+ // Create a series for each range attribute (note: the 0
+ // array element useless, but it is more comfortable to
+ // use an array of the same size as "attributes"
+ XYSeries[] xySeries = new XYSeries[attrCount];
+ for (int i = 1; i < xySeries.length; i++)
+ xySeries[i] = new XYSeries(chartStyle.getAttributeName(i), false, true); // IMPORTANT
+ // :
+ // Do
+ // not
+ // use
+ // autosort
+ // !
+ // !
- // Create a new dataset and insert the series
- XYSeriesCollection dataset = new XYSeriesCollection();
- Feature2SeriesDatasetMapping mapping = new Feature2SeriesDatasetMapping(
- fc, dataset);
- dataset.setGroup(new FeatureDatasetMetaData(mapping));
- for (int i = 1; i < xySeries.length; i++)
- dataset.addSeries(xySeries[i]);
+ // Create a new dataset and insert the series
+ XYSeriesCollection dataset = new XYSeriesCollection();
+ Feature2SeriesDatasetMapping mapping = new Feature2SeriesDatasetMapping(fc,
+ dataset);
+ dataset.setGroup(new FeatureDatasetMetaData(mapping));
+ for (int i = 1; i < xySeries.length; i++)
+ dataset.addSeries(xySeries[i]);
- // Calculate any statistics needed for normalization.
- HashMap<String, QuantileBin1D> statisticsForNormalization = calcStatisticsForNormalization(
- fc, chartStyle);
- // Prepare set for statistics to calculate aggregation
- // functions (one statistic for each range attribute of
- // each domain value)
- HashMap<Number, QuantileBin1D>[] statisticsForAggregation = new HashMap[attrCount];
- for (int i = 1; i < attrCount; i++)
- statisticsForAggregation[i] = new HashMap<Number, QuantileBin1D>();
+ // Calculate any statistics needed for normalization.
+ HashMap<String, QuantileBin1D> statisticsForNormalization = calcStatisticsForNotAggregatedNormalization(
+ fc,
+ chartStyle);
+ // Prepare set for statistics to calculate aggregation
+ // functions (one statistic for each range attribute of
+ // each domain value)
+ HashMap<Number, QuantileBin1D>[] statisticsForAggregation = new HashMap[attrCount];
+ for (int i = 1; i < attrCount; i++)
+ statisticsForAggregation[i] = new HashMap<Number, QuantileBin1D>();
- // If dataset should be sorted, the features must be sorted first
- // according to the domain attribute. The "autoSort" functionality
- // of XYSeries can NOT BE USED because of the following reason:
- // To realize the synchronized feature/dataitem a mapping
- // between the feature IDs and the data item index (in the series)
- // must be created. Using the "autoSort" functionality, the
- // indices inside the series change with every XYSeries.add(..)
- // call, so that the mapping is destroyed!!
- //
- // Only solution: Pre-sort the features so that the XYSeries internal
- // order does not change!
- Iterator<SimpleFeature> fi = null;
- if (chartStyle.isSortDomainAxis()) {
- Vector<SimpleFeature> sortedFeatures = FeatureUtil.sortFeatures(fc,
- xAttrName);
- // Create an Iterator for the sorted Features
- fi = sortedFeatures.iterator();
- } else
- fi = new PipedFeatureIterator(fc.features());
+ // If dataset should be sorted, the features must be sorted first
+ // according to the domain attribute. The "autoSort" functionality
+ // of XYSeries can NOT BE USED because of the following reason:
+ // To realize the synchronized feature/dataitem a mapping
+ // between the feature IDs and the data item index (in the series)
+ // must be created. Using the "autoSort" functionality, the
+ // indices inside the series change with every XYSeries.add(..)
+ // call, so that the mapping is destroyed!!
+ //
+ // Only solution: Pre-sort the features so that the XYSeries internal
+ // order does not change!
+ Iterator<SimpleFeature> fi = null;
+ if (chartStyle.isSortDomainAxis()) {
+ Vector<SimpleFeature> sortedFeatures = FeatureUtil.sortFeatures(fc,
+ xAttrName);
+ // Create an Iterator for the sorted Features
+ fi = sortedFeatures.iterator();
+ } else
+ fi = new PipedFeatureIterator(fc.features());
- // Iterate the FeatureCollection and fill the series
- int datasetIdx = 0;
- for (; fi.hasNext();) {
- SimpleFeature f = fi.next();
- // Determine X value (NULL not permitted for XYDateset!)
- Number xValue = (Number) f.getAttribute(xAttrName);
+ // Iterate the FeatureCollection and fill the series
+ int datasetIdx = 0;
+ for (; fi.hasNext();) {
+ SimpleFeature f = fi.next();
+ // Determine X value (NULL not permitted for XYDateset!)
+ Number xValue = (Number) f.getAttribute(xAttrName);
- // Filter out NODATA values
- xValue = chartStyle.filterNoDataValue(ChartStyle.DOMAIN_AXIS,
- xValue);
- if (xValue == null)
- continue;
+ // Filter out NODATA values
+ xValue = chartStyle.filterNoDataValue(ChartStyle.DOMAIN_AXIS, xValue);
+ if (xValue == null)
+ continue;
- /*
- * Normalization of the domain axis value (if they are not handled
- * as categories)
- */
- if (chartStyle.isAttributeNormalized(ChartStyle.DOMAIN_AXIS))
- xValue = normalize(xValue, xAttrName,
- statisticsForNormalization);
+ /*
+ * Normalization of the domain axis value (if they are not handled as
+ * categories)
+ */
+ if (chartStyle.isAttributeNormalized(ChartStyle.DOMAIN_AXIS))
+ xValue = normalize(xValue, xAttrName, statisticsForNormalization);
- // Determine the Y values and fill the series
- for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
- String yAttrName = chartStyle.getAttributeName(attrIdx);
- Number yValue = (Number) f.getAttribute(yAttrName);
- // AggregationFunction attributeAggregation = chartStyle
- // .getAttributeAggregation(attrIdx);
+ // Determine the Y values and fill the series
+ for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
+ String yAttrName = chartStyle.getAttributeName(attrIdx);
+ Number yValue = (Number) f.getAttribute(yAttrName);
+ // AggregationFunction attributeAggregation = chartStyle
+ // .getAttributeAggregation(attrIdx);
- // Filter out NoDataValues
- yValue = chartStyle.filterNoDataValue(attrIdx, yValue);
- if (yValue == null)
- continue;
+ // Filter out NoDataValues
+ yValue = chartStyle.filterNoDataValue(attrIdx, yValue);
+ if (yValue == null)
+ continue;
- /* Normalization of a range axis value */
- if (chartStyle.isAttributeNormalized(attrIdx))
- yValue = normalize(yValue, yAttrName,
- statisticsForNormalization);
+ /* Normalization of a range axis value */
+ if (chartStyle.isAttributeNormalized(attrIdx))
+ yValue = normalize(yValue, yAttrName, statisticsForNormalization);
- // Fill series, if no aggregation function is defined.
- // Otherwise fill statistic (dataset is filled later!)
- // if (attributeAggregation == null) {
- // Fill series
- xySeries[attrIdx].add(xValue, yValue);
- // Mapping between FID and data index in series
- mapping.setMapping(f.getID(), yAttrName, datasetIdx++);
- // } else {
- // // The values for this are aggregated
- // StaticBin1D aggrStat = statisticsForAggregation[attrIdx]
- // .get(xValue);
- // if (aggrStat == null) {
- // aggrStat = new DynamicBin1D();
- // statisticsForAggregation[attrIdx].put(xValue, aggrStat);
- // }
- //
- // // The default weight is 1
- // // for (int i = 0; i < yWeightValue; i++)
- // aggrStat.add(yValue.doubleValue());
- //
- // // TODO: Mapping vormerken (??)
- // // Problem: siehe unten
- // }
- }
- }
+ // Fill series, if no aggregation function is defined.
+ // Otherwise fill statistic (dataset is filled later!)
+ // if (attributeAggregation == null) {
+ // Fill series
+ xySeries[attrIdx].add(xValue, yValue);
+ // Mapping between FID and data index in series
+ mapping.setMapping(f.getID(), yAttrName, datasetIdx++);
+ // } else {
+ // // The values for this are aggregated
+ // StaticBin1D aggrStat = statisticsForAggregation[attrIdx]
+ // .get(xValue);
+ // if (aggrStat == null) {
+ // aggrStat = new DynamicBin1D();
+ // statisticsForAggregation[attrIdx].put(xValue, aggrStat);
+ // }
+ //
+ // // The default weight is 1
+ // // for (int i = 0; i < yWeightValue; i++)
+ // aggrStat.add(yValue.doubleValue());
+ //
+ // // TODO: Mapping vormerken (??)
+ // // Problem: siehe unten
+ // }
+ }
+ }
- // // Fill series for aggregated range attributes
- // for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
- // // String yAttrName = chartStyle.getAttributeName(attrIdx);
- // AggregationFunction aggrFunc = chartStyle
- // .getAttributeAggregation(attrIdx);
- // if (aggrFunc == null)
- // continue;
- // for (Number xValue : statisticsForAggregation[attrIdx].keySet()) {
- // StaticBin1D aggrStat = statisticsForAggregation[attrIdx]
- // .get(xValue);
- // Number yValue = aggrFunc.getResult(aggrStat);
- // // Fill series
- // xySeries[attrIdx].add(xValue, yValue);
- // // TODO: Mapping setzen
- // // Problem: Pro dataset item kann nur EINE FeatureID gesetzt
- // // werden (Feature2DatasetMapping, Zeile 124)
- // // // Mapping between FID and data index in series
- // // mapping.setMapping(f.getID() ??, yAttrName, datasetIdx++);
- // }
- // }
+ // // Fill series for aggregated range attributes
+ // for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
+ // // String yAttrName = chartStyle.getAttributeName(attrIdx);
+ // AggregationFunction aggrFunc = chartStyle
+ // .getAttributeAggregation(attrIdx);
+ // if (aggrFunc == null)
+ // continue;
+ // for (Number xValue : statisticsForAggregation[attrIdx].keySet()) {
+ // StaticBin1D aggrStat = statisticsForAggregation[attrIdx]
+ // .get(xValue);
+ // Number yValue = aggrFunc.getResult(aggrStat);
+ // // Fill series
+ // xySeries[attrIdx].add(xValue, yValue);
+ // // TODO: Mapping setzen
+ // // Problem: Pro dataset item kann nur EINE FeatureID gesetzt
+ // // werden (Feature2DatasetMapping, Zeile 124)
+ // // // Mapping between FID and data index in series
+ // // mapping.setMapping(f.getID() ??, yAttrName, datasetIdx++);
+ // }
+ // }
- return dataset;
- }
+ return dataset;
+ }
- /**
- * Calculates statistics needed to normalize data. If normalization is not
- * used, this function returns an empty map.
- *
- * @param fc
- * {@link FeatureCollection} where the data comes from
- * @param chartStyle
- * {@link ChartStyle} to determine which attributes shall be
- * normalized.
- */
- public static HashMap<String, QuantileBin1D> calcStatisticsForNormalization(
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- FeatureChartStyle chartStyle) {
- // NORMALIZATION:
- // We have to create a descriptive statistic of all items before we can
- // transform the first one. So we iterate over all items before we do
- // optional sorting and insertion.
- /**
- * Holds the statistics needed to normalize the attribute values. Key =
- * attributeName
- */
- HashMap<String, QuantileBin1D> attribStats = new HashMap<String, QuantileBin1D>();
- // First check if any attribute needs normalization. If not we can
- // skip the whole iteration
- boolean doNormalization = false;
- for (int attrIdx = 0; attrIdx < chartStyle.getAttributeCount(); attrIdx++) {
- if (chartStyle.isAttributeNormalized(attrIdx)) {
- doNormalization = true;
- break;
- }
- }
+ /**
+ * Calculates statistics needed to normalize data. If normalization is not
+ * used, this function returns an empty map.
+ * @param fc {@link FeatureCollection} where the data comes from
+ * @param chartStyle {@link ChartStyle} to determine which attributes shall be
+ * normalized.
+ */
+ private static HashMap<String, QuantileBin1D> calcStatisticsForAggregatedNormalization(
+ HashMap<Comparable<?>,QuantileBin1D>[] aggrAttrValues, FeatureChartStyle chartStyle) {
+
+ HashMap<String, QuantileBin1D> normStats = new HashMap<String, QuantileBin1D>();
- if (doNormalization) {
- final FeatureIterator<SimpleFeature> fIt = fc.features();
- try {
+ for (int attrIdx = 0; attrIdx < chartStyle.getAttributeCount(); attrIdx++) {
+ if ( aggrAttrValues[attrIdx] == null )
+ continue;
+ if (!chartStyle.isAttributeNormalized(attrIdx))
+ continue;
+ String attrName = chartStyle.getAttributeName(attrIdx);
+ QuantileBin1D stat = normStats.get(attrName);
+ if (stat == null) {
+ stat = new DynamicBin1D();
+ normStats.put(attrName, stat);
+ }
+
+ for (Comparable<?> catValue : aggrAttrValues[attrIdx].keySet())
+ stat.add( chartStyle.getAttributeAggregation(attrIdx).getResult(aggrAttrValues[attrIdx].get(catValue)) );
+ }
- // Loop over all features, and collect the attribute values we
- // are interested in.
- while (fIt.hasNext()) {
- SimpleFeature f = fIt.next();
+
+ return normStats;
+ }
+
+ /**
+ }
+ * Calculates statistics needed to normalize data. If normalization is not
+ * used, this function returns an empty map.
+ * @param fc {@link FeatureCollection} where the data comes from
+ * @param chartStyle {@link ChartStyle} to determine which attributes shall be
+ * normalized.
+ */
+ private static HashMap<String, QuantileBin1D> calcStatisticsForNotAggregatedNormalization(
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ FeatureChartStyle chartStyle) {
+ // NORMALIZATION:
+ // We have to create a descriptive statistic of all items before we can
+ // transform the first one. So we iterate over all items before we do
+ // optional sorting and insertion.
+ /**
+ * Holds the statistics needed to normalize the attribute values. Key =
+ * attributeName
+ */
+ HashMap<String, QuantileBin1D> attribStats = new HashMap<String, QuantileBin1D>();
- for (int attrIdx = 0; attrIdx < chartStyle
- .getAttributeCount(); attrIdx++) {
+ // First check if any attribute needs normalization. If not we can
+ // skip the whole iteration
+ boolean doNormalization = false;
+ for (int attrIdx = 0; attrIdx < chartStyle.getAttributeCount(); attrIdx++) {
+ if (chartStyle.isAttributeNormalized(attrIdx) && chartStyle.getAttributeAggregation(attrIdx) == null) {
+ doNormalization = true;
+ break;
+ }
+ }
- if (chartStyle.isAttributeNormalized(attrIdx)) {
+ if (doNormalization) {
+ final FeatureIterator<SimpleFeature> fIt = fc.features();
+ try {
- String attrName = chartStyle
- .getAttributeName(attrIdx);
+ // Loop over all features, and collect the attribute values we
+ // are interested in.
+ while (fIt.hasNext()) {
+ SimpleFeature f = fIt.next();
- // SK: Since normalization is now usually set for
- // all
- // attributes (even when they are not numeric), we
- // double check here, whether it is really a numeric
- // attribute
- if (!Number.class.isAssignableFrom(f
- .getFeatureType().getDescriptor(attrName)
- .getType().getBinding())) {
- continue;
- }
+ for (int attrIdx = 0; attrIdx < chartStyle.getAttributeCount(); attrIdx++) {
+ if (chartStyle.isAttributeNormalized(attrIdx) && chartStyle.getAttributeAggregation(attrIdx) == null) {
- // Look for a cached version of the Statistics or
- // create a new one
- QuantileBin1D stat = attribStats.get(attrName);
- if (stat == null) {
- stat = new DynamicBin1D();
- attribStats.put(attrName, stat);
- }
+ String attrName = chartStyle.getAttributeName(attrIdx);
- // Filter out NoDataValues
- Object rawValue = chartStyle.filterNoDataValue(
- attrIdx, f.getAttribute(attrName));
- if (rawValue == null)
- continue;
+ // SK: Since normalization is now usually set for
+ // all
+ // attributes (even when they are not numeric), we
+ // double check here, whether it is really a numeric
+ // attribute
+ if (!Number.class.isAssignableFrom(f.getFeatureType()
+ .getDescriptor(attrName)
+ .getType()
+ .getBinding())) {
+ continue;
+ }
- final Double doubleValue = new Double(
- ((Number) rawValue).doubleValue());
+ // Look for a cached version of the Statistics or
+ // create a new one
+ QuantileBin1D stat = attribStats.get(attrName);
+ if (stat == null) {
+ stat = new DynamicBin1D();
+ attribStats.put(attrName, stat);
+ }
- stat.add(doubleValue);
- }
- }
- }
- } // Feature iterator
- finally {
- fc.close(fIt);
- }
- } // doNormlization
+ // Filter out NoDataValues
+ Object rawValue = chartStyle.filterNoDataValue(
+ attrIdx,
+ f.getAttribute(attrName));
+ if (rawValue == null)
+ continue;
- return attribStats;
- }
+ final Double doubleValue = new Double(
+ ((Number) rawValue).doubleValue());
- /**
- * Do a z-transformation on the data item.
- *
- * @param statisticsForNormalization
- * The statistics needed for normalization.
- *
- * @see #calcStatisticsForNormalization(FeatureCollection,
- * FeatureChartStyle, int)
- */
- private static Number normalize(Number yValue, String attrName,
- HashMap<String, QuantileBin1D> statisticsForNormalization) {
- Number zValue;
+ stat.add(doubleValue);
+ }
+ }
+ }
+ } // Feature iterator
+ finally {
+ fc.close(fIt);
+ }
+ } // doNormlization
- if (statisticsForNormalization.get(attrName) == null) {
- throw new IllegalArgumentException(
- "The statistics needed for the normlization need to be created before normalizing.");
- }
+ return attribStats;
+ }
- StaticBin1D stats = statisticsForNormalization.get(attrName);
+ /**
+ * Do a z-transformation on the data item.
+ * @param statisticsForNormalization The statistics needed for normalization.
+ * @see #calcStatisticsForNormalization(FeatureCollection, FeatureChartStyle,
+ * int)
+ */
+ private static Number normalize(Number yValue, String attrName,
+ HashMap<String, QuantileBin1D> statisticsForNormalization) {
+ Number zValue;
- zValue = (yValue.doubleValue() - stats.mean())
- / stats.standardDeviation();
+ if (statisticsForNormalization.get(attrName) == null) {
+ throw new IllegalArgumentException(
+ "The statistics needed for the normlization need to be created before normalizing.");
+ }
- return zValue;
- }
+ StaticBin1D stats = statisticsForNormalization.get(attrName);
- /**
- * Creates a {@link XYDataset} for 2 (or more) attributes of a
- * {@link FeatureCollection}. XYDateset can only be created for
- * <b>numeric</b> attributes.
- *
- * @param fc
- * a {@link FeatureCollection}
- * @param style
- * defines the attributes used to create the dataset from, as
- * well as the sorting and normalization properties
- * @throws IllegalArgumentException
- * if less then 2 attributes are specified
- * @throws UnsupportedOperationException
- * if attributes are not numeric
- */
- public static DefaultCategoryDataset createCategoryDataset(
- FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- FeatureChartStyle chartStyle) {
- int attrCount = chartStyle.getAttributeCount();
- if (attrCount < 2)
- throw new IllegalArgumentException(
- "FeatureChartStyle must define at least 2 attributes to create CategoryDataset: "
- + attrCount);
- String xAttrName = chartStyle.getAttributeName(ChartStyle.DOMAIN_AXIS);
- // only check whether X attribute exists (numeric and not-numeric
- // allowed)
- checkAttributeType(fc.getSchema(), xAttrName, Comparable.class,
- "Domain attribute", "CategoryDataset");
- // check data types of Y attribute (only numeric allowed)
- for (int i = 1; i < attrCount; i++)
- checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i),
- Number.class, "Range attribute", "CategoryDataset");
+ zValue = (yValue.doubleValue() - stats.mean()) / stats.standardDeviation();
- // Calculate any statistics needed for normalization.
- HashMap<String, QuantileBin1D> statisticsForNormalization = calcStatisticsForNormalization(
- fc, chartStyle);
- // Prepare set for statistics to calculate aggregation
- // functions (one statistic for each range attribute of
- // each domain value)
- HashMap<Comparable<?>, QuantileBin1D>[] statisticsForAggregation = new HashMap[attrCount];
- for (int i = 1; i < attrCount; i++)
- statisticsForAggregation[i] = new HashMap<Comparable<?>, QuantileBin1D>();
+ return zValue;
+ }
- // Create a new dataset and insert the series
- DefaultCategoryDataset dataset = new DefaultCategoryDataset();
- Feature2CategoryDatasetMapping mapping = new Feature2CategoryDatasetMapping(
- fc, dataset);
- dataset.setGroup(new FeatureDatasetMetaData(mapping));
+ /**
+ * Creates a {@link XYDataset} for 2 (or more) attributes of a
+ * {@link FeatureCollection}. XYDateset can only be created for <b>numeric</b>
+ * attributes.
+ * @param fc a {@link FeatureCollection}
+ * @param style defines the attributes used to create the dataset from, as
+ * well as the sorting and normalization properties
+ * @throws IllegalArgumentException if less then 2 attributes are specified
+ * @throws UnsupportedOperationException if attributes are not numeric
+ */
+ public static DefaultCategoryDataset createCategoryDataset(
+ FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ FeatureChartStyle chartStyle) {
+ int attrCount = chartStyle.getAttributeCount();
+ if (attrCount < 2)
+ throw new IllegalArgumentException(
+ "FeatureChartStyle must define at least 2 attributes to create CategoryDataset: " +
+ attrCount);
+ String xAttrName = chartStyle.getAttributeName(ChartStyle.DOMAIN_AXIS);
+ // only check whether X attribute exists (numeric and not-numeric
+ // allowed)
+ checkAttributeType(fc.getSchema(), xAttrName, Comparable.class,
+ "Domain attribute", "CategoryDataset");
+ // check data types of Y attribute (only numeric allowed)
+ for (int i = 1; i < attrCount; i++)
+ checkAttributeType(fc.getSchema(), chartStyle.getAttributeName(i),
+ Number.class, "Range attribute", "CategoryDataset");
- // If dataset should be sorted, the features must be sorted first
- // according to the domain attribute. CategoryDataset has no
- // "autoSort", and this - at all - would not work (see
- // createXYDataset(..))
- Iterator<SimpleFeature> fi = null;
- FeatureIterator<SimpleFeature> features = null;
+ // Calculate any statistics needed for normalization.
+ HashMap<String, QuantileBin1D> statisticsForNormalization = calcStatisticsForNotAggregatedNormalization(
+ fc,
+ chartStyle);
+ // Prepare set for statistics to calculate aggregation
+ // functions (one statistic for each range attribute of
+ // each domain value)
+ HashMap<Comparable<?>, QuantileBin1D>[] statisticsForAggregation = new HashMap[attrCount];
+ for (int i = 1; i < attrCount; i++)
+ statisticsForAggregation[i] = new HashMap<Comparable<?>, QuantileBin1D>();
- // Für die Gewichtung muss zuerst Summe aller Gewichte ermittelt werden
- Double[] sumWeights = new Double[attrCount];
- for (int attrIdx = 1; attrIdx < attrCount; attrIdx++)
- sumWeights[attrIdx - 1] = 0.;
- long[] validFeaturesCount = new long[attrCount];
- {
- features = fc.features();
- try {
- while (features.hasNext()) {
+ // Create a new dataset and insert the series
+ DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+ Feature2CategoryDatasetMapping mapping = new Feature2CategoryDatasetMapping(
+ fc, dataset);
+ dataset.setGroup(new FeatureDatasetMetaData(mapping));
- SimpleFeature next = features.next();
- // Determine the Y values and fill the dataset
- for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
- AggregationFunction attributeAggregation = chartStyle
- .getAttributeAggregation(attrIdx);
+ FeatureIterator<SimpleFeature> features = null;
+ // Für die Gewichtung muss zuerst Summe aller Gewichte (pro Category!)
+ // ermittelt werden
+ HashMap<Comparable<?>, Double>[] weightSumsForAggregation = new HashMap[attrCount];
+ for (int i = 1; i < attrCount; i++)
+ weightSumsForAggregation[i] = new HashMap<Comparable<?>, Double>();
+ features = fc.features();
+ try {
+ while (features.hasNext()) {
+ SimpleFeature f = features.next();
+ // ignore features with NODATA in domain attribute
+ Comparable<?> catValue = (Comparable<?>) f.getAttribute(xAttrName);
+ catValue = chartStyle.filterNoDataValue(ChartStyle.DOMAIN_AXIS,
+ catValue);
+ if (catValue == null)
+ continue;
- if (attributeAggregation == null)
- continue;
- if (!attributeAggregation.isWeighted())
- continue;
- if (chartStyle
- .getAttributeAggregationWeightAttributeName(attrIdx) == null)
- throw new RuntimeException(
- JFreeChartUtil.R("Exception.noWeightAttributeDefinedforAWeightedAggregation"));
-
-
-
- // NODATA Check yValue attribute
- String yAttrName = chartStyle.getAttributeName(attrIdx);
- Number yValue = (Number) next.getAttribute(yAttrName);
- yValue = chartStyle.filterNoDataValue(attrIdx, yValue);
- if (yValue == null)
- continue;
+ // Iterate the feature attributes
+ for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
+ AggregationFunction attributeAggregation = chartStyle.getAttributeAggregation(attrIdx);
+ // Ignore
+ // - not aggregated attributes
+ // - not weighted aggregation attributes
+ if (attributeAggregation == null)
+ continue;
+ if (!attributeAggregation.isWeighted())
+ continue;
+ // weights must be defined for weighted aggregation
+ if (chartStyle.getAttributeAggregationWeightAttributeName(attrIdx) == null)
+ throw new RuntimeException(
+ JFreeChartUtil.R("Exception.noWeightAttributeDefinedforAWeightedAggregation"));
+ // ignore features with NODATA in range attribute
+ String yAttrName = chartStyle.getAttributeName(attrIdx);
+ Number yValue = (Number) chartStyle.filterNoDataValue(
+ attrIdx,
+ f.getAttribute(yAttrName));
+ if (yValue == null)
+ continue;
+ // ignore features with NODATA in weight attribute
+ String weightAttrName = chartStyle.getAttributeAggregationWeightAttributeName(attrIdx);
+ Number weight = (Number) chartStyle.filterWeightAttributeNoDataValue(
+ attrIdx,
+ f.getAttribute(weightAttrName));
+ if (weight == null)
+ continue;
- // NODATA Check WEIGHT attribute
- Number weight = (Number) next
- .getAttribute(chartStyle
- .getAttributeAggregationWeightAttributeName(attrIdx));
- if (chartStyle.isWeightAttributeNoDataValue(attrIdx,
- weight))
- continue;
+ Double weightSum = weightSumsForAggregation[attrIdx].get(catValue);
+ if (weightSum == null)
+ weightSum = 0.0;
+ weightSum += weight.doubleValue();
+ weightSumsForAggregation[attrIdx].put(catValue, weightSum);
+ }
+ }
+ } finally {
+ if (features != null) {
+ // this is a hint
+ fc.close(features);
+ }
+ }
- // NODATA Check Domain attribute
- Comparable<?> catValue = (Comparable<?>) next
- .getAttribute(xAttrName);
- catValue = chartStyle.filterNoDataValue(
- ChartStyle.DOMAIN_AXIS, catValue);
- if (catValue == null)
- continue;
+ // If dataset should be sorted, the features must be sorted first
+ // according to the domain attribute. CategoryDataset has no
+ // "autoSort", and this - at all - would not work (see
+ // createXYDataset(..))
+ Iterator<SimpleFeature> fi = null;
+ if (chartStyle.isSortDomainAxis()) {
+ Vector<SimpleFeature> sortedFeatures = FeatureUtil.sortFeatures(fc,
+ xAttrName);
+ // Create an Iterator for the sorted Features
+ fi = sortedFeatures.iterator();
+ } else {
+ features = fc.features();
+ fi = new PipedFeatureIterator(features);
+ }
- // So, alle drei werte sind nicht NODATA
- sumWeights[attrIdx - 1] += weight.doubleValue();
- validFeaturesCount[attrIdx - 1]++;
- }
- }
- } finally {
- if (features != null) {
- // this is a hint
- fc.close(features);
- }
- }
- } // Die Summe aller gewichte ist ermittelt
+ try {
+ // Iterate the FeatureCollection and fill the series
+ for (int fIdx = 0; fi.hasNext(); fIdx++) {
+ SimpleFeature f = fi.next();
+ // Determine the category (NULL not permitted!)
+ Comparable<?> catValue = (Comparable<?>) f.getAttribute(xAttrName);
+ // Filter out NODATA values
+ catValue = chartStyle.filterNoDataValue(ChartStyle.DOMAIN_AXIS,
+ catValue);
+ if (catValue == null)
+ continue;
- if (chartStyle.isSortDomainAxis()) {
- Vector<SimpleFeature> sortedFeatures = FeatureUtil.sortFeatures(fc,
- xAttrName);
- // Create an Iterator for the sorted Features
- fi = sortedFeatures.iterator();
- } else {
- features = fc.features();
- fi = new PipedFeatureIterator(features);
- }
+ // Determine the Y values and fill the dataset
+ for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
+ AggregationFunction attributeAggregation = chartStyle.getAttributeAggregation(attrIdx);
- try {
- // Iterate the FeatureCollection and fill the series
- for (int fIdx = 0; fi.hasNext(); fIdx++) {
- SimpleFeature f = fi.next();
- // Determine the category (NULL not permitted!)
- Comparable<?> catValue = (Comparable<?>) f
- .getAttribute(xAttrName);
+ String yAttrName = chartStyle.getAttributeName(attrIdx);
+ Number yValue = (Number) f.getAttribute(yAttrName);
- // Filter out NODATA values
- catValue = chartStyle.filterNoDataValue(ChartStyle.DOMAIN_AXIS,
- catValue);
+ // By default the wight is 1 => no weighting. If the
+ // aggregation uses weighting, read the weight attribnute
+ // if (attributeAggregation != null &&
+ // attributeAggregation.isWeighted())
+ // yWeightValue = ((Number) f.getAttribute(WEIGHTATTRIB))
+ // .longValue();
- if (catValue == null)
- continue;
+ // Filter out NoDataValues
+ yValue = chartStyle.filterNoDataValue(attrIdx, yValue);
+ if (yValue == null)
+ continue;
- // Determine the Y values and fill the dataset
- for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
- AggregationFunction attributeAggregation = chartStyle
- .getAttributeAggregation(attrIdx);
+ // Fill series, if no aggregation function is defined.
+ // Otherwise fill statistic (dataset is filled later!)
+ if (attributeAggregation == null) {
+ /* Normalization of a range axis value */
+ if (chartStyle.isAttributeNormalized(attrIdx))
+ yValue = normalize(yValue, yAttrName, statisticsForNormalization);
+ // Add data to dataset
+ dataset.addValue(yValue, yAttrName, catValue);
+ // Mapping between FID and data index in series
+ mapping.setMapping(f.getID(), yAttrName, catValue);
+ } else {
+ QuantileBin1D aggrStat = statisticsForAggregation[attrIdx].get(catValue);
+ if (aggrStat == null) {
+ aggrStat = new DynamicBin1D();
+ statisticsForAggregation[attrIdx].put(catValue, aggrStat);
+ }
- String yAttrName = chartStyle.getAttributeName(attrIdx);
- Number yValue = (Number) f.getAttribute(yAttrName);
+ if (attributeAggregation.isWeighted()) {
+ // weight attribute must not be NULL
+ Object weightObj = f.getAttribute(chartStyle.getAttributeAggregationWeightAttributeName(attrIdx));
+ Number weight = (Number)chartStyle.filterWeightAttributeNoDataValue(attrIdx, weightObj);
+ if ( weight == null )
+ continue;
+ aggrStat.add(yValue.doubleValue() * weight.doubleValue() / weightSumsForAggregation[attrIdx].get(catValue));
+ } else {
+ aggrStat.add(yValue.doubleValue());
+ }
+ // TODO: Mapping vormerken (??)
+ // Problem: siehe unten
+ }
+ }
- // By default the wight is 1 => no weighting. If the
- // aggregation uses weighting, read the weight attribnute
- // if (attributeAggregation != null &&
- // attributeAggregation.isWeighted())
- // yWeightValue = ((Number) f.getAttribute(WEIGHTATTRIB))
- // .longValue();
+ }
- // Filter out NoDataValues
- yValue = chartStyle.filterNoDataValue(attrIdx, yValue);
- if (yValue == null)
- continue;
+ // Fill series for aggregated range attributes
+ statisticsForNormalization = calcStatisticsForAggregatedNormalization(statisticsForAggregation,chartStyle);
+ for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
+ String yAttrName = chartStyle.getAttributeName(attrIdx);
+ AggregationFunction aggrFunc = chartStyle.getAttributeAggregation(attrIdx);
+ if (aggrFunc == null)
+ continue;
+ for (Comparable<?> catValue : statisticsForAggregation[attrIdx].keySet()) {
+ QuantileBin1D aggrStat = statisticsForAggregation[attrIdx].get(catValue);
+ Number yValue = aggrFunc.getResult(aggrStat);
+
+ // Normalize the aggregated value
+ if ( chartStyle.isAttributeNormalized(attrIdx) )
+ yValue = normalize(yValue, yAttrName, statisticsForNormalization);
+
+ // Fill series
+ dataset.addValue(yValue, yAttrName, catValue);
+ // TODO: Mapping setzen
+ // Problem: Pro dataset item kann nur EINE FeatureID gesetzt
+ // werden (Feature2DatasetMapping, Zeile 124)
+ // // Mapping between FID and data index in series
+ // mapping.setMapping(f.getID() ??, yAttrName,
+ // datasetIdx++);
+ }
+ }
+ } finally {
+ if (features != null) {
+ fc.close(features);
+ }
+ }
- /* Normalization of a range axis value */
- if (chartStyle.isAttributeNormalized(attrIdx))
- yValue = normalize(yValue, yAttrName,
- statisticsForNormalization);
+ return dataset;
+ }
- // Fill series, if no aggregation function is defined.
- // Otherwise fill statistic (dataset is filled later!)
- if (attributeAggregation == null) {
- // Add data to dataset
- dataset.addValue(yValue, yAttrName, catValue);
- // Mapping between FID and data index in series
- mapping.setMapping(f.getID(), yAttrName, catValue);
- } else {
- QuantileBin1D aggrStat = statisticsForAggregation[attrIdx]
- .get(catValue);
- if (aggrStat == null) {
- aggrStat = new DynamicBin1D();
- statisticsForAggregation[attrIdx].put(catValue,
- aggrStat);
- }
+ /**
+ * After loading from XML, a {@link FeatureChartStyle} contains whatever is
+ * written in the XML. But the DBF Schema can change quickly by accident! This
+ * method checks an {@link FeatureChartStyle} against a schema and corrects
+ * upperCase/lowerCase problems where possible. Returns <code>false</code> if
+ * attributes had to be removed from the {@link FeatureChartStyle}.
+ * @author SK
+ */
+ public static boolean correctAttributeNames(
+ FeatureChartStyle featureChartStyle, SimpleFeatureType schema) {
- if (attributeAggregation.isWeighted()) {
-// fliegt schon vorher raus..
-// if (chartStyle
-// .getAttributeAggregationWeightAttributeName(attrIdx) == null)
-// throw new RuntimeException(
-// JFreeChartUtil.R("Exception.noWeightAttributeDefinedforAWeightedAggregation"));
+ ArrayList<Integer> willRemove = new ArrayList<Integer>();
- Object weightObj = f
- .getAttribute(chartStyle
- .getAttributeAggregationWeightAttributeName(attrIdx));
+ // 1. Check.. all attributes in the atm should be in the schema as well.
+ // maybe correct some upperCase/loweCase stuff
+ for (int idx = 0; idx < featureChartStyle.getAttributeCount(); idx++) {
- if (!chartStyle.isWeightAttributeNoDataValue(
- attrIdx, weightObj)) {
- Number weight = (Number) weightObj;
- aggrStat.add(yValue.doubleValue()
- * weight.doubleValue()
- / sumWeights[attrIdx - 1]
- * validFeaturesCount[attrIdx - 1]);
- } else {
- // NIchts added, denn das weight ist hier NODATA
- }
+ // Check the main attribute
+ String attributeName = featureChartStyle.getAttributeName(idx);
- } else {
- aggrStat.add(yValue.doubleValue());
- }
+ AttributeDescriptor foundDescr = schema.getDescriptor(attributeName);
+ if (foundDescr == null) {
+ Name bestMatch = FeatureUtil.findBestMatchingAttribute(schema,
+ attributeName);
+ if (bestMatch == null) {
+ willRemove.add(idx);
+ continue;
+ } else
+ featureChartStyle.setAttributeName(idx, bestMatch.getLocalPart());
+ }
- // TODO: Mapping vormerken (??)
- // Problem: siehe unten
- }
- }
+ // Check the optional weight attribute value
+ if (idx > 0) {
+ String weightAtt = featureChartStyle.getAttributeAggregationWeightAttributeName(idx);
+ if (weightAtt != null) {
+ AttributeDescriptor foundWeightDescr = schema.getDescriptor(attributeName);
+ if (foundWeightDescr == null) {
+ Name bestMatch = FeatureUtil.findBestMatchingAttribute(schema,
+ weightAtt);
+ if (bestMatch == null) {
+ featureChartStyle.setAttributeAggregationWeightAttributeName(idx,
+ null);
+ } else
+ featureChartStyle.setAttributeAggregationWeightAttributeName(
+ idx,
+ bestMatch.getLocalPart());
+ }
+ }
+ }
+ }
- }
+ // Remove the ones that were not findable in the schema
+ for (Integer removeIdx : willRemove) {
+ featureChartStyle.removeAttribute(removeIdx);
+ }
- // Fill series for aggregated range attributes
- for (int attrIdx = 1; attrIdx < attrCount; attrIdx++) {
- String yAttrName = chartStyle.getAttributeName(attrIdx);
- AggregationFunction aggrFunc = chartStyle
- .getAttributeAggregation(attrIdx);
- if (aggrFunc == null)
- continue;
- for (Comparable<?> catValue : statisticsForAggregation[attrIdx]
- .keySet()) {
- QuantileBin1D aggrStat = statisticsForAggregation[attrIdx]
- .get(catValue);
- Number yValue = aggrFunc.getResult(aggrStat);
- // Fill series
- dataset.addValue(yValue, yAttrName, catValue);
- // TODO: Mapping setzen
- // Problem: Pro dataset item kann nur EINE FeatureID gesetzt
- // werden (Feature2DatasetMapping, Zeile 124)
- // // Mapping between FID and data index in series
- // mapping.setMapping(f.getID() ??, yAttrName,
- // datasetIdx++);
- }
- }
- } finally {
- if (features != null) {
- fc.close(features);
- }
- }
+ // * Returns false if attributes had to be removed from the {@link
+ // FeatureChartStyle}.
+ return willRemove.isEmpty();
+ }
- return dataset;
- }
+ /**
+ * Passes the NODATA Values stored in the {@link AttributeMetadataMap} to the
+ * attributes (and optional weighting attributes) of the {@link ChartStyle}.
+ */
+ public static void passNoDataValues(
+ AttributeMetadataMap attributeMetaDataMap,
+ FeatureChartStyle featureChartStyle) {
- /**
- * After loading from XML, a {@link FeatureChartStyle} contains whatever is
- * written in the XML. But the DBF Schema can change quickly by accident!
- * This method checks an {@link FeatureChartStyle} against a schema and
- * corrects upperCase/lowerCase problems where possible.
- *
- * Returns <code>false</code> if attributes had to be removed from the
- * {@link FeatureChartStyle}.
- *
- * @author SK
- */
- public static boolean correctAttributeNames(
- FeatureChartStyle featureChartStyle, SimpleFeatureType schema) {
+ // Pass the NODATA values for the attributes to the ChartStyle
+ for (int idx = 0; idx < featureChartStyle.getAttributeCount(); idx++) {
- ArrayList<Integer> willRemove = new ArrayList<Integer>();
+ String attributeName = featureChartStyle.getAttributeName(idx);
+ AttributeMetadata attributeMetadata = attributeMetaDataMap.get(attributeName);
- // 1. Check.. all attributes in the atm should be in the schema as well.
- // maybe correct some upperCase/loweCase stuff
- for (int idx = 0; idx < featureChartStyle.getAttributeCount(); idx++) {
+ if (attributeMetadata != null) {
+ featureChartStyle.setNoDataValues(idx,
+ attributeMetadata.getNodataValues());
+ }
- // Check the main attribute
- String attributeName = featureChartStyle.getAttributeName(idx);
-
- AttributeDescriptor foundDescr = schema
- .getDescriptor(attributeName);
- if (foundDescr == null) {
- Name bestMatch = FeatureUtil.findBestMatchingAttribute(schema,
- attributeName);
- if (bestMatch == null) {
- willRemove.add(idx);
- continue;
- } else
- featureChartStyle.setAttributeName(idx, bestMatch
- .getLocalPart());
- }
-
- // Check the optional weight attribute value
- if (idx > 0) {
- String weightAtt = featureChartStyle
- .getAttributeAggregationWeightAttributeName(idx);
- if (weightAtt != null) {
- AttributeDescriptor foundWeightDescr = schema
- .getDescriptor(attributeName);
- if (foundWeightDescr == null) {
- Name bestMatch = FeatureUtil.findBestMatchingAttribute(
- schema, weightAtt);
- if (bestMatch == null) {
- featureChartStyle
- .setAttributeAggregationWeightAttributeName(
- idx, null);
- } else
- featureChartStyle
- .setAttributeAggregationWeightAttributeName(
- idx, bestMatch.getLocalPart());
- }
- }
- }
- }
-
- // Remove the ones that were not findable in the schema
- for (Integer removeIdx : willRemove) {
- featureChartStyle.removeAttribute(removeIdx);
- }
-
- // * Returns false if attributes had to be removed from the {@link
- // FeatureChartStyle}.
- return willRemove.isEmpty();
- }
-
- /**
- * Passes the NODATA Values stored in the {@link AttributeMetadataMap} to
- * the attributes (and optional weighting attributes) of the
- * {@link ChartStyle}.
- */
- public static void passNoDataValues(
- AttributeMetadataMap attributeMetaDataMap,
- FeatureChartStyle featureChartStyle) {
-
- // Pass the NODATA values for the attributes to the ChartStyle
- for (int idx = 0; idx < featureChartStyle.getAttributeCount(); idx++) {
-
- String attributeName = featureChartStyle.getAttributeName(idx);
- AttributeMetadata attributeMetadata = attributeMetaDataMap
- .get(attributeName);
-
- if (attributeMetadata != null) {
- featureChartStyle.setNoDataValues(idx, attributeMetadata
- .getNodataValues());
- }
-
- // Set NODATA-Values for the weight attributes
- String weightAtt = featureChartStyle
- .getAttributeAggregationWeightAttributeName(idx);
- if (weightAtt != null) {
- AttributeMetadata weightAttributeMetadata = attributeMetaDataMap
- .get(attributeName);
- if (weightAttributeMetadata != null) {
- featureChartStyle.setWeightAttributeNoDataValues(idx,
- weightAttributeMetadata.getNodataValues());
- }
- }
- }
- }
+ // Set NODATA-Values for the weight attributes
+ String weightAtt = featureChartStyle.getAttributeAggregationWeightAttributeName(idx);
+ if (weightAtt != null) {
+ AttributeMetadata weightAttributeMetadata = attributeMetaDataMap.get(attributeName);
+ if (weightAttributeMetadata != null) {
+ featureChartStyle.setWeightAttributeNoDataValues(
+ idx,
+ weightAttributeMetadata.getNodataValues());
+ }
+ }
+ }
+ }
}
More information about the Schmitzm-commits
mailing list