package edu.oregonstate.cartography.gui;
import com.fizzysoft.sdu.RecentDocumentsManager;
import edu.oregonstate.cartography.app.FileUtils;
import edu.oregonstate.cartography.app.GeometryUtils;
import edu.oregonstate.cartography.geometryexport.ShapeExporter;
import edu.oregonstate.cartography.geometryimport.GeometryCollectionImporter;
import edu.oregonstate.cartography.geometryimport.ShapeImporter;
import edu.oregonstate.cartography.grid.ESRIASCIIGridExporter;
import edu.oregonstate.cartography.grid.EsriASCIIGridReader;
import edu.oregonstate.cartography.grid.Grid;
import edu.oregonstate.cartography.grid.Model;
import edu.oregonstate.cartography.grid.Model.ForegroundVisualization;
import edu.oregonstate.cartography.grid.WorldFileExporter;
import edu.oregonstate.cartography.grid.operators.IlluminatedContoursOperator;
import edu.oregonstate.cartography.grid.operators.NormalMapOperator;
import edu.oregonstate.cartography.grid.operators.NormalMapOperator.Channel;
import edu.oregonstate.cartography.grid.operators.PlanObliqueOperator;
import edu.oregonstate.cartography.simplefeatures.GeometryCollection;
import edu.oregonstate.cartography.simplefeatures.LineString;
import edu.oregonstate.cartography.simplefeatures.PlanObliqueShearing;
import edu.oregonstate.cartography.simplefeatures.Point;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
/**
* Shades a DEM generalizedGrid using weighted Laplacian Pyramids. Results are
* displayed in this JFrame with options for user input.
*
* @author Charles Preppernau and Bernie Jenny, Oregon State University
*/
public class MainWindow extends javax.swing.JFrame {
private static final String OPEN_ERROR_MESSAGE = "Could not open the terrain file.";
private static final String SAVE_IMAGE_ERROR_MESSAGE = "Could not save the image file.";
private static final String SAVE_TERRAIN_ERROR_MESSAGE = "Could not save the terrain file.";
private final Model model;
private SettingsDialog settingsDialog = null;
private RecentDocumentsManager rdm;
private final ProgressPanel progressPanel;
/**
* Constructor for the JFrame. Initializes components and sets up the
* default color gradient.
*
* @param model model object
*/
public MainWindow(Model model) {
this.model = model;
initRecentDocumentsMenu();
initComponents();
// hide menu with experimental features
menuBar.remove(experimentalMenu);
// get menu keyboard events from owned dialogs
DialogUtil.setupDialogActions(menuBar);
progressPanel = new ProgressPanel();
progressPanel.setOpaque(false);
setGlassPane(progressPanel);
progressPanel.setVisible(false);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
imageResolutionPanel = new javax.swing.JPanel();
javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
imageResolutionSpinner = new javax.swing.JSpinner();
scaleGridPanel = new javax.swing.JPanel();
javax.swing.JLabel jLabel8 = new javax.swing.JLabel();
scaleTerrainFormattedTextField = new javax.swing.JFormattedTextField();
javax.swing.JLabel jLabel9 = new javax.swing.JLabel();
offsetGridPanel = new javax.swing.JPanel();
javax.swing.JLabel jLabel10 = new javax.swing.JLabel();
offsetTerrainFormattedTextField = new javax.swing.JFormattedTextField();
javax.swing.JLabel jLabel11 = new javax.swing.JLabel();
voidGridPanel = new javax.swing.JPanel();
javax.swing.JLabel jLabel12 = new javax.swing.JLabel();
voidGridFormattedTextField = new javax.swing.JFormattedTextField();
javax.swing.JLabel jLabel13 = new javax.swing.JLabel();
navigableImagePanel = new edu.oregonstate.cartography.gui.NavigableImagePanel();
menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu fileMenu = new javax.swing.JMenu();
javax.swing.JMenuItem openMenuItem = new javax.swing.JMenuItem();
openRecentMenu = rdm.createOpenRecentMenu();
javax.swing.JPopupMenu.Separator jSeparator1 = new javax.swing.JPopupMenu.Separator();
saveGridMenuItem = new javax.swing.JMenuItem();
saveGeneralizedGridMenuItem = new javax.swing.JMenuItem();
saveLocalGridMenuItem = new javax.swing.JMenuItem();
saveDownsampledMenu = new javax.swing.JMenu();
javax.swing.JPopupMenu.Separator jSeparator5 = new javax.swing.JPopupMenu.Separator();
javax.swing.JMenu saveImageMenu = new javax.swing.JMenu();
saveTIFFImageMenuItem = new javax.swing.JMenuItem();
savePNGImageMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu saveContoursMenu = new javax.swing.JMenu();
saveTIFFContoursMenuItem = new javax.swing.JMenuItem();
savePNGContoursMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu saveContoursMenu1 = new javax.swing.JMenu();
saveTIFFNormalMapMenuItem = new javax.swing.JMenuItem();
savePNGNormalMapMenuItem = new javax.swing.JMenuItem();
editMenu = new javax.swing.JMenu();
scaleGridMenuItem = new javax.swing.JMenuItem();
offsetGridMenuItem = new javax.swing.JMenuItem();
voidGridMenuItem = new javax.swing.JMenuItem();
viewMenu = new javax.swing.JMenu();
viewResetMenuItem = new javax.swing.JMenuItem();
javax.swing.JPopupMenu.Separator jSeparator4 = new javax.swing.JPopupMenu.Separator();
viewZoomInMenuItem = new javax.swing.JMenuItem();
viewZoomOutMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu infoMenu = new javax.swing.JMenu();
settingsMenuItem = new javax.swing.JMenuItem();
javax.swing.JPopupMenu.Separator jSeparator3 = new javax.swing.JPopupMenu.Separator();
terrainInfoMenuItem = new javax.swing.JMenuItem();
javax.swing.JPopupMenu.Separator jSeparator2 = new javax.swing.JPopupMenu.Separator();
infoMenuItem = new javax.swing.JMenuItem();
experimentalMenu = new javax.swing.JMenu();
planObliqueFeaturesMenuItem = new javax.swing.JMenuItem();
savePlanObliqueMenuItem = new javax.swing.JMenuItem();
imageResolutionPanel.setLayout(new java.awt.GridBagLayout());
jLabel1.setText("Image resolution relative to terrain model size:");
imageResolutionPanel.add(jLabel1, new java.awt.GridBagConstraints());
imageResolutionSpinner.setModel(new javax.swing.SpinnerNumberModel(1, 1, 25, 1));
imageResolutionPanel.add(imageResolutionSpinner, new java.awt.GridBagConstraints());
scaleGridPanel.setLayout(new java.awt.GridBagLayout());
jLabel8.setText("Scale Factor:");
scaleGridPanel.add(jLabel8, new java.awt.GridBagConstraints());
scaleTerrainFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter()));
scaleTerrainFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28));
scaleTerrainFormattedTextField.setValue(new Float(1));
scaleGridPanel.add(scaleTerrainFormattedTextField, new java.awt.GridBagConstraints());
jLabel9.setFont(jLabel9.getFont().deriveFont(jLabel9.getFont().getSize()-2f));
jLabel9.setText("All values in the terrain grid are scaled by this factor.");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
scaleGridPanel.add(jLabel9, gridBagConstraints);
offsetGridPanel.setLayout(new java.awt.GridBagLayout());
jLabel10.setText("Value to Add:");
offsetGridPanel.add(jLabel10, new java.awt.GridBagConstraints());
offsetTerrainFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter()));
offsetTerrainFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28));
offsetTerrainFormattedTextField.setValue(new Float(1));
offsetGridPanel.add(offsetTerrainFormattedTextField, new java.awt.GridBagConstraints());
jLabel11.setFont(jLabel11.getFont().deriveFont(jLabel11.getFont().getSize()-2f));
jLabel11.setText("The value entered is added to all values in the terrain grid.");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
offsetGridPanel.add(jLabel11, gridBagConstraints);
voidGridPanel.setLayout(new java.awt.GridBagLayout());
jLabel12.setText("Mark this value as void:");
voidGridPanel.add(jLabel12, new java.awt.GridBagConstraints());
voidGridFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter()));
voidGridFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28));
voidGridFormattedTextField.setValue(new Float(0));
voidGridPanel.add(voidGridFormattedTextField, new java.awt.GridBagConstraints());
jLabel13.setFont(jLabel13.getFont().deriveFont(jLabel13.getFont().getSize()-2f));
jLabel13.setText("All values in the grid with the selected value will be set to the void value.");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
voidGridPanel.add(jLabel13, gridBagConstraints);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Pyramid Shader");
setMinimumSize(new java.awt.Dimension(700, 700));
navigableImagePanel.setNavigationImageEnabled(false);
getContentPane().add(navigableImagePanel, java.awt.BorderLayout.CENTER);
fileMenu.setText("File");
fileMenu.addMenuListener(new javax.swing.event.MenuListener() {
public void menuSelected(javax.swing.event.MenuEvent evt) {
fileMenuMenuSelected(evt);
}
public void menuDeselected(javax.swing.event.MenuEvent evt) {
}
public void menuCanceled(javax.swing.event.MenuEvent evt) {
}
});
openMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
openMenuItem.setText("Open Grid…");
openMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
openMenuItemActionPerformed(evt);
}
});
fileMenu.add(openMenuItem);
openRecentMenu.setText("Open Recent");
fileMenu.add(openRecentMenu);
fileMenu.add(jSeparator1);
saveGridMenuItem.setText("Save Grid…");
saveGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveGridMenuItemActionPerformed(evt);
}
});
fileMenu.add(saveGridMenuItem);
saveGeneralizedGridMenuItem.setText("Save Generalized Grid…");
saveGeneralizedGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveGeneralizedGridMenuItemActionPerformed(evt);
}
});
fileMenu.add(saveGeneralizedGridMenuItem);
saveLocalGridMenuItem.setText("Save Locally Filtered Grid…");
saveLocalGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveLocalGridMenuItemActionPerformed(evt);
}
});
fileMenu.add(saveLocalGridMenuItem);
saveDownsampledMenu.setText("Save Downsampled Grid");
saveDownsampledMenu.addMenuListener(new javax.swing.event.MenuListener() {
public void menuSelected(javax.swing.event.MenuEvent evt) {
saveDownsampledMenuMenuSelected(evt);
}
public void menuDeselected(javax.swing.event.MenuEvent evt) {
}
public void menuCanceled(javax.swing.event.MenuEvent evt) {
}
});
fileMenu.add(saveDownsampledMenu);
fileMenu.add(jSeparator5);
saveImageMenu.setText("Save Image");
saveTIFFImageMenuItem.setText("TIFF");
saveTIFFImageMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveTIFFImageMenuItemActionPerformed(evt);
}
});
saveImageMenu.add(saveTIFFImageMenuItem);
savePNGImageMenuItem.setText("PNG");
savePNGImageMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
savePNGImageMenuItemActionPerformed(evt);
}
});
saveImageMenu.add(savePNGImageMenuItem);
fileMenu.add(saveImageMenu);
saveContoursMenu.setText("Save Contour Image");
saveTIFFContoursMenuItem.setText("TIFF");
saveTIFFContoursMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveTIFFContoursMenuItemActionPerformed(evt);
}
});
saveContoursMenu.add(saveTIFFContoursMenuItem);
savePNGContoursMenuItem.setText("PNG");
savePNGContoursMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
savePNGContoursMenuItemActionPerformed(evt);
}
});
saveContoursMenu.add(savePNGContoursMenuItem);
fileMenu.add(saveContoursMenu);
saveContoursMenu1.setText("Save Normal Map");
saveTIFFNormalMapMenuItem.setText("TIFF");
saveTIFFNormalMapMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
saveTIFFNormalMapMenuItemActionPerformed(evt);
}
});
saveContoursMenu1.add(saveTIFFNormalMapMenuItem);
savePNGNormalMapMenuItem.setText("PNG");
savePNGNormalMapMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
savePNGNormalMapMenuItemActionPerformed(evt);
}
});
saveContoursMenu1.add(savePNGNormalMapMenuItem);
fileMenu.add(saveContoursMenu1);
menuBar.add(fileMenu);
editMenu.setText("Edit");
editMenu.addMenuListener(new javax.swing.event.MenuListener() {
public void menuSelected(javax.swing.event.MenuEvent evt) {
editMenuMenuSelected(evt);
}
public void menuDeselected(javax.swing.event.MenuEvent evt) {
}
public void menuCanceled(javax.swing.event.MenuEvent evt) {
}
});
scaleGridMenuItem.setText("Scale Grid Values…");
scaleGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
scaleGridMenuItemActionPerformed(evt);
}
});
editMenu.add(scaleGridMenuItem);
offsetGridMenuItem.setText("Offset Grid Values…");
offsetGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
offsetGridMenuItemActionPerformed(evt);
}
});
editMenu.add(offsetGridMenuItem);
voidGridMenuItem.setText("Void Grid Values…");
voidGridMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
voidGridMenuItemActionPerformed(evt);
}
});
editMenu.add(voidGridMenuItem);
menuBar.add(editMenu);
viewMenu.setText("View");
viewMenu.addMenuListener(new javax.swing.event.MenuListener() {
public void menuSelected(javax.swing.event.MenuEvent evt) {
viewMenuMenuSelected(evt);
}
public void menuDeselected(javax.swing.event.MenuEvent evt) {
}
public void menuCanceled(javax.swing.event.MenuEvent evt) {
}
});
viewResetMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_0, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
viewResetMenuItem.setText("Reset View");
viewResetMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
viewResetMenuItemActionPerformed(evt);
}
});
viewMenu.add(viewResetMenuItem);
viewMenu.add(jSeparator4);
viewZoomInMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PLUS, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
viewZoomInMenuItem.setText("Zoom In");
viewZoomInMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
viewZoomInMenuItemActionPerformed(evt);
}
});
viewMenu.add(viewZoomInMenuItem);
viewZoomOutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
viewZoomOutMenuItem.setText("Zoom Out");
viewZoomOutMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
viewZoomOutMenuItemActionPerformed(evt);
}
});
viewMenu.add(viewZoomOutMenuItem);
menuBar.add(viewMenu);
infoMenu.setText("Window");
infoMenu.addMenuListener(new javax.swing.event.MenuListener() {
public void menuSelected(javax.swing.event.MenuEvent evt) {
infoMenuMenuSelected(evt);
}
public void menuDeselected(javax.swing.event.MenuEvent evt) {
}
public void menuCanceled(javax.swing.event.MenuEvent evt) {
}
});
settingsMenuItem.setText("Show Settings");
settingsMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
settingsMenuItemActionPerformed(evt);
}
});
infoMenu.add(settingsMenuItem);
infoMenu.add(jSeparator3);
terrainInfoMenuItem.setText("Grid Info");
terrainInfoMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
terrainInfoMenuItemActionPerformed(evt);
}
});
infoMenu.add(terrainInfoMenuItem);
infoMenu.add(jSeparator2);
infoMenuItem.setText("Info");
infoMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
infoMenuItemActionPerformed(evt);
}
});
infoMenu.add(infoMenuItem);
menuBar.add(infoMenu);
experimentalMenu.setText("Experimental");
planObliqueFeaturesMenuItem.setText("Plan Oblique Lines…");
planObliqueFeaturesMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
planObliqueFeaturesMenuItemActionPerformed(evt);
}
});
experimentalMenu.add(planObliqueFeaturesMenuItem);
savePlanObliqueMenuItem.setText("Save Plan Oblique… ");
savePlanObliqueMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
savePlanObliqueMenuItemActionPerformed(evt);
}
});
experimentalMenu.add(savePlanObliqueMenuItem);
menuBar.add(experimentalMenu);
setJMenuBar(menuBar);
pack();
}// </editor-fold>//GEN-END:initComponents
private void initRecentDocumentsMenu() {
final String APPNAME = "PyramidShader";
rdm = new RecentDocumentsManager() {
private Preferences getPreferences() {
return Preferences.userNodeForPackage(MainWindow.class);
}
@Override
protected byte[] readRecentDocs() {
return getPreferences().getByteArray("RecentDocuments" + APPNAME, null);
}
@Override
protected void writeRecentDocs(byte[] data) {
getPreferences().putByteArray("RecentDocuments" + APPNAME, data);
}
@Override
protected void openFile(File file, ActionEvent event) {
if (file != null) {
try {
openGrid(file.getCanonicalPath());
} catch (IOException ex) {
ErrorDialog.showErrorDialog(OPEN_ERROR_MESSAGE, "Error", ex, null);
}
}
}
@Override
protected Icon getFileIcon(File file) {
return null;
}
};
}
// A SwingWorker for rendering the background image to a file.
class FileRenderer extends SwingWorkerWithProgressIndicatorDialog<Void> {
private final BufferedImage backgroundImage;
private final String filePath;
private final String fileFormat;
protected FileRenderer(BufferedImage backgroundImage, String filePath,
String fileFormat, Frame owner) {
super(owner, "", "", true);
this.backgroundImage = backgroundImage;
this.filePath = filePath;
this.fileFormat = fileFormat;
this.setIndeterminate(false);
this.setCancellable(false);
}
@Override
public Void doInBackground() {
if (model.getGeneralizedGrid() != null) {
// initialize the progress dialog
start();
model.renderBackgroundImage(backgroundImage, this);
}
return null;
}
@Override
protected void done() {
try {
if (!isCancelled()) {
get();
this.setIndeterminate(true);
ImageIO.write(backgroundImage, fileFormat, new File(filePath));
// create world file for image file
String worldFilePath = WorldFileExporter.constructPath(filePath);
Grid dem = model.getGeneralizedGrid();
double cellSize = dem.getCellSize();
// for each grid value, one image cell is contructed. The extent
// of the image is therefore one pixel larger horizontally and
// vertically.
double west = dem.getWest() - cellSize / 2;
double north = dem.getNorth() + cellSize / 2;
WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north);
}
} catch (Exception ignore) {
} finally {
completeProgress();
}
}
}
private void saveImage(String format, String message) {
String filePath = askFile(message, false); // file selection dialog
// make sure the choice is a valid file
if (filePath != null) {
filePath = FileUtils.forceFileNameExtension(filePath, format);
// render to image with the same size as the input grid
// instead of using navigableImagePanel.getImage(), which can
// have a different size
BufferedImage img = model.createDestinationImage(1);
new FileRenderer(img, filePath, format, this).execute();
}
}
private void saveTIFFImageMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFImageMenuItemActionPerformed
saveImage("tif", "Save TIFF Image");
}//GEN-LAST:event_saveTIFFImageMenuItemActionPerformed
private void saveGeneralizedGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveGeneralizedGridMenuItemActionPerformed
saveTerrain(model.getGeneralizedGrid());
}//GEN-LAST:event_saveGeneralizedGridMenuItemActionPerformed
private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMenuItemActionPerformed
openGrid();
}//GEN-LAST:event_openMenuItemActionPerformed
private void infoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_infoMenuItemActionPerformed
ProgramInfoPanel.showApplicationInfo(this);
}//GEN-LAST:event_infoMenuItemActionPerformed
private void terrainInfoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_terrainInfoMenuItemActionPerformed
StringBuilder sb = new StringBuilder();
sb.append("<html> <b>");
sb.append(getTitle());
sb.append("</b><br>");
sb.append(model.getGrid().getDescriptionWithStatistics("<br>"));
String title = "Terrain Model Info";
JOptionPane.showMessageDialog(this, sb.toString(), title, JOptionPane.PLAIN_MESSAGE);
}//GEN-LAST:event_terrainInfoMenuItemActionPerformed
private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_settingsMenuItemActionPerformed
settingsDialog.setVisible(!settingsDialog.isVisible());
}//GEN-LAST:event_settingsMenuItemActionPerformed
private void infoMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_infoMenuMenuSelected
boolean gridLoaded = (model.getGrid() != null);
terrainInfoMenuItem.setEnabled(gridLoaded);
boolean settingsVisible = settingsDialog.isVisible();
settingsMenuItem.setText(settingsVisible ? "Hide Settings" : "Show Settings");
}//GEN-LAST:event_infoMenuMenuSelected
private void viewResetMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewResetMenuItemActionPerformed
navigableImagePanel.setZoom(0);
}//GEN-LAST:event_viewResetMenuItemActionPerformed
private void viewZoomInMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewZoomInMenuItemActionPerformed
navigableImagePanel.setZoom(navigableImagePanel.getZoom() + navigableImagePanel.getZoomIncrement());
}//GEN-LAST:event_viewZoomInMenuItemActionPerformed
private void viewZoomOutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewZoomOutMenuItemActionPerformed
navigableImagePanel.setZoom(navigableImagePanel.getZoom() - navigableImagePanel.getZoomIncrement());
}//GEN-LAST:event_viewZoomOutMenuItemActionPerformed
private void savePNGImageMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGImageMenuItemActionPerformed
saveImage("png", "Save PNG Image");
}//GEN-LAST:event_savePNGImageMenuItemActionPerformed
/**
* Render an image and write it to a file, while a progress dialog with a
* cancel button is displayed.
*
* @param filePath file to write to.
* @param scale The final image will be this many times larger than the
* terrain model.
*/
private void exportContours(final String filePath, final String imageFormat, final int scale) {
String dialogTitle = "Contours Export";
SwingWorkerWithProgressIndicatorDialog worker;
worker = new SwingWorkerWithProgressIndicatorDialog<Void>(this, dialogTitle, "", true) {
@Override
public void done() {
try {
// a call to get() will throw an ExecutionException if an
// exception occured in doInBackground
get();
// create world file for image file
String worldFilePath = WorldFileExporter.constructPath(filePath);
Grid dem = model.getGeneralizedGrid();
double cellSize = dem.getCellSize() / scale;
double west = dem.getWest() - cellSize / 2;
double north = dem.getNorth() + cellSize / 2;
WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north);
} catch (ExecutionException e) {
// an exception was thrown in doInBackground
new File(filePath).delete();
String msg = "An error occured when exporting the image.";
String title = "Export Error";
JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.ERROR_MESSAGE);
} catch (InterruptedException | CancellationException e) {
} catch (IOException exc) {
new File(filePath).delete();
} finally {
// hide the progress dialog
completeProgress();
}
}
@Override
protected Void doInBackground() throws Exception {
// initialize the progress dialog
start();
// compute the image with illuminated contours
IlluminatedContoursOperator op;
boolean illuminated = (model.foregroundVisualization == ForegroundVisualization.ILLUMINATED_CONTOURS);
op = model.setupIlluminatedContoursOperator(illuminated);
int w = model.getGeneralizedGrid().getCols() * scale;
int h = model.getGeneralizedGrid().getRows() * scale;
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
op.renderToImage(image, model.getGeneralizedGrid(),
model.getGeneralizedSlopeGrid(), this);
if (!isCancelled()) {
// writing to file cannot be canceled
setCancellable(false);
setIndeterminate(true);
File file = new File(filePath);
setMessage("Writing image to \"" + file.getName() + "\"");
ImageIO.write(image, imageFormat, file);
}
return null;
}
};
worker.setMaxTimeWithoutDialogMilliseconds(500);
worker.setIndeterminate(false);
worker.setMessage("Computing contours image");
worker.execute();
}
private void saveContours(String askFileMessage, String imageFormat) {
String PREFS_NAME = "contours_scale";
String filePath = askFile(askFileMessage, false);
if (filePath != null) {
filePath = FileUtils.forceFileNameExtension(filePath, imageFormat);
String title = "Image Resolution";
Preferences prefs = Preferences.userNodeForPackage(MainWindow.class);
imageResolutionSpinner.setValue(prefs.getInt(PREFS_NAME, 5));
int res = JOptionPane.showOptionDialog(getContentPane(), imageResolutionPanel, title,
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
if (res == JOptionPane.OK_OPTION) {
int scale = (Integer) (imageResolutionSpinner.getValue());
exportContours(filePath, imageFormat, scale);
prefs.putInt(PREFS_NAME, scale);
}
}
}
private void saveTIFFContoursMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFContoursMenuItemActionPerformed
saveContours("Save TIFF Contour Image", "tif");
}//GEN-LAST:event_saveTIFFContoursMenuItemActionPerformed
private void savePNGContoursMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGContoursMenuItemActionPerformed
saveContours("Save PNG Contour Image", "png");
}//GEN-LAST:event_savePNGContoursMenuItemActionPerformed
private void fileMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_fileMenuMenuSelected
boolean gridLoaded = (model.getGrid() != null);
boolean contoursVisible
= model.foregroundVisualization != Model.ForegroundVisualization.NONE;
saveGridMenuItem.setEnabled(gridLoaded);
saveGeneralizedGridMenuItem.setEnabled(gridLoaded);
saveLocalGridMenuItem.setEnabled(model.backgroundVisualization.isLocal());
saveDownsampledMenu.setEnabled(gridLoaded);
saveTIFFImageMenuItem.setEnabled(gridLoaded);
savePNGImageMenuItem.setEnabled(gridLoaded);
saveTIFFContoursMenuItem.setEnabled(contoursVisible);
savePNGContoursMenuItem.setEnabled(contoursVisible);
saveTIFFNormalMapMenuItem.setEnabled(gridLoaded);
savePNGNormalMapMenuItem.setEnabled(gridLoaded);
}//GEN-LAST:event_fileMenuMenuSelected
private void viewMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_viewMenuMenuSelected
boolean gridLoaded = (model.getGrid() != null);
viewResetMenuItem.setEnabled(gridLoaded);
viewZoomInMenuItem.setEnabled(gridLoaded);
viewZoomOutMenuItem.setEnabled(gridLoaded);
}//GEN-LAST:event_viewMenuMenuSelected
private void saveLocalGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveLocalGridMenuItemActionPerformed
saveTerrain(model.getLocalGrid());
}//GEN-LAST:event_saveLocalGridMenuItemActionPerformed
private void scaleGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_scaleGridMenuItemActionPerformed
int option = JOptionPane.showOptionDialog(this,
scaleGridPanel,
"Scale Terrain",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (option != JOptionPane.OK_OPTION) {
return;
}
try {
scaleTerrainFormattedTextField.commitEdit();
java.lang.Number f = (java.lang.Number) (scaleTerrainFormattedTextField.getValue());
float scale = f.floatValue();
model.scaleGrid(scale);
settingsDialog.modelChanged();
} catch (Exception exc) {
ErrorDialog.showErrorDialog("An error occured while scaling the terrain.",
"Error", exc, this);
}
}//GEN-LAST:event_scaleGridMenuItemActionPerformed
private void offsetGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_offsetGridMenuItemActionPerformed
int option = JOptionPane.showOptionDialog(this,
offsetGridPanel,
"Vertically Offset Terrain",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (option != JOptionPane.OK_OPTION) {
return;
}
try {
offsetTerrainFormattedTextField.commitEdit();
java.lang.Number f = (java.lang.Number) (offsetTerrainFormattedTextField.getValue());
float offset = f.floatValue();
model.verticallyOffsetGrid(offset);
settingsDialog.modelChanged();
} catch (Exception exc) {
ErrorDialog.showErrorDialog("An error occured while changing the terrain.",
"Error", exc, this);
}
}//GEN-LAST:event_offsetGridMenuItemActionPerformed
private void editMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_editMenuMenuSelected
boolean gridLoaded = (model.getGrid() != null);
scaleGridMenuItem.setEnabled(gridLoaded);
offsetGridMenuItem.setEnabled(gridLoaded);
voidGridMenuItem.setEnabled(gridLoaded);
}//GEN-LAST:event_editMenuMenuSelected
/**
* Draw a set of lines into an image
*
* @param img
* @param lines
* @param grid
*/
private static void drawLines(BufferedImage img, GeometryCollection lines, Grid grid) {
int imageHeight = img.getHeight();
Graphics2D g2 = (Graphics2D) img.getGraphics();
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(rh);
g2.setStroke(new BasicStroke(3));
g2.setColor(Color.BLACK);
double dx = grid.getWest();
double sx = img.getWidth() / (grid.getEast() - grid.getWest());
double dy = grid.getSouth();
double sy = img.getHeight() / (grid.getNorth() - grid.getSouth());
int nLines = lines.getNumGeometries();
for (int lineID = 0; lineID < nLines; lineID++) {
LineString line = (LineString) lines.getGeometryN(lineID);
int nPoints = line.getNumPoints();
GeneralPath path = new GeneralPath();
Point pt = line.getFirstPoint();
double x = (pt.getX() - dx) * sx;
double y = (pt.getY() - dy) * sy;
path.moveTo(x, imageHeight - y);
for (int pointID = 1; pointID < nPoints; pointID++) {
pt = line.getPointN(pointID);
x = (pt.getX() - dx) * sx;
y = (pt.getY() - dy) * sy;
path.lineTo(x, imageHeight - y);
}
g2.draw(path);
}
g2.dispose();
}
private void planObliqueFeaturesMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_planObliqueFeaturesMenuItemActionPerformed
try {
// erase previously drawn lines
navigableImagePanel.repaint();
if (model.planObliqueAngle == 90) {
String msg = "Please first adjust the plan oblique relief angle.";
String title = "Plan Oblique Lines";
JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.WARNING_MESSAGE);
return;
}
// ask the user for a file to read
String filePath = askFile("Select a Line Shapefile", true);
if (filePath == null) {
// user canceled
return;
}
GeometryCollectionImporter importer = new ShapeImporter();
GeometryCollection vectors = importer.importData(filePath);
// test whether the vector geometry intersects with the grid
Rectangle2D vectorsBB = vectors.getBoundingBox();
Rectangle2D gridBB = model.getGeneralizedGrid().getBoundingBox();
if (GeometryUtils.rectanglesIntersect(gridBB, vectorsBB) == false) {
String msg = "<html>The shapefile geometry does not align with "
+ "the terrain model.<br>It is likely that the shapefile "
+ "and the grid use different coordinate systems.";
String title = "Data Misalignment";
JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.ERROR_MESSAGE);
return;
}
// ask the user whether occluded line segments are to be clipped
String[] options = new String[]{"Clip", "Do Not Clip", "Cancel"};
String title = "Occlusion Clipping";
String msg = "Clip occluded line segments?";
int lineClipping = JOptionPane.showOptionDialog(getContentPane(), msg, title,
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if (lineClipping == 2) {
// user canceled
return;
}
// apply shearing
PlanObliqueShearing shearingOp = new PlanObliqueShearing(
model.planObliqueAngle,
model.getGeneralizedGrid(),
model.getGeneralizedGrid().getMinMax()[0],
lineClipping == 0);
GeometryCollection shearedLines = shearingOp.shear(vectors);
BufferedImage img = navigableImagePanel.getImage();
drawLines(img, shearedLines, model.getGeneralizedGrid());
navigableImagePanel.repaint();
// ask the user for a file to save
filePath = askFile("Save Plan Oblique Lines", false);
if (filePath == null) {
// user canceled
return;
}
filePath = FileUtils.forceFileNameExtension(filePath, "shp");
ShapeExporter geometryExporter = new ShapeExporter();
geometryExporter.export(shearedLines, filePath);
geometryExporter.exportTableForGeometry(filePath, shearedLines, "");
} catch (IOException ex) {
Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
}
}//GEN-LAST:event_planObliqueFeaturesMenuItemActionPerformed
private void saveDownsampledMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_saveDownsampledMenuMenuSelected
saveDownsampledMenu.removeAll();
if (model == null || model.laplacianPyramid == null) {
return;
}
Grid[] levels = model.laplacianPyramid.getLevels();
for (int i = 0; i < levels.length; i++) {
String str = levels[i].getCols() + "\u00D7" + levels[i].getRows();
if (i == 0) {
str += " (Full Resolution)";
}
JMenuItem menuItem = new JMenuItem(str);
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// weights for Laplacian pyramid levels
float[] w = model.laplacianPyramid.createConstantWeights(1f);
for (int j = 0; j < saveDownsampledMenu.getMenuComponentCount(); j++) {
Component comp = saveDownsampledMenu.getMenuComponent(j);
if (comp == e.getSource()) {
Arrays.fill(w, 0, j, 0f);
break;
}
}
saveTerrain(model.laplacianPyramid.sumLevels(w, false));
}
});
saveDownsampledMenu.add(menuItem);
}
}//GEN-LAST:event_saveDownsampledMenuMenuSelected
private void saveNormalMap(String format) {
String filePath = askFile("Normal Map", false);
if (filePath != null) {
filePath = FileUtils.forceFileNameExtension(filePath, format);
try {
BufferedImage img = model.createDestinationImage(1);
NormalMapOperator op = new NormalMapOperator(Channel.R, Channel.G, Channel.B,
false, false, false, 1f);
op.operate(model.getGeneralizedGrid(), img, model.shadingVerticalExaggeration);
ImageIO.write(img, format, new File(filePath));
// create world file for image file
String worldFilePath = WorldFileExporter.constructPath(filePath);
Grid dem = model.getGeneralizedGrid();
double cellSize = dem.getCellSize();
// for each grid value, one image cell is contructed. The extent
// of the image is therefore one pixel larger horizontally and
// vertically.
double west = dem.getWest() - cellSize / 2;
double north = dem.getNorth() + cellSize / 2;
WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north);
} catch (IOException ex) {
ErrorDialog.showErrorDialog(SAVE_IMAGE_ERROR_MESSAGE, "Error", ex, this);
}
}
}
private void saveTIFFNormalMapMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFNormalMapMenuItemActionPerformed
saveNormalMap("tif");
}//GEN-LAST:event_saveTIFFNormalMapMenuItemActionPerformed
private void savePNGNormalMapMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGNormalMapMenuItemActionPerformed
saveNormalMap("png");
}//GEN-LAST:event_savePNGNormalMapMenuItemActionPerformed
private void voidGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_voidGridMenuItemActionPerformed
int option = JOptionPane.showOptionDialog(this,
voidGridPanel,
"Void Values",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (option != JOptionPane.OK_OPTION) {
return;
}
try {
voidGridFormattedTextField.commitEdit();
java.lang.Number f = (java.lang.Number) (voidGridFormattedTextField.getValue());
model.voidGridValue(f.floatValue());
settingsDialog.modelChanged();
} catch (Exception exc) {
ErrorDialog.showErrorDialog("An error occured while changing the terrain.",
"Error", exc, this);
}
}//GEN-LAST:event_voidGridMenuItemActionPerformed
private void saveGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveGridMenuItemActionPerformed
saveTerrain(model.getGrid());
}//GEN-LAST:event_saveGridMenuItemActionPerformed
private void savePlanObliqueMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePlanObliqueMenuItemActionPerformed
Grid grid = model.getGrid();
if (model.planObliqueAngle != 90) {
float min = grid.getMinMax()[0];
PlanObliqueOperator planObliqueOp = new PlanObliqueOperator(model.planObliqueAngle, min);
grid = planObliqueOp.operate(grid);
}
saveTerrain(grid);
}//GEN-LAST:event_savePlanObliqueMenuItemActionPerformed
/**
* Ask the user for a file to read or write.
*
* @param frame A Frame for which to display the dialog.
* @param message A message that will be displayed in the dialog.
* @param load Pass true if an existing file for reading should be selected.
* Pass false if a new file for writing should be specified.
* @return A path to the file, including the file name.
*/
private String askFile(String message, boolean load) {
int flag = load ? java.awt.FileDialog.LOAD : java.awt.FileDialog.SAVE;
// display the dialog
java.awt.FileDialog fd = new java.awt.FileDialog(this, message, flag);
fd.setVisible(true);
// construct the path to the file that the user selected.
String fileName = fd.getFile();
String directory = fd.getDirectory();
if (fileName == null || directory == null) {
return null;
}
return directory + fileName;
}
public void initDisplayImage() {
// compute a scale factor for the display image
// this makes sure contour lines for small grids do not
// appear overly pixelated
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int screenWidth = gd.getDisplayMode().getWidth();
int screenHeight = gd.getDisplayMode().getHeight();
int imageScaleFactor = 1;
Dimension dim = model.getGridDimensionForDisplay();
double heightRatio = (double) screenHeight / dim.getHeight();
double widthRatio = (double) screenWidth / dim.getWidth();
double maxRatio = Math.max(heightRatio, widthRatio);
if (maxRatio > 1) {
imageScaleFactor = (int) Math.ceil(maxRatio);
}
// initialize the display image
BufferedImage image = model.createDestinationImage(imageScaleFactor);
navigableImagePanel.setImage(image);
}
/**
* Open a grid file and initialize the data model.
*
* @param filePath The file to open
* @throws IOException
*/
private void openGrid(final String filePath) throws IOException {
SwingWorkerWithProgressIndicatorDialog worker;
String dialogTitle = "Pyramid Shader";
worker = new SwingWorkerWithProgressIndicatorDialog<Void>(this, dialogTitle, "", true) {
@Override
public void done() {
try {
// a call to get() will throw an ExecutionException if an
// exception occured in doInBackground
get();
// hide the progress dialog before rendering the image
// if rendering throws an error, the progress dialog should
// have been closed
completeProgress();
// set window title to file name
setTitle(filePath.substring(filePath.lastIndexOf(File.separator) + 1));
// add document to Open Recent menu
rdm.addDocument(new File(filePath), null);
} catch (InterruptedException | CancellationException e) {
return;
} catch (Throwable e) {
// hide the progress dialog
completeProgress();
// an exception was thrown in doInBackground
String msg = "<html>An error occured when importing the terrain model."
+ "<br>The file must be in Esri ASCII Grid format.</html>";
ErrorDialog.showErrorDialog(msg, "Error", null, getContentPane());
return;
} finally {
// hide the progress dialog
completeProgress();
}
try {
initDisplayImage();
// this will render the image
settingsDialog.modelChanged();
// display warning when value range in grid is so low that
// shading does not show any variation
float[] minMax = model.getGrid().getMinMax();
float range = minMax[1] - minMax[0];
if (range < model.getGrid().getCellSize() * 2) {
String msg = "<html>"
+ "This grid is rather flat and the shading may "
+ "not show any variation."
+ "<br>Use <i>Edit > " + scaleGridMenuItem.getText()
+ "</i> to vertically exaggerate the grid."
+ "</html>";
JOptionPane.showMessageDialog(getContentPane(), msg,
"Pyramid Shader", JOptionPane.WARNING_MESSAGE);
}
} catch (Throwable e) {
BufferedImage img = navigableImagePanel.getImage();
if (img != null) {
Graphics g = img.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
g.dispose();
}
String msg = "An error occured when rendering the terrain.";
ErrorDialog.showErrorDialog(msg, "Error", e, getContentPane());
assert false : e.getStackTrace();
}
}
@Override
protected Void doInBackground() throws Exception {
start();
//import the DEM and create pyramids
Grid grid = EsriASCIIGridReader.read(filePath, this);
this.setIndeterminate(true);
this.setCancellable(false);
model.setGrid(grid);
return null;
}
};
worker.setMaxTimeWithoutDialogMilliseconds(2000);
worker.setIndeterminate(false);
worker.setMessage("Importing Terrain Model");
worker.execute();
}
/**
* Ask user for grid file, open the file, and initialized data model.
*/
public void openGrid() {
try {
// ask the user for a file
String filePath = askFile("Select an Esri ASCII Grid", true);
if (filePath != null) {
openGrid(filePath);
}
} catch (IOException ex) {
ErrorDialog.showErrorDialog(OPEN_ERROR_MESSAGE, "Error", ex, this);
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenu editMenu;
private javax.swing.JMenu experimentalMenu;
private javax.swing.JPanel imageResolutionPanel;
private javax.swing.JSpinner imageResolutionSpinner;
private javax.swing.JMenuItem infoMenuItem;
private javax.swing.JMenuBar menuBar;
private edu.oregonstate.cartography.gui.NavigableImagePanel navigableImagePanel;
private javax.swing.JMenuItem offsetGridMenuItem;
private javax.swing.JPanel offsetGridPanel;
private javax.swing.JFormattedTextField offsetTerrainFormattedTextField;
private javax.swing.JMenu openRecentMenu;
private javax.swing.JMenuItem planObliqueFeaturesMenuItem;
private javax.swing.JMenu saveDownsampledMenu;
private javax.swing.JMenuItem saveGeneralizedGridMenuItem;
private javax.swing.JMenuItem saveGridMenuItem;
private javax.swing.JMenuItem saveLocalGridMenuItem;
private javax.swing.JMenuItem savePNGContoursMenuItem;
private javax.swing.JMenuItem savePNGImageMenuItem;
private javax.swing.JMenuItem savePNGNormalMapMenuItem;
private javax.swing.JMenuItem savePlanObliqueMenuItem;
private javax.swing.JMenuItem saveTIFFContoursMenuItem;
private javax.swing.JMenuItem saveTIFFImageMenuItem;
private javax.swing.JMenuItem saveTIFFNormalMapMenuItem;
private javax.swing.JMenuItem scaleGridMenuItem;
private javax.swing.JPanel scaleGridPanel;
private javax.swing.JFormattedTextField scaleTerrainFormattedTextField;
private javax.swing.JMenuItem settingsMenuItem;
private javax.swing.JMenuItem terrainInfoMenuItem;
private javax.swing.JMenu viewMenu;
private javax.swing.JMenuItem viewResetMenuItem;
private javax.swing.JMenuItem viewZoomInMenuItem;
private javax.swing.JMenuItem viewZoomOutMenuItem;
private javax.swing.JFormattedTextField voidGridFormattedTextField;
private javax.swing.JMenuItem voidGridMenuItem;
private javax.swing.JPanel voidGridPanel;
// End of variables declaration//GEN-END:variables
/**
* @return the model
*/
public Model getModel() {
return model;
}
public void repaintImage() {
navigableImagePanel.repaint();
}
public BufferedImage getImage() {
return navigableImagePanel.getImage();
}
void setPreferredImageSize(Dimension dimension) {
navigableImagePanel.setPreferredSize(dimension);
}
/**
* @param settingsDialog the settingsDialog to set
*/
public void setSettingsDialog(SettingsDialog settingsDialog) {
this.settingsDialog = settingsDialog;
navigableImagePanel.addPropertyChangeListener(settingsDialog);
}
private void saveTerrain(Grid grid) {
//call up a save file dialog
String filePath = askFile("Save Terrain File", false);
if (filePath != null) {
filePath = FileUtils.forceFileNameExtension(filePath, "asc");
try {
ESRIASCIIGridExporter.export(grid, filePath);
} catch (IOException ex) {
ErrorDialog.showErrorDialog(SAVE_TERRAIN_ERROR_MESSAGE, "Error", ex, this);
}
}
}
public ProgressPanel getProgressPanel() {
return progressPanel;
}
}