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 21.06.2006
030: * last modified:
031: *
032: * author: sstein
033: *
034: * description:
035: * joins attribute values according to some spatial and statistical criterion
036: *
037: ***********************************************/package org.openjump.core.spatialAttributeOps;
038:
039: import java.util.ArrayList;
040: import java.util.Collection;
041: import java.util.Iterator;
042: import java.util.List;
043:
044: import com.vividsolutions.jts.geom.Geometry;
045: import com.vividsolutions.jts.index.quadtree.Quadtree;
046: import com.vividsolutions.jump.feature.AttributeType;
047: import com.vividsolutions.jump.feature.BasicFeature;
048: import com.vividsolutions.jump.feature.Feature;
049: import com.vividsolutions.jump.feature.FeatureDataset;
050: import com.vividsolutions.jump.feature.FeatureSchema;
051: import com.vividsolutions.jump.task.TaskMonitor;
052:
053: /**
054: * @description:
055: * joins attribute values according to some spatial and statistical criterion
056: *
057: * @author sstein
058: *
059: *
060: */
061: public class JoinAttributes {
062:
063: /**
064: *
065: * @param sourceFeatures
066: * @param targetFeatures
067: * @param attributeName
068: * @param attributeOp
069: * @param spatialRelation
070: * @param bufferRadius
071: * @return
072: */
073: public static FeatureDataset joinAttributes(
074: Collection sourceFeatures, Collection targetFeatures,
075: String attributeName, int attributeOp, int spatialRelation,
076: double bufferRadius, TaskMonitor monitor) {
077: /*
078: System.out.println("Join Attributes --- attribute op:" + attributeOp + " - " +
079: AttributeOp.getName(attributeOp) + " --- spatial op: " + spatialRelation + " - " +
080: SpatialRelationOp.getName(spatialRelation));
081: */
082: FeatureDataset fd = null;
083: AttributeType newAttributeType = AttributeType.DOUBLE;
084: String newAttributeName = attributeName + "_"
085: + AttributeOp.getName(attributeOp);
086: if (attributeOp == AttributeOp.COUNT) {
087: newAttributeName = AttributeOp.getName(attributeOp);
088: }
089:
090: //-- put all in a tree
091: Quadtree fqTree = new Quadtree();
092: FeatureSchema sourceFS = null;
093: int count = 0;
094: for (Iterator iter = sourceFeatures.iterator(); iter.hasNext();) {
095: Feature pt = (Feature) iter.next();
096: fqTree.insert(pt.getGeometry().getEnvelopeInternal(), pt);
097: if (count == 0) {
098: sourceFS = pt.getSchema();
099: }
100: count++;
101: }
102: //-- get AttributeType
103: AttributeType at = null;
104: try {
105: at = sourceFS.getAttributeType(attributeName);
106: } catch (Exception e) {
107: at = AttributeType.GEOMETRY;
108: attributeName = sourceFS.getAttributeName(0);
109: System.out
110: .println("JoinAttributes.joinAttributes: replace unknown attribute name by geometry");
111: }
112: //
113: ArrayList outPolys = new ArrayList();
114: int size = targetFeatures.size();
115: FeatureSchema targetFSnew = null;
116: count = 0;
117: Iterator iterp = targetFeatures.iterator();
118: while (iterp.hasNext()) {
119: count = count + 1;
120: if (monitor != null) {
121: monitor.report("item: " + count + " of " + size);
122: }
123: Feature p = (Feature) iterp.next();
124: if (count == 1) {
125: FeatureSchema targetFs = p.getSchema();
126: targetFSnew = copyFeatureSchema(targetFs);
127: if (targetFSnew.hasAttribute(newAttributeName)) {
128: //attribute will be overwriten
129: } else {
130: //add attribute
131: targetFSnew.addAttribute(newAttributeName,
132: newAttributeType);
133: }
134: }
135: //-- evaluate value for every polygon
136: double value = evaluateSinglePolygon(p.getGeometry(),
137: fqTree, attributeName, attributeOp,
138: spatialRelation, bufferRadius);
139: Feature fcopy = copyFeature(p, targetFSnew);
140: fcopy.setAttribute(newAttributeName, new Double(value));
141: outPolys.add(fcopy);
142: }
143: fd = new FeatureDataset(targetFSnew);
144: fd.addAll(outPolys);
145: return fd;
146: }
147:
148: /**
149: *
150: * @param poly
151: * @param
152: * @return value
153: */
154: private static double evaluateSinglePolygon(Geometry poly,
155: Quadtree fqTree, String attributeName, int attributeOp,
156: int spatialRelation, double bufferRadius) {
157: List items = SpatialRelationOp.evaluateSpatial(spatialRelation,
158: fqTree, poly, bufferRadius);
159: double val = AttributeOp.evaluateAttributes(attributeOp, items,
160: attributeName);
161: return val;
162: }
163:
164: /**
165: * copy/clone the input featureSchema since it is not proper implemented in Jump
166: * @param oldSchema
167: * @return
168: */
169: private static FeatureSchema copyFeatureSchema(
170: FeatureSchema oldSchema) {
171: FeatureSchema fs = new FeatureSchema();
172: for (int i = 0; i < oldSchema.getAttributeCount(); i++) {
173: AttributeType at = oldSchema.getAttributeType(i);
174: String aname = oldSchema.getAttributeName(i);
175: fs.addAttribute(aname, at);
176: fs.setCoordinateSystem(oldSchema.getCoordinateSystem());
177: }
178: return fs;
179: }
180:
181: /**
182: * copy the input feature to a new Schema whereby the new
183: * Feature Schema musst be an extended or shortened one
184: * @param oldSchema
185: * @return Feature
186: */
187: private static Feature copyFeature(Feature feature,
188: FeatureSchema newSchema) {
189: FeatureSchema oldSchema = feature.getSchema();
190: Feature newF = new BasicFeature(newSchema);
191: int n = 0;
192: if (oldSchema.getAttributeCount() > newSchema
193: .getAttributeCount()) {
194: //for schema shortening
195: n = newSchema.getAttributeCount();
196: } else {
197: //for schema extension
198: n = oldSchema.getAttributeCount();
199: }
200: for (int i = 0; i < n; i++) {
201: String aname = oldSchema.getAttributeName(i);
202: Object value = feature.getAttribute(aname);
203: newF.setAttribute(aname, value);
204: }
205: return newF;
206: }
207:
208: }
|