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.duplicate / src / main / java / org / gvsig / vectorediting / lib / prov / duplicate / DuplicateEditingProvider.java @ 2871

History | View | Annotate | Download (16.9 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.duplicate;
26

    
27
import java.awt.geom.AffineTransform;
28
import java.text.DecimalFormat;
29
import java.util.ArrayList;
30
import java.util.HashMap;
31
import java.util.List;
32
import java.util.Map;
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.GeometryUtils;
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.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.dispose.DisposableIterator;
57
import org.gvsig.tools.dispose.DisposeUtils;
58
import org.gvsig.tools.dynobject.DynObject;
59
import org.gvsig.tools.exception.BaseException;
60
import org.gvsig.tools.service.spi.ProviderServices;
61
import org.gvsig.vectorediting.lib.api.DrawingStatus;
62
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
63
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
64
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
65
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
66
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
67
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
68
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
69
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
70
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
71
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
72
import org.gvsig.vectorediting.lib.spi.EditingProvider;
73
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
74
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
77

    
78
/**
79
 * @author llmarques
80
 *
81
 */
82
public class DuplicateEditingProvider extends AbstractEditingProvider implements
83
    EditingProvider {
84

    
85
    private final EditingServiceParameter selection;
86

    
87
    private final EditingServiceParameter firstPoint;
88

    
89
    private final EditingServiceParameter secondPoint;
90
    
91
    private final EditingServiceParameter equidistantCopies;
92

    
93
    private final FeatureStore featureStore;
94

    
95
    private Map<EditingServiceParameter, Object> values;
96

    
97
    /**
98
     * Default constructor.
99
     *
100
     * @param services
101
     *            available services for this provider
102
     * @param parameters
103
     *            of this provider
104
     */
105
    public DuplicateEditingProvider(DynObject parameters,
106
        ProviderServices services) {
107
        super(services);
108

    
109
        this.featureStore =
110
            (FeatureStore) parameters
111
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
112

    
113
        this.selection =
114
            new DefaultEditingServiceParameter("selection", "selection",
115
                TYPE.SELECTION);
116

    
117
        this.firstPoint =
118
            new DefaultEditingServiceParameter("first_point", "first_point",
119
                TYPE.POSITION);
120

    
121
        this.secondPoint =
122
            new DefaultEditingServiceParameter("second_point", "second_point",
123
                TYPE.POSITION);
124

    
125
        this.equidistantCopies = new DefaultEditingServiceParameter("equidistant_copies", "equidistant_copies", true, TYPE.VALUE);
126
        this.equidistantCopies.setDefaultValue(1);
127

    
128
    }
129

    
130
    @Override
131
    public EditingServiceParameter next() {
132
        if (values.get(selection) == null) {
133
            return selection;
134
        } else if (values.get(firstPoint) == null) {
135
            return firstPoint;
136
        } else if (values.get(secondPoint) == null) {
137
            return secondPoint;
138
        }
139
        return null;
140
    }
141

    
142
    @Override
143
    public DrawingStatus getDrawingStatus(Point mousePosition)
144
        throws DrawServiceException {
145
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
146

    
147
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
148
        EditingProviderManager editingProviderManager =
149
            EditingProviderLocator.getProviderManager();
150
        EditingProviderServices editingProviderServices =
151
            (EditingProviderServices) getProviderServices();
152
        int subtype;
153
        try {
154
            subtype = editingProviderServices.getSubType(featureStore);
155
        } catch (DataException e2) {
156
            throw new DrawServiceException(e2);
157
        }
158
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
159
        ISymbol auxiliarylineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
160
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
161
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
162

    
163
        
164
        if (values != null) {
165

    
166
            FeatureSelection featureSelection =
167
                (FeatureSelection) values.get(selection);
168
            Point firstPointValue = (Point) values.get(firstPoint);
169
            Number equidistantCopiesNumberValue = ((Number) values.get(this.equidistantCopies));
170
            int equidistantCopiesValue = equidistantCopiesNumberValue != null ? equidistantCopiesNumberValue.intValue() : ((Number)this.equidistantCopies.getDefaultValue()).intValue();
171

    
172
            if (featureSelection != null && firstPointValue != null) {
173
                drawingStatus.addStatus(firstPointValue, auxiliaryPointSymbolEditing, "");
174

    
175
                Point offset = GeometryUtils.createPoint(
176
                        mousePosition.getX() - firstPointValue.getX(),
177
                        mousePosition.getY() - firstPointValue.getY()
178
                );
179

    
180
                DisposableIterator it = null;
181
                try {
182
                    it = featureSelection.fastIterator();
183
                    Point pos = null;
184
                    while (it.hasNext()) {
185
                        Feature feature = (Feature) it.next();
186
                        ISymbol previewSymbol = this.getPreviewSymbol(feature);
187

    
188
                        Point antPos = firstPointValue;
189
                        for (int c = 1; c <= equidistantCopiesValue; c++) {
190
                            
191
                            pos = GeometryUtils.createPoint(
192
                                    firstPointValue.getX() + (c * offset.getX()),
193
                                    firstPointValue.getY() + (c * offset.getY())
194
                            );
195

    
196
                            Geometry geometry
197
                                    = feature.getDefaultGeometry().cloneGeometry();
198
                            AffineTransform at
199
                                    = getMoveAffineTransform(firstPointValue,
200
                                            pos);
201
                            geometry.transform(at);
202
                            ISymbol symbol = null;
203
                            if (geometry instanceof Curve || geometry instanceof MultiCurve) {
204
                                symbol = lineSymbolEditing;
205
                            } else if (geometry instanceof Surface || geometry instanceof MultiSurface) {
206
                                symbol = polygonSymbolEditing;
207
                            } else if (geometry instanceof Point || geometry instanceof MultiPoint) {
208
                                symbol = auxiliaryPointSymbolEditing;
209
                            }
210

    
211
                            if (geometry instanceof Aggregate) {
212
                                int primitivesNumber = ((Aggregate) geometry).getPrimitivesNumber();
213
                                for (int i = 0; i < primitivesNumber; i++) {
214
                                    drawingStatus.addStatus(((Aggregate) geometry).getPrimitiveAt(i), symbol, "");
215
                                    drawingStatus.addStatus(((Aggregate) geometry).getPrimitiveAt(i), previewSymbol, "");
216
                                }
217
                            } else {
218
                                drawingStatus.addStatus(geometry, symbol, "");
219
                                drawingStatus.addStatus(geometry, previewSymbol, "");
220
                            }
221
                            antPos = pos;
222
                        }
223
                        
224
                    }
225
                    
226
                    if(pos != null) {
227
                        Line auxLine = GeometryUtils.createLine(firstPointValue, pos, subtype);
228
                        drawingStatus.addStatus(auxLine, auxiliarylineSymbolEditing, "");
229
                    }
230
 
231
                    Point pointText = GeometryUtils.createPoint(
232
                                firstPointValue.getX() + (0.5 * offset.getX()),
233
                                firstPointValue.getY() + (0.5 * offset.getY())
234
                        );
235

    
236
                    ISimpleTextSymbol textSymbol = getTextSymbol();
237
                    drawingStatus.addStatus(
238
                            pointText, 
239
                            textSymbol, 
240
                            new DecimalFormat("#.0#").format(Math.sqrt(Math.pow(offset.getX(),2)+Math.pow(offset.getY(),2)))
241
                    );
242
                    
243
                } catch (BaseException e) {
244
                    throw new DrawServiceException(e);
245
                } finally {
246
                    DisposeUtils.disposeQuietly(it);
247
                }
248
            }
249
        }
250
        return drawingStatus;
251
    }
252

    
253
    private AffineTransform getMoveAffineTransform(Point p1, Point p2)
254
        throws GeometryOperationNotSupportedException,
255
        GeometryOperationException {
256

    
257
        AffineTransform translate =
258
            AffineTransform.getTranslateInstance(p2.getX() - p1.getX(),
259
                p2.getY() - p1.getY());
260

    
261
        return translate;
262
    }
263

    
264
    @Override
265
    public void stop() throws StopServiceException {
266
        if (values != null) {
267
            values.clear();
268
        }
269
    }
270

    
271
    @Override
272
    public List<EditingServiceParameter> getParameters() {
273
        List<EditingServiceParameter> parameters =
274
            new ArrayList<>();
275
        parameters.add(selection);
276
        parameters.add(firstPoint);
277
        parameters.add(secondPoint);
278
        parameters.add(equidistantCopies);
279
        return parameters;
280
    }
281

    
282
    @Override
283
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
284
        validateAndInsertValue(parameter, value);
285
    }
286

    
287
    @Override
288
    public void setValue(Object value) throws InvalidEntryException {
289
        EditingServiceParameter parameter = next();
290
        validateAndInsertValue(parameter, value);
291
    }
292

    
293
    private void validateAndInsertValue(EditingServiceParameter parameter,
294
        Object value) {
295

    
296
        if (parameter == selection) {
297
            if (value instanceof FeatureSelection) {
298
                if (((FeatureSelection) value).getSelectedCount() > 0) {
299
                    values.put(selection, value);
300
                }
301
            }
302
        } else if (parameter == firstPoint || parameter == secondPoint) {
303
            if (value instanceof Point) {
304
                values.put(parameter, value);
305
            }
306
        } else if (parameter == equidistantCopies) {
307
            if (value instanceof Number) {
308
                int intValue = ((Number) value).intValue();
309
                if(intValue >= 1) {
310
                    values.put(parameter, ((Number) value).intValue());
311
                }
312
            }
313
        }
314
    }
315

    
316
    @Override
317
    public Geometry finish() throws FinishServiceException {
318
        return null;
319
    }
320

    
321
    @Override
322
    public void finishAndStore() throws FinishServiceException {
323
        if (values != null) {
324

    
325
            final Point p1 = (Point) values.get(firstPoint);
326
            final Point p2 = (Point) values.get(secondPoint);
327
            Number equidistantCopiesNumberValue = ((Number) values.get(this.equidistantCopies));
328
            int equidistantCopiesValue = equidistantCopiesNumberValue != null ? equidistantCopiesNumberValue.intValue() : ((Number)this.equidistantCopies.getDefaultValue()).intValue();
329

    
330
            FeatureSelection featureSelection =
331
                (FeatureSelection) values.get(selection);
332
//            ToolsLocator.getDisposableManager().bind(featureSelection);
333

    
334
            try {
335
                featureSelection.accept((Object obj) -> {
336
                    Feature feature = (Feature) obj;
337
                    
338
                    EditingProviderServices editingProviderServices =
339
                            (EditingProviderServices) getProviderServices();
340
                    
341
                    Point offset = GeometryUtils.createPoint(
342
                            p2.getX() - p1.getX(),
343
                            p2.getY() - p1.getY()
344
                    );
345
                    
346
                    for(int c = 1; c <= equidistantCopiesValue; c++){
347

    
348
                        EditableFeature editable =
349
                                editingProviderServices.getFeatureCopyWithoutUniqueIndex(
350
                                        featureStore, feature);
351

    
352
                        Geometry geometry =
353
                                feature.getDefaultGeometry().cloneGeometry();
354
                        
355
                        Point pos = GeometryUtils.createPoint(
356
                                p1.getX() + (c * offset.getX()),
357
                                p1.getY() + (c * offset.getY())
358
                        );
359
                        
360
                        
361
                        geometry.transform(getMoveAffineTransform(p1, pos));
362

    
363
                        editable.setDefaultGeometry(geometry);
364
                        editingProviderServices.insertFeatureIntoFeatureStore(
365
                                editable, featureStore);
366
                    }
367
                });
368

    
369
//                featureStore.getFeatureSelection().deselectAll();
370
//                featureSelection.dispose();
371

    
372
            } catch (BaseException e) {
373
                throw new FinishServiceException(e);
374
            }
375
        }
376
    }
377

    
378
    @Override
379
    public void start() throws StartServiceException, InvalidEntryException {
380
        values = new HashMap<>();
381
        FeatureSelection selected = null;
382
        if (featureStore != null) {
383
            try {
384
                selected = featureStore.getFeatureSelection();
385
            } catch (DataException e) {
386
                throw new StartServiceException(e);
387
            }
388
            try {
389
                setValue(selected);
390
            } catch (InvalidEntryException e) {
391
                throw new InvalidEntryException(e);
392
            }
393
        }
394
    }
395

    
396
    @Override
397
    public void restart() throws StartServiceException, InvalidEntryException, StopServiceException {
398
        values.put(secondPoint,null);
399
    }
400
    
401
    @Override
402
    public String getName() {
403
        return DuplicateEditingProviderFactory.PROVIDER_NAME;
404
    }
405

    
406
    @Override
407
    public Object getValue(EditingServiceParameter parameter) {
408
        return values!=null?values.get(parameter):null;
409
    }
410
    
411
    private ISimpleTextSymbol getTextSymbol(){
412
        SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager();
413
        ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol();
414
        textSymbol.setFontSize(10);
415
        return textSymbol;
416
    }
417

    
418
    @Override
419
    public boolean isEnabled(EditingServiceParameter parameter) {
420

    
421
        if (parameter == equidistantCopies) {
422
            return true;
423
        }
424
        return true;
425
    }
426

    
427
}