All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.h2gis.utilities.GeometryMetaData Maven / Gradle / Ivy
/**
* H2GIS is a library that brings spatial support to the H2 Database Engine
* http://www.h2database.com . H2GIS is developed by CNRS
* http://www.cnrs.fr/ .
*
* This code is part of the H2GIS project. H2GIS is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; version 3.0 of
* the License.
*
* H2GIS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details .
*
*
* For more information, please consult: http://www.h2gis.org/
* or contact directly: info_at_h2gis.org
*/
package org.h2gis.utilities;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.value.ValueGeometry;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.*;
/**
* Extract Geometry MetaData from various geometry signatures
*/
public class GeometryMetaData {
/**
* If Z Component is available
*/
public boolean hasZ = false;
/**
* If M Component is available
*/
public boolean hasM = false;
/**
* Geometry dimension 2 , 3 or 4
*/
public int dimension = 2;
/**
* Full string representation of the geometry type include z and m dimension
* e.g POINTZM
*/
public String geometryType = "GEOMETRY";
/**
* SFS String representation of the geometry type only canonical form POINT,
* LINESTRING...
*/
public String sfs_geometryType = "GEOMETRY";
/**
* EPSG code
*/
public int SRID = 0;
/**
* Geometry type mask that indicates presence of dimension Z.
*/
public static final int EWKB_Z = 0x8000_0000;
/**
* Geometry type mask that indicates presence of dimension M.
*/
public static final int EWKB_M = 0x4000_0000;
/**
* Geometry type mask that indicates presence of SRID.
*/
public static final int EWKB_SRID = 0x2000_0000;
/**
* 0-based type names of geometries, subtract 1 from type code to get index
* in this array.
*/
static final String[] TYPES = { //
"POINT", //
"LINESTRING", //
"POLYGON", //
"MULTIPOINT", //
"MULTILINESTRING", //
"MULTIPOLYGON", //
"GEOMETRYCOLLECTION", //
};
/**
* Geometry type and dimension system in OGC geometry code format.
*/
public int geometryTypeCode = 0;
/**
* Simplified geometry type code without +1000
*/
public int sfs_geometryTypeCode = 0;
/**
* Geometry pattern used by create table
*/
static Pattern GEOMETRY_TABLE_PATTERN =null;
public GeometryMetaData() {
}
/**
* Linked with the H2 ValueGeometry model
*
* @param valueGeometry
*/
private GeometryMetaData(ValueGeometry valueGeometry) {
this.SRID = valueGeometry.getSRID();
this.geometryTypeCode = valueGeometry.getTypeAndDimensionSystem();
this.sfs_geometryTypeCode = geometryTypeCode % 1_000;
initDimension();
initGeometryType();
}
/**
* Find geometry dimension properties
*
*/
public void initDimension() {
switch (geometryTypeCode / 1_000) {
case 0:
dimension = 2;
break;
case 1:
dimension = 3;
hasZ = true;
hasM = false;
break;
case 2:
dimension = 3;
hasM = true;
hasZ = false;
break;
case 3:
dimension = 4;
hasZ = true;
hasM = true;
break;
default:
}
}
/**
* Find full geometryType
*
*/
public void initGeometryType() {
if (sfs_geometryTypeCode != 0) {
geometryType = TYPES[sfs_geometryTypeCode - 1];
sfs_geometryType = geometryType;
if (hasM && hasZ) {
geometryType += "ZM";
dimension = 4;
} else if (hasZ) {
geometryType += "Z";
dimension = 3;
} else if (hasM) {
geometryType += "M";
dimension = 3;
}
}
}
/**
* Return the dimension of the geometry
*
* 2 if XZ 3 if XZZ or XYM 4 if XYZM
*
* @return
*/
public int getDimension() {
return dimension;
}
/**
* Return a string representation of the geometry type as defined in SQL/MM
* specification. SQL-MM 3: 5.1.4 and OGC SFS 1.2
*
* @return
*/
public String getGeometryType() {
return geometryType;
}
/**
* Return an integer code representation of the geometry type as defined in
* SQL/MM specification. SQL-MM 3: 5.1.4 and OGC SFS 1.2
*
* @return
*/
public int getGeometryTypeCode() {
return geometryTypeCode;
}
/**
* Return the SRID
*
* @return
*/
public int getSRID() {
return SRID;
}
/**
* true if the geometry as a M dimension
*
* @return
*/
public boolean hasM() {
return hasM;
}
/**
* true if the geometry as a Z dimension
*
* @return
*/
public boolean hasZ() {
return hasZ;
}
/**
* Set SFS type code
* @param sfs_geometryTypeCode
*/
public void setSfs_geometryTypeCode(int sfs_geometryTypeCode) {
this.sfs_geometryTypeCode = sfs_geometryTypeCode;
}
/**
* Get SFS type code
* @return
*/
public String getSfs_geometryType() {
return sfs_geometryType;
}
/**
* Set the dimension of the geometry
* @param dimension
*/
public void setDimension(int dimension) {
this.dimension = dimension;
}
/**
* Set full geometry type with +1000
* @param geometryTypeCode
*/
public void setGeometryTypeCode(int geometryTypeCode) {
this.geometryTypeCode = geometryTypeCode;
this.sfs_geometryTypeCode = geometryTypeCode % 1_000;
}
/**
* Set the geometry type name
* @param geometryType
*/
public void setGeometryType(String geometryType) {
this.geometryType = geometryType;
}
/**
* Set the SRID
* @param SRID
*/
public void setSRID(int SRID) {
this.SRID = SRID;
}
/**
* Set the SFS geometry type name
* @param sfs_geometryType
*/
public void setSfs_geometryType(String sfs_geometryType) {
this.sfs_geometryType = sfs_geometryType;
}
/**
* True is geometry has M
* @param hasM
*/
public void setHasM(boolean hasM) {
this.hasM = hasM;
}
/**
* True is geometry has Z
* @param hasZ
*/
public void setHasZ(boolean hasZ) {
this.hasZ = hasZ;
}
/**
* Return the SQL representation of the geometry signature
*
* @return
*/
public String getSQL() {
StringBuilder sb = new StringBuilder("GEOMETRY");
if (geometryTypeCode != GeometryTypeCodes.GEOMETRY) {
sb.append("(").append(geometryType);
if (SRID != 0) {
sb.append(",").append(SRID);
}
sb.append(")");
}
return sb.toString();
}
/**
* Read the first bytes of Geometry WKB.
* Note this method read the SRID from the EWKB mask
* It's better to use getMetaData(geometry) to get all metadata
* @param bytes WKB Bytes
* @return Geometry MetaData
*/
public static GeometryMetaData getMetaData(byte[] bytes) {
try {
ByteOrderDataInStream dis = new ByteOrderDataInStream();
dis.setInStream(new ByteArrayInStream(bytes));
// determine byte order
byte byteOrderWKB = dis.readByte();
// always set byte order, since it may change from geometry to geometry
int byteOrder = byteOrderWKB == WKBConstants.wkbNDR ? ByteOrderValues.LITTLE_ENDIAN : ByteOrderValues.BIG_ENDIAN;
dis.setOrder(byteOrder);
int typeInt = dis.readInt();
int geometryType = typeInt & 0xff;
//From H2
boolean hasZ = (typeInt & EWKB_Z) != 0;
boolean hasM = (typeInt & EWKB_M) != 0;
int srid = (typeInt & EWKB_SRID) != 0 ? dis.readInt() : 0;
GeometryMetaData geomMet = new GeometryMetaData();
geomMet.setHasM(hasM);
geomMet.setHasZ(hasZ);
geomMet.setSRID(srid);
geomMet.setSfs_geometryTypeCode(geometryType);
geomMet.initGeometryType();
return geomMet;
}catch (IOException | ParseException ex) {
throw new RuntimeException("Cannot read the geometry metadata");
}
}
/**
* Read the first bytes of Geometry.
*
* @param geometry
* @return Geometry MetaData
*/
public static GeometryMetaData getMetaData(Geometry geometry) {
ValueGeometry valueGeometry = ValueGeometry.getFromGeometry(geometry);
return new GeometryMetaData(valueGeometry);
}
/**
* Read the metadata from its string representation
* The following signatures are allowed :
*
* SRID=4326,
* POINT(0 0)
* POINT(0 0)
*
* GEOMETRY
* GEOMETRY(POINTZ)
* GEOMETRY(POINTZ, 4326)
*
* @param geometry string representation
*
* @return Geometry MetaData
*/
public static GeometryMetaData getMetaData(String geometry) {
if (geometry != null && !geometry.isEmpty()) {
if (geometry.toUpperCase().startsWith("GEOMETRY")) {
if(GEOMETRY_TABLE_PATTERN==null) {
GEOMETRY_TABLE_PATTERN = Pattern.compile("(?:(?:GEOMETRY\\s*\\(\\s*([a-zA-Z]+\\s*(?:[ZM]+)?)\\s*(?:,\\s*([\\d]+))?\\))|^\\s*([a-zA-Z]+\\s*(?:[ZM]+)?))", Pattern.CASE_INSENSITIVE);
}
Matcher matcher = GEOMETRY_TABLE_PATTERN.matcher(geometry);
if (matcher.find()) {
String type = matcher.group(1);
if (type == null) {
return new GeometryMetaData();
} else {
String srid = matcher.group(2);
if (srid != null && !srid.isEmpty()) {
return createMetadataFromGeometryType(type, Integer.valueOf(srid));
} else {
return createMetadataFromGeometryType(type);
}
}
}
} else {
ValueGeometry valueGeometry = ValueGeometry.get(geometry);
return new GeometryMetaData(valueGeometry);
}
}
return null;
}
/**
* Read the metadata from its string representation
* The following signatures is allowed :
*
* GEOMETRY
* GEOMETRY(POINTZ)
* GEOMETRY(POINTZ, 4326)
*
* @param geometry_pattern pattern representation
*
* @return Geometry MetaData
*/
public static GeometryMetaData getMetaDataFromTablePattern(String geometry_pattern) {
if (geometry_pattern != null && !geometry_pattern.isEmpty()) {
if (geometry_pattern.toUpperCase().startsWith("GEOMETRY")) {
if(GEOMETRY_TABLE_PATTERN==null) {
GEOMETRY_TABLE_PATTERN = Pattern.compile("(?:(?:GEOMETRY\\s*\\(\\s*([a-zA-Z]+\\s*(?:[ZM]+)?)\\s*(?:,\\s*([\\d]+))?\\))|^\\s*([a-zA-Z]+\\s*(?:[ZM]+)?))", Pattern.CASE_INSENSITIVE);
}
Matcher matcher = GEOMETRY_TABLE_PATTERN.matcher(geometry_pattern);
if (matcher.find()) {
String type = matcher.group(1);
if (type == null) {
return new GeometryMetaData();
} else {
String srid = matcher.group(2);
if (srid != null && !srid.isEmpty()) {
return createMetadataFromGeometryType(type, Integer.valueOf(srid));
} else {
return createMetadataFromGeometryType(type);
}
}
}
}
}
return null;
}
/**
* Find geometry metadata according the EWKT canonical form
*
* as defined in SQL/MM specification. SQL-MM 3: 5.1.4 and OGC SFS 1.2
*
* @param type : geometry type
* @return GeometryMetaData
*/
public static GeometryMetaData createMetadataFromGeometryType(String type) {
return createMetadataFromGeometryType(type, 0);
}
/**
* Find geometry metadata according the EWKT canonical form and a SRID
*
* as defined in SQL/MM specification. SQL-MM 3: 5.1.4 and OGC SFS 1.2
*
* @param type : geometry type
* @param srid : srid value
* @return GeometryMetaData
*/
public static GeometryMetaData createMetadataFromGeometryType(String type, int srid) {
GeometryMetaData geometryMetaData = new GeometryMetaData();
geometryMetaData.setSRID(srid);
if (type == null) {
return geometryMetaData;
}
int dimension_ = 2;
int geometry_code = GeometryTypeCodes.GEOMETRY;
String sfs_geometry_type = "GEOMETRY";
String geometry_type = "GEOMETRY";
boolean hasz_ = false;
boolean hasm_ = false;
type = type.replaceAll(" ", "").replaceAll("\"", "");
switch (type) {
case "POINT":
dimension_ = 2;
geometry_code = GeometryTypeCodes.POINT;
sfs_geometry_type = "POINT";
geometry_type = "POINT";
hasz_ = false;
hasm_ = false;
break;
case "LINESTRING":
dimension_ = 2;
geometry_code = GeometryTypeCodes.LINESTRING;
sfs_geometry_type = "LINESTRING";
geometry_type = "LINESTRING";
hasz_ = false;
hasm_ = false;
break;
case "POLYGON":
dimension_ = 2;
geometry_code = GeometryTypeCodes.POLYGON;
sfs_geometry_type = "POLYGON";
geometry_type = "POLYGON";
hasz_ = false;
hasm_ = false;
break;
case "MULTIPOINT":
dimension_ = 2;
geometry_code = GeometryTypeCodes.MULTIPOINT;
sfs_geometry_type = "MULTIPOINT";
geometry_type = "MULTIPOINT";
hasz_ = false;
hasm_ = false;
break;
case "MULTILINESTRING":
dimension_ = 2;
geometry_code = GeometryTypeCodes.MULTILINESTRING;
sfs_geometry_type = "MULTILINESTRING";
geometry_type = "MULTILINESTRING";
hasz_ = false;
hasm_ = false;
break;
case "MULTIPOLYGON":
dimension_ = 2;
geometry_code = GeometryTypeCodes.MULTIPOLYGON;
sfs_geometry_type = "MULTIPOLYGON";
geometry_type = "MULTIPOLYGON";
hasz_ = false;
hasm_ = false;
break;
case "GEOMETRYCOLLECTION":
dimension_ = 2;
geometry_code = GeometryTypeCodes.GEOMCOLLECTION;
sfs_geometry_type = "GEOMCOLLECTION";
geometry_type = "GEOMCOLLECTION";
hasz_ = false;
hasm_ = false;
break;
case "POINTZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.POINTZ;
sfs_geometry_type = "POINTZ";
geometry_type = "POINTZ";
hasz_ = true;
hasm_ = false;
break;
case "LINESTRINGZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.LINESTRINGZ;
sfs_geometry_type = "LINESTRINGZ";
geometry_type = "LINESTRINGZ";
hasz_ = true;
hasm_ = false;
break;
case "POLYGONZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.POLYGONZ;
sfs_geometry_type = "POLYGONZ";
geometry_type = "POLYGONZ";
hasz_ = true;
hasm_ = false;
break;
case "MULTIPOINTZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTIPOINTZ;
sfs_geometry_type = "MULTIPOINTZ";
geometry_type = "MULTIPOINTZ";
hasz_ = true;
hasm_ = false;
break;
case "MULTILINESTRINGZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTILINESTRINGZ;
sfs_geometry_type = "MULTILINESTRINGZ";
geometry_type = "MULTILINESTRINGZ";
hasz_ = true;
hasm_ = false;
break;
case "MULTIPOLYGONZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTIPOLYGONZ;
sfs_geometry_type = "MULTIPOLYGONZ";
geometry_type = "MULTIPOLYGONZ";
hasz_ = true;
hasm_ = false;
break;
case "GEOMETRYCOLLECTIONZ":
dimension_ = 3;
geometry_code = GeometryTypeCodes.GEOMCOLLECTIONZ;
sfs_geometry_type = "GEOMETRYCOLLECTIONZ";
geometry_type = "GEOMETRYCOLLECTIONZ";
hasz_ = true;
hasm_ = false;
break;
case "POINTM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.POINTM;
sfs_geometry_type = "POINTM";
geometry_type = "POINTM";
hasz_ = false;
hasm_ = true;
break;
case "LINESTRINGM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.LINESTRINGM;
sfs_geometry_type = "LINESTRINGM";
geometry_type = "LINESTRINGM";
hasm_ = true;
break;
case "POLYGONM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.POLYGONM;
sfs_geometry_type = "POLYGONM";
geometry_type = "POLYGONM";
hasz_ = false;
hasm_ = true;
break;
case "MULTIPOINTM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTIPOINTM;
sfs_geometry_type = "MULTIPOINTM";
geometry_type = "MULTIPOINTM";
hasz_ = false;
hasm_ = true;
break;
case "MULTILINESTRINGM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTILINESTRINGM;
sfs_geometry_type = "MULTILINESTRINGM";
geometry_type = "MULTILINESTRINGM";
hasz_ = false;
hasm_ = true;
break;
case "MULTIPOLYGONM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.MULTIPOLYGONM;
sfs_geometry_type = "MULTIPOLYGONM";
geometry_type = "MULTIPOLYGONM";
hasz_ = false;
hasm_ = true;
break;
case "GEOMETRYCOLLECTIONM":
dimension_ = 3;
geometry_code = GeometryTypeCodes.GEOMCOLLECTIONM;
sfs_geometry_type = "GEOMETRYCOLLECTIONM";
geometry_type = "GEOMETRYCOLLECTIONM";
hasz_ = false;
hasm_ = true;
break;
case "POINTZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.POINTZM;
sfs_geometry_type = "POINTZM";
geometry_type = "POINTZM";
hasz_ = true;
hasm_ = true;
break;
case "LINESTRINGZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.LINESTRINGZM;
sfs_geometry_type = "LINESTRINGZM";
geometry_type = "LINESTRINGZM";
hasz_ = true;
hasm_ = true;
break;
case "POLYGONZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.POLYGONZM;
sfs_geometry_type = "POLYGONZM";
geometry_type = "POLYGONZM";
hasz_ = true;
hasm_ = true;
break;
case "MULTIPOINTZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.MULTIPOINTZM;
sfs_geometry_type = "MULTIPOINTZM";
geometry_type = "MULTIPOINTZM";
hasz_ = true;
hasm_ = true;
break;
case "MULTILINESTRINGZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.MULTILINESTRINGZM;
sfs_geometry_type = "MULTILINESTRINGZM";
geometry_type = "MULTILINESTRINGZM";
hasz_ = true;
hasm_ = true;
break;
case "MULTIPOLYGONZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.MULTIPOLYGONZM;
sfs_geometry_type = "MULTIPOLYGONZM";
geometry_type = "MULTIPOLYGONZM";
hasz_ = true;
hasm_ = true;
break;
case "GEOMETRYCOLLECTIONZM":
dimension_ = 4;
geometry_code = GeometryTypeCodes.GEOMCOLLECTIONZM;
sfs_geometry_type = "GEOMETRYCOLLECTIONZM";
geometry_type = "GEOMETRYCOLLECTIONZM";
hasz_ = true;
hasm_ = true;
break;
case "GEOMETRY":
default:
}
geometryMetaData.setDimension(dimension_);
geometryMetaData.setGeometryTypeCode(geometry_code);
geometryMetaData.setSfs_geometryType(sfs_geometry_type);
geometryMetaData.setGeometryType(geometry_type);
geometryMetaData.setHasM(hasm_);
geometryMetaData.setHasZ(hasz_);
return geometryMetaData;
}
/**
* Return the SFS geometry type code
* @return
*/
public int getSfs_geometryTypeCode() {
return sfs_geometryTypeCode;
}
}