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 22 package org.wkb4j.postgis; 23 24 import java.util.ArrayList; 25 26 import org.apache.log4j.Logger; 27 import org.postgis.Geometry; 28 import org.postgis.LineString; 29 import org.postgis.LinearRing; 30 import org.postgis.MultiLineString; 31 import org.postgis.MultiPoint; 32 import org.postgis.MultiPolygon; 33 import org.postgis.Point; 34 import org.postgis.Polygon; 35 import org.wkb4j.engine.WKBFactory3D; 36 import org.wkb4j.factories.AbstractWKBFactory; 37 38 /***This class has the capability to transform data in the WKB format into 39 * PostGIS objects. Since they conforms to the 40 * <i><a href="http://www.opengis.org/techno/specs.htm" target="_blank">Simple Features Specification for SQL</a><i> 41 * published by the <i><a href="http://www.opengis.org/index.htm" target="_blank">Open GIS Consortium</a><i>, 42 * the mapping is straighforward: each feature described in the WKB is mapped to a corresponding feature in 43 * PostGIS. 44 * 45 * 46 * 47 * Implementation notes:<ul><li> For efficiency, this class uses raw arrays. If performance isn't an issue 48 * for you, you can built a cleaner but still fast implementation using the 49 * <a href="http://trove4j.sourceforge.net/" target="_blank">GNU Trove</a> library of Collections. 50 * <a href="http://trove4j.sourceforge.net/" target="_blank">Check it out!</a></li> 51 * <li> This class is completly thread-UNSAFE. It isn't designed to receive events from multiple Parsers at the same time. 52 * 53 * </ul> 54 * @author David Garnier 55 * 56 * <br/>Creation date: 6 juil. 2002 23:10:29 57 * @version $Revision: 1.3 $ $Date: 2003/07/28 22:21:26 $ 58 */ 59 public class PostGISFactory 60 extends AbstractWKBFactory 61 implements WKBFactory3D { 62 protected static Logger Log = Logger.getLogger(PostGISFactory.class); 63 64 /*** Stores a array of Point objects.*/ 65 private Point[] coordinatesBuffer = null; 66 /*** Stores a array of Point objects, for MultiPoint.*/ 67 private Point[] pointsBuffer = null; 68 /*** Stores a array of LineString objects.*/ 69 private LineString[] lineStringBuffer = null; 70 /*** Stores a array of Polygon objects.*/ 71 private Polygon[] polygonBuffer = null; 72 /*** Stores a array of LinearRing objects.*/ 73 private LinearRing[] linearRingBuffer = null; 74 75 private Geometry[] geometryBuffer = null; 76 77 /*** Points to the next free slot in the lineStringBuffer.*/ 78 private volatile int lineStringPointer = 0; 79 /*** Points to the next free slot in the polygonBuffer.*/ 80 private volatile int polygonPointer = 0; 81 /*** Points to the next free slot in the linearRingBuffer.*/ 82 private volatile int linearRingPointer = 0; 83 /*** Points to the next free slot in the pointsBuffer.*/ 84 private volatile int pointsPointer = 0; 85 /*** Points to the next free slot in the pointsBuffer.*/ 86 private volatile int geometryPointer = 0; 87 88 /*** The SRID of the top-level Geometry being created.*/ 89 private int srid = -1; 90 91 /*** Keeps a list of all the object created by this Factory.*/ 92 private final ArrayList geometries = new ArrayList(); 93 94 /*** The Geometry being constructed now.*/ 95 private Geometry currentGeometry = null; 96 97 /*** Construct a JTSFactory.*/ 98 public PostGISFactory() { 99 super(); 100 } 101 102 // /*** 103 // * @see org.wkb4j.engine.WKBFactory#beginWork() 104 // */ 105 // public final void beginWork() { 106 // super.beginWork(); 107 // } 108 // 109 // /*** 110 // * @see org.wkb4j.engine.WKBFactory#endWork() 111 // */ 112 // public final void endWork() { 113 // super.endWork(); 114 // } 115 // 116 // /*** 117 // * @see org.wkb4j.engine.WKBFactory#abortWork() 118 // */ 119 // public final void abortWork() { 120 // super.abortWork(); 121 // 122 // } 123 124 // /*** 125 // * @see org.wkb4j.engine.WKBFactory#beginUnit() 126 // */ 127 // public final void beginUnit(int srid) { 128 // super.beginUnit(srid); 129 // } 130 131 /*** 132 * @see org.wkb4j.engine.WKBFactory#endUnit() 133 */ 134 public final void endUnit() { 135 super.endUnit(); 136 geometries.add(currentGeometry); 137 138 //There is no point of setting srid to another value because all values are correct. We could try to make sure that the value is invaled somehow.*/ 139 } 140 141 // /*** 142 // * @see org.wkb4j.engine.WKBFactory#abortUnit() 143 // */ 144 // public final void abortUnit() { 145 // super.abortUnit(); 146 // } 147 148 /*** 149 * @see org.wkb4j.engine.WKBFactory#beginGeometryCollection() 150 */ 151 public final boolean beginGeometryCollection(int count) { 152 if (super.beginGeometryCollection(count)) { 153 geometryBuffer = new Geometry[count]; 154 return true; 155 } else { 156 return false; 157 } 158 } 159 160 /*** 161 * @see org.wkb4j.engine.WKBFactory#endGeometryCollection() 162 */ 163 public final boolean endGeometryCollection() { 164 if (super.endGeometryCollection()) { 165 currentGeometry = new GeometryCollection(geometryBuffer); 166 geometryBuffer = null; 167 geometryPointer = 0; 168 return true; 169 } else { 170 return false; 171 } 172 } 173 174 public boolean newGeometryCollectionComponent() { 175 if (super.newGeometryCollectionComponent()) { 176 geometryBuffer[geometryPointer] = currentGeometry; 177 geometryPointer++; 178 currentGeometry = null; 179 return true; 180 } else { 181 return false; 182 } 183 184 } 185 /*** 186 * @see org.wkb4j.engine.WKBFactory#abortGeometryCollection() 187 */ 188 public final void abortGeometryCollection() { 189 super.abortGeometryCollection(); 190 } 191 192 /*** 193 * @see org.wkb4j.engine.WKBFactory#beginLineString() 194 */ 195 // public final boolean beginLineString(int count) { 196 // if (super.beginLineString(count)) { 197 // if (lineStringBuffer == null) { 198 // /* This is the case only if LineString was called directly. Therefore in this case, we need only one slot.*/ 199 // lineStringBuffer = new LineString[1]; 200 // } 201 // return true; 202 // } else { 203 // return false; 204 // } 205 // 206 // } 207 208 /*** Constructs a LineString using the current buffer of Points, 209 * resets the Points buffer, add the LineString to the lineStringBuffer 210 * and defines the new LineString as the currentGeometry. 211 * @see org.wkb4j.engine.WKBFactory#endLineString() 212 */ 213 public final boolean endLineString() { 214 if (super.endLineString()) { 215 LineString ls = new LineString(coordinatesBuffer); 216 if (lineStringBuffer != null) { 217 lineStringBuffer[lineStringPointer] = ls; 218 lineStringPointer++; 219 } 220 currentGeometry = ls; 221 coordinatesBuffer = null; 222 return true; 223 } else { 224 return false; 225 } 226 } 227 228 /*** 229 * @see org.wkb4j.engine.WKBFactory#abortLineString() 230 */ 231 public final void abortLineString() { 232 super.abortLineString(); 233 coordinatesBuffer = null; 234 } 235 236 /*** Constructs a new array of LineStrings with the supplied number of elements. 237 * @see org.wkb4j.engine.WKBFactory#beginMultiLineString() 238 */ 239 public final boolean beginMultiLineString(int count) { 240 if (super.beginMultiLineString(count)) { 241 lineStringBuffer = new LineString[count]; 242 return true; 243 } else { 244 return false; 245 } 246 } 247 248 /*** Constructs a MultiLineString using the current buffer of LineStrings, 249 * resets the LineStrings buffer 250 * and defines the new MultiLineString as the currentGeometry. 251 * @see org.wkb4j.engine.WKBFactory#endMultiLineString() 252 */ 253 public final boolean endMultiLineString() { 254 if (super.endMultiLineString()) { 255 MultiLineString mls = new MultiLineString(lineStringBuffer); 256 currentGeometry = mls; 257 lineStringBuffer = null; 258 lineStringPointer = 0; 259 return true; 260 } else { 261 return false; 262 } 263 } 264 265 // /*** 266 // * @see org.wkb4j.engine.WKBFactory#abortMultiLineString() 267 // */ 268 // public final void abortMultiLineString() { 269 // super.abortMultiLineString(); 270 // 271 // } 272 273 // 274 // /*** 275 // * @see org.wkb4j.engine.WKBFactory#beginPoint() 276 // */ 277 // public final boolean beginPoint() { 278 // return super.beginPoint(); 279 // } 280 281 /*** Constructs a Point using the current buffer of Coordinates, 282 * resets the Coordinates buffer, add the Point to the PointBuffer 283 * and defines the new Point as the currentGeometry. 284 * @see org.wkb4j.engine.WKBFactory#endPoint() 285 */ 286 public final boolean endPoint() { 287 if (super.endPoint()) { 288 if (coordinatesBuffer.length != 1) { 289 Log.error( 290 "Trying to create a new Point with more than one Coordinates."); 291 return false; 292 } 293 294 if (pointsBuffer != null) { 295 pointsBuffer[pointsPointer] = coordinatesBuffer[0]; 296 pointsPointer++; 297 } 298 currentGeometry = coordinatesBuffer[0]; 299 coordinatesBuffer = null; 300 return true; 301 } else { 302 return false; 303 } 304 } 305 306 /*** 307 * @see org.wkb4j.engine.WKBFactory#abortPoint() 308 */ 309 public final void abortPoint() { 310 super.abortPoint(); 311 coordinatesBuffer = null; 312 } 313 314 /*** Constructs a new array of Points with the supplied number of elements. 315 * @see org.wkb4j.engine.WKBFactory#beginMultiPoint() 316 */ 317 public final boolean beginMultiPoint(int count) { 318 if (super.beginMultiPoint(count)) { 319 pointsBuffer = new Point[count]; 320 return true; 321 } else { 322 return false; 323 } 324 } 325 326 /*** Constructs a MultiPoint using the current buffer of Points, 327 * resets the Points buffer 328 * and defines the new MultiPoint as the currentGeometry. 329 * @see org.wkb4j.engine.WKBFactory#endMultiPoint() 330 */ 331 public final boolean endMultiPoint() { 332 if (super.endMultiPoint()) { 333 MultiPoint mls = new MultiPoint(pointsBuffer); 334 currentGeometry = mls; 335 pointsBuffer = null; 336 pointsPointer = 0; 337 return true; 338 } else { 339 return false; 340 } 341 } 342 343 // /*** 344 // * @see org.wkb4j.engine.WKBFactory#abortMultiPoint() 345 // */ 346 // public final void abortMultiPoint() { 347 // super.abortMultiPoint(); 348 // 349 // } 350 351 /***Constructs a new array of Polygons with the supplied number of elements. 352 * @see org.wkb4j.engine.WKBFactory#beginMultiPolygon() 353 */ 354 public final boolean beginMultiPolygon(int count) { 355 if (super.beginMultiPolygon(count)) { 356 polygonBuffer = new Polygon[count]; 357 return true; 358 } else { 359 return false; 360 } 361 } 362 363 /***Constructs a MultiPolygon using the current buffer of LinearRings, 364 * resets the LinearRings buffer 365 * and defines the new LineString as the currentGeometry. 366 * @see org.wkb4j.engine.WKBFactory#endMultiPolygon() 367 */ 368 public final boolean endMultiPolygon() { 369 if (super.endMultiPolygon()) { 370 MultiPolygon mls = new MultiPolygon(polygonBuffer); 371 currentGeometry = mls; 372 polygonBuffer = null; 373 polygonPointer = 0; 374 return true; 375 } else { 376 return false; 377 } 378 } 379 380 // /*** 381 // * @see org.wkb4j.engine.WKBFactory#abortMultiPolygon() 382 // */ 383 // public final void abortMultiPolygon() { 384 // super.abortMultiPolygon(); 385 // 386 // } 387 388 /*** Constructs a new array of LinearRings with the supplied number of elements. 389 * @see org.wkb4j.engine.WKBFactory#beginPolygon() 390 */ 391 public final boolean beginPolygon(int count) { 392 if (super.beginPolygon(count)) { 393 linearRingBuffer = new LinearRing[count]; 394 return true; 395 } else { 396 return false; 397 } 398 } 399 400 /***Constructs a Polygon using the current buffer of LinearRings, 401 * resets the LinearRings buffer, add the Polygon to the polygonBuffer 402 * and defines the new Polygon as the currentGeometry. If the LinearRings buffer 403 * contains only one LinearRing, the Polygon is constructed with only one ring. 404 * If the LinearRings buffer 405 * contains more than one LinearRing, the Polygon is constructed with the first LinearRing as the 406 * exterior ring and the others LinearRings as the interior rings. 407 * @see org.wkb4j.engine.WKBFactory#endPolygon() 408 */ 409 public final boolean endPolygon() { 410 if (super.endPolygon()) { 411 Polygon ls = new Polygon(linearRingBuffer); 412 413 if (polygonBuffer != null) { 414 polygonBuffer[polygonPointer] = ls; 415 polygonPointer++; 416 } 417 418 currentGeometry = ls; 419 linearRingBuffer = null; 420 linearRingPointer = 0; 421 return true; 422 } else { 423 return false; 424 } 425 } 426 427 // /*** 428 // * @see org.wkb4j.engine.WKBFactory#abortPolygon() 429 // */ 430 // public final void abortPolygon() { 431 // super.abortPolygon(); 432 // } 433 434 // /*** Constructs a new array of Points with the supplied number of elements. 435 // * @see org.wkb4j.engine.WKBFactory#beginLinearRing() 436 // */ 437 // public final boolean beginLinearRing(int count) { 438 // if (super.beginLinearRing(count)) { 439 // coordinatesBuffer = new Point[count]; 440 // return true; 441 // } else { 442 // return false; 443 // } 444 // } 445 446 /*** Constructs a LinearRing using the current buffer of Points, 447 * resets the Points buffer, add the LinearRing to the linearRingBuffer 448 * and defines the new LineString as the currentGeometry. 449 * @see org.wkb4j.engine.WKBFactory#endLinearRing() 450 */ 451 public final boolean endLinearRing() { 452 if (super.endLinearRing()) { 453 linearRingBuffer[linearRingPointer] = 454 new LinearRing(coordinatesBuffer); 455 linearRingPointer++; 456 coordinatesBuffer = null; 457 return true; 458 } else { 459 return false; 460 } 461 } 462 463 // /*** 464 // * @see org.wkb4j.engine.WKBFactory#abortLinearRing() 465 // */ 466 // public final void abortLinearRing() { 467 // super.abortLinearRing(); 468 // 469 // } 470 471 /*** 472 * Transforms an array of Points in an array of Points. 473 * @see org.wkb4j.engine.WKBFactory#addPoints(double[]) 474 */ 475 public final boolean addPoints(double[] points) { 476 if (super.addPoints(points)) { 477 coordinatesBuffer = new Point[points.length >> 1]; 478 for (int i = 0, size = points.length; i < size; i += 2) { 479 coordinatesBuffer[i >> 1] = new Point(points[i], points[i + 1]); 480 } 481 return true; 482 } else { 483 return false; 484 } 485 } 486 487 /*** 488 * Transforms an array of doubles into an array of 3D Point objects. 489 * @see org.wkb4j.engine.WKBFactory#addPoints(double[]) 490 */ 491 public final boolean addPoints3D(double[] points) { 492 if (super.addPoints3D(points)) { 493 coordinatesBuffer = new Point[points.length / 3]; 494 for (int i = 0, size = points.length; i < size; i += 3) { 495 coordinatesBuffer[i >> 1] = 496 new Point(points[i], points[i + 1], points[i + 2]); 497 } 498 return true; 499 } else { 500 return false; 501 } 502 } 503 504 /*** 505 * Returns the geometries. 506 * @return ArrayList 507 */ 508 public final ArrayList getGeometries() { 509 geometries.trimToSize(); 510 return geometries; 511 } 512 513 /*** 514 * @see org.wkb4j.factories.AbstractWKBFactory#reset() 515 */ 516 public void reset() { 517 geometries.clear(); 518 519 } 520 521 }

This page was automatically generated by Maven