// ********************************************************************** // // // // BBN Technologies, a Verizon Company // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/dataAccess/shape/output/ScalableShxOutputStream.java,v $ // $RCSfile: ScalableShxOutputStream.java,v $ // $Revision: 1.3 $ // $Date: 2004/02/09 13:33:37 $ // $Author: dietrick $ // // ********************************************************************** package com.elster.gis; import java.io.*; import com.bbn.openmap.omGraphics.*; import com.bbn.openmap.LatLonPoint; import com.bbn.openmap.dataAccess.shape.*; import com.bbn.openmap.dataAccess.shape.output.*; import com.bbn.openmap.dataAccess.shape.input.*; import org.apache.commons.logging.*; /** * Writes the .shx file * @author Doug Van Auken */ public class ScalableShxOutputStream { /** * An outputstream that writes primitive data types in little * endian or big endian */ private LittleEndianOutputStream _leos = null; private LittleEndianOutputStream _leos_tmp = null; protected static Log mLog = LogFactory.getLog(ScalableShxOutputStream.class); private String mFinalFilePath = null; private String mTmpFilePath = null; private int mContentLength = 0; private float[] mExtents; private int mLayerType = -1; /** * Creates an outputstream to write to * @param os The output stream to write to */ public ScalableShxOutputStream(String finalFilePath, String tmpFilePath) throws Exception { mFinalFilePath = finalFilePath; mTmpFilePath = tmpFilePath; FileOutputStream os = new FileOutputStream(mTmpFilePath); BufferedOutputStream bos = new BufferedOutputStream(os); _leos_tmp = new LittleEndianOutputStream(bos); } /** * Writes the index, with the default extents of the graphics * being the entire earth. * @param indexData The index data to write * @param layerType Tye type of layer being written * @return True if no exceptions occur */ public synchronized boolean writeIndex(int[][] indexData, int layerType) { return writeIndex(indexData, layerType, new float[] { -90f, -180f, 90f, 180f }); } public synchronized void finalizeFile() throws Exception { FileOutputStream os = new FileOutputStream(mFinalFilePath); BufferedOutputStream bos = new BufferedOutputStream(os); _leos = new LittleEndianOutputStream(bos); _leos_tmp.flush(); _leos_tmp.close(); FileInputStream is = new FileInputStream(mTmpFilePath); BufferedInputStream bin = new BufferedInputStream(is); //LittleEndianInputStream lein = new LittleEndianInputStream(bin); mContentLength += 50; mLog.info("final content length: " + mContentLength + " for shx: " + mFinalFilePath); _leos.writeInt(9994); _leos.writeInt(0); _leos.writeInt(0); _leos.writeInt(0); _leos.writeInt(0); _leos.writeInt(0); _leos.writeInt(mContentLength); //_leos.writeInt(indexData[0].length * 4 + 50); _leos.writeLEInt(1000); _leos.writeLEInt(mLayerType); if (mExtents[0] == 90f && mExtents[1] == 180f && mExtents[2] == -90f && mExtents[3] == -180f) { //Whoa! not set from defaults correctly! // use old, hardcoded way. _leos.writeLEDouble(-180.0); //Hard-coding extents. _leos.writeLEDouble(-90.0); //When viewed through ArcView, this will _leos.writeLEDouble(180.0); //cause window to zoom to world extents _leos.writeLEDouble(90.0); //instead of layer extents. } else { _leos.writeLEDouble((float)mExtents[1]); _leos.writeLEDouble((float)mExtents[0]); _leos.writeLEDouble((float)mExtents[3]); _leos.writeLEDouble((float)mExtents[2]); } _leos.writeLEDouble(0.0); _leos.writeLEDouble(0.0); _leos.writeLEDouble(0.0); _leos.writeLEDouble(0.0); _leos.flush(); copy_stream(_leos, bin); bin.close(); _leos.flush(); _leos.close(); } // combine the header with contents public synchronized void copy_stream(OutputStream os, BufferedInputStream is) throws Exception { int length = 512; byte[] bytes = new byte[length+1]; int numRead = 0; while ((numRead = is.read(bytes, 0, length) ) >= 0) { os.write(bytes, 0, numRead); } os.flush(); } private void fixExtents(float[] extents) { if (mExtents == null) mExtents = extents; // fix the extent based on old else { if (mExtents[0] > extents[0]) mExtents[0] = extents[0]; // ymin if (mExtents[1] > extents[1]) mExtents[1] = extents[1]; // xmin if (mExtents[3] < extents[3]) mExtents[3] = extents[3]; // ymax if (mExtents[2] > extents[2]) mExtents[2] = extents[2]; // xmax } } /** * Writes the index, with the default extents of the graphics * being the entire earth. * @param indexData The index data to write * @param layerType Tye type of layer being written * @param extents an array of floats describing, in order, miny, * minx, maxy, maxx for the area that the graphics in the shape * file cover. * @return True if no exceptions occur */ public synchronized boolean writeIndex(int[][] indexData, int layerType, float[] extents) { mLayerType = layerType; mContentLength += (indexData[0].length * 4); fixExtents(extents); try { for (int i=0; i<=indexData[0].length-1; i++) { _leos_tmp.writeInt(indexData[0][i]); _leos_tmp.writeInt(indexData[1][i]); } _leos_tmp.flush(); } catch (Exception e) { mLog.error("exception=" + e.toString()); return false; } return true; } }