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