001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * JUMP is Copyright (C) 2003 Vivid Solutions
006: *
007: * This program implements extensions to JUMP and is
008: * Copyright (C) Stefan Steiniger.
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or (at your option) any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU General Public License for more details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
023: *
024: * For more information, contact:
025: * Stefan Steiniger
026: * perriger@gmx.de
027: */
028: /***********************************************
029: * created on 22.06.2006
030: * last modified:
031: *
032: * author: sstein
033: *
034: * description:
035: * provides some function to calculate mathematical
036: * indices like mean, max, median for a set of features.
037: *
038: ***********************************************/package org.openjump.core.spatialAttributeOps;
039:
040: import java.util.ArrayList;
041: import java.util.Iterator;
042: import java.util.List;
043:
044: import org.jmat.MatlabSyntax;
045: import org.jmat.data.AbstractMatrix;
046: import org.jmat.data.Matrix;
047:
048: import com.vividsolutions.jts.geom.Geometry;
049: import com.vividsolutions.jump.feature.AttributeType;
050: import com.vividsolutions.jump.feature.Feature;
051: import com.vividsolutions.jump.feature.FeatureSchema;
052:
053: /**
054: *
055: * description:
056: * provides some function to calculate mathematical
057: * indices like mean, max, median for a set of features.
058: *
059: * @author sstein
060: *
061: */
062: public class AttributeOp {
063: public final static int MAJORITY = 0;
064: public final static int MINORITY = 1;
065: public final static int MEAN = 2;
066: public final static int MEDIAN = 3;
067: public final static int MIN = 4;
068: public final static int MAX = 5;
069: public final static int STD = 6;
070: public final static int SUM = 7;
071: public final static int COUNT = 8;
072:
073: public static String getName(int attributeOP) {
074: String retval = "";
075: if (attributeOP == 0) {
076: retval = "major";
077: } else if (attributeOP == 1) {
078: retval = "minor";
079: } else if (attributeOP == 2) {
080: retval = "mean";
081: } else if (attributeOP == 3) {
082: retval = "median";
083: } else if (attributeOP == 4) {
084: retval = "min";
085: } else if (attributeOP == 5) {
086: retval = "max";
087: } else if (attributeOP == 6) {
088: retval = "std";
089: } else if (attributeOP == 7) {
090: retval = "sum";
091: } else if (attributeOP == 8) {
092: retval = "count";
093: }
094: return retval;
095: }
096:
097: public static double evaluateAttributes(int attributeOp,
098: List features, String attributeName) {
099: double result = Double.NaN;
100: if (features.size() > 0) {
101: Feature firstF = (Feature) features.get(0);
102: FeatureSchema fs = firstF.getSchema();
103: if (fs.hasAttribute(attributeName)) {
104: boolean doEval = true;
105: AttributeType at = fs.getAttributeType(attributeName);
106: int n = features.size();
107: Matrix mat = MatlabSyntax.zeros(n, 1);
108: int count = 0;
109: for (Iterator iter = features.iterator(); iter
110: .hasNext();) {
111: Feature f = (Feature) iter.next();
112: if (at == AttributeType.DOUBLE) {
113: Double val = (Double) f
114: .getAttribute(attributeName);
115: mat.set(count, 0, val.doubleValue());
116: } else if (at == AttributeType.INTEGER) {
117: Integer val = (Integer) f
118: .getAttribute(attributeName);
119: mat.set(count, 0, val.doubleValue());
120: } else if (at == AttributeType.GEOMETRY) {
121: //-- simply set to one for count
122: Geometry geom = (Geometry) f
123: .getAttribute(attributeName);
124: if (geom != null) {
125: mat.set(count, 0, 1);
126: } else {
127: mat.set(count, 0, 0);
128: }
129: } else {
130: System.out
131: .println("AttributeOp: attribute type not supported");
132: doEval = false;
133: }
134: count++;
135: }
136: if (doEval) {
137: if (attributeOp == AttributeOp.MAJORITY) {
138: result = majorityEval(mat);
139: } else if (attributeOp == AttributeOp.MINORITY) {
140: result = minorityEval(mat);
141: } else if (attributeOp == AttributeOp.MAX) {
142: AbstractMatrix max = mat.max();
143: result = max.get(0, 0);
144: } else if (attributeOp == AttributeOp.MIN) {
145: AbstractMatrix min = mat.min();
146: result = min.get(0, 0);
147: } else if (attributeOp == AttributeOp.MEAN) {
148: AbstractMatrix mean = mat.mean();
149: result = mean.get(0, 0);
150: } else if (attributeOp == AttributeOp.STD) {
151: AbstractMatrix var = mat.variance();
152: result = Math.sqrt(var.get(0, 0));
153: } else if (attributeOp == AttributeOp.MEDIAN) {
154: Matrix sortmat = MatlabSyntax.sort_Y(mat);
155: int index = (int) Math.ceil(mat
156: .getRowDimension() / 2.0);
157: result = mat.get(index - 1, 0);
158: } else if (attributeOp == AttributeOp.SUM) {
159: AbstractMatrix sum = mat.sum();
160: result = sum.get(0, 0);
161: } else if (attributeOp == AttributeOp.COUNT) {
162: result = (double) mat.getRowDimension();
163: } else {
164: System.out
165: .println("AttributeOp: attribute operation not supported");
166: }
167: }
168: } else {
169: System.out
170: .println("AttributeOp: attribute does not exist");
171: }
172: } else {
173: if (attributeOp == AttributeOp.COUNT) {
174: result = 0;
175: }
176: }
177: return result;
178: }
179:
180: private static double majorityEval(Matrix mat) {
181: double result = 0;
182: //-- built list of all values
183: ArrayList vals = new ArrayList();
184: for (int i = 0; i < mat.getRowDimension(); i++) {
185: for (int j = 0; j < mat.getColumnDimension(); j++) {
186: double val = mat.get(i, j);
187: if ((i == 0) && (j == 0)) {
188: //-- add first value
189: vals.add(new Double(val));
190: } else {
191: boolean stop = false;
192: int count = 0;
193: boolean found = false;
194: while (stop == false) {
195: Double d = (Double) vals.get(count);
196: if (val == d.doubleValue()) {
197: stop = true;
198: found = true;
199: }
200: count++;
201: if (count == vals.size()) {
202: //-- if last value reached stop and add
203: stop = true;
204: }
205: }
206: if (found == false) {
207: vals.add(new Double(val));
208: }
209: }
210: }
211: }
212: //-- count number of values
213: int[] countVals = new int[vals.size()];
214: //-- set to zero
215: for (int i = 0; i < countVals.length; i++) {
216: countVals[i] = 0;
217: }
218: for (int i = 0; i < mat.getRowDimension(); i++) {
219: for (int j = 0; j < mat.getColumnDimension(); j++) {
220: double val = mat.get(i, j);
221: boolean stop = false;
222: int count = 0;
223: while (stop == false) {
224: Double d = (Double) vals.get(count);
225: if (val == d.doubleValue()) {
226: //-- count
227: int oldVal = countVals[count];
228: countVals[count] = oldVal + 1;
229: //-- stop
230: stop = true;
231: }
232: count++;
233: if (count == countVals.length) {
234: stop = true;
235: }
236: }
237: }
238: }
239: // if (mat.getRowDimension() > 15){
240: // String s= "Stop here for debugging";
241: // }
242: //-- get maximum
243: int maxcount = 0;
244: int pos = 0;
245: for (int i = 0; i < countVals.length; i++) {
246: if (countVals[i] > maxcount) {
247: maxcount = countVals[i];
248: pos = i;
249: }
250: }
251: //-- assign value which appears most
252: result = ((Double) vals.get(pos)).doubleValue();
253: return result;
254: }
255:
256: private static double minorityEval(Matrix mat) {
257: double result = 0;
258: //-- built list of all values
259: ArrayList vals = new ArrayList();
260: for (int i = 0; i < mat.getRowDimension(); i++) {
261: for (int j = 0; j < mat.getColumnDimension(); j++) {
262: double val = mat.get(i, j);
263: if ((i == 0) && (j == 0)) {
264: //-- add first value
265: vals.add(new Double(val));
266: } else {
267: boolean stop = false;
268: int count = 0;
269: boolean found = false;
270: while (stop == false) {
271: Double d = (Double) vals.get(count);
272: if (val == d.doubleValue()) {
273: stop = true;
274: found = true;
275: }
276: count++;
277: if (count == vals.size()) {
278: //-- if last value reached stop and add
279: stop = true;
280: }
281: }
282: if (found == false) {
283: vals.add(new Double(val));
284: }
285: }
286: }
287: }
288: //-- count number of values
289: int[] countVals = new int[vals.size()];
290: //-- set to zero
291: for (int i = 0; i < countVals.length; i++) {
292: countVals[i] = 0;
293: }
294: for (int i = 0; i < mat.getRowDimension(); i++) {
295: for (int j = 0; j < mat.getColumnDimension(); j++) {
296: double val = mat.get(i, j);
297: boolean stop = false;
298: int count = 0;
299: while (stop == false) {
300: Double d = (Double) vals.get(count);
301: if (val == d.doubleValue()) {
302: //-- count
303: int oldVal = countVals[count];
304: countVals[count] = oldVal + 1;
305: //-- stop
306: stop = true;
307: }
308: count++;
309: if (count == countVals.length) {
310: stop = true;
311: }
312: }
313: }
314: }
315: //-- get minimum count
316: int mincount = countVals[0];
317: int pos = 0;
318: for (int i = 1; i < countVals.length; i++) {
319: if (countVals[i] < mincount) {
320: mincount = countVals[i];
321: pos = i;
322: }
323: }
324: //-- assign value which appears fewest
325: result = ((Double) vals.get(pos)).doubleValue();
326: return result;
327: }
328:
329: }
|