Revision 2228
org.gvsig.vectorediting/trunk/org.gvsig.vectorediting/org.gvsig.vectorediting.app/org.gvsig.vectorediting.app.mainplugin/src/main/resources-plugin/i18n/text.properties | ||
---|---|---|
159 | 159 |
sweep_angle = \u00c1ngulo de barrido |
160 | 160 |
center_point = Centro |
161 | 161 |
_graphic_distance = Distancia gr\u00e1fica |
162 |
geometry_to_extend_to=Geometr\u00eda hasta la que extender |
|
162 |
geometry_to_extend_to=Geometr\u00eda hasta la que extender |
|
163 |
geometry_to_trim_with=Geometr\u00eda con la que recortar |
|
164 |
shearing_point=Punto de recorte |
org.gvsig.vectorediting/trunk/org.gvsig.vectorediting/org.gvsig.vectorediting.app/org.gvsig.vectorediting.app.mainplugin/src/main/resources-plugin/i18n/text_en.properties | ||
---|---|---|
157 | 157 |
sweep_angle = Sweep angle |
158 | 158 |
center_point = Center point |
159 | 159 |
_graphic_distance = Graphic distance |
160 |
geometry_to_extend_to= Geometry to extend to |
|
160 |
geometry_to_extend_to= Geometry to extend to |
|
161 |
geometry_to_trim_with=Geometry to trim with |
|
162 |
shearing_point=Shearing point |
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/TrimLineOperation.java | ||
---|---|---|
26 | 26 |
|
27 | 27 |
import org.gvsig.fmap.dal.exception.DataException; |
28 | 28 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
29 |
import org.gvsig.fmap.geom.Geometry; |
|
29 | 30 |
import org.gvsig.fmap.geom.aggregate.MultiCurve; |
30 | 31 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
31 | 32 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
... | ... | |
43 | 44 |
public interface TrimLineOperation { |
44 | 45 |
|
45 | 46 |
/** |
47 |
* Trim line, taking as cutting edges the shears received as |
|
48 |
* parameters.Inserted point is the point inserted by user.It is used to determinate |
|
49 |
what segment of curve it must trimmed.If curveToBeExtended does not intersect with any geometry, the geometry |
|
50 |
will not be modified. |
|
51 |
* |
|
52 |
* |
|
53 |
* @param curveToTrim |
|
54 |
* Curve to trim |
|
55 |
* @param shearingPoint |
|
56 |
* Point inserted by user to determinate what side of curve must |
|
57 |
* be extended. |
|
58 |
* @param shears |
|
59 |
* If curveToBeExtended intersects with some shears, it will |
|
60 |
* be cutted to it. If there are several shears that |
|
61 |
* intersects with curveToTrim, it will be cutted to |
|
62 |
* nearest point. |
|
63 |
* @return Trimmed line |
|
64 |
* @throws org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException |
|
65 |
* @throws org.gvsig.fmap.geom.operation.GeometryOperationException |
|
66 |
* @throws org.gvsig.fmap.dal.exception.DataException |
|
67 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException |
|
68 |
*/ |
|
69 |
public MultiCurve trimLine(Curve curveToTrim, Point shearingPoint, |
|
70 |
FeatureSelection shears) |
|
71 |
throws GeometryOperationNotSupportedException, |
|
72 |
GeometryOperationException, DataException, CreateGeometryException, |
|
73 |
LocatorException; |
|
74 |
|
|
75 |
|
|
76 |
/** |
|
46 | 77 |
* Trim line, taking as cutting edges the boundary objects received as |
47 |
* parameters. |
|
78 |
* parameters.Inserted point is the point inserted by user.It is used to determinate |
|
79 |
what segment of curve it must trimmed.If curveToBeExtended does not intersect with any geometry, the geometry |
|
80 |
will not be modified. |
|
48 | 81 |
* |
49 |
* Inserted point is the point inserted by user. It is used to determinate |
|
50 |
* what segment of curve it must trimmed. |
|
51 | 82 |
* |
52 |
* If curveToBeExtended does not intersect with any geometry, the geometry |
|
53 |
* will not be modified. |
|
54 |
* |
|
55 | 83 |
* @param curveToTrim |
56 | 84 |
* Curve to trim |
57 |
* @param insertedPoint
|
|
85 |
* @param shearingPoint
|
|
58 | 86 |
* Point inserted by user to determinate what side of curve must |
59 | 87 |
* be extended. |
60 |
* @param boundaryObjects
|
|
88 |
* @param shears
|
|
61 | 89 |
* If curveToBeExtended intersects with some boundary object, it |
62 | 90 |
* will |
63 | 91 |
* be extend to it. If there are several boundary objects that |
... | ... | |
65 | 93 |
* nearest |
66 | 94 |
* point. |
67 | 95 |
* @return Trimmed line |
96 |
* @throws org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException |
|
97 |
* @throws org.gvsig.fmap.geom.operation.GeometryOperationException |
|
98 |
* @throws org.gvsig.fmap.dal.exception.DataException |
|
99 |
* @throws org.gvsig.fmap.geom.exception.CreateGeometryException |
|
68 | 100 |
*/ |
69 |
public MultiCurve trimLine(Curve curveToTrim, Point insertedPoint,
|
|
70 |
FeatureSelection boundaryObjects)
|
|
101 |
public MultiCurve trimLine(Curve curveToTrim, Point shearingPoint,
|
|
102 |
Geometry shears)
|
|
71 | 103 |
throws GeometryOperationNotSupportedException, |
72 | 104 |
GeometryOperationException, DataException, CreateGeometryException, |
73 | 105 |
LocatorException; |
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/TrimLineOperationUtils.java | ||
---|---|---|
26 | 26 |
|
27 | 27 |
import java.util.HashMap; |
28 | 28 |
import java.util.Map; |
29 |
|
|
29 |
import org.gvsig.fmap.geom.Geometry; |
|
30 | 30 |
import org.gvsig.fmap.geom.Geometry.TYPES; |
31 | 31 |
import org.gvsig.fmap.geom.GeometryLocator; |
32 |
import org.gvsig.fmap.geom.GeometryManager; |
|
33 |
import org.gvsig.fmap.geom.GeometryUtils; |
|
34 |
import org.gvsig.fmap.geom.aggregate.MultiLine; |
|
32 | 35 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
33 | 36 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
34 | 37 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
35 | 38 |
import org.gvsig.fmap.geom.primitive.Arc; |
36 | 39 |
import org.gvsig.fmap.geom.primitive.Curve; |
40 |
import org.gvsig.fmap.geom.primitive.Line; |
|
37 | 41 |
import org.gvsig.fmap.geom.primitive.Point; |
38 | 42 |
import org.gvsig.fmap.geom.primitive.Primitive; |
39 | 43 |
import org.gvsig.tools.locator.LocatorException; |
... | ... | |
56 | 60 |
|
57 | 61 |
private static Map<Integer, TrimLineOperation> operations = |
58 | 62 |
new HashMap<Integer, TrimLineOperation>(); |
63 |
|
|
64 |
public static final double SNAP_TOLERANCE = 0.1; |
|
59 | 65 |
|
66 |
|
|
60 | 67 |
public TrimLineOperationUtils() { |
61 | 68 |
} |
62 | 69 |
|
... | ... | |
72 | 79 |
return operation; |
73 | 80 |
} |
74 | 81 |
|
75 |
// FIXME: remove this method when geometry library has this utility method |
|
76 |
public static double getAngle(Point start, Point end) |
|
77 |
throws GeometryOperationNotSupportedException, |
|
78 |
GeometryOperationException { |
|
79 |
double angle = Math.acos((end.getX() - start.getX()) / start.distance(end)); |
|
80 |
|
|
81 |
if (start.getY() > end.getY()) { |
|
82 |
angle = -angle; |
|
83 |
} |
|
84 |
|
|
85 |
if (angle < 0) { |
|
86 |
angle += (2 * Math.PI); |
|
87 |
} |
|
88 |
|
|
89 |
return angle; |
|
90 |
} |
|
91 |
|
|
92 | 82 |
public static Arc createArc(Point center, double radius, Point initPoint, |
93 | 83 |
Point endPoint, int subtype) throws CreateGeometryException, |
94 | 84 |
LocatorException, GeometryOperationNotSupportedException, |
... | ... | |
98 | 88 |
(Arc) GeometryLocator.getGeometryManager().create(TYPES.ARC, |
99 | 89 |
subtype); |
100 | 90 |
|
101 |
double startAngle = TrimLineOperationUtils.getAngle(center, initPoint);
|
|
102 |
double endAngle = TrimLineOperationUtils.getAngle(center, endPoint);
|
|
91 |
double startAngle = GeometryUtils.calculateAngle(center, initPoint);
|
|
92 |
double endAngle = GeometryUtils.calculateAngle(center, endPoint);
|
|
103 | 93 |
|
104 | 94 |
arc.setPointsStartEnd(center, radius, startAngle, endAngle); |
105 | 95 |
return arc; |
... | ... | |
113 | 103 |
|
114 | 104 |
return curve.buffer(tolerance).intersects(projectedPoint); |
115 | 105 |
} |
106 |
|
|
107 |
|
|
108 |
public static Double getSide(Geometry geometry, Point point) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException{ |
|
109 |
GeometryManager geomManager= GeometryLocator.getGeometryManager(); |
|
110 |
int subtype = geometry.getGeometryType().getSubType(); |
|
111 |
Geometry[] closestPoints = geometry.closestPoints(point); |
|
112 |
if(geometry instanceof Line) { |
|
113 |
Line line = (Line)geometry; |
|
114 |
int index = 0; |
|
115 |
Point previousVertex = null; |
|
116 |
for (Point vertex : line) { |
|
117 |
if(index < line.getNumVertices()-1){ |
|
118 |
Point nextVertex = line.getVertex(index+1); |
|
119 |
Line segment = geomManager.createLine(subtype); |
|
120 |
segment.addVertex(vertex); |
|
121 |
segment.addVertex(nextVertex); |
|
122 |
Geometry p = closestPoints[0]; |
|
123 |
double coef = TrimLineOperationUtils.getSide(vertex, nextVertex, point); |
|
124 |
if(segment.isWithinDistance(p, SNAP_TOLERANCE)) { |
|
125 |
if(vertex.isWithinDistance(p, SNAP_TOLERANCE) && previousVertex != null){ |
|
126 |
double previousCoef = TrimLineOperationUtils.getSide(previousVertex, vertex, point); |
|
127 |
if(previousCoef == coef){ |
|
128 |
return coef; |
|
129 |
} else { |
|
130 |
return Double.NaN; |
|
131 |
} |
|
132 |
} else if(nextVertex.isWithinDistance(p, SNAP_TOLERANCE) && index < line.getNumVertices()-2){ |
|
133 |
Point nextNextVertex = line.getVertex(index+2); |
|
134 |
double nextCoef = TrimLineOperationUtils.getSide(nextVertex, nextNextVertex, point); |
|
135 |
if(nextCoef == coef){ |
|
136 |
return coef; |
|
137 |
} else { |
|
138 |
return Double.NaN; |
|
139 |
} |
|
140 |
} |
|
141 |
return coef; |
|
142 |
} |
|
143 |
previousVertex = vertex; |
|
144 |
} |
|
145 |
index++; |
|
146 |
} |
|
147 |
} else if (geometry instanceof MultiLine) { |
|
148 |
double minDistance = Double.POSITIVE_INFINITY; |
|
149 |
MultiLine multiline = (MultiLine)geometry; |
|
150 |
Geometry nearestComponent = null; |
|
151 |
for (Geometry component : multiline) { |
|
152 |
double distance = component.distance(point); |
|
153 |
if(distance < minDistance){ |
|
154 |
nearestComponent = component; |
|
155 |
minDistance = distance; |
|
156 |
} |
|
157 |
} |
|
158 |
if(nearestComponent != null) { |
|
159 |
return TrimLineOperationUtils.getSide(nearestComponent, point); |
|
160 |
} |
|
161 |
} |
|
162 |
return Double.NaN; |
|
163 |
} |
|
164 |
|
|
165 |
public static double getSide(Point a, Point b, Point c) { |
|
166 |
if (a == null || b == null || c == null || a.equals(b) || a.equals(c) || b.equals(c)) { |
|
167 |
throw new IllegalArgumentException("Points must be different and not null."); |
|
168 |
} |
|
169 |
return Math.signum((b.getX() - a.getX()) * (c.getY() - a.getY()) - (b.getY() - a.getY()) * (c.getX() - a.getX())); |
|
170 |
} |
|
171 |
|
|
172 |
public static Double getSide(Geometry geometry, Curve curve) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException { |
|
173 |
GeometryManager geomManager= GeometryLocator.getGeometryManager(); |
|
174 |
Double segmentSide = Double.NaN; |
|
175 |
if (curve.getNumVertices() == 1) { |
|
176 |
// |
|
177 |
segmentSide = TrimLineOperationUtils.getSide(geometry, curve.getVertex(0)); |
|
178 |
} if (curve.getNumVertices() == 2) { |
|
179 |
int steps = 100; |
|
180 |
//We skip the first and last points because |
|
181 |
//they can coincide with the geometry and give wrong results |
|
182 |
for(int t=1; t<steps; t++){ |
|
183 |
double xLen = curve.getVertex(1).getX() - curve.getVertex(0).getX(); |
|
184 |
double yLen = curve.getVertex(1).getY() - curve.getVertex(0).getY(); |
|
185 |
double diffX = xLen/steps; |
|
186 |
double diffY = yLen/steps; |
|
187 |
|
|
188 |
Point anyPoint = geomManager.createPoint( |
|
189 |
curve.getVertex(0).getX() + t*diffX, |
|
190 |
curve.getVertex(0).getY() + t*diffY, |
|
191 |
geometry.getGeometryType().getSubType()); |
|
192 |
segmentSide = TrimLineOperationUtils.getSide(geometry, anyPoint); |
|
193 |
if (!segmentSide.isNaN()) { |
|
194 |
break; |
|
195 |
} |
|
196 |
} |
|
197 |
|
|
198 |
} else { |
|
199 |
//We skip the first and last points because |
|
200 |
//they can coincide with the geometry and give wrong results |
|
201 |
for (int j = 1; j < curve.getNumVertices()-1; j++) { |
|
202 |
Point anyPoint = curve.getVertex(j); |
|
203 |
segmentSide = TrimLineOperationUtils.getSide(geometry, anyPoint); |
|
204 |
if (!segmentSide.isNaN()) { |
|
205 |
break; |
|
206 |
} |
|
207 |
} |
|
208 |
} |
|
209 |
return segmentSide; |
|
210 |
} |
|
211 |
|
|
116 | 212 |
} |
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/CurveTrimLineOperation.java | ||
---|---|---|
39 | 39 |
import org.gvsig.fmap.geom.primitive.Point; |
40 | 40 |
import org.gvsig.tools.dispose.DisposableIterator; |
41 | 41 |
import org.gvsig.tools.locator.LocatorException; |
42 |
import org.slf4j.Logger; |
|
43 |
import org.slf4j.LoggerFactory; |
|
42 | 44 |
|
43 | 45 |
/** |
44 | 46 |
* Operation to trim curves. |
... | ... | |
47 | 49 |
*/ |
48 | 50 |
public class CurveTrimLineOperation implements TrimLineOperation { |
49 | 51 |
|
52 |
private static final Logger LOGGER = LoggerFactory |
|
53 |
.getLogger(CurveTrimLineOperation.class); |
|
54 |
|
|
50 | 55 |
/* |
51 | 56 |
* Strategy: |
52 | 57 |
* |
53 |
* 1. Get arc segments between curve and boundary objects.
|
|
58 |
* 1. Get arc segments between curve and shears.
|
|
54 | 59 |
* 2. Determinate what segment of curve must be deleted |
55 | 60 |
* 3. Rebuild curve taking into account the segment that must be deleted |
56 | 61 |
*/ |
57 |
public MultiCurve trimLine(Curve curveToTrim, Point insertedPoint,
|
|
58 |
FeatureSelection boundaryObjects)
|
|
62 |
public MultiCurve trimLine(Curve curveToTrim, Point shearingPoint,
|
|
63 |
FeatureSelection shears)
|
|
59 | 64 |
throws GeometryOperationNotSupportedException, |
60 | 65 |
GeometryOperationException, DataException, CreateGeometryException, |
61 | 66 |
LocatorException { |
... | ... | |
63 | 68 |
GeometryManager geometryManager = GeometryLocator.getGeometryManager(); |
64 | 69 |
int subType = curveToTrim.getGeometryType().getSubType(); |
65 | 70 |
|
66 |
DisposableIterator it = boundaryObjects.fastIterator();
|
|
71 |
DisposableIterator it = shears.fastIterator();
|
|
67 | 72 |
MultiCurve segmentedLine = geometryManager.createMultiCurve(subType); |
68 | 73 |
segmentedLine.addCurve(curveToTrim); |
69 | 74 |
|
... | ... | |
98 | 103 |
double minDistance = Double.POSITIVE_INFINITY; |
99 | 104 |
for (int i = 0; i < segmentedLine.getPrimitivesNumber(); i++) { |
100 | 105 |
curve = segmentedLine.getCurveAt(i); |
101 |
double distance = curve.distance(insertedPoint);
|
|
106 |
double distance = curve.distance(shearingPoint);
|
|
102 | 107 |
if (distance < minDistance) { |
103 | 108 |
index = i; |
104 | 109 |
minDistance = distance; |
... | ... | |
171 | 176 |
private Geometry enhancedDifference(Geometry splitter, Curve curve) |
172 | 177 |
throws GeometryOperationNotSupportedException, |
173 | 178 |
GeometryOperationException { |
174 |
Geometry snapTo = curve.snapTo(splitter, 0.1);
|
|
179 |
Geometry snapTo = curve.snapTo(splitter, TrimLineOperationUtils.SNAP_TOLERANCE);
|
|
175 | 180 |
return snapTo.difference(splitter); |
176 | 181 |
} |
182 |
|
|
183 |
|
|
184 |
/* |
|
185 |
* Strategy: |
|
186 |
* |
|
187 |
* 1. Get line segments between curve and shears |
|
188 |
* 2. Determinate what segment of curve must be deleted |
|
189 |
* 3. Rebuild curve taking into account the segment that must be deleted |
|
190 |
*/ |
|
191 |
@Override |
|
192 |
public MultiCurve trimLine(Curve curveToTrim, Point shearingPoint, |
|
193 |
Geometry shears) |
|
194 |
throws GeometryOperationNotSupportedException, |
|
195 |
GeometryOperationException, DataException, CreateGeometryException, |
|
196 |
LocatorException { |
|
197 |
|
|
198 |
GeometryManager geometryManager = GeometryLocator.getGeometryManager(); |
|
199 |
int subType = curveToTrim.getGeometryType().getSubType(); |
|
200 |
|
|
201 |
MultiCurve segmentedLine = geometryManager.createMultiCurve(subType); |
|
202 |
segmentedLine.addCurve(curveToTrim); |
|
203 |
|
|
204 |
Geometry tmpDifference = segmentedLine.difference(shears); |
|
205 |
if (tmpDifference instanceof MultiCurve) { |
|
206 |
segmentedLine = (MultiCurve) tmpDifference; |
|
207 |
} else if(tmpDifference instanceof Curve) { |
|
208 |
// Sometimes line to split and splitter are so close ( distance |
|
209 |
// between geometries < 0.00000000001 ). In this cases, we try |
|
210 |
// to do an enhance difference. |
|
211 |
// If the result is instance of Curve, it is considered that |
|
212 |
// lines don't intersect. |
|
213 |
// If the result is instance of Multicurve, lines are so close |
|
214 |
// and it is considered that lines intersect. |
|
215 |
Geometry enchancedGeometry = enhancedDifference(shears, (Curve) tmpDifference); |
|
216 |
if(enchancedGeometry instanceof MultiCurve){ |
|
217 |
segmentedLine = (MultiCurve) enchancedGeometry; |
|
218 |
} |
|
219 |
} |
|
220 |
|
|
221 |
if (segmentedLine.getPrimitivesNumber() == 1) { |
|
222 |
return segmentedLine; |
|
223 |
} |
|
224 |
|
|
225 |
double side = TrimLineOperationUtils.getSide(shears, shearingPoint); |
|
226 |
|
|
227 |
int index = -1; |
|
228 |
if(!Double.isNaN(side)){ |
|
229 |
Curve curve; |
|
230 |
double minDistance = Double.POSITIVE_INFINITY; |
|
231 |
for (int i = 0; i < segmentedLine.getPrimitivesNumber(); i++) { |
|
232 |
curve = segmentedLine.getCurveAt(i); |
|
233 |
double distance = curve.distance(shearingPoint); |
|
234 |
if (distance < minDistance) { |
|
235 |
Double segmentSide = TrimLineOperationUtils.getSide(shears, curve); |
|
236 |
if(segmentSide == side){ |
|
237 |
index = i; |
|
238 |
minDistance = distance; |
|
239 |
} |
|
240 |
} |
|
241 |
} |
|
242 |
} |
|
243 |
|
|
244 |
MultiCurve trimmedCurve = geometryManager.createMultiCurve(subType); |
|
245 |
|
|
246 |
Curve tmpCurve = null; |
|
247 |
for (int i = 0; i < segmentedLine.getPrimitivesNumber(); i++) { |
|
248 |
|
|
249 |
if (i == index) { |
|
250 |
if (tmpCurve != null) { |
|
251 |
trimmedCurve.addCurve(tmpCurve); |
|
252 |
tmpCurve = null; |
|
253 |
} |
|
254 |
continue; |
|
255 |
} |
|
256 |
|
|
257 |
if (tmpCurve != null) { |
|
258 |
tmpCurve = union(tmpCurve, segmentedLine.getCurveAt(i)); |
|
259 |
} else { |
|
260 |
tmpCurve = segmentedLine.getCurveAt(i); |
|
261 |
} |
|
262 |
} |
|
263 |
if (tmpCurve != null) { |
|
264 |
trimmedCurve.addCurve(tmpCurve); |
|
265 |
} |
|
266 |
|
|
267 |
return trimmedCurve; |
|
268 |
} |
|
269 |
|
|
270 |
|
|
271 |
|
|
177 | 272 |
} |
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 | ||
---|---|---|
55 | 55 |
* 2. Determinate what segment of arc must be deleted |
56 | 56 |
* 3. Rebuild arc taking into account the segment that must be deleted |
57 | 57 |
*/ |
58 |
public MultiCurve trimLine(Curve curveToTrim, Point insertedPoint,
|
|
59 |
FeatureSelection boundaryObjects)
|
|
58 |
public MultiCurve trimLine(Curve curveToTrim, Point shearsPoint,
|
|
59 |
FeatureSelection shearingObjects)
|
|
60 | 60 |
throws GeometryOperationNotSupportedException, |
61 | 61 |
GeometryOperationException, DataException, CreateGeometryException, |
62 | 62 |
LocatorException { |
... | ... | |
69 | 69 |
MultiCurve segmentedArc = geoManager.createMultiCurve(subtype); |
70 | 70 |
segmentedArc.addCurve(curveToTrim); |
71 | 71 |
|
72 |
DisposableIterator it = boundaryObjects.fastIterator();
|
|
72 |
DisposableIterator it = shearingObjects.fastIterator();
|
|
73 | 73 |
|
74 | 74 |
while (it.hasNext()) { |
75 | 75 |
Feature feature = (Feature) it.next(); |
... | ... | |
86 | 86 |
double minDistance = Double.POSITIVE_INFINITY; |
87 | 87 |
for (int i = 0; i < segmentedArc.getPrimitivesNumber(); i++) { |
88 | 88 |
arc = segmentedArc.getCurveAt(i); |
89 |
double distance = arc.distance(insertedPoint);
|
|
89 |
double distance = arc.distance(shearsPoint);
|
|
90 | 90 |
if (distance < minDistance) { |
91 | 91 |
index = i; |
92 | 92 |
minDistance = distance; |
... | ... | |
138 | 138 |
int subtype1 = curveA.getGeometryType().getSubType(); |
139 | 139 |
int subtype2 = curveB.getGeometryType().getSubType(); |
140 | 140 |
|
141 |
Arc arc1 = |
|
141 |
Arc arc1 = null; |
|
142 |
if(curveA instanceof Arc){ |
|
143 |
arc1 = (Arc)curveA; |
|
144 |
} else { |
|
145 |
arc1 = |
|
142 | 146 |
TrimLineOperationUtils.createArc(center, radius, |
143 | 147 |
curveA.getVertex(0), |
144 | 148 |
curveA.getVertex(curveA.getNumVertices() - 1), subtype1); |
145 |
Arc arc2 = |
|
146 |
TrimLineOperationUtils.createArc(center, radius, |
|
149 |
} |
|
150 |
Arc arc2 = null; |
|
151 |
if(curveB instanceof Arc){ |
|
152 |
arc2 = (Arc)curveB; |
|
153 |
} else { |
|
154 |
arc2 = TrimLineOperationUtils.createArc(center, radius, |
|
147 | 155 |
curveB.getVertex(0), |
148 | 156 |
curveB.getVertex(curveB.getNumVertices() - 1), subtype1); |
157 |
} |
|
149 | 158 |
|
150 | 159 |
if (subtype1 == subtype2) { |
151 | 160 |
|
... | ... | |
168 | 177 |
} |
169 | 178 |
return null; |
170 | 179 |
} |
180 |
|
|
181 |
|
|
182 |
/* |
|
183 |
* Strategy: |
|
184 |
* |
|
185 |
* 1. Get arc segments between arc and boundary objects. |
|
186 |
* 2. Determinate what segment of arc must be deleted |
|
187 |
* 3. Rebuild arc taking into account the segment that must be deleted |
|
188 |
*/ |
|
189 |
@Override |
|
190 |
public MultiCurve trimLine(Curve curveToTrim, Point shearingPoint, |
|
191 |
Geometry boundaryObject) |
|
192 |
throws GeometryOperationNotSupportedException, |
|
193 |
GeometryOperationException, DataException, CreateGeometryException, |
|
194 |
LocatorException { |
|
195 |
|
|
196 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
197 |
Arc arcToTrim = (Arc) curveToTrim; |
|
198 |
if(!arcToTrim.isCCW()) { |
|
199 |
Arc tmpArcToTrim = (Arc)geomManager.create(arcToTrim.getGeometryType()); |
|
200 |
tmpArcToTrim.setPoints(arcToTrim.getEndPoint(), arcToTrim.getMiddlePoint(), arcToTrim.getInitPoint()); |
|
201 |
arcToTrim = tmpArcToTrim; |
|
202 |
} |
|
203 |
|
|
204 |
GeometryManager geoManager = GeometryLocator.getGeometryManager(); |
|
205 |
int subtype = arcToTrim.getGeometryType().getSubType(); |
|
206 |
|
|
207 |
MultiCurve segmentedArc = geoManager.createMultiCurve(subtype); |
|
208 |
segmentedArc.addCurve(arcToTrim); |
|
209 |
|
|
210 |
Geometry geometry = boundaryObject; |
|
211 |
|
|
212 |
Geometry tmpDifference = segmentedArc.difference(geometry); |
|
213 |
if (tmpDifference instanceof MultiCurve) { |
|
214 |
segmentedArc = (MultiCurve) tmpDifference; |
|
215 |
} |
|
216 |
|
|
217 |
double side = TrimLineOperationUtils.getSide(boundaryObject, shearingPoint); |
|
218 |
|
|
219 |
int index = -1; |
|
220 |
if(!Double.isNaN(side)){ |
|
221 |
Curve curve; |
|
222 |
double minDistance = Double.POSITIVE_INFINITY; |
|
223 |
for (int i = 0; i < segmentedArc.getPrimitivesNumber(); i++) { |
|
224 |
curve = segmentedArc.getCurveAt(i); |
|
225 |
double distance = curve.distance(shearingPoint); |
|
226 |
if (distance < minDistance) { |
|
227 |
Double segmentSide = TrimLineOperationUtils.getSide(boundaryObject, curve); |
|
228 |
if(segmentSide == side){ |
|
229 |
index = i; |
|
230 |
minDistance = distance; |
|
231 |
} |
|
232 |
} |
|
233 |
} |
|
234 |
} |
|
235 |
|
|
236 |
MultiCurve trimmedArc = geoManager.createMultiCurve(subtype); |
|
237 |
Point center = arcToTrim.getCenterPoint(); |
|
238 |
|
|
239 |
// If Arc#getCenter() return null, we will have to use this "trick" to |
|
240 |
// get arc center. |
|
241 |
if (center == null) { |
|
242 |
center = |
|
243 |
geoManager.createPoint(arcToTrim.getEnvelope().getCenter(0), |
|
244 |
arcToTrim.getEnvelope().getCenter(1), subtype); |
|
245 |
} |
|
246 |
|
|
247 |
double radius = center.distance(arcToTrim.getInitPoint()); |
|
248 |
|
|
249 |
Curve tmpCurve = null; |
|
250 |
for (int i = 0; i < segmentedArc.getPrimitivesNumber(); i++) { |
|
251 |
|
|
252 |
if (i == index) { |
|
253 |
if (tmpCurve != null) { |
|
254 |
trimmedArc.addCurve(tmpCurve); |
|
255 |
tmpCurve = null; |
|
256 |
} |
|
257 |
continue; |
|
258 |
} |
|
259 |
|
|
260 |
if (tmpCurve != null) { |
|
261 |
tmpCurve = |
|
262 |
union(center, radius, tmpCurve, segmentedArc.getCurveAt(i)); |
|
263 |
} else { |
|
264 |
tmpCurve = segmentedArc.getCurveAt(i); |
|
265 |
} |
|
266 |
} |
|
267 |
if (tmpCurve != null) { |
|
268 |
trimmedArc.addCurve(tmpCurve); |
|
269 |
} |
|
270 |
|
|
271 |
return trimmedArc; |
|
272 |
} |
|
273 |
|
|
171 | 274 |
} |
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/TrimLineEditingProvider.java | ||
---|---|---|
25 | 25 |
package org.gvsig.vectorediting.lib.prov.trimline; |
26 | 26 |
|
27 | 27 |
import java.util.ArrayList; |
28 |
import java.util.HashMap; |
|
28 | 29 |
import java.util.List; |
29 |
|
|
30 |
import org.cresques.cts.IProjection;
|
|
31 |
|
|
30 |
import java.util.Map; |
|
31 |
import java.util.logging.Level;
|
|
32 |
import java.util.logging.Logger; |
|
32 | 33 |
import org.gvsig.fmap.dal.exception.DataException; |
33 | 34 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
34 | 35 |
import org.gvsig.fmap.dal.feature.Feature; |
35 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
|
36 | 36 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
37 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
|
38 | 37 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
39 | 38 |
import org.gvsig.fmap.geom.Geometry; |
39 |
import static org.gvsig.fmap.geom.Geometry.TYPES.CURVE; |
|
40 |
import static org.gvsig.fmap.geom.Geometry.TYPES.MULTICURVE; |
|
41 |
import org.gvsig.fmap.geom.GeometryException; |
|
40 | 42 |
import org.gvsig.fmap.geom.GeometryLocator; |
41 | 43 |
import org.gvsig.fmap.geom.GeometryManager; |
42 | 44 |
import org.gvsig.fmap.geom.aggregate.MultiCurve; |
43 | 45 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
44 | 46 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
45 | 47 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
48 |
import org.gvsig.fmap.geom.primitive.Arc; |
|
46 | 49 |
import org.gvsig.fmap.geom.primitive.Curve; |
50 |
import org.gvsig.fmap.geom.primitive.Line; |
|
47 | 51 |
import org.gvsig.fmap.geom.primitive.Point; |
48 | 52 |
import org.gvsig.fmap.geom.primitive.Primitive; |
49 | 53 |
import org.gvsig.fmap.geom.type.GeometryType; |
50 | 54 |
import org.gvsig.fmap.mapcontext.MapContext; |
51 |
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory; |
|
52 | 55 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol; |
53 | 56 |
import org.gvsig.tools.dispose.DisposableIterator; |
54 |
import org.gvsig.tools.dispose.DisposeUtils; |
|
55 | 57 |
import org.gvsig.tools.dynobject.DynObject; |
56 |
import org.gvsig.tools.evaluator.Evaluator; |
|
57 | 58 |
import org.gvsig.tools.exception.BaseException; |
58 | 59 |
import org.gvsig.tools.service.spi.ProviderServices; |
59 | 60 |
import org.gvsig.tools.visitor.VisitCanceledException; |
... | ... | |
75 | 76 |
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory; |
76 | 77 |
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator; |
77 | 78 |
import org.gvsig.vectorediting.lib.spi.EditingProviderManager; |
79 |
import org.gvsig.vectorediting.lib.spi.EditingProviderServices; |
|
78 | 80 |
|
79 | 81 |
/** |
80 | 82 |
* @author llmarques |
... | ... | |
85 | 87 |
|
86 | 88 |
private final int TOLERANCE_PIXELS = 3; |
87 | 89 |
|
88 |
private Point insertedPoint; |
|
89 |
|
|
90 | 90 |
private final EditingServiceParameter selectionParameter; |
91 | 91 |
|
92 |
private final EditingServiceParameter linesToTrimParameter;
|
|
92 |
private final EditingServiceParameter geometryToTrimWithParameter;
|
|
93 | 93 |
|
94 |
private FeatureSelection selection; |
|
94 |
private final EditingServiceParameter shearingPointParameter; |
|
95 |
|
|
96 |
protected Map<EditingServiceParameter, Object> values; |
|
95 | 97 |
|
96 |
private FeatureSet linesToTrim; |
|
97 |
|
|
98 | 98 |
private final FeatureStore featureStore; |
99 | 99 |
|
100 | 100 |
private final MapContext mapContext; |
... | ... | |
123 | 123 |
new DefaultEditingServiceParameter("selection", "selection", |
124 | 124 |
TYPE.SELECTION); |
125 | 125 |
|
126 |
this.linesToTrimParameter =
|
|
127 |
new DefaultEditingServiceParameter("line_to_trim", "line_to_trim",
|
|
126 |
this.geometryToTrimWithParameter =
|
|
127 |
new DefaultEditingServiceParameter("geometry_to_trim_with", "geometry_to_trim_with",
|
|
128 | 128 |
TYPE.POSITION); |
129 |
|
|
130 |
this.shearingPointParameter |
|
131 |
= new DefaultEditingServiceParameter("shearing_point", |
|
132 |
"shearing_point", TYPE.POSITION); |
|
133 |
|
|
129 | 134 |
} |
130 | 135 |
|
136 |
@Override |
|
131 | 137 |
public EditingServiceParameter next() { |
132 |
if (selection == null) {
|
|
138 |
if (values.get(selectionParameter) == null) {
|
|
133 | 139 |
return selectionParameter; |
134 |
} else if (linesToTrim == null) { |
|
135 |
return linesToTrimParameter; |
|
140 |
} else if (values.get(geometryToTrimWithParameter) == null) { |
|
141 |
return geometryToTrimWithParameter; |
|
142 |
} else if (values.get(shearingPointParameter) == null) { |
|
143 |
return shearingPointParameter; |
|
136 | 144 |
} |
137 | 145 |
return null; |
138 | 146 |
} |
139 | 147 |
|
148 |
@Override |
|
140 | 149 |
public DrawingStatus getDrawingStatus(Point mousePosition) |
141 | 150 |
throws DrawServiceException { |
142 |
if (selection != null) { |
|
151 |
FeatureSelection selection = (FeatureSelection) values.get(selectionParameter); |
|
152 |
Geometry shears = (Geometry) values.get(geometryToTrimWithParameter); |
|
153 |
if (selection != null && shears != null) { |
|
143 | 154 |
DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus(); |
144 | 155 |
|
145 | 156 |
EditingProviderManager editingProviderManager = |
... | ... | |
147 | 158 |
ISymbol lineSymbolEditing = |
148 | 159 |
editingProviderManager.getSymbol("line-symbol-editing"); |
149 | 160 |
|
150 |
double tolerance = |
|
151 |
mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS); |
|
152 |
|
|
153 |
Geometry buffer; |
|
154 |
FeatureSet geometries; |
|
155 |
DisposableIterator it = null; |
|
156 | 161 |
try { |
157 |
// Create buffer with tolerance to get the geometry to be |
|
158 |
// extended |
|
159 |
buffer = mousePosition.buffer(tolerance); |
|
160 |
geometries = getGeometryByBuffer(buffer); |
|
161 |
|
|
162 |
it = geometries.fastIterator(); |
|
163 |
while (it.hasNext()) { |
|
164 |
Feature feature = (Feature) it.next(); |
|
165 |
if (!selection.isSelected(feature)) { |
|
162 |
|
|
163 |
DisposableIterator selectionIterator = null; |
|
164 |
selectionIterator = selection.fastIterator(); |
|
165 |
while (selectionIterator.hasNext()) { |
|
166 |
Feature feature = (Feature) selectionIterator.next(); |
|
167 |
if (feature != null) { |
|
166 | 168 |
Geometry geometry = feature.getDefaultGeometry(); |
169 |
if(geometry != null && geometry.intersects(shears)) { |
|
170 |
if (geometry instanceof MultiCurve) { |
|
171 |
MultiCurve multiCurve = (MultiCurve) geometry; |
|
167 | 172 |
|
168 |
if (geometry instanceof MultiCurve) {
|
|
169 |
MultiCurve multiCurve = (MultiCurve) geometry;
|
|
173 |
for (int i = 0; i < multiCurve
|
|
174 |
.getPrimitivesNumber(); i++) {
|
|
170 | 175 |
|
171 |
for (int i = 0; i < multiCurve |
|
172 |
.getPrimitivesNumber(); i++) { |
|
176 |
Curve curve = multiCurve.getCurveAt(i); |
|
177 |
MultiCurve trimmedCurve |
|
178 |
= trimLine(mousePosition, curve, shears); |
|
179 |
for (int j = 0; j < trimmedCurve |
|
180 |
.getPrimitivesNumber(); j++) { |
|
181 |
drawingStatus.addStatus(trimmedCurve.getCurveAt(j), |
|
182 |
lineSymbolEditing, ""); |
|
183 |
} |
|
184 |
} |
|
173 | 185 |
|
174 |
Curve curve = multiCurve.getCurveAt(i); |
|
175 |
MultiCurve extendedCurve = |
|
176 |
trimLine(mousePosition, curve); |
|
186 |
} else if (geometry instanceof Curve) { |
|
187 |
Curve curve = (Curve) geometry; |
|
188 |
MultiCurve extendedCurve |
|
189 |
= trimLine(mousePosition, curve, shears); |
|
177 | 190 |
for (int j = 0; j < extendedCurve |
178 |
.getPrimitivesNumber(); j++) { |
|
191 |
.getPrimitivesNumber(); j++) {
|
|
179 | 192 |
drawingStatus.addStatus( |
180 |
extendedCurve.getCurveAt(j), |
|
181 |
lineSymbolEditing, ""); |
|
193 |
extendedCurve.getCurveAt(j),
|
|
194 |
lineSymbolEditing, "");
|
|
182 | 195 |
} |
183 | 196 |
} |
184 |
|
|
185 |
} else if (geometry instanceof Curve) { |
|
186 |
Curve curve = (Curve) geometry; |
|
187 |
MultiCurve extendedCurve = |
|
188 |
trimLine(mousePosition, curve); |
|
189 |
for (int j = 0; j < extendedCurve |
|
190 |
.getPrimitivesNumber(); j++) { |
|
191 |
drawingStatus.addStatus( |
|
192 |
extendedCurve.getCurveAt(j), |
|
193 |
lineSymbolEditing, ""); |
|
194 |
} |
|
195 | 197 |
} |
196 | 198 |
} |
197 | 199 |
} |
198 |
} catch (BaseException e) { |
|
199 |
throw new DrawServiceException(e); |
|
200 |
} finally {
|
|
201 |
DisposeUtils.disposeQuietly(it);
|
|
200 |
|
|
201 |
|
|
202 |
} catch (BaseException ex) {
|
|
203 |
throw new DrawServiceException(ex);
|
|
202 | 204 |
} |
205 |
|
|
203 | 206 |
return drawingStatus; |
204 | 207 |
} |
205 | 208 |
return null; |
206 | 209 |
} |
207 | 210 |
|
208 |
private MultiCurve trimLine(Point point, Curve curve)
|
|
211 |
private MultiCurve trimLine(Point shearingPoint, Curve curve, Geometry shearsGeometry)
|
|
209 | 212 |
throws GeometryOperationNotSupportedException, |
210 | 213 |
GeometryOperationException, DataException, CreateGeometryException { |
211 | 214 |
|
212 | 215 |
TrimLineOperation operation = |
213 | 216 |
TrimLineOperationUtils.getOperation((Primitive) curve); |
214 | 217 |
|
215 |
return operation.trimLine(curve, point, selection);
|
|
218 |
return operation.trimLine(curve, shearingPoint, shearsGeometry);
|
|
216 | 219 |
} |
217 | 220 |
|
221 |
@Override |
|
218 | 222 |
public void stop() throws StopServiceException { |
219 |
linesToTrim = null;
|
|
223 |
values.clear();
|
|
220 | 224 |
} |
221 | 225 |
|
226 |
@Override |
|
222 | 227 |
public List<EditingServiceParameter> getParameters() { |
223 | 228 |
List<EditingServiceParameter> parameters = |
224 | 229 |
new ArrayList<>(); |
225 | 230 |
parameters.add(selectionParameter); |
226 |
parameters.add(linesToTrimParameter); |
|
231 |
parameters.add(geometryToTrimWithParameter); |
|
232 |
parameters.add(shearingPointParameter); |
|
227 | 233 |
return parameters; |
228 | 234 |
} |
229 | 235 |
|
... | ... | |
232 | 238 |
validateAndInsertValue(parameter, value); |
233 | 239 |
} |
234 | 240 |
|
241 |
@Override |
|
235 | 242 |
public void setValue(Object value) throws InvalidEntryException { |
236 | 243 |
EditingServiceParameter parameter = next(); |
237 | 244 |
validateAndInsertValue(parameter, value); |
... | ... | |
241 | 248 |
final EditingServiceParameter parameter, Object value) |
242 | 249 |
throws InvalidEntryException { |
243 | 250 |
|
244 |
if (parameter == selectionParameter |
|
245 |
&& value instanceof FeatureSelection) { |
|
251 |
if (parameter == selectionParameter) { |
|
252 |
if (value instanceof FeatureSelection) { |
|
253 |
FeatureSelection featureSelection = (FeatureSelection) value; |
|
254 |
if (featureSelection.getSelectedCount() > 0) { |
|
255 |
try { |
|
256 |
featureSelection.accept(new Visitor() { |
|
246 | 257 |
|
247 |
FeatureSelection featureSelection = (FeatureSelection) value; |
|
258 |
public void visit(Object obj) |
|
259 |
throws VisitCanceledException, BaseException { |
|
260 |
Feature feature = (Feature) obj; |
|
261 |
Geometry geometry |
|
262 |
= feature.getDefaultGeometry(); |
|
248 | 263 |
|
249 |
if (featureSelection.getSelectedCount() > 0) { |
|
250 |
try { |
|
251 |
featureSelection.accept(new Visitor() { |
|
252 |
|
|
253 |
public void visit(Object obj) |
|
254 |
throws VisitCanceledException, BaseException { |
|
255 |
Feature feature = (Feature) obj; |
|
256 |
Geometry geometry = feature.getDefaultGeometry(); |
|
257 |
GeometryType geoType = geometry.getGeometryType(); |
|
258 |
|
|
259 |
if (!geoType.isTypeOf(SURFACE) |
|
260 |
&& !geoType.isTypeOf(MULTISURFACE) |
|
261 |
&& !geoType.isTypeOf(CURVE) |
|
262 |
&& !geoType.isTypeOf(MULTICURVE)) { |
|
263 |
throw new InvalidEntryException(null); |
|
264 |
if (!isValidGeometryToSelect(geometry)) { |
|
265 |
throw new InvalidEntryException(null); |
|
266 |
} |
|
264 | 267 |
} |
265 |
} |
|
266 |
}); |
|
267 |
|
|
268 |
selection = featureSelection; |
|
269 |
return; |
|
270 |
} catch (BaseException e) { |
|
271 |
throw new InvalidEntryException(e); |
|
268 |
}); |
|
269 |
values.put(parameter, featureSelection); |
|
270 |
return; |
|
271 |
} catch (BaseException e) { |
|
272 |
throw new InvalidEntryException(e); |
|
273 |
} |
|
272 | 274 |
} |
273 | 275 |
} |
274 |
} else if (parameter == linesToTrimParameter && value instanceof Point) {
|
|
276 |
} else if (parameter == geometryToTrimWithParameter && value instanceof Point) {
|
|
275 | 277 |
|
276 |
Point point = (Point) value; |
|
278 |
if (value instanceof Point) { |
|
279 |
Point point = (Point) value; |
|
277 | 280 |
|
278 |
try { |
|
279 |
double tolerance = |
|
280 |
mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS); |
|
281 |
|
|
282 |
// Create buffer with tolerance to get geometries to be |
|
283 |
// extended |
|
284 |
Geometry buffer = point.buffer(tolerance); |
|
285 |
FeatureSet geometries = getGeometryByBuffer(buffer); |
|
286 |
|
|
287 |
if (geometries.getSize() > 0) { |
|
288 |
|
|
289 |
geometries.accept(new Visitor() { |
|
290 |
|
|
291 |
public void visit(Object obj) |
|
292 |
throws VisitCanceledException, BaseException { |
|
293 |
|
|
294 |
Feature feature = (Feature) obj; |
|
295 |
final Geometry geometry = |
|
296 |
feature.getDefaultGeometry(); |
|
297 |
GeometryType geoType = geometry.getGeometryType(); |
|
298 |
|
|
299 |
if (!geoType.isTypeOf(CURVE) |
|
300 |
&& !geoType.isTypeOf(MULTICURVE)) { |
|
301 |
throw new InvalidEntryException(null); |
|
302 |
} |
|
303 |
} |
|
304 |
}); |
|
305 |
|
|
306 |
insertedPoint = point; |
|
307 |
linesToTrim = geometries; |
|
281 |
Geometry geometry = getGeometry(point); //editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext); |
|
282 |
if (geometry != null) { |
|
283 |
try { |
|
284 |
values.put(parameter, geometry.toLines()); |
|
285 |
} catch (GeometryException ex) { |
|
286 |
throw new InvalidEntryException(ex); |
|
287 |
} |
|
308 | 288 |
return; |
309 | 289 |
} |
310 |
} catch (BaseException e) { |
|
311 |
throw new InvalidEntryException(e); |
|
290 |
|
|
312 | 291 |
} |
292 |
} else if (parameter == shearingPointParameter && value instanceof Point) { |
|
293 |
|
|
294 |
if (value instanceof Point) { |
|
295 |
Point point = (Point) value; |
|
296 |
values.put(parameter, point); |
|
297 |
return; |
|
298 |
} |
|
313 | 299 |
} |
314 | 300 |
throw new InvalidEntryException(null); |
315 | 301 |
} |
302 |
|
|
303 |
private boolean isValidGeometryToSelect(Geometry geometry) { |
|
304 |
GeometryType geoType |
|
305 |
= geometry.getGeometryType(); |
|
306 |
if (!geoType.isTypeOf(CURVE) |
|
307 |
&& !geoType.isTypeOf(MULTICURVE)) { |
|
308 |
return false; |
|
309 |
} |
|
316 | 310 |
|
317 |
private FeatureSet getGeometryByBuffer(Geometry buffer) |
|
318 |
throws DataException { |
|
319 |
FeatureQuery queryByGeometry = featureStore.createFeatureQuery(); |
|
311 |
if (geoType.isTypeOf(CURVE)) { |
|
312 |
if (geometry instanceof Line ) { |
|
313 |
Line line = (Line) geometry; |
|
314 |
return !line.isClosed(); |
|
315 |
} |
|
316 |
if (geometry instanceof Arc ) { |
|
317 |
Arc arc = (Arc) geometry; |
|
318 |
return !arc.getInitPoint().equals(arc.getEndPoint()); |
|
319 |
} |
|
320 |
return false; |
|
321 |
} |
|
320 | 322 |
|
321 |
// Get default SRS of default feature type |
|
322 |
IProjection defaultSRS = |
|
323 |
this.featureStore.getDefaultFeatureType().getDefaultSRS(); |
|
323 |
if (geoType.isTypeOf(MULTICURVE)) { |
|
324 |
MultiCurve multiCurve = (MultiCurve) geometry; |
|
325 |
for (Geometry geom : multiCurve) { |
|
326 |
if (!isValidGeometryToSelect(geom)) { |
|
327 |
return false; |
|
328 |
} |
|
329 |
} |
|
330 |
} |
|
331 |
return true; |
|
324 | 332 |
|
325 |
Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects( |
|
326 |
buffer, |
|
327 |
defaultSRS, |
|
328 |
featureStore |
|
329 |
); |
|
333 |
} |
|
330 | 334 |
|
331 |
queryByGeometry.setFilter(iee); |
|
332 |
queryByGeometry.setAttributeNames(null); |
|
333 |
return this.featureStore.getFeatureSet(queryByGeometry); |
|
335 |
private Geometry getGeometry(Point point) { |
|
336 |
EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices(); |
|
337 |
Geometry geometry = editingProviderServices.getGeometryOfVisibleLayers(point, featureStore, mapContext); |
|
338 |
return geometry; |
|
334 | 339 |
} |
335 | 340 |
|
341 |
@Override |
|
336 | 342 |
public Geometry finish() throws FinishServiceException { |
337 | 343 |
return null; |
338 | 344 |
} |
339 | 345 |
|
346 |
@Override |
|
340 | 347 |
public void finishAndStore() throws FinishServiceException { |
348 |
|
|
349 |
FeatureSelection selection = (FeatureSelection) values.get(selectionParameter); |
|
350 |
Geometry shearsGeometry = (Geometry) values.get(geometryToTrimWithParameter); |
|
351 |
Point point = (Point) values.get(shearingPointParameter); |
|
341 | 352 |
|
342 |
if (selection != null && linesToTrim != null) { |
|
343 |
|
|
353 |
if (selection != null && shearsGeometry != null && point != null) { |
|
344 | 354 |
try { |
345 |
linesToTrim.accept(new Visitor() { |
|
355 |
|
|
356 |
|
|
357 |
DisposableIterator selectionIterator = null; |
|
358 |
selectionIterator = selection.fastIterator(); |
|
359 |
while (selectionIterator.hasNext()) { |
|
360 |
Feature feature = (Feature) selectionIterator.next(); |
|
346 | 361 |
|
347 |
public void visit(Object obj) |
|
348 |
throws VisitCanceledException, BaseException { |
|
349 |
Feature feature = (Feature) obj; |
|
350 |
Geometry geometry = feature.getDefaultGeometry(); |
|
351 |
EditableFeature eFeature = feature.getEditable(); |
|
362 |
Geometry geometry = feature.getDefaultGeometry(); |
|
363 |
|
|
364 |
EditableFeature eFeature = feature.getEditable(); |
|
352 | 365 |
|
366 |
if(geometry.intersects(shearsGeometry)){ |
|
353 | 367 |
if (geometry instanceof Curve) { |
354 | 368 |
|
355 | 369 |
Curve curveToTrim = (Curve) geometry; |
356 | 370 |
MultiCurve result = |
357 |
trimLine(insertedPoint, curveToTrim);
|
|
371 |
trimLine(point, curveToTrim, shearsGeometry);
|
|
358 | 372 |
eFeature.setDefaultGeometry(result); |
373 |
selection.update(eFeature); |
|
359 | 374 |
|
360 | 375 |
} else if (geometry instanceof MultiCurve) { |
361 | 376 |
|
362 | 377 |
int subType = |
363 | 378 |
geometry.getGeometryType().getSubType(); |
364 |
MultiCurve multiCurveTrimmed =
|
|
379 |
MultiCurve trimmedMultiCurve =
|
|
365 | 380 |
createMultiCurve(subType); |
366 | 381 |
MultiCurve multiCurveToTrim = (MultiCurve) geometry; |
367 | 382 |
|
... | ... | |
371 | 386 |
for (int i = 0; i < multiCurveToTrim |
372 | 387 |
.getPrimitivesNumber(); i++) { |
373 | 388 |
|
374 |
Curve curveToTrim =
|
|
389 |
Curve primitive =
|
|
375 | 390 |
multiCurveToTrim.getCurveAt(i); |
376 | 391 |
|
377 | 392 |
double distance = |
378 |
curveToTrim.distance(insertedPoint);
|
|
393 |
primitive.distance(point);
|
|
379 | 394 |
if (distance < minDistance) { |
380 | 395 |
nearestCurveIndex = i; |
381 | 396 |
minDistance = distance; |
... | ... | |
383 | 398 |
} |
384 | 399 |
|
385 | 400 |
MultiCurve result = |
386 |
trimLine(insertedPoint, multiCurveToTrim
|
|
387 |
.getCurveAt(nearestCurveIndex)); |
|
401 |
trimLine(point, multiCurveToTrim
|
|
402 |
.getCurveAt(nearestCurveIndex), shearsGeometry);
|
|
388 | 403 |
|
389 | 404 |
for (int i = 0; i < result.getPrimitivesNumber(); i++) { |
390 |
multiCurveTrimmed.addCurve(result.getCurveAt(i));
|
|
405 |
trimmedMultiCurve.addCurve(result.getCurveAt(i));
|
|
391 | 406 |
} |
392 | 407 |
|
393 | 408 |
for (int i = 0; i < multiCurveToTrim |
394 | 409 |
.getPrimitivesNumber(); i++) { |
395 | 410 |
if (i != nearestCurveIndex) { |
396 |
multiCurveTrimmed.addCurve(multiCurveToTrim
|
|
411 |
trimmedMultiCurve.addCurve(multiCurveToTrim
|
|
397 | 412 |
.getCurveAt(i)); |
398 | 413 |
} |
399 | 414 |
} |
400 | 415 |
|
401 |
eFeature.setDefaultGeometry(multiCurveTrimmed); |
|
416 |
eFeature.setDefaultGeometry(trimmedMultiCurve); |
|
417 |
selection.update(eFeature); |
|
418 |
|
|
402 | 419 |
} |
403 |
|
|
404 |
linesToTrim.update(eFeature); |
|
405 | 420 |
} |
406 |
});
|
|
407 |
} catch (BaseException e) { |
|
408 |
throw new FinishServiceException(e); |
|
421 |
}
|
|
422 |
} catch (BaseException ex) {
|
|
423 |
throw new FinishServiceException(ex);
|
|
409 | 424 |
} |
410 | 425 |
} |
411 | 426 |
} |
... | ... | |
421 | 436 |
return extendedMultiCurve; |
422 | 437 |
} |
423 | 438 |
|
439 |
@Override |
|
424 | 440 |
public void start() throws StartServiceException, InvalidEntryException { |
425 |
linesToTrim = null; |
|
441 |
|
|
442 |
this.values = new HashMap<>(); |
|
426 | 443 |
FeatureSelection selected = null; |
427 |
if (featureStore != null && selection == null) {
|
|
444 |
if (featureStore != null && values.get(selectionParameter) == null) {
|
|
428 | 445 |
try { |
429 | 446 |
selected = featureStore.getFeatureSelection(); |
430 | 447 |
} catch (DataException e) { |
... | ... | |
441 | 458 |
|
442 | 459 |
} |
443 | 460 |
|
461 |
@Override |
|
444 | 462 |
public String getName() { |
445 | 463 |
return TrimLineEditingProviderFactory.PROVIDER_NAME; |
446 | 464 |
} |
Also available in: Unified diff