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