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 @ 80

History | View | Annotate | Download (10.7 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.EditingLocator;
37
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
38
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
39
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
40
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
41
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
42
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
43
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
44
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
45
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
46
import org.gvsig.vectorediting.lib.spi.EditingProvider;
47
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
48
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
49
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
50

    
51
public class SymmetryEditingProvider extends AbstractEditingProvider implements EditingProvider {
52

    
53
        protected GeometryManager geomManager = GeometryLocator
54
                        .getGeometryManager();
55

    
56
        private I18nManager i18nManager = ToolsLocator.getI18nManager();
57

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

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

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

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

    
80
        private boolean deleteOriginalGeometries = false;
81

    
82
        private Map<EditingServiceParameter, Object> values;
83

    
84
        private FeatureStore featureStore;
85

    
86
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
87

    
88
        public SymmetryEditingProvider(ProviderServices providerServices,
89
                        DynObject parameters) {
90
                super(providerServices);
91
                this.featureStore = (FeatureStore) parameters
92
                                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
93
        }
94

    
95
        public DrawingStatus draw(Point mousePosition) throws DrawServiceException {
96
                DefaultDrawingStatus geometries = new DefaultDrawingStatus();
97

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

    
119
                                        geometries.addGeometry(line);
120

    
121
                                        DisposableIterator it;
122
                                        it = selected.fastIterator();
123

    
124
                                        AffineTransform at;
125
                                        try {
126
                                                at = getSymmetryAffineTransform(p1, p2);
127
                                        } catch (Exception e) {
128
                                                throw new DrawServiceException(e);
129
                                        }
130

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

    
146
                return null;
147

    
148
        }
149

    
150
        private AffineTransform getSymmetryAffineTransform(Point axisP1,
151
                        Point axisP2) throws GeometryOperationNotSupportedException,
152
                        GeometryOperationException {
153

    
154
                AffineTransform translate = AffineTransform.getTranslateInstance(
155
                                -axisP1.getX(), -axisP1.getY());
156

    
157
                Double angle = -getAngle(axisP1, axisP2);
158
                AffineTransform rotate = AffineTransform.getRotateInstance(angle);
159

    
160
                AffineTransform symmetry = new AffineTransform(1, 0, 0, -1, 0, 0);
161
                AffineTransform inverseRotate = AffineTransform
162
                                .getRotateInstance(-angle);
163
                AffineTransform inverseTranslate = AffineTransform
164
                                .getTranslateInstance(axisP1.getX(), axisP1.getY());
165
                AffineTransform at = new AffineTransform(translate);
166

    
167
                at.preConcatenate(rotate);
168
                at.preConcatenate(symmetry);
169
                at.preConcatenate(inverseRotate);
170
                at.preConcatenate(inverseTranslate);
171
                return at;
172
        }
173

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

    
185
        public EditingServiceParameter next() {
186
                if (values.get(selectionParameter) == null) {
187
                        return this.selectionParameter;
188
                } else if (values.get(firstPointParameter) == null) {
189
                        return this.firstPointParameter;
190
                } else if (values.get(secondPointParameter) == null) {
191
                        return this.secondPointParameter;
192
                } else if (values.get(deleteOriginalGeometriesParameter) == null) {
193
                        return this.deleteOriginalGeometriesParameter;
194
                }
195
                return null;
196
        }
197

    
198
        public void stop() {
199

    
200
        }
201

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

    
234
        }
235

    
236
        public List<EditingServiceParameter> getParameters() {
237
                List<EditingServiceParameter> list = new ArrayList<EditingServiceParameter>();
238
                list.add(selectionParameter);
239
                list.add(firstPointParameter);
240
                list.add(secondPointParameter);
241
                return list;
242
        }
243

    
244
        public void value(Object value) throws InvalidEntryException {
245
                EditingServiceParameter param = next();
246
                validateAndInsertValue(param, value);
247
        }
248

    
249
        public void finishAndStore() throws FinishServiceException {
250

    
251
                FeatureSelection selected = (FeatureSelection) values
252
                                .get(selectionParameter);
253
                try {
254
                        if (!selected.isEmpty()) {
255
                                Point p1 = (Point) values.get(firstPointParameter);
256
                                Point p2 = (Point) values.get(secondPointParameter);
257
                                if (p1 != null && p2 != null) {
258

    
259
                                        AffineTransform at;
260
                                        try {
261
                                                at = getSymmetryAffineTransform(p1, p2);
262
                                        } catch (GeometryOperationNotSupportedException e) {
263
                                                throw new FinishServiceException(e);
264
                                        } catch (GeometryOperationException e) {
265
                                                throw new FinishServiceException(e);
266
                                        }
267

    
268
                                        DisposableIterator it;
269
                                        it = selected.fastIterator();
270

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

    
308
        public void start() throws StartServiceException {
309
                this.values = new HashMap<EditingServiceParameter, Object>();
310
                FeatureSelection selected = null;
311
                if (featureStore != null) {
312
                        try {
313
                                selected = (FeatureSelection) featureStore.getFeatureSelection().clone();
314
                        } catch (DataException e) {
315
                                throw new StartServiceException(e);
316
                        } catch (CloneNotSupportedException e) {
317
                                // Do nothing
318
                        }
319
                        if (selected != null && selected.getSelectedCount() > 0) {
320
                                values.put(selectionParameter, selected);
321
                        }
322
                }
323
        }
324

    
325
        public String getName() {
326
                return SymmetryEditingProviderFactory.PROVIDER_NAME;
327
        }
328

    
329
}