Revision 600

View differences:

org.gvsig.vectorediting.offset/trunk/org.gvsig.vectorediting.offset/pom.xml
3 3
  <parent>
4 4
    <groupId>org.gvsig</groupId>
5 5
    <artifactId>org.gvsig.desktop</artifactId>
6
    <version>2.0.105</version>
6
    <version>2.0.111</version>
7 7
  </parent>
8 8
  <artifactId>org.gvsig.vectorediting.offset</artifactId>
9 9
  <version>1.0.0-SNAPSHOT</version>
......
80 80
  </modules>
81 81

  
82 82
  <properties>
83
     <org.gvsig.vectorediting.version>1.0.17</org.gvsig.vectorediting.version>
83
     <org.gvsig.vectorediting.version>1.0.19</org.gvsig.vectorediting.version>
84 84
  </properties>
85 85
</project>
org.gvsig.vectorediting.offset/trunk/org.gvsig.vectorediting.offset/org.gvsig.vectorediting.offset.lib/org.gvsig.vectorediting.offset.lib.prov/org.gvsig.vectorediting.offset.lib.prov.offset/src/main/java/org/gvsig/vectorediting/offset/lib/prov/offset/OffsetEditingProvider.java
24 24

  
25 25
package org.gvsig.vectorediting.offset.lib.prov.offset;
26 26

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

  
34
import org.apache.commons.lang3.mutable.MutableDouble;
35 33
import org.gvsig.fmap.dal.exception.DataException;
36 34
import org.gvsig.fmap.dal.feature.EditableFeature;
37 35
import org.gvsig.fmap.dal.feature.Feature;
38 36
import org.gvsig.fmap.dal.feature.FeatureSelection;
39 37
import org.gvsig.fmap.dal.feature.FeatureStore;
40 38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryException;
41 40
import org.gvsig.fmap.geom.GeometryLocator;
42 41
import org.gvsig.fmap.geom.GeometryManager;
43 42
import org.gvsig.fmap.geom.aggregate.Aggregate;
44 43
import org.gvsig.fmap.geom.aggregate.MultiCurve;
45 44
import org.gvsig.fmap.geom.aggregate.MultiPoint;
46 45
import org.gvsig.fmap.geom.aggregate.MultiSurface;
47
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
48
import org.gvsig.fmap.geom.exception.CreateGeometryException;
49 46
import org.gvsig.fmap.geom.operation.GeometryOperationException;
50 47
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
48
import org.gvsig.fmap.geom.primitive.Arc;
51 49
import org.gvsig.fmap.geom.primitive.Circle;
52 50
import org.gvsig.fmap.geom.primitive.Circumference;
53 51
import org.gvsig.fmap.geom.primitive.Curve;
54 52
import org.gvsig.fmap.geom.primitive.Ellipse;
55
import org.gvsig.fmap.geom.primitive.Envelope;
53
import org.gvsig.fmap.geom.primitive.FilledSpline;
56 54
import org.gvsig.fmap.geom.primitive.Line;
57
import org.gvsig.fmap.geom.primitive.OrientablePrimitive;
58 55
import org.gvsig.fmap.geom.primitive.PeriEllipse;
59 56
import org.gvsig.fmap.geom.primitive.Point;
60 57
import org.gvsig.fmap.geom.primitive.Polygon;
58
import org.gvsig.fmap.geom.primitive.Spline;
61 59
import org.gvsig.fmap.geom.primitive.Surface;
62 60
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
63 61
import org.gvsig.tools.ToolsLocator;
64 62
import org.gvsig.tools.dispose.DisposableIterator;
65 63
import org.gvsig.tools.dynobject.DynObject;
66 64
import org.gvsig.tools.i18n.I18nManager;
67
import org.gvsig.tools.locator.LocatorException;
68 65
import org.gvsig.tools.service.spi.ProviderServices;
69 66
import org.gvsig.vectorediting.lib.api.DrawingStatus;
70 67
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
......
85 82
public class OffsetEditingProvider extends AbstractEditingProvider implements
86 83
    EditingProvider {
87 84

  
88
    private final Double PRECISION=new Double(1.0e-5);
85
    private final Double PRECISION = new Double(1.0e-5);
89 86

  
90 87
    private I18nManager i18nManager = ToolsLocator.getI18nManager();
91 88

  
92 89
    private EditingServiceParameter selectionParameter;
93 90

  
94
    private EditingServiceParameter pointParameter;
91
    private EditingServiceParameter offsetParameter;
95 92

  
93
    private EditingServiceParameter deleteOriginalGeometriesParameter;
94

  
95
    private boolean deleteOriginalGeometries = false;
96

  
96 97
    private Map<EditingServiceParameter, Object> values;
97 98

  
99
    private Map<String, String> options;
100

  
98 101
    private FeatureStore featureStore;
99 102

  
100
    public OffsetEditingProvider(ProviderServices providerServices,
101
        DynObject parameters) {
103
    public OffsetEditingProvider(ProviderServices providerServices, DynObject parameters) {
102 104
        super(providerServices);
103
        this.featureStore =
104
            (FeatureStore) parameters
105
                .getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
105
        this.featureStore = (FeatureStore) parameters.getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD);
106 106

  
107 107
        this.selectionParameter =
108 108
            new DefaultEditingServiceParameter("selection",
109 109
                i18nManager.getTranslation("selection"), TYPE.SELECTION);
110 110

  
111
        this.pointParameter =
111
        this.offsetParameter =
112 112
            new DefaultEditingServiceParameter("offset_distance",
113 113
                i18nManager.getTranslation("offset_distance"),
114
                TYPE.POSITION);
114
                TYPE.POSITION, TYPE.VALUE);
115

  
116
        this.options = new LinkedHashMap<String, String>();
117
        options.put(i18nManager.getTranslation("short_yes"),
118
            "delete_original_geometries");
119
        options.put(i18nManager.getTranslation("short_no"),
120
            "keep_original_geometries");
121

  
122
        EditingProviderServices editingProviderServices =
123
            (EditingProviderServices) getProviderServices();
124

  
125
        String consoleMsg =
126
            editingProviderServices.makeConsoleMessage(
127
                "delete_original_geometries_question", options);
128

  
129
        this.deleteOriginalGeometriesParameter =
130
            new DefaultEditingServiceParameter("Delete original geometries",
131
                consoleMsg, options, TYPE.OPTION);
132

  
115 133
    }
116 134

  
117 135
    public EditingServiceParameter next() {
118 136

  
119 137
        if (values.get(selectionParameter) == null) {
120 138
            return selectionParameter;
121
        } else if (values.get(pointParameter) == null) {
122
            return pointParameter;
139
        } else if (values.get(offsetParameter) == null) {
140
            return offsetParameter;
141
        } else if (values.get(deleteOriginalGeometriesParameter) == null) {
142
            return this.deleteOriginalGeometriesParameter;
123 143
        }
144

  
124 145
        return null;
125 146
    }
126 147

  
127
    public DrawingStatus getDrawingStatus(Point mousePosition)
128
        throws DrawServiceException {
148
    public DrawingStatus getDrawingStatus(Point mousePosition) throws DrawServiceException {
129 149
        DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
130 150
        EditingProviderManager editingProviderManager =
131 151
            EditingProviderLocator.getProviderManager();
132
        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
152
//        ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
133 153
        ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
134 154
        ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
135 155
        ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
......
139 159
            (FeatureSelection) values.get(selectionParameter);
140 160
        try {
141 161
            if ((selected != null) && !selected.isEmpty()) {
142
                Point point=null;
143
                Object pointValue = (Point) values.get(pointParameter);
144
                if ((pointValue != null) && (pointValue instanceof Point)) {
145
                    point=(Point)pointValue;
146
                }else{
147
                    point=mousePosition;
148
                    Line line;
149
                    line =
150
                        GeometryLocator.getGeometryManager().createLine(
151
                            featureStore.getDefaultFeatureType()
152
                                .getDefaultGeometryAttribute().getGeomType()
153
                                .getSubType());
154
                    Point closestPoint=getClosestPoint(point,selected);
155
                    //TODO
156
                    Point perpendicularPoint=null;
157
                    MutableDouble normalModule=new MutableDouble();
158
                    try {
159
                        perpendicularPoint=getPerpendicularPoint(closestPoint, point,selected,normalModule);
160
                    } catch (Exception e) {
161
                        throw new DrawServiceException(e);
162
                Point point = null;
163
                double distance = 0.0;
164
                Object offsetValue = values.get(offsetParameter);
165
                if (offsetValue != null){
166
                    if (offsetValue instanceof Point) {
167
                        point = (Point) offsetValue;
168
                    } else {
169
                        distance = (Double) offsetValue;
162 170
                    }
163
                    line.addVertex(closestPoint);
164
                    line.addVertex(perpendicularPoint);
171
                } else {
172
                    point = mousePosition;
173
                    distance = getMinDistance(selected, point);
174
                }
165 175

  
166
                    drawingStatus.addStatus(line, auxiliaryLineSymbolEditing, "");
167 176

  
168
                    AffineTransform at;
169
                    try {
170
                        at = getSymmetryAffineTransform(normalModule.getValue());
171
                    } catch (Exception e) {
172
                        throw new DrawServiceException(e);
173
                    }
177
                DisposableIterator it;
178
                it = selected.fastIterator();
174 179

  
175
                    DisposableIterator it;
176
                    it = selected.fastIterator();
180
                while (it.hasNext()) {
181
                    Feature feat = (Feature) it.next();
182
                    Geometry transformedGeometry = feat.getDefaultGeometry().offset(distance);
177 183

  
178
                    while (it.hasNext()) {
179
                        Feature feat = (Feature) it.next();
180
                        Geometry transformedGeometry = feat.getDefaultGeometry().cloneGeometry();
181
                        transformedGeometry.transform(at);
182

  
183
                        ISymbol symbol=null;
184
                        if(transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve){
185
                            symbol = lineSymbolEditing;
186
                        } else if(transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface){
187
                            symbol = polygonSymbolEditing;
188
                        } else if(transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint){
189
                            symbol = auxiliaryPointSymbolEditing;
184
                    ISymbol symbol = null;
185
                    if (transformedGeometry instanceof Curve || transformedGeometry instanceof MultiCurve) {
186
                        symbol = lineSymbolEditing;
187
                    } else if (transformedGeometry instanceof Surface || transformedGeometry instanceof MultiSurface) {
188
                        symbol = polygonSymbolEditing;
189
                    } else if (transformedGeometry instanceof Point || transformedGeometry instanceof MultiPoint) {
190
                        symbol = auxiliaryPointSymbolEditing;
191
                    }
192
                    if (transformedGeometry instanceof Aggregate) {
193
                        int primitivesNumber = ((Aggregate) transformedGeometry).getPrimitivesNumber();
194
                        for (int i = 0; i < primitivesNumber; i++) {
195
                            drawingStatus.addStatus(((Aggregate) transformedGeometry).getPrimitiveAt(i), symbol, "");
190 196
                        }
191
                        if(transformedGeometry instanceof Aggregate){
192
                            int primitivesNumber = ((Aggregate)transformedGeometry).getPrimitivesNumber();
193
                            for (int i = 0; i < primitivesNumber; i++) {
194
                                drawingStatus.addStatus(((Aggregate)transformedGeometry).getPrimitiveAt(i), symbol, "");
195
                            }
196
                        } else {
197
                            drawingStatus.addStatus(transformedGeometry, symbol, "");
198
                        }
197
                    } else {
198
                        drawingStatus.addStatus(transformedGeometry, symbol, "");
199 199
                    }
200
                    it.dispose();
201 200
                }
202
                return drawingStatus;
201
                it.dispose();
203 202
            }
203
            return drawingStatus;
204 204
        } catch (Exception e) {
205 205
            throw new DrawServiceException(e);
206 206
        }
207
        return null;
208 207
    }
209 208

  
210
    private AffineTransform getSymmetryAffineTransform(Double distance)
211
        throws GeometryOperationNotSupportedException,
212
        GeometryOperationException {
209
    /**
210
     * @param selected
211
     * @param point
212
     * @return
213
     * @throws DataException
214
     * @throws GeometryOperationException
215
     * @throws GeometryOperationNotSupportedException
216
     * @throws GeometryException
217
     */
218
    private double getMinDistance(FeatureSelection selected, Point point) throws DataException, GeometryOperationNotSupportedException, GeometryOperationException, GeometryException {
219
        double minorDistance=Double.POSITIVE_INFINITY;
220
        DisposableIterator it;
221
        it = selected.fastIterator();
222
        while (it.hasNext()) {
223
            Feature feat = (Feature) it.next();
224
            Geometry geometry = feat.getDefaultGeometry();
225
            double distance = getDistance(geometry, point);
226
            if(distance < minorDistance){
227
                minorDistance = distance;
228
            }
229
        }
230
        it.dispose();
231
        return minorDistance;
213 232

  
214
        AffineTransform translate =
215
            AffineTransform.getTranslateInstance(distance,
216
                0);
217

  
218
        return translate;
219 233
    }
220 234

  
235
    /**
236
     * @param geometry
237
     * @param point
238
     * @return
239
     * @throws GeometryOperationException
240
     * @throws GeometryOperationNotSupportedException
241
     * @throws GeometryException
242
     */
243
    private double getDistance(Geometry geometry, Point point) throws GeometryOperationNotSupportedException, GeometryOperationException, GeometryException {
244
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
245
        if(geometry instanceof Arc){
246
            Arc arc = (Arc)geometry;
247
            Point center = arc.getCenterPoint();
248
            double radius = center.distance(arc.getInitPoint());
249
            double distance = center.distance(point)-radius;
250
            return distance;
251
        }
221 252

  
253
        if(geometry instanceof Circle){
254
            Circle circle = (Circle)geometry;
255
            return circle.getCenter().distance(point)-circle.getRadious();
256
        }
257
        if(geometry instanceof Circumference){
258
            Circumference circumference = (Circumference)geometry;
259
            return circumference.getCenter().distance(point)-circumference.getRadious();
260
        }
261
        if(geometry instanceof PeriEllipse){
262
            double minDistance = Double.POSITIVE_INFINITY;
263
            PeriEllipse ellipse = (PeriEllipse)geometry;
264
            Geometry[] closestPoints = point.closestPoints(ellipse);
265
            if (closestPoints!=null){
266
                for (int i = 0; i < closestPoints.length; i++) {
267
                    Geometry closestPoint = closestPoints[i];
268
                    if (!point.equals(closestPoint)) {
269
                        double distance = closestPoint.distance(point);
270
                        if (distance < minDistance) {
271
                            minDistance = distance;
272
                        }
273
                    }
274
                }
275
            }
276
            Ellipse auxEllipse = (Ellipse)geomManager.create(Geometry.TYPES.ELLIPSE, geometry.getGeometryType().getSubType());
277
            auxEllipse.setPoints(ellipse.getAxis1Start(), ellipse.getAxis1End(), ellipse.getAxis2Dist());
278
            if(auxEllipse.contains(point)){
279
                return -minDistance;
280
            }
281
            return minDistance;
282
        }
283
        if(geometry instanceof Ellipse){
284
            Ellipse ellipse = (Ellipse)geometry;
285
            PeriEllipse auxPeriEllipse = (PeriEllipse)geomManager.create(Geometry.TYPES.PERIELLIPSE, geometry.getGeometryType().getSubType());
286
            auxPeriEllipse.setPoints(ellipse.getAxis1Start(), ellipse.getAxis1End(), ellipse.getAxis2Dist());
287
            double distance = getDistance(auxPeriEllipse, point);
288
//            if(ellipse.contains(point)){
289
//                return -distance;
290
//            }
291

  
292
            return distance;
293
        }
294

  
295
        if(geometry instanceof Spline || geometry instanceof FilledSpline ){
296
            return getDistance(geometry.toLines().getPrimitiveAt(0), point);
297
        }
298

  
299
        if(geometry instanceof Line){
300
            Line line = (Line)geometry;
301
            double minDistance = Double.POSITIVE_INFINITY;
302
            Geometry[] closestPoints = point.closestPoints(line);
303
            Point closestPoint = null;
304
            if (closestPoints!=null){
305
                for (int i=0;i<closestPoints.length;i++){
306
                    Point p=(Point)closestPoints[i];
307
                    if (!point.equals(p)) {
308
                        double distance = p.distance(point);
309
                        if (distance < minDistance) {
310
                            minDistance = distance;
311
                            closestPoint = p;
312
                        }
313
                    }
314
                }
315
            }
316
            if(closestPoint != null){
317
                for(int i=0; i<line.getNumVertices()-1; i++){
318
                    Line segment = (Line) geomManager.create(Geometry.TYPES.LINE, geometry.getGeometryType().getSubType());
319
                    segment.addVertex(line.getVertex(i));
320
                    segment.addVertex(line.getVertex(i+1));
321
                    if(segment.isWithinDistance(closestPoint, PRECISION)){
322
                        if(line.getVertex(0).equals(line.getVertex(line.getNumVertices()-1))){ //isClosed
323
                            if(line.toPolygons().contains(point)){
324
                                return -minDistance;
325
                            };
326
                            return minDistance;
327
                        } else {
328
                            return getDirectedDistance(closestPoint, point, segment);
329
                        }
330
                    }
331
                }
332
            }
333
        }
334

  
335
        if(geometry instanceof Polygon){
336
            Polygon polygon = (Polygon)geometry;
337
            if(!polygon.contains(point)){
338
                double minDistance = Double.POSITIVE_INFINITY;
339
                Geometry[] closestPoints = point.closestPoints(polygon);
340
                Point closestPoint = null;
341
                if (closestPoints!=null){
342
                    for (int i=0;i<closestPoints.length;i++){
343
                        Point p=(Point)closestPoints[i];
344
                        if (!point.equals(p)) {
345
                            double distance = p.distance(point);
346
                            if (distance < minDistance) {
347
                                minDistance = distance;
348
                                closestPoint = p;
349
                            }
350
                        }
351
                    }
352
                }
353
                if(closestPoint != null){
354
                    return closestPoint.distance(point);
355
                }
356
            } else {
357
                Line auxLine = (Line) polygon.toLines().getPrimitiveAt(0);
358
                if(auxLine!=null){
359
                    return getDistance(auxLine, point);
360
                }
361
            }
362
        }
363

  
364
        if(geometry instanceof Aggregate){
365
            double minDistance = Double.POSITIVE_INFINITY;
366
            Aggregate aggregate2 = (Aggregate)geometry;
367
            for(int i=0; i<aggregate2.getPrimitivesNumber(); i++){
368
                double distance = getDistance(aggregate2.getPrimitiveAt(i),point);
369
                if(distance<minDistance){
370
                    minDistance = distance;
371
                }
372
            }
373
            return minDistance;
374
        }
375
        return 0.0;
376
    }
377

  
222 378
    public void stop() {
223 379
        values.clear();
224 380
    }
......
230 386
                values.put(param, value);
231 387
                return;
232 388
            }
233
        } else if (param == pointParameter) {
389
        } else if (param == offsetParameter) {
234 390
            if (value instanceof Point) {
235
                values.put(param, value);
391
                try {
392
                    values.put(param, getMinDistance((FeatureSelection) values.get(selectionParameter), (Point) value));
393
                } catch (Exception e) {
394
                    throw new InvalidEntryException(e);
395
                }
236 396
                return;
237 397
            }
398
            if (value instanceof Double) {
399
                values.put(param, value);
400
            }
401
        } else if (param == deleteOriginalGeometriesParameter) {
402
            if (value instanceof String) {
403
                if (((String) value).trim().equalsIgnoreCase(
404
                    i18nManager.getTranslation("short_yes"))) {
405
                    deleteOriginalGeometries = true;
406
                } else if (((String) value).trim().equalsIgnoreCase(
407
                    i18nManager.getTranslation("short_no"))) {
408
                    deleteOriginalGeometries = false;
409
                } else {
410
                    throw new InvalidEntryException(null);
411
                }
412
                values.put(param, value);
413
            }
238 414
        }
415

  
239 416
    }
240 417

  
241 418
    public List<EditingServiceParameter> getParameters() {
242 419
        List<EditingServiceParameter> list =
243 420
            new ArrayList<EditingServiceParameter>();
244 421
        list.add(selectionParameter);
245
        list.add(pointParameter);
422
        list.add(offsetParameter);
246 423
        return list;
247 424
    }
248 425

  
......
257 434
            (FeatureSelection) values.get(selectionParameter);
258 435
        try {
259 436
            if (!selected.isEmpty()) {
260
                Point point = (Point) values.get(pointParameter);
261
                if ((point != null)) {
262

  
263
                    Double distance;
264
                    try {
265
                        Point closestPoint=getClosestPoint(point,selected);
266
                        distance = point.distance(closestPoint);
267
                    } catch (GeometryOperationNotSupportedException e1) {
268
                        throw new FinishServiceException(e1);
269
                    } catch (GeometryOperationException e1) {
270
                        throw new FinishServiceException(e1);
271
                    }
272

  
273
                    AffineTransform at;
274
                    try {
275
                        at = getSymmetryAffineTransform(distance);
276
                    } catch (GeometryOperationNotSupportedException e) {
277
                        throw new FinishServiceException(e);
278
                    } catch (GeometryOperationException e) {
279
                        throw new FinishServiceException(e);
280
                    }
281

  
437
                double distance = (Double) values.get(offsetParameter);
282 438
                    DisposableIterator it;
283 439
                    it = selected.fastIterator();
284 440

  
285 441
                    while (it.hasNext()) {
286 442
                        Feature feature = (Feature) it.next();
287
                        Geometry geom =
288
                            feature.getDefaultGeometry().cloneGeometry();
289
                        geom.transform(at);
443
                        Geometry geom;
444
                        try {
445
                            geom = feature.getDefaultGeometry().offset(distance);
446
                        } catch (GeometryOperationNotSupportedException e) {
447
                            throw new FinishServiceException(e);
448
                        } catch (GeometryOperationException e) {
449
                            throw new FinishServiceException(e);
450
                        }
290 451

  
291
                        // Se crea una feature nueva copiando los valores de
292
                        // la feature original excepto aquellos que sean PK
293
                        EditingProviderServices editingProviderServices =
294
                            (EditingProviderServices) getProviderServices();
295
                        EditableFeature editableFeature =
452
                        if (this.deleteOriginalGeometries) {
453
                            // Se sustituye la geometr?a original por la
454
                            // calculada
455
                            EditableFeature editableFeature =
456
                                feature.getEditable();
457
                            editableFeature.setDefaultGeometry(geom);
458
                            ((EditingProviderServices) getProviderServices())
459
                                .updateFeatureInFeatureStore(editableFeature,
460
                                    featureStore);
461
                        } else {
462
                            // Se crea una feature nueva copiando los valores de
463
                            // la feature original excepto aquellos que sean PK
464
                            EditingProviderServices editingProviderServices =
465
                                (EditingProviderServices) getProviderServices();
466
                            EditableFeature editableFeature =
467
                                editingProviderServices
468
                                    .getFeatureCopyWithoutPK(featureStore,
469
                                        feature);
470
                            editableFeature.setDefaultGeometry(geom);
296 471
                            editingProviderServices
297
                                .getFeatureCopyWithoutPK(featureStore,
298
                                    feature);
299
                        editableFeature.setDefaultGeometry(geom);
300
                        editingProviderServices
301
                            .insertFeatureIntoFeatureStore(editableFeature,
302
                                featureStore);
472
                                .insertFeatureIntoFeatureStore(editableFeature,
473
                                    featureStore);
474
                        }
303 475

  
304 476
                    }
305 477
                    it.dispose();
306 478
                    featureStore.getFeatureSelection().deselectAll();
307 479
                }
308
            }
309 480
        } catch (DataException e) {
310 481
            throw new FinishServiceException(e);
311 482
        }
312 483
    }
313 484

  
314

  
315
    private Point getPerpendicularPoint(Point closestPoint, Point distancePoint,FeatureSelection selected, MutableDouble normalModule)
316
        throws DataException, CreateEnvelopeException, GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException, LocatorException{
317

  
318
        int subType = featureStore.getDefaultFeatureType()
319
            .getDefaultGeometryAttribute().getGeomType()
320
            .getSubType();
321

  
322
        Geometry containingGeometry=getContainingGeometry(selected, closestPoint);
323

  
324
        if (containingGeometry instanceof Circle || containingGeometry instanceof Ellipse ||
325
            containingGeometry instanceof Circumference || containingGeometry instanceof PeriEllipse){
326
            if (containingGeometry instanceof Circle){
327
                Circle circle=(Circle)containingGeometry;
328
                Circumference circumference =(Circumference)GeometryLocator.
329
                getGeometryManager().create(Geometry.TYPES.CIRCUMFERENCE, subType);
330
                circumference.setPoints(circle.getCenter(), circle.getRadious());
331
                containingGeometry=circumference;
332
            }
333
            if (containingGeometry instanceof Ellipse ){
334
                Ellipse ellipse=(Ellipse)containingGeometry;
335
                PeriEllipse periellipse =(PeriEllipse)GeometryLocator.
336
                getGeometryManager().create(Geometry.TYPES.PERIELLIPSE, subType);
337
                periellipse.setPoints(ellipse.getAxis1Start(), ellipse.getAxis1End(), ellipse.getAxis2Dist());
338
                containingGeometry=periellipse;
339
            }
340
            if (containingGeometry instanceof PeriEllipse || containingGeometry instanceof Circumference){
341
                Integer direction;
342
                if (containingGeometry.contains(distancePoint)){
343
                    direction=-1;
344
                }else{
345
                    direction=1;
346
                }
347
                normalModule.setValue(closestPoint.distance(distancePoint)*direction);
348
                return distancePoint;
349
            }
350
        }
351

  
352
        Line containingLine=null;
353
        if (containingGeometry!=null){
354
            containingLine = getContainingLine(containingGeometry, closestPoint, subType);
355
        }
356

  
357
        if (containingLine!=null){
358
            Double module=containingLine.perimeter();
359

  
360
            Point point0=containingLine.getVertex(0);
361
            Point point1=containingLine.getVertex(1);
362

  
363
            Double unitarianX=(point1.getX()-point0.getX())/module;
364
            Double unitarianY=(point1.getY()-point0.getY())/module;
365

  
366
            Point unitarianPoint=GeometryLocator.getGeometryManager().createPoint(
367
                unitarianX,
368
                unitarianY,
369
                subType);
370

  
371
            Double perpendicularAngle=Math.PI/2;
372
            AffineTransform rotate = AffineTransform.getRotateInstance(perpendicularAngle);
373
            unitarianPoint.transform(rotate);
374

  
375
            double distance=getDirectedDistance(closestPoint, distancePoint, containingLine);
376

  
377
            unitarianPoint.setX(unitarianPoint.getX()*distance);
378
            unitarianPoint.setY(unitarianPoint.getY()*distance);
379

  
380
            unitarianPoint.setX(unitarianPoint.getX()+closestPoint.getX());
381
            unitarianPoint.setY(unitarianPoint.getY()+closestPoint.getY());
382

  
383
            if (distance>0){
384
                normalModule.setValue(unitarianPoint.distance(closestPoint));
385
            }else{
386
                normalModule.setValue(-unitarianPoint.distance(closestPoint));
387
            }
388

  
389
            return unitarianPoint;
390
        }
391
        return null;
392
    }
393

  
394 485
    private Double getDirectedDistance(Point pointInLine, Point distancePoint, Line line)
395 486
        throws GeometryOperationNotSupportedException, GeometryOperationException{
396 487
        Double distance=distancePoint.distance(pointInLine);
......
404 495
            angleDifference+=2*Math.PI;
405 496
        }
406 497
        if (angleDifference > Math.PI ) {
407
            distance = -distance; // perpendicularAngle=3*Math.PI/2;
498
            distance = -distance;
408 499
        }
409 500
        return distance;
410 501
    }
411 502

  
412
    private Line getContainingLine(Geometry containingGeometry,
413
        Point containedPoint, int subType)
414
            throws CreateGeometryException,
415
            GeometryOperationNotSupportedException, GeometryOperationException {
416
        if (containingGeometry instanceof Line ||containingGeometry instanceof Polygon ){
417
            OrientablePrimitive orientableGeometry=(OrientablePrimitive)containingGeometry;
418
            for (int i=0; i<orientableGeometry.getNumVertices()-1;i++){
419
                Point point=orientableGeometry.getVertex(i);
420
                Point nextPoint=orientableGeometry.getVertex(i+1);
421
                Line line =
422
                    GeometryLocator.getGeometryManager().createLine(
423
                        subType);
424
                 line.addVertex(point);
425
                 line.addVertex(nextPoint);
426
                 //FIXME
427
                 //if (line.contains(closestPoint)){
428
                 if (line.isWithinDistance(containedPoint, PRECISION)){
429
                     return line;
430
                 }
431
            }
432
        }
433
        return null;
434
    }
435

  
436
    private Geometry getContainingGeometry (FeatureSelection selected,Point point)
437
        throws DataException, GeometryOperationNotSupportedException, GeometryOperationException{
438

  
439
        DisposableIterator it;
440
        it = selected.fastIterator();
441
        while (it.hasNext()) {
442
            Feature feat = (Feature) it.next();
443
            Geometry geometry = feat.getDefaultGeometry();
444
            if(geometry instanceof Aggregate){
445
                int primitivesNumber = ((Aggregate)geometry).getPrimitivesNumber();
446
                for (int i = 0; i < primitivesNumber; i++) {
447
                    Geometry primitiveGeometry=((Aggregate)geometry).getPrimitiveAt(i);
448
                    if (primitiveGeometry instanceof Polygon) {
449
                        Polygon geomPoly = (Polygon)primitiveGeometry;
450
                        //FIXME
451
                        if (geomPoly.isWithinDistance(point, PRECISION)){
452
                        //if (geomPoly.touches(point)){
453
                            return primitiveGeometry;
454
                        }
455
                      //FIXME
456
                      //} else if(primitiveGeometry.contains(closestPoint)){
457
                      } else if(primitiveGeometry.isWithinDistance(point, PRECISION)){
458
                            return primitiveGeometry;
459
                    }
460
                }
461
            } else {
462
                if (geometry instanceof Polygon) {
463
                    Polygon geomPoly = (Polygon)geometry;
464
                  //FIXME
465
                    if (geomPoly.isWithinDistance(point, PRECISION)){
466
                    //if (geomPoly.touches(point)){
467
                        return geometry;
468
                    }
469
                //FIXME
470
                //} else if(geometry.contains(closestPoint)){
471
                } else if(geometry.isWithinDistance(point, PRECISION)){
472
                    return geometry;
473
                }
474
            }
475
        }
476
        return null;
477
    }
478

  
479
    private Point getClosestPoint(Point point, FeatureSelection selected)
480
        throws DataException, GeometryOperationNotSupportedException,
481
        GeometryOperationException{
482

  
483
        DisposableIterator it;
484
        it = selected.fastIterator();
485
        ArrayList<Point> closestPoints = new ArrayList<Point>();
486
        while (it.hasNext()) {
487
            Feature feat = (Feature) it.next();
488
            Geometry geometry = feat.getDefaultGeometry();
489
            Geometry[] geoms = point.closestPoints(geometry);
490
            if (geoms!=null){
491
                for (int i=0;i<geoms.length;i++){
492
                    Geometry closePoint=geoms[i];
493
                    if (closePoint!=null && closePoint instanceof Point){
494
                        closestPoints.add((Point)closePoint);
495
                    }
496
                }
497
            }
498
        }
499
        it.dispose();
500
        double minorDistance=Double.POSITIVE_INFINITY;
501
        Point closestPoint=null;
502
        for (Point closePoint:closestPoints){
503
            double distance=point.distance(closePoint);
504
            if (distance<minorDistance && distance>Double.valueOf(0)){
505
                minorDistance=distance;
506
                closestPoint=closePoint;
507
            }
508
        }
509
        return closestPoint;
510
    }
511

  
512

  
513 503
    public Geometry finish() throws FinishServiceException {
514 504
        return null;
515 505
    }
......
536 526
    public String getName() {
537 527
        return OffsetEditingProviderFactory.PROVIDER_NAME;
538 528
    }
539

  
540
}
529
}

Also available in: Unified diff