MultiPointHandler.java
/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
/*
* Copyright (c) 2003 Open Source Geospatial Foundation, All rights reserved.
*
* This program and the accompanying materials are made available under the terms
* of the OSGeo BSD License v1.0 available at:
*
* https://www.osgeo.org/sites/osgeo.org/files/Page/osgeo-bsd-license.txt
*/
/*
* MultiPointHandler.java
*
* Created on July 17, 2002, 4:13 PM
*/
package org.locationtech.jtstest.testbuilder.io.shapefile;
import java.io.IOException;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.PrecisionModel;
/**
*
* @author dblasby
*/
public class MultiPointHandler implements ShapeHandler {
int myShapeType= -1;
private PrecisionModel precisionModel = new PrecisionModel();
private GeometryFactory geometryFactory = new GeometryFactory(precisionModel, 0);
/** Creates new MultiPointHandler */
public MultiPointHandler() {
myShapeType = 8;
}
public MultiPointHandler(int type) throws InvalidShapefileException
{
if ( (type != 8) && (type != 18) && (type != 28) )
throw new InvalidShapefileException("Multipointhandler constructor - expected type to be 8, 18, or 28");
myShapeType = type;
}
public Geometry read(EndianDataInputStream file,GeometryFactory geometryFactory,int contentLength) throws IOException,InvalidShapefileException{
//file.setLittleEndianMode(true);
int actualReadWords = 0; //actual number of words read (word = 16bits)
int shapeType = file.readIntLE();
actualReadWords += 2;
if (shapeType ==0)
return geometryFactory.createMultiPointFromCoords(null);
if (shapeType != myShapeType)
{
throw new InvalidShapefileException("Multipointhandler.read() - expected type code "+myShapeType+" but got "+shapeType);
}
//read bbox
file.readDoubleLE();
file.readDoubleLE();
file.readDoubleLE();
file.readDoubleLE();
actualReadWords += 4*4;
int numpoints = file.readIntLE();
actualReadWords += 2;
Coordinate[] coords = new Coordinate[numpoints];
for (int t=0;t<numpoints;t++)
{
double x = file.readDoubleLE();
double y = file.readDoubleLE();
actualReadWords += 8;
coords[t] = new Coordinate(x,y);
}
if (myShapeType == 18)
{
file.readDoubleLE(); //z min/max
file.readDoubleLE();
actualReadWords += 8;
for (int t=0;t<numpoints;t++)
{
double z = file.readDoubleLE();//z
actualReadWords += 4;
coords[t].setZ(z);
}
}
if (myShapeType >= 18)
{
// int fullLength = numpoints * 8 + 20 +8 +4*numpoints + 8 +4*numpoints;
int fullLength;
if (myShapeType == 18)
{
//multipoint Z (with m)
fullLength = 20 + (numpoints * 8) +8 +4*numpoints + 8 +4*numpoints;
}
else
{
//multipoint M (with M)
fullLength = 20 + (numpoints * 8) +8 +4*numpoints;
}
if (contentLength >= fullLength) //is the M portion actually there?
{
file.readDoubleLE(); //m min/max
file.readDoubleLE();
actualReadWords += 8;
for (int t=0;t<numpoints;t++)
{
file.readDoubleLE();//m
actualReadWords += 4;
}
}
}
//verify that we have read everything we need
while (actualReadWords < contentLength)
{
int junk2 = file.readShortBE();
actualReadWords += 1;
}
return geometryFactory.createMultiPointFromCoords(coords);
}
double[] zMinMax(Geometry g)
{
double zmin,zmax;
boolean validZFound = false;
Coordinate[] cs = g.getCoordinates();
double[] result = new double[2];
zmin = Double.NaN;
zmax = Double.NaN;
double z;
for (int t=0;t<cs.length; t++)
{
z= cs[t].getZ();
if (!(Double.isNaN( z ) ))
{
if (validZFound)
{
if (z < zmin)
zmin = z;
if (z > zmax)
zmax = z;
}
else
{
validZFound = true;
zmin = z ;
zmax = z ;
}
}
}
result[0] = (zmin);
result[1] = (zmax);
return result;
}
/**
* 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 int The length of the record that this shapepoint will take up in a shapefile
**/
public int getLength(Geometry geometry){
MultiPoint mp = (MultiPoint) geometry;
if (myShapeType == 8)
return mp.getNumGeometries() * 8 + 20;
if (myShapeType == 28)
return mp.getNumGeometries() * 8 + 20 +8 +4*mp.getNumGeometries();
return mp.getNumGeometries() * 8 + 20 +8 +4*mp.getNumGeometries() + 8 +4*mp.getNumGeometries() ;
}
}