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

History | View | Annotate | Download (28.1 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 org.geotools.measure.AngleFormat;
30
import org.gvsig.euclidean.EuclideanLine2D;
31
import org.gvsig.expressionevaluator.Expression;
32
import org.gvsig.expressionevaluator.ExpressionUtils;
33
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
34
import org.gvsig.fmap.dal.DALLocator;
35
import org.gvsig.fmap.dal.DataManager;
36

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

    
80
public class DefaultEditingProviderServices extends AbstractProviderServices
81
        implements EditingProviderServices {
82

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

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

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

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

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

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

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

    
127
            featureStore.insert(eFeature);
128

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

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

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

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

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

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

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

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

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

    
181
            featureStore.insert(eFeature);
182

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

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

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

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

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

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

    
221
            set.delete(feature);
222

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

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

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

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

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

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

    
258
            featureStore.delete(feature);
259

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

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

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

    
274
        try {
275

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
479
        return res;
480
    }
481

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

    
490
        double m1 = Double.POSITIVE_INFINITY;
491

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

    
496
        double m2 = Double.POSITIVE_INFINITY;
497

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

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

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

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

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

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

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

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

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

    
530
        return null;
531
    }
532

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

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

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

    
548
        return angle;
549
    }
550

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

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

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

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

    
575
        I18nManager i18nManager = ToolsLocator.getI18nManager();
576

    
577
        StringBuilder stb = new StringBuilder();
578

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

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

    
592
        return stb.toString();
593
    }
594

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

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

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

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

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

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

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

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

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

    
647
        return feature;
648
    }
649

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

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

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

    
683
        return geometry;
684
    }
685

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

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

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

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

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

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

    
747
    }
748
}