001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/io/shpapi/shape_new/ShapeMultiPoint.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.io.shpapi.shape_new;
037
038 import org.deegree.model.crs.CoordinateSystem;
039 import org.deegree.model.spatialschema.ByteUtils;
040 import org.deegree.model.spatialschema.Geometry;
041 import org.deegree.model.spatialschema.GeometryException;
042 import org.deegree.model.spatialschema.GeometryFactory;
043 import org.deegree.model.spatialschema.MultiPoint;
044 import org.deegree.model.spatialschema.Point;
045 import org.deegree.model.spatialschema.WKTAdapter;
046
047 /**
048 * <code>ShapeMultiPoint</code> encapsulates shapefile MultiPoint/M/Z structures.
049 *
050 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
051 * @author last edited by: $Author: mschneider $
052 *
053 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
054 */
055 public class ShapeMultiPoint implements Shape {
056
057 private CoordinateSystem crs; // optional crs for geometry
058
059 private boolean isM, isZ;
060
061 private ShapeEnvelope envelope;
062
063 protected ShapePoint[] points;
064
065 /**
066 * @param isZ
067 * @param isM
068 */
069 public ShapeMultiPoint( boolean isZ, boolean isM ) {
070 this.isZ = isZ;
071 this.isM = isM;
072 }
073
074 /**
075 * @param isZ
076 * @param isM
077 * @param crs
078 * CoordinateSystem for shape
079 */
080 public ShapeMultiPoint( boolean isZ, boolean isM, CoordinateSystem crs ) {
081 this.isZ = isZ;
082 this.isM = isM;
083 this.crs = crs;
084 }
085
086 /**
087 * Creates MultiPointZ from deegree MultiPoint
088 *
089 * @param p
090 */
091 public ShapeMultiPoint( MultiPoint p ) {
092 if ( p.getDimension() == 3 ) {
093 isZ = true;
094 }
095 envelope = new ShapeEnvelope( p.getEnvelope() );
096
097 Point[] ps = p.getAllPoints();
098 points = new ShapePoint[ps.length];
099
100 for ( int i = 0; i < ps.length; ++i ) {
101 points[i] = new ShapePoint( ps[i] );
102 }
103 }
104
105 /*
106 * (non-Javadoc)
107 *
108 * @see org.deegree.io.shpapi.Shape#getByteLength()
109 */
110 public int getByteLength() {
111 int len = 44 + points.length * 16;
112 if ( isZ ) {
113 len += 32 + points.length * 16;
114 }
115 if ( isM ) {
116 len += 16 + points.length * 8;
117 }
118 return len;
119 }
120
121 private int readMultiPoint( byte[] bytes, int offset ) {
122 int off = offset;
123 envelope = new ShapeEnvelope( false, false );
124 off = envelope.read( bytes, off );
125
126 int numPoints = ByteUtils.readLEInt( bytes, off );
127 off += 4;
128
129 points = new ShapePoint[numPoints];
130
131 for ( int i = 0; i < numPoints; ++i ) {
132 points[i] = new ShapePoint( bytes, off );
133 off += 16;
134 }
135
136 return off;
137 }
138
139 private int readMultiPointZ( byte[] bytes, int offset ) {
140 int off = readMultiPoint( bytes, offset );
141
142 double zmin, zmax;
143
144 zmin = ByteUtils.readLEDouble( bytes, off );
145 off += 8;
146 zmax = ByteUtils.readLEDouble( bytes, off );
147 off += 8;
148
149 double[] zVals = new double[points.length];
150 for ( int i = 0; i < points.length; ++i ) {
151 zVals[i] = ByteUtils.readLEDouble( bytes, off );
152 off += 8;
153 }
154
155 double mmin, mmax;
156
157 mmin = ByteUtils.readLEDouble( bytes, off );
158 off += 8;
159 mmax = ByteUtils.readLEDouble( bytes, off );
160 off += 8;
161
162 double[] mVals = new double[points.length];
163 for ( int i = 0; i < points.length; ++i ) {
164 mVals[i] = ByteUtils.readLEDouble( bytes, off );
165 off += 8;
166 }
167
168 envelope.extend( zmin, zmax, mmin, mmax );
169
170 for ( int i = 0; i < points.length; ++i ) {
171 points[i].extend( zVals[i], mVals[i] );
172 }
173
174 return off;
175 }
176
177 private int readMultiPointM( byte[] bytes, int offset ) {
178 int off = readMultiPoint( bytes, offset );
179
180 double mmin, mmax;
181
182 mmin = ByteUtils.readLEDouble( bytes, off );
183 off += 8;
184 mmax = ByteUtils.readLEDouble( bytes, off );
185 off += 8;
186
187 envelope.extend( mmin, mmax );
188
189 double m;
190 for ( int i = 0; i < points.length; ++i ) {
191 m = ByteUtils.readLEDouble( bytes, off );
192 off += 8;
193 points[i].extend( m );
194 }
195
196 return off;
197 }
198
199 /*
200 * (non-Javadoc)
201 *
202 * @see org.deegree.io.shpapi.Shape#read(byte[], int)
203 */
204 public int read( byte[] bytes, int offset ) {
205 int t = ByteUtils.readLEInt( bytes, offset );
206 int off = offset + 4;
207
208 if ( t == ShapeFile.NULL ) {
209 return off;
210 }
211
212 if ( t == ShapeFile.MULTIPOINTZ ) {
213 return readMultiPointZ( bytes, off );
214 }
215
216 if ( t == ShapeFile.MULTIPOINTM ) {
217 return readMultiPointM( bytes, off );
218 }
219
220 if ( t == ShapeFile.MULTIPOINT ) {
221 return readMultiPoint( bytes, off );
222 }
223
224 return -1;
225 }
226
227 private int writeMultiPoint( byte[] bytes, int offset ) {
228 int off = envelope.write( bytes, offset );
229
230 ByteUtils.writeLEInt( bytes, off, points.length );
231 off += 4;
232
233 for ( int i = 0; i < points.length; ++i ) {
234 ByteUtils.writeLEDouble( bytes, off, points[i].x );
235 off += 8;
236 ByteUtils.writeLEDouble( bytes, off, points[i].y );
237 off += 8;
238 }
239
240 return off;
241 }
242
243 private int writeMultiPointZ( byte[] bytes, int offset ) {
244 int off = writeMultiPoint( bytes, offset );
245
246 ByteUtils.writeLEDouble( bytes, off, envelope.zmin );
247 off += 8;
248 ByteUtils.writeLEDouble( bytes, off, envelope.zmax );
249 off += 8;
250
251 for ( int i = 0; i < points.length; ++i ) {
252 ByteUtils.writeLEDouble( bytes, off, points[i].z );
253 off += 8;
254 }
255
256 ByteUtils.writeLEDouble( bytes, off, envelope.mmin );
257 off += 8;
258 ByteUtils.writeLEDouble( bytes, off, envelope.mmax );
259 off += 8;
260
261 for ( int i = 0; i < points.length; ++i ) {
262 ByteUtils.writeLEDouble( bytes, off, points[i].m );
263 off += 8;
264 }
265
266 return off;
267 }
268
269 private int writeMultiPointM( byte[] bytes, int offset ) {
270 int off = writeMultiPoint( bytes, offset );
271
272 ByteUtils.writeLEDouble( bytes, off, envelope.mmin );
273 off += 8;
274 ByteUtils.writeLEDouble( bytes, off, envelope.mmax );
275 off += 8;
276
277 for ( int i = 0; i < points.length; ++i ) {
278 ByteUtils.writeLEDouble( bytes, off, points[i].m );
279 off += 8;
280 }
281
282 return off;
283 }
284
285 /*
286 * (non-Javadoc)
287 *
288 * @see org.deegree.io.shpapi.Shape#write(byte[], int)
289 */
290 public int write( byte[] bytes, int offset ) {
291 if ( isZ ) {
292 ByteUtils.writeLEInt( bytes, offset, ShapeFile.MULTIPOINTZ );
293 return writeMultiPointZ( bytes, offset + 4 );
294 }
295 if ( isM ) {
296 ByteUtils.writeLEInt( bytes, offset, ShapeFile.MULTIPOINTM );
297 return writeMultiPointM( bytes, offset + 4 );
298 }
299 ByteUtils.writeLEInt( bytes, offset, ShapeFile.MULTIPOINT );
300 return writeMultiPoint( bytes, offset + 4 );
301 }
302
303 /*
304 * (non-Javadoc)
305 *
306 * @see org.deegree.io.shpapi.shape_new.Shape#getType()
307 */
308 public int getType() {
309 if ( isZ ) {
310 return ShapeFile.MULTIPOINTZ;
311 }
312 if ( isM ) {
313 return ShapeFile.MULTIPOINTM;
314 }
315 return ShapeFile.MULTIPOINT;
316 }
317
318 /*
319 * (non-Javadoc)
320 *
321 * @see org.deegree.io.shpapi.shape_new.Shape#getEnvelope()
322 */
323 public ShapeEnvelope getEnvelope() {
324 return envelope;
325 }
326
327 /**
328 * This creates a MultiPoint object.
329 *
330 * @see org.deegree.io.shpapi.shape_new.Shape#getGeometry()
331 */
332 public Geometry getGeometry()
333 throws ShapeGeometryException {
334 if ( points == null ) {
335 return null;
336 }
337 Point[] ps = new Point[points.length];
338
339 for ( int i = 0; i < ps.length; ++i ) {
340 ps[i] = (Point) points[i].getGeometry();
341 }
342
343 return GeometryFactory.createMultiPoint( ps, crs );
344 }
345
346 @Override
347 public String toString() {
348 try {
349 return WKTAdapter.export( getGeometry() ).toString();
350 } catch ( GeometryException e ) {
351 return "(unknown)";
352 }
353 }
354
355 }