gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.arc / src / main / java / org / gvsig / vectorediting / lib / prov / arc / ArcByCenterEditingProvider.java @ 4253
History | View | Annotate | Download (40.6 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.arc; |
25 |
|
26 |
import java.awt.geom.Point2D; |
27 |
import java.util.ArrayList; |
28 |
import java.util.HashMap; |
29 |
import java.util.List; |
30 |
import java.util.Map; |
31 |
import org.gvsig.euclidean.EuclideanLine2D; |
32 |
import org.gvsig.euclidean.EuclideanManager; |
33 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
34 |
import org.gvsig.fmap.geom.Geometry; |
35 |
import org.gvsig.fmap.geom.GeometryLocator; |
36 |
import org.gvsig.fmap.geom.GeometryUtils; |
37 |
import org.gvsig.fmap.geom.aggregate.MultiCurve; |
38 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
39 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
40 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
41 |
import org.gvsig.fmap.geom.primitive.Arc; |
42 |
import org.gvsig.fmap.geom.primitive.Curve; |
43 |
import org.gvsig.fmap.geom.primitive.Line; |
44 |
import org.gvsig.fmap.geom.primitive.Point; |
45 |
import org.gvsig.fmap.geom.type.GeometryType; |
46 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol; |
47 |
import org.gvsig.tools.ToolsLocator; |
48 |
import org.gvsig.tools.dataTypes.CoercionException; |
49 |
import org.gvsig.tools.dataTypes.DataTypes; |
50 |
import org.gvsig.tools.dataTypes.impl.coercion.CoerceToDouble; |
51 |
import org.gvsig.tools.dynobject.DynObject; |
52 |
import org.gvsig.tools.i18n.I18nManager; |
53 |
import org.gvsig.tools.service.spi.ProviderServices; |
54 |
import org.gvsig.tools.util.ToolsUtilLocator; |
55 |
import org.gvsig.vectorediting.lib.api.DrawingStatus; |
56 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter; |
57 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE; |
58 |
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException; |
59 |
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException; |
60 |
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException; |
61 |
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException; |
62 |
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException; |
63 |
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider; |
64 |
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus; |
65 |
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter; |
66 |
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameterOptions; |
67 |
import org.gvsig.vectorediting.lib.spi.EditingProvider; |
68 |
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory; |
69 |
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator; |
70 |
import org.gvsig.vectorediting.lib.spi.EditingProviderManager; |
71 |
import org.gvsig.vectorediting.lib.spi.EditingProviderServices; |
72 |
import org.slf4j.Logger; |
73 |
import org.slf4j.LoggerFactory; |
74 |
|
75 |
/**
|
76 |
* @author fdiaz
|
77 |
*
|
78 |
*/
|
79 |
public class ArcByCenterEditingProvider extends AbstractEditingProvider implements |
80 |
EditingProvider { |
81 |
|
82 |
private static final String CCW = "CCW"; // counterclockwise |
83 |
private static final String CW = "CW"; // clockwise |
84 |
|
85 |
private static final Logger LOGGER = LoggerFactory.getLogger(ArcByCenterEditingProvider.class); |
86 |
|
87 |
//Optionals
|
88 |
private final EditingServiceParameter radius; |
89 |
private final EditingServiceParameter startAngle; |
90 |
private final EditingServiceParameter sweepAngle; |
91 |
private final EditingServiceParameter direction; |
92 |
|
93 |
private final EditingServiceParameter centerPoint; |
94 |
|
95 |
private final EditingServiceParameter startPoint; |
96 |
|
97 |
private final EditingServiceParameter endPoint; |
98 |
|
99 |
private Map<EditingServiceParameter, Object> values; |
100 |
|
101 |
private final FeatureStore featureStore; |
102 |
|
103 |
/**
|
104 |
* Default constructor.
|
105 |
*
|
106 |
* @param providerServices available services for this provider
|
107 |
* @param parameters of this provider
|
108 |
*/
|
109 |
public ArcByCenterEditingProvider(ProviderServices providerServices,
|
110 |
DynObject parameters) { |
111 |
super(providerServices);
|
112 |
|
113 |
this.featureStore
|
114 |
= (FeatureStore) parameters |
115 |
.getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD); |
116 |
|
117 |
this.centerPoint
|
118 |
= new DefaultEditingServiceParameter("center_point", "center_point", |
119 |
TYPE.POSITION); |
120 |
|
121 |
this.startPoint
|
122 |
= new DefaultEditingServiceParameter("start_point", "start_point", |
123 |
TYPE.POSITION); |
124 |
|
125 |
this.endPoint
|
126 |
= new DefaultEditingServiceParameter("end_point", "end_point", |
127 |
TYPE.POSITION); |
128 |
|
129 |
this.radius
|
130 |
= new DefaultEditingServiceParameter("radius", "radius", true, |
131 |
TYPE.VALUE); |
132 |
|
133 |
this.startAngle
|
134 |
= new DefaultEditingServiceParameter("start_angle", "start_angle", true, |
135 |
TYPE.VALUE); |
136 |
|
137 |
this.sweepAngle
|
138 |
= new DefaultEditingServiceParameter("sweep_angle", "sweep_angle", true, |
139 |
TYPE.VALUE); |
140 |
|
141 |
I18nManager i18nManager = ToolsLocator.getI18nManager(); |
142 |
|
143 |
EditingProviderServices editingProviderServices |
144 |
= (EditingProviderServices) getProviderServices(); |
145 |
|
146 |
DefaultEditingServiceParameterOptions directionOptions = new DefaultEditingServiceParameterOptions()
|
147 |
.add(CCW, CCW, CCW) |
148 |
.add(CW, CW, CW); |
149 |
|
150 |
String consoleMsg
|
151 |
= editingProviderServices.makeConsoleMessage( |
152 |
"_Direction", directionOptions);
|
153 |
|
154 |
// CCW should be the default value, but I don't assign it as such
|
155 |
// to detect whether the user has selected a value or not.
|
156 |
this.direction
|
157 |
= new DefaultEditingServiceParameter(
|
158 |
i18nManager.getTranslation("_Direction"),
|
159 |
consoleMsg, |
160 |
directionOptions, |
161 |
null,
|
162 |
true,
|
163 |
TYPE.OPTION).setDataType(DataTypes.STRING); |
164 |
|
165 |
|
166 |
} |
167 |
|
168 |
@Override
|
169 |
public EditingServiceParameter next() {
|
170 |
if (values.get(centerPoint) == null) { |
171 |
return this.centerPoint; |
172 |
} else if (values.get(startPoint) == null && (values.get(radius) == null || values.get(startAngle) == null)) { |
173 |
return this.startPoint; |
174 |
} else if (values.get(endPoint) == null ) { |
175 |
return this.endPoint; |
176 |
} |
177 |
return null; |
178 |
} |
179 |
|
180 |
@Override
|
181 |
public DrawingStatus getDrawingStatus(Point mousePosition) |
182 |
throws DrawServiceException {
|
183 |
|
184 |
Point centerPointValue = (Point) values.get(centerPoint); |
185 |
Point startPointValue = (Point) values.get(startPoint); |
186 |
Point endPointValue = (Point) values.get(endPoint); |
187 |
|
188 |
Double radiusValue = (Double) values.get(radius); |
189 |
Double startAngleValue = (Double) values.get(startAngle); |
190 |
Double sweepAngleValue = (Double) values.get(sweepAngle); |
191 |
String directionValue = (String) values.get(direction); |
192 |
|
193 |
|
194 |
DefaultDrawingStatus geometries = new DefaultDrawingStatus();
|
195 |
|
196 |
ISymbol previewSymbol = this.getPreviewSymbol();
|
197 |
geometries.setPreviewSymbol(previewSymbol); |
198 |
|
199 |
EditingProviderManager editingProviderManager |
200 |
= EditingProviderLocator.getProviderManager(); |
201 |
ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
|
202 |
ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
|
203 |
ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
|
204 |
|
205 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
206 |
|
207 |
if (values != null) { |
208 |
if(centerPointValue == null) { |
209 |
if (radiusValue != null && startAngleValue != null) { |
210 |
try {
|
211 |
startPointValue = GeometryUtils.createPoint(mousePosition, radiusValue, startAngleValue); |
212 |
geometries.addStatus(startPointValue, auxiliaryPointSymbolEditing, "");
|
213 |
|
214 |
Line auxLine = GeometryUtils.createLine(mousePosition, startPointValue, CURVE);
|
215 |
geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
|
216 |
|
217 |
if (sweepAngleValue != null && directionValue != null) { |
218 |
|
219 |
addArcAndEndPointToDrawingStatus(geometries, mousePosition, radiusValue, startAngleValue, startPointValue, sweepAngleValue, directionValue); |
220 |
} |
221 |
|
222 |
return geometries;
|
223 |
} catch (CreateGeometryException | GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
224 |
throw new DrawServiceException(ex); |
225 |
} |
226 |
} |
227 |
|
228 |
} else { //centerPointValue != null |
229 |
|
230 |
geometries.addStatus(centerPointValue, auxiliaryPointSymbolEditing, "");
|
231 |
|
232 |
if (startPointValue == null) { |
233 |
try {
|
234 |
if (radiusValue != null && startAngleValue != null) { |
235 |
startPointValue = GeometryUtils.createPoint(centerPointValue, radiusValue, startAngleValue); |
236 |
addArcAndEndPointToDrawingStatus(geometries, centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue, directionValue); |
237 |
} else if (radiusValue != null) { // startAngleValue == null |
238 |
double distance = centerPointValue.distance(mousePosition);
|
239 |
Point auxStartPoint = GeometryUtils.createPoint(
|
240 |
centerPointValue.getX() + radiusValue * ((mousePosition.getX() - centerPointValue.getX()) / distance), |
241 |
centerPointValue.getY() + radiusValue * ((mousePosition.getY() - centerPointValue.getY()) / distance) |
242 |
); |
243 |
geometries.addStatus(auxStartPoint, auxiliaryPointSymbolEditing, "");
|
244 |
Line auxLine = GeometryUtils.createLine(centerPointValue, auxStartPoint, CURVE);
|
245 |
geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
|
246 |
addArcAndEndPointToDrawingStatus( |
247 |
geometries, |
248 |
centerPointValue, |
249 |
radiusValue, |
250 |
GeometryUtils.calculateAngle(centerPointValue, auxStartPoint), |
251 |
auxStartPoint, |
252 |
sweepAngleValue, |
253 |
directionValue); |
254 |
|
255 |
} else if (startAngleValue != null) { // radiusValue == null |
256 |
double m = Math.tan(startAngleValue); |
257 |
Point auxStartPoint;
|
258 |
if (Double.isInfinite(m)) { |
259 |
auxStartPoint = GeometryUtils.createPoint( |
260 |
centerPointValue.getX(), mousePosition.getY()); |
261 |
} else {
|
262 |
EuclideanLine2D auxLine = euclideanManager.createLine2D( |
263 |
m, |
264 |
euclideanManager.getYIntercept( |
265 |
m, |
266 |
centerPointValue.getX(), |
267 |
centerPointValue.getY() |
268 |
) |
269 |
); |
270 |
|
271 |
double anglePointValue = GeometryUtils.calculateAngle(centerPointValue, mousePosition);
|
272 |
double x = centerPointValue.getX();
|
273 |
double y = centerPointValue.getY();
|
274 |
if (Double.isInfinite(m)) { |
275 |
auxStartPoint = GeometryUtils.createPoint( |
276 |
centerPointValue.getX(), mousePosition.getY()); |
277 |
} else if (m == 0) { |
278 |
auxStartPoint = GeometryUtils.createPoint( |
279 |
mousePosition.getX(), centerPointValue.getY()); |
280 |
} else {
|
281 |
if (Math.signum(Math.cos(startAngleValue)) == Math.signum(Math.cos(anglePointValue))) { |
282 |
x = mousePosition.getX(); |
283 |
} |
284 |
if (Math.signum(Math.sin(startAngleValue)) == Math.signum(Math.sin(anglePointValue))) { |
285 |
y = mousePosition.getY(); |
286 |
} |
287 |
Point2D proyected = auxLine.getNearestPoint(x, y);
|
288 |
auxStartPoint = GeometryUtils.createPoint(proyected.getX(), proyected.getY()); |
289 |
} |
290 |
} |
291 |
|
292 |
geometries.addStatus(auxStartPoint, auxiliaryPointSymbolEditing, "");
|
293 |
Line auxLine = GeometryUtils.createLine(centerPointValue, auxStartPoint, CURVE);
|
294 |
geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
|
295 |
addArcAndEndPointToDrawingStatus( |
296 |
geometries, |
297 |
centerPointValue, |
298 |
centerPointValue.distance(auxStartPoint), |
299 |
startAngleValue, |
300 |
auxStartPoint, |
301 |
sweepAngleValue, |
302 |
directionValue); |
303 |
|
304 |
} else { //radiusValue == null && startAngleValue == null |
305 |
geometries.addStatus(mousePosition, auxiliaryPointSymbolEditing, "");
|
306 |
Line auxLine = GeometryUtils.createLine(centerPointValue, mousePosition, CURVE);
|
307 |
geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
|
308 |
addArcAndEndPointToDrawingStatus( |
309 |
geometries, |
310 |
centerPointValue, |
311 |
centerPointValue.distance(mousePosition), |
312 |
GeometryUtils.calculateAngle(centerPointValue, mousePosition), |
313 |
mousePosition, |
314 |
sweepAngleValue, |
315 |
directionValue); |
316 |
} |
317 |
} catch (CreateGeometryException | GeometryOperationException | GeometryOperationNotSupportedException ex) {
|
318 |
throw new DrawServiceException(ex); |
319 |
} |
320 |
return geometries;
|
321 |
} else if (endPointValue == null) { |
322 |
|
323 |
try {
|
324 |
Line startLine = GeometryUtils.createLine(
|
325 |
centerPointValue.getX(), |
326 |
centerPointValue.getY(), |
327 |
startPointValue.getX(), |
328 |
startPointValue.getY(), CURVE); |
329 |
geometries.addStatus(startPointValue, auxiliaryPointSymbolEditing, "");
|
330 |
geometries.addStatus(startLine, auxiliaryLineSymbolEditing, "");
|
331 |
|
332 |
if (radiusValue == null) { |
333 |
radiusValue = centerPointValue.distance(startPointValue); |
334 |
} |
335 |
|
336 |
if (startAngleValue == null) { |
337 |
startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue); |
338 |
} |
339 |
|
340 |
|
341 |
double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, mousePosition);
|
342 |
if (sweepAngleValue != null) { |
343 |
if (directionValue == null) { |
344 |
|
345 |
Point auxPoint;
|
346 |
auxPoint = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue); |
347 |
|
348 |
geometries.addStatus(auxPoint, auxiliaryPointSymbolEditing, "");
|
349 |
|
350 |
if(Math.signum(coefDirection)!= Math.signum(sweepAngleValue)){ |
351 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
352 |
} |
353 |
|
354 |
Arc auxArc = GeometryUtils.createArc( |
355 |
centerPointValue, |
356 |
radiusValue, |
357 |
startAngleValue, |
358 |
sweepAngleValue, |
359 |
GEOM2D); |
360 |
|
361 |
geometries.addStatus(auxArc, lineSymbolEditing, "");
|
362 |
geometries.addStatus(auxArc, previewSymbol, "");
|
363 |
return geometries;
|
364 |
} |
365 |
} else { //sweepAngleValue == null |
366 |
|
367 |
double distance = centerPointValue.distance(mousePosition);
|
368 |
Point point = GeometryUtils.createPoint(
|
369 |
centerPointValue.getX() + radiusValue * ((mousePosition.getX() - centerPointValue.getX()) / distance), |
370 |
centerPointValue.getY() + radiusValue * ((mousePosition.getY() - centerPointValue.getY()) / distance) |
371 |
); |
372 |
geometries.addStatus(point, auxiliaryPointSymbolEditing, "");
|
373 |
Line auxLine = GeometryUtils.createLine(centerPointValue, point, CURVE);
|
374 |
geometries.addStatus(auxLine, auxiliaryLineSymbolEditing, "");
|
375 |
|
376 |
//calculate sweepAngle
|
377 |
sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, mousePosition); |
378 |
|
379 |
if(directionValue != null){ |
380 |
if(directionValue.equalsIgnoreCase(CW)){
|
381 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
382 |
} |
383 |
} else if(coefDirection<0) { |
384 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
385 |
} |
386 |
|
387 |
if(Math.abs(sweepAngleValue) > 0d){ |
388 |
Arc auxArc = GeometryUtils.createArc( |
389 |
centerPointValue, |
390 |
radiusValue, |
391 |
startAngleValue, |
392 |
sweepAngleValue, |
393 |
GEOM2D); |
394 |
|
395 |
geometries.addStatus(auxArc, lineSymbolEditing, "");
|
396 |
geometries.addStatus(auxArc, previewSymbol, "");
|
397 |
} |
398 |
return geometries;
|
399 |
|
400 |
} |
401 |
} catch (CreateGeometryException | GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
402 |
throw new DrawServiceException(ex); |
403 |
} |
404 |
|
405 |
} |
406 |
} |
407 |
|
408 |
} |
409 |
|
410 |
return null; |
411 |
} |
412 |
|
413 |
private void addArcAndEndPointToDrawingStatus(DefaultDrawingStatus geometries, Point centerValue, Double radiusValue, Double startAngleValue, Point startPointValue, Double sweepAngleValue, String directionValue) throws GeometryOperationException, GeometryOperationNotSupportedException, CreateGeometryException { |
414 |
|
415 |
if (sweepAngleValue != null && directionValue != null) { |
416 |
EditingProviderManager editingProviderManager |
417 |
= EditingProviderLocator.getProviderManager(); |
418 |
ISymbol auxiliaryLineSymbolEditing = editingProviderManager.getSymbol("auxiliary-line-symbol-editing");
|
419 |
ISymbol auxiliaryPointSymbolEditing = editingProviderManager.getSymbol("auxiliary-point-symbol-editing");
|
420 |
ISymbol lineSymbolEditing = editingProviderManager.getSymbol("line-symbol-editing");
|
421 |
|
422 |
Point auxEndPoint;
|
423 |
auxEndPoint = calculateEndPoint(centerValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue); |
424 |
|
425 |
geometries.addStatus(auxEndPoint, auxiliaryPointSymbolEditing, "");
|
426 |
|
427 |
double coefDirection = GeometryUtils.getCoefDirection(centerValue, startPointValue, auxEndPoint);
|
428 |
|
429 |
if (Math.signum(coefDirection) != Math.signum(sweepAngleValue)) { |
430 |
sweepAngleValue = -(2 * Math.PI - sweepAngleValue); |
431 |
} |
432 |
|
433 |
if (directionValue.equalsIgnoreCase(CW)) {
|
434 |
sweepAngleValue = -(2 * Math.PI - sweepAngleValue); |
435 |
} |
436 |
|
437 |
Arc auxArc = GeometryUtils.createArc(centerValue, |
438 |
radiusValue, |
439 |
startAngleValue, |
440 |
sweepAngleValue, |
441 |
GEOM2D); |
442 |
|
443 |
geometries.addStatus(auxArc, lineSymbolEditing, "");
|
444 |
geometries.addStatus(auxArc, geometries.getPreviewSymbol(), "");
|
445 |
} |
446 |
} |
447 |
|
448 |
@Override
|
449 |
public void stop() throws StopServiceException { |
450 |
values.clear(); |
451 |
} |
452 |
|
453 |
@Override
|
454 |
public List<EditingServiceParameter> getParameters() { |
455 |
List<EditingServiceParameter> parameters
|
456 |
= new ArrayList<>(); |
457 |
|
458 |
|
459 |
parameters.add(centerPoint); |
460 |
parameters.add(startPoint); |
461 |
parameters.add(endPoint); |
462 |
|
463 |
parameters.add(radius); |
464 |
parameters.add(startAngle); |
465 |
parameters.add(sweepAngle); |
466 |
parameters.add(direction); |
467 |
|
468 |
return parameters;
|
469 |
} |
470 |
|
471 |
@Override
|
472 |
public void setValue(Object value) throws InvalidEntryException { |
473 |
EditingServiceParameter param = next(); |
474 |
setValue(param, value); |
475 |
} |
476 |
|
477 |
@Override
|
478 |
public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException { |
479 |
validateAndInsertValue(parameter, value); |
480 |
removeRelatedParams(parameter); |
481 |
fillEmptyParams(); |
482 |
} |
483 |
|
484 |
private void removeRelatedParams(EditingServiceParameter parameter) { |
485 |
|
486 |
if (parameter == startAngle) {
|
487 |
values.remove(startPoint); |
488 |
return;
|
489 |
} |
490 |
|
491 |
if (parameter == radius) {
|
492 |
values.remove(startPoint); |
493 |
return;
|
494 |
} |
495 |
|
496 |
if( parameter == sweepAngle) {
|
497 |
values.remove(endPoint); |
498 |
} |
499 |
|
500 |
if( parameter == direction) {
|
501 |
values.remove(endPoint); |
502 |
} |
503 |
|
504 |
} |
505 |
|
506 |
private void fillEmptyParams() throws InvalidEntryException{ |
507 |
Point centerPointValue = (Point) values.get(centerPoint); |
508 |
Point startPointValue = (Point) values.get(startPoint); |
509 |
Point endPointValue = (Point) values.get(endPoint); |
510 |
|
511 |
Double radiusValue = (Double) values.get(radius); |
512 |
Double startAngleValue = (Double) values.get(startAngle); |
513 |
Double sweepAngleValue = (Double) values.get(sweepAngle); |
514 |
String directionValue = (String) values.get(direction); |
515 |
|
516 |
if( startPointValue == null && centerPointValue != null && radiusValue != null && startAngleValue != null){ |
517 |
startPointValue = GeometryUtils.createPoint(centerPointValue, radiusValue, startAngleValue); |
518 |
values.put(startPoint, startPointValue); |
519 |
} |
520 |
|
521 |
if(radiusValue == null && centerPointValue != null && startPointValue != null){ |
522 |
try {
|
523 |
radiusValue = centerPointValue.distance(startPointValue); |
524 |
values.put(radius, radiusValue); |
525 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
526 |
throw new InvalidEntryException(ex); |
527 |
} |
528 |
} |
529 |
|
530 |
if(startAngleValue == null && centerPointValue != null && startPointValue != null){ |
531 |
startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue); |
532 |
values.put(startAngle, startAngleValue); |
533 |
} |
534 |
|
535 |
if(sweepAngleValue == null && startPointValue != null && endPointValue != null){ |
536 |
sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue); |
537 |
values.put(sweepAngle, sweepAngleValue); |
538 |
} |
539 |
|
540 |
if(endPointValue == null && centerPointValue != null && startPointValue != null && sweepAngleValue != null && directionValue != null){ |
541 |
try {
|
542 |
endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue); |
543 |
values.put(endPoint, endPointValue); |
544 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
545 |
throw new InvalidEntryException(ex); |
546 |
} |
547 |
} |
548 |
|
549 |
if(sweepAngleValue == null && centerPointValue != null && startPointValue != null && endPointValue != null){ |
550 |
sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue); |
551 |
values.put(sweepAngle, sweepAngleValue); |
552 |
} |
553 |
} |
554 |
|
555 |
private void validateAndInsertValue(EditingServiceParameter param, |
556 |
Object value) throws InvalidEntryException { |
557 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
558 |
CoerceToDouble coerceToDouble = new CoerceToDouble();
|
559 |
if (param == centerPoint) {
|
560 |
if (value instanceof Point) { |
561 |
values.put(param, value); |
562 |
return;
|
563 |
} |
564 |
} else if (param == startPoint) { |
565 |
if (value instanceof Point) { |
566 |
Point pointValue = (Point) value; |
567 |
|
568 |
Point centerPointValue = (Point) (values.get(centerPoint)); |
569 |
Double radiusValue = (Double) (values.get(radius)); |
570 |
Double startAngleValue = (Double) (values.get(startAngle)); |
571 |
if (radiusValue != null) { |
572 |
try {
|
573 |
double distance = centerPointValue.distance(pointValue);
|
574 |
Point point = GeometryUtils.createPoint(
|
575 |
centerPointValue.getX() + radiusValue * ((pointValue.getX() - centerPointValue.getX()) / distance), |
576 |
centerPointValue.getY() + radiusValue * ((pointValue.getY() - centerPointValue.getY()) / distance) |
577 |
); |
578 |
values.put(param, point); |
579 |
return;
|
580 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
581 |
throw new InvalidEntryException(ex); |
582 |
} |
583 |
} else if (startAngleValue != null) { |
584 |
double m = Math.tan(startAngleValue); |
585 |
double anglePointValue = GeometryUtils.calculateAngle(centerPointValue, pointValue);
|
586 |
Point point;
|
587 |
double x = centerPointValue.getX();
|
588 |
double y = centerPointValue.getY();
|
589 |
if (Double.isInfinite(m)) { |
590 |
point = GeometryUtils.createPoint( |
591 |
centerPointValue.getX(), pointValue.getY()); |
592 |
} else if (m==0) { |
593 |
point = GeometryUtils.createPoint( |
594 |
pointValue.getX(), centerPointValue.getY()); |
595 |
} else {
|
596 |
if(Math.signum(Math.cos(startAngleValue)) == Math.signum(Math.cos(anglePointValue))){ |
597 |
x = pointValue.getX(); |
598 |
} |
599 |
|
600 |
if(Math.signum(Math.sin(startAngleValue)) == Math.signum(Math.sin(anglePointValue))){ |
601 |
y = pointValue.getY(); |
602 |
} |
603 |
|
604 |
EuclideanLine2D auxLine = euclideanManager.createLine2D( |
605 |
m, |
606 |
euclideanManager.getYIntercept( |
607 |
m, |
608 |
centerPointValue.getX(), |
609 |
centerPointValue.getY() |
610 |
) |
611 |
); |
612 |
Point2D proyected = auxLine.getNearestPoint(x, y);
|
613 |
point = GeometryUtils.createPoint(proyected.getX(), proyected.getY()); |
614 |
|
615 |
} |
616 |
values.put(param, point); |
617 |
return;
|
618 |
|
619 |
} else {
|
620 |
values.put(param, pointValue); |
621 |
|
622 |
} |
623 |
|
624 |
values.put(param, value); |
625 |
return;
|
626 |
} |
627 |
|
628 |
} else if (param == endPoint) { |
629 |
if (value instanceof Point) { |
630 |
|
631 |
Point pointValue = (Point) value; |
632 |
Double sweepAngleValue = (Double) values.get(sweepAngle); |
633 |
String directionValue = (String) values.get(direction); |
634 |
Point centerPointValue = (Point) values.get(centerPoint); |
635 |
Point startPointValue = (Point) values.get(startPoint); |
636 |
Double radiusValue = (Double) values.get(radius); |
637 |
Double startAngleValue = (Double) (values.get(startAngle)); |
638 |
if(startPointValue == null){ |
639 |
if (radiusValue != null && startAngleValue != null) { |
640 |
startPointValue = GeometryUtils.createPoint( |
641 |
centerPointValue.getX() + radiusValue * Math.cos(startAngleValue),
|
642 |
centerPointValue.getY() + radiusValue * Math.sin(startAngleValue)
|
643 |
); |
644 |
} |
645 |
} |
646 |
|
647 |
Point endPointValue;
|
648 |
if (sweepAngleValue != null) { |
649 |
|
650 |
if (directionValue == null) { |
651 |
|
652 |
double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, pointValue);
|
653 |
if(coefDirection>=0){ |
654 |
values.put(direction, CCW); |
655 |
} else {
|
656 |
values.put(direction, CW); |
657 |
} |
658 |
} |
659 |
try {
|
660 |
endPointValue = calculateEndPoint(centerPointValue, radiusValue, startAngleValue, startPointValue, sweepAngleValue); |
661 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
662 |
throw new InvalidEntryException(ex); |
663 |
} |
664 |
} else {
|
665 |
if (radiusValue == null) { |
666 |
try {
|
667 |
radiusValue = centerPointValue.distance(startPointValue); |
668 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
669 |
throw new InvalidEntryException(ex); |
670 |
} |
671 |
} |
672 |
|
673 |
|
674 |
double module;
|
675 |
try {
|
676 |
module = centerPointValue.distance(pointValue); |
677 |
} catch (GeometryOperationNotSupportedException | GeometryOperationException ex) {
|
678 |
throw new InvalidEntryException(ex); |
679 |
} |
680 |
|
681 |
endPointValue = GeometryUtils.createPoint( |
682 |
centerPointValue.getX()+radiusValue*(pointValue.getX()-centerPointValue.getX())/module, |
683 |
centerPointValue.getY()+radiusValue*(pointValue.getY()-centerPointValue.getY())/module |
684 |
); |
685 |
} |
686 |
values.put(endPoint, endPointValue); |
687 |
return;
|
688 |
} |
689 |
} else if (param == radius) { |
690 |
try {
|
691 |
Double doubleValue = (Double) coerceToDouble.coerce(value); |
692 |
// To avoid infinite, Nan and very small values
|
693 |
if (doubleValue != null && Double.isFinite(doubleValue) && (doubleValue - 0.01) > 0) { |
694 |
values.put(param, doubleValue); |
695 |
return;
|
696 |
} |
697 |
} catch (CoercionException ex) {
|
698 |
throw new InvalidEntryException(null); |
699 |
} |
700 |
} else if (param == startAngle) { |
701 |
try {
|
702 |
Double doubleValue = (Double) coerceToDouble.coerce(value); |
703 |
if (doubleValue != null && Double.isFinite(doubleValue)) { |
704 |
values.put(param, Math.toRadians(doubleValue));
|
705 |
return;
|
706 |
} |
707 |
} catch (CoercionException ex) {
|
708 |
throw new InvalidEntryException(ex); |
709 |
} |
710 |
} else if (param == sweepAngle) { |
711 |
try {
|
712 |
Double doubleValue = (Double) coerceToDouble.coerce(value); |
713 |
if (doubleValue != null && Double.isFinite(doubleValue)) { |
714 |
values.put(param, Math.toRadians(doubleValue));
|
715 |
return;
|
716 |
} |
717 |
} catch (CoercionException ex) {
|
718 |
throw new InvalidEntryException(null); |
719 |
} |
720 |
} else if (param == direction) { |
721 |
if (value instanceof String) { |
722 |
if (((String) value).trim().equalsIgnoreCase(CCW)) { |
723 |
values.put(param, CCW); |
724 |
return;
|
725 |
} else if (((String) value).trim().equalsIgnoreCase(CW)) { |
726 |
values.put(param, CW); |
727 |
return;
|
728 |
} |
729 |
} |
730 |
} |
731 |
throw new InvalidEntryException(null); |
732 |
} |
733 |
|
734 |
private Point calculateEndPoint(Point centerPointValue, Double radiusValue, Double startAngleValue, Point startPointValue, Double sweepAngleValue) throws GeometryOperationNotSupportedException, GeometryOperationException { //String directionValue |
735 |
|
736 |
Point endPointValue = (Point) values.get(endPoint); |
737 |
if (endPointValue != null) { |
738 |
return endPointValue;
|
739 |
} |
740 |
|
741 |
if (startPointValue == null || centerPointValue == null || sweepAngleValue == null) { |
742 |
return null; |
743 |
} |
744 |
if (startAngleValue == null) { |
745 |
startAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue); |
746 |
} |
747 |
|
748 |
if (radiusValue == null) { |
749 |
radiusValue = centerPointValue.distance(startPointValue); |
750 |
} |
751 |
|
752 |
double endAngle;
|
753 |
endAngle = startAngleValue + sweepAngleValue; |
754 |
|
755 |
endPointValue = GeometryUtils.createPoint( |
756 |
centerPointValue.getX() + radiusValue * Math.cos(endAngle),
|
757 |
centerPointValue.getY() + radiusValue * Math.sin(endAngle)
|
758 |
); |
759 |
|
760 |
return endPointValue;
|
761 |
} |
762 |
|
763 |
@Override
|
764 |
public Geometry finish() throws FinishServiceException { |
765 |
//FIXME
|
766 |
Point centerPointValue = (Point) values.get(centerPoint); |
767 |
Point startPointValue = (Point) values.get(startPoint); |
768 |
Point endPointValue = (Point) values.get(endPoint); |
769 |
|
770 |
Double radiusValue = (Double) values.get(radius); |
771 |
Double startAngleValue = (Double) values.get(startAngle); |
772 |
Double sweepAngleValue = (Double) values.get(sweepAngle); |
773 |
String directionValue = (String) values.get(direction); |
774 |
|
775 |
EditingProviderServices editingProviderServices |
776 |
= (EditingProviderServices) getProviderServices(); |
777 |
|
778 |
EuclideanManager euclideanManager = ToolsUtilLocator.getEuclideanManager(); |
779 |
|
780 |
try {
|
781 |
|
782 |
int subtype
|
783 |
= editingProviderServices.getSubType(featureStore); |
784 |
|
785 |
if (radiusValue == null) { |
786 |
radiusValue = centerPointValue.distance(startPointValue); |
787 |
} |
788 |
|
789 |
Curve arc = null;
|
790 |
double coefDirection = GeometryUtils.getCoefDirection(centerPointValue, startPointValue, endPointValue);
|
791 |
if (sweepAngleValue != null) { |
792 |
if (directionValue != null) { |
793 |
if(directionValue.equalsIgnoreCase(CCW)){
|
794 |
if(sweepAngleValue >= 0){ |
795 |
//Do nothing
|
796 |
} else {
|
797 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
798 |
} |
799 |
} else {
|
800 |
if(sweepAngleValue <= 0){ |
801 |
//Do nothing
|
802 |
} else {
|
803 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); //coefDirection * sweepAngleValue; |
804 |
} |
805 |
} |
806 |
} else if(Math.signum(coefDirection)!= Math.signum(sweepAngleValue)){ |
807 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
808 |
} |
809 |
|
810 |
arc = GeometryUtils.createArc( |
811 |
centerPointValue, |
812 |
radiusValue, |
813 |
startAngleValue, |
814 |
sweepAngleValue, |
815 |
GEOM2D); |
816 |
} else { //sweepAngleValue == null |
817 |
|
818 |
double distance = centerPointValue.distance(endPointValue);
|
819 |
Point point = GeometryUtils.createPoint(
|
820 |
centerPointValue.getX() + radiusValue * ((endPointValue.getX() - centerPointValue.getX()) / distance), |
821 |
centerPointValue.getY() + radiusValue * ((endPointValue.getY() - centerPointValue.getY()) / distance) |
822 |
); |
823 |
|
824 |
//calculate sweepAngle
|
825 |
sweepAngleValue = GeometryUtils.calculateAngle(centerPointValue, startPointValue, endPointValue); |
826 |
|
827 |
if(directionValue != null){ |
828 |
if(directionValue.equalsIgnoreCase(CW)){
|
829 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
830 |
} |
831 |
} else if(coefDirection<0) { |
832 |
sweepAngleValue = -(2*Math.PI-sweepAngleValue); |
833 |
} |
834 |
|
835 |
if(Math.abs(sweepAngleValue) > 0d){ |
836 |
arc = GeometryUtils.createArc( |
837 |
centerPointValue, |
838 |
radiusValue, |
839 |
startAngleValue, |
840 |
sweepAngleValue, |
841 |
GEOM2D); |
842 |
} |
843 |
} |
844 |
|
845 |
|
846 |
GeometryType geomType |
847 |
= editingProviderServices.getGeomType(featureStore); |
848 |
|
849 |
if (geomType.isTypeOf(MULTICURVE)) {
|
850 |
|
851 |
MultiCurve multiCurve; |
852 |
multiCurve |
853 |
= GeometryLocator.getGeometryManager().createMultiCurve( |
854 |
geomType.getSubType()); |
855 |
multiCurve.addCurve(arc); |
856 |
return multiCurve;
|
857 |
} |
858 |
|
859 |
return arc;
|
860 |
} catch (Exception e) { |
861 |
throw new FinishServiceException(e); |
862 |
} |
863 |
} |
864 |
|
865 |
@Override
|
866 |
public void finishAndStore() throws FinishServiceException { |
867 |
Geometry geometry = finish(); |
868 |
EditingProviderServices editingProviderServices |
869 |
= (EditingProviderServices) getProviderServices(); |
870 |
editingProviderServices.insertGeometryIntoFeatureStore(geometry, |
871 |
featureStore); |
872 |
} |
873 |
|
874 |
@Override
|
875 |
public void start() throws StartServiceException { |
876 |
values = new HashMap<>(); |
877 |
} |
878 |
|
879 |
@Override
|
880 |
public String getName() { |
881 |
return ArcByCenterEditingProviderFactory.PROVIDER_NAME;
|
882 |
} |
883 |
|
884 |
@Override
|
885 |
public boolean isEnabled(EditingServiceParameter parameter) { |
886 |
|
887 |
if (parameter == radius) {
|
888 |
if (values.get(startPoint) != null) { |
889 |
return false; |
890 |
} |
891 |
} else if (parameter == startAngle) { |
892 |
if (values.get(startPoint) != null) { |
893 |
return false; |
894 |
} |
895 |
} else if (parameter == sweepAngle) { |
896 |
if (values.get(endPoint) != null) { |
897 |
return false; |
898 |
} |
899 |
} else if (parameter == direction) { |
900 |
if (values.get(endPoint) != null) { |
901 |
return false; |
902 |
} |
903 |
} |
904 |
return true; |
905 |
} |
906 |
|
907 |
@Override
|
908 |
public Object getValue(EditingServiceParameter parameter) { |
909 |
return values!=null?values.get(parameter):null; |
910 |
} |
911 |
|
912 |
} |