001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/shpapi/SHPPolygon.java $ 002 003 /*---------------- FILE HEADER ------------------------------------------ 004 005 This file is part of deegree. 006 Copyright (C) 2001-2008 by: 007 EXSE, Department of Geography, University of Bonn 008 http://www.giub.uni-bonn.de/deegree/ 009 lat/lon GmbH 010 http://www.lat-lon.de 011 012 This library is free software; you can redistribute it and/or 013 modify it under the terms of the GNU Lesser General Public 014 License as published by the Free Software Foundation; either 015 version 2.1 of the License, or (at your option) any later version. 016 017 This library is distributed in the hope that it will be useful, 018 but WITHOUT ANY WARRANTY; without even the implied warranty of 019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 020 Lesser General Public License for more details. 021 022 You should have received a copy of the GNU Lesser General Public 023 License along with this library; if not, write to the Free Software 024 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 025 026 Contact: 027 028 Andreas Poth 029 lat/lon GmbH 030 Aennchenstr. 19 031 53115 Bonn 032 Germany 033 E-Mail: poth@lat-lon.de 034 035 Prof. Dr. Klaus Greve 036 Department of Geography 037 University of Bonn 038 Meckenheimer Allee 166 039 53115 Bonn 040 Germany 041 E-Mail: greve@giub.uni-bonn.de 042 043 044 ---------------------------------------------------------------------------*/ 045 046 package org.deegree.io.shpapi; 047 048 import org.deegree.model.spatialschema.ByteUtils; 049 import org.deegree.model.spatialschema.Curve; 050 import org.deegree.model.spatialschema.CurveSegment; 051 import org.deegree.model.spatialschema.GeometryFactory; 052 import org.deegree.model.spatialschema.Ring; 053 import org.deegree.model.spatialschema.Surface; 054 055 /** 056 * Class representig a two dimensional ESRI Polygon<BR> 057 * 058 * @version 16.08.2000 059 * @author Andreas Poth 060 */ 061 public class SHPPolygon extends SHPGeometry { 062 063 public int numRings = 0; 064 public int numPoints = 0; 065 public SHPPolyLine rings = null; 066 067 068 069 /** 070 * constructor: recieves a stream <BR> 071 */ 072 public SHPPolygon(byte[] recBuf) { 073 074 super(recBuf); 075 076 envelope = ShapeUtils.readBox(recBuf,4); 077 078 rings = new SHPPolyLine(recBuf); 079 080 numPoints = rings.numPoints; 081 numRings = rings.numParts; 082 083 } 084 085 /** 086 * constructor: recieves an array of arrays of Points <BR> 087 */ 088 public SHPPolygon(Surface[] surface) { 089 090 try { 091 int count = 0; 092 093 for (int i = 0; i < surface.length; i++) { 094 // increment for exterior ring 095 count++; 096 // increment for inner rings 097 Ring[] rings = surface[i].getSurfaceBoundary().getInteriorRings(); 098 if ( rings != null ) { 099 count += rings.length; 100 } 101 } 102 103 Curve[] curves = new Curve[count]; 104 105 count = 0; 106 for (int i = 0; i < surface.length; i++) { 107 108 CurveSegment cs = 109 surface[i].getSurfaceBoundary().getExteriorRing().getAsCurveSegment(); 110 curves[count++] = GeometryFactory.createCurve( cs ); 111 112 Ring[] rings = surface[i].getSurfaceBoundary().getInteriorRings(); 113 if ( rings != null ) { 114 for (int j = 0; j < rings.length; j++) { 115 cs =rings[j].getAsCurveSegment(); 116 curves[count++] = GeometryFactory.createCurve( cs ); 117 } 118 } 119 } 120 121 rings = new SHPPolyLine(curves); 122 123 envelope = rings.envelope; 124 125 numPoints = rings.numPoints; 126 numRings = rings.numParts; 127 128 } catch(Exception e) { 129 e.printStackTrace(); 130 } 131 132 } 133 134 /** 135 * method: writeSHPPolygon(byte[] bytearray, int start)<BR> 136 */ 137 public byte[] writeSHPPolygon(byte[] bytearray, int start) { 138 139 int offset = start; 140 141 double xmin = rings.points[0][0].x; 142 double xmax = rings.points[0][0].x; 143 double ymin = rings.points[0][0].y; 144 double ymax = rings.points[0][0].y; 145 146 // write shape type identifier 147 ByteUtils.writeLEInt(bytearray, offset, ShapeConst.SHAPE_TYPE_POLYGON); 148 149 offset += 4; 150 // save offset of the bounding box 151 int tmp1 = offset; 152 153 // increment offset with size of the bounding box 154 offset += (4*8); 155 156 // write numRings 157 ByteUtils.writeLEInt(bytearray, offset, numRings); 158 offset += 4; 159 // write numpoints 160 ByteUtils.writeLEInt(bytearray, offset, numPoints); 161 offset += 4; 162 163 // save offset of the list of offsets for each polyline 164 int tmp2 = offset; 165 166 // increment offset with numRings 167 offset += (4*numRings); 168 169 int count = 0; 170 for (int i = 0; i < rings.points.length; i++) { 171 172 // stores the index of the i'th part 173 ByteUtils.writeLEInt(bytearray, tmp2 , count); 174 tmp2 += 4; 175 176 // write the points of the i'th part and calculate bounding box 177 for (int j = 0; j < rings.points[i].length; j++) { 178 // number of the current point 179 count++; 180 181 // calculate bounding box 182 if (rings.points[i][j].x > xmax) { 183 xmax = rings.points[i][j].x; 184 } else if (rings.points[i][j].x < xmin) { 185 xmin = rings.points[i][j].x; 186 } 187 188 if (rings.points[i][j].y > ymax) { 189 ymax = rings.points[i][j].y; 190 } else if (rings.points[i][j].y < ymin) { 191 ymin = rings.points[i][j].y; 192 } 193 194 // write x-coordinate 195 ByteUtils.writeLEDouble(bytearray, offset, rings.points[i][j].x); 196 offset += 8; 197 198 // write y-coordinate 199 ByteUtils.writeLEDouble(bytearray, offset, rings.points[i][j].y); 200 offset += 8; 201 202 } 203 204 } 205 206 // jump back to the offset of the bounding box 207 offset = tmp1; 208 209 // write bounding box to the byte array 210 ByteUtils.writeLEDouble(bytearray, offset, xmin); 211 offset += 8; 212 ByteUtils.writeLEDouble(bytearray, offset, ymin); 213 offset += 8; 214 ByteUtils.writeLEDouble(bytearray, offset, xmax); 215 offset += 8; 216 ByteUtils.writeLEDouble(bytearray, offset, ymax); 217 218 return bytearray; 219 } 220 221 /** 222 * returns the polygon shape size in bytes<BR> 223 */ 224 public int size() { 225 return 44 + numRings * 4 + numPoints * 16; 226 } 227 228 229 230 public String toString() { 231 232 return "WKBPOLYGON" + " numRings: " + numRings; 233 234 } 235 }