1 /*
2 * WKB4J - WKB reader for geographical mapping toolkits
3 * (C) 2002,2003, David Garnier, dgarnier@users.sourceforge.net
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation,
8 * version 2.1 of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * or visit the web to http://www.gnu.org.
19 *
20 */
21 package org.wkb4j.openmap;
22
23 import org.apache.log4j.Logger;
24 import org.wkb4j.factories.AbstractWKBFactory;
25
26 import com.bbn.openmap.omGraphics.OMGeometryList;
27 import com.bbn.openmap.omGraphics.OMGraphic;
28 import com.bbn.openmap.omGraphics.OMGraphicList;
29 import com.bbn.openmap.omGraphics.OMLine;
30 import com.bbn.openmap.omGraphics.OMPoint;
31 import com.bbn.openmap.omGraphics.OMPoly;
32
33 /***
34 * This class has capability to transform data in the WKB format into
35 * OpenMap objects. The mapping between the WKB format and OpenMap is not perfect because OpenMap
36 * wasn't designed with WKB. To put it simply, they are many possible mappings. Here is the one I choose.
37 * <ul>
38 * <li>
39 * WKBLineStrings and WKBLinearRings are converted into OMLines if they contain 4 points,
40 * OMPolys if they contains more than 4 points. </li>
41 * <li>WKBPoints are converted into OMPoints.</li>
42 * <li>WKBMultiLineString,WKBMultiPolygon,WKBMultiPoints and WKBGeometryCollection are ignored
43 * since they don't have an obvious mapping in OpenMap. However, their content (WKBLineString, WKBPoints and WKBPolygons)
44 * are taken into account and added to the final list.</li>
45 * </ul>
46 * All the generated OMGraphics are
47 * stored in a single OMGraphicList. So this OMGraphicList is really a simple list of
48 * OMLines, OMPolys and OMPoints
49 * <br/>
50 * It would perfectly possible to program a library where OMGraphics could be nested. For example,
51 * a MultiLineString could be represented by an OMGraphicList. It would contain the OMLines emulating each LineString contained
52 * in the MultiLineString. If this MultiLineString is part of a GeometryCollection, the OMGraphicList could be nested into a larger
53 * OMGraphicList.<br/>
54 *
55 * Internally, the OMGraphicList is really an OMGeometryList, since this class is really designed to let users fetch
56 * and project OMGraphics as fast as possible.<br/>
57 *
58 * This class can set the AppObject of generated OMGraphics to an Integer representing the SRID of each feature.<br/>
59 *
60 * You can download the OpenMap library from <a href="http://openmap.bbn.com" target="_blank"> http://openmap.bbn.com</a>.
61 * @author David Garnier
62 *
63 * <br/>Creation date: 10 juil. 2002 22:05:22
64 * @version $Revision: 1.5 $ $Date: 2003/08/02 23:52:18 $
65 */
66
67 /* Note: there is a bug somewhere, related to the AbstractFactory. Basically, the depthPointer is off by one.
68 * This can be the result of not calling advancePointer or rewindPointer enough. This problems arises only
69 * when using this factory, not with the others.*/
70 public class OpenMapFactory extends AbstractWKBFactory {
71 protected static Logger log = Logger.getLogger(OpenMapFactory.class);
72 private final boolean sridAsAppObject;
73 private final OMGraphicList geometries = new OMGeometryList();
74
75 private float[] coordinatesBuffer = new float[0];
76 private OMGraphicList tempGraphicList;
77 private OMGraphicList tempGraphicList2;
78 private OMGraphicList geoColl;
79 private int srid = -1;
80 private Integer sridObject = new Integer(srid);
81
82 private OMGraphic currentGeometry = null;
83
84 // private OMGraphic currentGeometry = null;
85
86 /*** The OMGraphics won't contain the SRID in the AppObject.*/
87 public OpenMapFactory() {
88 this(false);
89 }
90
91 /*** If _sridAsShapeObject is true, the created OMGraphics will have the SRID of the record used as the AppObject.
92 * Otherwise, the SRID is ignored.*/
93 public OpenMapFactory(boolean _sridAsAppObject) {
94 super();
95 sridAsAppObject = _sridAsAppObject;
96 }
97
98 // /***
99 // * @see org.wkb4j.engine.WKBFactory#beginWork()
100 // */
101 // public final void beginWork() {
102 // super.beginWork();
103 // }
104 //
105 // /***
106 // * @see org.wkb4j.engine.WKBFactory#endWork()
107 // */
108 // public final void endWork() {
109 // super.endWork();
110 // }
111 //
112 // /***
113 // * @see org.wkb4j.engine.WKBFactory#abortWork()
114 // */
115 // public final void abortWork() {
116 // super.abortWork();
117 // }
118
119 /***
120 * @see org.wkb4j.engine.WKBFactory#beginUnit()
121 */
122 public final void beginUnit(String[] words, int[] values) {
123 super.beginUnit(words, values);
124
125 if (sridAsAppObject) {
126 int _srid = -2;
127
128 for (int i = 0; i < words.length; i++) {
129 if ("srid".equalsIgnoreCase(words[i])) {
130 srid = values[i];
131
132 break;
133 }
134 }
135
136 if (srid != _srid) {
137 setSrid(srid);
138 }
139 }
140 }
141
142 /***
143 * @see org.wkb4j.engine.WKBFactory#beginUnit()
144 */
145 public final void beginUnit(int _srid) {
146 if (sridAsAppObject && (srid != _srid)) {
147 setSrid(srid);
148 }
149 }
150
151 // /***
152 // * @see org.wkb4j.engine.WKBFactory#abortUnit()
153 // */
154 // public final void abortUnit() {
155 // super.abortUnit();
156 // }
157
158 // /***
159 // * @see org.wkb4j.engine.WKBFactory#beginLineString()
160 // */
161 // public final boolean beginLineString(int count) {
162 // return super.beginLineString(count);
163 // }
164
165 /***
166 * @see org.wkb4j.engine.WKBFactory#beginGeometryCollection()
167 */
168 public final boolean beginGeometryCollection(int count) {
169 if (super.beginGeometryCollection(count)) {
170 geoColl = new OMGraphicList(count);
171 return true;
172 } else {
173 return false;
174 }
175 }
176
177 /***
178 * @see org.wkb4j.engine.WKBFactory#endGeometryCollection()
179 */
180 public final boolean endGeometryCollection() {
181 if (super.endGeometryCollection()) {
182 currentGeometry = geoColl;
183 geoColl = null;
184 return true;
185 } else {
186 return false;
187 }
188 }
189
190 public final boolean newGeometryCollectionComponent() {
191 if (super.newGeometryCollectionComponent()) {
192 geoColl.addOMGraphic(currentGeometry);
193 currentGeometry = null;
194 return true;
195 } else {
196 return false;
197 }
198 }
199 /***
200 * @see org.wkb4j.engine.WKBFactory#abortGeometryCollection()
201 */
202 public final void abortGeometryCollection() {
203 super.abortGeometryCollection();
204 }
205
206 /***
207 * @see org.wkb4j.engine.WKBFactory#endLineString()
208 */
209 public final boolean endLineString() {
210 if (super.endLineString()) {
211 if (coordinatesBuffer.length == 4) {
212 OMLine line = new OMLine();
213 line.setRenderType(OMLine.RENDERTYPE_LATLON);
214 line.setLineType(OMLine.LINETYPE_STRAIGHT);
215 line.setLL(coordinatesBuffer);
216
217 if (sridAsAppObject) {
218 line.setAppObject(sridObject);
219 }
220 if (tempGraphicList == null) {
221 currentGeometry = line;
222 } else {
223 tempGraphicList.add(line);
224 }
225 } else if (
226 (coordinatesBuffer.length > 4)
227 && ((coordinatesBuffer.length % 2) == 0)) {
228 OMPoly poly =
229 new OMPoly(
230 coordinatesBuffer,
231 OMGraphic.DECIMAL_DEGREES,
232 OMGraphic.LINETYPE_STRAIGHT);
233 poly.setRenderType(OMLine.RENDERTYPE_LATLON);
234
235 if (sridAsAppObject) {
236 poly.setAppObject(sridObject);
237 }
238
239 if (tempGraphicList == null) {
240 currentGeometry = poly;
241 } else {
242 tempGraphicList.add(poly);
243 }
244 } else {
245 log.error(
246 "Impossible to parse a buffer of points of size:"
247 + coordinatesBuffer.length);
248
249 return false;
250 }
251
252 coordinatesBuffer = null;
253
254 return true;
255 } else {
256 return false;
257 }
258 }
259
260 // /***
261 // * @see org.wkb4j.engine.WKBFactory#abortLineString()
262 // */
263 // public final void abortLineString() {
264 // super.abortLineString();
265 // coordinatesBuffer = null;
266 // }
267
268 /***
269 * @see org.wkb4j.engine.WKBFactory#beginMultiLineString()
270 */
271 public final boolean beginMultiLineString(int count) {
272 if (super.beginMultiLineString(count)) {
273 tempGraphicList = new OMGraphicList(count);
274 return true;
275 } else {
276 return false;
277 }
278 }
279 /***
280 * @see org.wkb4j.engine.WKBFactory#endMultiLineString()
281 */
282 public final boolean endMultiLineString() {
283 if (super.endMultiLineString()) {
284 currentGeometry = tempGraphicList;
285 return true;
286 } else {
287 return false;
288 }
289 }
290 // /***
291 // * @see org.wkb4j.engine.WKBFactory#abortMultiLineString()
292 // */
293 // public final void abortMultiLineString() {
294 // super.abortMultiLineString();
295 //
296 // }
297 // /***
298 // * @see org.wkb4j.engine.WKBFactory#beginPoint()
299 // */
300 // public final boolean beginPoint() {
301 // return super.beginPoint();
302 // }
303
304 /***
305 * @see org.wkb4j.engine.WKBFactory#endPoint()
306 */
307 public final boolean endPoint() {
308 if (super.endPoint()) {
309 OMPoint point =
310 new OMPoint(coordinatesBuffer[1], coordinatesBuffer[0]);
311
312 if (sridAsAppObject) {
313 point.setAppObject(sridObject);
314 }
315 if (tempGraphicList == null) {
316 currentGeometry = point;
317 } else {
318 tempGraphicList.add(currentGeometry);
319 }
320 return true;
321 } else {
322 return false;
323 }
324 }
325
326 /***
327 * @see org.wkb4j.engine.WKBFactory#abortPoint()
328 */
329 public final void abortPoint() {
330 super.abortPoint();
331 coordinatesBuffer = null;
332 }
333
334 /***
335 * @see org.wkb4j.engine.WKBFactory#beginMultiPoint()
336 */
337 public final boolean beginMultiPoint(int count) {
338 if (super.beginMultiPoint(count)) {
339 tempGraphicList = new OMGraphicList(count);
340 return true;
341 } else {
342 return false;
343 }
344 }
345 /***
346 * @see org.wkb4j.engine.WKBFactory#endMultiPoint()
347 */
348 public final boolean endMultiPoint() {
349 if (super.endMultiPoint()) {
350 currentGeometry = tempGraphicList;
351 return true;
352 } else {
353 return false;
354 }
355 }
356 // /***
357 // * @see org.wkb4j.engine.WKBFactory#abortMultiPoint()
358 // */
359 // public final void abortMultiPoint() {
360 // super.abortMultiPoint();
361 //
362 // }
363 /***
364 * @see org.wkb4j.engine.WKBFactory#beginMultiPolygon()
365 */
366 public final boolean beginMultiPolygon(int count) {
367 if (super.beginMultiPolygon(count)) {
368 tempGraphicList2 = new OMGraphicList(count);
369 return true;
370 } else {
371 return false;
372 }
373 }
374 /***
375 * @see org.wkb4j.engine.WKBFactory#endMultiPolygon()
376 */
377 public final boolean endMultiPolygon() {
378 if (super.endMultiPolygon()) {
379 currentGeometry = tempGraphicList2;
380 return true;
381 } else {
382 return false;
383 }
384 }
385
386 /***
387 * @see org.wkb4j.engine.WKBFactory#abortMultiPolygon()
388 */
389 public final void abortMultiPolygon() {
390 super.abortMultiPolygon();
391
392 }
393
394 /***
395 * @see org.wkb4j.engine.WKBFactory#beginPolygon()
396 */
397 public final boolean beginPolygon(int count) {
398 if (super.beginPolygon(count)) {
399 tempGraphicList = new OMGraphicList(count);
400 return true;
401 } else {
402 return false;
403 }
404 }
405 /***
406 * @see org.wkb4j.engine.WKBFactory#endPolygon()
407 */
408 public final boolean endPolygon() {
409 if (super.endPolygon()) {
410 if (tempGraphicList2 == null) {
411 /* Simple case.*/
412 currentGeometry = tempGraphicList;
413 } else {
414 /* Multi case.*/
415 tempGraphicList2.addOMGraphic(tempGraphicList);
416 }
417 return true;
418 } else {
419 return false;
420 }
421 }
422
423 // /***
424 // * @see org.wkb4j.engine.WKBFactory#abortPolygon()
425 // */
426 // public final void abortPolygon() {
427 // super.abortPolygon();
428 //
429 // }
430
431 /***
432 * @see org.wkb4j.engine.WKBFactory#endLinearRing()
433 */
434 public final boolean endLinearRing() {
435 if (super.endLinearRing()) {
436 OMPoly poly =
437 new OMPoly(
438 coordinatesBuffer,
439 OMGraphic.DECIMAL_DEGREES,
440 OMGraphic.LINETYPE_STRAIGHT);
441 poly.setRenderType(OMLine.RENDERTYPE_LATLON);
442
443 if (sridAsAppObject) {
444 poly.setAppObject(sridObject);
445 }
446 tempGraphicList.add(poly);
447 return true;
448 } else {
449 log.error(
450 "Impossible to parse a buffer of points of size:"
451 + coordinatesBuffer.length);
452 return false;
453 }
454 }
455
456 // /***
457 // * @see org.wkb4j.engine.WKBFactory#abortLinearRing()
458 // */
459 // public final void abortLinearRing() {
460 // super.abortLinearRing();
461 //
462 // }
463
464 /***
465 * @see org.wkb4j.engine.WKBFactory#addPoints(double[])
466 */
467
468 /* Sadly, PostGIS and OpenMap don't represent arrays of points in
469 * the same order. PostGIS is lon,lat,lon,lat while OpenMap is lat,lon,lat,lon.*/
470 public final boolean addPoints(double[] points) {
471 if (super.addPoints(points)) {
472 coordinatesBuffer = new float[points.length];
473
474 for (int i = 0, size = points.length; i < size; i += 2) {
475 coordinatesBuffer[i + 1] = (float) points[i];
476 coordinatesBuffer[i] = (float) points[i + 1];
477 }
478
479 return true;
480 } else {
481 return false;
482 }
483 }
484
485 /*** OpenMap doesn't support 3D points, so the third coordinate is just discarded.
486 * OpenMap encodes coordinates as floats, so there is a possible loss of precision when casting from double to float.
487 * @see org.wkb4j.engine.WKBFactory#addPoints(double[])
488 */
489
490 /* Sadly, PostGIS and OpenMap don't represent arrays of points in
491 * the same order. PostGIS is lon,lat,lon,lat while OpenMap is lat,lon,lat,lon.*/
492 public final boolean addPoints3D(double[] points) {
493 if (super.addPoints3D(points)) {
494 coordinatesBuffer = new float[points.length];
495
496 for (int i = 0, size = points.length; i < size; i += 3) {
497 coordinatesBuffer[i + 1] = (float) points[i];
498 coordinatesBuffer[i] = (float) points[i + 1];
499 }
500
501 return true;
502 } else {
503 return false;
504 }
505 }
506
507 /***
508 * Returns the geometries.
509 * @return ArrayList
510 */
511 public final OMGraphicList getGeometries() {
512 return geometries;
513 }
514
515 /***
516 * Returns the srid.
517 * @return int
518 */
519 public final int getSrid() {
520 return srid;
521 }
522
523 /***
524 * Sets the srid.
525 * @param srid The srid to set
526 */
527 private void setSrid(int srid) {
528 sridObject = new Integer(srid);
529 this.srid = srid;
530 }
531
532 // /***
533 // * Returns the currentGeometry.
534 // * @return OMGraphic
535 // */
536 // public OMGraphic getCurrentGeometry() {
537 // return currentGeometry;
538 // }
539 // /***
540 // * Sets the currentGeometry.
541 // * @param currentGeometry The currentGeometry to set
542 // */
543 // public void setCurrentGeometry(OMGraphic currentGeometry) {
544 // if (sridAsAppObject) {
545 // currentGeometry.setAppObject(sridObject);
546 // }
547 // this.currentGeometry = currentGeometry;
548 // }
549 /***
550 * @see org.wkb4j.factories.AbstractWKBFactory#reset()
551 */
552 public void reset() {
553 geometries.clear();
554 }
555
556 /***
557 * @see org.wkb4j.engine.WKBFactory#endUnit()
558 */
559 public void endUnit() {
560 super.endUnit();
561 geometries.addOMGraphic(currentGeometry);
562 tempGraphicList = null;
563 }
564 }
This page was automatically generated by Maven