diff options
37 files changed, 5967 insertions, 1100 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c606279..3a93397 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.cbaines.suma" - android:versionCode="5" - android:versionName="0.2.2 (alpha)" > + android:versionCode="6" + android:versionName="0.3 (alpha)" > <uses-sdk android:minSdkVersion="7" /> @@ -14,10 +14,11 @@ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application + android:debuggable="true" android:icon="@drawable/icon" android:label="@string/app_name" > <activity - android:name=".SouthamptonUniversityMapActivity" + android:name=".MapActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -27,7 +28,9 @@ </activity> <activity android:name="FindActivity" > </activity> - <activity android:name=".BusStopActivity" > + <activity android:name="BusStopActivity" > + </activity> + <activity android:name="BusActivity" > </activity> <activity android:name="AboutActivity" > </activity> diff --git a/assets/data.db b/assets/data.db Binary files differindex f941f32..a128ffd 100644 --- a/assets/data.db +++ b/assets/data.db diff --git a/assets/routes.csv b/assets/routes.csv index 5f25362..b536ee7 100644 --- a/assets/routes.csv +++ b/assets/routes.csv @@ -1,6 +1,48 @@ -"id","code","label","forward direction","reverse direction" -326,U1,"NOC - Parkway - Eastleigh",C,A +"id","code","label" +427,1,"Southampton - Winchester" +464,1,"City - Weston" +333,10,"Lordshill - City Centre - Thor" +438,10s,"Southampton - Totton - Cadnam" +449,11s,"City-Sholing Loop" +437,12s,"Southampton - Totton - Cadnam" +472,14,"Southampton City Centre - Bitt" +339,16,"Hamble - City" +340,17s,"Lordshill - City - Weston" +376,18,"Thornhill - City - Millbrook" +428,2,"Southampton - Fair Oak" +331,21,"RSH Hospital - City - Nursling" +429,3,"Southampton - Botley" +323,3,"City - Townhill Park" +446,4,"City - Totton" +432,4,"Southampton - Romsey" +424,46,"Southampton - Winchester" +447,5,"Lordshill - City" +421,56,"Southampton - Lymington" +384,6,"Southampton - Lymington" +452,612,"Woolston - Barton Peveril" +448,7,"City-Swaythling" +494,7,"Southampton - Bishops Waltham" +409,72,"Southampton - Gosport" +466,78C,"Southampton - Fareham" +431,8,"Southampton - Hythe" +412,80,"Southampton - Fareham" +480,8A,"City - Hedge End" +341,8s,"Lordshill - City - Midanbury" +434,9,"Southampton - Calshot" +399,9s,"City - Harefield" +433,A,"Eastleigh - Hamble" +357,BSH,"Bitterne Shoppa Hoppa" +455,LINK,"Town Quay - Southampton Centra" +473,N12,"Leisure World - Totton" +462,N16,"City - Hamble" +441,N18,"City - Townhill" +442,N19,"City - Lords Hill" +495,N3,"Soton - Hedge End" +474,S1,"Shirley to Lordshill Centre" +479,S2,"City - Shirley via Tesco" +326,U1,"NOC - Parkway - Eastleigh" 468,U1N,"Leisure World - City Centre -" -329,U2,"Civic Centre - Highfield Campus",C,B -327,U6,"Dock Gate 4 - General Hospital",H,C -354,U9,"Townhill Park - General Hospital" +329,U2,"Civic Centre - Highfield Campu" +327,U6,"Dock Gate 4 - General Hospital" +354,U9,"Townhill Park - General Hospit" +423,X7,"Southampton - Salisbury" diff --git a/assets/routestops.csv b/assets/routestops.csv index 9edd2f4..8f966b1 100644 --- a/assets/routestops.csv +++ b/assets/routestops.csv @@ -1,4 +1,2900 @@ "route-id","seq","stop-id" +427,1,HAA13649 +427,2,SNA13768 +427,3,HA120625 +427,4,SN121021 +427,5,SN12532A +427,6,SN12524D +427,7,SN120522 +427,8,SN120535 +427,9,SN120405 +427,10,SN120401 +427,11,SN120398 +427,12,SN121052 +427,13,SN121053 +427,14,SN120118 +427,15,SN120117 +427,16,SN121007 +427,17,SN121006 +427,18,SN121008 +427,19,HA121017 +427,20,HA100779 +427,21,HA030002 +427,22,HA030107 +427,23,HA030013 +427,24,HA030015 +427,25,HA030067 +427,26,HA030071 +427,27,HA030181 +427,28,HA030180 +427,29,HA110433 +427,30,HA110430 +427,31,HA110428 +427,32,HA110427 +427,33,HA110424 +427,34,HA110423 +427,35,HA110420 +427,36,HA110419 +427,37,HA110041 +427,38,HA110043 +427,39,HA110044 +427,40,HA110046 +427,41,HA110049 +427,42,HA110050 +427,43,HA110100 +427,44,HA110111 +427,45,HA110113 +427,46,HA110058 +427,47,HA110103 +427,48,HA110125 +427,49,HA110009 +427,50,HA110058 +427,51,HA110066 +427,52,HA110112 +427,53,HA110051 +427,54,HA110048 +427,55,HA110047 +427,56,HA110045 +427,57,HA110042 +427,58,HA110040 +427,59,HA110038 +427,60,HA110418 +427,61,HA110421 +427,62,HA110422 +427,63,HA110425 +427,64,HA110426 +427,65,HA110429 +427,66,HA110431 +427,67,HA110432 +427,68,HA030179 +427,69,HA030072 +427,70,HA030066 +427,71,HA030068 +427,72,HA030069 +427,73,HA030014 +427,74,HA030012 +427,75,HA030108 +427,76,HA030001 +427,77,HA100778 +427,78,HA100780 +427,79,SN121009 +427,80,SN121005 +427,81,SN121010 +427,82,SN120116 +427,83,SN120115 +427,84,SN120119 +427,85,SN121054 +427,86,SN121055 +427,87,SN120400 +427,88,SN120404 +427,89,SN120406 +427,90,SN120536 +427,91,HAA40520 +464,1,SN12619D +464,2,SNA09464 +464,3,HA120626 +464,4,HA120630 +464,5,HA120638 +464,6,HA120641 +464,7,SN120652 +464,8,SN12658A +464,9,SN120661 +464,10,SN120712 +464,11,HAA13663 +464,12,HAA13662 +464,13,HAA13659 +464,14,HAA13658 +464,15,SN120717 +464,16,SN120719 +464,17,HA120721 +464,18,HAA13653 +464,19,HA120746 +464,20,HAA13654 +464,21,SN120747 +464,22,SN120752 +464,23,SN120754 +464,24,SN120755 +464,25,SN120756 +464,26,SN120757 +464,27,SN121020 +464,28,SN120753 +464,29,SN120751 +464,30,SN120758 +464,31,SN122001 +464,32,SN122003 +464,33,HA030525 +464,34,HA030527 +464,35,HA030529 +464,36,HA030530 +464,37,HA030532 +464,38,HA030535 +464,39,HA030536 +464,40,HA030539 +464,41,HA030541 +464,42,HA030542 +464,43,HA030523 +464,44,HA030522 +464,45,HA030519 +464,46,HA030516 +464,47,HA030501 +464,48,HA030505 +464,49,HA030507 +464,50,HA030509 +464,51,HA030511 +464,52,HA030512 +464,53,SN120752 +464,54,SN120754 +464,55,SN120755 +464,56,SN120756 +464,57,SN120757 +464,58,SN121020 +464,59,SN120753 +464,60,SN120751 +464,61,SN120748 +464,62,HAA13652 +464,63,HA120720 +464,64,HAA13655 +464,65,HAA13657 +464,66,HAA13660 +464,67,HAA13661 +464,68,HAA13664 +464,69,SN120713 +464,70,SN120718 +464,71,SN120711 +464,72,SN120660 +464,73,SN120659 +464,74,SN120653 +464,75,HA120642 +464,76,SN120635 +464,77,HA120633 +464,78,HA120621 +464,79,HA120625 +464,80,HAA13647 +464,81,HAA13371 +333,1,SN120467 +333,2,HA120465 +333,3,HA120466 +333,4,SN120468 +333,5,SN120470 +333,6,SN120472 +333,7,SN120473 +333,8,SN120792 +333,9,SN120789 +333,10,SN120778 +333,11,HA120777 +333,12,HA120611 +333,13,HA120612 +333,14,SN120614 +333,15,SN120607 +333,16,SN120604 +333,17,SN120603 +333,18,SN120600 +333,19,SN120598 +333,20,SN120962 +333,21,SN120963 +333,22,SN120965 +333,23,SN120602 +333,24,SN120699 +333,25,SN120694 +333,26,SN120692 +333,27,SN120687 +333,28,SN120690 +333,29,SN120964 +333,30,SN120764 +333,31,SN120678 +333,32,SN120726 +333,33,SNA09185 +333,34,SN120665 +333,35,SN120659 +333,36,SN120653 +333,37,HA120642 +333,38,SN120635 +333,39,HA120633 +333,40,SN120627 +333,41,SN120622 +333,42,HAA13371 +333,43,SN12617B +333,44,SN12441A +333,45,SN12518A +333,46,SN120516 +333,47,SN120501 +333,48,SN120498 +333,49,SN120380 +333,50,SN120377 +333,51,SN120371 +333,52,SN12368A +333,53,SN120217 +333,54,SN120214 +333,55,SN120211 +333,56,SN120210 +333,57,SN120080 +333,58,SN120986 +333,59,SN120979 +333,60,SN120085 +333,61,SN120091 +333,62,SN120090 +333,63,HAA13388 +333,64,HAA13389 +333,65,SN120010 +333,66,SN120009 +333,67,SN120047 +333,68,SN120088 +333,69,SN120071 +333,70,SN120070 +333,71,SN120066 +333,72,SN120061 +333,73,SN120049 +333,74,SN120045 +333,75,SN120045 +333,76,SN120008 +333,77,SN120013 +333,78,SN120011 +333,79,SN120047 +333,80,SN120048 +333,81,SN120063 +333,82,SN120069 +333,83,SN120065 +333,84,SN120087 +333,85,SN120089 +333,86,SN120014 +333,87,SN120092 +333,88,SN120086 +333,89,SN120083 +333,90,SN120102 +333,91,SN120985 +333,92,SN120081 +333,93,SN120209 +333,94,SN120213 +333,95,SN120216 +333,96,SN120367 +333,97,SN120372 +333,98,SN120376 +333,99,SN12367B +333,100,SN120381 +333,101,SN120496 +333,102,SN120499 +333,103,SN120515 +333,104,SN120519 +333,105,SN120523 +333,106,SN12532B +333,107,SN12619E +333,108,SN120623 +333,109,SN120632 +333,110,HA120638 +333,111,HA120641 +333,112,SN120652 +333,113,SN12658A +333,114,SN120664 +333,115,SN120710 +333,116,SN120676 +333,117,SN120677 +333,118,SN120689 +333,119,SN120682 +333,120,SN120966 +333,121,SN120967 +333,122,SN120961 +333,123,SN120684 +333,124,HAA13665 +333,125,SN120693 +333,126,SN120698 +333,127,SNA19479 +333,128,SN120599 +333,129,SN120597 +333,130,SN120605 +333,131,SN120606 +333,132,SN120608 +333,133,SN120615 +333,134,HA120613 +333,135,HA120610 +333,136,HA120776 +333,137,SN120779 +333,138,SN120780 +333,139,SN120790 +333,140,SN120460 +333,141,SN120471 +333,142,SN120469 +333,143,HA120465 +333,144,HA120462 +333,145,SN120467 +438,1,HAA13582 +438,2,SN120553 +438,3,SN121022 +438,4,SN120518 +438,5,SN120516 +438,6,SN120503 +438,7,SN12493A +438,8,HA120483 +438,9,HA121024 +438,10,SN121027 +438,11,SN120841 +438,12,SN120842 +438,13,SN120843 +438,14,HA080031 +438,15,HA080043 +438,16,HA080103 +438,17,HA080115 +438,18,HA080121 +438,19,HA080135 +438,20,HA080093 +438,21,HA080052 +438,22,HA080069 +438,23,HA080075 +438,24,HA080090 +438,25,HA080091 +438,26,HA080074 +438,27,HA080092 +438,28,HA080134 +438,29,HA080120 +438,30,HA080101 +438,31,HA080051 +438,32,HA080068 +438,33,HA080102 +438,34,HA080044 +438,35,HA080030 +438,36,HA122972 +438,37,SN120838 +438,38,SN120839 +438,39,SN120840 +438,40,SN121026 +438,41,SN121025 +438,42,HA120481 +438,43,HA120482 +438,44,SN120494 +438,45,SN120495 +438,46,SNA09017 +438,47,SN120515 +438,48,SN120519 +438,49,SNA09341 +449,1,SN12617A +449,2,SN12544B +449,3,SN120548 +449,4,SN120558 +449,5,SN12550B +449,6,HA120416 +449,7,HA120419 +449,8,SN120870 +449,9,SN120871 +449,10,SN12921A +449,11,SN120575 +449,12,SN120579 +449,13,SN120594 +449,14,SN120597 +449,15,SN120601 +449,16,SN120700 +449,17,SN120703 +449,18,SN120705 +449,19,SN120706 +449,20,SN120696 +449,21,SN120912 +449,22,SN120814 +449,23,SN120818 +449,24,SN120821 +449,25,SN120823 +449,26,SN120825 +449,27,SN120806 +449,28,SN120827 +449,29,SN120829 +449,30,SN120736 +449,31,SN120740 +449,32,SN120732 +449,33,SN120730 +449,34,SN120726 +449,35,SNA09185 +449,36,SN120665 +449,37,SN120659 +449,38,SN120653 +449,39,HA120642 +449,40,SN120635 +449,41,HA120633 +449,42,HA120621 +449,43,HA120625 +449,44,HAA13647 +449,45,HAA13371 +449,46,SN12616C +449,47,SNA09464 +449,48,HA120626 +449,49,HA120630 +449,50,HA120638 +449,51,HA120641 +449,52,SN120652 +449,53,SN12658B +449,54,SN120664 +449,55,SN120710 +449,56,SN120729 +449,57,SN120731 +449,58,SN120735 +449,59,SN120739 +449,60,SN120695 +449,61,SN120697 +449,62,SN120844 +449,63,SN120826 +449,64,SN120824 +449,65,SN120822 +449,66,SN120820 +449,67,SN120819 +449,68,SN120828 +449,69,SN120345 +449,70,SN120704 +449,71,SN120701 +449,72,SN120598 +449,73,SN120596 +449,74,SN120595 +449,75,SN120578 +449,76,SN120576 +449,77,SNA90798 +449,78,SN120431 +449,79,HA120420 +449,80,HA120418 +449,81,HA120417 +449,82,SN120551 +449,83,SN120559 +449,84,SN120547 +449,85,SN120545 +449,86,SN120533 +449,87,SN12532B +449,88,SN12617A +437,1,HAA13582 +437,2,SN120553 +437,3,SN121022 +437,4,SN120518 +437,5,SN120516 +437,6,SN120503 +437,7,SN12493A +437,8,HA120483 +437,9,HA121024 +437,10,SN121027 +437,11,SN120841 +437,12,SN120842 +437,13,SN120843 +437,14,HA080031 +437,15,HA080029 +437,16,HA080019 +437,17,HA080057 +437,18,HA080057 +437,19,HA080020 +437,20,HA080023 +437,21,HA080030 +437,22,HA122972 +437,23,SN120838 +437,24,SN120839 +437,25,SN120840 +437,26,SN121026 +437,27,SN121025 +437,28,HA120481 +437,29,HA120482 +437,30,SN120494 +437,31,SN120495 +437,32,SNA09017 +437,33,SN120515 +437,34,SN120519 +437,35,SNA09341 +472,1,HAA13582 +472,2,SN120527 +472,3,SN120522 +472,4,SN120535 +472,5,SN120405 +472,6,SN120401 +472,7,HAA13377 +472,8,HAA13374 +472,9,HAA13375 +472,10,SN120276 +472,11,SN12272A +472,12,SN120271 +472,13,SN120265 +472,14,SN120263 +472,15,SN120109 +472,16,SNA19495 +472,17,SN120121 +472,18,SN120127 +472,19,SN120900 +472,20,SN120125 +472,21,SN120123 +472,22,SN120130 +472,23,SN120139 +472,24,SN120137 +472,25,SN120144 +472,26,SN120146 +472,27,SN120151 +472,28,SN120160 +472,29,HAA13650 +472,30,SN120162 +472,31,SN120040 +472,32,SN120165 +472,33,SN120795 +472,34,HA120794 +472,35,HA030391 +472,36,HA030451 +472,37,HA030453 +472,38,HA120786 +472,39,HA030456 +472,40,HA120324 +472,41,SNA19473 +472,42,SN120315 +472,43,SNA19483 +472,44,SNA19472 +472,45,SN120435 +472,46,SNA19773 +472,47,SN120871 +472,48,SN12921A +472,49,SN12921A +472,50,SN120450 +472,51,SN120447 +472,52,SNA09593 +472,53,SN120316 +472,54,HA120322 +472,55,HA120323 +472,56,HA030457 +472,57,HA030454 +472,58,HA030452 +472,59,HA030450 +472,60,HA120796 +472,61,SN120797 +472,62,SNA90808 +472,63,SN120793 +472,64,SN120791 +472,65,SN120163 +472,66,HAA13651 +472,67,SNA19780 +472,68,SN120153 +472,69,SN120150 +472,70,SN120147 +472,71,SN120145 +472,72,SN120140 +472,73,SN120129 +472,74,SN120124 +472,75,SN120126 +472,76,SN120128 +472,77,SN120120 +472,78,SN120108 +472,79,SN120261 +472,80,SN120264 +472,81,SN120270 +472,82,SN12275A +472,83,SN120278 +472,84,HAA13376 +472,85,HAA13373 +472,86,SNA09201 +472,87,SN120400 +472,88,SN120404 +472,89,SN120406 +472,90,SN120536 +472,91,SNA40402 +472,92,HAA13583 +339,1,SN120891 +339,2,SNA90773 +339,3,SN12532B +339,4,SN120525 +339,5,SN12617A +339,6,SN120980 +339,7,SNA90830 +339,8,SNA09464 +339,9,HA120626 +339,10,HA120630 +339,11,HA120638 +339,12,HA120641 +339,13,SN120652 +339,14,SNA19721 +339,15,SN12658B +339,16,SN120661 +339,17,SN120712 +339,18,SN120717 +339,19,SN120719 +339,20,HA120721 +339,21,HAA13653 +339,22,SN120664 +339,23,SN120710 +339,24,SN120729 +339,25,SN120731 +339,26,SN120737 +339,27,SN120741 +339,28,SN122003 +339,29,HA030525 +339,30,HA030527 +339,31,HA030529 +339,32,HA030530 +339,33,HA030532 +339,34,SNA09576 +339,35,HA030535 +339,36,HA030536 +339,37,HA030539 +339,38,HA030541 +339,39,HA030542 +339,40,HA030523 +339,41,HA030522 +339,42,HA030519 +339,43,HA030516 +339,44,HAA19442 +339,45,HA030501 +339,46,HAA19444 +339,47,HA030505 +339,48,HA030507 +339,49,HA030509 +339,50,HA030511 +339,51,HA030512 +339,52,HA030512 +339,53,HA030510 +339,54,HA030508 +339,55,HA030506 +339,56,HA030504 +339,57,HA030502 +339,58,HA030500 +339,59,HAA19443 +339,60,HAA09198 +339,61,HA030517 +339,62,HA030518 +339,63,HA030521 +339,64,HAA09206 +339,65,HAA09202 +339,66,HA030540 +339,67,HA030538 +339,68,HA030537 +339,69,HA030534 +339,70,HA030533 +339,71,HA030531 +339,72,HA030528 +339,73,HA030526 +339,74,HA030524 +339,75,HA030493 +339,76,HA030494 +339,77,SN121035 +339,78,SN120827 +339,79,SN120829 +339,80,SN120739 +339,81,SN120695 +339,82,SN120686 +339,83,SN120682 +339,84,SN120590 +339,85,SN122002 +339,86,SN120742 +339,87,SN120738 +339,88,SN120732 +339,89,SN120730 +339,90,SN120726 +339,91,SNA09185 +339,92,SNA09577 +339,93,HAA13652 +339,94,HA120720 +339,95,SN120718 +339,96,SN120713 +339,97,SN120711 +339,98,SN120660 +339,99,SN120659 +339,100,SN120653 +339,101,SN120665 +339,102,HA120642 +339,103,SN120635 +339,104,HA120633 +339,105,HA120621 +339,106,HA120625 +339,107,SNA19739 +339,108,SNA19722 +339,109,SNA90831 +339,110,SN12617A +339,111,HAA13647 +339,112,SN12617B +339,113,SN12524B +339,114,SN120522 +339,115,SN120535 +339,116,SN120405 +339,117,SN120401 +339,118,SN120398 +339,119,SN121052 +339,120,SN121053 +339,121,SN120121 +339,122,SN120127 +339,123,SN120131 +339,124,SN120139 +339,125,SN120137 +339,126,SN120141 +339,127,SN120142 +339,128,SN120031 +339,129,HAA13387 +340,1,HAA13371 +340,2,SN12617B +340,3,SN12441B +340,4,SN12518A +340,5,SN120516 +340,6,SN120501 +340,7,SN120498 +340,8,SNA09572 +340,9,SN120380 +340,10,SN120377 +340,11,SN120371 +340,12,SN12370A +340,13,SN120361 +340,14,SN120355 +340,15,SN120350 +340,16,SN120349 +340,17,SN120347 +340,18,SN120339 +340,19,SN120335 +340,20,SN120181 +340,21,SN120178 +340,22,SN120174 +340,23,SN120953 +340,24,HAA91092 +340,25,SN120041 +340,26,SN120052 +340,27,SN120054 +340,28,SN120056 +340,29,SN120057 +340,30,SN120049 +340,31,SN120045 +340,32,SN120175 +340,33,SN120182 +340,34,SN120185 +340,35,SN120186 +340,36,SN120006 +340,37,SN120188 +340,38,SN120194 +340,39,SN120988 +340,40,SN120986 +340,41,SN120979 +340,42,SN120085 +340,43,SN120091 +340,44,SN120090 +340,45,HAA13388 +340,46,HAA13389 +340,47,SN120010 +340,48,SN120009 +340,49,SN120046 +340,50,SN120046 +340,51,SN120048 +340,52,SN120055 +340,53,SN120059 +340,54,SN120042 +340,55,SN120053 +340,56,SN120045 +340,57,SN120008 +340,58,SN120011 +340,59,SN120013 +340,60,SN120014 +340,61,SN120089 +340,62,SN120092 +340,63,SN120086 +340,64,SN120083 +340,65,SN120102 +340,66,SN120985 +340,67,SN120989 +340,68,SN120188 +340,69,SN120007 +340,70,SN120187 +340,71,SN120184 +340,72,SN120183 +340,73,SN120954 +340,74,HAA91092 +340,75,SN120177 +340,76,SN120179 +340,77,SN120180 +340,78,SN120334 +340,79,SN120338 +340,80,SN120346 +340,81,SN120348 +340,82,SN120351 +340,83,SN120360 +340,84,SN120362 +340,85,SN12369A +340,86,SN120372 +340,87,SN120376 +340,88,SN12367B +340,89,SN120381 +340,90,SN120496 +340,91,SN120499 +340,92,SN120515 +340,93,SN120519 +340,94,HAA13583 +340,95,HAA13371 +376,1,SN120183 +376,2,SN120177 +376,3,SN120179 +376,4,SN120180 +376,5,SN120334 +376,6,SN121066 +376,7,SN121068 +376,8,SN121067 +376,9,SN121041 +376,10,SN121038 +376,11,SN121037 +376,12,SN120216 +376,13,SN12367A +376,14,SN120372 +376,15,SN120376 +376,16,SN12367B +376,17,SN120381 +376,18,SN120496 +376,19,SN120499 +376,20,SN120515 +376,21,SN120519 +376,22,SN120523 +376,23,SN12532B +376,24,SN121069 +376,25,SNA19559 +376,26,SN12544A +376,27,SN120548 +376,28,SN120558 +376,29,SN12550C +376,30,HA120416 +376,31,HA120419 +376,32,SN12426B +376,33,SN120870 +376,34,SN120871 +376,35,SN12921C +376,36,SN120575 +376,37,SN120579 +376,38,SN120594 +376,39,SN120597 +376,40,SN120599 +376,41,SN120605 +376,42,SN120606 +376,43,SN120608 +376,44,SN120709 +376,45,SN120707 +376,46,SNA09412 +376,47,SN121059 +376,48,SN121059 +376,49,SN120708 +376,50,SN120609 +376,51,SN120607 +376,52,SN120604 +376,53,SN120603 +376,54,SN120600 +376,55,SN120598 +376,56,SN120596 +376,57,SN120595 +376,58,SN120578 +376,59,SN120576 +376,60,SNA90798 +376,61,SN120431 +376,62,HA120420 +376,63,HA120418 +376,64,HA120417 +376,65,SN120551 +376,66,SNA09318 +376,67,SN120547 +376,68,SN120766 +376,69,SN120899 +376,70,SN12618C +376,71,SN12617B +376,72,SN12441B +376,73,SN12518A +376,74,SN120516 +376,75,SN120501 +376,76,SN120498 +376,77,SN120380 +376,78,SN120377 +376,79,SN120371 +376,80,SN12368B +376,81,SN120217 +376,82,SN121040 +376,83,SN121036 +376,84,SN121039 +376,85,SN120187 +376,86,SN120184 +376,87,SN120183 +376,88,SN120177 +376,89,SN120179 +376,90,SN120180 +428,1,HAA13649 +428,2,SNA13768 +428,3,HA120625 +428,4,HAA13647 +428,5,SN12619A +428,6,SN12531B +428,7,SN12524D +428,8,SN120522 +428,9,SN120535 +428,10,SN120405 +428,11,SN120403 +428,12,SN120407 +428,13,SN120413 +428,14,SN120279 +428,15,SN12272A +428,16,SN120284 +428,17,SN120289 +428,18,SN120159 +428,19,SN120157 +428,20,SN120153 +428,21,SN120150 +428,22,SN120148 +428,23,SN121049 +428,24,SN121047 +428,25,HA030186 +428,26,HA030188 +428,27,HA030191 +428,28,HA030124 +428,29,HA030122 +428,30,HA030134 +428,31,HA030132 +428,32,HA030130 +428,33,HA030128 +428,34,HA030219 +428,35,HA030221 +428,36,HA030223 +428,37,HA030225 +428,38,HA030204 +428,39,HA030206 +428,40,HA030209 +428,41,HA030234 +428,42,HA030236 +428,43,HA030238 +428,44,HA030240 +428,45,HA030247 +428,46,HA030250 +428,47,HA030252 +428,48,HA030254 +428,49,HA030260 +428,50,HA030261 +428,51,HA030263 +428,52,HA030265 +428,53,HA030267 +428,54,HA030269 +428,55,HA030272 +428,56,HA030273 +428,57,HA030283 +428,58,HA030289 +428,59,HA030289 +428,60,HA030292 +428,61,HA030268 +428,62,HA030266 +428,63,HA030264 +428,64,HA030262 +428,65,HA030259 +428,66,HA030253 +428,67,HA030251 +428,68,HA030249 +428,69,HA030248 +428,70,HA030239 +428,71,HA030237 +428,72,HA030235 +428,73,HA030233 +428,74,HA030208 +428,75,HA030205 +428,76,HA030224 +428,77,HA030222 +428,78,HA030220 +428,79,HA030218 +428,80,HA030217 +428,81,HA030131 +428,82,HA030133 +428,83,HA030123 +428,84,HA030125 +428,85,HA030190 +428,86,HA030189 +428,87,HA030187 +428,88,SN121051 +428,89,SN121050 +428,90,SN121048 +428,91,SN120149 +428,92,SN120151 +428,93,HA120154 +428,94,SN120158 +428,95,SN120287 +428,96,SN120300 +428,97,SN120285 +428,98,SN12275A +428,99,SN120415 +428,100,SN120412 +428,101,SN120408 +428,102,SN120404 +428,103,SN120406 +428,104,SN120536 +428,105,HAA40520 +331,1,SN120004 +331,2,SN120542 +331,3,SN120766 +331,4,SN120899 +331,5,SN12617C +331,6,SN12531A +331,7,SN12441B +331,8,SNA09196 +331,9,SN120516 +331,10,SN120503 +331,11,SN12493A +331,12,HA120483 +331,13,SN120477 +331,14,SN120357 +331,15,SN120363 +331,16,SN120383 +331,17,SN120365 +331,18,SN12369B +331,19,SN12368A +331,20,SNA09200 +331,21,SN120226 +331,22,SN120367 +331,23,SN120372 +331,24,SN120374 +331,25,SN120373 +331,26,SN120238 +331,27,SN120236 +331,28,SN120234 +331,29,SN120096 +331,30,SN120094 +331,31,SN120P11 +331,32,SN120221 +331,33,SN120225 +331,34,SN120082 +331,35,SN120085 +331,36,SN120091 +331,37,SN120P12 +331,38,SN120P13 +331,39,SNA09237 +331,40,SN120P14 +331,41,SNA09238 +331,42,HAA13389 +331,43,SN120010 +331,44,SN120009 +331,45,SN120047 +331,46,SN120050 +331,47,SN120051 +331,48,SN120769 +331,49,HAA13383 +331,50,HAA13385 +331,51,HA120767 +331,52,HAA13385 +331,53,HA120767 +331,54,SN122769 +331,55,SN121042 +331,56,SN121043 +331,57,SN100810 +331,58,SN120017 +331,59,HA120018 +331,60,SN120019 +331,61,SN120023 +331,62,SN120024 +331,63,SN120025 +331,64,SN120026 +331,65,SNA40503 +331,66,SN120045 +331,67,SN120043 +331,68,SN120008 +331,69,SN120011 +331,70,SN120013 +331,71,SNA09242 +331,72,SNA09241 +331,73,SNA09240 +331,74,SNA09239 +331,75,SNA09236 +331,76,SN120092 +331,77,SN120086 +331,78,SN120083 +331,79,SN120084 +331,80,SN120222 +331,81,SN120223 +331,82,SN120224 +331,83,SN120227 +331,84,SN120220 +331,85,SN120095 +331,86,SN120240 +331,87,SN120235 +331,88,SN120237 +331,89,SN120239 +331,90,SN120378 +331,91,SN120375 +331,92,SN120371 +331,93,SN12370A +331,94,SN12367A +331,95,SN120366 +331,96,SN120382 +331,97,SN120364 +331,98,SN120358 +331,99,SN120479 +331,100,HA120481 +331,101,HA120482 +331,102,SN120494 +331,103,SN120495 +331,104,SNA09017 +331,105,SN120515 +331,106,SN120519 +331,107,SN120523 +331,108,SN12532B +331,109,SN12616E +331,110,SN120643 +331,111,SN120543 +331,112,SN120004 +429,1,SN121003 +429,2,SNA19559 +429,3,SN12544A +429,4,SN120548 +429,5,SN120558 +429,6,SN12550C +429,7,HA120416 +429,8,HA120419 +429,9,SN12426B +429,10,SN120870 +429,11,SN120871 +429,12,SN12921C +429,13,SN120457 +429,14,SN120459 +429,15,SN120792 +429,16,SN120789 +429,17,SN120778 +429,18,HA121057 +429,19,HA030331 +429,20,HA030337 +429,21,HA030309 +429,22,HA030419 +429,23,HA030439 +429,24,HA110571 +429,25,HA110572 +429,26,HA030438 +429,27,HA030437 +429,28,HA030442 +429,29,HA030443 +429,30,HA030445 +429,31,HA030426 +429,32,HA030423 +429,33,HA030422 +429,34,HA030420 +429,35,HA030418 +429,36,HA030416 +429,37,HA030413 +429,38,HA030402 +429,39,HA030404 +429,40,HA030405 +429,41,HA030306 +429,42,HA030310 +429,43,HA030311 +429,44,HA030313 +429,45,HA030337 +429,46,HA030315 +429,47,HA030336 +429,48,HA121056 +429,49,SN120779 +429,50,SN120780 +429,51,SN120790 +429,52,SN120577 +429,53,SN120474 +429,54,SN120576 +429,55,SNA90798 +429,56,SN120431 +429,57,HA120420 +429,58,HA120418 +429,59,HA120417 +429,60,SN120551 +429,61,SNA09318 +429,62,SN120547 +429,63,HAA40520 +429,64,HAA13582 +429,65,SN121022 +429,66,SN120522 +429,67,SN120535 +429,68,SN120405 +429,69,SN120402 +429,70,SN120891 +323,1,SN12616D +323,2,SN12531B +323,3,SN12524B +323,4,SN120539 +323,5,SN120537 +323,6,SN120409 +323,7,SN120413 +323,8,SN120279 +323,9,SN120273 +323,10,SN120302 +323,11,HA120304 +323,12,HA120306 +323,13,SN120308 +323,14,SN120311 +323,15,SN120312 +323,16,SN120292 +323,17,SN120291 +323,18,SN120775 +323,19,SN120774 +323,20,SN120171 +323,21,SN120171 +323,22,SN120319 +323,23,HA120322 +323,24,HA120323 +323,25,SN120443 +323,26,SN120438 +323,27,SN120316 +323,28,SN120314 +323,29,SN120297 +323,30,SN120290 +323,31,SN120293 +323,32,SN120295 +323,33,SN120313 +323,34,SN120296 +323,35,SN120294 +323,36,SN120310 +323,37,HA120307 +323,38,HA120305 +323,39,HA120303 +323,40,SN12275A +323,41,SN120415 +323,42,SN120412 +323,43,SN120411 +323,44,SN120410 +323,45,SN120538 +323,46,SN120540 +323,47,SN120881 +323,48,SN120525 +323,49,SN12616D +446,1,SN12618A +446,2,SN12441B +446,3,SNA09196 +446,4,SN120951 +446,5,SN120506 +446,6,SN120392 +446,7,SN120389 +446,8,SNA09195 +446,9,SN120248 +446,10,SN120246 +446,11,SN120242 +446,12,SN120100 +446,13,SN120096 +446,14,SN120094 +446,15,SN120092 +446,16,SN120086 +446,17,SN120083 +446,18,SN120084 +446,19,SN120222 +446,20,SN120219 +446,21,SN120213 +446,22,SN120216 +446,23,SN12367A +446,24,SN12370A +446,25,SN120361 +446,26,SN120355 +446,27,SNA40406 +446,28,SN120350 +446,29,SN120349 +446,30,SN120347 +446,31,SN120339 +446,32,SN120340 +446,33,SN120841 +446,34,SN120842 +446,35,SN120843 +446,36,HA080032 +446,37,HA080031 +446,38,HA080034 +446,39,HA080034 +446,40,HA080030 +446,41,HA080033 +446,42,HA122972 +446,43,SN120838 +446,44,SN120839 +446,45,SN120840 +446,46,SN120341 +446,47,SN120338 +446,48,SN120346 +446,49,SN120348 +446,50,SN120351 +446,51,SNA40406 +446,52,SN120360 +446,53,SN120362 +446,54,SN12369B +446,55,SN12368B +446,56,SN120217 +446,57,SN120214 +446,58,SNA09197 +446,59,SN120218 +446,60,SN120221 +446,61,SN120082 +446,62,SN120085 +446,63,SN120091 +446,64,SN120093 +446,65,SN120095 +446,66,SN120099 +446,67,SN120243 +446,68,SN120245 +446,69,SN120247 +446,70,SN120388 +446,71,SN120391 +446,72,SN120394 +446,73,SN120502 +446,74,SN120950 +446,75,SN120519 +446,76,SN120523 +446,77,SN12532B +446,78,SN12618A +432,1,SN12618C +432,2,SN12617B +432,3,SN12441A +432,4,SN12518A +432,5,SN120516 +432,6,SN120501 +432,7,SN120498 +432,8,SN120380 +432,9,SN120377 +432,10,SN120371 +432,11,SN12368B +432,12,SN120217 +432,13,SN120207 +432,14,SN120204 +432,15,SN121045 +432,16,SN121044 +432,17,SNA09323 +432,18,SN120056 +432,19,SN120057 +432,20,SN120049 +432,21,SN120050 +432,22,SN120051 +432,23,SN100809 +432,24,HA100808 +432,25,HA100794 +432,26,HA100783 +432,27,HA100239 +432,28,HA100220 +432,29,HA100220 +432,30,HA100240 +432,31,HA100784 +432,32,HA100793 +432,33,HA100807 +432,34,SN121042 +432,35,SN121043 +432,36,SN120043 +432,37,SN120048 +432,38,SN120059 +432,39,SN121046 +432,40,SN120062 +432,41,SN120196 +432,42,SN120203 +432,43,SN120208 +432,44,SN120216 +432,45,SN120367 +432,46,SN120372 +432,47,SN120376 +432,48,SN12367B +432,49,SN120381 +432,50,SN120496 +432,51,SN120499 +432,52,SN120515 +432,53,SN120519 +432,54,SN12619A +424,1,SN12618C +424,2,SN12617B +424,3,SN12441A +424,4,SNA09196 +424,5,SN120516 +424,6,SN120501 +424,7,SN120498 +424,8,SN120380 +424,9,SN120377 +424,10,SN120371 +424,11,SN12368B +424,12,SN120217 +424,13,SN120214 +424,14,SNA09197 +424,15,SN120218 +424,16,SN120221 +424,17,SN120082 +424,18,SN120102 +424,19,SN120985 +424,20,SN120981 +424,21,SN120061 +424,22,SN120049 +424,23,SN120045 +424,24,SNA40502 +424,25,SNA40501 +424,26,HAA19700 +424,27,SN120050 +424,28,SN120051 +424,29,SN100809 +424,30,HA100808 +424,31,HA100805 +424,32,HA100804 +424,33,HAA09360 +424,34,HAA10105 +424,35,HAA09361 +424,36,HA100798 +424,37,HA100794 +424,38,HA100796 +424,39,HA100763 +424,40,HA100771 +424,41,HA030001 +424,42,HA100010 +424,43,HAA09248 +424,44,HA030039 +424,45,HA030047 +424,46,HAA19695 +424,47,HA110245 +424,48,HAA19705 +424,49,HA110252 +424,50,HA110247 +424,51,HA110126 +424,52,HAA09127 +424,53,HA110058 +424,54,HA110058 +424,55,HA110108 +424,56,HA110125 +424,57,HA110251 +424,58,HA100026 +424,59,HAA19694 +424,60,HA030046 +424,61,HA030040 +424,62,HA100009 +424,63,HA100771 +424,64,HA100780 +424,65,SN121009 +424,66,SN121005 +424,67,SN121010 +424,68,SN120116 +424,69,SN120115 +424,70,SN120119 +424,71,SN121054 +424,72,SN121055 +424,73,SN120400 +424,74,SN120404 +424,75,SN120406 +424,76,HAA09248 +424,77,HA030002 +424,78,HA100770 +424,79,HA100762 +424,80,HA100793 +424,81,HA100795 +424,82,HAA19701 +424,83,SN122019 +424,84,SNA40503 +424,85,HA100797 +424,86,HAA09362 +424,87,HAA10104 +424,88,HAA09363 +424,89,HA100804 +424,90,HA100806 +424,91,HA100807 +424,92,SN121042 +424,93,SN121043 +424,94,SN120043 +424,95,SN120048 +424,96,SN120047 +424,97,SN120063 +424,98,SN120983 +424,99,SN120081 +424,100,SN120209 +424,101,SNA09197 +424,102,SN120218 +424,103,SN120221 +424,104,SN120082 +424,105,SN120986 +424,106,SN120979 +424,107,SN120084 +424,108,SN120222 +424,109,SN120219 +424,110,SN120213 +424,111,SN120216 +424,112,SN120367 +424,113,SN120372 +424,114,SN120376 +424,115,SN12367B +424,116,SN120381 +424,117,SN120496 +424,118,SN120499 +424,119,SN120515 +424,120,SN120519 +424,121,SN120523 +424,122,SN12532B +424,123,SN120536 +424,124,SN12618C +447,1,SN12618A +447,2,SN12531A +447,3,SN12524B +447,4,SNA90772 +447,5,SN120510 +447,6,SN120397 +447,7,SN120396 +447,8,SN120504 +447,9,SN120392 +447,10,SN120393 +447,11,SN120386 +447,12,SN120385 +447,13,SN120898 +447,14,SN120238 +447,15,SN120236 +447,16,SN120230 +447,17,SN120225 +447,18,SN120221 +447,19,SN120082 +447,20,SN120085 +447,21,SN120091 +447,22,SN120090 +447,23,HAA13388 +447,24,HAA13389 +447,25,SN120010 +447,26,SN120009 +447,27,SN120046 +447,28,SN120046 +447,29,SN120045 +447,30,SN120050 +447,31,SNA40503 +447,32,SN120051 +447,33,SN120008 +447,34,SN120011 +447,35,SN100810 +447,36,SN120013 +447,37,SN120017 +447,38,HA120018 +447,39,SN120014 +447,40,SN120019 +447,41,SN120089 +447,42,SN120092 +447,43,SN120023 +447,44,SN120024 +447,45,SN120086 +447,46,SN120025 +447,47,SN120083 +447,48,SN120026 +447,49,SN120084 +447,50,SN120222 +447,51,SN120223 +447,52,SN120224 +447,53,SN120228 +447,54,SN120235 +447,55,SN120237 +447,56,SNA09438 +447,57,SN120239 +447,58,SN120384 +447,59,SN120387 +447,60,SN120390 +447,61,SN120394 +447,62,SN120395 +447,63,SN120402 +447,64,SN120891 +447,65,SNA90773 +447,66,SN120525 +447,67,SN12532B +447,68,SN12618A +421,1,HA080661 +421,2,HAA13545 +421,3,HAA90784 +421,4,HA080562 +421,5,HA080545 +421,6,HA080541 +421,7,HA080531 +421,8,HA080544 +421,9,HA080527 +421,10,HA080222 +421,11,HA080226 +421,12,HA080236 +421,13,HA080030 +421,14,HA080212 +421,15,HA080033 +421,16,HA122972 +421,17,SN120838 +421,18,SN120839 +421,19,SN120840 +421,20,SN121026 +421,21,SN121025 +421,22,HA120481 +421,23,HA120482 +421,24,SN120494 +421,25,SN120495 +421,26,SNA09017 +421,27,SN120515 +421,28,SN120519 +421,29,SN120526 +421,30,SNA09341 +421,31,HAA13582 +421,32,SN120553 +421,33,SN121022 +421,34,SN120518 +421,35,SN120516 +421,36,SN120503 +421,37,SN12493A +421,38,HA120483 +421,39,HA121024 +421,40,SN121027 +421,41,SN120841 +421,42,SN120842 +421,43,SN120843 +421,44,HA080032 +421,45,HA080031 +421,46,HA080237 +421,47,HA080225 +421,48,HA080221 +421,49,HA080211 +421,50,HA080528 +421,51,HA080544 +421,52,HA080563 +421,53,HAA90784 +421,54,HA080661 +384,1,HAA13582 +384,2,SN120553 +384,3,SN121022 +384,4,SN120518 +384,5,SN120516 +384,6,SN120503 +384,7,SN12493A +384,8,HA120483 +384,9,HA121024 +384,10,SN121027 +384,11,SN120841 +384,12,SN120842 +384,13,SN120843 +384,14,HA080032 +384,15,HA080031 +384,16,HA080237 +384,17,HA080233 +384,18,HA080225 +384,19,HA080221 +384,20,HA080528 +384,21,HAA13538 +384,22,HA080563 +384,23,HAA90784 +384,24,HA080661 +384,25,HA080661 +384,26,HAA13545 +384,27,HAA90784 +384,28,HA080562 +384,29,HAA13538 +384,30,HA080531 +384,31,HA080527 +384,32,HA080222 +384,33,HA080226 +384,34,HA080233 +384,35,HA080236 +384,36,HA080030 +384,37,HA080033 +384,38,HA122972 +384,39,SN120838 +384,40,SN120839 +384,41,SN120840 +384,42,SN121026 +384,43,SN121025 +384,44,HA120481 +384,45,HA120482 +384,46,SN120494 +384,47,SN120495 +384,48,SNA09017 +384,49,SN120515 +384,50,SN120519 +384,51,SN120526 +384,52,SNA09341 +452,1,SN120734 +452,2,SN120744 +452,3,SN120748 +452,4,HAA13652 +452,5,HA120720 +452,6,SN120718 +452,7,SN120713 +452,8,SN120660 +452,9,SN120664 +452,10,SN120710 +452,11,SN120676 +452,12,SN120677 +452,13,SN120689 +452,14,SN120697 +452,15,SN120704 +452,16,SN120344 +452,17,SN120708 +452,18,SN120609 +452,19,SN120615 +452,20,HA120613 +452,21,HA120610 +452,22,HA120776 +452,23,SN120779 +452,24,SN120780 +452,25,SN120790 +452,26,SN120577 +452,27,SN120474 +452,28,SN120576 +452,29,SNA90798 +452,30,SN120431 +452,31,SN120310 +452,32,HA120307 +452,33,HA120305 +452,34,HA030191 +452,35,HA030193 +452,36,HA030193 +452,37,HA030199 +452,38,HA030200 +452,39,HA030201 +452,40,HA120304 +452,41,HA120306 +452,42,SN120309 +452,43,SN12426B +452,44,SN120870 +452,45,SN120457 +452,46,SN120459 +452,47,SN120792 +452,48,SN120789 +452,49,SN120778 +452,50,HA120777 +452,51,HA120611 +452,52,HA120612 +452,53,SN120614 +452,54,SN120709 +452,55,SN120707 +452,56,SNA19467 +452,57,SN120703 +452,58,SN120705 +452,59,SN120706 +452,60,SN120696 +452,61,SN120687 +452,62,SN120690 +452,63,SN120764 +452,64,SN120678 +452,65,SN120726 +452,66,SNA09185 +452,67,SN120665 +452,68,SN120661 +452,69,SN120712 +452,70,SN120717 +452,71,SN120719 +452,72,HA120721 +452,73,HAA13653 +452,74,HA120746 +452,75,SN120747 +452,76,SN120743 +452,77,SN120733 +448,1,SN12616D +448,2,SN12531B +448,3,SN12524B +448,4,SN120522 +448,5,SN120535 +448,6,SN120405 +448,7,SN120403 +448,8,SN120407 +448,9,SN120413 +448,10,SN120279 +448,11,SN12272A +448,12,SN120284 +448,13,SN120289 +448,14,SN120159 +448,15,SN120157 +448,16,SN120153 +448,17,SN120150 +448,18,SN120148 +448,19,SN121049 +448,20,SN120033 +448,21,SN120028 +448,22,SN120039 +448,23,SN120143 +448,24,SN120138 +448,25,SN120139 +448,26,SN120137 +448,27,SN120136 +448,28,SN120128 +448,29,SN120120 +448,30,SN120118 +448,31,SN120117 +448,32,SN120114 +448,33,SN120113 +448,34,SN120098 +448,35,SN120096 +448,36,SN120094 +448,37,SN120092 +448,38,SN120086 +448,39,SN120083 +448,40,SN120084 +448,41,SN120222 +448,42,SN120223 +448,43,SN120224 +448,44,SN120227 +448,45,SN120216 +448,46,SN12367A +448,47,SN12370A +448,48,SN120361 +448,49,SN120355 +448,50,SNA40406 +448,51,HAA13387 +448,52,SN120033 +448,53,SN120039 +448,54,SN120028 +448,55,SN120138 +448,56,SN120143 +448,57,SN120128 +448,58,SN120136 +448,59,SN121054 +448,60,SN120120 +448,61,SNA40406 +448,62,SN120360 +448,63,SN120362 +448,64,SN12369B +448,65,SN120217 +448,66,SN120226 +448,67,SN120225 +448,68,SN120221 +448,69,SN120082 +448,70,SN120085 +448,71,SN120091 +448,72,SN120093 +448,73,SN120095 +448,74,SN120097 +448,75,SN120112 +448,76,SN120111 +448,77,SN120115 +448,78,SN120119 +448,79,SN120121 +448,80,SN120127 +448,81,SN120131 +448,82,SN120139 +448,83,SN120137 +448,84,SN120141 +448,85,SN120142 +448,86,SN120031 +448,87,SN120032 +448,88,SN120034 +448,89,SN121048 +448,90,SN120149 +448,91,SN120151 +448,92,HA120154 +448,93,SN120158 +448,94,SN120287 +448,95,SN120300 +448,96,SN120285 +448,97,SN12275A +448,98,SN120415 +448,99,SN120412 +448,100,SN120408 +448,101,SN120400 +448,102,SN121055 +448,103,SN120404 +448,104,SN120406 +448,105,SN120536 +448,106,SNA40402 +448,107,SN120525 +448,108,SN12532B +448,109,SN12616D +494,1,SN121003 +494,2,SNA19559 +494,3,SN12544A +494,4,SN120548 +494,5,SN120558 +494,6,SN12550C +494,7,HA120416 +494,8,HA120419 +494,9,SN12426B +494,10,SN120870 +494,11,SN120871 +494,12,SN12921A +494,13,SN120450 +494,14,SN120447 +494,15,SN121063 +494,16,SN121060 +494,17,HA030447 +494,18,HA030385 +494,19,HA030377 +494,20,HA030465 +494,21,HA110817 +494,22,HA110549 +494,23,HA110611 +494,24,HA110611 +494,25,HA110550 +494,26,HA110818 +494,27,HA030466 +494,28,HA030378 +494,29,HA030386 +494,30,HA030446 +494,31,SN121062 +494,32,SN121061 +494,33,SN120449 +494,34,SN120451 +494,35,SNA90798 +494,36,SN120431 +494,37,HA120420 +494,38,HA120418 +494,39,HA120417 +494,40,SN120551 +494,41,SNA09318 +494,42,SN120547 +494,43,SN120545 +494,44,SN120533 +494,45,SN12532B +494,46,SN121003 +409,1,HA050182 +409,2,HA050160 +409,3,HA050136 +409,4,HA050111 +409,5,HA040298 +409,6,HA040108 +409,7,HA040023 +409,8,HA040047 +409,9,HA040005 +409,10,HA030477 +409,11,HA030484 +409,12,HA030486 +409,13,HA030491 +409,14,HA030493 +409,15,HA030494 +409,16,SN121035 +409,17,SN120827 +409,18,SN120829 +409,19,SN120730 +409,20,SN120726 +409,21,SNA09185 +409,22,SN120665 +409,23,SN120659 +409,24,SN120653 +409,25,HA120642 +409,26,SN120635 +409,27,HA120633 +409,28,SN120627 +409,29,SN120622 +409,30,SNA09464 +409,31,HAA13582 +409,32,SN121022 +409,33,SN120519 +409,34,SN120519 +409,35,SN120526 +409,36,SN121031 +409,37,HAA13583 +409,38,SNA09464 +409,39,HA120626 +409,40,HA120630 +409,41,HA120638 +409,42,HA120641 +409,43,SN120652 +409,44,SN12658B +409,45,SN120664 +409,46,SN120710 +409,47,SN120729 +409,48,SN120844 +409,49,SN121034 +409,50,SN121033 +409,51,HA030495 +409,52,HA030492 +409,53,HA030490 +409,54,HA030485 +409,55,HA030483 +409,56,HA030478 +409,57,HA040006 +409,58,HA040048 +409,59,HA040024 +409,60,HA040109 +409,61,HA040297 +409,62,HA050112 +409,63,HA050135 +409,64,HA050159 +409,65,HA050182 +466,1,HA040240 +466,2,HA040276 +466,3,HA040108 +466,4,HA040082 +466,5,HA040075 +466,6,HA040043 +466,7,HA040047 +466,8,HA040005 +466,9,HA040001 +466,10,HA030477 +466,11,HA030484 +466,12,HA030487 +466,13,HA030396 +466,14,SN121015 +466,15,SN120345 +466,16,SN120701 +466,17,SN120598 +466,18,SN120596 +466,19,SN120595 +466,20,SN120578 +466,21,SN120576 +466,22,SN120431 +466,23,HA120420 +466,24,HA120418 +466,25,HA120417 +466,26,SN120551 +466,27,SN120559 +466,28,SN120547 +466,29,SN120402 +466,30,SN120891 +466,31,HAA13583 +466,32,SNA09464 +466,33,SN120891 +466,34,SN120548 +466,35,SNA09317 +466,36,SN12550C +466,37,HA120416 +466,38,HA120419 +466,39,SN12426C +466,40,SN120870 +466,41,SN120575 +466,42,SN120579 +466,43,SN120594 +466,44,SN120597 +466,45,SN120601 +466,46,SN120700 +466,47,SN120344 +466,48,SN121014 +466,49,HA030395 +466,50,HA030488 +466,51,HA030487 +466,52,HA030483 +466,53,HA040002 +466,54,HA030478 +466,55,HA040006 +466,56,HA040043 +466,57,HA040048 +466,58,HA040076 +466,59,HA040083 +466,60,HA040109 +466,61,HA040277 +466,62,HA040240 +431,1,HAA13582 +431,2,SN120553 +431,3,SN121022 +431,4,SN120518 +431,5,HA120483 +431,6,SN120841 +431,7,HA080031 +431,8,HA080200 +431,9,HA080203 +431,10,HA080254 +431,11,HA080261 +431,12,HA080312 +431,13,HA080288 +431,14,HAA09339 +431,15,HA080295 +431,16,HA080327 +431,17,HA080357 +431,18,HA080357 +431,19,HA080328 +431,20,HA080294 +431,21,HAA09339 +431,22,HA080287 +431,23,HA080313 +431,24,HA080260 +431,25,HA080255 +431,26,HA080201 +431,27,HA080030 +431,28,SN120840 +431,29,HA120482 +431,30,SN120519 +431,31,SNA09341 +412,1,HA040240 +412,2,HA040276 +412,3,HA040078 +412,4,HA040082 +412,5,HA040023 +412,6,HA040471 +412,7,HA040005 +412,8,HA030477 +412,9,HA030484 +412,10,HA030486 +412,11,HA030491 +412,12,HA030493 +412,13,HA030494 +412,14,SN121035 +412,15,SN120827 +412,16,SN120829 +412,17,SN120730 +412,18,SN120726 +412,19,SNA09185 +412,20,SN120665 +412,21,SN120659 +412,22,SN120653 +412,23,HA120642 +412,24,SN120635 +412,25,HA120633 +412,26,SN120627 +412,27,SN120622 +412,28,HAA13582 +412,29,SN121022 +412,30,SN120519 +412,31,SN120519 +412,32,SN120526 +412,33,SN121031 +412,34,HAA13583 +412,35,SNA09464 +412,36,HA120626 +412,37,HA120630 +412,38,HA120638 +412,39,HA120641 +412,40,SN120652 +412,41,SN12658B +412,42,SN120664 +412,43,SN120710 +412,44,SN120729 +412,45,SN120844 +412,46,SN121034 +412,47,SN121033 +412,48,HA030495 +412,49,HA030492 +412,50,HA030490 +412,51,HA030485 +412,52,HA030483 +412,53,HA030478 +412,54,HA040006 +412,55,HA040014 +412,56,HA040024 +412,57,HA040083 +412,58,HA040109 +412,59,HA040277 +412,60,HA040240 +480,1,SN120519 +480,2,SN120523 +480,3,SN12532B +480,4,SN12618B +480,5,SN120980 +480,6,SNA90830 +480,7,SNA19721 +480,8,SN120652 +480,9,SN12658B +480,10,SN120661 +480,11,SN120657 +480,12,SN120654 +480,13,SN120571 +480,14,SN120569 +480,15,SN120566 +480,16,SN120563 +480,17,SN120562 +480,18,SN12921A +480,19,SN120450 +480,20,SN120447 +480,21,SN120442 +480,22,HA030457 +480,23,HA030454 +480,24,HA030452 +480,25,HA030450 +480,26,HA030389 +480,27,HA030387 +480,28,HA030385 +480,29,HA030384 +480,30,HA030379 +480,31,HA030564 +480,32,HA030382 +480,33,HA030339 +480,34,HA030337 +480,35,HA030338 +480,36,HA030343 +480,37,HAA09578 +480,38,HAA13694 +480,39,HA030346 +480,40,HA030347 +480,41,HA030350 +480,42,HA030351 +480,43,HA030353 +480,44,HA030354 +480,45,HA030357 +480,46,HA030356 +480,47,HA030355 +480,48,HA030352 +480,49,HA030351 +480,50,HA030349 +480,51,HA030348 +480,52,HA030345 +480,53,HAA13695 +480,54,HA030344 +480,55,HA030342 +480,56,HA030339 +480,57,HA030337 +480,58,HA030338 +480,59,HA030381 +480,60,HA030380 +480,61,HA030383 +480,62,HA030386 +480,63,HA030388 +480,64,HA030390 +480,65,HA030451 +480,66,HA030453 +480,67,HA120786 +480,68,HA030456 +480,69,SN120443 +480,70,SN120449 +480,71,SN120451 +480,72,SN12922A +480,73,SN120564 +480,74,SN120565 +480,75,SN120570 +480,76,SN120880 +480,77,SN120655 +480,78,SN120656 +480,79,SN120660 +480,80,SN120659 +480,81,SNA19739 +480,82,SNA19722 +480,83,SNA90831 +480,84,SN120899 +480,85,HAA13371 +480,86,SN12617B +480,87,SN121022 +480,88,SN12518A +480,89,SN12524B +341,1,SN120171 +341,2,SN120319 +341,3,HA120322 +341,4,HA120323 +341,5,HA030457 +341,6,HA030454 +341,7,HA030452 +341,8,HA030450 +341,9,HA030451 +341,10,HA030453 +341,11,HA120786 +341,12,HA030456 +341,13,SN120443 +341,14,SN120449 +341,15,SN120451 +341,16,SN12922A +341,17,SNA19711 +341,18,SNA19708 +341,19,SN120589 +341,20,SN120675 +341,21,SN120673 +341,22,SN120672 +341,23,SN120667 +341,24,SN120669 +341,25,SN120906 +341,26,SN120872 +341,27,SN120656 +341,28,SN120660 +341,29,SN120659 +341,30,SN120653 +341,31,HA120642 +341,32,SN120635 +341,33,HA120633 +341,34,SN120627 +341,35,SN120622 +341,36,HAA13371 +341,37,SN12617B +341,38,SN12441A +341,39,SN12518A +341,40,SN120516 +341,41,SN120501 +341,42,SN120498 +341,43,SNA09572 +341,44,SN120380 +341,45,SN120377 +341,46,SN120371 +341,47,SN12368A +341,48,SN120217 +341,49,SN120207 +341,50,SN120204 +341,51,SN120194 +341,52,SN120078 +341,53,SN120076 +341,54,SN120072 +341,55,SN120067 +341,56,SN120981 +341,57,SN120061 +341,58,SN120066 +341,59,SN120047 +341,60,SN120047 +341,61,SN120048 +341,62,SN120063 +341,63,SN120069 +341,64,SNA19692 +341,65,SN120073 +341,66,SN120077 +341,67,SN120983 +341,68,SN120079 +341,69,SN120196 +341,70,SN120203 +341,71,SN120208 +341,72,SN120216 +341,73,SN120367 +341,74,SN120372 +341,75,SN120376 +341,76,SN12367B +341,77,SN120381 +341,78,SN120496 +341,79,SN120499 +341,80,SN120515 +341,81,SN120519 +341,82,SN120523 +341,83,SN12532B +341,84,SN12618B +341,85,SN120623 +341,86,SN120632 +341,87,HA120638 +341,88,HA120641 +341,89,SN120652 +341,90,SN12658A +341,91,SN120661 +341,92,SN120657 +341,93,SN120662 +341,94,SN120666 +341,95,SN120668 +341,96,SN120671 +341,97,SN120670 +341,98,SN120674 +341,99,SN120588 +341,100,SN120587 +341,101,SNA19712 +341,102,SN12921A +341,103,SN120450 +341,104,SN120447 +341,105,SN120438 +341,106,SN120316 +341,107,SN120314 +341,108,SN120297 +341,109,SN120290 +341,110,SN120775 +341,111,SN120774 +341,112,SN120171 +434,1,SN120536 +434,2,SNA40402 +434,3,SN120525 +434,4,SN12532B +434,5,HAA13582 +434,6,SN120553 +434,7,SN121022 +434,8,SN120518 +434,9,HA120483 +434,10,HA121024 +434,11,SN120841 +434,12,HA080200 +434,13,HA080254 +434,14,HA080261 +434,15,HA080287 +434,16,HA080335 +434,17,HA080357 +434,18,HA080432 +434,19,HA080436 +434,20,HA080457 +434,21,HA080447 +434,22,HA080463 +434,23,HA080466 +434,24,HA080476 +434,25,HA081080 +434,26,HA080487 +434,27,HA080487 +434,28,HA080476 +434,29,HA081080 +434,30,HA080467 +434,31,HA080461 +434,32,HA080458 +434,33,HA080446 +434,34,HA080435 +434,35,HA080431 +434,36,HA080357 +434,37,HA080336 +434,38,HA080287 +434,39,HA080101 +434,40,SN120840 +434,41,SN121025 +434,42,HA120482 +434,43,SN120519 +434,44,SNA09341 +399,1,SN12616B +399,2,SN12544B +399,3,SN120548 +399,4,SN120558 +399,5,SN12550B +399,6,HA120416 +399,7,HA120419 +399,8,SN120870 +399,9,SN12426C +399,10,SN120430 +399,11,SN120433 +399,12,SN120557 +399,13,SN120561 +399,14,SN12921A +399,15,SN120871 +399,16,SN120450 +399,17,SN120447 +399,18,SN121063 +399,19,SN121060 +399,20,HA030447 +399,21,HA120462 +399,22,SN120467 +399,23,HA120466 +399,24,SN120468 +399,25,SN120470 +399,26,SN120472 +399,27,SN120473 +399,28,SN120792 +399,29,SN120789 +399,30,SN120778 +399,31,HA120777 +399,32,HA120611 +399,33,HA120612 +399,34,SN120614 +399,35,SN120709 +399,36,SN120707 +399,37,SNA09412 +399,38,SN121059 +399,39,SN121059 +399,40,SN120708 +399,41,SN120609 +399,42,SN120615 +399,43,HA120613 +399,44,HA120610 +399,45,HA120776 +399,46,SN120779 +399,47,SN120780 +399,48,SN120790 +399,49,SN120460 +399,50,SN120471 +399,51,SN120469 +399,52,SN120461 +399,53,HA120465 +399,54,HA120464 +399,55,SN120463 +399,56,HA030446 +399,57,SN121062 +399,58,SN121061 +399,59,SN120449 +399,60,SN120451 +399,61,SNA90798 +399,62,SN120556 +399,63,SN120560 +399,64,SN120434 +399,65,SN120432 +399,66,HA120420 +399,67,SN120431 +399,68,HA120418 +399,69,HA120417 +399,70,SN120551 +399,71,SNA09318 +399,72,SN120547 +399,73,SN120545 +399,74,SN120533 +399,75,SN12532B +399,76,SN12616B +433,1,HA030212 +433,2,HA030215 +433,3,HA030217 +433,4,HAA10043 +433,5,HAA10111 +433,6,HA030193 +433,7,HA030195 +433,8,HA030196 +433,9,HA030199 +433,10,HAA09426 +433,11,HA030201 +433,12,SN120999 +433,13,SN120164 +433,14,SN120040 +433,15,SN120165 +433,16,SN120795 +433,17,HA120794 +433,18,HA030391 +433,19,HA030389 +433,20,HA030387 +433,21,HA030385 +433,22,HA030384 +433,23,HA030379 +433,24,HA030564 +433,25,HA030382 +433,26,HA030339 +433,27,HA030337 +433,28,HA030314 +433,29,HA030312 +433,30,HA030307 +433,31,HA030407 +433,32,HA030309 +433,33,HA030414 +433,34,HA030415 +433,35,HA030417 +433,36,HA030419 +433,37,HA030421 +433,38,HA030424 +433,39,HA030425 +433,40,HAA10020 +433,41,HA030444 +433,42,HA030441 +433,43,HA030436 +433,44,HA030439 +433,45,HA030431 +433,46,HA030548 +433,47,HA030548 +433,48,HA030546 +433,49,HA030440 +433,50,HA030438 +433,51,HA030437 +433,52,HA030442 +433,53,HA030443 +433,54,HA030445 +433,55,HA030426 +433,56,HA030423 +433,57,HA030422 +433,58,HA030420 +433,59,HA030418 +433,60,HA030416 +433,61,HA030413 +433,62,HA030410 +433,63,HA030408 +433,64,HA030306 +433,65,HA030308 +433,66,HA030305 +433,67,HA030310 +433,68,HAA10056 +433,69,HA030311 +433,70,HA030313 +433,71,HA030315 +433,72,HA030337 +433,73,HA030338 +433,74,HA030381 +433,75,HA030380 +433,76,HA030383 +433,77,HA030386 +433,78,HA030388 +433,79,HA030390 +433,80,HA120796 +433,81,SN120797 +433,82,SNA90808 +433,83,SN120793 +433,84,SN120791 +433,85,HAA13386 +433,86,SN120998 +433,87,HA030200 +433,88,HAA09425 +433,89,HA030198 +433,90,HA030197 +433,91,HA030194 +433,92,HA030192 +433,93,HAA10110 +433,94,HAA10044 +433,95,HA030216 +433,96,HA030214 +433,97,HA030213 +433,98,HA030212 +357,1,SN12921A +357,2,SN120474 +357,3,SN120871 +357,4,SN120450 +357,5,SN120447 +357,6,SN120438 +357,7,SNA19772 +357,8,SNA19771 +357,9,SNA19473 +357,10,SN120315 +357,11,SNA19483 +357,12,SNA19472 +357,13,SN120435 +357,14,SNA19773 +357,15,SN120578 +357,16,SN120575 +357,17,SN120579 +357,18,SNA19774 +357,19,SN120790 +357,20,SN120460 +357,21,SNA19471 +357,22,SNA19470 +357,23,SNA19469 +357,24,SNA19478 +357,25,SNA19477 +357,26,SNA19476 +357,27,SNA19474 +357,28,SN120689 +357,29,SN120684 +357,30,HAA13665 +357,31,SN120693 +357,32,SN120698 +357,33,SNA19479 +357,34,SN120598 +357,35,SN120596 +357,36,SN120595 +455,1,SNA13761 +455,2,HA120546 +455,3,SNA13768 +455,4,HA120625 +455,5,SNA09343 +455,6,SN120553 +455,7,SN121022 +455,8,SNA19709 +455,9,SN120520 +455,10,SN120520 +455,11,SN121031 +455,12,HAA13583 +455,13,HA120626 +455,14,SNA13769 +455,15,HAA13580 +455,16,SNA13762 +473,1,SN120536 +473,2,SNA40402 +473,3,SN120525 +473,4,SN12532B +473,5,HAA13582 +473,6,SN120553 +473,7,SN121022 +473,8,SN120518 +473,9,SN120516 +473,10,SN120503 +473,11,SN12493A +473,12,HA120483 +473,13,HA121024 +473,14,SN121027 +473,15,SN120841 +473,16,SN120842 +473,17,SN120843 +473,18,HA080032 +473,19,HA080031 +473,20,HA080029 +473,21,HA080027 +473,22,HA080025 +473,23,HA080024 +473,24,HA080021 +473,25,HA080019 +473,26,HA080056 +473,27,HA080057 +473,28,HA080058 +473,29,HA080059 +473,30,HA080060 +473,31,HA080061 +473,32,HA080063 +473,33,HA080064 +473,34,HA080065 +473,35,HA080054 +473,36,HA080051 +473,37,HA080049 +473,38,HA080102 +473,39,HA080104 +473,40,HA080108 +473,41,HA080111 +462,1,SN120536 +462,2,SNA40402 +462,3,SN120525 +462,4,SN12532B +462,5,SN12619E +462,6,HAA13582 +462,7,SN120553 +462,8,HAA13649 +462,9,SNA13768 +462,10,HA120630 +462,11,HA120638 +462,12,HA120641 +462,13,SN120652 +462,14,SN12658B +462,15,SN120664 +462,16,SN120710 +462,17,SN120729 +462,18,SN120731 +462,19,SN120734 +462,20,SN120744 +462,21,SN120748 +462,22,HA030483 +462,23,HA030512 +462,24,HA030541 +462,25,HA030539 +462,26,HA030532 +462,27,HA030524 +441,1,HAA13648 +441,2,SN120536 +441,3,SNA40402 +441,4,SN120525 +441,5,SN12532B +441,6,SN12619E +441,7,SN121069 +441,8,HAA13582 +441,9,SNA19559 +441,10,SN12544A +441,11,SN120548 +441,12,SN120558 +441,13,SN12550C +441,14,HA120416 +441,15,HA120419 +441,16,SN12426B +441,17,SN120870 +441,18,SN120871 +441,19,SN12921C +441,20,SN120575 +441,21,SN120579 +441,22,SN120594 +441,23,SN120597 +441,24,SN120599 +441,25,SN120605 +441,26,SN120606 +441,27,SN120608 +441,28,SN120709 +441,29,SN120707 +441,30,SNA09412 +441,31,SN121059 +441,32,SNA19467 +441,33,SN120703 +441,34,SN120705 +441,35,SN120706 +441,36,SN120696 +441,37,SN120912 +441,38,SN120740 +442,1,HAA13649 +442,2,SNA13768 +442,3,HA120625 +442,4,HAA13647 +442,5,HAA40520 +442,6,SN12618C +442,7,SN12617B +442,8,SNA40401 +442,9,SN120913 +442,10,SN120536 +442,11,SNA40402 +442,12,SN12441B +442,13,SN12518A +442,14,SN120516 +442,15,SN120501 +442,16,SN120498 +442,17,SN120380 +442,18,SN120377 +442,19,SN120371 +442,20,SN12368B +442,21,SN120217 +442,22,SN121040 +442,23,SN121036 +442,24,SN121039 +442,25,SN120187 +442,26,SN120184 +442,27,SN120183 +442,28,SN120177 +442,29,SN120179 +442,30,SN120180 +442,31,SN120334 +442,32,SN121066 +442,33,SN121068 +442,34,SN121067 +442,35,SN120006 +442,36,SN120194 +442,37,SN120988 +442,38,SN120986 +442,39,SN120979 +442,40,SN120085 +442,41,SN120091 +442,42,SN120090 +442,43,HAA13388 +442,44,HAA13389 +442,45,SN120010 +442,46,SN120009 +442,47,SN120046 +495,1,HAA13649 +495,2,SNA13768 +495,3,HA120625 +495,4,HAA13647 +495,5,HAA40520 +495,6,SN12619C +495,7,SN12617B +495,8,SN12524B +495,9,SN120522 +495,10,SN120881 +495,11,SN120537 +495,12,SN120409 +495,13,HA120304 +495,14,HA120306 +495,15,SN120309 +495,16,SN120435 +495,17,SN120442 +495,18,HA030457 +495,19,HA120786 +495,20,HA030454 +495,21,HA030452 +495,22,HA030450 +495,23,HA030389 +495,24,HA030387 +495,25,HA030385 +495,26,HA030384 +495,27,HA030379 +495,28,HA030564 +495,29,HA030382 +495,30,HA030343 +495,31,HAA13694 +495,32,HA030346 +495,33,HA030347 +495,34,HA030350 +495,35,HA030353 +495,36,HA030354 +495,37,HA030357 +495,38,HA030323 +495,39,HA030326 +495,40,HA030445 +495,41,HA030444 +495,42,HA030435 +495,43,HA030440 +495,44,HA030438 +495,45,HA030436 +495,46,HA030442 +495,47,HA030443 +495,48,HA030328 +495,49,HA030329 +495,50,HA030308 +474,1,SN120367 +474,2,SN120372 +474,3,SN120374 +474,4,SN120373 +474,5,SN120238 +474,6,SN120236 +474,7,SN120230 +474,8,SN120225 +474,9,SN120221 +474,10,SN120082 +474,11,SN120085 +474,12,SN120091 +474,13,SN120P12 +474,14,SN120P13 +474,15,SNA09237 +474,16,SN120P14 +474,17,SNA09238 +474,18,HAA13389 +474,19,SN120010 +474,20,SN120009 +474,21,SN120047 +474,22,SN120047 +474,23,SN120008 +474,24,SN120011 +474,25,SN120013 +474,26,SNA09242 +474,27,SNA09241 +474,28,SNA09240 +474,29,SNA09239 +474,30,SNA09236 +474,31,SN120092 +474,32,SN120086 +474,33,SN120083 +474,34,SN120084 +474,35,SN120222 +474,36,SN120223 +474,37,SN120224 +474,38,SN120228 +474,39,SN120235 +474,40,SN120237 +474,41,SN120239 +474,42,SN120378 +474,43,SN120375 +474,44,SN120371 +474,45,SN12370A +479,1,SNA90867 +479,2,SNA90869 +479,3,SNA90831 +479,4,SN120899 +479,5,SN12617C +479,6,SN12531A +479,7,SN12524B +479,8,SNA90772 +479,9,SN120514 +479,10,SN120512 +479,11,SN120508 +479,12,SN120507 +479,13,SN120502 +479,14,SNA09221 +479,15,SNA09222 +479,16,SNA09223 +479,17,SNA09224 +479,18,SNA09225 +479,19,SNA09226 +479,20,SNA09227 +479,21,SN120P09 +479,22,SNA09228 +479,23,SNA09229 +479,24,SNA09230 +479,25,SN120364 +479,26,SN120358 +479,27,SN120326 +479,28,SN120352 +479,29,SN120354 +479,30,SN120928 +479,31,SNA40406 +479,32,SNA40406 +479,33,SN120216 +479,34,SN12367A +479,35,SN12370A +479,36,SN120361 +479,37,SN120355 +479,38,SN120329 +479,39,SN120330 +479,40,SN120357 +479,41,SNA09231 +479,42,SN120P10 +479,43,SNA09233 +479,44,SNA09234 +479,45,SNA09235 +479,46,SN120P08 +479,47,SN120P07 +479,48,SN120P06 +479,49,SN120P05 +479,50,SN120P04 +479,51,SN120P03 +479,52,SN120505 +479,53,SN120509 +479,54,SN120511 +479,55,SN120513 +479,56,SNA90870 +479,57,SN120525 +479,58,SN12441B +479,59,SN120526 +479,60,SN12532B +479,61,SN12616E +479,62,SN120980 +479,63,SNA90830 +479,64,SNA90868 +479,65,SNA90871 +479,66,SNA90867 326,1,HAA13579 326,2,SN120635 326,3,SNA13767 @@ -326,3 +3222,74 @@ 354,72,SN120775 354,73,SN120774 354,74,SN120171 +423,1,WIA04208 +423,2,WIA12275 +423,3,WIA12283 +423,4,HA140020 +423,5,WIA12348 +423,6,WIA12340 +423,7,HA100158 +423,8,WIY42982 +423,9,HA100152 +423,10,HA080008 +423,11,HA080020 +423,12,HA080022 +423,13,HA080023 +423,14,HA080026 +423,15,WIY42916 +423,16,HA080092 +423,17,HA080094 +423,18,HA080096 +423,19,HA080099 +423,20,HA081165 +423,21,HA080101 +423,22,HA080102 +423,23,HA080104 +423,24,HA080108 +423,25,HA080111 +423,26,HA080112 +423,27,HA080113 +423,28,HA080030 +423,29,HA080028 +423,30,HA080033 +423,31,SN120840 +423,32,HA120482 +423,33,SN120519 +423,34,SN120526 +423,35,SNA09341 +423,36,HAA13582 +423,37,SN120553 +423,38,SN121022 +423,39,SN120518 +423,40,HA120483 +423,41,SN120841 +423,42,HA080032 +423,43,HA080031 +423,44,HA080034 +423,45,HA080029 +423,46,HA080027 +423,47,HA080025 +423,48,HA080024 +423,49,HA080021 +423,50,HA080109 +423,51,HA080107 +423,52,HA080105 +423,53,HA080103 +423,54,HA080100 +423,55,HA081166 +423,56,HA080098 +423,57,HA080097 +423,58,HA080095 +423,59,HA080093 +423,60,WIY42915 +423,61,HA080007 +423,62,HA080019 +423,63,HA100153 +423,64,HA100159 +423,65,WIA12339 +423,66,HAA13562 +423,67,WIA12295 +423,68,WIY42983 +423,69,WIA12284 +423,70,WIA12274 +423,71,WIA04208 diff --git a/gen/net/cbaines/suma/R.java b/gen/net/cbaines/suma/R.java index c18db21..d8cc3af 100644 --- a/gen/net/cbaines/suma/R.java +++ b/gen/net/cbaines/suma/R.java @@ -54,59 +54,74 @@ public final class R { public static final int u9_radio_button=0x7f02001d; } public static final class id { - public static final int busStopID=0x7f0a000c; - public static final int busStopLoadBar=0x7f0a0011; - public static final int busStopMessage=0x7f0a000e; - public static final int busStopName=0x7f0a0004; - public static final int busStopTimes=0x7f0a000f; - public static final int busTimeContentLayout=0x7f0a000d; - public static final int centerLoadBar=0x7f0a0010; - public static final int check1=0x7f0a0021; - public static final int childname=0x7f0a0020; - public static final int donateBitcoinAddress=0x7f0a0018; + public static final int busActivityBusID=0x7f0a0005; + public static final int busActivityContentLayout=0x7f0a000b; + public static final int busActivityHeaderLayout=0x7f0a0004; + public static final int busActivityMessage=0x7f0a000c; + public static final int busActivityTimes=0x7f0a000d; + public static final int busActivityU1=0x7f0a0006; + public static final int busActivityU1N=0x7f0a0007; + public static final int busActivityU2=0x7f0a0008; + public static final int busActivityU6=0x7f0a0009; + public static final int busActivityU9=0x7f0a000a; + public static final int busStopID=0x7f0a0018; + public static final int busStopListItems=0x7f0a000f; + public static final int busStopLoadBar=0x7f0a001d; + public static final int busStopMessage=0x7f0a001a; + public static final int busStopName=0x7f0a0010; + public static final int busStopTimes=0x7f0a001b; + public static final int busTimeContentLayout=0x7f0a0019; + public static final int centerLoadBar=0x7f0a001c; + public static final int check1=0x7f0a002c; + public static final int childname=0x7f0a002b; + public static final int donateBitcoinAddress=0x7f0a0023; public static final int donateButton=0x7f0a0003; - public static final int donateDialogErrorMessage=0x7f0a0017; - public static final int donateDialogMessage=0x7f0a0014; - public static final int donateDialogMessageLayout=0x7f0a0016; - public static final int donateDialogProgress=0x7f0a0015; - public static final int favouriteCheckBox=0x7f0a000b; - public static final int favouriteDialogMessage=0x7f0a0019; - public static final int favouriteListItems=0x7f0a001a; - public static final int findContentLayout=0x7f0a001c; - public static final int findListItems=0x7f0a001e; - public static final int findLoadBar=0x7f0a001d; + public static final int donateDialogErrorMessage=0x7f0a0022; + public static final int donateDialogMessage=0x7f0a001f; + public static final int donateDialogMessageLayout=0x7f0a0021; + public static final int donateDialogProgress=0x7f0a0020; + public static final int favouriteCheckBox=0x7f0a0017; + public static final int favouriteDialogMessage=0x7f0a0029; + public static final int favouriteListItems=0x7f0a002a; + public static final int findContentLayout=0x7f0a0025; + public static final int findListItems=0x7f0a0027; + public static final int findLoadBar=0x7f0a0026; public static final int helpExpandableListView=0x7f0a0002; - public static final int layout_root=0x7f0a0012; - public static final int linearLayout1=0x7f0a0005; - public static final int linearLayout2=0x7f0a0013; - public static final int mapview=0x7f0a001f; - public static final int menu_about=0x7f0a0027; - public static final int menu_favourites=0x7f0a0028; - public static final int menu_find=0x7f0a0023; - public static final int menu_find_my_location=0x7f0a0025; - public static final int menu_preferences=0x7f0a0024; - public static final int menu_refresh_stop=0x7f0a0029; - public static final int menu_view=0x7f0a0026; - public static final int radio_u1=0x7f0a0006; - public static final int radio_u1n=0x7f0a0007; - public static final int radio_u2=0x7f0a0008; - public static final int radio_u6=0x7f0a0009; - public static final int radio_u9=0x7f0a000a; - public static final int searchBar=0x7f0a001b; + public static final int layout_root=0x7f0a000e; + public static final int linearLayout1=0x7f0a0011; + public static final int linearLayout2=0x7f0a001e; + public static final int mapview=0x7f0a0028; + public static final int menu_about=0x7f0a0032; + public static final int menu_favourites=0x7f0a0033; + public static final int menu_find=0x7f0a002e; + public static final int menu_find_my_location=0x7f0a0030; + public static final int menu_next_stop=0x7f0a0036; + public static final int menu_preferences=0x7f0a002f; + public static final int menu_previous_stop=0x7f0a0034; + public static final int menu_refresh_stop=0x7f0a0035; + public static final int menu_view=0x7f0a0031; + public static final int radio_u1=0x7f0a0012; + public static final int radio_u1n=0x7f0a0013; + public static final int radio_u2=0x7f0a0014; + public static final int radio_u6=0x7f0a0015; + public static final int radio_u9=0x7f0a0016; + public static final int searchBar=0x7f0a0024; public static final int textView1=0x7f0a0000; public static final int textView2=0x7f0a0001; - public static final int view_list=0x7f0a0022; + public static final int view_list=0x7f0a002d; } public static final class layout { public static final int about_dialog=0x7f030000; - public static final int bustimes=0x7f030001; - public static final int donate_dialog=0x7f030002; - public static final int favourite_dialog=0x7f030003; - public static final int find=0x7f030004; - public static final int main=0x7f030005; - public static final int view_child_row=0x7f030006; - public static final int view_dialog=0x7f030007; - public static final int view_group_row=0x7f030008; + public static final int bus_activity=0x7f030001; + public static final int bus_stop_dialog=0x7f030002; + public static final int bustimes=0x7f030003; + public static final int donate_dialog=0x7f030004; + public static final int find=0x7f030005; + public static final int main=0x7f030006; + public static final int poi_dialog=0x7f030007; + public static final int view_child_row=0x7f030008; + public static final int view_dialog=0x7f030009; + public static final int view_group_row=0x7f03000a; } public static final class menu { public static final int map_menu=0x7f090000; @@ -130,85 +145,86 @@ public final class R { public static final int U9=0x7f07000d; /** About Strings */ - public static final int about=0x7f070033; - public static final int about_android_market=0x7f070040; - public static final int about_android_market_summary=0x7f070041; - public static final int about_copyright=0x7f070036; - public static final int about_copyright_summary=0x7f070037; - public static final int about_data=0x7f07003e; - public static final int about_data_summary=0x7f07003f; - public static final int about_database=0x7f07004a; - public static final int about_database_summary=0x7f07004b; - public static final int about_developer=0x7f07003c; - public static final int about_developer_summary=0x7f07003d; - public static final int about_donate=0x7f07004c; - public static final int about_donate_summary=0x7f07004d; - public static final int about_help_message=0x7f070015; - public static final int about_license=0x7f070038; - public static final int about_license_summary=0x7f070039; - public static final int about_map_data=0x7f070042; - public static final int about_map_data_summary=0x7f070043; - public static final int about_map_icons=0x7f070044; - public static final int about_map_icons_summary=0x7f070045; - public static final int about_map_tiles=0x7f070048; - public static final int about_map_tiles_summary=0x7f070049; + public static final int about=0x7f070034; + public static final int about_android_market=0x7f070041; + public static final int about_android_market_summary=0x7f070042; + public static final int about_copyright=0x7f070037; + public static final int about_copyright_summary=0x7f070038; + public static final int about_data=0x7f07003f; + public static final int about_data_summary=0x7f070040; + public static final int about_database=0x7f07004b; + public static final int about_database_summary=0x7f07004c; + public static final int about_developer=0x7f07003d; + public static final int about_developer_summary=0x7f07003e; + public static final int about_donate=0x7f07004d; + public static final int about_donate_summary=0x7f07004e; + public static final int about_help_message=0x7f070016; + public static final int about_license=0x7f070039; + public static final int about_license_summary=0x7f07003a; + public static final int about_map_data=0x7f070043; + public static final int about_map_data_summary=0x7f070044; + public static final int about_map_icons=0x7f070045; + public static final int about_map_icons_summary=0x7f070046; + public static final int about_map_tiles=0x7f070049; + public static final int about_map_tiles_summary=0x7f07004a; /** About Messages */ - public static final int about_menu_instruction_text=0x7f07002c; - public static final int about_osm_map=0x7f070046; - public static final int about_osm_map_summary=0x7f070047; - public static final int about_project=0x7f07003a; - public static final int about_project_summary=0x7f07003b; - public static final int about_version=0x7f070034; - public static final int about_version_summary=0x7f070035; + public static final int about_menu_instruction_text=0x7f07002d; + public static final int about_osm_map=0x7f070047; + public static final int about_osm_map_summary=0x7f070048; + public static final int about_project=0x7f07003b; + public static final int about_project_summary=0x7f07003c; + public static final int about_version=0x7f070035; + public static final int about_version_summary=0x7f070036; public static final int app_name=0x7f070004; - public static final int bitcoin_error_message=0x7f07001a; + public static final int bitcoin_error_message=0x7f07001b; public static final int building_non_residential=0x7f070007; public static final int building_residential=0x7f070006; - public static final int bustimes_favourite_checkbox_label=0x7f07002d; - public static final int credits_help_message=0x7f070018; - public static final int donate_button=0x7f070019; - public static final int donate_dialog_error_title=0x7f07002f; - public static final int donate_dialog_message=0x7f07002e; - public static final int favourites_dialog_message=0x7f07001c; - public static final int favourites_help_message=0x7f070016; - public static final int find_help_message=0x7f070011; - public static final int findmylocation_help_message=0x7f070013; + public static final int bustimes_favourite_checkbox_label=0x7f07002e; + public static final int credits_help_message=0x7f070019; + public static final int donate_button=0x7f07001a; + public static final int donate_dialog_error_title=0x7f070030; + public static final int donate_dialog_message=0x7f07002f; + public static final int favourites_dialog_message=0x7f07001d; + public static final int favourites_dialog_title=0x7f070010; + public static final int favourites_help_message=0x7f070017; + public static final int find_help_message=0x7f070012; + public static final int findmylocation_help_message=0x7f070014; public static final int legal_message=0x7f070005; - public static final int licence_help_message=0x7f070017; + public static final int licence_help_message=0x7f070018; /** Help Messages */ - public static final int map_help_message=0x7f070010; + public static final int map_help_message=0x7f070011; public static final int menu_about=0x7f07000e; public static final int menu_favourites=0x7f07000f; public static final int menu_find=0x7f070000; public static final int menu_find_my_location=0x7f070003; - public static final int menu_next_stop=0x7f070031; + public static final int menu_next_stop=0x7f070032; public static final int menu_preferences=0x7f070001; - public static final int menu_previous_stop=0x7f070030; - public static final int menu_refresh_stop=0x7f070032; + public static final int menu_previous_stop=0x7f070031; + public static final int menu_refresh_stop=0x7f070033; public static final int menu_view=0x7f070002; public static final int pref_bus_stop=0x7f070008; - public static final int preferences=0x7f07001b; - public static final int preferences_catagory_data=0x7f070028; - public static final int preferences_catagory_live_bus_times=0x7f070021; + public static final int preferences=0x7f07001c; + public static final int preferences_catagory_data=0x7f070029; + public static final int preferences_catagory_live_bus_times=0x7f070022; /** Preferences Messages */ - public static final int preferences_catagory_positioning=0x7f07001d; - public static final int preferences_gps=0x7f07001e; - public static final int preferences_gps_disabled=0x7f070020; - public static final int preferences_gps_enabled=0x7f07001f; - public static final int preferences_help_message=0x7f070012; - public static final int preferences_non_uni_link=0x7f070029; - public static final int preferences_non_uni_link_disabled=0x7f07002b; - public static final int preferences_non_uni_link_enabled=0x7f07002a; - public static final int preferences_non_uni_link_live_bus_times=0x7f070025; - public static final int preferences_non_uni_link_live_bus_times_disabled=0x7f070027; - public static final int preferences_non_uni_link_live_bus_times_enabled=0x7f070026; - public static final int preferences_uni_link_live_bus_times=0x7f070022; - public static final int preferences_uni_link_live_bus_times_disabled=0x7f070024; - public static final int preferences_uni_link_live_bus_times_enabled=0x7f070023; - public static final int view_help_message=0x7f070014; + public static final int preferences_catagory_positioning=0x7f07001e; + public static final int preferences_gps=0x7f07001f; + public static final int preferences_gps_disabled=0x7f070021; + public static final int preferences_gps_enabled=0x7f070020; + public static final int preferences_help_message=0x7f070013; + public static final int preferences_non_uni_link=0x7f07002a; + public static final int preferences_non_uni_link_disabled=0x7f07002c; + public static final int preferences_non_uni_link_enabled=0x7f07002b; + public static final int preferences_non_uni_link_live_bus_times=0x7f070026; + public static final int preferences_non_uni_link_live_bus_times_disabled=0x7f070028; + public static final int preferences_non_uni_link_live_bus_times_enabled=0x7f070027; + public static final int preferences_uni_link_live_bus_times=0x7f070023; + public static final int preferences_uni_link_live_bus_times_disabled=0x7f070025; + public static final int preferences_uni_link_live_bus_times_enabled=0x7f070024; + public static final int view_help_message=0x7f070015; } public static final class xml { public static final int about=0x7f050000; diff --git a/res/layout/bus_activity.xml b/res/layout/bus_activity.xml new file mode 100644 index 0000000..3037916 --- /dev/null +++ b/res/layout/bus_activity.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:gravity="center|top" + android:orientation="vertical" + android:theme="@android:style/Theme.NoTitleBar" > + + <LinearLayout + android:id="@+id/busActivityHeaderLayout" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" > + + <TextView + android:id="@+id/busActivityBusID" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <TextView + android:id="@+id/busActivityU1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/u1_back_selected" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:text="@string/U1" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#FFFFFF" /> + + <TextView + android:id="@+id/busActivityU1N" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/u1n_back_selected" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:text="@string/U1N" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#FFFFFF" /> + + <TextView + android:id="@+id/busActivityU2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/u2_back_selected" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:text="@string/U2" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#FFFFFF" /> + + <TextView + android:id="@+id/busActivityU6" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/u6_back_selected" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:text="@string/U6" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#FFFFFF" /> + + <TextView + android:id="@+id/busActivityU9" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/u9_back_selected" + android:paddingLeft="5dp" + android:paddingRight="5dp" + android:text="@string/U9" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#FFFFFF" /> + </LinearLayout> + + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/busActivityContentLayout" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:gravity="center" + android:orientation="vertical" > + + <TextView + android:id="@+id/busActivityMessage" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <ListView + android:id="@+id/busActivityTimes" + android:layout_width="fill_parent" + android:layout_height="wrap_content" > + </ListView> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/bus_stop_dialog.xml b/res/layout/bus_stop_dialog.xml new file mode 100644 index 0000000..24148c6 --- /dev/null +++ b/res/layout/bus_stop_dialog.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/layout_root" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="horizontal" + android:padding="10dp" > + + <ListView + android:id="@+id/busStopListItems" + android:layout_width="fill_parent" + android:layout_height="wrap_content" > + </ListView> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/favourite_dialog.xml b/res/layout/poi_dialog.xml index 44cb02a..cf97083 100644 --- a/res/layout/favourite_dialog.xml +++ b/res/layout/poi_dialog.xml @@ -4,7 +4,9 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" - android:padding="10dp" > + android:paddingBottom="10dp" + android:paddingLeft="10dp" + android:paddingRight="10dp" > <TextView android:id="@+id/favouriteDialogMessage" diff --git a/res/menu/stop_menu.xml b/res/menu/stop_menu.xml index 408e536..c44efa2 100644 --- a/res/menu/stop_menu.xml +++ b/res/menu/stop_menu.xml @@ -1,17 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > - <!--<item + <item android:id="@+id/menu_previous_stop" android:icon="@drawable/ic_menu_back" - android:title="@string/menu_previous_stop"/>--> + android:title="@string/menu_previous_stop"/> <item android:id="@+id/menu_refresh_stop" android:icon="@drawable/ic_menu_refresh" android:title="@string/menu_refresh_stop"/> - <!--<item + <item android:id="@+id/menu_next_stop" android:icon="@drawable/ic_menu_forward" - android:title="@string/menu_next_stop"/>--> + android:title="@string/menu_next_stop"/> </menu>
\ No newline at end of file diff --git a/res/raw/ormlite_config.txt b/res/raw/ormlite_config.txt index 60f9ade..2268ae9 100644 --- a/res/raw/ormlite_config.txt +++ b/res/raw/ormlite_config.txt @@ -1,3 +1,3 @@ # -# generated on 2012/02/01 07:59:58 +# generated on 2012/02/19 09:50:39 # diff --git a/res/values/strings.xml b/res/values/strings.xml index 3bde7e1..c602a26 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -17,6 +17,7 @@ <string name="U9">U9</string> <string name="menu_about">About</string> <string name="menu_favourites">Favourites</string> + <string name="favourites_dialog_title">Favourites</string> <!-- Help Messages --> <string name="map_help_message">You can drag the map to move it, you can use pinch motions to zoom in and out, this can also be done with the buttons at the bottom of the screen. Taping the building markers will show you there full name, and tapping the bus stop markers will show the live times at that stop. Presing and holding a marker, will add the item to the favourites list.</string> @@ -101,7 +102,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.< <!-- About Strings --> <string name="about">About</string> <string name="about_version">Version</string> - <string name="about_version_summary">0.2.2 (alpha)</string> + <string name="about_version_summary">0.3 (alpha)</string> <string name="about_copyright">Copyright</string> <string name="about_copyright_summary">© 2012, Christopher Baines</string> <string name="about_license">License</string> diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index f4cdd9f..4a12e1c 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -28,7 +28,7 @@ android:orderingFromXml="true" android:title="@string/preferences_catagory_data" > <CheckBoxPreference - android:key="nonUniLinkBusStop" + android:key="nonUniLinkBusStops" android:summaryOff="@string/preferences_non_uni_link_disabled" android:summaryOn="@string/preferences_non_uni_link_enabled" android:title="@string/preferences_non_uni_link" /> diff --git a/src/net/cbaines/suma/BuildingNumOverlay.java b/src/net/cbaines/suma/BuildingNumOverlay.java index 4bd5f3a..32616a7 100644 --- a/src/net/cbaines/suma/BuildingNumOverlay.java +++ b/src/net/cbaines/suma/BuildingNumOverlay.java @@ -25,12 +25,10 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; - import org.osmdroid.views.MapView; import org.osmdroid.views.MapView.Projection; import org.osmdroid.views.overlay.Overlay; -import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -62,13 +60,13 @@ public class BuildingNumOverlay extends Overlay { private static final String TAG = "BuildingNumOverlay"; - private final Context context; + private final MapActivity context; private Dao<Building, String> buildingDao; private float userScale = 1f; - public BuildingNumOverlay(Context context, List<Building> buildings) throws SQLException { + public BuildingNumOverlay(MapActivity context, List<Building> buildings) throws SQLException { super(context); this.context = context; @@ -93,25 +91,29 @@ public class BuildingNumOverlay extends Overlay { /** * Draw a marker on each of our items. populate() must have been called first.<br/> * <br/> - * The marker will be drawn twice for each Item in the Overlay--once in the shadow phase, skewed and darkened, then again in the non-shadow phase. The - * bottom-center of the marker will be aligned with the geographical coordinates of the Item.<br/> + * The marker will be drawn twice for each Item in the Overlay--once in the shadow phase, skewed and darkened, then + * again in the non-shadow phase. The bottom-center of the marker will be aligned with the geographical coordinates + * of the Item.<br/> * <br/> - * The order of drawing may be changed by overriding the getIndexToDraw(int) method. An item may provide an alternate marker via its - * OverlayItem.getMarker(int) method. If that method returns null, the default marker is used.<br/> + * The order of drawing may be changed by overriding the getIndexToDraw(int) method. An item may provide an + * alternate marker via its OverlayItem.getMarker(int) method. If that method returns null, the default marker is + * used.<br/> * <br/> * The focused item is always drawn last, which puts it visually on top of the other items.<br/> * * @param canvas - * the Canvas upon which to draw. Note that this may already have a transformation applied, so be sure to leave it the way you found it + * the Canvas upon which to draw. Note that this may already have a transformation applied, so be sure to + * leave it the way you found it * @param mapView - * the MapView that requested the draw. Use MapView.getProjection() to convert between on-screen pixels and latitude/longitude pairs + * the MapView that requested the draw. Use MapView.getProjection() to convert between on-screen pixels + * and latitude/longitude pairs * @param shadow * if true, draw the shadow layer. If false, draw the overlay contents. */ @Override public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) { - if (shadow) { + if (shadow || !isEnabled()) { return; } @@ -180,43 +182,72 @@ public class BuildingNumOverlay extends Overlay { } @Override - public boolean onSingleTapUp(final MotionEvent event, final MapView mapView) { + public boolean onSingleTapConfirmed(final MotionEvent event, final MapView mapView) { + if (!this.isEnabled()) return false; final Building building = getSelectedItem(event, mapView); if (building == null) { - Log.i(TAG, "No building pressed"); + // Log.v(TAG, "No building pressed"); return false; } else { - Log.i(TAG, "building Pressed " + building.id); + Log.v(TAG, "building Pressed " + building.id); + + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, building.name + " (" + building.id + ")", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(building.name + " (" + building.id + ")"); + } + context.activityToast.show(); - Toast.makeText(context, building.name + " (" + building.id + ")", Toast.LENGTH_SHORT).show(); return true; } } + public boolean onDoubleTap(final MotionEvent e, final MapView mapView) { + return false; + } + @Override public boolean onLongPress(final MotionEvent event, final MapView mapView) { + if (!this.isEnabled()) return false; final Building building = getSelectedItem(event, mapView); if (building == null) { - Log.i(TAG, "No building pressed"); + // Log.v(TAG, "No building pressed"); return false; } else { - Log.i(TAG, "building Pressed " + building.id); + Log.v(TAG, "building Pressed " + building.id); if (building.favourite) { building.favourite = false; - Toast.makeText(context, building.id + " removed from favourites", Toast.LENGTH_SHORT).show(); + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, building.id + " removed from favourites", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(building.id + " removed from favourites"); + } + context.activityToast.show(); + } else { - Toast.makeText(context, building.id + " made a favourite", Toast.LENGTH_SHORT).show(); + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, building.id + " made a favourite", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(building.id + " made a favourite"); + } + context.activityToast.show(); building.favourite = true; } @@ -224,7 +255,6 @@ public class BuildingNumOverlay extends Overlay { try { buildingDao.update(building); } catch (SQLException e) { - // TODO Auto-generated catch block e.printStackTrace(); } diff --git a/src/net/cbaines/suma/Bus.java b/src/net/cbaines/suma/Bus.java index d8d96f3..b36dd89 100644 --- a/src/net/cbaines/suma/Bus.java +++ b/src/net/cbaines/suma/Bus.java @@ -53,13 +53,13 @@ public class Bus { /** * The direction which the bus is travelling. */ - @DatabaseField(canBeNull = false) + @DatabaseField(canBeNull = true) String direction; /** * The destination the bus is travelling towards. */ - @DatabaseField(canBeNull = false, foreign = true) + @DatabaseField(canBeNull = true, foreign = true) BusStop destination; Bus() { @@ -98,7 +98,11 @@ public class Bus { } String getName() { - return route.code + direction; + if (direction != null) { + return route.code + direction; + } else { + return route.code; + } } @Override diff --git a/src/net/cbaines/suma/BusActivity.java b/src/net/cbaines/suma/BusActivity.java new file mode 100644 index 0000000..b802cfb --- /dev/null +++ b/src/net/cbaines/suma/BusActivity.java @@ -0,0 +1,343 @@ +package net.cbaines.suma; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; + +import org.apache.http.client.ClientProtocolException; +import org.json.JSONException; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +import com.j256.ormlite.android.apptools.OrmLiteBaseActivity; + +public class BusActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Preferences { + final static String TAG = "BusActivity"; + + private TextView U1RouteTextView; + private TextView U1NRouteTextView; + private TextView U2RouteTextView; + private TextView U6RouteTextView; + private TextView U9RouteTextView; + + private TextView busIDTextView; + + private TextView busContentMessage; + private LinearLayout busActivityContentLayout; + + Toast activityToast; + + /** + * The bus this activity is focused on + */ + private Bus bus; + /** + * The bus stop this activity is working from + */ + private BusStop busStop; + + Runnable refreshData; + + protected Timetable timetable; + private Timetable visibleTimetable; + + private ListView timetableView; + + private Context instance; + + // BusStops and if they are being updated by the handler + List<BusStop> busStops; + + private HashMap<BusStop, GetTimetableStopTask> tasks = new HashMap<BusStop, GetTimetableStopTask>(); + + Handler handler; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.bus_activity); + instance = this; + + String busID = getIntent().getExtras().getString("busID"); + String busStopID = getIntent().getExtras().getString("busStopID"); + final DatabaseHelper helper = getHelper(); + + try { + List<Bus> buses = helper.getBusDao().queryForEq(Bus.ID_FIELD_NAME, busID); + bus = null; + if (buses.size() == 0) { + Log.e(TAG, "Bus " + busID + " not found!"); + } else if (buses.size() == 1) { + bus = buses.get(0); + } else if (buses.size() > 1) { + Log.e(TAG, "Found more than one bus? " + busID); + } + + helper.getBusRouteDao().refresh(bus.route); + + busStop = null; + if (busStopID != null) { + List<BusStop> busStops = helper.getBusStopDao().queryForEq(BusStop.ID_FIELD_NAME, busStopID); + if (busStops.size() == 0) { + Log.e(TAG, "BusStop " + busStopID + " not found!"); + } else if (busStops.size() == 1) { + busStop = busStops.get(0); + } else if (busStops.size() > 1) { + Log.e(TAG, "Found more than one busStop? " + busStopID); + } + } + + U1RouteTextView = (TextView) findViewById(R.id.busActivityU1); + U1NRouteTextView = (TextView) findViewById(R.id.busActivityU1N); + U2RouteTextView = (TextView) findViewById(R.id.busActivityU2); + U6RouteTextView = (TextView) findViewById(R.id.busActivityU6); + U9RouteTextView = (TextView) findViewById(R.id.busActivityU9); + + busIDTextView = (TextView) findViewById(R.id.busActivityBusID); + + busContentMessage = (TextView) findViewById(R.id.busActivityMessage); + busActivityContentLayout = (LinearLayout) findViewById(R.id.busActivityContentLayout); + timetableView = (ListView) findViewById(R.id.busActivityTimes); + + if (bus.id != null) { + Log.i(TAG, "Bus id is not null (" + bus.id + ") setting busIDTextView"); + busIDTextView.setText(bus.id + " " + bus.getName()); + } else { + Log.w(TAG, "Bus id is null?"); + // Might not ever happen + busIDTextView.setText("Unidentified"); + } + + U1RouteTextView.setVisibility(View.GONE); + U1NRouteTextView.setVisibility(View.GONE); + U2RouteTextView.setVisibility(View.GONE); + U6RouteTextView.setVisibility(View.GONE); + U9RouteTextView.setVisibility(View.GONE); + + // if (bus.route.uniLink) { + Log.i(TAG, "Bus is uniLink"); + if (bus.route.code.equals("U1")) { + U1RouteTextView.setVisibility(View.VISIBLE); + } else if (bus.route.code.equals("U1N")) { + U1NRouteTextView.setVisibility(View.VISIBLE); + } else if (bus.route.code.equals("U2")) { + U2RouteTextView.setVisibility(View.VISIBLE); + } else if (bus.route.code.equals("U6")) { + U6RouteTextView.setVisibility(View.VISIBLE); + } else if (bus.route.code.equals("U9")) { + U9RouteTextView.setVisibility(View.VISIBLE); + } else { + Log.e(TAG, "Route not found " + bus.route.code); + } + // } else { + // Log.i(TAG, "Bus is not uniLink"); + // } + + } catch (NumberFormatException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } + + busStops = bus.route.getRouteSection(instance, bus.direction); + Log.i(TAG, "Got " + busStops.size() + " bus stops for this bus"); + + if (bus.destination != null) { + Log.i(TAG, "Bus destination is " + bus.destination); + } else { + Log.i(TAG, "Bus destination is null"); + } + + /* + * for (int i = 0;; i++) { BusStop nextStop = bus.route.moveInRoute(instance, busStops.get(i), bus.direction, + * 1); + * + * if (nextStop.equals(busStop) || (bus.destination != null && bus.destination.equals(nextStop))) { break; } + * + * busStops.add(nextStop); busStopsActive.add(false); + * + * if (busStops.size() > 50) { Log.e(TAG, "Got more than 50 bus stops"); break; } } + */ + + refreshData = new Runnable() { + @Override + public void run() { + for (int num = timetableView.getFirstVisiblePosition(); num < timetableView.getLastVisiblePosition(); num++) { + Stop stop = timetable.get(num); + + GetTimetableStopTask task = tasks.get(busStops.get(num)); + + if (stop.timeOfFetch == null || (stop.timeOfFetch.getTime() - System.currentTimeMillis()) > 20000) { + if (task != null) { + if (task.getStatus() == AsyncTask.Status.FINISHED) { + task = null; + } + } + + if (task == null) { + task = new GetTimetableStopTask(); + BusStop[] str = { stop.busStop }; + task.execute(str); + tasks.put(stop.busStop, task); + } + } + + } + handler.postDelayed(refreshData, 50000); + } + }; + + } + + public void onResume() { + super.onResume(); + + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + if (sharedPrefs.getBoolean(UNI_LINK_BUS_TIMES, UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT) + || sharedPrefs.getBoolean(NON_UNI_LINK_BUS_TIMES, NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT)) { + Log.i(TAG, "Live Times enabled"); + timetable = (Timetable) getLastNonConfigurationInstance(); + + handler = new Handler(); + + if (timetable == null) { + Log.i(TAG, "No Previous timetable"); + timetable = new Timetable(); + for (int i = 0; i < busStops.size(); i++) { + timetable.add(new Stop(bus, busStops.get(i), null, null, false)); + } + Log.v(TAG, "Finished adding placeholder stops"); + } else { + Log.i(TAG, "Displaying previous timetable"); + + } + displayTimetable(timetable); + handler.postDelayed(refreshData, 500); + + } else { + Log.i(TAG, "Live Times Disabled"); + busContentMessage.setText("Live bus times disabled"); + busContentMessage.setVisibility(View.VISIBLE); + } + + } + + public void onPause() { + if (handler != null) { // BusTimes are enabled + handler.removeCallbacks(refreshData); + for (GetTimetableStopTask task : tasks.values()) { + if (task != null) { + task.cancel(true); + } + } + + Log.i(TAG, "Stoping refreshing timetable data"); + } + + super.onPause(); + } + + private class GetTimetableStopTask extends AsyncTask<BusStop, Integer, Stop> { + private String errorMessage; + + private BusStop busStop; + + private int position; + + protected void onPreExecute() { + // progBar.setVisibility(View.VISIBLE); + } + + protected Stop doInBackground(BusStop... busStopArray) { + busStop = busStopArray[0]; + position = busStops.indexOf(busStop); + Stop stop = null; + + try { + Log.i(TAG, "Fetching stop for busStop " + position); + stop = DataManager.getStop(instance, bus, busStop); + if (stop == null) { + stop = new Stop(bus, busStop, null, null, false); + } + Log.i(TAG, "Finished fetching stop for busStop " + position); + } catch (SQLException e) { + errorMessage = "Error message regarding SQL?"; + e.printStackTrace(); + } catch (ClientProtocolException e) { + errorMessage = "ClientProtocolException!?!"; + e.printStackTrace(); + } catch (IOException e) { + errorMessage = "Error fetching bus times from server, are you connected to the internet?"; + e.printStackTrace(); + } catch (JSONException e) { + errorMessage = "Error parsing bus times"; + e.printStackTrace(); + } + return stop; + } + + protected void onPostExecute(Stop stop) { + // Log.i(TAG, "Got timetable"); + if (stop == null) { + Log.i(TAG, "Its null"); + + busContentMessage.setText(errorMessage); + busContentMessage.setVisibility(View.VISIBLE); + } else { + synchronized (timetable) { + timetable.set(position, stop); + displayTimetable(timetable); + } + } + } + + } + + private void displayTimetable(Timetable timetable) { + visibleTimetable = (Timetable) timetable.clone(); + + // Log.i(TAG, "Displaying timetable, it contains " + visibleTimetable.size() + " stops"); + + if (timetable.size() == 0) { + busContentMessage.setText("No Busses"); + busContentMessage.setVisibility(View.VISIBLE); + busActivityContentLayout.setGravity(Gravity.CENTER); + } else { + if (visibleTimetable.size() == 0) { + busActivityContentLayout.setGravity(Gravity.CENTER); + busContentMessage.setText("No Busses (With the current enabled routes)"); + busContentMessage.setVisibility(View.VISIBLE); + timetableView.setVisibility(View.GONE); + } else { + timetableView.setVisibility(View.VISIBLE); + busContentMessage.setVisibility(View.GONE); + BusSpecificTimetableAdapter adapter; + if ((adapter = (BusSpecificTimetableAdapter) timetableView.getAdapter()) != null) { + adapter.updateTimetable(visibleTimetable); + } else { + adapter = new BusSpecificTimetableAdapter(this, visibleTimetable); + timetableView.setAdapter(adapter); + if (busStop != null) { + Log.i(TAG, + "Moving to position of " + busStop.description + " which is " + + busStops.indexOf(busStop)); + timetableView.setSelection(busStops.indexOf(busStop)); + } + } + busActivityContentLayout.setGravity(Gravity.TOP); + } + } + } +} diff --git a/src/net/cbaines/suma/BusRoute.java b/src/net/cbaines/suma/BusRoute.java index 5af89e7..4152605 100644 --- a/src/net/cbaines/suma/BusRoute.java +++ b/src/net/cbaines/suma/BusRoute.java @@ -20,7 +20,11 @@ package net.cbaines.suma; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashSet; import java.util.List; +import java.util.Set; import android.content.Context; import android.util.Log; @@ -41,6 +45,8 @@ import com.j256.ormlite.table.DatabaseTable; @DatabaseTable(tableName = "busroutes") public class BusRoute { + private static final String TAG = "BusRoute"; + final static String ID_FIELD_NAME = "id"; final static String CODE_FIELD_NAME = "code"; final static String LABEL_FIELD_NAME = "label"; @@ -57,25 +63,46 @@ public class BusRoute { @DatabaseField(canBeNull = false) String label; + /** + * The direction the bus is travelling if it is moving through the route and sequence is increasing. + * <ul> + * <li>U1 = A</li> + * <li>U2 = B</li> + * <li>U6 = H</li> + * </ul> + */ @DatabaseField(canBeNull = true) String forwardDirection; + /** + * The direction the bus is travelling if it is moving through the route and sequence is decreasing. + * <ul> + * <li>U1 = C</li> + * <li>U2 = C</li> + * <li>U6 = C</li> + * </ul> + */ @DatabaseField(canBeNull = true) String reverseDirection; + @DatabaseField(canBeNull = false) + boolean uniLink; + BusRoute() { } - public BusRoute(Integer id, String code, String label, String forwardDirection, String reverseDirection) { + public BusRoute(Integer id, String code, String label, String forwardDirection, String reverseDirection, + boolean uniLink) { this.id = id.intValue(); this.code = code; this.label = label; this.forwardDirection = forwardDirection; this.reverseDirection = reverseDirection; + this.uniLink = uniLink; } - public BusRoute(Integer id, String code, String label) { - this(id, code, label, null, null); + public BusRoute(Integer id, String code, String label, boolean uniLink) { + this(id, code, label, null, null, uniLink); } public String toString() { @@ -108,33 +135,107 @@ public class BusRoute { * Untested? * * @param context - * @param stop + * @param busStop * @param moveAmount * @return */ - BusStop moveInRoute(Context context, BusStop stop, String direction, int moveAmount) { + Set<BusStop> moveInRoute(final Context context, final BusStop busStop, final int moveAmount) { + + Set<BusStop> busStops = new HashSet<BusStop>(); + if (moveAmount == 0) { - return stop; + busStops.add(busStop); + return busStops; } DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); - if (forwardDirection != null) { + try { + Dao<RouteStops, Integer> routeStopsDao = helper.getRouteStopsDao(); + Dao<BusStop, String> busStopDao = helper.getBusStopDao(); + + QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); + routeStopsQueryBuilder.where().eq(RouteStops.ROUTE_ID_FIELD_NAME, this.id); + PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); + + List<RouteStops> routeStopsFound = routeStopsDao.query(routeStopsPreparedQuery); - if (direction == null) { - return null; + ArrayList<Integer> stopIndexs = new ArrayList<Integer>(); + + for (RouteStops routeStop : routeStopsFound) { + if (routeStop.busStop.id.equals(busStop.id)) { + stopIndexs.add(routeStop.sequence - 1); + } } - if (forwardDirection.equals(direction)) { + for (int stopIndex : stopIndexs) { + + if (moveAmount > 0) { + Log.v(TAG, "Moving forward " + moveAmount + " stops from " + busStop + " (" + stopIndex + "/" + + routeStopsFound.size() + ")"); + int stopWanted = stopIndex + moveAmount; + if ((stopWanted + 1) > routeStopsFound.size()) { + Log.v(TAG, "Off the end of the route"); + stopWanted = stopWanted % (routeStopsFound.size() - 1); + } + Log.v(TAG, " Stop wanted " + stopWanted); + BusStop busStopWanted = routeStopsFound.get(stopWanted).busStop; + + busStopDao.refresh(busStopWanted); + + Log.v(TAG, " Moving to " + busStopWanted + " (" + stopWanted + ") in route " + this); + + busStops.add(busStopWanted); + } else { + Log.v(TAG, "stopIndex " + stopIndex); + int stopWanted = stopIndex + moveAmount; + if (stopWanted < 0) { + stopWanted = routeStopsFound.size() - (Math.abs(stopWanted) % routeStopsFound.size()); + } + Log.v(TAG, "stopWanted " + stopWanted); + busStopDao.refresh(routeStopsFound.get(stopWanted).busStop); + + Log.v(TAG, + "Moving backwards " + moveAmount + " stops from " + busStop + " to " + + routeStopsFound.get(stopWanted).busStop + " in route " + this); + + busStops.add(routeStopsFound.get(stopWanted).busStop); + } + } - } else if (reverseDirection.equals(direction)) { - moveAmount = -moveAmount; + return busStops; + } catch (SQLException e) { + e.printStackTrace(); + } + Log.e(TAG, "Error moving in route"); + return null; + } + + /** + * Untested? + * + * @param context + * @param busStop + * @param moveAmount + * @return + */ + BusStop moveInRoute(final Context context, final BusStop busStop, String direction, final int moveAmount) { + + if (moveAmount == 0) { + return busStop; + } + + DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + + if (forwardDirection != null) { + + if (direction != null) { + + if (direction.equals("E")) + direction = "A"; // Quick hack for U1E } else { - Log.e("BusRoute", "Direction (" + direction + ") doesnt match either the forward direction (" + forwardDirection + ") or reverse direction (" - + reverseDirection + ")"); - return null; + throw new NullPointerException("direction is null"); } - } try { @@ -146,48 +247,232 @@ public class BusRoute { PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); List<RouteStops> routeStopsFound = routeStopsDao.query(routeStopsPreparedQuery); - Log.v("BusRoute", "Found " + routeStopsFound.size() + " stops"); - - int stopIndex = 0; - + + int stopIndex = -1; + for (RouteStops routeStop : routeStopsFound) { - if (routeStop.stop.id.equals(stop.id)) { - stopIndex = routeStop.sequence -1; + if (routeStop.busStop.id.equals(busStop.id)) { + if (stopIndex == -1) { + stopIndex = routeStop.sequence - 1; + } else { // ARGH, weird route + if (busStop.id.equals("HAA13651") && id == 327) { // U6 by Wessex Lane + if (direction.equals(forwardDirection)) { + stopIndex = 23; + } else { + stopIndex = 68; + } + } else if (busStop.id.equals("SN120134") && id == 327) { // U6 opposite the Stile + if (direction.equals(forwardDirection)) { + stopIndex = 30; + } else { + stopIndex = 59; + } + } else if (busStop.id.equals("SN120163") && id == 327) { // U6 just up past wessex lane + if (direction.equals(forwardDirection)) { + stopIndex = 22; + } else { + stopIndex = 67; + } + } else if (busStop.id.equals("SNA19482") && id == 327) { // U6 General Hosp West Door + if (moveAmount > 0) { + stopIndex = 44; + } else { + stopIndex = 43; + } + } else if (busStop.id.equals("SN120134") && id == 329) { // U2 opposite the Stile + if (direction.equals(forwardDirection)) { + stopIndex = 13; + } else { + stopIndex = 30; + } + } else if (busStop.id.equals("SN120527") && id == 329) { // U2 Civic Centre Rd os stop AO Civic + // Ctr E + if (moveAmount > 0) { + stopIndex = 0; + } else { + stopIndex = 42; + } + } else if (busStop.id.equals("SNA09298") && id == 329) { // U2 Bassett Green Rd nr Bassett Green + // Cl SE + if (moveAmount > 0) { + stopIndex = 22; + } else { + stopIndex = 21; + } + } else if (busStop.id.equals("SN120520") && id == 326) { // U1 By the station + if (direction.equals(forwardDirection)) { + stopIndex = 7; + } else { + stopIndex = 80; + } + } else if (busStop.id.equals("HA030183") && id == 326) { // U1 Up past Wessex Lane + if (direction.equals(forwardDirection)) { + stopIndex = 35; + } else { + stopIndex = 50; + } + } else if (busStop.id.equals("HA030212") && id == 326) { // U1 At Eastleigh + if (moveAmount > 0) { + stopIndex = 43; + } else { + stopIndex = 42; + } + } else if (busStop.id.equals("SN120171") && id == 354) { // U9 + if (moveAmount > 0) { + stopIndex = 0; + } else { + stopIndex = 73; + } + } else { + Log.e(TAG, "Error, unknown bus stop " + busStop.id + " (" + busStop.description + + ") that appears mutiple times in " + toString()); + throw new RuntimeException("Error, unknown bus stop " + busStop.id + + " that appears mutiple times in " + toString()); + } + Log.v(TAG, "Selecting " + stopIndex + " for " + busStop.id + " as direction == " + direction); + } } } if (moveAmount > 0) { - Log.v("BusStop", "stopIndex " + stopIndex); - int stopWanted = (stopIndex + moveAmount) % (routeStopsFound.size() + 1); - Log.v("BusStop", "stopWanted " + stopWanted); - busStopDao.refresh(routeStopsFound.get(stopWanted).stop); + Log.v(TAG, "Moving forward " + moveAmount + " stops from " + busStop + " (" + stopIndex + "/" + + routeStopsFound.size() + ")"); + int stopWanted = stopIndex + moveAmount; + if ((stopWanted + 1) > routeStopsFound.size()) { + Log.v(TAG, "Off the end of the route"); + stopWanted = stopWanted % (routeStopsFound.size() - 1); + } + Log.v(TAG, " Stop wanted " + stopWanted); + BusStop busStopWanted = routeStopsFound.get(stopWanted).busStop; + + busStopDao.refresh(busStopWanted); - Log.v("BusRoute", - "Moving forward in direction " + direction + " " + moveAmount + " stops from " + stop + " to " + routeStopsFound.get(stopWanted).stop - + " in route " + this); + Log.v(TAG, " Moving to " + busStopWanted + " (" + stopWanted + ") in route " + this); - return routeStopsFound.get(stopWanted).stop; + return busStopWanted; } else { - Log.v("BusStop", "stopIndex " + stopIndex); + Log.v(TAG, "stopIndex " + stopIndex); int stopWanted = stopIndex + moveAmount; if (stopWanted < 0) { stopWanted = routeStopsFound.size() - (Math.abs(stopWanted) % routeStopsFound.size()); } - Log.v("BusStop", "stopWanted " + stopWanted); - busStopDao.refresh(routeStopsFound.get(stopWanted).stop); + Log.v(TAG, "stopWanted " + stopWanted); + busStopDao.refresh(routeStopsFound.get(stopWanted).busStop); + + Log.v(TAG, + "Moving backwards " + moveAmount + " stops from " + busStop + " to " + + routeStopsFound.get(stopWanted).busStop + " in route " + this); + + return routeStopsFound.get(stopWanted).busStop; + } + + } catch (SQLException e) { + e.printStackTrace(); + } + Log.e(TAG, "Error moving in route"); + return null; + } + + /** + * Untested? + * + * @param context + * @param busStop + * @param moveAmount + * @return + */ + List<BusStop> getRouteSection(final Context context, String direction) { + + DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + + if (forwardDirection != null) { + + if (direction != null) { + + if (direction.equals("E")) + direction = "A"; // Quick hack for U1E + } else { + throw new NullPointerException("direction is null"); + } + } - Log.v("BusRoute", - "Moving backwards in direction " + direction + " " + moveAmount + " stops from " + stop + " to " + routeStopsFound.get(stopWanted).stop - + " in route " + this); + List<BusStop> busStops = new ArrayList<BusStop>(); - return routeStopsFound.get(stopWanted).stop; + try { + + Dao<RouteStops, Integer> routeStopsDao = helper.getRouteStopsDao(); + Dao<BusStop, String> busStopDao = helper.getBusStopDao(); + + QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); + routeStopsQueryBuilder.where().eq(RouteStops.ROUTE_ID_FIELD_NAME, this.id); + PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); + + List<RouteStops> routeStopsFound = routeStopsDao.query(routeStopsPreparedQuery); + + int startStopSeq = -1; + int endStopSeq = -1; + + if (id == 326) { // U1 + if (direction.equals(forwardDirection)) { + startStopSeq = 1; + endStopSeq = 43; + } else if (direction.equals(reverseDirection)) { + startStopSeq = 44; + endStopSeq = 88; + } else { + Log.e(TAG, "Error, unrecognised direction " + direction); + } + } else if (id == 468) { // U1N + startStopSeq = 1; + endStopSeq = 29; + } else if (id == 329) { // U2 + if (direction.equals(forwardDirection)) { + startStopSeq = 1; + endStopSeq = 22; + } else if (direction.equals(reverseDirection)) { + startStopSeq = 23; + endStopSeq = 43; + } else { + Log.e(TAG, "Error, unrecognised direction " + direction); + } + } else if (id == 327) { // U6 + if (direction.equals(forwardDirection)) { + startStopSeq = 1; + endStopSeq = 44; + } else if (direction.equals(reverseDirection)) { + startStopSeq = 45; + endStopSeq = 93; + } else { + Log.e(TAG, "Error, unrecognised direction " + direction); + } + } else if (id == 354) { // U9 + Calendar rightNow = Calendar.getInstance(); + if (rightNow.get(Calendar.HOUR_OF_DAY) < 12) { + startStopSeq = 1; + endStopSeq = 40; // TODO: Guess, and untested + } else { + startStopSeq = 41; // TODO: Guess, and untested + endStopSeq = 74; + } + } else { + Log.e(TAG, "Error, unrecognised route " + id); } + for (RouteStops routeStop : routeStopsFound) { + if (routeStop.sequence >= startStopSeq && routeStop.sequence <= endStopSeq) { + busStopDao.refresh(routeStop.busStop); + busStops.add(routeStop.busStop); + } + } + + return busStops; + } catch (SQLException e) { e.printStackTrace(); } - Log.e("BusRoute", "Error moving in route"); + Log.e(TAG, "Error moving in route"); return null; + } @Override diff --git a/src/net/cbaines/suma/BusRoutesView.java b/src/net/cbaines/suma/BusRoutesView.java new file mode 100644 index 0000000..32226b0 --- /dev/null +++ b/src/net/cbaines/suma/BusRoutesView.java @@ -0,0 +1,140 @@ +/* + * Southampton University Map App + * Copyright (C) 2011 Christopher Baines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.cbaines.suma; + +import android.content.Context; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class BusRoutesView extends LinearLayout { + + private TextView u1; + private TextView u1n; + private TextView u2; + private TextView u6; + private TextView u9; + + private LinearLayout bottomRow; + private LinearLayout topRow; + + public BusRoutesView(Context context, final byte routes) { + super(context); + + u1 = new TextView(context); + u1.setText(R.string.U1); + u1.setBackgroundResource(R.drawable.u1_back_selected); + u1.setPadding(5, 1, 5, 1); + + u1n = new TextView(context); + u1n.setText(R.string.U1N); + u1n.setBackgroundResource(R.drawable.u1n_back_selected); + u1n.setPadding(5, 1, 5, 1); + + u2 = new TextView(context); + u2.setText(R.string.U2); + u2.setBackgroundResource(R.drawable.u2_back_selected); + u2.setPadding(5, 1, 5, 1); + + u6 = new TextView(context); + u6.setText(R.string.U6); + u6.setBackgroundResource(R.drawable.u6_back_selected); + u6.setPadding(5, 1, 5, 1); + + u9 = new TextView(context); + u9.setText(R.string.U9); + u9.setBackgroundResource(R.drawable.u9_back_selected); + u9.setPadding(5, 1, 5, 1); + + this.setOrientation(LinearLayout.VERTICAL); + + topRow = new LinearLayout(context); + bottomRow = new LinearLayout(context); + + addView(topRow); + addView(bottomRow); + + } + + void setRoutes(byte routes) { + + topRow.removeView(u1); + topRow.removeView(u1n); + topRow.removeView(u2); + topRow.removeView(u6); + topRow.removeView(u9); + + bottomRow.removeView(u1); + bottomRow.removeView(u1n); + bottomRow.removeView(u2); + bottomRow.removeView(u6); + bottomRow.removeView(u9); + + boolean top = true; + + LayoutParams busRouteLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + + if ((routes & (1 << 0)) != 0) { + if (top) { + topRow.addView(u1, busRouteLayoutParams); + } else { + bottomRow.addView(u1, busRouteLayoutParams); + } + u1.setVisibility(View.VISIBLE); + top = !top; + } + if ((routes & (1 << 1)) != 0) { + if (top) { + topRow.addView(u1n, busRouteLayoutParams); + } else { + bottomRow.addView(u1n, busRouteLayoutParams); + } + u1n.setVisibility(View.VISIBLE); + top = !top; + } + if ((routes & (1 << 2)) != 0) { + if (top) { + topRow.addView(u2, busRouteLayoutParams); + } else { + bottomRow.addView(u2, busRouteLayoutParams); + } + u2.setVisibility(View.VISIBLE); + top = !top; + } + if ((routes & (1 << 3)) != 0) { + if (top) { + topRow.addView(u6, busRouteLayoutParams); + } else { + bottomRow.addView(u6, busRouteLayoutParams); + } + u6.setVisibility(View.VISIBLE); + top = !top; + } + if ((routes & (1 << 4)) != 0) { + if (top) { + topRow.addView(u9, busRouteLayoutParams); + } else { + bottomRow.addView(u9, busRouteLayoutParams); + } + u9.setVisibility(View.VISIBLE); + top = !top; + } + } +} diff --git a/src/net/cbaines/suma/BusSpecificStopView.java b/src/net/cbaines/suma/BusSpecificStopView.java new file mode 100644 index 0000000..77601ff --- /dev/null +++ b/src/net/cbaines/suma/BusSpecificStopView.java @@ -0,0 +1,187 @@ +/* + * Southampton University Map App + * Copyright (C) 2011 Christopher Baines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.cbaines.suma; + +import java.sql.SQLException; +import java.text.DateFormat; + +import android.app.Activity; +import android.content.Intent; +import android.util.Log; +import android.view.Gravity; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.j256.ormlite.android.apptools.OpenHelperManager; +import com.j256.ormlite.dao.Dao; + +public class BusSpecificStopView extends LinearLayout implements OnClickListener, OnLongClickListener { + + private static final String TAG = "BusSpecificStopView"; + + // private static final String TAG = "StopView"; + + private final TextView location; + private final TextView time; + private String onClickMessage = ""; + private final BusActivity context; + + private Stop stop; + + public BusSpecificStopView(BusActivity context, Stop stop) { + super(context); + + this.context = context; + + this.setOrientation(HORIZONTAL); + + location = new TextView(context); + location.setTextSize(22f); + + time = new TextView(context); + time.setTextSize(22f); + time.setGravity(Gravity.RIGHT); + + setStop(stop); + + addView(location, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); + addView(time, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); + + } + + public void setStop(Stop stop) { + + // Log.i(TAG, "Time of arival " + stop.arivalTime); + + this.stop = stop; + + if (stop == null) { + Log.e(TAG, "stop == null"); + } + if (stop.busStop == null) { + Log.e(TAG, "stop.busStop == null"); + } + if (stop.busStop.description == null) { + Log.e(TAG, "stop.busStop.description == null"); + } + + if (stop.busStop.description.length() > 20) { + location.setText(stop.busStop.description.substring(0, 20)); // TODO + } else { + location.setText(stop.busStop.description); // TODO + } + if (stop.arivalTime != null) { + time.setText(stop.getShortTimeToArival()); + } else { + time.setText(""); + } + + DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + + try { + Dao<Bus, Integer> busDao = helper.getBusDao(); + + busDao.refresh(stop.bus); + + if (stop.arivalTime != null) { + + if (stop.bus.id != null) { + if (stop.live) { + onClickMessage = "Bus " + stop.bus.toString() + " at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus " + stop.bus.toString() + " at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } + } else { + if (stop.live) { + onClickMessage = "Unidentified bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } + } + } else { + if (stop.bus.id != null) { + if (stop.live) { + onClickMessage = "Bus " + stop.bus.toString(); + } else { + onClickMessage = "Timetabled bus " + stop.bus.toString(); + } + } else { + if (stop.live) { + onClickMessage = "Unidentified bus (" + stop.bus.getName() + ")"; + } else { + onClickMessage = "Timetabled bus (" + stop.bus.getName() + ")"; + } + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + + this.setOnClickListener(this); + this.setOnLongClickListener(this); + } + + public void onClick(View v) { + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, onClickMessage, Toast.LENGTH_SHORT); + } else { + context.activityToast.setText(onClickMessage); + context.activityToast.setDuration(Toast.LENGTH_SHORT); + } + context.activityToast.show(); + } + + @Override + public boolean onLongClick(View v) { // TODO + DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + + try { + Dao<Bus, Integer> busDao = helper.getBusDao(); + + busDao.refresh(stop.bus); + + if (stop.bus.id != null) { + Intent i = new Intent(context, MapActivity.class); + i.putExtra("poiPoint", stop.busStop.point.toDoubleString()); + ((Activity) context).startActivityForResult(i, 0); + } else { + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, "Arival prediction not avalible for timetabled buses", Toast.LENGTH_SHORT); + } else { + context.activityToast.setText("Arival prediction not avalible for timetabled buses"); + context.activityToast.setDuration(Toast.LENGTH_SHORT); + } + context.activityToast.show(); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + +} diff --git a/src/net/cbaines/suma/BusSpecificTimetableAdapter.java b/src/net/cbaines/suma/BusSpecificTimetableAdapter.java new file mode 100644 index 0000000..c115fea --- /dev/null +++ b/src/net/cbaines/suma/BusSpecificTimetableAdapter.java @@ -0,0 +1,98 @@ +/* + * Southampton University Map App + * Copyright (C) 2011 Christopher Baines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.cbaines.suma; + +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.BaseAdapter; + +public class BusSpecificTimetableAdapter extends BaseAdapter { + + private final BusActivity context; + private Timetable timetable; + private final Animation a; + private boolean[] changed; + + private long timeOfLastForcedUpdate = System.currentTimeMillis(); + + // private static final String TAG = "BusSpecificTimetableAdapter"; + + public BusSpecificTimetableAdapter(BusActivity context, Timetable timetable) { + this.context = context; + this.timetable = timetable; + this.a = AnimationUtils.loadAnimation(context, R.anim.updated_stop_view); + } + + public View getView(int position, View convertView, ViewGroup parent) { + // Log.i(TAG, "Returning stop " + position + " " + timetable.get(position)); + + if (timeOfLastForcedUpdate + 1000 < System.currentTimeMillis()) { + context.handler.post(context.refreshData); + timeOfLastForcedUpdate = System.currentTimeMillis(); + } + + BusSpecificStopView stopView; + if (convertView == null) { + stopView = new BusSpecificStopView(context, timetable.get(position)); + } else { + stopView = (BusSpecificStopView) convertView; + stopView.setStop(timetable.get(position)); + } + + if (changed == null || changed[position]) { + a.reset(); + stopView.startAnimation(a); + // Log.i(TAG, "Animating it"); + } + + return stopView; + } + + public int getCount() { + return timetable.size(); + } + + public Object getItem(int position) { + return position; + } + + public long getItemId(int position) { + return position; + } + + public void updateTimetable(Timetable newTimetable) { + // Log.v(TAG, "Old timetable " + timetable); + // Log.v(TAG, "Adaptor loading new timetable"); + changed = new boolean[newTimetable.size()]; + for (int i = 0; i < newTimetable.size(); i++) { + if (newTimetable.get(i).arivalTime != null && !timetable.contains(newTimetable.get(i), true)) { + changed[i] = true; + // Log.i(TAG, "Old timetable does not contain: " + newTimetable.get(i)); + } else { + // Log.i(TAG, "Old timetable contains: " + newTimetable.get(i)); + changed[i] = false; + } + } + timetable = newTimetable; + this.notifyDataSetChanged(); + } +} diff --git a/src/net/cbaines/suma/BusStopActivity.java b/src/net/cbaines/suma/BusStopActivity.java index b711770..03dcbca 100644 --- a/src/net/cbaines/suma/BusStopActivity.java +++ b/src/net/cbaines/suma/BusStopActivity.java @@ -21,12 +21,15 @@ package net.cbaines.suma; import java.io.IOException; import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import org.apache.http.client.ClientProtocolException; import org.json.JSONException; +import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -40,6 +43,8 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -47,13 +52,14 @@ import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.j256.ormlite.android.apptools.OrmLiteBaseActivity; import com.j256.ormlite.dao.Dao; import com.j256.ormlite.stmt.PreparedQuery; import com.j256.ormlite.stmt.QueryBuilder; -public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> implements OnCheckedChangeListener, Preferences { +public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> implements OnCheckedChangeListener, Preferences, OnItemClickListener { final static String TAG = "BusTimeActivity"; @@ -90,8 +96,13 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme private CheckBox U6RouteRadioButton; private CheckBox U9RouteRadioButton; + private static final int POI_DIALOG_ID = 0; + private POIDialog busDialog; + private HashSet<BusRoute> routes = new HashSet<BusRoute>(); + Toast activityToast; + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.bustimes); @@ -163,10 +174,7 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme } else { U9RouteRadioButton.setVisibility(View.GONE); } - } else { - Log.e(TAG, "Error unknown route " + route.code); } - } busStopDao = helper.getBusStopDao(); @@ -199,7 +207,8 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme super.onResume(); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - if (sharedPrefs.getBoolean(UNI_LINK_BUS_TIMES, false) || sharedPrefs.getBoolean(NON_UNI_LINK_BUS_TIMES, false)) { + if (sharedPrefs.getBoolean(UNI_LINK_BUS_TIMES, UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT) + || sharedPrefs.getBoolean(NON_UNI_LINK_BUS_TIMES, NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT)) { Log.i(TAG, "Live Times enabled"); timetable = (Timetable) getLastNonConfigurationInstance(); @@ -265,11 +274,10 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme e.printStackTrace(); } } else { - Log.i(TAG, "Route radio button made " + checked); - - displayTimetable(timetable); - + if (timetable != null) { // If there is a timetable to display + displayTimetable(timetable); + } } } @@ -290,14 +298,14 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme try { final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(instance); - newTimetable = DataManager.getTimetable(instance, busStopID, sharedPrefs.getBoolean(SouthamptonUniversityMapActivity.UNI_LINK_BUS_TIMES, - SouthamptonUniversityMapActivity.UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT), sharedPrefs.getBoolean( - SouthamptonUniversityMapActivity.NON_UNI_LINK_BUS_TIMES, SouthamptonUniversityMapActivity.NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT)); + newTimetable = DataManager.getTimetable(instance, busStopID, sharedPrefs.getBoolean(MapActivity.UNI_LINK_BUS_TIMES, + MapActivity.UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT), sharedPrefs.getBoolean( + MapActivity.NON_UNI_LINK_BUS_TIMES, MapActivity.NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT)); } catch (SQLException e) { errorMessage = "Error message regarding SQL?"; e.printStackTrace(); } catch (ClientProtocolException e) { - errorMessage = "Insert error message here!"; + errorMessage = "ClientProtocolException!?!"; e.printStackTrace(); } catch (IOException e) { errorMessage = "Error fetching bus times from server, are you connected to the internet?"; @@ -305,7 +313,10 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme } catch (JSONException e) { errorMessage = "Error parsing bus times"; e.printStackTrace(); + } catch (Exception e) { + Log.e(TAG, e.getMessage(), e.getCause()); } + return newTimetable; } @@ -335,19 +346,25 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection - if (false) { // (item.getItemId() == R.id.menu_previous_stop || item.getItemId() == R.id.menu_next_stop) { + if (item.getItemId() == R.id.menu_previous_stop || item.getItemId() == R.id.menu_next_stop) { Log.v(TAG, "Got a request for the stop movement"); Log.v(TAG, routes.size() + " routes avalible from this stop"); - HashSet<BusStop> busStops = new HashSet<BusStop>(); + ArrayList<POI> busStops = new ArrayList<POI>(); for (BusRoute route : routes) { try { - if (false) { // (item.getItemId() == R.id.menu_next_stop) { - busStops.add(route.moveInRoute(this, getHelper().getBusStopDao().queryForId(busStopID), null, 1)); + Set<BusStop> tmpStops; + if (item.getItemId() == R.id.menu_next_stop) { + tmpStops = route.moveInRoute(this, getHelper().getBusStopDao().queryForId(busStopID), 1); } else { - busStops.add(route.moveInRoute(this, getHelper().getBusStopDao().queryForId(busStopID), null, -1)); + tmpStops = route.moveInRoute(this, getHelper().getBusStopDao().queryForId(busStopID), -1); + } + for (BusStop busStop : tmpStops) { + if (!busStops.contains(busStop)) { + busStops.add(busStop); + } } } catch (SQLException e) { e.printStackTrace(); @@ -358,7 +375,7 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme if (busStops.size() == 1) { Intent i = new Intent(this, BusStopActivity.class); - BusStop stop = busStops.iterator().next(); + BusStop stop = (BusStop) busStops.iterator().next(); if (stop == null) { Log.e(TAG, "stop == null"); } @@ -369,7 +386,16 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme i.putExtra("busStopName", stop.description); startActivity(i); } else { - // Show dialog + showDialog(POI_DIALOG_ID); + if (busDialog == null) { + Log.e(TAG, "Very wierd, just tried to launch the favourite's dialog, but its null?"); + return false; + } + + busDialog.setMessage(""); + busDialog.setItems(busStops); + busDialog.setTitle("Choose Bus Stop"); + Log.i(TAG, "Showing dialog"); } @@ -446,4 +472,42 @@ public class BusStopActivity extends OrmLiteBaseActivity<DatabaseHelper> impleme } } } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case POI_DIALOG_ID: + busDialog = new POIDialog(instance); + busDialog.setOnItemClickListener(this); + return busDialog; + } + return null; + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + Log.i(TAG, "OnItemClick pos " + position + " id " + id); + + String poiId = busDialog.adapter.getItemStringId(position); + + Log.i(TAG, "POI " + poiId + " selected"); + + Intent i = new Intent(this, BusStopActivity.class); + try { + busStop = busStopDao.queryForId(poiId); + + if (busStop == null) { + Log.e(TAG, "stop == null"); + } + if (busStop.id == null) { + Log.e(TAG, "stop.id == null"); + } + i.putExtra("busStopID", busStop.id); + i.putExtra("busStopName", busStop.description); + startActivity(i); + } catch (SQLException e) { + e.printStackTrace(); + } + + } } diff --git a/src/net/cbaines/suma/BusStopOverlay.java b/src/net/cbaines/suma/BusStopOverlay.java index 834b6dc..06a1729 100644 --- a/src/net/cbaines/suma/BusStopOverlay.java +++ b/src/net/cbaines/suma/BusStopOverlay.java @@ -28,7 +28,6 @@ import org.osmdroid.views.MapView.Projection; import org.osmdroid.views.overlay.Overlay; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.graphics.Canvas; import android.graphics.Paint; @@ -60,7 +59,7 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { private static final String TAG = "BusStopOverlay"; - private final Context context; + private final MapActivity context; private Dao<BusStop, String> busStopDao; @@ -68,7 +67,7 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { private boolean[] routes = new boolean[5]; - public BusStopOverlay(Context context, List<BusStop> busStops) throws SQLException { + public BusStopOverlay(MapActivity context, List<BusStop> busStops) throws SQLException { super(context); this.context = context; @@ -119,20 +118,21 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { boolean drawing = false; - for (int i = 0; i < 5; i++) { - if ((stopRoutes & (1 << i)) != 0) { - routeNum++; - if (routes[i]) { - drawing = true; + if (stop.uniLink) { + + for (int i = 0; i < 5; i++) { + if ((stopRoutes & (1 << i)) != 0) { + routeNum++; + if (routes[i]) { + drawing = true; + } } } - } - if (!drawing) - continue; + if (!drawing) + continue; - int yOfsetPerMarker = (int) (10 * scale); - int markerYSize = (int) (8 * scale); + } pj.toMapPixels(stop.point, mCurScreenCoords); @@ -141,60 +141,86 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { } else { Overlay.drawAt(canvas, marker, mCurScreenCoords.x, mCurScreenCoords.y, false); } - // Log.i(TAG, "Got " + routes.size() + " routes " + routes); - int makersPlaced = 0; + if (stop.uniLink) { - float rectLeft = mCurScreenCoords.x + (8.8f * scale); - float rectRight = rectLeft + markerYSize; + int makersPlaced = 0; + int yOfsetPerMarker = (int) (10 * scale); + int markerYSize = (int) (8 * scale); - if (routeNum == 5) { - markerYSize = (int) (5 * scale); - yOfsetPerMarker = (int) (7 * scale); - } else if (routeNum == 4) { - markerYSize = (int) (6.5f * scale); - yOfsetPerMarker = (int) (8 * scale); - } + float rectLeft = mCurScreenCoords.x + (8.8f * scale); + float rectRight = rectLeft + markerYSize; - for (int i = 0; i < 5; i++) { - if ((stopRoutes & (1 << i)) != 0) { - - // Log.i(TAG, "Route " + route + " is " + routes.get(route)); - - // Log.i(TAG, "Index is " + busRoutes.indexOf(route) + " busRoutes " + busRoutes); - - if (i == 0) { - paint.setColor(U1); - } else if (i == 1) { - paint.setColor(U1N); - } else if (i == 2) { - paint.setColor(U2); - } else if (i == 3) { - paint.setColor(U6); - } else if (i == 4) { - paint.setColor(U9); - } else { - Log.e(TAG, "Unknown route code"); - } + if (routeNum == 5) { + markerYSize = (int) (5 * scale); + yOfsetPerMarker = (int) (7 * scale); + } else if (routeNum == 4) { + markerYSize = (int) (6.5f * scale); + yOfsetPerMarker = (int) (8 * scale); + } + + for (int i = 0; i < 5; i++) { + if ((stopRoutes & (1 << i)) != 0) { + + // Log.i(TAG, "Route " + route + " is " + routes.get(route)); + + // Log.i(TAG, "Index is " + busRoutes.indexOf(route) + " busRoutes " + busRoutes); + + if (i == 0) { + paint.setColor(U1); + } else if (i == 1) { + paint.setColor(U1N); + } else if (i == 2) { + paint.setColor(U2); + } else if (i == 3) { + paint.setColor(U6); + } else if (i == 4) { + paint.setColor(U9); + } else { + Log.e(TAG, "Unknown route code"); + } - canvas.drawRect(rectLeft, mCurScreenCoords.y + ((yOfsetPerMarker * makersPlaced) - (45 * scale)), rectRight, mCurScreenCoords.y - + (yOfsetPerMarker * makersPlaced) - ((45 * scale) - markerYSize), paint); + canvas.drawRect(rectLeft, mCurScreenCoords.y + + ((yOfsetPerMarker * makersPlaced) - (45 * scale)), rectRight, mCurScreenCoords.y + + (yOfsetPerMarker * makersPlaced) - ((45 * scale) - markerYSize), paint); - makersPlaced++; + makersPlaced++; + } } } } - } @Override - public boolean onSingleTapUp(final MotionEvent event, final MapView mapView) { + public boolean onSingleTapConfirmed(final MotionEvent event, final MapView mapView) { BusStop busStop = getSelectedItem(event, mapView); if (busStop == null) { - Log.i(TAG, "No busStop pressed"); + // Log.v(TAG, "No busStop pressed"); + return false; + } else { + Log.i(TAG, "busStop Pressed " + busStop.id); + + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, busStop.description + " (" + busStop.id + ")", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(busStop.description + " (" + busStop.id + ")"); + } + context.activityToast.show(); + + return true; + } + } + public boolean onDoubleTap(final MotionEvent event, final MapView mapView) { + + BusStop busStop = getSelectedItem(event, mapView); + + if (busStop == null) { + // Log.v(TAG, "No busStop pressed"); return false; } else { Log.i(TAG, "Pressed " + busStop.id); @@ -211,10 +237,11 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { @Override public boolean onLongPress(final MotionEvent event, final MapView mapView) { + BusStop busStop = getSelectedItem(event, mapView); if (busStop == null) { - Log.i(TAG, "No busStop pressed"); + // Log.v(TAG, "No busStop pressed"); return false; } else { Log.i(TAG, "Pressed " + busStop.id); @@ -222,9 +249,23 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { if (busStop.favourite) { busStop.favourite = false; - Toast.makeText(context, busStop.id + " removed from favourites", Toast.LENGTH_SHORT).show(); + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, busStop.id + " removed from favourites", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(busStop.id + " removed from favourites"); + } + context.activityToast.show(); } else { - Toast.makeText(context, busStop.id + " made a favourite", Toast.LENGTH_SHORT).show(); + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, busStop.id + " made a favourite", + Toast.LENGTH_SHORT); + } else { + context.activityToast.setDuration(Toast.LENGTH_SHORT); + context.activityToast.setText(busStop.id + " made a favourite"); + } + context.activityToast.show(); busStop.favourite = true; } @@ -241,7 +282,6 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { return true; } - } public void refresh() { @@ -288,17 +328,19 @@ public class BusStopOverlay extends Overlay implements RouteColorConstants { pj.toPixels(busStop.point, mItemPoint); if (marker.getBounds().contains(mTouchScreenPoint.x - mItemPoint.x, mTouchScreenPoint.y - mItemPoint.y)) { - boolean drawing = false; - for (int route = 0; route < 5; route++) { - if ((busStop.routes & (1 << route)) != 0) { - if (routes[route]) { - drawing = true; - break; + if (busStop.uniLink) { + boolean drawing = false; + for (int route = 0; route < 5; route++) { + if ((busStop.routes & (1 << route)) != 0) { + if (routes[route]) { + drawing = true; + break; + } } } + if (!drawing) + continue; } - if (!drawing) - continue; return busStop; } diff --git a/src/net/cbaines/suma/DataHandler.java b/src/net/cbaines/suma/DataHandler.java index f564d19..25f66ff 100644 --- a/src/net/cbaines/suma/DataHandler.java +++ b/src/net/cbaines/suma/DataHandler.java @@ -25,8 +25,6 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import android.util.Log; - public class DataHandler extends DefaultHandler { // this holds the data @@ -70,7 +68,8 @@ public class DataHandler extends DefaultHandler { } /** - * This gets called at the start of an element. Here we're also setting the booleans to true if it's at that specific tag. (so we know where we are) + * This gets called at the start of an element. Here we're also setting the booleans to true if it's at that + * specific tag. (so we know where we are) * * @param namespaceURI * @param localName @@ -81,7 +80,8 @@ public class DataHandler extends DefaultHandler { @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { if (localName.equals("trkpt")) { - // Log.v("DataHandler", "Adding point to route overlay " + atts.getValue("lat") + " " + atts.getValue("lon")); + // Log.v("DataHandler", "Adding point to route overlay " + atts.getValue("lat") + " " + + // atts.getValue("lon")); _data.addPoint(Util.csLatLongToGeoPoint(atts.getValue("lat"), atts.getValue("lon"))); } } @@ -100,8 +100,8 @@ public class DataHandler extends DefaultHandler { } /** - * Calling when we're within an element. Here we're checking to see if there is any content in the tags that we're interested in and populating it in the - * Config object. + * Calling when we're within an element. Here we're checking to see if there is any content in the tags that we're + * interested in and populating it in the Config object. * * @param ch * @param start diff --git a/src/net/cbaines/suma/DataManager.java b/src/net/cbaines/suma/DataManager.java index d4d0968..c6a3a36 100644 --- a/src/net/cbaines/suma/DataManager.java +++ b/src/net/cbaines/suma/DataManager.java @@ -24,11 +24,15 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; @@ -62,12 +66,12 @@ import com.j256.ormlite.table.TableUtils; public class DataManager { - final static String TAG = "DataManager"; + private final static String TAG = "DataManager"; - final static String busStopUrl = "http://data.southampton.ac.uk/bus-stop/"; + private final static String busStopUrl = "http://data.southampton.ac.uk/bus-stop/"; private static DatabaseHelper helper; - private static Dao<BusRoute, Integer> busRoutes; + private static Dao<BusRoute, Integer> busRouteDao; private static Dao<Bus, Integer> busDao; private static Dao<BusStop, String> busStopDao; @@ -77,7 +81,7 @@ public class DataManager { TableUtils.clearTable(helper.getConnectionSource(), Building.class); - Log.i(TAG, "Loading buildings from csv"); + Log.i(TAG, "Begining loading buildings from csv"); HashMap<String, GeoPoint> buildingPoints = new HashMap<String, GeoPoint>(); @@ -92,32 +96,17 @@ public class DataManager { // Log.i(TAG, "Data: " + strLine); String[] dataBits = strLine.split(","); GeoPoint point = Util.csLatLongToGeoPoint(dataBits[2], dataBits[1]); - // Log.i(TAG, "Creating building with id " + dataBits[0] + " and " + point.getLatitudeE6() + " " + point.getLongitudeE6()); + // Log.i(TAG, "Creating building with id " + dataBits[0] + " and " + point.getLatitudeE6() + " " + + // point.getLongitudeE6()); buildingPoints.put(dataBits[0], point); } bufferedReader.close(); } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } - Log.i(TAG, "Number of building points " + buildingPoints.size()); - - /* - * inputStream = context.getResources().openRawResource(R.raw.buildings_shapes); bufferedReader = new BufferedReader(new - * InputStreamReader(inputStream)); - * - * try { String def = bufferedReader.readLine(); // Log.i(TAG, "Reading the definition " + def); - * - * while ((strLine = bufferedReader.readLine()) != null) { // Log.i(TAG, "Data: " + strLine); String[] dataBits = strLine.split(","); Polygon poly = - * Util.csPolygonToPolygon(strLine.split("\"")[1]); // Log.i(TAG, "Creating building with id " + dataBits[0] + " and " + poly); - * buildingPolys.put(dataBits[0], poly); } - * - * bufferedReader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } - * - * Log.i(TAG, "Number of polys points " + buildingPolys.size()); - */ + // Log.i(TAG, "Number of building points " + buildingPoints.size()); inputStream = context.getAssets().open("building_estates.csv"); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); @@ -139,16 +128,19 @@ public class DataManager { continue; } - Building bdg = new Building(dataBits[1], buildingPoints.get(dataBits[1]), dataBits[3].equals("R"), quoteBits[0]); + Building bdg = new Building(dataBits[1], buildingPoints.get(dataBits[1]), dataBits[3].equals("R"), + quoteBits[0]); /* * Polygon poly = buildingPolys.get(dataBits[1]); * - * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + - * bdg.point.getLongitudeE6() + " " + poly); } else { // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + + * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + + * bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6() + " " + poly); } else { // + * Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + * bdg.point.getLongitudeE6()); } */ - // Log.i(TAG, "Creating building " + bdg.id + " " + bdg.name + " " + bdg.point + " " + bdg.residential + " " + bdg.outline); + // Log.i(TAG, "Creating building " + bdg.id + " " + bdg.name + " " + bdg.point + " " + + // bdg.residential + " " + bdg.outline); buildingDao.create(bdg); @@ -161,16 +153,19 @@ public class DataManager { continue; } - Building bdg = new Building(dataBits[1], buildingPoints.get(dataBits[1]), dataBits[3].equals("R"), dataBits[0]); + Building bdg = new Building(dataBits[1], buildingPoints.get(dataBits[1]), dataBits[3].equals("R"), + dataBits[0]); /* * Polygon poly = buildingPolys.get(dataBits[1]); * - * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + - * bdg.point.getLongitudeE6() + " " + poly); } else { // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + + * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + + * bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6() + " " + poly); } else { // + * Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + * bdg.point.getLongitudeE6()); } */ - // Log.i(TAG, "Creating building " + bdg.id + " " + bdg.name + " " + bdg.point + " " + bdg.residential + " " + bdg.outline); + // Log.i(TAG, "Creating building " + bdg.id + " " + bdg.name + " " + bdg.point + " " + + // bdg.residential + " " + bdg.outline); buildingDao.create(bdg); @@ -188,8 +183,9 @@ public class DataManager { * * Building bdg = new Building(key, buildingPoints.get(key), false); Polygon poly = buildingPolys.get(key); * - * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6() + - * " " + poly); } else { // Log.i(TAG, "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6()); } + * if (poly != null) { bdg.outline = poly; // Log.i(TAG, "Adding building " + key + " " + + * bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6() + " " + poly); } else { // Log.i(TAG, + * "Adding building " + key + " " + bdg.point.getLatitudeE6() + " " + bdg.point.getLongitudeE6()); } * * buildingDao.create(bdg); } */ @@ -225,19 +221,21 @@ public class DataManager { String[] quBitsLng = dataBits[4].substring(1, dataBits[4].length() - 1).split(" "); // Log.i(TAG, "Whole " + dataBits[3] + " First bit " + quBitsLat[0] + " last bit " + quBitsLat[1]); - double lat = Double.valueOf(quBitsLat[0]) + Double.valueOf(quBitsLat[1].substring(0, quBitsLat[1].length() - 1)) / 60d; // TODO Much hackage + double lat = Double.valueOf(quBitsLat[0]) + + Double.valueOf(quBitsLat[1].substring(0, quBitsLat[1].length() - 1)) / 60d; // Log.i(TAG, "Whole " + dataBits[4] + " First bit " + quBitsLng[0] + " last bit " + quBitsLng[1]); - double lng = Double.valueOf(quBitsLng[0]) + Double.valueOf(quBitsLng[1].substring(0, quBitsLng[1].length() - 1)) / 60d; // TODO Much hackage + double lng = Double.valueOf(quBitsLng[0]) + + Double.valueOf(quBitsLng[1].substring(0, quBitsLng[1].length() - 1)) / 60d; GeoPoint point = new GeoPoint((int) (lat * 1e6), (int) (lng * -1e6)); // Log.i(TAG, "Lat " + point.getLatitudeE6() + " lng " + point.getLongitudeE6()); - busStopDao.create(new BusStop(dataBits[0].replace("\"", ""), dataBits[1].replace("\"", ""), dataBits[2].replace("\"", ""), point)); + busStopDao.create(new BusStop(dataBits[0].replace("\"", ""), dataBits[1].replace("\"", ""), dataBits[2] + .replace("\"", ""), point)); } bufferedReader.close(); } catch (IOException e) { - // TODO Auto-generated catch block Log.e(TAG, "Line: " + strLine); e.printStackTrace(); } @@ -256,11 +254,28 @@ public class DataManager { String[] dataBits = strLine.split(","); BusRoute route; - if (dataBits.length > 3) { - route = new BusRoute(Integer.parseInt(dataBits[0]), dataBits[1], dataBits[2].replace("\"", ""), dataBits[3], dataBits[4]); + + boolean uniLink; + int id = Integer.parseInt(dataBits[0]); + if (id == 326 || id == 468 || id == 327 || id == 329 || id == 354) { + uniLink = true; } else { - route = new BusRoute(Integer.parseInt(dataBits[0]), dataBits[1], dataBits[2].replace("\"", "")); + uniLink = false; } + + route = new BusRoute(id, dataBits[1], dataBits[2].replace("\"", ""), uniLink); + + if (id == 326) { // U1 + route.forwardDirection = "A"; + route.reverseDirection = "C"; + } else if (id == 329) { // U2 + route.forwardDirection = "B"; + route.reverseDirection = "C"; + } else if (id == 327) { // U6 + route.forwardDirection = "H"; + route.reverseDirection = "C"; + } + // Log.i(TAG, "Loaded route " + route.id + " " + route.code + " " + route.label); busRouteDao.create(route); @@ -268,7 +283,6 @@ public class DataManager { bufferedReader.close(); } catch (IOException e) { - // TODO Auto-generated catch block Log.e(TAG, "Line: " + strLine); e.printStackTrace(); } @@ -286,16 +300,16 @@ public class DataManager { // Log.i(TAG, "Data: " + strLine); String[] dataBits = strLine.split(","); - BusStop stop = busStopDao.queryForId(dataBits[2]); - if (stop != null) { + BusStop busStop = busStopDao.queryForId(dataBits[2]); + if (busStop != null) { // Log.i(TAG, "Found stop " + stop.id); } else { Log.w(TAG, "No stop found for " + dataBits[2]); continue; } - BusRoute route = busRouteDao.queryForId(Integer.parseInt(dataBits[0])); - if (route != null) { + BusRoute busRoute = busRouteDao.queryForId(Integer.parseInt(dataBits[0])); + if (busRoute != null) { // Log.i(TAG, "Found route " + route.id); } else { Log.w(TAG, "No route found for " + dataBits[0]); @@ -303,70 +317,64 @@ public class DataManager { } int sequence = Integer.parseInt(dataBits[1]); - Log.i(TAG, "Creating RouteStop " + stop.id + " " + route.code + " " + sequence); - - routeStopsDao.create(new RouteStops(stop, route, sequence)); - - if (route.id == 326) { // U1 - stop.routes = (byte) (stop.routes | 1); - } else if (route.id == 468) { // U1N - stop.routes = (byte) (stop.routes | (1 << 1)); - } else if (route.id == 329) { // U2 - stop.routes = (byte) (stop.routes | (1 << 2)); - } else if (route.id == 327) { // U6 - stop.routes = (byte) (stop.routes | (1 << 3)); - } else if (route.id == 354) { // U9 - stop.routes = (byte) (stop.routes | (1 << 4)); + Log.i(TAG, "Creating RouteStop " + busStop.id + " " + busRoute.code + " " + sequence); + + routeStopsDao.create(new RouteStops(busStop, busRoute, sequence)); + + if (busRoute.id == 326) { // U1 + busStop.routes = (byte) (busStop.routes | 1); + busStop.uniLink = true; + } else if (busRoute.id == 468) { // U1N + busStop.routes = (byte) (busStop.routes | (1 << 1)); + busStop.uniLink = true; + } else if (busRoute.id == 329) { // U2 + busStop.routes = (byte) (busStop.routes | (1 << 2)); + busStop.uniLink = true; + } else if (busRoute.id == 327) { // U6 + busStop.routes = (byte) (busStop.routes | (1 << 3)); + busStop.uniLink = true; + } else if (busRoute.id == 354) { // U9 + busStop.routes = (byte) (busStop.routes | (1 << 4)); + busStop.uniLink = true; + } else { + busStop.routes = 0; } - Log.v(TAG, "Stop routes " + stop.routes); - busStopDao.update(stop); + // Log.v(TAG, "Stop routes " + busStop.routes); + busStopDao.update(busStop); } bufferedReader.close(); } catch (IOException e) { - // TODO Auto-generated catch block Log.e(TAG, "Line: " + strLine); e.printStackTrace(); } - long sizeBeforeRemoval = busStopDao.countOf(); - - // Removing busstops not used by unilink busses - for (Iterator<BusStop> busStopIter = busStopDao.iterator(); busStopIter.hasNext();) { - BusStop stop = busStopIter.next(); - // Log.i(TAG, "Looking at stop " + stop.id); - - /* - * QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); routeStopsQueryBuilder.where().eq(columnName, value) - * - * DeleteBuilder<BusStop, String> deleteBuilder = busStopDao.deleteBuilder(); // only delete the rows where password is null - * deleteBuilder.where().in(RouteStops.STOP_ID_FIELD_NAME, objects) accountDao.delete(deleteBuilder.prepare()); - */ - - QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); - routeStopsQueryBuilder.setCountOf(true); - routeStopsQueryBuilder.where().eq(RouteStops.STOP_ID_FIELD_NAME, stop); - - PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); - long num = routeStopsDao.countOf(routeStopsPreparedQuery); - // long num = routeStopsDao.query(routeStopsPreparedQuery).size(); - // Log.i(TAG, "Number is " + num); - if (num == 0) { - // Log.i(TAG, "Removing " + stop.id); - stop.uniLink = false; - if (onlyUniLink) { - busStopIter.remove(); - } - } else { - stop.uniLink = true; - } - } - - long sizeAfterRemoval = busStopDao.countOf(); - - Log.i(TAG, "Removed " + (sizeBeforeRemoval - sizeAfterRemoval) + " stops (from " + sizeBeforeRemoval + ") now have " + sizeAfterRemoval); + /* + * for (Iterator<BusStop> busStopIter = busStopDao.iterator(); busStopIter.hasNext();) { BusStop stop = + * busStopIter.next(); // Log.i(TAG, "Looking at stop " + stop.id); + * + * + * QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); + * routeStopsQueryBuilder.where().eq(columnName, value) + * + * DeleteBuilder<BusStop, String> deleteBuilder = busStopDao.deleteBuilder(); // only delete the rows where + * password is null deleteBuilder.where().in(RouteStops.STOP_ID_FIELD_NAME, objects) + * accountDao.delete(deleteBuilder.prepare()); + * + * + * QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); + * routeStopsQueryBuilder.setCountOf(true); routeStopsQueryBuilder.where().eq(RouteStops.STOP_ID_FIELD_NAME, + * stop); + * + * PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); List<RouteStops> + * routeStops = routeStopsDao.query(routeStopsPreparedQuery); // long num = + * routeStopsDao.query(routeStopsPreparedQuery).size(); // Log.i(TAG, "Number is " + num); + * + * stop.uniLink = false; for (RouteStops routeStop : routeStops) { if (routeStop.busRoute.uniLink) { + * stop.uniLink = true; } } busStopDao.update(stop); } + */ Log.i(TAG, "Finished loading bus data"); } @@ -415,144 +423,180 @@ public class DataManager { Log.i(TAG, "Loaded sites from csv"); } - private static Stop getStop(Context context, JSONObject stopObj, BusStop busStop) throws SQLException { + private static Stop getStop(Context context, JSONObject stopObj, Set<BusRoute> routes, BusStop busStop) + throws SQLException, JSONException { if (helper == null) helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); - if (busRoutes == null) - busRoutes = helper.getBusRouteDao(); + if (busRouteDao == null) + busRouteDao = helper.getBusRouteDao(); + Dao<RouteStops, Integer> routeStopsDao = null; + if (routeStopsDao == null) + routeStopsDao = helper.getRouteStopsDao(); if (busDao == null) busDao = helper.getBusDao(); if (busStopDao == null) busStopDao = helper.getBusStopDao(); - try { - String time = stopObj.getString("time"); + String time = stopObj.getString("time"); - GregorianCalendar calender = new GregorianCalendar(); - if (!time.equals("Due")) { + GregorianCalendar calender = new GregorianCalendar(); + boolean live = true; + if (!time.equals("Due")) { - Log.v(TAG, "Time: " + time + " current time " + calender.getTime()); + // Log.v(TAG, "Time: " + time + " current time " + calender.getTime()); - if (time.contains(":")) { - String[] minAndHour = time.split(":"); - calender.set(Calendar.HOUR_OF_DAY, Integer.parseInt(minAndHour[0])); - calender.set(Calendar.MINUTE, Integer.parseInt(minAndHour[1])); - } else { - // Log.i(TAG, "Parsing " + time.substring(0, time.length() - 1) + " for min"); - calender.add(Calendar.MINUTE, Integer.parseInt(time.substring(0, time.length() - 1))); - } - - Log.v(TAG, "Date: " + calender.getTime()); + if (time.contains(":")) { + String[] minAndHour = time.split(":"); + calender.set(Calendar.HOUR_OF_DAY, Integer.parseInt(minAndHour[0])); + calender.set(Calendar.MINUTE, Integer.parseInt(minAndHour[1])); + live = false; + } else { + // Log.i(TAG, "Parsing " + time.substring(0, time.length() - 1) + " for min"); + calender.add(Calendar.MINUTE, Integer.parseInt(time.substring(0, time.length() - 1))); } - String name = stopObj.getString("name"); + // Log.v(TAG, "Date: " + calender.getTime()); + } - BusRoute route; - String dir = null; + String name = stopObj.getString("name"); - if (name.equals("U1N")) { - route = busRoutes.queryForId(468); - } else if (name.startsWith("U9")) { - route = busRoutes.queryForId(354); - } else { - if (name.startsWith("U1")) { - route = busRoutes.queryForId(326); - } else if (name.startsWith("U2")) { - route = busRoutes.queryForId(329); - } else if (name.startsWith("U6")) { - route = busRoutes.queryForId(327); - } else { - Log.e(TAG, "Error detecting route " + name); - return null; - } + BusRoute route = null; + String dir = ""; - if (route.forwardDirection.equals(name.substring(2))) { - dir = route.forwardDirection; - } else if (route.reverseDirection.equals(name.substring(2))) { - dir = route.reverseDirection; + for (BusRoute tempRoute : routes) { + if (name.contains("U")) { + if (name.equals("U1N")) { + if (tempRoute.code.equals(name)) { + route = tempRoute; + dir = null; + } } else { - Log.e(TAG, "Error detecting direction for " + name); - return null; + if (tempRoute == null) { + Log.e(TAG, "tempRoute == null"); + } + if (tempRoute.code == null) { + Log.e(TAG, "tempRoute.code == null"); + } + if (tempRoute.code.equals(name.substring(0, 2))) { + route = tempRoute; + if (route.forwardDirection.equals(name.substring(2))) { + dir = route.forwardDirection; + } else if (route.reverseDirection.equals(name.substring(2))) { + dir = route.reverseDirection; + } else { + Log.e(TAG, "Error detecting direction for " + name); + dir = null; + return null; + } + } } - } - - String destString = stopObj.getString("dest"); - BusStop destStop; - - if (destString.equals("Central Station")) { - destStop = busStopDao.queryForId("SNA19709"); - } else if (destString.equals("Civic Centre")) { - destStop = busStopDao.queryForId("SN120527"); - } else if (destString.equals("City DG4")) { - destStop = busStopDao.queryForId("HAA13579"); - } else if (destString.equals("Central Station")) { - destStop = busStopDao.queryForId("SN120520"); - } else if (destString.equals("Airport")) { - destStop = busStopDao.queryForId("HA030184"); - } else if (destString.equals("City, Town Quay")) { - destStop = busStopDao.queryForId("SNA13766"); - } else if (destString.equals("Dock Gate 4")) { - destStop = busStopDao.queryForId("MG1031"); - } else if (destString.equals("Eastleigh")) { - destStop = busStopDao.queryForId("HA030212"); - } else if (destString.equals("Crematorium")) { - destStop = busStopDao.queryForId("SN121009"); - } else if (destString.equals("General Hosp")) { - destStop = busStopDao.queryForId("SNA19482"); } else { - Log.e(TAG, "Unknown end dest " + destString + " for route " + route.code); - return null; + if (tempRoute.code.equals(name)) { + route = tempRoute; + dir = null; + } } + } - Date now = new Date(System.currentTimeMillis()); + if (route == null) { + Log.e(TAG, "Route not found (route == null) " + name); + return null; + } - String busID = null; - Stop stop; - Bus bus; - if (stopObj.has("vehicle")) { - busID = stopObj.getString("vehicle"); + if (dir != null && dir.equals("")) { + Log.e(TAG, "Error detecting direction for " + name); + return null; + } - QueryBuilder<Bus, Integer> busQueryBuilder = busDao.queryBuilder(); - busQueryBuilder.where().eq(Bus.ID_FIELD_NAME, busID); - PreparedQuery<Bus> busPreparedQuery = busQueryBuilder.prepare(); + String destString = stopObj.getString("dest"); + BusStop destStop = null; + + if (destString.equals("Central Station")) { + destStop = busStopDao.queryForId("SN120520"); + } else if (destString.equals("Civic Centre")) { + destStop = busStopDao.queryForId("SN120527"); + } else if (destString.equals("City DG4")) { + destStop = busStopDao.queryForId("HAA13579"); + } else if (destString.equals("Airport")) { + destStop = busStopDao.queryForId("HA030184"); + } else if (destString.equals("City, Town Quay")) { + destStop = busStopDao.queryForId("SNA13766"); + } else if (destString.equals("City Centre")) { + destStop = busStopDao.queryForId("SNA13766"); + } else if (destString.equals("Dock Gate 4")) { + destStop = busStopDao.queryForId("MG1031"); + } else if (destString.equals("Eastleigh")) { + destStop = busStopDao.queryForId("HA030212"); + } else if (destString.equals("Crematorium")) { + destStop = busStopDao.queryForId("SN121009"); + } else if (destString.equals("General Hosp")) { + destStop = busStopDao.queryForId("SNA19482"); + } else if (destString.equals("Wessex Lane")) { + destStop = busStopDao.queryForId("SNA19780"); + } else { + Log.e(TAG, "Unknown end dest " + destString + " for route " + route.code); + } - bus = busDao.queryForFirst(busPreparedQuery); + if (destStop != null) { - if (bus == null) { - bus = new Bus(busID, route, dir); - bus.destination = destStop; - } else { - bus.destination = destStop; - bus.route = route; - bus.direction = dir; - } + QueryBuilder<RouteStops, Integer> routeStopsQueryBuilder = routeStopsDao.queryBuilder(); + routeStopsQueryBuilder.where().eq(RouteStops.ROUTE_ID_FIELD_NAME, route.id).and() + .eq(RouteStops.STOP_ID_FIELD_NAME, destStop.id); + PreparedQuery<RouteStops> routeStopsPreparedQuery = routeStopsQueryBuilder.prepare(); + List<RouteStops> routeStops = routeStopsDao.query(routeStopsPreparedQuery); + if (routeStops.size() > 0) { + Log.i(TAG, "Found " + routeStops.size() + " stops matching the destStop " + destStop + " on route " + + route.code); } else { - bus = new Bus(null, route, dir); + Log.w(TAG, "Found " + routeStops.size() + " stops matching the destStop " + destStop + " on route " + + route.code); } + } - busDao.update(bus); + Date now = new Date(System.currentTimeMillis()); - stop = new Stop(bus, busStop, calender.getTime(), now); + String busID = null; + Stop stop; + Bus bus; + if (stopObj.has("vehicle")) { + busID = stopObj.getString("vehicle"); - return stop; + QueryBuilder<Bus, Integer> busQueryBuilder = busDao.queryBuilder(); + busQueryBuilder.where().eq(Bus.ID_FIELD_NAME, busID); + PreparedQuery<Bus> busPreparedQuery = busQueryBuilder.prepare(); - } catch (Exception e) { - // TODO Auto-generated catch block - Log.e(TAG, "Error parsing stop " + stopObj, e); - return null; + bus = busDao.queryForFirst(busPreparedQuery); + + if (bus == null) { + bus = new Bus(busID, route, dir); + bus.destination = destStop; + busDao.create(bus); + } else { + bus.destination = destStop; + bus.route = route; + bus.direction = dir; + busDao.update(bus); + } + + } else { + bus = new Bus(null, route, dir); + busDao.create(bus); } + stop = new Stop(bus, busStop, calender.getTime(), now, live); + + return stop; } - public static Timetable getTimetable(Context context, String busStop, boolean keepUniLink, boolean keepNonUniLink) throws SQLException, - ClientProtocolException, IOException, JSONException { + public static Timetable getTimetable(Context context, String busStop, boolean keepUniLink, boolean keepNonUniLink) + throws SQLException, ClientProtocolException, IOException, JSONException { if (helper == null) helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); - if (busRoutes == null) - busRoutes = helper.getBusRouteDao(); + if (busRouteDao == null) + busRouteDao = helper.getBusRouteDao(); if (busStopDao == null) busStopDao = helper.getBusStopDao(); @@ -561,8 +605,24 @@ public class DataManager { String file = getFileFromServer(busStopUrl + busStop + ".json"); JSONObject data = new JSONObject(file); - JSONArray stopsArray = data.getJSONArray("stops"); + JSONObject routesObject = data.getJSONObject("routes"); + + HashSet<BusRoute> busRoutes = new HashSet<BusRoute>(); + for (Iterator<String> keyIter = routesObject.keys(); keyIter.hasNext();) { + String key = keyIter.next(); + + Log.v(TAG, "Route Key: " + key); + + BusRoute route = busRouteDao.queryForId(Integer.parseInt(key.substring(key.length() - 3, key.length()))); + + if (route != null) { + busRoutes.add(route); + } else { + throw new RuntimeException("Route not found " + key.substring(key.length() - 3, key.length()) + " " + + key); + } + } Log.i(TAG, "Number of entries " + data.length()); @@ -572,10 +632,12 @@ public class DataManager { JSONObject stopObj = stopsArray.getJSONObject(stopNum); if (!keepNonUniLink && !stopObj.getString("name").startsWith("U")) { + Log.v(TAG, "Skipping non uni-link stop " + stopObj.getString("name")); continue; } - + if (!keepUniLink && stopObj.getString("name").startsWith("U")) { + Log.v(TAG, "Skipping uni-link stop " + stopObj.getString("name")); continue; } @@ -584,14 +646,15 @@ public class DataManager { Log.e(TAG, "BusStopObj == null"); } - Stop stop = getStop(context, stopObj, busStopObj); + Stop stop = getStop(context, stopObj, busRoutes, busStopObj); if (stop == null) { Log.w(TAG, "Null stop, skiping"); continue; } - Log.i(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + stop.arivalTime); + Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + + stop.arivalTime); timetable.add(stop); } @@ -600,6 +663,115 @@ public class DataManager { return timetable; } + public static Timetable getTimetable(Context context, Bus bus, BusStop startStop, int num) throws SQLException, + ClientProtocolException, IOException, JSONException { + + if (helper == null) + helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + if (busRouteDao == null) + busRouteDao = helper.getBusRouteDao(); + if (busStopDao == null) + busStopDao = helper.getBusStopDao(); + + Timetable timetable = new Timetable(); + + List<BusStop> busStops = new ArrayList<BusStop>(num); + busStops.add(startStop); + + BusRoute route = bus.route; + + for (int i = 0; i < num; i++) { + BusStop nextStop = route.moveInRoute(context, busStops.get(i), bus.direction, 1); + + if (nextStop != null) { + busStops.add(nextStop); + } else { + Log.e(TAG, "nextStop is null"); + } + } + + for (BusStop busStop : busStops) { + + String file = getFileFromServer(busStopUrl + busStop.id + ".json"); + + JSONObject data = new JSONObject(file); + JSONArray stopsArray = data.getJSONArray("stops"); + + HashSet<BusRoute> busRoutes = new HashSet<BusRoute>(); + busRoutes.add(bus.route); + + Log.v(TAG, "Number of entries " + data.length()); + + Log.v(TAG, "Stops: " + data.getJSONArray("stops")); + + for (int stopNum = 0; stopNum < stopsArray.length(); stopNum++) { + JSONObject stopObj = stopsArray.getJSONObject(stopNum); + + if (stopObj.getString("vehicle").equals(bus.id)) { + + Stop stop = getStop(context, stopObj, busRoutes, busStop); + + if (stop == null) { + Log.w(TAG, "Null stop, skiping"); + continue; + } + + Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + + " at " + stop.arivalTime); + + timetable.add(stop); + + } + } + } + + timetable.fetchTime = new Date(System.currentTimeMillis()); + + return timetable; + } + + public static Stop getStop(Context context, Bus bus, BusStop busStop) throws SQLException, ClientProtocolException, + IOException, JSONException { + + if (helper == null) + helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + if (busRouteDao == null) + busRouteDao = helper.getBusRouteDao(); + if (busStopDao == null) + busStopDao = helper.getBusStopDao(); + + String file = getFileFromServer(busStopUrl + busStop.id + ".json"); + + JSONObject data = new JSONObject(file); + JSONArray stopsArray = data.getJSONArray("stops"); + + HashSet<BusRoute> busRoutes = new HashSet<BusRoute>(); + busRouteDao.refresh(bus.route); + busRoutes.add(bus.route); + + Stop stop = null; + + // Log.v(TAG, "Number of entries " + data.length()); + + // Log.v(TAG, "Stops: " + data.getJSONArray("stops")); + + for (int stopNum = 0; stopNum < stopsArray.length(); stopNum++) { + JSONObject stopObj = stopsArray.getJSONObject(stopNum); + + // Log.v(TAG, "stopObj: " + stopObj); + if (stopObj.has("vehicle") && stopObj.getString("vehicle").equals(bus.id)) { + + stop = getStop(context, stopObj, busRoutes, busStop); + break; + + // Log.v(TAG, "Found stop for a unidentified " + stop.bus.toString() + " at " + stop.busStop.id + " at " + // + stop.arivalTime); + } + } + + return stop; + } + static PathOverlay getRoutePath(InputStream routeResource, int colour, ResourceProxy resProxy) { PathOverlay data = null; @@ -632,7 +804,7 @@ public class DataManager { StringBuilder builder = new StringBuilder(); HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(request); - Log.i("Util.getFileFromServer", "Request used: " + request); + Log.v("Util.getFileFromServer", "Request used: " + request); HttpResponse response = client.execute(httpGet); StatusLine statusLine = response.getStatusLine(); @@ -651,4 +823,66 @@ public class DataManager { return builder.toString(); } + + public static void routeMovementTest(Context context) throws SQLException { + + Dao<RouteStops, Integer> routeStopsDao = null; + + if (helper == null) + helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + if (routeStopsDao == null) + routeStopsDao = helper.getRouteStopsDao(); + if (busRouteDao == null) + busRouteDao = helper.getBusRouteDao(); + if (busStopDao == null) + busStopDao = helper.getBusStopDao(); + + for (BusRoute busRoute : busRouteDao) { + if (!busRoute.code.startsWith("U") || busRoute.code.equals("U9")) { + continue; + } + List<RouteStops> routeStops = routeStopsDao.queryForEq(RouteStops.ROUTE_ID_FIELD_NAME, busRoute.id); + + ArrayList<String> directions = new ArrayList<String>(); + if (busRoute.forwardDirection != null) { + directions.add(busRoute.forwardDirection); + } + if (busRoute.reverseDirection != null) { + directions.add(busRoute.reverseDirection); + } + if (directions.size() == 0) { + directions.add(null); + } + + BusStop startBusStop = null; + + for (int moveAmount = 1; moveAmount >= -1; moveAmount = moveAmount - 2) { + for (String direction : directions) { + for (int busStop = 0; busStop < routeStops.size() && busStop >= 0; busStop = busStop + moveAmount) { + // if (routeStops.get(busStop).stop.equals(startBusStop)) + // continue; + startBusStop = routeStops.get(busStop).busStop; + busStopDao.refresh(startBusStop); + + BusStop predictedNextStop = busRoute.moveInRoute(context, startBusStop, direction, moveAmount); + + BusStop nextStop; + if (busStop == routeStops.size() - 1) { + nextStop = routeStops.get(0).busStop; + } else { + nextStop = routeStops.get(busStop + 1).busStop; + } + busStopDao.refresh(nextStop); + + if (!nextStop.equals(predictedNextStop) && !startBusStop.equals(nextStop)) { + Log.e(TAG, "predicted: " + predictedNextStop + " next: " + nextStop); + Log.e(TAG, startBusStop.id + " " + nextStop.id); + return; + } + } + } + } + } + + } } diff --git a/src/net/cbaines/suma/DatabaseHelper.java b/src/net/cbaines/suma/DatabaseHelper.java index a72faca..2d8f9d2 100644 --- a/src/net/cbaines/suma/DatabaseHelper.java +++ b/src/net/cbaines/suma/DatabaseHelper.java @@ -40,7 +40,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { private static final String DATABASE_PATH = "/data/data/net.cbaines.suma/databases/"; private static final String DATABASE_NAME = "data.db"; - private static final int DATABASE_VERSION = 38; + private static final int DATABASE_VERSION = 39; private static final String TAG = "DatabaseHelper"; diff --git a/src/net/cbaines/suma/FavouriteDialog.java b/src/net/cbaines/suma/FavouriteDialog.java deleted file mode 100644 index ca39574..0000000 --- a/src/net/cbaines/suma/FavouriteDialog.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Southampton University Map App - * Copyright (C) 2011 Christopher Baines - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package net.cbaines.suma; - -import java.sql.SQLException; -import java.util.ArrayList; - - -import android.app.Dialog; -import android.content.Context; -import android.util.Log; -import android.view.View; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ListView; -import android.widget.TextView; - -import com.j256.ormlite.android.apptools.OpenHelperManager; -import com.j256.ormlite.dao.Dao; - -public class FavouriteDialog extends Dialog { - - private static final String TAG = "FavouriteDialog"; - private ListView listItems; - - private final Context context; - - private final TextView message; - - protected POIArrayAdapter adapter; - - private ArrayList<POI> favouriteItems; - - public FavouriteDialog(Context context) { - super(context); - - this.context = context; - - setContentView(R.layout.favourite_dialog); - setTitle("Favourite Items"); - - message = (TextView) findViewById(R.id.favouriteDialogMessage); - - favouriteItems = new ArrayList<POI>(); - - listItems = (ListView) findViewById(R.id.favouriteListItems); - - refresh(); - } - - public void refresh() { - - DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); - - try { - - Dao<Building, String> buildingDao = helper.getBuildingDao(); - Dao<BusStop, String> busStopDao = helper.getBusStopDao(); - - final ArrayList<POI> newFavouriteItems = new ArrayList<POI>(); - - newFavouriteItems.addAll(buildingDao.queryForEq(POI.FAVOURITE_FIELD_NAME, true)); - newFavouriteItems.addAll(busStopDao.queryForEq(POI.FAVOURITE_FIELD_NAME, true)); - - Log.i(TAG, "There are " + newFavouriteItems.size() + " favourites"); - if (newFavouriteItems.size() == 0) { - Log.i(TAG, "Favourite dialog has no favourites, displaying message"); - message.post(new Runnable() { - public void run() { - message.setText(R.string.favourites_dialog_message); - message.setVisibility(View.VISIBLE); - } - }); - listItems.post(new Runnable() { - public void run() { - listItems.setVisibility(View.GONE); - adapter = null; - favouriteItems.clear(); - } - }); - - } else { - message.post(new Runnable() { - public void run() { - message.setVisibility(View.GONE); - } - }); - - listItems.post(new Runnable() { - public void run() { - favouriteItems = newFavouriteItems; - adapter = new POIArrayAdapter(context, favouriteItems); - - listItems.setVisibility(View.VISIBLE); - listItems.setAdapter(adapter); - - } - }); - - } - } catch (SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - void setOnItemClickListener(OnItemClickListener item) { - listItems.setOnItemClickListener(item); - - } - - void setOnItemLongClickListener(OnItemLongClickListener item) { - listItems.setOnItemLongClickListener(item); - } - -} diff --git a/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java b/src/net/cbaines/suma/MapActivity.java index a5a255e..cad7567 100644 --- a/src/net/cbaines/suma/SouthamptonUniversityMapActivity.java +++ b/src/net/cbaines/suma/MapActivity.java @@ -42,7 +42,6 @@ import org.osmdroid.views.util.constants.MapViewConstants; import android.app.AlertDialog; import android.app.Dialog; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; @@ -54,28 +53,31 @@ import android.graphics.Paint; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.BaseExpandableListAdapter; -import android.widget.CheckBox; -import android.widget.ExpandableListView; -import android.widget.ExpandableListView.OnChildClickListener; -import android.widget.TextView; +import android.widget.Toast; import com.j256.ormlite.android.apptools.OrmLiteBaseActivity; import com.j256.ormlite.dao.Dao; -public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<DatabaseHelper> implements MapViewConstants, Runnable, RouteColorConstants, - OnChildClickListener, OnItemClickListener, OnItemLongClickListener, OnSharedPreferenceChangeListener, Preferences { +/** + * + * @author Christopher Baines <cbaines8@gmail.com> + * + */ +public class MapActivity extends OrmLiteBaseActivity<DatabaseHelper> implements MapViewConstants, Runnable, + RouteColorConstants, OnItemClickListener, OnItemLongClickListener, OnSharedPreferenceChangeListener, + Preferences { + /** + * Enable to use the database in the assets folder, if its not enabled, the database is built from the csv files in + * the assets folder + */ private boolean useBundledDatabase = true; private MapView mapView; @@ -86,33 +88,99 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa static final int VIEW_DIALOG_ID = 0; static final int FAVOURITE_DIALOG_ID = 1; + private POIDialog favDialog; private HashMap<String, Overlay> overlays = new HashMap<String, Overlay>(); private HashMap<String, Overlay> pastOverlays; - private ScaleBarOverlay scaleBarOverlay; - private static final boolean SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT = true; - private MyLocationOverlay myLocationOverlay; + // Overlays + + // -- Building Overlays + static final String BUILDING_OVERLAYS = "buildingOverlays:"; + + // ---- Residential Building Overlay + private static final String RESIDENTIAL_BUILDING_OVERLAY = "residentialBuildingOverlay"; private BuildingNumOverlay residentialBuildingOverlay; - private static final boolean NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT = true; + static final boolean RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT = true; + private static final int RESIDENTIAL_BUILDING_OVERLAY_RANK = 6; + + // ---- Non-Residential Building Overlay + private static final String NON_RESIDENTIAL_BUILDING_OVERLAY = "nonResidentialBuildingOverlay"; private BuildingNumOverlay nonResidentialBuildingOverlay; - private static final boolean RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT = true; - private BusStopOverlay busStopOverlay; - private static final boolean BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT = true; + static final boolean NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT = true; + private static final int NON_RESIDENTIAL_BUILDING_OVERLAY_RANK = 5; + + static final String[] BUILDING_TYPES = { RESIDENTIAL_BUILDING_OVERLAY, NON_RESIDENTIAL_BUILDING_OVERLAY }; + + // -- Bus Stop Overlays + static final String BUS_STOP_OVERLAYS = "busStopOverlays:"; + + // ---- Uni-Link Bus Stop Overlay + private static final String UNI_LINK_BUS_STOP_OVERLAY = "uniLinkBusStopOverlay"; + private BusStopOverlay uniLinkBusStopOverlay; + static final boolean UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT = true; + private static final int UNI_LINK_BUS_STOP_OVERLAY_RANK = 3; + + // ---- Non Uni-Link Bus Stop Overlay + private BusStopOverlay nonUniLinkBusStopOverlay; + private static final int NON_UNI_LINK_BUS_STOP_OVERLAY_RANK = 4; + + // -- Site Overlays + static final String[] SITE_NAMES = { "Highfield Campus", "Boldrewood Campus", "Avenue Campus", + "Winchester School of Art", "The University of Southampton Science Park", + "National Oceanography Centre Campus", "Boat House", "Southampton General Hospital", + "Royal South Hants Hospital", "Belgrave Industrial Site", "Highfield Hall", "Glen Eyre Hall", + "South Hill Hall", "Chamberlain Hall", "Hartley Grove", "Bencraft Hall", "Connaught Hall", + "Montefiore Hall", "Stoneham Hall", "Erasmus Park" }; + + private static final String SITE_OVERLAYS = "siteOverlays:"; private HashMap<Site, PathOverlay> siteOverlays = new HashMap<Site, PathOverlay>(21); - private static final boolean SITE_OVERLAY_ENABLED_BY_DEFAULT = false; - private HashMap<BusRoute, PathOverlay> routeOverlays = new HashMap<BusRoute, PathOverlay>(5); - private static final boolean ROUTE_OVERLAY_ENABLED_BY_DEFAULT = true; + static final boolean SITE_OVERLAYS_ENABLED_BY_DEFAULT = false; + private static final int SITE_OVERLAYS_RANK = 8; + + // -- Route Overlays + private static final String BUS_ROUTE_OVERLAYS = "routeOverlays:"; + private HashMap<BusRoute, PathOverlay> busRouteOverlays = new HashMap<BusRoute, PathOverlay>(5); + static final boolean BUS_ROUTE_OVERLAYS_ENABLED_BY_DEFAULT = true; + private static final int BUS_ROUTE_OVERLAYS_RANK = 7; + + // -- Other + static final String OTHER_OVERLAYS = "otherOverlay:"; + + // ---- Scale Bar Overlay + private static final String SCALE_BAR_OVERLAY = "scaleBarOverlay"; + private ScaleBarOverlay scaleBarOverlay; + static final boolean SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT = true; + private static final int SCALE_BAR_OVERLAY_RANK = 1; + + // ---- My Location Overlay + private static final String MY_LOCATION_OVERLAY = "myLocationOverlay"; + private static final String MY_LOCATION_OVERLAY_COMPASS = "myLocationOverlayCompass"; + private MyLocationOverlay myLocationOverlay; + static final boolean MY_LOCATION_OVERLAY_ENABLED_BY_DEFAULT = true; + static final boolean MY_LOCATION_OVERLAY_COMPASS_ENABLED_BY_DEFAULT = true; + private static final int MY_LOCATION_OVERLAY_RANK = 2; + + static final String[] OTHER_OVERLAY_NAMES = { SCALE_BAR_OVERLAY, MY_LOCATION_OVERLAY, MY_LOCATION_OVERLAY_COMPASS }; + + // Other bits - private String[] busRoutes; - private String[] buildingTypes; - private String[] other; - private String[] groupHeadings; - private String[] siteNames; + // Uni-Link routes + static final String[] UNI_LINK_ROUTES = { "U1", "U1N", "U2", "U6", "U9" }; - private FavouriteDialog favDialog; + static final String[] PREFERENCES_GROUPS = { BUS_STOP_OVERLAYS, BUS_ROUTE_OVERLAYS, BUILDING_OVERLAYS, + SITE_OVERLAYS, OTHER_OVERLAYS }; - private SouthamptonUniversityMapActivity instance; + static final String[][] PREFERENCES_CHILDREN = { UNI_LINK_ROUTES, UNI_LINK_ROUTES, BUILDING_TYPES, SITE_NAMES, + OTHER_OVERLAY_NAMES }; + + /** + * The toast for this activity, storing the toast centrally allows it to be changed quickly, instead of a queue + * building up + */ + Toast activityToast; + + private MapActivity instance; private static final String TAG = "SUM"; @@ -138,8 +206,10 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa pastOverlays = (HashMap<String, Overlay>) getLastNonConfigurationInstance(); - // SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); This code in the following constructor causes problems in - // some emulators, disable sensors to fix. + /* + * SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); This code in the + * following constructor causes problems in some emulators, disable sensors to fix. + */ Log.i(TAG, "Starting creating myLocationOverlay"); myLocationOverlay = new MyLocationOverlay(instance, mapView); Log.i(TAG, "Finished creating myLocationOverlay"); @@ -164,12 +234,26 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa mapController = mapView.getController(); mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext()); - GeoPoint userLocation = myLocationOverlay.getMyLocation(); - if (userLocation == null) { - userLocation = new GeoPoint(50935551, -1393488); // ECS + GeoPoint userLocation = null; + + Bundle extras = getIntent().getExtras(); + if (extras != null && extras.containsKey("poiPoint")) { + String poiPoint = getIntent().getExtras().getString("poiPoint"); + Log.i(TAG, "poiPoint " + poiPoint); + + String[] bits = poiPoint.split(","); + + userLocation = new GeoPoint(Double.valueOf(bits[0]), Double.valueOf(bits[1])); + mapController.setZoom(20); + + } else { + userLocation = myLocationOverlay.getMyLocation(); + if (userLocation == null) { + userLocation = new GeoPoint(50935551, -1393488); // ECS + } + mapController.setZoom(15); } - mapController.setZoom(15); mapController.setCenter(userLocation); Log.i(TAG, "Finished onCreate " + (System.currentTimeMillis() - startTime)); @@ -182,26 +266,19 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences activityPrefs = getPreferences(0); - if (activityPrefs.getBoolean("Other:Compass", false)) { + if (activityPrefs.getBoolean(OTHER_OVERLAYS + MY_LOCATION_OVERLAY_COMPASS, false)) { myLocationOverlay.enableCompass(); } else { myLocationOverlay.disableCompass(); } - if (activityPrefs.getBoolean("Other:My Location", false) && sharedPrefs.getBoolean("GPSEnabled", false)) { + if (activityPrefs.getBoolean(OTHER_OVERLAYS + MY_LOCATION_OVERLAY, false) + && sharedPrefs.getBoolean(GPS_ENABLED, false)) { myLocationOverlay.enableMyLocation(); } else { myLocationOverlay.disableMyLocation(); } - if (!sharedPrefs.contains("GPSEnabled")) { - sharedPrefs.edit().putBoolean("GPSEnabled", true).commit(); - } - - if (!sharedPrefs.contains("liveBusTimesEnabled")) { - sharedPrefs.edit().putBoolean("liveBusTimesEnabled", true).commit(); - } - sharedPrefs.registerOnSharedPreferenceChangeListener(this); activityPrefs.registerOnSharedPreferenceChangeListener(this); } @@ -330,7 +407,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } while (true) { - if ((buildingThread == null || !buildingThread.isAlive()) && (busStopThread == null || !busStopThread.isAlive()) + if ((buildingThread == null || !buildingThread.isAlive()) + && (busStopThread == null || !busStopThread.isAlive()) && (siteThread == null || !siteThread.isAlive())) break; @@ -348,30 +426,6 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa Log.i(TAG, "Begining setting up the static values " + (System.currentTimeMillis() - startTime)); - int size; - try { - size = (int) getHelper().getSiteDao().countOf(); - - ArrayList<Site> sites = new ArrayList<Site>(size); - - try { - sites.addAll(getHelper().getSiteDao().queryForAll()); - } catch (SQLException e) { - e.printStackTrace(); - } - siteNames = new String[size]; - for (int i = 0; i < size; i++) { - siteNames[i] = sites.get(i).name; - } - } catch (SQLException e1) { - e1.printStackTrace(); - } - - busRoutes = getResources().getStringArray(R.array.uniLinkBusRoutes); - buildingTypes = getResources().getStringArray(R.array.buildingTypes); - other = getResources().getStringArray(R.array.utilityOverlays); - groupHeadings = getResources().getStringArray(R.array.preferencesHeadings); - Log.i(TAG, "Finished the database thread " + (System.currentTimeMillis() - startTime)); } @@ -388,23 +442,25 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa showUtilityOverlays(); - for (int i = 0; i < busRoutes.length; i++) { - if (activityPrefs.getBoolean(groupHeadings[1] + ":" + busRoutes[i], true)) { - showBusStopOverlay(); - break; - } - } + showUniLinkBusStopOverlay(); - if (activityPrefs.getBoolean("Buildings:Residential", true) || activityPrefs.getBoolean("Buildings:Non-Residential", true)) { - // The argument currently dosent matter for this method. - showBuildingOverlay(true); + showNonUniLinkBusStopOverlay(); + if (activityPrefs.getBoolean(BUILDING_OVERLAYS + RESIDENTIAL_BUILDING_OVERLAY, + RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT) + || activityPrefs.getBoolean(BUILDING_OVERLAYS + NON_RESIDENTIAL_BUILDING_OVERLAY, + NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)) { + showBuildingOverlays(); } Log.i(TAG, "Begining to show the route overlays at " + (System.currentTimeMillis() - startTime)); for (BusRoute busRoute : getHelper().getBusRouteDao()) { + if (!busRoute.uniLink) { + Log.v(TAG, "Bus route " + busRoute.code + "(" + busRoute.id + ") is not unilink"); + continue; + } Log.v(TAG, "Looking at showing " + busRoute.code + " route overlay"); - if (activityPrefs.getBoolean("Bus Routes:" + busRoute.code, ROUTE_OVERLAY_ENABLED_BY_DEFAULT)) { + if (activityPrefs.getBoolean(BUS_ROUTE_OVERLAYS + busRoute.code, BUS_ROUTE_OVERLAYS_ENABLED_BY_DEFAULT)) { showRouteOverlay(busRoute); } } @@ -414,7 +470,7 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa try { for (Site site : getHelper().getSiteDao()) { Log.v(TAG, "Looking at showing " + site.name + " site overlay"); - if (activityPrefs.getBoolean("Sites:" + site.name, SITE_OVERLAY_ENABLED_BY_DEFAULT)) { + if (activityPrefs.getBoolean(SITE_OVERLAYS + site.name, SITE_OVERLAYS_ENABLED_BY_DEFAULT)) { showSiteOverlay(site); } } @@ -437,13 +493,14 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa if (scaleBarOverlay != null) { Log.v(TAG, "ScaleBarOverlay is already created"); } else { - if (pastOverlays != null && (scaleBarOverlay = (ScaleBarOverlay) pastOverlays.get("Other:Scale Bar")) != null) { + if (pastOverlays != null + && (scaleBarOverlay = (ScaleBarOverlay) pastOverlays.get(SCALE_BAR_OVERLAY)) != null) { Log.i(TAG, "Finished restoring utility overlays " + (System.currentTimeMillis() - startTime)); } else { scaleBarOverlay = new ScaleBarOverlay(instance); } - overlays.put("Other:Scale Bar", scaleBarOverlay); + overlays.put(SCALE_BAR_OVERLAY, scaleBarOverlay); synchronized (mapView.getOverlays()) { mapView.getOverlays().add(scaleBarOverlay); @@ -453,7 +510,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } - scaleBarOverlay.setEnabled(activityPrefs.getBoolean("Other:Scale Bar", SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT)); + scaleBarOverlay.setEnabled(activityPrefs.getBoolean(OTHER_OVERLAYS + SCALE_BAR_OVERLAY, + SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT)); mapView.postInvalidate(); @@ -465,20 +523,22 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa private void showRouteOverlay(final BusRoute route) { new Thread(new Runnable() { public void run() { - Log.i(TAG, "Begining showing route " + route.code + " overlay at " + (System.currentTimeMillis() - startTime)); + Log.i(TAG, "Begining showing route " + route.code + " overlay at " + + (System.currentTimeMillis() - startTime)); final SharedPreferences activityPrefs = getPreferences(0); final OverlayRankComparator comparator = new OverlayRankComparator(getPreferences(0)); PathOverlay routeOverlay; - if ((routeOverlay = routeOverlays.get(route)) != null) { + if ((routeOverlay = busRouteOverlays.get(route)) != null) { Log.v(TAG, route.code + " route overlay already existed"); } else { - if (pastOverlays != null && (routeOverlay = (PathOverlay) pastOverlays.get("Bus Routes:" + route.code)) != null) { + if (pastOverlays != null + && (routeOverlay = (PathOverlay) pastOverlays.get(BUS_ROUTE_OVERLAYS + route.code)) != null) { Log.v(TAG, "Restored " + route.code + " route overlay"); if (route.code.equals("U1")) { - PathOverlay routeOverlayU1E = (PathOverlay) pastOverlays.get("Bus Routes:U1E"); - overlays.put("Bus Routes:U1E", routeOverlayU1E); + PathOverlay routeOverlayU1E = (PathOverlay) pastOverlays.get(BUS_ROUTE_OVERLAYS + "U1E"); + overlays.put(BUS_ROUTE_OVERLAYS + "U1E", routeOverlayU1E); } } else { InputStream resource = null; @@ -488,15 +548,16 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa colour = U1; // TODO Is this a route like U1N or, something else, this hack works somewhat for now? - PathOverlay routeOverlayU1E = DataManager.getRoutePath(getResources().openRawResource(R.raw.u1e), colour, mResourceProxy); + PathOverlay routeOverlayU1E = DataManager.getRoutePath( + getResources().openRawResource(R.raw.u1e), colour, mResourceProxy); routeOverlayU1E.getPaint().setAntiAlias(true); routeOverlayU1E.getPaint().setAlpha(145); routeOverlayU1E.getPaint().setStrokeWidth(12); routeOverlayU1E.getPaint().setPathEffect(new DashPathEffect(new float[] { 20, 16 }, 0)); routeOverlayU1E.setEnabled(activityPrefs.getBoolean("Bus Routes:" + route.code, true)); - routeOverlays.put(new BusRoute(1000, "U1E", "U1e Route Label"), routeOverlayU1E); - overlays.put("Bus Routes:" + route.code + "E", routeOverlayU1E); + busRouteOverlays.put(new BusRoute(1000, "U1E", "U1E Route Label", true), routeOverlayU1E); + overlays.put(BUS_ROUTE_OVERLAYS + route.code + "E", routeOverlayU1E); } else if (route.code.equals("U1N")) { resource = getResources().openRawResource(R.raw.u1n); colour = U1N; @@ -522,8 +583,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa routeOverlay.getPaint().setStrokeWidth(12); } - routeOverlays.put(route, routeOverlay); - overlays.put("Bus Routes:" + route.code, routeOverlay); + busRouteOverlays.put(route, routeOverlay); + overlays.put(BUS_ROUTE_OVERLAYS + route.code, routeOverlay); synchronized (mapView.getOverlays()) { mapView.getOverlays().add(routeOverlay); @@ -532,14 +593,17 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } - routeOverlay.setEnabled(activityPrefs.getBoolean("Bus Routes:" + route.code, ROUTE_OVERLAY_ENABLED_BY_DEFAULT)); + routeOverlay.setEnabled(activityPrefs.getBoolean(BUS_ROUTE_OVERLAYS + route.code, + BUS_ROUTE_OVERLAYS_ENABLED_BY_DEFAULT)); if (route.code.equals("U1")) { - overlays.get("Bus Routes:U1E").setEnabled(activityPrefs.getBoolean("Bus Routes:U1", ROUTE_OVERLAY_ENABLED_BY_DEFAULT)); + overlays.get(BUS_ROUTE_OVERLAYS + "U1E").setEnabled( + activityPrefs.getBoolean(BUS_ROUTE_OVERLAYS + "U1", BUS_ROUTE_OVERLAYS_ENABLED_BY_DEFAULT)); } mapView.postInvalidate(); - Log.i(TAG, "Finished showing route " + route.code + " overlay at " + (System.currentTimeMillis() - startTime)); + Log.i(TAG, "Finished showing route " + route.code + " overlay at " + + (System.currentTimeMillis() - startTime)); } }).start(); } @@ -548,7 +612,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa new Thread(new Runnable() { public void run() { - Log.i(TAG, "Begining showing site " + site.name + " overlay at " + (System.currentTimeMillis() - startTime)); + Log.i(TAG, "Begining showing site " + site.name + " overlay at " + + (System.currentTimeMillis() - startTime)); final SharedPreferences activityPrefs = getPreferences(0); final OverlayRankComparator comparator = new OverlayRankComparator(getPreferences(0)); @@ -557,7 +622,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa if ((siteOverlay = siteOverlays.get(site)) != null) { } else { - if (pastOverlays != null && (siteOverlay = (PathOverlay) pastOverlays.get("Site Outlines:" + site.name)) != null) { + if (pastOverlays != null + && (siteOverlay = (PathOverlay) pastOverlays.get(SITE_OVERLAYS + site.name)) != null) { Log.i(TAG, "Restored " + site.name + " site overlay"); } else { @@ -573,7 +639,7 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } siteOverlays.put(site, siteOverlay); - overlays.put("Site Outlines:" + site.name, siteOverlay); + overlays.put(SITE_OVERLAYS + site.name, siteOverlay); Log.v(TAG, "Applyed the site overlay, now sorting them"); @@ -583,16 +649,18 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } } - siteOverlay.setEnabled(activityPrefs.getBoolean("Site Outlines:" + site.name, SITE_OVERLAY_ENABLED_BY_DEFAULT)); + siteOverlay.setEnabled(activityPrefs.getBoolean(SITE_OVERLAYS + site.name, + SITE_OVERLAYS_ENABLED_BY_DEFAULT)); mapView.postInvalidate(); - Log.i(TAG, "Finished showing site " + site.name + " overlay at " + (System.currentTimeMillis() - startTime)); + Log.i(TAG, "Finished showing site " + site.name + " overlay at " + + (System.currentTimeMillis() - startTime)); } }).start(); } - private void showBuildingOverlay(boolean residential) { + private void showBuildingOverlays() { new Thread(new Runnable() { public void run() { Log.i(TAG, "Begining showing building overlays at " + (System.currentTimeMillis() - startTime)); @@ -603,8 +671,11 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa if (residentialBuildingOverlay != null) { } else { - if (pastOverlays != null && (residentialBuildingOverlay = (BuildingNumOverlay) pastOverlays.get("Buildings:Residential")) != null) { - nonResidentialBuildingOverlay = (BuildingNumOverlay) pastOverlays.get("Buildings:Non-Residential"); + if (pastOverlays != null + && (residentialBuildingOverlay = (BuildingNumOverlay) pastOverlays + .get(RESIDENTIAL_BUILDING_OVERLAY)) != null) { + nonResidentialBuildingOverlay = (BuildingNumOverlay) pastOverlays + .get(NON_RESIDENTIAL_BUILDING_OVERLAY); Log.i(TAG, "Restored building overlays"); } else { @@ -620,22 +691,16 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa buildingDao = getHelper().getBuildingDao(); for (Building building : buildingDao) { - // Log.v(TAG, "Looking at building " + building.id); if (building.residential == true) { - // Log.v(TAG, "Its residential"); if (building.favourite) { - // Log.v(TAG, "Its residential and a favourite"); residentialBuildings.add(building); } else { - // Log.v(TAG, "Its residential and not a favourite"); residentialBuildings.add(0, building); } } else { if (building.favourite) { - // Log.v(TAG, "Its not residential and a favourite"); nonResidentialBuildings.add(building); } else { - // Log.v(TAG, "Its not residential and not a favourite"); nonResidentialBuildings.add(0, building); } } @@ -651,8 +716,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } } - overlays.put("Buildings:Residential", residentialBuildingOverlay); - overlays.put("Buildings:Non-Residential", nonResidentialBuildingOverlay); + overlays.put(RESIDENTIAL_BUILDING_OVERLAY, residentialBuildingOverlay); + overlays.put(NON_RESIDENTIAL_BUILDING_OVERLAY, nonResidentialBuildingOverlay); synchronized (mapView.getOverlays()) { mapView.getOverlays().add(residentialBuildingOverlay); @@ -661,9 +726,10 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } } - residentialBuildingOverlay.setEnabled(activityPrefs.getBoolean("Buildings:Residential", RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); - nonResidentialBuildingOverlay.setEnabled(activityPrefs.getBoolean("Buildings:Non-Residential", - NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); + residentialBuildingOverlay.setEnabled(activityPrefs.getBoolean(BUILDING_OVERLAYS + + RESIDENTIAL_BUILDING_OVERLAY, RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); + nonResidentialBuildingOverlay.setEnabled(activityPrefs.getBoolean(BUILDING_OVERLAYS + + NON_RESIDENTIAL_BUILDING_OVERLAY, NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); mapView.postInvalidate(); @@ -672,7 +738,7 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa }).start(); } - private void showBusStopOverlay() { + private void showUniLinkBusStopOverlay() { new Thread(new Runnable() { public void run() { Log.i(TAG, "Begining showing bus stop overlays at " + (System.currentTimeMillis() - startTime)); @@ -680,47 +746,158 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa final SharedPreferences activityPrefs = getPreferences(0); final OverlayRankComparator comparator = new OverlayRankComparator(getPreferences(0)); - if (busStopOverlay != null) { + if (uniLinkBusStopOverlay != null) { + if (!activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + && !activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1N", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + && !activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U2", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + && !activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U6", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + && !activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U9", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)) { + Log.i(TAG, "Uni-Link bus stop overlay not needed"); + overlays.remove(UNI_LINK_BUS_STOP_OVERLAY); + + synchronized (mapView.getOverlays()) { + mapView.getOverlays().remove(uniLinkBusStopOverlay); + Collections.sort(mapView.getOverlays(), comparator); + } + uniLinkBusStopOverlay = null; + } else { + uniLinkBusStopOverlay.setRoutes(0, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(1, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1N", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(2, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U2", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(3, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U6", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(4, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U9", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + } } else { - if (pastOverlays != null && (busStopOverlay = (BusStopOverlay) pastOverlays.get("BusStops")) != null) { - Log.i(TAG, "Restored bus stop overlays"); + if (activityPrefs + .getBoolean(BUS_STOP_OVERLAYS + "U1", UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + || activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1N", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + || activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U2", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + || activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U6", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT) + || activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U9", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)) { + if (pastOverlays != null + && (uniLinkBusStopOverlay = (BusStopOverlay) pastOverlays + .get(UNI_LINK_BUS_STOP_OVERLAY)) != null) { + Log.i(TAG, "Restored Uni-Link bus stop overlay"); + } else { + + try { + List<BusStop> busStops; + Log.v(TAG, "Begin fetching BusStops at " + (System.currentTimeMillis() - startTime)); + + busStops = getHelper().getBusStopDao().queryForEq(BusStop.UNI_LINK_FIELD_NAME, true); + + Log.v(TAG, "Finished fetching BusStops at " + (System.currentTimeMillis() - startTime)); + + uniLinkBusStopOverlay = new BusStopOverlay(instance, busStops); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + uniLinkBusStopOverlay.setRoutes(0, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(1, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U1N", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(2, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U2", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(3, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U6", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + uniLinkBusStopOverlay.setRoutes(4, activityPrefs.getBoolean(BUS_STOP_OVERLAYS + "U9", + UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + + overlays.put(UNI_LINK_BUS_STOP_OVERLAY, uniLinkBusStopOverlay); + + Log.v(TAG, "Applyed the site overlay, now sorting them"); + + synchronized (mapView.getOverlays()) { + mapView.getOverlays().add(uniLinkBusStopOverlay); + Collections.sort(mapView.getOverlays(), comparator); + } + } + } + + mapView.postInvalidate(); + + Log.i(TAG, "Finished showing bus stop overlays at " + (System.currentTimeMillis() - startTime)); + } + }).start(); + } + + private void showNonUniLinkBusStopOverlay() { + new Thread(new Runnable() { + public void run() { + Log.i(TAG, "Begining showing non uni link bus stop overlays at " + + (System.currentTimeMillis() - startTime)); + + // final SharedPreferences activityPrefs = getPreferences(0); + final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(instance); + final OverlayRankComparator comparator = new OverlayRankComparator(getPreferences(0)); + + if (nonUniLinkBusStopOverlay != null) { + nonUniLinkBusStopOverlay.setEnabled(sharedPrefs.getBoolean(NON_UNI_LINK_BUS_STOPS_OVERLAY, + NON_UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + + Log.i(TAG, + "nonUniLinkBusStopOverlay enabled ? " + + sharedPrefs.getBoolean(NON_UNI_LINK_BUS_STOPS_OVERLAY, + NON_UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + } else if (sharedPrefs.getBoolean(NON_UNI_LINK_BUS_STOPS_OVERLAY, + NON_UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)) { + if (pastOverlays != null + && (nonUniLinkBusStopOverlay = (BusStopOverlay) pastOverlays + .get(NON_UNI_LINK_BUS_STOPS_OVERLAY)) != null) { + Log.i(TAG, "Restored non Uni-Link bus stop overlays"); } else { try { List<BusStop> busStops; - Log.v(TAG, "Begin fetching BusStops at " + (System.currentTimeMillis() - startTime)); - if (activityPrefs.getBoolean(NON_UNI_LINK_BUS_STOPS, NON_UNI_LINK_BUS_STOPS_ENABLED_BY_DEFAULT)) { - busStops = getHelper().getBusStopDao().queryForAll(); - } else { - busStops = getHelper().getBusStopDao().queryForEq(BusStop.UNI_LINK_FIELD_NAME, true); - } - Log.v(TAG, "Finished fetching BusStops at " + (System.currentTimeMillis() - startTime)); + Log.v(TAG, "Begin fetching non Uni-Link BusStops at " + + (System.currentTimeMillis() - startTime)); + + busStops = getHelper().getBusStopDao().queryForEq(BusStop.UNI_LINK_FIELD_NAME, false); - busStopOverlay = new BusStopOverlay(instance, busStops); + Log.v(TAG, + "Finished fetching " + busStops.size() + " non Uni-Link BusStops at " + + (System.currentTimeMillis() - startTime)); + + nonUniLinkBusStopOverlay = new BusStopOverlay(instance, busStops); } catch (SQLException e) { e.printStackTrace(); } } - overlays.put("BusStops", busStopOverlay); + overlays.put(NON_UNI_LINK_BUS_STOPS_OVERLAY, nonUniLinkBusStopOverlay); Log.v(TAG, "Applyed the site overlay, now sorting them"); synchronized (mapView.getOverlays()) { - mapView.getOverlays().add(busStopOverlay); + mapView.getOverlays().add(nonUniLinkBusStopOverlay); Collections.sort(mapView.getOverlays(), comparator); } } - busStopOverlay.setRoutes(0, activityPrefs.getBoolean("Bus Stops:U1", BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); - busStopOverlay.setRoutes(1, activityPrefs.getBoolean("Bus Stops:U1N", BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); - busStopOverlay.setRoutes(2, activityPrefs.getBoolean("Bus Stops:U2", BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); - busStopOverlay.setRoutes(3, activityPrefs.getBoolean("Bus Stops:U6", BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); - busStopOverlay.setRoutes(4, activityPrefs.getBoolean("Bus Stops:U9", BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + if (nonUniLinkBusStopOverlay != null) { + + } mapView.postInvalidate(); - Log.i(TAG, "Finished showing bus stop overlays at " + (System.currentTimeMillis() - startTime)); + Log.i(TAG, "Finished showing non Uni-Link bus stop overlays at " + + (System.currentTimeMillis() - startTime)); } }).start(); } @@ -737,7 +914,7 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa // Handle item selection switch (item.getItemId()) { case R.id.menu_find: - Intent i = new Intent(SouthamptonUniversityMapActivity.this, FindActivity.class); + Intent i = new Intent(MapActivity.this, FindActivity.class); startActivityForResult(i, 0); return true; case R.id.menu_preferences: @@ -771,8 +948,9 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa }; AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage("GPS is not enabled, do you wish to enable it?").setPositiveButton("Yes", dialogClickListener) - .setNegativeButton("No", dialogClickListener).show(); + builder.setMessage("GPS is not enabled, do you wish to enable it?") + .setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener) + .show(); } return true; @@ -782,17 +960,18 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa return false; case R.id.menu_favourites: Log.i(TAG, "Showing favourite dialog"); - boolean refreshNeeded = favDialog != null; + showDialog(FAVOURITE_DIALOG_ID); - if (favDialog != null) { - if (refreshNeeded) - favDialog.refresh(); - } else { + if (favDialog == null) { Log.e(TAG, "Very wierd, just tried to launch the favourite's dialog, but its null?"); + return false; } + + refreshFavouriteDialog(); + return false; case R.id.menu_about: - Intent aboutIntent = new Intent(SouthamptonUniversityMapActivity.this, AboutActivity.class); + Intent aboutIntent = new Intent(MapActivity.this, AboutActivity.class); startActivityForResult(aboutIntent, 0); return true; default: @@ -801,9 +980,33 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } } + private void refreshFavouriteDialog() { + ArrayList<POI> newFavouriteItems = new ArrayList<POI>(); + + try { + Dao<Building, String> buildingDao = getHelper().getBuildingDao(); + Dao<BusStop, String> busStopDao = getHelper().getBusStopDao(); + + newFavouriteItems.addAll(buildingDao.queryForEq(POI.FAVOURITE_FIELD_NAME, true)); + newFavouriteItems.addAll(busStopDao.queryForEq(POI.FAVOURITE_FIELD_NAME, true)); + } catch (SQLException e) { + e.printStackTrace(); + } + + Log.i(TAG, "There are " + newFavouriteItems.size() + " favourites"); + if (newFavouriteItems.size() == 0) { + Log.i(TAG, "Favourite dialog has no favourites, displaying message"); + favDialog.setMessage(getResources().getString(R.string.favourites_dialog_message)); + favDialog.setItems(null); + } else { + favDialog.setMessage(""); + favDialog.setItems(newFavouriteItems); + } + } + @Override public boolean onSearchRequested() { - Intent i = new Intent(SouthamptonUniversityMapActivity.this, FindActivity.class); + Intent i = new Intent(MapActivity.this, FindActivity.class); startActivityForResult(i, 0); return false; } @@ -854,44 +1057,47 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa Log.v(TAG, "Got a busStop id back from the BusTimeActivity " + busStopID); BusStop busStop = getHelper().getBusStopDao().queryForId(busStopID); - busStopOverlay.refresh(busStop); // This does not invalidate the map, but it seems to make the changes appear + if (busStop.uniLink) { + uniLinkBusStopOverlay.refresh(busStop); // This does not invalidate the map, but it seems to + // make the changes appear + } else { + nonUniLinkBusStopOverlay.refresh(busStop); // This does not invalidate the map, but it seems + // to + // make the changes appear + } } } catch (SQLException e) { e.printStackTrace(); } if (favDialog != null) { - favDialog.refresh(); + refreshFavouriteDialog(); } } } } - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - - mapView.post(new Runnable() { - public void run() { - // updateEnabledOverlays(); TODO Fix whatever this did? - mapView.invalidate(); - } - }); - - return true; - } + /* + * public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { + * + * mapView.post(new Runnable() { public void run() { // updateEnabledOverlays(); TODO Fix whatever this did? + * mapView.invalidate(); } }); + * + * return true; } + */ protected Dialog onCreateDialog(int id) { switch (id) { case VIEW_DIALOG_ID: ViewDialog viewDialog = new ViewDialog(instance); - viewDialog.setOnItemClickListener(this); return viewDialog; case FAVOURITE_DIALOG_ID: - favDialog = new FavouriteDialog(instance); + favDialog = new POIDialog(instance); favDialog.setOnItemClickListener(this); favDialog.setOnItemLongClickListener(this); + favDialog.setTitle(R.string.favourites_dialog_title); return favDialog; - } return null; } @@ -997,32 +1203,35 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } private class OverlayRankComparator implements Comparator<Overlay> { - private final SharedPreferences prefs; + // private final SharedPreferences prefs; OverlayRankComparator(SharedPreferences prefs) { - this.prefs = prefs; + // this.prefs = prefs; } public int compare(Overlay arg0, Overlay arg1) { return getRank(arg1) - getRank(arg0); } - private final int getRank(Overlay arg0) { // TODO: Dont hardcode the rank values - if (arg0 == scaleBarOverlay) { - return prefs.getInt("mScaleBarOverlay", 1); - } else if (arg0 == myLocationOverlay) { - return prefs.getInt("myLocationOverlay", 0); - } else if (arg0 == busStopOverlay) { - return prefs.getInt("busStopOverlay", 2); - } else if (arg0 == residentialBuildingOverlay) { - return prefs.getInt("residentialBuildingOverlay", 4); - } else if (arg0 == nonResidentialBuildingOverlay) { - return prefs.getInt("nonResidentialBuildingOverlay", 3); - } else if (siteOverlays != null && siteOverlays.values().contains(arg0)) { - return prefs.getInt("siteOverlays", 6); - } else if (routeOverlays != null && routeOverlays.values().contains(arg0)) { - return prefs.getInt("routeOverlays", 5); + private final int getRank(Overlay overlay) { // TODO: Dont hardcode the rank values + if (overlay == scaleBarOverlay) { + return SCALE_BAR_OVERLAY_RANK; + } else if (overlay == myLocationOverlay) { + return MY_LOCATION_OVERLAY_RANK; + } else if (overlay == uniLinkBusStopOverlay) { + return UNI_LINK_BUS_STOP_OVERLAY_RANK; + } else if (overlay == nonUniLinkBusStopOverlay) { + return NON_UNI_LINK_BUS_STOP_OVERLAY_RANK; + } else if (overlay.equals(residentialBuildingOverlay)) { + return RESIDENTIAL_BUILDING_OVERLAY_RANK; + } else if (overlay.equals(nonResidentialBuildingOverlay)) { + return NON_RESIDENTIAL_BUILDING_OVERLAY_RANK; + } else if (siteOverlays != null && siteOverlays.values().contains(overlay)) { + return SITE_OVERLAYS_RANK; + } else if (busRouteOverlays != null && busRouteOverlays.values().contains(overlay)) { + return BUS_ROUTE_OVERLAYS_RANK; } else { + Log.e(TAG, "Trying to rank unknown overlay " + overlay); return -1; } } @@ -1034,7 +1243,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { Log.v(TAG, "Got shared prefs changed event for key " + key); - if (key.equals("GPSEnabled")) { + // Shared Preferences + if (key.equals(GPS_ENABLED)) { final SharedPreferences activityPrefs = getPreferences(0); if (activityPrefs.getBoolean("Other:Compass", false) && prefs.getBoolean("GPSEnabled", false)) { @@ -1042,52 +1252,53 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } else { myLocationOverlay.disableMyLocation(); } - } else if (key.equals("liveBusTimesEnabled")) { + } else if (key.equals(NON_UNI_LINK_BUS_TIMES)) { // Noting to do here atm - } else if (key.contains("Bus Stops")) { - showBusStopOverlay(); - } else if (key.contains("Bus Routes")) { + } else if (key.equals(UNI_LINK_BUS_TIMES)) { + // Noting to do here atm + } else if (key.startsWith(BUS_STOP_OVERLAYS)) { + showUniLinkBusStopOverlay(); + } else if (key.equals(NON_UNI_LINK_BUS_STOPS_OVERLAY)) { + showNonUniLinkBusStopOverlay(); + } else if (key.startsWith(BUS_ROUTE_OVERLAYS)) { try { + String routeName = key.substring(BUS_ROUTE_OVERLAYS.length(), key.length()); for (BusRoute route : getHelper().getBusRouteDao()) { - Log.v(TAG, route.code + " " + key.split(":")[1]); - if (route.code.equals(key.split(":")[1])) { + Log.v(TAG, route.code + " " + routeName); + if (route.code.equals(routeName)) { showRouteOverlay(route); } } } catch (SQLException e) { e.printStackTrace(); } - } else if (key.contains("Buildings")) { - if (key.equals("Buildings:Non-Residential")) { - showBuildingOverlay(false); - } else if (key.equals("Buildings:Residential")) { - showBuildingOverlay(true); - } else { - Log.e(TAG, "Wierd building preferences key " + key); - } - } else if (key.contains("Site Outlines")) { + } else if (key.startsWith(BUILDING_OVERLAYS)) { + showBuildingOverlays(); + } else if (key.startsWith(SITE_OVERLAYS)) { + String siteName = key.substring(SITE_OVERLAYS.length(), key.length()); try { for (Site site : getHelper().getSiteDao()) { - if (site.name.equals(key.split(":")[1])) { + if (site.name.equals(siteName)) { showSiteOverlay(site); } } } catch (SQLException e) { e.printStackTrace(); } - } else if (key.contains("Other")) { - if (key.contains("Scale Bar")) { + } else if (key.startsWith(OTHER_OVERLAYS)) { + if (key.substring(OTHER_OVERLAYS.length(), key.length()).equals(SCALE_BAR_OVERLAY)) { showUtilityOverlays(); - } else if (key.contains("Compass")) { - if (prefs.getBoolean("Other:Compass", false)) { + } else if (key.substring(OTHER_OVERLAYS.length(), key.length()).equals(MY_LOCATION_OVERLAY_COMPASS)) { + if (prefs.getBoolean(key, MY_LOCATION_OVERLAY_COMPASS_ENABLED_BY_DEFAULT)) { myLocationOverlay.enableCompass(); } else { myLocationOverlay.disableCompass(); } - } else if (key.contains("Other:My Location")) { + } else if (key.substring(OTHER_OVERLAYS.length(), key.length()).equals(MY_LOCATION_OVERLAY)) { final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - if (prefs.getBoolean("Other:Compass", false) && sharedPrefs.getBoolean("GPSEnabled", false)) { + if (prefs.getBoolean(key, MY_LOCATION_OVERLAY_ENABLED_BY_DEFAULT) + && sharedPrefs.getBoolean(GPS_ENABLED, GPS_ENABLED_BY_DEFAULT)) { myLocationOverlay.enableMyLocation(); } else { myLocationOverlay.disableMyLocation(); @@ -1095,249 +1306,8 @@ public class SouthamptonUniversityMapActivity extends OrmLiteBaseActivity<Databa } else { Log.e(TAG, "Unhandled preference key " + key); } - } else if (key.equals(NON_UNI_LINK_BUS_STOPS)) { - - Log.v(TAG, "Begin fetching BusStops at " + (System.currentTimeMillis() - startTime)); - try { - if (prefs.getBoolean(NON_UNI_LINK_BUS_STOPS, NON_UNI_LINK_BUS_STOPS_ENABLED_BY_DEFAULT)) { - busStopOverlay.busStops = getHelper().getBusStopDao().queryForAll(); - } else { - busStopOverlay.busStops = getHelper().getBusStopDao().queryForEq(BusStop.UNI_LINK_FIELD_NAME, true); - } - - Log.v(TAG, "Finished fetching BusStops at " + (System.currentTimeMillis() - startTime)); - - busStopOverlay.refresh(); - } catch (SQLException e) { - e.printStackTrace(); - } } else { Log.e(TAG, "Unhandled preference key " + key); } } - - class ViewDialog extends Dialog implements OnChildClickListener { - - private final ExpandableListView epView; - - private static final String TAG = "ViewDialog"; - - private final MyExpandableListAdapter mAdapter; - - private OnChildClickListener listener; - - public ViewDialog(Context context) { - super(context); - - setContentView(R.layout.view_dialog); - setTitle("Select the map elements to display"); - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.copyFrom(this.getWindow().getAttributes()); - lp.width = WindowManager.LayoutParams.FILL_PARENT; - lp.height = WindowManager.LayoutParams.FILL_PARENT; - - this.getWindow().setAttributes(lp); - - epView = (ExpandableListView) findViewById(R.id.view_list); - mAdapter = new MyExpandableListAdapter(context); - epView.setAdapter(mAdapter); - epView.setOnChildClickListener(this); - - } - - public void setOnItemClickListener(OnChildClickListener onChildClickListener) { - Log.i(TAG, "Listener set for dialog"); - listener = onChildClickListener; - } - - class MyExpandableListAdapter extends BaseExpandableListAdapter { - - private LayoutInflater inflater; - - private static final String TAG = "MyExpandableListAdapter"; - - // Bus Stops - // |_ U1 - // |_ U1N - // |_ U2 - // |_ U6 - // |_ U9 - // Bus Routes - // |_ U1 - // |_ U1N - // |_ U2 - // |_ U6 - // |_ U9 - // Buildings - // |_ Residential - // |_ Non-Residential - // Site Outlines - // |_ Highfield Campus - // |_ Boldrewood Campus - // |_ Avenue Campus - // |_ Winchester School of Art - // |_ The University of Southampton Science Park - // |_ National Oceanography Centre Campus - // |_ Boat House - // |_ Southampton General Hospital - // |_ Royal South Hants Hospital - // |_ Belgrave Industrial Site - // |_ Highfield Hall - // |_ Glen Eyre Hall - // |_ South Hill Hall - // |_ Chamberlain Hall - // |_ Hartley Grove - // |_ Bencraft Hall - // |_ Connaught Hall - // |_ Montefiore Hall - // |_ Stoneham Hall - // |_ Erasmus Park - // Other - // |_ Scale Bar - // |_ Compass - // |_ My Location - - MyExpandableListAdapter(Context context) { - inflater = LayoutInflater.from(context); - } - - public Object getChild(int groupPosition, int childPosition) { - if (groupPosition == 0 || groupPosition == 1) { - return busRoutes[childPosition]; - } else if (groupPosition == 2) { - return buildingTypes[childPosition]; - } else if (groupPosition == 3) { - return siteNames[childPosition]; - } else if (groupPosition == 4) { - return other[childPosition]; - } else { - Log.e(TAG, "Unrecognised groupPosition " + groupPosition); - return null; - } - } - - public long getChildId(int groupPosition, int childPosition) { - return groupPosition * 50 + childPosition; - } - - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { - View v = null; - if (convertView != null) - v = convertView; - else - v = inflater.inflate(R.layout.view_child_row, parent, false); - String c = (String) getChild(groupPosition, childPosition); - TextView childName = (TextView) v.findViewById(R.id.childname); - if (childName != null) - childName.setText(c); - CheckBox cb = (CheckBox) v.findViewById(R.id.check1); - cb.setClickable(false); - cb.setFocusable(false); - SharedPreferences activityPrefs = getPreferences(0); - if (groupPosition == 0) { - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + busRoutes[childPosition], BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); - } else if (groupPosition == 1) { - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + busRoutes[childPosition], ROUTE_OVERLAY_ENABLED_BY_DEFAULT)); - } else if (groupPosition == 2) { - if (childPosition == 0) { - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + buildingTypes[childPosition], - RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); - } else { - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + buildingTypes[childPosition], - NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); - } - } else if (groupPosition == 3) { - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + siteNames[childPosition], SITE_OVERLAY_ENABLED_BY_DEFAULT)); - } else if (groupPosition == 4) { - // TODO Default value below is not right - cb.setChecked(activityPrefs.getBoolean(groupHeadings[groupPosition] + ":" + other[childPosition], SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT)); // right - } - return v; - } - - public int getChildrenCount(int groupPosition) { - if (groupPosition == 0 || groupPosition == 1) { - return busRoutes.length; - } else if (groupPosition == 2) { - return buildingTypes.length; - } else if (groupPosition == 3) { - return siteNames.length; - } else if (groupPosition == 4) { - return other.length; - } - return 0; - } - - public Object getGroup(int groupPosition) { - return groupHeadings[groupPosition]; - } - - public int getGroupCount() { - return groupHeadings.length; - } - - public long getGroupId(int groupPosition) { - return groupPosition * 5; - } - - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - View v = null; - if (convertView != null) - v = convertView; - else - v = inflater.inflate(R.layout.view_group_row, parent, false); - String gt = (String) getGroup(groupPosition); - TextView colorGroup = (TextView) v.findViewById(R.id.childname); - if (gt != null) - colorGroup.setText(gt); - return v; - } - - public boolean hasStableIds() { - return true; - } - - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - - } - - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - Log.i(TAG, "Got view dialog click at " + groupPosition + ":" + childPosition); - - SharedPreferences activityPrefs = getPreferences(0); - - Editor editor = activityPrefs.edit(); - - CheckBox cb = (CheckBox) v.findViewById(R.id.check1); - - if (groupPosition == 0 || groupPosition == 1) { - Log.i(TAG, "Setting value of " + groupHeadings[groupPosition] + ":" + busRoutes[childPosition] + " to " + !cb.isChecked()); - editor.putBoolean(groupHeadings[groupPosition] + ":" + busRoutes[childPosition], !cb.isChecked()); - - } else if (groupPosition == 2) { - Log.i(TAG, "Setting value of " + groupHeadings[groupPosition] + ":" + buildingTypes[childPosition] + " to " + !cb.isChecked()); - editor.putBoolean(groupHeadings[groupPosition] + ":" + buildingTypes[childPosition], !cb.isChecked()); - - } else if (groupPosition == 3) { - Log.i(TAG, "Setting value of " + groupHeadings[groupPosition] + ":" + siteNames[childPosition] + " to " + !cb.isChecked()); - editor.putBoolean(groupHeadings[groupPosition] + ":" + siteNames[childPosition], !cb.isChecked()); - - } else if (groupPosition == 4) { - Log.i(TAG, "Setting value of " + groupHeadings[groupPosition] + ":" + other[childPosition] + " to " + !cb.isChecked()); - editor.putBoolean(groupHeadings[groupPosition] + ":" + other[childPosition], !cb.isChecked()); - } - - editor.commit(); - - mAdapter.notifyDataSetInvalidated(); - - listener.onChildClick(parent, v, groupPosition, childPosition, id); - - return true; - } - - } } diff --git a/src/net/cbaines/suma/POI.java b/src/net/cbaines/suma/POI.java index dba7924..244198d 100644 --- a/src/net/cbaines/suma/POI.java +++ b/src/net/cbaines/suma/POI.java @@ -60,8 +60,6 @@ public abstract class POI { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((point == null) ? 0 : point.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } @@ -79,16 +77,6 @@ public abstract class POI { return false; } else if (!id.equals(other.id)) return false; - if (point == null) { - if (other.point != null) - return false; - } else if (!point.equals(other.point)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; return true; } } diff --git a/src/net/cbaines/suma/POIDialog.java b/src/net/cbaines/suma/POIDialog.java new file mode 100644 index 0000000..20304bb --- /dev/null +++ b/src/net/cbaines/suma/POIDialog.java @@ -0,0 +1,92 @@ +/* + * Southampton University Map App + * Copyright (C) 2011 Christopher Baines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.cbaines.suma; + +import java.util.List; + +import android.app.Dialog; +import android.content.Context; +import android.view.View; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.ListView; +import android.widget.TextView; + +public class POIDialog extends Dialog { + + // private static final String TAG = "POIDialog"; + private ListView listItems; + + private final Context context; + + private final TextView message; + + protected POIArrayAdapter adapter; + + public POIDialog(Context context) { + super(context); + + this.context = context; + + setContentView(R.layout.poi_dialog); + + message = (TextView) findViewById(R.id.favouriteDialogMessage); + listItems = (ListView) findViewById(R.id.favouriteListItems); + + } + + void setMessage(final String text) { + message.post(new Runnable() { + public void run() { + if (text == null || text.length() == 0) { + message.setVisibility(View.GONE); + } else { + message.setText(text); + message.setVisibility(View.VISIBLE); + } + } + }); + } + + void setItems(final List<POI> items) { + listItems.post(new Runnable() { + public void run() { + if (items != null) { + adapter = new POIArrayAdapter(context, items); + + listItems.setVisibility(View.VISIBLE); + listItems.setAdapter(adapter); + } else { + listItems.setVisibility(View.GONE); + } + } + }); + } + + void setOnItemClickListener(OnItemClickListener item) { + listItems.setOnItemClickListener(item); + + } + + void setOnItemLongClickListener(OnItemLongClickListener item) { + listItems.setOnItemLongClickListener(item); + } + +} diff --git a/src/net/cbaines/suma/POIView.java b/src/net/cbaines/suma/POIView.java index 733cd0f..fb8a6c6 100644 --- a/src/net/cbaines/suma/POIView.java +++ b/src/net/cbaines/suma/POIView.java @@ -33,6 +33,7 @@ public class POIView extends LinearLayout { private final TextView name; private final TextView dist; + private final BusRoutesView routes; private LayoutParams textLayoutParams; @@ -52,18 +53,22 @@ public class POIView extends LinearLayout { this.setOrientation(HORIZONTAL); name = new TextView(context); - name.setTextSize(22f); + name.setTextSize(16f); name.setGravity(Gravity.LEFT); dist = new TextView(context); - dist.setTextSize(22f); + dist.setTextSize(16f); dist.setGravity(Gravity.RIGHT); + routes = new BusRoutesView(context, (byte) 0); + textLayoutParams = new LayoutParams(width - (width / 4), LayoutParams.WRAP_CONTENT); LayoutParams distLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); + LayoutParams busRouteLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); setPOIAndDist(poi, distInM); + addView(routes, busRouteLayoutParams); addView(name, textLayoutParams); addView(dist, distLayoutParams); } @@ -87,6 +92,9 @@ public class POIView extends LinearLayout { // Log.i(TAG, "Its a bus stop of description " + busStop.description); name.setText(busStop.description + " (" + busStop.id + ")"); + + routes.setRoutes(busStop.routes); + } else if (poi.type == POI.SITE) { Site site = (Site) poi; diff --git a/src/net/cbaines/suma/Preferences.java b/src/net/cbaines/suma/Preferences.java index e2c79a0..a978dd9 100644 --- a/src/net/cbaines/suma/Preferences.java +++ b/src/net/cbaines/suma/Preferences.java @@ -1,12 +1,13 @@ package net.cbaines.suma; public interface Preferences { + // Preferences static final String GPS_ENABLED = "GPSEnabled"; static final boolean GPS_ENABLED_BY_DEFAULT = true; static final String UNI_LINK_BUS_TIMES = "uniLinkLiveBusTimesEnabled"; static final boolean UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT = true; static final String NON_UNI_LINK_BUS_TIMES = "nonUniLinkLiveBusTimesEnabled"; static final boolean NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT = false; - static final String NON_UNI_LINK_BUS_STOPS = "nonUniLinkBusStop"; - static final boolean NON_UNI_LINK_BUS_STOPS_ENABLED_BY_DEFAULT = false; + static final String NON_UNI_LINK_BUS_STOPS_OVERLAY = "nonUniLinkBusStops"; + static final boolean NON_UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT = false; } diff --git a/src/net/cbaines/suma/PreferencesActivity.java b/src/net/cbaines/suma/PreferencesActivity.java index 0d61c6d..d72d266 100644 --- a/src/net/cbaines/suma/PreferencesActivity.java +++ b/src/net/cbaines/suma/PreferencesActivity.java @@ -42,8 +42,8 @@ public class PreferencesActivity extends PreferenceActivity implements Preferenc if (!sharedPrefs.contains(NON_UNI_LINK_BUS_TIMES)) { editor.putBoolean(NON_UNI_LINK_BUS_TIMES, NON_UNI_LINK_BUS_TIMES_ENABLED_BY_DEFAULT); } - if (!sharedPrefs.contains(NON_UNI_LINK_BUS_STOPS)) { - editor.putBoolean(NON_UNI_LINK_BUS_STOPS, NON_UNI_LINK_BUS_STOPS_ENABLED_BY_DEFAULT); + if (!sharedPrefs.contains(NON_UNI_LINK_BUS_STOPS_OVERLAY)) { + editor.putBoolean(NON_UNI_LINK_BUS_STOPS_OVERLAY, NON_UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT); } editor.commit(); diff --git a/src/net/cbaines/suma/RouteStops.java b/src/net/cbaines/suma/RouteStops.java index 1206153..29fb18c 100644 --- a/src/net/cbaines/suma/RouteStops.java +++ b/src/net/cbaines/suma/RouteStops.java @@ -40,18 +40,18 @@ public class RouteStops { // This is a foreign object which just stores the id from the User object in this table. @DatabaseField(foreign = true, columnName = STOP_ID_FIELD_NAME, indexName = "routestops_routestop_idx") - BusStop stop; + BusStop busStop; // This is a foreign object which just stores the id from the Post object in this table. @DatabaseField(foreign = true, columnName = ROUTE_ID_FIELD_NAME, indexName = "routestops_routestop_idx") - BusRoute route; + BusRoute busRoute; RouteStops() { } public RouteStops(BusStop stop, BusRoute route, int sequence) { - this.stop = stop; - this.route = route; + this.busStop = stop; + this.busRoute = route; this.sequence = sequence; } } diff --git a/src/net/cbaines/suma/Stop.java b/src/net/cbaines/suma/Stop.java index 8e2d466..94fc908 100644 --- a/src/net/cbaines/suma/Stop.java +++ b/src/net/cbaines/suma/Stop.java @@ -31,16 +31,10 @@ import android.text.format.DateUtils; */ public class Stop { - public static final String ID_FIELD_NAME = "id"; - public static final String BUS_FIELD_NAME = "bus"; - public static final String BUS_STOP_FIELD_NAME = "busStop"; - public static final String ARIVAL_TIME_FIELD_NAME = "arivalTime"; - public static final String FETCH_TIME_FIELD_NAME = "timeOfFetch"; - - /** - * A generated id for the bus - */ - int id; + // public static final String BUS_FIELD_NAME = "bus"; + // public static final String BUS_STOP_FIELD_NAME = "busStop"; + // public static final String ARIVAL_TIME_FIELD_NAME = "arivalTime"; + // public static final String FETCH_TIME_FIELD_NAME = "timeOfFetch"; /** * The Bus stopping at the stop @@ -63,17 +57,28 @@ public class Stop { Date timeOfFetch; /** + * Is the time live, or just expected + */ + boolean live; + + /** + * Assumed to be the number of seconds since this data was fetched from the ROMANSE system? + */ + int age; + + /** * * @param bus * @param busStop * @param arivalTime * @param timeOfFetch */ - public Stop(Bus bus, BusStop busStop, Date arivalTime, Date timeOfFetch) { + public Stop(Bus bus, BusStop busStop, Date arivalTime, Date timeOfFetch, boolean live) { this.busStop = busStop; this.bus = bus; this.arivalTime = arivalTime; this.timeOfFetch = timeOfFetch; + this.live = live; } /** @@ -84,7 +89,21 @@ public class Stop { if (arivalTime.getTime() - System.currentTimeMillis() <= 60000) { return "Due"; } else { - return (String) DateUtils.getRelativeTimeSpanString(arivalTime.getTime(), System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS); + return (String) DateUtils.getRelativeTimeSpanString(arivalTime.getTime(), System.currentTimeMillis(), + DateUtils.MINUTE_IN_MILLIS); + } + } + + public String getShortTimeToArival() { + if (arivalTime.getTime() - System.currentTimeMillis() <= 60000) { + return "Due"; + } else { + String time = (String) DateUtils.getRelativeTimeSpanString(arivalTime.getTime(), + System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS); + time = time.replace("in ", ""); + time = time.replace(" minutes", "m"); + time = time.replace(" minute", "m"); + return time; } } @@ -95,7 +114,6 @@ public class Stop { result = prime * result + ((arivalTime == null) ? 0 : arivalTime.hashCode()); result = prime * result + ((bus == null) ? 0 : bus.hashCode()); result = prime * result + ((busStop == null) ? 0 : busStop.hashCode()); - result = prime * result + id; return result; } @@ -132,8 +150,6 @@ public class Stop { return false; } else if (!busStop.equals(other.busStop)) return false; - if (id != other.id) - return false; return true; } diff --git a/src/net/cbaines/suma/StopView.java b/src/net/cbaines/suma/StopView.java index dc023aa..764072e 100644 --- a/src/net/cbaines/suma/StopView.java +++ b/src/net/cbaines/suma/StopView.java @@ -22,10 +22,13 @@ package net.cbaines.suma; import java.sql.SQLException; import java.text.DateFormat; -import android.content.Context; +import android.app.Activity; +import android.content.Intent; +import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; +import android.view.View.OnLongClickListener; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -33,7 +36,7 @@ import android.widget.Toast; import com.j256.ormlite.android.apptools.OpenHelperManager; import com.j256.ormlite.dao.Dao; -public class StopView extends LinearLayout implements OnClickListener { +public class StopView extends LinearLayout implements OnClickListener, OnLongClickListener { // private final ImageView icon; @@ -42,9 +45,11 @@ public class StopView extends LinearLayout implements OnClickListener { private final TextView name; private final TextView time; private String onClickMessage = ""; - private final Context context; + private final BusStopActivity context; - public StopView(Context context, Stop stop) { + private Stop stop; + + public StopView(BusStopActivity context, Stop stop) { super(context); this.context = context; @@ -68,6 +73,8 @@ public class StopView extends LinearLayout implements OnClickListener { // Log.i(TAG, "Time of arival " + stop.arivalTime); + this.stop = stop; + name.setText(stop.bus.getName()); time.setText(stop.getTimeToArival()); @@ -79,20 +86,85 @@ public class StopView extends LinearLayout implements OnClickListener { busDao.refresh(stop.bus); if (stop.bus.id != null) { - onClickMessage = "Bus " + stop.bus.toString() + " at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.live) { + onClickMessage = "Bus " + stop.bus.toString() + " at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus " + stop.bus.toString() + " at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } } else { - onClickMessage = "Unidentified bus (" + stop.bus.getName() + ") at " + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + if (stop.live) { + onClickMessage = "Unidentified bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } else { + onClickMessage = "Timetabled bus (" + stop.bus.getName() + ") at " + + DateFormat.getTimeInstance(DateFormat.SHORT).format(stop.arivalTime); + } } } catch (SQLException e) { e.printStackTrace(); } this.setOnClickListener(this); + this.setOnLongClickListener(this); } public void onClick(View v) { - Toast.makeText(context, onClickMessage, Toast.LENGTH_SHORT).show(); + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, onClickMessage, Toast.LENGTH_SHORT); + } else { + context.activityToast.setText(onClickMessage); + context.activityToast.setDuration(Toast.LENGTH_SHORT); + } + context.activityToast.show(); } + @Override + public boolean onLongClick(View v) { + DatabaseHelper helper = OpenHelperManager.getHelper(context, DatabaseHelper.class); + + try { + Dao<Bus, Integer> busDao = helper.getBusDao(); + Dao<BusRoute, Integer> busRouteDao = helper.getBusRouteDao(); + + busDao.refresh(stop.bus); + busRouteDao.refresh(stop.bus.route); + + Log.i("StopView", "Bus route " + stop.bus.route + " Uni-Link " + stop.bus.route.uniLink + " Bus ID " + + stop.bus.id); + + if (stop.bus.id != null && stop.bus.route.uniLink) { + Intent i = new Intent(context, BusActivity.class); + i.putExtra("busID", stop.bus.id); + i.putExtra("busStopID", stop.busStop.id); + ((Activity) context).startActivityForResult(i, 0); + } else { + if (!stop.bus.route.uniLink) { + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, + "Bus schedules only avalible for Uni-Link buses", Toast.LENGTH_SHORT); + } else { + context.activityToast.setText("Bus schedules only avalible for Uni-Link buses"); + context.activityToast.setDuration(Toast.LENGTH_SHORT); + } + context.activityToast.show(); + } else { + if (context.activityToast == null) { + context.activityToast = Toast.makeText(context, + "Bus schedules not avalible for unidentified buses", Toast.LENGTH_SHORT); + } else { + context.activityToast.setText("Bus schedules not avalible for unidentified buses"); + context.activityToast.setDuration(Toast.LENGTH_SHORT); + } + context.activityToast.show(); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + return true; + } } diff --git a/src/net/cbaines/suma/Timetable.java b/src/net/cbaines/suma/Timetable.java index 6e3db1e..93c8e8d 100644 --- a/src/net/cbaines/suma/Timetable.java +++ b/src/net/cbaines/suma/Timetable.java @@ -28,7 +28,7 @@ public class Timetable extends ArrayList<Stop> { * */ private static final long serialVersionUID = -9021303378059511643L; - + Date fetchTime; public String toString() { @@ -40,6 +40,8 @@ public class Timetable extends ArrayList<Stop> { } public boolean contains(Stop otherStop, boolean toTheMinute) { + if (otherStop == null) + return false; if (toTheMinute) { for (Stop stop : this) { if (otherStop.bus != null && stop.bus != null && otherStop.bus.equals(stop.bus)) { @@ -47,8 +49,14 @@ public class Timetable extends ArrayList<Stop> { return true; } } else if (otherStop.busStop.equals(stop.busStop)) { - if (Math.abs(otherStop.arivalTime.getTime() - stop.arivalTime.getTime()) < 60000) { + if (otherStop.arivalTime == null && stop.arivalTime == null) { return true; + } else { + if (otherStop.arivalTime == null || stop.arivalTime == null) { + return false; + } else if (Math.abs(otherStop.arivalTime.getTime() - stop.arivalTime.getTime()) < 60000) { + return true; + } } } } diff --git a/src/net/cbaines/suma/TimetableAdapter.java b/src/net/cbaines/suma/TimetableAdapter.java index b4dfab5..9ec7a72 100644 --- a/src/net/cbaines/suma/TimetableAdapter.java +++ b/src/net/cbaines/suma/TimetableAdapter.java @@ -19,7 +19,6 @@ package net.cbaines.suma; -import android.content.Context; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -29,14 +28,14 @@ import android.widget.BaseAdapter; public class TimetableAdapter extends BaseAdapter { - private final Context context; + private final BusStopActivity context; private Timetable timetable; private final Animation a; private boolean[] changed; private static final String TAG = "TimetableAdapter"; - public TimetableAdapter(Context context, Timetable timetable) { + public TimetableAdapter(BusStopActivity context, Timetable timetable) { this.context = context; this.timetable = timetable; this.a = AnimationUtils.loadAnimation(context, R.anim.updated_stop_view); diff --git a/src/net/cbaines/suma/ViewDialog.java b/src/net/cbaines/suma/ViewDialog.java new file mode 100644 index 0000000..432fec1 --- /dev/null +++ b/src/net/cbaines/suma/ViewDialog.java @@ -0,0 +1,274 @@ +/* + * Southampton University Map App + * Copyright (C) 2011 Christopher Baines + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.cbaines.suma; + +import android.app.Dialog; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.BaseExpandableListAdapter; +import android.widget.CheckBox; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.OnChildClickListener; +import android.widget.TextView; + +class ViewDialog extends Dialog implements OnChildClickListener { + + private final ExpandableListView epView; + + private static final String TAG = "ViewDialog"; + + private final MyExpandableListAdapter mAdapter; + + private OnChildClickListener listener; + + private String[] busRoutes; + private String[] buildingTypes; + private String[] other; + private String[] groupHeadings; + private String[] siteNames; + + protected MapActivity context; + + public ViewDialog(MapActivity context) { + super(context); + + this.context = context; + + busRoutes = context.getResources().getStringArray(R.array.uniLinkBusRoutes); + buildingTypes = context.getResources().getStringArray(R.array.buildingTypes); + other = context.getResources().getStringArray(R.array.utilityOverlays); + groupHeadings = context.getResources().getStringArray(R.array.preferencesHeadings); + siteNames = MapActivity.SITE_NAMES; // TODO: Temp hack, should be included in the strings res for translation + // purposes? + + setContentView(R.layout.view_dialog); + setTitle("Select the map elements to display"); + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); + lp.copyFrom(this.getWindow().getAttributes()); + lp.width = WindowManager.LayoutParams.FILL_PARENT; + lp.height = WindowManager.LayoutParams.FILL_PARENT; + + this.getWindow().setAttributes(lp); + + epView = (ExpandableListView) findViewById(R.id.view_list); + mAdapter = new MyExpandableListAdapter(context); + epView.setAdapter(mAdapter); + epView.setOnChildClickListener(this); + + } + + public void setOnItemClickListener(OnChildClickListener onChildClickListener) { + Log.i(TAG, "Listener set for dialog"); + listener = onChildClickListener; + } + + class MyExpandableListAdapter extends BaseExpandableListAdapter implements Preferences { + + private LayoutInflater inflater; + + private static final String TAG = "MyExpandableListAdapter"; + + // Bus Stops + // |_ U1 + // |_ U1N + // |_ U2 + // |_ U6 + // |_ U9 + // Bus Routes + // |_ U1 + // |_ U1N + // |_ U2 + // |_ U6 + // |_ U9 + // Buildings + // |_ Residential + // |_ Non-Residential + // Site Outlines + // |_ Highfield Campus + // |_ Boldrewood Campus + // |_ Avenue Campus + // |_ Winchester School of Art + // |_ The University of Southampton Science Park + // |_ National Oceanography Centre Campus + // |_ Boat House + // |_ Southampton General Hospital + // |_ Royal South Hants Hospital + // |_ Belgrave Industrial Site + // |_ Highfield Hall + // |_ Glen Eyre Hall + // |_ South Hill Hall + // |_ Chamberlain Hall + // |_ Hartley Grove + // |_ Bencraft Hall + // |_ Connaught Hall + // |_ Montefiore Hall + // |_ Stoneham Hall + // |_ Erasmus Park + // Other + // |_ Scale Bar + // |_ Compass + // |_ My Location + + MyExpandableListAdapter(Context context) { + inflater = LayoutInflater.from(context); + } + + public Object getChild(int groupPosition, int childPosition) { + if (groupPosition == 0 || groupPosition == 1) { + return busRoutes[childPosition]; + } else if (groupPosition == 2) { + return buildingTypes[childPosition]; + } else if (groupPosition == 3) { + return siteNames[childPosition]; + } else if (groupPosition == 4) { + return other[childPosition]; + } else { + Log.e(TAG, "Unrecognised groupPosition " + groupPosition); + return null; + } + } + + public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 50 + childPosition; + } + + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, + ViewGroup parent) { + View v = null; + if (convertView != null) + v = convertView; + else + v = inflater.inflate(R.layout.view_child_row, parent, false); + String c = (String) getChild(groupPosition, childPosition); + TextView childName = (TextView) v.findViewById(R.id.childname); + if (childName != null) + childName.setText(c); + CheckBox cb = (CheckBox) v.findViewById(R.id.check1); + cb.setClickable(false); + cb.setFocusable(false); + if (context == null) { + Log.e(TAG, "context == null"); + } + SharedPreferences activityPrefs = context.getPreferences(0); + + String str = MapActivity.PREFERENCES_GROUPS[groupPosition] + + MapActivity.PREFERENCES_CHILDREN[groupPosition][childPosition]; + + if (groupPosition == 0) { + cb.setChecked(activityPrefs.getBoolean(str, MapActivity.UNI_LINK_BUS_STOP_OVERLAY_ENABLED_BY_DEFAULT)); + } else if (groupPosition == 1) { + cb.setChecked(activityPrefs.getBoolean(str, MapActivity.BUS_ROUTE_OVERLAYS_ENABLED_BY_DEFAULT)); + } else if (groupPosition == 2) { + if (childPosition == 0) { + cb.setChecked(activityPrefs.getBoolean(str, + MapActivity.RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); + } else { + cb.setChecked(activityPrefs.getBoolean(str, + MapActivity.NON_RESIDENTIAL_BUILDING_OVERLAY_ENABLED_BY_DEFAULT)); + } + } else if (groupPosition == 3) { + cb.setChecked(activityPrefs.getBoolean(str, MapActivity.SITE_OVERLAYS_ENABLED_BY_DEFAULT)); + } else if (groupPosition == 4) { + cb.setChecked(activityPrefs.getBoolean(str, MapActivity.SCALE_BAR_OVERLAY_ENABLED_BY_DEFAULT)); + } + return v; + } + + public int getChildrenCount(int groupPosition) { + if (groupPosition == 0 || groupPosition == 1) { + return busRoutes.length; + } else if (groupPosition == 2) { + return buildingTypes.length; + } else if (groupPosition == 3) { + return siteNames.length; + } else if (groupPosition == 4) { + return other.length; + } + return 0; + } + + public Object getGroup(int groupPosition) { + return groupHeadings[groupPosition]; + } + + public int getGroupCount() { + return groupHeadings.length; + } + + public long getGroupId(int groupPosition) { + return groupPosition * 5; + } + + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + View v = null; + if (convertView != null) + v = convertView; + else + v = inflater.inflate(R.layout.view_group_row, parent, false); + String gt = (String) getGroup(groupPosition); + TextView colorGroup = (TextView) v.findViewById(R.id.childname); + if (gt != null) + colorGroup.setText(gt); + return v; + } + + public boolean hasStableIds() { + return true; + } + + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + + } + + public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { + Log.i(TAG, "Got view dialog click at " + groupPosition + ":" + childPosition); + + SharedPreferences activityPrefs = context.getPreferences(0); + + Editor editor = activityPrefs.edit(); + + CheckBox cb = (CheckBox) v.findViewById(R.id.check1); + + String str = MapActivity.PREFERENCES_GROUPS[groupPosition] + + MapActivity.PREFERENCES_CHILDREN[groupPosition][childPosition]; + + editor.putBoolean(str, !cb.isChecked()); + + editor.commit(); + + mAdapter.notifyDataSetInvalidated(); + + if (listener != null) { + listener.onChildClick(parent, v, groupPosition, childPosition, id); + } + + return true; + } + +}
\ No newline at end of file |