Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.split / src / main / java / org / gvsig / vectorediting / lib / prov / split / operation / LineSplitOperation.java @ 575

History | View | Annotate | Download (4.99 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.vectorediting.lib.prov.split.operation;
26

    
27
import org.gvsig.fmap.geom.Geometry;
28
import org.gvsig.fmap.geom.GeometryLocator;
29
import org.gvsig.fmap.geom.aggregate.MultiLine;
30
import org.gvsig.fmap.geom.aggregate.MultiPoint;
31
import org.gvsig.fmap.geom.exception.CreateGeometryException;
32
import org.gvsig.fmap.geom.operation.GeometryOperationException;
33
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
34
import org.gvsig.fmap.geom.primitive.Curve;
35
import org.gvsig.fmap.geom.primitive.Line;
36
import org.gvsig.fmap.geom.primitive.Point;
37

    
38
/**
39
 * @author llmarques
40
 *
41
 */
42
public class LineSplitOperation implements SplitOperation {
43

    
44
    /*
45
     * Strategy:
46
     *
47
     * 1. Get intersection points.
48
     * 2. Get difference between geometry and splitter. If splitter does not
49
     * touch geometry return original geometry.
50
     * 3. If any intersection points are not equal to first or last vertex of
51
     * original geometry, join last and first curve splitted. It's necessary do
52
     * it because the difference between geometry and splitter returns a
53
     * multicurve that its first curve starts at first vertex of ORGINAL and
54
     * ends at first intersection point and its last curve starts at
55
     * last intersection point and ends at last vertex of ORIGINAL geometry, so
56
     * we have to join them. If any intersection points are equal to first or
57
     * last vertex do nothing.
58
     */
59
    public Geometry split(Geometry geometryToBeSplitted, Geometry splitter)
60
        throws GeometryOperationNotSupportedException,
61
        GeometryOperationException, CreateGeometryException {
62

    
63
        Line lineToBeSplitted = (Line) geometryToBeSplitted;
64

    
65
        Geometry intersection = geometryToBeSplitted.intersection(splitter);
66
        MultiLine multilineSplitted = null;
67

    
68
        if (intersection instanceof MultiPoint) {
69
            MultiPoint intersectionMultiPoint = (MultiPoint) intersection;
70
            Point firstVertex = intersectionMultiPoint.getPointAt(0);
71
            Point lastVertex =
72
                intersectionMultiPoint.getPointAt(intersectionMultiPoint
73
                    .getPrimitivesNumber() - 1);
74

    
75
            MultiLine difference =
76
                (MultiLine) geometryToBeSplitted.difference(splitter);
77

    
78
            if (difference == null) {
79
                return geometryToBeSplitted;
80
            }
81

    
82
            if ((!firstVertex.equals(lineToBeSplitted.getVertex(0)) && !lastVertex
83
                .equals(lineToBeSplitted.getVertex(0)))
84
                && isClosed(lineToBeSplitted)) {
85

    
86
                Line firstLine = (Line) difference.getPrimitiveAt(0);
87
                Line lastLine =
88
                    (Line) difference.getPrimitiveAt(difference.getPrimitivesNumber() - 1);
89

    
90
                Curve union =
91
                    GeometryLocator.getGeometryManager().createLine(
92
                        geometryToBeSplitted.getGeometryType().getSubType());
93
                for (int i = 0; i < lastLine.getNumVertices(); i++) {
94
                    union.addVertex(lastLine.getVertex(i));
95
                }
96

    
97
                for (int i = 0; i < firstLine.getNumVertices(); i++) {
98
                    union.addVertex(firstLine.getVertex(i));
99
                }
100

    
101
                multilineSplitted =
102
                    GeometryLocator.getGeometryManager().createMultiLine(
103
                        geometryToBeSplitted.getGeometryType().getSubType());
104

    
105
                multilineSplitted.addPrimitive(union);
106
                for (int i = 1; i < difference.getPrimitivesNumber() - 1; i++) {
107
                    multilineSplitted.addPrimitive(difference.getPrimitiveAt(i));
108
                }
109
            }
110
        }
111

    
112
        if(multilineSplitted == null){
113
            return geometryToBeSplitted.difference(splitter);
114
        }
115

    
116
        return multilineSplitted;
117
    }
118

    
119
    private boolean isClosed(Line lineToBeSplitted) {
120

    
121
        Point firstPoint = lineToBeSplitted.getVertex(0);
122
        Point lastPoint =
123
            lineToBeSplitted.getVertex(lineToBeSplitted.getNumVertices()-1);
124

    
125
        if (firstPoint.equals(lastPoint)) {
126
            return true;
127
        }
128
        return false;
129
    }
130
}