Skip to content

Commit

Permalink
增加Geometry类型支持
Browse files Browse the repository at this point in the history
  • Loading branch information
entropy-cloud committed Jul 18, 2023
1 parent 15ff9dd commit 132bb85
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 44 deletions.
2 changes: 1 addition & 1 deletion nop-dao/src/main/java/io/nop/dao/dialect/IDialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface IDialect extends IComponentModel {

SQLDataType stdToNativeSqlType(StdSqlType sqlType, int precision, int scale);

IDataParameterBinder getGeometryDataParameterBinder();
IDataTypeHandler getGeometryTypeHandler();

ISQLExceptionTranslator getSQLExceptionTranslator();

Expand Down
21 changes: 13 additions & 8 deletions nop-dao/src/main/java/io/nop/dao/dialect/impl/DialectImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.nop.commons.util.IoHelper;
import io.nop.commons.util.StringHelper;
import io.nop.core.reflect.ReflectionManager;
import io.nop.dao.dialect.IDataTypeHandler;
import io.nop.dao.dialect.IDialect;
import io.nop.dao.dialect.SQLDataType;
import io.nop.dao.dialect.exception.ISQLExceptionTranslator;
Expand Down Expand Up @@ -78,7 +79,7 @@ public class DialectImpl implements IDialect {

private final boolean convertStringToNull = CFG_AUTO_CONVERT_EMPTY_STRING_TO_NULL.get();

private final IDataParameterBinder geometryParameterBinder;
private final IDataTypeHandler geometryTypeHandler;

public DialectImpl(DialectModel dialectModel) {
this.dialectModel = dialectModel;
Expand All @@ -95,13 +96,13 @@ public DialectImpl(DialectModel dialectModel) {
this.renameMap.putAll(dialectModel.getRename());
}

IDataParameterBinder binder = null;
IDataTypeHandler handler = null;
try {
binder = newInstance(dialectModel.getGeometryParameterBinder(), null);
handler = newInstance(dialectModel.getGeometryTypeHandler(), null);
} catch (Exception e) {
LOG.warn("nop.err.dao.load-geometry-parameter-binder-fail", e);
LOG.warn("nop.err.dao.load-geometry-type-handler-fail", e);
}
this.geometryParameterBinder = binder;
this.geometryTypeHandler = handler;
}

static <T> T newInstance(String className, T defaultImpl) {
Expand Down Expand Up @@ -140,8 +141,8 @@ String buildFunctionSql(String funcName) {
}

@Override
public IDataParameterBinder getGeometryDataParameterBinder() {
return geometryParameterBinder;
public IDataTypeHandler getGeometryTypeHandler() {
return geometryTypeHandler;
}

public DialectModel getDialectModel() {
Expand Down Expand Up @@ -508,6 +509,10 @@ public String getValueLiteral(Object value) {
return getDateTimeLiteral((LocalDateTime) value);
if (value instanceof java.util.Date)
return getDateTimeLiteral(ConvertHelper.toLocalDateTime(value));

IDataTypeHandler typeHandler = getGeometryTypeHandler();
if (typeHandler != null && typeHandler.isJavaType(value))
return typeHandler.toLiteral(value, this);
return value.toString();
}

Expand All @@ -517,7 +522,7 @@ public IDataParameterBinder getDataParameterBinder(StdDataType stdType, StdSqlTy
return DataParameterBinders.STRING_EX;

if (sqlType == StdSqlType.GEOMETRY)
return getGeometryDataParameterBinder();
return getGeometryTypeHandler();

IDataParameterBinder binder = DataParameterBinders.getDefaultBinder(sqlType.getName());
if (binder == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ public abstract class _DialectModel extends io.nop.core.resource.component.Abstr

/**
*
* xml name: geometryParameterBinder
* JDBC使用这个类存取GEOMETRY类型数据。 IDataParameterBinder类型
* xml name: geometryTypeHandler
* JDBC使用这个类存取GEOMETRY类型数据。 IDataTypeHandler类型
*/
private java.lang.String _geometryParameterBinder ;
private java.lang.String _geometryTypeHandler ;

/**
*
Expand Down Expand Up @@ -401,19 +401,19 @@ public boolean hasFunctions(){

/**
*
* xml name: geometryParameterBinder
* JDBC使用这个类存取GEOMETRY类型数据。 IDataParameterBinder类型
* xml name: geometryTypeHandler
* JDBC使用这个类存取GEOMETRY类型数据。 IDataTypeHandler类型
*/

public java.lang.String getGeometryParameterBinder(){
return _geometryParameterBinder;
public java.lang.String getGeometryTypeHandler(){
return _geometryTypeHandler;
}


public void setGeometryParameterBinder(java.lang.String value){
public void setGeometryTypeHandler(java.lang.String value){
checkAllowChange();

this._geometryParameterBinder = value;
this._geometryTypeHandler = value;

}

Expand Down Expand Up @@ -711,7 +711,7 @@ protected void outputJson(IJsonHandler out){
out.put("errorCodes",this.getErrorCodes());
out.put("features",this.getFeatures());
out.put("functions",this.getFunctions());
out.put("geometryParameterBinder",this.getGeometryParameterBinder());
out.put("geometryTypeHandler",this.getGeometryTypeHandler());
out.put("jdbcUrlPattern",this.getJdbcUrlPattern());
out.put("keywordQuote",this.getKeywordQuote());
out.put("keywordUnderscore",this.getKeywordUnderscore());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PostgresSQL, Oracle 10g/11g,MySQL,SQLServer,H2GIS,DB2,CockroachDB
<dialect x:schema="/nop/schema/orm/dialect.xdef"
xmlns:x="/nop/schema/xdsl.xdef"
>
<geometryParameterBinder>io.nop.orm.geo.binder.GeometryDataParameterBinder</geometryParameterBinder>
<geometryTypeHandler>io.nop.orm.geo.type.GeometryTypeHandler</geometryTypeHandler>

<functions>
<native name="st_dimension" returnType="INTEGER" argTypes="GEOMETRY">
Expand Down

This file was deleted.

138 changes: 138 additions & 0 deletions nop-orm-geo/src/main/java/io/nop/orm/geo/type/GeometryTypeHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package io.nop.orm.geo.type;

import io.nop.api.core.exceptions.NopException;
import io.nop.commons.type.StdSqlType;
import io.nop.commons.util.IoHelper;
import io.nop.dao.dialect.IDataTypeHandler;
import io.nop.dao.dialect.IDialect;
import io.nop.dataset.binder.IDataParameters;
import org.geolatte.geom.ByteBuffer;
import org.geolatte.geom.ByteOrder;
import org.geolatte.geom.C2D;
import org.geolatte.geom.Envelope;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.Polygon;
import org.geolatte.geom.PositionSequence;
import org.geolatte.geom.PositionSequenceBuilders;
import org.geolatte.geom.codec.Wkb;
import org.geolatte.geom.codec.WkbDecoder;
import org.geolatte.geom.codec.WkbEncoder;
import org.geolatte.geom.codec.Wkt;
import org.geolatte.geom.crs.CoordinateReferenceSystems;
import org.geolatte.geom.jts.JTS;

import java.io.InputStream;
import java.sql.Blob;

public class GeometryTypeHandler implements IDataTypeHandler {

@Override
public StdSqlType getStdSqlType() {
return StdSqlType.GEOMETRY;
}

protected String getGeomFromTextFunc() {
return "ST_GeomFromText";
}

protected Wkt.Dialect getWktDialect() {
return Wkt.Dialect.SFA_1_1_0;
}

protected Wkb.Dialect getWkbDialect() {
return Wkb.Dialect.POSTGIS_EWKB_1;
}

protected Geometry toGeometry(Object value) {
return (Geometry) value;
}

protected ByteOrder getByteOrder() {
return ByteOrder.NDR;
}

@Override
public String toLiteral(Object value, IDialect dialect) {
Geometry geom = toGeometry(value);
StringBuilder sb = new StringBuilder();
sb.append(getGeomFromTextFunc());
sb.append("('").append(Wkt.toWkt(geom, getWktDialect()));
sb.append("',").append(Math.max(geom.getSRID(), 0));
sb.append(')');
return sb.toString();
}


@Override
public Object fromLiteral(String text, IDialect dialect) {
return null;
}

@Override
public boolean isJavaType(Object value) {
return value instanceof Geometry;
}

@Override
public Object getValue(IDataParameters params, int index) {
Object value = params.getObject(index);
return fromValue(value);
}

@Override
public void setValue(IDataParameters params, int index, Object value) {
final Geometry geom = (Geometry) value;
params.setBytes(index, toBytes(geom, getWkbDialect(), getByteOrder()));
}

protected byte[] toBytes(Geometry geom, Wkb.Dialect dialect, ByteOrder byteOrder) {
final WkbEncoder encoder = Wkb.newEncoder(dialect);
final ByteBuffer buffer = encoder.encode(geom, byteOrder);
return (buffer == null ? null : buffer.toByteArray());
}

protected Geometry fromValue(Object object) {
if (object == null) {
return null;
}
try {
if (object instanceof org.locationtech.jts.geom.Geometry) {
return JTS.from((org.locationtech.jts.geom.Geometry) object);
}
final WkbDecoder decoder = Wkb.newDecoder(Wkb.Dialect.POSTGIS_EWKB_1);
if (object instanceof Blob) {
return decoder.decode(toByteBuffer((Blob) object));
} else if (object instanceof byte[]) {
return decoder.decode(ByteBuffer.from((byte[]) object));
} else if (object instanceof org.locationtech.jts.geom.Envelope) {
return toPolygon(JTS.from((org.locationtech.jts.geom.Envelope) object));
} else {
throw new IllegalArgumentException();
}
} catch (Exception e) {
throw NopException.adapt(e);
}
}

private static Geometry<C2D> toPolygon(Envelope env) {
final PositionSequence<C2D> ps = PositionSequenceBuilders.fixedSized(4, C2D.class)
.add(env.lowerLeft().getCoordinate(0), env.lowerLeft().getCoordinate(1))
.add(env.lowerLeft().getCoordinate(0), env.upperRight().getCoordinate(1))
.add(env.upperRight().getCoordinate(0), env.upperRight().getCoordinate(1))
.add(env.lowerLeft().getCoordinate(0), env.lowerLeft().getCoordinate(1))
.toPositionSequence();
return new Polygon<C2D>(ps, CoordinateReferenceSystems.PROJECTED_2D_METER);
}

private static ByteBuffer toByteBuffer(Blob blob) {
InputStream is = null;
try {
is = blob.getBinaryStream();
return ByteBuffer.from(IoHelper.readBytes(is));
} catch (Exception e) {
throw NopException.adapt(e);
} finally {
IoHelper.safeCloseObject(is);
}
}
}
4 changes: 2 additions & 2 deletions nop-xdefs/src/main/resources/_vfs/nop/schema/orm/dialect.xdef
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

<paginationHandler xdef:value="class-name"/>

<!-- JDBC使用这个类存取GEOMETRY类型数据。 IDataParameterBinder类型 -->
<geometryParameterBinder xdef:value="class-name"/>
<!-- JDBC使用这个类存取GEOMETRY类型数据。 IDataTypeHandler类型 -->
<geometryTypeHandler xdef:value="class-name"/>

<!--
@supportUpdateTableAlias update语句是否允许表别名。例如 update my_table a where ...
Expand Down

0 comments on commit 132bb85

Please sign in to comment.