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.regularpolygon / src / main / java / org / gvsig / vectorediting / lib / prov / regularpolygon / RegularPolygonEditingProvider.java @ 2101

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

    
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.LinkedHashMap;
30
import java.util.List;
31
import java.util.Map;
32

    
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
36
import org.gvsig.fmap.geom.Geometry.TYPES;
37
import org.gvsig.fmap.geom.GeometryLocator;
38
import org.gvsig.fmap.geom.GeometryManager;
39
import org.gvsig.fmap.geom.aggregate.MultiCurve;
40
import org.gvsig.fmap.geom.primitive.Circumference;
41
import org.gvsig.fmap.geom.primitive.Curve;
42
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
43
import org.gvsig.fmap.geom.primitive.Point;
44
import org.gvsig.fmap.geom.primitive.Surface;
45
import org.gvsig.fmap.geom.type.GeometryType;
46
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
47
import org.gvsig.tools.ToolsLocator;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.exception.BaseException;
50
import org.gvsig.tools.i18n.I18nManager;
51
import org.gvsig.tools.service.spi.ProviderServices;
52
import org.gvsig.vectorediting.lib.api.DrawingStatus;
53
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
54
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
55
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
56
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
57
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
58
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
59
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
60
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
61
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
62
import org.gvsig.vectorediting.lib.spi.EditingProvider;
63
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
64
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
65
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
66
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
67

    
68
/**
69
 *
70
 * @author llmarques
71
 *
72
 */
73
public class RegularPolygonEditingProvider extends AbstractEditingProvider
74
    implements EditingProvider {
75

    
76
    protected final Integer DEFAULT_VALUE_SIDES = 5;
77
    protected final String DEFAULT_VALUE_MODE = "key_inscribed";
78
    protected final String SIDES_KEY= "sides";
79
    protected final String MODE_KEY = "mode";
80

    
81
    protected EditingServiceParameter polygonSides;
82

    
83
    protected EditingServiceParameter center;
84

    
85
    protected EditingServiceParameter mode;
86

    
87
    protected EditingServiceParameter pointOfCircle;
88

    
89
    protected Map<EditingServiceParameter, Object> values;
90

    
91
    protected Map<String, String> defaultValues = null;
92

    
93
    protected Map<String, String> options;
94

    
95
    protected FeatureStore featureStore;
96

    
97
    public RegularPolygonEditingProvider(ProviderServices providerServices,
98
        DynObject parameters) {
99
        super(providerServices);
100
        this.featureStore =
101
            (FeatureStore) parameters
102
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
103

    
104
        Integer sideDefaultValue = Integer.valueOf((String)getDefaultValues().get(SIDES_KEY));
105
        if (sideDefaultValue == null){
106
            sideDefaultValue = DEFAULT_VALUE_SIDES;
107
        }
108

    
109
        polygonSides =
110
            new DefaultEditingServiceParameter(SIDES_KEY, sideDefaultValue,
111
                "sides_of_regular_polygon", EditingServiceParameter.TYPE.VALUE);
112

    
113
        I18nManager i18nManager = ToolsLocator.getI18nManager();
114
        options = new LinkedHashMap<String, String>();
115
        options.put(i18nManager.getTranslation("key_inscribed"), "inscribed");
116
        options.put(i18nManager.getTranslation("key_circumscribed"),
117
            "circumscribed");
118

    
119
        EditingProviderServices editingProviderServices =
120
            (EditingProviderServices) getProviderServices();
121

    
122
        String consoleMsg =
123
            editingProviderServices.makeConsoleMessage(null, options);
124

    
125
        String modeDefaultValue = (String)getDefaultValues().get(MODE_KEY);
126
        if (modeDefaultValue == null){
127
            modeDefaultValue = DEFAULT_VALUE_MODE;
128
        }
129

    
130
        mode =
131
            new DefaultEditingServiceParameter(MODE_KEY, consoleMsg, options,
132
                modeDefaultValue,
133
                EditingServiceParameter.TYPE.OPTION);
134

    
135
        center =
136
            new DefaultEditingServiceParameter("center",
137
                "center_of_regular_polygon",
138
                EditingServiceParameter.TYPE.POSITION);
139

    
140
        pointOfCircle =
141
            new DefaultEditingServiceParameter("point_of_circle",
142
                "point_of_circle", EditingServiceParameter.TYPE.POSITION);
143
    }
144

    
145
    private Map<String, String> getDefaultValues() {
146
        if (this.defaultValues == null){
147
            EditingProviderManager editingProviderManager =
148
                EditingProviderLocator.getProviderManager();
149
            this.defaultValues = editingProviderManager.getDefaultValues("regularpolygon");
150
        }
151
        return this.defaultValues;
152
    }
153

    
154
    public EditingServiceParameter next() {
155
        if (values.get(polygonSides) == null) {
156
            return polygonSides;
157
        } else if (values.get(mode) == null) {
158
            return mode;
159
        } else if (values.get(center) == null) {
160
            return center;
161
        } else if (values.get(pointOfCircle) == null) {
162
            return pointOfCircle;
163
        }
164
        return null;
165
    }
166

    
167
    public DrawingStatus getDrawingStatus(Point mousePosition)
168
        throws DrawServiceException {
169
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
170
        EditingProviderManager editingProviderManager =
171
            EditingProviderLocator.getProviderManager();
172
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
173
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
174
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
175
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
176

    
177
        if (values != null) {
178

    
179
            Integer sidesValue = (Integer) values.get(polygonSides);
180
            String modeValue = (String) values.get(mode);
181
            Point centerValue = (Point) values.get(center);
182

    
183
            if (centerValue != null) {
184

    
185
                try {
186

    
187
                    EditingProviderServices editingProviderServices =
188
                        (EditingProviderServices) getProviderServices();
189
                    int subtype =
190
                        editingProviderServices.getSubType(featureStore);
191

    
192
                    if (modeValue == null) {
193
                        modeValue = (String)getDefaultValues().get(MODE_KEY);
194
                    }
195

    
196
                    Curve polygon =
197
                        calculateRegularPolygon(modeValue, centerValue,
198
                            mousePosition, sidesValue);
199
                    Curve line =
200
                        editingProviderServices.createLine(centerValue,
201
                            mousePosition, subtype);
202

    
203
                    double radius = mousePosition.distance(centerValue);
204
                    Circumference circumference = (Circumference) geometryManager.create(TYPES.CIRCUMFERENCE, SUBTYPES.GEOM2D);
205
                    circumference.setPoints(centerValue, radius);
206

    
207
                    drawingStatus.addStatus(circumference, auxiliaryLineSymbolEditing, "");
208
                    if(polygon!=null){
209
                        drawingStatus.addStatus(polygon, lineSymbolEditing, "");
210
                    }
211
                    drawingStatus.addStatus(centerValue, auxiliaryPointSymbolEditing, "");
212
                    drawingStatus.addStatus(line, auxiliaryLineSymbolEditing, "");
213

    
214
                } catch (BaseException e) {
215
                    throw new DrawServiceException(e);
216
                }
217
            }
218
        }
219
        return drawingStatus;
220
    }
221

    
222
    /**
223
     * Calculates polygon as of mode (inscribed or circumscribed), center of
224
     * polygon, point of circle and number of sides.
225
     *
226
     * @param modeValue
227
     *            of polygon (inscribed or circumscribed).
228
     * @param centerValue
229
     *            of polygon
230
     * @param pointOfCircleValue
231
     *            of circle that inscribe or circumscribe polygon
232
     * @param sidesValue
233
     *            number of sides.
234
     */
235
    protected Curve calculateRegularPolygon(String modeValue,
236
        Point centerValue, Point pointOfCircle, int sidesValue)
237
        throws BaseException {
238

    
239
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
240

    
241
        EditingProviderServices editingProviderServices =
242
            (EditingProviderServices) getProviderServices();
243
        int subtype = editingProviderServices.getSubType(featureStore);
244

    
245
        Curve polygon =
246
            (Curve) geometryManager.create(Geometry.TYPES.CURVE, subtype);
247

    
248
        double initAngle =
249
            editingProviderServices.getAngle(centerValue, pointOfCircle);
250
        double radiusValue = pointOfCircle.distance(centerValue);
251
        if(radiusValue == 0.0){
252
            return null;
253
        }
254
        double theta = -(2 * Math.PI) / sidesValue;
255

    
256
        if (modeValue.equalsIgnoreCase("key_inscribed")) {
257

    
258
            for (int i = 0; i < sidesValue; ++i) {
259

    
260
                double x =
261
                    centerValue.getX()
262
                        + (radiusValue * Math.cos((theta * i) + initAngle));
263
                double y =
264
                    centerValue.getY()
265
                        + (radiusValue * Math.sin((theta * i) + initAngle));
266

    
267
                Point createPoint =
268
                    editingProviderServices.createPoint(x, y, subtype);
269

    
270
                polygon.addVertex(createPoint);
271
            }
272

    
273
        } else if (modeValue.equalsIgnoreCase("key_circumscribed")) {
274

    
275
            for (int i = 0; i < sidesValue; ++i) {
276

    
277
                double x =
278
                    centerValue.getX()
279
                        + (radiusValue * Math.cos((theta * i) + initAngle));
280
                double y =
281
                    centerValue.getY()
282
                        + (radiusValue * Math.sin((theta * i) + initAngle));
283

    
284
                Point apothemPoint =
285
                    editingProviderServices.createPoint(x, y, subtype);
286

    
287
                Double[] apothemParams =
288
                    editingProviderServices.getLineParams(centerValue,
289
                        apothemPoint);
290
                Point[] perpendicular =
291
                    editingProviderServices.getPerpendicular(apothemParams[0],
292
                        apothemParams[1], apothemPoint, subtype);
293

    
294
                double x1 =
295
                    centerValue.getX()
296
                        + (radiusValue * Math
297
                            .cos((theta * (i + 1)) + initAngle));
298
                double y1 =
299
                    centerValue.getY()
300
                        + (radiusValue * Math
301
                            .sin((theta * (i + 1)) + initAngle));
302

    
303
                Point nextApothemPoint =
304
                    editingProviderServices.createPoint(x1, y1, subtype);
305

    
306
                Double[] nextApothemParams =
307
                    editingProviderServices.getLineParams(centerValue,
308
                        nextApothemPoint);
309
                Point[] nextPerpendicular =
310
                    editingProviderServices.getPerpendicular(
311
                        nextApothemParams[0], nextApothemParams[1],
312
                        nextApothemPoint, subtype);
313

    
314
                Point vertex =
315
                    editingProviderServices.getIntersection(perpendicular,
316
                        nextPerpendicular, subtype);
317

    
318
                polygon.addVertex(vertex);
319
            }
320
        }
321
        polygon = (Curve) closeGeometry(polygon);
322
        return polygon;
323
    }
324

    
325
    /**
326
     * Close geometry if it is necessary.
327
     *
328
     * @param geometry
329
     *            to be closed.
330
     */
331
    protected Geometry closeGeometry(Geometry geometry) {
332

    
333
        if (!isClose(geometry) && (geometry != null)) {
334

    
335
            if (geometry instanceof Surface) {
336
                Surface surface = (Surface) geometry;
337
                Point firstp = surface.getVertex(0);
338
                firstp = (Point) firstp.cloneGeometry();
339
                surface.addVertex(firstp);
340
                return surface;
341
            } else if (geometry instanceof Curve) {
342
                Curve line = (Curve) geometry;
343
                Point firstp = line.getVertex(0);
344
                firstp = (Point) firstp.cloneGeometry();
345
                line.addVertex(firstp);
346
                return line;
347
            }
348
        }
349
        return geometry;
350
    }
351

    
352
    /**
353
     * Gets if the geometry received by parameter is closed or not.
354
     *
355
     * @param geometry
356
     * @return True if geometry is closed, otherwise false.
357
     */
358
    private boolean isClose(Geometry geometry) {
359

    
360
        if (geometry != null) {
361

    
362
            if (geometry instanceof OrientablePrimitive) {
363
                OrientablePrimitive orientablePrimitive =
364
                    (OrientablePrimitive) geometry;
365
                Point firstPoint = orientablePrimitive.getVertex(0);
366
                Point lastPoint =
367
                    orientablePrimitive.getVertex(orientablePrimitive
368
                        .getNumVertices() - 1);
369
                if (firstPoint.equals(lastPoint)) {
370
                    return true;
371
                }
372
            }
373
        }
374
        return false;
375
    }
376

    
377
    public void stop() throws StopServiceException {
378
        if (values != null) {
379
            values.clear();
380
        }
381
    }
382

    
383
    public List<EditingServiceParameter> getParameters() {
384
        List<EditingServiceParameter> parameters =
385
            new ArrayList<EditingServiceParameter>();
386
        parameters.add(polygonSides);
387
        parameters.add(mode);
388
        parameters.add(center);
389
        parameters.add(pointOfCircle);
390

    
391
        return parameters;
392
    }
393

    
394
    public void setValue(Object value) throws InvalidEntryException {
395
        EditingServiceParameter parameter = next();
396
        validateAndInsertValue(parameter, value);
397
    }
398

    
399
    private void validateAndInsertValue(EditingServiceParameter param,
400
        Object value) throws InvalidEntryException {
401

    
402
        if (param == polygonSides) {
403
            if (value instanceof Double) {
404

    
405
                Integer sides = ((Double) value).intValue();
406

    
407
                if (sides > 2) {
408
                    values.put(param, sides);
409
                    getDefaultValues().put(SIDES_KEY, sides.toString());
410
                    polygonSides.setDefaultValue(sides.toString());
411
                    return;
412
                } else {
413
                    throw new InvalidEntryException(null);
414
                }
415
            } else if (value instanceof Point) {
416

    
417
                values.put(param, Integer.valueOf((String)getDefaultValues().get(SIDES_KEY)));
418
                values.put(center, (Point) value);
419
                return;
420
            }
421
        } else if (param == mode) {
422

    
423
            if (value instanceof String) {
424

    
425
                I18nManager i18nManager = ToolsLocator.getI18nManager();
426
                String option = (String) value;
427

    
428
                if (option.equalsIgnoreCase(i18nManager
429
                    .getTranslation("key_inscribed"))) {
430

    
431
                    values.put(param, "key_inscribed");
432
                    getDefaultValues().put(MODE_KEY, "key_inscribed");
433
                    mode.setDefaultValue("key_inscribed");
434
                    return;
435

    
436
                } else if (option.equalsIgnoreCase(i18nManager
437
                    .getTranslation("key_circumscribed"))) {
438

    
439
                    values.put(param, "key_circumscribed");
440
                    getDefaultValues().put(MODE_KEY, "key_circumscribed");
441
                    mode.setDefaultValue("key_circumscribed");
442
                    return;
443

    
444
                } else {
445
                    throw new InvalidEntryException(null);
446
                }
447
            } else if (value instanceof Point) {
448

    
449
                values.put(param, getDefaultValues().get(MODE_KEY));
450
                if(values.get(center) != null){
451
                    values.put(pointOfCircle, (Point) value);
452
                } else {
453
                    values.put(center, (Point) value);
454
                }
455
                return;
456
            }
457

    
458
        } else if (param == center) {
459

    
460
            if (value instanceof Point) {
461
                values.put(param, value);
462
                return;
463
            }
464

    
465
        } else if (param == pointOfCircle) {
466
            if (value instanceof Point) {
467
                values.put(param, value);
468
                return;
469
            }
470

    
471
        }
472
        throw new InvalidEntryException(null);
473
    }
474

    
475
    public Geometry finish() throws FinishServiceException {
476

    
477
        if (values != null) {
478

    
479
            Integer sidesValue = (Integer) values.get(polygonSides);
480
            String modeValue = (String) values.get(mode);
481
            Point centerValue = (Point) values.get(center);
482
            Point pointOfCircleValue = (Point) values.get(pointOfCircle);
483

    
484
            try {
485
                Curve polygon =
486
                    calculateRegularPolygon(modeValue, centerValue,
487
                        pointOfCircleValue, sidesValue);
488
                if(polygon!=null){
489
                    EditingProviderServices editingProviderServices =
490
                        (EditingProviderServices) getProviderServices();
491
                    GeometryType geomType =
492
                        editingProviderServices.getGeomType(featureStore);
493

    
494
                    if (geomType.isTypeOf(Geometry.TYPES.MULTICURVE)) {
495

    
496
                        MultiCurve multiCurve =
497
                            GeometryLocator.getGeometryManager().createMultiCurve(
498
                                geomType.getSubType());
499
                        multiCurve.addCurve(polygon);
500
                        return multiCurve;
501
                    }
502
                }
503

    
504
                return polygon;
505
            } catch (Exception e) {
506
                throw new FinishServiceException(e);
507
            }
508
        }
509
        return null;
510
    }
511

    
512
    public void finishAndStore() throws FinishServiceException {
513
        try {
514
            Geometry geometry = finish();
515
            if (geometry != null) {
516
                EditingProviderServices editingProviderServices =
517
                    (EditingProviderServices) getProviderServices();
518
                editingProviderServices.insertGeometryIntoFeatureStore(
519
                    geometry, featureStore);
520
            }
521
        } catch (Exception e) {
522
            throw new FinishServiceException(e);
523
        }
524

    
525
    }
526

    
527
    public void start() throws StartServiceException {
528
        values = new HashMap<EditingServiceParameter, Object>();
529
    }
530

    
531
    public String getName() {
532
        return RegularPolygonEditingProviderFactory.PROVIDER_NAME;
533
    }
534

    
535
}