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.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