LUCENE-7936: Complete the serialization/deserialization implementation of Geo3d.

This commit is contained in:
Karl Wright 2017-08-25 10:07:25 -04:00
parent 26b7644d00
commit 554f0d5f20
4 changed files with 70 additions and 28 deletions

View File

@ -1273,14 +1273,21 @@ class GeoComplexPolygon extends GeoBasePolygon {
@Override
public boolean equals(Object o) {
// Way too expensive to do this the hard way, so each complex polygon will be considered unique.
return this == o;
if (!(o instanceof GeoComplexPolygon))
return false;
final GeoComplexPolygon other = (GeoComplexPolygon) o;
return super.equals(other) && testPointInSet == other.testPointInSet
&& testPoint.equals(testPoint)
&& pointsList.equals(other.pointsList);
}
@Override
public int hashCode() {
// Each complex polygon is considered unique.
return System.identityHashCode(this);
int result = super.hashCode();
result = 31 * result + Boolean.hashCode(testPointInSet);
result = 31 * result + testPoint.hashCode();
result = 31 * result + pointsList.hashCode();
return result;
}
@Override

View File

@ -16,11 +16,15 @@
*/
package org.apache.lucene.spatial3d.geom;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
/**
* Holds mathematical constants associated with the model of a planet.
* @lucene.experimental
*/
public class PlanetModel {
public class PlanetModel implements SerializableObject {
/** Planet model corresponding to sphere. */
public static final PlanetModel SPHERE = new PlanetModel(1.0,1.0);
@ -95,6 +99,19 @@ public class PlanetModel {
this.MAX_Y_POLE = new GeoPoint(ab, 0.0, 1.0, 0.0, 0.0, Math.PI * 0.5);
}
/** Deserialization constructor.
* @param inputStream is the input stream.
*/
public PlanetModel(final InputStream inputStream) throws IOException {
this(SerializableObject.readDouble(inputStream), SerializableObject.readDouble(inputStream));
}
@Override
public void write(final OutputStream outputStream) throws IOException {
SerializableObject.writeDouble(outputStream, ab);
SerializableObject.writeDouble(outputStream, c);
}
/** Find the minimum magnitude of all points on the ellipsoid.
* @return the minimum magnitude for the planet.
*/

View File

@ -39,6 +39,28 @@ public interface SerializableObject {
*/
void write(OutputStream outputStream) throws IOException;
/** Write a PlanetObject to a stream.
* @param outputStream is the output stream.
* @param object is the object to write.
*/
public static void writePlanetObject(final OutputStream outputStream, final PlanetObject object) throws IOException {
object.getPlanetModel().write(outputStream);
writeObject(outputStream, object);
}
/** Read a PlanetObject from a stream.
* @param inputStream is the input stream.
* @return the PlanetObject.
*/
public static PlanetObject readPlanetObject(final InputStream inputStream) throws IOException {
final PlanetModel pm = new PlanetModel(inputStream);
final SerializableObject so = readObject(pm, inputStream);
if (!(so instanceof PlanetObject)) {
throw new IOException("Type of object is not expected PlanetObject: "+so.getClass().getName());
}
return (PlanetObject)so;
}
/** Write an object to a stream.
* @param outputStream is the output stream.
* @param object is the object to write.
@ -65,6 +87,22 @@ public interface SerializableObject {
}
}
/** Read an object from a stream (for objects that do not need a PlanetModel).
* @param inputStream is the input stream.
* @return the deserialized object.
*/
public static SerializableObject readObject(final InputStream inputStream) throws IOException {
// Read the class name
final String className = readString(inputStream);
try {
// Look for the class
final Class<?> clazz = Class.forName(className);
return readObject(inputStream, clazz);
} catch (ClassNotFoundException e) {
throw new IOException("Can't find class "+className+" for deserialization: "+e.getMessage(), e);
}
}
/** Instantiate a serializable object from a stream.
* @param planetModel is the planet model.
* @param inputStream is the input stream.
@ -93,22 +131,6 @@ public interface SerializableObject {
}
/** Read an object from a stream (for objects that do not need a PlanetModel).
* @param inputStream is the input stream.
* @return the deserialized object.
*/
public static SerializableObject readObject(final InputStream inputStream) throws IOException {
// Read the class name
final String className = readString(inputStream);
try {
// Look for the class
final Class<?> clazz = Class.forName(className);
return readObject(inputStream, clazz);
} catch (ClassNotFoundException e) {
throw new IOException("Can't find class "+className+" for deserialization: "+e.getMessage(), e);
}
}
/** Instantiate a serializable object from a stream without a planet model.
* @param inputStream is the input stream.
* @param clazz is the class to instantiate.
@ -238,9 +260,9 @@ public interface SerializableObject {
* @param clazz is the class of the objects to read.
* @return the array.
*/
@SuppressWarnings("unchecked")
static <T extends SerializableObject> T[] readHomogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class<T> clazz) throws IOException {
final int count = readInt(inputStream);
@SuppressWarnings("unchecked")
final T[] rval = (T[])Array.newInstance(clazz, count);
for (int i = 0; i < count; i++) {
rval[i] = clazz.cast(readObject(planetModel, inputStream, clazz));
@ -283,9 +305,9 @@ public interface SerializableObject {
* @param inputStream is the input stream.
* @return the array.
*/
@SuppressWarnings("unchecked")
static <T extends SerializableObject> T[] readHeterogeneousArray(final PlanetModel planetModel, final InputStream inputStream, final Class<T> clazz) throws IOException {
final int count = readInt(inputStream);
@SuppressWarnings("unchecked")
final T[] rval = (T[])Array.newInstance(clazz, count);
for (int i = 0; i < count; i++) {
rval[i] = clazz.cast(readObject(planetModel, inputStream));

View File

@ -34,10 +34,6 @@ public class RandomBinaryCodecTest extends RandomGeoShapeGenerator{
public void testRandomShapeCodec() throws IOException{
PlanetModel planetModel = randomPlanetModel();
int type = randomShapeType();
while (type == COMPLEX_POLYGON){
//We need to implement equals method
type = randomShapeType();
}
GeoShape shape = randomGeoShape(type, planetModel);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();