/** * Add a geometry to the shapefile. */ bool add(Osmium::Geometry::Geometry* geometry, ///< the geometry v8::Local<v8::Object> attributes) { ///< a %Javascript object (hash) with the attributes try { add_geometry(geometry->create_shp_object()); } catch (Osmium::Exception::IllegalGeometry) { return false; } int ok = 0; for (size_t n=0; n < m_fields.size(); n++) { v8::Local<v8::String> key = v8::String::New(m_fields[n].name().c_str()); if (attributes->HasRealNamedProperty(key)) { v8::Local<v8::Value> value = attributes->GetRealNamedProperty(key); if (value->IsUndefined() || value->IsNull()) { DBFWriteNULLAttribute(m_dbf_handle, m_current_shape, n); } else { switch (m_fields[n].type()) { case FTString: ok = add_string_attribute(n, value); break; case FTInteger: ok = DBFWriteIntegerAttribute(m_dbf_handle, m_current_shape, n, value->Int32Value()); break; case FTDouble: throw std::runtime_error("fields of type double not implemented"); break; case FTLogical: ok = add_logical_attribute(n, value); break; default: ok = 0; // should never be here break; } if (!ok) { std::string errmsg("failed to add attribute '"); errmsg += m_fields[n].name(); errmsg += "'\n"; throw std::runtime_error(errmsg); } } } else { DBFWriteNULLAttribute(m_dbf_handle, m_current_shape, n); } } return true; }
int main( int argc, char ** argv ) { DBFHandle hDBF; int i, iRecord; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 3 ) { printf( "dbfadd xbase_file field_values\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create the database. */ /* -------------------------------------------------------------------- */ hDBF = DBFOpen( argv[1], "r+b" ); if( hDBF == NULL ) { printf( "DBFOpen(%s,\"rb+\") failed.\n", argv[1] ); exit( 2 ); } /* -------------------------------------------------------------------- */ /* Do we have the correct number of arguments? */ /* -------------------------------------------------------------------- */ if( DBFGetFieldCount( hDBF ) != argc - 2 ) { printf( "Got %d fields, but require %d\n", argc - 2, DBFGetFieldCount( hDBF ) ); exit( 3 ); } iRecord = DBFGetRecordCount( hDBF ); /* -------------------------------------------------------------------- */ /* Loop assigning the new field values. */ /* -------------------------------------------------------------------- */ for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { if( strcmp( argv[i+2], "" ) == 0 ) DBFWriteNULLAttribute(hDBF, iRecord, i ); else if( DBFGetFieldInfo( hDBF, i, NULL, NULL, NULL ) == FTString ) DBFWriteStringAttribute(hDBF, iRecord, i, argv[i+2] ); else DBFWriteDoubleAttribute(hDBF, iRecord, i, atof(argv[i+2]) ); } /* -------------------------------------------------------------------- */ /* Close and cleanup. */ /* -------------------------------------------------------------------- */ DBFClose( hDBF ); return( 0 ); }
int add_logical_attribute(int n, v8::Local<v8::Value> value) const { v8::String::Utf8Value str(value); if (atoi(*str) == 1 || !strncasecmp(*str, "T", 1) || !strncasecmp(*str, "Y", 1)) { return DBFWriteLogicalAttribute(m_dbf_handle, m_current_shape, n, 'T'); } else if ((!strcmp(*str, "0")) || !strncasecmp(*str, "F", 1) || !strncasecmp(*str, "N", 1)) { return DBFWriteLogicalAttribute(m_dbf_handle, m_current_shape, n, 'F'); } else { return DBFWriteNULLAttribute(m_dbf_handle, m_current_shape, n); } }
int save_table(int t) { int i, j, ncols, nrows, ret, field, rec; char name[2000], fname[20], element[100]; DBFHandle dbf; ROW *rows; VALUE *val; int dbftype, width, decimals; G_debug(2, "save_table %d", t); /* Note: because if driver is killed during the time the table is written, the process * is not completed and DATA ARE LOST. To minimize this, data are first written * to temporary file and then this file is renamed to 'database/table.dbf'. * Hopefully both file are on the same disk/partition */ if (!(db.tables[t].alive) || !(db.tables[t].updated)) return DB_OK; /* Construct our temp name because shapelib doesn't like '.' in name */ G__temp_element(element); sprintf(fname, "%d.dbf", getpid()); G_file_name(name, element, fname, G_mapset()); G_debug(2, "Write table to tempfile: '%s'", name); dbf = DBFCreate(name); if (dbf == NULL) return DB_FAILED; ncols = db.tables[t].ncols; rows = db.tables[t].rows; nrows = db.tables[t].nrows; for (i = 0; i < ncols; i++) { switch (db.tables[t].cols[i].type) { case DBF_INT: dbftype = FTInteger; break; case DBF_CHAR: dbftype = FTString; break; case DBF_DOUBLE: dbftype = FTDouble; break; } width = db.tables[t].cols[i].width; decimals = db.tables[t].cols[i].decimals; DBFAddField(dbf, db.tables[t].cols[i].name, dbftype, width, decimals); } G_debug(2, "Write %d rows", nrows); rec = 0; for (i = 0; i < nrows; i++) { if (rows[i].alive == FALSE) continue; for (j = 0; j < ncols; j++) { field = j; val = &(rows[i].values[j]); if (val->is_null) { DBFWriteNULLAttribute(dbf, rec, field); } else { switch (db.tables[t].cols[j].type) { case DBF_INT: ret = DBFWriteIntegerAttribute(dbf, rec, field, val->i); break; case DBF_CHAR: if (val->c != NULL) ret = DBFWriteStringAttribute(dbf, rec, field, val->c); else ret = DBFWriteStringAttribute(dbf, rec, field, ""); break; case DBF_DOUBLE: ret = DBFWriteDoubleAttribute(dbf, rec, field, val->d); break; } } } rec++; } G_debug(2, "Written %d records", rec); DBFClose(dbf); /* Copy */ if (G_rename_file(name, db.tables[t].file)) { append_error("Cannot move %s\nto %s\n", name, db.tables[t].file); return DB_FAILED; }; return DB_OK; }
void add_attribute(const int field) const { int ok = DBFWriteNULLAttribute(m_dbf_handle, m_current_shape, field); if (!ok) { throw std::runtime_error(std::string("Can't add null to field")); } }