Hi all,

I have a self-written ShapefileWriter which uses the ShapefileDatastore. 
Every time I want to write float or double values greater 10 into the 
shapefile the schema isn't correct. I always want to have 4 decimal 
places.
E.g. I have the value 12.1234, which has a length of 7 (because of the 
decimal point) and 4 decimal places. But the ShapefileDatastore calculates 
5 decimal places.  If I change the value in debug mode the correct decimal 
places are written.
My questions:
1. Why are the decimal places always fieldlength minus 2? (see arrows 
ShapefileDataStore below)
2. What do I have to do to get the correct decimal places in the 
shapefile?

Best regards
Benjamin Sokolowski

relevant code of ShapefileWriter:
private void writeShapeFile( final SimpleFeatureCollection fc, final 
String fileName ) throws IOException {
    URL shpURL = createURL( fc.getSchema(), fileName );
    HashMap<String, Serializable> parameters = getDataStoreParameter( 
shpURL );
    ShapefileDataStoreFactory dataStoreFactory = new 
ShapefileDataStoreFactory();
    ShapefileDataStore newDataStore = (ShapefileDataStore) 
dataStoreFactory
        .createNewDataStore( parameters );

    try {
      newDataStore.createSchema( fc.getSchema() );
    }
    catch ( IOException e ) {
      throw e;
    }
    CoordinateReferenceSystem crs = getCRS( fc );
    if ( crs != null )
      newDataStore.forceSchemaCRS( crs );


    try ( Transaction transaction = new DefaultTransaction( "create" ) ) {
      String typeName = newDataStore.getTypeNames()[0];
      SimpleFeatureSource featureSource = newDataStore.getFeatureSource( 
typeName );

      SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource
;
      featureStore.setTransaction( transaction );
      try {
        featureStore.addFeatures( fc );
        transaction.commit();
      }
      catch ( Exception e ) {
        e.printStackTrace();
        transaction.rollback();
      }
    }
    newDataStore.dispose();

relevant code of ShapefileDatastore:
/**
     * Attempt to create a DbaseFileHeader for the FeatureType. Note, we 
cannot set the number of
     * records until the write has completed.
     */
    protected static DbaseFileHeader createDbaseHeader(SimpleFeatureType 
featureType)
            throws IOException, DbaseFileException {

        DbaseFileHeader header = new DbaseFileHeader();

        for (int i = 0, ii = featureType.getAttributeCount(); i < ii; i++) 
{
            AttributeDescriptor type = featureType.getDescriptor(i);

            Class<?> colType = type.getType().getBinding();
            String colName = type.getLocalName();

            int fieldLen = FeatureTypes.getFieldLength(type);
            if (fieldLen == FeatureTypes.ANY_LENGTH) fieldLen = 255;
            if ((colType == Integer.class) || (colType == Short.class) || 
(colType == Byte.class)) {
                header.addColumn(colName, 'N', Math.min(fieldLen, 9), 0);
            } else if (colType == Long.class) {
                header.addColumn(colName, 'N', Math.min(fieldLen, 19), 0);
            } else if (colType == BigInteger.class) {
                header.addColumn(colName, 'N', Math.min(fieldLen, 33), 0);
      -->      } else if (colType == Float.class) {
                int l = Math.min(fieldLen, 24);
                // GDAL format default is 15 decimal places of precision
                // http://www.gdal.org/drv_shapefile.html
                int d = Math.min(Math.max(l - 2, 0), 15);
                header.addColumn(colName, 'N', l, d);
      -->      } else if (colType == Double.class) {
                int l = Math.min(fieldLen, 33);
                int d = Math.min(Math.max(l - 2, 0), 15);
                header.addColumn(colName, 'N', l, d);
            } else if (Number.class.isAssignableFrom(colType)) {
                int l = Math.min(fieldLen, 33);
                int d = Math.max(l - 2, 0);
                header.addColumn(colName, 'N', l, d);
                // This check has to come before the Date one or it is 
never reached
                // also, this field is only activated with the following 
system property:
                // org.geotools.shapefile.datetime=true
            } else if (java.util.Date.class.isAssignableFrom(colType)
                    && Boolean.getBoolean(
"org.geotools.shapefile.datetime")) {
                header.addColumn(colName, '@', fieldLen, 0);
            } else if (java.util.Date.class.isAssignableFrom(colType)
                    || Calendar.class.isAssignableFrom(colType)) {
                header.addColumn(colName, 'D', fieldLen, 0);
            } else if (colType == Boolean.class) {
                header.addColumn(colName, 'L', 1, 0);
            } else if (CharSequence.class.isAssignableFrom(colType)
                    || colType == java.util.UUID.class) {
                // Possible fix for GEOT-42 : ArcExplorer doesn't like 0 
length
                // ensure that maxLength is at least 1
                header.addColumn(colName, 'C', Math.min(254, fieldLen), 
0);
            } else if (Geometry.class.isAssignableFrom(colType)) {
                continue;
                // skip binary data types
            } else if (colType == byte[].class) {
                continue;
            } else {
                // Fallback to char columns
                header.addColumn(colName, 'C', Math.min(254, fieldLen), 
0);
            }
        }

        return header;
    }
_______________________________________________
GeoTools-GT2-Users mailing list
GeoTools-GT2-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to