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.rotate / src / main / java / org / gvsig / vectorediting / lib / prov / rotate / RotateEditingProvider.java @ 3838

History | View | Annotate | Download (35.6 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
package org.gvsig.vectorediting.lib.prov.rotate;
25

    
26
import java.awt.geom.AffineTransform;
27
import java.util.ArrayList;
28
import java.util.Collections;
29
import java.util.HashMap;
30
import java.util.List;
31
import java.util.Map;
32
import org.apache.commons.collections4.CollectionUtils;
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.GeometryManager;
41
import org.gvsig.fmap.geom.GeometryUtils;
42
import org.gvsig.fmap.geom.aggregate.Aggregate;
43
import org.gvsig.fmap.geom.aggregate.MultiCurve;
44
import org.gvsig.fmap.geom.aggregate.MultiPoint;
45
import org.gvsig.fmap.geom.aggregate.MultiSurface;
46
import org.gvsig.fmap.geom.operation.GeometryOperationException;
47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Arc;
49
import org.gvsig.fmap.geom.primitive.Curve;
50
import org.gvsig.fmap.geom.primitive.Envelope;
51
import org.gvsig.fmap.geom.primitive.Line;
52
import org.gvsig.fmap.geom.primitive.Point;
53
import org.gvsig.fmap.geom.primitive.Surface;
54
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
55
import org.gvsig.symbology.SymbologyLocator;
56
import org.gvsig.symbology.SymbologyManager;
57
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
58
import org.gvsig.tools.ToolsLocator;
59
import org.gvsig.tools.dataTypes.DataTypes;
60
import org.gvsig.tools.dynobject.DynObject;
61
import org.gvsig.tools.exception.BaseException;
62
import org.gvsig.tools.i18n.I18nManager;
63
import org.gvsig.tools.service.spi.ProviderServices;
64
import org.gvsig.vectorediting.lib.api.DrawingStatus;
65
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
66
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
67
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
69
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
70
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
71
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
72
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
73
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
74
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
75
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
76
import org.gvsig.vectorediting.lib.spi.EditingProvider;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
80
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
81

    
82
@SuppressWarnings("UseSpecificCatch")
83
public class RotateEditingProvider extends AbstractEditingProvider implements
84
        EditingProvider {
85

    
86
    public static final String KEY_PIVOT_CENTER_ENVELOPE = "_Key_pivot_center_envelope";
87

    
88
    public static final String PIVOT_CENTER_ENVELOPE = "_Pivot_center_envelope";
89

    
90
    public static final String KEY_PIVOT_CENTROID = "_Key_pivot_centroid";
91

    
92
    public static final String PIVOT_CENTROID = "_Pivot_centroid";
93

    
94
    public static final String ROTATE_MODE = "_Rotate_mode";
95

    
96
    public static final String ROTATE_ACTIVE_ANGLE_MODE = "_Rotate_active_angle_mode";
97

    
98
    public static final String ROTATE_TWO_POINTS_MODE = "_Rotate_two_points_mode";
99

    
100
    public static final String ROTATE_THREE_POINTS_MODE = "_Rotate_three_points_mode";
101

    
102
    public static final String KEY_ROTATE_ACTIVE_ANGLE_MODE = "_Key_rotate_active_angle_mode";
103

    
104
    public static final String KEY_ROTATE_TWO_POINTS_MODE = "_Key_rotate_two_points_mode";
105

    
106
    public static final String KEY_ROTATE_THREE_POINTS_MODE = "_Key_rotate_three_points_mode";
107
    
108
    private static final String SEPARATE_ELEMENTS_QUESTION = "_Separate_elements_question";
109
    
110
    private static final String ELEMENT_ROTATION = "_Element_rotation";
111

    
112
    private static final String INDIVIDUALLY = "_Individually";
113
    private static final String TOGETHER = "_Together";
114

    
115
    private static final String SHORT_YES = "_short_yes";
116
    private static final String SHORT_NO = "_short_no";
117

    
118

    
119
    //Variable est?tica para guardarnos el rotate_mode
120
//    private static String savedRotateMode;
121
    private static Boolean savedSeparateElements;
122

    
123
    private final EditingServiceParameter selectionParameter;
124

    
125
    private final EditingServiceParameter pivotPointParameter;
126

    
127
    private String center;
128

    
129
    private final EditingServiceParameter modeParameter;
130
    
131
    private final EditingServiceParameter separateElementsParameter;
132

    
133
    private final EditingServiceParameter angleParameter;
134

    
135
    private final EditingServiceParameter firstPointParameter;
136

    
137
    private final EditingServiceParameter secondPointParameter;
138

    
139
    private Map<EditingServiceParameter, Object> values;
140

    
141
    private final FeatureStore featureStore;
142

    
143
    private List<Feature> selectedFeatures;
144

    
145
    public RotateEditingProvider(ProviderServices providerServices,
146
            DynObject parameters) {
147
        super(providerServices);
148
        this.featureStore
149
                = (FeatureStore) parameters
150
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
151

    
152
        I18nManager i18nManager = ToolsLocator.getI18nManager();
153

    
154
        this.selectionParameter
155
                = new DefaultEditingServiceParameter("selection",
156
                        i18nManager.getTranslation("selection"), TYPE.SELECTION).setAllowNull(false);
157

    
158
        DefaultEditingServiceParameterOptions options = new DefaultEditingServiceParameterOptions()
159
                .add(i18nManager.getTranslation(PIVOT_CENTER_ENVELOPE), PIVOT_CENTER_ENVELOPE, i18nManager.getTranslation(KEY_PIVOT_CENTER_ENVELOPE))
160
                .add(i18nManager.getTranslation(PIVOT_CENTROID), PIVOT_CENTROID, i18nManager.getTranslation(KEY_PIVOT_CENTROID))
161
                ;
162

    
163
        String consoleMsg
164
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
165
                        "_Pivot_XcolonX_Point", options);
166

    
167
        this.pivotPointParameter
168
                = new DefaultEditingServiceParameter(
169
                        "_Pivot_point",
170
                        consoleMsg,
171
                        options,
172
                        PIVOT_CENTER_ENVELOPE,
173
                        TYPE.POSITION, TYPE.OPTION
174
                );
175
        
176
        DefaultEditingServiceParameterOptions modeOptions = new DefaultEditingServiceParameterOptions()
177
                .add(i18nManager.getTranslation(ROTATE_ACTIVE_ANGLE_MODE), ROTATE_ACTIVE_ANGLE_MODE, i18nManager.getTranslation(KEY_ROTATE_ACTIVE_ANGLE_MODE))
178
                .add(i18nManager.getTranslation(ROTATE_TWO_POINTS_MODE), ROTATE_TWO_POINTS_MODE, i18nManager.getTranslation(KEY_ROTATE_TWO_POINTS_MODE))
179
                .add(i18nManager.getTranslation(ROTATE_THREE_POINTS_MODE), ROTATE_THREE_POINTS_MODE, i18nManager.getTranslation(KEY_ROTATE_THREE_POINTS_MODE));
180

    
181
        String modeConsoleMsg
182
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
183
                        ROTATE_MODE, modeOptions);
184

    
185
        this.modeParameter
186
                = new DefaultEditingServiceParameter(
187
                        ROTATE_MODE,
188
                        modeConsoleMsg,
189
                        modeOptions,
190
                        ROTATE_TWO_POINTS_MODE,
191
                        false, //true, //Optional
192
                        TYPE.OPTION
193
                );
194
        
195
        DefaultEditingServiceParameterOptions separateElementsOptions=  new DefaultEditingServiceParameterOptions()
196
                .add(INDIVIDUALLY, true, i18nManager.getTranslation(SHORT_YES))
197
                .add(TOGETHER, false, i18nManager.getTranslation(SHORT_NO));
198

    
199
        String separateElementsConsoleMsg
200
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
201
                        SEPARATE_ELEMENTS_QUESTION, separateElementsOptions);
202

    
203
        
204
        this.separateElementsParameter
205
                = new DefaultEditingServiceParameter(
206
                        ELEMENT_ROTATION,
207
                        separateElementsConsoleMsg, 
208
                        separateElementsOptions, 
209
                        i18nManager.getTranslation(SHORT_NO), 
210
                        true, 
211
                        TYPE.OPTION).setDataType(DataTypes.BOOLEAN);
212

    
213
        this.angleParameter
214
                = new DefaultEditingServiceParameter(
215
                        "_Angle",
216
                        i18nManager.getTranslation("_Angle"),
217
                        TYPE.VALUE
218
                ).setDataType(DataTypes.DOUBLE).setAllowNull(false);
219

    
220
        this.firstPointParameter
221
                = new DefaultEditingServiceParameter(
222
                        "Start_of_rotation",
223
                        i18nManager.getTranslation("_Start_of_rotation"),
224
                        TYPE.POSITION).setAllowNull(false);
225

    
226
        this.secondPointParameter
227
                = new DefaultEditingServiceParameter(
228
                        "_End_of_rotation",
229
                        i18nManager.getTranslation("_End_of_rotation"),
230
                        TYPE.POSITION
231
                ).setAllowNull(false);
232

    
233
        this.values = new HashMap<>();
234

    
235
    }
236

    
237
    private ISimpleTextSymbol getTextSymbol() {
238
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
239
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
240
        textSymbol.setFontSize(10);
241
        return textSymbol;
242
    }
243

    
244
    @Override
245
    public DrawingStatus getDrawingStatus(Point mousePosition)
246
            throws DrawServiceException {
247
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
248
        if(values.get(modeParameter) == null){
249
            return null;
250
        }
251
        EditingProviderManager editingProviderManager
252
                = EditingProviderLocator.getProviderManager();
253
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
254
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
255
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
256
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
257
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
258

    
259
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
260

    
261
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
262

    
263
        try {
264
            int subType
265
                    = editingProviderServices.getSubType(featureStore);
266
            if ( !CollectionUtils.isEmpty(selectedFeatures) ) {
267
                Point p1 = (Point) values.get(pivotPointParameter);
268
                Point p2;
269
                Point p3;
270
                Double angle = null;
271
                if (p1 != null) {
272
                    drawingStatus.addStatus(p1, auxiliaryPointSymbolEditing, "");
273
                    switch ((String) values.get(modeParameter)) {
274
                        case ROTATE_ACTIVE_ANGLE_MODE:
275
                            return drawingStatus;
276
                        case ROTATE_TWO_POINTS_MODE:
277
                            p3 = (Point) values.get(secondPointParameter);
278
                            if (p3 == null) {
279
                                angle = GeometryUtils.calculateAngle(
280
                                        (Point) values.get(pivotPointParameter),
281
                                        mousePosition);
282

    
283
                                Line line;
284
                                line = geometryManager.createLine(subType);
285
                                line.addVertex(p1);
286
                                p3 = geometryManager.createPoint(
287
                                        p1.getX() + p1.distance(mousePosition),
288
                                        p1.getY(), subType);
289
                                line.addVertex(p3);
290
                                drawingStatus.addStatus(line, ruleAxisSymbol, "");
291
                                Line line2;
292
                                line2 = geometryManager.createLine(subType);
293
                                line2.addVertex(p1);
294
                                line2.addVertex(mousePosition);
295
                                drawingStatus.addStatus(line2, ruleAxisSymbol, "");
296
                                Double ext = (2 * Math.PI) - angle;
297
                                Arc arc = GeometryUtils.createArc(
298
                                        p1,
299
                                        p1.distance(mousePosition) / 2,
300
                                        0,
301
                                        angle,
302
                                        Geometry.SUBTYPES.GEOM2D);
303
                                drawingStatus.addStatus(arc, auxiliaryLineSymbolEditing, "");
304
                                double textDistance = 3 * p1.distance(mousePosition) / 4;
305
                                Point pointText = geometryManager.createPoint(p1.getX() + textDistance * Math.cos(angle / 2), p1.getY() + textDistance * Math.sin(angle / 2), subType);
306
                                ISimpleTextSymbol textSymbol = getTextSymbol();
307
                                drawingStatus.addStatus(pointText, textSymbol, degToDms(Math.toDegrees(angle)));
308
                            }
309
                            break;
310
                        case ROTATE_THREE_POINTS_MODE:
311
                            p2 = (Point) values.get(firstPointParameter);
312
                            p3 = (Point) values.get(secondPointParameter);
313
                            if (p2 == null) {
314
                                Line line;
315
                                line = geometryManager.createLine(subType);
316
                                line.addVertex(p1);
317
                                line.addVertex(mousePosition);
318
                                drawingStatus.addStatus(line, ruleAxisSymbol, "");
319
                            } else {
320
                                if (p3 == null) {
321
                                    angle = GeometryUtils.calculateAngle(
322
                                            (Point) values.get(pivotPointParameter),
323
                                            p2,
324
                                            mousePosition);
325

    
326
                                    double startAngle = GeometryUtils.calculateAngle(
327
                                            (Point) values.get(pivotPointParameter),
328
                                            p2);
329

    
330
                                    Line line;
331
                                    line = geometryManager.createLine(subType);
332
                                    line.addVertex(p1);
333
                                    line.addVertex(p2);
334
                                    drawingStatus.addStatus(line, ruleAxisSymbol, "");
335
                                    Line line2;
336
                                    line2 = geometryManager.createLine(subType);
337
                                    line2.addVertex(p1);
338
                                    line2.addVertex(mousePosition);
339
                                    drawingStatus.addStatus(line2, ruleAxisSymbol, "");
340
                                    Double ext = (2 * Math.PI) - angle;
341
                                    double minDistance = Math.min(p1.distance(p2), p1.distance(mousePosition));
342
                                    Arc arc = GeometryUtils.createArc(
343
                                            p1,
344
                                            minDistance/2,
345
                                            GeometryUtils.calculateAngle(p1, p2),
346
                                            GeometryUtils.calculateAngle(p1, p2, mousePosition),
347
                                            subType);
348
                                    drawingStatus.addStatus(arc, auxiliaryLineSymbolEditing, "");
349
                                    double textDistance = 3 * minDistance / 4;
350
                                    Point pointText = geometryManager.createPoint(p1.getX() + textDistance * Math.cos(startAngle+(angle / 2)), p1.getY() + textDistance * Math.sin(startAngle+(angle / 2)), subType);
351
                                    ISimpleTextSymbol textSymbol = getTextSymbol();
352
                                    drawingStatus.addStatus(pointText, textSymbol, degToDms(Math.toDegrees(angle)));
353
                                }
354
                            }
355
                            break;
356
                    }
357

    
358
                    if (angle != null) {
359
                        AffineTransform at;
360
                        try {
361
                            at = getRotateAffineTransform(p1, angle);
362
                        } catch (Exception e) {
363
                            throw new DrawServiceException(e);
364
                        }
365

    
366
                        Boolean separateElements = (Boolean) getValue(separateElementsParameter);
367
                        for (Feature feat : selectedFeatures) {
368
                            ISymbol previewSymbol = this.getPreviewSymbol(feat);
369

    
370
                            Geometry transformedGeometry = feat.getDefaultGeometry().cloneGeometry();
371
                            if(separateElements){
372
                                Point pivot = null;
373
                                //Si es cualquier punto y separamos elementos tambi?n pivotamos sobre el centro de la envoltura
374
                                if (center == null || PIVOT_CENTER_ENVELOPE.equalsIgnoreCase(center)) {
375
                                    Envelope featEnv = feat.getDefaultEnvelope();
376
                                    if (!featEnv.isEmpty()) {
377
                                        pivot = geometryManager.createPoint(featEnv.getCenter(0), featEnv.getCenter(1), subType);
378
                                    }
379
                                } else if (PIVOT_CENTROID.equalsIgnoreCase(center)) {
380
                                    pivot = feat.getDefaultGeometry().centroid();
381
                                }
382
                                if(pivot != null){
383
                                    try {
384
                                        at = getRotateAffineTransform(pivot, angle);
385
                                    } catch (Exception e) {
386
                                        throw new DrawServiceException(e);
387
                                    }
388
                                }
389
                            }
390
                            transformedGeometry.transform(at);
391

    
392
                            ISymbol symbol = null;
393
                            if (transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve) {
394
                                symbol = lineSymbolEditing;
395
                            } else if (transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface) {
396
                                symbol = polygonSymbolEditing;
397
                            } else if (transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint) {
398
                                symbol = auxiliaryPointSymbolEditing;
399
                            }
400
                            if (transformedGeometry instanceof Aggregate) {
401
                                int primitivesNumber = ((Aggregate) transformedGeometry).getPrimitivesNumber();
402
                                for (int i = 0; i < primitivesNumber; i++) {
403
                                    drawingStatus.addStatus(((Aggregate) transformedGeometry).getPrimitiveAt(i), symbol, "");
404
                                    drawingStatus.addStatus(((Aggregate) transformedGeometry).getPrimitiveAt(i), previewSymbol, "");
405
                                }
406
                            } else {
407
                                drawingStatus.addStatus(transformedGeometry, symbol, "");
408
                                drawingStatus.addStatus(transformedGeometry, previewSymbol, "");
409
                            }
410

    
411
                        }
412
                    }
413
                }
414
                return drawingStatus;
415
            }
416
        } catch (Exception e) {
417
            throw new DrawServiceException(e);
418
        }
419

    
420
        return null;
421

    
422
    }
423

    
424
    private String degToDms(double deg) {
425
        int d = (int) Math.floor(deg);
426
        double minfloat = (deg - d) * 60;
427
        int m = (int) Math.floor(minfloat);
428
        double secfloat = (minfloat - m) * 60;
429
        int s = (int) Math.round(secfloat);
430
        // After rounding, the seconds might become 60. These two
431
        // if-tests are not necessary if no rounding is done.
432
        if (s == 60) {
433
            m++;
434
            s = 0;
435
        }
436
        if (m == 60) {
437
            d++;
438
            m = 0;
439
        }
440
        return ("" + d + "\u00B0" + m + "\u2032" + s + "\u2033");
441
    }
442

    
443
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
444
            throws GeometryOperationNotSupportedException,
445
            GeometryOperationException {
446

    
447
        AffineTransform translate
448
                = AffineTransform
449
                        .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
450

    
451
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
452

    
453
        AffineTransform inverseTranslate
454
                = AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
455
        AffineTransform at = new AffineTransform(translate);
456

    
457
        at.preConcatenate(rotate);
458
        at.preConcatenate(inverseTranslate);
459
        return at;
460
    }
461

    
462
    @Override
463
    public EditingServiceParameter next() {
464
        if (values.get(selectionParameter) == null) {
465
            return this.selectionParameter;
466
        } else if (values.get(modeParameter) == null) {
467
            return this.modeParameter;
468
        } else if (values.get(pivotPointParameter) == null) {
469
            return this.pivotPointParameter;
470
        } else if (((String) values.get(modeParameter)).equalsIgnoreCase(ROTATE_ACTIVE_ANGLE_MODE)) {
471
            if (values.get(angleParameter) == null) {
472
                return angleParameter;
473
            }
474
        } else if (((String) values.get(modeParameter)).equalsIgnoreCase(ROTATE_TWO_POINTS_MODE)) {
475
            if (values.get(secondPointParameter) == null) {
476
                return secondPointParameter;
477
            }
478
        } else if (((String) values.get(modeParameter)).equalsIgnoreCase(ROTATE_THREE_POINTS_MODE)) {
479
            if (values.get(firstPointParameter) == null) {
480
                return firstPointParameter;
481
            }
482
            if (values.get(secondPointParameter) == null) {
483
                return secondPointParameter;
484
            }
485
        }
486
        return null;
487
    }
488

    
489
    public void stop() {
490
        values.clear();
491
        this.selectedFeatures = Collections.EMPTY_LIST;
492
    }
493

    
494
    private void validateAndInsertValue(EditingServiceParameter param,
495
            Object value) throws InvalidEntryException {
496
        if (param == selectionParameter) {
497
            if (!param.isValidValue(value)) {
498
                throw new InvalidEntryException(null);
499
            }
500
            values.put(param, value);
501
            this.selectedFeatures = this.getSelectedFeaturesCopy((FeatureSelection) value);
502

    
503
        } else if (param == modeParameter) {
504
            if (!param.isValidValue(value)) {
505
                throw new InvalidEntryException(null);
506
            }
507
            String rotateMode = (String) param.getOptions2().getValue(value, param.getDefaultValue());
508
            modeParameter.setDefaultValue(rotateMode);
509
            values.put(param, rotateMode);
510
        } else if (param == separateElementsParameter) {
511
            if (!param.isValidValue(value)) {
512
                throw new InvalidEntryException(null);
513
            }
514
            savedSeparateElements = (Boolean) param.getOptions2().getValue(value, param.getDefaultValue());
515
            values.put(param, savedSeparateElements);
516
        } else if (param == pivotPointParameter) {
517
            if (!param.isValidValue(value)) {
518
                center = null;
519
                throw new InvalidEntryException(null);
520
            }
521
            if (value == null) {
522
                value = param.getDefaultValue();
523
            } 
524
            if (value instanceof Point) {
525
                values.put(param, value);
526
                center = null;
527
            } else { //String
528
                String pivotMode = (String) param.getOptions2().getValue(value, param.getDefaultValue());
529
                center = pivotMode;
530
                FeatureSelection selected
531
                        = (FeatureSelection) values.get(this.selectionParameter);
532
                values.put(param, calculatePivot(selected, pivotMode));
533
            }
534
        } else if (param == firstPointParameter) {
535
            if (!param.isValidValue(value)) {
536
                throw new InvalidEntryException(null);
537
            }
538
            if (((Point) value).equals((Point) values.get(pivotPointParameter))) {
539
                throw new InvalidEntryException(null);
540
            }
541
            values.put(param, value);
542
        } else if (param == secondPointParameter) {
543
            if (!param.isValidValue(value)) {
544
                throw new InvalidEntryException(null);
545
            }
546
            if (((Point) value).equals((Point) values.get(firstPointParameter))
547
                    || ((Point) value).equals((Point) values.get(pivotPointParameter))) {
548
                throw new InvalidEntryException(null);
549
            }
550
            values.put(param, value);
551
        } else if (param == angleParameter) {
552
            if (!param.isValidValue(value)) {
553
                throw new InvalidEntryException(null);
554
            }
555
            Object v = angleParameter.coerceValue(value);
556
            if ((Double)v == 0.0){
557
                throw new InvalidEntryException(null);
558
            }
559
            values.put(param, v);
560
        }
561
    }
562

    
563
    @Override
564
    public List<EditingServiceParameter> getParameters() {
565
        List<EditingServiceParameter> list
566
                = new ArrayList<>();
567
        list.add(selectionParameter);
568
        list.add(modeParameter);
569
        list.add(pivotPointParameter);
570
        list.add(separateElementsParameter);
571
        list.add(angleParameter);
572
        list.add(firstPointParameter);
573
        list.add(secondPointParameter);
574
        return list;
575
    }
576

    
577
    @Override
578
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
579
        validateAndInsertValue(parameter, value);
580
    }
581

    
582
    @Override
583
    public void setValue(Object value) throws InvalidEntryException {
584
        EditingServiceParameter param = next();
585
        validateAndInsertValue(param, value);
586
    }
587

    
588
    @Override
589
    public void finishAndStore() throws FinishServiceException {
590

    
591
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
592

    
593
        try {
594
            int subType = editingProviderServices.getSubType(featureStore);
595
            if (CollectionUtils.isNotEmpty(selectedFeatures)) {
596
                Point p0 = (Point) values.get(pivotPointParameter);
597
                Point p1;
598
                Object p2;
599
                Double angle = null;
600
                if(values.get(angleParameter) != null){
601
                    angle = Math.toRadians((Double) values.get(angleParameter));
602
                }
603
                switch ((String) values.get(modeParameter)) {
604
                    case ROTATE_ACTIVE_ANGLE_MODE:
605
                        break;
606
                    case ROTATE_TWO_POINTS_MODE:
607
                        p2 = values.get(secondPointParameter);
608
                        angle = GeometryUtils.calculateAngle(p0, (Point)p2);
609
                        break;
610
                    case ROTATE_THREE_POINTS_MODE:
611
                        p1 = (Point) values.get(firstPointParameter);
612
                        p2 = values.get(secondPointParameter);
613
                        angle = GeometryUtils.calculateAngle(p0, p1, (Point)p2);
614
                        break;
615
                }
616
                
617
                if(angle != null){
618
                    final Double finalAngle = angle;
619

    
620
                    final AffineTransform at;
621
                    try {
622
                        at = getRotateAffineTransform(p0, finalAngle);
623
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException e) {
624
                        throw new FinishServiceException(e);
625
                    }
626

    
627
                    Boolean separateElements = (Boolean) getValue(separateElementsParameter);
628
                    GeometryManager geometryManager = GeometryLocator.getGeometryManager();
629

    
630
                    try {
631
                        for (Feature feature : selectedFeatures) {
632
                            AffineTransform individualAt = at;
633
                            Geometry geom
634
                                    = feature.getDefaultGeometry()
635
                                            .cloneGeometry();
636
                            if(separateElements){
637
                                Point pivot = null;
638
                                //Si es cualquier punto y separamos elementos tambi?n pivotamos sobre el centro de la envoltura
639
                                if (center == null || PIVOT_CENTER_ENVELOPE.equalsIgnoreCase(center)) {
640
                                    Envelope featEnv = feature.getDefaultEnvelope();
641
                                    if (!featEnv.isEmpty()) {
642
                                        pivot = geometryManager.createPoint(featEnv.getCenter(0), featEnv.getCenter(1), subType);
643
                                    }
644
                                } else if (PIVOT_CENTROID.equalsIgnoreCase(center)) {
645
                                    pivot = feature.getDefaultGeometry().centroid();
646
                                }
647
                                if(pivot != null){
648
                                    try {
649
                                        individualAt = getRotateAffineTransform(pivot, finalAngle);
650
                                    } catch (Exception e) {
651
                                        throw new DrawServiceException(e);
652
                                    }
653
                                }
654
                            }
655

    
656
                            
657
                            geom.transform(individualAt);
658
                            // Se sustituye la geometr?a original por la
659
                            // calculada
660
                            EditableFeature editableFeature
661
                                    = feature.getEditable();
662
                            editableFeature.setDefaultGeometry(geom);
663
                            ((EditingProviderServices) getProviderServices())
664
                                    .updateFeatureInFeatureStore(
665
                                            editableFeature, featureStore);
666
                        }
667
                    } catch (BaseException e) {
668
                        throw new FinishServiceException(e);
669
                    }
670
                    featureStore.getFeatureSelection().deselectAll();
671
                }
672
            }
673
        } catch (DataException e) {
674
            throw new FinishServiceException(e);
675
        }
676
    }
677

    
678
    @Override
679
    public Geometry finish() throws FinishServiceException {
680
        return null;
681
    }
682

    
683
    @Override
684
    public void start() throws StartServiceException {
685
        this.values = new HashMap<>();        
686
        this.selectedFeatures = Collections.EMPTY_LIST;
687
        if (featureStore != null) {
688
            FeatureSelection selected = null;
689
            try {
690
                selected = (FeatureSelection) featureStore.getFeatureSelection().clone();
691
            } catch (DataException e) {
692
                throw new StartServiceException(e);
693
            } catch (CloneNotSupportedException ex) {
694
                LOGGER.debug("Can't init selection",ex);
695
            }
696
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
697
                values.put(selectionParameter, selected);
698
                this.selectedFeatures = this.getSelectedFeaturesCopy(selected);
699
            }
700
        }
701
//        if (savedRotateMode != null) {
702
//            this.values.put(modeParameter, savedRotateMode);
703
//        }
704
    }
705

    
706
    @Override
707
    public void restart() throws StartServiceException, InvalidEntryException, StopServiceException {
708
        values.put(selectionParameter, null);
709
        this.selectedFeatures = Collections.EMPTY_LIST;
710
        values.put(pivotPointParameter, null);
711
        center = null;
712
        values.put(angleParameter, null);
713
        values.put(firstPointParameter, null);
714
        values.put(secondPointParameter, null);
715
        values.put(modeParameter, null);
716
    }
717

    
718
    @Override
719
    public String getName() {
720
        return RotateEditingProviderFactory.PROVIDER_NAME;
721
    }
722

    
723
    @Override
724
    public Object getValue(EditingServiceParameter parameter) {
725
        return values != null ? values.get(parameter) : null;
726
    }
727

    
728
    @Override
729
    public Object getValue(EditingServiceParameter parameter, EditingServiceParameter.TYPE type) {
730
        if(values == null){
731
            return null;
732
        }
733
        if(parameter == pivotPointParameter){
734
            if (type == TYPE.OPTION) {
735
                return center;
736
            }
737
        }
738
        return values != null ? values.get(parameter) : null;
739
    }
740

    
741
    @Override
742
    public boolean isEnabled(EditingServiceParameter parameter) {
743
        return true;
744
    }
745

    
746
    private Point calculatePivot(FeatureSelection selection, String mode) throws InvalidEntryException {
747
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
748
        Point pivot = null;
749
        FeatureSelection selected
750
                = (FeatureSelection) values.get(this.selectionParameter);
751
        try {
752
            int subType = this.getProviderServices().getSubType(featureStore);
753
            if ((selected != null) && !selected.isEmpty()) {
754
                if (PIVOT_CENTER_ENVELOPE.equalsIgnoreCase(mode)) {
755
                    Envelope envelope = geomManager.createEnvelope(subType);
756
                    for (Feature feature : selected) {
757
                        Envelope featEnv = feature.getDefaultEnvelope();
758
                        envelope.add(featEnv);
759
                    }
760
                    if (!envelope.isEmpty()) {
761
                        pivot = geomManager.createPoint(envelope.getCenter(0), envelope.getCenter(1), subType);
762
                    }
763
                } else if (PIVOT_CENTROID.equalsIgnoreCase(mode)) {
764
                    Geometry geometry = null;
765
                    for (Feature feature : selected) {
766
                        if (geometry == null) {
767
                            geometry = feature.getDefaultGeometry().clone();
768
                        } else {
769
                            geometry = geometry.union(feature.getDefaultGeometry().clone());
770
                        }
771
                    }
772
                    if (geometry != null) {
773
                        pivot = geometry.centroid();
774
                    }
775
                }
776
            }
777
        } catch (Exception ex) {
778
            throw new InvalidEntryException(ex);
779
        }
780

    
781
        return pivot;
782
    }
783

    
784
}