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 }