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

History | View | Annotate | Download (17.7 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.GeometryLocator;
36
import org.gvsig.fmap.geom.GeometryManager;
37
import org.gvsig.fmap.geom.aggregate.MultiCurve;
38
import org.gvsig.fmap.geom.primitive.Curve;
39
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
40
import org.gvsig.fmap.geom.primitive.Point;
41
import org.gvsig.fmap.geom.primitive.Surface;
42
import org.gvsig.fmap.geom.type.GeometryType;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dynobject.DynObject;
46
import org.gvsig.tools.exception.BaseException;
47
import org.gvsig.tools.i18n.I18nManager;
48
import org.gvsig.tools.service.spi.ProviderServices;
49
import org.gvsig.vectorediting.lib.api.DrawingStatus;
50
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
51
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException;
52
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException;
53
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
54
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
55
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
56
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider;
57
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
58
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter;
59
import org.gvsig.vectorediting.lib.spi.EditingProvider;
60
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory;
61
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
62
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
63
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
64

    
65
/**
66
 *
67
 * @author llmarques
68
 *
69
 */
70
public class RegularPolygonEditingProvider extends AbstractEditingProvider
71
    implements EditingProvider {
72

    
73
    protected final Integer DEFAULT_VALUE_SIDES = 5;
74

    
75
    protected final String DEFAULT_VALUE_MODE = "key_inscribed";
76

    
77
    protected EditingServiceParameter polygonSides;
78

    
79
    protected EditingServiceParameter center;
80

    
81
    protected EditingServiceParameter mode;
82

    
83
    protected EditingServiceParameter pointOfCircle;
84

    
85
    protected Map<EditingServiceParameter, Object> values;
86

    
87
    protected Map<String, String> options;
88

    
89
    protected FeatureStore featureStore;
90

    
91
    public RegularPolygonEditingProvider(ProviderServices providerServices,
92
        DynObject parameters) {
93
        super(providerServices);
94
        this.featureStore =
95
            (FeatureStore) parameters
96
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
97

    
98
        polygonSides =
99
            new DefaultEditingServiceParameter("sides", DEFAULT_VALUE_SIDES,
100
                "sides_of_regular_polygon", EditingServiceParameter.TYPE.VALUE);
101

    
102
        I18nManager i18nManager = ToolsLocator.getI18nManager();
103
        options = new LinkedHashMap<String, String>();
104
        options.put(i18nManager.getTranslation("key_inscribed"), "inscribed");
105
        options.put(i18nManager.getTranslation("key_circumscribed"),
106
            "circumscribed");
107

    
108
        EditingProviderServices editingProviderServices =
109
            (EditingProviderServices) getProviderServices();
110

    
111
        String consoleMsg =
112
            editingProviderServices.makeConsoleMessage(null, options);
113

    
114
        mode =
115
            new DefaultEditingServiceParameter("mode", consoleMsg, options,
116
                i18nManager.getTranslation(DEFAULT_VALUE_MODE),
117
                EditingServiceParameter.TYPE.OPTION);
118

    
119
        center =
120
            new DefaultEditingServiceParameter("center",
121
                "center_of_regular_polygon",
122
                EditingServiceParameter.TYPE.POSITION);
123

    
124
        pointOfCircle =
125
            new DefaultEditingServiceParameter("point_of_circle",
126
                "point_of_circle", EditingServiceParameter.TYPE.POSITION);
127
    }
128

    
129
    public EditingServiceParameter next() {
130
        if (values.get(polygonSides) == null) {
131
            return polygonSides;
132
        } else if (values.get(mode) == null) {
133
            return mode;
134
        } else if (values.get(center) == null) {
135
            return center;
136
        } else if (values.get(pointOfCircle) == null) {
137
            return pointOfCircle;
138
        }
139
        return null;
140
    }
141

    
142
    public DrawingStatus getDrawingStatus(Point mousePosition)
143
        throws DrawServiceException {
144
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
145
        EditingProviderManager editingProviderManager =
146
            EditingProviderLocator.getProviderManager();
147
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
148
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
149
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
150

    
151
        if (values != null) {
152

    
153
            Integer sidesValue = (Integer) values.get(polygonSides);
154
            String modeValue = (String) values.get(mode);
155
            Point centerValue = (Point) values.get(center);
156

    
157
            if (centerValue != null) {
158

    
159
                try {
160

    
161
                    EditingProviderServices editingProviderServices =
162
                        (EditingProviderServices) getProviderServices();
163
                    int subtype =
164
                        editingProviderServices.getSubType(featureStore);
165

    
166
                    if (modeValue == null) {
167
                        modeValue = DEFAULT_VALUE_MODE;
168
                    }
169

    
170
                    Curve polygon =
171
                        calculateRegularPolygon(modeValue, centerValue,
172
                            mousePosition, sidesValue);
173
                    Curve line =
174
                        editingProviderServices.createLine(centerValue,
175
                            mousePosition, subtype);
176

    
177
                    double radius = mousePosition.distance(centerValue);
178
                    Curve circumference =
179
                        editingProviderServices.createArc(centerValue, radius,
180
                            0, 2 * Math.PI, subtype);
181

    
182
                    drawingStatus.addStatus(circumference, auxiliaryLineSymbolEditing, "");
183
                    drawingStatus.addStatus(polygon, lineSymbolEditing, "");
184
                    drawingStatus.addStatus(centerValue, auxiliaryPointSymbolEditing, "");
185
                    drawingStatus.addStatus(line, auxiliaryLineSymbolEditing, "");
186

    
187
                } catch (BaseException e) {
188
                    throw new DrawServiceException(e);
189
                }
190
            }
191
        }
192
        return drawingStatus;
193
    }
194

    
195
    /**
196
     * Calculates polygon as of mode (inscribed or circumscribed), center of
197
     * polygon, point of circle and number of sides.
198
     *
199
     * @param modeValue
200
     *            of polygon (inscribed or circumscribed).
201
     * @param centerValue
202
     *            of polygon
203
     * @param pointOfCircleValue
204
     *            of circle that inscribe or circumscribe polygon
205
     * @param sidesValue
206
     *            number of sides.
207
     */
208
    protected Curve calculateRegularPolygon(String modeValue,
209
        Point centerValue, Point pointOfCircle, int sidesValue)
210
        throws BaseException {
211

    
212
        GeometryManager geometryManager = GeometryLocator.getGeometryManager();
213

    
214
        EditingProviderServices editingProviderServices =
215
            (EditingProviderServices) getProviderServices();
216
        int subtype = editingProviderServices.getSubType(featureStore);
217

    
218
        Curve polygon =
219
            (Curve) geometryManager.create(Geometry.TYPES.CURVE, subtype);
220

    
221
        double initAngle =
222
            editingProviderServices.getAngle(centerValue, pointOfCircle);
223
        double radiusValue = pointOfCircle.distance(centerValue);
224
        double theta = (2 * Math.PI) / sidesValue;
225

    
226
        if (modeValue.equalsIgnoreCase("key_inscribed")) {
227

    
228
            for (int i = 0; i < sidesValue; ++i) {
229

    
230
                double x =
231
                    centerValue.getX()
232
                        + (radiusValue * Math.cos((theta * i) + initAngle));
233
                double y =
234
                    centerValue.getY()
235
                        + (radiusValue * Math.sin((theta * i) + initAngle));
236

    
237
                Point createPoint =
238
                    editingProviderServices.createPoint(x, y, subtype);
239

    
240
                polygon.addVertex(createPoint);
241
            }
242

    
243
        } else if (modeValue.equalsIgnoreCase("key_circumscribed")) {
244

    
245
            for (int i = 0; i < sidesValue; ++i) {
246

    
247
                double x =
248
                    centerValue.getX()
249
                        + (radiusValue * Math.cos((theta * i) + initAngle));
250
                double y =
251
                    centerValue.getY()
252
                        + (radiusValue * Math.sin((theta * i) + initAngle));
253

    
254
                Point apothemPoint =
255
                    editingProviderServices.createPoint(x, y, subtype);
256

    
257
                Double[] apothemParams =
258
                    editingProviderServices.getLineParams(centerValue,
259
                        apothemPoint);
260
                Point[] perpendicular =
261
                    editingProviderServices.getPerpendicular(apothemParams[0],
262
                        apothemParams[1], apothemPoint, subtype);
263

    
264
                double x1 =
265
                    centerValue.getX()
266
                        + (radiusValue * Math
267
                            .cos((theta * (i + 1)) + initAngle));
268
                double y1 =
269
                    centerValue.getY()
270
                        + (radiusValue * Math
271
                            .sin((theta * (i + 1)) + initAngle));
272

    
273
                Point nextApothemPoint =
274
                    editingProviderServices.createPoint(x1, y1, subtype);
275

    
276
                Double[] nextApothemParams =
277
                    editingProviderServices.getLineParams(centerValue,
278
                        nextApothemPoint);
279
                Point[] nextPerpendicular =
280
                    editingProviderServices.getPerpendicular(
281
                        nextApothemParams[0], nextApothemParams[1],
282
                        nextApothemPoint, subtype);
283

    
284
                Point vertex =
285
                    editingProviderServices.getIntersection(perpendicular,
286
                        nextPerpendicular, subtype);
287

    
288
                polygon.addVertex(vertex);
289
            }
290
        }
291
        polygon = (Curve) closeGeometry(polygon);
292
        return polygon;
293
    }
294

    
295
    /**
296
     * Close geometry if it is necessary.
297
     *
298
     * @param geometry
299
     *            to be closed.
300
     */
301
    protected Geometry closeGeometry(Geometry geometry) {
302

    
303
        if (!isClose(geometry) && (geometry != null)) {
304

    
305
            if (geometry instanceof Surface) {
306
                Surface surface = (Surface) geometry;
307
                Point firstp = surface.getVertex(0);
308
                firstp = (Point) firstp.cloneGeometry();
309
                surface.addVertex(firstp);
310
                return surface;
311
            } else if (geometry instanceof Curve) {
312
                Curve line = (Curve) geometry;
313
                Point firstp = line.getVertex(0);
314
                firstp = (Point) firstp.cloneGeometry();
315
                line.addVertex(firstp);
316
                return line;
317
            }
318
        }
319
        return geometry;
320
    }
321

    
322
    /**
323
     * Gets if the geometry received by parameter is closed or not.
324
     *
325
     * @param geometry
326
     * @return True if geometry is closed, otherwise false.
327
     */
328
    private boolean isClose(Geometry geometry) {
329

    
330
        if (geometry != null) {
331

    
332
            if (geometry instanceof OrientablePrimitive) {
333
                OrientablePrimitive orientablePrimitive =
334
                    (OrientablePrimitive) geometry;
335
                Point firstPoint = orientablePrimitive.getVertex(0);
336
                Point lastPoint =
337
                    orientablePrimitive.getVertex(orientablePrimitive
338
                        .getNumVertices() - 1);
339
                if (firstPoint.equals(lastPoint)) {
340
                    return true;
341
                }
342
            }
343
        }
344
        return false;
345
    }
346

    
347
    public void stop() throws StopServiceException {
348
        if (values != null) {
349
            values.clear();
350
        }
351
    }
352

    
353
    public List<EditingServiceParameter> getParameters() {
354
        List<EditingServiceParameter> parameters =
355
            new ArrayList<EditingServiceParameter>();
356
        parameters.add(polygonSides);
357
        parameters.add(mode);
358
        parameters.add(center);
359
        parameters.add(pointOfCircle);
360

    
361
        return parameters;
362
    }
363

    
364
    public void setValue(Object value) throws InvalidEntryException {
365
        EditingServiceParameter parameter = next();
366
        validateAndInsertValue(parameter, value);
367
    }
368

    
369
    private void validateAndInsertValue(EditingServiceParameter param,
370
        Object value) throws InvalidEntryException {
371

    
372
        if (param == polygonSides) {
373
            if (value instanceof Double) {
374

    
375
                Integer sides = ((Double) value).intValue();
376

    
377
                if (sides > 2) {
378
                    values.put(param, sides);
379
                    return;
380
                } else {
381
                    throw new InvalidEntryException(null);
382
                }
383
            } else if (value instanceof Point) {
384

    
385
                values.put(param, DEFAULT_VALUE_SIDES);
386
                values.put(center, (Point) value);
387
                return;
388
            }
389
        } else if (param == mode) {
390

    
391
            if (value instanceof String) {
392

    
393
                I18nManager i18nManager = ToolsLocator.getI18nManager();
394
                String option = (String) value;
395

    
396
                if (option.equalsIgnoreCase(i18nManager
397
                    .getTranslation("key_inscribed"))) {
398

    
399
                    values.put(param, "key_inscribed");
400
                    return;
401

    
402
                } else if (option.equalsIgnoreCase(i18nManager
403
                    .getTranslation("key_circumscribed"))) {
404

    
405
                    values.put(param, "key_circumscribed");
406
                    return;
407

    
408
                } else {
409
                    throw new InvalidEntryException(null);
410
                }
411
            } else if (value instanceof Point) {
412

    
413
                values.put(param, DEFAULT_VALUE_MODE);
414
                if(values.get(center) != null){
415
                    values.put(pointOfCircle, (Point) value);
416
                } else {
417
                    values.put(center, (Point) value);
418
                }
419
                return;
420
            }
421

    
422
        } else if (param == center) {
423

    
424
            if (value instanceof Point) {
425
                values.put(param, value);
426
                return;
427
            }
428

    
429
        } else if (param == pointOfCircle) {
430
            if (value instanceof Point) {
431
                values.put(param, value);
432
                return;
433
            }
434

    
435
        }
436
        throw new InvalidEntryException(null);
437
    }
438

    
439
    public Geometry finish() throws FinishServiceException {
440

    
441
        if (values != null) {
442

    
443
            Integer sidesValue = (Integer) values.get(polygonSides);
444
            String modeValue = (String) values.get(mode);
445
            Point centerValue = (Point) values.get(center);
446
            Point pointOfCircleValue = (Point) values.get(pointOfCircle);
447

    
448
            try {
449
                Curve polygon =
450
                    calculateRegularPolygon(modeValue, centerValue,
451
                        pointOfCircleValue, sidesValue);
452

    
453
                EditingProviderServices editingProviderServices =
454
                    (EditingProviderServices) getProviderServices();
455
                GeometryType geomType =
456
                    editingProviderServices.getGeomType(featureStore);
457

    
458
                if (geomType.isTypeOf(Geometry.TYPES.MULTICURVE)) {
459

    
460
                    MultiCurve multiCurve =
461
                        GeometryLocator.getGeometryManager().createMultiCurve(
462
                            geomType.getSubType());
463
                    multiCurve.addCurve(polygon);
464
                    return multiCurve;
465
                }
466

    
467
                return polygon;
468
            } catch (Exception e) {
469
                throw new FinishServiceException(e);
470
            }
471
        }
472
        return null;
473
    }
474

    
475
    public void finishAndStore() throws FinishServiceException {
476
        try {
477
            Geometry geometry = finish();
478
            if (geometry != null) {
479
                EditingProviderServices editingProviderServices =
480
                    (EditingProviderServices) getProviderServices();
481
                editingProviderServices.insertGeometryIntoFeatureStore(
482
                    geometry, featureStore);
483
            }
484
        } catch (Exception e) {
485
            throw new FinishServiceException(e);
486
        }
487

    
488
    }
489

    
490
    public void start() throws StartServiceException {
491
        values = new HashMap<EditingServiceParameter, Object>();
492
    }
493

    
494
    public String getName() {
495
        return RegularPolygonEditingProviderFactory.PROVIDER_NAME;
496
    }
497

    
498
}