/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * JUMP is Copyright (C) 2003 Vivid Solutions * * This program implements extensions to JUMP and is * Copyright (C) Stefan Steiniger. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * Stefan Steiniger * perriger@gmx.de */ /*********************************************** * created on 22.06.2006 * last modified: * * author: sstein * * description: * provides some function to calculate mathematical * indices like mean, max, median for a set of features. * ***********************************************/ package org.openjump.core.attributeoperations; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.math.array.DoubleArray; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jump.feature.AttributeType; import com.vividsolutions.jump.feature.Feature; import com.vividsolutions.jump.feature.FeatureSchema; /** * * description: * provides some function to calculate mathematical * indices like mean, max, median for a set of features. * * @author sstein * */ public class AttributeOp { public final static int MAJORITY = 0; public final static int MINORITY = 1; public final static int MEAN = 2; public final static int MEDIAN = 3; public final static int MIN = 4; public final static int MAX = 5; public final static int STD = 6; public final static int SUM = 7; public final static int COUNT = 8; public static String getName(int attributeOP){ String retval = ""; if(attributeOP == 0){ retval ="major"; } else if(attributeOP == 1){ retval ="minor"; } else if(attributeOP == 2){ retval ="mean"; } else if(attributeOP == 3){ retval ="median"; } else if(attributeOP == 4){ retval ="min"; } else if(attributeOP == 5){ retval ="max"; } else if(attributeOP == 6){ retval ="std"; } else if(attributeOP == 7){ retval ="sum"; } else if(attributeOP == 8){ retval ="count"; } return retval; } public static double evaluateAttributes(int attributeOp, Feature[] features, String attributeName){ ArrayList<Feature> featureL = new ArrayList<Feature>(); for (int i = 0; i < features.length; i++) { featureL.add(features[i]); } return AttributeOp.evaluateAttributes(attributeOp, featureL, attributeName); } public static double evaluateAttributes(int attributeOp, List features, String attributeName){ double result= Double.NaN; if (features.size() > 0){ Feature firstF = (Feature)features.get(0); FeatureSchema fs = firstF.getSchema(); if (fs.hasAttribute(attributeName)){ boolean doEval = true; AttributeType at = fs.getAttributeType(attributeName); int n = features.size(); double[] vals = org.math.array.StatisticSample.fill(n,0); //Matrix mat = MatlabSyntax.zeros(n,1); int count=0; for (Iterator iter = features.iterator(); iter.hasNext();) { Feature f = (Feature) iter.next(); Object value = f.getAttribute(attributeName); if (value == null) { // will be counted as 0 } else if (at == AttributeType.DOUBLE){ Double val = (Double)value; //mat.set(count,0, val.doubleValue()); vals[count] = val.doubleValue(); } else if(at == AttributeType.INTEGER){ Integer val = (Integer)value; //mat.set(count,0, val.doubleValue()); vals[count] = val.doubleValue(); } else if(at == AttributeType.GEOMETRY){ //-- simply set to one for count //mat.set(count,0, 1); vals[count] = 1; } else{ System.out.println("AttributeOp: attribute type not supported"); doEval = false; } count++; } if(doEval){ if (attributeOp == AttributeOp.MAJORITY){ result = majorityEval(vals); } else if(attributeOp == AttributeOp.MINORITY){ result = minorityEval(vals); } else if(attributeOp == AttributeOp.MAX){ result = org.math.array.DoubleArray.max(vals); } else if(attributeOp == AttributeOp.MIN){ result = org.math.array.DoubleArray.min(vals); } else if(attributeOp == AttributeOp.MEAN){ result = org.math.array.StatisticSample.mean(vals); } else if(attributeOp == AttributeOp.STD){ result = org.math.array.StatisticSample.stddeviation(vals); } else if(attributeOp == AttributeOp.MEDIAN){ double[] sortvals = DoubleArray.sort(vals); int index = (int)Math.ceil(vals.length/2.0); result = sortvals[index-1]; } else if(attributeOp == AttributeOp.SUM){ result = DoubleArray.sum(vals); } else if(attributeOp == AttributeOp.COUNT){ result = (double)vals.length; } else{ System.out.println("AttributeOp: attribute operation not supported"); } } } else{ System.out.println("AttributeOp: attribute does not exist"); } } else{ if(attributeOp == AttributeOp.COUNT){ result = 0; } } return result; } private static double majorityEval(double[] values){ double result=0; //-- built list of all values ArrayList vals = new ArrayList(); for(int i=0; i < values.length; i++){ double val = values[i]; if(i==0){ //-- add first value vals.add(new Double(val)); } else{ boolean stop = false; int count =0; boolean found = false; while(stop == false){ Double d = (Double)vals.get(count); if(val == d.doubleValue()){ stop = true; found = true; } count++; if(count == vals.size()){ //-- if last value reached stop and add stop = true; } } if(found == false){ vals.add(new Double(val)); } } } //-- count number of values int[] countVals = new int[vals.size()]; //-- set to zero for (int i = 0; i < countVals.length; i++) { countVals[i]=0; } for(int i=0; i < values.length; i++){ double val = values[i]; boolean stop = false; int count =0; while(stop == false){ Double d = (Double)vals.get(count); if(val == d.doubleValue()){ //-- count int oldVal = countVals[count]; countVals[count] = oldVal +1; //-- stop stop = true; } count++; if(count == countVals.length){ stop = true; } } } // if (mat.getRowDimension() > 15){ // String s= "Stop here for debugging"; // } //-- get maximum int maxcount = 0; int pos = 0; for (int i = 0; i < countVals.length; i++) { if (countVals[i] > maxcount){ maxcount = countVals[i]; pos = i; } } //-- assign value which appears most result = ((Double)vals.get(pos)).doubleValue(); return result; } private static double minorityEval(double[] values){ double result=0; //-- built list of all values ArrayList vals = new ArrayList(); for(int i=0; i < values.length; i++){ double val = values[i]; if(i==0){ //-- add first value vals.add(new Double(val)); } else{ boolean stop = false; int count =0; boolean found = false; while(stop == false){ Double d = (Double)vals.get(count); if(val == d.doubleValue()){ stop = true; found = true; } count++; if(count == vals.size()){ //-- if last value reached stop and add stop = true; } } if(found == false){ vals.add(new Double(val)); } } } //-- count number of values int[] countVals = new int[vals.size()]; //-- set to zero for (int i = 0; i < countVals.length; i++) { countVals[i]=0; } for(int i=0; i < values.length; i++){ double val = values[i]; boolean stop = false; int count =0; while(stop == false){ Double d = (Double)vals.get(count); if(val == d.doubleValue()){ //-- count int oldVal = countVals[count]; countVals[count] = oldVal +1; //-- stop stop = true; } count++; if(count == countVals.length){ stop = true; } } } //-- get minimum count int mincount = countVals[0]; int pos = 0; for (int i = 1; i < countVals.length; i++) { if (countVals[i] < mincount){ mincount = countVals[i]; pos = i; } } //-- assign value which appears fewest result = ((Double)vals.get(pos)).doubleValue(); return result; } }