/[projects]/dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/afstandandenrute/DatabaseRouteDistance.java
ViewVC logotype

Annotation of /dao/DaoAdresseVedligehold/src/main/java/dk/daoas/adressevedligehold/afstandandenrute/DatabaseRouteDistance.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2972 - (hide annotations) (download)
Tue Mar 8 09:41:53 2016 UTC (8 years, 2 months ago) by torben
File size: 11887 byte(s)
First attemt at handling route distances across weekdays
1 torben 2878 package dk.daoas.adressevedligehold.afstandandenrute;
2    
3     import java.io.IOException;
4     import java.sql.Connection;
5     import java.sql.PreparedStatement;
6     import java.sql.ResultSet;
7     import java.sql.SQLException;
8 torben 2879 import java.sql.Statement;
9 torben 2878 import java.util.ArrayList;
10     import java.util.HashMap;
11     import java.util.List;
12     import java.util.Map;
13     import java.util.Queue;
14     import java.util.Set;
15     import java.util.TreeSet;
16     import java.util.concurrent.ConcurrentLinkedQueue;
17    
18     import dk.daoas.adressevedligehold.beans.Address;
19 torben 2903 import dk.daoas.adressevedligehold.tasks.TaskLogger;
20 torben 2878 import dk.daoas.adressevedligehold.util.DeduplicateHelper;
21 torben 2884 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22 torben 2878
23    
24    
25 torben 2946 public class DatabaseRouteDistance {
26 torben 2903 private TaskLogger logger = TaskLogger.getInstance();
27 torben 2878
28     int batchCount = 0;
29    
30     Connection conn;
31     PreparedStatement saveStmt;
32    
33     List<Address> alleAddressr;
34     Address alleIkkeDaekkede[];
35    
36     Map<Short,List<Address>> daekkedeAddressrHO = new HashMap<Short,List<Address>>();
37    
38 torben 2972 String weekdayField;
39 torben 2878
40    
41    
42 torben 2972
43 torben 2878
44     DeduplicateHelper<String> vejnavnCache = new DeduplicateHelper<String>();
45     DeduplicateHelper<String> husnrbogstavCache = new DeduplicateHelper<String>();
46     DeduplicateHelper<String> ruteCache = new DeduplicateHelper<String>();
47    
48     Set<Short> postnumre = new TreeSet<Short>();
49    
50     //Map<Short, List<Address>> ikkeDaekkedePrPost = new HashMap<Short, List<Address>>();
51    
52 torben 2927 boolean isIncremental;
53 torben 2878
54     private HashMap<Short,BoundingBox> bbCache = new HashMap<Short,BoundingBox>();
55    
56 torben 2972 public DatabaseRouteDistance(Connection conn, boolean isIncremental, String weekdayField) throws SQLException,IOException {
57 torben 2878 this.conn = conn;
58 torben 2927
59     String newExt = "";
60     if (isIncremental == false) {
61     newExt = "_ny";
62     }
63 torben 2972
64     this.weekdayField = weekdayField;
65 torben 2878
66 torben 2972 String sql = "INSERT IGNORE INTO fulddaekning.afstand_anden_rute" + newExt + " (orgId,orgPostnr, orgAdresse,orgGadeid,orgHusnr,orgHusnrBogstav,orgRute,id,postnr,adresse,gadeid,husnr,husnrbogstav,rute,afstand,`timestamp`) "+
67 torben 2878 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, now() )";
68    
69     saveStmt = conn.prepareStatement(sql);
70 torben 2927 this.isIncremental = isIncremental;
71 torben 2878
72     }
73    
74     public void resetResultTable() throws SQLException {
75 torben 2927 if (isIncremental == true) {
76     return;
77     }
78    
79 torben 2879 try (Statement stmt = conn.createStatement()) {
80     logger.info("Dropping old result table (if exists)");
81     String sql = "DROP TABLE IF EXISTS fulddaekning.afstand_anden_rute_ny";
82     stmt.executeUpdate(sql);
83    
84     logger.info("Create new result table");
85     sql = "CREATE TABLE fulddaekning.afstand_anden_rute_ny LIKE fulddaekning.afstand_anden_rute";
86     stmt.executeUpdate(sql);
87    
88     }
89 torben 2878 }
90    
91 torben 2884 @SuppressFBWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE")
92 torben 2878 public void renameResultTables() throws SQLException {
93     if (AfstandAndenRuteTask.test_mode == true) {
94     throw new RuntimeException("Can not rename tables in test mode");
95     }
96 torben 2879
97 torben 2927 if (isIncremental) {
98     return;
99     }
100    
101 torben 2878 Constants consts = Constants.getInstance();
102    
103 torben 2879 try (Statement stmt = conn.createStatement()) {
104    
105     String ext = consts.getTableExtension();
106    
107     logger.info("Dropping old backup table (if exists)");
108     String sql = "DROP TABLE IF EXISTS fulddaekning.afstand_anden_rute_old" + ext;
109     stmt.executeUpdate(sql);
110    
111     logger.info("Rename tables");
112     String sql2 = "RENAME TABLE fulddaekning.afstand_anden_rute" + ext + " TO fulddaekning.afstand_anden_rute_old" + ext + ", fulddaekning.afstand_anden_rute_ny TO fulddaekning.afstand_anden_rute" + ext;
113    
114     logger.info("Executing: " + sql2);
115     stmt.executeUpdate(sql2);
116     }
117    
118 torben 2878
119     }
120    
121     public BoundingBox getBoundingbox(short postnr) {
122     BoundingBox bb = bbCache.get(postnr);
123 torben 2884 return new BoundingBox(bb); //never return the original / cached object
124 torben 2878 }
125    
126    
127     public Set<Short> hentPostnumreCache() {
128     return postnumre;
129     }
130    
131    
132     public Queue<Address> hentAlleIkkedaekkedeAdresser(int minPostnr, int maxPostnr) throws SQLException {
133 torben 2927 String placeHolder1 = "%INCREMENTAL1%";
134     String placeHolder2 = "%INCREMENTAL2%";
135 torben 2878
136 torben 2927 Constants consts = Constants.getInstance();
137    
138 torben 2878 logger.info("Henter alle IKKE-daekkede Addressr");
139    
140 torben 2927 String sql = "SELECT a.id,a.postnr,a.vejnavn,a.gadeid,a.husnr,a.husnrbogstav,latitude,longitude,ruteMa,p.distributor as ho " +
141 torben 2890 "FROM fulddaekning.adressetabel a " +
142 torben 2878 "LEFT JOIN bogleveringer.postnummerdistributor p on (a.postnr=p.postnr) " +
143 torben 2927 placeHolder1 +
144 torben 2972 "WHERE " + weekdayField + " IS NULL " + //Ingen dækning
145 torben 2878 "AND a.postnr BETWEEN ? AND ? " +
146     "AND latitude IS NOT NULL " +
147     "AND longitude IS NOT NULL " +
148 torben 2927 "AND a.gadeid IS NOT NULL " +
149 torben 2922 "AND (a.distributor IS NULL OR a.distributor<>'LUKKET') " +
150 torben 2927 placeHolder2 +
151 torben 2922 "ORDER BY gadeid "
152 torben 2878 ;
153    
154 torben 2927
155     if (isIncremental) {
156     sql = sql.replace(placeHolder1, "LEFT JOIN fulddaekning.afstand_anden_rute" + consts.getTableExtension() +" afstand ON (a.id = afstand.orgId) " );
157     sql = sql.replace(placeHolder2, "AND afstand.id IS NULL " );
158     } else {
159     sql = sql.replace(placeHolder1, "");
160     sql = sql.replace(placeHolder2, "");
161     }
162    
163 torben 2878 if (AfstandAndenRuteTask.test_mode == true) {
164     sql = sql + " LIMIT 100 ";
165     }
166    
167 torben 2879 try (PreparedStatement stmt = conn.prepareStatement(sql)) {
168    
169 torben 2878
170 torben 2879 stmt.setInt(1, minPostnr);
171     stmt.setInt(2, maxPostnr);
172    
173     List<Address> list = hentAdresseListe( stmt );
174     alleIkkeDaekkede = list.toArray( new Address[ list.size() ] );
175 torben 2878
176 torben 2879 logger.info("Analyserer ikke-daekkede Addressr");
177 torben 2878
178 torben 2879 for (Address a : alleIkkeDaekkede) {
179 torben 2878
180    
181 torben 2879 BoundingBox bbox;
182 torben 2878
183 torben 2879 if (! postnumre.contains(a.postnr )) {
184     postnumre.add( a.postnr );
185    
186     bbox = new BoundingBox();
187    
188     bbCache.put( a.postnr, bbox);
189    
190     } else {
191     bbox = bbCache.get( a.postnr);
192     }
193    
194     bbox.latitudeMax = Math.max(bbox.latitudeMax, a.latitude);
195     bbox.latitudeMin = Math.min(bbox.latitudeMin, a.latitude);
196     bbox.longitudeMax = Math.max(bbox.longitudeMax, a.longitude);
197     bbox.longitudeMin = Math.min(bbox.longitudeMin, a.longitude);
198    
199    
200 torben 2878 }
201 torben 2879 return new ConcurrentLinkedQueue<Address>( list );
202 torben 2878 }
203     }
204    
205    
206    
207    
208     public Map<Short, List<Address>> getDaekkedeAdresserHO() {
209     return daekkedeAddressrHO;
210     }
211    
212     public int hentAlleDaekkedeAdresser(String distributor) throws SQLException {
213    
214     if ( alleAddressr == null ) {
215     String sql = "SELECT id,a.postnr,vejnavn,gadeid,husnr,husnrbogstav,latitude,longitude,ruteMa,p.distributor as ho " +
216 torben 2890 "FROM fulddaekning.adressetabel a " +
217 torben 2878 "LEFT JOIN bogleveringer.postnummerdistributor p on (a.postnr=p.postnr) " +
218 torben 2972 "WHERE " + weekdayField + " IS NOT NULL " +
219 torben 2878 "AND latitude IS NOT NULL " +
220     "AND longitude IS NOT NULL " +
221     "AND a.distributor = ? ";
222    
223     if (AfstandAndenRuteTask.test_mode == true) {
224     sql = sql + " AND a.postnr BETWEEN 6000 and 7200 ";
225     }
226    
227     // Forward only + concur_read_only + fetchsize tvinger driver til at hente en række af gangen (bedre performance ved store result sets)
228 torben 2879 // Se http://dev.mysql.com/doc/connector-j/en/connector-j-reference-implementation-notes.html
229 torben 2878
230 torben 2937 try (PreparedStatement stmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
231 torben 2879 stmt.setFetchSize(Integer.MIN_VALUE);
232    
233     stmt.setString(1, distributor);
234    
235     List<Address> list = hentAdresseListe( stmt );
236 torben 2878
237 torben 2879 alleAddressr = new ArrayList<Address>();
238     alleAddressr.addAll(list);
239 torben 2878
240 torben 2879 for(Address addr : list) {
241     short ho = addr.ho;
242     List<Address> hoListe = daekkedeAddressrHO.get(ho);
243     if ( hoListe == null) {
244     hoListe = new ArrayList<Address>();
245     daekkedeAddressrHO.put(ho, hoListe);
246     }
247    
248     hoListe.add(addr);
249    
250     }
251 torben 2878 }
252     }
253    
254     return alleAddressr.size();
255 torben 2879
256 torben 2878 }
257    
258    
259    
260     public synchronized void gemResultat(Address orgAddress, Address bedsteAddress, double bedsteAfstand) throws SQLException {
261     /*String sql = "INSERT INTO fulddaekning.afstand_anden_rute_thn (orgId,orgPostnr, orgVejnavn,orgGadeid,orgHusnr,orgHusnrBogstav,orgLatitude,orgLongitude,orgRute,id,postnr,vejnavn,gadeid,husnr,husnrbogstav,latitude,longitude,rute,afstand,`timestamp`) "+
262     "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, now() )";
263    
264    
265     PreparedStatement saveStmt = conn.prepareStatement(sql);*/
266    
267     saveStmt.setInt(1, orgAddress.id);
268     saveStmt.setShort(2, orgAddress.postnr);
269     saveStmt.setString(3, orgAddress.vejnavn);
270     saveStmt.setInt(4, orgAddress.gadeid);
271     saveStmt.setShort(5, orgAddress.husnr);
272     saveStmt.setString(6, orgAddress.husnrbogstav);
273     saveStmt.setString(7, orgAddress.ruteMandag);
274    
275    
276     saveStmt.setInt(8, bedsteAddress.id);
277     saveStmt.setShort(9, bedsteAddress.postnr);
278     saveStmt.setString(10, bedsteAddress.vejnavn);
279     saveStmt.setInt(11, bedsteAddress.gadeid);
280     saveStmt.setShort(12, bedsteAddress.husnr);
281     saveStmt.setString(13, bedsteAddress.husnrbogstav);
282     saveStmt.setString(14, bedsteAddress.ruteMandag);
283    
284     saveStmt.setDouble(15, bedsteAfstand);
285    
286     saveStmt.addBatch();
287     batchCount++;
288     if (batchCount >= 1000) {
289     saveStmt.executeBatch();
290     batchCount = 0;
291     }
292     //saveStmt.executeUpdate();
293     //saveStmt.clearParameters();
294    
295     //saveStmt.close();
296     }
297    
298 torben 2927
299     @SuppressFBWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE")
300     public void prepareIncrementalSearch() throws SQLException {
301 torben 2930 if (isIncremental == false) {
302     return;
303     }
304 torben 2927
305     logger.info("prepareIncrementalSearch() ");
306    
307     Constants consts = Constants.getInstance();
308    
309     String sql1 = "UPDATE fulddaekning.afstand_anden_rute" + consts.getTableExtension() + " afstand " +
310     "JOIN fulddaekning.adressetabel addr ON (afstand.id = addr.id) " +
311     "SET afstand.id = 0 " +
312 torben 2972 "WHERE ruteMa is null "
313 torben 2927 ;
314    
315     String sql2 = "DELETE FROM fulddaekning.afstand_anden_rute" + consts.getTableExtension() + " " +
316     "WHERE id=0 "
317     ;
318    
319    
320     try (Statement stmt = conn.createStatement()) {
321    
322     int rows = stmt.executeUpdate(sql1);
323     logger.info(sql1 + "\n updated rows: " + rows);
324    
325     rows = stmt.executeUpdate(sql2);
326     logger.info(sql2 + "\n deleted rows: " + rows);
327    
328     }
329     }
330    
331 torben 2878 public synchronized void saveBatch() throws SQLException{
332     saveStmt.executeBatch();
333     batchCount = 0;
334     }
335    
336    
337    
338     protected ArrayList<Address> hentAdresseListe(PreparedStatement stmt) throws SQLException{
339     ArrayList<Address> list = new ArrayList<Address>( 1000000 );
340    
341     Constants consts = Constants.getInstance();
342    
343     //logger.info("Starting query");
344 torben 2880 try ( ResultSet res = stmt.executeQuery() ) {
345    
346 torben 2878
347 torben 2880 while (res.next()) {
348    
349 torben 2927
350 torben 2880 double latitude = res.getDouble(7);
351     double longitude = res.getDouble(8);
352    
353    
354     Address adr = new Address(latitude,longitude);
355    
356     adr.id = res.getInt(1);
357     adr.postnr = res.getShort(2);
358     adr.vejnavn = vejnavnCache.getInstance( res.getString(3) );
359     adr.gadeid = res.getInt(4);
360     adr.husnr = res.getShort(5);
361     adr.husnrbogstav = husnrbogstavCache.getInstance( res.getString(6) );
362     //adr.latitude = res.getDouble(7);
363     //adr.longitude = res.getDouble(8);
364     adr.ruteMandag = ruteCache.getInstance( res.getString(9) );
365     adr.ho = res.getShort(10);
366    
367 torben 2927
368     if (consts.validatePostnr(adr.postnr) == false) {//delegate to Constants implementations to validate whether we should look at this address
369     continue;
370     }
371    
372 torben 2880 list.add(adr);
373    
374     if (consts.doCheckHO() == true && adr.ho == 0) {
375 torben 2903 logger.info( "Mangler HO: " + adr );
376 torben 2881 throw new RuntimeException("Mangler HO: "+ adr);
377 torben 2880 }
378    
379     //logger.info( "Adress:" + adr);
380 torben 2878 }
381 torben 2880
382     res.close();
383     stmt.close();
384    
385     return list;
386 torben 2878 }
387     }
388    
389     }

  ViewVC Help
Powered by ViewVC 1.1.20