Refactoring and gpkg
This commit is contained in:
parent
ee9cdcfd20
commit
42aaf1e10c
|
@ -127,19 +127,19 @@ public class PostgisDBManager {
|
|||
}
|
||||
|
||||
public PostgisTable.BBOX evaluateBoundingBox(PostgisTable table) throws SQLException, DataParsingException {
|
||||
ResultSet rs=conn.createStatement().executeQuery("Select ST_Extent("+table.getGeometryColumnName()+") as extent from "+table.getTablename());
|
||||
ResultSet rs=conn.createStatement().executeQuery("Select ST_Extent("+table.getGeometryColumn()+") as extent from "+table.getTablename());
|
||||
if(rs.next())
|
||||
return PostgisTable.BBOX.parseST_Extent(rs.getString("extent"));
|
||||
else throw new SQLException("No extent returned");
|
||||
}
|
||||
|
||||
public PreparedStatement prepareInsertStatement(PostgisTable target, boolean createTable) throws SQLException {
|
||||
public PreparedStatement prepareInsertStatement(PostgisTable target, boolean createTable, boolean geometryAsText) throws SQLException {
|
||||
if(createTable) {
|
||||
String createStmt=target.getCreateStatement();
|
||||
log.debug("Executing create : "+createStmt);
|
||||
conn.createStatement().executeUpdate(createStmt);
|
||||
}
|
||||
String insertStmt=target.getInsertionStatement();
|
||||
String insertStmt=target.getInsertionStatement(geometryAsText);
|
||||
log.debug("Preparing insert statement : "+insertStmt);
|
||||
return conn.prepareStatement(insertStmt);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package org.gcube.application.geoportal;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.gcube.application.geoportal.model.DBInteractionException;
|
||||
import org.gcube.application.geoportal.model.DataParsingException;
|
||||
import org.gcube.application.geoportal.model.PostgisTable;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.Field;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.FieldType;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.GeometryType;
|
||||
import org.gcube.application.geoportal.utils.CSV;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mil.nga.geopackage.GeoPackage;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class PostgisTableFactory {
|
||||
|
||||
@NonNull
|
||||
private PostgisDBManager db;
|
||||
|
||||
|
||||
public PostgisTable fromCSV(String csvFile) throws DBInteractionException, FileNotFoundException, IOException, SQLException, DataParsingException {
|
||||
CSVParser parser=null;
|
||||
try {
|
||||
log.debug("Creating table from CSV FILE "+csvFile);
|
||||
parser=CSV.fromPath(csvFile);
|
||||
|
||||
|
||||
// Getting type
|
||||
GeometryType type=GeometryType.POINT;
|
||||
if(csvFile.contains("linee"))
|
||||
type=GeometryType.LINE;
|
||||
else if(csvFile.contains("poligoni"))
|
||||
type=GeometryType.POLYGON;
|
||||
|
||||
PostgisTable toReturn=fromCSVHeaders(parser.getHeaderNames(), type);
|
||||
|
||||
|
||||
|
||||
//insert Prepared statmenet
|
||||
PreparedStatement ps=db.prepareInsertStatement(toReturn, true,true);
|
||||
|
||||
|
||||
log.debug("Inserting records..");
|
||||
long count=0l;
|
||||
for(CSVRecord r:parser.getRecords()) {
|
||||
Map<String,String> map=r.toMap();
|
||||
try {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
toReturn.fillCSVPreparedStatament(map, ps,false);
|
||||
count+=ps.executeUpdate();
|
||||
}catch(Throwable t) {
|
||||
log.warn("Row in error : "+map);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
if(count!=parser.getRecordNumber())
|
||||
throw new DBInteractionException("Incoherent number of inserted records : "+count+" / "+parser.getRecordNumber());
|
||||
|
||||
log.debug("Evaluating extent.. ");
|
||||
toReturn.setBoundingBox(db.evaluateBoundingBox(toReturn));
|
||||
return toReturn;
|
||||
|
||||
|
||||
}finally {
|
||||
if(parser!=null&&!parser.isClosed())
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
|
||||
public PostgisTable getExisting(String tableName) {
|
||||
throw new RuntimeException("IMPLEMENT THIS");
|
||||
}
|
||||
|
||||
public PostgisTable fromGPKGFeatureTable(GeoPackage gpkg, String featureTableName) {
|
||||
throw new RuntimeException("IMPLEMENT THIS");
|
||||
}
|
||||
|
||||
|
||||
//***************** DEFAULTS
|
||||
private static final String DEFAULT_GEOMETRY_COLUMN_NAME="geom";
|
||||
private static final String INTERNAL_ID="internal_id";
|
||||
|
||||
public static final PostgisTable CENTROID=new PostgisTable(INTERNAL_ID,true,"centroids",
|
||||
new ArrayList<Field>(), GeometryType.POINT);
|
||||
|
||||
|
||||
static {
|
||||
CENTROID.getFields().add(new Field("uuid",FieldType.TEXT));
|
||||
CENTROID.getFields().add(new Field("nome",FieldType.TEXT));
|
||||
CENTROID.getFields().add(new Field("anno",FieldType.INT));
|
||||
CENTROID.getFields().add(new Field("regione",FieldType.INT));
|
||||
CENTROID.getFields().add(new Field("geom",FieldType.GEOMETRY));
|
||||
}
|
||||
|
||||
|
||||
//***************** CSV
|
||||
|
||||
private static final PostgisTable fromCSVHeaders(List<String> csvHeaders, GeometryType expectedType) {
|
||||
String tableName="l"+UUID.randomUUID().toString().toLowerCase().replaceAll("-", "_");
|
||||
|
||||
//check constraints..
|
||||
switch(expectedType) {
|
||||
case POINT :{
|
||||
if(!csvHeaders.contains("xcoord")) throw new RuntimeException("No xcoord in headers");
|
||||
if(!csvHeaders.contains("ycoord")) throw new RuntimeException("No ycoord in headers");
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
if(!csvHeaders.contains("wkt"))
|
||||
throw new RuntimeException("No wkt in headers");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// parsing expected field types
|
||||
ArrayList<Field> toSetFields=new ArrayList<PostgisTable.Field>();
|
||||
for(String csvHeader:csvHeaders) {
|
||||
String fieldName=PostgisTable.sanitizeFieldName(csvHeader);
|
||||
FieldType type=FieldType.TEXT;
|
||||
|
||||
switch(fieldName) {
|
||||
|
||||
case("xcoord"):
|
||||
case("ycoord"):{
|
||||
type=FieldType.FLOAT;
|
||||
break;
|
||||
}
|
||||
case("year"):
|
||||
case ("fid"):
|
||||
case ("objectid"):{
|
||||
type=FieldType.INT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
toSetFields.add(new Field(fieldName, type));
|
||||
}
|
||||
|
||||
String geometryColumnName=DEFAULT_GEOMETRY_COLUMN_NAME;
|
||||
GeometryType geometryColumnType=expectedType;
|
||||
|
||||
toSetFields.add(new Field(DEFAULT_GEOMETRY_COLUMN_NAME,FieldType.GEOMETRY));
|
||||
toSetFields.add(new Field(INTERNAL_ID,FieldType.AUTOINCREMENT));
|
||||
|
||||
|
||||
return new PostgisTable(INTERNAL_ID,true,tableName,toSetFields, geometryColumnType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -160,17 +160,9 @@ public class Uploader {
|
|||
}
|
||||
|
||||
|
||||
public static LayerDescriptor publishPostgisTable(PostgisTable table,GISInterface gis, GeoNetworkPublisher geonetwork, String layerName, String workspace, String storeName) throws Exception {
|
||||
|
||||
|
||||
public static LayerDescriptor publishLayer(String csvLayer, PostgisTable.GeometryType expectedType,PostgisDBManager db,GISInterface gis, GeoNetworkPublisher geonetwork) throws Exception {
|
||||
|
||||
|
||||
PostgisTable table =CSV.persistCSVLayer(csvLayer, expectedType, db);
|
||||
|
||||
db.commit();
|
||||
|
||||
String workspace = "geona-proto";
|
||||
String storeName = "postgis_db";
|
||||
|
||||
String DEFAULT_CRS="GEOGCS[\"WGS 84\", \n" +
|
||||
" DATUM[\"World Geodetic System 1984\", \n" +
|
||||
|
@ -189,14 +181,14 @@ public class Uploader {
|
|||
BBOX bbox=table.getBoundingBox();
|
||||
fte.setLatLonBoundingBox(bbox.getMinLong(), bbox.getMinLat(), bbox.getMaxLong(), bbox.getMaxLat(), DEFAULT_CRS);
|
||||
fte.setName(table.getTablename());
|
||||
fte.setTitle(Files.getName(csvLayer));
|
||||
fte.setTitle(layerName);
|
||||
// fte.setNativeCRS(DEFAULT_CRS);
|
||||
|
||||
GSLayerEncoder le=new GSLayerEncoder();
|
||||
|
||||
String defaultStyle=null;
|
||||
|
||||
switch(expectedType) {
|
||||
switch(table.getGeometryColumnType()) {
|
||||
case LINE : {
|
||||
defaultStyle = "line";
|
||||
break;
|
||||
|
@ -244,6 +236,23 @@ public class Uploader {
|
|||
table.getTablename());
|
||||
}
|
||||
|
||||
public static LayerDescriptor publishLayer(String csvLayer, PostgisTable.GeometryType expectedType,PostgisDBManager db,GISInterface gis, GeoNetworkPublisher geonetwork) throws Exception {
|
||||
|
||||
|
||||
PostgisTable table =CSV.persistCSVLayer(csvLayer, expectedType, db);
|
||||
|
||||
db.commit();
|
||||
|
||||
String workspace = "geona-proto";
|
||||
String storeName = "postgis_db";
|
||||
|
||||
String layerName=Files.getName(csvLayer);
|
||||
|
||||
return publishPostgisTable(table, gis, geonetwork, layerName, workspace, storeName);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static Metadata generateMeta(LayerDescriptor layerDescriptor) {
|
||||
try {
|
||||
|
|
|
@ -4,17 +4,15 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.SQLException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
@ -29,10 +27,44 @@ import lombok.extern.slf4j.Slf4j;
|
|||
public class PostgisTable {
|
||||
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static enum GeometryType{
|
||||
POINT,LINE,POLYGON
|
||||
POINT("4326","geometry (POINT,4326)","",""),
|
||||
LINE("4326","geometry (MULTILINESTRING,4326)","",""),
|
||||
POLYGON("4326","geometry (MULTIPOLYGON,4326)","","");
|
||||
private final String SRID;
|
||||
private final String definition;
|
||||
private final String InsertWKT;
|
||||
private final String insertWKB;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public static class Field{
|
||||
@NonNull
|
||||
private String name;
|
||||
@NonNull
|
||||
private FieldType type;
|
||||
private Boolean isIndexed;
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum FieldType{
|
||||
INT("int",java.sql.Types.INTEGER),
|
||||
TEXT("text",java.sql.Types.LONGNVARCHAR),
|
||||
FLOAT("float",java.sql.Types.FLOAT),
|
||||
GEOMETRY("",0),
|
||||
AUTOINCREMENT("BIGSERIAL PRIMARY KEY",java.sql.Types.BIGINT);
|
||||
|
||||
private String definition;
|
||||
private int sqlType;
|
||||
}
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
|
@ -90,49 +122,24 @@ public class PostgisTable {
|
|||
}
|
||||
|
||||
|
||||
private static final String GEOMETRY_COLUMN_NAME="geom";
|
||||
private static final String INTERNAL_ID="internal_id";
|
||||
|
||||
public static final PostgisTable CENTROID=new PostgisTable("centroids", Arrays.asList(new String[] {"uuid","nome","anno","regione","geom"}), GEOMETRY_COLUMN_NAME, GeometryType.POINT);
|
||||
|
||||
|
||||
public static final PostgisTable fromCSVHeaders(List<String> csvHeaders, GeometryType expectedType) {
|
||||
String tableName="l"+UUID.randomUUID().toString().toLowerCase().replaceAll("-", "_");
|
||||
|
||||
ArrayList<String> fields=new ArrayList<String>();
|
||||
for(String csvHeader:csvHeaders)
|
||||
fields.add(sanitizeFieldName(csvHeader));
|
||||
|
||||
String geometryColumnName=GEOMETRY_COLUMN_NAME;
|
||||
GeometryType geometryColumnType=expectedType;
|
||||
|
||||
fields.add(GEOMETRY_COLUMN_NAME);
|
||||
fields.add(INTERNAL_ID);
|
||||
|
||||
switch(expectedType) {
|
||||
case POINT :{
|
||||
if(!fields.contains("xcoord")) throw new RuntimeException("No xcoord in headers");
|
||||
if(!fields.contains("ycoord")) throw new RuntimeException("No ycoord in headers");
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
if(!fields.contains("wkt"))
|
||||
throw new RuntimeException("No wkt in headers");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new PostgisTable(tableName, fields, geometryColumnName, geometryColumnType);
|
||||
public String getGeometryColumn() {
|
||||
for(Field f:fields)
|
||||
if(f.getType().equals(FieldType.GEOMETRY)) return f.getName();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NonNull
|
||||
private String keyField;
|
||||
@NonNull
|
||||
private Boolean isAutoIncrement;
|
||||
|
||||
@NonNull
|
||||
private String tablename;
|
||||
|
||||
@NonNull
|
||||
private List<String> fieldNames;
|
||||
@NonNull
|
||||
private String geometryColumnName;
|
||||
private List<Field> fields;
|
||||
|
||||
|
||||
@NonNull
|
||||
private GeometryType geometryColumnType;
|
||||
|
||||
|
@ -147,69 +154,38 @@ public class PostgisTable {
|
|||
public String getCreateStatement() {
|
||||
StringBuilder stmt=new StringBuilder();
|
||||
stmt.append("CREATE TABLE "+tablename+"( ");
|
||||
for(String field:fieldNames) {
|
||||
String fieldDefinition=null;
|
||||
switch(field) {
|
||||
case(GEOMETRY_COLUMN_NAME):{
|
||||
switch(geometryColumnType) {
|
||||
case LINE:{
|
||||
fieldDefinition="geometry (MULTILINESTRING,4326)";
|
||||
break;
|
||||
}
|
||||
case POLYGON : {
|
||||
fieldDefinition="geometry (MULTIPOLYGON,4326)";
|
||||
break;
|
||||
}
|
||||
case POINT:{
|
||||
fieldDefinition="geometry (POINT,4326)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case("xcoord"):
|
||||
case("ycoord"):{
|
||||
fieldDefinition="float";
|
||||
break;
|
||||
}
|
||||
case("year"):{
|
||||
fieldDefinition="int";
|
||||
break;
|
||||
}
|
||||
case ("fid"):
|
||||
// case ("id"):
|
||||
case ("objectid"):{
|
||||
fieldDefinition="int";
|
||||
// fieldDefinition="BIGSERIAL PRIMARY KEY";
|
||||
break;
|
||||
}
|
||||
case(INTERNAL_ID):{
|
||||
fieldDefinition="BIGSERIAL PRIMARY KEY";
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
fieldDefinition="text";
|
||||
break;
|
||||
}
|
||||
}
|
||||
stmt.append(field+" "+fieldDefinition+",");
|
||||
for(Field field:fields){
|
||||
|
||||
String fieldDefinition=field.getType().getDefinition();
|
||||
if(field.getType().equals(FieldType.GEOMETRY))
|
||||
fieldDefinition=this.getGeometryColumnType().definition;
|
||||
|
||||
stmt.append(field.getName()+" "+fieldDefinition+",");
|
||||
}
|
||||
stmt.deleteCharAt(stmt.lastIndexOf(","));
|
||||
stmt.append(")");
|
||||
return stmt.toString();
|
||||
}
|
||||
|
||||
public String getInsertionStatement() {
|
||||
public String getInsertionStatement(boolean geometryText) {
|
||||
StringBuilder fieldList=new StringBuilder();
|
||||
StringBuilder fieldInsertion=new StringBuilder();
|
||||
|
||||
for(String field:fieldNames) {
|
||||
if(!field.equals(INTERNAL_ID)) {
|
||||
for(Field field:fields) {
|
||||
switch(field.getType()) {
|
||||
case AUTOINCREMENT : break;
|
||||
case GEOMETRY : {
|
||||
fieldList.append(field+",");
|
||||
|
||||
if(field.equals(geometryColumnName)) {
|
||||
if(geometryText)
|
||||
fieldInsertion.append("ST_GeomFromText(?, 4326),");
|
||||
}else fieldInsertion.append("?,");
|
||||
else
|
||||
fieldInsertion.append("ST_GeomFromWKB(?, 4326),");
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
fieldList.append(field+",");
|
||||
fieldInsertion.append("?,");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,22 +198,87 @@ public class PostgisTable {
|
|||
}
|
||||
|
||||
|
||||
public void fillPreparedStatement(Map<String,String> row, PreparedStatement toFill) throws SQLException {
|
||||
public void fillObjectsPreparedStatement(Map<String,Object> row, PreparedStatement toFill) throws SQLException {
|
||||
int psFieldIndex=0;
|
||||
HashMap<String,String> rowValues=new HashMap<String, String>();
|
||||
for(Entry<String,String> entry:row.entrySet())
|
||||
HashMap<String,Object> rowValues=new HashMap<String,Object>();
|
||||
for(Entry<String,Object> entry:row.entrySet())
|
||||
rowValues.put(sanitizeFieldName(entry.getKey()), entry.getValue());
|
||||
|
||||
|
||||
for(String field:fieldNames) {
|
||||
if(!field.equals(INTERNAL_ID)) {
|
||||
for(Field field:fields) {
|
||||
if(!field.getType().equals(FieldType.AUTOINCREMENT)) {
|
||||
psFieldIndex++;
|
||||
String currentValue=rowValues.get(field);
|
||||
// log.debug("Setting "+field+" ["+psFieldIndex+"] = "+currentValue);
|
||||
|
||||
switch(field) {
|
||||
case(GEOMETRY_COLUMN_NAME):{
|
||||
Object value=rowValues.get(field.getName());
|
||||
|
||||
if(value==null) toFill.setNull(psFieldIndex, field.getType().sqlType);
|
||||
else
|
||||
switch(field.getType()) {
|
||||
case FLOAT :{
|
||||
toFill.setFloat(psFieldIndex, (Float)value);
|
||||
break;
|
||||
}
|
||||
case INT : {
|
||||
toFill.setInt(psFieldIndex, (Integer)value);
|
||||
break;
|
||||
}
|
||||
case TEXT : {
|
||||
toFill.setString(psFieldIndex, value.toString());
|
||||
break;
|
||||
}
|
||||
case GEOMETRY : {
|
||||
toFill.setBytes(psFieldIndex, (byte[])value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void fillCSVPreparedStatament(Map<String,String> row, PreparedStatement toFill,boolean explicitGeometry) throws SQLException {
|
||||
int psFieldIndex=0;
|
||||
|
||||
HashMap<String,String> rowValues=new HashMap<String,String>();
|
||||
for(Entry<String,String> entry:row.entrySet())
|
||||
rowValues.put(sanitizeFieldName(entry.getKey()), entry.getValue());
|
||||
|
||||
for(Field field:fields) {
|
||||
|
||||
|
||||
if(!field.getType().equals(FieldType.AUTOINCREMENT)) {
|
||||
psFieldIndex++;
|
||||
|
||||
String value=rowValues.get(field.getName());
|
||||
|
||||
if(value==null||value.equalsIgnoreCase("null")) toFill.setNull(psFieldIndex, field.getType().sqlType);
|
||||
else
|
||||
switch(field.getType()) {
|
||||
case FLOAT :{
|
||||
try{
|
||||
toFill.setFloat(psFieldIndex, Float.parseFloat(value));
|
||||
}catch(NumberFormatException e) {
|
||||
throw new SQLException(field+" cannot be null. CSV Row is "+rowValues,e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INT : {
|
||||
try{
|
||||
toFill.setInt(psFieldIndex, Integer.parseInt(value));
|
||||
}catch(NumberFormatException e) {
|
||||
log.warn("Skipping value for "+field+" row was "+rowValues,e);
|
||||
toFill.setNull(psFieldIndex, java.sql.Types.INTEGER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEXT : {
|
||||
toFill.setString(psFieldIndex, value.toString());
|
||||
break;
|
||||
}
|
||||
case GEOMETRY : {
|
||||
if(explicitGeometry) {
|
||||
toFill.setString(psFieldIndex,value);
|
||||
}else {
|
||||
switch(geometryColumnType){
|
||||
case POINT: {
|
||||
String xRepresentation=DECIMAL_FORMAT.format(Double.parseDouble(rowValues.get("xcoord")));
|
||||
|
@ -252,40 +293,20 @@ public class PostgisTable {
|
|||
break;
|
||||
}
|
||||
}
|
||||
//END GEOMETRY
|
||||
break;
|
||||
}
|
||||
case("xcoord"):
|
||||
case("ycoord"):{
|
||||
try{
|
||||
toFill.setFloat(psFieldIndex, Float.parseFloat(currentValue));
|
||||
}catch(NumberFormatException e) {
|
||||
throw new SQLException(field+" cannot be null. CSV Row is "+rowValues,e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case("year"):
|
||||
case ("fid"):
|
||||
// case ("id"):
|
||||
case ("objectid"):{
|
||||
try{
|
||||
toFill.setInt(psFieldIndex, Integer.parseInt(currentValue));
|
||||
}catch(NumberFormatException e) {
|
||||
log.warn("Skipping value for "+field+" row was "+rowValues,e);
|
||||
toFill.setNull(psFieldIndex, java.sql.Types.INTEGER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
toFill.setString(psFieldIndex, currentValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String sanitizeFieldName(String fieldName) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String sanitizeFieldName(String fieldName) {
|
||||
return fieldName.toLowerCase().replaceAll(" ", "_").replaceAll("\\.", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,75 +27,44 @@ public class CSV {
|
|||
|
||||
|
||||
|
||||
public static final PostgisTable tableFromCSV(String path,GeometryType geometryType) throws IOException {
|
||||
CSVParser parser=null;
|
||||
try {
|
||||
parser=fromPath(path);
|
||||
return PostgisTable.fromCSVHeaders(parser.getHeaderNames(), geometryType);
|
||||
}finally {
|
||||
if(parser!=null&&!parser.isClosed())
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final PostgisTable updateTable(PostgisTable table, String csvPath, PostgisDBManager db, boolean clean) throws SQLException, IOException, DBInteractionException, DataParsingException {
|
||||
CSVParser parser=null;
|
||||
try {
|
||||
log.debug("Updateing table "+table.getTablename()+" with "+csvPath);
|
||||
parser=fromPath(csvPath);
|
||||
if(clean) {
|
||||
log.debug("Truncating existing");
|
||||
db.truncate(table.getTablename());
|
||||
}
|
||||
return persist(parser,table,db);
|
||||
|
||||
|
||||
}finally {
|
||||
if(parser!=null&&!parser.isClosed())
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static final PostgisTable persist(CSVParser source,PostgisTable target, PostgisDBManager db) throws IOException, SQLException, DBInteractionException, DataParsingException {
|
||||
PreparedStatement ps=db.prepareInsertStatement(target, true);
|
||||
log.debug("Inserting records..");
|
||||
long count=0l;
|
||||
for(CSVRecord r:source.getRecords()) {
|
||||
Map<String,String> map=r.toMap();
|
||||
try {
|
||||
target.fillPreparedStatement(map, ps);
|
||||
count+=ps.executeUpdate();
|
||||
}catch(Throwable t) {
|
||||
log.warn("Row in error : "+map);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
if(count!=source.getRecordNumber())
|
||||
throw new DBInteractionException("Incoherent number of inserted records : "+count+" / "+source.getRecordNumber());
|
||||
|
||||
log.debug("Evaluating extent.. ");
|
||||
target.setBoundingBox(db.evaluateBoundingBox(target));
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
public static final PostgisTable persistCSVLayer(String csvFile,GeometryType type, PostgisDBManager db) throws FileNotFoundException, IOException, SQLException, DBInteractionException, DataParsingException {
|
||||
CSVParser parser=null;
|
||||
try {
|
||||
parser=fromPath(csvFile);
|
||||
PostgisTable toPersist= PostgisTable.fromCSVHeaders(parser.getHeaderNames(), type);
|
||||
|
||||
toPersist.setTablename(Files.getName(csvFile)+"_"+toPersist.getTablename());
|
||||
// public static final PostgisTable updateTable(PostgisTable table, String csvPath, PostgisDBManager db, boolean clean) throws SQLException, IOException, DBInteractionException, DataParsingException {
|
||||
// CSVParser parser=null;
|
||||
// try {
|
||||
// log.debug("Updateing table "+table.getTablename()+" with "+csvPath);
|
||||
// parser=fromPath(csvPath);
|
||||
// if(clean) {
|
||||
// log.debug("Truncating existing");
|
||||
// db.truncate(table.getTablename());
|
||||
// }
|
||||
// return persist(parser,table,db);
|
||||
//
|
||||
//
|
||||
// }finally {
|
||||
// if(parser!=null&&!parser.isClosed())
|
||||
// parser.close();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
return persist(parser,toPersist,db);
|
||||
}finally {
|
||||
if(parser!=null&&!parser.isClosed())
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
// public static final PostgisTable persistCSVLayer(String csvFile,GeometryType type, PostgisDBManager db) throws FileNotFoundException, IOException, SQLException, DBInteractionException, DataParsingException {
|
||||
// CSVParser parser=null;
|
||||
// try {
|
||||
// parser=fromPath(csvFile);
|
||||
// PostgisTable toPersist= PostgisTable.fromCSVHeaders(parser.getHeaderNames(), type);
|
||||
//
|
||||
// toPersist.setTablename(Files.getName(csvFile)+"_"+toPersist.getTablename());
|
||||
//
|
||||
//
|
||||
//
|
||||
// return persist(parser,toPersist,db);
|
||||
// }finally {
|
||||
// if(parser!=null&&!parser.isClosed())
|
||||
// parser.close();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public static GeometryType getTypeFromPath(String csv) {
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
package org.gcube.application.geoportal.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.print.attribute.HashAttributeSet;
|
||||
|
||||
import org.gcube.application.geoportal.PostgisDBManager;
|
||||
import org.gcube.application.geoportal.model.GeoPackageInteractionException;
|
||||
import org.gcube.application.geoportal.model.PostgisTable;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.GeometryType;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mil.nga.geopackage.GeoPackage;
|
||||
import mil.nga.geopackage.features.user.FeatureColumn;
|
||||
import mil.nga.geopackage.features.user.FeatureDao;
|
||||
import mil.nga.geopackage.features.user.FeatureResultSet;
|
||||
import mil.nga.geopackage.manager.GeoPackageManager;
|
||||
|
||||
@Slf4j
|
||||
|
@ -28,17 +37,61 @@ public class GpkgUtils {
|
|||
FeatureDao featureDao = gpkg.getFeatureDao(tableName);
|
||||
log.debug("Columns : ");
|
||||
// Query Features
|
||||
String geometry=null;
|
||||
PostgisTable.GeometryType type=null;
|
||||
List<String> fields=new ArrayList<String>();
|
||||
|
||||
for(FeatureColumn featCol:featureDao.getColumns()) {
|
||||
log.debug(featCol.getName()+"\t"+featCol.getType()+"\t"+featCol.getConstraints()+"\t"+featCol.getGeometryType());
|
||||
fields.add(featCol.getName());
|
||||
|
||||
if(featCol.getGeometryType()!=null) {
|
||||
geometry=featCol.getName();
|
||||
switch(featCol.getGeometryType().toString()) {
|
||||
case "POINT" : type=GeometryType.POINT;
|
||||
break;
|
||||
case "MULTIPOLYGON" : type=GeometryType.POLYGON;
|
||||
break;
|
||||
case "MULTILINESTRING" : type=GeometryType.LINE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// FeatureResultSet featureResultSet = featureDao.queryForAll();
|
||||
String toCreate=tableName+"_"+UUID.randomUUID().toString().toLowerCase().replaceAll("-", "_");
|
||||
return new PostgisTable(toCreate, fields, geometry, type);
|
||||
|
||||
}
|
||||
|
||||
public static PostgisTable storeIntoPostgis(GeoPackage gpkg, String gpkgFeatureTableName, PostgisDBManager db) {
|
||||
PostgisTable toReturn=asPostgisTable(gpkg, gpkgFeatureTableName);
|
||||
PreparedStatement ps=db.prepareInsertStatement(toReturn, true);
|
||||
|
||||
FeatureDao featureDao = gpkg.getFeatureDao(gpkgFeatureTableName);
|
||||
|
||||
FeatureResultSet rs=featureDao.query();
|
||||
|
||||
|
||||
while (rs.moveToNext()) {
|
||||
for(int i=0;i<toReturn.getFieldNames().size();i++) {
|
||||
String fieldName=toReturn.getFieldNames().get(i);
|
||||
if(fieldName.equals(toReturn.getGeometryColumnName())) {
|
||||
// Setting geometry from WKB
|
||||
}
|
||||
|
||||
|
||||
String value=fieldName.equals(toReturn.getGeometryColumnName())?
|
||||
rs.getGeometry().getWkbBytes():rs.getString(i+1);
|
||||
row.put(,rs.getString(i+1));
|
||||
}
|
||||
|
||||
ps=toReturn.fillPreparedStatement(row, ps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static GeoPackage open(File gpkg) {
|
||||
return GeoPackageManager.open(gpkg);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.gcube.application.geoportal;
|
|||
import java.io.File;
|
||||
|
||||
import org.gcube.application.geoportal.model.GeoPackageInteractionException;
|
||||
import org.gcube.application.geoportal.model.PostgisTable;
|
||||
import org.gcube.application.geoportal.utils.Files;
|
||||
import org.gcube.application.geoportal.utils.GpkgUtils;
|
||||
import org.junit.Test;
|
||||
|
@ -15,11 +16,17 @@ public class GeopackageTests {
|
|||
public void readMOSI() throws GeoPackageInteractionException {
|
||||
File gpkgFile = Files.getFileFromResources("gpkg/ArcheoPrevTemplateItalia.gpkg");
|
||||
GeoPackage gpkg=GpkgUtils.open(gpkgFile);
|
||||
GpkgUtils.asPostgisTable(gpkg, "MOSI_point");
|
||||
PostgisTable t=GpkgUtils.asPostgisTable(gpkg, "MOSI_point");
|
||||
PostgisDBManager db=PostgisDBManager.get();
|
||||
|
||||
PreparedStatment psInsert=db.prepareInsertStatement(t, true);
|
||||
t.fillPreparedStatement(row, toFill);
|
||||
|
||||
|
||||
GpkgUtils.asPostgisTable(gpkg, "MOSI_multipolygon");
|
||||
GpkgUtils.asPostgisTable(gpkg, "MOSI_multilinea");
|
||||
GpkgUtils.asPostgisTable(gpkg, "MOSI_SW");
|
||||
GpkgUtils.asPostgisTable(gpkg, "MOSI_MOPR");
|
||||
// GpkgUtils.asPostgisTable(gpkg, "MOSI_MOPR");
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ package org.gcube.application.geoportal.db;
|
|||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
|
||||
import org.gcube.application.geoportal.PostgisTableFactory;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.GeometryType;
|
||||
import org.gcube.application.geoportal.utils.CSV;
|
||||
import org.gcube.application.geoportal.utils.Files;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -35,18 +35,12 @@ public class PostgisTableTests {
|
|||
return pathname.getName().endsWith(".csv");
|
||||
}
|
||||
})){
|
||||
String csv=csvFile.getName();
|
||||
System.out.println("loading : "+csv);
|
||||
GeometryType type=GeometryType.POINT;
|
||||
if(csv.contains("linee"))
|
||||
type=GeometryType.LINE;
|
||||
else if(csv.contains("poligoni"))
|
||||
type=GeometryType.POLYGON;
|
||||
PostgisTableFactory f=new PostgisTableFactory(null);
|
||||
|
||||
try {
|
||||
System.out.println(CSV.tableFromCSV(csvFolder.getAbsolutePath()+File.separator+csv, type));
|
||||
System.out.println(f.fromCSV(csvFile.getAbsolutePath()));
|
||||
}catch(Throwable t) {
|
||||
if(!csv.contains("wrong")) {
|
||||
if(!csvFile.getName().contains("wrong")) {
|
||||
t.printStackTrace();
|
||||
Assert.fail();
|
||||
}
|
||||
|
|
|
@ -2,17 +2,15 @@ package org.gcube.application.geoportal.db;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.gcube.application.geoportal.PostgisDBManager;
|
||||
import org.gcube.application.geoportal.PostgisTableFactory;
|
||||
import org.gcube.application.geoportal.model.PostgisTable;
|
||||
import org.gcube.application.geoportal.model.PostgisTable.GeometryType;
|
||||
import org.gcube.application.geoportal.utils.CSV;
|
||||
import org.gcube.application.geoportal.utils.Files;
|
||||
import org.gcube.application.geoportal.utils.MainUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class PostgisTests {
|
||||
|
||||
|
@ -41,8 +39,8 @@ public class PostgisTests {
|
|||
|
||||
|
||||
System.out.println("CXurrent centroids extent");
|
||||
System.out.println(db.evaluateBoundingBox(PostgisTable.CENTROID));
|
||||
|
||||
System.out.println(db.evaluateBoundingBox(PostgisTableFactory.CENTROID));
|
||||
PostgisTableFactory f=new PostgisTableFactory(db);
|
||||
|
||||
File csvFolder=null;
|
||||
try {
|
||||
|
@ -60,23 +58,16 @@ public class PostgisTests {
|
|||
return pathname.getName().endsWith(".csv");
|
||||
}
|
||||
})){
|
||||
String csv=csvFile.getName();
|
||||
System.out.println("loading : "+csv);
|
||||
GeometryType type=GeometryType.POINT;
|
||||
if(csv.contains("linee"))
|
||||
type=GeometryType.LINE;
|
||||
else if(csv.contains("poligoni"))
|
||||
type=GeometryType.POLYGON;
|
||||
|
||||
try {
|
||||
PostgisTable table =CSV.persistCSVLayer(csvFolder.getAbsolutePath()+File.separator+csv, type, db);
|
||||
PostgisTable table =f.fromCSV(csvFile.getAbsolutePath());
|
||||
|
||||
System.out.println("Created table : "+table);
|
||||
db.deleteTable(table.getTablename());
|
||||
db.commit();
|
||||
System.out.println("Deleted");
|
||||
}catch(Throwable t) {
|
||||
if(!csv.contains("wrong"))
|
||||
if(!csvFile.getName().contains("wrong"))
|
||||
throw t;
|
||||
else {
|
||||
System.out.println(" File was corrupted as expected");
|
||||
|
|
Loading…
Reference in New Issue