package org.geotools.shapefile;
import java.io.IOException;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
import com.vividsolutions.jump.io.EndianDataInputStream;
import com.vividsolutions.jump.io.EndianDataOutputStream;
/**
* Wrapper for a Shapefile Point.
*/
// getLength() modified by Michaël MICHAUD on 3 nov. 2004 to handle
// Point, PointM and PointZ length properly
public class PointHandler implements ShapeHandler {
int Ncoords=2; //2 = x,y ; 3= x,y,m ; 4 = x,y,z,m
int myShapeType = -1;
public PointHandler(int type) throws InvalidShapefileException {
if ((type != 1) && (type != 11) && (type != 21)) {
throw new InvalidShapefileException("PointHandler constructor: expected a type of 1, 11 or 21");
}
myShapeType = type;
}
public PointHandler() {
myShapeType = 1; //2d
}
public Geometry read(EndianDataInputStream file,
GeometryFactory geometryFactory,
int contentLength) throws IOException, InvalidShapefileException {
int actualReadWords = 0; //actual number of 16 bits words
Geometry geom = null;
int shapeType = file.readIntLE();
actualReadWords += 2;
if (shapeType == 0) {
geom = geometryFactory.createPoint(new CoordinateArraySequence(0));
}
else if (shapeType != myShapeType) {
throw new InvalidShapefileException("pointhandler.read() - handler's shapetype doesnt match file's");
}
else {
double x = file.readDoubleLE();
double y = file.readDoubleLE();
double m , z = Double.NaN;
actualReadWords += 8;
if ( shapeType ==21 ) {
m= file.readDoubleLE();
actualReadWords += 4;
}
else if ( shapeType ==11 ) {
z = file.readDoubleLE();
actualReadWords += 4;
if (contentLength>actualReadWords) {
m = file.readDoubleLE();
actualReadWords += 8;
}
}
geom = geometryFactory.createPoint(new Coordinate(x,y,z));
}
//verify that we have read everything we need
while (actualReadWords < contentLength) {
int junk2 = file.readShortBE();
actualReadWords += 1;
}
return geom;
}
public void write(Geometry geometry, EndianDataOutputStream file) throws IOException {
if (geometry.isEmpty()) {
file.writeIntLE(0);
return;
}
file.writeIntLE(getShapeType());
Coordinate c = geometry.getCoordinates()[0];
file.writeDoubleLE(c.x);
file.writeDoubleLE(c.y);
if (myShapeType ==11) {
if (Double.isNaN(c.z)) // nan means not defined
file.writeDoubleLE(0.0);
else
file.writeDoubleLE(c.z);
}
if ( (myShapeType ==11) || (myShapeType ==21) ) {
file.writeDoubleLE(-10E40); //M
}
}
/**
* Returns the shapefile shape type value for a point
* @return int Shapefile.POINT
*/
public int getShapeType() {
return myShapeType;
}
/**
* Calcuates the record length of this object.
* @return the length of the record that this point will take up in a shapefile (in WORDS)
**/
public int getLength(Geometry geometry) {
if (geometry.isEmpty()) return 2;
else if (myShapeType == 1) return 10;
else if (myShapeType == 21) return 14;
else return 18;
}
/**
* Return a empty geometry.
*/
public Geometry getEmptyGeometry(GeometryFactory factory) {
return factory.createPoint(new CoordinateArraySequence(0));
}
}