/* * 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.shapefile; import java.nio.ByteBuffer; import java.nio.ByteOrder; import whitebox.utilities.ByteSwapper; /** * * @author Dr. John Lindsay email: jlindsay@uoguelph.ca */ public class ShapeFileRecord { private int recordNumber; private int contentLength; private ShapeType shapeType; // notice that the shape type is not officially part of the // record header, but that it is the starting part of each shapeType and as such // is effectively a component of the header. private Geometry data; private boolean pointType; /** * Constructors. */ public ShapeFileRecord() { } /** * Constructor. * @param recordNumber * @param contentLength content length in 16-bit words. * @param shapeType * @param rawData */ public ShapeFileRecord(int recordNumber, int contentLength, ShapeType shapeType, byte[] rawData) { this.recordNumber = recordNumber; this.contentLength = contentLength; this.shapeType = shapeType; this.pointType = false; switch (shapeType) { case POINT: this.data = new whitebox.geospatialfiles.shapefile.Point(rawData); this.pointType = true; break; case MULTIPOINT: this.data = new MultiPoint(rawData); this.pointType = true; break; case POLYLINE: this.data = new PolyLine(rawData); break; case POINTZ: this.data = new PointZ(rawData); this.pointType = true; break; case POINTM: this.data = new PointM(rawData); this.pointType = true; break; case MULTIPOINTM: this.data = new MultiPointM(rawData); this.pointType = true; break; case POLYLINEM: this.data = new PolyLineM(rawData); break; case MULTIPOINTZ: this.data = new MultiPointZ(rawData); this.pointType = true; break; case POLYLINEZ: this.data = new PolyLineZ(rawData); break; case POLYGON: this.data = new Polygon(rawData); break; case POLYGONM: this.data = new PolygonM(rawData); break; case POLYGONZ: this.data = new PolygonZ(rawData); break; case MULTIPATCH: this.data = new MultiPatch(rawData); break; case NULLSHAPE: this.data = null; break; default: System.err.println("Shape type not recognized."); break; } } public ShapeFileRecord(int recordNumber, int contentLength, ShapeType shapeType, Geometry geom) { this.recordNumber = recordNumber; this.contentLength = contentLength; this.shapeType = shapeType; this.data = geom; switch (shapeType) { case POINT: case MULTIPOINT: case POINTZ: case POINTM: case MULTIPOINTM: case MULTIPOINTZ: this.pointType = true; break; case POLYLINE: case POLYLINEZ: case POLYLINEM: case POLYGON: case POLYGONM: case POLYGONZ: case MULTIPATCH: case NULLSHAPE: this.pointType = false; break; } } // properties public int getContentLength() { return contentLength; } public void setContentLength(int contentLength) { this.contentLength = contentLength; } public int getRecordNumber() { return recordNumber; } public void setRecordNumber(int recordNumber) { this.recordNumber = recordNumber; } public ShapeType getShapeType() { return shapeType; } public void setShapeType(ShapeType shapeType) { this.shapeType = shapeType; } public Geometry getGeometry() { return data; } public boolean isPointType() { return pointType; } // methods /** * This is used by the ShapeFile class to get convert the current data * contained in this object into a bytebuffer than can then be written to * disc. * @return A ByteBuffer representation of this object. */ public byte[] toBytes() { ByteBuffer geometryByteBuffer = data.toByteBuffer(); geometryByteBuffer.rewind(); int size = 12 + geometryByteBuffer.capacity(); ByteBuffer buf = ByteBuffer.allocate(size); buf.order(ByteOrder.LITTLE_ENDIAN); buf.rewind(); buf.putInt(ByteSwapper.swap(recordNumber)); buf.putInt(ByteSwapper.swap(contentLength)); buf.putInt(getIntFromShapeType(shapeType)); byte[] bytes = geometryByteBuffer.array(); for (int i = 0; i < bytes.length; i++) { buf.put(bytes[i]); //i + 12, } //buf.put(bytes); return buf.array(); } public int getLength() { return 12 + data.getLength(); // 12 is the size of the recordNumber, // contentLength, and shapeType. } 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[] getPartDataFromRecord() { // // } // // public double[][] getXYGeometryFromRecord() { // if (data == null) { return null; } // double[][] ret; // ShapeType shapeType = this.getShapeType(); // switch (shapeType) { // case POLYLINE: // whitebox.geospatialfiles.shapefile.PolyLine recPolyLine = // (whitebox.geospatialfiles.shapefile.PolyLine) (data); // ret = recPolyLine.getPoints(); // partData = recPolyLine.getParts(); // break; // case POLYLINEZ: // PolyLineZ recPolyLineZ = (PolyLineZ) (data); // ret = recPolyLineZ.getPoints(); // partData = recPolyLineZ.getParts(); // break; // case POLYLINEM: // PolyLineM recPolyLineM = (PolyLineM) (data); // ret = recPolyLineM.getPoints(); // partData = recPolyLineM.getParts(); // break; // case POLYGON: // Polygon recPolygon = (Polygon) (data); // ret = recPolygon.getPoints(); // partData = recPolygon.getParts(); // break; // case POLYGONZ: // PolygonZ recPolygonZ = (PolygonZ) (data); // ret = recPolygonZ.getPoints(); // partData = recPolygonZ.getParts(); // break; // case POLYGONM: // PolygonM recPolygonM = (PolygonM) (data); // ret = recPolygonM.getPoints(); // partData = recPolygonM.getParts(); // break; // default: // ret = new double[1][2]; // ret[1][0] = -1; // ret[1][1] = -1; // break; // } // // return ret; // } }