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 / ArcByCenterEditingProvider.java @ 4253

History | View | Annotate | Download (40.6 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.vectorediting.lib.prov.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.gvsig.euclidean.EuclideanLine2D;
32
import org.gvsig.euclidean.EuclideanManager;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryUtils;
37
import org.gvsig.fmap.geom.aggregate.MultiCurve;
38
import org.gvsig.fmap.geom.exception.CreateGeometryException;
39
import org.gvsig.fmap.geom.operation.GeometryOperationException;
40
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
41
import org.gvsig.fmap.geom.primitive.Arc;
42
import org.gvsig.fmap.geom.primitive.Curve;
43
import org.gvsig.fmap.geom.primitive.Line;
44
import org.gvsig.fmap.geom.primitive.Point;
45
import org.gvsig.fmap.geom.type.GeometryType;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.dataTypes.CoercionException;
49
import org.gvsig.tools.dataTypes.DataTypes;
50
import org.gvsig.tools.dataTypes.impl.coercion.CoerceToDouble;
51
import org.gvsig.tools.dynobject.DynObject;
52
import org.gvsig.tools.i18n.I18nManager;
53
import org.gvsig.tools.service.spi.ProviderServices;
54
import org.gvsig.tools.util.ToolsUtilLocator;
55
import org.gvsig.vectorediting.lib.api.DrawingStatus;
56
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
57
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
58
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
59
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
60
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
61
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
63
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
64
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
65
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
66
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
67
import org.gvsig.vectorediting.lib.spi.EditingProvider;
68
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
69
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
70
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
71
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
72
import org.slf4j.Logger;
73
import org.slf4j.LoggerFactory;
74

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

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

    
85
    private static final Logger LOGGER = LoggerFactory.getLogger(ArcByCenterEditingProvider.class);
86

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

    
93
    private final EditingServiceParameter centerPoint;
94

    
95
    private final EditingServiceParameter startPoint;
96

    
97
    private final EditingServiceParameter endPoint;
98

    
99
    private Map<EditingServiceParameter, Object> values;
100

    
101
    private final FeatureStore featureStore;
102

    
103
    /**
104
     * Default constructor.
105
     *
106
     * @param providerServices available services for this provider
107
     * @param parameters of this provider
108
     */
109
    public ArcByCenterEditingProvider(ProviderServices providerServices,
110
            DynObject parameters) {
111
        super(providerServices);
112

    
113
        this.featureStore
114
                = (FeatureStore) parameters
115
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
116

    
117
        this.centerPoint
118
                = new DefaultEditingServiceParameter("center_point", "center_point",
119
                        TYPE.POSITION);
120

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

    
125
        this.endPoint
126
                = new DefaultEditingServiceParameter("end_point", "end_point",
127
                        TYPE.POSITION);
128

    
129
        this.radius
130
                = new DefaultEditingServiceParameter("radius", "radius", true,
131
                        TYPE.VALUE);
132

    
133
        this.startAngle
134
                = new DefaultEditingServiceParameter("start_angle", "start_angle", true,
135
                        TYPE.VALUE);
136

    
137
        this.sweepAngle
138
                = new DefaultEditingServiceParameter("sweep_angle", "sweep_angle", true,
139
                        TYPE.VALUE);
140

    
141
        I18nManager i18nManager = ToolsLocator.getI18nManager();
142

    
143
        EditingProviderServices editingProviderServices
144
                = (EditingProviderServices) getProviderServices();
145

    
146
        DefaultEditingServiceParameterOptions directionOptions = new DefaultEditingServiceParameterOptions()
147
                .add(CCW, CCW, CCW)
148
                .add(CW, CW, CW);
149

    
150
        String consoleMsg
151
                = editingProviderServices.makeConsoleMessage(
152
                        "_Direction", directionOptions);
153

    
154
        // CCW should be the default value, but I don't assign it as such
155
        // to detect whether the user has selected a value or not.
156
        this.direction
157
                = new DefaultEditingServiceParameter(
158
                        i18nManager.getTranslation("_Direction"),
159
                        consoleMsg,
160
                        directionOptions,
161
                        null,
162
                        true,
163
                        TYPE.OPTION).setDataType(DataTypes.STRING);
164
        
165

    
166
    }
167

    
168
    @Override
169
    public EditingServiceParameter next() {
170
        if (values.get(centerPoint) == null) {
171
            return this.centerPoint;
172
        } else if (values.get(startPoint) == null && (values.get(radius) == null || values.get(startAngle) == null)) {
173
            return this.startPoint;
174
        } else if (values.get(endPoint) == null ) {
175
            return this.endPoint;
176
        }
177
        return null;
178
    }
179

    
180
    @Override
181
    public DrawingStatus getDrawingStatus(Point mousePosition)
182
            throws DrawServiceException {
183

    
184
        Point centerPointValue = (Point) values.get(centerPoint);
185
        Point startPointValue = (Point) values.get(startPoint);
186
        Point endPointValue = (Point) values.get(endPoint);
187
        
188
        Double radiusValue = (Double) values.get(radius);
189
        Double startAngleValue = (Double) values.get(startAngle);
190
        Double sweepAngleValue = (Double) values.get(sweepAngle);
191
        String directionValue = (String) values.get(direction);
192
        
193
        
194
        DefaultDrawingStatus geometries = new DefaultDrawingStatus();
195

    
196
        ISymbol previewSymbol = this.getPreviewSymbol();
197
        geometries.setPreviewSymbol(previewSymbol);
198
        
199
        EditingProviderManager editingProviderManager
200
                = EditingProviderLocator.getProviderManager();
201
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
202
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
203
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
204

    
205
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
206

    
207
        if (values != null) {
208
            if(centerPointValue == null) {
209
                    if (radiusValue != null && startAngleValue != null) {
210
                        try {
211
                            startPointValue = GeometryUtils.createPoint(mousePosition, radiusValue, startAngleValue);
212
                            geometries.addStatus(startPointValue, auxiliaryPointSymbolEditing, "");
213

    
214
                            Line auxLine = GeometryUtils.createLine(mousePosition, startPointValue, CURVE);
215
                            geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
216
                            
217
                            if (sweepAngleValue != null && directionValue != null) {
218

    
219
                                addArcAndEndPointToDrawingStatus(geometries, mousePosition, radiusValue, startAngleValue, startPointValue, sweepAngleValue, directionValue);
220
                            } 
221
                            
222
                            return geometries;
223
                        } catch (CreateGeometryException | GeometryOperationNotSupportedException | GeometryOperationException ex) {
224
                            throw new DrawServiceException(ex);
225
                        }
226
                    }
227
                
228
            } else { //centerPointValue != null
229

    
230
                geometries.addStatus(centerPointValue, auxiliaryPointSymbolEditing, "");
231

    
232
                if (startPointValue == null) {
233
                    try {
234
                        if (radiusValue != null && startAngleValue != null) {
235
                            startPointValue = GeometryUtils.createPoint(centerPointValue, radiusValue, startAngleValue);
236
                            addArcAndEndPointToDrawingStatus(geometries, centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue, directionValue);
237
                        } else if (radiusValue != null) { // startAngleValue == null
238
                            double distance = centerPointValue.distance(mousePosition);
239
                            Point auxStartPoint = GeometryUtils.createPoint(
240
                                    centerPointValue.getX() + radiusValue * ((mousePosition.getX() - centerPointValue.getX()) / distance),
241
                                    centerPointValue.getY() + radiusValue * ((mousePosition.getY() - centerPointValue.getY()) / distance)
242
                            );
243
                            geometries.addStatus(auxStartPoint, auxiliaryPointSymbolEditing, "");
244
                            Line auxLine = GeometryUtils.createLine(centerPointValue, auxStartPoint, CURVE);
245
                            geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
246
                            addArcAndEndPointToDrawingStatus(
247
                                    geometries, 
248
                                    centerPointValue, 
249
                                    radiusValue, 
250
                                    GeometryUtils.calculateAngle(centerPointValue, auxStartPoint), 
251
                                    auxStartPoint, 
252
                                    sweepAngleValue, 
253
                                    directionValue);
254

    
255
                        } else if (startAngleValue != null) { // radiusValue == null
256
                            double m = Math.tan(startAngleValue);
257
                            Point auxStartPoint;
258
                            if (Double.isInfinite(m)) {
259
                                auxStartPoint = GeometryUtils.createPoint(
260
                                        centerPointValue.getX(), mousePosition.getY());
261
                            } else {
262
                                EuclideanLine2D auxLine = euclideanManager.createLine2D(
263
                                        m,
264
                                        euclideanManager.getYIntercept(
265
                                                m,
266
                                                centerPointValue.getX(),
267
                                                centerPointValue.getY()
268
                                        )
269
                                );
270

    
271
                                double anglePointValue = GeometryUtils.calculateAngle(centerPointValue, mousePosition);
272
                                double x = centerPointValue.getX();
273
                                double y = centerPointValue.getY();
274
                                if (Double.isInfinite(m)) {
275
                                    auxStartPoint = GeometryUtils.createPoint(
276
                                            centerPointValue.getX(), mousePosition.getY());
277
                                } else if (m == 0) {
278
                                    auxStartPoint = GeometryUtils.createPoint(
279
                                            mousePosition.getX(), centerPointValue.getY());
280
                                } else {
281
                                    if (Math.signum(Math.cos(startAngleValue)) == Math.signum(Math.cos(anglePointValue))) {
282
                                        x = mousePosition.getX();
283
                                    }
284
                                    if (Math.signum(Math.sin(startAngleValue)) == Math.signum(Math.sin(anglePointValue))) {
285
                                        y = mousePosition.getY();
286
                                    }
287
                                    Point2D proyected = auxLine.getNearestPoint(x, y);
288
                                    auxStartPoint = GeometryUtils.createPoint(proyected.getX(), proyected.getY());
289
                                }
290
                            }
291

    
292
                            geometries.addStatus(auxStartPoint, auxiliaryPointSymbolEditing, "");
293
                            Line auxLine = GeometryUtils.createLine(centerPointValue, auxStartPoint, CURVE);
294
                            geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
295
                            addArcAndEndPointToDrawingStatus(
296
                                    geometries, 
297
                                    centerPointValue, 
298
                                    centerPointValue.distance(auxStartPoint), 
299
                                    startAngleValue, 
300
                                    auxStartPoint, 
301
                                    sweepAngleValue, 
302
                                    directionValue);
303

    
304
                        } else { //radiusValue == null && startAngleValue == null
305
                            geometries.addStatus(mousePosition, auxiliaryPointSymbolEditing, "");
306
                            Line auxLine = GeometryUtils.createLine(centerPointValue, mousePosition, CURVE);
307
                            geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
308
                            addArcAndEndPointToDrawingStatus(
309
                                    geometries, 
310
                                    centerPointValue, 
311
                                    centerPointValue.distance(mousePosition), 
312
                                    GeometryUtils.calculateAngle(centerPointValue, mousePosition), 
313
                                    mousePosition, 
314
                                    sweepAngleValue, 
315
                                    directionValue);
316
                        }
317
                    } catch (CreateGeometryException | GeometryOperationException | GeometryOperationNotSupportedException ex) {
318
                        throw new DrawServiceException(ex);
319
                    }
320
                    return geometries;
321
                } else if (endPointValue == null) {
322

    
323
                    try {
324
                        Line startLine = GeometryUtils.createLine(
325
                                centerPointValue.getX(),
326
                                centerPointValue.getY(),
327
                                startPointValue.getX(),
328
                                startPointValue.getY(), CURVE);
329
                        geometries.addStatus(startPointValue, auxiliaryPointSymbolEditing, "");
330
                        geometries.addStatus(startLine, auxiliaryLineSymbolEditing, "");
331

    
332
                        if (radiusValue == null) {
333
                            radiusValue = centerPointValue.distance(startPointValue);
334
                        }
335

    
336
                        if (startAngleValue == null) {
337
                            startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue);
338
                        }
339

    
340

    
341
                        double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, mousePosition);
342
                        if (sweepAngleValue != null) {
343
                            if (directionValue == null) {
344

    
345
                                Point auxPoint;
346
                                auxPoint = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
347

    
348
                                geometries.addStatus(auxPoint, auxiliaryPointSymbolEditing, "");
349

    
350
                                if(Math.signum(coefDirection)!= Math.signum(sweepAngleValue)){
351
                                    sweepAngleValue = -(2*Math.PI-sweepAngleValue);
352
                                }
353

    
354
                                Arc auxArc = GeometryUtils.createArc(
355
                                        centerPointValue,
356
                                        radiusValue,
357
                                        startAngleValue,
358
                                        sweepAngleValue,
359
                                        GEOM2D);
360

    
361
                                geometries.addStatus(auxArc, lineSymbolEditing, "");
362
                                geometries.addStatus(auxArc, previewSymbol, "");
363
                                return geometries;
364
                            } 
365
                        } else {  //sweepAngleValue == null
366

    
367
                            double distance = centerPointValue.distance(mousePosition);
368
                            Point point = GeometryUtils.createPoint(
369
                                    centerPointValue.getX() + radiusValue * ((mousePosition.getX() - centerPointValue.getX()) / distance),
370
                                    centerPointValue.getY() + radiusValue * ((mousePosition.getY() - centerPointValue.getY()) / distance)
371
                            );
372
                            geometries.addStatus(point, auxiliaryPointSymbolEditing, "");
373
                            Line auxLine = GeometryUtils.createLine(centerPointValue, point, CURVE);
374
                            geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
375

    
376
                            //calculate sweepAngle
377
                            sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, mousePosition);
378

    
379
                            if(directionValue != null){
380
                                if(directionValue.equalsIgnoreCase(CW)){
381
                                    sweepAngleValue = -(2*Math.PI-sweepAngleValue);
382
                                }
383
                            } else if(coefDirection<0) {
384
                                sweepAngleValue = -(2*Math.PI-sweepAngleValue);
385
                            }
386

    
387
                            if(Math.abs(sweepAngleValue) > 0d){
388
                                Arc auxArc = GeometryUtils.createArc(
389
                                        centerPointValue,
390
                                        radiusValue,
391
                                        startAngleValue,
392
                                        sweepAngleValue,
393
                                        GEOM2D);
394

    
395
                                geometries.addStatus(auxArc, lineSymbolEditing, "");
396
                                geometries.addStatus(auxArc, previewSymbol, "");
397
                            }
398
                            return geometries;
399

    
400
                        }
401
                    } catch (CreateGeometryException | GeometryOperationNotSupportedException | GeometryOperationException ex) {
402
                        throw new DrawServiceException(ex);
403
                    }
404

    
405
                }
406
            }
407

    
408
        }
409

    
410
        return null;
411
    }
412

    
413
    private void addArcAndEndPointToDrawingStatus(DefaultDrawingStatus geometries, Point centerValue, Double radiusValue, Double startAngleValue, Point startPointValue, Double sweepAngleValue,  String directionValue) throws GeometryOperationException, GeometryOperationNotSupportedException, CreateGeometryException {
414
        
415
        if (sweepAngleValue != null && directionValue != null) {
416
            EditingProviderManager editingProviderManager
417
                    = EditingProviderLocator.getProviderManager();
418
            ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
419
            ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
420
            ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
421

    
422
            Point auxEndPoint;
423
            auxEndPoint = calculateEndPoint(centerValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
424

    
425
            geometries.addStatus(auxEndPoint, auxiliaryPointSymbolEditing, "");
426

    
427
            double coefDirection = GeometryUtils.getCoefDirection(centerValue, startPointValue, auxEndPoint);
428

    
429
            if (Math.signum(coefDirection) != Math.signum(sweepAngleValue)) {
430
                sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
431
            }
432

    
433
            if (directionValue.equalsIgnoreCase(CW)) {
434
                sweepAngleValue = -(2 * Math.PI - sweepAngleValue);
435
            }
436

    
437
            Arc auxArc = GeometryUtils.createArc(centerValue,
438
                    radiusValue,
439
                    startAngleValue,
440
                    sweepAngleValue,
441
                    GEOM2D);
442

    
443
            geometries.addStatus(auxArc, lineSymbolEditing, "");
444
            geometries.addStatus(auxArc, geometries.getPreviewSymbol(), "");
445
        }
446
    }
447
    
448
    @Override
449
    public void stop() throws StopServiceException {
450
        values.clear();
451
    }
452

    
453
    @Override
454
    public List<EditingServiceParameter> getParameters() {
455
        List<EditingServiceParameter> parameters
456
                = new ArrayList<>();
457

    
458

    
459
        parameters.add(centerPoint);
460
        parameters.add(startPoint);
461
        parameters.add(endPoint);
462

    
463
        parameters.add(radius);
464
        parameters.add(startAngle);
465
        parameters.add(sweepAngle);
466
        parameters.add(direction);
467

    
468
        return parameters;
469
    }
470

    
471
    @Override
472
    public void setValue(Object value) throws InvalidEntryException {
473
        EditingServiceParameter param = next();
474
        setValue(param, value);
475
    }
476

    
477
    @Override
478
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
479
        validateAndInsertValue(parameter, value);
480
        removeRelatedParams(parameter);
481
        fillEmptyParams();
482
    }
483
    
484
    private void removeRelatedParams(EditingServiceParameter parameter) {
485
        
486
        if (parameter == startAngle) {
487
            values.remove(startPoint);
488
            return;
489
        }
490

    
491
        if (parameter == radius) {
492
            values.remove(startPoint);
493
            return;
494
        }
495
        
496
        if( parameter == sweepAngle) {
497
            values.remove(endPoint);
498
        }
499

    
500
        if( parameter == direction) {
501
            values.remove(endPoint);
502
        }
503
        
504
    }
505
    
506
    private void fillEmptyParams() throws InvalidEntryException{
507
        Point centerPointValue = (Point) values.get(centerPoint);
508
        Point startPointValue = (Point) values.get(startPoint);
509
        Point endPointValue = (Point) values.get(endPoint);
510
        
511
        Double radiusValue = (Double) values.get(radius);
512
        Double startAngleValue = (Double) values.get(startAngle);
513
        Double sweepAngleValue = (Double) values.get(sweepAngle);
514
        String directionValue = (String) values.get(direction);
515

    
516
        if( startPointValue == null && centerPointValue != null && radiusValue != null && startAngleValue != null){
517
            startPointValue = GeometryUtils.createPoint(centerPointValue, radiusValue, startAngleValue);
518
            values.put(startPoint, startPointValue);
519
        }
520
        
521
        if(radiusValue == null && centerPointValue != null && startPointValue != null){
522
            try {
523
                radiusValue = centerPointValue.distance(startPointValue);
524
                values.put(radius, radiusValue);
525
            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
526
                throw new InvalidEntryException(ex);
527
            }
528
        }
529

    
530
        if(startAngleValue == null && centerPointValue != null && startPointValue != null){
531
            startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue);
532
            values.put(startAngle, startAngleValue);
533
        }
534
        
535
        if(sweepAngleValue == null && startPointValue != null && endPointValue != null){
536
            sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue);
537
            values.put(sweepAngle, sweepAngleValue);
538
        }
539
        
540
        if(endPointValue == null && centerPointValue != null && startPointValue != null && sweepAngleValue != null && directionValue != null){
541
            try {
542
                endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
543
                values.put(endPoint, endPointValue);
544
            } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
545
                throw new InvalidEntryException(ex);
546
            }
547
        }
548
        
549
        if(sweepAngleValue == null && centerPointValue != null && startPointValue != null && endPointValue != null){
550
            sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue);
551
            values.put(sweepAngle, sweepAngleValue);
552
        }
553
    }
554

    
555
    private void validateAndInsertValue(EditingServiceParameter param,
556
            Object value) throws InvalidEntryException {
557
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
558
        CoerceToDouble coerceToDouble = new CoerceToDouble();
559
        if (param == centerPoint) {
560
            if (value instanceof Point) {
561
                values.put(param, value);
562
                return;
563
            }
564
        } else if (param == startPoint) {
565
            if (value instanceof Point) {
566
                Point pointValue = (Point) value;
567

    
568
                Point centerPointValue = (Point) (values.get(centerPoint));
569
                Double radiusValue = (Double) (values.get(radius));
570
                Double startAngleValue = (Double) (values.get(startAngle));
571
                if (radiusValue != null) {
572
                    try {
573
                        double distance = centerPointValue.distance(pointValue);
574
                        Point point = GeometryUtils.createPoint(
575
                                centerPointValue.getX() + radiusValue * ((pointValue.getX() - centerPointValue.getX()) / distance),
576
                                centerPointValue.getY() + radiusValue * ((pointValue.getY() - centerPointValue.getY()) / distance)
577
                        );
578
                        values.put(param, point);
579
                        return;
580
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
581
                        throw new InvalidEntryException(ex);
582
                    }
583
                } else if (startAngleValue != null) {
584
                    double m = Math.tan(startAngleValue);
585
                    double anglePointValue = GeometryUtils.calculateAngle(centerPointValue, pointValue);
586
                    Point point;
587
                    double x = centerPointValue.getX();
588
                    double y = centerPointValue.getY();
589
                    if (Double.isInfinite(m)) {
590
                        point = GeometryUtils.createPoint(
591
                                centerPointValue.getX(), pointValue.getY());
592
                    } else if (m==0) {
593
                        point = GeometryUtils.createPoint(
594
                                pointValue.getX(), centerPointValue.getY());
595
                    } else {
596
                        if(Math.signum(Math.cos(startAngleValue)) == Math.signum(Math.cos(anglePointValue))){
597
                            x = pointValue.getX();
598
                        }
599

    
600
                        if(Math.signum(Math.sin(startAngleValue)) == Math.signum(Math.sin(anglePointValue))){
601
                            y = pointValue.getY();
602
                        }
603

    
604
                        EuclideanLine2D auxLine = euclideanManager.createLine2D(
605
                                m,
606
                                euclideanManager.getYIntercept(
607
                                        m,
608
                                        centerPointValue.getX(),
609
                                        centerPointValue.getY()
610
                                )
611
                        );
612
                        Point2D proyected = auxLine.getNearestPoint(x, y);
613
                        point = GeometryUtils.createPoint(proyected.getX(), proyected.getY());
614

    
615
                    }
616
                    values.put(param, point);
617
                    return;
618

    
619
                } else {
620
                    values.put(param, pointValue);
621

    
622
                }
623

    
624
                values.put(param, value);
625
                return;
626
            }
627

    
628
        } else if (param == endPoint) {
629
            if (value instanceof Point) {
630

    
631
                Point pointValue = (Point) value;
632
                Double sweepAngleValue = (Double) values.get(sweepAngle);
633
                String directionValue = (String) values.get(direction);
634
                Point centerPointValue = (Point) values.get(centerPoint);
635
                Point startPointValue = (Point) values.get(startPoint);
636
                Double radiusValue = (Double) values.get(radius);
637
                Double startAngleValue = (Double) (values.get(startAngle));
638
                if(startPointValue == null){
639
                    if (radiusValue != null && startAngleValue != null) {
640
                        startPointValue = GeometryUtils.createPoint(
641
                                centerPointValue.getX() + radiusValue * Math.cos(startAngleValue),
642
                                centerPointValue.getY() + radiusValue * Math.sin(startAngleValue)
643
                        );
644
                    }
645
                }
646

    
647
                Point endPointValue;
648
                if (sweepAngleValue != null) {
649

    
650
                        if (directionValue == null) {
651
                            
652
                            double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, pointValue);
653
                            if(coefDirection>=0){
654
                                values.put(direction, CCW);
655
                            } else {
656
                                values.put(direction, CW);
657
                            }
658
                        }
659
                    try {
660
                            endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue);
661
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
662
                        throw new InvalidEntryException(ex);
663
                    }
664
                } else {
665
                    if (radiusValue == null) {
666
                        try {
667
                            radiusValue = centerPointValue.distance(startPointValue);
668
                        } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
669
                            throw new InvalidEntryException(ex);
670
                        }
671
                    }
672
                    
673
                
674
                    double module;
675
                    try {
676
                        module = centerPointValue.distance(pointValue);
677
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
678
                        throw new InvalidEntryException(ex);
679
                    }
680
                    
681
                    endPointValue = GeometryUtils.createPoint(
682
                            centerPointValue.getX()+radiusValue*(pointValue.getX()-centerPointValue.getX())/module,
683
                            centerPointValue.getY()+radiusValue*(pointValue.getY()-centerPointValue.getY())/module
684
                            );
685
                }
686
                values.put(endPoint, endPointValue);
687
                return;
688
            }
689
        } else if (param == radius) {
690
            try {
691
                Double doubleValue = (Double) coerceToDouble.coerce(value);
692
                // To avoid infinite, Nan and very small values
693
                if (doubleValue != null && Double.isFinite(doubleValue) && (doubleValue - 0.01) > 0) {
694
                    values.put(param, doubleValue);
695
                    return;
696
                }
697
            } catch (CoercionException ex) {
698
                throw new InvalidEntryException(null);
699
            }
700
        } else if (param == startAngle) {
701
            try {
702
                Double doubleValue = (Double) coerceToDouble.coerce(value);
703
                if (doubleValue != null && Double.isFinite(doubleValue)) {
704
                    values.put(param, Math.toRadians(doubleValue));
705
                    return;
706
                }
707
            } catch (CoercionException ex) {
708
                throw new InvalidEntryException(ex);
709
            }
710
        } else if (param == sweepAngle) {
711
            try {
712
                Double doubleValue = (Double) coerceToDouble.coerce(value);
713
                if (doubleValue != null && Double.isFinite(doubleValue)) {
714
                    values.put(param, Math.toRadians(doubleValue));
715
                    return;
716
                }
717
            } catch (CoercionException ex) {
718
                throw new InvalidEntryException(null);
719
            }
720
        } else if (param == direction) {
721
            if (value instanceof String) {
722
                if (((String) value).trim().equalsIgnoreCase(CCW)) {
723
                    values.put(param, CCW);
724
                    return;
725
                } else if (((String) value).trim().equalsIgnoreCase(CW)) {
726
                    values.put(param, CW);
727
                    return;
728
                }
729
            }
730
        }
731
        throw new InvalidEntryException(null);
732
    }
733

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

    
736
        Point endPointValue = (Point) values.get(endPoint);
737
        if (endPointValue != null) {
738
            return endPointValue;
739
        }
740

    
741
        if (startPointValue == null || centerPointValue == null || sweepAngleValue == null) {
742
            return null;
743
        }
744
        if (startAngleValue == null) {
745
            startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue);
746
        }
747

    
748
        if (radiusValue == null) {
749
            radiusValue = centerPointValue.distance(startPointValue);
750
        }
751

    
752
        double endAngle;
753
        endAngle = startAngleValue + sweepAngleValue;
754

    
755
        endPointValue = GeometryUtils.createPoint(
756
                centerPointValue.getX() + radiusValue * Math.cos(endAngle),
757
                centerPointValue.getY() + radiusValue * Math.sin(endAngle)
758
        );
759

    
760
        return endPointValue;
761
    }
762

    
763
    @Override
764
    public Geometry finish() throws FinishServiceException {
765
        //FIXME
766
        Point centerPointValue = (Point) values.get(centerPoint);
767
        Point startPointValue = (Point) values.get(startPoint);
768
        Point endPointValue = (Point) values.get(endPoint);
769

    
770
        Double radiusValue = (Double) values.get(radius);
771
        Double startAngleValue = (Double) values.get(startAngle);
772
        Double sweepAngleValue = (Double) values.get(sweepAngle);
773
        String directionValue = (String) values.get(direction);
774

    
775
        EditingProviderServices editingProviderServices
776
                = (EditingProviderServices) getProviderServices();
777

    
778
        EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager();
779

    
780
        try {
781

    
782
            int subtype
783
                    = editingProviderServices.getSubType(featureStore);
784

    
785
            if (radiusValue == null) {
786
                radiusValue = centerPointValue.distance(startPointValue);
787
            }
788

    
789
            Curve arc = null;
790
            double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, endPointValue);
791
            if (sweepAngleValue != null) {
792
                if (directionValue != null) {
793
                    if(directionValue.equalsIgnoreCase(CCW)){
794
                        if(sweepAngleValue >= 0){
795
                            //Do nothing
796
                        } else {
797
                            sweepAngleValue = -(2*Math.PI-sweepAngleValue);
798
                        }
799
                    } else {
800
                        if(sweepAngleValue <= 0){
801
                            //Do nothing
802
                        } else {
803
                            sweepAngleValue = -(2*Math.PI-sweepAngleValue); //coefDirection * sweepAngleValue;
804
                        }
805
                    }
806
                } else if(Math.signum(coefDirection)!= Math.signum(sweepAngleValue)){
807
                    sweepAngleValue = -(2*Math.PI-sweepAngleValue);
808
                }
809

    
810
                arc = GeometryUtils.createArc(
811
                        centerPointValue,
812
                        radiusValue,
813
                        startAngleValue,
814
                        sweepAngleValue,
815
                        GEOM2D);
816
            } else {  //sweepAngleValue == null
817

    
818
                double distance = centerPointValue.distance(endPointValue);
819
                Point point = GeometryUtils.createPoint(
820
                        centerPointValue.getX() + radiusValue * ((endPointValue.getX() - centerPointValue.getX()) / distance),
821
                        centerPointValue.getY() + radiusValue * ((endPointValue.getY() - centerPointValue.getY()) / distance)
822
                );
823

    
824
                //calculate sweepAngle
825
                sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue);
826

    
827
                if(directionValue != null){
828
                    if(directionValue.equalsIgnoreCase(CW)){
829
                        sweepAngleValue = -(2*Math.PI-sweepAngleValue);
830
                    }
831
                } else if(coefDirection<0) {
832
                    sweepAngleValue = -(2*Math.PI-sweepAngleValue);
833
                }
834

    
835
                if(Math.abs(sweepAngleValue) > 0d){
836
                    arc = GeometryUtils.createArc(
837
                            centerPointValue,
838
                            radiusValue,
839
                            startAngleValue,
840
                            sweepAngleValue,
841
                            GEOM2D);
842
                }
843
            }
844

    
845

    
846
            GeometryType geomType
847
                    = editingProviderServices.getGeomType(featureStore);
848

    
849
            if (geomType.isTypeOf(MULTICURVE)) {
850

    
851
                MultiCurve multiCurve;
852
                multiCurve
853
                        = GeometryLocator.getGeometryManager().createMultiCurve(
854
                                geomType.getSubType());
855
                multiCurve.addCurve(arc);
856
                return multiCurve;
857
            }
858

    
859
            return arc;
860
        } catch (Exception e) {
861
            throw new FinishServiceException(e);
862
        }
863
    }
864
    
865
    @Override
866
    public void finishAndStore() throws FinishServiceException {
867
        Geometry geometry = finish();
868
        EditingProviderServices editingProviderServices
869
                = (EditingProviderServices) getProviderServices();
870
        editingProviderServices.insertGeometryIntoFeatureStore(geometry,
871
                featureStore);
872
    }
873

    
874
    @Override
875
    public void start() throws StartServiceException {
876
        values = new HashMap<>();
877
    }
878

    
879
    @Override
880
    public String getName() {
881
        return ArcByCenterEditingProviderFactory.PROVIDER_NAME;
882
    }
883

    
884
    @Override
885
    public boolean isEnabled(EditingServiceParameter parameter) {
886

    
887
        if (parameter == radius) {
888
            if (values.get(startPoint) != null) {
889
                return false;
890
            }
891
        } else if (parameter == startAngle) {
892
            if (values.get(startPoint) != null) {
893
                return false;
894
            }
895
        } else if (parameter == sweepAngle) {
896
            if (values.get(endPoint) != null) {
897
                return false;
898
            }
899
        } else if (parameter == direction) {
900
            if (values.get(endPoint) != null) {
901
                return false;
902
            }
903
        }
904
        return true;
905
    }
906

    
907
    @Override
908
    public Object getValue(EditingServiceParameter parameter) {
909
        return values!=null?values.get(parameter):null;
910
    }
911

    
912
}