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 / CurveSplitOperation.java @ 496

History | View | Annotate | Download (4.98 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.MultiCurve;
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.Point;
36

    
37
/**
38
 * @author llmarques
39
 *
40
 */
41
public class CurveSplitOperation implements SplitOperation {
42

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

    
62
        Curve curveToBeSplitted = (Curve) geometryToBeSplitted;
63

    
64
        Geometry intersection = geometryToBeSplitted.intersection(splitter);
65
        MultiCurve multicurveSplitted = null;
66

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

    
74
            MultiCurve difference =
75
                (MultiCurve) geometryToBeSplitted.difference(splitter);
76

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

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

    
85
                Curve firstCurve = difference.getCurveAt(0);
86
                Curve lastCurve =
87
                    difference.getCurveAt(difference.getPrimitivesNumber() - 1);
88

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

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

    
100
                multicurveSplitted =
101
                    GeometryLocator.getGeometryManager().createMultiCurve(
102
                        geometryToBeSplitted.getGeometryType().getSubType());
103

    
104
                multicurveSplitted.addCurve(union);
105
                for (int i = 1; i < difference.getPrimitivesNumber() - 1; i++) {
106
                    multicurveSplitted.addCurve(difference.getCurveAt(i));
107
                }
108
            }
109
        }
110
        
111
        if(multicurveSplitted == null){
112
            return geometryToBeSplitted.difference(splitter);
113
        }
114
        
115
        return multicurveSplitted;
116
    }
117

    
118
    private boolean isClosed(Curve curveToBeSplitted) {
119
        
120
        Point firstPoint = curveToBeSplitted.getVertex(0);
121
        Point lastPoint =
122
            curveToBeSplitted.getVertex(curveToBeSplitted.getNumVertices()-1);
123
        
124
        if (firstPoint.equals(lastPoint)) {
125
            return true;
126
        }
127
        return false;
128
    }
129
}