    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    }