// **********************************************************************
//
// <copyright>
//
// BBN Technologies
// 10 Moulton Street
// Cambridge, MA 02138
// (617) 873-8000
//
// Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/shape/ShapeFileCrop.java,v $
// $RCSfile: ShapeFileCrop.java,v $
// $Revision: 1.5 $
// $Date: 2005/12/09 21:09:10 $
// $Author: dietrick $
//
// **********************************************************************
/* ShapeFileCrop class - written by Eliot T. Lebsack of the MITRE Corp. 10/16/2002. */
package com.bbn.openmap.layer.shape;
import java.io.IOException;
import com.bbn.openmap.dataAccess.shape.ShapeUtils;
/**
* Class that supports cropping of ESRI Shapefiles with a simple bounding box.
* Does not yet update the .shx or .dbf files.
*
* <pre>
* <b>Usage:</b>
*
* <code>java com.bbn.openmap.layer.shape.ShapeFileCrop -ul lat,lon -lr lat,lon -i srcShapeFile -o destShapeFile</code>
*
* <i>Crops the srcShapeFile, dumps the output into destShapeFile.</i>
* Note that this does simple rejection of entities based on their bounding
* boxes.
*
* A better scheme (unimplemented) would be to actually crop the line
* segments.
*
* </pre>
*
* @author Eliot Lebsack
* @version $Revision: 1.5 $ $Date: 2005/12/09 21:09:10 $
*/
public class ShapeFileCrop {
/** Input ShapeFile object. */
public ShapeFile sfin = null;
/** Output ShapeFile object. */
public ShapeFile sfout = null;
/** Bounding Box Object used for cropping */
ESRIBoundingBox ebb = null;
/**
* Construct a <code>ShapeFileCrop</code> object from a pair of file names.
*
* @exception IOException
* if something goes wrong opening or reading the file.
*/
public ShapeFileCrop(String namein, String nameout) throws IOException {
sfin = new ShapeFile(namein);
sfout = new ShapeFile(nameout);
}
/**
* Read the input <code>ShapeFile</code> object, and apply cropping rules to
* the read entities. Writes the output <code>ShapeFile</code> object, and
* then invokes the <code>ShapeFile</code> .verify method to fix the output
* file header.
*
* @exception IOException
* if something goes wrong opening or reading the file.
*/
public void cropShapeFile() throws IOException {
ESRIPolygonRecord pr;
int nRecordNum = 0;
int nRecords = 0;
sfin.readHeader();
sfout.setShapeType(sfin.fileShapeType);
switch (sfin.fileShapeType) {
case (ShapeUtils.SHAPE_TYPE_ARC):
case (ShapeUtils.SHAPE_TYPE_POLYGON):
while ((pr = (ESRIPolygonRecord) sfin.getNextRecord()) != null) {
nRecords++;
if (overlapBBTest(pr.bounds) != 0) {
pr.recordNumber = nRecordNum + 1;
sfout.add(pr);
nRecordNum++;
nRecords++;
}
}
}
System.out.println("Number of input records = " + (nRecords + 1));
System.out.println("Number of candidate records = " + nRecordNum);
if (nRecordNum > 0)
sfout.verify(true, true);
sfin.close();
sfout.close();
}
private int overlapBBTest(ESRIBoundingBox bb) {
int result = 0;
result += boundaryTest(bb.min.x, bb.min.y);
result += boundaryTest(bb.max.x, bb.min.y);
result += boundaryTest(bb.min.x, bb.max.y);
result += boundaryTest(bb.max.x, bb.max.y);
return result;
}
private int boundaryTest(double x, double y) {
int ns = 0;
int ew = 0;
if ((x >= ebb.min.x) && (x < ebb.max.x))
ew++;
if ((y >= ebb.min.y) && (y < ebb.max.y))
ns++;
return ns * ew;
}
public static void usage() {
System.out
.println("Usage: java ShapeFileCrop [args] -i <infile.shp> -o <outfile.shp>");
System.out.println("Arguments:");
System.out
.println("-ul lat,lon Coordinates of upper-left corner of the bounding box to use for cropping");
System.out
.println("-lr lat,lon Coordinates of lower-right corner of the bounding box to use for cropping");
System.exit(1);
}
/**
* The driver for the command line interface. Reads the command line
* arguments and executes appropriate calls.
* <p>
* See the file documentation for usage.
*
* @param args
* the command line arguments
* @exception IOException
* if something goes wrong reading or writing the file
*/
public static void main(String[] args) throws IOException {
String inpath = "";
String outpath = "";
String sllp;
String[] sllpa;
ShapeFileCrop sfc = null;
ESRIPoint ul = null;
ESRIPoint lr = null;
int index = 0;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-i")) {
inpath = args[++i];
} else if (args[i].equals("-o")) {
outpath = args[++i];
} else if (args[i].equals("-ul")) {
sllp = args[++i];
// sllpa = sllp.split(","); // jdk 1.4
index = sllp.indexOf(",");
if (index != -1) {
sllpa = new String[2];
sllpa[0] = sllp.substring(0, index);
sllpa[1] = sllp.substring(index + 1);
ul = new ESRIPoint(Double.valueOf(sllpa[1]).doubleValue(),
Double.valueOf(sllpa[0]).doubleValue());
}
} else if (args[i].equals("-lr")) {
sllp = args[++i];
// sllpa = sllp.split(","); // jdk 1.4
index = sllp.indexOf(",");
if (index != -1) {
sllpa = new String[2];
sllpa[0] = sllp.substring(0, index);
sllpa[1] = sllp.substring(index + 1);
lr = new ESRIPoint(Double.valueOf(sllpa[1]).doubleValue(),
Double.valueOf(sllpa[0]).doubleValue());
}
} else {
usage();
}
}
if ((ul == null) || (lr == null) || (inpath.length() == 0)
|| (outpath.length() == 0)) {
usage();
} else {
sfc = new ShapeFileCrop(inpath, outpath);
sfc.ebb = new ESRIBoundingBox(ul, lr);
}
if (sfc != null) {
sfc.cropShapeFile();
}
}
}