gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.lib / org.gvsig.vectorediting.lib.prov / org.gvsig.vectorediting.lib.prov.editvertex / src / main / java / org / gvsig / vectorediting / lib / prov / editvertex / EditVertexEditingProvider.java @ 841
History | View | Annotate | Download (38.5 KB)
1 |
/**
|
---|---|
2 |
* gvSIG. Desktop Geographic Information System.
|
3 |
*
|
4 |
* Copyright ? 2007-2015 gvSIG Association
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* as published by the Free Software Foundation; either version 2
|
9 |
* of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This program is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with this program; if not, write to the Free Software
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 |
* MA 02110-1301, USA.
|
20 |
*
|
21 |
* For any additional information, do not hesitate to contact us
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
23 |
*/
|
24 |
package org.gvsig.vectorediting.lib.prov.editvertex; |
25 |
|
26 |
|
27 |
import java.awt.Color; |
28 |
import java.awt.geom.AffineTransform; |
29 |
import java.util.ArrayList; |
30 |
import java.util.Iterator; |
31 |
import java.util.LinkedHashMap; |
32 |
import java.util.List; |
33 |
|
34 |
import org.cresques.cts.IProjection; |
35 |
import org.slf4j.Logger; |
36 |
import org.slf4j.LoggerFactory; |
37 |
|
38 |
import org.gvsig.fmap.dal.exception.DataException; |
39 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
40 |
import org.gvsig.fmap.dal.feature.Feature; |
41 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
42 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
43 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
44 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
45 |
import org.gvsig.fmap.geom.Geometry; |
46 |
import org.gvsig.fmap.geom.GeometryLocator; |
47 |
import org.gvsig.fmap.geom.GeometryManager; |
48 |
import org.gvsig.fmap.geom.aggregate.MultiPrimitive; |
49 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
50 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
51 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
52 |
import org.gvsig.fmap.geom.primitive.OrientablePrimitive; |
53 |
import org.gvsig.fmap.geom.primitive.Point; |
54 |
import org.gvsig.fmap.geom.primitive.Primitive; |
55 |
import org.gvsig.fmap.geom.type.GeometryType; |
56 |
import org.gvsig.fmap.mapcontext.MapContext; |
57 |
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsGeometryEvaluator; |
58 |
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol; |
59 |
import org.gvsig.symbology.SymbologyLocator; |
60 |
import org.gvsig.symbology.SymbologyManager; |
61 |
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.text.ISimpleTextSymbol; |
62 |
import org.gvsig.tools.dispose.DisposableIterator; |
63 |
import org.gvsig.tools.dynobject.DynObject; |
64 |
import org.gvsig.tools.exception.BaseException; |
65 |
import org.gvsig.tools.service.spi.ProviderServices; |
66 |
import org.gvsig.vectorediting.lib.api.DrawingStatus; |
67 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter; |
68 |
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE; |
69 |
import org.gvsig.vectorediting.lib.api.exceptions.DrawServiceException; |
70 |
import org.gvsig.vectorediting.lib.api.exceptions.FinishServiceException; |
71 |
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException; |
72 |
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException; |
73 |
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException; |
74 |
import org.gvsig.vectorediting.lib.prov.editvertex.operation.EditVertexOperation; |
75 |
import org.gvsig.vectorediting.lib.prov.editvertex.operation.EditVertexOperationUtils; |
76 |
import org.gvsig.vectorediting.lib.spi.AbstractEditingProvider; |
77 |
import org.gvsig.vectorediting.lib.spi.DefaultDrawingStatus; |
78 |
import org.gvsig.vectorediting.lib.spi.DefaultEditingServiceParameter; |
79 |
import org.gvsig.vectorediting.lib.spi.EditingProvider; |
80 |
import org.gvsig.vectorediting.lib.spi.EditingProviderFactory; |
81 |
import org.gvsig.vectorediting.lib.spi.EditingProviderLocator; |
82 |
import org.gvsig.vectorediting.lib.spi.EditingProviderManager; |
83 |
import org.gvsig.vectorediting.lib.spi.EditingProviderServices; |
84 |
|
85 |
/**
|
86 |
* @author fdiaz
|
87 |
*
|
88 |
*/
|
89 |
public class EditVertexEditingProvider extends AbstractEditingProvider implements |
90 |
EditingProvider { |
91 |
private static final Logger logger = LoggerFactory |
92 |
.getLogger(EditVertexEditingProvider.class); |
93 |
|
94 |
private final int TOLERANCE_PIXELS = 3; |
95 |
|
96 |
private EditingServiceParameter selectionParameter;
|
97 |
|
98 |
private EditingServiceParameter vertexSelectionPointParameter;
|
99 |
|
100 |
private EditingServiceParameter actionParameter;
|
101 |
|
102 |
private FeatureSelection selection;
|
103 |
|
104 |
private Point selectedVertex; |
105 |
private int selectedIndex; |
106 |
|
107 |
private Point pointToMove; |
108 |
|
109 |
private String action; |
110 |
|
111 |
private FeatureStore featureStore;
|
112 |
|
113 |
private MapContext mapContext;
|
114 |
|
115 |
/**
|
116 |
* Default constructor.
|
117 |
* @param services
|
118 |
* available services for this provider
|
119 |
* @param parameters
|
120 |
* of this provider
|
121 |
*/
|
122 |
public EditVertexEditingProvider(ProviderServices services,
|
123 |
DynObject parameters) { |
124 |
super(services);
|
125 |
|
126 |
selectedIndex = -1;
|
127 |
|
128 |
this.featureStore =
|
129 |
(FeatureStore) parameters |
130 |
.getDynValue(EditingProviderFactory.FEATURE_STORE_FIELD); |
131 |
|
132 |
this.mapContext =
|
133 |
(MapContext) parameters |
134 |
.getDynValue(EditingProviderFactory.MAPCONTEXT_FIELD); |
135 |
|
136 |
this.selectionParameter =
|
137 |
new DefaultEditingServiceParameter("selection", "uniqueselection", |
138 |
TYPE.SELECTION); |
139 |
|
140 |
this.vertexSelectionPointParameter =
|
141 |
new DefaultEditingServiceParameter("selectvertex", "selectvertex", |
142 |
TYPE.POSITION, |
143 |
TYPE.VALUE); |
144 |
|
145 |
LinkedHashMap<String, String> options = new LinkedHashMap<String, String>(); |
146 |
options.put("+", "insert_vertex"); |
147 |
options.put("-", "remove_vertex"); |
148 |
GeometryType geomType = null;
|
149 |
try {
|
150 |
geomType = featureStore.getDefaultFeatureType().getDefaultGeometryAttribute().getGeomType(); |
151 |
} catch (DataException e) {
|
152 |
String message =
|
153 |
String.format("Error getting feature type of %1", |
154 |
featureStore); |
155 |
logger.info(message, e); |
156 |
} |
157 |
if(geomType != null && (geomType.isSubTypeOf(Geometry.SUBTYPES.GEOM3D) || geomType.isSubTypeOf(Geometry.SUBTYPES.GEOM3DM))){ |
158 |
this.actionParameter =
|
159 |
new DefaultEditingServiceParameter(
|
160 |
"new_position_or_z_value",
|
161 |
((EditingProviderServices) getProviderServices()).makeConsoleMessage("new_position_or_z_value", options),
|
162 |
options, |
163 |
TYPE.POSITION, |
164 |
TYPE.OPTION, |
165 |
TYPE.VALUE); |
166 |
} else {
|
167 |
this.actionParameter =
|
168 |
new DefaultEditingServiceParameter("new_position", |
169 |
((EditingProviderServices) getProviderServices()).makeConsoleMessage("new_position", options),
|
170 |
options, TYPE.POSITION, TYPE.OPTION); |
171 |
} |
172 |
} |
173 |
|
174 |
public EditingServiceParameter next() {
|
175 |
if (selection == null) { |
176 |
return selectionParameter;
|
177 |
} else if (selectedVertex == null) { |
178 |
return vertexSelectionPointParameter;
|
179 |
} else if (action == null && pointToMove == null) { |
180 |
return actionParameter;
|
181 |
} |
182 |
return null; |
183 |
} |
184 |
|
185 |
public DrawingStatus getDrawingStatus(Point mousePosition) |
186 |
throws DrawServiceException {
|
187 |
DefaultDrawingStatus drawingStatus = new DefaultDrawingStatus();
|
188 |
EditingProviderManager editingProviderManager = |
189 |
EditingProviderLocator.getProviderManager(); |
190 |
ISymbol selectedVertexSymbolEditing = |
191 |
editingProviderManager.getSymbol("selected-vertex-symbol-editing");
|
192 |
ISymbol editedVertexSymbolEditing = |
193 |
editingProviderManager.getSymbol("edited-vertex-symbol-editing");
|
194 |
Color colorToTextSymbol = Color.BLACK; |
195 |
if (selectedVertexSymbolEditing != null) { |
196 |
colorToTextSymbol = selectedVertexSymbolEditing |
197 |
.getColor(); |
198 |
} |
199 |
|
200 |
double translationForTextSymbol =
|
201 |
mapContext.getViewPort().toMapDistance(5);
|
202 |
double tolerance =
|
203 |
mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS); |
204 |
try {
|
205 |
if (this.selection == null) { |
206 |
Geometry geometry = null;
|
207 |
geometry = getNearestGeometry(mousePosition); |
208 |
if (geometry != null) { |
209 |
List<Point> vertexesList = getVertexesList(geometry); |
210 |
if (vertexesList != null) { |
211 |
int i = 0; |
212 |
for (Iterator<Point> iterator = vertexesList.iterator(); iterator |
213 |
.hasNext();) { |
214 |
Point point = (Point) iterator.next(); |
215 |
drawingStatus.addStatus(point, |
216 |
selectedVertexSymbolEditing, "");
|
217 |
Point pointToText = (Point) point.cloneGeometry(); |
218 |
pointToText.transform(new AffineTransform(1, 0, 0, |
219 |
1, translationForTextSymbol, 0)); |
220 |
drawingStatus.addStatus(pointToText, |
221 |
getTextSymbol(colorToTextSymbol), String.valueOf(i++));
|
222 |
} |
223 |
} |
224 |
} |
225 |
} else {
|
226 |
Geometry selectedGeometry = getSelectedGeometry(); |
227 |
if (selectedVertex == null) { |
228 |
List<Point> vertexesList = |
229 |
getVertexesList(selectedGeometry); |
230 |
Point vertex =
|
231 |
getVertex(selectedGeometry, mousePosition, tolerance); |
232 |
if (vertexesList != null) { |
233 |
int i = 0; |
234 |
int selectedIndex = -1; |
235 |
for (Iterator<Point> iterator = vertexesList.iterator(); iterator |
236 |
.hasNext();) { |
237 |
Point point = (Point) iterator.next(); |
238 |
Point pointToText = (Point) point.cloneGeometry(); |
239 |
pointToText.transform(new AffineTransform(1, 0, 0, |
240 |
1, translationForTextSymbol, 0)); |
241 |
if (vertex != null && vertex.equals(point)) { |
242 |
if(selectedIndex<0){ |
243 |
selectedIndex = i++; |
244 |
} else {
|
245 |
i++; |
246 |
} |
247 |
} else {
|
248 |
drawingStatus.addStatus(point, |
249 |
selectedVertexSymbolEditing, "");
|
250 |
drawingStatus |
251 |
.addStatus( |
252 |
pointToText, |
253 |
getTextSymbol(colorToTextSymbol), |
254 |
String.valueOf(i++));
|
255 |
} |
256 |
} |
257 |
if (selectedIndex >= 0) { |
258 |
Point pointToText = (Point) vertex.cloneGeometry(); |
259 |
pointToText.transform(new AffineTransform(1, 0, 0, |
260 |
1, translationForTextSymbol, 0)); |
261 |
drawingStatus.addStatus(vertex, |
262 |
editedVertexSymbolEditing, "");
|
263 |
drawingStatus |
264 |
.addStatus(pointToText, |
265 |
getTextSymbol(colorToTextSymbol), |
266 |
createInfoPointMessage(pointToText, selectedIndex) |
267 |
); |
268 |
|
269 |
} |
270 |
} |
271 |
} else {
|
272 |
List<Point> vertexesList = |
273 |
getVertexesList(selectedGeometry); |
274 |
if (vertexesList != null) { |
275 |
int i = 0; |
276 |
if (selectedIndex < 0) { |
277 |
for (Iterator<Point> iterator = vertexesList.iterator(); iterator.hasNext();) { |
278 |
Point point = (Point) iterator.next(); |
279 |
Point pointToText = (Point) point.cloneGeometry(); |
280 |
pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0)); |
281 |
if (selectedVertex.equals(point)) {
|
282 |
if (selectedIndex < 0) { |
283 |
selectedIndex = i++; |
284 |
} else {
|
285 |
i++; |
286 |
} |
287 |
} else {
|
288 |
drawingStatus.addStatus(point, selectedVertexSymbolEditing, "");
|
289 |
drawingStatus.addStatus(pointToText, getTextSymbol(colorToTextSymbol), |
290 |
String.valueOf(i++));
|
291 |
} |
292 |
} |
293 |
} |
294 |
if (selectedIndex >= 0) { |
295 |
Point pointToText =
|
296 |
(Point) selectedVertex.cloneGeometry();
|
297 |
pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0)); |
298 |
drawingStatus.addStatus(selectedVertex, |
299 |
editedVertexSymbolEditing, "");
|
300 |
drawingStatus |
301 |
.addStatus(pointToText, |
302 |
getTextSymbol(colorToTextSymbol), createInfoPointMessage(pointToText, selectedIndex)); |
303 |
Point newPosition = (Point) selectedVertex.cloneGeometry(); |
304 |
newPosition.setX(mousePosition.getX()); |
305 |
newPosition.setY(mousePosition.getY()); |
306 |
Geometry modifiedGeometry = this.getModifiedGeometry(selectedGeometry, selectedIndex, newPosition);
|
307 |
addToDrawingStatus(drawingStatus, modifiedGeometry); |
308 |
|
309 |
drawingStatus.addStatus(mousePosition, |
310 |
selectedVertexSymbolEditing, "");
|
311 |
pointToText =(Point) selectedVertex.cloneGeometry();
|
312 |
pointToText.setX(mousePosition.getX()); |
313 |
pointToText.setY(mousePosition.getY()); |
314 |
pointToText.transform(new AffineTransform(1, 0, 0, 1, translationForTextSymbol, 0)); |
315 |
drawingStatus.addStatus(pointToText, |
316 |
getTextSymbol(colorToTextSymbol), createInfoPointMessage(pointToText, selectedIndex)); |
317 |
} |
318 |
} |
319 |
} |
320 |
} |
321 |
} catch (BaseException e) {
|
322 |
throw new DrawServiceException(e); |
323 |
} |
324 |
return drawingStatus;
|
325 |
} |
326 |
|
327 |
private String createInfoPointMessage(Point point, int index) throws GeometryOperationNotSupportedException, GeometryOperationException{ |
328 |
StringBuilder builder = new StringBuilder(); |
329 |
builder.append(index); |
330 |
builder.append(" ");
|
331 |
builder.append(point.convertToWKT().replaceAll("POINT ", "").replaceAll(" ", " , ")); |
332 |
return builder.toString();
|
333 |
} |
334 |
|
335 |
private void addToDrawingStatus(DefaultDrawingStatus drawingStatus, |
336 |
Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
|
337 |
|
338 |
if (geometry instanceof MultiPrimitive) { |
339 |
MultiPrimitive aggregate = (MultiPrimitive) geometry; |
340 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
341 |
Primitive primitive = aggregate.getPrimitiveAt(i); |
342 |
|
343 |
EditVertexOperation operation = |
344 |
EditVertexOperationUtils.getOperation(primitive); |
345 |
if (operation != null) { |
346 |
operation.addToDrawingStatus(drawingStatus, primitive); |
347 |
} |
348 |
} |
349 |
} else if (geometry instanceof Primitive) { |
350 |
Primitive primitive = (Primitive) geometry; |
351 |
EditVertexOperation operation = |
352 |
EditVertexOperationUtils.getOperation(primitive); |
353 |
if (operation != null) { |
354 |
operation.addToDrawingStatus(drawingStatus, primitive); |
355 |
} |
356 |
} |
357 |
return;
|
358 |
} |
359 |
|
360 |
private Geometry getModifiedGeometry(Geometry geometry, int index, |
361 |
Point newPosition) throws CreateGeometryException, |
362 |
GeometryOperationNotSupportedException, GeometryOperationException { |
363 |
|
364 |
if (geometry instanceof MultiPrimitive) { |
365 |
GeometryManager geometryManager = |
366 |
GeometryLocator.getGeometryManager(); |
367 |
MultiPrimitive aggregate = (MultiPrimitive) geometry; |
368 |
GeometryType geometryType = aggregate.getGeometryType(); |
369 |
MultiPrimitive newAggregate = |
370 |
(MultiPrimitive) geometryManager.create(geometryType.getType(), |
371 |
geometryType.getSubType()); |
372 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
373 |
Primitive primitive = aggregate.getPrimitiveAt(i); |
374 |
EditVertexOperation operation = |
375 |
EditVertexOperationUtils.getOperation(primitive); |
376 |
if (operation != null) { |
377 |
int numVertexes = operation.getNumVertex(primitive);
|
378 |
if (index > -1 && index < numVertexes) { |
379 |
Geometry modifiedPrimitive = |
380 |
operation.moveVertex(primitive, index, |
381 |
newPosition); |
382 |
newAggregate |
383 |
.addPrimitive((Primitive) modifiedPrimitive); |
384 |
index = -1;
|
385 |
} else {
|
386 |
index -= numVertexes; |
387 |
newAggregate.addPrimitive((Primitive) primitive |
388 |
.cloneGeometry()); |
389 |
} |
390 |
} |
391 |
} |
392 |
return newAggregate;
|
393 |
} else if (geometry instanceof Primitive) { |
394 |
Primitive primitive = (Primitive) geometry; |
395 |
EditVertexOperation operation = |
396 |
EditVertexOperationUtils.getOperation(primitive); |
397 |
if (operation != null) { |
398 |
return operation.moveVertex(primitive, index, newPosition);
|
399 |
} |
400 |
} |
401 |
return null; |
402 |
} |
403 |
|
404 |
private Geometry getInsertVertexGeometry(Geometry geometry, int index) |
405 |
throws CreateGeometryException {
|
406 |
if (geometry instanceof MultiPrimitive) { |
407 |
GeometryManager geometryManager = |
408 |
GeometryLocator.getGeometryManager(); |
409 |
MultiPrimitive aggregate = (MultiPrimitive) geometry; |
410 |
GeometryType geometryType = aggregate.getGeometryType(); |
411 |
MultiPrimitive newAggregate = |
412 |
(MultiPrimitive) geometryManager.create(geometryType.getType(), |
413 |
geometryType.getSubType()); |
414 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
415 |
Primitive primitive = aggregate.getPrimitiveAt(i); |
416 |
EditVertexOperation operation = |
417 |
EditVertexOperationUtils.getOperation(primitive); |
418 |
if (operation != null) { |
419 |
int numVertexes = operation.getNumVertex(primitive);
|
420 |
if (index > -1 && index < numVertexes) { |
421 |
Geometry modifiedPrimitive = |
422 |
operation.insertVertex(primitive, index); |
423 |
newAggregate |
424 |
.addPrimitive((Primitive) modifiedPrimitive); |
425 |
index = -1;
|
426 |
} else {
|
427 |
index -= numVertexes; |
428 |
newAggregate.addPrimitive((Primitive) primitive |
429 |
.cloneGeometry()); |
430 |
} |
431 |
} |
432 |
} |
433 |
return newAggregate;
|
434 |
} else if (geometry instanceof Primitive) { |
435 |
Primitive primitive = (Primitive) geometry; |
436 |
EditVertexOperation operation = |
437 |
EditVertexOperationUtils.getOperation(primitive); |
438 |
if (operation != null) { |
439 |
return operation.insertVertex(primitive, index);
|
440 |
} |
441 |
} |
442 |
return null; |
443 |
} |
444 |
|
445 |
private Geometry getRemovedVertexGeometry(Geometry geometry, int index) |
446 |
throws CreateGeometryException {
|
447 |
if (geometry instanceof MultiPrimitive) { |
448 |
GeometryManager geometryManager = |
449 |
GeometryLocator.getGeometryManager(); |
450 |
MultiPrimitive aggregate = (MultiPrimitive) geometry; |
451 |
GeometryType geometryType = aggregate.getGeometryType(); |
452 |
MultiPrimitive newAggregate = |
453 |
(MultiPrimitive) geometryManager.create(geometryType.getType(), |
454 |
geometryType.getSubType()); |
455 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
456 |
Primitive primitive = aggregate.getPrimitiveAt(i); |
457 |
EditVertexOperation operation = |
458 |
EditVertexOperationUtils.getOperation(primitive); |
459 |
if (operation != null) { |
460 |
int numVertexes = operation.getNumVertex(primitive);
|
461 |
if (index > -1 && index < numVertexes) { |
462 |
Geometry modifiedPrimitive = |
463 |
operation.removeVertex(primitive, index); |
464 |
newAggregate |
465 |
.addPrimitive((Primitive) modifiedPrimitive); |
466 |
index = -1;
|
467 |
} else {
|
468 |
index -= numVertexes; |
469 |
newAggregate.addPrimitive((Primitive) primitive |
470 |
.cloneGeometry()); |
471 |
} |
472 |
} |
473 |
} |
474 |
return newAggregate;
|
475 |
} else if (geometry instanceof Primitive) { |
476 |
Primitive primitive = (Primitive) geometry; |
477 |
EditVertexOperation operation = |
478 |
EditVertexOperationUtils.getOperation(primitive); |
479 |
if (operation != null) { |
480 |
return operation.removeVertex(primitive, index);
|
481 |
} |
482 |
} |
483 |
return null; |
484 |
} |
485 |
|
486 |
private ISimpleTextSymbol getTextSymbol(Color color){ |
487 |
SymbologyManager symbologyManager = SymbologyLocator.getSymbologyManager(); |
488 |
ISimpleTextSymbol textSymbol = symbologyManager.createSimpleTextSymbol(); |
489 |
textSymbol.setFontSize(12);
|
490 |
textSymbol.setColor(color); |
491 |
return textSymbol;
|
492 |
} |
493 |
|
494 |
public void stop() throws StopServiceException { |
495 |
this.selection = null; |
496 |
this.selectedVertex = null; |
497 |
this.pointToMove = null; |
498 |
this.action = null; |
499 |
} |
500 |
|
501 |
public List<EditingServiceParameter> getParameters() { |
502 |
List<EditingServiceParameter> parameters =
|
503 |
new ArrayList<EditingServiceParameter>(); |
504 |
parameters.add(selectionParameter); |
505 |
parameters.add(vertexSelectionPointParameter); |
506 |
parameters.add(actionParameter); |
507 |
return parameters;
|
508 |
} |
509 |
|
510 |
public void setValue(Object value) throws InvalidEntryException { |
511 |
EditingServiceParameter parameter = next(); |
512 |
validateAndInsertValue(parameter, value); |
513 |
} |
514 |
|
515 |
private void validateAndInsertValue( |
516 |
final EditingServiceParameter parameter, Object value) |
517 |
throws InvalidEntryException {
|
518 |
|
519 |
if (parameter == selectionParameter) {
|
520 |
if (value instanceof FeatureSelection) { |
521 |
FeatureSelection featureSelection = (FeatureSelection) value; |
522 |
if (featureSelection.getSelectedCount() == 1) { |
523 |
this.selection = featureSelection;
|
524 |
} else {
|
525 |
throw new InvalidEntryException(null); |
526 |
} |
527 |
} |
528 |
} else {
|
529 |
Geometry selectedGeometry; |
530 |
try {
|
531 |
selectedGeometry = getSelectedGeometry(); |
532 |
} catch (DataException e1) {
|
533 |
throw new InvalidEntryException(e1); |
534 |
} |
535 |
if (parameter == vertexSelectionPointParameter) {
|
536 |
if (value instanceof Point) { |
537 |
Point point = (Point) value; |
538 |
double tolerance = mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS);
|
539 |
try {
|
540 |
this.selectedVertex = getVertex(selectedGeometry, point, tolerance);
|
541 |
selectedIndex = getSelectedIndex(getVertexesList(selectedGeometry)); |
542 |
} catch (BaseException e) {
|
543 |
throw new InvalidEntryException(e); |
544 |
} |
545 |
return;
|
546 |
} else if (value instanceof Double) { |
547 |
Double index = (Double) value; |
548 |
if (index != Math.round(index)) { |
549 |
throw new InvalidEntryException(null); |
550 |
} else {
|
551 |
List<Point> vertexesList; |
552 |
try {
|
553 |
vertexesList = getVertexesList(selectedGeometry); |
554 |
} catch (BaseException e) {
|
555 |
throw new InvalidEntryException(e); |
556 |
} |
557 |
if(index >= vertexesList.size()){
|
558 |
throw new InvalidEntryException(null); |
559 |
} |
560 |
this.selectedIndex = index.intValue();
|
561 |
this.selectedVertex = vertexesList.get(this.selectedIndex); |
562 |
} |
563 |
} |
564 |
|
565 |
} else if (parameter == actionParameter) { |
566 |
if (value instanceof Point) { |
567 |
this.pointToMove = (Point) value; |
568 |
} else if (value instanceof String) { |
569 |
|
570 |
List<Point> vertexesList; |
571 |
try {
|
572 |
vertexesList = getVertexesList(selectedGeometry); |
573 |
} catch (BaseException e) {
|
574 |
throw new InvalidEntryException(e); |
575 |
} |
576 |
EditVertexOperation operation = null;
|
577 |
if (vertexesList != null) { |
578 |
Primitive primitive = null;
|
579 |
if (selectedIndex < 0) { |
580 |
if (selectedGeometry instanceof MultiPrimitive) { |
581 |
MultiPrimitive aggregate = (MultiPrimitive) selectedGeometry; |
582 |
boolean found = false; |
583 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
584 |
// selectedIndex = -1;
|
585 |
primitive = aggregate.getPrimitiveAt(i); |
586 |
operation = EditVertexOperationUtils.getOperation(primitive); |
587 |
if (operation != null) { |
588 |
int numVertexes = operation.getNumVertex(primitive);
|
589 |
if (primitive instanceof OrientablePrimitive) { |
590 |
OrientablePrimitive orientable = (OrientablePrimitive) primitive; |
591 |
for (int j = 0; j < numVertexes; j++) { |
592 |
if (selectedVertex.equals(orientable.getVertex(j))) {
|
593 |
selectedIndex = j; |
594 |
found = true;
|
595 |
break;
|
596 |
} |
597 |
} |
598 |
} |
599 |
} |
600 |
if (found) {
|
601 |
break;
|
602 |
} |
603 |
} |
604 |
} |
605 |
} else if (selectedGeometry instanceof Primitive) { |
606 |
primitive = (Primitive) selectedGeometry; |
607 |
if (selectedIndex < 0) { |
608 |
|
609 |
operation = EditVertexOperationUtils.getOperation(primitive); |
610 |
if (operation != null) { |
611 |
int numVertexes = operation.getNumVertex(primitive);
|
612 |
if (primitive instanceof OrientablePrimitive) { |
613 |
OrientablePrimitive orientable = (OrientablePrimitive) primitive; |
614 |
for (int j = 0; j < numVertexes; j++) { |
615 |
if (selectedVertex.equals(orientable.getVertex(j))) {
|
616 |
selectedIndex = j; |
617 |
break;
|
618 |
} |
619 |
} |
620 |
} |
621 |
} |
622 |
} |
623 |
} |
624 |
|
625 |
String str = (String) value; |
626 |
if (str.equalsIgnoreCase("+") || str.equalsIgnoreCase("-")) { |
627 |
if (operation != null) { |
628 |
if (str.equalsIgnoreCase("+")) { |
629 |
if (selectedIndex < 0 || !operation.canInsertVertex(primitive, selectedIndex)) { |
630 |
throw new InvalidEntryException(null); |
631 |
} |
632 |
} else if (str.equalsIgnoreCase("-")) { |
633 |
if (selectedIndex < 0 || !operation.canRemoveVertex(primitive, selectedIndex)) { |
634 |
throw new InvalidEntryException(null); |
635 |
} |
636 |
} |
637 |
} |
638 |
this.action = str;
|
639 |
} else {
|
640 |
if (str.equalsIgnoreCase("z")) { |
641 |
|
642 |
} else {
|
643 |
throw new InvalidEntryException(null); |
644 |
} |
645 |
} |
646 |
} |
647 |
} else if (value instanceof Double) { |
648 |
this.pointToMove = (Point) selectedVertex.cloneGeometry(); |
649 |
this.pointToMove.setCoordinateAt(2, (Double) value); |
650 |
} |
651 |
} |
652 |
} |
653 |
} |
654 |
|
655 |
private Point getVertex(Geometry geometry, Point point, double tolerance) |
656 |
throws GeometryOperationNotSupportedException,
|
657 |
GeometryOperationException, CreateGeometryException { |
658 |
List<Point> vertexesList = getVertexesList(geometry); |
659 |
double min = Double.POSITIVE_INFINITY; |
660 |
Point vertex = null; |
661 |
if (vertexesList != null) { |
662 |
for (Iterator<Point> iterator = vertexesList.iterator(); iterator |
663 |
.hasNext();) { |
664 |
Point point2 = (Point) iterator.next(); |
665 |
double distance = getDistance(point, point2);
|
666 |
if (distance <= tolerance) {
|
667 |
if (distance < min) {
|
668 |
vertex = point2; |
669 |
min = distance; |
670 |
} |
671 |
} |
672 |
} |
673 |
} |
674 |
return vertex;
|
675 |
} |
676 |
|
677 |
private double getDistance(Point p1, Point p2) throws GeometryOperationNotSupportedException, GeometryOperationException, CreateGeometryException{ |
678 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
679 |
if(p1.getDimension()==p2.getDimension()){
|
680 |
return p1.distance(p2);
|
681 |
} else {
|
682 |
Point auxP1 = geomManager.createPoint(p1.getX(), p1.getY(), Geometry.SUBTYPES.GEOM2D);
|
683 |
Point auxP2 = geomManager.createPoint(p2.getX(), p2.getY(), Geometry.SUBTYPES.GEOM2D);
|
684 |
return auxP1.distance(auxP2);
|
685 |
} |
686 |
} |
687 |
|
688 |
private List<Point> getVertexesList(Geometry geometry) throws CreateGeometryException, GeometryOperationNotSupportedException, GeometryOperationException { |
689 |
if (geometry instanceof MultiPrimitive) { |
690 |
MultiPrimitive aggregate = (MultiPrimitive) geometry; |
691 |
List<Point> vertexesList = new ArrayList<Point>(); |
692 |
for (int i = 0; i < aggregate.getPrimitivesNumber(); i++) { |
693 |
Primitive primitive = aggregate.getPrimitiveAt(i); |
694 |
EditVertexOperation operation = |
695 |
EditVertexOperationUtils.getOperation(primitive); |
696 |
if (operation != null) { |
697 |
vertexesList.addAll(operation.getVertexesList(primitive)); |
698 |
} |
699 |
} |
700 |
return vertexesList;
|
701 |
} else if (geometry instanceof Primitive) { |
702 |
Primitive primitive = (Primitive) geometry; |
703 |
EditVertexOperation operation = |
704 |
EditVertexOperationUtils.getOperation(primitive); |
705 |
if (operation != null) { |
706 |
List<Point> vertexesList = operation.getVertexesList(primitive); |
707 |
return vertexesList;
|
708 |
} |
709 |
} |
710 |
return null; |
711 |
} |
712 |
|
713 |
|
714 |
|
715 |
private FeatureSet getGeometryByBuffer(Geometry buffer)
|
716 |
throws DataException {
|
717 |
FeatureQuery queryByGeometry = featureStore.createFeatureQuery(); |
718 |
|
719 |
// Get default SRS of default feature type
|
720 |
IProjection defaultSRS = |
721 |
this.featureStore.getDefaultFeatureType().getDefaultSRS();
|
722 |
|
723 |
// Name of default geometry type
|
724 |
String geomName =
|
725 |
featureStore.getDefaultFeatureType() |
726 |
.getDefaultGeometryAttributeName(); |
727 |
|
728 |
IntersectsGeometryEvaluator iee = |
729 |
new IntersectsGeometryEvaluator(buffer, defaultSRS,
|
730 |
featureStore.getDefaultFeatureType(), geomName); |
731 |
|
732 |
queryByGeometry.setFilter(iee); |
733 |
queryByGeometry.setAttributeNames(null);
|
734 |
return this.featureStore.getFeatureSet(queryByGeometry); |
735 |
} |
736 |
|
737 |
private Geometry getNearestGeometry(final Point point) throws GeometryOperationNotSupportedException, GeometryOperationException, DataException{ |
738 |
double tolerance =
|
739 |
mapContext.getViewPort().toMapDistance(TOLERANCE_PIXELS); |
740 |
Geometry buffer = point.buffer(tolerance); |
741 |
FeatureSet featureSet = getGeometryByBuffer(buffer); |
742 |
double min = Double.POSITIVE_INFINITY; |
743 |
Geometry geometry = null;
|
744 |
|
745 |
DisposableIterator iterator = featureSet.fastIterator(); |
746 |
while (iterator.hasNext()) {
|
747 |
Feature feat = (Feature) iterator.next(); |
748 |
double distance = point.distance(feat.getDefaultGeometry());
|
749 |
if (distance < min){
|
750 |
geometry = feat.getDefaultGeometry(); |
751 |
min = distance; |
752 |
} |
753 |
} |
754 |
iterator.dispose(); |
755 |
return geometry;
|
756 |
} |
757 |
|
758 |
private Geometry getSelectedGeometry() throws DataException { |
759 |
|
760 |
Geometry selectedGeometry = null;
|
761 |
if (this.selection != null && this.selection.getSelectedCount() == 1) { |
762 |
DisposableIterator it = this.selection.fastIterator();
|
763 |
while (it.hasNext()) {
|
764 |
Feature feature = (Feature) it.next(); |
765 |
selectedGeometry = feature.getDefaultGeometry(); |
766 |
} |
767 |
it.dispose(); |
768 |
} |
769 |
return selectedGeometry;
|
770 |
} |
771 |
|
772 |
|
773 |
public Geometry finish() throws FinishServiceException { |
774 |
return null; |
775 |
} |
776 |
|
777 |
public void finishAndStore() throws FinishServiceException { |
778 |
if (this.selection != null) { |
779 |
try {
|
780 |
Geometry selectedGeometry = getSelectedGeometry(); |
781 |
List<Point> vertexesList; |
782 |
vertexesList = getVertexesList(selectedGeometry); |
783 |
if(vertexesList != null){ |
784 |
if(selectedIndex<0){ |
785 |
selectedIndex = getSelectedIndex(vertexesList); |
786 |
} |
787 |
Geometry modifiedGeometry = null;
|
788 |
if (pointToMove != null) { |
789 |
if (selectedIndex >= 0) { |
790 |
modifiedGeometry = |
791 |
this.getModifiedGeometry(selectedGeometry,
|
792 |
selectedIndex, pointToMove); |
793 |
} |
794 |
} else if (action != null){ |
795 |
if(action.equalsIgnoreCase("+")){ |
796 |
modifiedGeometry = |
797 |
this.getInsertVertexGeometry(selectedGeometry, selectedIndex);
|
798 |
|
799 |
} else if(action.equalsIgnoreCase("-")){ |
800 |
modifiedGeometry = this.getRemovedVertexGeometry(selectedGeometry, selectedIndex);
|
801 |
|
802 |
} |
803 |
} |
804 |
DisposableIterator it = null;
|
805 |
|
806 |
try {
|
807 |
it = selection.fastIterator(); |
808 |
|
809 |
while (it.hasNext()) {
|
810 |
Feature feature = (Feature) it.next(); |
811 |
EditableFeature editableFeature = |
812 |
feature.getEditable(); |
813 |
editableFeature.setDefaultGeometry(modifiedGeometry); |
814 |
((EditingProviderServices) getProviderServices()) |
815 |
.updateFeatureInFeatureStore( |
816 |
editableFeature, featureStore); |
817 |
} |
818 |
} catch (BaseException e) {
|
819 |
throw new FinishServiceException(e); |
820 |
} finally {
|
821 |
it.dispose(); |
822 |
} |
823 |
|
824 |
} |
825 |
} catch (BaseException e) {
|
826 |
throw new FinishServiceException(e); |
827 |
} |
828 |
} |
829 |
|
830 |
} |
831 |
|
832 |
private int getSelectedIndex(List<Point> vertexesList) { |
833 |
int selectedIndex = -1; |
834 |
if (vertexesList != null) { |
835 |
int i = 0; |
836 |
if (selectedVertex != null) { |
837 |
for (Iterator<Point> iterator = vertexesList.iterator(); iterator.hasNext();) { |
838 |
Point point = (Point) iterator.next(); |
839 |
if (selectedVertex.equals(point)) {
|
840 |
selectedIndex = i; |
841 |
break;
|
842 |
} |
843 |
i++; |
844 |
} |
845 |
} |
846 |
} |
847 |
return selectedIndex;
|
848 |
} |
849 |
|
850 |
public void start() throws StartServiceException, InvalidEntryException { |
851 |
FeatureSelection selected = null;
|
852 |
if (featureStore != null) { |
853 |
try {
|
854 |
selected = featureStore.getFeatureSelection(); |
855 |
long selectedCount = selected.getSelectedCount();
|
856 |
if(selectedCount==1){ |
857 |
this.selection = selected;
|
858 |
} else {
|
859 |
selected.deselectAll(); |
860 |
} |
861 |
} catch (DataException e) {
|
862 |
throw new StartServiceException(e); |
863 |
} |
864 |
} |
865 |
} |
866 |
|
867 |
public String getName() { |
868 |
return EditVertexEditingProviderFactory.PROVIDER_NAME;
|
869 |
} |
870 |
|
871 |
} |