Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / gui / cad / tools / SplitGeometryCADTool.java @ 39578

History | View | Annotate | Download (22.5 KB)

1 37138 cordinyana
/* gvSIG. Geographic Information System of the Valencian Government
2 28070 vcaballero
 *
3 37138 cordinyana
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6 28070 vcaballero
 * 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 37138 cordinyana
 *
11 28070 vcaballero
 * 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 37138 cordinyana
 *
16 28070 vcaballero
 * 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 37138 cordinyana
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21 28070 vcaballero
 */
22 29616 jpiera
package org.gvsig.editing.gui.cad.tools;
23 28070 vcaballero
24 38539 jldominguez
import java.awt.Color;
25
import java.awt.Component;
26 28070 vcaballero
import java.awt.Image;
27
import java.awt.event.InputEvent;
28
import java.awt.event.MouseEvent;
29
import java.awt.geom.Point2D;
30
import java.util.ArrayList;
31
import java.util.List;
32
33 38539 jldominguez
import javax.swing.JOptionPane;
34
35 34696 cordinyana
import com.vividsolutions.jts.geom.Coordinate;
36
import com.vividsolutions.jts.geom.Geometry;
37
import com.vividsolutions.jts.geom.GeometryCollection;
38
import com.vividsolutions.jts.geom.GeometryFactory;
39
import com.vividsolutions.jts.geom.LineString;
40
import com.vividsolutions.jts.geom.MultiLineString;
41
import com.vividsolutions.jts.geom.MultiPoint;
42
import com.vividsolutions.jts.geom.MultiPolygon;
43
import com.vividsolutions.jts.geom.Point;
44
import com.vividsolutions.jts.geom.Polygon;
45
import com.vividsolutions.jts.geom.PrecisionModel;
46
47 38539 jldominguez
import org.slf4j.Logger;
48
import org.slf4j.LoggerFactory;
49
50 29756 jpiera
import org.gvsig.andami.PluginServices;
51 38539 jldominguez
import org.gvsig.andami.ui.mdiManager.IWindow;
52
import org.gvsig.app.ApplicationLocator;
53 29616 jpiera
import org.gvsig.editing.gui.cad.DefaultCADTool;
54
import org.gvsig.editing.gui.cad.exception.CommandException;
55
import org.gvsig.editing.gui.cad.tools.smc.SplitGeometryCADToolContext;
56
import org.gvsig.editing.gui.cad.tools.split.SplitStrategy;
57
import org.gvsig.editing.layers.VectorialLayerEdited;
58 29756 jpiera
import org.gvsig.fmap.dal.exception.DataException;
59 28070 vcaballero
import org.gvsig.fmap.dal.feature.EditableFeature;
60
import org.gvsig.fmap.dal.feature.Feature;
61
import org.gvsig.fmap.dal.feature.FeatureStore;
62
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
63 34696 cordinyana
import org.gvsig.fmap.geom.GeometryLocator;
64 28070 vcaballero
import org.gvsig.fmap.geom.exception.CreateGeometryException;
65
import org.gvsig.fmap.geom.operation.GeometryOperationException;
66
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
67
import org.gvsig.fmap.geom.primitive.Envelope;
68
import org.gvsig.fmap.geom.primitive.GeneralPathX;
69 37328 cordinyana
import org.gvsig.fmap.geom.type.GeometryType;
70 28070 vcaballero
import org.gvsig.fmap.geom.util.Converter;
71
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
72
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
73 38539 jldominguez
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
74 30335 jpiera
import org.gvsig.fmap.mapcontrol.MapControlDrawer;
75 38539 jldominguez
import org.gvsig.i18n.Messages;
76
import org.gvsig.symbology.SymbologyLocator;
77
import org.gvsig.symbology.SymbologyManager;
78
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.ISimpleFillSymbol;
79 31284 cordinyana
import org.gvsig.tools.dispose.DisposableIterator;
80
import org.gvsig.tools.dispose.DisposeUtils;
81 28070 vcaballero
import org.gvsig.tools.locator.LocatorException;
82
83
import statemap.State;
84 38539 jldominguez
import statemap.StateUndefinedException;
85 28070 vcaballero
86
/**
87
 * CAD Tool which splits the selected geometries of a vectorial editing
88
 * layer with a digitized polyline.
89 37138 cordinyana
 *
90
 *
91 28070 vcaballero
 * @author Alvaro Zabala
92 37138 cordinyana
 *
93 28070 vcaballero
 */
94
public class SplitGeometryCADTool extends DefaultCADTool {
95
96 38539 jldominguez
    private static Logger logger =
97
        LoggerFactory.getLogger(SplitGeometryCADTool.class);
98 37138 cordinyana
    /**
99
     * String representation of this tool (used for example to active the tool
100
     * in mapcontrol)
101
     */
102 38564 jjdelcerro
    public static final String SPLIT_GEOMETRY_ACTION_NAME = "layer-modify-split";
103 37138 cordinyana
    public static final String SPLIT_GEOMETRY_TOOL_NAME = "_split_geometry";
104 28070 vcaballero
105 37138 cordinyana
    /**
106
     * finite state machine for this CAD tool
107
     */
108
    protected SplitGeometryCADToolContext _fsm;
109 28070 vcaballero
110 37138 cordinyana
    /**
111
     * Flag to mark if the digitized line has been finished.
112
     */
113
    protected boolean digitizingFinished = false;
114 28070 vcaballero
115 37138 cordinyana
    /**
116
     * Collection of digitized geometries
117
     */
118
    protected List<Point2D> clickedPoints;
119 28070 vcaballero
120 37138 cordinyana
    /**
121 38539 jldominguez
     * used to draw helping rectangle (bbox)
122
     */
123
    protected ISymbol rectSymbol = null;
124
    /**
125 37138 cordinyana
     * Initialization method.
126
     */
127
    public void init() {
128
        digitizingFinished = false;
129
        _fsm = new SplitGeometryCADToolContext(this);
130
        setNextTool(SplitGeometryCADTool.SPLIT_GEOMETRY_TOOL_NAME);
131
    }
132 28070 vcaballero
133 37138 cordinyana
    public boolean isDigitizingFinished() {
134
        return digitizingFinished;
135
    }
136 28070 vcaballero
137 37138 cordinyana
    public String toString() {
138
        return SplitGeometryCADTool.SPLIT_GEOMETRY_TOOL_NAME;
139
    }
140 28070 vcaballero
141 37138 cordinyana
    public void finishDigitizedLine() {
142
    }
143 28070 vcaballero
144 37138 cordinyana
    public Coordinate[] getPoint2DAsCoordinates(Point2D[] point2d) {
145
        Coordinate[] solution = new Coordinate[point2d.length];
146
        for (int i = 0; i < point2d.length; i++) {
147
            solution[i] = new Coordinate(point2d[i].getX(), point2d[i].getY());
148
        }
149
        return solution;
150
    }
151 28070 vcaballero
152 37138 cordinyana
    public void splitSelectedGeometryWithDigitizedLine() {
153 38539 jldominguez
154
        // comprobar bucle, probar interseccion?
155 37138 cordinyana
        Point2D[] clickedPts = new Point2D[this.clickedPoints.size()];
156
        clickedPoints.toArray(clickedPts);
157
        Coordinate[] digitizedCoords = getPoint2DAsCoordinates(clickedPts);
158
        LineString splittingLs =
159
            new GeometryFactory(new PrecisionModel(10000))
160
                .createLineString(digitizedCoords);
161
        DisposableIterator selected = null;
162
        try {
163
            VectorialLayerEdited vle = getVLE();
164
            FeatureStore store = vle.getFeatureStore();
165
            selected = store.getFeatureSelection().iterator();
166 28070 vcaballero
167 37138 cordinyana
            getCadToolAdapter().getMapControl().getMapContext()
168
                .beginAtomicEvent();
169
            store.beginEditingGroup(getName());
170
            while (selected.hasNext()) {
171
                Feature feature = (Feature) selected.next();
172
                org.gvsig.fmap.geom.Geometry ig = feature.getDefaultGeometry();
173 37776 jpiera
                Geometry jtsGeo = (Geometry)ig.invokeOperation("toJTS", null);
174 37138 cordinyana
                if (jtsGeo == null)
175
                    return;
176
                Geometry splitGeo = SplitStrategy.splitOp(jtsGeo, splittingLs);
177
                if (splitGeo instanceof GeometryCollection
178
                    && ((GeometryCollection) splitGeo).getNumGeometries() > 1) {
179 28070 vcaballero
180 37138 cordinyana
                    GeometryCollection gc = (GeometryCollection) splitGeo;
181
                    ArrayList<Geometry> geoms0 = new ArrayList<Geometry>();
182
                    ArrayList<Geometry> geoms1 = new ArrayList<Geometry>();
183
                    if (gc.getNumGeometries() > 2) {
184
                        Geometry[] splitGroups =
185
                            createSplitGroups(jtsGeo, splittingLs);
186 38539 jldominguez
187
                        if (splitGroups == null) {
188
189
                            String _tit = Messages.getText("split_geometry");
190
                            String _msg = Messages.getText("_Split_line_must_start_and_end_outside_bbox");
191
                            Component parent = getCurrentWindow();
192
                            JOptionPane.showMessageDialog(
193
                                parent,
194
                                _msg,
195
                                _tit,
196
                                JOptionPane.WARNING_MESSAGE);
197
                            // cancel splitting
198
                            break;
199
                        }
200
201 37138 cordinyana
                        if (splitGroups.length == 0) {
202
                            continue;
203
                        }
204 28070 vcaballero
205 37138 cordinyana
                        for (int j = 0; j < gc.getNumGeometries(); j++) {
206
                            Geometry g = gc.getGeometryN(j);
207 38539 jldominguez
208
                            if (isRatherInside(g, splitGroups[0])) {
209
                                geoms0.add(g);
210
                            } else {
211
                                geoms1.add(g);
212 37138 cordinyana
                            }
213
                        }
214 38539 jldominguez
                    } else {
215 37138 cordinyana
                        if (gc.getNumGeometries() == 2) {
216
                            geoms0.add(gc.getGeometryN(0));
217
                            geoms1.add(gc.getGeometryN(1));
218
                        } else {
219
                            continue;
220
                        }
221 38539 jldominguez
                    }
222 37138 cordinyana
                    GeometryCollection gc0 =
223
                        createMulti(geoms0, gc.getFactory());
224 28070 vcaballero
225 37138 cordinyana
                    // for(int j = 0; j < gc.getNumGeometries(); j++){
226
                    // Geometry g = gc.getGeometryN(j);
227
                    org.gvsig.fmap.geom.Geometry fmapGeo =
228
                        Converter.jtsToGeometry(gc0);
229 28070 vcaballero
230 37138 cordinyana
                    // if (j==0){
231
                    EditableFeature eFeature = feature.getEditable();
232
                    eFeature.setGeometry(store.getDefaultFeatureType()
233
                        .getDefaultGeometryAttributeName(), fmapGeo);
234
                    store.update(eFeature);
235
                    // }else{
236
                    GeometryCollection gc1 =
237
                        createMulti(geoms1, gc.getFactory());
238
                    fmapGeo = Converter.jtsToGeometry(gc1);
239 28070 vcaballero
240 39578 jjdelcerro
                    super.insertGeometry(fmapGeo,feature);
241
//                    EditableFeature newFeature =
242
//                        store.createNewFeature(store.getDefaultFeatureType(),
243
//                            feature);
244
//                    newFeature.setGeometry(store.getDefaultFeatureType()
245
//                        .getDefaultGeometryAttributeName(), fmapGeo);
246
//                    store.insert(newFeature);
247
//
248
//                    SpatialCache spatialCache =
249
//                        ((FLyrVect) vle.getLayer()).getSpatialCache();
250
//                    Envelope envelope = fmapGeo.getEnvelope();
251
//                    spatialCache.insert(envelope, fmapGeo);
252
253 37138 cordinyana
                    // }
254
                    // }//for j
255
                }// if splitGeo
256 28070 vcaballero
257 37138 cordinyana
            }
258 28070 vcaballero
259 37138 cordinyana
            store.endEditingGroup();
260 28070 vcaballero
261 37138 cordinyana
            getCadToolAdapter().getMapControl().getMapContext()
262
                .endAtomicEvent();
263
        } catch (Exception ex) {
264
            PluginServices.getLogger().error("Error splitting geom", ex);
265
        } finally {
266
            DisposeUtils.dispose(selected);
267
        }
268
    }
269 28070 vcaballero
270 38539 jldominguez
    /**
271
     * @return
272
     */
273
    private Component getCurrentWindow() {
274
275
        IWindow iw = PluginServices.getMDIManager().getActiveWindow();
276
        if (iw instanceof Component) {
277
            return (Component) iw;
278
        } else {
279
            return null;
280
        }
281
    }
282
283 37138 cordinyana
    private GeometryCollection createMulti(ArrayList<Geometry> geoms,
284
        GeometryFactory factory) {
285
        if (geoms.size() == 0)
286
            return null;
287
        if (geoms.get(0) instanceof Polygon) {
288
            return new MultiPolygon((Polygon[]) geoms.toArray(new Polygon[0]),
289
                factory);
290
        } else
291
            if (geoms.get(0) instanceof LineString) {
292
                return new MultiLineString(
293
                    (LineString[]) geoms.toArray(new LineString[0]), factory);
294
            } else
295
                if (geoms.get(0) instanceof Point) {
296
                    return new MultiPoint(
297
                        (Point[]) geoms.toArray(new Point[0]), factory);
298
                }
299
        return null;
300
    }
301 28070 vcaballero
302 37138 cordinyana
    private Geometry[] createSplitGroups(Geometry splitGeo,
303
        LineString splittingLs) {
304
        try {
305
            Geometry[] geomsJTS = new Geometry[2];
306
            Geometry r = splitGeo.getEnvelope();
307
            Geometry splitG = SplitStrategy.splitOp(r, splittingLs);
308
            if (splitG instanceof GeometryCollection
309
                && ((GeometryCollection) splitG).getNumGeometries() > 1) {
310
                GeometryCollection gc = (GeometryCollection) splitG;
311
                for (int j = 0; j < gc.getNumGeometries(); j++) {
312
                    geomsJTS[j] = gc.getGeometryN(j);
313
                }
314
            }
315
            return geomsJTS;
316
        } catch (Exception e) {
317 38539 jldominguez
            logger.info("Warning: Found split line which does not leave bbox. User will be prompted.");
318 37138 cordinyana
        }
319
        return null;
320
    }
321 29724 vcaballero
322 37138 cordinyana
    public void end() {
323
        getCadToolAdapter().refreshEditedLayer();
324
        init();
325
    }
326 29724 vcaballero
327 37138 cordinyana
    public void addOption(String s) {
328
        State actualState = _fsm.getPreviousState();
329
        String status = actualState.getName();
330
        if (s.equals(PluginServices.getText(this, "cancel"))) {
331
            init();
332
            return;
333
        }
334
        if (status.equals("TopologicalEdition.FirstPoint")) {
335
            return;
336
        }
337
        init();
338 29724 vcaballero
339 37138 cordinyana
    }
340 28070 vcaballero
341 37138 cordinyana
    public void addPoint(double x, double y, InputEvent event) {
342 28070 vcaballero
343 37138 cordinyana
        State actualState = _fsm.getPreviousState();
344
        String status = actualState.getName();
345
        if (status.equals("SplitGeometry.FirstPoint")) {
346
            clickedPoints = new ArrayList<Point2D>();
347
            clickedPoints.add(new Point2D.Double(x, y));
348
        } else
349
            if (status.equals("SplitGeometry.DigitizingLine")) {
350
                clickedPoints.add(new Point2D.Double(x, y));
351
                if (event != null && ((MouseEvent) event).getClickCount() == 2) {
352
                    digitizingFinished = true;
353
                    finishDigitizedLine();
354
                    splitSelectedGeometryWithDigitizedLine();
355
                    end();
356
                }
357
            }
358
    }
359 28070 vcaballero
360 37138 cordinyana
    public void addValue(double d) {
361
    }
362 28070 vcaballero
363 37138 cordinyana
    /**
364
     * Draws a polyline with the clicked digitized points in the specified
365
     * graphics.
366
     *
367
     * @param g2
368
     *            graphics on to draw the polyline
369
     * @param x
370
     *            last x mouse pointer position
371
     * @param y
372
     *            last y mouse pointer position
373
     */
374
    protected void drawPolyLine(MapControlDrawer renderer, double x, double y) {
375
        GeneralPathX gpx =
376
            new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, clickedPoints.size());
377
        Point2D firstPoint = clickedPoints.get(0);
378
        gpx.moveTo(firstPoint.getX(), firstPoint.getY());
379
        for (int i = 1; i < clickedPoints.size(); i++) {
380
            Point2D clickedPoint = clickedPoints.get(i);
381
            gpx.lineTo(clickedPoint.getX(), clickedPoint.getY());
382 28070 vcaballero
383 37138 cordinyana
        }
384
        gpx.lineTo(x, y);
385
        org.gvsig.fmap.geom.Geometry geom;
386
        try {
387
            geom =
388
                GeometryLocator.getGeometryManager().createCurve(gpx,
389
                    SUBTYPES.GEOM2D);
390
            renderer.draw(geom, mapControlManager.getGeometrySelectionSymbol());
391
        } catch (LocatorException e) {
392
            e.printStackTrace();
393
        } catch (CreateGeometryException e) {
394
            e.printStackTrace();
395
        }
396
    }
397 28070 vcaballero
398 37138 cordinyana
    private void drawRectangleOfSplit(MapControlDrawer renderer)
399
        throws GeometryOperationNotSupportedException,
400 38378 jldominguez
        GeometryOperationException, DataException,
401
        CreateGeometryException {
402 37138 cordinyana
        VectorialLayerEdited vle = getVLE();
403
        FeatureStore store = vle.getFeatureStore();
404
        DisposableIterator selected = null;
405 28070 vcaballero
406 37138 cordinyana
        try {
407
            selected = store.getFeatureSelection().iterator();
408
            while (selected.hasNext()) {
409
                Feature feature = (Feature) selected.next();
410
                org.gvsig.fmap.geom.Geometry ig = feature.getDefaultGeometry();
411 37776 jpiera
                Geometry jtsG = (Geometry)ig.invokeOperation("toJTS", null);
412 37138 cordinyana
                if (jtsG != null && jtsG instanceof GeometryCollection
413
                    && jtsG.getNumGeometries() > 1) {
414 38378 jldominguez
415
                    /*
416 37138 cordinyana
                    org.gvsig.fmap.geom.Geometry r =
417
                        ig.getEnvelope().getGeometry();
418 38378 jldominguez
                        */
419
                    // get perimeter of envelope to prevent
420
                    // opaque rectangle
421
                    org.gvsig.fmap.geom.Geometry geom =
422
                        GeometryLocator.getGeometryManager().createCurve(
423
                            ig.getEnvelope().getGeometry().getGeneralPath(),
424
                            SUBTYPES.GEOM2D);
425
426 38539 jldominguez
                    renderer.draw(geom, getRectangleOfSplitSymbol());
427 37138 cordinyana
                }
428
            }
429
        } finally {
430
            DisposeUtils.dispose(selected);
431
        }
432
    }
433 28070 vcaballero
434 38539 jldominguez
    /**
435
     * @return
436
     */
437
    private ISymbol getRectangleOfSplitSymbol() {
438
439
        if (rectSymbol == null) {
440
            SymbologyManager sm = SymbologyLocator.getSymbologyManager();
441
            ISimpleFillSymbol resp = sm.createSimpleFillSymbol();
442
            resp.setColor(Color.RED);
443
            resp.setFillColor(new Color(0,0,0, 100));
444
            rectSymbol = resp;
445
        }
446
        return rectSymbol;
447
    }
448
449 37138 cordinyana
    public void drawOperation(MapControlDrawer renderer, double x, double y) {
450 38539 jldominguez
451
        // decide whether user line must be drawn
452
        boolean draw_user_poly_line = false;
453 29756 jpiera
        try {
454 38539 jldominguez
            State currentState = _fsm.getState();
455
            if (currentState != null) {
456
                String status = currentState.getName();
457
                if (status != null && status.equals("SplitGeometry.DigitizingLine")) {
458
                    draw_user_poly_line = true;
459
                }
460
            }
461
        } catch (StateUndefinedException sue) {
462
            // this happens when state is null
463
            // because the line has been finished and we must not draw it
464
            draw_user_poly_line = false;
465
        }
466
467
        // =======================================================
468
469
        try {
470 37138 cordinyana
            drawRectangleOfSplit(renderer);
471 38539 jldominguez
472
            // possibly draw splitting line
473
            if (draw_user_poly_line) {
474 37138 cordinyana
                drawPolyLine(renderer, x, y);
475
            }
476 28070 vcaballero
477 29756 jpiera
            // draw selection
478 37138 cordinyana
            Image imgSel = getVLE().getSelectionImage();
479
            renderer.drawImage(imgSel, 0, 0);
480 28070 vcaballero
        } catch (Exception e) {
481 38539 jldominguez
482
            logger.info("Error while drawing split tool.", e);
483
            ApplicationLocator.getManager().message(
484
                Messages.getText("_Drawing_error") + e.getMessage(),
485
                JOptionPane.ERROR_MESSAGE);
486 28070 vcaballero
        }
487 37138 cordinyana
    }
488 28070 vcaballero
489 37138 cordinyana
    public String getName() {
490
        return PluginServices.getText(this, "split_geometry_shell");
491
    }
492 28070 vcaballero
493 37138 cordinyana
    public void transition(double x, double y, InputEvent event) {
494
        try {
495
            _fsm.addPoint(x, y, event);
496
        } catch (Exception e) {
497
            init();
498
        }
499 28070 vcaballero
500 37138 cordinyana
    }
501 28070 vcaballero
502 37138 cordinyana
    public void transition(double d) {
503
        _fsm.addValue(d);
504
    }
505 28070 vcaballero
506 37138 cordinyana
    public void transition(String s) throws CommandException {
507
        if (!super.changeCommand(s)) {
508
            _fsm.addOption(s);
509
        }
510
    }
511 28070 vcaballero
512 37328 cordinyana
    @Override
513
    public boolean isApplicable(GeometryType geometryType) {
514
        return true;
515
    }
516
517
    @Override
518
    protected int[] getSupportedGeometryTypes() {
519
        return null;
520
    }
521 38539 jldominguez
522
    /**
523
     * This method decides if geometrya  is inside geometry b
524
     * by more than 50%. This is useful because it will be
525
     * used to assign each geometry to one of two possible containers
526
     *
527
     * @param a
528
     * @param b must be a multi(polygon)
529
     * @return
530
     */
531
    private static boolean isRatherInside(Geometry a, Geometry b) {
532
533
        if (a instanceof Polygon || a instanceof MultiPolygon) {
534
            return polygonIsRatherInside(a, b);
535
        } else {
536
            if (a instanceof LineString || a instanceof MultiLineString) {
537
                return lineIsRatherInside(a, b);
538
            } else {
539
                if (a instanceof MultiPoint) {
540
541
                    MultiPoint mp = (MultiPoint) a;
542
                    int n = mp.getNumPoints();
543
                    int inn = 0;
544
                    Geometry itemg = null;
545
                    for (int i=0; i<n; i++) {
546
                        itemg = mp.getGeometryN(i);
547
                        if (isRatherInside(itemg, b)) {
548
                            inn++;
549
                        }
550
                    }
551
                    return inn > (n/2);
552
                } else {
553
                    // last case: should be a point
554
                    return b.contains(a);
555
                }
556
            }
557
        }
558
559
    }
560
561
562
563
    /**
564
     * This method decides if a polygon is inside another
565
     * by more than 50%. This is useful because it will be
566
     * used to assign each polygon to one of two possible containers
567
     *
568
     * @param a
569
     * @param b
570
     * @return whether a is 'rather' contained by b
571
     */
572
    private static boolean polygonIsRatherInside(Geometry a, Geometry b) {
573
574
        if (a == null || b == null || a.isEmpty() || b.isEmpty()) {
575
            return false;
576
        }
577
578
        double area_a = a.getArea();
579
580
        if (area_a == 0) {
581
            return false;
582
        }
583
584
        Geometry a_inters_b = null;
585
586
        a_inters_b = a.intersection(b);
587
        if (a_inters_b == null || a_inters_b.isEmpty()) {
588
            return false;
589
        }
590
591
        double area_aib = a_inters_b.getArea();
592
593
        if (area_aib == 0) {
594
            return false;
595
        }
596
597
        return area_aib > (0.5d * area_a);
598
    }
599
600
    /**
601
     *
602
     * @param a assumed to be a (multi)linestring
603
     * @param b the (possibly) containing polygon
604
     * @return
605
     */
606
    private static boolean lineIsRatherInside(Geometry a, Geometry b) {
607
608
        if (a == null || b == null || a.isEmpty() || b.isEmpty()) {
609
            return false;
610
        }
611
612
        double len_a = a.getLength();
613
614
        if (len_a == 0) {
615
            return false;
616
        }
617
618
        Geometry a_inters_b = null;
619
620
        a_inters_b = a.intersection(b);
621
        if (a_inters_b == null || a_inters_b.isEmpty()) {
622
            return false;
623
        }
624
625
        double len_aib = a_inters_b.getLength();
626
627
        if (len_aib == 0) {
628
            return false;
629
        }
630
631
        return len_aib > (0.5d * len_a);
632
    }
633 28070 vcaballero
}