/webportal/src/main/java/au/org/emii/portal/composer/AnimationControlsComposer.java

http://alageospatialportal.googlecode.com/ · Java · 363 lines · 217 code · 44 blank · 102 comment · 24 complexity · ad241c300a8c4df614af604474307304 MD5 · raw file

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