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

History | View | Annotate | Download (35.3 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.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
import org.gvsig.fmap.dal.exception.DataException;
32
import org.gvsig.fmap.dal.feature.EditableFeature;
33
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.dal.feature.FeatureSelection;
35
import org.gvsig.fmap.dal.feature.FeatureStore;
36
import org.gvsig.fmap.geom.Geometry;
37
import org.gvsig.fmap.geom.GeometryLocator;
38
import org.gvsig.fmap.geom.GeometryManager;
39
import org.gvsig.fmap.geom.GeometryUtils;
40
import org.gvsig.fmap.geom.aggregate.Aggregate;
41
import org.gvsig.fmap.geom.aggregate.MultiCurve;
42
import org.gvsig.fmap.geom.aggregate.MultiPoint;
43
import org.gvsig.fmap.geom.aggregate.MultiSurface;
44
import org.gvsig.fmap.geom.operation.GeometryOperationException;
45
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
46
import org.gvsig.fmap.geom.primitive.Arc;
47
import org.gvsig.fmap.geom.primitive.Curve;
48
import org.gvsig.fmap.geom.primitive.Envelope;
49
import org.gvsig.fmap.geom.primitive.Line;
50
import org.gvsig.fmap.geom.primitive.Point;
51
import org.gvsig.fmap.geom.primitive.Surface;
52
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
53
import org.gvsig.symbology.SymbologyLocator;
54
import org.gvsig.symbology.SymbologyManager;
55
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
56
import org.gvsig.tools.ToolsLocator;
57
import org.gvsig.tools.dataTypes.DataTypes;
58
import org.gvsig.tools.dispose.DisposableIterator;
59
import org.gvsig.tools.dynobject.DynObject;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.i18n.I18nManager;
62
import org.gvsig.tools.service.spi.ProviderServices;
63
import org.gvsig.vectorediting.lib.api.DrawingStatus;
64
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
65
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
66
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
67
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
69
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
70
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
71
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
72
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
73
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
74
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
75
import org.gvsig.vectorediting.lib.spi.EditingProvider;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
80

    
81
public class RotateEditingProvider extends AbstractEditingProvider implements
82
        EditingProvider {
83

    
84
    public static final String KEY_PIVOT_CENTER_ENVELOPE = "_Key_pivot_center_envelope";
85

    
86
    public static final String PIVOT_CENTER_ENVELOPE = "_Pivot_center_envelope";
87

    
88
    public static final String KEY_PIVOT_CENTROID = "_Key_pivot_centroid";
89

    
90
    public static final String PIVOT_CENTROID = "_Pivot_centroid";
91

    
92
    public static final String ROTATE_MODE = "_Rotate_mode";
93

    
94
    public static final String ROTATE_ACTIVE_ANGLE_MODE = "_Rotate_active_angle_mode";
95

    
96
    public static final String ROTATE_TWO_POINTS_MODE = "_Rotate_two_points_mode";
97

    
98
    public static final String ROTATE_THREE_POINTS_MODE = "_Rotate_three_points_mode";
99

    
100
    public static final String KEY_ROTATE_ACTIVE_ANGLE_MODE = "_Key_rotate_active_angle_mode";
101

    
102
    public static final String KEY_ROTATE_TWO_POINTS_MODE = "_Key_rotate_two_points_mode";
103

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

    
110
    private static final String INDIVIDUALLY = "_Individually";
111
    private static final String TOGETHER = "_Together";
112

    
113
    private static final String SHORT_YES = "_short_yes";
114
    private static final String SHORT_NO = "_short_no";
115

    
116

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

    
121
    private final EditingServiceParameter selectionParameter;
122

    
123
    private final EditingServiceParameter pivotPointParameter;
124

    
125
    private String center;
126

    
127
    private final EditingServiceParameter modeParameter;
128
    
129
    private final EditingServiceParameter separateElementsParameter;
130

    
131
    private final EditingServiceParameter angleParameter;
132

    
133
    private final EditingServiceParameter firstPointParameter;
134

    
135
    private final EditingServiceParameter secondPointParameter;
136

    
137
    private Map<EditingServiceParameter, Object> values;
138

    
139
    private final FeatureStore featureStore;
140

    
141
    public RotateEditingProvider(ProviderServices providerServices,
142
            DynObject parameters) {
143
        super(providerServices);
144
        this.featureStore
145
                = (FeatureStore) parameters
146
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
147

    
148
        I18nManager i18nManager = ToolsLocator.getI18nManager();
149

    
150
        this.selectionParameter
151
                = new DefaultEditingServiceParameter("selection",
152
                        i18nManager.getTranslation("selection"), TYPE.SELECTION);
153

    
154
        DefaultEditingServiceParameterOptions options = new DefaultEditingServiceParameterOptions()
155
                .add(i18nManager.getTranslation(PIVOT_CENTER_ENVELOPE), PIVOT_CENTER_ENVELOPE, i18nManager.getTranslation(KEY_PIVOT_CENTER_ENVELOPE))
156
                .add(i18nManager.getTranslation(PIVOT_CENTROID), PIVOT_CENTROID, i18nManager.getTranslation(KEY_PIVOT_CENTROID))
157
                ;
158

    
159
        String consoleMsg
160
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
161
                        "_Pivot_point", options);
162

    
163
        this.pivotPointParameter
164
                = new DefaultEditingServiceParameter(
165
                        "_Pivot_point",
166
                        consoleMsg,
167
                        options,
168
                        null,
169
                        TYPE.POSITION, TYPE.OPTION
170
                );
171
        
172
        DefaultEditingServiceParameterOptions modeOptions = new DefaultEditingServiceParameterOptions()
173
                .add(i18nManager.getTranslation(ROTATE_ACTIVE_ANGLE_MODE), ROTATE_ACTIVE_ANGLE_MODE, i18nManager.getTranslation(KEY_ROTATE_ACTIVE_ANGLE_MODE))
174
                .add(i18nManager.getTranslation(ROTATE_TWO_POINTS_MODE), ROTATE_TWO_POINTS_MODE, i18nManager.getTranslation(KEY_ROTATE_TWO_POINTS_MODE))
175
                .add(i18nManager.getTranslation(ROTATE_THREE_POINTS_MODE), ROTATE_THREE_POINTS_MODE, i18nManager.getTranslation(KEY_ROTATE_THREE_POINTS_MODE));
176

    
177
        String modeConsoleMsg
178
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
179
                        ROTATE_MODE, options);
180

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

    
195
        String separateElementsConsoleMsg
196
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
197
                        SEPARATE_ELEMENTS_QUESTION, separateElementsOptions);
198

    
199
        
200
        this.separateElementsParameter
201
                = new DefaultEditingServiceParameter(
202
                        ELEMENT_ROTATION,
203
                        separateElementsConsoleMsg, 
204
                        separateElementsOptions, 
205
                        i18nManager.getTranslation(SHORT_NO), 
206
                        true, 
207
                        TYPE.OPTION).setDataType(DataTypes.BOOLEAN);
208

    
209

    
210
        this.angleParameter
211
                = new DefaultEditingServiceParameter(
212
                        "_Angle",
213
                        i18nManager.getTranslation("_Angle"),
214
                        TYPE.VALUE
215
                );
216

    
217
        this.firstPointParameter
218
                = new DefaultEditingServiceParameter(
219
                        "Start_of_rotation",
220
                        i18nManager.getTranslation("_Start_of_rotation"),
221
                        TYPE.POSITION);
222

    
223
        this.secondPointParameter
224
                = new DefaultEditingServiceParameter(
225
                        "_End_of_rotation",
226
                        i18nManager.getTranslation("_End_of_rotation"),
227
                        TYPE.POSITION
228
                );
229

    
230
        this.values = new HashMap<>();
231

    
232
    }
233

    
234
    private ISimpleTextSymbol getTextSymbol() {
235
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
236
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
237
        textSymbol.setFontSize(10);
238
        return textSymbol;
239
    }
240

    
241
    @Override
242
    public DrawingStatus getDrawingStatus(Point mousePosition)
243
            throws DrawServiceException {
244
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
245
        EditingProviderManager editingProviderManager
246
                = EditingProviderLocator.getProviderManager();
247
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
248
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
249
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
250
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
251
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
252

    
253
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
254

    
255
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
256

    
257
        FeatureSelection selected
258
                = (FeatureSelection) values.get(selectionParameter);
259
        try {
260
            int subType
261
                    = editingProviderServices.getSubType(featureStore);
262
            if ((selected != null) && !selected.isEmpty()) {
263
                Point p1 = (Point) values.get(pivotPointParameter);
264
                Point p2 = null;
265
                Point p3 = null;
266
                Double angle = null;
267
                if (p1 != null) {
268
                    drawingStatus.addStatus(p1, auxiliaryPointSymbolEditing, "");
269

    
270
                    switch ((String) values.get(modeParameter)) {
271
                        case ROTATE_ACTIVE_ANGLE_MODE:
272
                            return drawingStatus;
273
                        case ROTATE_TWO_POINTS_MODE:
274
                            p3 = (Point) values.get(secondPointParameter);
275
                            if (p3 == null) {
276
                                angle = GeometryUtils.calculateAngle(
277
                                        (Point) values.get(pivotPointParameter),
278
                                        mousePosition);
279

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

    
323
                                    double startAngle = GeometryUtils.calculateAngle(
324
                                            (Point) values.get(pivotPointParameter),
325
                                            p2);
326

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

    
355
                    if (angle != null) {
356
                        DisposableIterator it;
357
                        it = selected.fastIterator();
358

    
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
                        while (it.hasNext()) {
368
                            Feature feat = (Feature) it.next();
369

    
370
                            ISymbol previewSymbol = this.getPreviewSymbol(feat);
371

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

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

    
413
                        }
414
                        it.dispose();
415
                    }
416
                }
417
                return drawingStatus;
418
            }
419
        } catch (Exception e) {
420
            throw new DrawServiceException(e);
421
        }
422

    
423
        return null;
424

    
425
    }
426

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

    
446
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
447
            throws GeometryOperationNotSupportedException,
448
            GeometryOperationException {
449

    
450
        AffineTransform translate
451
                = AffineTransform
452
                        .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
453

    
454
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
455

    
456
        AffineTransform inverseTranslate
457
                = AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
458
        AffineTransform at = new AffineTransform(translate);
459

    
460
        at.preConcatenate(rotate);
461
        at.preConcatenate(inverseTranslate);
462
        return at;
463
    }
464

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

    
490
    public void stop() {
491
        values.clear();
492
    }
493

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

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

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

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

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

    
586
    @Override
587
    public void finishAndStore() throws FinishServiceException {
588

    
589
        FeatureSelection selected
590
                = (FeatureSelection) values.get(selectionParameter);
591
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
592

    
593
        try {
594
            int subType = editingProviderServices.getSubType(featureStore);
595
            if (!selected.isEmpty()) {
596
                Point p0 = (Point) values.get(pivotPointParameter);
597
                Point p1 = null;
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
                        selected.accept((Object obj) -> {
632
                            AffineTransform individualAt = at;
633
                            Feature feature = (Feature) obj;
634
                            Geometry geom
635
                                    = feature.getDefaultGeometry()
636
                                            .cloneGeometry();
637
                            if(separateElements){
638
                                Point pivot = null;
639
                                //Si es cualquier punto y separamos elementos tambi?n pivotamos sobre el centro de la envoltura
640
                                if (center == null || PIVOT_CENTER_ENVELOPE.equalsIgnoreCase(center)) {
641
                                    Envelope featEnv = feature.getDefaultEnvelope();
642
                                    if (!featEnv.isEmpty()) {
643
                                        pivot = geometryManager.createPoint(featEnv.getCenter(0), featEnv.getCenter(1), subType);
644
                                    }
645
                                } else if (PIVOT_CENTROID.equalsIgnoreCase(center)) {
646
                                    pivot = feature.getDefaultGeometry().centroid();
647
                                }
648
                                if(pivot != null){
649
                                    try {
650
                                        individualAt = getRotateAffineTransform(pivot, finalAngle);
651
                                    } catch (Exception e) {
652
                                        throw new DrawServiceException(e);
653
                                    }
654
                                }
655
                            }
656

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

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

    
684
    @Override
685
    public void start() throws StartServiceException {
686
        this.values = new HashMap<>();
687
        FeatureSelection selected = null;
688
        if (featureStore != null) {
689
            try {
690
                selected
691
                        = (FeatureSelection) featureStore.getFeatureSelection()
692
                                .clone();
693
            } catch (DataException e) {
694
                throw new StartServiceException(e);
695
            } catch (CloneNotSupportedException e) {
696
                // Do nothing
697
            }
698
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
699
                values.put(selectionParameter, selected);
700
            }
701
        }
702
        if (savedRotateMode != null) {
703
            this.values.put(modeParameter, savedRotateMode);
704
        }
705
    }
706

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

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

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

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

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

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

    
779
        return pivot;
780
    }
781

    
782
}