Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.stretch / src / main / java / org / gvsig / vectorediting / lib / prov / stretch / StretchEditingProvider.java @ 3067

History | View | Annotate | Download (19.1 KB)

1
package org.gvsig.vectorediting.lib.prov.stretch;
2

    
3

    
4

    
5

    
6
import java.awt.geom.AffineTransform;
7
import java.util.ArrayList;
8
import java.util.Collections;
9
import java.util.HashMap;
10
import java.util.Iterator;
11
import java.util.List;
12
import java.util.Map;
13
import org.apache.commons.collections4.CollectionUtils;
14
import org.gvsig.fmap.dal.exception.DataException;
15
import org.gvsig.fmap.dal.feature.EditableFeature;
16
import org.gvsig.fmap.dal.feature.Feature;
17
import org.gvsig.fmap.dal.feature.FeatureSelection;
18
import org.gvsig.fmap.dal.feature.FeatureStore;
19
import org.gvsig.fmap.geom.Geometry;
20
import org.gvsig.fmap.geom.GeometryLocator;
21
import org.gvsig.fmap.geom.GeometryManager;
22
import org.gvsig.fmap.geom.aggregate.Aggregate;
23
import org.gvsig.fmap.geom.aggregate.MultiCurve;
24
import org.gvsig.fmap.geom.aggregate.MultiPoint;
25
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
26
import org.gvsig.fmap.geom.aggregate.MultiSurface;
27
import org.gvsig.fmap.geom.exception.CreateGeometryException;
28
import org.gvsig.fmap.geom.operation.GeometryOperationException;
29
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
30
import org.gvsig.fmap.geom.primitive.Curve;
31
import org.gvsig.fmap.geom.primitive.Point;
32
import org.gvsig.fmap.geom.primitive.Primitive;
33
import org.gvsig.fmap.geom.primitive.Surface;
34
import org.gvsig.fmap.geom.type.GeometryType;
35
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
36
import org.gvsig.tools.ToolsLocator;
37
import org.gvsig.tools.dispose.DisposableIterator;
38
import org.gvsig.tools.dispose.DisposeUtils;
39
import org.gvsig.tools.dynobject.DynObject;
40
import org.gvsig.tools.exception.BaseException;
41
import org.gvsig.tools.i18n.I18nManager;
42
import org.gvsig.tools.service.spi.ProviderServices;
43
import org.gvsig.vectorediting.lib.api.DrawingStatus;
44
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
45
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
46
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
47
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
48
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
49
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
50
import org.gvsig.vectorediting.lib.prov.stretch.operation.StretchOperation;
51
import org.gvsig.vectorediting.lib.prov.stretch.operation.StretchOperationUtils;
52
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
53
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
54
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
55
import org.gvsig.vectorediting.lib.spi.EditingProvider;
56
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
57
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
58
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
59
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
60
import org.slf4j.Logger;
61
import org.slf4j.LoggerFactory;
62

    
63
@SuppressWarnings("UseSpecificCatch")
64
public class StretchEditingProvider extends AbstractEditingProvider implements
65
    EditingProvider {
66

    
67
    private static final Logger LOGGER = LoggerFactory.getLogger(StretchEditingProvider.class);
68

    
69
    private final EditingServiceParameter selectionParameter;
70

    
71
    private final EditingServiceParameter geometryParameter;
72

    
73
    private final EditingServiceParameter firstPointParameter;
74

    
75
    private final EditingServiceParameter secondPointParameter;
76

    
77
    private Map<EditingServiceParameter, Object> values;
78

    
79
    private final FeatureStore featureStore;
80

    
81
    private List<Feature> selectedFeatures;
82
    
83
    public StretchEditingProvider(ProviderServices providerServices,
84
        DynObject parameters) {
85
        super(providerServices);
86
        this.featureStore =
87
            (FeatureStore) parameters
88
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
89
        
90
        I18nManager i18nManager = ToolsLocator.getI18nManager();
91

    
92
        this.selectionParameter =
93
            new DefaultEditingServiceParameter("selection",
94
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
95

    
96
        this.geometryParameter =
97
            new DefaultEditingServiceParameter("Draw geometry",
98
                "draw_geometry_to_select_vertex", Geometry.TYPES.MULTISURFACE, TYPE.GEOMETRY);
99

    
100
        this.firstPointParameter =
101
            new DefaultEditingServiceParameter("first_point",
102
                i18nManager.getTranslation("first_point"), TYPE.VALUE, TYPE.POSITION);
103

    
104
        this.secondPointParameter =
105
            new DefaultEditingServiceParameter("second_point",
106
                i18nManager.getTranslation("second_point"), TYPE.VALUE, TYPE.POSITION);
107

    
108
    }
109

    
110
    @Override
111
    public List<EditingServiceParameter> getParameters() {
112
        List<EditingServiceParameter> list =
113
            new ArrayList<>();
114
        list.add(selectionParameter);
115
        list.add(geometryParameter);
116
        list.add(firstPointParameter);
117
        list.add(secondPointParameter);
118
        return list;
119
    }
120

    
121
    private void validateAndInsertValue(EditingServiceParameter param,
122
        Object value) throws InvalidEntryException {
123
        if (param == selectionParameter) {
124
            if (value instanceof FeatureSelection) {
125
                values.put(param, value);
126
                this.selectedFeatures = this.getSelectedFeaturesCopy((FeatureSelection)value);
127
            }
128
        } else if (param == firstPointParameter) {
129
            if (value instanceof Point) {
130
                values.put(param, value);
131
            }
132
        } else if (param == secondPointParameter) {
133
            if (value instanceof Point) {
134
                values.put(param, value);
135
            }
136
        } else if (param == geometryParameter) {
137
            if (value instanceof Geometry) {
138

    
139
                // Before set value checks if some geometry intersects the
140
                // geometry received as parameter.
141
                Geometry geometry = (Geometry) value;
142
                FeatureSelection selection =
143
                    (FeatureSelection) values.get(selectionParameter);
144
                DisposableIterator it = null;
145

    
146
                try {
147
                    it = selection.fastIterator();
148

    
149
                    while (it.hasNext()) {
150
                        Feature feature = (Feature) it.next();
151

    
152
                        Geometry defaultGeometry = feature.getDefaultGeometry();
153
                        if (defaultGeometry.intersects(geometry) || defaultGeometry.contains(geometry)) {
154
                            values.put(param, value);
155
                            return;
156
                        }
157
                    }
158
                    throw new InvalidEntryException(null);
159
                } catch (BaseException e) {
160
                    throw new InvalidEntryException(e);
161
                } finally {
162
                    DisposeUtils.disposeQuietly(it);
163
                }
164
            }
165
        }
166
    }
167

    
168
    @Override
169
    public EditingServiceParameter next() {
170
        if (values.get(selectionParameter) == null) {
171
            return this.selectionParameter;
172
        } else if (values.get(geometryParameter) == null) {
173
            return this.geometryParameter;
174
        } else if (values.get(firstPointParameter) == null) {
175
            return this.firstPointParameter;
176
        } else if (values.get(secondPointParameter) == null) {
177
            return this.secondPointParameter;
178
        }
179
        return null;
180
    }
181

    
182
    public static Geometry applyTransform(Geometry geometry, AffineTransform at,
183
        Geometry roi) throws CreateGeometryException,
184
        GeometryOperationNotSupportedException, GeometryOperationException {
185
        if (geometry instanceof MultiPrimitive) {
186
            GeometryManager geometryManager = GeometryLocator.getGeometryManager();
187
            MultiPrimitive aggregate = (MultiPrimitive)geometry;
188
            GeometryType geometryType = aggregate.getGeometryType();
189
            MultiPrimitive newAggregate = (MultiPrimitive) geometryManager.create(geometryType.getType(), geometryType.getSubType());
190
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
191
                Primitive primitive = aggregate.getPrimitiveAt(i);
192
                StretchOperation operation = StretchOperationUtils.getOperation(primitive);
193
                if (operation != null) {
194
                    Geometry element = operation.transform(at, primitive, roi);
195
                    if (element instanceof MultiPrimitive) {
196
                        for (int j = 0; j < ((MultiPrimitive)element).getPrimitivesNumber(); j++) {
197
                            newAggregate.addPrimitive(((MultiPrimitive)element).getPrimitiveAt(j));
198
                        }
199
                    } else if(element instanceof Primitive){
200
                        newAggregate.addPrimitive((Primitive)element);
201
                    } else {
202
                        LOGGER.warn("StretchOperation has returned a not-supported geometry type. "+operation.toString()+" "+element.getClass().getName());
203
                    }
204
                } else {
205
                    newAggregate.addPrimitive(primitive);
206
                }
207
            }
208
            return newAggregate;
209
        } else if (geometry instanceof Primitive) {
210
            StretchOperation operation = StretchOperationUtils.getOperation((Primitive)geometry);
211
            if (operation != null) {
212
                return operation.transform(at, (Primitive)geometry, roi);
213
            }
214
        }
215
        return geometry;
216
    }
217

    
218

    
219
    public static List<Point> getSelectedVertex(Geometry geometry,
220
        Geometry roi) throws CreateGeometryException,
221
        GeometryOperationNotSupportedException, GeometryOperationException {
222
        List<Point> selectedVertex = new ArrayList<>();
223
        if (geometry instanceof MultiPrimitive) {
224
            MultiPrimitive aggregate = (MultiPrimitive)geometry;
225
            for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) {
226
                Primitive primitive = aggregate.getPrimitiveAt(i);
227
                StretchOperation operation = StretchOperationUtils.getOperation(primitive);
228
                if (operation != null) {
229
                    selectedVertex.addAll(operation.getSelectedVertex(primitive, roi));
230
                }
231
            }
232
        } else if (geometry instanceof Primitive) {
233
            Primitive primitive = (Primitive)geometry;
234
            StretchOperation operation = StretchOperationUtils.getOperation(primitive);
235
            if (operation != null) {
236
                selectedVertex.addAll(operation.getSelectedVertex(primitive, roi));
237
            }
238
        }
239
        return selectedVertex;
240
    }
241

    
242

    
243
    @Override
244
    public DrawingStatus getDrawingStatus(Point mousePosition)
245
        throws DrawServiceException {
246
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
247
        EditingProviderManager editingProviderManager =
248
            EditingProviderLocator.getProviderManager();
249
        ISymbol selectedVertexEditingSymbol = editingProviderManager.getSymbol("selected-vertex-symbol-editing");
250
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
251
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
252
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
253

    
254
        FeatureSelection selection =
255
            (FeatureSelection) values.get(this.selectionParameter);
256
        try {
257
            if ( CollectionUtils.isNotEmpty(selectedFeatures) ) {
258
                Geometry geometry = (Geometry) values.get(this.geometryParameter);
259
                if (geometry != null) {
260
                    //
261
                    List<Point> selectedVertex = new ArrayList<>();
262
                    try {
263
                        for (Feature feature : selectedFeatures) {
264
                            Geometry featureGeometry = feature.getDefaultGeometry();
265
                            List<Point> vertex = getSelectedVertex(featureGeometry, geometry);
266
                            if(vertex != null){
267
                                selectedVertex.addAll(vertex);
268
                            }
269
                        }
270
                    } catch (BaseException e) {
271
                        throw new InvalidEntryException(e);
272
                    }
273

    
274
                    if(!selectedVertex.isEmpty()){
275
                        for (Point point : selectedVertex) {
276
                            drawingStatus.addStatus(point, selectedVertexEditingSymbol, "");
277
                        }
278
                    }
279

    
280
                    Point firstPoint = (Point) values.get(this.firstPointParameter);
281
                    if (firstPoint != null){
282
                        AffineTransform at = getMoveAffineTransform(firstPoint, mousePosition);
283

    
284
                        if(!selectedVertex.isEmpty()){
285
                            for (Iterator<Point> iterator = selectedVertex.iterator(); iterator.hasNext();) {
286
                                Point point = (Point) ((Point) iterator.next()).cloneGeometry();
287
                                point.transform(at);
288
                                drawingStatus.addStatus(point, selectedVertexEditingSymbol, "");
289
                            }
290
                        }
291

    
292
                        try {
293
                            for (Feature feature : selectedFeatures) {
294
                                ISymbol previewSymbol = this.getPreviewSymbol(feature);
295
        
296
                                Geometry featureGeometry = feature.getDefaultGeometry();
297
                                Geometry transformedGeometry = applyTransform(featureGeometry, at, geometry);
298
                                ISymbol symbol=null;
299
                                if(transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve){
300
                                    symbol = lineSymbolEditing;
301
                                } else if(transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface){
302
                                    symbol = polygonSymbolEditing;
303
                                } else if(transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint){
304
                                    symbol = auxiliaryPointSymbolEditing;
305
                                }
306
                                if(transformedGeometry instanceof Aggregate){
307
                                    int primitivesNumber = ((Aggregate)transformedGeometry).getPrimitivesNumber();
308
                                    for (int i = 0; i < primitivesNumber; i++) {
309
                                        drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), symbol, "");
310
                                        drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), previewSymbol, "");
311
                                    }
312
                                } else {
313
                                    drawingStatus.addStatus(transformedGeometry, symbol, "");
314
                                    drawingStatus.addStatus(transformedGeometry, previewSymbol, "");
315
                                }
316
                            }
317
                        } catch (BaseException e) {
318
                            throw new InvalidEntryException(e);
319
                        }
320
                    }
321
                }
322
                return drawingStatus;
323
            }
324
        } catch (Exception e) {
325
            throw new DrawServiceException(e);
326
        }
327
        return null;
328
    }
329

    
330
    private AffineTransform getMoveAffineTransform(Point p1, Point p2) {
331

    
332
        AffineTransform translate =
333
            AffineTransform.getTranslateInstance(p2.getX() - p1.getX(),
334
                p2.getY() - p1.getY());
335

    
336
        return translate;
337
    }
338

    
339
    @Override
340
    public void stop() {
341
        values.clear();
342
        this.selectedFeatures = Collections.EMPTY_LIST;
343
    }
344

    
345

    
346

    
347
    @Override
348
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
349
        validateAndInsertValue(parameter, value);
350
    }
351

    
352
    @Override
353
    public void setValue(Object value) throws InvalidEntryException {
354
        EditingServiceParameter param = next();
355
        validateAndInsertValue(param, value);
356
    }
357

    
358
    @Override
359
    public void finishAndStore() throws FinishServiceException {
360

    
361
        FeatureSelection selection
362
                = (FeatureSelection) values.get(selectionParameter);
363

    
364
        try {
365
            if ( CollectionUtils.isNotEmpty(selectedFeatures) ) {
366
                Geometry geometry = (Geometry) values.get(this.geometryParameter);
367
                if (geometry != null) {
368
                    Point firstPoint
369
                            = (Point) values.get(this.firstPointParameter);
370
                    if (firstPoint != null) {
371
                        Point secondPoint
372
                                = (Point) values.get(this.secondPointParameter);
373
                        if (secondPoint != null) {
374
                            AffineTransform at
375
                                    = getMoveAffineTransform(firstPoint, secondPoint);
376

    
377
                            try {
378
                                for (Feature feature : selectedFeatures) {
379
                                    Geometry featureGeometry
380
                                            = feature.getDefaultGeometry();
381

    
382
                                    Geometry geom
383
                                            = applyTransform(featureGeometry, at,
384
                                                    geometry);
385

    
386
                                    EditableFeature editableFeature
387
                                            = feature.getEditable();
388
                                    editableFeature.setDefaultGeometry(geom);
389
                                    ((EditingProviderServices) getProviderServices())
390
                                            .updateFeatureInFeatureStore(
391
                                                    editableFeature, featureStore);
392
                                }
393
                            } catch (BaseException e) {
394
                                throw new FinishServiceException(e);
395
                            }
396
                        }
397
                    }
398
                }
399
            }
400
        } catch (Exception e) {
401
            throw new FinishServiceException(e);
402
        }
403
    }
404

    
405
    @Override
406
    public Geometry finish() throws FinishServiceException {
407
        return null;
408
    }
409

    
410
    @Override
411
    public void start() throws StartServiceException {
412
        this.values = new HashMap<>();
413
        this.selectedFeatures = Collections.EMPTY_LIST;
414

    
415
        if (featureStore != null) {
416
            FeatureSelection selected = null;
417
            try {
418
                selected = (FeatureSelection) featureStore.getFeatureSelection().clone();
419
            } catch (DataException e) {
420
                throw new StartServiceException(e);
421
            } catch (CloneNotSupportedException ex) {
422
                LOGGER.debug("Can't init selection",ex);
423
            }
424
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
425
                values.put(selectionParameter, selected);
426
                this.selectedFeatures = this.getSelectedFeaturesCopy(selected);
427
            }
428
        }
429
    }
430

    
431
    @Override
432
    public String getName() {
433
        return StretchEditingProviderFactory.PROVIDER_NAME;
434
    }
435

    
436
    @Override
437
    public Object getValue(EditingServiceParameter parameter) {
438
        return values!=null?values.get(parameter):null;
439
    }
440
}