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

History | View | Annotate | Download (18.5 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

    
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.primitive.Curve;
46
import org.gvsig.fmap.geom.primitive.Point;
47
import org.gvsig.fmap.geom.primitive.Surface;
48
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
49
import org.gvsig.symbology.SymbologyLocator;
50
import org.gvsig.symbology.SymbologyManager;
51
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dispose.DisposableIterator;
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.tools.visitor.VisitCanceledException;
59
import org.gvsig.tools.visitor.Visitor;
60
import org.gvsig.vectorediting.lib.api.DrawingStatus;
61
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
62
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
63
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
64
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
65
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
66
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
67
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
68
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
69
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
70
import org.gvsig.vectorediting.lib.spi.EditingProvider;
71
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
72
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
73
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
74
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
75

    
76
/**
77
 * @author llmarques
78
 *
79
 */
80
public class RectangularMatrixEditingProvider extends AbstractEditingProvider
81
    implements EditingProvider {
82

    
83
    private FeatureStore featureStore;
84

    
85
    private Map<EditingServiceParameter, Object> values;
86

    
87
    private EditingServiceParameter selection;
88

    
89
    private EditingServiceParameter columns;
90

    
91
    private EditingServiceParameter rows;
92

    
93
    private EditingServiceParameter basePoint;
94

    
95
    private EditingServiceParameter columnDistance;
96

    
97
    private EditingServiceParameter rowDistance;
98

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

    
111
        this.featureStore =
112
            (FeatureStore) parameters
113
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
114

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

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

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

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

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

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

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

    
159
    public DrawingStatus getDrawingStatus(Point mousePosition)
160
        throws DrawServiceException {
161

    
162
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
163

    
164
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
165
        I18nManager i18nManager = ToolsLocator.getI18nManager();
166

    
167
        FeatureSelection featureSelection =
168
            (FeatureSelection) values.get(selection);
169
        Integer columnsValue = (Integer) values.get(columns);
170
        Integer rowsValue = (Integer) values.get(rows);
171
        Point basePointValue = (Point) values.get(basePoint);
172
        Double columnDistanceValue = (Double) values.get(columnDistance);
173
        Double rowDistanceValue = (Double) values.get(rowDistance);
174

    
175
        if (featureSelection != null && columnsValue != null
176
            && rowsValue != null && basePointValue != null) {
177

    
178
            int subtype = basePointValue.getGeometryType().getSubType();
179

    
180
            if (columnDistanceValue == null) {
181
                columnDistanceValue =
182
                    mousePosition.getX() - basePointValue.getX();
183
            }
184

    
185
            if (rowDistanceValue == null) {
186
                rowDistanceValue = mousePosition.getY() - basePointValue.getY();
187
            }
188

    
189
            // Creation of symbology
190
            EditingProviderManager editingProviderManager =
191
                EditingProviderLocator.getProviderManager();
192
            ISymbol auxiliaryPointSymbolEditing =
193
                editingProviderManager
194
                    .getSymbol("auxiliary-point-symbol-editing");
195

    
196
            // Create base point indicator
197
            drawingStatus.addStatus(basePointValue,
198
                auxiliaryPointSymbolEditing, "");
199

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

    
215
                drawingStatus
216
                    .addStatus(pointText, getTextSymbol(), columnsText);
217

    
218
                String rowsText =
219
                    i18nManager.getTranslation("space_between_rows")
220
                        .concat(" ").concat(String.valueOf(rowDistanceValue));
221
                pointText =
222
                    geometryManager.createPoint(
223
                        mousePosition.getX() + textDistance
224
                            * Math.cos(Math.PI / 4),
225
                        mousePosition.getY() + textDistance
226
                            * Math.sin(3 * Math.PI / 2), subtype);
227

    
228
                drawingStatus.addStatus(pointText, getTextSymbol(), rowsText);
229

    
230
            } catch (BaseException e) {
231
                throw new DrawServiceException(e);
232
            }
233

    
234
            DisposableIterator it = null;
235
            try {
236
                it = featureSelection.fastIterator();
237
                while (it.hasNext()) {
238
                    Feature feature = (Feature) it.next();
239
                    Geometry geometry = feature.getDefaultGeometry();
240
                    Geometry[][] matrix =
241
                        createRectangularMatrix(geometry, columnsValue,
242
                            rowsValue, basePointValue, columnDistanceValue,
243
                            rowDistanceValue);
244

    
245
                    for (int i = 0; i < matrix.length; i++) {
246
                        for (int j = 0; j < matrix[i].length; j++) {
247

    
248
                            ISymbol symbol = getSymbol(matrix[i][j]);
249

    
250
                            if (matrix[i][j] instanceof Aggregate) {
251
                                int primitivesNumber =
252
                                    ((Aggregate) matrix[i][j])
253
                                        .getPrimitivesNumber();
254
                                for (int k = 0; k < primitivesNumber; k++) {
255
                                    drawingStatus.addStatus(
256
                                        ((Aggregate) matrix[i][j])
257
                                            .getPrimitiveAt(k), symbol, "");
258
                                }
259
                            } else {
260
                                drawingStatus.addStatus(matrix[i][j], symbol,
261
                                    "");
262
                            }
263
                        }
264
                    }
265
                }
266
            } catch (BaseException e) {
267
                throw new DrawServiceException(e);
268
            } finally {
269
                it.dispose();
270
            }
271
        }
272
        return drawingStatus;
273
    }
274

    
275
    private ISymbol getSymbol(Geometry geometry) {
276

    
277
        EditingProviderManager editingProviderManager =
278
            EditingProviderLocator.getProviderManager();
279
        ISymbol auxiliaryPointSymbolEditing =
280
            editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
281
        ISymbol lineSymbolEditing =
282
            editingProviderManager.getSymbol("line-symbol-editing");
283
        ISymbol polygonSymbolEditing =
284
            editingProviderManager.getSymbol("polygon-symbol-editing");
285

    
286
        if (geometry instanceof Curve || geometry instanceof MultiCurve) {
287
            return lineSymbolEditing;
288
        } else if (geometry instanceof Surface
289
            || geometry instanceof MultiSurface) {
290
            return polygonSymbolEditing;
291
        } else if (geometry instanceof Point || geometry instanceof MultiPoint) {
292
            return auxiliaryPointSymbolEditing;
293
        }
294
        return null;
295
    }
296

    
297
    private ISimpleTextSymbol getTextSymbol() {
298
        SymbologyManager symbologyManager =
299
            SymbologyLocator.getSymbologyManager();
300
        ISimpleTextSymbol textSymbol =
301
            symbologyManager.createSimpleTextSymbol();
302
        textSymbol.setFontSize(10);
303
        return textSymbol;
304
    }
305

    
306
    private Geometry[][] createRectangularMatrix(Geometry geometry,
307
        int columnsValue, int rowsValue, Point basePointValue,
308
        double spacingColumns, double spacingRows) throws BaseException {
309

    
310
        Geometry[][] geometryMatrix = new Geometry[columnsValue][rowsValue];
311

    
312
        for (int i = 0; i < columnsValue; i++) {
313

    
314
            for (int j = 0; j < rowsValue; j++) {
315

    
316
                if (i == 0 && j == 0) {
317
                    continue;
318
                }
319

    
320
                AffineTransform at = new AffineTransform();
321
                at.translate(spacingColumns * i, spacingRows * j);
322
                Geometry clonedGeoemtry = geometry.cloneGeometry();
323
                clonedGeoemtry.transform(at);
324
                geometryMatrix[i][j] = clonedGeoemtry;
325
            }
326
        }
327

    
328
        return geometryMatrix;
329
    }
330

    
331
    public void stop() throws StopServiceException {
332
        values.clear();
333
    }
334

    
335
    public List<EditingServiceParameter> getParameters() {
336
        List<EditingServiceParameter> parameters =
337
            new ArrayList<EditingServiceParameter>();
338
        parameters.add(basePoint);
339
        parameters.add(columns);
340
        parameters.add(rows);
341
        parameters.add(columnDistance);
342
        parameters.add(rowDistance);
343
        return parameters;
344
    }
345

    
346
    public void setValue(Object value) throws InvalidEntryException {
347
        EditingServiceParameter parameter = next();
348
        validateAndInsertValue(parameter, value);
349
    }
350

    
351
    private void validateAndInsertValue(EditingServiceParameter parameter,
352
        Object value) throws InvalidEntryException {
353
        boolean insertedValue = false;
354

    
355
        if (parameter.equals(selection) && value instanceof FeatureSelection) {
356
            FeatureSelection featureSelection = (FeatureSelection) value;
357
            if (featureSelection.getSelectedCount() > 0) {
358
                values.put(parameter, featureSelection);
359
                insertedValue = true;
360
            }
361
        } else if (parameter.equals(columns) || parameter.equals(rows)) {
362

    
363
            if (value instanceof Double) {
364
                Double number = (Double) value;
365
                values.put(parameter, number.intValue());
366
                insertedValue = true;
367
            }
368

    
369
        } else if (parameter.equals(basePoint) && value instanceof Point) {
370

    
371
            values.put(basePoint, value);
372
            insertedValue = true;
373

    
374
        } else if (parameter.equals(columnDistance)
375
            || parameter.equals(rowDistance)) {
376

    
377
            if (value instanceof Double) {
378
                Double doubleValue = (Double) value;
379
                values.put(parameter, doubleValue);
380
                insertedValue = true;
381

    
382
            } else if (value instanceof Point) {
383

    
384
                Point basePointValue = (Point) values.get(basePoint);
385
                Point valuePoint = (Point) value;
386
                double distance = 0;
387
                if (parameter.equals(columnDistance)) {
388
                    distance = valuePoint.getX() - basePointValue.getX();
389
                    values.put(columnDistance, distance);
390
                } else if (parameter.equals(rowDistance)) {
391
                    distance = valuePoint.getY() - basePointValue.getY();
392
                    values.put(rowDistance, distance);
393
                }
394
                insertedValue = true;
395
            }
396
        }
397

    
398
        if (!insertedValue) {
399
            throw new InvalidEntryException(null);
400
        }
401
    }
402

    
403
    public Geometry finish() throws FinishServiceException {
404
        return null;
405
    }
406

    
407
    public void finishAndStore() throws FinishServiceException {
408

    
409
        FeatureSelection featureSelection =
410
            (FeatureSelection) values.get(selection);
411
        final Integer columnsValue = (Integer) values.get(columns);
412
        final Integer rowsValue = (Integer) values.get(rows);
413
        final Point basePointValue = (Point) values.get(basePoint);
414
        final Double spacingColumnsValue = (Double) values.get(columnDistance);
415
        final Double spacingRowsValue = (Double) values.get(rowDistance);
416

    
417
        final EditingProviderServices editingProviderServices =
418
            (EditingProviderServices) getProviderServices();
419

    
420
        if (featureSelection != null && columnsValue != null
421
            && rowsValue != null && basePointValue != null
422
            && spacingColumnsValue != null && spacingRowsValue != null) {
423

    
424
            try {
425
                featureSelection.accept(new Visitor() {
426

    
427
                    public void visit(Object obj)
428
                        throws VisitCanceledException, BaseException {
429

    
430
                        Feature feature = (Feature) obj;
431
                        Geometry geometry = feature.getDefaultGeometry();
432
                        Geometry[][] matrix =
433
                            createRectangularMatrix(geometry, columnsValue,
434
                                rowsValue, basePointValue, spacingColumnsValue,
435
                                spacingRowsValue);
436

    
437
                        for (int i = 0; i < matrix.length; i++) {
438
                            for (int j = 0; j < matrix[i].length; j++) {
439
                                EditableFeature eFeature =
440
                                    editingProviderServices
441
                                        .getFeatureCopyWithoutPK(featureStore,
442
                                            feature);
443
                                eFeature.setDefaultGeometry(matrix[i][j]);
444
                                editingProviderServices
445
                                    .insertFeatureIntoFeatureStore(eFeature,
446
                                        featureStore);
447
                            }
448
                        }
449
                    }
450
                });
451
            } catch (BaseException e) {
452
                throw new FinishServiceException(e);
453
            }
454
        }
455
    }
456

    
457
    public void start() throws StartServiceException, InvalidEntryException {
458
        values = new HashMap<EditingServiceParameter, Object>();
459
        FeatureSelection selected = null;
460
        if (featureStore != null && values.get(selection) == null) {
461
            try {
462
                selected = featureStore.getFeatureSelection();
463
            } catch (DataException e) {
464
                throw new StartServiceException(e);
465
            }
466
            if (selected.getSelectedCount() > 0) {
467
                try {
468
                    setValue(selected);
469
                } catch (InvalidEntryException e) {
470
                    throw new InvalidEntryException(e);
471
                }
472
            }
473
        }
474
    }
475

    
476
    public String getName() {
477
        return RectangularMatrixEditingProviderFactory.PROVIDER_NAME;
478
    }
479
}