View Javadoc
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