svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.jts / src / main / java / org / gvsig / fmap / geom / jts / coerce / CoerceToGeometry.java @ 45673
History | View | Annotate | Download (15 KB)
1 | 42260 | fdiaz | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | *
|
||
4 | * Copyright (C) 2007-2013 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 3
|
||
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.fmap.geom.jts.coerce; |
||
25 | |||
26 | 45673 | jjdelcerro | import java.util.Iterator; |
27 | import java.util.logging.Level; |
||
28 | import java.util.logging.Logger; |
||
29 | 45425 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
30 | 42260 | fdiaz | import org.gvsig.fmap.geom.Geometry; |
31 | 45673 | jjdelcerro | import org.gvsig.fmap.geom.GeometryCoercionContext; |
32 | import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_DONTCONVERT; |
||
33 | import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_NULL; |
||
34 | import static org.gvsig.fmap.geom.GeometryCoercionContext.MODE_ONERROR_THROW; |
||
35 | 42260 | fdiaz | import org.gvsig.fmap.geom.GeometryLocator; |
36 | import org.gvsig.fmap.geom.GeometryManager; |
||
37 | 45673 | jjdelcerro | import org.gvsig.fmap.geom.aggregate.MultiLine; |
38 | import org.gvsig.fmap.geom.aggregate.MultiPoint; |
||
39 | import org.gvsig.fmap.geom.aggregate.MultiPolygon; |
||
40 | import org.gvsig.fmap.geom.jts.AbstractGeometry; |
||
41 | import org.gvsig.fmap.geom.operation.GeometryOperationException; |
||
42 | import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
||
43 | import org.gvsig.fmap.geom.primitive.Line; |
||
44 | import org.gvsig.fmap.geom.primitive.Point; |
||
45 | import org.gvsig.fmap.geom.primitive.Polygon; |
||
46 | import org.gvsig.fmap.geom.primitive.Primitive; |
||
47 | import org.gvsig.fmap.geom.type.GeometryType; |
||
48 | 44669 | jjdelcerro | import org.gvsig.tools.dataTypes.AbstractCoercion; |
49 | 42260 | fdiaz | import org.gvsig.tools.dataTypes.CoercionException; |
50 | 44669 | jjdelcerro | import org.gvsig.tools.dataTypes.CoercionContext; |
51 | 42260 | fdiaz | |
52 | /**
|
||
53 | * Convert a object to Geometry.
|
||
54 | 44432 | jjdelcerro | *
|
55 | * Support convert: - Geometry to Geometry (do nothing) - WKB (byte[]) to
|
||
56 | * Geometry - WKT (String/toString) to Geometry
|
||
57 | *
|
||
58 | *
|
||
59 | 42260 | fdiaz | * @author gvSIG Team
|
60 | * @version $Id$
|
||
61 | 44432 | jjdelcerro | *
|
62 | 42260 | fdiaz | */
|
63 | 44432 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
64 | 44669 | jjdelcerro | public class CoerceToGeometry extends AbstractCoercion { |
65 | 42260 | fdiaz | |
66 | 45673 | jjdelcerro | private static GeometryManager manager = null; |
67 | |||
68 | @Override
|
||
69 | public Object coerce(Object value, CoercionContext context) throws CoercionException { |
||
70 | if (value == null) { |
||
71 | return value;
|
||
72 | } |
||
73 | int mode = MODE_ONERROR_NULL;
|
||
74 | Geometry geom; |
||
75 | GeometryType targetGeometryType = null;
|
||
76 | Geometry sourcegeom = null;
|
||
77 | try {
|
||
78 | // TODO: descomentarizar para que tengan efecto los cambios.
|
||
79 | // if ( context instanceof GeometryCoercionContext) {
|
||
80 | // GeometryCoercionContext geomContext = (GeometryCoercionContext) context;
|
||
81 | // targetGeometryType = geomContext.getGeometryType();
|
||
82 | // mode = geomContext.getMode();
|
||
83 | // }
|
||
84 | |||
85 | if ( value instanceof Geometry ) { |
||
86 | geom = (Geometry) value; |
||
87 | } else {
|
||
88 | if (value instanceof byte[]) { |
||
89 | geom = getManager().createFrom((byte[]) value); |
||
90 | } else {
|
||
91 | String wkt = value.toString();
|
||
92 | if (StringUtils.isBlank(wkt)) {
|
||
93 | return null; |
||
94 | } |
||
95 | geom = getManager().createFrom(value.toString()); |
||
96 | } |
||
97 | if (geom == null) { |
||
98 | // Can't parse from WKB/WKT
|
||
99 | switch(mode) {
|
||
100 | case MODE_ONERROR_NULL:
|
||
101 | case MODE_ONERROR_DONTCONVERT:
|
||
102 | return null; |
||
103 | case MODE_ONERROR_THROW:
|
||
104 | default:
|
||
105 | throw new CoercionException(); |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | if ( targetGeometryType==null) { |
||
110 | return geom;
|
||
111 | } |
||
112 | sourcegeom = geom; |
||
113 | if (geom.getGeometryType().equals(targetGeometryType)) {
|
||
114 | return geom;
|
||
115 | } |
||
116 | switch (targetGeometryType.getType()) {
|
||
117 | case Geometry.TYPES.MULTIPOINT:
|
||
118 | geom = this.convertToMultipoint(targetGeometryType, geom);
|
||
119 | break;
|
||
120 | case Geometry.TYPES.MULTILINE:
|
||
121 | geom = this.convertToMultiline(targetGeometryType, geom);
|
||
122 | break;
|
||
123 | case Geometry.TYPES.MULTIPOLYGON:
|
||
124 | geom = this.convertToMultipolygon(targetGeometryType, geom);
|
||
125 | break;
|
||
126 | case Geometry.TYPES.POINT:
|
||
127 | geom = this.convertToPoint(targetGeometryType, geom);
|
||
128 | break;
|
||
129 | case Geometry.TYPES.LINE:
|
||
130 | geom = this.convertToLine(targetGeometryType, geom);
|
||
131 | break;
|
||
132 | case Geometry.TYPES.POLYGON:
|
||
133 | geom = this.convertToPolygon(targetGeometryType, geom);
|
||
134 | break;
|
||
135 | case Geometry.TYPES.GEOMETRY:
|
||
136 | geom = this.convertToGeometry(targetGeometryType, geom);
|
||
137 | break;
|
||
138 | default:
|
||
139 | geom = null;
|
||
140 | break;
|
||
141 | } |
||
142 | if (geom != null) { |
||
143 | // Return converted geometry
|
||
144 | return geom;
|
||
145 | } |
||
146 | switch(mode) {
|
||
147 | case MODE_ONERROR_NULL:
|
||
148 | return null; |
||
149 | case MODE_ONERROR_DONTCONVERT:
|
||
150 | return sourcegeom;
|
||
151 | case MODE_ONERROR_THROW:
|
||
152 | default:
|
||
153 | throw new CoercionException(); |
||
154 | } |
||
155 | } catch (Exception e) { |
||
156 | switch(mode) {
|
||
157 | case MODE_ONERROR_NULL:
|
||
158 | return null; |
||
159 | case MODE_ONERROR_DONTCONVERT:
|
||
160 | return sourcegeom;
|
||
161 | case MODE_ONERROR_THROW:
|
||
162 | default:
|
||
163 | throw new CoercionException(); |
||
164 | } |
||
165 | } |
||
166 | 44432 | jjdelcerro | } |
167 | 45673 | jjdelcerro | |
168 | private static GeometryManager getManager() { |
||
169 | if (manager == null) { |
||
170 | manager = GeometryLocator.getGeometryManager(); |
||
171 | } |
||
172 | return manager;
|
||
173 | } |
||
174 | |||
175 | private Geometry convertToMultipoint(GeometryType geometryType, Geometry geom) {
|
||
176 | try {
|
||
177 | MultiPoint target = null;
|
||
178 | switch (geom.getType()) {
|
||
179 | case Geometry.TYPES.POINT:
|
||
180 | target = (MultiPoint) geometryType.create(); |
||
181 | target.addPoint((Point) geom);
|
||
182 | break;
|
||
183 | case Geometry.TYPES.LINE:
|
||
184 | if( geometryType.getSubType() == geom.getGeometryType().getSubType() ) {
|
||
185 | target = ((Line) geom).toPoints();
|
||
186 | } else {
|
||
187 | target = (MultiPoint) geometryType.create(); |
||
188 | for (Point point : convertPoints(geometryType, ((Line) geom).toPoints().iterator())) { |
||
189 | |||
190 | } |
||
191 | target.addPoint((Point) geom);
|
||
192 | } |
||
193 | break;
|
||
194 | case Geometry.TYPES.POLYGON:
|
||
195 | target = ((Polygon) geom).toPoints();
|
||
196 | break;
|
||
197 | case Geometry.TYPES.MULTILINE:
|
||
198 | target = ((MultiLine) geom).toPoints(); |
||
199 | break;
|
||
200 | case Geometry.TYPES.MULTIPOLYGON:
|
||
201 | target = ((MultiPolygon) geom).toPoints(); |
||
202 | break;
|
||
203 | } |
||
204 | return target;
|
||
205 | } catch (Exception ex) { |
||
206 | 45425 | jjdelcerro | return null; |
207 | } |
||
208 | 44669 | jjdelcerro | } |
209 | 42260 | fdiaz | |
210 | 45673 | jjdelcerro | private Geometry convertToMultiline(GeometryType geometryType, Geometry geom) {
|
211 | try {
|
||
212 | MultiLine target = null;
|
||
213 | switch (geom.getType()) {
|
||
214 | case Geometry.TYPES.LINE:
|
||
215 | target = (MultiLine) geometryType.create(); |
||
216 | target.addPrimitive((Primitive) geom); |
||
217 | break;
|
||
218 | case Geometry.TYPES.POLYGON:
|
||
219 | target = (MultiLine) geometryType.create(); |
||
220 | target.addPrimitive((Primitive) ((Polygon) geom).toLines());
|
||
221 | break;
|
||
222 | case Geometry.TYPES.MULTIPOLYGON:
|
||
223 | target = (MultiLine) geometryType.create(); |
||
224 | for (Geometry polygon : ((MultiPolygon) geom)) {
|
||
225 | target.addPrimitive((Primitive) ((Polygon) polygon).toLines());
|
||
226 | } |
||
227 | break;
|
||
228 | } |
||
229 | return target;
|
||
230 | } catch (Exception ex) { |
||
231 | return null; |
||
232 | } |
||
233 | } |
||
234 | 44669 | jjdelcerro | |
235 | 45673 | jjdelcerro | private Geometry convertToMultipolygon(GeometryType geometryType, Geometry geom) {
|
236 | try {
|
||
237 | MultiPolygon target = null;
|
||
238 | switch (geom.getType()) {
|
||
239 | case Geometry.TYPES.LINE:
|
||
240 | target = (MultiPolygon) geometryType.create(); |
||
241 | Polygon polygon = getManager().createPolygon(geometryType.getSubType());
|
||
242 | for (Point point : (Line)geom ) { |
||
243 | polygon.addVertex(point); |
||
244 | } |
||
245 | if( !polygon.isClosed() ) {
|
||
246 | polygon.addVertex(polygon.getVertex(0));
|
||
247 | } |
||
248 | target.addPrimitive(polygon); |
||
249 | break;
|
||
250 | |||
251 | case Geometry.TYPES.POLYGON:
|
||
252 | target = (MultiPolygon) geometryType.create(); |
||
253 | target.addPrimitive((Primitive) ((Polygon) geom));
|
||
254 | break;
|
||
255 | } |
||
256 | return target;
|
||
257 | } catch (Exception ex) { |
||
258 | return null; |
||
259 | } |
||
260 | } |
||
261 | |||
262 | private Geometry convertToPoint(GeometryType geometryType, Geometry geom) {
|
||
263 | try {
|
||
264 | Point target = null; |
||
265 | switch (geom.getType()) {
|
||
266 | case Geometry.TYPES.MULTIPOINT:
|
||
267 | MultiPoint multi = (MultiPoint)geom; |
||
268 | if( multi.getPrimitivesNumber()==1 ) { |
||
269 | target = (Point) multi.getPrimitiveAt(0); |
||
270 | } |
||
271 | break;
|
||
272 | |||
273 | } |
||
274 | return target;
|
||
275 | } catch (Exception ex) { |
||
276 | return null; |
||
277 | } |
||
278 | } |
||
279 | |||
280 | private Geometry convertToLine(GeometryType geometryType, Geometry geom) {
|
||
281 | try {
|
||
282 | Line target = null; |
||
283 | MultiLine multiline; |
||
284 | MultiPolygon multipolygon; |
||
285 | switch (geom.getType()) {
|
||
286 | case Geometry.TYPES.MULTILINE:
|
||
287 | multiline = (MultiLine)geom; |
||
288 | if( multiline.getPrimitivesNumber()==1 ) { |
||
289 | target = (Line) multiline.getPrimitiveAt(0); |
||
290 | } |
||
291 | break;
|
||
292 | case Geometry.TYPES.POLYGON:
|
||
293 | multiline = ((Polygon)geom).toLines();
|
||
294 | if( multiline.getPrimitivesNumber()==1 ) { |
||
295 | target = (Line) multiline.getPrimitiveAt(0); |
||
296 | } |
||
297 | break;
|
||
298 | case Geometry.TYPES.MULTIPOLYGON:
|
||
299 | multipolygon = (MultiPolygon)geom; |
||
300 | if( multipolygon.getPrimitivesNumber()==1 ) { |
||
301 | multiline = multipolygon.getPrimitiveAt(0).toLines();
|
||
302 | if( multiline.getPrimitivesNumber()==1 ) { |
||
303 | target = (Line) multiline.getPrimitiveAt(0); |
||
304 | } |
||
305 | } |
||
306 | break;
|
||
307 | } |
||
308 | return target;
|
||
309 | } catch (Exception ex) { |
||
310 | return null; |
||
311 | } |
||
312 | } |
||
313 | |||
314 | private Geometry convertToPolygon(GeometryType geometryType, Geometry geom) {
|
||
315 | try {
|
||
316 | Polygon target = null; |
||
317 | switch (geom.getType()) {
|
||
318 | case Geometry.TYPES.LINE:
|
||
319 | target = (Polygon) geometryType.create();
|
||
320 | for (Point point : (Line)geom ) { |
||
321 | target.addVertex(point); |
||
322 | } |
||
323 | if( !target.isClosed() ) {
|
||
324 | target.addVertex(target.getVertex(0));
|
||
325 | } |
||
326 | break;
|
||
327 | case Geometry.TYPES.MULTILINE:
|
||
328 | MultiLine multiline = (MultiLine)geom; |
||
329 | if( multiline.getPrimitivesNumber()==1 ) { |
||
330 | target = (Polygon) geometryType.create();
|
||
331 | for (Point point : (Line) multiline.getPrimitiveAt(0) ) { |
||
332 | target.addVertex(point); |
||
333 | } |
||
334 | if( !target.isClosed() ) {
|
||
335 | target.addVertex(target.getVertex(0));
|
||
336 | } |
||
337 | } |
||
338 | break;
|
||
339 | case Geometry.TYPES.MULTIPOLYGON:
|
||
340 | MultiPolygon multipolygon = (MultiPolygon)geom; |
||
341 | if( multipolygon.getPrimitivesNumber()==1 ) { |
||
342 | target = (Polygon) multipolygon.getPrimitiveAt(0); |
||
343 | } |
||
344 | break;
|
||
345 | } |
||
346 | return target;
|
||
347 | } catch (Exception ex) { |
||
348 | return null; |
||
349 | } |
||
350 | } |
||
351 | |||
352 | private Geometry convertToGeometry(GeometryType geometryType, Geometry geom) {
|
||
353 | try {
|
||
354 | if( geom instanceof AbstractGeometry ) { |
||
355 | ((AbstractGeometry)geom).setGeometryType(geometryType); |
||
356 | return geom;
|
||
357 | } |
||
358 | return null; |
||
359 | } catch (Exception ex) { |
||
360 | return null; |
||
361 | } |
||
362 | } |
||
363 | |||
364 | private Iterable<Point> convertPoints(GeometryType geometryType, Iterator<Geometry> pointIterator) { |
||
365 | Iterable<Point> iterable = () -> { |
||
366 | Iterator<Point> iterator = new Iterator<Point>() { |
||
367 | @Override
|
||
368 | public boolean hasNext() { |
||
369 | return pointIterator.hasNext();
|
||
370 | } |
||
371 | |||
372 | @Override
|
||
373 | public Point next() { |
||
374 | Point sourcePoint = (Point) pointIterator.next(); |
||
375 | if( geometryType.hasZ() ) {
|
||
376 | if( geometryType.hasM() ) {
|
||
377 | return sourcePoint.force3DM();
|
||
378 | } else {
|
||
379 | return (Point) sourcePoint.force3D(); |
||
380 | } |
||
381 | } else if( geometryType.hasM() ) { |
||
382 | return sourcePoint.force2DM();
|
||
383 | } else {
|
||
384 | try {
|
||
385 | return (Point) sourcePoint.force2D(); |
||
386 | } catch (Exception ex) { |
||
387 | throw new RuntimeException(ex); |
||
388 | } |
||
389 | } |
||
390 | } |
||
391 | }; |
||
392 | return iterator;
|
||
393 | }; |
||
394 | return iterable;
|
||
395 | } |
||
396 | |||
397 | |||
398 | 42260 | fdiaz | } |