Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions h2/src/main/org/h2/api/SpatialDriver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2004-2016 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;

/**
* Interface which will be used by h2 to create the geometry factory.
*
* @author Steve Hruda
*/
public interface SpatialDriver {

/**
* A new {@link ValueGeometryFactory} instance.
*
* @return a new {@link ValueGeometryFactory} instance
*/
public ValueGeometryFactory<?,?> createGeometryFactory();
}
120 changes: 120 additions & 0 deletions h2/src/main/org/h2/api/ValueGeometryFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright 2004-2015 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;

import org.h2.message.DbException;
import org.h2.value.Value;
import org.h2.value.ValueGeometry;

import com.vividsolutions.jts.geom.Geometry;

/**
* Interface of a factory which provides methods for the conversion of a
* geometry object of a framework like JTS into a {@link ValueGeometry}.
*
* @author Steve Hruda
* @param <T> the type of your {@link ValueGeometry} implementation
* @param <S> the type of the frameworks geometry object
*/
public interface ValueGeometryFactory<T extends ValueGeometry<S>, S> {

/**
* Get or create a geometry value for the given geometry.
*
* @param g
* the geometry object
* @return the value
*/
public T get(Object g);

/**
* Get or create a geometry value for the given byte array.
* @param g
* the geometry object as a byte array
* @return the value
*/
public T get(byte[] g);

/**
* Get or create a geometry value for the given {@link Value}.
* @param g
* the geometry as {@link Value}
* @return the value
*/
public T get(Value g);

/**
* Returns the type of the used geometry framework.
* @return the type of the used geometry framework.
*/
public Class<S> getGeometryType();

/**
* Returns <code>true</code> if the given object is an instance
* of the used geometry framework, <code>false</code> otherwise.
* @param g
* the geometry
* @return <code>true</code> if the given object is an instance
* of the used geometry framework, <code>false</code> otherwise.
*/
public boolean isGeometryTypeSupported(Object g);

/**
* Creates a geometry instance by using the given byte array
* representation.
*
* @param bytes the byte array representation of the geometry
* @return a new geometry instance
* @throws DbException - if an exception occurs during the creation
*/
public S getGeometry(byte[] bytes) throws DbException;

/**
* Creates a geometry instance by using the given string
* representation.
*
* @param s the string representation of the geometry
* @return a new geometry instance
* @throws DbException - if an exception occurs during the creation
*/
public S getGeometry(String s) throws DbException;

/**
* Get or create a geometry value for the given geometry.
*
* @param s the WKT representation of the geometry
* @param srid the srid of the object
* @return the value
* @throws DbException - if an exception occurs during the creation
*/
public S getGeometry(String s, int srid) throws DbException;

/**
* Get or create a geometry value for the given geometry.
*
* @param g
* the geometry object
* @return the value
*/
public T get(Geometry g);

/**
* Get or create a geometry value for the given geometry.
*
* @param s the WKT representation of the geometry
* @return the value
*/
public T get(String s);

/**
* Get or create a geometry value for the given geometry.
*
* @param s the WKT representation of the geometry
* @param srid the srid of the object
* @return the value
*/
public T get(String s, int srid);
}
4 changes: 1 addition & 3 deletions h2/src/main/org/h2/expression/Comparison.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,7 @@ static boolean compareNotNull(Database database, Value l, Value r,
result = database.compare(l, r) < 0;
break;
case SPATIAL_INTERSECTS: {
ValueGeometry lg = (ValueGeometry) l.convertTo(Value.GEOMETRY);
ValueGeometry rg = (ValueGeometry) r.convertTo(Value.GEOMETRY);
result = lg.intersectsBoundingBox(rg);
result = Value.getGeometryFactory().get(l).intersectsBoundingBox(Value.getGeometryFactory().get(r));
break;
}
default:
Expand Down
9 changes: 4 additions & 5 deletions h2/src/main/org/h2/index/IndexCursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import java.util.ArrayList;
import java.util.HashSet;

import org.h2.engine.Session;
import org.h2.expression.Comparison;
import org.h2.message.DbException;
Expand All @@ -19,7 +20,6 @@
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.value.Value;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueNull;

/**
Expand Down Expand Up @@ -185,10 +185,9 @@ private SearchRow getSpatialSearchRow(SearchRow row, int columnId, Value v) {
// if an object needs to overlap with both a and b,
// then it needs to overlap with the the union of a and b
// (not the intersection)
ValueGeometry vg = (ValueGeometry) row.getValue(columnId).
convertTo(Value.GEOMETRY);
v = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).
getEnvelopeUnion(vg);

v= Value.getGeometryFactory().get(v).getEnvelopeUnion(
Value.getGeometryFactory().get(row.getValue(columnId)));
}
if (columnId < 0) {
row.setKey(v.getLong());
Expand Down
23 changes: 6 additions & 17 deletions h2/src/main/org/h2/index/SpatialTreeIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
import org.h2.table.TableFilter;
import org.h2.value.Value;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueNull;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

/**
* This is an index based on a MVR-TreeMap.
Expand Down Expand Up @@ -126,30 +122,23 @@ public void add(Session session, Row row) {
if (closed) {
throw DbException.throwInternalError();
}
treeMap.add(getKey(row), row.getKey());
treeMap.add(getEnvelope(row), row.getKey());
}

private SpatialKey getKey(SearchRow row) {
if (row == null) {
private SpatialKey getEnvelope(SearchRow row) {
if (row == null) {
return null;
}
Value v = row.getValue(columnIds[0]);
if (v == ValueNull.INSTANCE) {
return null;
}
Geometry g = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getGeometryNoCopy();
Envelope env = g.getEnvelopeInternal();
return new SpatialKey(row.getKey(),
(float) env.getMinX(), (float) env.getMaxX(),
(float) env.getMinY(), (float) env.getMaxY());
return ((ValueGeometry<?>) v.convertTo(Value.GEOMETRY)).getSpatialKey(row.getKey());
}

@Override
public void remove(Session session, Row row) {
if (closed) {
throw DbException.throwInternalError();
}
if (!treeMap.remove(getKey(row), row.getKey())) {
if (!treeMap.remove(getEnvelope(row), row.getKey())) {
throw DbException.throwInternalError("row not found");
}
}
Expand All @@ -174,7 +163,7 @@ public Cursor findByGeometry(TableFilter filter, SearchRow intersection) {
return find(filter.getSession());
}
return new SpatialCursor(
treeMap.findIntersectingKeys(getKey(intersection)), table,
treeMap.findIntersectingKeys(getEnvelope(intersection)), table,
filter.getSession());
}

Expand Down
32 changes: 11 additions & 21 deletions h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
import org.h2.value.Value;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

/**
* This is an index based on a MVRTreeMap.
Expand Down Expand Up @@ -125,7 +121,7 @@ public void close(Session session) {
@Override
public void add(Session session, Row row) {
TransactionMap<SpatialKey, Value> map = getMap(session);
SpatialKey key = getKey(row);
SpatialKey key = getEnvelope(row);
if (indexType.isUnique()) {
// this will detect committed entries only
RTreeCursor cursor = spatialMap.findContainedKeys(key);
Expand Down Expand Up @@ -164,9 +160,17 @@ public void add(Session session, Row row) {
}
}

private SpatialKey getEnvelope(SearchRow row) {
if (row == null) {
return null;
}
Value v = row.getValue(columnIds[0]);
return ((ValueGeometry<?>) v.convertTo(Value.GEOMETRY)).getSpatialKey(row.getKey());
}

@Override
public void remove(Session session, Row row) {
SpatialKey key = getKey(row);
SpatialKey key = getEnvelope(row);
TransactionMap<SpatialKey, Value> map = getMap(session);
try {
Value old = map.remove(key);
Expand Down Expand Up @@ -204,26 +208,12 @@ public Cursor findByGeometry(TableFilter filter, SearchRow intersection) {
return find(session);
}
Iterator<SpatialKey> cursor =
spatialMap.findIntersectingKeys(getKey(intersection));
spatialMap.findIntersectingKeys(getEnvelope(intersection));
TransactionMap<SpatialKey, Value> map = getMap(session);
Iterator<SpatialKey> it = map.wrapIterator(cursor, false);
return new MVStoreCursor(session, it);
}

private SpatialKey getKey(SearchRow row) {
if (row == null) {
return null;
}
Value v = row.getValue(columnIds[0]);
if (v == ValueNull.INSTANCE) {
return null;
}
Geometry g = ((ValueGeometry) v.convertTo(Value.GEOMETRY)).getGeometryNoCopy();
Envelope env = g.getEnvelopeInternal();
return new SpatialKey(row.getKey(),
(float) env.getMinX(), (float) env.getMaxX(),
(float) env.getMinY(), (float) env.getMaxY());
}

/**
* Get the row with the given index key.
Expand Down
2 changes: 1 addition & 1 deletion h2/src/main/org/h2/mvstore/db/ValueDataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ private Object readValue(ByteBuffer buff) {
int len = readVarInt(buff);
byte[] b = DataUtils.newBytes(len);
buff.get(b, 0, len);
return ValueGeometry.get(b);
return Value.getGeometryFactory().get(b);
}
case SPATIAL_KEY_2D:
return getSpatialDataType().read(buff);
Expand Down
3 changes: 1 addition & 2 deletions h2/src/main/org/h2/store/Data.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.h2.value.ValueDecimal;
import org.h2.value.ValueDouble;
import org.h2.value.ValueFloat;
import org.h2.value.ValueGeometry;
import org.h2.value.ValueInt;
import org.h2.value.ValueJavaObject;
import org.h2.value.ValueLob;
Expand Down Expand Up @@ -773,7 +772,7 @@ public Value readValue() {
int len = readVarInt();
byte[] b = DataUtils.newBytes(len);
read(b, 0, len);
return ValueGeometry.get(b);
return Value.getGeometryFactory().get(b);
}
case Value.JAVA_OBJECT: {
int len = readVarInt();
Expand Down
Loading