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.polarmatrix / src / main / java / org / gvsig / vectorediting / lib / prov / polarmatrix / PolarMatrixEditingProvider.java @ 364

History | View | Annotate | Download (21.6 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 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

    
25
package org.gvsig.vectorediting.lib.prov.polarmatrix;
26

    
27
import java.awt.geom.AffineTransform;
28
import java.util.ArrayList;
29
import java.util.HashMap;
30
import java.util.LinkedHashMap;
31
import java.util.List;
32
import java.util.Map;
33

    
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.operation.GeometryOperationException;
47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Arc;
49
import org.gvsig.fmap.geom.primitive.Curve;
50
import org.gvsig.fmap.geom.primitive.Line;
51
import org.gvsig.fmap.geom.primitive.Point;
52
import org.gvsig.fmap.geom.primitive.Surface;
53
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
54
import org.gvsig.symbology.SymbologyLocator;
55
import org.gvsig.symbology.SymbologyManager;
56
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dispose.DisposableIterator;
59
import org.gvsig.tools.dynobject.DynObject;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.i18n.I18nManager;
62
import org.gvsig.tools.service.spi.ProviderServices;
63
import org.gvsig.tools.visitor.VisitCanceledException;
64
import org.gvsig.tools.visitor.Visitor;
65
import org.gvsig.vectorediting.lib.api.DrawingStatus;
66
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
67
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
69
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
70
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
71
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
72
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
73
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
74
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
75
import org.gvsig.vectorediting.lib.spi.EditingProvider;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
79
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
80

    
81
/**
82
 * @author llmarques
83
 *
84
 */
85
public class PolarMatrixEditingProvider extends AbstractEditingProvider
86
    implements EditingProvider {
87

    
88
    private FeatureStore featureStore;
89

    
90
    private Map<EditingServiceParameter, Object> values;
91

    
92
    private EditingServiceParameter selection;
93

    
94
    private EditingServiceParameter elementsNumber;
95

    
96
    private EditingServiceParameter centerPoint;
97

    
98
    private EditingServiceParameter elementAngle;
99

    
100
    private EditingServiceParameter rotateElements;
101

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

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

    
118
        this.selection =
119
            new DefaultEditingServiceParameter("selection", "selection",
120
                EditingServiceParameter.TYPE.SELECTION);
121

    
122
        this.elementsNumber =
123
            new DefaultEditingServiceParameter("number_of_total_elements",
124
                "number_of_total_elements", EditingServiceParameter.TYPE.VALUE);
125

    
126
        I18nManager i18nManager = ToolsLocator.getI18nManager();
127
        Map<String, String> options = new LinkedHashMap<String, String>();
128
        options.put(i18nManager.getTranslation("key_yes"), "yes");
129
        options.put(i18nManager.getTranslation("key_no"), "no");
130

    
131
        EditingProviderServices editingProviderServices =
132
            (EditingProviderServices) getProviderServices();
133

    
134
        this.rotateElements =
135
            new DefaultEditingServiceParameter("rotate_elements",
136
                editingProviderServices.makeConsoleMessage("rotate_elements",
137
                    options), options, EditingServiceParameter.TYPE.OPTION);
138

    
139
        this.centerPoint =
140
            new DefaultEditingServiceParameter("center", "center",
141
                EditingServiceParameter.TYPE.POSITION);
142

    
143
        this.elementAngle =
144
            new DefaultEditingServiceParameter("angle_between_elements",
145
                "angle_between_elements", EditingServiceParameter.TYPE.VALUE,
146
                EditingServiceParameter.TYPE.POSITION);
147
    }
148

    
149
    public EditingServiceParameter next() {
150
        if (values.get(selection) == null) {
151
            return selection;
152
        } else if (values.get(elementsNumber) == null) {
153
            return elementsNumber;
154
        } else if (values.get(rotateElements) == null) {
155
            return rotateElements;
156
        } else if (values.get(centerPoint) == null) {
157
            return centerPoint;
158
        } else if (values.get(elementAngle) == null) {
159
            return elementAngle;
160
        }
161
        return null;
162
    }
163

    
164
    public DrawingStatus getDrawingStatus(Point mousePosition)
165
        throws DrawServiceException {
166

    
167
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
168
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
169
        EditingProviderServices editingProviderServices =
170
            (EditingProviderServices) getProviderServices();
171

    
172
        FeatureSelection featureSelection =
173
            (FeatureSelection) values.get(selection);
174
        Integer elementsNumberValue = (Integer) values.get(elementsNumber);
175
        Boolean rotateElementsValue = (Boolean) values.get(rotateElements);
176
        Point centerPointValue = (Point) values.get(centerPoint);
177

    
178
        if (featureSelection != null && elementsNumberValue != null
179
            && rotateElementsValue != null && centerPointValue != null) {
180

    
181
            Double angle = (Double) values.get(elementAngle);
182
            if (angle == null) {
183
                try {
184
                    angle =
185
                        editingProviderServices.getAngle(centerPointValue,
186
                            mousePosition);
187
                } catch (BaseException e) {
188
                    throw new DrawServiceException(e);
189
                }
190
            }
191

    
192
            // Creation of symbology
193
            EditingProviderManager editingProviderManager =
194
                EditingProviderLocator.getProviderManager();
195
            ISymbol auxiliaryPointSymbolEditing =
196
                editingProviderManager
197
                    .getSymbol("auxiliary-point-symbol-editing");
198
            ISymbol ruleAxisSymbol =
199
                editingProviderManager.getSymbol("rule-axis-symbol");
200
            ISymbol auxiliaryLineSymbolEditing =
201
                editingProviderManager
202
                    .getSymbol("auxiliary-line-symbol-editing");
203

    
204
            try {
205

    
206
                drawingStatus.addStatus(centerPointValue,
207
                    auxiliaryPointSymbolEditing, "");
208

    
209
                // Grade indicator creation
210
                int subtype = centerPointValue.getGeometryType().getSubType();
211
                double textDistance =
212
                    3 * centerPointValue.distance(mousePosition) / 4;
213
                Geometry pointText =
214
                    geometryManager.createPoint(
215
                        centerPointValue.getX() + textDistance
216
                            * Math.cos(angle / 2),
217
                        centerPointValue.getY() + textDistance
218
                            * Math.sin(angle / 2), subtype);
219
                drawingStatus.addStatus(pointText, getTextSymbol(),
220
                    degToDms(Math.toDegrees(angle)));
221

    
222
                // Horizontal line of angle indicator creation
223
                Line horizontalLine = geometryManager.createLine(subtype);
224
                horizontalLine.setPoints(centerPointValue, geometryManager
225
                    .createPoint(
226
                        centerPointValue.getX()
227
                            + centerPointValue.distance(mousePosition),
228
                        centerPointValue.getY(), subtype));
229
                drawingStatus.addStatus(horizontalLine, ruleAxisSymbol, "");
230

    
231
                // Vertical line of angle indicator creation
232
                Line verticalLine = geometryManager.createLine(subtype);
233
                verticalLine.setPoints(centerPointValue, mousePosition);
234
                drawingStatus.addStatus(verticalLine, ruleAxisSymbol, "");
235

    
236
                // Arc angle indicator creation
237
                Double ext = (2 * Math.PI) - angle;
238
                Arc arc =
239
                    editingProviderServices.createArc(centerPointValue,
240
                        centerPointValue.distance(mousePosition) / 2, 0, ext,
241
                        subtype);
242
                drawingStatus.addStatus(arc, auxiliaryLineSymbolEditing, "");
243

    
244
            } catch (BaseException e) {
245
                throw new DrawServiceException(e);
246
            }
247

    
248
            DisposableIterator it = null;
249
            try {
250
                it = featureSelection.fastIterator();
251
                while (it.hasNext()) {
252
                    Feature feature = (Feature) it.next();
253
                    Geometry geometry = feature.getDefaultGeometry();
254
                    Geometry[] matrix =
255
                        createPolarMatrix(geometry, elementsNumberValue,
256
                            rotateElementsValue, centerPointValue, angle);
257

    
258
                    for (int i = 0; i < matrix.length; i++) {
259

    
260
                        ISymbol symbol = getSymbol(matrix[i]);
261

    
262
                        if (matrix[i] instanceof Aggregate) {
263
                            int primitivesNumber =
264
                                ((Aggregate) matrix[i]).getPrimitivesNumber();
265
                            for (int j = 0; j < primitivesNumber; j++) {
266
                                drawingStatus.addStatus(
267
                                    ((Aggregate) matrix[i]).getPrimitiveAt(j),
268
                                    symbol, "");
269
                            }
270
                        } else {
271
                            drawingStatus.addStatus(matrix[i], symbol, "");
272
                        }
273
                    }
274
                }
275
            } catch (BaseException e) {
276
                throw new DrawServiceException(e);
277
            } finally {
278
                it.dispose();
279
            }
280
        }
281
        return drawingStatus;
282
    }
283

    
284
    private ISymbol getSymbol(Geometry geometry) {
285

    
286
        EditingProviderManager editingProviderManager =
287
            EditingProviderLocator.getProviderManager();
288
        ISymbol auxiliaryPointSymbolEditing =
289
            editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
290
        ISymbol lineSymbolEditing =
291
            editingProviderManager.getSymbol("line-symbol-editing");
292
        ISymbol polygonSymbolEditing =
293
            editingProviderManager.getSymbol("polygon-symbol-editing");
294

    
295
        if (geometry instanceof Curve || geometry instanceof MultiCurve) {
296
            return lineSymbolEditing;
297
        } else if (geometry instanceof Surface
298
            || geometry instanceof MultiSurface) {
299
            return polygonSymbolEditing;
300
        } else if (geometry instanceof Point || geometry instanceof MultiPoint) {
301
            return auxiliaryPointSymbolEditing;
302
        }
303
        return null;
304
    }
305

    
306
    private ISimpleTextSymbol getTextSymbol() {
307
        SymbologyManager symbologyManager =
308
            SymbologyLocator.getSymbologyManager();
309
        ISimpleTextSymbol textSymbol =
310
            symbologyManager.createSimpleTextSymbol();
311
        textSymbol.setFontSize(10);
312
        return textSymbol;
313
    }
314

    
315
    private String degToDms(double deg) {
316
        int d = (int) Math.floor(deg);
317
        double minfloat = (deg - d) * 60;
318
        int m = (int) Math.floor(minfloat);
319
        double secfloat = (minfloat - m) * 60;
320
        int s = (int) Math.round(secfloat);
321
        // After rounding, the seconds might become 60. These two
322
        // if-tests are not necessary if no rounding is done.
323
        if (s == 60) {
324
            m++;
325
            s = 0;
326
        }
327
        if (m == 60) {
328
            d++;
329
            m = 0;
330
        }
331
        return ("" + d + "\u00B0" + m + "\u2032" + s + "\u2033");
332
    }
333

    
334
    private Geometry[] createPolarMatrix(Geometry geometry,
335
        Integer elementsNumberValue, Boolean rotateElementsValue,
336
        Point centerPointValue, Double angle)
337
        throws GeometryOperationNotSupportedException,
338
        GeometryOperationException {
339

    
340
        Geometry[] geometryMatrix = new Geometry[elementsNumberValue];
341

    
342
        for (int i = 0; i < elementsNumberValue; i++) {
343

    
344
            AffineTransform at = new AffineTransform();
345
            if (rotateElementsValue) {
346
                at = getRotateAffineTransform(centerPointValue, angle * i);
347
            } else {
348
                at = getRotateAffineTransform(centerPointValue, angle * i);
349
                Point lowerCorner = geometry.getEnvelope().getLowerCorner();
350
                Point lowerCornerCloned = (Point) lowerCorner.cloneGeometry();
351
                lowerCornerCloned.transform(at);
352
                at = getMoveAffineTransform(lowerCorner, lowerCornerCloned);
353
            }
354

    
355
            Geometry clonedGeometry = geometry.cloneGeometry();
356
            clonedGeometry.transform(at);
357
            geometryMatrix[i] = clonedGeometry;
358
        }
359

    
360
        return geometryMatrix;
361
    }
362

    
363
    public void stop() throws StopServiceException {
364
        values.clear();
365
    }
366

    
367
    public List<EditingServiceParameter> getParameters() {
368
        List<EditingServiceParameter> parameters =
369
            new ArrayList<EditingServiceParameter>();
370
        parameters.add(selection);
371
        parameters.add(rotateElements);
372
        parameters.add(centerPoint);
373
        parameters.add(elementAngle);
374
        return parameters;
375
    }
376

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

    
382
    private void validateAndInsertValue(EditingServiceParameter parameter,
383
        Object value) throws InvalidEntryException {
384

    
385
        boolean insertedValue = false;
386

    
387
        if (parameter.equals(selection) && value instanceof FeatureSelection) {
388
            FeatureSelection featureSelection = (FeatureSelection) value;
389

    
390
            if (featureSelection.getSelectedCount() > 0) {
391
                values.put(parameter, featureSelection);
392
                insertedValue = true;
393
            }
394

    
395
        } else if (parameter.equals(elementsNumber) && value instanceof Double) {
396

    
397
            if (value instanceof Double) {
398
                Double number = (Double) value;
399
                values.put(parameter, number.intValue());
400
                insertedValue = true;
401
            }
402

    
403
        } else if (parameter.equals(rotateElements) && value instanceof String) {
404

    
405
            String option = (String) value;
406
            I18nManager i18nManager = ToolsLocator.getI18nManager();
407
            if (option.equalsIgnoreCase(i18nManager.getTranslation("key_yes"))) {
408
                values.put(rotateElements, true);
409
                insertedValue = true;
410
            } else if (option.equalsIgnoreCase(i18nManager
411
                .getTranslation("key_no"))) {
412
                values.put(rotateElements, false);
413
                insertedValue = true;
414
            }
415

    
416
        } else if (parameter.equals(centerPoint) && value instanceof Point) {
417

    
418
            values.put(centerPoint, value);
419
            insertedValue = true;
420

    
421
        } else if (parameter.equals(elementAngle)) {
422

    
423
            if (value instanceof Double) {
424

    
425
                values.put(elementAngle, Math.toRadians((Double) value));
426
                insertedValue = true;
427

    
428
            } else if (value instanceof Point) {
429
                EditingProviderServices editingProviderServices =
430
                    (EditingProviderServices) getProviderServices();
431
                Point centerPointValue = (Point) values.get(centerPoint);
432
                Point valuePoint = (Point) value;
433
                try {
434
                    double angle =
435
                        editingProviderServices.getAngle(centerPointValue,
436
                            valuePoint);
437
                    values.put(elementAngle, angle);
438
                    insertedValue = true;
439
                } catch (BaseException e) {
440
                    throw new InvalidEntryException(e);
441
                }
442
            }
443
        }
444

    
445
        if (!insertedValue) {
446
            throw new InvalidEntryException(null);
447
        }
448
    }
449

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

    
454
    public void finishAndStore() throws FinishServiceException {
455

    
456
        final EditingProviderServices editingProviderServices =
457
            (EditingProviderServices) getProviderServices();
458

    
459
        FeatureSelection featureSelection =
460
            (FeatureSelection) values.get(selection);
461
        final Integer elementsNumberValue =
462
            (Integer) values.get(elementsNumber);
463
        final Boolean rotateElementsValue =
464
            (Boolean) values.get(rotateElements);
465
        final Point centerPointValue = (Point) values.get(centerPoint);
466
        final Double elementAngleValue = (Double) values.get(elementAngle);
467

    
468
        if (featureSelection != null && elementsNumberValue != null
469
            && rotateElementsValue != null && centerPointValue != null
470
            && elementAngleValue != null) {
471

    
472
            try {
473
                featureSelection.accept(new Visitor() {
474

    
475
                    public void visit(Object obj)
476
                        throws VisitCanceledException, BaseException {
477

    
478
                        Feature feature = (Feature) obj;
479
                        Geometry geometry = feature.getDefaultGeometry();
480
                        Geometry[] matrix =
481
                            createPolarMatrix(geometry, elementsNumberValue,
482
                                rotateElementsValue, centerPointValue,
483
                                elementAngleValue);
484

    
485
                        for (int i = 0; i < matrix.length; i++) {
486
                            EditableFeature eFeature =
487
                                editingProviderServices
488
                                    .getFeatureCopyWithoutPK(featureStore,
489
                                        feature);
490
                            eFeature.setDefaultGeometry(matrix[i]);
491
                            editingProviderServices
492
                                .insertFeatureIntoFeatureStore(eFeature,
493
                                    featureStore);
494
                        }
495
                    }
496
                });
497
            } catch (BaseException e) {
498
                throw new FinishServiceException(e);
499
            }
500
        }
501
    }
502

    
503
    public void start() throws StartServiceException, InvalidEntryException {
504
        values = new HashMap<EditingServiceParameter, Object>();
505
        FeatureSelection selected = null;
506
        if (featureStore != null && values.get(selection) == null) {
507
            try {
508
                selected = featureStore.getFeatureSelection();
509
            } catch (DataException e) {
510
                throw new StartServiceException(e);
511
            }
512
            if (selected.getSelectedCount() > 0) {
513
                try {
514
                    setValue(selected);
515
                } catch (InvalidEntryException e) {
516
                    throw new InvalidEntryException(e);
517
                }
518
            }
519
        }
520
    }
521

    
522
    public String getName() {
523
        return PolarMatrixEditingProviderFactory.PROVIDER_NAME;
524
    }
525

    
526
    private AffineTransform getMoveAffineTransform(Point p1, Point p2)
527
        throws GeometryOperationNotSupportedException,
528
        GeometryOperationException {
529

    
530
        AffineTransform translate =
531
            AffineTransform.getTranslateInstance(p2.getX() - p1.getX(),
532
                p2.getY() - p1.getY());
533

    
534
        return translate;
535
    }
536

    
537
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
538
        throws GeometryOperationNotSupportedException,
539
        GeometryOperationException {
540

    
541
        AffineTransform translate =
542
            AffineTransform
543
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
544

    
545
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
546

    
547
        AffineTransform inverseTranslate =
548
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
549
        AffineTransform at = new AffineTransform(translate);
550

    
551
        at.preConcatenate(rotate);
552
        at.preConcatenate(inverseTranslate);
553
        return at;
554
    }
555
}