001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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 }