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.reversedirection / src / main / java / org / gvsig / vectorediting / lib / prov / reversedirection / ReverseDirectionEditingProvider.java @ 4300

History | View | Annotate | Download (10.3 KB)

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

    
25
import java.util.ArrayList;
26
import java.util.List;
27
import org.gvsig.fmap.dal.exception.DataException;
28
import org.gvsig.fmap.dal.feature.EditableFeature;
29
import org.gvsig.fmap.dal.feature.Feature;
30
import org.gvsig.fmap.dal.feature.FeatureSelection;
31
import org.gvsig.fmap.dal.feature.FeatureStore;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.Geometry.TYPES;
34
import org.gvsig.fmap.geom.GeometryException;
35
import org.gvsig.fmap.geom.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.aggregate.MultiCurve;
38
import org.gvsig.fmap.geom.operation.GeometryOperationException;
39
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
40
import org.gvsig.fmap.geom.primitive.Curve;
41
import org.gvsig.fmap.geom.primitive.Line;
42
import org.gvsig.fmap.geom.primitive.Point;
43
import org.gvsig.fmap.geom.primitive.Spline;
44
import org.gvsig.fmap.geom.type.GeometryType;
45
import org.gvsig.tools.ToolsLocator;
46
import org.gvsig.tools.dispose.DisposeUtils;
47
import org.gvsig.tools.dynobject.DynObject;
48
import org.gvsig.tools.exception.BaseException;
49
import org.gvsig.tools.service.spi.ProviderServices;
50
import org.gvsig.vectorediting.lib.api.DrawingStatus;
51
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
52
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
53
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
54
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
55
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
56
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
57
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
58
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
59
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
60
import org.gvsig.vectorediting.lib.spi.EditingProvider;
61
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
62
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
63

    
64
/**
65
 *
66
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
67
 *
68
 */
69
public class ReverseDirectionEditingProvider extends AbstractEditingProvider
70
    implements EditingProvider {
71

    
72
    private final EditingServiceParameter selectionParameter;
73

    
74
    private FeatureSelection selection;
75

    
76
    private final FeatureStore featureStore;
77

    
78
    public ReverseDirectionEditingProvider(ProviderServices providerServices,
79
        DynObject parameters) {
80
        super(providerServices);
81

    
82
        this.featureStore =
83
            (FeatureStore) parameters
84
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
85

    
86
        this.selectionParameter =
87
            new DefaultEditingServiceParameter("selection", "selection",
88
                TYPE.SELECTION);
89
    }
90

    
91
    @Override
92
    public EditingServiceParameter next() {
93
        if (selection == null) {
94
            return this.selectionParameter;
95
        }
96
        return null;
97
    }
98

    
99
    @Override
100
    public boolean mustRestartAtFinish() {
101
        return false;
102
    }
103

    
104
    @Override
105
    public DrawingStatus getDrawingStatus(Point mousePosition)
106
        throws DrawServiceException {
107
        return null;
108
    }
109

    
110
    @Override
111
    public void stop() throws StopServiceException {
112
        ToolsLocator.getDisposableManager().release(selection);
113
        DisposeUtils.disposeQuietly(selection);
114
        this.selection = null;
115
    }
116

    
117
    @Override
118
    public List<EditingServiceParameter> getParameters() {
119
        List<EditingServiceParameter> parameters =
120
            new ArrayList<>();
121
        parameters.add(selectionParameter);
122
        return parameters;
123
    }
124

    
125
    @Override
126
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
127
        validateAndInsertValue(parameter, value);
128
    }
129

    
130
    @Override
131
    public void setValue(Object value) throws InvalidEntryException {
132
        EditingServiceParameter parameter = next();
133
        validateAndInsertValue(parameter, value);
134
    }
135

    
136
    private void validateAndInsertValue(EditingServiceParameter parameter,
137
        Object value) throws InvalidEntryException {
138

    
139
        if (parameter == selectionParameter) {
140

    
141
            if (value instanceof FeatureSelection) {
142
                FeatureSelection featureSelection = (FeatureSelection) value;
143

    
144
                if (featureSelection.getSelectedCount() > 0) {
145
                    try {
146
                        featureSelection.accept((Object obj) -> {
147
                            Feature feature = (Feature) obj;
148
                            Geometry geometry =
149
                                    feature.getDefaultGeometry();
150
                            GeometryType geometryType =
151
                                    geometry.getGeometryType();
152
                            
153
                            if (!geometryType.isTypeOf(TYPES.CURVE)
154
                                    && !geometryType.isTypeOf(TYPES.MULTICURVE)) {
155
                                throw new InvalidEntryException(null);
156
                            }
157
                        });
158
                    } catch (BaseException e) {
159
                        throw new InvalidEntryException(e);
160
                    }
161
                    ToolsLocator.getDisposableManager().bind(
162
                        (FeatureSelection) value);
163
                    this.selection = featureSelection;
164
                } else {
165
                    throw new InvalidEntryException(null);
166
                }
167
            }
168
        }
169
    }
170

    
171
    @Override
172
    public Geometry finish() throws FinishServiceException {
173
        return null;
174
    }
175

    
176
    @Override
177
    public void finishAndStore() throws FinishServiceException {
178

    
179
        if (selection != null) {
180

    
181
            final EditingProviderServices editingProviderServices =
182
                (EditingProviderServices) getProviderServices();
183

    
184
            try {
185
                selection.accept((Object obj) -> {
186
                    Feature feature = (Feature) obj;
187
                    EditableFeature eFeature = feature.getEditable();
188
                    Geometry geometry = eFeature.getDefaultGeometry();
189
                    
190
                    eFeature.setDefaultGeometry(reverseDirection(geometry));
191
                    editingProviderServices.updateFeatureInFeatureStore(
192
                            eFeature, featureStore);
193
                });
194

    
195
                ToolsLocator.getDisposableManager().release(selection);
196
                DisposeUtils.dispose(selection);
197
                featureStore.getFeatureSelection().deselectAll();
198

    
199
            } catch (BaseException e) {
200
                throw new FinishServiceException(e);
201
            }
202
        }
203
    }
204

    
205
    private Geometry reverseDirection(Geometry geometry)
206
        throws GeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
207
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
208
        GeometryType geometryType = geometry.getGeometryType();
209

    
210
        if (geometryType.isTypeOf(TYPES.MULTICURVE)) {
211
            MultiCurve reversedMultiCurve =
212
                geometryManager.createMultiCurve(geometryType.getSubType());
213
            MultiCurve multicurve = (MultiCurve) geometry;
214
            for (int i = 0; i < multicurve.getPrimitivesNumber(); i++) {
215
                reversedMultiCurve.addCurve(reverseCurve(multicurve.getCurveAt(i)));
216
            }
217
            return reversedMultiCurve;
218
        } else if (geometryType.isTypeOf(TYPES.CURVE)) {
219
            return reverseCurve((Curve) geometry);
220
        } else {
221
            throw new IllegalArgumentException(String.format(
222
                "Can't reverse geometry with {} type", geometryType.getType()));
223
        }
224
    }
225

    
226
    private Curve reverseCurve(Curve curve) throws GeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
227
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
228
        Curve curveToReverse = null;
229
        Curve reverseCurve = null;
230
        if(curve instanceof Line || curve instanceof Spline){
231
            reverseCurve = (Curve) curve.cloneGeometry();
232
            reverseCurve.flip();
233
        } else {
234
            curveToReverse = (Curve) curve.toLines().getPrimitiveAt(0);
235
            reverseCurve = (Curve) geometryManager.create(Geometry.TYPES.LINE, curve.getGeometryType().getSubType());
236
            for (int i = curveToReverse.getNumVertices() - 1; i >= 0; i--) {
237
                reverseCurve.addVertex(curveToReverse.getVertex(i));
238
            }
239
        }
240
        return reverseCurve;
241
    }
242

    
243
    @Override
244
    public void start() throws StartServiceException, InvalidEntryException {
245
        FeatureSelection selected = null;
246
        if (featureStore != null) {
247
            try {
248
                selected = featureStore.getFeatureSelection();
249
            } catch (DataException e) {
250
                throw new StartServiceException(e);
251
            }
252

    
253
            if (selected.getSelectedCount() > 0) {
254
                try {
255
                    setValue(selected);
256
                } catch (InvalidEntryException e) {
257
                    throw new InvalidEntryException(e);
258
                }
259
            }
260
        }
261
    }
262

    
263
    @Override
264
    public String getName() {
265
        return ReverseDirectionEditingProviderFactory.PROVIDER_NAME;
266
    }
267

    
268
    @Override
269
    public Object getValue(EditingServiceParameter parameter) {
270
        if(parameter == this.selectionParameter){
271
            return this.selection;
272
        }
273
        return null;
274
    }
275
}