Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting.symmetry / trunk / org.gvsig.vectorediting.symmetry / org.gvsig.vectorediting.symmetry.lib / org.gvsig.vectorediting.symmetry.lib.prov / org.gvsig.vectorediting.symmetry.lib.prov.symmetry / src / main / java / org / gvsig / vectorediting / symmetry / lib / prov / symmetry / SymmetryEditingProvider.java @ 2944

History | View | Annotate | Download (16.8 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.vectorediting.symmetry.lib.prov.symmetry;
26

    
27
import java.awt.geom.AffineTransform;
28
import java.util.ArrayList;
29
import java.util.HashMap;
30
import java.util.LinkedHashMap;
31
import java.util.List;
32
import java.util.Map;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.EditableFeature;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureSelection;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.aggregate.Aggregate;
41
import org.gvsig.fmap.geom.aggregate.MultiCurve;
42
import org.gvsig.fmap.geom.aggregate.MultiPoint;
43
import org.gvsig.fmap.geom.aggregate.MultiSurface;
44
import org.gvsig.fmap.geom.operation.GeometryOperationException;
45
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
46
import org.gvsig.fmap.geom.primitive.Curve;
47
import org.gvsig.fmap.geom.primitive.Line;
48
import org.gvsig.fmap.geom.primitive.Point;
49
import org.gvsig.fmap.geom.primitive.Primitive;
50
import org.gvsig.fmap.geom.primitive.Surface;
51
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dataTypes.DataTypes;
54
import org.gvsig.tools.dispose.DisposableIterator;
55
import org.gvsig.tools.dynobject.DynObject;
56
import org.gvsig.tools.i18n.I18nManager;
57
import org.gvsig.tools.service.spi.ProviderServices;
58
import org.gvsig.vectorediting.lib.api.DrawingStatus;
59
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
60
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
61
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
63
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
64
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
65
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
66
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
67
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
68
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
69
import org.gvsig.vectorediting.lib.spi.EditingProvider;
70
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
71
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
72
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
73
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
74

    
75
public class SymmetryEditingProvider extends AbstractEditingProvider implements
76
    EditingProvider {
77

    
78
    private final EditingServiceParameter selectionParameter;
79

    
80
    private final EditingServiceParameter firstPointParameter;
81

    
82
    private final EditingServiceParameter secondPointParameter;
83

    
84
    private final EditingServiceParameter deleteOriginalGeometriesParameter;
85

    
86
    private Map<EditingServiceParameter, Object> values;
87

    
88
    private final FeatureStore featureStore;
89

    
90
    public SymmetryEditingProvider(ProviderServices providerServices,
91
        DynObject parameters) {
92
        super(providerServices);
93
        
94
        I18nManager i18nManager = ToolsLocator.getI18nManager();
95

    
96
        this.featureStore =
97
            (FeatureStore) parameters
98
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
99

    
100
        this.selectionParameter =
101
            new DefaultEditingServiceParameter("selection",
102
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
103

    
104
        this.firstPointParameter =
105
            new DefaultEditingServiceParameter("first_point_of_symmetry_axis",
106
                i18nManager.getTranslation("first_point_of_symmetry_axis"),
107
                TYPE.POSITION);
108

    
109
        this.secondPointParameter =
110
            new DefaultEditingServiceParameter("second_point_of_symmetry_axis",
111
                i18nManager.getTranslation("second_point_of_symmetry_axis"),
112
                TYPE.POSITION);
113

    
114
        EditingProviderServices editingProviderServices =
115
            (EditingProviderServices) getProviderServices();
116

    
117
        DefaultEditingServiceParameterOptions deleteOriginalGeometriesOptions2 = new DefaultEditingServiceParameterOptions()
118
                .add("delete_original_geometries", true, i18nManager.getTranslation("_yes"))
119
                .add("keep_original_geometries", false, i18nManager.getTranslation("_no"));
120

    
121
        String consoleMsg
122
                = editingProviderServices.makeConsoleMessage(
123
                        "delete_original_geometries_question", deleteOriginalGeometriesOptions2);
124

    
125
        this.deleteOriginalGeometriesParameter
126
                = new DefaultEditingServiceParameter(
127
                        i18nManager.getTranslation("delete_original_geometries"),
128
                        consoleMsg,
129
                        deleteOriginalGeometriesOptions2,
130
                        false,
131
                        TYPE.OPTION).setDataType(DataTypes.BOOLEAN);;
132
    }
133

    
134
    @Override
135
    public DrawingStatus getDrawingStatus(Point mousePosition)
136
        throws DrawServiceException {
137
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
138
        EditingProviderManager editingProviderManager =
139
            EditingProviderLocator.getProviderManager();
140
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
141
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
142
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
143
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
144

    
145

    
146
        FeatureSelection selected =
147
            (FeatureSelection) values.get(selectionParameter);
148
        try {
149
            if ((selected != null) && !selected.isEmpty()) {
150
                Point p1 = (Point) values.get(firstPointParameter);
151
                if (p1 != null) {
152
                    Object p2Value = values.get(secondPointParameter);
153
                    Point p2;
154
                    if ((p2Value != null) && (p2Value instanceof Point)) {
155
                        p2 = (Point) p2Value;
156
                    } else {
157
                        p2 = mousePosition;
158
                    }
159
                    Line line;
160
                    line =
161
                        GeometryLocator.getGeometryManager().createLine(
162
                            featureStore.getDefaultFeatureType()
163
                                .getDefaultGeometryAttribute().getGeomType()
164
                                .getSubType());
165
                    line.addVertex(p1);
166
                    line.addVertex(p2);
167

    
168
                    drawingStatus.addStatus(line, auxiliaryLineSymbolEditing, "");
169

    
170
                    DisposableIterator it;
171
                    it = selected.fastIterator();
172
                    
173
                    AffineTransform at;
174
                    try {
175
                        at = getSymmetryAffineTransform(p1, p2);
176
                    } catch (Exception e) {
177
                        throw new DrawServiceException(e);
178
                    }
179

    
180
                    while (it.hasNext()) {
181
                        Feature feat = (Feature) it.next();
182
                        
183
                        ISymbol previewSymbol = this.getPreviewSymbol(feat);
184
                        
185
                        Geometry transformedGeometry = feat.getDefaultGeometry().cloneGeometry();
186
                        transformedGeometry.transform(at);
187

    
188
                        ISymbol symbol=null;
189
                        if(transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve){
190
                            symbol = lineSymbolEditing;
191
                        } else if(transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface){
192
                            symbol = polygonSymbolEditing;
193
                        } else if(transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint){
194
                            symbol = auxiliaryPointSymbolEditing;
195
                        }
196
                        if(transformedGeometry instanceof Aggregate){
197
                            int primitivesNumber = ((Aggregate)transformedGeometry).getPrimitivesNumber();
198
                            for (int i = 0; i < primitivesNumber; i++) {
199
                                final Primitive primitive = ((Aggregate)transformedGeometry).getPrimitiveAt(i);
200
                                drawingStatus.addStatus(primitive, symbol, "");
201
                                drawingStatus.addStatus(primitive, previewSymbol, "");
202
                            }
203
                        } else {
204
                            drawingStatus.addStatus(transformedGeometry, symbol, "");
205
                            drawingStatus.addStatus(transformedGeometry, previewSymbol, "");
206
                        }
207
                    }
208
                    it.dispose();
209
                }
210
                return drawingStatus;
211
            }
212
        } catch (Exception e) {
213
            throw new DrawServiceException(e);
214
        }
215
        return null;
216
    }
217

    
218
    private AffineTransform getSymmetryAffineTransform(Point axisP1,
219
        Point axisP2) throws GeometryOperationNotSupportedException,
220
        GeometryOperationException {
221

    
222
        AffineTransform translate =
223
            AffineTransform
224
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
225

    
226
        EditingProviderServices editingProviderServices =
227
            (EditingProviderServices) getProviderServices();
228
        Double angle = -editingProviderServices.getAngle(axisP1, axisP2);
229
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
230

    
231
        AffineTransform symmetry = new AffineTransform(1, 0, 0, -1, 0, 0);
232
        AffineTransform inverseRotate =
233
            AffineTransform.getRotateInstance(-angle);
234
        AffineTransform inverseTranslate =
235
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
236
        AffineTransform at = new AffineTransform(translate);
237

    
238
        at.preConcatenate(rotate);
239
        at.preConcatenate(symmetry);
240
        at.preConcatenate(inverseRotate);
241
        at.preConcatenate(inverseTranslate);
242
        return at;
243
    }
244

    
245
    @Override
246
    public EditingServiceParameter next() {
247
        if (values.get(selectionParameter) == null) {
248
            return this.selectionParameter;
249
        } else if (values.get(firstPointParameter) == null) {
250
            return this.firstPointParameter;
251
        } else if (values.get(secondPointParameter) == null) {
252
            return this.secondPointParameter;
253
        } else if (values.get(deleteOriginalGeometriesParameter) == null) {
254
            return this.deleteOriginalGeometriesParameter;
255
        }
256
        return null;
257
    }
258

    
259
    @Override
260
    public void stop() {
261
        values.clear();
262
    }
263

    
264
    private void validateAndInsertValue(EditingServiceParameter param,
265
        Object value) throws InvalidEntryException {
266
        
267
        I18nManager i18nManager = ToolsLocator.getI18nManager();
268

    
269
        
270
        if (param == selectionParameter) {
271
            if (value instanceof FeatureSelection) {
272
                values.put(param, value);
273
            }
274
        } else if (param == firstPointParameter) {
275
            if (value instanceof Point) {
276
                values.put(param, value);
277
            }
278
        } else if (param == secondPointParameter) {
279
            if (value instanceof Point) {
280
                values.put(param, value);
281
            }
282
        } else if (param == deleteOriginalGeometriesParameter) {
283
            values.put(param, param.getOptions2().getValue(value, param.getDefaultValue()));
284
        }
285

    
286
    }
287

    
288
    @Override
289
    public List<EditingServiceParameter> getParameters() {
290
        List<EditingServiceParameter> list =
291
            new ArrayList<>();
292
        list.add(selectionParameter);
293
        list.add(firstPointParameter);
294
        list.add(secondPointParameter);
295
        list.add(deleteOriginalGeometriesParameter);
296
        return list;
297
    }
298

    
299
    @Override
300
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
301
        validateAndInsertValue(parameter, value);
302
    }
303

    
304
    @Override
305
    public void setValue(Object value) throws InvalidEntryException {
306
        EditingServiceParameter param = next();
307
        validateAndInsertValue(param, value);
308
    }
309

    
310
    @Override
311
    public void finishAndStore() throws FinishServiceException {
312

    
313
        FeatureSelection selected =
314
            (FeatureSelection) values.get(selectionParameter);
315
        final Boolean deleteOriginalGeometriesValue = (Boolean) values.get(deleteOriginalGeometriesParameter);
316
        
317
        try {
318
            if (!selected.isEmpty()) {
319
                Point p1 = (Point) values.get(firstPointParameter);
320
                Point p2 = (Point) values.get(secondPointParameter);
321
                if ((p1 != null) && (p2 != null)) {
322

    
323
                    AffineTransform at;
324
                    try {
325
                        at = getSymmetryAffineTransform(p1, p2);
326
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException e) {
327
                        throw new FinishServiceException(e);
328
                    }
329

    
330
                    DisposableIterator it;
331
                    it = selected.fastIterator();
332

    
333
                    while (it.hasNext()) {
334
                        Feature feature = (Feature) it.next();
335
                        Geometry geom =
336
                            feature.getDefaultGeometry().cloneGeometry();
337
                        geom.transform(at);
338
                        if (deleteOriginalGeometriesValue) {
339
                            // Se sustituye la geometr?a original por la
340
                            // calculada
341
                            EditableFeature editableFeature =
342
                                feature.getEditable();
343
                            editableFeature.setDefaultGeometry(geom);
344
                            ((EditingProviderServices) getProviderServices())
345
                                .updateFeatureInFeatureStore(editableFeature,
346
                                    featureStore);
347
                        } else {
348
                            // Se crea una feature nueva copiando los valores de
349
                            // la feature original excepto aquellos que sean PK
350
                            EditingProviderServices editingProviderServices =
351
                                (EditingProviderServices) getProviderServices();
352
                            EditableFeature editableFeature =
353
                                editingProviderServices
354
                                    .getFeatureCopyWithoutUniqueIndex(featureStore,
355
                                        feature);
356
                            editableFeature.setDefaultGeometry(geom);
357
                            editingProviderServices
358
                                .insertFeatureIntoFeatureStore(editableFeature,
359
                                    featureStore);
360
                        }
361
                    }
362
                    it.dispose();
363
                    featureStore.getFeatureSelection().deselectAll();
364
                }
365
            }
366
        } catch (DataException e) {
367
            throw new FinishServiceException(e);
368
        }
369
    }
370

    
371
    @Override
372
    public Geometry finish() throws FinishServiceException {
373
        return null;
374
    }
375

    
376
    @Override
377
    public void start() throws StartServiceException {
378
        this.values = new HashMap<>();
379
        FeatureSelection selected = null;
380
        if (featureStore != null) {
381
            try {
382
                selected =
383
                    (FeatureSelection) featureStore.getFeatureSelection()
384
                        .clone();
385
            } catch (DataException e) {
386
                throw new StartServiceException(e);
387
            } catch (CloneNotSupportedException e) {
388
                // Do nothing
389
            }
390
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
391
                values.put(selectionParameter, selected);
392
            }
393
        }
394
    }
395

    
396
    @Override
397
    public String getName() {
398
        return SymmetryEditingProviderFactory.PROVIDER_NAME;
399
    }
400

    
401
}