/*
* Copyright (C) 2012 Dr. John Lindsay <jlindsay@uoguelph.ca>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package whitebox.geospatialfiles;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.*;
import java.nio.file.Path;
import java.nio.file.Files;
import java.util.ArrayList;
import whitebox.geospatialfiles.shapefile.attributes.DBFField;
import whitebox.geospatialfiles.shapefile.*;
import static whitebox.geospatialfiles.shapefile.ShapeType.*;
import whitebox.structures.BoundingBox;
import whitebox.utilities.ByteSwapper;
import whitebox.geospatialfiles.shapefile.attributes.AttributeTable;
import whitebox.utilities.StringUtilities;
import whitebox.structures.KdTree;
import whitebox.structures.KdTree.Entry;
import whitebox.utilities.FileUtilities;
/**
*
* @author Dr. John Lindsay <jlindsay@uoguelph.ca>
*/
public class ShapeFile {
private String fileName;
private String shortFileName;
private String indexFile;
private String databaseFile;
private String projectionFile;
private int fileCode;
private int fileLength;
private int version;
private ShapeType shapeType;
private double xMin;
private double yMin;
private double xMax;
private double yMax;
private double zMin;
private double zMax;
private double mMin;
private double mMax;
private int numRecs;
private String projection = "";
private String zUnits = "";
private String xyUnits = "";
private String spheroid = "";
private String xShift = "";
private String yShift = "";
private double[] parameters;
public boolean databaseFileExists;
public ArrayList<ShapeFileRecord> records = new ArrayList<>();
private boolean pointType;
private AttributeTable attributeTable = null;
// Constructors
public ShapeFile() {
}
public ShapeFile(String fileName) throws IOException {
setFileName(fileName);
this.indexFile = StringUtilities.replaceLast(fileName, ".shp", ".shx");
setProjectionFile(StringUtilities.replaceLast(fileName, ".shp", ".prj"));
setDatabaseFile(StringUtilities.replaceLast(fileName, ".shp", ".dbf"));
// int extensionIndex = fileName.lastIndexOf(".");
// this.indexFile = fileName.substring(0, extensionIndex) + ".shx";
// setProjectionFile(fileName.substring(0, extensionIndex) + ".prj");
// setDatabaseFile(fileName.substring(0, extensionIndex) + ".dbf");
// see if the databaseFile exists.
databaseFileExists = (new File(databaseFile)).exists();
if (databaseFileExists) {
this.attributeTable = new AttributeTable(databaseFile);
}
}
public ShapeFile(String fileName, ShapeType st) {
this.fileName = fileName;
int extensionIndex = fileName.lastIndexOf(".");
this.indexFile = fileName.substring(0, extensionIndex) + ".shx";
this.projectionFile = fileName.substring(0, extensionIndex) + ".prj";
this.databaseFile = fileName.substring(0, extensionIndex) + ".dbf";
this.fileCode = 9994;
this.version = 1000;
this.shapeType = st;
this.xMin = Float.POSITIVE_INFINITY;
this.yMin = Float.POSITIVE_INFINITY;
this.xMax = Float.NEGATIVE_INFINITY;
this.yMax = Float.NEGATIVE_INFINITY;
this.zMin = Float.POSITIVE_INFINITY;
this.zMax = Float.NEGATIVE_INFINITY;
this.mMin = Float.POSITIVE_INFINITY;
this.mMax = Float.NEGATIVE_INFINITY;
this.numRecs = 0;
deleteFiles();
}
public ShapeFile(String fileName, ShapeType st, DBFField[] fields) {
this.fileName = fileName;
int extensionIndex = fileName.lastIndexOf(".");
this.indexFile = fileName.substring(0, extensionIndex) + ".shx";
this.projectionFile = fileName.substring(0, extensionIndex) + ".prj";
this.databaseFile = fileName.substring(0, extensionIndex) + ".dbf";
this.fileCode = 9994;
this.version = 1000;
this.shapeType = st;
this.xMin = Float.POSITIVE_INFINITY;
this.yMin = Float.POSITIVE_INFINITY;
this.xMax = Float.NEGATIVE_INFINITY;
this.yMax = Float.NEGATIVE_INFINITY;
this.zMin = Float.POSITIVE_INFINITY;
this.zMax = Float.NEGATIVE_INFINITY;
this.mMin = Float.POSITIVE_INFINITY;
this.mMax = Float.NEGATIVE_INFINITY;
this.numRecs = 0;
deleteFiles();
try {
this.attributeTable = new AttributeTable(databaseFile, fields, false);
} catch (Exception e) {
// do nothing
}
}
// Properties
public String getFileName() {
return fileName;
}
public String getShortName() {
if (shortFileName == null) {
File file = new File(fileName);
shortFileName = file.getName();
shortFileName = shortFileName.replace(".shp", "");
}
return shortFileName;
}
public final void setFileName(String fileName) {
this.fileName = fileName;
// See if the data file exists.
File file = new File(fileName);
if (file.exists()) { // it's an existing file
readHeaderData();
readRecords();
} else { // it's a new file
}
}
public String getProjectionFile() {
return projectionFile;
}
public final void setProjectionFile(String projectionFile) {
this.projectionFile = projectionFile;
readProjectionFile();
}
public void setProjectionStringFromOtherFile(String otherProjectionFile) {
try {
File otherFile = new File(otherProjectionFile);
if (otherFile.exists()) {
FileUtilities.copyFile(otherFile, new File(this.projectionFile));
}
readProjectionFile();
} catch (IOException e) {
// do nothing.
}
}
public void setProjectionStringFromOtherShapefile(ShapeFile otherShapeFile) {
try {
File otherFile = new File(otherShapeFile.getProjectionFile());
if (otherFile.exists()) {
FileUtilities.copyFile(otherFile, new File(this.projectionFile));
}
readProjectionFile();
} catch (IOException e) {
// do nothing.
}
}
public String getDatabaseFile() {
return databaseFile;
}
public final void setDatabaseFile(String databaseFile) {
this.databaseFile = databaseFile;
}
public String getIndexFile() {
return indexFile;
}
private static ShapeType[] st = new ShapeType[]{ShapeType.NULLSHAPE, ShapeType.POINT,
ShapeType.UNUSED1, ShapeType.POLYLINE, ShapeType.UNUSED2, ShapeType.POLYGON,
ShapeType.UNUSED3, ShapeType.UNUSED4, ShapeType.MULTIPOINT,
ShapeType.UNUSED5, ShapeType.UNUSED6, ShapeType.POINTZ, ShapeType.UNUSED7,
ShapeType.POLYLINEZ, ShapeType.UNUSED8, ShapeType.POLYGONZ, ShapeType.UNUSED9,
ShapeType.UNUSED10, ShapeType.MULTIPOINTZ, ShapeType.UNUSED11,
ShapeType.UNUSED12, ShapeType.POINTM, ShapeType.UNUSED13, ShapeType.POLYLINEM,
ShapeType.UNUSED14, ShapeType.POLYGONM, ShapeType.UNUSED15, ShapeType.UNUSED16,
ShapeType.MULTIPOINTM, ShapeType.UNUSED17, ShapeType.UNUSED18, ShapeType.MULTIPATCH};
private ShapeType getShapeTypeFromInt(int i) {
return st[i];
}
private int getIntFromShapeType(ShapeType st) {
switch (st) {
case NULLSHAPE:
return 0;
case POINT:
return 1;
case POLYLINE:
return 3;
case POLYGON:
return 5;
case MULTIPOINT:
return 8;
case POINTZ:
return 11;
case POLYLINEZ:
return 13;
case POLYGONZ:
return 15;
case MULTIPOINTZ:
return 18;
case POINTM:
return 21;
case POLYLINEM:
return 23;
case POLYGONM:
return 25;
case MULTIPOINTM:
return 28;
case MULTIPATCH:
return 31;
}
return -1; // it should never reach here.
}
public int getFileCode() {
return fileCode;
}
public void setFileCode(int fileCode) {
this.fileCode = fileCode;
}
public int getFileLength() {
return fileLength;
}
public void setFileLength(int fileLength) {
this.fileLength = fileLength;
}
public double getmMax() {
return mMax;
}
public void setmMax(double mMax) {
this.mMax = mMax;
}
public double getmMin() {
return mMin;
}
public void setmMin(double mMin) {
this.mMin = mMin;
}
public ShapeType getShapeType() {
return shapeType;
}
public void setShapeType(ShapeType shapeType) {
this.shapeType = shapeType;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public double getxMax() {
return xMax;
}
public void setxMax(double xMax) {
this.xMax = xMax;
}
public double getxMin() {
return xMin;
}
public void setxMin(double xMin) {
this.xMin = xMin;
}
public double getyMax() {
return yMax;
}
public void setyMax(double yMax) {
this.yMax = yMax;
}
public double getyMin() {
return yMin;
}
public void setyMin(double yMin) {
this.yMin = yMin;
}
public double getzMax() {
return zMax;
}
public void setzMax(double zMax) {
this.zMax = zMax;
}
public double getzMin() {
return zMin;
}
public void setzMin(double zMin) {
this.zMin = zMin;
}
public int getNumberOfRecords() {
return numRecs;
}
public int getNumberOfDataPoints() {
int ret = 0;
for (ShapeFileRecord sfr : records) {
ret += sfr.getGeometry().getPoints().length;
}
return ret;
}
public String getXYUnits() {
return xyUnits;
}
public void setXYUnits(String xyUnits) {
this.xyUnits = xyUnits;
}
public boolean isPointType() {
return pointType;
}
// Methods
public final boolean deleteFiles() {
try {
File file = new File(fileName);
file.delete();
file = new File(databaseFile);
file.delete();
file = new File(indexFile);
file.delete();
return true;
} catch (Exception e) {
return false;
}
}
private boolean readHeaderData() {
RandomAccessFile rIn = null;
ByteBuffer buf;
try {
// See if the data file exists.
File file = new File(fileName);
if (!file.exists()) {
return false;
}
buf = ByteBuffer.allocate(100);
rIn = new RandomAccessFile(fileName, "r");
FileChannel inChannel = rIn.getChannel();
inChannel.position(0);
inChannel.read(buf);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.rewind();
fileCode = ByteSwapper.swap(buf.getInt(0));
fileLength = ByteSwapper.swap(buf.getInt(24)); // in 16-bit words.
version = buf.getShort(28);
shapeType = getShapeTypeFromInt(buf.getShort(32));
if (shapeType == ShapeType.POINT) {
this.pointType = true;
} else if (shapeType == ShapeType.MULTIPOINT) {
this.pointType = true;
} else if (shapeType == ShapeType.POINTZ) {
this.pointType = true;
} else if (shapeType == ShapeType.POINTM) {
this.pointType = true;
} else if (shapeType == ShapeType.MULTIPOINTM) {
this.pointType = true;
} else if (shapeType == ShapeType.MULTIPOINTZ) {
this.pointType = true;
} else {
pointType = false;
}
xMin = buf.getDouble(36);
yMin = buf.getDouble(44);
xMax = buf.getDouble(52);
yMax = buf.getDouble(60);
zMin = buf.getDouble(68);
zMax = buf.getDouble(76);
mMin = buf.getDouble(84);
mMax = buf.getDouble(92);
} catch (Exception e) {
return false;
} finally {
if (rIn != null) {
try {
rIn.close();
} catch (Exception e) {
}
}
return true;
}
}
public boolean write() throws IOException {
ByteBuffer buf;
try {
OutputStream output = null;
try {
// what is the size of the file?
int size = 100; // initialized to the size of the file header
for (ShapeFileRecord sfr : records) {
size += sfr.getLength();
}
fileLength = size / 2; // in 16-bit words
buf = ByteBuffer.allocate(size);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.rewind();
// place the file header data into the buffer then output it
buf.putInt(0, ByteSwapper.swap(fileCode));
buf.putInt(24, ByteSwapper.swap(fileLength));
buf.putInt(28, version);
buf.putInt(32, getIntFromShapeType(shapeType));
buf.putDouble(36, xMin);
buf.putDouble(44, yMin);
buf.putDouble(52, xMax);
buf.putDouble(60, yMax);
buf.putDouble(68, zMin);
buf.putDouble(76, zMax);
buf.putDouble(84, mMin);
buf.putDouble(92, mMax);
int pos = 100;
byte[] bytes;
int[] indexData = new int[numRecs];
int a = 0;
for (ShapeFileRecord sfr : records) {
bytes = sfr.toBytes();
for (int i = 0; i < bytes.length; i++) {
buf.put(i + pos, bytes[i]); //i + pos,
}
indexData[a] = pos / 2;
a++;
pos += sfr.getLength();
}
output = new BufferedOutputStream(new FileOutputStream(fileName));
output.write(buf.array());
output.close();
// now save the index file
size = 100 + 8 * numRecs;
buf = ByteBuffer.allocate(size);
buf.order(ByteOrder.BIG_ENDIAN);
buf.rewind();
buf.putInt(0, fileCode);
buf.putInt(24, size / 2);
buf.putInt(28, ByteSwapper.swap(version));
buf.putInt(32, ByteSwapper.swap(getIntFromShapeType(shapeType)));
buf.putDouble(36, ByteSwapper.swap(xMin));
buf.putDouble(44, ByteSwapper.swap(yMin));
buf.putDouble(52, ByteSwapper.swap(xMax));
buf.putDouble(60, ByteSwapper.swap(yMax));
buf.putDouble(68, ByteSwapper.swap(zMin));
buf.putDouble(76, ByteSwapper.swap(zMax));
buf.putDouble(84, ByteSwapper.swap(mMin));
buf.putDouble(92, ByteSwapper.swap(mMax));
pos = 100;
a = 0;
for (ShapeFileRecord sfr : records) {
buf.putInt(pos, indexData[a]);
a++;
buf.putInt(pos + 4, sfr.getContentLength());
pos += 8;
}
output = new BufferedOutputStream(new FileOutputStream(indexFile));
output.write(buf.array());
if (this.attributeTable != null) {
this.attributeTable.write();
}
} finally {
output.close();
}
return true;
} catch (FileNotFoundException ex) {
return false;
} catch (IOException ex) {
return false;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return false;
}
}
public boolean addRecord(Geometry recordGeometry) {
if (recordGeometry.getShapeType() == shapeType) {
numRecs++;
int contentLength = (4 + recordGeometry.getLength()) / 2;
ShapeFileRecord sfr = new ShapeFileRecord(numRecs, contentLength,
shapeType, recordGeometry);
records.add(sfr);
// update the min and max coordinates
double recXMin = 0, recYMin = 0, recXMax = 0, recYMax = 0,
recZMin = 0, recZMax = 0, recMMin = 0, recMMax = 0;
switch (shapeType) {
case POINT:
Point recPoint = (Point) recordGeometry;
recXMin = recPoint.getX();
recYMin = recPoint.getY();
recXMax = recXMin;
recYMax = recYMin;
break;
case MULTIPOINT:
MultiPoint recMultiPoint = (MultiPoint) recordGeometry;
recXMin = recMultiPoint.getXMin();
recYMin = recMultiPoint.getYMin();
recXMax = recMultiPoint.getXMax();
recYMax = recMultiPoint.getYMax();
break;
case POLYLINE:
PolyLine recPolyLine = (PolyLine) recordGeometry;
recXMin = recPolyLine.getXMin();
recYMin = recPolyLine.getYMin();
recXMax = recPolyLine.getXMax();
recYMax = recPolyLine.getYMax();
break;
case POINTZ:
PointZ recPointZ = (PointZ) recordGeometry;
recXMin = recPointZ.getX();
recYMin = recPointZ.getY();
recXMax = recXMin;
recYMax = recYMin;
recZMin = recPointZ.getZ();
recZMax = recPointZ.getZ();
recMMin = recPointZ.getM();
recMMax = recPointZ.getM();
break;
case POINTM:
PointM recPointM = (PointM) recordGeometry;
recXMin = recPointM.getX();
recYMin = recPointM.getY();
recXMax = recXMin;
recYMax = recYMin;
recMMin = recPointM.getM();
recMMax = recPointM.getM();
break;
case MULTIPOINTM:
MultiPointM recMultiPointM = (MultiPointM) recordGeometry;
recXMin = recMultiPointM.getXMin();
recYMin = recMultiPointM.getYMin();
recXMax = recMultiPointM.getXMax();
recYMax = recMultiPointM.getYMax();
recMMin = recMultiPointM.getmMin();
recMMax = recMultiPointM.getmMax();
break;
case POLYLINEM:
PolyLineM recPolyLineM = (PolyLineM) recordGeometry;
recXMin = recPolyLineM.getXMin();
recYMin = recPolyLineM.getYMin();
recXMax = recPolyLineM.getXMax();
recYMax = recPolyLineM.getYMax();
recMMin = recPolyLineM.getmMin();
recMMax = recPolyLineM.getmMax();
break;
case MULTIPOINTZ:
MultiPointZ recMultiPointZ = (MultiPointZ) recordGeometry;
recXMin = recMultiPointZ.getXMin();
recYMin = recMultiPointZ.getYMin();
recXMax = recMultiPointZ.getXMax();
recYMax = recMultiPointZ.getYMax();
recZMin = recMultiPointZ.getzMin();
recZMax = recMultiPointZ.getzMin();
recMMin = recMultiPointZ.getmMin();
recMMax = recMultiPointZ.getmMax();
break;
case POLYLINEZ:
PolyLineZ recPolyLineZ = (PolyLineZ) recordGeometry;
recXMin = recPolyLineZ.getXMin();
recYMin = recPolyLineZ.getYMin();
recXMax = recPolyLineZ.getXMax();
recYMax = recPolyLineZ.getYMax();
recZMin = recPolyLineZ.getzMin();
recZMax = recPolyLineZ.getzMax();
recMMin = recPolyLineZ.getmMin();
recMMax = recPolyLineZ.getmMax();
break;
case POLYGON:
Polygon recPolygon = (Polygon) recordGeometry;
recXMin = recPolygon.getXMin();
recYMin = recPolygon.getYMin();
recXMax = recPolygon.getXMax();
recYMax = recPolygon.getYMax();
break;
case POLYGONM:
PolygonM recPolygonM = (PolygonM) recordGeometry;
recXMin = recPolygonM.getXMin();
recYMin = recPolygonM.getYMin();
recXMax = recPolygonM.getXMax();
recYMax = recPolygonM.getYMax();
recMMin = recPolygonM.getmMin();
recMMax = recPolygonM.getmMax();
break;
case POLYGONZ:
PolygonZ recPolygonZ = (PolygonZ) recordGeometry;
recXMin = recPolygonZ.getXMin();
recYMin = recPolygonZ.getYMin();
recXMax = recPolygonZ.getXMax();
recYMax = recPolygonZ.getYMax();
recZMin = recPolygonZ.getzMin();
recZMax = recPolygonZ.getzMax();
recMMin = recPolygonZ.getmMin();
recMMax = recPolygonZ.getmMax();
break;
case MULTIPATCH:
MultiPatch recMultiPatch = (MultiPatch) recordGeometry;
recXMin = recMultiPatch.getXMin();
recYMin = recMultiPatch.getYMin();
recXMax = recMultiPatch.getXMax();
recYMax = recMultiPatch.getYMax();
recZMin = recMultiPatch.getzMin();
recZMax = recMultiPatch.getzMax();
recMMin = recMultiPatch.getmMin();
recMMax = recMultiPatch.getmMax();
break;
}
if (recXMin < xMin) {
xMin = recXMin;
}
if (recYMin < yMin) {
yMin = recYMin;
}
if (recXMax > xMax) {
xMax = recXMax;
}
if (recYMax > yMax) {
yMax = recYMax;
}
if (recZMin < zMin) {
zMin = recZMin;
}
if (recZMax > zMax) {
zMax = recZMax;
}
if (recMMin < mMin) {
mMin = recMMin;
}
if (recMMax > mMax) {
mMax = recMMax;
}
return true;
} else {
return false;
}
}
public boolean addRecord(Geometry recordGeometry, Object[] rowData) {
if (recordGeometry.getShapeType() == shapeType) {
numRecs++;
int contentLength = (4 + recordGeometry.getLength()) / 2;
ShapeFileRecord sfr = new ShapeFileRecord(numRecs, contentLength,
shapeType, recordGeometry);
records.add(sfr);
// update the min and max coordinates
double recXMin = 0, recYMin = 0, recXMax = 0, recYMax = 0,
recZMin = 0, recZMax = 0, recMMin = 0, recMMax = 0;
switch (shapeType) {
case POINT:
Point recPoint = (Point) recordGeometry;
recXMin = recPoint.getX();
recYMin = recPoint.getY();
recXMax = recXMin;
recYMax = recYMin;
break;
case MULTIPOINT:
MultiPoint recMultiPoint = (MultiPoint) recordGeometry;
recXMin = recMultiPoint.getXMin();
recYMin = recMultiPoint.getYMin();
recXMax = recMultiPoint.getXMax();
recYMax = recMultiPoint.getYMax();
break;
case POLYLINE:
PolyLine recPolyLine = (PolyLine) recordGeometry;
recXMin = recPolyLine.getXMin();
recYMin = recPolyLine.getYMin();
recXMax = recPolyLine.getXMax();
recYMax = recPolyLine.getYMax();
break;
case POINTZ:
PointZ recPointZ = (PointZ) recordGeometry;
recXMin = recPointZ.getX();
recYMin = recPointZ.getY();
recXMax = recXMin;
recYMax = recYMin;
recZMin = recPointZ.getZ();
recZMax = recPointZ.getZ();
recMMin = recPointZ.getM();
recMMax = recPointZ.getM();
break;
case POINTM:
PointM recPointM = (PointM) recordGeometry;
recXMin = recPointM.getX();
recYMin = recPointM.getY();
recXMax = recXMin;
recYMax = recYMin;
recMMin = recPointM.getM();
recMMax = recPointM.getM();
break;
case MULTIPOINTM:
MultiPointM recMultiPointM = (MultiPointM) recordGeometry;
recXMin = recMultiPointM.getXMin();
recYMin = recMultiPointM.getYMin();
recXMax = recMultiPointM.getXMax();
recYMax = recMultiPointM.getYMax();
recMMin = recMultiPointM.getmMin();
recMMax = recMultiPointM.getmMax();
break;
case POLYLINEM:
PolyLineM recPolyLineM = (PolyLineM) recordGeometry;
recXMin = recPolyLineM.getXMin();
recYMin = recPolyLineM.getYMin();
recXMax = recPolyLineM.getXMax();
recYMax = recPolyLineM.getYMax();
recMMin = recPolyLineM.getmMin();
recMMax = recPolyLineM.getmMax();
break;
case MULTIPOINTZ:
MultiPointZ recMultiPointZ = (MultiPointZ) recordGeometry;
recXMin = recMultiPointZ.getXMin();
recYMin = recMultiPointZ.getYMin();
recXMax = recMultiPointZ.getXMax();
recYMax = recMultiPointZ.getYMax();
recZMin = recMultiPointZ.getzMin();
recZMax = recMultiPointZ.getzMin();
recMMin = recMultiPointZ.getmMin();
recMMax = recMultiPointZ.getmMax();
break;
case POLYLINEZ:
PolyLineZ recPolyLineZ = (PolyLineZ) recordGeometry;
recXMin = recPolyLineZ.getXMin();
recYMin = recPolyLineZ.getYMin();
recXMax = recPolyLineZ.getXMax();
recYMax = recPolyLineZ.getYMax();
recZMin = recPolyLineZ.getzMin();
recZMax = recPolyLineZ.getzMax();
recMMin = recPolyLineZ.getmMin();
recMMax = recPolyLineZ.getmMax();
break;
case POLYGON:
Polygon recPolygon = (Polygon) recordGeometry;
recXMin = recPolygon.getXMin();
recYMin = recPolygon.getYMin();
recXMax = recPolygon.getXMax();
recYMax = recPolygon.getYMax();
break;
case POLYGONM:
PolygonM recPolygonM = (PolygonM) recordGeometry;
recXMin = recPolygonM.getXMin();
recYMin = recPolygonM.getYMin();
recXMax = recPolygonM.getXMax();
recYMax = recPolygonM.getYMax();
recMMin = recPolygonM.getmMin();
recMMax = recPolygonM.getmMax();
break;
case POLYGONZ:
PolygonZ recPolygonZ = (PolygonZ) recordGeometry;
recXMin = recPolygonZ.getXMin();
recYMin = recPolygonZ.getYMin();
recXMax = recPolygonZ.getXMax();
recYMax = recPolygonZ.getYMax();
recZMin = recPolygonZ.getzMin();
recZMax = recPolygonZ.getzMax();
recMMin = recPolygonZ.getmMin();
recMMax = recPolygonZ.getmMax();
break;
case MULTIPATCH:
MultiPatch recMultiPatch = (MultiPatch) recordGeometry;
recXMin = recMultiPatch.getXMin();
recYMin = recMultiPatch.getYMin();
recXMax = recMultiPatch.getXMax();
recYMax = recMultiPatch.getYMax();
recZMin = recMultiPatch.getzMin();
recZMax = recMultiPatch.getzMax();
recMMin = recMultiPatch.getmMin();
recMMax = recMultiPatch.getmMax();
break;
}
if (recXMin < xMin) {
xMin = recXMin;
}
if (recYMin < yMin) {
yMin = recYMin;
}
if (recXMax > xMax) {
xMax = recXMax;
}
if (recYMax > yMax) {
yMax = recYMax;
}
if (recZMin < zMin) {
zMin = recZMin;
}
if (recZMax > zMax) {
zMax = recZMax;
}
if (recMMin < mMin) {
mMin = recMMin;
}
if (recMMax > mMax) {
mMax = recMMax;
}
try {
this.attributeTable.addRecord(rowData);
} catch (Exception e) {
return false;
}
return true;
} else {
return false;
}
}
public boolean addRecords(ArrayList<Geometry> recordsGeometry) {
boolean allRightShapeType = true;
for (Geometry rec : recordsGeometry) {
if (rec.getShapeType() != shapeType) {
allRightShapeType = false;
}
}
if (allRightShapeType) {
double recXMin = 0, recYMin = 0, recXMax = 0, recYMax = 0,
recZMin = 0, recZMax = 0, recMMin = 0, recMMax = 0;
for (Geometry rec : recordsGeometry) {
numRecs++;
int contentLength = (4 + rec.getLength()) / 2;
ShapeFileRecord sfr = new ShapeFileRecord(numRecs, contentLength,
shapeType, rec);
records.add(sfr);
// update the min and max coordinates
switch (shapeType) {
case POINT:
Point recPoint = (Point) rec;
recXMin = recPoint.getX();
recYMin = recPoint.getY();
recXMax = recXMin;
recYMax = recYMin;
break;
case MULTIPOINT:
MultiPoint recMultiPoint = (MultiPoint) rec;
recXMin = recMultiPoint.getXMin();
recYMin = recMultiPoint.getYMin();
recXMax = recMultiPoint.getXMax();
recYMax = recMultiPoint.getYMax();
break;
case POLYLINE:
PolyLine recPolyLine = (PolyLine) rec;
recXMin = recPolyLine.getXMin();
recYMin = recPolyLine.getYMin();
recXMax = recPolyLine.getXMax();
recYMax = recPolyLine.getYMax();
break;
case POINTZ:
PointZ recPointZ = (PointZ) rec;
recXMin = recPointZ.getX();
recYMin = recPointZ.getY();
recXMax = recXMin;
recYMax = recYMin;
recZMin = recPointZ.getZ();
recZMax = recPointZ.getZ();
recMMin = recPointZ.getM();
recMMax = recPointZ.getM();
break;
case POINTM:
PointM recPointM = (PointM) rec;
recXMin = recPointM.getX();
recYMin = recPointM.getY();
recXMax = recXMin;
recYMax = recYMin;
recMMin = recPointM.getM();
recMMax = recPointM.getM();
break;
case MULTIPOINTM:
MultiPointM recMultiPointM = (MultiPointM) rec;
recXMin = recMultiPointM.getXMin();
recYMin = recMultiPointM.getYMin();
recXMax = recMultiPointM.getXMax();
recYMax = recMultiPointM.getYMax();
recMMin = recMultiPointM.getmMin();
recMMax = recMultiPointM.getmMax();
break;
case POLYLINEM:
PolyLineM recPolyLineM = (PolyLineM) rec;
recXMin = recPolyLineM.getXMin();
recYMin = recPolyLineM.getYMin();
recXMax = recPolyLineM.getXMax();
recYMax = recPolyLineM.getYMax();
recMMin = recPolyLineM.getmMin();
recMMax = recPolyLineM.getmMax();
break;
case MULTIPOINTZ:
MultiPointZ recMultiPointZ = (MultiPointZ) rec;
recXMin = recMultiPointZ.getXMin();
recYMin = recMultiPointZ.getYMin();
recXMax = recMultiPointZ.getXMax();
recYMax = recMultiPointZ.getYMax();
recZMin = recMultiPointZ.getzMin();
recZMax = recMultiPointZ.getzMin();
recMMin = recMultiPointZ.getmMin();
recMMax = recMultiPointZ.getmMax();
break;
case POLYLINEZ:
PolyLineZ recPolyLineZ = (PolyLineZ) rec;
recXMin = recPolyLineZ.getXMin();
recYMin = recPolyLineZ.getYMin();
recXMax = recPolyLineZ.getXMax();
recYMax = recPolyLineZ.getYMax();
recZMin = recPolyLineZ.getzMin();
recZMax = recPolyLineZ.getzMax();
recMMin = recPolyLineZ.getmMin();
recMMax = recPolyLineZ.getmMax();
break;
case POLYGON:
Polygon recPolygon = (Polygon) rec;
recXMin = recPolygon.getXMin();
recYMin = recPolygon.getYMin();
recXMax = recPolygon.getXMax();
recYMax = recPolygon.getYMax();
break;
case POLYGONM:
PolygonM recPolygonM = (PolygonM) rec;
recXMin = recPolygonM.getXMin();
recYMin = recPolygonM.getYMin();
recXMax = recPolygonM.getXMax();
recYMax = recPolygonM.getYMax();
recMMin = recPolygonM.getmMin();
recMMax = recPolygonM.getmMax();
break;
case POLYGONZ:
PolygonZ recPolygonZ = (PolygonZ) rec;
recXMin = recPolygonZ.getXMin();
recYMin = recPolygonZ.getYMin();
recXMax = recPolygonZ.getXMax();
recYMax = recPolygonZ.getYMax();
recZMin = recPolygonZ.getzMin();
recZMax = recPolygonZ.getzMax();
recMMin = recPolygonZ.getmMin();
recMMax = recPolygonZ.getmMax();
break;
case MULTIPATCH:
MultiPatch recMultiPatch = (MultiPatch) rec;
recXMin = recMultiPatch.getXMin();
recYMin = recMultiPatch.getYMin();
recXMax = recMultiPatch.getXMax();
recYMax = recMultiPatch.getYMax();
recZMin = recMultiPatch.getzMin();
recZMax = recMultiPatch.getzMax();
recMMin = recMultiPatch.getmMin();
recMMax = recMultiPatch.getmMax();
break;
}
if (recXMin < xMin) {
xMin = recXMin;
}
if (recYMin < yMin) {
yMin = recYMin;
}
if (recXMax > xMax) {
xMax = recXMax;
}
if (recYMax > yMax) {
yMax = recYMax;
}
if (recZMin < zMin) {
zMin = recZMin;
}
if (recZMax > zMax) {
zMax = recZMax;
}
if (recMMin < mMin) {
mMin = recMMin;
}
if (recMMax > mMax) {
mMax = recMMax;
}
}
return true;
} else {
return false;
}
}
public boolean addRecords(ArrayList<Geometry> recordsGeometry, ArrayList<Object[]> attributeData) {
boolean allRightShapeType = true;
for (Geometry rec : recordsGeometry) {
if (rec.getShapeType() != shapeType) {
allRightShapeType = false;
}
}
if (allRightShapeType) {
if (recordsGeometry.size() != attributeData.size()) {
// there must be an attribute array for each record.
return false;
}
double recXMin = 0, recYMin = 0, recXMax = 0, recYMax = 0,
recZMin = 0, recZMax = 0, recMMin = 0, recMMax = 0;
for (Geometry rec : recordsGeometry) {
numRecs++;
int contentLength = (4 + rec.getLength()) / 2;
ShapeFileRecord sfr = new ShapeFileRecord(numRecs, contentLength,
shapeType, rec);
records.add(sfr);
// update the min and max coordinates
switch (shapeType) {
case POINT:
Point recPoint = (Point) rec;
recXMin = recPoint.getX();
recYMin = recPoint.getY();
recXMax = recXMin;
recYMax = recYMin;
break;
case MULTIPOINT:
MultiPoint recMultiPoint = (MultiPoint) rec;
recXMin = recMultiPoint.getXMin();
recYMin = recMultiPoint.getYMin();
recXMax = recMultiPoint.getXMax();
recYMax = recMultiPoint.getYMax();
break;
case POLYLINE:
PolyLine recPolyLine = (PolyLine) rec;
recXMin = recPolyLine.getXMin();
recYMin = recPolyLine.getYMin();
recXMax = recPolyLine.getXMax();
recYMax = recPolyLine.getYMax();
break;
case POINTZ:
PointZ recPointZ = (PointZ) rec;
recXMin = recPointZ.getX();
recYMin = recPointZ.getY();
recXMax = recXMin;
recYMax = recYMin;
recZMin = recPointZ.getZ();
recZMax = recPointZ.getZ();
recMMin = recPointZ.getM();
recMMax = recPointZ.getM();
break;
case POINTM:
PointM recPointM = (PointM) rec;
recXMin = recPointM.getX();
recYMin = recPointM.getY();
recXMax = recXMin;
recYMax = recYMin;
recMMin = recPointM.getM();
recMMax = recPointM.getM();
break;
case MULTIPOINTM:
MultiPointM recMultiPointM = (MultiPointM) rec;
recXMin = recMultiPointM.getXMin();
recYMin = recMultiPointM.getYMin();
recXMax = recMultiPointM.getXMax();
recYMax = recMultiPointM.getYMax();
recMMin = recMultiPointM.getmMin();
recMMax = recMultiPointM.getmMax();
break;
case POLYLINEM:
PolyLineM recPolyLineM = (PolyLineM) rec;
recXMin = recPolyLineM.getXMin();
recYMin = recPolyLineM.getYMin();
recXMax = recPolyLineM.getXMax();
recYMax = recPolyLineM.getYMax();
recMMin = recPolyLineM.getmMin();
recMMax = recPolyLineM.getmMax();
break;
case MULTIPOINTZ:
MultiPointZ recMultiPointZ = (MultiPointZ) rec;
recXMin = recMultiPointZ.getXMin();
recYMin = recMultiPointZ.getYMin();
recXMax = recMultiPointZ.getXMax();
recYMax = recMultiPointZ.getYMax();
recZMin = recMultiPointZ.getzMin();
recZMax = recMultiPointZ.getzMin();
recMMin = recMultiPointZ.getmMin();
recMMax = recMultiPointZ.getmMax();
break;
case POLYLINEZ:
PolyLineZ recPolyLineZ = (PolyLineZ) rec;
recXMin = recPolyLineZ.getXMin();
recYMin = recPolyLineZ.getYMin();
recXMax = recPolyLineZ.getXMax();
recYMax = recPolyLineZ.getYMax();
recZMin = recPolyLineZ.getzMin();
recZMax = recPolyLineZ.getzMax();
recMMin = recPolyLineZ.getmMin();
recMMax = recPolyLineZ.getmMax();
break;
case POLYGON:
Polygon recPolygon = (Polygon) rec;
recXMin = recPolygon.getXMin();
recYMin = recPolygon.getYMin();
recXMax = recPolygon.getXMax();
recYMax = recPolygon.getYMax();
break;
case POLYGONM:
PolygonM recPolygonM = (PolygonM) rec;
recXMin = recPolygonM.getXMin();
recYMin = recPolygonM.getYMin();
recXMax = recPolygonM.getXMax();
recYMax = recPolygonM.getYMax();
recMMin = recPolygonM.getmMin();
recMMax = recPolygonM.getmMax();
break;
case POLYGONZ:
PolygonZ recPolygonZ = (PolygonZ) rec;
recXMin = recPolygonZ.getXMin();
recYMin = recPolygonZ.getYMin();
recXMax = recPolygonZ.getXMax();
recYMax = recPolygonZ.getYMax();
recZMin = recPolygonZ.getzMin();
recZMax = recPolygonZ.getzMax();
recMMin = recPolygonZ.getmMin();
recMMax = recPolygonZ.getmMax();
break;
case MULTIPATCH:
MultiPatch recMultiPatch = (MultiPatch) rec;
recXMin = recMultiPatch.getXMin();
recYMin = recMultiPatch.getYMin();
recXMax = recMultiPatch.getXMax();
recYMax = recMultiPatch.getYMax();
recZMin = recMultiPatch.getzMin();
recZMax = recMultiPatch.getzMax();
recMMin = recMultiPatch.getmMin();
recMMax = recMultiPatch.getmMax();
break;
}
if (recXMin < xMin) {
xMin = recXMin;
}
if (recYMin < yMin) {
yMin = recYMin;
}
if (recXMax > xMax) {
xMax = recXMax;
}
if (recYMax > yMax) {
yMax = recYMax;
}
if (recZMin < zMin) {
zMin = recZMin;
}
if (recZMax > zMax) {
zMax = recZMax;
}
if (recMMin < mMin) {
mMin = recMMin;
}
if (recMMax > mMax) {
mMax = recMMax;
}
}
try {
for (Object[] rowData : attributeData) {
this.attributeTable.addRecord(rowData);
}
} catch (Exception e) {
return false;
}
return true;
} else {
return false;
}
}
/**
* Used to retrieve a particular record.
*
* @param recordNumber The zero-based record number.
* @return A ShapeFileRecord corresponding with the record number.
*/
public ShapeFileRecord getRecord(int recordNumber) {
return records.get(recordNumber);
}
public void deleteRecord(int recordNumber) {
try {
String tempFile = StringUtilities.replaceLast(fileName, ".shp", "_temp.shp");
DBFField fields[] = this.attributeTable.getAllFields();
ShapeFile tempShape = new ShapeFile(tempFile, this.shapeType, fields);
int i = 0;
for (ShapeFileRecord record : this.records) {
if (record.getRecordNumber() != recordNumber) {
tempShape.addRecord(record.getGeometry(), attributeTable.getRecord(i));
}
i++;
}
tempShape.write();
Path source = Paths.get(tempFile);
Path target = Paths.get(fileName);
Files.move(source, target, REPLACE_EXISTING);
source = Paths.get(tempShape.getDatabaseFile());
target = Paths.get(this.databaseFile);
Files.move(source, target, REPLACE_EXISTING);
source = Paths.get(tempShape.getIndexFile());
target = Paths.get(this.indexFile);
Files.move(source, target, REPLACE_EXISTING);
// reload the data files.
setFileName(fileName);
this.indexFile = StringUtilities.replaceLast(fileName, ".shp", ".shx");
setProjectionFile(StringUtilities.replaceLast(fileName, ".shp", ".prj"));
setDatabaseFile(StringUtilities.replaceLast(fileName, ".shp", ".dbf"));
// see if the databaseFile exists.
databaseFileExists = (new File(databaseFile)).exists();
if (databaseFileExists) {
this.attributeTable = new AttributeTable(databaseFile);
}
} catch (Exception e) {
System.out.println("ShapeFile.deleteRecord Error: " + e.getMessage());
}
}
private boolean readRecords() {
int pos;
int recordNumber, contentLength;
ShapeType recShapeType;
RandomAccessFile rIn = null;
ByteBuffer buf;
try {
records.clear();
// See if the data file exists.
File file = new File(fileName);
if (!file.exists()) {
return false;
}
buf = ByteBuffer.allocate(fileLength * 2);
rIn = new RandomAccessFile(fileName, "r");
FileChannel inChannel = rIn.getChannel();
inChannel.position(0);
inChannel.read(buf);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.rewind();
// read the records into an arraylist of ShapeFileRecords
pos = 100;
buf.rewind();
byte[] data;
int i = 0;
int contentLenInBytes;
while (pos < fileLength * 2) {
recordNumber = ByteSwapper.swap(buf.getInt(pos));
contentLength = ByteSwapper.swap(buf.getInt(pos + 4));
contentLenInBytes = contentLength * 2 - 4; // the minus four is to exclude the recShapeType
recShapeType = getShapeTypeFromInt(buf.getInt(pos + 8));
data = new byte[contentLenInBytes];
buf.position(pos + 12);
buf.get(data, 0, contentLenInBytes);
records.add(new ShapeFileRecord(recordNumber, contentLength, recShapeType, data));
//records[i] = new ShapeFileRecord(recordNumber, contentLength, recShapeType, data);
pos += 8 + contentLength * 2;
i++;
}
numRecs = records.size();
try {
rIn.close();
} catch (Exception e) {
}
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}// finally {
//if (rIn != null) {
// try {
// rIn.close();
// } catch (Exception e) {
// }
//}
//}
}
/**
* Returns an ArrayList of ShapeFileRecords that are within an area
* described by a BoundingBox, which usually corresponds with a mapped area.
*
* @param box The bounding box describing the extent of the area into which
* the data will be mapped.
* @param minSize The minimum size of feature to be mapped, in map units.
* This is based on the size of a single pixel, in map units, which is
* affected by the scale of the map.
* @return An array list of ShapeFileRecords that intersect with the map
* area bounding box and that are larger than the minimum size..
*/
public ArrayList<ShapeFileRecord> getRecordsInBoundingBox(BoundingBox box, double minSize) {
ArrayList<ShapeFileRecord> recs = new ArrayList<>();
// first see if the bounding box for the entire shapefile fits within box
BoundingBox myBox = new BoundingBox(xMin, yMin, xMax, yMax);
if (box.contains(myBox)) {
// just return all of the records
for (ShapeFileRecord sfr : records) {
recs.add(sfr);
}
return recs;
}
if (myBox.overlaps(box)) {
for (ShapeFileRecord sfr : records) {
Geometry sfrGeom = sfr.getGeometry();
if (sfrGeom != null) {
if (sfrGeom.isMappable(box, minSize)) {
recs.add(sfr);
}
}
}
return recs;
} else {
// it doesn't overlap with box at all and null is returned.
return null;
}
}
public ArrayList<ShapeFileRecord> clipRecordsToBoundingBox(BoundingBox box, double minSize) {
ArrayList<ShapeFileRecord> recs = new ArrayList<>();
// first see if the bounding box for the entire shapefile fits within box
BoundingBox myBox = new BoundingBox(xMin, yMin, xMax, yMax);
if (box.contains(myBox)) {
// just return all of the records
for (ShapeFileRecord sfr : records) {
recs.add(sfr);
}
return recs;
}
if (myBox.overlaps(box)) {
for (ShapeFileRecord sfr : records) {
Geometry sfrGeometry = sfr.getGeometry();
if (sfrGeometry.isMappable(box, minSize)) {
// does it need to be clipped?
if (!sfrGeometry.needsClipping(box)) {
recs.add(sfr);
} else {
}
}
}
return recs;
} else {
// it doesn't overlap with box at all and null is returned.
return null;
}
}
/**
* Gets the AttributeTable object associated with this ShapeFile. If no
* database exists for this ShapeFile null will be returned.
*
* @return AttributeTable object or null
*/
public AttributeTable getAttributeTable() {
return this.attributeTable;
}
public String[] getAttributeTableFields() {
// try {
if (databaseFileExists) {
// DBFReader reader = new DBFReader(databaseFile);
try {
AttributeTable reader = new AttributeTable(databaseFile);
//DBFReader reader = new DBFReader( inputStream);
// get the field count if you want for some reasons like the following
//
int numberOfFields = reader.getFieldCount();
String[] ret = new String[numberOfFields];
for (int i = 0; i < numberOfFields; i++) {
DBFField field = reader.getField(i);
ret[i] = field.getName();
}
return ret;
} catch (Exception e) {
return null;
}
} else {
// return an empty string array
return new String[1];
}
// // Now, lets us start reading the rows
// //
// Object[] rowObjects;
//
// while ((rowObjects = reader.nextRecord()) != null) {
//
// for (int i = 0; i < rowObjects.length; i++) {
//
// System.out.println(rowObjects[i]);
// }
// }
// } catch (DBFException dbfe) {
// System.out.println(dbfe);
// return null;
// }
}
// private boolean readDatabaseFile() {
// try {
//// DBFReader reader = new DBFReader(databaseFile);
////
//// //DBFReader reader = new DBFReader( inputStream);
////
//// // get the field count if you want for some reasons like the following
//// //
//// int numberOfFields = reader.getFieldCount();
////
//// // use this count to fetch all field information
//// // if required
//// //
//// for (int i = 0; i < numberOfFields; i++) {
////
//// DBFField field = reader.getField(i);
////
//// // do something with it if you want
//// // refer the JavaDoc API reference for more details
//// //
//// System.out.println(field.getName());
//// }
////
//// // Now, lets us start reading the rows
//// //
//// Object[] rowObjects;
////
//// while ((rowObjects = reader.nextRecord()) != null) {
////
//// for (int i = 0; i < rowObjects.length; i++) {
////
//// System.out.println(rowObjects[i]);
//// }
//// }
//
// return true;
// } catch (DBFException dbfe) {
// System.out.println(dbfe);
// return false;
// }
// }
private void readProjectionFile() {
// this method still needs work to enable parsing of a WKT file.
boolean wktFormat = false;
DataInputStream in = null;
BufferedReader br = null;
try {
// see if the projection file exists
File projFile = new File(projectionFile);
if (!projFile.exists()) {
//System.out.println("The projection file could not be located.");
return;
}
// Open the file
FileInputStream fstream = new FileInputStream(projectionFile);
// Get the object of DataInputStream
in = new DataInputStream(fstream);
br = new BufferedReader(new InputStreamReader(in));
if (projectionFile != null) {
String line;
//Read File Line By Line
while ((line = br.readLine()) != null) {
// is it in WKT format?
if (line.toLowerCase().endsWith("unit[\"meter\",1.0]]")) {
xyUnits = "metres";
}
if (line.toLowerCase().contains("unit")) {
int j = line.toLowerCase().indexOf("unit");
int k = line.toLowerCase().indexOf("[", j);
//System.out.println(line);
}
if (line.contains("[") || line.contains("(")) {
// it is in WKT format
wktFormat = true;
// first make sure that it contains square and not round brackets
line = line.replace("(", "[");
line = line.replace(")", "]");
// String[] str = line.split(",");
// for (int i = 0; i < str.length; i++) {
// System.out.println(str[i]);
// }
} else {
// it is in the older format for .prj files.
}
//str = line.split("\t");
//System.out.println(line);
}
//Close the input stream
in.close();
br.close();
}
} catch (java.io.IOException e) {
System.err.println("Error: " + e.getMessage());
} catch (Exception e) { //Catch exception if any
System.err.println("Error: " + e.getMessage());
} finally {
try {
if (in != null || br != null) {
in.close();
br.close();
}
} catch (java.io.IOException ex) {
}
}
}
private String getTabString(int i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i; j++) {
sb.append("\t");
}
return sb.toString();
}
public boolean areGeometriesEqual(ShapeFile other) {
if (other.getNumberOfRecords() != this.getNumberOfRecords()) {
return false;
}
if (other.getShapeType() != this.getShapeType()) {
return false;
}
int numRecords = this.getNumberOfRecords();
double[][] thisPoints;
double[][] otherPoints;
for (int a = 0; a < numRecords; a++) {
thisPoints = this.getRecord(a).getGeometry().getPoints();
otherPoints = other.getRecord(a).getGeometry().getPoints();
if (thisPoints.length != otherPoints.length) {
return false;
} else {
for (int b = 0; b < thisPoints.length; b++) {
if (thisPoints[b][0] != otherPoints[b][0]
|| thisPoints[b][1] != otherPoints[b][1]) {
return false;
}
}
}
}
return true;
}
public void refreshAttributeTable() {
try {
this.attributeTable = new AttributeTable(databaseFile);
} catch (Exception e) {
}
}
public KdTree<Integer> getKdTree() {
// figure out how many nodes there are
int nodes = 0;
for (ShapeFileRecord rec : records) {
double[][] points = rec.getGeometry().getPoints();
nodes += points.length;
}
KdTree<Integer> kdTree = new KdTree.SqrEuclid<>(2, new Integer(nodes));
int recNum;
for (ShapeFileRecord rec : records) {
recNum = rec.getRecordNumber() - 1;
double[][] points = rec.getGeometry().getPoints();
for (int p = 0; p < points.length; p++) {
double[] entry = {points[p][0], points[p][1]};
kdTree.addPoint(entry, recNum);
}
}
return kdTree;
}
// // this is only used for debugging the tool
// public static void main(String[] args) {
//
// // reading shapefiles test
//
//// //String fileName = "/Users/johnlindsay/Documents/Data/Marvin-UofG-20111005-Order2133/SWOOP 2010/DEM - Masspoints and Breaklines - 400km_ZIP_UTM17_50cm_XXbands_0bits/20km174000471002010MAPCON/20km17400047100_masspoints.shp";
//// //String fileName = "/Users/johnlindsay/Documents/Data/ShapeFiles/NTDB_roads_rmow.shp";
//// String fileName = "/Users/johnlindsay/Documents/Data/ShapeFiles/Water_Body_rmow.shp";
////
//// ShapeFile shp = new ShapeFile(fileName);
////
//// System.out.println("ShapeFile info");
//// System.out.println("Number of records: " + shp.getNumberOfRecords());
//// ShapeFileRecord rec = shp.getRecord(0);
//// System.out.println("Record number: " + rec.getRecordNumber());
//// System.out.println("Shape Type: " + rec.getShapeType() + ", Length: " + rec.getContentLength());
//// System.out.println(rec.getGeometry().getClass());
//// if (rec.getShapeType() == ShapeType.POINTZ) {
//// PointZ pt = (PointZ)(rec.getGeometry());
//// System.out.println(rec.getGeometry().getClass());
//// System.out.println(pt.getZ());
//// } else if (rec.getShapeType() == ShapeType.POLYLINE) {
//// PolyLine pl = (PolyLine)(rec.getGeometry());
//// System.out.println("First point x: " + pl.getPoints()[0][0] + " First point y: " + pl.getPoints()[0][1]);
//// }
//
// // writing shapefiles test
// String fileName = "/Users/johnlindsay/Documents/Data/tmp2.shp";
// //ShapeFile shp = new ShapeFile(fileName, ShapeType.POINT);
// ShapeFile shp = new ShapeFile(fileName, ShapeType.POLYLINE);
// shp.deleteFiles();
//// ArrayList<Geometry> pnts = new ArrayList<Geometry>();
//// Random generator = new Random();
//// double x, y;
////
//// for (int i = 0; i < 500; i++) {
//// x = generator.nextInt(1000);
//// y = generator.nextInt(600);
//// pnts.add(new Point(x, y));
//// }
//// shp.addRecords(pnts);
//
// ArrayList<Geometry> lines = new ArrayList<Geometry>();
// int[] parts = {0, 6};
// //double[][] points = new double[11][2];
// PointsList pl = new PointsList();
// // pentagon
// pl.addPoint(50, 100);
// pl.addPoint(100, 75);
// pl.addPoint(75, 0);
// pl.addPoint(25, 0);
// pl.addPoint(0, 75);
// pl.addPoint(50, 100);
// //square
// pl.addPoint(25, 75);
// pl.addPoint(25, 25);
// pl.addPoint(75, 25);
// pl.addPoint(75, 75);
// pl.addPoint(25, 75);
//
// lines.add(new PolyLine(parts, pl.getPointsArray()));
//
// shp.addRecords(lines);
// try {
// shp.write();
// } catch (IOException ioe) {
//
// }
// // now read it in
// //ShapeFile shp2 = new ShapeFile(fileName);
// }
}