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.scale / src / main / java / org / gvsig / vectorediting / lib / prov / scale / ScaleEditingProvider.java @ 2995

History | View | Annotate | Download (36.3 KB)

1
package org.gvsig.vectorediting.lib.prov.scale;
2
/**
3
 * gvSIG. Desktop Geographic Information System.
4
 *
5
 * Copyright ? 2007-2014 gvSIG Association
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
 * MA  02110-1301, USA.
21
 *
22
 * For any additional information, do not hesitate to contact us
23
 * at info AT gvsig.com, or visit our website www.gvsig.com.
24
 */
25

    
26

    
27

    
28
import java.awt.geom.AffineTransform;
29
import java.text.DecimalFormat;
30
import java.util.ArrayList;
31
import java.util.HashMap;
32
import java.util.List;
33
import java.util.Map;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureSelection;
38
import org.gvsig.fmap.dal.feature.FeatureStore;
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.aggregate.Aggregate;
43
import org.gvsig.fmap.geom.aggregate.MultiCurve;
44
import org.gvsig.fmap.geom.aggregate.MultiPoint;
45
import org.gvsig.fmap.geom.aggregate.MultiSurface;
46
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.operation.GeometryOperationException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
50
import org.gvsig.fmap.geom.primitive.Curve;
51
import org.gvsig.fmap.geom.primitive.Envelope;
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.ViewPort;
57
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
58
import org.gvsig.symbology.SymbologyLocator;
59
import org.gvsig.symbology.SymbologyManager;
60
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
61
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
62
import org.gvsig.tools.ToolsLocator;
63
import org.gvsig.tools.dataTypes.DataTypes;
64
import org.gvsig.tools.dynobject.DynObject;
65
import org.gvsig.tools.exception.BaseException;
66
import org.gvsig.tools.i18n.I18nManager;
67
import org.gvsig.tools.service.spi.ProviderServices;
68
import org.gvsig.vectorediting.lib.api.DrawingStatus;
69
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
70
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
71
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
72
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
73
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
74
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
75
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
76
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
77
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
78
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
79
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions;
80
import org.gvsig.vectorediting.lib.spi.EditingProvider;
81
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
82
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
83
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
84
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
85

    
86
public class ScaleEditingProvider extends AbstractEditingProvider implements
87
    EditingProvider {
88
    
89
    public static final String KEY_ORIGIN_CENTER = "_Key_origin_center";
90

    
91
    public static final String ORIGIN_CENTER = "_Origin_center";
92

    
93
    private static final String PROPORTIONAL_SCALE_QUESTION = "_Proportional_scale_question";
94
    private static final String PROPORTIONAL_SCALE = "_Proportional_scale";
95

    
96
    private static final String YES = "_yes";
97
    private static final String NO = "_no";
98
    private static final String SHORT_YES = "_short_yes";
99
    private static final String SHORT_NO = "_short_no";
100

    
101

    
102
    private final EditingServiceParameter selectionParameter;
103

    
104
    private final EditingServiceParameter proportionalModeParameter;
105
    
106
    private final EditingServiceParameter originPointParameter;
107
    
108
    private String center;
109

    
110
    private final EditingServiceParameter scaleFactorOrReferencePointParameter;
111
    
112
    private final EditingServiceParameter secondScalePointParameter;
113

    
114
    private final EditingServiceParameter verticalScaleFactorParameter;
115

    
116
    private Map<EditingServiceParameter, Object> values;
117

    
118
    private final FeatureStore featureStore;
119

    
120
    private final MapContext mapContext;
121

    
122
    public ScaleEditingProvider(ProviderServices providerServices,
123
        DynObject parameters) {
124
        super(providerServices);
125
        
126

    
127
        this.mapContext =
128
            (MapContext) parameters
129
                .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
130

    
131
        this.featureStore =
132
            (FeatureStore) parameters
133
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
134

    
135
        I18nManager i18nManager = ToolsLocator.getI18nManager();
136

    
137
        this.selectionParameter 
138
                = new DefaultEditingServiceParameter("selection",
139
                        i18nManager.getTranslation("selection"), TYPE.SELECTION);
140

    
141
        DefaultEditingServiceParameterOptions options = new DefaultEditingServiceParameterOptions()
142
                .add(i18nManager.getTranslation(ORIGIN_CENTER), ORIGIN_CENTER, i18nManager.getTranslation(KEY_ORIGIN_CENTER));
143

    
144

    
145
        String consoleMsg
146
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
147
                        "_Origin_point", options);
148

    
149
        this.originPointParameter
150
                = new DefaultEditingServiceParameter(
151
                        "_Origin_point",
152
                        consoleMsg,
153
                        options,
154
                        null,
155
                        TYPE.POSITION, TYPE.OPTION);
156

    
157
        this.scaleFactorOrReferencePointParameter =
158
            new DefaultEditingServiceParameter("_Scale_factor_or_reference_point",
159
                i18nManager.getTranslation("_Horizontal_scale_factor_or_reference_point"), TYPE.VALUE, TYPE.POSITION);
160

    
161
        this.verticalScaleFactorParameter =
162
            new DefaultEditingServiceParameter("_Vertical_scale_factor",
163
                i18nManager.getTranslation("_Vertical_scale_factor"), TYPE.VALUE);
164

    
165
        this.secondScalePointParameter =
166
            new DefaultEditingServiceParameter("_Second_scale_point",
167
                i18nManager.getTranslation("_Second_scale_point"), TYPE.POSITION);
168
        
169
        DefaultEditingServiceParameterOptions proportionalModeOptions=  new DefaultEditingServiceParameterOptions()
170
                .add(YES, true, i18nManager.getTranslation(SHORT_YES))
171
                .add(NO, false, i18nManager.getTranslation(SHORT_NO));
172

    
173
        String proportionalModeConsoleMsg
174
                = ((EditingProviderServices) providerServices).makeConsoleMessage(
175
                        PROPORTIONAL_SCALE_QUESTION, proportionalModeOptions);
176

    
177
        this.proportionalModeParameter
178
                = new DefaultEditingServiceParameter(
179
                        PROPORTIONAL_SCALE,
180
                        proportionalModeConsoleMsg, 
181
                        proportionalModeOptions, 
182
                        true, 
183
                        true, 
184
                        TYPE.OPTION).setDataType(DataTypes.BOOLEAN);
185

    
186
    }
187

    
188
    @Override
189
    public List<EditingServiceParameter> getParameters() {
190
        //FIXME:
191
        List<EditingServiceParameter> list = new ArrayList<>();
192
        list.add(selectionParameter);
193
        list.add(originPointParameter);
194
        list.add(secondScalePointParameter);
195
        list.add(proportionalModeParameter);
196
        list.add(scaleFactorOrReferencePointParameter);
197
        list.add(verticalScaleFactorParameter);
198
        return list;
199
    }
200

    
201
    private void validateAndInsertValue(EditingServiceParameter param,
202
        Object value) throws InvalidEntryException {
203

    
204
        if (param == selectionParameter) {
205
            if (value instanceof FeatureSelection) {
206
                values.put(param, value);
207
            }
208
        } else if (param == originPointParameter) {
209
            if (value == null){
210
                center = null;
211
                values.remove(param);
212
            } else if (value instanceof Point) {
213
                values.put(param, value);
214
                center = null;
215
            } else if (value instanceof String) {
216
                if(ORIGIN_CENTER.equalsIgnoreCase((String) param.getOptions2().getValue(value, param.getDefaultValue()))){
217
                    center = ORIGIN_CENTER;
218
                    GeometryManager geomManager = GeometryLocator.getGeometryManager();
219
                    FeatureSelection selected
220
                            = (FeatureSelection) values.get(this.selectionParameter);
221
                    if ((selected != null) && !selected.isEmpty()) {
222
                        try {
223
                            int subType = this.getProviderServices().getSubType(featureStore);
224
                            Envelope envelope = geomManager.createEnvelope(subType);
225
                            for (Feature feature : selected) {
226
                                Envelope featEnv = feature.getDefaultEnvelope();
227
                                envelope.add(featEnv);
228
                            }
229
                            if(!envelope.isEmpty()){
230
                                Point center = geomManager.createPoint(envelope.getCenter(0), envelope.getCenter(1), subType);
231
                                values.put(param, center);
232
                            }
233
                        } catch (DataException | CreateGeometryException | CreateEnvelopeException ex) {
234
                            throw new InvalidEntryException(ex);
235
                        }
236
                    }
237
                } else {
238
                    center = null;
239
                    values.remove(param);
240
                }
241
            }
242
        } else if (param == scaleFactorOrReferencePointParameter) {
243
            if (value instanceof Point) {
244
                if (((Point) value).equals((Point)values.get(originPointParameter))){
245
                    throw new InvalidEntryException(null);
246
                }
247
                values.put(param, value);
248
            } else if (value instanceof Double) {
249
                if ((Double)value == 0.0){
250
                    throw new InvalidEntryException(null);
251
                }
252
                values.put(param, value);
253
            }
254
        } else if (param == secondScalePointParameter) {
255
            if (value instanceof Point) {
256
                values.put(param, value);
257
            }
258
        } else if (param == proportionalModeParameter) {
259
            boolean proportionalMode = (boolean) param.getOptions2().getValue(value, param.getDefaultValue());
260
             values.put(param, proportionalMode);
261
        } else if (param == verticalScaleFactorParameter) {
262
             if (value instanceof Double) {
263
                if ((Double)value == 0.0){
264
                    throw new InvalidEntryException(null);
265
                }
266
                values.put(param, value);
267
            } else {
268
                throw new InvalidEntryException(null);
269
            }
270
        }
271
    }
272

    
273
    @Override
274
    public EditingServiceParameter next() {
275
        boolean proportionalModeValue = (boolean) values.get(proportionalModeParameter);
276
        if (values.get(selectionParameter) == null) {
277
            return this.selectionParameter;
278
        } else if (values.get(originPointParameter) == null) {
279
            return this.originPointParameter;
280
        } else if (values.get(scaleFactorOrReferencePointParameter) == null) {
281
            I18nManager i18nManager = ToolsLocator.getI18nManager();
282
            if(proportionalModeValue){
283
                this.scaleFactorOrReferencePointParameter.setDescription(i18nManager.getTranslation("_Scale_factor_or_reference_point"));
284
            } else {
285
                this.scaleFactorOrReferencePointParameter.setDescription(i18nManager.getTranslation("_Horizontal_scale_factor_or_reference_point"));
286
            }
287
            return this.scaleFactorOrReferencePointParameter;
288
        } else {
289
            if (values.get(scaleFactorOrReferencePointParameter) instanceof Point ) {
290
                if (values.get(secondScalePointParameter) == null) {
291
                    return this.secondScalePointParameter;
292
                }
293
            } else {
294
                if (!proportionalModeValue && values.get(verticalScaleFactorParameter) == null) {
295
                    return this.verticalScaleFactorParameter;
296
                }
297
            }
298
        }
299
        return null;
300
    }
301

    
302

    
303
    @Override
304
    public DrawingStatus getDrawingStatus(Point mousePosition)
305
        throws DrawServiceException {
306
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
307
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
308

    
309
        EditingProviderManager editingProviderManager =
310
            EditingProviderLocator.getProviderManager();
311
        IMarkerSymbol ruleMarkerSymbol = (IMarkerSymbol) editingProviderManager.getSymbol("rule-marker-symbol");
312
        IMarkerSymbol verticalRuleMarkerSymbol = (IMarkerSymbol) editingProviderManager.getSymbol("vertical-rule-marker-symbol");
313
        
314
        ViewPort vp = this.mapContext.getViewPort();
315
        
316
        DecimalFormat format = new DecimalFormat("0.00");
317

    
318
        
319
        EditingProviderServices editingProviderServices =
320
            (EditingProviderServices) getProviderServices();
321

    
322
        FeatureSelection selected =
323
            (FeatureSelection) values.get(this.selectionParameter);
324
        try {
325
//            IMarkerSymbol verticalRuleMarkerSymbol = (IMarkerSymbol) ruleMarkerSymbol.clone();
326
//            verticalRuleMarkerSymbol.setRotation(Math.PI/2);
327
            int subType =
328
                editingProviderServices
329
                .getSubType(featureStore);
330
            boolean proportional = (boolean) values.get(this.proportionalModeParameter);
331
            if ((selected != null) && !selected.isEmpty()) {
332
                Point origin = (Point) values.get(this.originPointParameter);
333
                if (origin != null) {
334
                    Object scaleFactorOrReferencePointValue =
335
                        values.get(this.scaleFactorOrReferencePointParameter);
336
                    Double horizontalScale = 1.0;
337
                    Double verticalScale = 1.0;
338

    
339
                    if (scaleFactorOrReferencePointValue != null) {
340
                        if (scaleFactorOrReferencePointValue instanceof Double) {
341
                            horizontalScale = (Double) scaleFactorOrReferencePointValue;
342
                            if(proportional){
343
                                verticalScale = horizontalScale;
344
                            }
345
                        } else if (scaleFactorOrReferencePointValue instanceof Point) {
346
                            // Unidades de referencia
347
                            double horizontalUnity = ((Point) scaleFactorOrReferencePointValue).getX()-origin.getX();
348
                            double verticalUnity = ((Point) scaleFactorOrReferencePointValue).getY()-origin.getY();
349
                            createRule(drawingStatus, origin, horizontalUnity, horizontalUnity, false, subType); //+(Math.signum(unity)*0.01), subType);
350
                            if(!proportional){
351
                                createRule(drawingStatus, origin, verticalUnity, verticalUnity, true, subType); //+(Math.signum(unity)*0.01), subType);
352
                            }
353

    
354
                            Object secondScalePointValue =
355
                                values.get(this.secondScalePointParameter);
356
                            if (secondScalePointValue != null && secondScalePointValue instanceof Point) {
357
                                double horizontalRawScale = ((Point) secondScalePointValue).getX()-origin.getX();
358
                                horizontalScale = horizontalRawScale / horizontalUnity;
359
                                createRule(drawingStatus, origin, horizontalUnity, horizontalRawScale, false, subType);
360

    
361
                                Point horizontalMarker = geometryManager.createPoint(origin.getX()+horizontalRawScale,origin.getY(), subType);
362
                                drawingStatus.addStatus(horizontalMarker, ruleMarkerSymbol, "");
363
                                ISimpleTextSymbol textSymbol = getTextSymbol();
364
                                Point horizontalTextPoint = geometryManager.createPoint(
365
                                        horizontalMarker.getX()-vp.toMapDistance(10), 
366
                                        horizontalMarker.getY()-vp.toMapDistance(20), 
367
                                        subType);
368
                                drawingStatus.addStatus(horizontalTextPoint, textSymbol, format.format(Math.round(horizontalScale*100.0)/100.0));
369
                                
370
                                double verticalRawScale;
371
                                if(proportional){
372
                                    verticalScale = horizontalScale;
373
                                    verticalRawScale = horizontalRawScale;
374
                                } else {
375
                                    verticalRawScale = ((Point) secondScalePointValue).getY()-origin.getY();
376
                                    verticalScale = verticalRawScale / verticalUnity;
377
                                    createRule(drawingStatus, origin, verticalUnity, verticalRawScale, true, subType);
378

    
379
                                    Point verticalMarker = geometryManager.createPoint(origin.getX(), origin.getY() + verticalRawScale, subType);
380
                                    drawingStatus.addStatus(verticalMarker, verticalRuleMarkerSymbol, "");
381
                                    Point verticalTextPoint = geometryManager.createPoint(
382
                                            verticalMarker.getX() - vp.toMapDistance(verticalScale<0?40:35),
383
                                            verticalMarker.getY() - vp.toMapDistance(4),
384
                                            subType);
385
                                    drawingStatus.addStatus(verticalTextPoint, textSymbol, format.format(Math.round(verticalScale * 100.0) / 100.0));
386
                                }
387

    
388
                            } else {
389

    
390
                                double horizontalRawScale = mousePosition.getX()-origin.getX();
391
                                horizontalScale = horizontalRawScale / horizontalUnity;
392
                                createRule(drawingStatus, origin, horizontalUnity, horizontalRawScale, false, subType);
393

    
394
                                Point horizontalMarker = geometryManager.createPoint(origin.getX()+horizontalRawScale,origin.getY(), subType);
395
                                drawingStatus.addStatus(horizontalMarker, ruleMarkerSymbol, "");
396
                                ISimpleTextSymbol textSymbol = getTextSymbol();
397
                                Point horizontalTextPoint = geometryManager.createPoint(
398
                                        horizontalMarker.getX() - vp.toMapDistance(10), 
399
                                        horizontalMarker.getY() - vp.toMapDistance(20), 
400
                                        subType);
401
                                drawingStatus.addStatus(horizontalTextPoint, textSymbol, format.format(Math.round(horizontalScale*100.0)/100.0));
402
                                
403
                                double verticalRawScale;
404
                                if(proportional){
405
                                    verticalScale = horizontalScale;
406
                                    verticalRawScale = horizontalRawScale;
407
                                } else {
408
                                    verticalRawScale = ((Point) mousePosition).getY()-origin.getY();
409
                                    verticalScale = verticalRawScale / verticalUnity;
410
                                    createRule(drawingStatus, origin, verticalUnity, verticalRawScale, true, subType);
411

    
412
                                    Point verticalMarker = geometryManager.createPoint(origin.getX(),origin.getY()+verticalRawScale, subType);
413
                                    drawingStatus.addStatus(verticalMarker, verticalRuleMarkerSymbol, "");
414
                                    Point verticalTextPoint = geometryManager.createPoint(
415
                                            verticalMarker.getX() - vp.toMapDistance(verticalScale<0?40:35), 
416
                                            verticalMarker.getY() - vp.toMapDistance(4), 
417
                                            subType);
418
                                    drawingStatus.addStatus(verticalTextPoint, textSymbol, format.format(Math.round(verticalScale*100.0)/100.0));
419
                                }
420

    
421

    
422

    
423
                                AffineTransform at;
424
                                try {
425
                                    at = getScaleAffineTransform(origin, horizontalScale, verticalScale);
426
                                } catch (Exception e) {
427
                                    throw new DrawServiceException(e);
428
                                }
429
                                applyTransformToDrawingStatus(drawingStatus, selected, at);
430
                            }
431
                        }
432
                    } else {
433
                        if(proportional){
434
                            double unity = mousePosition.getX()-origin.getX();
435
                            createRule(drawingStatus, origin, unity, unity, false, subType); //+(Math.signum(unity)*0.01), subType);
436
                        } else {
437
                            double horizontalUnity = mousePosition.getX()-origin.getX();
438
                            createRule(drawingStatus, origin, horizontalUnity, horizontalUnity, false, subType); //+(Math.signum(unity)*0.01), subType);
439
                            double verticalUnity = mousePosition.getY()-origin.getY();
440
                            createRule(drawingStatus, origin, verticalUnity, verticalUnity, true, subType); //+(Math.signum(unity)*0.01), subType);
441
                            
442
                        }
443
                    }
444

    
445
                }
446
                return drawingStatus;
447
            }
448
        } catch (Exception e) {
449
            throw new DrawServiceException(e);
450
        }
451
        return null;
452
    }
453

    
454
    private Line createLineFromAPointWithLenght(Point origin,
455
        double length, int subType, boolean vertical) throws CreateGeometryException {
456
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
457

    
458
        Line line = geometryManager.createLine(subType);
459
        line.addVertex(origin);
460
        Point p3;
461
        if (vertical) {
462
            p3 = geometryManager.createPoint(origin.getX(),
463
                            origin.getY() + length, subType);
464

    
465
        } else {
466
            p3 = geometryManager.createPoint(origin.getX() + length,
467
                            origin.getY(), subType);
468
        }
469
        line.addVertex(p3);
470
        return line;
471
    }
472

    
473
    private ISimpleTextSymbol getTextSymbol(){
474
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
475
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
476
        textSymbol.setFontSize(10);
477
        return textSymbol;
478
    }
479

    
480
    private void createRule(DefaultDrawingStatus drawingStatus, Point point, double unity, double length, boolean vertical, int subType) throws CreateGeometryException {
481
        if(unity==0.0 || length==0.0){
482
            return;
483
        }
484
        
485
        EditingProviderManager editingProviderManager = EditingProviderLocator.getProviderManager();
486

    
487
        ISymbol ruleUnitySymbol;
488
        ISymbol ruleDecimalSymbol;
489

    
490
        if (vertical) {
491
            ruleUnitySymbol = (IMarkerSymbol) editingProviderManager.getSymbol("vertical-rule-unity-symbol");
492
            ruleDecimalSymbol = (IMarkerSymbol) editingProviderManager.getSymbol("vertical-rule-decimal-symbol");
493

    
494
        } else {
495
            ruleUnitySymbol = (IMarkerSymbol) editingProviderManager.getSymbol("rule-unity-symbol");
496
            ruleDecimalSymbol = (IMarkerSymbol) editingProviderManager.getSymbol("rule-decimal-symbol");
497
        }
498

    
499
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
500

    
501
        
502
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
503

    
504
        ViewPort vp = this.mapContext.getViewPort();
505

    
506
        Line line =
507
            createLineFromAPointWithLenght(point, length, subType, vertical);
508
        drawingStatus.addStatus(line, ruleAxisSymbol, "");
509

    
510
        double pos = 0.0;
511
        int i = 0;
512
        // Se le a?ade 0.01 del length a la condici?n de parada del bucle para evitar
513
        // que por problemas de precisi?n de los n?meros en punto flotante
514
        // no se termine de dibujar la regla
515
        while (Math.abs(pos)<=Math.abs(length)*1.01) {
516
            Point mark;
517
            if(vertical){
518
                mark = geometryManager.createPoint(point.getX(),point.getY()+pos, subType);
519
            } else {
520
                mark = geometryManager.createPoint(point.getX()+pos,point.getY(), subType);
521
            }
522
            if (i%10==0){
523
                drawingStatus.addStatus(mark, ruleUnitySymbol, "");
524
                ISimpleTextSymbol textSymbol = getTextSymbol();
525
                Point textPoint;
526
                if(vertical) {
527
                    textPoint = geometryManager.createPoint(
528
                            mark.getX()-vp.toMapDistance(pos<0?15:10), 
529
                            mark.getY()-vp.toMapDistance(3), 
530
                            subType);
531
                } else {
532
                    textPoint = geometryManager.createPoint(
533
                            mark.getX()-vp.toMapDistance(3), 
534
                            mark.getY()-vp.toMapDistance(10), 
535
                            subType);
536
                }
537
                drawingStatus.addStatus(textPoint, textSymbol, String.valueOf(((int)Math.signum(length*unity))*i/10));
538

    
539
            } else {
540
                drawingStatus.addStatus(mark, ruleDecimalSymbol, "");
541
            }
542
            pos += Math.signum(length)*Math.signum(unity)*unity/10;
543
            i++;
544
        }
545
    }
546

    
547
    private void applyTransformToDrawingStatus(
548
        final DefaultDrawingStatus drawingStatus, FeatureSelection selected,
549
        final AffineTransform at) throws BaseException {
550

    
551
        EditingProviderManager editingProviderManager =
552
            EditingProviderLocator.getProviderManager();
553

    
554
        final ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
555
        final ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
556
        final ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
557

    
558
        selected.accept((Object obj) -> {
559
            Feature feature = (Feature) obj;
560
            
561
            ISymbol previewSymbol = getPreviewSymbol(feature);
562
            
563
            Geometry transformedGeometry = feature.getDefaultGeometry().cloneGeometry();
564
            transformedGeometry.transform(at);
565
            
566
            ISymbol symbol=null;
567
            if(transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve){
568
                symbol = lineSymbolEditing;
569
            } else if(transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface){
570
                symbol = polygonSymbolEditing;
571
            } else if(transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint){
572
                symbol = auxiliaryPointSymbolEditing;
573
            }
574
            if(transformedGeometry instanceof Aggregate){
575
                int primitivesNumber = ((Aggregate)transformedGeometry).getPrimitivesNumber();
576
                for (int i = 0; i < primitivesNumber; i++) {
577
                    drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), symbol, "");
578
                    drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), previewSymbol, "");
579
                }
580
            } else {
581
                drawingStatus.addStatus(transformedGeometry, symbol, "");
582
                drawingStatus.addStatus(transformedGeometry, previewSymbol, "");
583
            }
584
        });
585
    }
586

    
587
    private AffineTransform getScaleAffineTransform(Point axisP1, Double horizontalScale, Double verticalScale)
588
        throws GeometryOperationNotSupportedException,
589
        GeometryOperationException {
590

    
591
        AffineTransform translate =
592
            AffineTransform
593
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
594

    
595
        AffineTransform scaleTransform = AffineTransform.getScaleInstance(horizontalScale,verticalScale);
596

    
597
        AffineTransform inverseTranslate =
598
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
599
        AffineTransform at = new AffineTransform(translate);
600

    
601
        at.preConcatenate(scaleTransform);
602
        at.preConcatenate(inverseTranslate);
603
        return at;
604
    }
605

    
606

    
607
    @Override
608
    public void stop() {
609
        values.clear();
610
    }
611

    
612

    
613

    
614
    @Override
615
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
616
        validateAndInsertValue(parameter, value);
617
    }
618

    
619
    @Override
620
    public void setValue(Object value) throws InvalidEntryException {
621
        EditingServiceParameter param = next();
622
        validateAndInsertValue(param, value);
623
    }
624

    
625
    @Override
626
    public void finishAndStore() throws FinishServiceException {
627

    
628
        FeatureSelection selected =
629
            (FeatureSelection) values.get(selectionParameter);
630
        try {
631
            if (!selected.isEmpty()) {
632
                Point origin = (Point) values.get(this.originPointParameter);
633
                Double horizontalScale = null;
634
                Double verticalScale = null;
635
                boolean proportionalMode = (boolean) values.get(proportionalModeParameter);
636
                if (origin != null) {
637
                    Object horizontalScaleFactorOrReferencePointValue =
638
                        values.get(this.scaleFactorOrReferencePointParameter);
639

    
640
                    if (horizontalScaleFactorOrReferencePointValue != null) {
641
                        if (horizontalScaleFactorOrReferencePointValue instanceof Double) {
642
                            horizontalScale = (Double) horizontalScaleFactorOrReferencePointValue;
643
                            if(proportionalMode){
644
                                verticalScale = horizontalScale;
645
                            } else {
646
                                Object verticalScaleFactorValue =
647
                                    values.get(this.verticalScaleFactorParameter);
648
                                if(verticalScaleFactorValue != null && verticalScaleFactorValue instanceof Double){
649
                                    verticalScale = (Double) verticalScaleFactorValue;
650
                                }
651
                            }
652
                        } else if (horizontalScaleFactorOrReferencePointValue instanceof Point) {
653
                            Object secondScalePointValue = values.get(this.secondScalePointParameter);
654
                            if (secondScalePointValue != null && secondScalePointValue instanceof Point) {
655
                                double horizontalUnity = ((Point) horizontalScaleFactorOrReferencePointValue).getX() - origin.getX();
656
                                double horizontalRawScale = ((Point) secondScalePointValue).getX() - origin.getX();
657
                                horizontalScale = horizontalRawScale / horizontalUnity;
658
                                if(proportionalMode) {
659
                                    verticalScale = horizontalScale;
660
                                } else {
661
                                    double verticalUnity = ((Point) horizontalScaleFactorOrReferencePointValue).getY() - origin.getY();
662
                                    double verticalRawScale = ((Point) secondScalePointValue).getY() - origin.getY();
663
                                    verticalScale = verticalRawScale / verticalUnity;
664
                                }
665
                            }
666
                        }
667
                    }
668
                }
669

    
670
                if ((origin != null) && (horizontalScale != null) && (verticalScale != null)) {
671

    
672
                    final AffineTransform at;
673
                    try {
674
                        at = getScaleAffineTransform(origin, horizontalScale, verticalScale);
675
                    } catch (GeometryOperationNotSupportedException | GeometryOperationException e) {
676
                        throw new FinishServiceException(e);
677
                    }
678

    
679
                    try {
680
                        selected.accept((Object obj) -> {
681
                            Feature feature = (Feature) obj;
682
                            Geometry geom =
683
                                    feature.getDefaultGeometry()
684
                                            .cloneGeometry();
685
                            geom.transform(at);
686
                            // Se sustituye la geometr?a original por la
687
                            // calculada
688
                            EditableFeature editableFeature =
689
                                    feature.getEditable();
690
                            editableFeature.setDefaultGeometry(geom);
691
                            ((EditingProviderServices) getProviderServices())
692
                                    .updateFeatureInFeatureStore(
693
                                            editableFeature, featureStore);
694
                        });
695
                    } catch (BaseException e) {
696
                        throw new FinishServiceException(e);
697
                    }
698
                    featureStore.getFeatureSelection().deselectAll();
699
                }
700
            }
701
        } catch (DataException e) {
702
            throw new FinishServiceException(e);
703
        }
704
    }
705

    
706
    @Override
707
    public Geometry finish() throws FinishServiceException {
708
        return null;
709
    }
710

    
711
    @Override
712
    public void start() throws StartServiceException {
713
        this.values = new HashMap<>();
714
        FeatureSelection selected = null;
715
        if (featureStore != null) {
716
            try {
717
                selected =
718
                    (FeatureSelection) featureStore.getFeatureSelection()
719
                        .clone();
720
            } catch (DataException e) {
721
                throw new StartServiceException(e);
722
            } catch (CloneNotSupportedException e) {
723
                // Do nothing
724
            }
725
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
726
                values.put(selectionParameter, selected);
727
            }
728
        }
729
    }
730

    
731
    @Override
732
    public String getName() {
733
        return ScaleEditingProviderFactory.PROVIDER_NAME;
734
    }
735

    
736
    @Override
737
    public Object getValue(EditingServiceParameter parameter) {
738
        return values!=null?values.get(parameter):null;
739
    }
740
    
741
    public Object getValue(EditingServiceParameter parameter, EditingServiceParameter.TYPE type) {
742
        if(values == null){
743
            return null;
744
        }
745
        if(parameter == scaleFactorOrReferencePointParameter){
746
            Object value = values.get(parameter);
747
            if (type == TYPE.VALUE) {
748
                if (value instanceof Double) {
749
                    return value;
750
                } else {
751
                    return null;
752
                }
753
            }
754
        } else if(parameter == originPointParameter){
755
            if (type == TYPE.OPTION) {
756
                return center;
757
            }
758
        }
759
        return values!=null?values.get(parameter):null;
760
    }
761

    
762
    
763
    @Override
764
    public boolean isEnabled(EditingServiceParameter parameter) {
765

    
766
        if (parameter == this.proportionalModeParameter) {
767
            return true;
768
        }
769
        return true;
770
    }
771

    
772
    @Override
773
    public void restart() throws StartServiceException, InvalidEntryException, StopServiceException {
774
        values.put(selectionParameter, null);
775
        values.put(originPointParameter, null);
776
        values.put(scaleFactorOrReferencePointParameter, null);
777
        values.put(secondScalePointParameter, null);
778
        values.put(verticalScaleFactorParameter, null);
779
    }
780
    
781
    
782

    
783
}