Package com.bbn.openmap.dataAccess.shape

Source Code of com.bbn.openmap.dataAccess.shape.EsriShapeExport$ESEInterface

/*
*  File: EsriShapeExport.java
*  OptiMetrics, Inc.
*  2107 Laurel Bush Road - Suite 209
*  Bel Air, MD 21015
*  (410)569 - 6081
*/
package com.bbn.openmap.dataAccess.shape;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.MalformedURLException;
import java.util.*;
import javax.swing.*;

import com.bbn.openmap.omGraphics.*;
import com.bbn.openmap.dataAccess.shape.output.*;
import com.bbn.openmap.proj.Projection;
import com.bbn.openmap.util.ArgParser;
import com.bbn.openmap.util.ColorFactory;
import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.FileUtils;
import com.bbn.openmap.util.PropUtils;

/**
* Provides methods for saving OMGraphicLists as ShapeFiles. This code was
* originally submitted by Karl Stuempfle of OptiMetrics, and I modified it a
* little to add a user interface to modify the DBF files if the user wants to.
* <P>
*
* Since Shape files can only hold one type of graphic, this class will create
* one to three different lists as needed, for points, lines and polygons.
* <P>
*
* If the OMGraphicList's AppObject holds a DbfTableModel, it will be used for
* the shape file database file.
*/
public class EsriShapeExport implements ShapeConstants, OMGraphicConstants {

    /**
     * The source graphics to write to a shape file.
     */
    protected OMGraphicList graphicList = null;

    /**
     * The optional DbfTableModel that describes properties for the OMGraphics.
     * This should be set in the AppObject of the OMGraphicList.
     */
    protected DbfTableModel masterDBF = null;

    /**
     * The projection needed to convert other OMGraphicTypes to polygons.
     */
    protected Projection projection;

    /**
     * The path where the shape files should be written.
     */
    protected String filePath;

    /**
     * Gets set automatically if Debug.debugging("shape");
     */
    protected boolean DEBUG = false;

    /**
     * A list of ESEInterface classes, holding information for different type
     * ESRIGraphicLists created from the OMGraphicList.
     */
    protected ArrayList eseInterfaces = new ArrayList();

    /**
     * Flag for whether the DBF file should be written when the OMGraphicList is
     * exported to a .shp/.shx file. The .dbf file will be created if set to
     * true, and this is true by default.
     */
    protected boolean writeDBF = true;

    /**
     * Flad to note whether, if a DbfTableModel is set, to add the rendering
     * information (DrawingAttributes contents) about the OMGraphics to the
     * contents of the DbfTableModel. False by default. Doesn't do anything yet.
     */
    protected boolean dbfHasRenderingInfo = false;

    /**
     * Create an EsriShapeExport object.
     *
     * @param list the OMGraphicList to export.
     * @param proj the Projection of the map, needed to convert some OMGraphic
     *        types to OMPolys.
     * @param pathToFile the file path of the shape file to save to. If null,
     *        the user will be queried. If not null, the files will be saved
     *        without any GUI confirmation.
     */
    public EsriShapeExport(OMGraphicList list, Projection proj,
            String pathToFile) {

        setGraphicList(list);
        projection = proj;
        filePath = pathToFile;
        DEBUG = Debug.debugging("shape");
    }

    /**
     * Create an EsriShapeExport object.
     *
     * @param list the EsriGraphicList to export.
     * @param dbf the DbfTableModel holding the attributes for the list objects.
     * @param pathToFile the file path of the shape file to save to. If null,
     *        the user will be queried. If not null, the files will be saved
     *        without any GUI confirmation.
     */
    public EsriShapeExport(EsriGraphicList list, DbfTableModel dbf,
            String pathToFile) {

        setGraphicList(list);
        setMasterDBF(dbf);
        filePath = pathToFile;
        DEBUG = Debug.debugging("shape");
    }

    /**
     * Set the OMGraphicList to use for export. If the AppObject in the
     * OMGraphicList holds a DbfTableModel, it will be used in the export.
     */
    public void setGraphicList(OMGraphicList list) {
        graphicList = list;

        if (list != null) {
            Object obj = list.getAttribute(DBF_ATTRIBUTE);
            // Do this check for backward compatibility
            if (obj == null) {
                obj = list.getAppObject();
            }

            if (obj instanceof DbfTableModel) {
                masterDBF = (DbfTableModel) obj;
                Debug.message("shape", "Setting master DBF in ESE");
            }
        }
    }

    public OMGraphicList getGraphicList() {
        return graphicList;
    }

    public void setProjection(Projection proj) {
        projection = proj;
    }

    public Projection getProjection() {
        return projection;
    }

    public void setFilePath(String pathToFile) {
        filePath = pathToFile;
    }

    public String getFilePath() {
        return filePath;
    }

    protected EsriPolygonList polyList = null;
    protected EsriPolylineList lineList = null;
    protected EsriPointList pointList = null;

    /**
     * Return the polygon list, create it if needed.
     */
    protected EsriPolygonList getPolyList() {
        if (polyList == null) {
            polyList = new EsriPolygonList();
            polyList.setTable(getMasterDBFHeaderClone());
        }
        return polyList;
    }

    /**
     * Return the line list, create it if needed.
     */
    protected EsriPolylineList getLineList() {
        if (lineList == null) {
            lineList = new EsriPolylineList();
            lineList.setTable(getMasterDBFHeaderClone());
        }
        return lineList;
    }

    /**
     * Return the point list, create it if needed. If the masterDBF object
     * exists, then a new one is created, which matching structure, and put in
     * the AppObject of the new list that is returned. If there isn't a
     * masterDBF object, then the AppObject is set to null, and a default one
     * will be created.
     */
    protected EsriPointList getPointList() {
        if (pointList == null) {
            pointList = new EsriPointList();
            pointList.setTable(getMasterDBFHeaderClone());
        }
        return pointList;
    }

    /**
     * Add a graphic to the list, and add the record to the list's DbfTableModel
     * if both exist.
     */
    protected void addGraphic(EsriGraphicList egl, OMGraphic graphic,
                              ArrayList record) {
        egl.add(graphic);
        DbfTableModel dtm = egl.getTable();
        if (dtm != null && record != null) {
            dtm.addRecord(record);
        }
    }

    /** Scoping method to call addGraphic with the right list. */
    protected void addPolygon(OMGraphic graphic, ArrayList record) {
        addGraphic(getPolyList(), graphic, record);
    }

    /** Scoping method to call addGraphic with the right list. */
    protected void addLine(OMGraphic graphic, ArrayList record) {
        addGraphic(getLineList(), graphic, record);
    }

    /** Scoping method to call addGraphic with the right list. */
    protected void addPoint(OMGraphic graphic, ArrayList record) {
        addGraphic(getPointList(), graphic, record);
    }

    /**
     * Set the DbfTableModel representing the dbf file for the main
     * OMGraphicList. Can also be passed to this object as an attribute in the
     * EsriGraphicList under the DBF_ATTRIBUTE key.
     */
    public void setMasterDBF(DbfTableModel dbf) {
        masterDBF = dbf;
    }

    /**
     * Get the DbfTableModel representing the dbf file for the main
     * OMGraphicList.
     */
    public DbfTableModel getMasterDBF() {
        return masterDBF;
    }

    /**
     * Set whether the DBF file should be written when the OMGraphicList is
     * exported to a .shp/.shx file. The .dbf file will be created if set to
     * true, and this is true by default.
     */
    public void setWriteDBF(boolean value) {
        writeDBF = value;
    }

    /**
     * Get whether the DBF file should be written when the OMGraphicList is
     * exported to a .shp/.shx file.
     */
    public boolean getWriteDBF() {
        return writeDBF;
    }

    /**
     * Get whether the DBF file should have the DrawingAttributes information
     * added to the DbfTableModel if it isn't already there.
     */
    public void setDBFHasRenderingInfo(boolean value) {
        dbfHasRenderingInfo = value;
    }

    /**
     * Get whether the DBF file should have the DrawingAttributes information
     * added to the DbfTableModel if it isn't already there.
     */
    public boolean getDBFHasRenderingInfo() {
        return dbfHasRenderingInfo;
    }

    /**
     * If the OMGraphicList has a DbfTableModel in its AppObject slot, a new
     * DbfTableModel is created that has the same structure.
     *
     * @return DbfTableModel that matches the structure that is in the
     *         OMGraphicList AppObject.
     */
    protected DbfTableModel getMasterDBFHeaderClone() {
        if (masterDBF != null) {
            return masterDBF.headerClone();
        }
        return null;
    }

    /**
     * Gets the DbfTableModel record at the index. Used when the OMGraphicList
     * contents are being split up into different type EsriGraphicLists, and the
     * records are being split into different tables, too.
     */
    protected ArrayList getMasterDBFRecord(int index) {
        try {
            if (masterDBF != null) {
                return (ArrayList) masterDBF.getRecord(index);
            }
        } catch (IndexOutOfBoundsException ioobe) {
        }
        return null;
    }

    /**
     * Separates the graphics from the OMGraphicList into Polygon, Polyline and
     * Point lists, then passes the desired shape lists to their respective
     * export functions to be added to an EsriLayer of the same type and
     * prepared for export. OMGraphics that are on sublists within the top-level
     * OMGraphicList will be simply written to the appropriate list at the top
     * level of that list. They will be handled as multi-part geometries.
     * <p>
     *
     * Separating the graphics into the three types is necessary due to shape
     * file specification limitations which will only allow shape files to be of
     * one type.
     * <P>
     *
     * For OMGraphicLists that are actually EsriGraphicLists, this export method
     * will be redirected to a different method that will handle
     * sub-OMGraphicLists as multi-part geometries.
     * <P>
     *
     * If you want to write out multi-part geometries and have a regular
     * OMGraphicList, you have to convert them to EsriGraphicLists first (and
     * OMGraphics to EsriGraphics), which forces you to group shapes into like
     * types (points, polylines and polygons).
     */
    public void export() {
        OMGraphicList list = getGraphicList();
        if (list == null) {
            Debug.error("EsriShapeExport: no graphic list to export!");
            return;
        }

        export(list, null, true);
    }

    /**
     * A counter for graphics that are not RENDERTYPE_LATLON.
     */
    int badGraphics;

    /**
     * This method is intended to allow embedded OMGraphicLists to be handled.
     * The record should be set if the list is an embedded list, reusing a
     * record from the top level interation. Set the record to null at the top
     * level iteration to cause the method to fetch the record from the
     * masterDBF, if it exists.
     *
     * @param list the OMGraphicList to write
     * @param record the record for the current list, used if the list is
     *        actually a multipart geometry for the overall list. May be null
     *        anyway, though.
     * @deprecated use export(OMGraphicList, ArrayList, boolean) instead.
     * @see #export(OMGraphicList list, ArrayList record, boolean writeFiles)
     */
    protected void export(OMGraphicList list, ArrayList record) {
        export(list, record, true);
    }

    /**
     * This method is intended to allow embedded OMGraphicLists to be handled.
     * The record should be set if the list is an embedded list, reusing a
     * record from the top level interation. Set the record to null at the top
     * level iteration to cause the method to fetch the record from the
     * masterDBF, if it exists. If the list is an EsriGraphicList, then the
     * export for EsriGraphicLists will be called. The DbfTableModel for the
     * list should be stored as an attribute in the EsriGraphicList under the
     * DBF_ATTRIBUTE key.
     *
     * @param list the OMGraphicList to write.
     * @param masterRecord the record for the current list, used if the list is
     *        actually a multipart geometry for the overall list. May be null
     *        anyway, though.
     * @param writeFiles Flag to note when this method is being called
     *        iteratively, which is when record is not null. If it is iterative,
     *        then the writing of the files should not be performed on this
     *        round of the method call.
     */
    protected void export(OMGraphicList list, ArrayList masterRecord,
                          boolean writeFiles) {
        badGraphics = 0;

        if (list == null) {
            return;
        } else if (list instanceof EsriGraphicList) {
            export((EsriGraphicList) list);
            return;
        }

        int dbfIndex = 0;

        // parse the graphic list and fill the individual lists with
        // the appropriate shape types
        Iterator it = list.iterator();
        while (it.hasNext()) {
            OMGraphic dtlGraphic = (OMGraphic) it.next();
            // Reset the record to the master flag record, which will
            // cause a new record to be read for the top level list
            // contents, but duplicate the current masterRecord for
            // iterative contents.
            ArrayList record = masterRecord;

            if (record == null) {
                record = getMasterDBFRecord(dbfIndex++);
            }

            // If we have an OMGraphicList, interate through that one
            // as well. We're not handling multi-part geometries yet.
            if (dtlGraphic instanceof OMGraphicList) {
                if (DEBUG)
                    Debug.output("ESE: handling OMGraphicList");
                export((OMGraphicList) dtlGraphic, record, false);
                continue;
            }

            // check to be sure the graphic is rendered in LAT/LON
            if (dtlGraphic.getRenderType() != RENDERTYPE_LATLON) {
                badGraphics++;
                continue;
            }

            if (dtlGraphic instanceof OMPoly) {
                OMPoly omPoly = (OMPoly) dtlGraphic;
                // verify that this instance of OMPoly is a polygon
                if (isPolygon(omPoly)) {
                    if (DEBUG)
                        Debug.output("ESE: handling OMPoly polygon");
                    addPolygon(dtlGraphic, record);
                }
                // if it is not it must be a polyline and therefore
                // added to the line list
                else {
                    if (DEBUG)
                        Debug.output("ESE: handling OMPoly line");
                    addLine(dtlGraphic, record);
                }
            }
            // (end)if (dtlGraphic instanceof OMPoly)
            // add all other fully enclosed graphics to the polyList
            else if (dtlGraphic instanceof OMRect) {
                if (DEBUG)
                    Debug.output("ESE: handling OMRect");
                addPolygon((OMGraphic) EsriPolygonList.convert((OMRect) dtlGraphic),
                        record);
            } else if (dtlGraphic instanceof OMCircle) {
                if (DEBUG)
                    Debug.output("ESE: handling OMCircle");
                addPolygon((OMGraphic) EsriPolygonList.convert((OMCircle) dtlGraphic,
                        projection),
                        record);

            } else if (dtlGraphic instanceof OMRangeRings) {
                if (DEBUG)
                    Debug.output("ESE: handling OMRangeRings");
                export(EsriPolygonList.convert((OMRangeRings) dtlGraphic,
                        projection), record, false);

            }

            // add lines to the lineList
            else if (dtlGraphic instanceof OMLine) {
                if (DEBUG)
                    Debug.output("ESE: handling OMLine");
                addLine((OMGraphic) EsriPolylineList.convert((OMLine) dtlGraphic),
                        record);
            }
            // add points to the pointList
            else if (dtlGraphic instanceof OMPoint) {
                if (DEBUG)
                    Debug.output("ESE: handling OMPoint");
                addPoint(dtlGraphic, record);
            }
        }
        // (end)for (int i = 0; i < dtlGraphicList.size(); i++)

        if (badGraphics > 0) {
            // Information popup provider, it's OK that this gets
            // dropped.
            DrawingToolRenderException.notifyUserOfNonLatLonGraphics(badGraphics);
        }

        if (!writeFiles) {
            // Punch the stack back up so that the initial call will
            // write the files.
            return;
        }

        boolean needConfirmation = false;
        // call the file chooser if no path is given
        if (filePath == null) {
            filePath = getFilePathFromUser();

            if (filePath == null) {
                return; // User cancelled.
            }

            needConfirmation = true;
        }

        if (DEBUG)
            Debug.output("ESE: writing files...");

        boolean needTypeSuffix = false;

        // (end)if (filePath == null) call the appropriate methods to
        // set up the shape files of their respective types
        if (polyList != null) {
            eseInterfaces.add(new ESEInterface(polyList, filePath, null));
            needTypeSuffix = true;
        }

        if (lineList != null) {
            eseInterfaces.add(new ESEInterface(lineList, filePath, (needTypeSuffix ? "Lines"
                    : null)));
            needTypeSuffix = true;
        }

        if (pointList != null) {
            eseInterfaces.add(new ESEInterface(pointList, filePath, (needTypeSuffix ? "Pts"
                    : null)));
        }

        if (needConfirmation) {
            showGUI();
        } else {
            writeFiles();
        }
    }

    /**
     * Writes out EsriGraphicLists as shape files, assumes that the
     * DbfTableModel representing the attribute data for the list objects is
     * stored as an attribute in the EsriGraphicList under the DBF_ATTRIBUTE
     * key. This export handles multi-part geometries, because it's assumed that
     * the sorting of the graphic types have been handled and that any sub-lists
     * are meant to be multi-part geometries. If the filePath hasn't been set in
     * the EsriShapeExport class, the user will be asked to provide it.
     */
    protected void export(EsriGraphicList egList) {

        Object obj = egList.getAttribute(DBF_ATTRIBUTE);
        // Backward compatibility
        if (obj == null) {
            obj = egList.getAppObject();
        }

        if (obj == null) {
            egList.putAttribute(DBF_ATTRIBUTE, getMasterDBF());
            // egList.setAppObject(getMasterDBF());
        }

        eseInterfaces.add(new ESEInterface(egList, filePath, null));
        writeFiles();
    }

    /**
     * The the Iterator of ESEIterators.
     */
    protected Iterator getInterfaces() {
        return eseInterfaces.iterator();
    }

    /**
     * Just write the files from the ESEInterfaces.
     */
    protected void writeFiles() {
        Iterator it = getInterfaces();
        while (it.hasNext()) {
            ((ESEInterface) it.next()).write();
        }
    }

    protected JFrame frame = null;

    /**
     * Show the GUI for saving the Shape files.
     */
    public void showGUI() {

        if (frame == null) {
            frame = new JFrame("Saving Shape Files");

            frame.getContentPane().add(getGUI(), BorderLayout.CENTER);
            // frame.setSize(400, 300);
            frame.pack();
        }

        frame.setVisible(true);
    }

    /**
     * Hide the Frame holding the GUI.
     */
    public void hideGUI() {
        if (frame != null) {
            frame.setVisible(false);
        }
    }

    /**
     * Create the GUI for managing the different ESEIterators.
     */
    public Component getGUI() {

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        JPanel interfacePanel = new JPanel();
        interfacePanel.setLayout(new GridLayout(0, 1));

        Iterator interfaces = getInterfaces();
        int count = 0;
        while (interfaces.hasNext()) {
            interfacePanel.add(((ESEInterface) interfaces.next()).getGUI());
            count++;
        }
        panel.add(interfacePanel, BorderLayout.CENTER);

        if (count > 1) {
            JLabel notification = new JLabel("  " + count
                    + " Shape file sets needed:");
            panel.add(notification, BorderLayout.NORTH);
        }

        JButton saveButton = new JButton("Save");
        saveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                writeFiles();
                hideGUI();
            }
        });

        JButton cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                hideGUI();
            }
        });
        JPanel controlPanel = new JPanel();
        controlPanel.add(saveButton);
        controlPanel.add(cancelButton);
        panel.add(controlPanel, BorderLayout.SOUTH);
        return panel;
    }

    /**
     * Prepares and returns a 7 column DbfTableModel to accept input for columns
     * of TYPE_CHARACTER. <br>
     * <br>
     * The default model used holds most of the DrawingAttributes of the
     * OMGraphics.
     *
     *
     * @param list the EsriGraphicList to create a DbfTableModel from.
     * @return The completed DbfTableModel.
     */
    public static DbfTableModel createDefaultModel(EsriGraphicList list) {
        if (Debug.debugging("shape"))
            Debug.output("ESE: creating DbfTableModel");

        DbfTableModel _model = new DbfTableModel(7);
        // Setup table structure
        // column 0
        // The first parameter, 0, respresents the first column
        _model.setLength(0, (byte) 50);
        _model.setColumnName(0, SHAPE_DBF_DESCRIPTION);
        _model.setType(0, (byte) DbfTableModel.TYPE_CHARACTER);
        _model.setDecimalCount(0, (byte) 0);
        // column 1
        // The first parameter, 1, respresents the second column
        _model.setLength(1, (byte) 10);
        _model.setColumnName(1, SHAPE_DBF_LINECOLOR);
        _model.setType(1, (byte) DbfTableModel.TYPE_CHARACTER);
        _model.setDecimalCount(1, (byte) 0);
        // column2
        // The first parameter, 2, respresents the third column
        _model.setLength(2, (byte) 10);
        _model.setColumnName(2, SHAPE_DBF_FILLCOLOR);
        _model.setType(2, (byte) DbfTableModel.TYPE_CHARACTER);
        _model.setDecimalCount(2, (byte) 0);
        // column3
        // The first parameter, 3, respresents the fourth column
        _model.setLength(3, (byte) 10);
        _model.setColumnName(3, SHAPE_DBF_SELECTCOLOR);
        _model.setType(3, (byte) DbfTableModel.TYPE_CHARACTER);
        _model.setDecimalCount(3, (byte) 0);
        // column4
        // The first parameter, 4, respresents the fifth column
        _model.setLength(4, (byte) 4);
        _model.setColumnName(4, SHAPE_DBF_LINEWIDTH);
        _model.setType(4, (byte) DbfTableModel.TYPE_NUMERIC);
        _model.setDecimalCount(4, (byte) 0);
        // column5
        // The first parameter, 5, respresents the sixth column
        _model.setLength(5, (byte) 20);
        _model.setColumnName(5, SHAPE_DBF_DASHPATTERN);
        _model.setType(5, (byte) DbfTableModel.TYPE_CHARACTER);
        _model.setDecimalCount(5, (byte) 0);
        // column6
        // The first parameter, 6, respresents the seventh column
        _model.setLength(6, (byte) 10);
        _model.setColumnName(6, SHAPE_DBF_DASHPHASE);
        _model.setType(6, (byte) DbfTableModel.TYPE_NUMERIC);
        _model.setDecimalCount(6, (byte) 4);

        // At a later time, more stroke parameters can be addded, like
        // dash phase, end cap, line joins, and dash pattern.

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            OMGraphic omg = (OMGraphic) iterator.next();

            ArrayList record = new ArrayList();

            // Description
            Object obj = omg.getAppObject();
            if (obj instanceof String) {
                record.add(obj);
            } else {
                record.add("");
            }

            record.add(ColorFactory.getHexColorString(omg.getLineColor()));
            record.add(ColorFactory.getHexColorString(omg.getFillColor()));
            record.add(ColorFactory.getHexColorString(omg.getSelectColor()));
            BasicStroke bs = (BasicStroke) omg.getStroke();
            record.add(new Double(bs.getLineWidth()));
            String dp = BasicStrokeEditor.dashArrayToString(bs.getDashArray());
            if (dp == BasicStrokeEditor.NONE) {
                dp = "";
            }
            record.add(dp);
            record.add(new Double(bs.getDashPhase()));
            _model.addRecord(record);
            if (Debug.debugging("shape"))
                Debug.output("ESE: adding record: " + record);
        }

        return _model;
    }

    /**
     * Takes an OMPoly as the parameter and checks whether or not it is a
     * polygon or polyline. <br>
     * <br>
     * This method incorporates the OMPoly.isPolygon() method which returns true
     * if the fill color is not clear, but also checks the first set and last
     * set of lat/lon points of the float[] defined by OMPoly.getLatLonArray().
     * Returns true for a polygon and false for a polyline.
     *
     * @param omPoly the OMPoly object to be verified
     * @return The polygon value
     */
    public static boolean isPolygon(OMPoly omPoly) {
        boolean isPolygon = false;
        // get the array of lat/lon points
        float[] points = omPoly.getLatLonArray();
        int i = points.length;

        // compare the first and last set of points, equal points
        // verifies a polygon.
        if (points[0] == points[i - 2] && points[1] == points[i - 1]) {

            isPolygon = true;
        }
        // check OMPoly's definition of a polygon
        if (omPoly.isPolygon()) {
            isPolygon = true;
        }

        return isPolygon;
    }

    /**
     * Generic error handling, puts up an error window.
     */
    protected void handleException(Exception e) {
        // System.out.println(e);
        StringBuffer sb = new StringBuffer("ShapeFile Export Error:");
        sb.append("\nProblem with creating the shapefile set.");
        sb.append("\n" + e.toString());

        JOptionPane.showMessageDialog(null,
                sb.toString(),
                "ESRI Shape Export to File",
                JOptionPane.ERROR_MESSAGE);
        e.printStackTrace();
    }

    /**
     * Fetches a file path from the user, via a JFileChooser. Returns null if
     * the user cancels.
     *
     * @see com.bbn.openmap.util.FileUtils.getFilePathFromUser
     */
    public String getFilePathFromUser() {
        return FileUtils.getFilePathToSaveFromUser("Select Name for Shape File Set...");
    }

    /**
     * The main function is a test, reads in a Shape file (with the .shx and
     * .dbf files) and writes them back out.
     */
    public static void main(String[] argv) {
        Debug.init();

        ArgParser ap = new ArgParser("EsriShapeExport");
        ap.add("shp", "A URL to a shape file (.shp).", 1);

        if (argv.length < 1) {
            ap.bail("", true);
        }

        ap.parse(argv);

        String[] files = ap.getArgValues("shp");
        if (files != null && files[0] != null) {
            String shp = files[0];
            String dbf = null;

            try {
                dbf = shp.substring(0, shp.lastIndexOf('.') + 1) + PARAM_DBF;

                DbfTableModel model = DbfTableModel.getDbfTableModel(PropUtils.getResourceOrFileOrURL(dbf));
                EsriGraphicList list = EsriGraphicList.getEsriGraphicList(PropUtils.getResourceOrFileOrURL(shp),
                        null,
                        null);

                Debug.output(list.getDescription());

                EsriShapeExport ese = new EsriShapeExport(list, model, null);
                ese.export();

            } catch (MalformedURLException murle) {
                Debug.error("EsriShapeExport: Malformed URL Exception\n"
                        + murle.getMessage());
            } catch (NullPointerException npe) {
                Debug.error("EsriShapeExport: Path to shape file isn't good enough to find .dbf file and .shx file.");
            } catch (Exception exception) {
                Debug.error("EsriShapeExport: Exception\n"
                        + exception.getMessage());
                exception.printStackTrace();
            }

        } else {
            ap.bail("Need a path to a Shape file (.shp)", true);
        }
        System.exit(0);
    }

    /**
     * A helper class to manage a specific instance of a EsriGraphicList, it's
     * data model, etc. Provides a GUI to display and change the name of the
     * file, and the DbfTableModel GUI, and also writes the files out.
     */
    public class ESEInterface {

        protected EsriGraphicList list;
        protected DbfTableModel model;
        protected String suffix;
        protected String filePath;

        File shpFile = null;
        File shxFile = null;
        File dbfFile = null;

        protected JTextField filePathField;

        public ESEInterface(EsriGraphicList eglist, String filePathString,
                String fileNameSuffix) {
            list = eglist;
            filePath = filePathString;

            model = eglist.getTable();

            if (model == null) {
                model = createDefaultModel(list);
            }
            model.setWritable(true);

            suffix = (fileNameSuffix == null ? "" : fileNameSuffix);
        }

        public Component getGUI() {
            JPanel panel = new JPanel();

            int type = list.getType();
            String sectionTitle;
            switch (type) {
            case (SHAPE_TYPE_POINT):
                sectionTitle = "Point Shape File";
                break;
            case (SHAPE_TYPE_POLYLINE):
                sectionTitle = "Line Shape File";
                break;
            case (SHAPE_TYPE_POLYGON):
                sectionTitle = "Polygon Shape File";
                break;
            default:
                sectionTitle = "Shape File";
            }

            panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
                    sectionTitle));

            panel.setLayout(new GridLayout(0, 1));
            JPanel pathPanel = new JPanel();
            filePathField = new JTextField(20);
            filePathField.setText(filePath + suffix);
            JButton filePathChooserLauncher = new JButton("Change Path");
            filePathChooserLauncher.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    setFilePath(getFilePathFromUser());
                }
            });

            panel.add(filePathField);

            JButton editDBFButton = new JButton("Edit the Attribute File...");
            editDBFButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    model.showGUI(getFilePath() + " Attributes",
                            DbfTableModel.DONE_MASK
                                    | DbfTableModel.MODIFY_COLUMN_MASK);
                }
            });

            pathPanel.add(editDBFButton);
            pathPanel.add(filePathChooserLauncher);

            panel.add(pathPanel);

            return panel;
        }

        protected void setFilePath(String path) {
            filePath = path;
        }

        public void write() {

            if (filePathField != null) {
                filePath = filePathField.getText();
            }

            if (filePath == null) {
                filePath = getFilePathFromUser();
                if (filePath == null) {
                    return;
                }
            }

            // This helps when a file chooser has been used to pick a file to be
            // replaced.
            if (filePath.endsWith(".shp") || filePath.endsWith(".shx")
                    || filePath.endsWith(".dbf")) {
                filePath = filePath.substring(0, filePath.length() - 4);
            }

            shpFile = new File(filePath + ".shp");
            shxFile = new File(filePath + ".shx");
            dbfFile = new File(filePath + ".dbf");

            try {

                // create an esriGraphicList and export it to the
                // shapefile set
                if (DEBUG)
                    Debug.output("ESE writing: " + list.size() + " elements");

                ShpOutputStream pos = new ShpOutputStream(new FileOutputStream(shpFile));
                int[][] indexData = pos.writeGeometry(list);

                ShxOutputStream xos = new ShxOutputStream(new FileOutputStream(shxFile));
                xos.writeIndex(indexData, list.getType());

                if (getWriteDBF()) {
                    DbfOutputStream dos = new DbfOutputStream(new FileOutputStream(dbfFile));
                    dos.writeModel(model);
                }

            } catch (Exception e) {
                handleException(e);
            }
        }

    }
}
TOP

Related Classes of com.bbn.openmap.dataAccess.shape.EsriShapeExport$ESEInterface

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.