001: package org.openjump.sigle.plugin.geoprocessing.layers;
002:
003: import java.util.Iterator;
004: import java.util.ArrayList;
005: import java.util.List;
006: import java.util.Collection;
007:
008: import com.vividsolutions.jump.I18N;
009: import com.vividsolutions.jump.feature.*;
010: import com.vividsolutions.jts.geom.*;
011:
012: import com.vividsolutions.jump.workbench.ui.GUIUtil;
013: import com.vividsolutions.jump.workbench.ui.GenericNames;
014: import com.vividsolutions.jump.workbench.ui.MenuNames;
015: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
016: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
017: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
018: import com.vividsolutions.jump.workbench.plugin.ThreadedBasePlugIn;
019: import com.vividsolutions.jump.task.TaskMonitor;
020: import com.vividsolutions.jump.tools.AttributeMapping;
021: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
022: import com.vividsolutions.jump.workbench.model.Layer;
023: import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
024: import com.vividsolutions.jump.feature.FeatureCollection;
025:
026: /**
027: * @author ERWAN BOCHER Laboratoire RESO UMR CNRS 6590
028: * @url www.projet-sigle.org
029: * @curentdate 20 févr. 2006
030: * @package name org.openjump.sigle.plugin.geoprocessing.layers
031: * @license Licence CeCILL http://www.cecill.info/
032: * @todo TODO
033: *
034: * Ce plugin permet de réaliser des jointures spatiales en utilisant différents
035: * prédicats spatiaux.
036: *
037: */
038:
039: public class SpatialJoinPlugIn extends ThreadedBasePlugIn {
040:
041: private final static String LAYER1 = GenericNames.LAYER_A;
042: private final static String LAYER2 = GenericNames.LAYER_B;
043: //-- reset in execute to correct language
044: private static String METHODS = I18N
045: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.spatial-operation");
046:
047: private static String METHOD_EQUAL = I18N
048: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal");
049: private static String METHOD_WITHIN = I18N
050: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.within");
051: private static String METHOD_EQUAL_AND_WITHIN = I18N
052: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal-AND-within");
053: private static String METHOD_EQUAL_OR_WITHIN = I18N
054: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal-OR-within");
055:
056: private static Collection getSpatialJoinMethodNames() {
057: Collection names = new ArrayList();
058: names.add(METHOD_EQUAL);
059: names.add(METHOD_WITHIN);
060: names.add(METHOD_EQUAL_AND_WITHIN);
061: names.add(METHOD_EQUAL_OR_WITHIN);
062:
063: return names;
064: }
065:
066: private Collection SpatialJoinMethodNames;
067: private MultiInputDialog dialog;
068: private Layer layer1, layer2;
069: private String methodNameToRun;
070: private boolean exceptionThrown = false;
071:
072: /**
073: * Sets geomentryMethodNames variable using getGeometryMethodNames function.
074: */
075: public SpatialJoinPlugIn() {
076: SpatialJoinMethodNames = getSpatialJoinMethodNames();
077: }
078:
079: public void initialize(PlugInContext context) throws Exception {
080: context
081: .getFeatureInstaller()
082: .addMainMenuItem(
083: this ,
084: new String[] { MenuNames.TOOLS,
085: MenuNames.TOOLS_EDIT_ATTRIBUTES },
086: this .getName(),
087: false,
088: null,
089: new MultiEnableCheck()
090: .add(
091: new EnableCheckFactory(context
092: .getWorkbenchContext())
093: .createTaskWindowMustBeActiveCheck())
094: .add(
095: new EnableCheckFactory(context
096: .getWorkbenchContext())
097: .createAtLeastNLayersMustExistCheck(2)));
098: }
099:
100: public boolean execute(PlugInContext context) throws Exception {
101: METHODS = I18N
102: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.spatial-operation");
103: METHOD_EQUAL = I18N
104: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal");
105: METHOD_WITHIN = I18N
106: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.within");
107: METHOD_EQUAL_AND_WITHIN = I18N
108: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal-AND-within");
109: METHOD_EQUAL_OR_WITHIN = I18N
110: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.equal-OR-within");
111:
112: MultiInputDialog dialog = new MultiInputDialog(context
113: .getWorkbenchFrame(), getName(), true);
114: setDialogValues(dialog, context);
115: GUIUtil.centreOnWindow(dialog);
116: dialog.setVisible(true);
117: if (!dialog.wasOKPressed()) {
118: return false;
119: }
120: getDialogValues(dialog);
121: return true;
122: }
123:
124: public String getName() {
125: return I18N
126: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Transfer-Attributes");
127: }
128:
129: public void run(TaskMonitor monitor, PlugInContext context)
130: throws Exception {
131: FeatureSchema featureSchema = new FeatureSchema();
132:
133: FeatureCollection resultColl = runSpatialJoinMethod(layer1
134: .getFeatureCollectionWrapper(), layer2
135: .getFeatureCollectionWrapper(), methodNameToRun);
136: if (resultColl.size() > 0)
137: context
138: .addLayer(
139: StandardCategoryNames.WORKING,
140: I18N
141: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Result")
142: + methodNameToRun, resultColl);
143: if (exceptionThrown)
144: context
145: .getWorkbenchFrame()
146: .warnUser(
147: I18N
148: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Error-while-executing-spatial-function"));
149: }
150:
151: private FeatureCollection runSpatialJoinMethod(
152: FeatureCollection fcA, FeatureCollection fcB,
153: String methodName) {
154: exceptionThrown = false;
155: FeatureCollection resultFC;
156: Feature fEqual = null;
157: Feature fWithin = null;
158: Feature fEqualAndWithin = null;
159: Feature fEqualOrWithin = null;
160:
161: AttributeMapping mapping = null;
162:
163: mapping = new AttributeMapping(new FeatureSchema(),
164: new FeatureSchema());
165: List aFeatures = null;
166: mapping = new AttributeMapping(fcB.getFeatureSchema(), fcA
167: .getFeatureSchema());
168: aFeatures = fcA.getFeatures();
169:
170: FeatureDataset fcRecup = new FeatureDataset(mapping
171: .createSchema("GEOMETRY"));
172: IndexedFeatureCollection indexedB = new IndexedFeatureCollection(
173: fcB);
174:
175: for (int i = 0; (i < aFeatures.size()); i++) {
176: Feature aFeature = (Feature) aFeatures.get(i);
177: Feature feature = new BasicFeature(fcRecup
178: .getFeatureSchema());
179: int nbFeatureEqual = 0;
180: int nbFeatureWithin = 0;
181: int nbFeatureEqualAndWithin = 0;
182: int nbFeatureEqualOrWithin = 0;
183: int nbFeature = 0;
184:
185: for (Iterator j = indexedB.query(
186: aFeature.getGeometry().getEnvelopeInternal())
187: .iterator(); j.hasNext();) {
188:
189: Feature bFeature = (Feature) j.next();
190: if (methodName.equals(METHOD_EQUAL)) {
191: if (aFeature.getGeometry().equals(
192: bFeature.getGeometry())) {
193: nbFeatureEqual++;
194: nbFeature++;
195: fEqual = bFeature;
196: }
197: }
198:
199: else if (methodName.equals(METHOD_WITHIN)) {
200: if (aFeature.getGeometry().within(
201: bFeature.getGeometry())) {
202: nbFeatureWithin++;
203: nbFeature++;
204: fWithin = bFeature;
205: }
206: }
207:
208: else if (methodName.equals(METHOD_EQUAL_AND_WITHIN)) {
209: if ((aFeature.getGeometry().equals(bFeature
210: .getGeometry()))
211: && ((aFeature.getGeometry().within(bFeature
212: .getGeometry())))) {
213: nbFeatureEqualAndWithin++;
214: nbFeature++;
215: fEqualAndWithin = bFeature;
216: }
217: }
218:
219: else if (methodName.equals(METHOD_EQUAL_OR_WITHIN)) {
220: if ((aFeature.getGeometry().equals(bFeature
221: .getGeometry()))
222: || ((aFeature.getGeometry().within(bFeature
223: .getGeometry())))) {
224: nbFeatureEqualOrWithin++;
225: nbFeature++;
226: fEqualOrWithin = bFeature;
227: }
228: }
229: }
230: // on ne transfere les attributs que lorsque la geometry resultat
231: // n'est contenue que une seule geometry source
232: if (nbFeatureEqual == 1) {
233: mapping.transferAttributes(fWithin, aFeature, feature);
234: feature.setGeometry((Geometry) aFeature.getGeometry()
235: .clone());
236: fcRecup.add(feature);
237: }
238:
239: else if (nbFeatureWithin == 1) {
240: mapping.transferAttributes(fEqual, aFeature, feature);
241: feature.setGeometry((Geometry) aFeature.getGeometry()
242: .clone());
243: fcRecup.add(feature);
244: }
245:
246: else if (nbFeatureWithin == 1) {
247: mapping.transferAttributes(fEqual, aFeature, feature);
248: feature.setGeometry((Geometry) aFeature.getGeometry()
249: .clone());
250: fcRecup.add(feature);
251: }
252:
253: else if (nbFeatureEqualAndWithin == 1) {
254: mapping.transferAttributes(fEqual, aFeature, feature);
255: feature.setGeometry((Geometry) aFeature.getGeometry()
256: .clone());
257: fcRecup.add(feature);
258: }
259:
260: else if (nbFeatureEqualOrWithin == 1) {
261: mapping.transferAttributes(fEqual, aFeature, feature);
262: feature.setGeometry((Geometry) aFeature.getGeometry()
263: .clone());
264: fcRecup.add(feature);
265: }
266:
267: // on clone la geometry pour que les modifs sur la geometry source
268: // ne soient pas transferees sur la geometry resultat
269: //feature.setGeometry((Geometry) aFeature.getGeometry().clone());
270: // fcRecup.add(feature);
271:
272: }
273: return fcRecup;
274: }
275:
276: private void setDialogValues(MultiInputDialog dialog,
277: PlugInContext context) {
278: //dialog.setSideBarImage(new ImageIcon(getClass().getResource("DiffSegments.png")));
279: dialog
280: .setSideBarDescription(I18N
281: .get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Transfers-the-attributes-of-Layer-B-to-Layer-A-using-a-spatial-criterion"));
282: //Set initial layer values to the first and second layers in the layer list.
283: //In #initialize we've already checked that the number of layers >= 2. [Jon Aquino]
284: dialog.addLayerComboBox(LAYER1, layer1, context
285: .getLayerManager());
286: dialog.addLayerComboBox(LAYER2, layer2, context
287: .getLayerManager());
288: dialog.addComboBox(METHODS, methodNameToRun,
289: SpatialJoinMethodNames, null);
290:
291: }
292:
293: private void getDialogValues(MultiInputDialog dialog) {
294: layer1 = dialog.getLayer(LAYER1);
295: layer2 = dialog.getLayer(LAYER2);
296: methodNameToRun = dialog.getText(METHODS);
297: }
298:
299: }
|