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

History | View | Annotate | Download (21.5 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
            ISymbol lineSymbolEditing =
204
                editingProviderManager.getSymbol("line-symbol-editing");
205
            ISymbol polygonSymbolEditing =
206
                editingProviderManager.getSymbol("polygon-symbol-editing");
207

    
208
            try {
209

    
210
                drawingStatus.addStatus(centerPointValue,
211
                    auxiliaryPointSymbolEditing, "");
212

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

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

    
235
                // Vertical line of angle indicator creation
236
                Line verticalLine = geometryManager.createLine(subtype);
237
                verticalLine.setPoints(centerPointValue, mousePosition);
238
                drawingStatus.addStatus(verticalLine, ruleAxisSymbol, "");
239

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

    
248
            } catch (BaseException e) {
249
                throw new DrawServiceException(e);
250
            }
251

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

    
262
                    for (int i = 0; i < matrix.length; i++) {
263

    
264
                        ISymbol symbol = null;
265
                        if (matrix[i] instanceof Curve
266
                            || matrix[i] instanceof MultiCurve) {
267
                            symbol = lineSymbolEditing;
268
                        } else if (matrix[i] instanceof Surface
269
                            || matrix[i] instanceof MultiSurface) {
270
                            symbol = polygonSymbolEditing;
271
                        } else if (matrix[i] instanceof Point
272
                            || matrix[i] instanceof MultiPoint) {
273
                            symbol = auxiliaryPointSymbolEditing;
274
                        }
275

    
276
                        if (matrix[i] instanceof Aggregate) {
277
                            int primitivesNumber =
278
                                ((Aggregate) matrix[i]).getPrimitivesNumber();
279
                            for (int j = 0; j < primitivesNumber; j++) {
280
                                drawingStatus.addStatus(
281
                                    ((Aggregate) matrix[i]).getPrimitiveAt(j),
282
                                    symbol, "");
283
                            }
284
                        } else {
285
                            drawingStatus.addStatus(matrix[i],symbol,"");
286
                        }
287
                    }
288
                }
289
            } catch (BaseException e) {
290
                throw new DrawServiceException(e);
291
            } finally {
292
                it.dispose();
293
            }
294
        }
295
        return drawingStatus;
296
    }
297

    
298
    private ISimpleTextSymbol getTextSymbol() {
299
        SymbologyManager symbologyManager =
300
            SymbologyLocator.getSymbologyManager();
301
        ISimpleTextSymbol textSymbol =
302
            symbologyManager.createSimpleTextSymbol();
303
        textSymbol.setFontSize(10);
304
        return textSymbol;
305
    }
306

    
307
    private String degToDms(double deg) {
308
        int d = (int) Math.floor(deg);
309
        double minfloat = (deg - d) * 60;
310
        int m = (int) Math.floor(minfloat);
311
        double secfloat = (minfloat - m) * 60;
312
        int s = (int) Math.round(secfloat);
313
        // After rounding, the seconds might become 60. These two
314
        // if-tests are not necessary if no rounding is done.
315
        if (s == 60) {
316
            m++;
317
            s = 0;
318
        }
319
        if (m == 60) {
320
            d++;
321
            m = 0;
322
        }
323
        return ("" + d + "\u00B0" + m + "\u2032" + s + "\u2033");
324
    }
325

    
326
    private Geometry[] createPolarMatrix(Geometry geometry,
327
        Integer elementsNumberValue, Boolean rotateElementsValue,
328
        Point centerPointValue, Double angle)
329
        throws GeometryOperationNotSupportedException,
330
        GeometryOperationException {
331

    
332
        Geometry[] geometryMatrix = new Geometry[elementsNumberValue];
333

    
334
        for (int i = 0; i < elementsNumberValue; i++) {
335

    
336
            AffineTransform at = new AffineTransform();
337
            if (rotateElementsValue) {
338
                at = getRotateAffineTransform(centerPointValue, angle * i);
339
            } else {
340
                at = getRotateAffineTransform(centerPointValue, angle * i);
341
                Point lowerCorner = geometry.getEnvelope().getLowerCorner();
342
                Point lowerCornerCloned = (Point) lowerCorner.cloneGeometry();
343
                lowerCornerCloned.transform(at);
344
                at = getMoveAffineTransform(lowerCorner, lowerCornerCloned);
345
            }
346

    
347
            Geometry clonedGeometry = geometry.cloneGeometry();
348
            clonedGeometry.transform(at);
349
            geometryMatrix[i] = clonedGeometry;
350
        }
351

    
352
        return geometryMatrix;
353
    }
354

    
355
    public void stop() throws StopServiceException {
356
        values.clear();
357
    }
358

    
359
    public List<EditingServiceParameter> getParameters() {
360
        List<EditingServiceParameter> parameters =
361
            new ArrayList<EditingServiceParameter>();
362
        parameters.add(selection);
363
        parameters.add(rotateElements);
364
        parameters.add(centerPoint);
365
        parameters.add(elementAngle);
366
        return parameters;
367
    }
368

    
369
    public void setValue(Object value) throws InvalidEntryException {
370
        EditingServiceParameter parameter = next();
371
        validateAndInsertValue(parameter, value);
372
    }
373

    
374
    private void validateAndInsertValue(EditingServiceParameter parameter,
375
        Object value) throws InvalidEntryException {
376

    
377
        boolean insertedValue = false;
378

    
379
        if (parameter.equals(selection) && value instanceof FeatureSelection) {
380
            FeatureSelection featureSelection = (FeatureSelection) value;
381

    
382
            if (featureSelection.getSelectedCount() > 0) {
383
                values.put(parameter, featureSelection);
384
                insertedValue = true;
385
            }
386

    
387
        } else if (parameter.equals(elementsNumber) && value instanceof Double) {
388

    
389
            if (value instanceof Double) {
390
                Double number = (Double) value;
391
                values.put(parameter, number.intValue());
392
                insertedValue = true;
393
            }
394

    
395
        } else if (parameter.equals(rotateElements) && value instanceof String) {
396

    
397
            String option = (String) value;
398
            I18nManager i18nManager = ToolsLocator.getI18nManager();
399
            if (option.equalsIgnoreCase(i18nManager.getTranslation("key_yes"))) {
400
                values.put(rotateElements, true);
401
                insertedValue = true;
402
            } else if (option.equalsIgnoreCase(i18nManager
403
                .getTranslation("key_no"))) {
404
                values.put(rotateElements, false);
405
                insertedValue = true;
406
            }
407

    
408
        } else if (parameter.equals(centerPoint) && value instanceof Point) {
409

    
410
            values.put(centerPoint, value);
411
            insertedValue = true;
412

    
413
        } else if (parameter.equals(elementAngle)) {
414

    
415
            if (value instanceof Double) {
416

    
417
                values.put(elementAngle, Math.toRadians((Double) value));
418
                insertedValue = true;
419

    
420
            } else if (value instanceof Point) {
421
                EditingProviderServices editingProviderServices =
422
                    (EditingProviderServices) getProviderServices();
423
                Point centerPointValue = (Point) values.get(centerPoint);
424
                Point valuePoint = (Point) value;
425
                try {
426
                    double angle =
427
                        editingProviderServices.getAngle(centerPointValue,
428
                            valuePoint);
429
                    values.put(elementAngle, angle);
430
                    insertedValue = true;
431
                } catch (BaseException e) {
432
                    throw new InvalidEntryException(e);
433
                }
434
            }
435
        }
436

    
437
        if (!insertedValue) {
438
            throw new InvalidEntryException(null);
439
        }
440
    }
441

    
442
    public Geometry finish() throws FinishServiceException {
443
        return null;
444
    }
445

    
446
    public void finishAndStore() throws FinishServiceException {
447

    
448
        final EditingProviderServices editingProviderServices =
449
            (EditingProviderServices) getProviderServices();
450

    
451
        FeatureSelection featureSelection =
452
            (FeatureSelection) values.get(selection);
453
        final Integer elementsNumberValue =
454
            (Integer) values.get(elementsNumber);
455
        final Boolean rotateElementsValue =
456
            (Boolean) values.get(rotateElements);
457
        final Point centerPointValue = (Point) values.get(centerPoint);
458
        final Double elementAngleValue = (Double) values.get(elementAngle);
459

    
460
        if (featureSelection != null && elementsNumberValue != null
461
            && rotateElementsValue != null && centerPointValue != null
462
            && elementAngleValue != null) {
463

    
464
            try {
465
                featureSelection.accept(new Visitor() {
466

    
467
                    public void visit(Object obj)
468
                        throws VisitCanceledException, BaseException {
469

    
470
                        Feature feature = (Feature) obj;
471
                        Geometry geometry = feature.getDefaultGeometry();
472
                        Geometry[] matrix =
473
                            createPolarMatrix(geometry, elementsNumberValue,
474
                                rotateElementsValue, centerPointValue,
475
                                elementAngleValue);
476

    
477
                        for (int i = 0; i < matrix.length; i++) {
478
                            EditableFeature eFeature =
479
                                editingProviderServices
480
                                    .getFeatureCopyWithoutPK(featureStore,
481
                                        feature);
482
                            eFeature.setDefaultGeometry(matrix[i]);
483
                            editingProviderServices
484
                                .insertFeatureIntoFeatureStore(eFeature,
485
                                    featureStore);
486
                        }
487
                    }
488
                });
489
            } catch (BaseException e) {
490
                throw new FinishServiceException(e);
491
            }
492
        }
493
    }
494

    
495
    public void start() throws StartServiceException, InvalidEntryException {
496
        values = new HashMap<EditingServiceParameter, Object>();
497
        FeatureSelection selected = null;
498
        if (featureStore != null && values.get(selection) == null) {
499
            try {
500
                selected = featureStore.getFeatureSelection();
501
            } catch (DataException e) {
502
                throw new StartServiceException(e);
503
            }
504
            if (selected.getSelectedCount() > 0) {
505
                try {
506
                    setValue(selected);
507
                } catch (InvalidEntryException e) {
508
                    throw new InvalidEntryException(e);
509
                }
510
            }
511
        }
512
    }
513

    
514
    public String getName() {
515
        return PolarMatrixEditingProviderFactory.PROVIDER_NAME;
516
    }
517

    
518
    private AffineTransform getMoveAffineTransform(Point p1, Point p2)
519
        throws GeometryOperationNotSupportedException,
520
        GeometryOperationException {
521

    
522
        AffineTransform translate =
523
            AffineTransform.getTranslateInstance(p2.getX() - p1.getX(),
524
                p2.getY() - p1.getY());
525

    
526
        return translate;
527
    }
528

    
529
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
530
        throws GeometryOperationNotSupportedException,
531
        GeometryOperationException {
532

    
533
        AffineTransform translate =
534
            AffineTransform
535
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
536

    
537
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
538

    
539
        AffineTransform inverseTranslate =
540
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
541
        AffineTransform at = new AffineTransform(translate);
542

    
543
        at.preConcatenate(rotate);
544
        at.preConcatenate(inverseTranslate);
545
        return at;
546
    }
547
}