/webportal/src/main/java/au/org/emii/portal/composer/AnimationControlsComposer.java
Java | 363 lines | 217 code | 44 blank | 102 comment | 24 complexity | ad241c300a8c4df614af604474307304 MD5 | raw file
1package au.org.emii.portal.composer; 2 3import au.org.emii.portal.menu.AnimationSelection; 4import au.org.emii.portal.util.LayerUtilities; 5import au.org.emii.portal.menu.MapLayer; 6import au.org.emii.portal.menu.MapLayerMetadata; 7import au.org.emii.portal.wms.NcWMSSupport; 8import au.org.emii.portal.javascript.OpenLayersJavascript; 9import au.org.emii.portal.wms.ThreddsSupport; 10import au.org.emii.portal.util.Validate; 11import au.org.emii.portal.settings.SettingsSupplementary; 12import au.org.emii.portal.lang.LanguagePack; 13import java.text.DateFormat; 14import java.text.ParseException; 15import java.util.AbstractMap; 16import java.util.Date; 17import java.util.HashMap; 18import java.util.List; 19import java.util.Map; 20 21import org.zkoss.zk.ui.Executions; 22import org.zkoss.zk.ui.WrongValueException; 23import org.zkoss.zul.Button; 24import org.zkoss.zul.Label; 25import org.zkoss.zul.Window; 26//import au.org.emii.zk.DateboxPlus; 27 28public class AnimationControlsComposer extends GenericAutowireAutoforwardComposer { 29 30 private static final long serialVersionUID = 1L; 31 /** 32 * The window containing all controls 33 */ 34 private Window animationControls; 35 /** 36 * Start date 37 */ 38 // private DateboxPlus startDatebox; 39 /** 40 * End date 41 */ 42// private DateboxPlus endDatebox; 43 /** 44 * Start animation button 45 */ 46 private Button startButton; 47 /** 48 * Stop animation button 49 */ 50 private Button stopButton; 51 private Label invalidStartDate; 52 private Label invalidEndDate; 53 private LanguagePack languagePack = null; 54 private OpenLayersJavascript openLayersJavascript = null; 55 private LayerUtilities layerUtilities = null; 56 private SettingsSupplementary settingsSupplementary = null; 57 private NcWMSSupport ncWMSSupport = null; 58 private ThreddsSupport threddsSupport = null; 59 60 public LanguagePack getLanguagePack() { 61 return languagePack; 62 } 63 64 public void setLanguagePack(LanguagePack languagePack) { 65 this.languagePack = languagePack; 66 } 67 68 public boolean animationDatesValid() { 69 boolean valid = false; 70 71// Date start = startDatebox.getValue(); 72// Date end = endDatebox.getValue(); 73// 74// if ((start != null) 75// && (end != null) 76// && (start.before(end)) 77// && startDatebox.isValid() 78// && endDatebox.isValid()) { 79// 80// valid = true; 81// } 82 return valid; 83 } 84 85 public void onClick$startButton() { 86 MapComposer mc = getMapComposer(); 87 if (mc.safeToPerformMapAction()) { 88 MapLayer activeLayer = mc.getActiveLayersSelection(true); 89 if (activeLayer != null) { 90 AnimationSelection as = new AnimationSelection(); 91 activeLayer.setAnimationSelection(as); 92 93 // 1) check dates are valid 94 if (animationDatesValid()) { 95 96// // 2) populate maplayer.animationSelection 97// as.setStartDate(startDatebox.getValue()); 98// as.setEndDate(endDatebox.getValue()); 99 100 // 3) ask ncwms for the the timeStrings 101 // (will be stored within activeLayer) 102 // This process can fail if the server is down 103 switch (activeLayer.getType()) { 104 case LayerUtilities.NCWMS: 105 logger.debug("NCWMS animation settings..."); 106 startNcWMSAnimation(activeLayer); 107 break; 108 case LayerUtilities.THREDDS: 109 logger.debug("THREDDS animation settings..."); 110 startThreddsAnimation(activeLayer); 111 break; 112 default: 113 logger.info( 114 "unsupported animation type requested: " + activeLayer.getType()); 115 } 116 } else { 117 mc.showMessage(languagePack.getLang("invalid_animation_date")); 118 } 119 } else { 120 logger.info( 121 "user requested start animation but no layer is" 122 + "selected in active layers"); 123 } 124 } 125 } 126 127 private void startNcWMSAnimation(MapLayer activeLayer) { 128 if (ncWMSSupport.animationDateStrings(activeLayer)) { 129 // NCWMS: user must now select the framerate 130 animationFramesPopup(activeLayer); 131 } else { 132 getMapComposer().showMessage(languagePack.getLang("error_getting_timestrings")); 133 } 134 } 135 136 private void startThreddsAnimation(MapLayer activeLayer) { 137 /** 138 * Thredds doesn't support framerates so we can just pick our 139 * own dates, as long as they are within 140 */ 141 if (threddsSupport.animationDateStrings(activeLayer)) { 142 if (threddsSupport.maxFramesExceeded(activeLayer)) { 143 getMapComposer().showMessage( 144 languagePack.getCompoundLang( 145 "thredds_frames_exceeded", 146 new Object[]{ 147 Integer.valueOf(ThreddsSupport.MAXIMUM_ALLOWED_FRAMES), 148 Integer.valueOf(threddsSupport.countSelectedFrames(activeLayer)) 149 })); 150 } else { 151 activateAnimation(activeLayer); 152 } 153 } else { 154 // error - should never happen ... 155 getMapComposer().showMessage(languagePack.getLang("error_getting_timestrings")); 156 } 157 } 158 159 // 4) give user a popup asking how many frames, then ask mapcontroller 160 // to get the party started 161 private void animationFramesPopup(MapLayer activeLayer) { 162 Map<String, AbstractMap<String, String>> params = new HashMap<String, AbstractMap<String, String>>(); 163 params.put("timeString", activeLayer.getAnimationSelection().getTimeStrings()); 164 AnimationFramesComposer window = (AnimationFramesComposer) Executions.createComponents("WEB-INF/zul/AnimationFrames.zul", null, params); 165 window.setActiveLayer(activeLayer); 166 window.doOverlapped(); 167 } 168 169 public void activateAnimation(MapLayer activeLayer) { 170 MapComposer mc = getMapComposer(); 171 //if (imageTester.testAnimationImage(activeLayer)) { 172 // we requested the image and it checks out ok 173 174 // mark the layer as animated, hide the 'start' button 175 activeLayer.setCurrentlyAnimated(true); 176 updateAnimationStartStopButtons(activeLayer); 177 178 // update our row in activeLayers to show the correct 179 // icon 180 mc.refreshActiveLayer(activeLayer); 181 182 // let rip 183 openLayersJavascript.execute( 184 openLayersJavascript.iFrameReferences 185 + openLayersJavascript.removeMapLayer(activeLayer) 186 + openLayersJavascript.animate(activeLayer) 187 + openLayersJavascript.updateMapLayerIndexes( 188 mc.getPortalSession().getActiveLayers())); 189 //} else { 190 // mc.errorMessageBrokenWMSLayer(imageTester); 191 //} 192 } 193 194 private void updateAnimationStartStopButtons(MapLayer mapLayer) { 195 boolean startButtonDisabled = mapLayer.isCurrentlyAnimated(); 196 startButton.setVisible(!startButtonDisabled); 197 stopButton.setVisible(startButtonDisabled); 198 } 199 200 public void onClick$stopButton() { 201 MapComposer mc = getMapComposer(); 202 if (mc.safeToPerformMapAction()) { 203 MapLayer activeLayer = mc.getActiveLayersSelection(true); 204 if (activeLayer != null) { 205 activeLayer.setCurrentlyAnimated(false); 206 updateAnimationStartStopButtons(activeLayer); 207 mc.refreshActiveLayer(activeLayer); 208 209 openLayersJavascript.execute( 210 openLayersJavascript.iFrameReferences 211 + openLayersJavascript.removeMapLayer(activeLayer) 212 + openLayersJavascript.activateMapLayer(activeLayer) 213 + openLayersJavascript.updateMapLayerIndexes( 214 mc.getPortalSession().getActiveLayers())); 215 } else { 216 logger.info( 217 "user requested stop animation but no layer is selected"); 218 } 219 } 220 221 } 222 223 /** 224 * Pre-select the date range in the start/end animation date 225 * boxes. 226 * 227 * For ncWMS, we can select the whole date range with reasonable 228 * performance 229 * @throws ParseException 230 * @throws WrongValueException 231 */ 232 private void preSelectNcWMSDateRange(List<String> validDates) throws WrongValueException, ParseException { 233 logger.debug("selecting maximum date range for ncwms"); 234 DateFormat sd = Validate.getShortIsoDateFormatter(); 235// startDatebox.setValue( 236// sd.parse(validDates.get(0))); 237// endDatebox.setValue( 238// sd.parse( 239// validDates.get(validDates.size() - 1))); 240 } 241 242 /** 243 * Pre-select the date range in the start/end animation date 244 * boxes. 245 * 246 * For Thredds, we have to restrict the selected range for 247 * performance, so that only a maximum of 248 * ThreddsSupport.MAXIMUM_ALLOWED_FRAMES are selected. 249 * 250 * We will preselect MAXIMUM_ALLOWED_FRAMES of the latest 251 * dates we have data for 252 * @throws ParseException 253 * @throws WrongValueException 254 */ 255 private void preSelectThreddsDateRange(List<String> validDates) throws WrongValueException, ParseException { 256 logger.debug("restricting THREADS date range to " + ThreddsSupport.MAXIMUM_ALLOWED_FRAMES + " frames"); 257 DateFormat sd = Validate.getShortIsoDateFormatter(); 258 259 /* protect against the case where there are less than 260 * MAXIMUM_ALLOWED_FRAMES of animation available 261 */ 262 int startIndex = Math.max(0, validDates.size() - settingsSupplementary.getValueAsInt(ThreddsSupport.MAXIMUM_ALLOWED_FRAMES)); 263// startDatebox.setValue( 264// sd.parse(validDates.get(startIndex))); 265// endDatebox.setValue( 266// sd.parse( 267// validDates.get(validDates.size() - 1))); 268 } 269 270 public void updateAnimationControls(MapLayer currentSelection) { 271 MapLayerMetadata animationParameters = 272 currentSelection.getMapLayerMetadata(); 273 if ((layerUtilities.supportsAnimation(currentSelection.getType())) 274 && (animationParameters != null)) { 275 276 List<String> validDates = animationParameters.getDatesWithData(); 277 updateAnimationStartStopButtons(currentSelection); 278 279// startDatebox.setValidDates(validDates); 280// endDatebox.setValidDates(validDates); 281 282 if (validDates.size() > 1) { 283 try { 284 switch (currentSelection.getType()) { 285 case LayerUtilities.THREDDS: 286 preSelectThreddsDateRange(validDates); 287 break; 288 case LayerUtilities.NCWMS: 289 preSelectNcWMSDateRange(validDates); 290 break; 291 default: 292 logger.warn("unsupported type " + currentSelection.getType()); 293 } 294 295 invalidStartDate.setVisible(false); 296 invalidEndDate.setVisible(false); 297 298 animationControls.setVisible(true); 299 300 } catch (WrongValueException e) { 301 logger.error(e); 302 } catch (ParseException e) { 303 logger.error(e); 304 } 305 } else { 306 logger.debug( 307 "less than 2 dates available for animation so not showing controls"); 308 } 309 310 } else { 311 animationControls.setVisible(false); 312 } 313 } 314 315 /** 316 * Reset selected date range to max allowable 317 */ 318 public void onClick$resetAnimationDateRange() { 319 updateAnimationControls(getMapComposer().getActiveLayersSelection(true)); 320 } 321 322 public void onChange$startDatebox() { 323 logger.debug("start date changed"); 324// invalidStartDate.setVisible(!startDatebox.isValid()); 325 } 326 327 public void onChange$endDatebox() { 328 logger.debug("end date changed"); 329// invalidEndDate.setVisible(!endDatebox.isValid()); 330 } 331 332 public OpenLayersJavascript getOpenLayersJavascript() { 333 return openLayersJavascript; 334 } 335 336 public void setOpenLayersJavascript(OpenLayersJavascript openLayersJavascript) { 337 this.openLayersJavascript = openLayersJavascript; 338 } 339 340 public LayerUtilities getLayerUtilities() { 341 return layerUtilities; 342 } 343 344 public void setLayerUtilities(LayerUtilities layerUtilities) { 345 this.layerUtilities = layerUtilities; 346 } 347 348 public SettingsSupplementary getSettingsSupplementary() { 349 return settingsSupplementary; 350 } 351 352 public void setSettingsSupplementary(SettingsSupplementary settingsSupplementary) { 353 this.settingsSupplementary = settingsSupplementary; 354 } 355 356 /*public ImageTester getImageTester() { 357 return imageTester; 358 } 359 360 public void setImageTester(ImageTester imageTester) { 361 this.imageTester = imageTester; 362 }*/ 363}