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.arc / src / main / java / org / gvsig / vectorediting / lib / prov / arc / ArcThreePointsEditingProvider.java @ 2141

History | View | Annotate | Download (87 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.arc;
25

    
26
import java.awt.geom.Point2D;
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
import org.apache.commons.lang.StringUtils;
32
import org.gvsig.euclidean.EuclideanLine2D;
33
import org.gvsig.euclidean.EuclideanManager;
34

    
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.GeometryUtils;
39
import org.gvsig.fmap.geom.aggregate.MultiCurve;
40
import org.gvsig.fmap.geom.exception.CreateGeometryException;
41
import org.gvsig.fmap.geom.operation.GeometryOperationException;
42
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
43
import org.gvsig.fmap.geom.primitive.Arc;
44
import org.gvsig.fmap.geom.primitive.Curve;
45
import org.gvsig.fmap.geom.primitive.Line;
46
import org.gvsig.fmap.geom.primitive.Point;
47
import org.gvsig.fmap.geom.type.GeometryType;
48
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
49
import org.gvsig.symbology.SymbologyLocator;
50
import org.gvsig.symbology.SymbologyManager;
51
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
52
import org.gvsig.tools.dataTypes.impl.coercion.CoerceToDouble;
53
import org.gvsig.tools.dynobject.DynObject;
54
import org.gvsig.tools.exception.BaseException;
55
import org.gvsig.tools.service.spi.ProviderServices;
56
import org.gvsig.tools.util.ToolsUtilLocator;
57
import org.gvsig.vectorediting.lib.api.DrawingStatus;
58
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
59
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
60
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
61
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
63
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
64
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
65
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
66
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
67
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
68
import org.gvsig.vectorediting.lib.spi.EditingProvider;
69
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
70
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
71
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
72
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
73
import org.slf4j.Logger;
74
import org.slf4j.LoggerFactory;
75

    
76
/**
77
 * @author fdiaz
78
 *
79
 */
80
public class ArcThreePointsEditingProvider extends AbstractEditingProvider implements
81
        EditingProvider {
82

    
83
    private static final String CCW = "CCW"; // counterclockwise
84
    private static final String CW = "CW";   // clockwise
85

    
86
    private static final Logger LOGGER = LoggerFactory.getLogger(ArcThreePointsEditingProvider.class);
87

    
88
    //Optionals
89
    private final EditingServiceParameter radius;
90
    private final EditingServiceParameter startAngle;
91
    private final EditingServiceParameter sweepAngle;
92
    private final EditingServiceParameter direction;
93

    
94
    private final EditingServiceParameter startPoint;
95

    
96
    private final EditingServiceParameter middlePoint;
97

    
98
    private final EditingServiceParameter endPoint;
99

    
100
    private Map<EditingServiceParameter, Object> values;
101

    
102
    private final FeatureStore featureStore;
103

    
104
    private Point centerPointValue;
105

    
106
    /**
107
     * Default constructor.
108
     *
109
     * @param providerServices available services for this provider
110
     * @param parameters of this provider
111
     */
112
    public ArcThreePointsEditingProvider(ProviderServices providerServices,
113
            DynObject parameters) {
114
        super(providerServices);
115

    
116
        this.featureStore
117
                = (FeatureStore) parameters
118
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
119

    
120
        this.startPoint
121
                = new DefaultEditingServiceParameter("start_point", "start_point",
122
                        TYPE.POSITION);
123

    
124
        this.middlePoint
125
                = new DefaultEditingServiceParameter("middle_point", "middle_point",
126
                        TYPE.POSITION);
127

    
128
        this.endPoint
129
                = new DefaultEditingServiceParameter("end_point", "end_point",
130
                        TYPE.POSITION);
131

    
132
        this.radius
133
                = new DefaultEditingServiceParameter("radius", "radius", true,
134
                        TYPE.VALUE);
135

    
136
        this.startAngle
137
                = new DefaultEditingServiceParameter("start_angle", "start_angle", true,
138
                        TYPE.VALUE);
139

    
140
        this.sweepAngle
141
                = new DefaultEditingServiceParameter("sweep_angle", "sweep_angle", true,
142
                        TYPE.VALUE);
143

    
144
        Map<String, String> directionOptions = new HashMap<>();
145
        directionOptions.put(CCW, CCW);
146
        directionOptions.put(CW, CW);
147
        // CCW should be the default value, but I don't assign it as such
148
        // to detect whether the user has selected a value or not.
149
        this.direction
150
                = new DefaultEditingServiceParameter("direction", "direction", directionOptions, null, true,
151
                        TYPE.OPTION);
152

    
153
    }
154

    
155
    @Override
156
    public EditingServiceParameter next() {
157
        if (values.get(startPoint) == null) {
158
            return this.startPoint;
159
        } else if (values.get(middlePoint) == null && (centerPointValue == null && values.get(startAngle) == null && values.get(sweepAngle) == null)) {
160
            return this.middlePoint;
161
        } else if (values.get(endPoint) == null) {
162
            return this.endPoint;
163
        }
164
        return null;
165
    }
166

    
167
    @Override
168
    public DrawingStatus getDrawingStatus(Point mousePosition)
169
            throws DrawServiceException {
170

    
171
        Point startPointValue = (Point) values.get(startPoint);
172
        Point middlePointValue = (Point) values.get(middlePoint);
173
        Point endPointValue = (Point) values.get(endPoint);
174

    
175
        Double radiusValue = (Double) values.get(radius);
176
        Double startAngleValue = (Double) values.get(startAngle);
177
        Double sweepAngleValue = (Double) values.get(sweepAngle);
178
        String directionValue = (String) values.get(direction);
179

    
180
        DefaultDrawingStatus geometries = new DefaultDrawingStatus();
181

    
182
        EditingProviderManager editingProviderManager
183
                = EditingProviderLocator.getProviderManager();
184
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
185
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
186
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
187

    
188
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
189
        EditingProviderServices editingProviderServices
190
                = (EditingProviderServices) getProviderServices();
191

    
192
        try {
193

    
194
            int subtype
195
                    = editingProviderServices.getSubType(featureStore);
196

    
197
            Point auxCenterPointValue;
198
            if (values != null) {
199
                if (startPointValue == null) {
200
                    if (radiusValue != null && startAngleValue != null) {
201
                        auxCenterPointValue = GeometryUtils.createPoint(
202
                                mousePosition.getX() - radiusValue * Math.cos(startAngleValue),
203
                                mousePosition.getY() - radiusValue * Math.sin(startAngleValue)
204
                        );
205

    
206
                        geometries.addStatus(auxCenterPointValue, auxiliaryPointSymbolEditing, "");
207

    
208
                        Line auxLine = GeometryUtils.createLine(auxCenterPointValue, mousePosition, subtype);
209
                        geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
210
                        
211
                        Line horizontal = GeometryUtils.createLine(
212
                                auxCenterPointValue.getX(),
213
                                auxCenterPointValue.getY(),
214
                                mousePosition.getX(),
215
                                auxCenterPointValue.getY(),
216
                                subtype);
217
                        geometries.addStatus(horizontal, auxiliaryLineSymbolEditing, "");
218

    
219
                        Line vertical = GeometryUtils.createLine(
220
                                mousePosition.getX(),
221
                                mousePosition.getY(),
222
                                mousePosition.getX(),
223
                                auxCenterPointValue.getY(),
224
                                subtype);
225
                        geometries.addStatus(vertical, auxiliaryLineSymbolEditing, "");
226

    
227

    
228
                        editingProviderServices.addAngleToDrawingStatus(
229
                                geometries,
230
                                getTextSymbol(),
231
                                auxCenterPointValue, 
232
                                GeometryUtils.createPoint(
233
                                    auxCenterPointValue.getX() + radiusValue,
234
                                    auxCenterPointValue.getY()
235
                                ), 
236
                                mousePosition, 
237
                                subtype
238
                        );
239

    
240
                        if (sweepAngleValue != null) {
241
                            addArcAndEndPointToDrawingStatus(geometries, auxCenterPointValue, radiusValue, startAngleValue, mousePosition, sweepAngleValue, directionValue, subtype);
242
                        }
243

    
244
                        return geometries;
245
                    }
246

    
247
                } else { //startPointValue != null
248

    
249
                    geometries.addStatus(startPointValue, auxiliaryPointSymbolEditing, "");
250
                    if(centerPointValue!=null){
251
                        Line auxCenterLine = GeometryUtils.createLine(centerPointValue.getX(), centerPointValue.getY()
252
                                , startPointValue.getX(), startPointValue.getY(), subtype);
253
                        geometries.addStatus(auxCenterLine, auxiliaryLineSymbolEditing, "");
254
                        geometries.addStatus(centerPointValue, auxiliaryPointSymbolEditing, "");
255

    
256
                        Double auxRadiusValue = radiusValue;
257
                        if (auxRadiusValue == null) {
258
                            auxRadiusValue = centerPointValue.distance(startPointValue);
259
                        }
260
                        Line horizontal = GeometryUtils.createLine(
261
                                centerPointValue.getX(),
262
                                centerPointValue.getY(),
263
                                centerPointValue.getX() + auxRadiusValue,
264
                                centerPointValue.getY(),
265
                                subtype);
266
                        geometries.addStatus(horizontal, auxiliaryLineSymbolEditing, "");
267

    
268
                        Line vertical = GeometryUtils.createLine(
269
                                startPointValue.getX(),
270
                                startPointValue.getY(),
271
                                centerPointValue.getX() + auxRadiusValue,
272
                                centerPointValue.getY(),
273
                                subtype);
274
                        geometries.addStatus(vertical, auxiliaryLineSymbolEditing, "");
275

    
276

    
277
                        
278
                        editingProviderServices.addAngleToDrawingStatus(
279
                                geometries,
280
                                getTextSymbol(),
281
                                centerPointValue,
282
                                GeometryUtils.createPoint(
283
                                        centerPointValue.getX() + auxRadiusValue,
284
                                        centerPointValue.getY()
285
                                ),
286
                                startPointValue,
287
                                subtype
288
                        );
289

    
290
                    }
291

    
292
                    if (startAngleValue != null && radiusValue == null) {
293

    
294
                        double m = Math.tan(startAngleValue);
295
                        double b = euclideanManager.getYIntercept(m, startPointValue.getX(), startPointValue.getY());
296
                        EuclideanLine2D startLine = euclideanManager.createLine2D(m, b);
297

    
298
                        if(sweepAngleValue == null) {
299
                            Point auxEndPoint = mousePosition.cloneGeometry();
300
                            double endAngle = GeometryUtils.calculateAngle(startPointValue, auxEndPoint);
301
                            double auxSweepAngle = editingProviderServices.angleDistance(startAngleValue, endAngle);
302
                            if (auxSweepAngle > Math.PI / 2 && auxSweepAngle < 3 * Math.PI / 2) {
303

    
304
                                EuclideanLine2D startEndLine = euclideanManager.createLine2D(
305
                                        startPointValue.getX(),
306
                                        startPointValue.getY(),
307
                                        auxEndPoint.getX(),
308
                                        auxEndPoint.getY()
309
                                );
310

    
311
                                Point averagePoint = GeometryUtils.createPoint(
312
                                        (startPointValue.getX() + auxEndPoint.getX()) / 2,
313
                                        (startPointValue.getY() + auxEndPoint.getY()) / 2
314
                                );
315

    
316
                                Point2D auxCenter2D = startLine.getIntersection(startEndLine.getPerpendicular(averagePoint.getX(), averagePoint.getY()));
317
                                Point auxCenter = GeometryUtils.createPoint(auxCenter2D.getX(), auxCenter2D.getY());
318

    
319
                                editingProviderServices.addAngleToDrawingStatus(
320
                                        geometries,
321
                                        getTextSymbol(),
322
                                        auxCenter, 
323
                                        GeometryUtils.createPoint(
324
                                            auxCenter.getX() + auxCenter.distance(startPointValue),
325
                                            auxCenter.getY()
326
                                        ), 
327
                                        startPointValue, 
328
                                        subtype
329
                                );
330

    
331
                                Line horizontal = GeometryUtils.createLine(
332
                                        auxCenter.getX(),
333
                                        auxCenter.getY(),
334
                                        startPointValue.getX(),
335
                                        auxCenter.getY(),
336
                                        subtype);
337
                                geometries.addStatus(horizontal, auxiliaryLineSymbolEditing, "");
338

    
339
                                Line vertical = GeometryUtils.createLine(
340
                                        startPointValue.getX(),
341
                                        startPointValue.getY(),
342
                                        startPointValue.getX(),
343
                                        auxCenter.getY(),
344
                                        subtype);
345
                                geometries.addStatus(vertical, auxiliaryLineSymbolEditing, "");
346

    
347
                                Line auxStartLine = GeometryUtils.createLine(
348
                                        auxCenter.getX(),
349
                                        auxCenter.getY(),
350
                                        startPointValue.getX(),
351
                                        startPointValue.getY(),
352
                                        subtype);
353
                                geometries.addStatus(auxStartLine, auxiliaryLineSymbolEditing, "");
354

    
355
                                Line auxStartEndLine = GeometryUtils.createLine(startPointValue.getX(),
356
                                        startPointValue.getY(),
357
                                        auxEndPoint.getX(),
358
                                        auxEndPoint.getY(),
359
                                        subtype);
360
                                geometries.addStatus(auxStartEndLine, auxiliaryLineSymbolEditing, "");
361

    
362
                                Line auxEndLine = GeometryUtils.createLine(
363
                                        auxCenter.getX(),
364
                                        auxCenter.getY(),
365
                                        auxEndPoint.getX(),
366
                                        auxEndPoint.getY(),
367
                                        subtype);
368
                                geometries.addStatus(auxEndLine, auxiliaryLineSymbolEditing, "");
369

    
370
                                Point2D perp = startEndLine.getNearestPoint(auxCenter2D);
371
                                Line perpLine = GeometryUtils.createLine(perp.getX(),
372
                                        perp.getY(),
373
                                        auxCenter.getX(),
374
                                        auxCenter.getY(),
375
                                        subtype);
376
                                geometries.addStatus(perpLine, auxiliaryLineSymbolEditing, "");
377

    
378
                                geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
379

    
380
                                double auxSweepAngleValue = GeometryUtils.calculateAngle(auxCenter, startPointValue, auxEndPoint);
381

    
382
                                if (Math.abs(auxSweepAngleValue) > 0.0) {
383
                                    
384
                                    addArcAndEndPointToDrawingStatus(geometries,
385
                                            auxCenter,
386
                                            auxCenter.distance(startPointValue),
387
                                            startAngleValue,
388
                                            startPointValue,
389
                                            auxSweepAngleValue,
390
                                            directionValue, 
391
                                            subtype
392
                                    );
393
                                }
394
                                geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
395
                            }
396
                        } else { //sweepAngleValue != null
397
                            double endAngle = startAngleValue+sweepAngleValue;
398
                            double endLineM = Math.tan(startAngleValue+sweepAngleValue);
399
                            double endLineB = euclideanManager.getYIntercept(endLineM, mousePosition.getX(), mousePosition.getY());
400
                            EuclideanLine2D endLine = euclideanManager.createLine2D(endLineM, endLineB);
401
                            
402
                            Point2D auxCenter2D = startLine.getIntersection(endLine);
403
                            Point auxCenter = GeometryUtils.createPoint(auxCenter2D.getX(), auxCenter2D.getY());
404
                            
405
                            if (Math.abs(GeometryUtils.calculateAngle(auxCenter, startPointValue) - startAngleValue) <= 0.001) {
406

    
407
                                Point horizontalPoint = GeometryUtils.createPoint(
408
                                        startPointValue.getX(),
409
                                        auxCenter.getY()
410
                                );
411
                                
412
                                editingProviderServices.addAngleToDrawingStatus(
413
                                        geometries,
414
                                        getTextSymbol(),
415
                                        auxCenter, 
416
                                        horizontalPoint, 
417
                                        startPointValue, 
418
                                        subtype
419
                                );
420

    
421
                                Line horizontal = GeometryUtils.createLine(
422
                                        auxCenter.getX(),
423
                                        auxCenter.getY(),
424
                                        startPointValue.getX(),
425
                                        auxCenter.getY(),
426
                                        subtype);
427
                                geometries.addStatus(horizontal, auxiliaryLineSymbolEditing, "");
428

    
429
                                Line vertical = GeometryUtils.createLine(
430
                                        startPointValue.getX(),
431
                                        startPointValue.getY(),
432
                                        startPointValue.getX(),
433
                                        auxCenter.getY(),
434
                                        subtype);
435
                                geometries.addStatus(vertical, auxiliaryLineSymbolEditing, "");
436
                                
437
                                
438
                                Line auxStartLine = GeometryUtils.createLine(
439
                                        auxCenter.getX(),
440
                                        auxCenter.getY(),
441
                                        startPointValue.getX(),
442
                                        startPointValue.getY(),
443
                                        subtype);
444
                                geometries.addStatus(auxStartLine, auxiliaryLineSymbolEditing, "");
445

    
446
                                double auxRadiusValue = startPointValue.distance(auxCenter);
447

    
448
                                Point auxEndPoint = GeometryUtils.createPoint(auxCenter, auxRadiusValue, endAngle);
449

    
450
                                Line auxEndLine = GeometryUtils.createLine(
451
                                        auxCenter.getX(),
452
                                        auxCenter.getY(),
453
                                        auxEndPoint.getX(),
454
                                        auxEndPoint.getY(),
455
                                        subtype);
456
                                geometries.addStatus(auxEndLine, auxiliaryLineSymbolEditing, "");
457

    
458
                                Double auxSweepAngleValue = directedAngle(sweepAngleValue, directionValue);
459

    
460
                                geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
461

    
462
                                addArcAndEndPointToDrawingStatus(geometries,
463
                                        auxCenter,
464
                                        auxCenter.distance(startPointValue),
465
                                        startAngleValue,
466
                                        startPointValue,
467
                                        sweepAngleValue,
468
                                        directionValue,
469
                                        subtype
470
                                );
471
                            }
472
                        }
473
                        return geometries;
474

    
475
                    } else if (radiusValue != null && startAngleValue == null && sweepAngleValue == null && middlePointValue == null ) {
476
                            double distance = startPointValue.distance(mousePosition);
477

    
478
                            if (startPointValue.distance(mousePosition) >= 2 * radiusValue) {
479
                                Point auxPoint = GeometryUtils.createPoint(
480
                                        startPointValue.getX() + 2 * radiusValue * (mousePosition.getX() - startPointValue.getX()) / distance,
481
                                        startPointValue.getY() + 2 * radiusValue * (mousePosition.getY() - startPointValue.getY()) / distance
482
                                );
483
                                Line auxLine = GeometryUtils.createLine(
484
                                        startPointValue.getX(),
485
                                        startPointValue.getY(),
486
                                        auxPoint.getX(),
487
                                        auxPoint.getY(),
488
                                        subtype);
489

    
490
                                geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
491
                                geometries.addStatus(auxPoint, auxiliaryPointSymbolEditing, "");
492
                            } else {
493
                                Line auxLine = GeometryUtils.createLine(
494
                                        startPointValue.getX(),
495
                                        startPointValue.getY(),
496
                                        mousePosition.getX(),
497
                                        mousePosition.getY(),
498
                                        subtype);
499

    
500
                                geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
501
                                geometries.addStatus(mousePosition, auxiliaryPointSymbolEditing, "");
502
                            }
503
                            return geometries;
504

    
505
                    } else if (radiusValue != null && startAngleValue != null && endPointValue == null) { //centerPointValue != null
506
                        double coefDirection = getCoefDirection(centerPointValue, startPointValue, mousePosition);
507
                        if (sweepAngleValue != null) {
508
                            if (directionValue == null) {
509

    
510
                                Point auxPoint;
511
                                auxPoint = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
512

    
513
                                geometries.addStatus(auxPoint, auxiliaryPointSymbolEditing, "");
514

    
515
                                if (Math.signum(coefDirection) != Math.signum(sweepAngleValue)) {
516
                                    sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
517
                                }
518

    
519
                                Arc auxArc = GeometryUtils.createArc(
520
                                        centerPointValue,
521
                                        radiusValue,
522
                                        startAngleValue,
523
                                        sweepAngleValue,
524
                                        GEOM2D);
525

    
526
                                geometries.addStatus(auxArc, lineSymbolEditing, "");
527
                                return geometries;
528
                            }
529
                        } else {  //sweepAngleValue == null //centerPointValue != null
530
                            double auxSweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, mousePosition);
531
                            addArcAndEndPointToDrawingStatus(
532
                                    geometries, 
533
                                    centerPointValue, 
534
                                    radiusValue, 
535
                                    startAngleValue, 
536
                                    startPointValue, 
537
                                    auxSweepAngleValue, 
538
                                    directionValue, 
539
                                    subtype
540
                            );
541
                            
542
                            return geometries;
543
                        }
544

    
545
                    } else if (radiusValue != null && startPointValue != null && sweepAngleValue != null && endPointValue == null) {
546

    
547
                        // A combination of the sweep angle and the mouse position 
548
                        // will determine the center and the end point 
549
                        Line chord1 = GeometryUtils.createLine(
550
                                startPointValue.getX(),
551
                                startPointValue.getY(),
552
                                mousePosition.getX(),
553
                                mousePosition.getY(),
554
                                subtype
555
                        );
556
                        geometries.addStatus(chord1, auxiliaryLineSymbolEditing, "");
557

    
558
                        Point auxCenter = null;
559
                        double auxSweepAngleValue = sweepAngleValue;
560
                        double lenChord1 = startPointValue.distance(mousePosition);
561
                        if (lenChord1 >= 2 * radiusValue) {
562
                            auxCenter = GeometryUtils.createPoint(
563
                                    startPointValue.getX() + radiusValue * (mousePosition.getX()-startPointValue.getX()) / lenChord1,
564
                                    startPointValue.getY() + radiusValue * (mousePosition.getY()-startPointValue.getY()) / lenChord1
565
                            );
566
                        } else {
567
                            Point medium = GeometryUtils.createPoint(
568
                                    (startPointValue.getX() + mousePosition.getX()) / 2,
569
                                    (startPointValue.getY() + mousePosition.getY()) / 2
570
                            );
571
                            Point dir = GeometryUtils.createPoint(
572
                                    (mousePosition.getX() - startPointValue.getX()) / lenChord1,
573
                                    (mousePosition.getY() - startPointValue.getY()) / lenChord1
574
                            );
575
                            Point perpDir = GeometryUtils.createPoint(
576
                                    -dir.getY(),
577
                                    dir.getX()
578
                            );
579
                            double sagitta = Math.sqrt(Math.pow(radiusValue, 2) - Math.pow(lenChord1 / 2, 2));
580

    
581
                            Point auxCenter1 = GeometryUtils.createPoint(
582
                                    medium.getX() + sagitta * perpDir.getX(),
583
                                    medium.getY() + sagitta * perpDir.getY()
584
                            );
585
                            
586
                            Point auxCenter2 = GeometryUtils.createPoint(
587
                                    medium.getX() - sagitta * perpDir.getX(),
588
                                    medium.getY() - sagitta * perpDir.getY()
589
                            );
590

    
591
                            if(sweepAngleValue>=0){
592
                                auxCenter = auxCenter1;
593
                            } else {
594
                                auxCenter = auxCenter2;
595
                            }
596

    
597
                            Line perpChord1 = GeometryUtils.createLine(
598
                                    medium.getX(),
599
                                    medium.getY(),
600
                                    auxCenter.getX(),
601
                                    auxCenter.getY(),
602
                                    subtype
603
                            );
604
                            geometries.addStatus(perpChord1, auxiliaryLineSymbolEditing, "");
605
                        }
606

    
607
                        Line startLine = GeometryUtils.createLine(
608
                                startPointValue.getX(),
609
                                startPointValue.getY(),
610
                                auxCenter.getX(),
611
                                auxCenter.getY(),
612
                                subtype
613
                        );
614
                        geometries.addStatus(startLine, auxiliaryLineSymbolEditing, "");
615
                        
616
                        auxSweepAngleValue = directedAngle(sweepAngleValue, directionValue);
617

    
618
                        geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
619

    
620
                        Point auxEndPoint = calculateEndPoint(auxCenter, radiusValue, null, startPointValue, sweepAngleValue);
621
                        geometries.addStatus(auxEndPoint, auxiliaryPointSymbolEditing, "");
622

    
623
                        Line chord2 = GeometryUtils.createLine(
624
                                auxCenter.getX(),
625
                                auxCenter.getY(),
626
                                auxEndPoint.getX(),
627
                                auxEndPoint.getY(),
628
                                subtype
629
                        );
630

    
631
                        geometries.addStatus(chord2, auxiliaryLineSymbolEditing, "");
632

    
633
                        Arc auxArc = GeometryUtils.createArc(
634
                                auxCenter, 
635
                                radiusValue, 
636
                                GeometryUtils.calculateAngle(auxCenter, startPointValue), 
637
                                auxSweepAngleValue, 
638
                                subtype);
639

    
640
                        geometries.addStatus(auxArc, lineSymbolEditing, "");
641
                        return geometries;
642

    
643
                    } else if (middlePointValue == null) {
644
                        if(sweepAngleValue != null){
645
                            
646
                            Line endLine2D = GeometryUtils.createLine(startPointValue.getX(), 
647
                                    startPointValue.getY(),
648
                                    mousePosition.getX(), 
649
                                    mousePosition.getY(),
650
                                    subtype);
651
                            geometries.addStatus(endLine2D, auxiliaryLineSymbolEditing, "");
652

    
653
                            EuclideanLine2D endLine = euclideanManager.createLine2D(
654
                                    startPointValue.getX(), 
655
                                    startPointValue.getY(), 
656
                                    mousePosition.getX(), 
657
                                    mousePosition.getY());
658
                            Point averagePoint = GeometryUtils.createPoint(
659
                                    (startPointValue.getX()+mousePosition.getX())/2, 
660
                                    (startPointValue.getY()+mousePosition.getY())/2);
661
                            
662
                            geometries.addStatus(averagePoint, auxiliaryPointSymbolEditing, "");
663
                            
664
                            EuclideanLine2D perp = endLine.getPerpendicular(averagePoint.getX(), averagePoint.getY());
665
                            
666
                            double lenEndLine = startPointValue.distance(mousePosition);
667
                            
668
                            double auxRadiusValue = Math.abs(lenEndLine/(2*Math.sin(sweepAngleValue/2)));
669
                            double sagitta = auxRadiusValue*Math.cos(sweepAngleValue/2);
670
                            
671
                            Point dir = GeometryUtils.createPoint(
672
                                    (mousePosition.getX() - startPointValue.getX() )/lenEndLine,
673
                                    (mousePosition.getY() - startPointValue.getY() )/lenEndLine
674
                            );
675
                            
676
                            Point perpDir = GeometryUtils.createPoint(
677
                                    -dir.getY(),
678
                                    dir.getX()
679
                            );
680
                            Point auxCenter1 = GeometryUtils.createPoint(averagePoint.getX() + sagitta * perpDir.getX(),
681
                                    averagePoint.getY() + sagitta * perpDir.getY()
682
                            );
683
                            
684
                            Point auxCenter2 = GeometryUtils.createPoint(averagePoint.getX() - sagitta * perpDir.getX(),
685
                                    averagePoint.getY() - sagitta * perpDir.getY()
686
                            );
687
                            Point auxCenter = auxCenter1; // = auxCenter2;
688
                            
689
                            if(sweepAngleValue>=0){
690
                                auxCenter = auxCenter1;
691
                            } else {
692
                                auxCenter = auxCenter2;
693
                            }
694

    
695
                            
696
                            // Add info start point
697
                            Point horizontalPoint = GeometryUtils.createPoint(
698
                                    startPointValue.getX(),
699
                                    auxCenter.getY()
700
                            );
701

    
702
                            editingProviderServices.addAngleToDrawingStatus(
703
                                    geometries,
704
                                    getTextSymbol(),
705
                                    auxCenter, 
706
                                    horizontalPoint, 
707
                                    startPointValue, 
708
                                    subtype
709
                            );
710

    
711
                            Line horizontal = GeometryUtils.createLine(
712
                                    auxCenter.getX(),
713
                                    auxCenter.getY(),
714
                                    startPointValue.getX(),
715
                                    auxCenter.getY(),
716
                                    subtype);
717
                            geometries.addStatus(horizontal, auxiliaryLineSymbolEditing, "");
718

    
719
                            Line vertical = GeometryUtils.createLine(
720
                                    startPointValue.getX(),
721
                                    startPointValue.getY(),
722
                                    startPointValue.getX(),
723
                                    auxCenter.getY(),
724
                                    subtype);
725
                            geometries.addStatus(vertical, auxiliaryLineSymbolEditing, "");
726

    
727

    
728
                            Line auxStartLine = GeometryUtils.createLine(
729
                                    auxCenter.getX(),
730
                                    auxCenter.getY(),
731
                                    startPointValue.getX(),
732
                                    startPointValue.getY(),
733
                                    subtype);
734
                            geometries.addStatus(auxStartLine, auxiliaryLineSymbolEditing, "");
735

    
736
                            // End of add info start point
737
                            
738
                            geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
739
                            Arc auxArc = GeometryUtils.createArc(
740
                                    auxCenter,
741
                                    auxRadiusValue,
742
                                    GeometryUtils.calculateAngle(auxCenter, startPointValue),
743
                                    directedAngle(sweepAngleValue, directionValue), //GeometryUtils.calculateAngle(auxCenter, startPointValue, mousePosition),
744
                                    subtype);
745
                            geometries.addStatus(auxArc, auxiliaryLineSymbolEditing, "");
746

    
747
                            // Add info end point
748
                            
749
                            editingProviderServices.addAngleToDrawingStatus(
750
                                    geometries,
751
                                    getTextSymbol(),
752
                                    auxCenter,
753
                                    startPointValue,
754
                                    mousePosition,
755
                                    subtype
756
                            );
757

    
758
                            Line auxEndLine = GeometryUtils.createLine(
759
                                    auxCenter.getX(),
760
                                    auxCenter.getY(),
761
                                    mousePosition.getX(),
762
                                    mousePosition.getY(),
763
                                    subtype
764
                            );
765
                            geometries.addStatus(auxEndLine, auxiliaryLineSymbolEditing, "");
766
                            
767
                            // End of add info end point
768

    
769
                            return geometries;
770
                            
771
                        } else {
772
                            Line middleLine = GeometryUtils.createLine(
773
                                    startPointValue.getX(),
774
                                    startPointValue.getY(),
775
                                    mousePosition.getX(),
776
                                    mousePosition.getY(),
777
                                    subtype
778
                            );
779
                            geometries.addStatus(middleLine, auxiliaryLineSymbolEditing, "");
780
                            return geometries;
781
                        }
782

    
783
                    } else if (endPointValue == null) {
784
                        Line chord1 = GeometryUtils.createLine(
785
                                startPointValue.getX(),
786
                                startPointValue.getY(),
787
                                middlePointValue.getX(),
788
                                middlePointValue.getY(),
789
                                subtype
790
                        );
791
                        geometries.addStatus(chord1, auxiliaryLineSymbolEditing, "");
792
                        Point auxCenter = null;
793
                        if (radiusValue != null) {
794
                            double lenChord1 = startPointValue.distance(middlePointValue);
795
                            if (lenChord1 >= 2 * radiusValue) {
796
                                auxCenter = GeometryUtils.createPoint(
797
                                        (startPointValue.getX() + middlePointValue.getX()) / 2,
798
                                        (startPointValue.getY() + middlePointValue.getY()) / 2
799
                                );
800
                            } else {
801
                                Point medium = GeometryUtils.createPoint(
802
                                        (startPointValue.getX() + middlePointValue.getX()) / 2,
803
                                        (startPointValue.getY() + middlePointValue.getY()) / 2
804
                                );
805
                                Point dir = GeometryUtils.createPoint(
806
                                        (middlePointValue.getX() - startPointValue.getX())/lenChord1,
807
                                        (middlePointValue.getY() - startPointValue.getY())/lenChord1
808
                                );
809
                                Point perpDir = GeometryUtils.createPoint(
810
                                        dir.getY(),
811
                                        -dir.getX()
812
                                );
813
                                double sagitta = Math.sqrt(Math.pow(radiusValue, 2)-Math.pow(lenChord1/2, 2));
814
                                
815
                                Point auxCenter1 = GeometryUtils.createPoint(
816
                                        medium.getX() + sagitta * perpDir.getX(),
817
                                        medium.getY() + sagitta * perpDir.getY()
818
                                );
819
                                Point auxCenter2 = GeometryUtils.createPoint(
820
                                        medium.getX() - sagitta * perpDir.getX(),
821
                                        medium.getY() - sagitta * perpDir.getY()
822
                                );
823

    
824
                                if (directionValue != null){
825
                                    if(StringUtils.equals(directionValue, CCW)){
826
                                        auxCenter = auxCenter2;
827
                                    } else {
828
                                        auxCenter = auxCenter1;
829
                                    }
830
                                } else {
831
                                    if (mousePosition.distance(auxCenter1) <= mousePosition.distance(auxCenter2)) {
832
                                        auxCenter = auxCenter1;
833
                                    } else {
834
                                        auxCenter = auxCenter2;
835
                                    }
836
                                }
837
                                Line perpChord1 = GeometryUtils.createLine(
838
                                        medium.getX(),
839
                                        medium.getY(),
840
                                        auxCenter.getX(),
841
                                        auxCenter.getY(),
842
                                        subtype
843
                                );
844
                                geometries.addStatus(perpChord1, auxiliaryLineSymbolEditing, "");
845

    
846
                            }
847

    
848
                            geometries.addStatus(auxCenter, auxiliaryPointSymbolEditing, "");
849

    
850
                            double distance = auxCenter.distance(mousePosition);
851

    
852
                            Point auxEndPoint = GeometryUtils.createPoint(
853
                                    auxCenter.getX() + radiusValue * (mousePosition.getX() - auxCenter.getX()) / distance,
854
                                    auxCenter.getY() + radiusValue * (mousePosition.getY() - auxCenter.getY()) / distance
855
                            );
856

    
857
                            Line chord2 = GeometryUtils.createLine(
858
                                    middlePointValue.getX(),
859
                                    middlePointValue.getY(),
860
                                    auxEndPoint.getX(),
861
                                    auxEndPoint.getY(),
862
                                    subtype
863
                            );
864

    
865
                            geometries.addStatus(chord2, auxiliaryLineSymbolEditing, "");
866

    
867
                            Arc auxArc = GeometryUtils.createArc(startPointValue, middlePointValue, auxEndPoint, subtype);
868

    
869
                            geometries.addStatus(auxArc, lineSymbolEditing, "");
870
                            return geometries;
871
                        } else {
872
                            auxCenter = GeometryUtils.getCenter(startPointValue, middlePointValue, mousePosition, POINT);
873
                            geometries.addStatus(middlePointValue, auxiliaryPointSymbolEditing, "");
874
                            Line endLine = GeometryUtils.createLine(
875
                                    middlePointValue.getX(),
876
                                    middlePointValue.getY(),
877
                                    mousePosition.getX(),
878
                                    mousePosition.getY(),
879
                                    subtype
880
                            );
881
                            geometries.addStatus(endLine, auxiliaryLineSymbolEditing, "");
882
 
883
                            boolean isValidPoint = false;
884
                            if (!GeometryUtils.areThreePointsInLine(startPointValue, middlePointValue, mousePosition)) {
885
                                if(directionValue != null){
886
                                    double coefDirection = getCoefDirection(startPointValue, middlePointValue, mousePosition);
887
                                    if(StringUtils.equalsIgnoreCase(directionValue, CCW)){
888
                                        if(coefDirection>=0){
889
                                            isValidPoint = true;
890
                                        }
891
                                    } else {
892
                                        if(coefDirection<0){
893
                                            isValidPoint = true;
894
                                        }
895
                                    }
896
                                } else {
897
                                    isValidPoint = true;
898
                                }
899
                            }
900
                            
901
                            if(isValidPoint) {
902

    
903
                                Line middle2CenterLine = GeometryUtils.createLine(
904
                                        (startPointValue.getX() + middlePointValue.getX()) / 2,
905
                                        (startPointValue.getY() + middlePointValue.getY()) / 2,
906
                                        auxCenter.getX(),
907
                                        auxCenter.getY(),
908
                                        subtype
909
                                );
910
                                geometries.addStatus(middle2CenterLine, auxiliaryLineSymbolEditing, "");
911
                                Line end2CenterLine = GeometryUtils.createLine(
912
                                        (middlePointValue.getX() + mousePosition.getX()) / 2,
913
                                        (middlePointValue.getY() + mousePosition.getY()) / 2,
914
                                        auxCenter.getX(),
915
                                        auxCenter.getY(),
916
                                        subtype
917
                                );
918
                                geometries.addStatus(end2CenterLine, auxiliaryLineSymbolEditing, "");
919
                                geometries.addStatus(mousePosition, auxiliaryPointSymbolEditing, "");
920

    
921
                                Arc auxArc = GeometryUtils.createArc(startPointValue, middlePointValue, mousePosition, subtype);
922
                                geometries.addStatus(auxArc, lineSymbolEditing, "");
923
                            }
924
                            return geometries;
925
                        }
926
                    }
927
                }
928
            }
929
        } catch (BaseException ex) {
930
            throw new DrawServiceException(ex);
931
        }
932

    
933
        return null;
934
    }
935

    
936
    private Double directedAngle(Double sweepAngleValue, String directionValue) {
937
        Double auxSweepAngleValue = sweepAngleValue;
938
        if (directionValue != null) {
939
            if (StringUtils.equalsIgnoreCase(directionValue, CCW)) {
940
                if (sweepAngleValue < 0) {
941
                    auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
942
                }
943
            } else {
944
                if (sweepAngleValue > 0) {
945
                    auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
946
                }
947
            }
948
        }
949
        return auxSweepAngleValue;
950
    }
951

    
952
    private void addArcAndEndPointToDrawingStatus(DefaultDrawingStatus geometries, Point centerValue, Double radiusValue, Double startAngleValue, Point startPointValue, Double sweepAngleValue, String directionValue, int subtype) throws GeometryOperationException, GeometryOperationNotSupportedException, CreateGeometryException {
953

    
954
        if (sweepAngleValue != null) {
955
            EditingProviderManager editingProviderManager
956
                    = EditingProviderLocator.getProviderManager();
957
            ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
958
            ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
959
            ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
960

    
961
            Point auxEndPoint;
962
            auxEndPoint = calculateEndPoint(centerValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
963

    
964
            geometries.addStatus(auxEndPoint, auxiliaryPointSymbolEditing, "");
965

    
966
            double auxSweepAngleValue = sweepAngleValue;
967
            if (directionValue != null) {
968
                if (StringUtils.equalsIgnoreCase(directionValue, CCW)) {
969
                    if (sweepAngleValue < 0) {
970
                        auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
971
                    }
972
                } else {
973
                    if (sweepAngleValue > 0) {
974
                        auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
975
                    }
976
                }
977
            }
978

    
979
            Arc auxArc = GeometryUtils.createArc(centerValue,
980
                    radiusValue,
981
                    startAngleValue,
982
                    auxSweepAngleValue,
983
                    subtype);
984

    
985
            geometries.addStatus(auxArc, lineSymbolEditing, "");
986
            
987
            EditingProviderServices editingProviderServices
988
                = (EditingProviderServices) getProviderServices();
989

    
990
            editingProviderServices.addAngleToDrawingStatus(
991
                    geometries, 
992
                    getTextSymbol(),
993
                    centerValue, 
994
                    startPointValue, 
995
                    auxEndPoint, 
996
                    subtype
997
            );
998
            
999
            Line auxEndLine = GeometryUtils.createLine(
1000
                    centerValue.getX(), 
1001
                    centerValue.getY(), 
1002
                    auxEndPoint.getX(), 
1003
                    auxEndPoint.getY(), 
1004
                    subtype
1005
            );
1006
            geometries.addStatus(auxEndLine, auxiliaryLineSymbolEditing, "");
1007
        }
1008
    }
1009

    
1010
    private double getCoefDirection(Point a, Point b, Point c) {
1011
        return Math.signum((b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY()) * (c.getX() - a.getX()));
1012
    }
1013

    
1014
    @Override
1015
    public void stop() throws StopServiceException {
1016
        values.clear();
1017
    }
1018

    
1019
    @Override
1020
    public List<EditingServiceParameter> getParameters() {
1021
        List<EditingServiceParameter> parameters
1022
                = new ArrayList<>();
1023

    
1024
        parameters.add(radius);
1025
        parameters.add(startAngle);
1026
        parameters.add(sweepAngle);
1027
        parameters.add(direction);
1028

    
1029
        parameters.add(startPoint);
1030
        parameters.add(middlePoint);
1031
        parameters.add(endPoint);
1032
        return parameters;
1033
    }
1034

    
1035
    @Override
1036
    public void setValue(Object value) throws InvalidEntryException {
1037
        EditingServiceParameter param = next();
1038
        setValue(param, value);
1039
    }
1040

    
1041
    @Override
1042
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
1043
        validateAndInsertValue(parameter, value);
1044
        removeRelatedParams(parameter);
1045
        fillEmptyParams();
1046
    }
1047

    
1048
    private void removeRelatedParams(EditingServiceParameter parameter) {
1049

    
1050
        if (parameter == startAngle) {
1051
            centerPointValue = null;
1052
        }
1053

    
1054
        if (parameter == radius) {
1055
            centerPointValue = null;
1056
        }
1057

    
1058
        if (parameter == sweepAngle) {
1059
            values.remove(endPoint);
1060
        }
1061

    
1062
        if (parameter == direction) {
1063
            values.remove(endPoint);
1064
        }
1065

    
1066
    }
1067

    
1068
    private void fillEmptyParams() throws InvalidEntryException {
1069
        Point startPointValue = (Point) values.get(startPoint);
1070
        Point middlePointValue = (Point) values.get(middlePoint);
1071
        Point endPointValue = (Point) values.get(endPoint);
1072

    
1073
        Double radiusValue = (Double) values.get(radius);
1074
        Double startAngleValue = (Double) values.get(startAngle);
1075
        Double sweepAngleValue = (Double) values.get(sweepAngle);
1076
        String directionValue = (String) values.get(direction);
1077

    
1078
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
1079

    
1080
        if (centerPointValue == null && startPointValue != null && radiusValue != null && startAngleValue != null) {
1081

    
1082
            centerPointValue = GeometryUtils.createPoint(
1083
                    startPointValue.getX() - radiusValue * Math.cos(startAngleValue),
1084
                    startPointValue.getY() - radiusValue * Math.sin(startAngleValue)
1085
            );
1086
        }
1087

    
1088
        if (centerPointValue == null && startPointValue != null && startAngleValue != null && endPointValue != null) {
1089

    
1090
            double m = Math.tan(startAngleValue);
1091
            double b = euclideanManager.getYIntercept(m, startPointValue.getX(), startPointValue.getY());
1092
            EuclideanLine2D startLine = euclideanManager.createLine2D(m, b);
1093

    
1094
            EuclideanLine2D midLine = euclideanManager.createLine2D(
1095
                    startPointValue.getX(),
1096
                    startPointValue.getY(),
1097
                    endPointValue.getX(),
1098
                    endPointValue.getY()
1099
            );
1100
            
1101
            Point averagePoint = GeometryUtils.createPoint(
1102
                    (startPointValue.getX() + endPointValue.getX()) / 2,
1103
                    (startPointValue.getY() + endPointValue.getY()) / 2
1104
            );
1105

    
1106
            Point2D center2D = startLine.getIntersection(midLine.getPerpendicular(averagePoint.getX(), averagePoint.getY()));
1107

    
1108
            centerPointValue = GeometryUtils.createPoint(center2D.getX(), center2D.getY());
1109

    
1110
        }
1111

    
1112
        if (centerPointValue == null && startPointValue != null && middlePointValue != null && endPointValue != null) {
1113
            try {
1114
                centerPointValue = GeometryUtils.getCenter(startPointValue, middlePointValue, endPointValue, GEOM2D);
1115
            } catch (CreateGeometryException ex) {
1116
                throw new InvalidEntryException(ex);
1117
            }
1118
        }
1119

    
1120
        if (radiusValue == null && centerPointValue != null && startPointValue != null) {
1121
            try {
1122
                radiusValue = centerPointValue.distance(startPointValue);
1123
                values.put(radius, radiusValue);
1124
            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
1125
                throw new InvalidEntryException(ex);
1126
            }
1127
        }
1128

    
1129
        if (endPointValue == null && centerPointValue != null && radiusValue != null && startAngleValue != null && sweepAngleValue != null) {
1130
            endPointValue = GeometryUtils.createPoint(centerPointValue, radiusValue, startAngleValue + sweepAngleValue);
1131
            values.put(endPoint, endPointValue);
1132
        }
1133

    
1134
        if (endPointValue == null && centerPointValue != null && startPointValue != null && sweepAngleValue != null) {
1135
            try {
1136
                endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
1137
                values.put(endPoint, endPointValue);
1138
            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
1139
                throw new InvalidEntryException(ex);
1140
            }
1141
        }
1142

    
1143
        if (sweepAngleValue == null && centerPointValue != null && startPointValue != null && endPointValue != null) {
1144
            sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue);
1145
            values.put(sweepAngle, sweepAngleValue);
1146
        }
1147

    
1148
    }
1149

    
1150
    private void validateAndInsertValue(EditingServiceParameter param,
1151
            Object value) throws InvalidEntryException {
1152
        try {
1153
            EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
1154

    
1155
            EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
1156
            int subtype = editingProviderServices.getSubType(featureStore);
1157

    
1158
            Double radiusValue = (Double) (values.get(radius));
1159
            Double startAngleValue = (Double) (values.get(startAngle));
1160
            Point startPointValue = (Point) (values.get(startPoint));
1161
            Double sweepAngleValue = (Double) (values.get(sweepAngle));
1162
            String directionValue = (String) (values.get(direction));
1163
            Point middlePointValue = (Point) (values.get(middlePoint));
1164

    
1165
            CoerceToDouble coerceToDouble = new CoerceToDouble();
1166
            if (param == startPoint) {
1167
                if (value instanceof Point) {
1168
                    values.put(param, value);
1169
                    return;
1170
                }
1171
            } else if (param == middlePoint) {
1172
                if (value instanceof Point) {
1173
                    Point pointValue = (Point) value;
1174
                    if (centerPointValue != null) {
1175
                        if (startPointValue != null) {
1176
                            if (radiusValue != null) {
1177
                                // If the center, radius and starting point values are already known, 
1178
                                // this should not be possible, but we will check it just in case.
1179
                                double midAngle = GeometryUtils.calculateAngle(centerPointValue, pointValue);
1180
                                Point auxMiddlePointValue = GeometryUtils.createPoint(
1181
                                        centerPointValue.getX() + radiusValue * Math.cos(midAngle),
1182
                                        centerPointValue.getY() + radiusValue * Math.sin(midAngle)
1183
                                );
1184
                                values.put(param, auxMiddlePointValue);
1185
                            } else if (startAngleValue != null) {
1186
                                //Unreachable code
1187
                                throw new InvalidEntryException(null);
1188
                            }
1189
                        }
1190
                    } else if (startPointValue != null && radiusValue != null) {
1191
                        double distance = startPointValue.distance(pointValue);
1192

    
1193
                        if (distance >= 2 * radiusValue) {
1194
                            Point auxPoint = GeometryUtils.createPoint(
1195
                                    startPointValue.getX() + 2 * radiusValue * (pointValue.getX() - startPointValue.getX()) / distance,
1196
                                    startPointValue.getY() + 2 * radiusValue * (pointValue.getY() - startPointValue.getY()) / distance
1197
                            );
1198
                            values.put(middlePoint, auxPoint);
1199
                        } else {
1200
                            values.put(middlePoint, pointValue);
1201
                        }
1202
                    }
1203
                    values.put(param, value);
1204
                    return;
1205
                }
1206

    
1207
            } else if (param == endPoint) {
1208

    
1209
                if (value instanceof Point) {
1210
                    Point pointValue = (Point) value;
1211
                    Point auxCenter = null;
1212
                    if (radiusValue != null && startPointValue != null && sweepAngleValue != null) {
1213

    
1214
                        // A combination of the sweep angle and the mouse position 
1215
                        // will determine the center and the end point 
1216
                        double auxSweepAngleValue = sweepAngleValue;
1217
                        double lenChord = startPointValue.distance(pointValue);
1218
                        if (lenChord >= 2 * radiusValue) {
1219
                            auxCenter = GeometryUtils.createPoint(
1220
                                    startPointValue.getX() + radiusValue * (pointValue.getX()-startPointValue.getX()) / lenChord,
1221
                                    startPointValue.getY() + radiusValue * (pointValue.getY()-startPointValue.getY()) / lenChord
1222
                            );
1223
                        } else {
1224
                            Point medium = GeometryUtils.createPoint(
1225
                                    (startPointValue.getX() + pointValue.getX()) / 2,
1226
                                    (startPointValue.getY() + pointValue.getY()) / 2
1227
                            );
1228
                            Point dir = GeometryUtils.createPoint(
1229
                                    (pointValue.getX() - startPointValue.getX()) / lenChord,
1230
                                    (pointValue.getY() - startPointValue.getY()) / lenChord
1231
                            );
1232
                            Point perpDir = GeometryUtils.createPoint(
1233
                                    -dir.getY(),
1234
                                    dir.getX()
1235
                            );
1236
                            double sagitta = Math.sqrt(Math.pow(radiusValue, 2) - Math.pow(lenChord / 2, 2));
1237

    
1238
                            Point auxCenter1 = GeometryUtils.createPoint(
1239
                                    medium.getX() + sagitta * perpDir.getX(),
1240
                                    medium.getY() + sagitta * perpDir.getY()
1241
                            );
1242
                            
1243
                            Point auxCenter2 = GeometryUtils.createPoint(
1244
                                    medium.getX() - sagitta * perpDir.getX(),
1245
                                    medium.getY() - sagitta * perpDir.getY()
1246
                            );
1247

    
1248
                            if(sweepAngleValue>=0){
1249
                                auxCenter = auxCenter1;
1250
                            } else {
1251
                                auxCenter = auxCenter2;
1252
                            }
1253
                        }
1254
                        centerPointValue = auxCenter;
1255

    
1256
                        auxSweepAngleValue = directedAngle(sweepAngleValue, directionValue);
1257

    
1258
                        Point auxEndPoint = calculateEndPoint(auxCenter, radiusValue, null, startPointValue, sweepAngleValue);
1259

    
1260
                        values.put(param, auxEndPoint);
1261
                        return;
1262
                    }
1263
                    
1264
                    if(middlePointValue == null) {
1265
                        Point endPointValue;
1266
                        if(startAngleValue != null){
1267
                            double m = Math.tan(startAngleValue);
1268
                            double b = euclideanManager.getYIntercept(m, startPointValue.getX(), startPointValue.getY());
1269
                            EuclideanLine2D startLine = euclideanManager.createLine2D(m, b);
1270
                            
1271
                            if(sweepAngleValue == null) {
1272

    
1273
                                endPointValue = pointValue.cloneGeometry();
1274

    
1275
                                double endAngle = GeometryUtils.calculateAngle(startPointValue, endPointValue);
1276
                                double angleDistance = editingProviderServices.angleDistance(startAngleValue, endAngle);
1277
                                if (angleDistance > Math.PI / 2 && angleDistance < 3 * Math.PI / 2) {
1278
                                    EuclideanLine2D endLine = euclideanManager.createLine2D(
1279
                                            startPointValue.getX(),
1280
                                            startPointValue.getY(),
1281
                                            endPointValue.getX(),
1282
                                            endPointValue.getY()
1283
                                    );
1284

    
1285
                                    Point averagePoint = GeometryUtils.createPoint(
1286
                                            (startPointValue.getX() + endPointValue.getX()) / 2,
1287
                                            (startPointValue.getY() + endPointValue.getY()) / 2
1288
                                    );
1289

    
1290
                                    Point2D auxCenter2D = startLine.getIntersection(endLine.getPerpendicular(averagePoint.getX(), averagePoint.getY()));
1291
                                    auxCenter = GeometryUtils.createPoint(auxCenter2D.getX(), auxCenter2D.getY());
1292
                                    Point2D perp = endLine.getNearestPoint(auxCenter2D);
1293

    
1294
                                    double auxSweepAngleValue = GeometryUtils.calculateAngle(auxCenter, startPointValue, endPointValue);
1295

    
1296
                                    endPointValue = calculateEndPoint(auxCenter, radiusValue, startAngleValue, startPointValue, auxSweepAngleValue);
1297
                                    values.put(param, endPointValue);
1298
                                    return;
1299
                                }
1300
                            } else { // sweepAngle != null
1301
                                double endAngle = startAngleValue + sweepAngleValue;
1302
                                double endLineM = Math.tan(startAngleValue + sweepAngleValue);
1303
                                double endLineB = euclideanManager.getYIntercept(endLineM, pointValue.getX(), pointValue.getY());
1304
                                EuclideanLine2D endLine = euclideanManager.createLine2D(endLineM, endLineB);
1305

    
1306
                                Point2D auxCenter2D = startLine.getIntersection(endLine);
1307
                                auxCenter = GeometryUtils.createPoint(auxCenter2D.getX(), auxCenter2D.getY());
1308
                                if (Math.abs(GeometryUtils.calculateAngle(auxCenter, startPointValue) - startAngleValue) <= 0.001) {
1309

    
1310
                                    double auxRadiusValue = startPointValue.distance(auxCenter);
1311

    
1312
                                    Point auxEndPoint = GeometryUtils.createPoint(auxCenter, auxRadiusValue, endAngle);
1313

    
1314
                                    centerPointValue = auxCenter;
1315
                                    values.put(endPoint, auxEndPoint);
1316
                                } else {
1317
                                    throw new InvalidEntryException(null);
1318
                                }
1319
                                return;
1320
                            }
1321
                        } else if (sweepAngleValue != null) { //startAngleValue == null
1322
                            EuclideanLine2D endLine = euclideanManager.createLine2D(
1323
                                    startPointValue.getX(), 
1324
                                    startPointValue.getY(), 
1325
                                    pointValue.getX(), 
1326
                                    pointValue.getY());
1327
                            Point averagePoint = GeometryUtils.createPoint(
1328
                                    (startPointValue.getX()+pointValue.getX())/2, 
1329
                                    (startPointValue.getY()+pointValue.getY())/2);
1330
                            
1331
                            EuclideanLine2D perp = endLine.getPerpendicular(averagePoint.getX(), averagePoint.getY());
1332
                            
1333
                            double lenEndLine = startPointValue.distance(pointValue);
1334
                            
1335
                            double auxRadiusValue = Math.abs(lenEndLine/(2*Math.sin(sweepAngleValue/2)));
1336
                            double sagitta = auxRadiusValue*Math.cos(sweepAngleValue/2);
1337
                            
1338
                            Point dir = GeometryUtils.createPoint(
1339
                                    (pointValue.getX() - startPointValue.getX() )/lenEndLine,
1340
                                    (pointValue.getY() - startPointValue.getY() )/lenEndLine
1341
                            );
1342
                            
1343
                            Point perpDir = GeometryUtils.createPoint(
1344
                                    -dir.getY(),
1345
                                    dir.getX()
1346
                            );
1347
                            Point auxCenter1 = GeometryUtils.createPoint(averagePoint.getX() + sagitta * perpDir.getX(),
1348
                                    averagePoint.getY() + sagitta * perpDir.getY()
1349
                            );
1350
                            Point auxCenter2 = GeometryUtils.createPoint(averagePoint.getX() - sagitta * perpDir.getX(),
1351
                                    averagePoint.getY() - sagitta * perpDir.getY()
1352
                            );
1353
                            
1354
                            if(sweepAngleValue>=0){
1355
                                auxCenter = auxCenter1;
1356
                            } else {
1357
                                auxCenter = auxCenter2;
1358
                            }
1359

    
1360
                            values.put(radius, auxRadiusValue);
1361
                            centerPointValue = auxCenter;
1362
                            values.put(param, pointValue);
1363
                            return;
1364
                        }
1365
                        
1366
                        if (sweepAngleValue != null) { //startAngleValue == null
1367
                            if (directionValue == null) {
1368
                                double coefDirection = getCoefDirection(centerPointValue, startPointValue, pointValue);
1369
                                if (coefDirection >= 0) {
1370
                                    values.put(direction, CCW);
1371
                                } else {
1372
                                    values.put(direction, CW);
1373
                                }
1374
                            }
1375
                            try {
1376
                                endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
1377
                            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
1378
                                throw new InvalidEntryException(ex);
1379
                            }
1380
                        } else {
1381
                            if (radiusValue == null) {
1382
                                try {
1383
                                    radiusValue = centerPointValue.distance(startPointValue);
1384
                                } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
1385
                                    throw new InvalidEntryException(ex);
1386
                                }
1387
                            }
1388

    
1389
                            double module;
1390
                            try {
1391
                                module = centerPointValue.distance(pointValue);
1392
                            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
1393
                                throw new InvalidEntryException(ex);
1394
                            }
1395

    
1396
                            endPointValue = GeometryUtils.createPoint(
1397
                                    centerPointValue.getX() + radiusValue * (pointValue.getX() - centerPointValue.getX()) / module,
1398
                                    centerPointValue.getY() + radiusValue * (pointValue.getY() - centerPointValue.getY()) / module
1399
                            );
1400
                        }
1401
                        values.put(endPoint, endPointValue);
1402
                        return;
1403

    
1404
                    } 
1405
                    if (radiusValue != null) {
1406
                        double lenChord1 = startPointValue.distance(middlePointValue);
1407
                        if (lenChord1 >= 2 * radiusValue) {
1408
                            auxCenter = GeometryUtils.createPoint(startPointValue.getX() + radiusValue * (middlePointValue.getX() - startPointValue.getX()) / lenChord1,
1409
                                    startPointValue.getY() + radiusValue * (middlePointValue.getY() - startPointValue.getY()) / lenChord1
1410
                            );
1411
                        } else {
1412
                            Point averagePoint = GeometryUtils.createPoint(
1413
                                    (startPointValue.getX() + middlePointValue.getX()) / 2,
1414
                                    (startPointValue.getY() + middlePointValue.getY()) / 2
1415
                            );
1416
                            Point dir = GeometryUtils.createPoint(
1417
                                    (middlePointValue.getX() - startPointValue.getX())/lenChord1,
1418
                                    (middlePointValue.getY() - startPointValue.getY())/lenChord1
1419
                            );
1420
                            Point perpDir = GeometryUtils.createPoint(
1421
                                    dir.getY(),
1422
                                    -dir.getX()
1423
                            );
1424
                            double sagitta = Math.sqrt(Math.pow(radiusValue, 2)-Math.pow(lenChord1/2, 2));
1425
                            Point auxCenter1 = GeometryUtils.createPoint(averagePoint.getX() + sagitta * perpDir.getX(),
1426
                                    averagePoint.getY() + sagitta * perpDir.getY()
1427
                            );
1428
                            Point auxCenter2 = GeometryUtils.createPoint(averagePoint.getX() - sagitta * perpDir.getX(),
1429
                                    averagePoint.getY() - sagitta * perpDir.getY()
1430
                            );
1431
                            
1432
                            if (directionValue != null){
1433
                                if(StringUtils.equals(directionValue, CCW)){
1434
                                    auxCenter = auxCenter2;
1435
                                } else {
1436
                                    auxCenter = auxCenter1;
1437
                                }
1438
                            } else {
1439
                                if (pointValue.distance(auxCenter1) <= pointValue.distance(auxCenter2)) {
1440
                                    auxCenter = auxCenter1;
1441
                                } else {
1442
                                    auxCenter = auxCenter2;
1443
                                }
1444
                            }
1445
                        }
1446

    
1447
                        double distance = auxCenter.distance(pointValue);
1448

    
1449
                        Point auxEndPoint = GeometryUtils.createPoint(
1450
                                auxCenter.getX() + radiusValue * (pointValue.getX() - auxCenter.getX()) / distance,
1451
                                auxCenter.getY() + radiusValue * (pointValue.getY() - auxCenter.getY()) / distance
1452
                        );
1453

    
1454
                        centerPointValue = auxCenter;
1455
                        values.put(param, auxEndPoint);
1456
                        return;
1457
                    } else {
1458
                        if(!GeometryUtils.areThreePointsInLine(startPointValue, middlePointValue, pointValue)){
1459
                            if(directionValue != null){
1460
                                double coefDirection = getCoefDirection(startPointValue, middlePointValue, pointValue);
1461
                                if(StringUtils.equalsIgnoreCase(directionValue, CCW)) {
1462
                                    if (coefDirection >= 0) {
1463
                                        values.put(param, pointValue);
1464
                                    } else {
1465
                                        throw new InvalidEntryException(null);
1466
                                    }
1467
                                } else {
1468
                                    if (coefDirection < 0) {
1469
                                        values.put(param, pointValue);
1470
                                    } else {
1471
                                        throw new InvalidEntryException(null);
1472
                                    }
1473
                                }
1474
                            } else {
1475
                                values.put(param, pointValue);
1476
                                return;
1477
                            }
1478
                        }
1479
                    }
1480
                    return;
1481
                }
1482
            } else if (param == radius) {
1483
                Double doubleValue = (Double) coerceToDouble.coerce(value);
1484
                // To avoid infinite, Nan and negative values
1485
                if (Double.isFinite(doubleValue)) {
1486
                    values.put(param, Math.abs(doubleValue));
1487
                    return;
1488
                }
1489
            } else if (param == startAngle) {
1490
                Double doubleValue = (Double) coerceToDouble.coerce(value);
1491
                values.put(param, reduceAngle(Math.toRadians(doubleValue)));
1492
                return;
1493
            } else if (param == sweepAngle) {
1494
                Double doubleValue = (Double) coerceToDouble.coerce(value);
1495
                values.put(param, reduceAngle(Math.toRadians(doubleValue)));
1496
                return;
1497
            } else if (param == direction) {
1498
                if (value instanceof String) {
1499
                    if (((String) value).trim().equalsIgnoreCase(CCW)) {
1500
                        values.put(param, CCW);
1501
                        return;
1502
                    } else if (((String) value).trim().equalsIgnoreCase(CW)) {
1503
                        values.put(param, CW);
1504
                        return;
1505
                    }
1506
                }
1507
            }
1508
        } catch (Exception ex) {
1509
            throw new InvalidEntryException(ex);
1510
        }
1511
        throw new InvalidEntryException(null);
1512
    }
1513
    
1514
    /**
1515
     * Reduce the angle so that it is in the range (-2*PI, +2*PI) 
1516
     * @param angle
1517
     * @return 
1518
     */
1519
    private double reduceAngle(double angle){
1520
        return Math.IEEEremainder(angle, 2*Math.PI);
1521
    }
1522

    
1523
    private Point calculateEndPoint(Point centerPointValue, Double radiusValue, Double startAngleValue, Point startPointValue, Double sweepAngleValue) throws GeometryOperationNotSupportedException, GeometryOperationException { //String directionValue
1524

    
1525
        Point auxEndPointValue = (Point) values.get(endPoint);
1526
        if (auxEndPointValue != null) {
1527
            return auxEndPointValue;
1528
        }
1529
        if (startPointValue == null || centerPointValue == null || sweepAngleValue == null) {
1530
            return null;
1531
        }
1532
        if (startAngleValue == null) {
1533
            startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue);
1534
        }
1535

    
1536
        if (radiusValue == null) {
1537
            radiusValue = centerPointValue.distance(startPointValue);
1538
        }
1539

    
1540
        double endAngle;
1541
        endAngle = startAngleValue + sweepAngleValue;
1542

    
1543
        auxEndPointValue = GeometryUtils.createPoint(
1544
                centerPointValue.getX() + radiusValue * Math.cos(endAngle),
1545
                centerPointValue.getY() + radiusValue * Math.sin(endAngle)
1546
        );
1547

    
1548
        return auxEndPointValue;
1549
    }
1550

    
1551
    @Override
1552
    public Geometry finish() throws FinishServiceException {
1553
        Point startPointValue = (Point) values.get(startPoint);
1554
        Point middlePointValue = (Point) values.get(middlePoint);
1555
        Point endPointValue = (Point) values.get(endPoint);
1556

    
1557
        Double radiusValue = (Double) values.get(radius);
1558
        Double startAngleValue = (Double) values.get(startAngle);
1559
        Double sweepAngleValue = (Double) values.get(sweepAngle);
1560
        String directionValue = (String) values.get(direction);
1561

    
1562
        EditingProviderServices editingProviderServices
1563
                = (EditingProviderServices) getProviderServices();
1564

    
1565
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
1566

    
1567
        try {
1568

    
1569
            int subtype
1570
                    = editingProviderServices.getSubType(featureStore);
1571

    
1572
            if (radiusValue == null) {
1573
                radiusValue = centerPointValue.distance(startPointValue);
1574
            }
1575

    
1576
            Curve arc = null;
1577

    
1578
            
1579
            if (startPointValue!=null && middlePointValue!=null && endPointValue!=null) {
1580
                arc = GeometryUtils.createArc(startPointValue,
1581
                        middlePointValue, endPointValue, subtype);
1582

    
1583
            } else if (radiusValue != null && startPointValue != null && sweepAngleValue != null && centerPointValue != null && endPointValue != null) {
1584

    
1585
                /* IN PROCESS */
1586
                double auxSweepAngleValue = sweepAngleValue;
1587

    
1588
                if (directionValue != null) {
1589
                    if (StringUtils.equalsIgnoreCase(directionValue, CCW)) {
1590
                        if (sweepAngleValue < 0) {
1591
                            auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1592
                        }
1593
                    } else {
1594
                        if (sweepAngleValue > 0) {
1595
                            auxSweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1596
                        }
1597
                    }
1598
                }
1599

    
1600
                arc = GeometryUtils.createArc(
1601
                        centerPointValue,
1602
                        radiusValue,
1603
                        GeometryUtils.calculateAngle(centerPointValue, startPointValue),
1604
                        auxSweepAngleValue,
1605
                        subtype);
1606

    
1607
                /* END OF IN PROCESS */
1608
            } else if (middlePointValue == null) {
1609

    
1610
                double coefDirection = getCoefDirection(centerPointValue, startPointValue, endPointValue);
1611
                if (sweepAngleValue != null) {
1612
                    if (directionValue != null) {
1613
                        if (directionValue.equalsIgnoreCase(CCW)) {
1614
                            if (sweepAngleValue >= 0) {
1615
                                //Do nothing
1616
                            } else {
1617
                                sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1618
                            }
1619
                        } else {
1620
                            if (sweepAngleValue <= 0) {
1621
                                //Do nothing
1622
                            } else {
1623
                                sweepAngleValue = -(2 * Math.PI - sweepAngleValue); //coefDirection * sweepAngleValue;
1624
                            }
1625
                        }
1626
                    } else if (Math.signum(coefDirection) != Math.signum(sweepAngleValue)) {
1627
                        sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1628
                    }
1629

    
1630
                    arc = GeometryUtils.createArc(
1631
                            centerPointValue,
1632
                            radiusValue,
1633
                            startAngleValue,
1634
                            sweepAngleValue,
1635
                            GEOM2D);
1636
                } else {  //sweepAngleValue == null
1637

    
1638
                    double distance = centerPointValue.distance(endPointValue);
1639
                    Point point = GeometryUtils.createPoint(
1640
                            centerPointValue.getX() + radiusValue * ((endPointValue.getX() - centerPointValue.getX()) / distance),
1641
                            centerPointValue.getY() + radiusValue * ((endPointValue.getY() - centerPointValue.getY()) / distance)
1642
                    );
1643

    
1644
                    //calculate sweepAngle
1645
                    sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue);
1646

    
1647
                    if (Math.abs(sweepAngleValue) > 0d) {
1648
                        if (directionValue != null) {
1649
                            if (directionValue.equalsIgnoreCase(CCW)) {
1650
                                if (sweepAngleValue >= 0) {
1651
                                    //Do nothing
1652
                                } else {
1653
                                    sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1654
                                }
1655
                            } else {
1656
                                if (sweepAngleValue <= 0) {
1657
                                    //Do nothing
1658
                                } else {
1659
                                    sweepAngleValue = -(2 * Math.PI - sweepAngleValue); //coefDirection * sweepAngleValue;
1660
                                }
1661
                            }
1662
                        } else if (Math.signum(coefDirection) != Math.signum(sweepAngleValue)) {
1663
                            sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
1664
                        }
1665
                        arc = GeometryUtils.createArc(
1666
                                centerPointValue,
1667
                                radiusValue,
1668
                                startAngleValue,
1669
                                sweepAngleValue,
1670
                                GEOM2D);
1671
                    }
1672
                }
1673
            } else { //startPointValue!=null && middlePointValue!=null && endPointValue!=null
1674
                arc = GeometryUtils.createArc(startPointValue,
1675
                        middlePointValue, endPointValue, subtype);
1676

    
1677
            }
1678

    
1679
            GeometryType geomType
1680
                    = editingProviderServices.getGeomType(featureStore);
1681

    
1682
            if (geomType.isTypeOf(MULTICURVE)) {
1683

    
1684
                MultiCurve multiCurve;
1685
                multiCurve
1686
                        = GeometryLocator.getGeometryManager().createMultiCurve(
1687
                                geomType.getSubType());
1688
                multiCurve.addCurve(arc);
1689
                return multiCurve;
1690
            }
1691

    
1692
            return arc;
1693
        } catch (Exception e) {
1694
            throw new FinishServiceException(e);
1695
        }
1696
    }
1697

    
1698
    @Override
1699
    public void finishAndStore() throws FinishServiceException {
1700
        Geometry geometry = finish();
1701
        EditingProviderServices editingProviderServices
1702
                = (EditingProviderServices) getProviderServices();
1703
        editingProviderServices.insertGeometryIntoFeatureStore(geometry,
1704
                featureStore);
1705
        centerPointValue = null;
1706
    }
1707

    
1708
    @Override
1709
    public void start() throws StartServiceException {
1710
        values = new HashMap<>();
1711
    }
1712

    
1713
    @Override
1714
    public String getName() {
1715
        return ArcThreePointsEditingProviderFactory.PROVIDER_NAME;
1716
    }
1717

    
1718
    @Override
1719
    public boolean isEnabled(EditingServiceParameter parameter) {
1720

    
1721
        if (parameter == radius) {
1722
            if (centerPointValue != null || values.get(middlePoint) != null || values.get(endPoint) != null) {
1723
                return false;
1724
            }
1725
        } else if (parameter == startAngle) {
1726
            if (centerPointValue != null || values.get(middlePoint) != null || values.get(endPoint) != null) {
1727
                return false;
1728
            }
1729
        } else if (parameter == sweepAngle) {
1730
            if (values.get(endPoint) != null || values.get(middlePoint) != null) {
1731
                return false;
1732
            }
1733
        } else if (parameter == direction) {
1734
            if (values.get(endPoint) != null) {
1735
                return false;
1736
            }
1737
            if (values.get(middlePoint) != null && centerPointValue != null) {
1738
                return false;
1739
            }
1740
        }
1741
        return true;
1742
    }
1743

    
1744
    private ISimpleTextSymbol getTextSymbol() {
1745
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
1746
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
1747
        textSymbol.setFontSize(10);
1748
        return textSymbol;
1749
    }
1750

    
1751
}