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