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.rectangularmatrix / src / main / java / org / gvsig / vectorediting / lib / prov / rectangularmatrix / RectangularMatrixEditingProvider.java @ 2869

History | View | Annotate | Download (19.2 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.rectangularmatrix;
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
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureSelection;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.aggregate.Aggregate;
41
import org.gvsig.fmap.geom.aggregate.MultiCurve;
42
import org.gvsig.fmap.geom.aggregate.MultiPoint;
43
import org.gvsig.fmap.geom.aggregate.MultiSurface;
44
import org.gvsig.fmap.geom.primitive.Curve;
45
import org.gvsig.fmap.geom.primitive.Point;
46
import org.gvsig.fmap.geom.primitive.Surface;
47
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
48
import org.gvsig.symbology.SymbologyLocator;
49
import org.gvsig.symbology.SymbologyManager;
50
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dispose.DisposableIterator;
53
import org.gvsig.tools.dispose.DisposeUtils;
54
import org.gvsig.tools.dynobject.DynObject;
55
import org.gvsig.tools.exception.BaseException;
56
import org.gvsig.tools.i18n.I18nManager;
57
import org.gvsig.tools.service.spi.ProviderServices;
58
import org.gvsig.vectorediting.lib.api.DrawingStatus;
59
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
60
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
61
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
62
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
63
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
64
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
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
import org.slf4j.Logger;
74
import org.slf4j.LoggerFactory;
75

    
76
/**
77
 * @author llmarques
78
 *
79
 */
80
public class RectangularMatrixEditingProvider extends AbstractEditingProvider
81
    implements EditingProvider {
82
    
83
    private static final Logger LOGGER = LoggerFactory.getLogger(RectangularMatrixEditingProvider.class);
84

    
85
    private final FeatureStore featureStore;
86

    
87
    private Map<EditingServiceParameter, Object> values;
88

    
89
    private final EditingServiceParameter selection;
90

    
91
    private final EditingServiceParameter columns;
92

    
93
    private final EditingServiceParameter rows;
94

    
95
    private final EditingServiceParameter basePoint;
96

    
97
    private final EditingServiceParameter columnDistance;
98

    
99
    private final EditingServiceParameter rowDistance;
100

    
101
    /**
102
     * Default constructor.
103
     *
104
     * @param services
105
     *            available services for this provider
106
     * @param parameters
107
     *            of this provider
108
     */
109
    public RectangularMatrixEditingProvider(DynObject parameters,
110
        ProviderServices services) {
111
        super(services);
112

    
113
        this.featureStore =
114
            (FeatureStore) parameters
115
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
116

    
117
        this.selection =
118
            new DefaultEditingServiceParameter("selection", "selection",
119
                EditingServiceParameter.TYPE.SELECTION);
120

    
121
        this.basePoint =
122
            new DefaultEditingServiceParameter("indicate_new_point",
123
                "indicate_new_point", EditingServiceParameter.TYPE.POSITION);
124

    
125
        this.columns =
126
            new DefaultEditingServiceParameter("columns_number",
127
                "columns_number", EditingServiceParameter.TYPE.VALUE);
128

    
129
        this.rows =
130
            new DefaultEditingServiceParameter("rows_number", "rows_number",
131
                EditingServiceParameter.TYPE.VALUE);
132

    
133
        this.columnDistance =
134
            new DefaultEditingServiceParameter("distance_between_columns",
135
                "distance_between_columns", EditingServiceParameter.TYPE.VALUE,
136
                EditingServiceParameter.TYPE.POSITION);
137

    
138
        this.rowDistance =
139
            new DefaultEditingServiceParameter("distance_between_rows",
140
                "distance_between_rows", EditingServiceParameter.TYPE.VALUE,
141
                EditingServiceParameter.TYPE.POSITION);
142
    }
143

    
144
    @Override
145
    public EditingServiceParameter next() {
146
        if (values.get(selection) == null) {
147
            return selection;
148
        } else if (values.get(columns) == null) {
149
            return columns;
150
        } else if (values.get(rows) == null) {
151
            return rows;
152
        } else if (values.get(basePoint) == null) {
153
            return basePoint;
154
        } else if (values.get(columnDistance) == null) {
155
            return columnDistance;
156
        } else if (values.get(rowDistance) == null) {
157
            return rowDistance;
158
        }
159
        return null;
160
    }
161

    
162
    @Override
163
    public DrawingStatus getDrawingStatus(Point mousePosition)
164
        throws DrawServiceException {
165

    
166
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
167

    
168
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
169
        I18nManager i18nManager = ToolsLocator.getI18nManager();
170

    
171
        FeatureSelection featureSelection =
172
            (FeatureSelection) values.get(selection);
173
        Integer columnsValue = (Integer) values.get(columns);
174
        Integer rowsValue = (Integer) values.get(rows);
175
        Point basePointValue = (Point) values.get(basePoint);
176
        Double columnDistanceValue = (Double) values.get(columnDistance);
177
        Double rowDistanceValue = (Double) values.get(rowDistance);
178

    
179
        if (featureSelection != null && columnsValue != null
180
            && rowsValue != null && basePointValue != null) {
181

    
182
            int subtype = basePointValue.getGeometryType().getSubType();
183

    
184
            if (columnDistanceValue == null) {
185
                columnDistanceValue =
186
                    mousePosition.getX() - basePointValue.getX();
187
            }
188

    
189
            if (rowDistanceValue == null) {
190
                rowDistanceValue = mousePosition.getY() - basePointValue.getY();
191
            }
192

    
193
            // Creation of symbology
194
            EditingProviderManager editingProviderManager =
195
                EditingProviderLocator.getProviderManager();
196
            ISymbol auxiliaryPointSymbolEditing =
197
                editingProviderManager
198
                    .getSymbol("auxiliary-point-symbol-editing");
199

    
200
            // Create base point indicator
201
            drawingStatus.addStatus(basePointValue,
202
                auxiliaryPointSymbolEditing, "");
203

    
204
            // Create distance text indicator
205
            try {
206
                double textDistance =
207
                    basePointValue.distance(mousePosition) / 6;
208
                String columnsText =
209
                    i18nManager.getTranslation("distance_between_columns")
210
                        .concat(" ")
211
                        .concat(String.valueOf(columnDistanceValue));
212
                Geometry pointText =
213
                    geometryManager.createPoint(
214
                        mousePosition.getX() + textDistance
215
                            * Math.cos(Math.PI / 4),
216
                        mousePosition.getY() + textDistance
217
                            * Math.sin(Math.PI / 4), subtype);
218

    
219
                drawingStatus
220
                    .addStatus(pointText, getTextSymbol(), columnsText);
221

    
222
                String rowsText =
223
                    i18nManager.getTranslation("distance_between_rows")
224
                        .concat(" ").concat(String.valueOf(rowDistanceValue));
225
                pointText =
226
                    geometryManager.createPoint(
227
                        mousePosition.getX() + textDistance
228
                            * Math.cos(Math.PI / 4),
229
                        mousePosition.getY() + textDistance
230
                            * Math.sin(3 * Math.PI / 2), subtype);
231

    
232
                drawingStatus.addStatus(pointText, getTextSymbol(), rowsText);
233

    
234
            } catch (BaseException e) {
235
                throw new DrawServiceException(e);
236
            }
237

    
238
            DisposableIterator it = null;
239
            try {
240
                it = featureSelection.fastIterator();
241
                while (it.hasNext()) {
242
                    Feature feature = (Feature) it.next();
243
                    
244
                    ISymbol previewSymbol = this.getPreviewSymbol(feature);
245
                    
246
                    Geometry geometry = feature.getDefaultGeometry();
247
                    Geometry[][] matrix =
248
                        createRectangularMatrix(geometry, columnsValue,
249
                            rowsValue, basePointValue, columnDistanceValue,
250
                            rowDistanceValue);
251

    
252
                    for (Geometry[] row : matrix) {
253
                        for (Geometry element : row) {
254
                            if (element != null) {
255
                                ISymbol symbol = getSymbol(element);
256
                                if (element instanceof Aggregate) {
257
                                    int primitivesNumber = ((Aggregate) element).getPrimitivesNumber();
258
                                    for (int k = 0; k < primitivesNumber; k++) {
259
                                        drawingStatus.addStatus(((Aggregate) element).getPrimitiveAt(k), symbol, "");
260
                                        drawingStatus.addStatus(((Aggregate) element).getPrimitiveAt(k), previewSymbol, "");
261
                                    }
262
                                } else {
263
                                    drawingStatus.addStatus(element, symbol, "");
264
                                    drawingStatus.addStatus(element, previewSymbol, "");
265
                                }
266
                            }
267
                        }
268
                    }
269
                }
270
            } catch (BaseException e) {
271
                throw new DrawServiceException(e);
272
            } finally {
273
                DisposeUtils.disposeQuietly(it);
274
            }
275
        }
276
        return drawingStatus;
277
    }
278

    
279
    private ISymbol getSymbol(Geometry geometry) {
280

    
281
        EditingProviderManager editingProviderManager =
282
            EditingProviderLocator.getProviderManager();
283
        ISymbol auxiliaryPointSymbolEditing =
284
            editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
285
        ISymbol lineSymbolEditing =
286
            editingProviderManager.getSymbol("line-symbol-editing");
287
        ISymbol polygonSymbolEditing =
288
            editingProviderManager.getSymbol("polygon-symbol-editing");
289

    
290
        if (geometry instanceof Curve || geometry instanceof MultiCurve) {
291
            return lineSymbolEditing;
292
        } else if (geometry instanceof Surface
293
            || geometry instanceof MultiSurface) {
294
            return polygonSymbolEditing;
295
        } else if (geometry instanceof Point || geometry instanceof MultiPoint) {
296
            return auxiliaryPointSymbolEditing;
297
        }
298
        return null;
299
    }
300

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

    
310
    private Geometry[][] createRectangularMatrix(Geometry geometry,
311
        int columnsValue, int rowsValue, Point basePointValue,
312
        double spacingColumns, double spacingRows) throws BaseException {
313

    
314
        Geometry[][] geometryMatrix = new Geometry[columnsValue][rowsValue];
315

    
316
        for (int i = 0; i < columnsValue; i++) {
317

    
318
            for (int j = 0; j < rowsValue; j++) {
319

    
320
                if (i == 0 && j == 0) {
321
                    continue;
322
                }
323

    
324
                AffineTransform at = new AffineTransform();
325
                at.translate(spacingColumns * i, spacingRows * j);
326
                Geometry clonedGeoemtry = geometry.cloneGeometry();
327
                clonedGeoemtry.transform(at);
328
                geometryMatrix[i][j] = clonedGeoemtry;
329
            }
330
        }
331

    
332
        return geometryMatrix;
333
    }
334

    
335
    @Override
336
    public void stop() throws StopServiceException {
337
        values.clear();
338
    }
339

    
340
    @Override
341
    public List<EditingServiceParameter> getParameters() {
342
        List<EditingServiceParameter> parameters =
343
            new ArrayList<>();
344
        parameters.add(basePoint);
345
        parameters.add(columns);
346
        parameters.add(rows);
347
        parameters.add(columnDistance);
348
        parameters.add(rowDistance);
349
        return parameters;
350
    }
351

    
352
    @Override
353
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
354
        validateAndInsertValue(parameter, value);
355
    }
356

    
357
    @Override
358
    public void setValue(Object value) throws InvalidEntryException {
359
        EditingServiceParameter parameter = next();
360
        validateAndInsertValue(parameter, value);
361
    }
362

    
363
    private void validateAndInsertValue(EditingServiceParameter parameter,
364
        Object value) throws InvalidEntryException {
365
        boolean insertedValue = false;
366

    
367
        if (parameter.equals(selection) && value instanceof FeatureSelection) {
368
            FeatureSelection featureSelection = (FeatureSelection) value;
369
            if (featureSelection.getSelectedCount() > 0) {
370
                values.put(parameter, featureSelection);
371
                insertedValue = true;
372
            }
373
        } else if (parameter.equals(columns) || parameter.equals(rows)) {
374

    
375
            if (value instanceof Double) {
376
                Double number = (Double) value;
377
                if(number>=1){
378
                    values.put(parameter, number.intValue());
379
                    insertedValue = true;
380
                }
381
            }
382

    
383
        } else if (parameter.equals(basePoint) && value instanceof Point) {
384

    
385
            values.put(basePoint, value);
386
            insertedValue = true;
387

    
388
        } else if (parameter.equals(columnDistance)
389
            || parameter.equals(rowDistance)) {
390

    
391
            if (value instanceof Double) {
392
                Double doubleValue = (Double) value;
393
                values.put(parameter, doubleValue);
394
                insertedValue = true;
395

    
396
            } else if (value instanceof Point) {
397

    
398
                Point basePointValue = (Point) values.get(basePoint);
399
                Point valuePoint = (Point) value;
400
                double distance = 0;
401
                if (parameter.equals(columnDistance)) {
402
                    distance = valuePoint.getX() - basePointValue.getX();
403
                    values.put(columnDistance, distance);
404
                } else if (parameter.equals(rowDistance)) {
405
                    distance = valuePoint.getY() - basePointValue.getY();
406
                    values.put(rowDistance, distance);
407
                }
408
                insertedValue = true;
409
            }
410
        }
411

    
412
        if (!insertedValue) {
413
            throw new InvalidEntryException(null);
414
        }
415
    }
416

    
417
    @Override
418
    public Geometry finish() throws FinishServiceException {
419
        return null;
420
    }
421

    
422
    @Override
423
    public void finishAndStore() throws FinishServiceException {
424

    
425
        FeatureSelection featureSelection =
426
            (FeatureSelection) values.get(selection);
427
        final Integer columnsValue = (Integer) values.get(columns);
428
        final Integer rowsValue = (Integer) values.get(rows);
429
        final Point basePointValue = (Point) values.get(basePoint);
430
        final Double spacingColumnsValue = (Double) values.get(columnDistance);
431
        final Double spacingRowsValue = (Double) values.get(rowDistance);
432

    
433
        final EditingProviderServices editingProviderServices =
434
            (EditingProviderServices) getProviderServices();
435

    
436
        if (featureSelection != null && columnsValue != null
437
            && rowsValue != null && basePointValue != null
438
            && spacingColumnsValue != null && spacingRowsValue != null) {
439

    
440
            try {
441
                featureSelection.accept((Object obj) -> {
442
                    Feature feature = (Feature) obj;
443
                    Geometry geometry = feature.getDefaultGeometry();
444
                    Geometry[][] matrix =
445
                            createRectangularMatrix(geometry, columnsValue,
446
                                    rowsValue, basePointValue, spacingColumnsValue,
447
                                    spacingRowsValue);
448
                    
449
                    for (Geometry[] matrix1 : matrix) {
450
                        for (Geometry item : matrix1) {
451
                            EditableFeature eFeature =
452
                                    editingProviderServices
453
                                            .getFeatureCopyWithoutUniqueIndex(featureStore,
454
                                                    feature);
455
                            eFeature.setDefaultGeometry(item);
456
                            editingProviderServices
457
                                    .insertFeatureIntoFeatureStore(eFeature,
458
                                            featureStore);
459
                        }
460
                    }
461
                });
462
            } catch (BaseException e) {
463
                throw new FinishServiceException(e);
464
            }
465
        }
466
    }
467

    
468
    @Override
469
    public void start() throws StartServiceException, InvalidEntryException {
470
        values = new HashMap<>();
471
        FeatureSelection selected = null;
472
        if (featureStore != null && values.get(selection) == null) {
473
            try {
474
                selected = featureStore.getFeatureSelection();
475
            } catch (DataException e) {
476
                throw new StartServiceException(e);
477
            }
478
            if (selected.getSelectedCount() > 0) {
479
                try {
480
                    setValue(selected);
481
                } catch (InvalidEntryException e) {
482
                    throw new InvalidEntryException(e);
483
                }
484
            }
485
        }
486
    }
487

    
488
    @Override
489
    public String getName() {
490
        return RectangularMatrixEditingProviderFactory.PROVIDER_NAME;
491
    }
492
    @Override
493
    public Object getValue(EditingServiceParameter parameter) {
494
        return values!=null?values.get(parameter):null;
495
    }
496
}