/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.io.shpapi; import org.deegree.model.spatialschema.ByteUtils; import org.deegree.model.spatialschema.Curve; import org.deegree.model.spatialschema.LineString; /** * Class representig a two dimensional ESRI PolyLine<BR> * * @version 16.08.2000 * @author Andreas Poth */ public class SHPPolyLine extends SHPGeometry { public int numParts; public int numPoints; /** * * @uml.property name="points" * @uml.associationEnd multiplicity="(0 -1)" */ public SHPPoint[][] points = null; /** * constructor: gets a stream <BR> */ public SHPPolyLine(byte[] recBuf) { // constructor invocation super(recBuf); int pointsStart = 0; int sumPoints = 0; envelope = ShapeUtils.readBox(recBuf,4); numParts = ByteUtils.readLEInt(recBuffer, 36); numPoints = ByteUtils.readLEInt(recBuffer, 40); pointsStart = ShapeConst.PARTS_START + (numParts * 4); points = new SHPPoint[numParts][]; for (int j = 0; j < numParts; j++) { int firstPointNo= 0; int nextFirstPointNo= 0; int offset= 0; int lnumPoints= 0; // get number of first point of current part out of ESRI shape Record: firstPointNo = ByteUtils.readLEInt(recBuffer,ShapeConst.PARTS_START + (j * 4)); // calculate offset of part in bytes, count from the beginning of recordbuffer offset = pointsStart + (firstPointNo * 16); // get number of first point of next part ... if (j < numParts-1) { // ... usually out of ESRI shape Record nextFirstPointNo= ByteUtils.readLEInt(recBuffer,ShapeConst.PARTS_START + ((j+1) * 4)); } //... for the last part as total number of points else if (j == numParts-1) { nextFirstPointNo = numPoints; } // calculate number of points per part due to distance and // calculate some checksum for the total number of points to be worked lnumPoints = nextFirstPointNo - firstPointNo; sumPoints += lnumPoints; // allocate memory for the j-th part points[j] = new SHPPoint[lnumPoints]; // create the points of the j-th part from the buffer for (int i=0; i < lnumPoints; i++) { points[j][i]= new SHPPoint(recBuf, offset + (i*16)); } } } /** * constructor: recieves a matrix of Points <BR> */ public SHPPolyLine(Curve[] curve) { double xmin = curve[0].getEnvelope().getMin().getX(); double xmax = curve[0].getEnvelope().getMax().getX(); double ymin = curve[0].getEnvelope().getMin().getY(); double ymax = curve[0].getEnvelope().getMax().getY(); numParts = curve.length; numPoints = 0; points = new SHPPoint[numParts][]; try { // create SHPPoints from the Points array for (int i = 0; i < numParts; i++) { LineString ls = curve[i].getAsLineString(); numPoints += ls.getNumberOfPoints(); points[i] = new SHPPoint[ls.getNumberOfPoints()]; for (int j = 0; j < ls.getNumberOfPoints(); j++) { points[i][j] = new SHPPoint( ls.getPositionAt(j) ); if (points[i][j].x > xmax) { xmax = points[i][j].x; } else if (points[i][j].x < xmin) { xmin = points[i][j].x; } if (points[i][j].y > ymax) { ymax = points[i][j].y; } else if (points[i][j].y < ymin) { ymin = points[i][j].y; } } } } catch(Exception e) { e.printStackTrace(); } envelope = new SHPEnvelope(xmin,xmax,ymax,ymin); } /** * method: writeSHPPolyLine(byte[] bytearray, int start)<BR> */ public void writeSHPPolyLine(byte[] bytearray, int start) { int offset = start; double xmin = points[0][0].x; double xmax = points[0][0].x; double ymin = points[0][0].y; double ymax = points[0][0].y; // write shape type identifier ( 3 = polyline ) ByteUtils.writeLEInt(bytearray, offset, 3); offset += 4; // save offset of the bounding box int tmp1 = offset; // increment offset with size of the bounding box offset += (4*8); // write numparts ByteUtils.writeLEInt(bytearray, offset, numParts); offset += 4; // write numpoints ByteUtils.writeLEInt(bytearray, offset, numPoints); offset += 4; // save offset of the list of offsets for each polyline int tmp2 = offset; // increment offset with numParts offset += (4*numParts); int count = 0; for (int i = 0; i < points.length; i++) { // stores the index of the i'th part ByteUtils.writeLEInt(bytearray, tmp2 , count); tmp2 += 4; // write the points of the i'th part and calculate bounding box for (int j = 0; j < points[i].length; j++) { count++; // calculate bounding box if (points[i][j].x > xmax) { xmax = points[i][j].x; } else if (points[i][j].x < xmin) { xmin = points[i][j].x; } if (points[i][j].y > ymax) { ymax = points[i][j].y; } else if (points[i][j].y < ymin) { ymin = points[i][j].y; } // write x-coordinate ByteUtils.writeLEDouble(bytearray, offset, points[i][j].x); offset += 8; // write y-coordinate ByteUtils.writeLEDouble(bytearray, offset, points[i][j].y); offset += 8; } } // jump back to the offset of the bounding box offset = tmp1; // write bounding box to the byte array ByteUtils.writeLEDouble(bytearray, offset, xmin); offset += 8; ByteUtils.writeLEDouble(bytearray, offset, ymin); offset += 8; ByteUtils.writeLEDouble(bytearray, offset, xmax); offset += 8; ByteUtils.writeLEDouble(bytearray, offset, ymax); } /** * returns the polyline shape size in bytes<BR> */ public int size() { return 44 + numParts * 4 + numPoints * 16; } } // end of class PolyLine /* * * Last changes: * $Log: SHPPolyLine.java,v $ * Revision 1.9 2006/07/12 14:46:14 poth * comment footer added * * Revision 1.8 2006/04/06 20:25:23 poth * *** empty log message *** * * Revision 1.7 2006/04/04 20:39:41 poth * *** empty log message *** * * Revision 1.6 2006/03/30 21:20:24 poth * *** empty log message *** * * Revision 1.5 2005/12/06 13:45:20 poth * System.out.println substituted by logging api * * Revision 1.4 2005/02/13 21:34:58 friebe * fix javadoc errors * * 12.01.2000 ap: constructor re-declared<BR> * 25.01.2000 ap: public variables numRings and numPoints declared<BR> * 21.03.2000 ap: parameter list of the second constructor modified<BR> * 14.08.2000 ap: constructor SHPPolyLine(Point[][] gm_points) added<BR> * 14.08.2000 ap: method writeSHPPolyline(..) added<BR> * 14.08.2000 ap: method size() added<BR> * 16.08.2000 ap: constructor SHPPolyLine(Point[][] gm_points) modified<BR> */ /* ******************************************************************** Changes to this class. What the people have been up to: $Log: SHPPolyLine.java,v $ Revision 1.9 2006/07/12 14:46:14 poth comment footer added ********************************************************************** */