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.trimline / src / main / java / org / gvsig / vectorediting / lib / prov / trimline / operation / ArcTrimLineOperation.java @ 346

History | View | Annotate | Download (6.13 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 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.trimline.operation;
26

    
27
import org.gvsig.fmap.dal.exception.DataException;
28
import org.gvsig.fmap.dal.feature.Feature;
29
import org.gvsig.fmap.dal.feature.FeatureSelection;
30
import org.gvsig.fmap.geom.Geometry;
31
import org.gvsig.fmap.geom.GeometryLocator;
32
import org.gvsig.fmap.geom.GeometryManager;
33
import org.gvsig.fmap.geom.aggregate.MultiCurve;
34
import org.gvsig.fmap.geom.exception.CreateGeometryException;
35
import org.gvsig.fmap.geom.operation.GeometryOperationException;
36
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
37
import org.gvsig.fmap.geom.primitive.Arc;
38
import org.gvsig.fmap.geom.primitive.Curve;
39
import org.gvsig.fmap.geom.primitive.Point;
40
import org.gvsig.tools.dispose.DisposableIterator;
41
import org.gvsig.tools.locator.LocatorException;
42

    
43
/**
44
 * Operation to trim arcs.
45
 * 
46
 * @author llmarques
47
 *
48
 */
49
public class ArcTrimLineOperation implements TrimLineOperation {
50

    
51
    /*
52
     * Strategy:
53
     * 
54
     * 1. Get arc segments between arc and boundary objects.
55
     * 2. Determinate what segment of arc must be deleted
56
     * 3. Rebuild arc taking into account the segment that must be deleted
57
     */
58
    public MultiCurve trimLine(Curve curveToTrim, Point insertedPoint,
59
        FeatureSelection boundaryObjects)
60
        throws GeometryOperationNotSupportedException,
61
        GeometryOperationException, DataException, CreateGeometryException,
62
        LocatorException {
63

    
64
        final Arc arcToTrim = (Arc) curveToTrim;
65

    
66
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
67
        int subtype = arcToTrim.getGeometryType().getSubType();
68

    
69
        MultiCurve segmentedArc = geoManager.createMultiCurve(subtype);
70
        segmentedArc.addCurve(curveToTrim);
71

    
72
        DisposableIterator it = boundaryObjects.fastIterator();
73

    
74
        while (it.hasNext()) {
75
            Feature feature = (Feature) it.next();
76
            Geometry geometry = feature.getDefaultGeometry();
77

    
78
            Geometry tmpDifference = segmentedArc.difference(geometry);
79
            if (tmpDifference instanceof MultiCurve) {
80
                segmentedArc = (MultiCurve) tmpDifference;
81
            }
82
        }
83

    
84
        int index = 0;
85
        Curve arc;
86
        double minDistance = Double.POSITIVE_INFINITY;
87
        for (int i = 0; i < segmentedArc.getPrimitivesNumber(); i++) {
88
            arc = segmentedArc.getCurveAt(i);
89
            double distance = arc.distance(insertedPoint);
90
            if (distance < minDistance) {
91
                index = i;
92
                minDistance = distance;
93
            }
94
        }
95

    
96
        MultiCurve trimmedArc = geoManager.createMultiCurve(subtype);
97
        Point center = arcToTrim.getCenterPoint();
98

    
99
        // If Arc#getCenter() return null, we will have to use this "trick" to
100
        // get arc center.
101
        if (center == null) {
102
            center =
103
                geoManager.createPoint(arcToTrim.getEnvelope().getCenter(0),
104
                    arcToTrim.getEnvelope().getCenter(1), subtype);
105
        }
106

    
107
        double radius = center.distance(arcToTrim.getInitPoint());
108

    
109
        Curve tmpCurve = null;
110
        for (int i = 0; i < segmentedArc.getPrimitivesNumber(); i++) {
111

    
112
            if (i == index) {
113
                if (tmpCurve != null) {
114
                    trimmedArc.addCurve(tmpCurve);
115
                    tmpCurve = null;
116
                }
117
                continue;
118
            }
119

    
120
            if (tmpCurve != null) {
121
                tmpCurve =
122
                    union(center, radius, tmpCurve, segmentedArc.getCurveAt(i));
123
            } else {
124
                tmpCurve = segmentedArc.getCurveAt(i);
125
            }
126
        }
127
        if (tmpCurve != null) {
128
            trimmedArc.addCurve(tmpCurve);
129
        }
130

    
131
        return trimmedArc;
132
    }
133

    
134
    private Arc union(Point center, double radius, Curve curveA, Curve curveB)
135
        throws GeometryOperationNotSupportedException,
136
        GeometryOperationException, CreateGeometryException, LocatorException {
137

    
138
        int subtype1 = curveA.getGeometryType().getSubType();
139
        int subtype2 = curveB.getGeometryType().getSubType();
140

    
141
        Arc arc1 =
142
            TrimLineOperationUtils.createArc(center, radius,
143
                curveA.getVertex(0),
144
                curveA.getVertex(curveA.getNumVertices() - 1), subtype1);
145
        Arc arc2 =
146
            TrimLineOperationUtils.createArc(center, radius,
147
                curveB.getVertex(0),
148
                curveB.getVertex(curveB.getNumVertices() - 1), subtype1);
149

    
150
        if (subtype1 == subtype2) {
151

    
152
            double Xcenter1 = arc1.getCenterPoint().getX();
153
            double Ycenter1 = arc1.getCenterPoint().getY();
154
            double Xcenter2 = arc2.getCenterPoint().getX();
155
            double Ycenter2 = arc2.getCenterPoint().getY();
156

    
157
            double differenceX = Xcenter1 - Xcenter2;
158
            double differenceY = Ycenter1 - Ycenter2;
159

    
160
            if (Math.abs(differenceX) <= 0.001
161
                && Math.abs(differenceY) <= 0.001) {
162

    
163
                Point tmpCenter = arc1.getCenterPoint();
164
                double tmpRadius = center.distance(arc1.getInitPoint());
165
                return TrimLineOperationUtils.createArc(tmpCenter, tmpRadius,
166
                    arc1.getInitPoint(), arc2.getEndPoint(), subtype1);
167
            }
168
        }
169
        return null;
170
    }
171
}