Dear Even,
2014-03-19 11:17 GMT+01:00 Even Rouault <[email protected]>:
> Just for Martin's enlightment, the GML driver manages to recognize several
> layers in that case since the RekisteriyksikonTietoja is the top feature
> present in the first bytes of the file, and the other feature types are sub
> feature types, also defined in RekisteriyksikonTietoja.xsd. In the case, the
> schema were simple enough so that the XSD parser could understand them.
>
> For Martin's case, I think that a .gfs will be necessary to extract properties
> in nested XML elements.
thanks a lot for your notes, it helped a lot. When working on support
for this format in OGR I found two problems.
First is related to GML registry. The input file contains different
layers based on its internal type (TypSouboru). For each of these
types are prepared separated GFS file.
<!-- Czech VFR schame-->
<namespace prefix="vf"
uri="urn:cz:isvs:ruian:schemas:VymennyFormatTypy:v1
../ruian/xsd/vymenny_format/VymennyFormatTypy.xsd"
useGlobalSRSName="true">
<featureType elementName="TypSouboru"
elementValue="OB_UKSH"
gfsSchemaLocation="vfr_ob_uksh_v1.gfs"/>
<featureType elementName="TypSouboru"
elementValue="ST_UKSH"
gfsSchemaLocation="vfr_st_uksh_v1.gfs"/>
<featureType elementName="TypSouboru"
elementValue="ST_UKSG"
gfsSchemaLocation="vfr_st_uksg_v1.gfs"/>
</namespace>
I have added a new attribute to 'osElementValue' to
'GMLRegistryFeatureType' class (see attached 'gmlregistry.diff' file).
Then the library also checks value of 'elementName' and if it's
defined and than uses related GFS.
The second problem is related to class and tag names. The layer names
are in plural form, features in singular form, eg.
<data>
<cities>
<city>
...
</city>
</cities>
</data>
To allow GML driver to create layer 'cities' I need to modify
'GMLHandler::startElementDefault()' method, see 'gmlhandler.diff'.
Thanks for any comments in advance, Martin
--
Martin Landa * http://geo.fsv.cvut.cz/gwiki/Landa
Index: ogr/ogrsf_frmts/gml/gmlregistry.cpp
===================================================================
--- ogr/ogrsf_frmts/gml/gmlregistry.cpp (revision 27127)
+++ ogr/ogrsf_frmts/gml/gmlregistry.cpp (working copy)
@@ -110,6 +110,7 @@
int GMLRegistryFeatureType::Parse(const char* pszRegistryFilename, CPLXMLNode*
psNode)
{
const char* pszElementName = CPLGetXMLValue(psNode, "elementName", NULL);
+ const char* pszElementValue = CPLGetXMLValue(psNode, "elementValue", NULL);
const char* pszSchemaLocation = CPLGetXMLValue(psNode, "schemaLocation",
NULL);
const char* pszGFSSchemaLocation = CPLGetXMLValue(psNode,
"gfsSchemaLocation", NULL);
if( pszElementName == NULL || (pszSchemaLocation == NULL &&
pszGFSSchemaLocation == NULL) )
@@ -139,5 +140,10 @@
osGFSSchemaLocation = pszGFSSchemaLocation;
}
+ if ( pszElementValue != NULL )
+ {
+ osElementValue = pszElementValue;
+ }
+
return TRUE;
}
Index: ogr/ogrsf_frmts/gml/gmlregistry.h
===================================================================
--- ogr/ogrsf_frmts/gml/gmlregistry.h (revision 27127)
+++ ogr/ogrsf_frmts/gml/gmlregistry.h (working copy)
@@ -39,6 +39,7 @@
{
public:
CPLString osElementName;
+ CPLString osElementValue;
CPLString osSchemaLocation;
CPLString osGFSSchemaLocation;
Index: ogr/ogrsf_frmts/gml/ogrgmldatasource.cpp
===================================================================
--- ogr/ogrsf_frmts/gml/ogrgmldatasource.cpp (revision 27127)
+++ ogr/ogrsf_frmts/gml/ogrgmldatasource.cpp (working copy)
@@ -758,16 +758,26 @@
{
if( oNamespace.bUseGlobalSRSName )
bUseGlobalSRSName = TRUE;
-
+
for( size_t iTypename = 0;
iTypename <
oNamespace.aoFeatureTypes.size();
iTypename ++ )
{
+ const char* pszElementToFind = NULL;
+
GMLRegistryFeatureType& oFeatureType =
oNamespace.aoFeatureTypes[iTypename];
- const char* pszElementToFind =
- CPLSPrintf("%s:%s",
oNamespace.osPrefix.c_str(),
- oFeatureType.osElementName.c_str());
+
+ if ( oFeatureType.osElementValue.size() )
+ pszElementToFind = CPLSPrintf("%s:%s>%s",
+
oNamespace.osPrefix.c_str(),
+
oFeatureType.osElementName.c_str(),
+
oFeatureType.osElementValue.c_str());
+ else
+ pszElementToFind = CPLSPrintf("%s:%s",
+
oNamespace.osPrefix.c_str(),
+
oFeatureType.osElementName.c_str());
+
if( osHeader.ifind(pszElementToFind) !=
std::string::npos )
{
if( oFeatureType.osSchemaLocation.size() )
Index: ogr/ogrsf_frmts/gml/gmlhandler.cpp
===================================================================
--- ogr/ogrsf_frmts/gml/gmlhandler.cpp (revision 27127)
+++ ogr/ogrsf_frmts/gml/gmlhandler.cpp (working copy)
@@ -1262,12 +1262,28 @@
strcmp(pszName, "FeatureCollection") == 0)) &&
(nClassIndex = m_poReader->GetFeatureElementIndex( pszName,
nLenName, eAppSchemaType )) != -1 )
{
+ const char *pszElementName = NULL;
+ CPLString pszFilteredElementName;
+
m_bAlreadyFoundGeometry = FALSE;
- pszFilteredClassName = m_poReader->GetFilteredClassName();
- if ( pszFilteredClassName != NULL &&
- strcmp(pszName, pszFilteredClassName) != 0 )
+ if ( nClassIndex < m_poReader->GetClassCount() )
+ pszElementName = m_poReader->GetClass( nClassIndex
)->GetElementName();
+ pszFilteredClassName = (char *)m_poReader->GetFilteredClassName();
+
+ if ( pszElementName != NULL )
{
+ if ( pszElementName[m_poReader->GetState()->osPath.size()] == '|' )
+ pszFilteredElementName = pszElementName + 1 +
m_poReader->GetState()->osPath.size();
+ else
+ pszFilteredElementName = (char *) pszElementName;
+ }
+
+
+ if ( pszFilteredClassName != NULL && pszFilteredElementName != NULL &&
+ strcmp(pszName, !pszFilteredElementName.empty() ?
+ pszFilteredElementName.c_str() : pszFilteredClassName) !=
0 )
+ {
m_nDepthFeature = m_nDepth;
PUSH_STATE(STATE_IGNORED_FEATURE);
@@ -1285,7 +1301,8 @@
m_poReader->SetFeaturePropertyDirectly( "gid", pszGID, -1,
GMLPT_String );
}
else
- m_poReader->PushFeature( pszName, GetFID(attr), nClassIndex );
+ m_poReader->PushFeature( pszFilteredClassName ?
pszFilteredClassName : pszName,
+ GetFID(attr), nClassIndex );
m_nDepthFeature = m_nDepth;
_______________________________________________
gdal-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/gdal-dev