001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028package edu.wisc.ssec.mcidasv.data.hydra; 029 030import java.awt.BorderLayout; 031import java.awt.Color; 032import java.awt.FlowLayout; 033import java.awt.event.ActionEvent; 034import java.awt.event.ActionListener; 035import java.net.URL; 036import java.rmi.RemoteException; 037 038import javax.swing.JComponent; 039import javax.swing.JLabel; 040import javax.swing.JPanel; 041import javax.swing.JTextField; 042 043import org.slf4j.Logger; 044import org.slf4j.LoggerFactory; 045 046import ucar.unidata.data.DataChoice; 047import ucar.unidata.data.DataSelection; 048import ucar.unidata.data.DataSelectionComponent; 049import ucar.unidata.data.GeoLocationInfo; 050import ucar.unidata.data.GeoSelection; 051import ucar.unidata.geoloc.projection.LatLonProjection; 052import ucar.unidata.view.geoloc.MapProjectionDisplay; 053import ucar.unidata.view.geoloc.MapProjectionDisplayJ3D; 054import ucar.visad.ProjectionCoordinateSystem; 055import ucar.visad.display.DisplayMaster; 056import ucar.visad.display.LineDrawing; 057import ucar.visad.display.MapLines; 058import ucar.visad.display.RubberBandBox; 059import visad.CellImpl; 060import visad.FlatField; 061import visad.Gridded2DSet; 062import visad.RealTupleType; 063import visad.RealType; 064import visad.SampledSet; 065import visad.UnionSet; 066import visad.VisADException; 067import visad.data.mcidas.BaseMapAdapter; 068import visad.georef.MapProjection; 069 070public class TrackSelection extends DataSelectionComponent { 071 072 private static final Logger logger = LoggerFactory.getLogger(TrackSelection.class); 073 074 public static final int DEFAULT_TRACK_STRIDE = 5; 075 public static final int DEFAULT_VERTICAL_STRIDE = 2; 076 077 DataChoice dataChoice; 078 FlatField track; 079 080 double[] x_coords = new double[2]; 081 double[] y_coords = new double[2]; 082 boolean hasSubset = true; 083 MapProjectionDisplayJ3D mapProjDsp; 084 DisplayMaster dspMaster; 085 086 int trackStride; 087 int verticalStride; 088 089 JTextField trkStr; 090 JTextField vrtStr; 091 MultiDimensionDataSource datSrc; 092 093 TrackSelection(DataChoice dataChoice, FlatField track, 094 MultiDimensionDataSource datSrc) throws VisADException, RemoteException { 095 super("track"); 096 this.dataChoice = dataChoice; 097 this.track = track; 098 this.datSrc = datSrc; 099 mapProjDsp = new MapProjectionDisplayJ3D( 100 MapProjectionDisplay.MODE_2Din3D); 101 mapProjDsp.enableRubberBanding(false); 102 dspMaster = mapProjDsp; 103 mapProjDsp.setMapProjection(getDataProjection()); 104 LineDrawing trackDsp = new LineDrawing("track"); 105 trackDsp.setLineWidth(2f); 106 trackDsp.setData(track); 107 mapProjDsp.addDisplayable(trackDsp); 108 109 MapLines mapLines = new MapLines("maplines"); 110 URL mapSource = mapProjDsp.getClass().getResource( 111 "/auxdata/maps/OUTLSUPU"); 112 try { 113 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 114 mapLines.setMapLines(mapAdapter.getData()); 115 mapLines.setColor(java.awt.Color.cyan); 116 mapProjDsp.addDisplayable(mapLines); 117 } catch (Exception excp) { 118 logger.error("cannot open map file: " + mapSource, excp); 119 } 120 121 mapLines = new MapLines("maplines"); 122 mapSource = mapProjDsp.getClass().getResource("/auxdata/maps/OUTLSUPW"); 123 try { 124 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 125 mapLines.setMapLines(mapAdapter.getData()); 126 mapLines.setColor(java.awt.Color.cyan); 127 mapProjDsp.addDisplayable(mapLines); 128 } catch (Exception excp) { 129 logger.error("cannot open map file: " + mapSource, excp); 130 } 131 132 mapLines = new MapLines("maplines"); 133 mapSource = mapProjDsp.getClass().getResource("/auxdata/maps/OUTLHPOL"); 134 try { 135 BaseMapAdapter mapAdapter = new BaseMapAdapter(mapSource); 136 mapLines.setMapLines(mapAdapter.getData()); 137 mapLines.setColor(java.awt.Color.cyan); 138 mapProjDsp.addDisplayable(mapLines); 139 } catch (Exception excp) { 140 logger.error("cannot open map file: " + mapSource, excp); 141 } 142 143 final LineDrawing selectBox = new LineDrawing("select"); 144 selectBox.setColor(Color.green); 145 146 final RubberBandBox rbb = new RubberBandBox(RealType.Longitude, 147 RealType.Latitude, 1); 148 rbb.setColor(Color.green); 149 rbb.addAction(new CellImpl() { 150 public void doAction() throws VisADException, RemoteException { 151 Gridded2DSet set = rbb.getBounds(); 152 float[] low = set.getLow(); 153 float[] hi = set.getHi(); 154 x_coords[0] = low[0]; 155 x_coords[1] = hi[0]; 156 y_coords[0] = low[1]; 157 y_coords[1] = hi[1]; 158 159 SampledSet[] sets = new SampledSet[4]; 160 sets[0] = new Gridded2DSet( 161 RealTupleType.SpatialEarth2DTuple, 162 new float[][] { { low[0], hi[0] }, { low[1], low[1] } }, 163 2); 164 sets[1] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, 165 new float[][] { { hi[0], hi[0] }, { low[1], hi[1] } }, 166 2); 167 sets[2] = new Gridded2DSet(RealTupleType.SpatialEarth2DTuple, 168 new float[][] { { hi[0], low[0] }, { hi[1], hi[1] } }, 169 2); 170 sets[3] = new Gridded2DSet( 171 RealTupleType.SpatialEarth2DTuple, 172 new float[][] { { low[0], low[0] }, { hi[1], low[1] } }, 173 2); 174 UnionSet uset = new UnionSet(sets); 175 selectBox.setData(uset); 176 } 177 }); 178 dspMaster.addDisplayable(rbb); 179 dspMaster.addDisplayable(selectBox); 180 dspMaster.draw(); 181 } 182 183 public MapProjection getDataProjection() { 184 MapProjection mp = null; 185 try { 186 mp = new ProjectionCoordinateSystem(new LatLonProjection()); 187 } catch (Exception e) { 188 logger.error("error getting data projection", e); 189 } 190 return mp; 191 } 192 193 protected JComponent doMakeContents() { 194 try { 195 JPanel panel = new JPanel(new BorderLayout()); 196 panel.add("Center", dspMaster.getDisplayComponent()); 197 198 JPanel stridePanel = new JPanel(new FlowLayout()); 199 trkStr = new JTextField(Integer.toString(TrackSelection.DEFAULT_TRACK_STRIDE), 3); 200 vrtStr = new JTextField(Integer.toString(TrackSelection.DEFAULT_VERTICAL_STRIDE), 3); 201 trkStr.addActionListener(new ActionListener() { 202 public void actionPerformed(ActionEvent ae) { 203 setTrackStride(Integer.valueOf(trkStr.getText().trim())); 204 } 205 }); 206 vrtStr.addActionListener(new ActionListener() { 207 public void actionPerformed(ActionEvent ae) { 208 setVerticalStride(Integer.valueOf(vrtStr.getText().trim())); 209 } 210 }); 211 212 stridePanel.add(new JLabel("Track Stride: ")); 213 stridePanel.add(trkStr); 214 stridePanel.add(new JLabel("Vertical Stride: ")); 215 stridePanel.add(vrtStr); 216 panel.add("South", stridePanel); 217 218 return panel; 219 } catch (Exception e) { 220 logger.error("error creating contents", e); 221 } 222 return null; 223 } 224 225 public void setTrackStride(int stride) { 226 trackStride = stride; 227 } 228 229 public void setVerticalStride(int stride) { 230 verticalStride = stride; 231 } 232 233 /** 234 * Update Track Stride if input text box holds a positive integer. 235 * 236 * @return true if trackStride was updated 237 */ 238 239 public boolean setTrackStride() { 240 boolean setOk = false; 241 try { 242 int newStride = Integer.valueOf(trkStr.getText().trim()); 243 trackStride = newStride; 244 setOk = true; 245 } catch (NumberFormatException nfe) { 246 // do nothing, will return correct result code 247 } 248 return setOk; 249 } 250 251 /** 252 * Update Vertical Stride if input text box holds a positive integer. 253 * 254 * @return true if verticalStride was updated 255 */ 256 257 public boolean setVerticalStride() { 258 boolean setOk = false; 259 try { 260 int newStride = Integer.valueOf(vrtStr.getText().trim()); 261 verticalStride = newStride; 262 setOk = true; 263 } catch (NumberFormatException nfe) { 264 // do nothing, will return correct result code 265 } 266 return setOk; 267 } 268 269 public void applyToDataSelection(DataSelection dataSelection) { 270 setTrackStride(); 271 setVerticalStride(); 272 if (hasSubset) { 273 GeoSelection geoSelect = new GeoSelection(new GeoLocationInfo( 274 y_coords[1], x_coords[0], y_coords[0], x_coords[1])); 275 geoSelect.setXStride(trackStride); 276 geoSelect.setYStride(verticalStride); 277 dataSelection.setGeoSelection(geoSelect); 278 279 DataSelection datSel = new DataSelection(); 280 datSel.setGeoSelection(geoSelect); 281 datSrc.setDataSelection(datSel); 282 dataChoice.setDataSelection(dataSelection); 283 } 284 } 285}