/** * Returns a Collection with double values that are corresponding to the class breaks. Note: the * smallest number is equal to the minValue of all attributes. */ public Collection filterAttributeValues(SortedSet attributeValues) { // -1 because one row in the table is reserved for "all other values". [Bob Boseko] // int classCount = getRangeCount() - 1; Collection filteredValues = new ArrayList(); if (attributeValues.size() == 0) { return filteredValues; } // -1 deleted because class range is false int classCount = Math.min(getRangeCount(), attributeValues.size()); // -- [sstein 15.Feb. 2009] // replaced O-Bedels code by own code to be consistent // in case somebody uses Classifier1D methods for classification // and attaches the result as attribute values (i.e. to ensure // that same values are obtained) /* int featuresCount = stylePanel.getLayer().getFeatureCollectionWrapper().size(); double avgClassSize = ((double) featuresCount) / ((double) classCount); // type double to avoid round off errors SortedMap valuesCount = stylePanel.getAttributeValuesCount(); Collection filteredValues = getQuantileBreaks(avgClassSize, valuesCount); */ // -- sstein: new code double[] data = new double[attributeValues.size()]; int i = 0; boolean isInteger = false; for (Iterator iterator = attributeValues.iterator(); iterator.hasNext(); ) { Object val = (Object) iterator.next(); if (val instanceof Integer) { data[i] = (Integer) val; isInteger = true; } else if (val instanceof Double) { data[i] = (Double) val; } else { data[i] = Double.NaN; } i++; } double[] breaks = Classifier1D.classifyEqualNumber(data, classCount); double minVal = org.math.array.DoubleArray.min(data); // add minVal as smallest value if (isInteger) { filteredValues.add(new Integer((int) minVal)); } else { filteredValues.add(new Double(minVal)); } for (int j = 0; j < breaks.length; j++) { if (isInteger) { filteredValues.add(new Integer((int) breaks[j])); } else { filteredValues.add(new Double(breaks[j])); } } // -- sstein: end return filteredValues; }
private void setDialogValues(MultiInputDialog dialog, PlugInContext context) { dialog.setSideBarDescription(sideBarText); dialog.addLayerComboBox(CLAYER, context.getCandidateLayer(0), context.getLayerManager()); List listNumAttributes = FeatureSchemaTools.getFieldsFromLayerWithoutGeometryAndString(context.getCandidateLayer(0)); Object valAttribute = listNumAttributes.size() > 0 ? listNumAttributes.iterator().next() : null; final JComboBox jcb_attribute = dialog.addComboBox(this.ATTRIBUTE, valAttribute, listNumAttributes, this.ATTRIBUTE); if (listNumAttributes.size() == 0) jcb_attribute.setEnabled(false); List listClassifiers = Classifier1D.getAvailableClassificationMethods(); Object valClassifier = listNumAttributes.size() > 0 ? listNumAttributes.iterator().next() : null; final JComboBox jcb_classifier = dialog.addComboBox(this.CLASSIFIER, valClassifier, listClassifiers, this.CLASSIFIER); dialog.addIntegerField(T2, this.ranges, 6, T2); dialog.addCheckBox(this.OPTIMIZEWITHKMEANS, false); dialog.addCheckBox(this.PROCESSNULLASZERO, false); dialog .getComboBox(CLAYER) .addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { List list = getFieldsFromLayerWithoutGeometryAndString(); if (list.size() == 0) { jcb_attribute.setModel(new DefaultComboBoxModel(new String[0])); jcb_attribute.setEnabled(false); } else { jcb_attribute.setModel(new DefaultComboBoxModel(list.toArray(new String[0]))); jcb_attribute.setEnabled(true); } } }); }
private FeatureDataset classifyAndCreatePlot(TaskMonitor monitor, final PlugInContext context) throws Exception { monitor.report(this.sCalculateBreaks); // =============== get DATA and prepare ==============/ FeatureSchema fs = this.fc.getFeatureSchema(); AttributeType type = null; if ((fs.getAttributeType(this.selAttribute) == AttributeType.DOUBLE) || (fs.getAttributeType(this.selAttribute) == AttributeType.INTEGER)) { // -- move on type = fs.getAttributeType(this.selAttribute); } else { // System.out.println("ClassifyAttributesPlugIn: wrong datatype of chosen attribute"); context.getWorkbenchFrame().warnUser(sWrongDataType); return null; } int size = getFeatureCollectionSize(this.fc, this.selAttribute, this.nullAsZero); if (size < 3) { return null; } this.ranges = Math.min(this.ranges, size); double[] data = new double[size]; double[][] plotdata = new double[2][size]; // for drawing 1-D scatter plot int[] fID = new int[size]; int i = 0; for (Iterator iter = fc.iterator(); iter.hasNext(); ) { Feature f = (Feature) iter.next(); if (f.getAttribute(this.selAttribute) == null && !nullAsZero) continue; fID[i] = f.getID(); plotdata[1][i] = 1; Object val = f.getAttribute(this.selAttribute); if (type == AttributeType.DOUBLE) { if (val == null) data[i] = 0.0; else data[i] = ((Double) val).doubleValue(); } else if (type == AttributeType.INTEGER) { if (val == null) data[i] = 0; else data[i] = ((Integer) val).intValue(); } plotdata[0][i] = data[i]; i++; } /* //-- some testdata double[][] plotdata2 = new double[2][8]; double[] data2 = { -2, 4, 6, 5, 0, 10, 7, 1 }; double[] axis2 = { 1, 1, 1, 1, 1, 1, 1, 1 }; plotdata2[0] = data2; plotdata2[1] = axis2; */ if (monitor.isCancelRequested()) { return null; } // =============== find breaks according to chosen method ==============/ double[] limits = null; if (this.useKmeans == false) { if (this.selClassifier == Classifier1D.EQUAL_NUMBER) { limits = Classifier1D.classifyEqualNumber(data, this.ranges); } else if (this.selClassifier == Classifier1D.EQUAL_RANGE) { limits = Classifier1D.classifyEqualRange(data, this.ranges); } else if (this.selClassifier == Classifier1D.MEAN_STDEV) { limits = Classifier1D.classifyMeanStandardDeviation(data, this.ranges); } else if (this.selClassifier == Classifier1D.MAX_BREAKS) { limits = Classifier1D.classifyMaxBreaks(data, this.ranges); } else if (this.selClassifier == Classifier1D.JENKS_BREAKS) { limits = Classifier1D.classifyNaturalBreaks(data, this.ranges); } } else { if (this.selClassifier == Classifier1D.EQUAL_NUMBER) { limits = Classifier1D.classifyKMeansOnExistingBreaks(data, this.ranges, 3); } else if (this.selClassifier == Classifier1D.EQUAL_RANGE) { limits = Classifier1D.classifyKMeansOnExistingBreaks(data, this.ranges, 2); } else if (this.selClassifier == Classifier1D.MEAN_STDEV) { limits = Classifier1D.classifyKMeansOnExistingBreaks(data, this.ranges, 4); } else if (this.selClassifier == Classifier1D.MAX_BREAKS) { limits = Classifier1D.classifyKMeansOnExistingBreaks(data, this.ranges, 1); } else if (this.selClassifier == Classifier1D.JENKS_BREAKS) { limits = Classifier1D.classifyKMeansOnExistingBreaks(data, this.ranges, 5); } } if (monitor.isCancelRequested()) { return null; } monitor.report(this.sDisplayBreaks); // =============== plot data and class breaks ==============/ // -- do display here - in case we later want to allow interactive editing of the limits // -- reformat limits double[][] limits2show = new double[2][limits.length]; // -- due to bug in jmathplot add limits twice if only three classes = 2breaks are sought if (limits.length == 2) { limits2show = new double[2][limits.length * 2]; } for (int j = 0; j < limits.length; j++) { limits2show[0][j] = limits[j]; // x-axis limits2show[1][j] = Math.floor( i / (4.0 * this.ranges)); // y-axis, estimate height of "bar" from number of items // limits2show[1][j]= 1; // -- due to bug in jmathplot add limits twice if only three classes are sought if (limits.length == 2) { limits2show[0][limits.length + j] = limits[j]; limits2show[1][limits.length + j] = Math.floor(i / (4.0 * this.ranges)); } } // =============== plot data and class breaks ==============/ // -- create plots /*final Plot2DPanelOJ*/ plot = new Plot2DPanelOJ(); plot.addHistogramPlotOJ( this.selAttribute, data, this.ranges * 3, context, selLayer, this.selAttribute); plot.addScatterPlotOJ(this.sDatapoints, plotdata, fID, context, this.selLayer); plot.addBarPlot(this.sClassbreaks, limits2show); plot.plotToolBar.setVisible(true); plot.setAxisLabel(0, this.selAttribute); plot.setAxisLabel(1, this.sCount); plot.addLegend("SOUTH"); // [mmichaud 2012-04-09] Moved in run method after the addLayer method // to avoid the problem of the focus change // JInternalFrame frame = new JInternalFrame(this.sHistogram); // frame.setLayout(new BorderLayout()); // frame.add(plot, BorderLayout.CENTER); // frame.setClosable(true); // frame.setResizable(true); // frame.setMaximizable(true); // frame.setSize(450, 450); // frame.setVisible(true); // context.getWorkbenchFrame().addInternalFrame(frame); // =============== classify data ==============/ if (monitor.isCancelRequested()) { return null; } monitor.report(this.sClassifying); int[] classes = Classifier1D.classifyData(data, limits); // double[] classes = org.math.array.StatisticSample.one(data.length); // context.getWorkbenchFrame().warnUser("classification not yet implemented"); // =============== add field ==============/ if (monitor.isCancelRequested()) { return null; } monitor.report(sAddingField); FeatureDataset fd = null; ArrayList outData = new ArrayList(); FeatureSchema targetFSnew = null; int count = 0; Iterator iterp = fc.iterator(); String attname = this.selAttribute + "_" + this.selClassifier; while (iterp.hasNext()) { // count=count+1; // if(monitor != null){ // monitor.report("item: " + count + " of " + size); // } Feature p = (Feature) iterp.next(); Object val = p.getAttribute(this.selAttribute); if (val == null && !this.nullAsZero) continue; else count++; if (count == 1) { FeatureSchema targetFs = p.getSchema(); targetFSnew = FeatureSchemaTools.copyFeatureSchema(targetFs); if (targetFSnew.hasAttribute(attname)) { // attribute will be overwriten } else { // add attribute targetFSnew.addAttribute(attname, AttributeType.INTEGER); } } // -- evaluate value for every polygon Feature fcopy = FeatureSchemaTools.copyFeature(p, targetFSnew); // fcopy.setAttribute(this.selClassifier, new Integer(classes[count-1])); fcopy.setAttribute(attname, new Integer(classes[count - 1])); outData.add(fcopy); } fd = new FeatureDataset(targetFSnew); fd.addAll(outData); return fd; }