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

History | View | Annotate | Download (20.4 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.Font;
29
import java.awt.geom.AffineTransform;
30
import java.util.ArrayList;
31
import java.util.HashMap;
32
import java.util.List;
33
import java.util.Map;
34

    
35
import net.sf.antcontrib.net.httpclient.GetMethodTask;
36

    
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.feature.EditableFeature;
39
import org.gvsig.fmap.dal.feature.Feature;
40
import org.gvsig.fmap.dal.feature.FeatureSelection;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.geom.Geometry;
43
import org.gvsig.fmap.geom.GeometryLocator;
44
import org.gvsig.fmap.geom.GeometryManager;
45
import org.gvsig.fmap.geom.exception.CreateGeometryException;
46
import org.gvsig.fmap.geom.operation.GeometryOperationException;
47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Line;
49
import org.gvsig.fmap.geom.primitive.Point;
50
import org.gvsig.fmap.mapcontext.MapContext;
51
import org.gvsig.fmap.mapcontext.ViewPort;
52
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
53
import org.gvsig.symbology.SymbologyLocator;
54
import org.gvsig.symbology.SymbologyManager;
55
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
56
import org.gvsig.tools.ToolsLocator;
57
import org.gvsig.tools.dynobject.DynObject;
58
import org.gvsig.tools.exception.BaseException;
59
import org.gvsig.tools.i18n.I18nManager;
60
import org.gvsig.tools.service.spi.ProviderServices;
61
import org.gvsig.tools.visitor.VisitCanceledException;
62
import org.gvsig.tools.visitor.Visitor;
63
import org.gvsig.vectorediting.lib.api.DrawingStatus;
64
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
65
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
66
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
67
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
69
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
70
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
71
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
72
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
73
import org.gvsig.vectorediting.lib.spi.EditingProvider;
74
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
78

    
79
public class ScaleEditingProvider extends AbstractEditingProvider implements
80
    EditingProvider {
81

    
82
    private I18nManager i18nManager = ToolsLocator.getI18nManager();
83

    
84
    private EditingServiceParameter selectionParameter;
85

    
86
    private EditingServiceParameter originPointParameter;
87

    
88
    private EditingServiceParameter scaleFactorOrReferencePointParameter;
89

    
90
    private EditingServiceParameter secondScalePointParameter;
91

    
92
    private Map<EditingServiceParameter, Object> values;
93

    
94
    private FeatureStore featureStore;
95

    
96
    private MapContext mapContext;
97

    
98
    public ScaleEditingProvider(ProviderServices providerServices,
99
        DynObject parameters) {
100
        super(providerServices);
101
        this.mapContext =
102
            (MapContext) parameters
103
                .getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD);
104

    
105
        this.featureStore =
106
            (FeatureStore) parameters
107
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
108

    
109
        this.selectionParameter =
110
            new DefaultEditingServiceParameter("selection",
111
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
112

    
113
        this.originPointParameter =
114
            new DefaultEditingServiceParameter("origin_point",
115
                i18nManager.getTranslation("origin_point"), TYPE.VALUE, TYPE.POSITION);
116

    
117
        this.scaleFactorOrReferencePointParameter =
118
            new DefaultEditingServiceParameter("scale_factor_or_reference_point",
119
                i18nManager.getTranslation("scale_factor_or_reference_point"), TYPE.VALUE, TYPE.POSITION);
120

    
121
        this.secondScalePointParameter =
122
            new DefaultEditingServiceParameter("second_scale_point",
123
                i18nManager.getTranslation("second_scale_point"), TYPE.POSITION);
124
    }
125

    
126
    public List<EditingServiceParameter> getParameters() {
127
        List<EditingServiceParameter> list =
128
            new ArrayList<EditingServiceParameter>();
129
        list.add(selectionParameter);
130
        list.add(originPointParameter);
131
        list.add(secondScalePointParameter);
132
        return list;
133
    }
134

    
135
    private void validateAndInsertValue(EditingServiceParameter param,
136
        Object value) throws InvalidEntryException {
137
        if (param == selectionParameter) {
138
            if (value instanceof FeatureSelection) {
139
                values.put(param, value);
140
                return;
141
            }
142
        } else if (param == originPointParameter) {
143
            if (value instanceof Point) {
144
                values.put(param, value);
145
                return;
146
            }
147
        } else if (param == scaleFactorOrReferencePointParameter) {
148
            if (value instanceof Point) {
149
                if (((Point) value).getX() == ((Point)values.get(originPointParameter)).getX()){
150
                    throw new InvalidEntryException(null);
151
                }
152
                values.put(param, value);
153
                return;
154
            } else if (value instanceof Double) {
155
                if ((Double)value == 0.0){
156
                    throw new InvalidEntryException(null);
157
                }
158
                values.put(param, value);
159
                return;
160
            }
161
        } else if (param == secondScalePointParameter) {
162
            if (value instanceof Point) {
163
                values.put(param, value);
164
                return;
165
            }
166
        }
167
    }
168

    
169
    public EditingServiceParameter next() {
170
        if (values.get(selectionParameter) == null) {
171
            return this.selectionParameter;
172
        } else if (values.get(originPointParameter) == null) {
173
            return this.originPointParameter;
174
        } else if (values.get(scaleFactorOrReferencePointParameter) == null) {
175
            return this.scaleFactorOrReferencePointParameter;
176
        } else {
177
            if (values.get(scaleFactorOrReferencePointParameter) instanceof Point ) {
178
                if (values.get(secondScalePointParameter) == null) {
179
                    return this.secondScalePointParameter;
180
                }
181
            }
182
        }
183
        return null;
184
    }
185

    
186

    
187
    public DrawingStatus getDrawingStatus(Point mousePosition)
188
        throws DrawServiceException {
189
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
190
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
191

    
192
        EditingProviderManager editingProviderManager =
193
            EditingProviderLocator.getProviderManager();
194
        ISymbol ruleMarkerSymbol = editingProviderManager.getSymbol("rule-marker-symbol");
195
        ViewPort vp = this.mapContext.getViewPort();
196

    
197

    
198
        EditingProviderServices editingProviderServices =
199
            (EditingProviderServices) getProviderServices();
200

    
201
        FeatureSelection selected =
202
            (FeatureSelection) values.get(this.selectionParameter);
203
        try {
204
            int subType =
205
                editingProviderServices
206
                .getSubType(featureStore);
207
            if ((selected != null) && !selected.isEmpty()) {
208
                Point origin = (Point) values.get(this.originPointParameter);
209
                if (origin != null) {
210
                    Object scaleFactorOrReferencePointValue =
211
                        values.get(this.scaleFactorOrReferencePointParameter);
212
                    Double scale = 1.0;
213

    
214
                    if (scaleFactorOrReferencePointValue != null) {
215
                        if (scaleFactorOrReferencePointValue instanceof Double) {
216
                            scale = (Double) scaleFactorOrReferencePointValue;
217
                        } else if (scaleFactorOrReferencePointValue instanceof Point) {
218
                            double unity = ((Point) scaleFactorOrReferencePointValue).getX()-origin.getX();
219
                            // Unidad de referencia
220
                            createRule(drawingStatus, origin, unity, unity, subType); //+(Math.signum(unity)*0.01), subType);
221

    
222
                            Object secondScalePointParameter =
223
                                values.get(this.secondScalePointParameter);
224
                            if (secondScalePointParameter != null
225
                                && secondScalePointParameter instanceof Point) {
226
                                double rawScale = ((Point) secondScalePointParameter).getX()-origin.getX();
227
                                scale = rawScale / unity;
228
                                createRule(drawingStatus, origin, unity, rawScale, subType);
229

    
230
                                Point marker = null;
231
                                marker = geometryManager.createPoint(origin.getX()+rawScale,origin.getY(), subType);
232
                                drawingStatus.addStatus(marker, ruleMarkerSymbol, "");
233
                                ISimpleTextSymbol textSymbol = getTextSymbol();
234
                                Point textPoint = geometryManager.createPoint(marker.getX()-vp.toMapDistance(10), marker.getY()-vp.toMapDistance(20), subType);
235
                                drawingStatus.addStatus(textPoint, textSymbol, String.valueOf(Math.round(scale*100.0)/100.0));
236

    
237
                            } else {
238
                                double rawScale = mousePosition.getX()-origin.getX();
239
                                scale = rawScale / unity;
240
                                createRule(drawingStatus, origin, unity, rawScale, subType);
241

    
242
                                Point marker = null;
243
                                marker = geometryManager.createPoint(origin.getX()+rawScale,origin.getY(), subType);
244
                                drawingStatus.addStatus(marker, ruleMarkerSymbol, "");
245
                                ISimpleTextSymbol textSymbol = getTextSymbol();
246
                                Point textPoint = geometryManager.createPoint(marker.getX()-vp.toMapDistance(10), marker.getY()-vp.toMapDistance(20), subType);
247
                                drawingStatus.addStatus(textPoint, textSymbol, String.valueOf(Math.round(scale*100.0)/100.0));
248

    
249
                                AffineTransform at;
250
                                try {
251
                                    at = getScaleAffineTransform(origin, scale);
252
                                } catch (Exception e) {
253
                                    throw new DrawServiceException(e);
254
                                }
255
                                applyTransformToDrawingStatus(drawingStatus, selected, at);
256
                            }
257
                        }
258
                    } else {
259
                        double unity = mousePosition.getX()-origin.getX();
260
                        createRule(drawingStatus, origin, unity, unity, subType); //+(Math.signum(unity)*0.01), subType);
261

    
262
                    }
263

    
264
                }
265
                return drawingStatus;
266
            }
267
        } catch (Exception e) {
268
            throw new DrawServiceException(e);
269
        }
270
        return null;
271
    }
272

    
273
    private Line createHorizontalLineFromAPointWithLenght(Point origin,
274
        double length, int subType) throws CreateGeometryException {
275
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
276

    
277
        Line line = geometryManager.createLine(subType);
278
        line.addVertex(origin);
279
        Point p3 =
280
            geometryManager.createPoint(origin.getX() + length,
281
                origin.getY(), subType);
282
        line.addVertex(p3);
283
        return line;
284
    }
285

    
286
    private ISimpleTextSymbol getTextSymbol(){
287
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
288
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
289
        textSymbol.setFontSize(10);
290
        return textSymbol;
291
    }
292

    
293
    private void createRule(DefaultDrawingStatus drawingStatus, Point point, double unity, double length, int subType) throws CreateGeometryException {
294
        if(unity==0.0 || length==0.0){
295
            return;
296
        }
297
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
298
        EditingProviderManager editingProviderManager =
299
            EditingProviderLocator.getProviderManager();
300
        ISymbol ruleUnitySymbol = editingProviderManager.getSymbol("rule-unity-symbol");
301
        ISymbol ruleDecimalSymbol = editingProviderManager.getSymbol("rule-decimal-symbol");
302
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
303

    
304
        ViewPort vp = this.mapContext.getViewPort();
305

    
306
        Line line =
307
            createHorizontalLineFromAPointWithLenght(point, length, subType);
308
        drawingStatus.addStatus(line, ruleAxisSymbol, "");
309

    
310
        double pos = 0.0;
311
        int i = 0;
312
        // Se le a?ade 0.01 del length a la condici?n de parada del bucle para evitar
313
        // que por problemas de precisi?n de los n?meros en punto flotante
314
        // no se termine de dibujar la regla
315
        while (Math.abs(pos)<=Math.abs(length)*1.01) {
316
            Point mark = null;
317
            mark = geometryManager.createPoint(point.getX()+pos,point.getY(), subType);
318
            if (i%10==0){
319
                drawingStatus.addStatus(mark, ruleUnitySymbol, "");
320
                ISimpleTextSymbol textSymbol = getTextSymbol();
321
                Point textPoint = geometryManager.createPoint(mark.getX()-vp.toMapDistance(3), mark.getY()-vp.toMapDistance(10), subType);
322
                drawingStatus.addStatus(textPoint, textSymbol, String.valueOf(((int)Math.signum(length*unity))*i/10));
323

    
324
            } else {
325
                drawingStatus.addStatus(mark, ruleDecimalSymbol, "");
326
            }
327
            pos += Math.signum(length)*Math.signum(unity)*unity/10;
328
            i++;
329
        }
330
    }
331

    
332

    
333

    
334
    private void applyTransformToDrawingStatus(
335
        final DefaultDrawingStatus geometries, FeatureSelection selected,
336
        final AffineTransform at) throws BaseException {
337
        selected.accept(new Visitor() {
338

    
339
            public void visit(Object obj) throws VisitCanceledException,
340
                BaseException {
341
                Feature feature = (Feature) obj;
342
                Geometry geom = feature.getDefaultGeometry().cloneGeometry();
343
                geom.transform(at);
344
                geometries.addGeometry(geom);
345

    
346
            }
347
        });
348
    }
349

    
350
    private AffineTransform getScaleAffineTransform(Point axisP1, Double scale)
351
        throws GeometryOperationNotSupportedException,
352
        GeometryOperationException {
353

    
354
        AffineTransform translate =
355
            AffineTransform
356
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
357

    
358
        AffineTransform scaleTransform = AffineTransform.getScaleInstance(scale,scale);
359

    
360
        AffineTransform inverseTranslate =
361
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
362
        AffineTransform at = new AffineTransform(translate);
363

    
364
        at.preConcatenate(scaleTransform);
365
        at.preConcatenate(inverseTranslate);
366
        return at;
367
    }
368

    
369

    
370
    public void stop() {
371
        values.clear();
372
    }
373

    
374

    
375

    
376
    public void setValue(Object value) throws InvalidEntryException {
377
        EditingServiceParameter param = next();
378
        validateAndInsertValue(param, value);
379
    }
380

    
381
    public void finishAndStore() throws FinishServiceException {
382

    
383
        FeatureSelection selected =
384
            (FeatureSelection) values.get(selectionParameter);
385
        try {
386
            if (!selected.isEmpty()) {
387
                Point origin = (Point) values.get(this.originPointParameter);
388
                Double scale = null;
389
                if (origin != null) {
390
                    Object scaleFactorOrReferencePointValue =
391
                        values.get(this.scaleFactorOrReferencePointParameter);
392

    
393
                    if (scaleFactorOrReferencePointValue != null) {
394
                        if (scaleFactorOrReferencePointValue instanceof Double) {
395
                            scale = (Double) scaleFactorOrReferencePointValue;
396
                        } else if (scaleFactorOrReferencePointValue instanceof Point) {
397
                            Object secondScalePointParameter =
398
                                values.get(this.secondScalePointParameter);
399
                            if (secondScalePointParameter != null
400
                                && secondScalePointParameter instanceof Point) {
401
                                double unity = ((Point) scaleFactorOrReferencePointValue).getX()-origin.getX();
402
                                double rawScale = ((Point) secondScalePointParameter).getX()-origin.getX();
403
                                scale = rawScale / unity;
404
                            }
405
                        }
406
                    }
407
                }
408

    
409
                if ((origin != null) && (scale != null)) {
410

    
411
                    final AffineTransform at;
412
                    try {
413
                        at = getScaleAffineTransform(origin, scale);
414
                    } catch (GeometryOperationNotSupportedException e) {
415
                        throw new FinishServiceException(e);
416
                    } catch (GeometryOperationException e) {
417
                        throw new FinishServiceException(e);
418
                    }
419

    
420
                    try {
421
                        selected.accept(new Visitor() {
422

    
423
                            public void visit(Object obj)
424
                                throws VisitCanceledException, BaseException {
425
                                Feature feature = (Feature) obj;
426
                                Geometry geom =
427
                                    feature.getDefaultGeometry()
428
                                        .cloneGeometry();
429
                                geom.transform(at);
430
                                // Se sustituye la geometr?a original por la
431
                                // calculada
432
                                EditableFeature editableFeature =
433
                                    feature.getEditable();
434
                                editableFeature.setDefaultGeometry(geom);
435
                                ((EditingProviderServices) getProviderServices())
436
                                    .updateFeatureInFeatureStore(
437
                                        editableFeature, featureStore);
438
                            }
439
                        });
440
                    } catch (BaseException e) {
441
                        throw new FinishServiceException(e);
442
                    }
443
                    featureStore.getFeatureSelection().deselectAll();
444
                }
445
            }
446
        } catch (DataException e) {
447
            throw new FinishServiceException(e);
448
        }
449
    }
450

    
451
    public Geometry finish() throws FinishServiceException {
452
        return null;
453
    }
454

    
455
    public void start() throws StartServiceException {
456
        this.values = new HashMap<EditingServiceParameter, Object>();
457
        FeatureSelection selected = null;
458
        if (featureStore != null) {
459
            try {
460
                selected =
461
                    (FeatureSelection) featureStore.getFeatureSelection()
462
                        .clone();
463
            } catch (DataException e) {
464
                throw new StartServiceException(e);
465
            } catch (CloneNotSupportedException e) {
466
                // Do nothing
467
            }
468
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
469
                values.put(selectionParameter, selected);
470
            }
471
        }
472
    }
473

    
474
    public String getName() {
475
        return ScaleEditingProviderFactory.PROVIDER_NAME;
476
    }
477

    
478
}