/[projects]/android/TrainInfoService/src/dk/thoerup/traininfoservice/StationDAO.java
ViewVC logotype

Contents of /android/TrainInfoService/src/dk/thoerup/traininfoservice/StationDAO.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1254 - (show annotations) (download)
Mon Apr 4 10:39:12 2011 UTC (13 years, 1 month ago) by torben
File size: 8748 byte(s)
Add an explanatory comment regarding latitude/longitude
1 package dk.thoerup.traininfoservice;
2
3 import java.sql.Array;
4 import java.sql.Connection;
5 import java.sql.PreparedStatement;
6 import java.sql.ResultSet;
7 import java.sql.SQLException;
8 import java.sql.Statement;
9 import java.util.logging.Logger;
10
11 import dk.thoerup.android.traininfo.common.StationBean;
12 import dk.thoerup.android.traininfo.common.StationBean.StationEntry;
13
14 public class StationDAO {
15
16 public static class NostationException extends Exception {
17 private static final long serialVersionUID = 1L;
18 }
19
20 final static int LOCATION_LIMIT = 8;
21 static final Logger logger = Logger.getLogger(StationDAO.class.getName());
22
23
24 private StationEntry convertSingleRow(ResultSet res) throws SQLException {
25 StationEntry station = new StationEntry();
26
27 station.setId( res.getInt(1) );
28 station.setName( res.getString(2) );
29 station.setLatitude( res.getDouble(3) );
30 station.setLongitude( res.getDouble(4) );
31 station.setRegional( res.getString(5) );
32 station.setStrain( res.getString(6) );
33 station.setMetro( res.getString(7) );
34 station.setAddress( res.getString(8) );
35 station.setCalcdist( (int)res.getDouble(9) );
36
37 station.setIsRegional( station.getRegional() != null );
38 station.setIsStrain( station.getStrain() != null );
39 station.setIsMetro( station.getMetro() != null );
40
41 return station;
42 }
43
44 private StationBean convertResultset(ResultSet res) throws SQLException {
45 StationBean stations = new StationBean();
46 while (res.next()) {
47 stations.entries.add( convertSingleRow(res) );
48 }
49 return stations;
50
51 }
52
53
54 public StationEntry getById(int id) throws SQLException,NostationException {
55 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog,stationcode_metro,address,0.0 " +
56 "FROM trainstations WHERE id=" + id + " AND enabled=true";
57
58 Connection conn = null;
59 Statement stmt = null;
60 ResultSet res = null;
61 StationEntry result;
62
63 try {
64 conn = DBConnection.getConnection();
65
66 stmt = conn.createStatement();
67 res = stmt.executeQuery(SQL);
68
69 if (res.next()) {
70 result = convertSingleRow(res);
71 } else {
72 throw new NostationException();
73 }
74 } finally {
75 if (res != null)
76 res.close();
77 if (stmt != null)
78 stmt.close();
79 if (conn != null)
80 conn.close();
81 }
82
83 return result;
84 }
85
86 public StationBean dumpAll() throws SQLException {
87
88 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog,stationcode_metro,address,0.0,aliases " +
89 "FROM trainstations WHERE enabled = true ORDER BY id";
90
91 Connection conn = null;
92 Statement stmt = null;
93 ResultSet res = null;
94
95
96 try {
97 conn = DBConnection.getConnection();
98
99 stmt = conn.createStatement();
100 res = stmt.executeQuery(SQL);
101
102 // Does mostly the same as convertResultset()
103 StationBean stations = new StationBean();
104 while (res.next()) {
105 StationEntry entry = convertSingleRow(res);
106
107 Array arr = res.getArray(10);
108 if (arr != null) {
109 String[] aliases = (String[]) arr.getArray();
110 entry.setAliases(aliases);
111 }
112
113 stations.entries.add( entry );
114
115 }
116 return stations;
117
118
119 } finally {
120 if (res != null)
121 res.close();
122 if (stmt != null)
123 stmt.close();
124 if (conn != null)
125 conn.close();
126 }
127
128 }
129
130 /*
131 * this code requires theses statements are run on database in order to do ILIKE searches against aliases (which is defines as array of varchar(64) )
132 * create function rlike(text,text) returns bool as
133 * 'select $2 ilike $1' language sql strict immutable;
134 * create operator ~~~ (procedure = rlike, leftarg = text, rightarg = text, commutator = ~~);
135 */
136 public StationBean getByName(String name) throws SQLException {
137 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, 0.0 " +
138 "FROM trainstations " +
139 "WHERE (name ILIKE ? OR ? ~~~ ANY(aliases)) AND enabled = true " +
140 "ORDER BY name ";
141
142
143 StationBean result;
144 Connection conn = null;
145 PreparedStatement stmt = null;
146 ResultSet res = null;
147 try {
148 conn = DBConnection.getConnection();
149 stmt = conn.prepareStatement(SQL);
150
151 stmt.setString(1, name + "%");
152 stmt.setString(2, name + "%");
153
154 res = stmt.executeQuery();
155 result = convertResultset(res);
156
157 } finally {
158 if (res != null)
159 res.close();
160 if (stmt != null)
161 stmt.close();
162 if (conn!= null)
163 conn.close();
164 }
165 return result;
166 }
167
168 //Latitude (horizonal), longitude(vertical) so
169 // 1 degree latitude is ~ 111320 meters, since the distance between the horizonal lines is always the same
170 // 1 degree longitude is ~111320 meters at equator but gets shorter as we get closer to the poles.
171 // the "hack" with max 0.4 degrees latitude and 0.75 degrees longitude is only valid since we only service danish trains,
172 // in denmark 0.4dg latitude ~ 44km, 0.75dg longitude ~ 47km
173
174 // the ultra fast method (and only slightly inaccurate as long as we only cover a limited geographically area)
175 // is using an aproximation of the length of 1 latitude degree and 1 longitude degree and just use pythagoras to
176 // calculate the distance:
177 // sqrt( power(abs(latitude-?)*111320, 2) + power(abs(longitude-?)*63000,2) )::int as calcdist
178
179 public StationBean getByLocationWorker(double latitude, double longitude, boolean geolimit) throws SQLException {
180
181 String limitExpression = (geolimit == true) ? "AND abs(latitude-?)<0.4 AND abs(longitude-?)<0.75 " : "";
182
183 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, " +
184 "earth_distance( earth_coord, ll_to_earth(?,?))::int AS calcdist " +
185 "FROM trainstations " +
186 "WHERE enabled = true " + limitExpression +
187 "ORDER BY calcdist ASC " +
188 "LIMIT " + LOCATION_LIMIT;
189
190
191
192 StationBean result;
193 Connection conn = null;
194 PreparedStatement stmt = null;
195 ResultSet res = null;
196 try {
197 conn = DBConnection.getConnection();
198 stmt = conn.prepareStatement(SQL);
199 stmt.setDouble(1, latitude);
200 stmt.setDouble(2, longitude);
201 if (geolimit == true) {
202 stmt.setDouble(3, latitude);
203 stmt.setDouble(4, longitude);
204 }
205 res = stmt.executeQuery();
206 result = convertResultset(res);
207
208 } finally {
209 if (res != null)
210 res.close();
211 if (stmt != null)
212 stmt.close();
213 if (conn!= null)
214 conn.close();
215 }
216 return result;
217 }
218
219 public StationBean getByLocation(double latitude, double longitude) throws SQLException {
220 StationBean result = getByLocationWorker(latitude, longitude, true);
221
222 if (result.entries.size() < LOCATION_LIMIT) { //failover
223 logger.info("getByLocation failover: " +latitude + "," + longitude);
224
225 result = getByLocationWorker(latitude, longitude, false);
226 }
227
228 return result;
229 }
230
231
232
233 public StationBean getByList(String list) throws SQLException {
234 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog,stationcode_metro, address,0.0 " +
235 "FROM trainstations " +
236 "WHERE id IN " + list + " AND enabled = true " +
237 "ORDER BY name ";
238
239 Connection conn = null;
240 Statement stmt = null;
241 ResultSet res = null;
242 StationBean result;
243
244 try {
245 conn = DBConnection.getConnection();
246 stmt = conn.createStatement();
247 res = stmt.executeQuery(SQL);
248 result = convertResultset(res);
249 } finally {
250 if (res != null)
251 res.close();
252 if (stmt != null)
253 stmt.close();
254 if (conn!= null)
255 conn.close();
256 }
257
258 return result;
259
260 }
261 public static String getStationName(int stationID) {
262 String station = "";
263
264 Connection conn = null;
265 try {
266 conn = DBConnection.getConnection();
267 Statement stmt = conn.createStatement();
268 ResultSet rs = stmt.executeQuery("SELECT name FROM trainstations WHERE id=" + stationID);
269 if (rs.next()) {
270 station = rs.getString(1);
271 }
272
273 } catch (Exception e) {
274 } finally {
275 try {
276 if (conn != null && !conn.isClosed())
277 conn.close();
278 } catch (Exception e) {}
279 }
280
281 return station;
282 }
283
284 public int getIdByName(String name) throws SQLException {
285 String SQL = "SELECT id,name,latitude,longitude,stationcode_fjrn,stationcode_stog, stationcode_metro, address, 0.0 " +
286 "FROM trainstations " +
287 "WHERE name = ? AND enabled = true " +
288 "LIMIT 1 ";
289
290 StationBean result;
291 Connection conn = null;
292 PreparedStatement stmt = null;
293 ResultSet res = null;
294 try {
295 conn = DBConnection.getConnection();
296 stmt = conn.prepareStatement(SQL);
297
298 stmt.setString(1, name );
299
300 res = stmt.executeQuery();
301 result = convertResultset(res);
302
303 } finally {
304 if (res != null)
305 res.close();
306 if (stmt != null)
307 stmt.close();
308 if (conn!= null)
309 conn.close();
310 }
311
312 if (result.entries.size() == 1) {
313 return result.entries.get(0).getId();
314 } else {
315 return -1;
316 }
317 }
318 }

  ViewVC Help
Powered by ViewVC 1.1.20