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

History | View | Annotate | Download (28.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
package org.gvsig.vectorediting.lib.impl;
25

    
26
import java.util.Iterator;
27
import java.util.List;
28
import java.util.Map;
29
import java.util.logging.Level;
30
import org.geotools.measure.AngleFormat;
31
import org.gvsig.euclidean.EuclideanLine2D;
32
import org.gvsig.expressionevaluator.Expression;
33
import org.gvsig.expressionevaluator.ExpressionUtils;
34
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
35
import org.gvsig.fmap.dal.DALLocator;
36
import org.gvsig.fmap.dal.DataManager;
37

    
38
import org.gvsig.fmap.dal.EditingNotification;
39
import org.gvsig.fmap.dal.EditingNotificationManager;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
42
import org.gvsig.fmap.dal.feature.EditableFeature;
43
import org.gvsig.fmap.dal.feature.Feature;
44
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.FeatureSet;
46
import org.gvsig.fmap.dal.feature.FeatureStore;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.swing.DALSwingLocator;
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
51
import org.gvsig.fmap.geom.GeometryLocator;
52
import org.gvsig.fmap.geom.GeometryManager;
53
import org.gvsig.fmap.geom.GeometryUtils;
54
import org.gvsig.fmap.geom.exception.CreateGeometryException;
55
import org.gvsig.fmap.geom.operation.GeometryOperationException;
56
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
57
import org.gvsig.fmap.geom.primitive.Arc;
58
import org.gvsig.fmap.geom.primitive.Circle;
59
import org.gvsig.fmap.geom.primitive.Ellipse;
60
import org.gvsig.fmap.geom.primitive.Line;
61
import org.gvsig.fmap.geom.primitive.Point;
62
import org.gvsig.fmap.geom.primitive.Spline;
63
import org.gvsig.fmap.geom.type.GeometryType;
64
import org.gvsig.fmap.mapcontext.MapContext;
65
import org.gvsig.fmap.mapcontext.layers.CancelationException;
66
import org.gvsig.fmap.mapcontext.layers.FLayer;
67
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
68
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
69
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
70
import org.gvsig.tools.ToolsLocator;
71
import org.gvsig.tools.exception.BaseException;
72
import org.gvsig.tools.i18n.I18nManager;
73
import org.gvsig.tools.service.spi.AbstractProviderServices;
74
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus;
75
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator;
76
import org.gvsig.vectorediting.lib.spi.EditingProviderManager;
77
import org.gvsig.vectorediting.lib.spi.EditingProviderServices;
78
import org.slf4j.Logger;
79
import org.slf4j.LoggerFactory;
80

    
81
public class DefaultEditingProviderServices extends AbstractProviderServices
82
        implements EditingProviderServices {
83

    
84
    private static final Logger LOGGER = LoggerFactory
85
            .getLogger(DefaultEditingProviderServices.class);
86

    
87
    @Override
88
    public void insertFeatureIntoFeatureStore(Feature feature,
89
            FeatureStore featureStore) {
90
        EditableFeature eFeature = null;
91
        try {
92

    
93
            if (feature instanceof EditableFeature) {
94
                eFeature = (EditableFeature) feature;
95
            } else {
96
                eFeature = feature.getEditable();
97
            }
98

    
99
            EditingNotificationManager editingNotificationManager
100
                    = DALSwingLocator.getEditingNotificationManager();
101

    
102
            EditingNotification notification
103
                    = editingNotificationManager.notifyObservers(this, // source
104
                            EditingNotification.BEFORE_INSERT_FEATURE, // type
105
                            null,// document
106
                            null,// layer
107
                            featureStore,// store
108
                            eFeature// feature
109
                    );
110

    
111
            if (notification.isCanceled()) {
112
                String msg
113
                        = String
114
                                .format(
115
                                        "Can't insert feature into %1$s, canceled by some observer.",
116
                                        featureStore.getName());
117
                throw new CancelationException(msg, null);
118
            }
119

    
120
            if (notification.shouldValidateTheFeature()) {
121
                if (!editingNotificationManager.validateFeature(eFeature)) {
122
                    String msg
123
                            = String.format("%1$s is not valid", eFeature.toString());
124
                    throw new Exception(msg);
125
                }
126
            }
127

    
128
            featureStore.insert(eFeature);
129

    
130
            editingNotificationManager.notifyObservers(this,
131
                    EditingNotification.AFTER_INSERT_FEATURE, null, null,
132
                    featureStore, eFeature);
133

    
134
        } catch (Exception e) {
135
            String msg
136
                    = String.format("Can't insert %1$s into %2$s",
137
                            eFeature.toString(), featureStore.getName());
138
            LOGGER.info(msg, e);
139
        }
140
    }
141

    
142
    @Override
143
    public void insertGeometryIntoFeatureStore(Geometry geometry,
144
            FeatureStore featureStore) {
145
        EditableFeature eFeature = null;
146

    
147
        try {
148
            eFeature = featureStore.createNewFeature(true);
149

    
150
            eFeature.setGeometry(featureStore.getDefaultFeatureType()
151
                    .getDefaultGeometryAttributeName(), geometry);
152

    
153
            EditingNotificationManager editingNotificationManager
154
                    = DALSwingLocator.getEditingNotificationManager();
155

    
156
            EditingNotification notification
157
                    = editingNotificationManager.notifyObservers(this, // source
158
                            EditingNotification.BEFORE_INSERT_FEATURE, // type
159
                            null,// document
160
                            null,// layer
161
                            featureStore,// store
162
                            eFeature// feature
163
                    );
164

    
165
            if (notification.isCanceled()) {
166
                String msg
167
                        = String
168
                                .format(
169
                                        "Can't insert geometry into %1$s, canceled by some observer.",
170
                                        featureStore.getName());
171
                throw new CancelationException(msg, null);
172
            }
173

    
174
            if (notification.shouldValidateTheFeature()) {
175
                if (!editingNotificationManager.validateFeature(eFeature)) {
176
                    String msg
177
                            = String.format("%1$s is not valid", eFeature.toString());
178
                    throw new Exception(msg);
179
                }
180
            }
181

    
182
            featureStore.insert(eFeature);
183

    
184
            editingNotificationManager.notifyObservers(this,
185
                    EditingNotification.AFTER_INSERT_FEATURE, null, null,
186
                    featureStore, eFeature);
187

    
188
        } catch (Exception e) {
189
            String msg
190
                    = String.format("Can't insert %1$s into %2$s",
191
                            eFeature.toString(), featureStore.getName());
192
            LOGGER.info(msg, e);
193
        }
194
    }
195

    
196
    @Override
197
    public void deleteFeatureFromFeatureSet(Feature feature,
198
            FeatureStore featureStore, FeatureSet set) {
199

    
200
        try {
201
            EditingNotificationManager editingNotificationManager
202
                    = DALSwingLocator.getEditingNotificationManager();
203

    
204
            EditingNotification notification
205
                    = editingNotificationManager.notifyObservers(this, // source
206
                            EditingNotification.BEFORE_REMOVE_FEATURE, // type
207
                            null,// document
208
                            null,// layer
209
                            featureStore,// store
210
                            feature// feature
211
                    );
212

    
213
            if (notification.isCanceled()) {
214
                String msg
215
                        = String
216
                                .format(
217
                                        "Can't delete feature from %1$s, canceled by some observer.",
218
                                        featureStore.getName());
219
                throw new CancelationException(msg, null);
220
            }
221

    
222
            set.delete(feature);
223

    
224
            editingNotificationManager.notifyObservers(this,
225
                    EditingNotification.AFTER_REMOVE_FEATURE, null, null,
226
                    featureStore, feature);
227

    
228
        } catch (Exception e) {
229
            LOGGER.warn(e.getMessage(), e);
230
        }
231
    }
232

    
233
    @Override
234
    public void deleteFeatureFromFeatureStore(Feature feature,
235
            FeatureStore featureStore) {
236

    
237
        try {
238
            EditingNotificationManager editingNotificationManager
239
                    = DALSwingLocator.getEditingNotificationManager();
240

    
241
            EditingNotification notification
242
                    = editingNotificationManager.notifyObservers(this, // source
243
                            EditingNotification.BEFORE_REMOVE_FEATURE, // type
244
                            null,// document
245
                            null,// layer
246
                            featureStore,// store
247
                            feature// feature
248
                    );
249

    
250
            if (notification.isCanceled()) {
251
                String msg
252
                        = String
253
                                .format(
254
                                        "Can't delete feature from %1$s, canceled by some observer.",
255
                                        featureStore.getName());
256
                throw new CancelationException(msg, null);
257
            }
258

    
259
            featureStore.delete(feature);
260

    
261
            editingNotificationManager.notifyObservers(this,
262
                    EditingNotification.AFTER_REMOVE_FEATURE, null, null,
263
                    featureStore, feature);
264

    
265
        } catch (Exception e) {
266
            LOGGER.warn(e.getMessage(), e);
267
        }
268
    }
269

    
270
    @Override
271
    public void updateFeatureInFeatureStore(Feature feature,
272
            FeatureStore featureStore) {
273
        EditableFeature eFeature = null;
274

    
275
        try {
276

    
277
            if (feature instanceof EditableFeature) {
278
                eFeature = (EditableFeature) feature;
279
            } else {
280
                eFeature = feature.getEditable();
281
            }
282

    
283
            EditingNotificationManager editingNotificationManager
284
                    = DALSwingLocator.getEditingNotificationManager();
285

    
286
            EditingNotification notification
287
                    = editingNotificationManager.notifyObservers(this, // source
288
                            EditingNotification.BEFORE_UPDATE_FEATURE, // type
289
                            null,// document
290
                            null,// layer
291
                            featureStore,// store
292
                            eFeature// feature
293
                    );
294

    
295
            if (notification.isCanceled()) {
296
                String msg
297
                        = String
298
                                .format(
299
                                        "Can't update feature in %1$s, canceled by some observer.",
300
                                        featureStore.getName());
301
                throw new CancelationException(msg, null);
302
            }
303

    
304
            if (notification.shouldValidateTheFeature()) {
305
                if (!editingNotificationManager.validateFeature(eFeature)) {
306
                    String msg
307
                            = String.format("%1$s is not valid", eFeature.toString());
308
                    throw new Exception(msg);
309
                }
310
            }
311

    
312
            featureStore.update(eFeature);
313
            editingNotificationManager.notifyObservers(this,
314
                    EditingNotification.AFTER_UPDATE_FEATURE, null, null,
315
                    featureStore, eFeature);
316

    
317
        } catch (Exception e) {
318
            String msg
319
                    = String.format("Can't update %1$s in %2$s", eFeature.toString(),
320
                            featureStore.getName());
321
            LOGGER.info(msg, e);
322
        }
323
    }
324

    
325
    @Override
326
    public Circle createCircle(Point center, double radius, int subtype)
327
            throws CreateGeometryException {
328
        return GeometryUtils.createCircle(center, radius, subtype);
329
    }
330

    
331
    @Override
332
    public Circle createCircle(Point firstPoint, Point secondPoint,
333
            Point thridPoint, int subtype) throws CreateGeometryException {
334
        return GeometryUtils.createCircle(firstPoint, secondPoint, thridPoint, subtype);
335
    }
336

    
337
    @Override
338
    public Arc createArc(Point center, double radius, double startAngle,
339
            double angleExt, int subtype) throws CreateGeometryException {
340
        return GeometryUtils.createArc(center, radius, startAngle, angleExt, subtype);
341
    }
342

    
343
    @Override
344
    public Ellipse createFilledEllipse(Point firstPointAxisA,
345
            Point secondPointAxisA, double halfLengthAxisB, int subtype)
346
            throws CreateGeometryException {
347
        return GeometryUtils.createFilledEllipse(firstPointAxisA, secondPointAxisA, halfLengthAxisB, subtype);
348
    }
349

    
350
    @Override
351
    public Arc createArc(Point start, Point middle, Point end, int subtype)
352
            throws BaseException {
353
        return GeometryUtils.createArc(start, middle, end, subtype);
354
    }
355

    
356
    @Override
357
    public Point createPoint(double x, double y, int subtype)
358
            throws CreateGeometryException {
359
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
360
        return geomManager.createPoint(x, y, subtype);
361
    }
362

    
363
    @Override
364
    public Line createLine(double x1, double y1, double x2, double y2,
365
            int subtype) throws CreateGeometryException {
366
        return GeometryUtils.createLine(x1, y1, x2, y2, subtype);
367
    }
368

    
369
    @Override
370
    public int getSubType(FeatureStore featureStore) throws DataException {
371

    
372
        GeometryType geomType = getGeomType(featureStore);
373
        if (geomType != null) {
374
            return geomType.getSubType();
375
        }
376
        return SUBTYPES.UNKNOWN;
377
    }
378

    
379
    @Override
380
    public GeometryType getGeomType(FeatureStore featureStore)
381
            throws DataException {
382
        return featureStore.getDefaultFeatureType()
383
                .getDefaultGeometryAttribute().getGeomType();
384
    }
385

    
386
    @Override
387
    public EditableFeature getFeatureCopyWithoutPK(FeatureStore featureStore,
388
            Feature feature) throws DataException {
389
        EditableFeature editableFeature
390
                = featureStore.createNewFeature(feature.getType(), true);
391

    
392
        FeatureType type_src = feature.getType();
393
        @SuppressWarnings("rawtypes")
394
        Iterator iterator = type_src.iterator();
395
        FeatureType type_dest = editableFeature.getType();
396

    
397
        while (iterator.hasNext()) {
398
            FeatureAttributeDescriptor attribute_src
399
                    = (FeatureAttributeDescriptor) iterator.next();
400

    
401
            FeatureAttributeDescriptor attribute_dest
402
                    = type_dest.getAttributeDescriptor(attribute_src.getName());
403
            if (attribute_dest != null) {
404
                if (!attribute_dest.isPrimaryKey()) {
405
                    editableFeature.set(attribute_dest.getIndex(),
406
                            feature.get(attribute_src.getIndex()));
407
                }
408
            }
409
        }
410
        return editableFeature;
411
    }
412

    
413
    @Override
414
    public Point getCenter(Point a, Point b, Point c, int subtype)
415
            throws CreateGeometryException {
416
        return GeometryUtils.getCenter(a, b, c, subtype);
417
    }
418

    
419
    @Override
420
    public Point getMidPoint(Point a, Point b, int subtype)
421
            throws CreateGeometryException {
422
        return GeometryUtils.getMidPoint(a, b, subtype);
423
    }
424

    
425
    @Override
426
    public Double[] getLineParams(Point point, Point nextPoint) {
427
        Double[] lineParams = new Double[2];
428
        double denom = nextPoint.getX() - point.getX();
429
        if (denom != 0) {
430
            lineParams[0] = (nextPoint.getY() - point.getY()) / denom;
431
            lineParams[1] = point.getY() - (lineParams[0] * point.getX());
432
        } else {
433
            if (nextPoint.getY() >= point.getY()) {
434
                lineParams[0] = Double.POSITIVE_INFINITY;
435
                lineParams[1] = Double.NEGATIVE_INFINITY;
436
                if (point.getX() == 0) {
437
                    lineParams[1] = 0.0;
438
                }
439
            } else {
440
                lineParams[0] = Double.NEGATIVE_INFINITY;
441
                lineParams[1] = Double.POSITIVE_INFINITY;
442
                if (point.getX() == 0) {
443
                    lineParams[1] = 0.0;
444
                }
445
            }
446
        }
447
        return lineParams;
448
    }
449

    
450
    @Override
451
    public Point[] getPerpendicular(Double m, Double b, Point point, int subtype)
452
            throws CreateGeometryException {
453
        // Pendiente de la recta perpendicular
454
        Double m1 = -1 / m;
455

    
456
        // b de la funcion de la recta perpendicular
457
        Double b1 = point.getY() - (m1 * point.getX());
458

    
459
        // Obtenemos un par de puntos
460
        Point[] res = new Point[2];
461

    
462
        if (Double.isInfinite(m1)) {
463
            if (m1 > 0) {
464
                //return the director vector of the line
465
                res[0] = createPoint(point.getX(), 0.0, subtype);
466
                res[1] = createPoint(point.getX(), 1.0, subtype);
467
            } else {
468
                res[0] = createPoint(point.getX(), 0.0, subtype);
469
                res[1] = createPoint(point.getX(), -1.0, subtype);
470
            }
471
        } else {
472
            //return the director vector of the line
473
            res[0] = createPoint(0.0, b1, subtype);
474
            Double mod = Math.sqrt(1 + Math.pow(m1, 2));
475
            Double x = 1 / mod;
476
            Double y = m1 * x + b1;
477
            res[1] = createPoint(x, y, subtype);
478
        }
479

    
480
        return res;
481
    }
482

    
483
    @Override
484
    public Point getIntersection(Point[] lineA, Point[] lineB, int subtype)
485
            throws CreateGeometryException {
486
        Point p1 = lineA[0];
487
        Point p2 = lineA[1];
488
        Point p3 = lineB[0];
489
        Point p4 = lineB[1];
490

    
491
        double m1 = Double.POSITIVE_INFINITY;
492

    
493
        if ((p2.getX() - p1.getX()) != 0) {
494
            m1 = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
495
        }
496

    
497
        double m2 = Double.POSITIVE_INFINITY;
498

    
499
        if ((p4.getX() - p3.getX()) != 0) {
500
            m2 = (p4.getY() - p3.getY()) / (p4.getX() - p3.getX());
501
        }
502

    
503
        if ((m1 == Double.POSITIVE_INFINITY)
504
                && (m2 == Double.POSITIVE_INFINITY)) {
505
            return null;
506
        }
507

    
508
        double b1 = p2.getY() - (m1 * p2.getX());
509

    
510
        double b2 = p4.getY() - (m2 * p4.getX());
511

    
512
        if ((m1 != Double.POSITIVE_INFINITY)
513
                && (m2 != Double.POSITIVE_INFINITY)) {
514
            if (m1 == m2) {
515
                return null;
516
            }
517

    
518
            double x = (b2 - b1) / (m1 - m2);
519

    
520
            return createPoint(x, (m1 * x) + b1, subtype);
521
        } else if (m1 == Double.POSITIVE_INFINITY) {
522
            double x = p1.getX();
523

    
524
            return createPoint(x, (m2 * x) + b2, subtype);
525
        } else if (m2 == Double.POSITIVE_INFINITY) {
526
            double x = p3.getX();
527

    
528
            return createPoint(x, (m1 * x) + b1, subtype);
529
        }
530

    
531
        return null;
532
    }
533

    
534
    @Override
535
    public double getAngle(Point start, Point end)
536
            throws GeometryOperationNotSupportedException,
537
            GeometryOperationException {
538
        double angle
539
                = Math.acos((end.getX() - start.getX()) / start.distance(end));
540

    
541
        if (start.getY() > end.getY()) {
542
            angle = -angle;
543
        }
544

    
545
        if (angle < 0) {
546
            angle += (2 * Math.PI);
547
        }
548

    
549
        return angle;
550
    }
551

    
552
    @Override
553
    public double angleDistance(double angle1, double angle2) {
554
        double result = angle2 - angle1;
555
        if (result < 0) {
556
            result = (Math.PI * 2) + result;
557
        }
558
        return result;
559
    }
560

    
561
    @Override
562
    public Line createLine(Point p1, Point p2, int subtype)
563
            throws CreateGeometryException {
564
        return GeometryUtils.createLine(p1, p2, subtype);
565
    }
566

    
567
    @Override
568
    public Spline createSpline(List<Point> points, int subtype)
569
            throws CreateGeometryException {
570
        return GeometryUtils.createSpline(points, subtype);
571
    }
572

    
573
    @Override
574
    public String makeConsoleMessage(String preText, Map<String, String> options) {
575

    
576
        I18nManager i18nManager = ToolsLocator.getI18nManager();
577

    
578
        StringBuilder stb = new StringBuilder();
579

    
580
        if (preText != null) {
581
            stb.append(i18nManager.getTranslation(preText));
582
            stb.append(" ");
583
        }
584

    
585
        for (String option : options.keySet()) {
586
            stb.append("[");
587
            stb.append(option);
588
            stb.append("]");
589
            stb.append(i18nManager.getTranslation(options.get(option)));
590
            stb.append(" ");
591
        }
592

    
593
        return stb.toString();
594
    }
595

    
596
    @Override
597
    public Arc createEllipse(Point firstPointAxisA, Point secondPointAxisA,
598
            double halfLengthAxisB, int subtype) throws CreateGeometryException {
599
        return GeometryUtils.createEllipse(firstPointAxisA, secondPointAxisA, halfLengthAxisB, subtype);
600
    }
601

    
602
    @Override
603
    public Circle createCircle(Point firstPoint, Point secondPoint, Point thirdPoint, Point fourthPoint, Point fifthPoint, int subtype) throws CreateGeometryException {
604
        return GeometryUtils.createCircle(firstPoint, secondPoint, thirdPoint, fourthPoint, fifthPoint, subtype);
605
    }
606

    
607
    @Override
608
    public Circle createCircle(EuclideanLine2D line1, EuclideanLine2D line2, Point point, int subtype) throws CreateGeometryException {
609
        return GeometryUtils.createCircle(line1, line2, point, subtype);
610
    }
611

    
612
    @Override
613
    public Circle createCircle(Geometry geometry1, Geometry geometry2, double radius, Point firstPoint, Point secondPoint, int subtype) throws CreateGeometryException {
614
        return GeometryUtils.createCircle(geometry1, geometry2, radius, firstPoint, secondPoint, subtype);
615
    }
616

    
617
    @Override
618
    public Feature getFeature(Point point, FeatureStore store, MapContext mapContext) {
619
        Feature feature = null;
620
        try {
621
            double tolerance = mapContext.getViewPort().toMapDistance(mapContext.getLayers().getDefaultTolerance());
622
            Geometry buffer = point.buffer(tolerance);
623

    
624
            DataManager dataManager = DALLocator.getDataManager();
625
            DALExpressionBuilder dalBuilder = dataManager.createDALExpressionBuilder();
626
            GeometryExpressionBuilder builder = dalBuilder.expression();
627

    
628
            FeatureType featureType = store.getDefaultFeatureType();
629
            
630
            String filter = builder.ST_Intersects(
631
                    builder.geometry(
632
                            buffer, mapContext.getProjection()
633
                    ), 
634
                    builder.column(featureType.getDefaultGeometryAttributeName())
635
            ).toString();
636
            String sortBy = builder.ST_Distance(
637
                    builder.geometry(buffer), 
638
                    builder.column(featureType.getDefaultGeometryAttributeName())
639
            ).toString();
640
            Expression sortByExpression = ExpressionUtils.createExpression(sortBy);
641

    
642
            feature = store.findFirst(filter, sortByExpression, true);
643

    
644
        } catch (Exception ex) {
645
            LOGGER.warn("Can't get feature on point (" + point.getX() + "," + point.getY(), ex);
646
        }
647

    
648
        return feature;
649
    }
650

    
651
    @Override
652
    public Geometry getGeometry(Point point, FeatureStore store, MapContext mapContext) {
653
        Geometry geometry = null;
654
        try {
655
//            Feature f = getFeature(point, store, mapContext);
656
//            if (f != null) {
657
//                geometry = f.getDefaultGeometry();
658
//            }
659

    
660
            double tolerance = mapContext.getViewPort().toMapDistance(mapContext.getLayers().getDefaultTolerance());
661
            Geometry buffer = point.buffer(tolerance);
662
            FLyrVect layer = (FLyrVect) mapContext.getLayers().getLayer(store);
663
            SpatialCache sc = layer.getSpatialCache();
664
            if(sc.isOverflown()){
665
                LOGGER.warn("Spatial Cache overflown. Limit = "+sc.getMaxFeatures()+". You must increase limit or zoom in.");
666
            }
667
                
668
            List<Geometry> geometries = sc.query(buffer.getEnvelope());
669
            double minDistance = Double.POSITIVE_INFINITY;
670
            for (Geometry geom : geometries) {
671
                if(geom.intersects(buffer)){
672
                    double distance = geom.distance(point);
673
                    if(distance<minDistance){
674
                        minDistance = distance;
675
                        geometry = geom;
676
                    }
677
                }
678
            }
679

    
680
        } catch (Exception ex) {
681
            LOGGER.warn("Can't get geometry on point (" + point.getX() + "," + point.getY(), ex);
682
        }
683

    
684
        return geometry;
685
    }
686

    
687
    @Override
688
    public Geometry getGeometryOfVisibleLayers(Point point, FeatureStore store, MapContext mapContext) {
689

    
690
        // Search in the store itself
691
        Geometry geometry = this.getGeometry(point, store, mapContext);
692
        // Search in the store for the layers that are in edit
693
        if (geometry == null) {
694
            for (Iterator<FLayer> iterator = mapContext.getLayers().deepiterator(); iterator.hasNext();) {
695
                FLayer layer = iterator.next();
696
                if (layer instanceof FLyrVect) {
697
                    FLyrVect vectLayer = (FLyrVect) layer;
698
                    if (vectLayer.getFeatureStore() != store && vectLayer.isEditing()) {
699
                        geometry = this.getGeometry(point, vectLayer.getFeatureStore(), mapContext);
700
                        if (geometry != null) {
701
                            break;
702
                        }
703
                    }
704
                }
705
            }
706
        }
707
        // Search in the store for the active layers
708
        if (geometry == null) {
709
            FLayer[] activeLayers = mapContext.getLayers().getActives();
710
            for (FLayer activeLayer : activeLayers) {
711
                if (activeLayer instanceof FLyrVect) {
712
                    FLyrVect activeVectLayer = (FLyrVect) activeLayer;
713
                    if (activeVectLayer.getFeatureStore() != store && !activeVectLayer.isEditing()) {
714
                        geometry = this.getGeometry(point, activeVectLayer.getFeatureStore(), mapContext);
715
                        if (geometry != null) {
716
                            break;
717
                        }
718
                    }
719
                }
720
            }
721
        }
722
        return geometry;
723
    }
724

    
725
    @Override
726
    public void addAngleToDrawingStatus(DefaultDrawingStatus drawingStatus, ISymbol textSymbol, Point vertex, Point ray1, Point ray2, int subtype) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
727
        EditingProviderManager editingProviderManager
728
                = EditingProviderLocator.getProviderManager();
729
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
730

    
731
        double angleRay1 = GeometryUtils.calculateAngle(vertex, ray1);
732
        double angle = GeometryUtils.calculateAngle(vertex, ray1, ray2);
733
        double radius = vertex.distance(ray1) / 4;
734
        Arc auxArc = GeometryUtils.createArc(
735
                vertex,
736
                radius,
737
                GeometryUtils.calculateAngle(vertex, ray1),
738
                angle,
739
                subtype
740
        );
741
        drawingStatus.addStatus(auxArc, auxiliaryLineSymbolEditing, "");
742

    
743
        Point measurePoint = GeometryUtils.createPoint(vertex, radius, angleRay1 + angle / 2);
744

    
745
//        drawingStatus.addStatus(measurePoint, textSymbol, new AngleFormat("DD?MM'").format(Math.toDegrees(angle)));
746
        drawingStatus.addStatus(measurePoint, textSymbol, new AngleFormat("DD.ddd?").format(Math.toDegrees(angle)));
747

    
748
    }
749
    
750
    
751
    @Override
752
    public EditableFeature createNewFeature(FeatureStore store){
753
        try {
754
            return store.createNewFeature();
755
        } catch (DataException ex) {
756
            throw new RuntimeException("Can't create feature", ex);
757
        }
758
    }
759
}