//--------------------------------------------------------- bool CPGIS_Shapes_Save::On_Execute(void) { int SRID; CSG_Shapes *pShapes; CSG_String SQL, Geo_Table, Geo_Type, Geo_Field, sSRID; pShapes = Parameters("SHAPES") ->asShapes(); Geo_Table = Parameters("NAME") ->asString(); if( Geo_Table.Length() == 0 ) Geo_Table = pShapes->Get_Name(); SRID = Parameters("SRID") ->asInt(); SRID = SG_Get_Projections().Get_SRID_byNamesIndex(SRID); sSRID.Printf(SG_T("%d"), SRID); //----------------------------------------------------- switch( pShapes->Get_Vertex_Type() ) { case SG_VERTEX_TYPE_XY: switch( pShapes->Get_Type() ) { default: return( false ); case SHAPE_TYPE_Point: Geo_Type = SG_OGIS_TYPE_STR_Point; Geo_Field = SG_T("geo_point"); break; case SHAPE_TYPE_Points: Geo_Type = SG_OGIS_TYPE_STR_MultiPoint; Geo_Field = SG_T("geo_points"); break; case SHAPE_TYPE_Line: Geo_Type = SG_OGIS_TYPE_STR_MultiLine; Geo_Field = SG_T("geo_line"); break; case SHAPE_TYPE_Polygon: Geo_Type = SG_OGIS_TYPE_STR_MultiPolygon; Geo_Field = SG_T("geo_polygon"); break; } break; case SG_VERTEX_TYPE_XYZ: switch( pShapes->Get_Type() ) { default: return( false ); case SHAPE_TYPE_Point: Geo_Type = SG_OGIS_TYPE_STR_Point_Z; Geo_Field = SG_T("geo_point_z"); break; case SHAPE_TYPE_Points: Geo_Type = SG_OGIS_TYPE_STR_MultiPoint_Z; Geo_Field = SG_T("geo_points_z"); break; case SHAPE_TYPE_Line: Geo_Type = SG_OGIS_TYPE_STR_MultiLine_Z; Geo_Field = SG_T("geo_line_z"); break; case SHAPE_TYPE_Polygon: Geo_Type = SG_OGIS_TYPE_STR_MultiPolygon_Z; Geo_Field = SG_T("geo_polygon_z"); break; } break; case SG_VERTEX_TYPE_XYZM: switch( pShapes->Get_Type() ) { default: return( false ); case SHAPE_TYPE_Point: Geo_Type = SG_OGIS_TYPE_STR_Point_ZM; Geo_Field = SG_T("geo_point_zm"); break; case SHAPE_TYPE_Points: Geo_Type = SG_OGIS_TYPE_STR_MultiPoint_ZM; Geo_Field = SG_T("geo_points_zm"); break; case SHAPE_TYPE_Line: Geo_Type = SG_OGIS_TYPE_STR_MultiLine_ZM; Geo_Field = SG_T("geo_line_zm"); break; case SHAPE_TYPE_Polygon: Geo_Type = SG_OGIS_TYPE_STR_MultiPolygon_ZM; Geo_Field = SG_T("geo_polygon_zm"); break; } break; } //----------------------------------------------------- if( Get_Connection()->Table_Exists(Geo_Table) ) { Message_Add(CSG_String::Format(SG_T("%s: %s"), _TL("table already exists"), Geo_Table.c_str())); switch( Parameters("EXISTS")->asInt() ) { case 0: // abort export return( false ); case 1: // replace existing table Message_Add(CSG_String::Format(SG_T("%s: %s"), _TL("trying to drop table"), Geo_Table.c_str())); if( !Get_Connection()->Table_Drop(Geo_Table, false) ) { Message_Add(CSG_String::Format(SG_T(" ...%s!"), _TL("failed"))); return( false ); } break; case 2: // append records, if table structure allows break; } } //----------------------------------------------------- if( !Get_Connection()->Table_Exists(Geo_Table) && !Get_Connection()->Table_Create(Geo_Table, *pShapes, Get_Constraints(Parameters("FLAGS")->asParameters(), pShapes), false) ) { Get_Connection()->Rollback(); return( false ); } //----------------------------------------------------- SQL.Printf(SG_T("SELECT AddGeometryColumn('%s', '%s', %d, '%s', %d)"), Geo_Table.c_str(), // <table_name> Geo_Field.c_str(), // <column_name> SRID, // <srid> Geo_Type.Make_Upper().c_str(), // <type> 2 // <dimension> ); if( !Get_Connection()->Execute(SQL) ) { Get_Connection()->Rollback(); Message_Add(_TL("could not create geometry field")); return( false ); } //----------------------------------------------------- int iShape, iField, nAdded; CSG_String Insert, Fields, sWKT; Fields = Geo_Field; for(iField=0; iField<pShapes->Get_Field_Count(); iField++) { Fields += CSG_String(", ") + pShapes->Get_Field_Name(iField); } Insert.Printf(SG_T("INSERT INTO %s (%s) VALUES ("), Geo_Table.c_str(), Fields.c_str()); for(iShape=0, nAdded=0; iShape<pShapes->Get_Count() && Set_Progress(iShape, pShapes->Get_Count()); iShape++) { CSG_Shape *pShape = pShapes->Get_Shape(iShape); if( pShape->is_Valid() ) { SQL = Insert; CSG_Shapes_OGIS_Converter::to_WKText(pShape, sWKT); SQL += SG_T("GeomFromText('") + sWKT + SG_T("', ") + sSRID + SG_T(")"); for(iField=0; iField<pShapes->Get_Field_Count(); iField++) { CSG_String s = pShape->asString(iField); if( pShapes->Get_Field_Type(iField) == SG_DATATYPE_String ) { s.Replace(SG_T("'"), SG_T("\"")); s = SG_T("'") + s + SG_T("'"); } SQL += SG_T(", ") + s; } SQL += SG_T(")"); if( Get_Connection()->Execute(SQL) ) { nAdded++; } else { Message_Add(CSG_String::Format(SG_T("dropped %d. shape"), iShape)); } } } //----------------------------------------------------- if( nAdded == 0 ) { Get_Connection()->Rollback(); Get_Connection()->Table_Drop(Geo_Table); return( false ); } return( Get_Connection()->Commit() ); }
//--------------------------------------------------------- bool CShapes_Save::On_Execute(void) { if( !Get_Connection()->has_PostGIS() ) { Error_Set(_TL("not a valid PostGIS database!")); return( false ); } //----------------------------------------------------- CSG_Shapes *pShapes; CSG_String SQL, Name, Type, Field, SavePoint; pShapes = Parameters("SHAPES")->asShapes(); Name = Parameters("NAME" )->asString(); if( Name.Length() == 0 ) Name = pShapes->Get_Name(); Field = "geometry"; int SRID = Get_SRID(); //----------------------------------------------------- if( !CSG_Shapes_OGIS_Converter::from_ShapeType(Type, pShapes->Get_Type(), pShapes->Get_Vertex_Type()) ) { Error_Set(_TL("invalid or unsupported shape or vertex type")); return( false ); } //----------------------------------------------------- Get_Connection()->Begin(SavePoint = Get_Connection()->is_Transaction() ? "SHAPES_SAVE" : ""); //----------------------------------------------------- if( Get_Connection()->Table_Exists(Name) ) { Message_Add(_TL("table already exists") + CSG_String(": ") + Name); switch( Parameters("EXISTS")->asInt() ) { case 0: // abort export return( false ); case 1: // replace existing table Message_Add(_TL("trying to drop table") + CSG_String(": ") + Name); if( !Get_Connection()->Table_Drop(Name, false) ) { Message_Add(CSG_String(" ...") + _TL("failed") + "!"); return( false ); } break; case 2: // append records, if table structure allows break; } } //----------------------------------------------------- if( !Get_Connection()->Table_Exists(Name) ) { if( !Get_Connection()->Table_Create(Name, *pShapes, Get_Constraints(&Parameters, "SHAPES"), false) ) { Error_Set(_TL("could not create table")); Get_Connection()->Rollback(SavePoint); return( false ); } //------------------------------------------------- // SELECT AddGeometryColumn(<table_name>, <column_name>, <srid>, <type>, <dimension>) SQL.Printf(SG_T("SELECT AddGeometryColumn('%s', '%s', %d, '%s', %d)"), Name.c_str(), Field.c_str(), SRID, Type.c_str(), pShapes->Get_Vertex_Type() == SG_VERTEX_TYPE_XY ? 2 : pShapes->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZ ? 3 : 4 ); if( !Get_Connection()->Execute(SQL) ) { Error_Set(_TL("could not create geometry field")); Get_Connection()->Rollback(SavePoint); return( false ); } } //----------------------------------------------------- bool bBinary = Get_Connection()->has_Version(9); int iShape, iField, nAdded; CSG_String Insert = "INSERT INTO \"" + Name + "\" (" + Field; for(iField=0; iField<pShapes->Get_Field_Count(); iField++) { Insert += CSG_String(", ") + pShapes->Get_Field_Name(iField); } Insert += ") VALUES ("; //----------------------------------------------------- for(iShape=0, nAdded=0; iShape==nAdded && iShape<pShapes->Get_Count() && Set_Progress(iShape, pShapes->Get_Count()); iShape++) { CSG_Shape *pShape = pShapes->Get_Shape(iShape); if( pShape->is_Valid() ) { SQL = Insert; if( bBinary ) { CSG_Bytes WKB; CSG_Shapes_OGIS_Converter::to_WKBinary(pShape, WKB); SQL += "ST_GeomFromWKB(E'\\\\x" + WKB.toHexString() + CSG_String::Format("', %d)", SRID); } else { CSG_String WKT; CSG_Shapes_OGIS_Converter::to_WKText(pShape, WKT); SQL += "ST_GeomFromText('" + WKT + CSG_String::Format("', %d)", SRID); } for(iField=0; iField<pShapes->Get_Field_Count(); iField++) { CSG_String s = pShape->asString(iField); if( pShapes->Get_Field_Type(iField) == SG_DATATYPE_String ) { if( 1 ) { char *_s = NULL; if( s.to_ASCII(&_s) ) s = _s; SG_FREE_SAFE(_s); } s.Replace("'", "\""); s = "'" + s + "'"; } SQL += ", " + s; } SQL += ")"; if( Get_Connection()->Execute(SQL) ) { nAdded++; } else { Message_Add(CSG_String::Format("%s [%d/%d]", _TL("could not save shape"), 1 + iShape, pShapes->Get_Count())); } } } //----------------------------------------------------- if( nAdded < pShapes->Get_Count() ) { Message_Add(SQL); Get_Connection()->Rollback(SavePoint); return( false ); } Get_Connection()->Commit(SavePoint); Get_Connection()->GUI_Update(); Get_Connection()->Add_MetaData(*pShapes, Name); pShapes->Set_Modified(false); return( true ); }