gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.chamfer / src / main / java / org / gvsig / vectorediting / lib / prov / chamfer / ChamferByLengthAndAngleEditingProvider.java @ 4284
History | View | Annotate | Download (66.8 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 |
package org.gvsig.vectorediting.lib.prov.chamfer; |
25 |
|
26 |
import java.awt.Color; |
27 |
import java.awt.geom.Point2D; |
28 |
import java.util.ArrayList; |
29 |
import java.util.Arrays; |
30 |
import java.util.HashMap; |
31 |
import java.util.List; |
32 |
import java.util.Map; |
33 |
import java.util.Objects; |
34 |
import org.apache.commons.lang3.tuple.ImmutablePair; |
35 |
import org.apache.commons.lang3.tuple.Pair; |
36 |
import org.gvsig.euclidean.EuclideanLine2D; |
37 |
import org.gvsig.euclidean.EuclideanManager; |
38 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
39 |
import org.gvsig.fmap.dal.feature.Feature; |
40 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
41 |
import org.gvsig.fmap.geom.Geometry; |
42 |
import org.gvsig.fmap.geom.GeometryException; |
43 |
import org.gvsig.fmap.geom.GeometryLocator; |
44 |
import org.gvsig.fmap.geom.GeometryManager; |
45 |
import org.gvsig.fmap.geom.GeometryUtils; |
46 |
import org.gvsig.fmap.geom.aggregate.MultiLine; |
47 |
import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
48 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
49 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
50 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
51 |
import org.gvsig.fmap.geom.primitive.Arc; |
52 |
import org.gvsig.fmap.geom.primitive.Curve; |
53 |
import org.gvsig.fmap.geom.primitive.Line; |
54 |
import org.gvsig.fmap.geom.primitive.Point; |
55 |
import org.gvsig.fmap.geom.primitive.Polygon; |
56 |
import org.gvsig.fmap.geom.primitive.Primitive; |
57 |
import org.gvsig.fmap.geom.primitive.Surface; |
58 |
import org.gvsig.fmap.mapcontext.MapContext; |
59 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol; |
60 |
import org.gvsig.symbology.SymbologyLocator; |
61 |
import org.gvsig.symbology.SymbologyManager; |
62 |
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol; |
63 |
import org.gvsig.tools.ToolsLocator; |
64 |
import org.gvsig.tools.dataTypes.DataTypes; |
65 |
import org.gvsig.tools.dynobject.DynObject; |
66 |
import org.gvsig.tools.i18n.I18nManager; |
67 |
import org.gvsig.tools.service.spi.ProviderServices; |
68 |
import org.gvsig.tools.util.ToolsUtilLocator; |
69 |
import org.gvsig.vectorediting.lib.api.DrawingStatus; |
70 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter; |
71 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE; |
72 |
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException; |
73 |
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException; |
74 |
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException; |
75 |
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException; |
76 |
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException; |
77 |
import static org.gvsig.vectorediting.lib.prov.chamfer.SegmentData.SEGMENT_POSITION_FIRST; |
78 |
import static org.gvsig.vectorediting.lib.prov.chamfer.SegmentData.SEGMENT_POSITION_LAST; |
79 |
import static org.gvsig.vectorediting.lib.prov.chamfer.SegmentData.SEGMENT_POSITION_MIDDLE; |
80 |
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider; |
81 |
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus; |
82 |
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter; |
83 |
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions; |
84 |
import org.gvsig.vectorediting.lib.spi.EditingProvider; |
85 |
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory; |
86 |
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator; |
87 |
import org.gvsig.vectorediting.lib.spi.EditingProviderManager; |
88 |
import org.gvsig.vectorediting.lib.spi.EditingProviderServices; |
89 |
import org.slf4j.Logger; |
90 |
import org.slf4j.LoggerFactory; |
91 |
|
92 |
/**
|
93 |
* @author fdiaz
|
94 |
*
|
95 |
*/
|
96 |
public class ChamferByLengthAndAngleEditingProvider extends AbstractEditingProvider { |
97 |
|
98 |
private static final Logger LOGGER = LoggerFactory.getLogger(ChamferByLengthAndAngleEditingProvider.class); |
99 |
|
100 |
private static final int ERR_OK = 0; |
101 |
private static final int ERR_CHAMFER_TOO_LARGE = 1; |
102 |
private static final int ERR_SEGMENT_DATA_NOT_FILLED = 2; |
103 |
private static final int ERR_FIRST_SEGMENT_DATA_NULL = 3; |
104 |
private static final int ERR_SAME_SEGMENT = 4; |
105 |
private static final int ERR_CANT_CALCULATE_CHAMFER_POINT = 5; |
106 |
private static final int ERR_NON_ADJACENT_SEGMENTS = 6; |
107 |
private static final int ERR_DIFFERENT_GEOMETRY_TYPES = 7; |
108 |
private static final int ERR_CANT_CONNECT_SEGMENTS = 8; |
109 |
private static final int ERR_ONE_OF_THE_TWO_SEGMENTS_ISNT_EXTREME = 9; |
110 |
private static final int ERR_INVALID_VALUE = 10; |
111 |
private static final int ERR_INVALID_GEOMETRY_TYPE = 11; |
112 |
private static final int ERR_CANT_FIND_NEAREST_GEOMETRY = 12; |
113 |
private static final int ERR_CANT_CALCULATE_CHAMFER = 13; |
114 |
|
115 |
private static String[] stateMessages= { |
116 |
"_Valid",
|
117 |
"_Chamfer_too_large",
|
118 |
"_Cant_fill_segment_data",
|
119 |
"_First_segment_data_is_null",
|
120 |
"_Same_segment",
|
121 |
"_Cant_calculate_chamfer_point",
|
122 |
"_Non-adjacent_segments",
|
123 |
"_Different_geometry_types",
|
124 |
"_Cant_connect_segments",
|
125 |
"_One_of_the_two_segments_isnt_extreme",
|
126 |
"_Invalid_value",
|
127 |
"_Invalid_geometry_type",
|
128 |
"_Cant_find_nearest_geometry",
|
129 |
"_Cant_calculate_chamfer"
|
130 |
|
131 |
}; |
132 |
|
133 |
|
134 |
private static final int INSIDE_THE_SEGMENT = 0; |
135 |
private static final int BEYOND_THE_SEGMENT = 1; |
136 |
private static final int INVALID_ZONE = -1; |
137 |
|
138 |
private static final String CHAMFER_LENGTH = "_Length"; |
139 |
// private static final String CHAMFER_ANGLE = "_Angle";
|
140 |
//
|
141 |
// private static final String SHORT_CHAMFER_LENGTH = "_Short_length";
|
142 |
// private static final String SHORT_CHAMFER_ANGLE = "_Short_angle";
|
143 |
|
144 |
// private static final String CHAMFER_METHOD = "_Method";
|
145 |
|
146 |
private static final String DELETE_SECOND_SELECTED_GEOMETRY_QUESTION = "_Delete_second_selected_geometry_question"; |
147 |
|
148 |
private static final String DELETE_SECOND_SELECTED_GEOMETRY = "_Delete_second_selected_geometry"; |
149 |
|
150 |
private static final String YES = "_yes"; |
151 |
private static final String NO = "_no"; |
152 |
|
153 |
private static final String SHORT_YES = "_short_yes"; |
154 |
private static final String SHORT_NO = "_short_no"; |
155 |
//Variable est?tica para guardarnos el deleteSecondFeatureDefaultValue
|
156 |
private static Boolean deleteSecondFeatureDefaultValue; |
157 |
|
158 |
private final EditingServiceParameter lengthParameter; |
159 |
|
160 |
private final EditingServiceParameter firstSegmentParameter; |
161 |
|
162 |
private final EditingServiceParameter secondSegmentParameter; |
163 |
|
164 |
private final EditingServiceParameter angleParameter; |
165 |
|
166 |
private final EditingServiceParameter deleteSecondSelectedGeometryParameter; |
167 |
|
168 |
private final Map<EditingServiceParameter, Object> values; |
169 |
|
170 |
private final FeatureStore featureStore; |
171 |
|
172 |
private final MapContext mapContext; |
173 |
|
174 |
private SegmentData firstSegmentData;
|
175 |
private SegmentData secondSegmentData;
|
176 |
|
177 |
private Point pointToChamfer; |
178 |
|
179 |
//Variable est?tica para guardarnos la distancia por defecto
|
180 |
private static Double savedDistance; |
181 |
|
182 |
private ISymbol previewSymbol;
|
183 |
|
184 |
/**
|
185 |
* Default constructor.
|
186 |
*
|
187 |
* @param providerServices available services for this provider
|
188 |
* @param parameters of this provider
|
189 |
*/
|
190 |
public ChamferByLengthAndAngleEditingProvider(ProviderServices providerServices,
|
191 |
DynObject parameters) { |
192 |
super(providerServices);
|
193 |
I18nManager i18nManager = ToolsLocator.getI18nManager(); |
194 |
|
195 |
this.featureStore
|
196 |
= (FeatureStore) parameters |
197 |
.getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD); |
198 |
|
199 |
this.mapContext
|
200 |
= (MapContext) parameters |
201 |
.getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD); |
202 |
|
203 |
this.firstSegmentParameter
|
204 |
= new DefaultEditingServiceParameter("_First_segment", "_First_segment", TYPE.POSITION); |
205 |
|
206 |
this.secondSegmentParameter
|
207 |
= new DefaultEditingServiceParameter("_Second_segment", "_Second_segment", TYPE.POSITION); |
208 |
|
209 |
// DefaultEditingServiceParameterOptions methodOptions = new DefaultEditingServiceParameterOptions()
|
210 |
// .add(i18nManager.getTranslation(CHAMFER_LENGTH), CHAMFER_LENGTH, i18nManager.getTranslation(SHORT_CHAMFER_LENGTH))
|
211 |
// .add(i18nManager.getTranslation(CHAMFER_ANGLE), CHAMFER_ANGLE, i18nManager.getTranslation(SHORT_CHAMFER_ANGLE));
|
212 |
|
213 |
// String methodConsoleMsg
|
214 |
// = ((EditingProviderServices) providerServices).makeConsoleMessage(
|
215 |
// i18nManager.getTranslation(CHAMFER_METHOD), methodOptions);
|
216 |
|
217 |
this.lengthParameter = new DefaultEditingServiceParameter( |
218 |
"_Length",
|
219 |
"_Length",
|
220 |
TYPE.VALUE, |
221 |
// TYPE.POSITION,
|
222 |
TYPE.DISTANCE |
223 |
); |
224 |
|
225 |
this.angleParameter
|
226 |
= new DefaultEditingServiceParameter("_Angle", "_Angle", |
227 |
TYPE.POSITION, |
228 |
TYPE.VALUE); |
229 |
|
230 |
DefaultEditingServiceParameterOptions deleteSecondSelectedGeometryParameterOptions = new DefaultEditingServiceParameterOptions()
|
231 |
.add(YES, true, i18nManager.getTranslation(SHORT_YES))
|
232 |
.add(NO, false, i18nManager.getTranslation(SHORT_NO));
|
233 |
|
234 |
String consoleMsg
|
235 |
= ((EditingProviderServices) providerServices).makeConsoleMessage( |
236 |
DELETE_SECOND_SELECTED_GEOMETRY_QUESTION, deleteSecondSelectedGeometryParameterOptions); |
237 |
|
238 |
this.deleteSecondSelectedGeometryParameter
|
239 |
= new DefaultEditingServiceParameter(
|
240 |
DELETE_SECOND_SELECTED_GEOMETRY, |
241 |
consoleMsg, |
242 |
deleteSecondSelectedGeometryParameterOptions, |
243 |
null, //deleteSecondFeatureDefaultValue, |
244 |
false,
|
245 |
TYPE.OPTION).setDataType(DataTypes.BOOLEAN); |
246 |
|
247 |
this.values = new HashMap<>(); |
248 |
this.firstSegmentData = null; |
249 |
this.secondSegmentData = null; |
250 |
} |
251 |
|
252 |
@Override
|
253 |
public String getName() { |
254 |
return ChamferByLengthAndAngleEditingProviderFactory.PROVIDER_NAME;
|
255 |
} |
256 |
|
257 |
@Override
|
258 |
public EditingServiceParameter next() {
|
259 |
if (values.get(lengthParameter) == null) { |
260 |
return this.lengthParameter; |
261 |
} else if (values.get(firstSegmentParameter) == null) { |
262 |
return this.firstSegmentParameter; |
263 |
} else if (values.get(secondSegmentParameter) == null) { |
264 |
return this.secondSegmentParameter; |
265 |
} else if (values.get(angleParameter) == null) { |
266 |
return this.angleParameter; |
267 |
} else if (values.get(deleteSecondSelectedGeometryParameter) == null && |
268 |
!Objects.equals(firstSegmentData.getFeature().getReference(), secondSegmentData.getFeature().getReference())) { |
269 |
return this.deleteSecondSelectedGeometryParameter; |
270 |
} |
271 |
return null; |
272 |
} |
273 |
|
274 |
@Override
|
275 |
public DrawingStatus getDrawingStatus(Point mousePosition) |
276 |
throws DrawServiceException {
|
277 |
DefaultDrawingStatus geometries = new DefaultDrawingStatus();
|
278 |
|
279 |
GeometryManager geometryManager = GeometryLocator.getGeometryManager(); |
280 |
EditingProviderManager editingProviderManager |
281 |
= EditingProviderLocator.getProviderManager(); |
282 |
ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
|
283 |
ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
|
284 |
ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
|
285 |
ISymbol polygonSymbolEditing = editingProviderManager.getSymbol("polygon-symbol-editing");
|
286 |
ISymbol ruleAxisSymbol = editingProviderManager.getSymbol("rule-axis-symbol");
|
287 |
|
288 |
auxiliaryPointSymbolEditing.setColor(Color.RED);
|
289 |
ISimpleTextSymbol textSymbol = getTextSymbol(); |
290 |
|
291 |
EditingProviderServices editingProviderServices |
292 |
= (EditingProviderServices) getProviderServices(); |
293 |
|
294 |
ISymbol previewSymbol = null;
|
295 |
try {
|
296 |
int subtype = editingProviderServices.getSubType(featureStore);
|
297 |
Double distance;
|
298 |
if (values != null) { |
299 |
if (values.get(this.lengthParameter) == null) { |
300 |
return geometries;
|
301 |
} else if (this.firstSegmentData == null) { |
302 |
Feature firstFeature = getFeatureNearestPoint(mousePosition); |
303 |
if (firstFeature == null) { |
304 |
return geometries;
|
305 |
} |
306 |
Geometry firstGeometry = firstFeature.getDefaultGeometry(); |
307 |
if (firstGeometry == null || !validateGeometryType(firstGeometry)) { |
308 |
return geometries;
|
309 |
} |
310 |
|
311 |
SegmentData segmentData = new SegmentData(firstFeature, mousePosition);
|
312 |
geometries.addStatus(segmentData.getProjectedPoint(), auxiliaryPointSymbolEditing, "");
|
313 |
geometries.addStatus(GeometryUtils.createLine(mousePosition, segmentData.getProjectedPoint(), subtype), auxiliaryLineSymbolEditing, "");
|
314 |
geometries.addStatus(segmentData.getLine(), auxiliaryLineSymbolEditing, "");
|
315 |
return geometries;
|
316 |
|
317 |
} else if (this.secondSegmentData == null) { |
318 |
geometries.addStatus(firstSegmentData.getLine(), auxiliaryLineSymbolEditing, "");
|
319 |
geometries.addStatus(firstSegmentData.getProjectedPoint(), auxiliaryPointSymbolEditing, "");
|
320 |
|
321 |
Feature secondFeature = getFeatureNearestPoint(mousePosition); |
322 |
if (secondFeature == null) { |
323 |
return geometries;
|
324 |
} |
325 |
Geometry secondGeometry = secondFeature.getDefaultGeometry(); |
326 |
if (secondGeometry == null || !validateGeometryType(secondGeometry)) { |
327 |
return geometries;
|
328 |
} |
329 |
SegmentData segmentData = new SegmentData(secondFeature, mousePosition);
|
330 |
Pair<Point, Point> oppositePoints = calculateOpositeToChamferVertices(firstSegmentData, segmentData); |
331 |
if (validateAsSecondSegmentData(segmentData, oppositePoints.getRight()) == ERR_OK) {
|
332 |
geometries.addStatus(segmentData.getProjectedPoint(), auxiliaryPointSymbolEditing, "");
|
333 |
geometries.addStatus(GeometryUtils.createLine(mousePosition, segmentData.getProjectedPoint(), subtype), auxiliaryLineSymbolEditing, "");
|
334 |
geometries.addStatus(segmentData.getLine(), auxiliaryLineSymbolEditing, "");
|
335 |
|
336 |
Point tmpPointToChamfer = calculatePointToChamfer(firstSegmentData, segmentData);
|
337 |
geometries.addStatus(tmpPointToChamfer, auxiliaryPointSymbolEditing, "");
|
338 |
|
339 |
} else {
|
340 |
return geometries;
|
341 |
} |
342 |
} else if (values.get(angleParameter) == null) { |
343 |
Point tmpPointToFillet = calculatePointToChamfer(firstSegmentData, secondSegmentData);
|
344 |
Pair<Point, Point> oppositePoints = calculateOpositeToChamferVertices(firstSegmentData, secondSegmentData); |
345 |
geometries.addStatus( |
346 |
GeometryUtils.createLine(oppositePoints.getLeft(), tmpPointToFillet, subtype), |
347 |
auxiliaryLineSymbolEditing, |
348 |
""
|
349 |
); |
350 |
geometries.addStatus( |
351 |
GeometryUtils.createLine(oppositePoints.getRight(), tmpPointToFillet, subtype), |
352 |
auxiliaryLineSymbolEditing, |
353 |
""
|
354 |
); |
355 |
|
356 |
distance = (Double) getValue(lengthParameter);
|
357 |
double angle = GeometryUtils.calculateAngle(
|
358 |
pointToChamfer, |
359 |
mousePosition); |
360 |
|
361 |
geometries.addStatus(tmpPointToFillet, auxiliaryPointSymbolEditing, "");
|
362 |
|
363 |
//Draw scaffolding
|
364 |
ScaffoldingToChamfer scaffolding = calculateScaffolding(firstSegmentData, secondSegmentData, tmpPointToFillet, distance, angle, subtype); |
365 |
if(scaffolding == null){ |
366 |
return geometries;
|
367 |
} |
368 |
|
369 |
geometries.addStatus( |
370 |
GeometryUtils.createLine( |
371 |
tmpPointToFillet, |
372 |
scaffolding.getP1(), |
373 |
subtype), |
374 |
auxiliaryLineSymbolEditing, |
375 |
""
|
376 |
); |
377 |
if(scaffolding.isReversed()){
|
378 |
geometries.addStatus( |
379 |
GeometryUtils.createLine( |
380 |
scaffolding.getP1(), |
381 |
GeometryUtils.createPoint(scaffolding.getChamferRight().getX(), scaffolding.getChamferRight().getY()), |
382 |
subtype), |
383 |
auxiliaryLineSymbolEditing, |
384 |
""
|
385 |
); |
386 |
} else {
|
387 |
geometries.addStatus( |
388 |
GeometryUtils.createLine( |
389 |
scaffolding.getP1(), |
390 |
GeometryUtils.createPoint(scaffolding.getChamferRight().getX(), scaffolding.getChamferRight().getY()), |
391 |
subtype), |
392 |
auxiliaryLineSymbolEditing, |
393 |
""
|
394 |
); |
395 |
} |
396 |
|
397 |
geometries.addStatus( |
398 |
GeometryUtils.createLine( |
399 |
GeometryUtils.createPoint(scaffolding.getChamferRight().getX(), scaffolding.getChamferRight().getY()), |
400 |
GeometryUtils.createPoint(scaffolding.getChamferLeft().getX(), scaffolding.getChamferLeft().getY()), |
401 |
subtype), |
402 |
auxiliaryLineSymbolEditing, |
403 |
""
|
404 |
); |
405 |
|
406 |
//Draw angle
|
407 |
Line ruleAxisBaseLine;
|
408 |
ruleAxisBaseLine = geometryManager.createLine(subtype); |
409 |
ruleAxisBaseLine.addVertex(tmpPointToFillet); |
410 |
Point p2 = geometryManager.createPoint(
|
411 |
tmpPointToFillet.getX() + tmpPointToFillet.distance(mousePosition), |
412 |
tmpPointToFillet.getY(), subtype); |
413 |
ruleAxisBaseLine.addVertex(p2); |
414 |
geometries.addStatus(ruleAxisBaseLine, ruleAxisSymbol, "");
|
415 |
|
416 |
Line angleLine = geometryManager.createLine(subtype);
|
417 |
angleLine.addVertex(tmpPointToFillet); |
418 |
angleLine.addVertex(mousePosition); |
419 |
geometries.addStatus(angleLine, ruleAxisSymbol, "");
|
420 |
|
421 |
Double ext = (2 * Math.PI) - angle; |
422 |
Arc arc = GeometryUtils.createArc( |
423 |
tmpPointToFillet, |
424 |
tmpPointToFillet.distance(mousePosition) / 2,
|
425 |
0,
|
426 |
angle, |
427 |
Geometry.SUBTYPES.GEOM2D); |
428 |
geometries.addStatus(arc, auxiliaryLineSymbolEditing, "");
|
429 |
double textDistance = 3 * tmpPointToFillet.distance(mousePosition) / 4; |
430 |
Point pointText = geometryManager.createPoint(tmpPointToFillet.getX() + textDistance * Math.cos(angle / 2), tmpPointToFillet.getY() + textDistance * Math.sin(angle / 2), subtype); |
431 |
geometries.addStatus(pointText, textSymbol, GeometryUtils.formatAngle("%5.3D\u00B0", Math.toDegrees(angle))); |
432 |
|
433 |
|
434 |
//Draw result
|
435 |
drawResult(geometries, firstSegmentData, secondSegmentData, distance, angle, subtype); |
436 |
return geometries;
|
437 |
} else {
|
438 |
drawResult( |
439 |
geometries, |
440 |
firstSegmentData, |
441 |
secondSegmentData, |
442 |
(Double) getValue(lengthParameter),
|
443 |
Math.toRadians((Double) getValue(angleParameter)), |
444 |
subtype |
445 |
); |
446 |
return geometries;
|
447 |
} |
448 |
} |
449 |
} catch (Exception e) { |
450 |
throw new DrawServiceException(e); |
451 |
} |
452 |
return geometries;
|
453 |
} |
454 |
|
455 |
private void drawResult(DefaultDrawingStatus geometries, SegmentData firstSegmentData, SegmentData secondSegmentData, Double length, Double angle, int subtype) throws CreateGeometryException, GeometryOperationNotSupportedException, IllegalStateException, GeometryException, GeometryOperationException { |
456 |
if(previewSymbol == null){ |
457 |
return;
|
458 |
} |
459 |
//Draw result
|
460 |
Line chamfer = calculateChamfer(firstSegmentData, secondSegmentData, length, angle, subtype);
|
461 |
if (chamfer == null) { |
462 |
return;
|
463 |
} |
464 |
if (Objects.equals(firstSegmentData.getPrimitive(), secondSegmentData.getPrimitive())) {
|
465 |
geometries.addStatus(chamferPrimitive(firstSegmentData.getPrimitive(), chamfer), previewSymbol, null);
|
466 |
} else {
|
467 |
geometries.addStatus(chamferPrimitives(firstSegmentData.getPrimitive(), secondSegmentData.getPrimitive(), chamfer), previewSymbol, null);
|
468 |
} |
469 |
} |
470 |
|
471 |
private ISimpleTextSymbol getTextSymbol() {
|
472 |
SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager(); |
473 |
ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol(); |
474 |
textSymbol.setFontSize(10);
|
475 |
return textSymbol;
|
476 |
} |
477 |
|
478 |
@Override
|
479 |
public List<EditingServiceParameter> getParameters() { |
480 |
List<EditingServiceParameter> parameters
|
481 |
= new ArrayList<>(); |
482 |
parameters.add(lengthParameter); |
483 |
parameters.add(firstSegmentParameter); |
484 |
parameters.add(secondSegmentParameter); |
485 |
parameters.add(angleParameter); |
486 |
parameters.add(deleteSecondSelectedGeometryParameter); |
487 |
return parameters;
|
488 |
} |
489 |
|
490 |
@Override
|
491 |
public boolean isEnabled(EditingServiceParameter parameter) { |
492 |
return true; |
493 |
} |
494 |
|
495 |
@Override
|
496 |
public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException { |
497 |
validateAndInsertValue(parameter, value); |
498 |
} |
499 |
|
500 |
@Override
|
501 |
public void setValue(Object value) throws InvalidEntryException { |
502 |
EditingServiceParameter param = next(); |
503 |
validateAndInsertValue(param, value); |
504 |
} |
505 |
|
506 |
private void validateAndInsertValue(EditingServiceParameter param, |
507 |
Object value) throws InvalidEntryException { |
508 |
|
509 |
try {
|
510 |
EditingProviderServices editingProviderServices |
511 |
= (EditingProviderServices) getProviderServices(); |
512 |
int subtype = editingProviderServices.getSubType(featureStore);
|
513 |
|
514 |
I18nManager i18n = ToolsLocator.getI18nManager(); |
515 |
|
516 |
|
517 |
if (param == lengthParameter) {
|
518 |
Double distance = null; |
519 |
if (value instanceof Double) { |
520 |
distance = (Double) value;
|
521 |
} else if (value == null) { |
522 |
distance = (Double) lengthParameter.getDefaultValue();
|
523 |
if(distance == null){ |
524 |
throw new InvalidEntryException(getName(), ERR_INVALID_VALUE, i18n.getTranslation(stateMessages[ERR_INVALID_VALUE])); |
525 |
} |
526 |
} |
527 |
values.put(param, distance); |
528 |
savedDistance = distance; |
529 |
} else if (param == firstSegmentParameter) { |
530 |
if (value instanceof Point) { |
531 |
Point point = (Point) value; |
532 |
|
533 |
Feature firstFeature = getFeatureNearestPoint(point); |
534 |
if (firstFeature == null) { |
535 |
throw new InvalidEntryException(new IllegalArgumentException("Can't find nearest feature.")); |
536 |
} |
537 |
Geometry firstGeometry = firstFeature.getDefaultGeometry(); |
538 |
if (!validateGeometryType(firstGeometry)) {
|
539 |
throw new InvalidEntryException(getName(), ERR_INVALID_GEOMETRY_TYPE, i18n.getTranslation(stateMessages[ERR_INVALID_GEOMETRY_TYPE])); |
540 |
} |
541 |
this.firstSegmentData = new SegmentData(firstFeature, point); |
542 |
if (!this.firstSegmentData.isFilled()) { |
543 |
this.firstSegmentData = null; |
544 |
throw new InvalidEntryException(getName(), ERR_CANT_FIND_NEAREST_GEOMETRY, i18n.getTranslation(stateMessages[ERR_CANT_FIND_NEAREST_GEOMETRY])); |
545 |
} |
546 |
if (firstSegmentData == null) { |
547 |
throw new InvalidEntryException(getName(), ERR_CANT_FIND_NEAREST_GEOMETRY, i18n.getTranslation(stateMessages[ERR_CANT_FIND_NEAREST_GEOMETRY])); |
548 |
} |
549 |
values.put(param, value); |
550 |
previewSymbol = getPreviewSymbol(this.firstSegmentData.getFeature());
|
551 |
} |
552 |
} else if (param == secondSegmentParameter) { |
553 |
if (value instanceof Point) { |
554 |
Point point = (Point) value; |
555 |
Feature secondFeature = getFeatureNearestPoint(point); |
556 |
if (secondFeature == null) { |
557 |
throw new InvalidEntryException(getName(), ERR_CANT_FIND_NEAREST_GEOMETRY, i18n.getTranslation(stateMessages[ERR_CANT_FIND_NEAREST_GEOMETRY])); |
558 |
} |
559 |
SegmentData segmentData = new SegmentData(secondFeature, point);
|
560 |
Pair<Point, Point> oppositeVertices = calculateOpositeToChamferVertices(this.firstSegmentData, segmentData); |
561 |
int errno = validateAsSecondSegmentData(segmentData, oppositeVertices.getRight());
|
562 |
if (errno != ERR_OK) {
|
563 |
this.secondSegmentData = null; |
564 |
this.pointToChamfer = null; |
565 |
throw new InvalidEntryException(getName(), errno, i18n.getTranslation(stateMessages[errno])); |
566 |
} else {
|
567 |
try {
|
568 |
this.secondSegmentData = segmentData;
|
569 |
this.pointToChamfer = calculatePointToChamfer(this.firstSegmentData, this.secondSegmentData); |
570 |
angleParameter.setDefaultValue(calculateDefaultAngle(this.pointToChamfer, oppositeVertices));
|
571 |
values.put(param, value); |
572 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
573 |
throw new InvalidEntryException(getName(), ERR_CANT_CALCULATE_CHAMFER_POINT, i18n.getTranslation(stateMessages[ERR_CANT_FIND_NEAREST_GEOMETRY])); |
574 |
} |
575 |
} |
576 |
} |
577 |
|
578 |
} else if (param == angleParameter) { |
579 |
|
580 |
Double angle = null; |
581 |
if (value instanceof Double) { |
582 |
angle = Math.toRadians((Double)value); |
583 |
} else if (value instanceof Point) { |
584 |
Point point = (Point) value; |
585 |
angle = GeometryUtils.calculateAngle( |
586 |
pointToChamfer, |
587 |
point); |
588 |
} else if (value == null) { |
589 |
angle = Math.toRadians((Double) param.getDefaultValue()); |
590 |
} else {
|
591 |
throw new InvalidEntryException(getName(), ERR_INVALID_VALUE, i18n.getTranslation(stateMessages[ERR_INVALID_VALUE])); |
592 |
} |
593 |
Double distance = (Double) getValue(lengthParameter); |
594 |
Line chamfer = calculateChamfer(firstSegmentData, secondSegmentData, distance, angle, subtype);
|
595 |
if(chamfer == null){ |
596 |
throw new InvalidEntryException(getName(), ERR_CANT_CALCULATE_CHAMFER, i18n.getTranslation(stateMessages[ERR_CANT_FIND_NEAREST_GEOMETRY])); |
597 |
} else {
|
598 |
values.put(param, Math.toDegrees(angle));
|
599 |
} |
600 |
} else if (param == deleteSecondSelectedGeometryParameter) { |
601 |
Boolean v = (Boolean) param.getOptions2().getValue(value, param.getDefaultValue()); |
602 |
values.put(param, v); |
603 |
deleteSecondFeatureDefaultValue = v; |
604 |
} |
605 |
} catch (InvalidEntryException ex) {
|
606 |
throw ex;
|
607 |
} catch (Exception ex) { |
608 |
throw new InvalidEntryException(ex); |
609 |
} |
610 |
|
611 |
} |
612 |
|
613 |
private boolean validateGeometryType(Geometry geometry) throws IllegalArgumentException { |
614 |
List<Integer> validGeometryTypes = new ArrayList(Arrays.asList( |
615 |
Geometry.TYPES.LINE, |
616 |
Geometry.TYPES.POLYGON, |
617 |
Geometry.TYPES.MULTILINE, |
618 |
Geometry.TYPES.MULTIPOLYGON |
619 |
)); |
620 |
|
621 |
return validGeometryTypes.contains(geometry.getType());
|
622 |
} |
623 |
|
624 |
@Override
|
625 |
public Geometry finish() throws FinishServiceException { |
626 |
return null; |
627 |
} |
628 |
|
629 |
@Override
|
630 |
public void finishAndStore() throws FinishServiceException { |
631 |
Line chamfer; // = null; |
632 |
Double distance = (Double) getValue(lengthParameter); |
633 |
Double angle = (Double) getValue(angleParameter); |
634 |
try {
|
635 |
|
636 |
EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices(); |
637 |
int subType = editingProviderServices.getSubType(featureStore);
|
638 |
|
639 |
chamfer = calculateChamfer( |
640 |
this.firstSegmentData,
|
641 |
this.secondSegmentData,
|
642 |
(Double) getValue(lengthParameter),
|
643 |
Math.toRadians((Double) getValue(angleParameter)), |
644 |
subType |
645 |
); |
646 |
if(chamfer == null){ |
647 |
throw new FinishServiceException("Can't calculate chamfer.", null); |
648 |
} |
649 |
|
650 |
Feature firstFeature = firstSegmentData.getFeature(); |
651 |
Feature secondFeature = secondSegmentData.getFeature(); |
652 |
|
653 |
Boolean doDeleteSecondSelectedGeometry = false; |
654 |
if (!Objects.equals(firstFeature.getReference(), secondFeature.getReference())) {
|
655 |
doDeleteSecondSelectedGeometry = (Boolean) values.get(this.deleteSecondSelectedGeometryParameter); |
656 |
} |
657 |
|
658 |
EditableFeature editableFeature = firstFeature.getEditable(); |
659 |
Geometry modifiedGeometry; //= null; //editableFeature.getDefaultGeometry().cloneGeometry();
|
660 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
661 |
Geometry firstGeometry = firstSegmentData.getGeometry(); |
662 |
Primitive firstPrimitive = firstSegmentData.getPrimitive(); |
663 |
Primitive secondPrimitive = secondSegmentData.getPrimitive(); |
664 |
if (Objects.equals(firstFeature.getReference(), secondFeature.getReference())) {
|
665 |
if (firstGeometry instanceof MultiPrimitive) { |
666 |
modifiedGeometry = geomManager.create(firstGeometry.getGeometryType()); |
667 |
MultiPrimitive firstMultiPrimitive = (MultiPrimitive) firstGeometry; |
668 |
if (Objects.equals(firstPrimitive, secondPrimitive)) {
|
669 |
for (Geometry geometry : firstMultiPrimitive) {
|
670 |
Primitive primitive = (Primitive) geometry; |
671 |
if (Objects.equals(firstPrimitive, primitive)) {
|
672 |
Primitive modifiedPrimitive = chamferPrimitive(primitive, chamfer); |
673 |
((MultiPrimitive) modifiedGeometry).addPrimitive(modifiedPrimitive); |
674 |
} else if (Objects.equals(secondPrimitive, primitive)) { |
675 |
//Don't add second primitive
|
676 |
} else {
|
677 |
((MultiPrimitive) modifiedGeometry).addPrimitive(primitive); |
678 |
} |
679 |
} |
680 |
} else {
|
681 |
Primitive modifiedPrimitive = chamferPrimitives(firstPrimitive, secondPrimitive, chamfer); |
682 |
for (Geometry geometry : firstMultiPrimitive) {
|
683 |
Primitive primitive = (Primitive) geometry; |
684 |
if (Objects.equals(firstPrimitive, primitive)) {
|
685 |
((MultiPrimitive) modifiedGeometry).addPrimitive(modifiedPrimitive); |
686 |
} else if (Objects.equals(secondPrimitive, primitive)) { |
687 |
//Don't add second primitive
|
688 |
} else {
|
689 |
((MultiPrimitive) modifiedGeometry).addPrimitive(primitive); |
690 |
} |
691 |
} |
692 |
} |
693 |
} else {
|
694 |
modifiedGeometry = chamferPrimitive((Primitive) editableFeature.getDefaultGeometry(), chamfer); |
695 |
} |
696 |
|
697 |
} else { // Different features |
698 |
|
699 |
doDeleteSecondSelectedGeometry = (Boolean) values.get(this.deleteSecondSelectedGeometryParameter); |
700 |
Primitive modifiedPrimitive = chamferPrimitives(firstPrimitive, secondPrimitive, chamfer); |
701 |
|
702 |
modifiedGeometry = geomManager.create(firstGeometry.getGeometryType()); |
703 |
if (firstGeometry instanceof MultiPrimitive) { |
704 |
MultiPrimitive firstMultiPrimitive = (MultiPrimitive) firstGeometry; |
705 |
for (Geometry geometry : firstMultiPrimitive) {
|
706 |
Primitive primitive = (Primitive) geometry; |
707 |
if (Objects.equals(firstPrimitive, primitive)) {
|
708 |
((MultiPrimitive) modifiedGeometry).addPrimitive(modifiedPrimitive); |
709 |
} else {
|
710 |
((MultiPrimitive) modifiedGeometry).addPrimitive(primitive); |
711 |
} |
712 |
} |
713 |
} else {
|
714 |
modifiedGeometry = modifiedPrimitive; |
715 |
} |
716 |
if (doDeleteSecondSelectedGeometry) {
|
717 |
secondFeature.getStore().delete(secondFeature); |
718 |
} |
719 |
} |
720 |
editableFeature.setDefaultGeometry(modifiedGeometry); |
721 |
((EditingProviderServices) getProviderServices()) |
722 |
.updateFeatureInFeatureStore( |
723 |
editableFeature, featureStore); |
724 |
|
725 |
|
726 |
} catch (Exception e) { |
727 |
throw new FinishServiceException(e); |
728 |
} |
729 |
} |
730 |
|
731 |
private Primitive chamferPrimitive(Primitive primitive, Line chamfer) throws IllegalStateException, GeometryException, GeometryOperationException, GeometryOperationNotSupportedException { |
732 |
Primitive modifiedPrimitive = (Primitive) (primitive.cloneGeometry()); |
733 |
if (primitive instanceof Line || primitive instanceof Polygon) { |
734 |
modifiedPrimitive = (Primitive) (primitive.cloneGeometry()); |
735 |
} else if (primitive instanceof Curve) { |
736 |
modifiedPrimitive = (Line) primitive.toLines().getPrimitiveAt(0); |
737 |
} else if (primitive instanceof Surface) { |
738 |
modifiedPrimitive = (Line) primitive.toPolygons().getPrimitiveAt(0); |
739 |
} |
740 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() - 1)) { |
741 |
if (modifiedPrimitive instanceof Line) { |
742 |
((Line) modifiedPrimitive).removeVertex(firstSegmentData.getIdxVertex() + 1); |
743 |
int i = 1; |
744 |
for (Point point : chamfer) { |
745 |
((Line) modifiedPrimitive).insertVertex(firstSegmentData.getIdxVertex() + i++, point);
|
746 |
} |
747 |
} else if (modifiedPrimitive instanceof Polygon) { |
748 |
((Polygon) modifiedPrimitive).removeVertex(firstSegmentData.getIdxVertex() + 1); |
749 |
int i = 1; |
750 |
for (Point point : chamfer) { |
751 |
((Polygon) modifiedPrimitive).insertVertex(firstSegmentData.getIdxVertex() + i++, point);
|
752 |
} |
753 |
} |
754 |
} else if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() + 1)) { |
755 |
if (modifiedPrimitive instanceof Line) { |
756 |
((Line) modifiedPrimitive).removeVertex(secondSegmentData.getIdxVertex() + 1); |
757 |
Line flipedChamfer = (Line)chamfer.cloneGeometry(); |
758 |
flipedChamfer.flip(); |
759 |
int i = 1; |
760 |
for (Point point : flipedChamfer) { |
761 |
((Line) modifiedPrimitive).insertVertex(secondSegmentData.getIdxVertex() + i++, point);
|
762 |
} |
763 |
} else if (modifiedPrimitive instanceof Polygon) { |
764 |
((Polygon) modifiedPrimitive).removeVertex(secondSegmentData.getIdxVertex() + 1); |
765 |
Line flipedChamfer = (Line)chamfer.cloneGeometry(); |
766 |
flipedChamfer.flip(); |
767 |
int i = 1; |
768 |
for (Point point : flipedChamfer) { |
769 |
((Polygon) modifiedPrimitive).insertVertex(secondSegmentData.getIdxVertex() + i++, point);
|
770 |
} |
771 |
} |
772 |
} else if (Objects.equals(this.firstSegmentData.getPosition(), SEGMENT_POSITION_LAST) && Objects.equals(this.secondSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) { |
773 |
if (modifiedPrimitive instanceof Line) { |
774 |
((Line) modifiedPrimitive).removeVertex(0); |
775 |
((Line) modifiedPrimitive).removeVertex(((Line) modifiedPrimitive).getNumVertices() - 1); |
776 |
for (Point point : chamfer) { |
777 |
((Line) modifiedPrimitive).addVertex(point); //.insertVertex(secondSegmentData.getIdxVertex() + i++, point); |
778 |
} |
779 |
|
780 |
} else if (modifiedPrimitive instanceof Polygon) { |
781 |
((Polygon) modifiedPrimitive).removeVertex(0); |
782 |
((Polygon) modifiedPrimitive).removeVertex(((Polygon) modifiedPrimitive).getNumVertices() - 1); |
783 |
|
784 |
((Polygon) modifiedPrimitive).insertVertex(0, chamfer.getVertex(chamfer.getNumVertices()-1)); |
785 |
for (Point point : chamfer) { |
786 |
((Polygon) modifiedPrimitive).addVertex(point); //.insertVertex(secondSegmentData.getIdxVertex() + i++, point); |
787 |
} |
788 |
|
789 |
} |
790 |
} else if (Objects.equals(this.firstSegmentData.getPosition(), SEGMENT_POSITION_FIRST) && Objects.equals(this.secondSegmentData.getPosition(), SEGMENT_POSITION_LAST)) { |
791 |
Line flipedChamfer = (Line)chamfer.cloneGeometry(); |
792 |
flipedChamfer.flip(); |
793 |
if (modifiedPrimitive instanceof Line) { |
794 |
((Line) modifiedPrimitive).removeVertex(0); |
795 |
((Line) modifiedPrimitive).removeVertex(((Line) modifiedPrimitive).getNumVertices() - 1); |
796 |
|
797 |
int i = 1; |
798 |
for (Point point : flipedChamfer) { |
799 |
((Line) modifiedPrimitive).addVertex(point); //.insertVertex(firstSegmentData.getIdxVertex() + i++, point); |
800 |
} |
801 |
} else if (modifiedPrimitive instanceof Polygon) { |
802 |
((Polygon) modifiedPrimitive).removeVertex(0); |
803 |
((Polygon) modifiedPrimitive).removeVertex(((Polygon) modifiedPrimitive).getNumVertices() - 1); |
804 |
|
805 |
((Polygon) modifiedPrimitive).insertVertex(0, flipedChamfer.getVertex(flipedChamfer.getNumVertices()-1)); |
806 |
for (Point point : flipedChamfer) { |
807 |
((Polygon) modifiedPrimitive).addVertex(point);//.insertVertex(firstSegmentData.getIdxVertex() + i++, point); |
808 |
} |
809 |
} |
810 |
} else {
|
811 |
throw new IllegalStateException("Invalid segments"); |
812 |
} |
813 |
return modifiedPrimitive;
|
814 |
} |
815 |
|
816 |
private Primitive chamferPrimitives(Primitive firstPrimitive, Primitive secondPrimitive, Line chamfer) throws IllegalStateException, GeometryException, GeometryOperationNotSupportedException, GeometryOperationException { |
817 |
//Cannot be polygons
|
818 |
if(firstPrimitive == null){ |
819 |
throw new IllegalArgumentException("firstPrimitive is null"); |
820 |
} |
821 |
Line firstLine;
|
822 |
if (firstPrimitive instanceof Line) { |
823 |
firstLine = (Line) firstPrimitive.cloneGeometry();
|
824 |
} else {
|
825 |
MultiLine lines = firstPrimitive.toLines(); |
826 |
if(lines==null){ |
827 |
throw new IllegalArgumentException("Can't find first primitive."); |
828 |
} |
829 |
firstLine = (Line) lines.getPrimitiveAt(0); |
830 |
} |
831 |
if(secondPrimitive == null){ |
832 |
throw new IllegalArgumentException("secondPrimitive is null"); |
833 |
} |
834 |
Line secondLine;
|
835 |
if (secondPrimitive instanceof Line) { |
836 |
secondLine = (Line) secondPrimitive;
|
837 |
} else {
|
838 |
MultiLine lines = secondPrimitive.toLines(); |
839 |
if(lines==null){ |
840 |
throw new IllegalArgumentException("Can't find second primitive."); |
841 |
} |
842 |
secondLine = (Line) lines.getPrimitiveAt(0); |
843 |
} |
844 |
|
845 |
Line modifiedPrimitive = firstLine;
|
846 |
if (Objects.equals(this.firstSegmentData.getPosition(), SEGMENT_POSITION_LAST)) { |
847 |
modifiedPrimitive.removeVertex(modifiedPrimitive.getNumVertices() - 1);
|
848 |
for (Point point : chamfer) { |
849 |
modifiedPrimitive.addVertex(point); |
850 |
} |
851 |
|
852 |
if (Objects.equals(this.secondSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) { |
853 |
for (int i = 0; i < secondLine.getNumVertices(); i++) { |
854 |
if (i != 0) { |
855 |
((Line) modifiedPrimitive).addVertex(secondLine.getVertex(i));
|
856 |
} |
857 |
} |
858 |
} else { //LAST |
859 |
for (int i = secondLine.getNumVertices() - 1; i >= 0; i--) { |
860 |
if (i != secondLine.getNumVertices() - 1) { |
861 |
((Line) modifiedPrimitive).addVertex(secondLine.getVertex(i));
|
862 |
} |
863 |
} |
864 |
} |
865 |
} else {
|
866 |
modifiedPrimitive.removeVertex(0);
|
867 |
for (Point point : chamfer) { |
868 |
modifiedPrimitive.insertVertex(0, point);
|
869 |
} |
870 |
|
871 |
if (Objects.equals(this.secondSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) { |
872 |
for (int i = 0; i < secondLine.getNumVertices(); i++) { |
873 |
if (i != 0) { |
874 |
((Line) modifiedPrimitive).insertVertex(0, secondLine.getVertex(i)); |
875 |
} |
876 |
} |
877 |
} else { //LAST |
878 |
for (int i = secondLine.getNumVertices() - 1; i >= 0; i--) { |
879 |
if (i != secondLine.getNumVertices() - 1) { |
880 |
((Line) modifiedPrimitive).insertVertex(0, secondLine.getVertex(i)); |
881 |
} |
882 |
} |
883 |
} |
884 |
} |
885 |
return modifiedPrimitive;
|
886 |
} |
887 |
|
888 |
private Pair<Point, Point> calculateOpositeToChamferVertices(SegmentData firstSegmentData, SegmentData secondSegmentData) throws GeometryOperationNotSupportedException, GeometryOperationException { |
889 |
Point firstVertex;
|
890 |
Point secondVertex;
|
891 |
if (Objects.equals(firstSegmentData.getPrimitive(), secondSegmentData.getPrimitive())) {
|
892 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() - 1)) { |
893 |
firstVertex = firstSegmentData.getLine().getVertex(0);
|
894 |
secondVertex = secondSegmentData.getLine().getVertex(1);
|
895 |
} else if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() + 1)) { |
896 |
firstVertex = firstSegmentData.getLine().getVertex(1);
|
897 |
secondVertex = secondSegmentData.getLine().getVertex(0);
|
898 |
} else {
|
899 |
if (Objects.equals(firstSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) {
|
900 |
firstVertex = firstSegmentData.getLine().getVertex(1);
|
901 |
} else { //SEGMENT_POSITION_LAST |
902 |
firstVertex = firstSegmentData.getLine().getVertex(0);
|
903 |
} |
904 |
|
905 |
if (Objects.equals(secondSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) {
|
906 |
secondVertex = secondSegmentData.getLine().getVertex(1);
|
907 |
} else { //SEGMENT_POSITION_LAST |
908 |
secondVertex = secondSegmentData.getLine().getVertex(0);
|
909 |
} |
910 |
} |
911 |
} else {
|
912 |
if (Objects.equals(firstSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) {
|
913 |
firstVertex = firstSegmentData.getLine().getVertex(1);
|
914 |
} else {
|
915 |
firstVertex = firstSegmentData.getLine().getVertex(0);
|
916 |
} |
917 |
|
918 |
if (Objects.equals(secondSegmentData.getPosition(), SEGMENT_POSITION_FIRST)) {
|
919 |
secondVertex = secondSegmentData.getLine().getVertex(1);
|
920 |
} else {
|
921 |
secondVertex = secondSegmentData.getLine().getVertex(0);
|
922 |
} |
923 |
} |
924 |
return new ImmutablePair<>(firstVertex, secondVertex); |
925 |
} |
926 |
|
927 |
@Override
|
928 |
public void start() throws StartServiceException { |
929 |
this.values.clear();
|
930 |
this.firstSegmentData = null; |
931 |
this.secondSegmentData = null; |
932 |
this.pointToChamfer = null; |
933 |
|
934 |
if (savedDistance != null) { |
935 |
this.lengthParameter.setDefaultValue(savedDistance);
|
936 |
} |
937 |
} |
938 |
|
939 |
@Override
|
940 |
public void restart() throws StartServiceException, InvalidEntryException, StopServiceException { |
941 |
this.values.clear();
|
942 |
this.firstSegmentData = null; |
943 |
this.secondSegmentData = null; |
944 |
this.pointToChamfer = null; |
945 |
|
946 |
if (savedDistance != null) { |
947 |
this.lengthParameter.setDefaultValue(savedDistance);
|
948 |
} |
949 |
|
950 |
} |
951 |
|
952 |
@Override
|
953 |
public void initDefaultValues() { |
954 |
super.initDefaultValues();
|
955 |
if (deleteSecondFeatureDefaultValue != null) { |
956 |
this.deleteSecondSelectedGeometryParameter.setDefaultValue(deleteSecondFeatureDefaultValue);
|
957 |
} |
958 |
} |
959 |
|
960 |
|
961 |
|
962 |
@Override
|
963 |
public void stop() throws StopServiceException { |
964 |
this.values.clear();
|
965 |
this.firstSegmentData = null; |
966 |
this.secondSegmentData = null; |
967 |
this.pointToChamfer = null; |
968 |
} |
969 |
|
970 |
@Override
|
971 |
public Object getValue(EditingServiceParameter parameter) { |
972 |
return values != null ? values.get(parameter) : null; |
973 |
} |
974 |
|
975 |
private Feature getFeatureNearestPoint(Point point) { |
976 |
EditingProviderServices editingProviderServices = (EditingProviderServices) getProviderServices(); |
977 |
Feature feature = editingProviderServices.getFeature(point, featureStore, mapContext); |
978 |
return feature;
|
979 |
} |
980 |
|
981 |
private int validateAsSecondSegmentData(SegmentData segmentData, Point oppositeVertex) throws GeometryOperationNotSupportedException, GeometryOperationException { |
982 |
|
983 |
if (!segmentData.isFilled()) {
|
984 |
return ERR_SEGMENT_DATA_NOT_FILLED;
|
985 |
} |
986 |
if (this.firstSegmentData == null) { |
987 |
return ERR_FIRST_SEGMENT_DATA_NULL;
|
988 |
} |
989 |
Primitive firstPrimitive = this.firstSegmentData.getPrimitive();
|
990 |
Primitive secondPrimitive = segmentData.getPrimitive(); |
991 |
if (Objects.equals(firstPrimitive, secondPrimitive)) {
|
992 |
if (Objects.equals(this.firstSegmentData.getIdxVertex(), segmentData.getIdxVertex())) { |
993 |
return ERR_SAME_SEGMENT;
|
994 |
} |
995 |
if (Math.abs(this.firstSegmentData.getIdxVertex() - segmentData.getIdxVertex()) <= 1) { |
996 |
return validateSegmentsAndLength(firstSegmentData, segmentData, calculatePointToChamfer(firstSegmentData, segmentData));
|
997 |
} |
998 |
switch (firstPrimitive.getType()) {
|
999 |
case Geometry.TYPES.LINE:
|
1000 |
if (((Line) firstPrimitive).isClosed()) { |
1001 |
if ((this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) && segmentData.getPosition().equals(SEGMENT_POSITION_LAST) |
1002 |
|| this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) && segmentData.getPosition().equals(SEGMENT_POSITION_FIRST))) {
|
1003 |
return validateSegmentsAndLength(firstSegmentData, segmentData, calculatePointToChamfer(firstSegmentData, segmentData));
|
1004 |
} |
1005 |
|
1006 |
} else {
|
1007 |
if ((this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) || this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST)) |
1008 |
&& (segmentData.getPosition().equals(SEGMENT_POSITION_FIRST) || segmentData.getPosition().equals(SEGMENT_POSITION_LAST))) { |
1009 |
Point tmpPointToChamfer = calculatePointToChamfer(firstSegmentData, segmentData);
|
1010 |
if (tmpPointToChamfer == null |
1011 |
|| calculateZoneInSegment(tmpPointToChamfer, segmentData) == INVALID_ZONE |
1012 |
|| calculateZoneInSegment(tmpPointToChamfer, firstSegmentData) == INVALID_ZONE) { |
1013 |
return ERR_CANT_CALCULATE_CHAMFER_POINT;
|
1014 |
} |
1015 |
if (!isPointBetweenTwoPoints(segmentData.getProjectedPoint(), oppositeVertex, tmpPointToChamfer)) {
|
1016 |
return ERR_CANT_CALCULATE_CHAMFER_POINT;
|
1017 |
} |
1018 |
return validateSegmentsAndLength(firstSegmentData, segmentData, calculatePointToChamfer(firstSegmentData, segmentData));
|
1019 |
} |
1020 |
} |
1021 |
return ERR_NON_ADJACENT_SEGMENTS;
|
1022 |
|
1023 |
case Geometry.TYPES.POLYGON:
|
1024 |
if (this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) && segmentData.getPosition().equals(SEGMENT_POSITION_LAST) |
1025 |
|| this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) && segmentData.getPosition().equals(SEGMENT_POSITION_FIRST)) {
|
1026 |
return validateSegmentsAndLength(firstSegmentData, segmentData, calculatePointToChamfer(firstSegmentData, segmentData));
|
1027 |
} |
1028 |
return ERR_NON_ADJACENT_SEGMENTS;
|
1029 |
default:
|
1030 |
return ERR_NON_ADJACENT_SEGMENTS;
|
1031 |
} |
1032 |
} else {
|
1033 |
if (firstPrimitive.getType() != Geometry.TYPES.LINE
|
1034 |
|| secondPrimitive.getType() != Geometry.TYPES.LINE) { |
1035 |
return ERR_DIFFERENT_GEOMETRY_TYPES;
|
1036 |
} |
1037 |
if (this.firstSegmentData.getPosition().equals(SEGMENT_POSITION_MIDDLE) |
1038 |
|| segmentData.getPosition().equals(SEGMENT_POSITION_MIDDLE)) { |
1039 |
return ERR_ONE_OF_THE_TWO_SEGMENTS_ISNT_EXTREME;
|
1040 |
} |
1041 |
Point tmpPointToChamfer = calculatePointToChamfer(firstSegmentData, segmentData);
|
1042 |
if (tmpPointToChamfer == null || !isPointBetweenTwoPoints(segmentData.getProjectedPoint(), oppositeVertex, tmpPointToChamfer)) { |
1043 |
return ERR_CANT_CALCULATE_CHAMFER_POINT;
|
1044 |
} |
1045 |
return validateSegmentsAndLength(firstSegmentData, segmentData, tmpPointToChamfer);
|
1046 |
} |
1047 |
} |
1048 |
|
1049 |
private int validateSegmentsAndLength(SegmentData firstSegmentData, SegmentData secondSegmentData, Point pointToChamfer) throws GeometryOperationNotSupportedException, GeometryOperationException { |
1050 |
Pair<Point, Point> oppositeVertices = calculateOpositeToChamferVertices(firstSegmentData, secondSegmentData); |
1051 |
Double length = (Double) getValue(lengthParameter); |
1052 |
double maxLength = Math.max( |
1053 |
oppositeVertices.getLeft().distance(pointToChamfer), |
1054 |
Math.max(
|
1055 |
oppositeVertices.getRight().distance(pointToChamfer), |
1056 |
oppositeVertices.getRight().distance(oppositeVertices.getLeft()) |
1057 |
) |
1058 |
); |
1059 |
if (length > maxLength) {
|
1060 |
return ERR_CHAMFER_TOO_LARGE;
|
1061 |
} |
1062 |
return ERR_OK;
|
1063 |
} |
1064 |
|
1065 |
private Point calculatePointToChamfer(SegmentData firstSegmentData, SegmentData secondSegmentData) throws GeometryOperationNotSupportedException, GeometryOperationException { |
1066 |
Primitive firstPrimitive = firstSegmentData.getPrimitive(); |
1067 |
Primitive secondPrimitive = secondSegmentData.getPrimitive(); |
1068 |
if (Objects.equals(firstPrimitive, secondPrimitive)) {
|
1069 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex())) {
|
1070 |
return null; |
1071 |
} |
1072 |
switch (firstPrimitive.getType()) {
|
1073 |
case Geometry.TYPES.LINE:
|
1074 |
if (((Line) firstPrimitive).isClosed()) { |
1075 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() - 1)) { |
1076 |
return firstSegmentData.getLine().getVertex(1); |
1077 |
} else if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() + 1)) { |
1078 |
return firstSegmentData.getLine().getVertex(0); |
1079 |
} else if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_LAST)) { |
1080 |
return firstSegmentData.getLine().getVertex(0); |
1081 |
} else if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST)) { |
1082 |
return firstSegmentData.getLine().getVertex(1); |
1083 |
} else {
|
1084 |
return null; |
1085 |
} |
1086 |
} else {
|
1087 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() - 1)) { |
1088 |
return firstSegmentData.getLine().getVertex(1); |
1089 |
} else if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() + 1)) { |
1090 |
return firstSegmentData.getLine().getVertex(0); |
1091 |
} else if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) |
1092 |
|| firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST)) { |
1093 |
return calculatePointToChamferSeparateSegments(firstSegmentData, secondSegmentData);
|
1094 |
} else {
|
1095 |
return null; |
1096 |
} |
1097 |
} |
1098 |
case Geometry.TYPES.POLYGON:
|
1099 |
if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() - 1)) { |
1100 |
return firstSegmentData.getLine().getVertex(1); |
1101 |
} else if (Objects.equals(firstSegmentData.getIdxVertex(), secondSegmentData.getIdxVertex() + 1)) { |
1102 |
return firstSegmentData.getLine().getVertex(0); |
1103 |
} else if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_LAST)) { |
1104 |
return firstSegmentData.getLine().getVertex(0); |
1105 |
} else if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST) && secondSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST)) { |
1106 |
return firstSegmentData.getLine().getVertex(1); |
1107 |
} else {
|
1108 |
return null; |
1109 |
} |
1110 |
default:
|
1111 |
return null; |
1112 |
} |
1113 |
} else {
|
1114 |
if (firstPrimitive.getType() != Geometry.TYPES.LINE) {
|
1115 |
return null; |
1116 |
} |
1117 |
if (secondPrimitive.getType() != Geometry.TYPES.LINE) {
|
1118 |
return null; |
1119 |
} |
1120 |
|
1121 |
if ((firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) || firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST))
|
1122 |
&& (secondSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST) || secondSegmentData.getPosition().equals(SEGMENT_POSITION_LAST))) { |
1123 |
return calculatePointToChamferSeparateSegments(firstSegmentData, secondSegmentData);
|
1124 |
} else {
|
1125 |
return null; |
1126 |
} |
1127 |
} |
1128 |
} |
1129 |
|
1130 |
private Point calculatePointToChamferSeparateSegments(SegmentData firstSegmentData, SegmentData secondSegmentData) throws GeometryOperationNotSupportedException, GeometryOperationException { |
1131 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
1132 |
EuclideanLine2D firstLine = euclideanManager.createLine2D( |
1133 |
firstSegmentData.getLine().getVertex(0).getX(),
|
1134 |
firstSegmentData.getLine().getVertex(0).getY(),
|
1135 |
firstSegmentData.getLine().getVertex(1).getX(),
|
1136 |
firstSegmentData.getLine().getVertex(1).getY());
|
1137 |
EuclideanLine2D secondLine = euclideanManager.createLine2D( |
1138 |
secondSegmentData.getLine().getVertex(0).getX(),
|
1139 |
secondSegmentData.getLine().getVertex(0).getY(),
|
1140 |
secondSegmentData.getLine().getVertex(1).getX(),
|
1141 |
secondSegmentData.getLine().getVertex(1).getY());
|
1142 |
Point2D intersection = firstLine.getIntersection(secondLine);
|
1143 |
Point intersectionPoint = GeometryUtils.createPoint(intersection.getX(), intersection.getY());
|
1144 |
if (intersectionPoint == null) { |
1145 |
return null; //throw new IllegalArgumentException("Not valid segments."); |
1146 |
} |
1147 |
if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_LAST)
|
1148 |
&& calculateZoneInSegment(intersectionPoint, firstSegmentData) == INVALID_ZONE) { |
1149 |
return null; |
1150 |
} |
1151 |
if (firstSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST)
|
1152 |
&& calculateZoneInSegment(intersectionPoint, firstSegmentData) == INVALID_ZONE) { |
1153 |
return null; |
1154 |
} |
1155 |
if (secondSegmentData.getPosition().equals(SEGMENT_POSITION_LAST)
|
1156 |
&& calculateZoneInSegment(intersectionPoint, firstSegmentData) == INVALID_ZONE) { |
1157 |
return null; |
1158 |
} |
1159 |
if (secondSegmentData.getPosition().equals(SEGMENT_POSITION_FIRST)
|
1160 |
&& calculateZoneInSegment(intersectionPoint, firstSegmentData) == INVALID_ZONE) { |
1161 |
return null; |
1162 |
} |
1163 |
return intersectionPoint;
|
1164 |
} |
1165 |
|
1166 |
private int calculateZoneInSegment(Point point, SegmentData segmentData) throws GeometryOperationNotSupportedException, GeometryOperationException { |
1167 |
//We assume that the point is on the line to which the segment belongs.
|
1168 |
Line line = segmentData.getLine();
|
1169 |
if (line.getNumVertices() > 2) { |
1170 |
throw new IllegalArgumentException("Segment has more than two vertex."); |
1171 |
} |
1172 |
|
1173 |
Point firstVertex;
|
1174 |
Point secondVertex;
|
1175 |
|
1176 |
if (Objects.equals(segmentData.getPosition(), SEGMENT_POSITION_LAST)) {
|
1177 |
firstVertex = line.getVertex(0);
|
1178 |
secondVertex = line.getVertex(1);
|
1179 |
} else { // SEGMENT_POSITION_FIRST, SEGMENT_POSITION_MIDDLE doesn't matter |
1180 |
firstVertex = line.getVertex(1);
|
1181 |
secondVertex = line.getVertex(0);
|
1182 |
} |
1183 |
|
1184 |
double segmentLenght = firstVertex.distance(secondVertex);
|
1185 |
if (segmentLenght >= firstVertex.distance(point) && segmentLenght >= secondVertex.distance(point)) {
|
1186 |
return INSIDE_THE_SEGMENT; //0 |
1187 |
} else if (firstVertex.distance(point) > secondVertex.distance(point)) { |
1188 |
return BEYOND_THE_SEGMENT; //1 |
1189 |
} else {
|
1190 |
return INVALID_ZONE; //-1 |
1191 |
} |
1192 |
} |
1193 |
|
1194 |
private boolean isPointBetweenTwoPoints(Point point, Point vertex1, Point vertex2) { |
1195 |
//The three points must be aligned
|
1196 |
if (point.getX() < vertex1.getX() && point.getX() < vertex2.getX()) {
|
1197 |
return false; |
1198 |
} |
1199 |
if (point.getX() > vertex1.getX() && point.getX() > vertex2.getX()) {
|
1200 |
return false; |
1201 |
} |
1202 |
if (point.getY() < vertex1.getY() && point.getY() < vertex2.getY()) {
|
1203 |
return false; |
1204 |
} |
1205 |
if (point.getY() > vertex1.getY() && point.getY() > vertex2.getY()) {
|
1206 |
return false; |
1207 |
} |
1208 |
return true; |
1209 |
} |
1210 |
|
1211 |
private double calculateDefaultAngle(Point pointToChamfer, Pair<Point, Point> oppositeVertices) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException { |
1212 |
|
1213 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
1214 |
Point2D p = euclideanManager.getPointAtDistance(
|
1215 |
pointToChamfer.getX(), |
1216 |
pointToChamfer.getY(), |
1217 |
pointToChamfer.distance(oppositeVertices.getLeft()), |
1218 |
GeometryUtils.calculateAngle(pointToChamfer, oppositeVertices.getRight()), |
1219 |
null
|
1220 |
); |
1221 |
|
1222 |
Point midPoint = GeometryUtils.getMidPoint(
|
1223 |
oppositeVertices.getLeft(), |
1224 |
GeometryUtils.createPoint(p.getX(), p.getY()), |
1225 |
pointToChamfer.getGeometryType().getSubType() |
1226 |
); |
1227 |
double angle = GeometryUtils.calculateAngle(
|
1228 |
pointToChamfer, |
1229 |
midPoint |
1230 |
); |
1231 |
angle = angle + Math.PI/2; |
1232 |
if(angle > 2*Math.PI){ |
1233 |
angle = angle - 2*Math.PI; |
1234 |
} |
1235 |
return Math.toDegrees(angle); |
1236 |
} |
1237 |
|
1238 |
private Line calculateChamfer(SegmentData firstSegmentData, SegmentData secondSegmentData, Double length, Double angle, int subType) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException { |
1239 |
|
1240 |
ScaffoldingToChamfer scaffolding = calculateScaffolding(firstSegmentData, secondSegmentData, pointToChamfer, length, angle, subType); |
1241 |
if(scaffolding == null){ |
1242 |
return null; |
1243 |
} |
1244 |
Line chamfer;
|
1245 |
if(scaffolding.isReversed()) {
|
1246 |
chamfer = GeometryUtils.createLine( |
1247 |
scaffolding.chamferRight.getX(), |
1248 |
scaffolding.chamferRight.getY(), |
1249 |
scaffolding.chamferLeft.getX(), |
1250 |
scaffolding.chamferLeft.getY(), |
1251 |
subType |
1252 |
); |
1253 |
} else {
|
1254 |
chamfer = GeometryUtils.createLine( |
1255 |
scaffolding.chamferLeft.getX(), |
1256 |
scaffolding.chamferLeft.getY(), |
1257 |
scaffolding.chamferRight.getX(), |
1258 |
scaffolding.chamferRight.getY(), |
1259 |
subType |
1260 |
); |
1261 |
} |
1262 |
|
1263 |
return chamfer;
|
1264 |
} |
1265 |
|
1266 |
/**
|
1267 |
*
|
1268 |
* @param firstSegmentData
|
1269 |
* @param secondSegmentData
|
1270 |
* @param pointToChamfer
|
1271 |
* @param distance
|
1272 |
* @param angle must be in radians
|
1273 |
* @param subType
|
1274 |
* @return
|
1275 |
*/
|
1276 |
private ScaffoldingToChamfer calculateScaffolding(SegmentData firstSegmentData, SegmentData secondSegmentData, Point pointToChamfer, Double length, Double angle, int subType) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException { |
1277 |
|
1278 |
Pair<Point, Point> oppositeVertices = calculateOpositeToChamferVertices(firstSegmentData, secondSegmentData); |
1279 |
Point p1 = GeometryUtils.createPoint(pointToChamfer, length, angle);
|
1280 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
1281 |
|
1282 |
boolean reverse = false; |
1283 |
|
1284 |
EuclideanLine2D base = euclideanManager.createLine2D( |
1285 |
pointToChamfer.getX(), |
1286 |
pointToChamfer.getY(), |
1287 |
p1.getX(), |
1288 |
p1.getY() |
1289 |
); |
1290 |
|
1291 |
Point o1 = oppositeVertices.getLeft();
|
1292 |
Point o2 = oppositeVertices.getRight();
|
1293 |
|
1294 |
EuclideanLine2D left = euclideanManager.createLine2D( |
1295 |
pointToChamfer.getX(), |
1296 |
pointToChamfer.getY(), |
1297 |
o1.getX(), |
1298 |
o1.getY() |
1299 |
); |
1300 |
EuclideanLine2D leftParallel = left.getParallel(p1.getX(), p1.getY()); |
1301 |
|
1302 |
EuclideanLine2D right = euclideanManager.createLine2D( |
1303 |
pointToChamfer.getX(), |
1304 |
pointToChamfer.getY(), |
1305 |
o2.getX(), |
1306 |
o2.getY() |
1307 |
); |
1308 |
|
1309 |
Point2D chamferRight = leftParallel.getIntersection(right);
|
1310 |
|
1311 |
if (!isPointBetweenTwoPoints(
|
1312 |
GeometryUtils.createPoint(chamferRight.getX(), chamferRight.getY()), |
1313 |
o2, |
1314 |
pointToChamfer)) { //Le damos la vuelta a los vertices opuestos y volvemos probar
|
1315 |
reverse = true;
|
1316 |
o1 = oppositeVertices.getRight(); |
1317 |
o2 = oppositeVertices.getLeft(); |
1318 |
|
1319 |
left = euclideanManager.createLine2D( |
1320 |
pointToChamfer.getX(), |
1321 |
pointToChamfer.getY(), |
1322 |
o1.getX(), |
1323 |
o1.getY() |
1324 |
); |
1325 |
leftParallel = left.getParallel(p1.getX(), p1.getY()); |
1326 |
|
1327 |
right = euclideanManager.createLine2D( |
1328 |
pointToChamfer.getX(), |
1329 |
pointToChamfer.getY(), |
1330 |
o2.getX(), |
1331 |
o2.getY() |
1332 |
); |
1333 |
|
1334 |
chamferRight = leftParallel.getIntersection(right); |
1335 |
|
1336 |
if (!isPointBetweenTwoPoints(
|
1337 |
GeometryUtils.createPoint(chamferRight.getX(), chamferRight.getY()), |
1338 |
o2, |
1339 |
pointToChamfer)) { |
1340 |
return null; |
1341 |
} |
1342 |
} |
1343 |
|
1344 |
|
1345 |
EuclideanLine2D baseParallel = base.getParallel(chamferRight); |
1346 |
|
1347 |
Point2D chamferLeft = baseParallel.getIntersection(left);
|
1348 |
|
1349 |
if (!isPointBetweenTwoPoints(
|
1350 |
GeometryUtils.createPoint(chamferLeft.getX(), chamferLeft.getY()), |
1351 |
o1, |
1352 |
pointToChamfer) |
1353 |
) { |
1354 |
return null; |
1355 |
} |
1356 |
|
1357 |
ScaffoldingToChamfer scaffolding; |
1358 |
scaffolding = new ScaffoldingToChamfer(chamferLeft, chamferRight, p1, reverse);
|
1359 |
|
1360 |
return scaffolding;
|
1361 |
} |
1362 |
|
1363 |
private class ScaffoldingToChamfer { |
1364 |
|
1365 |
private final Point2D chamferLeft; |
1366 |
private final Point2D chamferRight; |
1367 |
private final Point p1; |
1368 |
private final boolean reverse; |
1369 |
|
1370 |
public ScaffoldingToChamfer(Point2D chamferLeft, Point2D chamferRight, Point p1, boolean reverse) { |
1371 |
this.chamferLeft = chamferLeft;
|
1372 |
this.chamferRight = chamferRight;
|
1373 |
this.p1 = p1;
|
1374 |
this.reverse = reverse;
|
1375 |
} |
1376 |
|
1377 |
|
1378 |
public Point2D getChamferRight() { |
1379 |
return chamferRight;
|
1380 |
} |
1381 |
|
1382 |
public Point2D getChamferLeft() { |
1383 |
return chamferLeft;
|
1384 |
} |
1385 |
|
1386 |
public Point getP1() { |
1387 |
return p1;
|
1388 |
} |
1389 |
|
1390 |
public boolean isReversed() { |
1391 |
return reverse;
|
1392 |
} |
1393 |
|
1394 |
|
1395 |
} |
1396 |
} |