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

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

    
74
public class RotateEditingProvider extends AbstractEditingProvider implements
75
    EditingProvider {
76

    
77
    private I18nManager i18nManager = ToolsLocator.getI18nManager();
78

    
79
    private EditingServiceParameter selectionParameter;
80

    
81
    private EditingServiceParameter centerPointParameter;
82

    
83
    private EditingServiceParameter angleParameter;
84

    
85
    private Map<EditingServiceParameter, Object> values;
86

    
87
    private FeatureStore featureStore;
88

    
89
    public RotateEditingProvider(ProviderServices providerServices,
90
        DynObject parameters) {
91
        super(providerServices);
92
        this.featureStore =
93
            (FeatureStore) parameters
94
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
95

    
96
        this.selectionParameter =
97
            new DefaultEditingServiceParameter("selection",
98
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
99

    
100
        this.centerPointParameter =
101
            new DefaultEditingServiceParameter("center_of_rotation",
102
                i18nManager.getTranslation("center_of_rotation"), TYPE.POSITION);
103

    
104
        this.angleParameter =
105
            new DefaultEditingServiceParameter("angle_of_rotation",
106
                i18nManager.getTranslation("angle_of_rotation"), TYPE.POSITION,
107
                TYPE.VALUE);
108
    }
109

    
110
    private ISimpleTextSymbol getTextSymbol(){
111
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
112
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
113
        textSymbol.setFontSize(10);
114
        return textSymbol;
115
    }
116

    
117
    public DrawingStatus getDrawingStatus(Point mousePosition)
118
        throws DrawServiceException {
119
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
120
        EditingProviderManager editingProviderManager =
121
            EditingProviderLocator.getProviderManager();
122
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
123
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
124
        ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
125

    
126

    
127
        FeatureSelection selected =
128
            (FeatureSelection) values.get(selectionParameter);
129
        try {
130
            if ((selected != null) && !selected.isEmpty()) {
131
                Point p1 = (Point) values.get(centerPointParameter);
132
                if (p1 != null) {
133
                    drawingStatus.addStatus(p1, auxiliaryPointSymbolEditing, "");
134
                    Object angleValue = values.get(angleParameter);
135
                    Double angle = null;
136
                    EditingProviderServices editingProviderServices =
137
                        (EditingProviderServices) getProviderServices();
138
                    if ((angleValue != null) && (angleValue instanceof Double)) {
139
                        angle = (Double) angleValue;
140
                    } else {
141
                        angle =
142
                            editingProviderServices.getAngle(
143
                                (Point) values.get(centerPointParameter),
144
                                mousePosition);
145

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

    
176
                    DisposableIterator it;
177
                    it = selected.fastIterator();
178

    
179
                    AffineTransform at;
180
                    try {
181
                        at = getRotateAffineTransform(p1, angle);
182
                    } catch (Exception e) {
183
                        throw new DrawServiceException(e);
184
                    }
185

    
186
                    while (it.hasNext()) {
187
                        Feature feat = (Feature) it.next();
188
                        Geometry geom =
189
                            feat.getDefaultGeometry().cloneGeometry();
190
                        geom.transform(at);
191
                        drawingStatus.addGeometry(geom);
192
                    }
193
                    it.dispose();
194
                }
195
                return drawingStatus;
196
            }
197
        } catch (Exception e) {
198
            throw new DrawServiceException(e);
199
        }
200

    
201
        return null;
202

    
203
    }
204

    
205
    private String degToDms (double deg) {
206
        int d = (int)Math.floor(deg);
207
        double minfloat = (deg-d)*60;
208
        int m = (int)Math.floor(minfloat);
209
        double secfloat = (minfloat-m)*60;
210
        int s = (int)Math.round(secfloat);
211
        // After rounding, the seconds might become 60. These two
212
        // if-tests are not necessary if no rounding is done.
213
        if (s==60) {
214
          m++;
215
          s=0;
216
        }
217
        if (m==60) {
218
          d++;
219
          m=0;
220
        }
221
        return ("" + d + "\u00B0" + m + "\u2032" + s+"\u2033");
222
     }
223

    
224
    private AffineTransform getRotateAffineTransform(Point axisP1, Double angle)
225
        throws GeometryOperationNotSupportedException,
226
        GeometryOperationException {
227

    
228
        AffineTransform translate =
229
            AffineTransform
230
                .getTranslateInstance(-axisP1.getX(), -axisP1.getY());
231

    
232
        AffineTransform rotate = AffineTransform.getRotateInstance(angle);
233

    
234
        AffineTransform inverseTranslate =
235
            AffineTransform.getTranslateInstance(axisP1.getX(), axisP1.getY());
236
        AffineTransform at = new AffineTransform(translate);
237

    
238
        at.preConcatenate(rotate);
239
        at.preConcatenate(inverseTranslate);
240
        return at;
241
    }
242

    
243
    public EditingServiceParameter next() {
244
        if (values.get(selectionParameter) == null) {
245
            return this.selectionParameter;
246
        } else if (values.get(centerPointParameter) == null) {
247
            return this.centerPointParameter;
248
        } else if (values.get(angleParameter) == null) {
249
            return this.angleParameter;
250
        }
251
        return null;
252
    }
253

    
254
    public void stop() {
255
        values.clear();
256
    }
257

    
258
    private void validateAndInsertValue(EditingServiceParameter param,
259
        Object value) throws InvalidEntryException {
260
        if (param == selectionParameter) {
261
            if (value instanceof FeatureSelection) {
262
                values.put(param, value);
263
                return;
264
            }
265
        } else if (param == centerPointParameter) {
266
            if (value instanceof Point) {
267
                values.put(param, value);
268
                return;
269
            }
270
        } else if (param == angleParameter) {
271
            if (value instanceof Point) {
272
                Double angleValue = null;
273

    
274
                try {
275
                    EditingProviderServices editingProviderServices =
276
                        (EditingProviderServices) getProviderServices();
277
                    angleValue =
278
                        editingProviderServices.getAngle(
279
                            (Point) values.get(centerPointParameter),
280
                            ((Point) value));
281
                } catch (Exception e) {
282
                    throw new InvalidEntryException(e);
283
                }
284

    
285
                if (angleValue != null) {
286
                    values.put(param, angleValue);
287
                    return;
288
                }
289

    
290
            } else if (value instanceof Double) {
291
                values.put(param, value);
292
                return;
293
            }
294
        }
295

    
296
    }
297

    
298
    public List<EditingServiceParameter> getParameters() {
299
        List<EditingServiceParameter> list =
300
            new ArrayList<EditingServiceParameter>();
301
        list.add(selectionParameter);
302
        list.add(centerPointParameter);
303
        list.add(angleParameter);
304
        return list;
305
    }
306

    
307
    public void setValue(Object value) throws InvalidEntryException {
308
        EditingServiceParameter param = next();
309
        validateAndInsertValue(param, value);
310
    }
311

    
312
    public void finishAndStore() throws FinishServiceException {
313

    
314
        FeatureSelection selected =
315
            (FeatureSelection) values.get(selectionParameter);
316
        try {
317
            if (!selected.isEmpty()) {
318
                Point p1 = (Point) values.get(centerPointParameter);
319
                Double angle = (Double) values.get(angleParameter);
320
                if ((p1 != null) && (angle != null)) {
321

    
322
                    final AffineTransform at;
323
                    try {
324
                        at = getRotateAffineTransform(p1, angle);
325
                    } catch (GeometryOperationNotSupportedException e) {
326
                        throw new FinishServiceException(e);
327
                    } catch (GeometryOperationException e) {
328
                        throw new FinishServiceException(e);
329
                    }
330

    
331
                    try {
332
                        selected.accept(new Visitor() {
333

    
334
                            public void visit(Object obj)
335
                                throws VisitCanceledException, BaseException {
336
                                Feature feature = (Feature) obj;
337
                                Geometry geom =
338
                                    feature.getDefaultGeometry()
339
                                        .cloneGeometry();
340
                                geom.transform(at);
341
                                // Se sustituye la geometr?a original por la
342
                                // calculada
343
                                EditableFeature editableFeature =
344
                                    feature.getEditable();
345
                                editableFeature.setDefaultGeometry(geom);
346
                                ((EditingProviderServices) getProviderServices())
347
                                    .updateFeatureInFeatureStore(
348
                                        editableFeature, featureStore);
349
                            }
350
                        });
351
                    } catch (BaseException e) {
352
                        throw new FinishServiceException(e);
353
                    }
354
                    featureStore.getFeatureSelection().deselectAll();
355
                }
356
            }
357
        } catch (DataException e) {
358
            throw new FinishServiceException(e);
359
        }
360
    }
361

    
362
    public Geometry finish() throws FinishServiceException {
363
        return null;
364
    }
365

    
366
    public void start() throws StartServiceException {
367
        this.values = new HashMap<EditingServiceParameter, Object>();
368
        FeatureSelection selected = null;
369
        if (featureStore != null) {
370
            try {
371
                selected =
372
                    (FeatureSelection) featureStore.getFeatureSelection()
373
                        .clone();
374
            } catch (DataException e) {
375
                throw new StartServiceException(e);
376
            } catch (CloneNotSupportedException e) {
377
                // Do nothing
378
            }
379
            if ((selected != null) && (selected.getSelectedCount() > 0)) {
380
                values.put(selectionParameter, selected);
381
            }
382
        }
383
    }
384

    
385
    public String getName() {
386
        return RotateEditingProviderFactory.PROVIDER_NAME;
387
    }
388

    
389
}