Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.impl / src / main / java / org / gvsig / vectorediting / lib / impl / DefaultEditingProviderServices.java @ 575

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

    
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.Map;
30

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
import org.gvsig.andami.messages.NotificationManager;
35
import org.gvsig.editing.EditingNotification;
36
import org.gvsig.editing.EditingNotificationManager;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.feature.EditableFeature;
39
import org.gvsig.fmap.dal.feature.Feature;
40
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
45
import org.gvsig.fmap.geom.Geometry.TYPES;
46
import org.gvsig.fmap.geom.GeometryLocator;
47
import org.gvsig.fmap.geom.GeometryManager;
48
import org.gvsig.fmap.geom.exception.CreateGeometryException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationException;
50
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
51
import org.gvsig.fmap.geom.primitive.Arc;
52
import org.gvsig.fmap.geom.primitive.Circle;
53
import org.gvsig.fmap.geom.primitive.Ellipse;
54
import org.gvsig.fmap.geom.primitive.Line;
55
import org.gvsig.fmap.geom.primitive.Point;
56
import org.gvsig.fmap.geom.primitive.Spline;
57
import org.gvsig.fmap.geom.type.GeometryType;
58
import org.gvsig.fmap.mapcontext.layers.CancelationException;
59
import org.gvsig.fmap.mapcontrol.MapControlLocator;
60
import org.gvsig.tools.ToolsLocator;
61
import org.gvsig.tools.exception.BaseException;
62
import org.gvsig.tools.i18n.I18nManager;
63
import org.gvsig.tools.service.spi.AbstractProviderServices;
64
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
65

    
66
public class DefaultEditingProviderServices extends AbstractProviderServices
67
    implements EditingProviderServices {
68

    
69
    private static final Logger logger = LoggerFactory
70
        .getLogger(DefaultEditingProviderServices.class);
71

    
72
    protected GeometryManager geomManager = GeometryLocator
73
        .getGeometryManager();
74

    
75
    public void insertFeatureIntoFeatureStore(Feature feature,
76
        FeatureStore featureStore) {
77
        EditableFeature eFeature = null;
78
        try {
79

    
80
            if (feature instanceof EditableFeature) {
81
                eFeature = (EditableFeature) feature;
82
            } else {
83
                eFeature = feature.getEditable();
84
            }
85

    
86
            EditingNotificationManager editingNotificationManager =
87
                MapControlLocator.getEditingNotificationManager();
88

    
89
            EditingNotification notification =
90
                editingNotificationManager.notifyObservers(this, // source
91
                    EditingNotification.BEFORE_INSERT_FEATURE, // type
92
                    null,// document
93
                    null,// layer
94
                    featureStore,// store
95
                    eFeature// feature
96
                    );
97

    
98
            if (notification.isCanceled()) {
99
                String msg =
100
                    String
101
                        .format(
102
                            "Can't insert feature into %1$s, canceled by some observer.",
103
                            featureStore.getName());
104
                throw new CancelationException(msg, null);
105
            }
106

    
107
            if (notification.shouldValidateTheFeature()) {
108
                if (!editingNotificationManager.validateFeature(eFeature)) {
109
                    String msg =
110
                        String.format("%1$s is not valid", eFeature.toString());
111
                    throw new Exception(msg);
112
                }
113
            }
114

    
115
            featureStore.insert(eFeature);
116

    
117
            editingNotificationManager.notifyObservers(this,
118
                EditingNotification.AFTER_INSERT_FEATURE, null, null,
119
                featureStore, eFeature);
120

    
121
        } catch (Exception e) {
122
            String msg =
123
                String.format("Can't insert %1$s into %2$s",
124
                    eFeature.toString(), featureStore.getName());
125
            logger.info(msg, e);
126
        }
127
    }
128

    
129
    public void insertGeometryIntoFeatureStore(Geometry geometry,
130
        FeatureStore featureStore) {
131
        EditableFeature eFeature = null;
132

    
133
        try {
134
            eFeature = featureStore.createNewFeature(true);
135

    
136
            eFeature.setGeometry(featureStore.getDefaultFeatureType()
137
                .getDefaultGeometryAttributeName(), geometry);
138

    
139
            EditingNotificationManager editingNotificationManager =
140
                MapControlLocator.getEditingNotificationManager();
141

    
142
            EditingNotification notification =
143
                editingNotificationManager.notifyObservers(this, // source
144
                    EditingNotification.BEFORE_INSERT_FEATURE, // type
145
                    null,// document
146
                    null,// layer
147
                    featureStore,// store
148
                    eFeature// feature
149
                    );
150

    
151
            if (notification.isCanceled()) {
152
                String msg =
153
                    String
154
                        .format(
155
                            "Can't insert geometry into %1$s, canceled by some observer.",
156
                            featureStore.getName());
157
                throw new CancelationException(msg, null);
158
            }
159

    
160
            if (notification.shouldValidateTheFeature()) {
161
                if (!editingNotificationManager.validateFeature(eFeature)) {
162
                    String msg =
163
                        String.format("%1$s is not valid", eFeature.toString());
164
                    throw new Exception(msg);
165
                }
166
            }
167

    
168
            featureStore.insert(eFeature);
169

    
170
            editingNotificationManager.notifyObservers(this,
171
                EditingNotification.AFTER_INSERT_FEATURE, null, null,
172
                featureStore, eFeature);
173

    
174
        } catch (Exception e) {
175
            String msg =
176
                String.format("Can't insert %1$s into %2$s",
177
                    eFeature.toString(), featureStore.getName());
178
            logger.info(msg, e);
179
        }
180
    }
181

    
182
    public void deleteFeatureFromFeatureStore(Feature feature,
183
        FeatureStore featureStore) {
184

    
185
        try {
186
            EditingNotificationManager editingNotificationManager =
187
                MapControlLocator.getEditingNotificationManager();
188

    
189
            EditingNotification notification =
190
                editingNotificationManager.notifyObservers(this, // source
191
                    EditingNotification.BEFORE_REMOVE_FEATURE, // type
192
                    null,// document
193
                    null,// layer
194
                    featureStore,// store
195
                    feature// feature
196
                    );
197

    
198
            if (notification.isCanceled()) {
199
                String msg =
200
                    String
201
                        .format(
202
                            "Can't delete feature from %1$s, canceled by some observer.",
203
                            featureStore.getName());
204
                throw new CancelationException(msg, null);
205
            }
206

    
207
            featureStore.delete(feature);
208

    
209
            editingNotificationManager.notifyObservers(this,
210
                EditingNotification.AFTER_REMOVE_FEATURE, null, null,
211
                featureStore, feature);
212

    
213
        } catch (Exception e) {
214
            NotificationManager.addError(e.getMessage(), e);
215
        }
216
    }
217

    
218
    public void updateFeatureInFeatureStore(Feature feature,
219
        FeatureStore featureStore) {
220
        EditableFeature eFeature = null;
221

    
222
        try {
223

    
224
            if (feature instanceof EditableFeature) {
225
                eFeature = (EditableFeature) feature;
226
            } else {
227
                eFeature = feature.getEditable();
228
            }
229

    
230
            EditingNotificationManager editingNotificationManager =
231
                MapControlLocator.getEditingNotificationManager();
232

    
233
            EditingNotification notification =
234
                editingNotificationManager.notifyObservers(this, // source
235
                    EditingNotification.BEFORE_UPDATE_FEATURE, // type
236
                    null,// document
237
                    null,// layer
238
                    featureStore,// store
239
                    eFeature// feature
240
                    );
241

    
242
            if (notification.isCanceled()) {
243
                String msg =
244
                    String
245
                        .format(
246
                            "Can't update feature in %1$s, canceled by some observer.",
247
                            featureStore.getName());
248
                throw new CancelationException(msg, null);
249
            }
250

    
251
            if (notification.shouldValidateTheFeature()) {
252
                if (!editingNotificationManager.validateFeature(eFeature)) {
253
                    String msg =
254
                        String.format("%1$s is not valid", eFeature.toString());
255
                    throw new Exception(msg);
256
                }
257
            }
258

    
259
            featureStore.update(eFeature);
260
            editingNotificationManager.notifyObservers(this,
261
                EditingNotification.AFTER_UPDATE_FEATURE, null, null,
262
                featureStore, eFeature);
263

    
264
        } catch (Exception e) {
265
            String msg =
266
                String.format("Can't update %1$s in %2$s", eFeature.toString(),
267
                    featureStore.getName());
268
            logger.info(msg, e);
269
        }
270
    }
271

    
272
    public Circle createCircle(Point center, double radius, int subtype)
273
        throws CreateGeometryException {
274
        Circle circle = null;
275
        circle = (Circle) geomManager.create(TYPES.CIRCLE, subtype);
276
        circle.setPoints(center, radius);
277

    
278
        return circle;
279
    }
280

    
281
    public Circle createCircle(Point firstPoint, Point secondPoint,
282
        Point thridPoint, int subtype) throws CreateGeometryException {
283
        Circle circle = null;
284
        circle = (Circle) geomManager.create(TYPES.CIRCLE, subtype);
285
        circle.setPoints(firstPoint, secondPoint, thridPoint);
286

    
287
        return circle;
288
    }
289

    
290
    public Arc createArc(Point center, double radius, double startAngle,
291
        double angleExt, int subtype) throws CreateGeometryException {
292
        Arc arc = null;
293
        arc = (Arc) geomManager.create(TYPES.ARC, subtype);
294
        arc.setPoints(center, radius, startAngle, angleExt);
295
        return arc;
296
    }
297

    
298
    public Ellipse createFilledEllipse(Point firstPointAxisA,
299
        Point secondPointAxisA, double halfLengthAxisB, int subtype)
300
        throws CreateGeometryException {
301
        Ellipse ellipse = (Ellipse) geomManager.create(TYPES.ELLIPSE, subtype);
302
        ellipse.setPoints(firstPointAxisA, secondPointAxisA, halfLengthAxisB);
303
        return ellipse;
304
    }
305

    
306
    public Arc createArc(Point start, Point middle, Point end, int subtype)
307
        throws BaseException {
308

    
309
        Arc arc = (Arc)GeometryLocator.getGeometryManager().create(Geometry.TYPES.ARC, subtype);
310
        arc.setPoints(start, middle, end);
311
        return arc;
312

    
313
    }
314

    
315
    public Point createPoint(double x, double y, int subtype)
316
        throws CreateGeometryException {
317
        Point point = null;
318
        point = (Point) geomManager.create(TYPES.POINT, subtype);
319
        point.setX(x);
320
        point.setY(y);
321
        return point;
322
    }
323

    
324
    public Line createLine(double x1, double y1, double x2, double y2,
325
        int subtype) throws CreateGeometryException {
326
        Line line = null;
327
        line = (Line) geomManager.create(TYPES.CURVE, subtype);
328
        line.addVertex(x1, y1);
329
        line.addVertex(x2, y2);
330
        return line;
331
    }
332

    
333
    public int getSubType(FeatureStore featureStore) throws DataException {
334

    
335
        GeometryType geomType = getGeomType(featureStore);
336
        if (geomType != null) {
337
            return geomType.getSubType();
338
        }
339
        return SUBTYPES.UNKNOWN;
340
    }
341

    
342
    public GeometryType getGeomType(FeatureStore featureStore)
343
        throws DataException {
344
        return featureStore.getDefaultFeatureType()
345
            .getDefaultGeometryAttribute().getGeomType();
346
    }
347

    
348
    public EditableFeature getFeatureCopyWithoutPK(FeatureStore featureStore,
349
        Feature feature) throws DataException {
350
        EditableFeature editableFeature =
351
            featureStore.createNewFeature(feature.getType(), true);
352

    
353
        FeatureType type_src = feature.getType();
354
        @SuppressWarnings("rawtypes")
355
        Iterator iterator = type_src.iterator();
356
        FeatureType type_dest = editableFeature.getType();
357

    
358
        while (iterator.hasNext()) {
359
            FeatureAttributeDescriptor attribute_src =
360
                (FeatureAttributeDescriptor) iterator.next();
361

    
362
            FeatureAttributeDescriptor attribute_dest =
363
                type_dest.getAttributeDescriptor(attribute_src.getName());
364
            if (attribute_dest != null) {
365
                if (!attribute_dest.isPrimaryKey()) {
366
                    editableFeature.set(attribute_dest.getIndex(),
367
                        feature.get(attribute_src.getIndex()));
368
                }
369
            }
370
        }
371
        return editableFeature;
372
    }
373

    
374
    public Point getCenter(Point a, Point b, Point c, int subtype)
375
        throws CreateGeometryException {
376

    
377
        Point midPointAC = getMidPoint(a, c, subtype);
378
        Double[] lineParamsAC = getLineParams(a, c);
379
        Point[] bisectorAC =
380
            getPerpendicular(lineParamsAC[0], lineParamsAC[1], midPointAC,
381
                subtype);
382

    
383
        Point midPointBC = getMidPoint(b, c, subtype);
384
        Double[] lineParamsBC = getLineParams(c, b);
385
        Point[] bisectorBC =
386
            getPerpendicular(lineParamsBC[0], lineParamsBC[1], midPointBC,
387
                subtype);
388

    
389
        return getIntersection(bisectorAC, bisectorBC, subtype);
390
    }
391

    
392
    public Point getMidPoint(Point a, Point b, int subtype)
393
        throws CreateGeometryException {
394
        double x = (a.getX() + b.getX()) / 2;
395
        double y = (a.getY() + b.getY()) / 2;
396
        return createPoint(x, y, subtype);
397
    }
398

    
399
    public Double[] getLineParams(Point point, Point nextPoint) {
400
        Double[] lineParams = new Double[2];
401
        double denom = nextPoint.getX() - point.getX();
402
        if (denom != 0) {
403
            lineParams[0] = (nextPoint.getY() - point.getY()) / denom;
404
            lineParams[1] = point.getY() - (lineParams[0] * point.getX());
405
        } else {
406
            if (nextPoint.getY() >= point.getY()) {
407
                lineParams[0] = Double.POSITIVE_INFINITY;
408
                lineParams[1] = Double.NEGATIVE_INFINITY;
409
                if (point.getX() == 0) {
410
                    lineParams[1] = 0.0;
411
                }
412
            } else {
413
                lineParams[0] = Double.NEGATIVE_INFINITY;
414
                lineParams[1] = Double.POSITIVE_INFINITY;
415
                if (point.getX() == 0) {
416
                    lineParams[1] = 0.0;
417
                }
418
            }
419
        }
420
        return lineParams;
421
    }
422

    
423
    public Point[] getPerpendicular(Double m, Double b, Point perp, int subtype)
424
        throws CreateGeometryException {
425
        if (m == Double.POSITIVE_INFINITY) {
426
            Point[] res = new Point[2];
427
            res[0] = createPoint(0, perp.getY(), subtype);
428
            res[1] = createPoint(1, perp.getY(), subtype);
429
            return res;
430
        } else if (m == Double.NEGATIVE_INFINITY) {
431
            Point[] res = new Point[2];
432
            res[0] = createPoint(1, perp.getY(), subtype);
433
            res[1] = createPoint(0, perp.getY(), subtype);
434
            return res;
435
        } else {
436
            // Pendiente de la recta perpendicular
437
            Double m1 = -1 / m;
438

    
439
            // b de la funcion de la recta perpendicular
440
            Double b1 = perp.getY() - (m1 * perp.getX());
441

    
442
            // Obtenemos un par de puntos
443
            Point[] res = new Point[2];
444

    
445
            if (Double.isInfinite(m1)) {
446
                res[0] = createPoint(perp.getX(), 0.0, subtype);
447
                res[1] = createPoint(perp.getX(), perp.getY(), subtype);
448
            } else {
449
                res[0] = createPoint(0, 0.0 + b1, subtype);
450
                res[1] =
451
                    createPoint(perp.getX(), (m1 * perp.getX()) + b1, subtype);
452
            }
453

    
454
            return res;
455
        }
456
    }
457

    
458
    public Point getIntersection(Point[] lineA, Point[] lineB, int subtype)
459
        throws CreateGeometryException {
460
        Point p1 = lineA[0];
461
        Point p2 = lineA[1];
462
        Point p3 = lineB[0];
463
        Point p4 = lineB[1];
464

    
465
        double m1 = Double.POSITIVE_INFINITY;
466

    
467
        if ((p2.getX() - p1.getX()) != 0) {
468
            m1 = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
469
        }
470

    
471
        double m2 = Double.POSITIVE_INFINITY;
472

    
473
        if ((p4.getX() - p3.getX()) != 0) {
474
            m2 = (p4.getY() - p3.getY()) / (p4.getX() - p3.getX());
475
        }
476

    
477
        if ((m1 == Double.POSITIVE_INFINITY)
478
            && (m2 == Double.POSITIVE_INFINITY)) {
479
            return null;
480
        }
481

    
482
        double b1 = p2.getY() - (m1 * p2.getX());
483

    
484
        double b2 = p4.getY() - (m2 * p4.getX());
485

    
486
        if ((m1 != Double.POSITIVE_INFINITY)
487
            && (m2 != Double.POSITIVE_INFINITY)) {
488
            if (m1 == m2) {
489
                return null;
490
            }
491

    
492
            double x = (b2 - b1) / (m1 - m2);
493

    
494
            return createPoint(x, (m1 * x) + b1, subtype);
495
        } else if (m1 == Double.POSITIVE_INFINITY) {
496
            double x = p1.getX();
497

    
498
            return createPoint(x, (m2 * x) + b2, subtype);
499
        } else if (m2 == Double.POSITIVE_INFINITY) {
500
            double x = p3.getX();
501

    
502
            return createPoint(x, (m1 * x) + b1, subtype);
503
        }
504

    
505
        return null;
506
    }
507

    
508
    public double getAngle(Point start, Point end)
509
        throws GeometryOperationNotSupportedException,
510
        GeometryOperationException {
511
        double angle =
512
            Math.acos((end.getX() - start.getX()) / start.distance(end));
513

    
514
        if (start.getY() > end.getY()) {
515
            angle = -angle;
516
        }
517

    
518
        if (angle < 0) {
519
            angle += (2 * Math.PI);
520
        }
521

    
522
        return angle;
523
    }
524

    
525
    public double angleDistance(double angle1, double angle2) {
526
        double result = angle2-angle1;
527
        if(result<0){
528
            result = (Math.PI *2)+result;
529
        }
530
        return result;
531
    }
532

    
533
    public Line createLine(Point p1, Point p2, int subtype)
534
        throws CreateGeometryException {
535
        return this.createLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(),
536
            subtype);
537
    }
538

    
539
    public Spline createSpline(List<Point> points, int subtype)
540
        throws CreateGeometryException {
541
        Spline spline = null;
542
        spline = (Spline) geomManager.create(TYPES.SPLINE, subtype);
543

    
544
        for (Point point : points) {
545

    
546
            spline.addVertex(point);
547
        }
548

    
549
        return spline;
550
    }
551

    
552
    public String makeConsoleMessage(String preText, Map<String, String> options) {
553

    
554
        I18nManager i18nManager = ToolsLocator.getI18nManager();
555

    
556
        StringBuilder stb = new StringBuilder();
557

    
558
        if (preText != null) {
559
            stb.append(i18nManager.getTranslation(preText));
560
            stb.append(" ");
561
        }
562

    
563
        for (String option : options.keySet()) {
564
            stb.append("[");
565
            stb.append(option);
566
            stb.append("]");
567
            stb.append(i18nManager.getTranslation(options.get(option)));
568
            stb.append(" ");
569
        }
570

    
571
        return stb.toString();
572
    }
573

    
574
    public Arc createEllipse(Point firstPointAxisA, Point secondPointAxisA,
575
        double halfLengthAxisB, int subtype) throws CreateGeometryException {
576
        try {
577
            double lengthAxisA = secondPointAxisA.distance(firstPointAxisA);
578

    
579
            Point origen = this.createPoint(0, 0, subtype);
580
        Arc ellipse = this.createArc(
581
            origen,
582
            lengthAxisA/2,
583
            0,
584
            2*Math.PI,
585
            subtype);
586

    
587
            ellipse.scale(origen, 1, halfLengthAxisB*2/lengthAxisA);
588
            ellipse.rotate(this.getAngle(firstPointAxisA, secondPointAxisA), 0, 0);
589
            Point centerOfEllipse = this.getMidPoint(firstPointAxisA, secondPointAxisA, subtype);
590
            ellipse.move(centerOfEllipse.getX(), centerOfEllipse.getY());
591
            return ellipse;
592
        } catch (GeometryOperationNotSupportedException e) {
593
            throw new CreateGeometryException(Geometry.TYPES.ARC, subtype, e);
594
        } catch (GeometryOperationException e) {
595
            throw new CreateGeometryException(Geometry.TYPES.ARC, subtype, e);
596
        }
597
    }
598
}