001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/shpapi/SHPPolyLine.java $ 002 003 /*---------------------------------------------------------------------------- 004 This file is part of deegree, http://deegree.org/ 005 Copyright (C) 2001-2009 by: 006 Department of Geography, University of Bonn 007 and 008 lat/lon GmbH 009 010 This library is free software; you can redistribute it and/or modify it under 011 the terms of the GNU Lesser General Public License as published by the Free 012 Software Foundation; either version 2.1 of the License, or (at your option) 013 any later version. 014 This library is distributed in the hope that it will be useful, but WITHOUT 015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 016 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 017 details. 018 You should have received a copy of the GNU Lesser General Public License 019 along with this library; if not, write to the Free Software Foundation, Inc., 020 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 021 022 Contact information: 023 024 lat/lon GmbH 025 Aennchenstr. 19, 53177 Bonn 026 Germany 027 http://lat-lon.de/ 028 029 Department of Geography, University of Bonn 030 Prof. Dr. Klaus Greve 031 Postfach 1147, 53001 Bonn 032 Germany 033 http://www.geographie.uni-bonn.de/deegree/ 034 035 e-mail: info@deegree.org 036 ----------------------------------------------------------------------------*/ 037 038 package org.deegree.io.shpapi; 039 040 import org.deegree.model.spatialschema.ByteUtils; 041 import org.deegree.model.spatialschema.Curve; 042 import org.deegree.model.spatialschema.LineString; 043 044 /** 045 * Class representig a two dimensional ESRI PolyLine<BR> 046 * 047 * 048 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 049 * @author last edited by: $Author: mschneider $ 050 * 051 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 052 */ 053 public class SHPPolyLine extends SHPGeometry { 054 055 /** 056 * 057 */ 058 public int numParts; 059 060 /** 061 * 062 */ 063 public int numPoints; 064 065 /** 066 * 067 */ 068 public SHPPoint[][] points = null; 069 070 /** 071 * constructor: gets a stream <BR> 072 * 073 * @param recBuf 074 */ 075 public SHPPolyLine( byte[] recBuf ) { 076 077 // constructor invocation 078 super( recBuf ); 079 080 int pointsStart = 0; 081 int sumPoints = 0; 082 083 envelope = ShapeUtils.readBox( recBuf, 4 ); 084 085 numParts = ByteUtils.readLEInt( recBuffer, 36 ); 086 numPoints = ByteUtils.readLEInt( recBuffer, 40 ); 087 088 pointsStart = ShapeConst.PARTS_START + ( numParts * 4 ); 089 090 points = new SHPPoint[numParts][]; 091 092 for ( int j = 0; j < numParts; j++ ) { 093 094 int firstPointNo = 0; 095 int nextFirstPointNo = 0; 096 int offset = 0; 097 int lnumPoints = 0; 098 099 // get number of first point of current part out of ESRI shape Record: 100 firstPointNo = ByteUtils.readLEInt( recBuffer, ShapeConst.PARTS_START + ( j * 4 ) ); 101 102 // calculate offset of part in bytes, count from the beginning of recordbuffer 103 offset = pointsStart + ( firstPointNo * 16 ); 104 105 // get number of first point of next part ... 106 if ( j < numParts - 1 ) { 107 // ... usually out of ESRI shape Record 108 nextFirstPointNo = ByteUtils.readLEInt( recBuffer, ShapeConst.PARTS_START + ( ( j + 1 ) * 4 ) ); 109 } 110 // ... for the last part as total number of points 111 else if ( j == numParts - 1 ) { 112 nextFirstPointNo = numPoints; 113 } 114 115 // calculate number of points per part due to distance and 116 // calculate some checksum for the total number of points to be worked 117 lnumPoints = nextFirstPointNo - firstPointNo; 118 sumPoints += lnumPoints; 119 120 // allocate memory for the j-th part 121 points[j] = new SHPPoint[lnumPoints]; 122 123 // create the points of the j-th part from the buffer 124 for ( int i = 0; i < lnumPoints; i++ ) { 125 points[j][i] = new SHPPoint( recBuf, offset + ( i * 16 ) ); 126 } 127 128 } 129 130 } 131 132 /** 133 * constructor: recieves a matrix of Points <BR> 134 * 135 * @param curve 136 */ 137 public SHPPolyLine( Curve[] curve ) { 138 139 double xmin = curve[0].getEnvelope().getMin().getX(); 140 double xmax = curve[0].getEnvelope().getMax().getX(); 141 double ymin = curve[0].getEnvelope().getMin().getY(); 142 double ymax = curve[0].getEnvelope().getMax().getY(); 143 144 numParts = curve.length; 145 146 numPoints = 0; 147 148 points = new SHPPoint[numParts][]; 149 150 try { 151 // create SHPPoints from the Points array 152 for ( int i = 0; i < numParts; i++ ) { 153 154 LineString ls = curve[i].getAsLineString(); 155 156 numPoints += ls.getNumberOfPoints(); 157 158 points[i] = new SHPPoint[ls.getNumberOfPoints()]; 159 160 for ( int j = 0; j < ls.getNumberOfPoints(); j++ ) { 161 points[i][j] = new SHPPoint( ls.getPositionAt( j ) ); 162 if ( points[i][j].x > xmax ) { 163 xmax = points[i][j].x; 164 } else if ( points[i][j].x < xmin ) { 165 xmin = points[i][j].x; 166 } 167 if ( points[i][j].y > ymax ) { 168 ymax = points[i][j].y; 169 } else if ( points[i][j].y < ymin ) { 170 ymin = points[i][j].y; 171 } 172 } 173 174 } 175 } catch ( Exception e ) { 176 e.printStackTrace(); 177 } 178 179 envelope = new SHPEnvelope( xmin, xmax, ymax, ymin ); 180 } 181 182 /** 183 * 184 * @param bytearray 185 * @param start 186 */ 187 public void writeSHPPolyLine( byte[] bytearray, int start ) { 188 189 int offset = start; 190 191 double xmin = points[0][0].x; 192 double xmax = points[0][0].x; 193 double ymin = points[0][0].y; 194 double ymax = points[0][0].y; 195 196 // write shape type identifier ( 3 = polyline ) 197 ByteUtils.writeLEInt( bytearray, offset, 3 ); 198 199 offset += 4; 200 // save offset of the bounding box 201 int tmp1 = offset; 202 203 // increment offset with size of the bounding box 204 offset += ( 4 * 8 ); 205 206 // write numparts 207 ByteUtils.writeLEInt( bytearray, offset, numParts ); 208 offset += 4; 209 // write numpoints 210 ByteUtils.writeLEInt( bytearray, offset, numPoints ); 211 offset += 4; 212 213 // save offset of the list of offsets for each polyline 214 int tmp2 = offset; 215 216 // increment offset with numParts 217 offset += ( 4 * numParts ); 218 219 int count = 0; 220 for ( int i = 0; i < points.length; i++ ) { 221 222 // stores the index of the i'th part 223 ByteUtils.writeLEInt( bytearray, tmp2, count ); 224 tmp2 += 4; 225 226 // write the points of the i'th part and calculate bounding box 227 for ( int j = 0; j < points[i].length; j++ ) { 228 229 count++; 230 231 // calculate bounding box 232 if ( points[i][j].x > xmax ) { 233 xmax = points[i][j].x; 234 } else if ( points[i][j].x < xmin ) { 235 xmin = points[i][j].x; 236 } 237 238 if ( points[i][j].y > ymax ) { 239 ymax = points[i][j].y; 240 } else if ( points[i][j].y < ymin ) { 241 ymin = points[i][j].y; 242 } 243 244 // write x-coordinate 245 ByteUtils.writeLEDouble( bytearray, offset, points[i][j].x ); 246 offset += 8; 247 248 // write y-coordinate 249 ByteUtils.writeLEDouble( bytearray, offset, points[i][j].y ); 250 offset += 8; 251 252 } 253 254 } 255 256 // jump back to the offset of the bounding box 257 offset = tmp1; 258 259 // write bounding box to the byte array 260 ByteUtils.writeLEDouble( bytearray, offset, xmin ); 261 offset += 8; 262 ByteUtils.writeLEDouble( bytearray, offset, ymin ); 263 offset += 8; 264 ByteUtils.writeLEDouble( bytearray, offset, xmax ); 265 offset += 8; 266 ByteUtils.writeLEDouble( bytearray, offset, ymax ); 267 268 } 269 270 /** 271 * returns the polyline shape size in bytes<BR> 272 * 273 * @return the polyline shape size in bytes 274 */ 275 public int size() { 276 return 44 + numParts * 4 + numPoints * 16; 277 } 278 279 }