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.sql.Connection;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.sql.Statement;
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import org.apache.log4j.Logger;
32
33 /***
34 * Creation date: 3 juil. 2002 00:16:50
35 * @author David Garnier
36 * @version $Revision: 1.8 $ $Date: 2003/07/08 21:49:16 $
37 */
38 public class WKBReader implements WKBGeometryTypes {
39 protected static Logger log = Logger.getLogger(WKBReader.class);
40
41 protected String[] emptyStringArray = new String[] {
42 };
43
44 /***
45 * Constructor for WKBReader.
46 */
47 public WKBReader() {
48 super();
49 }
50
51 protected String[] sanitizeWords(List words) {
52 for (int i = 0; i < words.size(); i++) {
53 Object tmp = words.get(i);
54 if (!(tmp instanceof String)) {
55 String errorString =
56 "An object inside this List of words isn't a String:" + tmp;
57 log.error(errorString);
58 words.remove(i);
59 i--;
60 continue;
61 }
62 String word = (String) tmp;
63 if (word.length() == 0) {
64 String errorString = "This String is empty";
65 log.error(errorString);
66 words.remove(i);
67 i--;
68 continue;
69 }
70 }
71
72 if (log.isDebugEnabled()) {
73 log.debug("Final words: " + words);
74 }
75
76 return (String[]) words.toArray(emptyStringArray);
77 }
78
79 /*** Fetches the binary data from the database and pass each record to the submitted WKBParser.
80 * The partialSQLQuery should contain a partial SQL query.
81 * The data will be fetched from the geocolumn name.
82 * <br/>Example of an correct value for <code>partialSQLQuery</code>:
83 <code>"FROM geotable WHERE id BETWEEN 125 AND 168"
84 * @param dbConn
85 * @param partialSQLQuery
86 * @param parser
87 */
88 public void readDataWithPartialQuery(
89 Connection dbConn,
90 String geocolumn,
91 String partialSQLQuery,
92 WKBParser parser) {
93
94 if (geocolumn == null) {
95 throw new IllegalArgumentException("Submitted geocolumn is null.");
96 }
97
98 if (partialSQLQuery == null) {
99 throw new IllegalArgumentException("Submitted partialSQLQuery is null.");
100 }
101
102 readData(
103 dbConn,
104 "select srid("
105 + geocolumn
106 + ") as srid, asbinary("
107 + geocolumn
108 + ",'XDR') as wkb "
109 + partialSQLQuery,
110 parser);
111 }
112
113 /*** Fetches the binary data from the database and pass each record to the submitted WKBParser.
114 * The whereClause should contain a valid SQL where clause, without the where at the beginning. If whereClause is null
115 or empty, it is ignored, causing all the records in the specified geotable to be loaded.
116 * The data will be fetched from the geocolumn name.
117 * <br/>Example of an correct value for <code>partialSQLQuery</code>:
118 <code>"FROM geotable WHERE id BETWEEN 125 AND 168"
119 * @param dbConn
120 * @param partialSQLQuery
121 * @param parser
122 */
123 public void readDataWithWhereClause(
124 Connection dbConn,
125 String geocolumn,
126 String geotable,
127 String whereClause,
128 WKBParser parser) {
129
130 if (geocolumn == null) {
131 throw new IllegalArgumentException("Submitted geocolumn is null.");
132 }
133
134 if (geotable == null) {
135 throw new IllegalArgumentException("Submitted geotable is null.");
136 }
137
138 // // if(whereClause == null){
139 // // throw new IllegalArgumentException("Submitted whereClause is null.");
140 // // }
141 String sqlQuery =
142 "select srid("
143 + geocolumn
144 + ") as srid, asbinary("
145 + geocolumn
146 + ",'XDR') as wkb from "
147 + geotable;
148
149 if (whereClause != null && whereClause.length() != 0) {
150 sqlQuery += " where " + whereClause;
151 }
152 readData(dbConn, sqlQuery, parser);
153 }
154
155 /*** Fetches the binary data from the database and pass each record to the WKBParser
156 * with the submitted WKBFactory. The submitted query must
157 * creates at least a column named "srid" holding the SRID and a column named "wkb" holding the WKB data.
158 * <br/>Example of an correct value for <code>completeSQLQuery</code>:
159 *<code>"SELECT srid(geocolumn) AS srid, asbinary(geocolumn,'XDR') AS wkb FROM geotable WHERE id BETWEEN 125 AND 168"</code>
160 * @param dbConn
161 * @param completeSQLQuery
162 * @param wordList
163 * @param parser
164 */
165 public void readData(
166 Connection dbConn,
167 String completeSQLQuery,
168 List wordList,
169 WKBParser parser) {
170
171 if (parser == null) {
172 throw new IllegalArgumentException("Submitted WKBParser is null.");
173 }
174
175 /* According to the PostgreSQL documentation, there should be only
176 * one cursor valid at any time. Should this method be synchronized ?*/
177 String[] words = sanitizeWords(wordList);
178 try {
179 /* Here the false implies that the srid bytes are in little endian order.*/
180 Statement wkbSta = dbConn.createStatement();
181 if (log.isDebugEnabled()) {
182 log.debug("Selecting data using " + completeSQLQuery);
183 }
184
185 wkbSta.execute("begin");
186 wkbSta.execute(
187 "declare wkb_cursor binary cursor for " + completeSQLQuery);
188 ResultSet wkbRecords =
189 wkbSta.executeQuery("fetch forward all in wkb_cursor");
190
191
192 /* Allocate a buffer to hold the bytes, according to the number of words.*/
193 byte[][] fields = new byte[words.length][];
194
195 while (wkbRecords.next()) {
196
197 try {
198 byte[] record = wkbRecords.getBytes("wkb");
199
200 parser.parseData(record, fields);
201 } catch (Exception e) {
202 e.printStackTrace();
203 log.error(e);
204 continue;
205 }
206 for (int i = 0; i < words.length; i++) {
207 fields[i] = wkbRecords.getBytes(words[i]);
208 }
209 }
210 wkbSta.execute("close wkb_cursor");
211 wkbSta.execute("end");
212 wkbRecords.close();
213 wkbSta.close();
214 } catch (SQLException sqle) {
215 log.error(
216 "Something went wrong while selecting the data from the database.",
217 sqle);
218 int id = 0;
219 }
220 }
221
222 /*** Fetches the binary data from the database and pass each record to the WKBParser
223 * with the submitted WKBFactory. The submitted query must
224 * creates at least a column named "srid" holding the SRID and a column named "wkb" holding the WKB data.
225 * <br/>Example:
226 *<code>"SELECT srid(geocolumn) AS srid, asbinary(geocolumn,'XDR') AS wkb FROM geotable WHERE id BETWEEN 125 AND 168"</code>
227 * @param dbConn
228 * @param completeSQLQuery
229 * @param parser
230 */
231 public void readData(
232 Connection dbConn,
233 String completeSQLQuery,
234 WKBParser parser) {
235 List words = new ArrayList(1);
236 words.add("srid");
237 readData(dbConn, completeSQLQuery, words, parser);
238 }
239
240 private byte[] parseNDRRecord(byte[] record) {
241 record[0] = 1;
242 return record;
243 }
244
245 private void invertInt(byte[] record, int offset) {
246 byte b0 = record[offset];
247 byte b1 = record[offset + 1];
248 byte b2 = record[offset + 2];
249 byte b3 = record[offset + 3];
250 record[offset + 3] = b0;
251 record[offset + 2] = b1;
252 record[offset + 1] = b2;
253 record[offset + 0] = b3;
254 }
255
256 private void invertLong(byte[] record, int offset) {
257 byte b0 = record[offset];
258 byte b1 = record[offset + 1];
259 byte b2 = record[offset + 2];
260 byte b3 = record[offset + 3];
261 byte b4 = record[offset + 4];
262 byte b5 = record[offset + 5];
263 byte b6 = record[offset + 6];
264 byte b7 = record[offset + 7];
265
266 record[offset + 7] = b0;
267 record[offset + 6] = b1;
268 record[offset + 5] = b2;
269 record[offset + 4] = b3;
270 record[offset + 3] = b4;
271 record[offset + 2] = b5;
272 record[offset + 1] = b5;
273 record[offset + 0] = b7;
274 }
275
276 }
This page was automatically generated by Maven