[Gvsig_desarrolladores] Info on shp/dbf driver

Stefano Orlando orste en libero.it
Mie Abr 8 10:59:29 CEST 2009


Hello Francisco, sorry for the delay of my answer.

I was a little vague: now I'm experimenting with the .dbf writer trying to
export to .shp format the content of a memory driver; if a field in the data
table is set to SQL TIMESTAMP type, the RuntimeException "Unknown type" with
the number 93 (that is the code of TIMESTAMP in java.sql.Types) is cast
(I've not tested it, but looking at code of the .dbf reader this should also
occur when reading a .dbf file). I don't use .dbfs with a TIMESTAMP column
(I've tried to create one with Openoffice but surprisingly - for me ;-) -
the column is transformed to a text data type), but I've tested it with a
Postgres table with a "timestamp without time zone" field and the 'export to
.shp' function fails.
Regarding the detection of the field type, this is also related to the
attempt to export to a .shp file the content of a memory driver
(ConcreteMemoryDriver): perhaps I miss something, but when you create a
ConcreteMemoryDriver is there a method to set the types of the columns (and
not only the names by the .getTableModel().setColumnIdentifiers(...)
method)? If not, how the type is retrieved by the data table of the memory
driver (especially when I set a NullValue through the ValueFactory)?

Thank you for your help!

Stefano

----- Original Message ----- 
From: "Francisco José Peñarrubia" <fpenarru at gmail.com>
To: "Lista de Desarrolladores de gvSIG" 
<gvsig_desarrolladores at runas.cap.gva.es>
Sent: Monday, April 06, 2009 7:54 PM
Subject: Re: [Gvsig_desarrolladores] Info on shp/dbf driver


> Hi, Stefano.
>
> As far as I know, the Dbf driver 
> (com.iver.cit.gvsig.fmap.drivers.dbf.DBFDriver.java) reads the field type 
> from the dBase Header (using DbaseFileHeader class). It seems that we are 
> only taking care of some field types:
>
>    public int getFieldType(int i) throws ReadDriverException {
>        char fieldType = fieldTypes[i];
>
>        if (fieldType == 'L') {
>            return Types.BOOLEAN;
>        } else if ((fieldType == 'F') || (fieldType == 'N')) {
>            if (dbf.getFieldDecimalLength(i)>0)
>                return Types.DOUBLE;
>            else
>                return Types.INTEGER;
>        } else if (fieldType == 'C') {
>            return Types.VARCHAR;
>        } else if (fieldType == 'D') {
>            return Types.DATE;
>        } else {
>            throw new 
> BadFieldDriverException(getName(),null,String.valueOf(fieldType));
>        }
>    }
>
> From here:
>
> http://www.clicketyclick.dk/databases/xbase/format/data_types.html
>
> It seems we should take care of '@' character, at least. Do you have any 
> example of dbf file with this kind of data?.
>
> Or maybe you mean the DbfWriter. Then, you can have a look to this 
> function in DbaseFileWriterNIO:
>
> private String fieldString(Object obj,final int col) {
>    String o;
>    final int fieldLen = header.getFieldLength(col);
>    switch (header.getFieldType(col)) {
>      case 'C':
>      case 'c':
>        o = formatter.getFieldString(
>          fieldLen,
>          (obj instanceof NullValue)? NULL_STRING : ((StringValue) 
> obj).getValue()
>        );
>        break;
>      case 'L':
>      case 'l':
>        o = (obj instanceof NullValue) ? "F" : 
> ((BooleanValue)obj).getValue() == true ? "T" : "F";
>        break;
>      case 'M':
>      case 'G':
>        o = formatter.getFieldString(
>          fieldLen,
>          (obj instanceof NullValue) ? NULL_STRING : ((StringValue) 
> obj).getValue()
>        );
>        break;
>     /* case 'N':
>      case 'n':
>        // int?
>        if (header.getFieldDecimalCount(col) == 0) {
>           o = formatter.getFieldString(
>            fieldLen, 0, (Number) (obj == null ? NULL_NUMBER : 
> Double.valueOf(obj.toString()))
>          );
>          break;
>      }
>      */
>      case 'N':
>      case 'n':
>      case 'F':
>      case 'f':
>        Number number = null;
>        if(obj instanceof NullValue){
>            number = NULL_NUMBER;
>        }else{
>            NumericValue gVal = (NumericValue) obj;
>            number = new Double(gVal.doubleValue());
>        }
>        o = formatter.getFieldString(fieldLen,
>                header.getFieldDecimalCount(col),
>                    number);
>        break;
>      case 'D':
>      case 'd':
>          if (obj instanceof NullValue)
>              o = NULL_DATE;
>          else
>              o = formatter.getFieldString(((DateValue)obj).getValue());
>        break;
>      default:
>        throw new RuntimeException("Unknown type " + 
> header.getFieldType(col));
>    }
>
>    return o;
>  }
>
> It seems there is not support to TIMESTAMP  type.
>
> Hope this helps... If you find the problema and wants to contribute, 
> please, let us know.
>
> Thanks for your help.
>
> Fran Peñarrubia
> gvSIG Team
>
>
> Stefano Orlando escribió:
>> Playing a bit with data conversion in gvSIG 1.9 alpha, I've noticed that 
>> the .shp driver (the .dbf part really) doesn't support the SQL 
>> 'TIMESTAMP' type and that the driver determines the type of a column 
>> reading the value from the first row of the table (so, if the value is a 
>> null value, there are some troubles because there isn't a 'null' data 
>> type in .dbf specs). Could you confirm these behaviours or I've missed 
>> something? And if this is true, there will be any changes in future 
>> versions of gvSIG?
>> Thank you for your assistance!
>>
>> Stefano
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> gvSIG_desarrolladores mailing list
>> gvSIG_desarrolladores at runas.cap.gva.es
>> http://runas.cap.gva.es/mailman/listinfo/gvsig_desarrolladores
>>
>
> _______________________________________________
> gvSIG_desarrolladores mailing list
> gvSIG_desarrolladores at runas.cap.gva.es
> http://runas.cap.gva.es/mailman/listinfo/gvsig_desarrolladores 



Más información sobre la lista de distribución gvSIG_desarrolladores