001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/shpapi/shape_new/ShapePoint.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.Point;
044 import org.deegree.model.spatialschema.Position;
045 import org.deegree.model.spatialschema.WKTAdapter;
046
047 import com.vividsolutions.jts.geom.Coordinate;
048
049 /**
050 * <code>ShapePoint</code> corresponds to Point, PointZ and PointM in shapefile terminology.
051 *
052 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
053 * @author last edited by: $Author: mschneider $
054 *
055 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
056 */
057 public class ShapePoint implements Shape {
058
059 private CoordinateSystem crs; // optional crs for geometry
060
061 /**
062 *
063 */
064 public boolean isZ;
065
066 /**
067 *
068 */
069 public boolean isM;
070
071 /**
072 * The x value.
073 */
074 public double x;
075
076 /**
077 * The y value.
078 */
079 public double y;
080
081 /**
082 * The z value.
083 */
084 public double z;
085
086 /**
087 * The m value.
088 */
089 public double m;
090
091 private boolean isNull;
092
093 /**
094 * Constructs one without values, use read to fill it.
095 *
096 * @param z
097 * if PointZ
098 * @param m
099 * if PointM
100 */
101 public ShapePoint( boolean z, boolean m ) {
102 isZ = z;
103 isM = m;
104 }
105
106 /**
107 * Constructs one without values, use read to fill it.
108 *
109 * @param z
110 * if PointZ
111 * @param m
112 * if PointM
113 * @param crs
114 * CoordinateSystem of the shape
115 */
116 public ShapePoint( boolean z, boolean m, CoordinateSystem crs ) {
117 isZ = z;
118 isM = m;
119 this.crs = crs;
120 }
121
122 /**
123 * Creates a new PointZ from deegree Point.
124 *
125 * @param p
126 */
127 public ShapePoint( Point p ) {
128 x = p.getX();
129 y = p.getY();
130 z = p.getZ();
131 if ( p.getCoordinateDimension() == 3 ) {
132 isZ = true;
133 }
134 }
135
136 /**
137 * Creates a new PointZ from deegree Position.
138 *
139 * @param p
140 */
141 public ShapePoint( Position p ) {
142 x = p.getX();
143 y = p.getY();
144 z = p.getZ();
145 if ( p.getCoordinateDimension() == 3 ) {
146 isZ = true;
147 }
148 }
149
150 /**
151 * Just reads x and y from the byte array.
152 *
153 * @param bytes
154 * @param offset
155 */
156 public ShapePoint( byte[] bytes, int offset ) {
157 x = ByteUtils.readLEDouble( bytes, offset );
158 y = ByteUtils.readLEDouble( bytes, offset + 8 );
159 }
160
161 /**
162 * @return the Point as (x, y, NaN), the PointZ as (x, y, z) Coordinate
163 */
164 public Coordinate export() {
165 if ( isZ ) {
166 return new Coordinate( x, y, z );
167 }
168 return new Coordinate( x, y );
169 }
170
171 /**
172 * Extends this point with z and m values, so it is a PointZ
173 *
174 * @param zVal
175 * @param mVal
176 */
177 public void extend( double zVal, double mVal ) {
178 z = zVal;
179 m = mVal;
180 isZ = true;
181 }
182
183 /**
184 * Extends this point with m values, so it is a PointM
185 *
186 * @param mVal
187 */
188 public void extend( double mVal ) {
189 m = mVal;
190 isM = true;
191 }
192
193 /*
194 * (non-Javadoc)
195 *
196 * @see org.deegree.io.shpapi.Shape#getByteLength()
197 */
198 public int getByteLength() {
199 if ( isZ ) {
200 return 36;
201 }
202 if ( isM ) {
203 return 28;
204 }
205 return 20;
206 }
207
208 private int readPoint( byte[] bytes, int offset ) {
209 int off = offset;
210 isM = false;
211 isZ = false;
212 x = ByteUtils.readLEDouble( bytes, off );
213
214 off += 8;
215
216 y = ByteUtils.readLEDouble( bytes, off );
217
218 off += 8;
219 return off;
220 }
221
222 private int readPointZ( byte[] bytes, int offset ) {
223 int off = offset;
224 isM = false;
225 isZ = true;
226 x = ByteUtils.readLEDouble( bytes, off );
227
228 off += 8;
229
230 y = ByteUtils.readLEDouble( bytes, off );
231
232 off += 8;
233
234 z = ByteUtils.readLEDouble( bytes, off );
235
236 off += 8;
237
238 m = ByteUtils.readLEDouble( bytes, off );
239
240 off += 8;
241
242 return off;
243 }
244
245 private int readPointM( byte[] bytes, int offset ) {
246 int off = offset;
247 isM = true;
248 isZ = false;
249 x = ByteUtils.readLEDouble( bytes, off );
250
251 off += 8;
252
253 y = ByteUtils.readLEDouble( bytes, off );
254
255 off += 8;
256
257 m = ByteUtils.readLEDouble( bytes, off );
258
259 off += 8;
260 return off;
261 }
262
263 /*
264 * (non-Javadoc)
265 *
266 * @see org.deegree.io.shpapi.Shape#read(byte[], int)
267 */
268 public int read( byte[] bytes, int offset ) {
269 int off = offset;
270
271 int type = ByteUtils.readLEInt( bytes, off );
272 off += 4;
273
274 if ( type == ShapeFile.NULL ) {
275 isNull = true;
276 return off;
277 }
278
279 if ( type == ShapeFile.POINT ) {
280 return readPoint( bytes, off );
281 }
282
283 if ( type == ShapeFile.POINTZ ) {
284 return readPointZ( bytes, off );
285 }
286
287 if ( type == ShapeFile.POINTM ) {
288 return readPointM( bytes, off );
289 }
290
291 return -1;
292 }
293
294 private int writePoint( byte[] bytes, int offset ) {
295 int off = offset;
296
297 ByteUtils.writeLEDouble( bytes, off, x );
298 off += 8;
299
300 ByteUtils.writeLEDouble( bytes, off, y );
301 off += 8;
302
303 return off;
304 }
305
306 private int writePointZ( byte[] bytes, int offset ) {
307 int off = writePoint( bytes, offset );
308
309 ByteUtils.writeLEDouble( bytes, off, z );
310 off += 8;
311
312 ByteUtils.writeLEDouble( bytes, off, m );
313 off += 8;
314
315 return off;
316 }
317
318 private int writePointM( byte[] bytes, int offset ) {
319 int off = writePoint( bytes, offset );
320
321 ByteUtils.writeLEDouble( bytes, off, m );
322 off += 8;
323
324 return off;
325 }
326
327 /*
328 * (non-Javadoc)
329 *
330 * @see org.deegree.io.shpapi.Shape#write(byte[], int)
331 */
332 public int write( byte[] bytes, int offset ) {
333 if ( isZ ) {
334 ByteUtils.writeLEInt( bytes, offset, ShapeFile.POINTZ );
335 return writePointZ( bytes, offset + 4 );
336 }
337 if ( isM ) {
338 ByteUtils.writeLEInt( bytes, offset, ShapeFile.POINTM );
339 return writePointM( bytes, offset + 4 );
340 }
341
342 ByteUtils.writeLEInt( bytes, offset, ShapeFile.POINT );
343 return writePoint( bytes, offset + 4 );
344 }
345
346 /*
347 * (non-Javadoc)
348 *
349 * @see org.deegree.io.shpapi.shape_new.Shape#getType()
350 */
351 public int getType() {
352 if ( isZ ) {
353 return ShapeFile.POINTZ;
354 }
355 if ( isM ) {
356 return ShapeFile.POINTM;
357 }
358 return ShapeFile.POINT;
359 }
360
361 /**
362 * @return null, points do not have an envelope
363 * @see org.deegree.io.shpapi.shape_new.Shape#getEnvelope()
364 */
365 public ShapeEnvelope getEnvelope() {
366 return null;
367 }
368
369 /**
370 * This creates a Point object.
371 *
372 * @see org.deegree.io.shpapi.shape_new.Shape#getGeometry()
373 */
374 public Geometry getGeometry()
375 throws ShapeGeometryException {
376 if ( isNull ) {
377 return null;
378 }
379 if ( isZ ) {
380 return GeometryFactory.createPoint( x, y, z, crs );
381 }
382 return GeometryFactory.createPoint( x, y, crs );
383 }
384
385 @Override
386 public String toString() {
387 try {
388 return WKTAdapter.export( getGeometry() ).toString();
389 } catch ( GeometryException e ) {
390 return "(unknown)";
391 }
392 }
393
394 }