001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/shpapi/SHPPolygon.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.CurveSegment; 043 import org.deegree.model.spatialschema.GeometryFactory; 044 import org.deegree.model.spatialschema.Ring; 045 import org.deegree.model.spatialschema.Surface; 046 047 /** 048 * Class representig a two dimensional ESRI Polygon<BR> 049 * 050 * @version 16.08.2000 051 * @author Andreas Poth 052 */ 053 public class SHPPolygon extends SHPGeometry { 054 055 /** 056 * 057 */ 058 public int numRings = 0; 059 060 /** 061 * 062 */ 063 public int numPoints = 0; 064 065 /** 066 * 067 */ 068 public SHPPolyLine rings = null; 069 070 /** 071 * constructor: recieves a stream <BR> 072 * @param recBuf 073 */ 074 public SHPPolygon( byte[] recBuf ) { 075 076 super( recBuf ); 077 078 envelope = ShapeUtils.readBox( recBuf, 4 ); 079 080 rings = new SHPPolyLine( recBuf ); 081 082 numPoints = rings.numPoints; 083 numRings = rings.numParts; 084 085 } 086 087 /** 088 * constructor: recieves an array of arrays of Points <BR> 089 * @param surface 090 */ 091 public SHPPolygon( Surface[] surface ) { 092 093 try { 094 int count = 0; 095 096 for ( int i = 0; i < surface.length; i++ ) { 097 // increment for exterior ring 098 count++; 099 // increment for inner rings 100 Ring[] rings = surface[i].getSurfaceBoundary().getInteriorRings(); 101 if ( rings != null ) { 102 count += rings.length; 103 } 104 } 105 106 Curve[] curves = new Curve[count]; 107 108 count = 0; 109 for ( int i = 0; i < surface.length; i++ ) { 110 111 CurveSegment cs = surface[i].getSurfaceBoundary().getExteriorRing().getAsCurveSegment(); 112 curves[count++] = GeometryFactory.createCurve( cs ); 113 114 Ring[] rings = surface[i].getSurfaceBoundary().getInteriorRings(); 115 if ( rings != null ) { 116 for ( int j = 0; j < rings.length; j++ ) { 117 cs = rings[j].getAsCurveSegment(); 118 curves[count++] = GeometryFactory.createCurve( cs ); 119 } 120 } 121 } 122 123 rings = new SHPPolyLine( curves ); 124 125 envelope = rings.envelope; 126 127 numPoints = rings.numPoints; 128 numRings = rings.numParts; 129 130 } catch ( Exception e ) { 131 e.printStackTrace(); 132 } 133 134 } 135 136 /** 137 * method: writeSHPPolygon(byte[] bytearray, int start)<BR> 138 * @param bytearray 139 * @param start 140 * @return the byte array again 141 */ 142 public byte[] writeSHPPolygon( byte[] bytearray, int start ) { 143 144 int offset = start; 145 146 double xmin = rings.points[0][0].x; 147 double xmax = rings.points[0][0].x; 148 double ymin = rings.points[0][0].y; 149 double ymax = rings.points[0][0].y; 150 151 // write shape type identifier 152 ByteUtils.writeLEInt( bytearray, offset, ShapeConst.SHAPE_TYPE_POLYGON ); 153 154 offset += 4; 155 // save offset of the bounding box 156 int tmp1 = offset; 157 158 // increment offset with size of the bounding box 159 offset += ( 4 * 8 ); 160 161 // write numRings 162 ByteUtils.writeLEInt( bytearray, offset, numRings ); 163 offset += 4; 164 // write numpoints 165 ByteUtils.writeLEInt( bytearray, offset, numPoints ); 166 offset += 4; 167 168 // save offset of the list of offsets for each polyline 169 int tmp2 = offset; 170 171 // increment offset with numRings 172 offset += ( 4 * numRings ); 173 174 int count = 0; 175 for ( int i = 0; i < rings.points.length; i++ ) { 176 177 // stores the index of the i'th part 178 ByteUtils.writeLEInt( bytearray, tmp2, count ); 179 tmp2 += 4; 180 181 // write the points of the i'th part and calculate bounding box 182 for ( int j = 0; j < rings.points[i].length; j++ ) { 183 // number of the current point 184 count++; 185 186 // calculate bounding box 187 if ( rings.points[i][j].x > xmax ) { 188 xmax = rings.points[i][j].x; 189 } else if ( rings.points[i][j].x < xmin ) { 190 xmin = rings.points[i][j].x; 191 } 192 193 if ( rings.points[i][j].y > ymax ) { 194 ymax = rings.points[i][j].y; 195 } else if ( rings.points[i][j].y < ymin ) { 196 ymin = rings.points[i][j].y; 197 } 198 199 // write x-coordinate 200 ByteUtils.writeLEDouble( bytearray, offset, rings.points[i][j].x ); 201 offset += 8; 202 203 // write y-coordinate 204 ByteUtils.writeLEDouble( bytearray, offset, rings.points[i][j].y ); 205 offset += 8; 206 207 } 208 209 } 210 211 // jump back to the offset of the bounding box 212 offset = tmp1; 213 214 // write bounding box to the byte array 215 ByteUtils.writeLEDouble( bytearray, offset, xmin ); 216 offset += 8; 217 ByteUtils.writeLEDouble( bytearray, offset, ymin ); 218 offset += 8; 219 ByteUtils.writeLEDouble( bytearray, offset, xmax ); 220 offset += 8; 221 ByteUtils.writeLEDouble( bytearray, offset, ymax ); 222 223 return bytearray; 224 } 225 226 /** 227 * returns the polygon shape size in bytes<BR> 228 * @return the polygon shape size in bytes<BR> 229 */ 230 public int size() { 231 return 44 + numRings * 4 + numPoints * 16; 232 } 233 234 @Override 235 public String toString() { 236 237 return "WKBPOLYGON" + " numRings: " + numRings; 238 239 } 240 }