001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2002, Centre for Computational Geography
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.data.shapefile.shp;
018:
019: import java.nio.ByteBuffer;
020:
021: import com.vividsolutions.jts.geom.Coordinate;
022: import com.vividsolutions.jts.geom.Envelope;
023: import com.vividsolutions.jts.geom.GeometryFactory;
024: import com.vividsolutions.jts.geom.MultiPoint;
025:
026: /**
027: *
028: * @author aaime
029: * @author Ian Schneider
030: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/MultiPointHandler.java $
031: *
032: */
033: public class MultiPointHandler implements ShapeHandler {
034: final ShapeType shapeType;
035: GeometryFactory geometryFactory = new GeometryFactory();
036:
037: /** Creates new MultiPointHandler */
038: public MultiPointHandler() {
039: shapeType = ShapeType.POINT;
040: }
041:
042: public MultiPointHandler(ShapeType type) throws ShapefileException {
043: if ((type != ShapeType.MULTIPOINT)
044: && (type != ShapeType.MULTIPOINTM)
045: && (type != ShapeType.MULTIPOINTZ)) {
046: throw new ShapefileException(
047: "Multipointhandler constructor - expected type to be 8, 18, or 28");
048: }
049:
050: shapeType = type;
051: }
052:
053: /**
054: * Returns the shapefile shape type value for a point
055: * @return int Shapefile.POINT
056: */
057: public ShapeType getShapeType() {
058: return shapeType;
059: }
060:
061: /**
062: * Calcuates the record length of this object.
063: * @return int The length of the record that this shapepoint will take up in a shapefile
064: **/
065: public int getLength(Object geometry) {
066: MultiPoint mp = (MultiPoint) geometry;
067:
068: int length;
069:
070: if (shapeType == ShapeType.MULTIPOINT) {
071: // two doubles per coord (16 * numgeoms) + 40 for header
072: length = (mp.getNumGeometries() * 16) + 40;
073: } else if (shapeType == ShapeType.MULTIPOINTM) {
074: // add the additional MMin, MMax for 16, then 8 per measure
075: length = (mp.getNumGeometries() * 16) + 40 + 16
076: + (8 * mp.getNumGeometries());
077: } else if (shapeType == ShapeType.MULTIPOINTZ) {
078: // add the additional ZMin,ZMax, plus 8 per Z
079: length = (mp.getNumGeometries() * 16) + 40 + 16
080: + (8 * mp.getNumGeometries()) + 16
081: + (8 * mp.getNumGeometries());
082: } else {
083: throw new IllegalStateException(
084: "Expected ShapeType of Arc, got " + shapeType);
085: }
086:
087: return length;
088: }
089:
090: private Object createNull() {
091: Coordinate[] c = null;
092: return geometryFactory.createMultiPoint(c);
093: }
094:
095: public Object read(ByteBuffer buffer, ShapeType type) {
096: if (type == ShapeType.NULL) {
097: return createNull();
098: }
099:
100: //read bounding box (not needed)
101: buffer.position(buffer.position() + 4 * 8);
102:
103: int numpoints = buffer.getInt();
104: Coordinate[] coords = new Coordinate[numpoints];
105:
106: for (int t = 0; t < numpoints; t++) {
107: double x = buffer.getDouble();
108: double y = buffer.getDouble();
109: coords[t] = new Coordinate(x, y);
110: }
111:
112: if (shapeType == ShapeType.MULTIPOINTZ) {
113: buffer.position(buffer.position() + 2 * 8);
114:
115: for (int t = 0; t < numpoints; t++) {
116: coords[t].z = buffer.getDouble(); //z
117: }
118: }
119:
120: return geometryFactory.createMultiPoint(coords);
121: }
122:
123: public void write(ByteBuffer buffer, Object geometry) {
124: MultiPoint mp = (MultiPoint) geometry;
125:
126: Envelope box = mp.getEnvelopeInternal();
127: buffer.putDouble(box.getMinX());
128: buffer.putDouble(box.getMinY());
129: buffer.putDouble(box.getMaxX());
130: buffer.putDouble(box.getMaxY());
131:
132: buffer.putInt(mp.getNumGeometries());
133:
134: for (int t = 0, tt = mp.getNumGeometries(); t < tt; t++) {
135: Coordinate c = (mp.getGeometryN(t)).getCoordinate();
136: buffer.putDouble(c.x);
137: buffer.putDouble(c.y);
138: }
139:
140: if (shapeType == ShapeType.MULTIPOINTZ) {
141: double[] zExtreame = JTSUtilities.zMinMax(mp
142: .getCoordinates());
143:
144: if (Double.isNaN(zExtreame[0])) {
145: buffer.putDouble(0.0);
146: buffer.putDouble(0.0);
147: } else {
148: buffer.putDouble(zExtreame[0]);
149: buffer.putDouble(zExtreame[1]);
150: }
151:
152: for (int t = 0; t < mp.getNumGeometries(); t++) {
153: Coordinate c = (mp.getGeometryN(t)).getCoordinate();
154: double z = c.z;
155:
156: if (Double.isNaN(z)) {
157: buffer.putDouble(0.0);
158: } else {
159: buffer.putDouble(z);
160: }
161: }
162: }
163:
164: if (shapeType == ShapeType.MULTIPOINTM
165: || shapeType == ShapeType.MULTIPOINTZ) {
166: buffer.putDouble(-10E40);
167: buffer.putDouble(-10E40);
168:
169: for (int t = 0; t < mp.getNumGeometries(); t++) {
170: buffer.putDouble(-10E40);
171: }
172: }
173: }
174:
175: }
|