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.rotate / src / main / java / org / gvsig / vectorediting / lib / prov / rotate / RotateEditingProvider.java @ 335

History | View | Annotate | Download (17.2 KB)

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

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

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

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.EditableFeature;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureSelection;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryLocator;
40
import org.gvsig.fmap.geom.GeometryManager;
41
import org.gvsig.fmap.geom.aggregate.Aggregate;
42
import org.gvsig.fmap.geom.aggregate.MultiCurve;
43
import org.gvsig.fmap.geom.aggregate.MultiPoint;
44
import org.gvsig.fmap.geom.aggregate.MultiSurface;
45
import org.gvsig.fmap.geom.operation.GeometryOperationException;
46
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
47
import org.gvsig.fmap.geom.primitive.Arc;
48
import org.gvsig.fmap.geom.primitive.Curve;
49
import org.gvsig.fmap.geom.primitive.Line;
50
import org.gvsig.fmap.geom.primitive.Point;
51
import org.gvsig.fmap.geom.primitive.Surface;
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.dispose.DisposableIterator;
58
import org.gvsig.tools.dynobject.DynObject;
59
import org.gvsig.tools.exception.BaseException;
60
import org.gvsig.tools.i18n.I18nManager;
61
import org.gvsig.tools.service.spi.ProviderServices;
62
import org.gvsig.tools.visitor.VisitCanceledException;
63
import org.gvsig.tools.visitor.Visitor;
64
import org.gvsig.vectorediting.lib.api.DrawingStatus;
65
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
66
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
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.spi.AbstractEditingProvider;
72
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
73
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
74
import org.gvsig.vectorediting.lib.spi.EditingProvider;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
78
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
79

    
80
public class RotateEditingProvider extends AbstractEditingProvider implements
81
    EditingProvider {
82

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

    
85
    private EditingServiceParameter selectionParameter;
86

    
87
    private EditingServiceParameter centerPointParameter;
88

    
89
    private EditingServiceParameter angleParameter;
90

    
91
    private Map<EditingServiceParameter, Object> values;
92

    
93
    private FeatureStore featureStore;
94

    
95
    public RotateEditingProvider(ProviderServices providerServices,
96
        DynObject parameters) {
97
        super(providerServices);
98
        this.featureStore =
99
            (FeatureStore) parameters
100
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
101

    
102
        this.selectionParameter =
103
            new DefaultEditingServiceParameter("selection",
104
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
105

    
106
        this.centerPointParameter =
107
            new DefaultEditingServiceParameter("center_of_rotation",
108
                i18nManager.getTranslation("center_of_rotation"), TYPE.POSITION);
109

    
110
        this.angleParameter =
111
            new DefaultEditingServiceParameter("angle_of_rotation",
112
                i18nManager.getTranslation("angle_of_rotation"), TYPE.POSITION,
113
                TYPE.VALUE);
114
    }
115

    
116
    private ISimpleTextSymbol getTextSymbol(){
117
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
118
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
119
        textSymbol.setFontSize(10);
120
        return textSymbol;
121
    }
122

    
123
    public DrawingStatus getDrawingStatus(Point mousePosition)
124
        throws DrawServiceException {
125
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
126
        EditingProviderManager editingProviderManager =
127
            EditingProviderLocator.getProviderManager();
128
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
129
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
130
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
131
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
132
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
133

    
134

    
135

    
136
        FeatureSelection selected =
137
            (FeatureSelection) values.get(selectionParameter);
138
        try {
139
            if ((selected != null) && !selected.isEmpty()) {
140
                Point p1 = (Point) values.get(centerPointParameter);
141
                if (p1 != null) {
142
                    drawingStatus.addStatus(p1, auxiliaryPointSymbolEditing, "");
143
                    Object angleValue = values.get(angleParameter);
144
                    Double angle = null;
145
                    EditingProviderServices editingProviderServices =
146
                        (EditingProviderServices) getProviderServices();
147
                    if ((angleValue != null) && (angleValue instanceof Double)) {
148
                        angle = (Double) angleValue;
149
                    } else {
150
                        angle =
151
                            editingProviderServices.getAngle(
152
                                (Point) values.get(centerPointParameter),
153
                                mousePosition);
154

    
155
                        Line line;
156
                        GeometryManager geometryManager =
157
                            GeometryLocator.getGeometryManager();
158
                        int subType =
159
                            editingProviderServices.getSubType(featureStore);
160
                        line = geometryManager.createLine(subType);
161
                        line.addVertex(p1);
162
                        Point p2 =
163
                            geometryManager.createPoint(
164
                                p1.getX() + p1.distance(mousePosition),
165
                                p1.getY(), subType);
166
                        line.addVertex(p2);
167
                        drawingStatus.addStatus(line, ruleAxisSymbol, "");
168
                        Line line2;
169
                        line2 = geometryManager.createLine(subType);
170
                        line2.addVertex(p1);
171
                        line2.addVertex(mousePosition);
172
                        drawingStatus.addStatus(line2, ruleAxisSymbol, "");
173
                        Double ext = (2 * Math.PI) - angle;
174
                        Arc arc =
175
                            editingProviderServices
176
                                .createArc(p1, p1.distance(mousePosition) / 2,
177
                                    0, ext, subType);
178
                        drawingStatus.addStatus(arc, auxiliaryLineSymbolEditing, "");
179
                        double textDistance = 3*p1.distance(mousePosition) / 4;
180
                        Point pointText = geometryManager.createPoint(p1.getX()+textDistance*Math.cos(angle/2), p1.getY()+textDistance*Math.sin(angle/2), subType);
181
                        ISimpleTextSymbol textSymbol = getTextSymbol();
182
                        drawingStatus.addStatus(pointText, textSymbol, degToDms(Math.toDegrees(angle)));
183
                    }
184

    
185
                    DisposableIterator it;
186
                    it = selected.fastIterator();
187

    
188
                    AffineTransform at;
189
                    try {
190
                        at = getRotateAffineTransform(p1, angle);
191
                    } catch (Exception e) {
192
                        throw new DrawServiceException(e);
193
                    }
194

    
195
                    while (it.hasNext()) {
196
                        Feature feat = (Feature) it.next();
197

    
198
                        Geometry transformedGeometry = feat.getDefaultGeometry().cloneGeometry();
199
                        transformedGeometry.transform(at);
200

    
201
                        ISymbol symbol=null;
202
                        if(transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve){
203
                            symbol = lineSymbolEditing;
204
                        } else if(transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface){
205
                            symbol = polygonSymbolEditing;
206
                        } else if(transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint){
207
                            symbol = auxiliaryPointSymbolEditing;
208
                        }
209
                        if(transformedGeometry instanceof Aggregate){
210
                            int primitivesNumber = ((Aggregate)transformedGeometry).getPrimitivesNumber();
211
                            for (int i = 0; i < primitivesNumber; i++) {
212
                                drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), symbol, "");
213
                            }
214
                        } else {
215
                            drawingStatus.addStatus(transformedGeometry, symbol, "");
216
                        }
217

    
218
                    }
219
                    it.dispose();
220
                }
221
                return drawingStatus;
222
            }
223
        } catch (Exception e) {
224
            throw new DrawServiceException(e);
225
        }
226

    
227
        return null;
228

    
229
    }
230

    
231
    private String degToDms (double deg) {
232
        int d = (int)Math.floor(deg);
233
        double minfloat = (deg-d)*60;
234
        int m = (int)Math.floor(minfloat);
235
        double secfloat = (minfloat-m)*60;
236
        int s = (int)Math.round(secfloat);
237
        // After rounding, the seconds might become 60. These two
238
        // if-tests are not necessary if no rounding is done.
239
        if (s==60) {
240
          m++;
241
          s=0;
242
        }
243
        if (m==60) {
244
          d++;
245
          m=0;
246
        }
247
        return ("" + d + "\u00B0" + m + "\u2032" + s+"\u2033");
248
     }
249

    
250
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
251
        throws GeometryOperationNotSupportedException,
252
        GeometryOperationException {
253

    
254
        AffineTransform translate =
255
            AffineTransform
256
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
257

    
258
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
259

    
260
        AffineTransform inverseTranslate =
261
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
262
        AffineTransform at = new AffineTransform(translate);
263

    
264
        at.preConcatenate(rotate);
265
        at.preConcatenate(inverseTranslate);
266
        return at;
267
    }
268

    
269
    public EditingServiceParameter next() {
270
        if (values.get(selectionParameter) == null) {
271
            return this.selectionParameter;
272
        } else if (values.get(centerPointParameter) == null) {
273
            return this.centerPointParameter;
274
        } else if (values.get(angleParameter) == null) {
275
            return this.angleParameter;
276
        }
277
        return null;
278
    }
279

    
280
    public void stop() {
281
        values.clear();
282
    }
283

    
284
    private void validateAndInsertValue(EditingServiceParameter param,
285
        Object value) throws InvalidEntryException {
286
        if (param == selectionParameter) {
287
            if (value instanceof FeatureSelection) {
288
                values.put(param, value);
289
                return;
290
            }
291
        } else if (param == centerPointParameter) {
292
            if (value instanceof Point) {
293
                values.put(param, value);
294
                return;
295
            }
296
        } else if (param == angleParameter) {
297
            if (value instanceof Point) {
298
                Double angleValue = null;
299

    
300
                try {
301
                    EditingProviderServices editingProviderServices =
302
                        (EditingProviderServices) getProviderServices();
303
                    angleValue =
304
                        editingProviderServices.getAngle(
305
                            (Point) values.get(centerPointParameter),
306
                            ((Point) value));
307
                } catch (Exception e) {
308
                    throw new InvalidEntryException(e);
309
                }
310

    
311
                if (angleValue != null) {
312
                    values.put(param, angleValue);
313
                    return;
314
                }
315

    
316
            } else if (value instanceof Double) {
317
                values.put(param, (Double)value*Math.PI/180);
318
                return;
319
            }
320
        }
321

    
322
    }
323

    
324
    public List<EditingServiceParameter> getParameters() {
325
        List<EditingServiceParameter> list =
326
            new ArrayList<EditingServiceParameter>();
327
        list.add(selectionParameter);
328
        list.add(centerPointParameter);
329
        list.add(angleParameter);
330
        return list;
331
    }
332

    
333
    public void setValue(Object value) throws InvalidEntryException {
334
        EditingServiceParameter param = next();
335
        validateAndInsertValue(param, value);
336
    }
337

    
338
    public void finishAndStore() throws FinishServiceException {
339

    
340
        FeatureSelection selected =
341
            (FeatureSelection) values.get(selectionParameter);
342
        try {
343
            if (!selected.isEmpty()) {
344
                Point p1 = (Point) values.get(centerPointParameter);
345
                Double angle = (Double) values.get(angleParameter);
346
                if ((p1 != null) && (angle != null)) {
347

    
348
                    final AffineTransform at;
349
                    try {
350
                        at = getRotateAffineTransform(p1, angle);
351
                    } catch (GeometryOperationNotSupportedException e) {
352
                        throw new FinishServiceException(e);
353
                    } catch (GeometryOperationException e) {
354
                        throw new FinishServiceException(e);
355
                    }
356

    
357
                    try {
358
                        selected.accept(new Visitor() {
359

    
360
                            public void visit(Object obj)
361
                                throws VisitCanceledException, BaseException {
362
                                Feature feature = (Feature) obj;
363
                                Geometry geom =
364
                                    feature.getDefaultGeometry()
365
                                        .cloneGeometry();
366
                                geom.transform(at);
367
                                // Se sustituye la geometr?a original por la
368
                                // calculada
369
                                EditableFeature editableFeature =
370
                                    feature.getEditable();
371
                                editableFeature.setDefaultGeometry(geom);
372
                                ((EditingProviderServices) getProviderServices())
373
                                    .updateFeatureInFeatureStore(
374
                                        editableFeature, featureStore);
375
                            }
376
                        });
377
                    } catch (BaseException e) {
378
                        throw new FinishServiceException(e);
379
                    }
380
                    featureStore.getFeatureSelection().deselectAll();
381
                }
382
            }
383
        } catch (DataException e) {
384
            throw new FinishServiceException(e);
385
        }
386
    }
387

    
388
    public Geometry finish() throws FinishServiceException {
389
        return null;
390
    }
391

    
392
    public void start() throws StartServiceException {
393
        this.values = new HashMap<EditingServiceParameter, Object>();
394
        FeatureSelection selected = null;
395
        if (featureStore != null) {
396
            try {
397
                selected =
398
                    (FeatureSelection) featureStore.getFeatureSelection()
399
                        .clone();
400
            } catch (DataException e) {
401
                throw new StartServiceException(e);
402
            } catch (CloneNotSupportedException e) {
403
                // Do nothing
404
            }
405
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
406
                values.put(selectionParameter, selected);
407
            }
408
        }
409
    }
410

    
411
    public String getName() {
412
        return RotateEditingProviderFactory.PROVIDER_NAME;
413
    }
414

    
415
}