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.symmetry / src / main / java / org / gvsig / vectorediting / lib / prov / symmetry / SymmetryEditingProvider.java @ 66

History | View | Annotate | Download (11 KB)

1
/*
2
 * Copyright 2014 DiSiD Technologies S.L.L. All rights reserved.
3
 *
4
 * Project  : DiSiD org.gvsig.vectorediting.lib.prov.symmetry
5
 * SVN Id   : $Id$
6
 */
7
package org.gvsig.vectorediting.lib.prov.symmetry;
8

    
9
import java.awt.geom.AffineTransform;
10
import java.util.ArrayList;
11
import java.util.HashMap;
12
import java.util.Iterator;
13
import java.util.List;
14
import java.util.Map;
15

    
16
import org.gvsig.fmap.dal.exception.DataException;
17
import org.gvsig.fmap.dal.feature.EditableFeature;
18
import org.gvsig.fmap.dal.feature.Feature;
19
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
20
import org.gvsig.fmap.dal.feature.FeatureSelection;
21
import org.gvsig.fmap.dal.feature.FeatureStore;
22
import org.gvsig.fmap.dal.feature.FeatureType;
23
import org.gvsig.fmap.geom.Geometry;
24
import org.gvsig.fmap.geom.GeometryLocator;
25
import org.gvsig.fmap.geom.GeometryManager;
26
import org.gvsig.fmap.geom.operation.GeometryOperationException;
27
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
28
import org.gvsig.fmap.geom.primitive.Line;
29
import org.gvsig.fmap.geom.primitive.Point;
30
import org.gvsig.tools.ToolsLocator;
31
import org.gvsig.tools.dispose.DisposableIterator;
32
import org.gvsig.tools.dynobject.DynObject;
33
import org.gvsig.tools.i18n.I18nManager;
34
import org.gvsig.tools.service.spi.ProviderServices;
35
import org.gvsig.vectorediting.lib.api.DrawingStatus;
36
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
37
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
38
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
39
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
40
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
41
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
42
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
43
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
44
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
45
import org.gvsig.vectorediting.lib.spi.EditingProvider;
46
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
47
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
48

    
49
public class SymmetryEditingProvider extends AbstractEditingProvider implements EditingProvider {
50

    
51
        protected GeometryManager geomManager = GeometryLocator
52
                        .getGeometryManager();
53

    
54
        private I18nManager i18nManager = ToolsLocator.getI18nManager();
55

    
56
        private EditingServiceParameter selectionParameter = new DefaultEditingServiceParameter(
57
                        "Selection", i18nManager.getTranslation("selection"),
58
                        TYPE.SELECTION);
59

    
60
        private EditingServiceParameter firstPointParameter = new DefaultEditingServiceParameter(
61
                        "First point",
62
                        i18nManager.getTranslation("first_point_of_symmetry_axis"),
63
                        TYPE.POSITION);
64

    
65
        private EditingServiceParameter secondPointParameter = new DefaultEditingServiceParameter(
66
                        "Second point",
67
                        i18nManager.getTranslation("second_point_of_symmetry_axis"),
68
                        TYPE.POSITION);
69

    
70
        private EditingServiceParameter deleteOriginalGeometriesParameter = new DefaultEditingServiceParameter(
71
                        "Delete original geometries", i18nManager
72
                                        .getTranslation("delete_original_geometries_question")
73
                                        .concat(" (")
74
                                        .concat(i18nManager.getTranslation("short_yes"))
75
                                        .concat("/").concat(i18nManager.getTranslation("short_no"))
76
                                        .concat(") "), TYPE.OPTION);
77

    
78
        private boolean deleteOriginalGeometries = false;
79

    
80
        private Map<EditingServiceParameter, Object> values;
81

    
82
        private FeatureStore featureStore;
83

    
84
        public SymmetryEditingProvider(ProviderServices providerServices,
85
                        DynObject parameters) {
86
                super(providerServices);
87
                this.featureStore = (FeatureStore) parameters
88
                                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
89
        }
90

    
91
        public DrawingStatus draw(Point mousePosition) throws DrawServiceException {
92
                DefaultDrawingStatus geometries = new DefaultDrawingStatus();
93

    
94
                FeatureSelection selected = (FeatureSelection) values
95
                                .get(selectionParameter);
96
                try {
97
                        if (selected != null && !selected.isEmpty()) {
98
                                Point p1 = (Point) values.get(firstPointParameter);
99
                                if (p1 != null) {
100
                                        Object p2Value = values.get(secondPointParameter);
101
                                        Point p2 = null;
102
                                        if (p2Value != null && p2Value instanceof Point) {
103
                                                p2 = (Point) p2Value;
104
                                        } else {
105
                                                p2 = mousePosition;
106
                                        }
107
                                        Line line;
108
                                        line = geomManager.createLine(featureStore
109
                                                        .getDefaultFeatureType()
110
                                                        .getDefaultGeometryAttribute().getGeomType()
111
                                                        .getSubType());
112
                                        line.addVertex(p1);
113
                                        line.addVertex(p2);
114

    
115
                                        geometries.addGeometry(line);
116

    
117
                                        DisposableIterator it;
118
                                        it = selected.fastIterator();
119

    
120
                                        AffineTransform at;
121
                                        try {
122
                                                at = getSymmetryAffineTransform(p1, p2);
123
                                        } catch (Exception e) {
124
                                                throw new DrawServiceException(e);
125
                                        }
126

    
127
                                        while (it.hasNext()) {
128
                                                Feature feat = (Feature) it.next();
129
                                                Geometry geom = (Geometry) feat.getDefaultGeometry()
130
                                                                .cloneGeometry();
131
                                                geom.transform(at);
132
                                                geometries.addGeometry(geom);
133
                                        }
134
                                        it.dispose();
135
                                }
136
                                return geometries;
137
                        }
138
                } catch (Exception e) {
139
                        throw new DrawServiceException(e);
140
                }
141

    
142
                return null;
143

    
144
        }
145

    
146
        private AffineTransform getSymmetryAffineTransform(Point axisP1,
147
                        Point axisP2) throws GeometryOperationNotSupportedException,
148
                        GeometryOperationException {
149

    
150
                AffineTransform translate = AffineTransform.getTranslateInstance(
151
                                -axisP1.getX(), -axisP1.getY());
152

    
153
                Double angle = -getAngle(axisP1, axisP2);
154
                AffineTransform rotate = AffineTransform.getRotateInstance(angle);
155

    
156
                AffineTransform symmetry = new AffineTransform(1, 0, 0, -1, 0, 0);
157
                AffineTransform inverseRotate = AffineTransform
158
                                .getRotateInstance(-angle);
159
                AffineTransform inverseTranslate = AffineTransform
160
                                .getTranslateInstance(axisP1.getX(), axisP1.getY());
161
                AffineTransform at = new AffineTransform(translate);
162

    
163
                at.preConcatenate(rotate);
164
                at.preConcatenate(symmetry);
165
                at.preConcatenate(inverseRotate);
166
                at.preConcatenate(inverseTranslate);
167
                return at;
168
        }
169

    
170
        private static Double getAngle(Point start, Point end)
171
                        throws GeometryOperationNotSupportedException,
172
                        GeometryOperationException {
173
                Double angle = Math.acos((end.getX() - start.getX())
174
                                / start.distance(end));
175
                if (start.getY() > end.getY()) {
176
                        angle = -angle;
177
                }
178
                return angle;
179
        }
180

    
181
        public EditingServiceParameter next() {
182
                if (values.get(selectionParameter) == null) {
183
                        return this.selectionParameter;
184
                } else if (values.get(firstPointParameter) == null) {
185
                        return this.firstPointParameter;
186
                } else if (values.get(secondPointParameter) == null) {
187
                        return this.secondPointParameter;
188
                } else if (values.get(deleteOriginalGeometriesParameter) == null) {
189
                        return this.deleteOriginalGeometriesParameter;
190
                }
191
                return null;
192
        }
193

    
194
        public void stop() {
195

    
196
        }
197

    
198
        private void validateAndInsertValue(EditingServiceParameter param,
199
                        Object value) throws InvalidEntryException {
200
                if (param == selectionParameter) {
201
                        if (value instanceof FeatureSelection) {
202
                                values.put(param, value);
203
                                return;
204
                        }
205
                } else if (param == firstPointParameter) {
206
                        if (value instanceof Point) {
207
                                values.put(param, value);
208
                                return;
209
                        }
210
                } else if (param == secondPointParameter) {
211
                        if (value instanceof Point) {
212
                                values.put(param, value);
213
                                return;
214
                        }
215
                } else if (param == deleteOriginalGeometriesParameter) {
216
                        if (value instanceof String) {
217
                                if (((String) value).trim().equalsIgnoreCase(i18nManager
218
                                                .getTranslation("short_yes"))) {
219
                                        deleteOriginalGeometries = true;
220
                                } else if (((String) value).trim().equalsIgnoreCase(i18nManager
221
                                                .getTranslation("short_no"))) {
222
                                        deleteOriginalGeometries = false;
223
                                } else {
224
                                        throw new InvalidEntryException(null);
225
                                }
226
                                values.put(param, value);
227
                        }
228
                }
229

    
230
        }
231

    
232
        public List<EditingServiceParameter> getParameters() {
233
                List<EditingServiceParameter> list = new ArrayList<EditingServiceParameter>();
234
                list.add(selectionParameter);
235
                list.add(firstPointParameter);
236
                list.add(secondPointParameter);
237
                return list;
238
        }
239

    
240
        public void value(Object value) throws InvalidEntryException {
241
                EditingServiceParameter param = next();
242
                validateAndInsertValue(param, value);
243
        }
244

    
245
        public void finish() throws FinishServiceException {
246

    
247
                FeatureSelection selected = (FeatureSelection) values
248
                                .get(selectionParameter);
249
                try {
250
                        if (!selected.isEmpty()) {
251
                                Point p1 = (Point) values.get(firstPointParameter);
252
                                Point p2 = (Point) values.get(secondPointParameter);
253
                                if (p1 != null && p2 != null) {
254

    
255
                                        AffineTransform at;
256
                                        try {
257
                                                at = getSymmetryAffineTransform(p1, p2);
258
                                        } catch (GeometryOperationNotSupportedException e) {
259
                                                throw new FinishServiceException(e);
260
                                        } catch (GeometryOperationException e) {
261
                                                throw new FinishServiceException(e);
262
                                        }
263

    
264
                                        DisposableIterator it;
265
                                        it = selected.fastIterator();
266

    
267
                                        while (it.hasNext()) {
268
                                                Feature feat = (Feature) it.next();
269
                                                Geometry geom = (Geometry) feat.getDefaultGeometry()
270
                                                                .cloneGeometry();
271
                                                geom.transform(at);
272
                                                if (this.deleteOriginalGeometries) {
273
                                                        // Se sustituye la geometr?a original por la
274
                                                        // calculada
275
                                                        EditableFeature editableFeature = feat
276
                                                                        .getEditable();
277
                                                        editableFeature.setDefaultGeometry(geom);
278
                                                        ((EditingProviderServices) getProviderServices())
279
                                                                        .updateFeatureInFeatureStore(
280
                                                                                        editableFeature, featureStore);
281
                                                } else {
282
                                                        // Se crea una feature nueva copiando los valores de
283
                                                        // la feature original excepto aquellos que sean PK
284
                                                        EditableFeature editableFeature = getFeatureCopyWithoutPK(feat);
285
                                                        editableFeature.setDefaultGeometry(geom);
286
                                                        ((EditingProviderServices) getProviderServices())
287
                                                                        .insertFeatureIntoFeatureStore(
288
                                                                                        editableFeature, featureStore);
289
                                                }
290
                                        }
291
                                        it.dispose();
292
                                        featureStore.getFeatureSelection().deselectAll();
293
                                }
294
                        }
295
                } catch (DataException e) {
296
                        throw new FinishServiceException(e);
297
                }
298
        }
299

    
300
        private EditableFeature getFeatureCopyWithoutPK(Feature feat)
301
                        throws DataException {
302
                EditableFeature editableFeature = featureStore.createNewFeature(
303
                                feat.getType(), true);
304

    
305
                FeatureType type_src = feat.getType();
306
                @SuppressWarnings("rawtypes")
307
                Iterator iterator = type_src.iterator();
308
                FeatureType type_dest = editableFeature.getType();
309

    
310
                while (iterator.hasNext()) {
311
                        FeatureAttributeDescriptor attribute_src = (FeatureAttributeDescriptor) iterator
312
                                        .next();
313

    
314
                        FeatureAttributeDescriptor attribute_dest = type_dest
315
                                        .getAttributeDescriptor(attribute_src.getName());
316
                        if (attribute_dest != null) {
317
                                if (!attribute_dest.isPrimaryKey()) {
318
                                        editableFeature.set(attribute_dest.getIndex(),
319
                                                        feat.get(attribute_src.getIndex()));
320
                                }
321
                        }
322
                }
323
                return editableFeature;
324
        }
325

    
326
        public void start() throws StartServiceException {
327
                this.values = new HashMap<EditingServiceParameter, Object>();
328
                FeatureSelection selected = null;
329
                if (featureStore != null) {
330
                        try {
331
                                selected = featureStore.getFeatureSelection();
332
                        } catch (DataException e) {
333
                                throw new StartServiceException(e);
334
                        }
335
                        if (selected != null && selected.getSelectedCount() > 0) {
336
                                values.put(selectionParameter, selected);
337
                        }
338
                }
339
        }
340

    
341
        public String getName() {
342
                return SymmetryEditingProviderFactory.PROVIDER_NAME;
343
        }
344

    
345
}