001: package org.geotools.shapefile;
002:
003: import java.io.IOException;
004:
005: import com.vividsolutions.jts.geom.*;
006: import com.vividsolutions.jump.io.EndianDataInputStream;
007: import com.vividsolutions.jump.io.EndianDataOutputStream;
008:
009: /**
010: * Wrapper for a Shapefile point.
011: *
012: * getLength() modified by Michaël MICHAUD on 3 nov. 2004 to handle properly
013: * Point, PointM and PointZ length
014: */
015: public class PointHandler implements ShapeHandler {
016:
017: int Ncoords = 2; //2 = x,y ; 3= x,y,m ; 4 = x,y,z,m
018: int myShapeType = -1;
019:
020: public PointHandler(int type) throws InvalidShapefileException {
021: if ((type != 1) && (type != 11) && (type != 21))// 2d, 2d+m, 3d+m
022: throw new InvalidShapefileException(
023: "PointHandler constructor: expected a type of 1, 11 or 21");
024: myShapeType = type;
025: }
026:
027: public PointHandler() {
028: myShapeType = 1; //2d
029: }
030:
031: public Geometry read(EndianDataInputStream file,
032: GeometryFactory geometryFactory, int contentLength)
033: throws IOException, InvalidShapefileException {
034: // file.setLittleEndianMode(true);
035: int actualReadWords = 0; //actual number of words read (word = 16bits)
036:
037: int shapeType = file.readIntLE();
038: actualReadWords += 2;
039:
040: if (shapeType != myShapeType)
041: throw new InvalidShapefileException(
042: "pointhandler.read() - handler's shapetype doesnt match file's");
043:
044: double x = file.readDoubleLE();
045: double y = file.readDoubleLE();
046: double m, z = Double.NaN;
047: actualReadWords += 8;
048: /*
049: if ( shapeType ==11 )
050: {
051: z= file.readDoubleLE();
052: actualReadWords += 4;
053: }
054: if ( shapeType >=11 )
055: {
056: m = file.readDoubleLE();
057: actualReadWords += 4;
058: }
059: */
060: // added on march, 24 by michael michaud
061: // to read shapefile containing PointZ without m value
062: if (shapeType == 21) {
063: m = file.readDoubleLE();
064: actualReadWords += 4;
065: } else if (shapeType == 11) {
066: z = file.readDoubleLE();
067: actualReadWords += 4;
068: if (contentLength > actualReadWords) {
069: m = file.readDoubleLE();
070: actualReadWords += 8;
071: }
072: }
073:
074: //verify that we have read everything we need
075: while (actualReadWords < contentLength) {
076: int junk2 = file.readShortBE();
077: actualReadWords += 1;
078: }
079:
080: return geometryFactory.createPoint(new Coordinate(x, y, z));
081: }
082:
083: public void write(Geometry geometry, EndianDataOutputStream file)
084: throws IOException {
085: // file.setLittleEndianMode(true);
086: file.writeIntLE(getShapeType());
087: Coordinate c = geometry.getCoordinates()[0];
088: file.writeDoubleLE(c.x);
089: file.writeDoubleLE(c.y);
090:
091: if (myShapeType == 11) {
092: if (Double.isNaN(c.z)) // nan means not defined
093: file.writeDoubleLE(0.0);
094: else
095: file.writeDoubleLE(c.z);
096: }
097: if ((myShapeType == 11) || (myShapeType == 21)) {
098: file.writeDoubleLE(-10E40); //M
099: }
100: }
101:
102: /**
103: * Returns the shapefile shape type value for a point
104: * @return int Shapefile.POINT
105: */
106: public int getShapeType() {
107: return myShapeType;
108: }
109:
110: /**
111: * Calcuates the record length of this object.
112: * @return int The length of the record that this shapepoint will take up in a shapefile
113: **/
114: public int getLength(Geometry geometry) {
115: // 2004/03/12 : type 1 (Point) has length 10
116: if (myShapeType == 1)
117: return 10;
118: // 2004/03/12 : type 21 (PointM) has length 14
119: if (myShapeType == 21)
120: return 14;
121: // 2004/03/12 : type 11 (PointZ) has length 18
122: return 18;
123: }
124: }
|