[gdal-dev] S57 field definition incorrect
ogr user
mrxonx at hotmail.com
Thu Jan 15 19:56:15 EST 2009
In case anyone is interested, here is a patch that adds appropriate
handling of IntegerList field types to S57 parser. For backwards
compatibility it is only activated if specific option is passed to the
reader (actually to class registrar). This is for 1.5.3.
Frank Warmerdam wrote:
>
> Dear OGR User,
>
> It appears the S57 code deliberately treats list attributes as simple
> strings. While this may have been a poor choice, I hesitate to change it
> at this point for fear of breaking fragile software built on this driver
> (notably the FME S-57 reader).
>
> My suggestion is that you fetch it as a string, and parse the integers
> out yourself.
>
> Best regards,
-------------- next part --------------
Index: gdal-1.5.3/ogr/ogrutils.cpp
===================================================================
--- gdal-1.5.3/ogr/ogrutils.cpp
+++ gdal-1.5.3/ogr/ogrutils.cpp
@@ -817,3 +817,41 @@
return TRUE;
}
+
+
+#define P_DELIM " ,"
+int OGRParseIntegerList(const char *pszInput, OGRField *psField)
+{
+ const char *p;
+ int nCount, nLen, sLen;
+ int *pVals;
+
+ p = pszInput;
+ nCount = 0;
+ while ((nLen = strcspn(p, P_DELIM)) > 0) {
+ nCount++;
+ p += nLen;
+ sLen = strspn(p, P_DELIM);
+ p += sLen;
+ }
+
+ if (nCount == 0)
+ return 0;
+
+ pVals = (int *)CPLMalloc(sizeof(int) * nCount);
+
+ p = pszInput;
+ nCount = 0;
+ while ((nLen = strcspn(p, P_DELIM)) > 0) {
+ pVals[nCount] = atoi(p);
+ nCount++;
+ p += nLen;
+ sLen = strspn(p, P_DELIM);
+ p += sLen;
+ }
+
+ psField->IntegerList.paList = pVals;
+ psField->IntegerList.nCount = nCount;
+
+ return 1;
+}
Index: gdal-1.5.3/ogr/ogrsf_frmts/s57/s57reader.cpp
===================================================================
--- gdal-1.5.3/ogr/ogrsf_frmts/s57/s57reader.cpp
+++ gdal-1.5.3/ogr/ogrsf_frmts/s57/s57reader.cpp
@@ -246,6 +246,14 @@
/* SetOptions() */
/************************************************************************/
+void S57Reader::SetOptions( int nFlagsOn, int nFlagsOff )
+{
+ nOptionFlags |= nFlagsOn;
+ if (nFlagsOff)
+ nOptionFlags &= ~nFlagsOff;
+}
+
+
void S57Reader::SetOptions( char ** papszOptionsIn )
{
@@ -254,6 +262,12 @@
CSLDestroy( papszOptions );
papszOptions = CSLDuplicate( papszOptionsIn );
+ pszOptionValue = CSLFetchNameValue( papszOptions, S57O_PARSE_INTEGERLIST );
+ if( pszOptionValue != NULL && !EQUAL(pszOptionValue,"OFF") )
+ nOptionFlags |= S57M_PARSE_INTEGERLIST;
+ else
+ nOptionFlags &= ~S57M_PARSE_INTEGERLIST;
+
pszOptionValue = CSLFetchNameValue( papszOptions, S57O_SPLIT_MULTIPOINT );
if( pszOptionValue != NULL && !EQUAL(pszOptionValue,"OFF") )
nOptionFlags |= S57M_SPLIT_MULTIPOINT;
Index: gdal-1.5.3/ogr/ogrsf_frmts/s57/s57featuredefns.cpp
===================================================================
--- gdal-1.5.3/ogr/ogrsf_frmts/s57/s57featuredefns.cpp
+++ gdal-1.5.3/ogr/ogrsf_frmts/s57/s57featuredefns.cpp
@@ -416,7 +416,10 @@
break;
case SAT_LIST:
- oField.SetType( OFTString );
+ if (nOptionFlags & S57M_PARSE_INTEGERLIST)
+ oField.SetType( OFTIntegerList );
+ else
+ oField.SetType( OFTString );
break;
}
Index: gdal-1.5.3/ogr/ogrsf_frmts/s57/s57.h
===================================================================
--- gdal-1.5.3/ogr/ogrsf_frmts/s57/s57.h
+++ gdal-1.5.3/ogr/ogrsf_frmts/s57/s57.h
@@ -52,6 +52,7 @@
#define S57O_RETURN_PRIMITIVES "RETURN_PRIMITIVES"
#define S57O_RETURN_LINKAGES "RETURN_LINKAGES"
#define S57O_RETURN_DSID "RETURN_DSID"
+#define S57O_PARSE_INTEGERLIST "PARSE_INTEGERLIST"
#define S57M_UPDATES 0x01
#define S57M_LNAM_REFS 0x02
@@ -61,6 +62,7 @@
#define S57M_RETURN_PRIMITIVES 0x20
#define S57M_RETURN_LINKAGES 0x40
#define S57M_RETURN_DSID 0x80
+#define S57M_PARSE_INTEGERLIST 0x0100
/* -------------------------------------------------------------------- */
/* RCNM values. */
@@ -291,6 +293,7 @@
void SetClassBased( S57ClassRegistrar * );
void SetOptions( char ** );
+ void SetOptions( int nFlagsOn, int nFlagsOff );
int GetOptionFlags() { return nOptionFlags; }
int Open( int bTestOpen );
Index: gdal-1.5.3/ogr/ogrfeature.cpp
===================================================================
--- gdal-1.5.3/ogr/ogrfeature.cpp
+++ gdal-1.5.3/ogr/ogrfeature.cpp
@@ -1860,6 +1860,16 @@
if( OGRParseDate( pszValue, &sWrkField, 0 ) )
memcpy( pauFields+iField, &sWrkField, sizeof(sWrkField));
}
+ else if (poFDefn->GetType() == OFTIntegerList) {
+ OGRField sWrkField;
+
+ if (OGRParseIntegerList(pszValue, &sWrkField)) {
+ if (IsFieldSet(iField))
+ CPLFree(pauFields[iField].IntegerList.paList);
+
+ memcpy(pauFields+iField, &sWrkField, sizeof(sWrkField));
+ }
+ }
else
/* do nothing for other field types */;
}
Index: gdal-1.5.3/ogr/ogr_core.h
===================================================================
--- gdal-1.5.3/ogr/ogr_core.h
+++ gdal-1.5.3/ogr/ogr_core.h
@@ -292,6 +292,8 @@
int CPL_DLL OGRParseDate( const char *pszInput, OGRField *psOutput,
int nOptions );
+int CPL_DLL OGRParseIntegerList(const char *pszInput, OGRField *psField);
+
/* -------------------------------------------------------------------- */
/* Constants from ogrsf_frmts.h for capabilities. */
/* -------------------------------------------------------------------- */
More information about the gdal-dev
mailing list