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

History | View | Annotate | Download (10.6 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
        private I18nManager i18nManager = ToolsLocator.getI18nManager();
54

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

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

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

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

    
77
        private boolean deleteOriginalGeometries = false;
78

    
79
        private Map<EditingServiceParameter, Object> values;
80

    
81
        private FeatureStore featureStore;
82

    
83
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
84

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

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

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

    
116
                                        geometries.addGeometry(line);
117

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

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

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

    
143
                return null;
144

    
145
        }
146

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

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

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

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

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

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

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

    
195
        public void stop() {
196

    
197
        }
198

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

    
231
        }
232

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

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

    
246
        public void finishAndStore() throws FinishServiceException {
247

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

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

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

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

    
301
        public Geometry finish() throws FinishServiceException{
302
          return null;
303
        }
304

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

    
322
        public String getName() {
323
                return SymmetryEditingProviderFactory.PROVIDER_NAME;
324
        }
325

    
326
}