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.engine;
23
24 import java.io.IOException;
25
26 import org.apache.log4j.Logger;
27
28 /***
29 * Generate events from the submitted array of bytes holding binary data in the Well-Known Binary format.
30 * It generates a beginGeometry event when it sees the beginning of a given Geometry,
31 * an endGeometry event when it sees the end of a given Geometry, and an abortGeometry
32 * event if something happens that makes the completion of the current Geometry impossible.
33 * <br/>Points are treated differently from other Geometries: all the points in a Geometry are collected into a single
34 * array of byte and passed to the WKBFactory all at once.
35 *
36 * Events are nested, meaning that for a classical MultiLineString element with two LineStrings
37 * made of respectively 3 and 2 Points each, the following events will occur:
38 *
39 * <code>
40 * <ul>
41 * <li> beginWork()</li>
42 * <li> ...</li>
43 * <li> beginUnit()
44 * <ul>
45 * <li>beginMultiLineString(2)
46 * <ul>
47 * <li>beginLineString(3)</li>
48 * <li>addPoints(points)</li>
49 * <li>endLineString()</li>
50 * <li>beginLineString(2)</li>
51 * <li>addPoints(points)</li>
52 * <li>endLineString()</li>
53 * </ul>
54 * </li>
55 * <li>endMultiLineString()</li>
56 * </ul>
57 * <li> endUnit()</li>
58 * <li> ...</li>
59 * <li> endWork()</li>
60 * </ul>
61 * </code>
62 * <br/>
63 *
64 * The basic idea is to provide the author of each factory with as much freedom as possible while
65 * allowing for strong performance.
66 *
67 * wkbByteOrder aren't taken into account because will rely on the database to provide the data in the Big-Endian
68 * format (MSB, Most Significant Byte), the Endian used in Java.
69 *
70 * <br/> Unlike the WKBParser, the WKBParser3D can handle 3D points as specified in:
71 * <br/>Inspired by the SAX API.
72 *
73 * <br/>Creation date: 6 juil. 2002 23:49:28
74 * @author David Garnier
75 * @version $Revision: 1.3 $ $Date: 2003/06/14 22:31:26 $
76 */
77
78 public class WKBParser3D extends WKBParser {
79 protected static Logger log = Logger.getLogger(WKBParser3D.class);
80
81 private final static int ZFLAG = 0x80000000;
82 /***
83 * Constructor for WKBParser.
84 * @param _factory that will receive the events.
85 */
86 public WKBParser3D(WKBFactory3D _factory) {
87 super((WKBFactory) _factory);
88
89 }
90
91 /*** Read the raw WKB data from the DataInputStream and generate the beginUnit/endUnit calls and
92 * the calls to the top-level geometries (<code>MultiLineString, LineString, Polygon, MultiPolygon,
93 * GeometryCollection, Point<code>)<br/> All the readGeometry method can throw IOException if something goes wrong.
94 * @param srid defines the SRID applied to all the geometries contained in the current record.
95 *
96 * */
97 protected void decodeData(int srid) {
98 /* Right now if something goes wrong we just abort the curren unit and continue with the next record.*/
99 try {
100 //skip the byteOrder byte
101 inputStream.skipBytes(1);
102 //read the wkbType()
103 int geotype = inputStream.readInt();
104 //log.debug("Geotype:"+geotype);
105 int dimension = DIMENSION2;
106 if ((geotype & ZFLAG) == ZFLAG) {
107 geotype ^= ZFLAG;
108 dimension = DIMENSION3;
109 }
110 factory.beginUnit(srid);
111 parseType(geotype, dimension);
112 factory.endUnit();
113 } catch (IOException ioe) {
114 log.error("Problem is the current record:\n", ioe);
115 factory.abortUnit();
116 }
117 }
118
119 /***
120 * Reads a MultiLineString.
121 * @throws IOException
122 */
123 protected void readMultiLineString() throws IOException {
124 int size = inputStream.readInt();
125 factory.beginMultiLineString(size);
126 for (int i = 0; i < size; i++) {
127 //skip the byteOrder byte
128 inputStream.skipBytes(1);
129 int geotype = inputStream.readInt();
130 int dimension = DIMENSION2;
131 if ((geotype & ZFLAG) == ZFLAG) {
132 geotype ^= ZFLAG;
133 dimension = DIMENSION3;
134 }
135 if (geotype != wkbLineString) {
136 factory.abortMultiLineString();
137 return;
138 }
139 readLineString(dimension);
140 }
141 factory.endMultiLineString();
142 }
143
144 /***
145 * Reads a number of Points.
146 * @param pointCount
147 * @param dimension dimension of the points contained in this geometry.
148 * @throws IOException
149 */
150 protected void readPoints(int pointCount, int dimension) throws IOException {
151 pointCount *= dimension;
152 double[] sendVal = new double[pointCount];
153 for (int i = 0; i < pointCount; i++) {
154 sendVal[i] = (float) inputStream.readDouble();
155 }
156 switch (dimension) {
157 case (DIMENSION2) :
158 factory.addPoints(sendVal);
159 break;
160 case (DIMENSION3) :
161 ((WKBFactory3D) factory).addPoints3D(sendVal);
162 break;
163 default :
164 log.error("The submitted dimension isn't egal to 2 or 3");
165 }
166 }
167
168 /***
169 * Reads a MultiPolygon.
170 * @param dimension dimension of the points contained in this geometry.
171 * @throws IOException
172 */
173 protected void readMultiPolygon() throws IOException {
174 int size = inputStream.readInt();
175 factory.beginMultiPolygon(size);
176 for (int i = 0; i < size; i++) {
177 //skip the byteOrder byte
178 inputStream.skipBytes(1);
179 int geotype = inputStream.readInt();
180 int dimension = DIMENSION2;
181 if ((geotype & ZFLAG) == ZFLAG) {
182 geotype ^= ZFLAG;
183 dimension = DIMENSION3;
184 }
185 if (geotype != wkbPolygon) {
186 factory.abortMultiPolygon();
187 return;
188 }
189 readPolygon(dimension);
190 }
191 factory.endMultiPolygon();
192 }
193
194 /***
195 * Reads a MultiPoint.
196 * @throws IOException
197 */
198 protected void readMultiPoint() throws IOException {
199 int size = inputStream.readInt();
200 factory.beginMultiPoint(size);
201 for (int i = 0; i < size; i++) {
202 //skip the byteOrder byte
203 inputStream.skipBytes(1);
204 int geotype = inputStream.readInt();
205 int dimension = DIMENSION2;
206 if ((geotype & ZFLAG) == ZFLAG) {
207 geotype ^= ZFLAG;
208 dimension = DIMENSION3;
209 }
210 if (geotype != wkbPoint) {
211 factory.abortMultiPoint();
212 return;
213 }
214 readPoint(dimension);
215 }
216 factory.endMultiPoint();
217 }
218
219 /***
220 * Reads a GeometryCollection.
221 * @param dimension dimension of the points contained in this geometry.
222 * @throws IOException
223 */
224 protected void readGeometryCollection() throws IOException {
225 int size = inputStream.readInt();
226 factory.beginGeometryCollection(size);
227 for (int i = 0; i < size; i++) {
228 //skip the byteOrder byte
229 inputStream.skipBytes(1);
230 int geotype = inputStream.readInt();
231 int dimension = DIMENSION2;
232 if ((geotype & ZFLAG) == ZFLAG) {
233 geotype ^= ZFLAG;
234 dimension = DIMENSION3;
235 }
236 if (!parseType(geotype, dimension)) {
237 factory.abortGeometryCollection();
238 return;
239 }
240 }
241 factory.endGeometryCollection();
242 }
243 }
This page was automatically generated by Maven