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.duplicate / src / main / java / org / gvsig / vectorediting / lib / prov / duplicate / MeasureEditingProvider.java @ 2870

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

    
26
import java.awt.geom.AffineTransform;
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Map;
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureSelection;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.GeometryLocator;
41
import org.gvsig.fmap.geom.GeometryManager;
42
import org.gvsig.fmap.geom.GeometryUtils;
43
import org.gvsig.fmap.geom.aggregate.Aggregate;
44
import org.gvsig.fmap.geom.aggregate.MultiCurve;
45
import org.gvsig.fmap.geom.aggregate.MultiLine;
46
import org.gvsig.fmap.geom.aggregate.MultiPoint;
47
import org.gvsig.fmap.geom.aggregate.MultiSurface;
48
import org.gvsig.fmap.geom.exception.CreateGeometryException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationException;
50
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
51
import org.gvsig.fmap.geom.primitive.Curve;
52
import org.gvsig.fmap.geom.primitive.Line;
53
import org.gvsig.fmap.geom.primitive.Point;
54
import org.gvsig.fmap.geom.primitive.Surface;
55
import org.gvsig.fmap.mapcontext.MapContext;
56
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dataTypes.DataTypes;
59
import org.gvsig.tools.dispose.DisposableIterator;
60
import org.gvsig.tools.dispose.DisposeUtils;
61
import org.gvsig.tools.dynobject.DynObject;
62
import org.gvsig.tools.exception.BaseException;
63
import org.gvsig.tools.i18n.I18nManager;
64
import org.gvsig.tools.service.spi.ProviderServices;
65
import org.gvsig.vectorediting.lib.api.DrawingStatus;
66
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
67
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
68
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
69
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
70
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
71
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
72
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
73
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
74
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
75
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
76
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
77
import org.gvsig.vectorediting.lib.spi.EditingProvider;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
80
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
81
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
82

    
83
/**
84
 * @author fdiaz
85
 *
86
 */
87
public class MeasureEditingProvider extends AbstractEditingProvider implements
88
        EditingProvider {
89

    
90
    protected final EditingServiceParameter selection;
91

    
92
    protected final EditingServiceParameter insertionPointParameter;
93

    
94
    protected final EditingServiceParameter geometryBaseParameter;
95

    
96
    private final EditingServiceParameter measureParameter;
97

    
98
    protected final EditingServiceParameter alignParameter;
99

    
100
    protected final EditingServiceParameter rotateFieldParameter;
101

    
102
    protected final EditingServiceParameter deleteOriginalGeometriesParameter;
103

    
104
    protected final FeatureStore featureStore;
105

    
106
    protected final MapContext mapContext;
107

    
108
    protected Map<EditingServiceParameter, Object> values;
109

    
110
    /**
111
     * Default constructor.
112
     *
113
     * @param services available services for this provider
114
     * @param parameters of this provider
115
     */
116
    public MeasureEditingProvider(DynObject parameters,
117
            ProviderServices services) {
118
        super(services);
119

    
120
        I18nManager i18nManager = ToolsLocator.getI18nManager();
121

    
122
        EditingProviderServices editingProviderServices
123
                = (EditingProviderServices) getProviderServices();
124

    
125
        this.featureStore
126
                = (FeatureStore) parameters
127
                        .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
128

    
129
        this.mapContext
130
                = (MapContext) parameters
131
                        .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
132

    
133
        this.selection
134
                = new DefaultEditingServiceParameter("selection", "selection",
135
                        TYPE.SELECTION);
136

    
137
        this.insertionPointParameter
138
                = new DefaultEditingServiceParameter("_insertion_point", "_insertion_point",
139
                        TYPE.POSITION);
140

    
141
        this.geometryBaseParameter
142
                = new DefaultEditingServiceParameter("_geometry_base", "_geometry_base",
143
                        TYPE.POSITION);
144

    
145
        this.measureParameter
146
                = new DefaultEditingServiceParameter("_measure",
147
                        "_measure", EditingServiceParameter.TYPE.VALUE).setDataType(DataTypes.DOUBLE);;
148

    
149
        DefaultEditingServiceParameterOptions alignOptions2 = new DefaultEditingServiceParameterOptions()
150
                .add("_align", true, i18nManager.getTranslation("_yes"))
151
                .add("_dont_align", false, i18nManager.getTranslation("_no"));
152

    
153
        String alignConsoleMsg
154
                = editingProviderServices.makeConsoleMessage(
155
                        "_align", alignOptions2);
156

    
157
        this.alignParameter
158
                = new DefaultEditingServiceParameter(
159
                        "_align",
160
                        alignConsoleMsg,
161
                        alignOptions2,
162
                        i18nManager.getTranslation("_no"),
163
                        true,
164
                        TYPE.OPTION
165
                ).setDataType(DataTypes.BOOLEAN);
166

    
167
        DefaultEditingServiceParameterOptions rotateFieldOptions2 = new DefaultEditingServiceParameterOptions();
168
        Iterable<FeatureAttributeDescriptor> attrs = featureStore.getDefaultFeatureTypeQuietly().getAllAttributeDescriptors();
169
        for (FeatureAttributeDescriptor attr : attrs) {
170
            if(attr.getDataType().isNumeric()) {
171
                rotateFieldOptions2.add(attr.getLabel(), attr.getName(), attr.getShortLabel());
172
            }
173
        }
174

    
175
        this.rotateFieldParameter
176
                = new DefaultEditingServiceParameter(
177
                        "_rotate_field",
178
                        "_rotate_field",
179
                        rotateFieldOptions2,
180
                        null,
181
                        TYPE.OPTION);
182

    
183

    
184
        DefaultEditingServiceParameterOptions deleteOriginalGeometriesOptions2 = new DefaultEditingServiceParameterOptions()
185
                .add("delete_original_geometries", true, i18nManager.getTranslation("_yes"))
186
                .add("keep_original_geometries", false, i18nManager.getTranslation("_no"));
187

    
188
        String consoleMsg
189
                = editingProviderServices.makeConsoleMessage(
190
                        "delete_original_geometries_question", deleteOriginalGeometriesOptions2);
191

    
192
        this.deleteOriginalGeometriesParameter
193
                = new DefaultEditingServiceParameter(
194
                        i18nManager.getTranslation("delete_original_geometries"),
195
                        consoleMsg,
196
                        deleteOriginalGeometriesOptions2,
197
                        false,
198
                        TYPE.OPTION).setDataType(DataTypes.BOOLEAN);;
199

    
200
    }
201

    
202
    @Override
203
    public EditingServiceParameter next() {
204
        if (values.get(selection) == null) {
205
            return selection;
206
        } else if (values.get(insertionPointParameter) == null) {
207
            return insertionPointParameter;
208
        } else if (values.get(geometryBaseParameter) == null) {
209
            return geometryBaseParameter;
210
        } else if (values.get(measureParameter) == null) {
211
            return measureParameter;
212
        } else if (values.get(alignParameter) == null) {
213
            return alignParameter;
214
        } else if ((boolean) (values.get(alignParameter)) == true && isPointType() && values.get(rotateFieldParameter) == null) {
215
            return rotateFieldParameter;
216
        } else if (values.get(deleteOriginalGeometriesParameter) == null) {
217
            return deleteOriginalGeometriesParameter;
218
        }
219
        return null;
220
    }
221

    
222
    protected boolean isPointType() {
223
        return featureStore.getDefaultFeatureTypeQuietly().getDefaultGeometryAttribute().getGeomType().getType() == Geometry.TYPES.POINT;
224
    }
225

    
226
    @Override
227
    public DrawingStatus getDrawingStatus(Point mousePosition)
228
            throws DrawServiceException {
229

    
230
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
231

    
232
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
233
        EditingProviderManager editingProviderManager
234
                = EditingProviderLocator.getProviderManager();
235
        EditingProviderServices editingProviderServices
236
                = (EditingProviderServices) getProviderServices();
237
        int subtype;
238
        try {
239
            subtype = editingProviderServices.getSubType(featureStore);
240
        } catch (DataException e2) {
241
            throw new DrawServiceException(e2);
242
        }
243
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
244
        ISymbol auxiliarylineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
245
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
246
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
247

    
248
        if (values != null) {
249

    
250
            FeatureSelection featureSelection
251
                    = (FeatureSelection) values.get(selection);
252
            Point insertionPointValue = (Point) values.get(insertionPointParameter);
253

    
254
            if (featureSelection != null && insertionPointValue != null) {
255
                drawingStatus.addStatus(insertionPointValue, auxiliaryPointSymbolEditing, "");
256
                Line auxLine;
257
                try {
258
                    auxLine = geometryManager.createLine(subtype);
259
                } catch (CreateGeometryException e1) {
260
                    throw new DrawServiceException(e1);
261
                }
262

    
263
                MultiLine geometryBaseValue = (MultiLine) values.get(geometryBaseParameter);
264
                if (geometryBaseValue != null) {
265
                    for (Geometry geometry : geometryBaseValue) {
266
                        Line line = (Line) geometry;
267
                        List<PointAndRotation> pointsAndRotation;
268
                        try {
269
                            pointsAndRotation = getPointsAndRotations(line);
270
                        } catch (Exception ex) {
271
                            throw new DrawServiceException(ex);
272
                        }
273
                        if (pointsAndRotation != null) {
274
                            for (PointAndRotation pointAndRotation : pointsAndRotation) {
275
                                DisposableIterator it = null;
276
                                try {
277
                                    it = featureSelection.fastIterator();
278
                                    while (it.hasNext()) {
279
                                        Feature feature = (Feature) it.next();
280
                                        ISymbol previewSymbol = this.getPreviewSymbol(feature);
281

    
282
                                        Geometry geom
283
                                                = feature.getDefaultGeometry().cloneGeometry();
284

    
285
                                        AffineTransform at
286
                                                = getMoveAffineTransform(insertionPointValue,
287
                                                        pointAndRotation.getPoint());
288
                                        geom.transform(at);
289

    
290
                                        Boolean alignValue = (Boolean) values.get(alignParameter);
291
                                        if (alignValue != null && alignValue.equals(Boolean.TRUE)) {
292
                                            AffineTransform rotateTransform = getRotateAffineTransform(pointAndRotation.getPoint(), pointAndRotation.getAngle()); //pointAndRotation.getAngle()-Math.PI/2);
293
                                            geom.transform(rotateTransform);
294
                                        }
295

    
296
                                        ISymbol symbol = null;
297
                                        if (geom instanceof Curve || geom instanceof MultiCurve) {
298
                                            symbol = lineSymbolEditing;
299
                                        } else if (geom instanceof Surface || geom instanceof MultiSurface) {
300
                                            symbol = polygonSymbolEditing;
301
                                        } else if (geom instanceof Point || geom instanceof MultiPoint) {
302
                                            symbol = auxiliaryPointSymbolEditing;
303
                                        }
304
                                        if (geom instanceof Aggregate) {
305
                                            int primitivesNumber = ((Aggregate) geometry).getPrimitivesNumber();
306
                                            for (int i = 0; i < primitivesNumber; i++) {
307
                                                drawingStatus.addStatus(((Aggregate) geom).getPrimitiveAt(i), symbol, "");
308
                                                drawingStatus.addStatus(((Aggregate) geom).getPrimitiveAt(i), previewSymbol, "");
309
                                            }
310
                                        } else {
311
                                            drawingStatus.addStatus(geom, symbol, "");
312
                                            drawingStatus.addStatus(geom, previewSymbol, "");
313
                                        }
314
                                    }
315
                                } catch (BaseException e) {
316
                                    throw new DrawServiceException(e);
317
                                } finally {
318
                                    DisposeUtils.disposeQuietly(it);
319
                                }
320
                            }
321
                        }
322
                    }
323
                }
324

    
325
            }
326
        }
327
        return drawingStatus;
328
    }
329

    
330
    private AffineTransform getMoveAffineTransform(Point p1, Point p2)
331
            throws GeometryOperationNotSupportedException,
332
            GeometryOperationException {
333

    
334
        AffineTransform translate
335
                = AffineTransform.getTranslateInstance(p2.getX() - p1.getX(),
336
                        p2.getY() - p1.getY());
337

    
338
        return translate;
339
    }
340

    
341
    private AffineTransform getRotateAffineTransform(Point p, double angle)
342
            throws GeometryOperationNotSupportedException,
343
            GeometryOperationException {
344

    
345
        AffineTransform rotate
346
                = AffineTransform.getRotateInstance(angle, p.getX(), p.getY());
347

    
348
        return rotate;
349
    }
350

    
351
    @Override
352
    public void stop() throws StopServiceException {
353
        if (values != null) {
354
            values.clear();
355
        }
356
    }
357

    
358
    @Override
359
    public List<EditingServiceParameter> getParameters() {
360
        List<EditingServiceParameter> parameters
361
                = new ArrayList<>();
362
        parameters.add(selection);
363
        parameters.add(insertionPointParameter);
364
        parameters.add(geometryBaseParameter);
365
        parameters.add(measureParameter);
366
        parameters.add(alignParameter);
367
        parameters.add(rotateFieldParameter);
368
        parameters.add(deleteOriginalGeometriesParameter);
369
        return parameters;
370
    }
371

    
372
    @Override
373
    public boolean isEnabled(EditingServiceParameter parameter) {
374
        return true;
375
    }
376

    
377
    @Override
378
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
379
        validateAndInsertValue(parameter, value);
380
    }
381

    
382
    @Override
383
    public void setValue(Object value) throws InvalidEntryException {
384
        EditingServiceParameter parameter = next();
385
        validateAndInsertValue(parameter, value);
386
    }
387

    
388
    protected void validateAndInsertValue(EditingServiceParameter parameter,
389
            Object value) throws InvalidEntryException {
390

    
391
        if (parameter == selection) {
392
            if (value instanceof FeatureSelection) {
393
                if (((FeatureSelection) value).getSelectedCount() > 0) {
394
                    values.put(selection, value);
395
                }
396
            }
397
        } else if (parameter == insertionPointParameter) {
398
            if (value instanceof Point) {
399
                values.put(parameter, value);
400
            }
401

    
402
        } else if (parameter == geometryBaseParameter && value instanceof Point) {
403

    
404
            if (value instanceof Point) {
405
                Point point = (Point) value;
406

    
407
                Geometry geometry = getGeometry(point); //editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
408
                if (geometry != null) {
409
                    try {
410
                        if (geometry instanceof Curve
411
                                || geometry instanceof MultiCurve
412
                                || geometry instanceof Surface
413
                                || geometry instanceof MultiSurface) {
414
                            values.put(parameter, geometry.toLines());
415
                        } else {
416
                            throw new InvalidEntryException(null);
417
                        }
418
                    } catch (Exception ex) {
419
                        throw new InvalidEntryException(ex);
420
                    }
421
                    return;
422
                }
423

    
424
            }
425
        } else if (parameter.equals(measureParameter)) {
426
            if (value instanceof Double) {
427
                values.put(parameter, value);
428
            } else {
429
                throw new InvalidEntryException(null);
430
            }
431
        } else if (parameter == rotateFieldParameter) {
432
            values.put(parameter, parameter.getOptions2().getValue(value, parameter.getDefaultValue()));
433
        } else if (parameter == alignParameter) {
434
            values.put(parameter, parameter.getOptions2().getValue(value, parameter.getDefaultValue()));
435
        } else if (parameter == deleteOriginalGeometriesParameter) {
436
            values.put(parameter, parameter.getOptions2().getValue(value, parameter.getDefaultValue()));
437
        }
438

    
439
    }
440

    
441
    private Geometry getGeometry(Point point) {
442
        EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices();
443
        Geometry geometry = editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext);
444
        return geometry;
445
    }
446

    
447
    @Override
448
    public Geometry finish() throws FinishServiceException {
449
        return null;
450
    }
451

    
452
    @Override
453
    public void finishAndStore() throws FinishServiceException {
454
        if (values != null) {
455

    
456
            final Point insertionPointValue = (Point) values.get(insertionPointParameter);
457
            final MultiLine geometryBaseValue = (MultiLine) values.get(geometryBaseParameter);
458
//            final Double measureValue = (Double) values.get(measureParameter);
459
            final Boolean alignValue = (Boolean) values.get(alignParameter);
460
            final String rotateFieldValue = (String) values.get(rotateFieldParameter);
461
            final Boolean deleteOriginalGeometriesValue = (Boolean) values.get(deleteOriginalGeometriesParameter);
462

    
463
            FeatureSelection featureSelection
464
                    = (FeatureSelection) values.get(selection);
465
            ToolsLocator.getDisposableManager().bind(featureSelection);
466

    
467
            try {
468

    
469
                for (Geometry geometry : geometryBaseValue) {
470
                    Line line = (Line) geometry;
471
                    List<PointAndRotation> pointsAndRotations;
472
                    try {
473
                        pointsAndRotations = getPointsAndRotations(line);
474
                    } catch (Exception ex) {
475
                        throw new DrawServiceException(ex);
476
                    }
477
                    if (pointsAndRotations == null) {
478
                        return;
479
                    }
480
                    for (PointAndRotation pointAndRotation : pointsAndRotations) {
481
                        DisposableIterator it = null;
482

    
483
                        featureSelection.accept((Object obj) -> {
484
                            Feature feature = (Feature) obj;
485

    
486
                            EditingProviderServices editingProviderServices
487
                                    = (EditingProviderServices) getProviderServices();
488

    
489
                            EditableFeature editable
490
                                    = editingProviderServices.getFeatureCopyWithoutUniqueIndex(
491
                                            featureStore, feature);
492

    
493
                            Geometry geom
494
                                    = feature.getDefaultGeometry().cloneGeometry();
495

    
496
                            AffineTransform at
497
                                    = getMoveAffineTransform(insertionPointValue,
498
                                            pointAndRotation.getPoint());
499
                            geom.transform(at);
500

    
501
                            if (alignValue != null && alignValue.equals(Boolean.TRUE)) {
502
                                // We subtract PI/2 because we consider that when a figure is not rotated it points upwards
503
                                AffineTransform rotateTransform = getRotateAffineTransform(pointAndRotation.getPoint(), pointAndRotation.getAngle()); //-Math.PI/2);
504
                                geom.transform(rotateTransform);
505
                                if (rotateFieldValue != null) {
506
                                    FeatureType featType = featureStore.getDefaultFeatureTypeQuietly();
507
                                    if (featType != null) {
508
                                        FeatureAttributeDescriptor attr = featType.getAttributeDescriptor((String) rotateFieldValue);
509
                                        if (attr != null) {
510
                                            // We change the sign of the angle because in the MarkerSymbols the angles go in a clockwise direction
511
                                            editable.set(rotateFieldValue, -(Math.toDegrees(pointAndRotation.getAngle()-Math.PI/2)));
512
                                        }
513
                                    }
514
                                }
515
                            }
516

    
517
                            editable.setDefaultGeometry(geom);
518
                            editingProviderServices.insertFeatureIntoFeatureStore(
519
                                    editable, featureStore);
520
                        });
521
                    }
522
                }
523
                
524
                if(deleteOriginalGeometriesValue) {
525
                    for(Feature feature : featureStore.getFeatureSelection()) {
526
                        featureStore.delete(feature);
527
                    }
528
                }
529

    
530
                featureStore.getFeatureSelection().deselectAll();
531
                featureSelection.dispose();
532

    
533
            } catch (BaseException e) {
534
                throw new FinishServiceException(e);
535
            }
536
        }
537
    }
538

    
539
    @Override
540
    public void start() throws StartServiceException, InvalidEntryException {
541
        values = new HashMap<>();
542
        FeatureSelection selected = null;
543
        if (featureStore != null) {
544
            try {
545
                selected = featureStore.getFeatureSelection();
546
            } catch (DataException e) {
547
                throw new StartServiceException(e);
548
            }
549
            try {
550
                setValue(selected);
551
            } catch (InvalidEntryException e) {
552
                throw new InvalidEntryException(e);
553
            }
554
        }
555
    }
556

    
557
    @Override
558
    public String getName() {
559
        return MeasureEditingProviderFactory.PROVIDER_NAME;
560
    }
561

    
562
    @Override
563
    public Object getValue(EditingServiceParameter parameter) {
564
        return values != null ? values.get(parameter) : null;
565
    }
566

    
567
    protected List<PointAndRotation> getPointsAndRotations(Line line) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException, CloneNotSupportedException {
568
        Double measureValue = (Double) values.get(measureParameter);
569
        if (measureValue == null) {
570
            return null;
571
        }
572
        return MeasureEditingProvider.this.getPointsAndRotations(line, measureValue);
573
    }
574

    
575
    protected List<PointAndRotation> getPointsAndRotations(Line line, double measure) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException, CloneNotSupportedException {
576

    
577
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
578
        List<PointAndRotation> res = new ArrayList<>();
579

    
580
        if (line.getNumVertices() <= 1) {
581
            return res;
582
        }
583

    
584
        Point previousPoint = null;
585
        double previousLength = 0;
586
        // Insertamos el primer punto solo si la linea es cerrada
587
        if(line.isClosed()){
588
            Point v0 = line.getVertex(0);
589
            int i = 1;
590
            Point v1 = line.getVertex(1);
591
            // Este bucle es para evitar un problema con geometr?as que lleguen con puntos repetidos al inicio
592
//            while (v0.equals(v1) && line.getNumVertices() > i+1 ){
593
//                v1 = line.getVertex(i++);
594
//            }
595
            
596
            PointAndRotation rotatedPoint = new PointAndRotation(
597
                    line.getVertex(0),
598
                    GeometryUtils.calculateAngle(v0, v1)
599
            );
600
            res.add(rotatedPoint);
601
        }
602

    
603
        boolean advanceToNext = true;
604
        Iterator<Point> it = line.iterator();
605
        Point currentPoint = null;
606
        while (it.hasNext() || !advanceToNext) {
607
            if (advanceToNext) {
608
                currentPoint = it.next();
609
            }
610
            if (previousPoint == null) {
611
                previousPoint = currentPoint.clone();
612
                advanceToNext = true;
613
                continue;
614
            }
615
            double distance = previousPoint.distance(currentPoint);
616
            if (previousLength + distance < measure) {
617
                previousLength += distance;
618
                previousPoint = currentPoint.cloneGeometry();
619
                advanceToNext = true;
620
            } else {
621
                //buscar punto dentro del segmento a una distancia = segmentLengthMeters-previousLength
622
                Point point = GeometryUtils.calculateLambdaPoint(previousPoint, currentPoint, (measure - previousLength) / distance);
623
                //agregarlo al currentSegment,
624
                PointAndRotation rotatedPoint = new PointAndRotation(
625
                        point,
626
                        GeometryUtils.calculateAngle(previousPoint, currentPoint)
627
                );
628
                res.add(rotatedPoint);
629
                previousPoint = point.clone();
630
                previousLength = 0;
631
                advanceToNext = false;
632
            }
633
        }
634

    
635
        return res;
636

    
637
    }
638

    
639
    public static class PointAndRotation {
640

    
641
        private Point point;
642
        private double angle;
643

    
644
        public PointAndRotation(Point point, double angle) {
645
            this.point = point;
646
            this.angle = angle;
647
        }
648

    
649
        public void setPoint(Point point) {
650
            this.point = point;
651
        }
652

    
653
        public Point getPoint() {
654
            return point;
655
        }
656

    
657
        public void setAngle(double angle) {
658
            this.angle = angle;
659
        }
660

    
661
        public double getAngle() {
662
            return angle;
663
        }
664

    
665
    }
666

    
667
}