24 #include <QNetworkRequest>
25 #include <QNetworkReply>
26 #include <QProgressDialog>
52 for (
int i = 0; i < mFields.
size(); i++ )
54 if ( mFields[i].name() == name )
return i;
62 , mCurrentFeature( NULL )
65 , mSkipLevel( std::numeric_limits<int>::
max() )
67 mGeometryTypes <<
"Point" <<
"MultiPoint"
68 <<
"LineString" <<
"MultiLineString"
69 <<
"Polygon" <<
"MultiPolygon";
77 QString QgsGmlSchema::readAttribute(
const QString& attributeName,
const XML_Char** attr )
const
80 while ( attr[i] != NULL )
82 if ( attributeName.
compare( attr[i] ) == 0 )
97 if ( !dom.
setContent( xml,
false, &errorMsg, &errorLine, &errorColumn ) )
109 Q_FOREACH (
const QDomElement& elementElement, elementElements )
114 QString gmlBaseType = xsdComplexTypeGmlBaseType( docElem, stripNS( type ) );
121 if ( gmlBaseType ==
"AbstractFeatureType" )
125 xsdFeatureClass( docElem, stripNS( type ), featureClass );
126 mFeatureClassMap.
insert( name, featureClass );
137 QDomElement complexTypeElement = domElement( element,
"complexType",
"name", typeName );
138 if ( complexTypeElement.
isNull() )
return false;
141 QDomElement extrest = domElement( complexTypeElement,
"complexContent.extension" );
144 extrest = domElement( complexTypeElement,
"complexContent.restriction" );
146 if ( extrest.
isNull() )
return false;
149 if ( extrestName ==
"gml:AbstractFeatureType" )
158 if ( !xsdFeatureClass( element, stripNS( extrestName ), featureClass ) )
return false;
163 Q_FOREACH (
const QString& geom, mGeometryTypes )
165 geometryPropertyTypes << geom +
"PropertyType";
169 geometryAliases <<
"location" <<
"centerOf" <<
"position" <<
"extentOf"
170 <<
"coverage" <<
"edgeOf" <<
"centerLineOf" <<
"multiLocation"
171 <<
"multiCenterOf" <<
"multiPosition" <<
"multiCenterLineOf"
172 <<
"multiEdgeOf" <<
"multiCoverage" <<
"multiExtentOf";
176 Q_FOREACH (
const QDomElement& sequenceElement, sequenceElements )
183 if ( !ref.isEmpty() )
185 if ( ref.startsWith(
"gml:" ) )
187 if ( geometryAliases.
contains( stripNS( ref ) ) )
199 QgsDebugMsg(
QString(
"field %1.%2 is referencing %3 - not supported" ).arg( typeName, fieldName ) );
214 QDomElement sequenceElementRestriction = domElement( sequenceElement,
"simpleType.restriction" );
215 fieldTypeName = stripNS( sequenceElementRestriction.
attribute(
"base" ) );
218 QVariant::Type fieldType = QVariant::String;
225 if ( geometryPropertyTypes.
contains( fieldTypeName ) )
232 if ( fieldTypeName ==
"decimal" )
234 fieldType = QVariant::Double;
236 else if ( fieldTypeName ==
"integer" )
238 fieldType = QVariant::Int;
242 QgsField field( fieldName, fieldType, fieldTypeName );
252 QDomElement complexTypeElement = domElement( element,
"complexType",
"name", name );
253 if ( complexTypeElement.
isNull() )
return "";
255 QDomElement extrest = domElement( complexTypeElement,
"complexContent.extension" );
258 extrest = domElement( complexTypeElement,
"complexContent.restriction" );
260 if ( extrest.
isNull() )
return "";
266 return stripNS( extrestName );
269 return xsdComplexTypeGmlBaseType( element, stripNS( extrestName ) );
282 if ( names.
size() == 0 )
return list;
293 if ( tagName == name )
295 if ( names.
size() == 0 )
301 list.
append( domElements( el, names.
join(
"." ) ) );
313 return domElements( element, path ).
value( 0 );
332 return domElements( list, attr, attrVal ).
value( 0 );
340 XML_Parser p = XML_ParserCreateNS( NULL,
NS_SEPARATOR );
341 XML_SetUserData( p,
this );
342 XML_SetElementHandler( p, QgsGmlSchema::start, QgsGmlSchema::end );
343 XML_SetCharacterDataHandler( p, QgsGmlSchema::chars );
345 int res = XML_Parse( p, data.
constData(), data.
size(), atEnd );
349 QString err =
QString( XML_ErrorString( XML_GetErrorCode( p ) ) );
351 mError =
QgsError( err,
"GML schema" );
352 mError.
append(
tr(
"Cannot guess schema" ) );
358 void QgsGmlSchema::startElement(
const XML_Char* el,
const XML_Char** attr )
364 QgsDebugMsgLevel(
QString(
"-> %1 %2 %3" ).arg( mLevel ).arg( elementName, mLevel >= mSkipLevel ?
"skip" :
"" ), 5 );
366 if ( mLevel >= mSkipLevel )
372 mParsePathStack.
append( elementName );
380 ParseMode parseMode = modeStackTop();
383 if ( ns == GML_NAMESPACE && localName ==
"boundedBy" )
386 mSkipLevel = mLevel + 1;
388 else if ( localName.
compare(
"featureMembers", Qt::CaseInsensitive ) == 0 )
390 mParseModeStack.
push( QgsGmlSchema::featureMembers );
397 else if ( localName.
endsWith(
"member", Qt::CaseInsensitive ) )
399 mParseModeStack.
push( QgsGmlSchema::featureMember );
402 else if ( elementName.
endsWith(
"_layer" ) )
410 else if ( elementName.
endsWith(
"_feature" )
411 || parseMode == QgsGmlSchema::featureMember
412 || parseMode == QgsGmlSchema::featureMembers
413 || localName.
compare(
"feature", Qt::CaseInsensitive ) == 0 )
416 if ( mFeatureClassMap.
count( localName ) == 0 )
420 mCurrentFeatureName = localName;
421 mParseModeStack.
push( QgsGmlSchema::feature );
423 else if ( parseMode == QgsGmlSchema::attribute && ns == GML_NAMESPACE && mGeometryTypes.
indexOf( localName ) >= 0 )
427 if ( geometryAttributes.
count( mAttributeName ) == 0 )
429 geometryAttributes.
append( mAttributeName );
431 mSkipLevel = mLevel + 1;
433 else if ( parseMode == QgsGmlSchema::feature )
442 QString name = readAttribute(
"name", attr );
444 if ( localName.
compare(
"attribute", Qt::CaseInsensitive ) == 0
447 QString value = readAttribute(
"value", attr );
449 addAttribute( name, value );
453 mAttributeName = localName;
454 mParseModeStack.
push( QgsGmlSchema::attribute );
460 void QgsGmlSchema::endElement(
const XML_Char* el )
465 if ( mLevel >= mSkipLevel )
481 QgsGmlSchema::ParseMode parseMode = modeStackTop();
483 if ( parseMode == QgsGmlSchema::featureMembers )
487 else if ( parseMode == QgsGmlSchema::attribute && localName == mAttributeName )
493 if ( mFeatureClassMap[mCurrentFeatureName].
geometryAttributes().count( mAttributeName ) == 0 )
495 addAttribute( mAttributeName, mStringCash );
498 else if ( ns == GML_NAMESPACE && localName ==
"boundedBy" )
502 else if ( localName.
endsWith(
"member", Qt::CaseInsensitive ) )
510 void QgsGmlSchema::characters(
const XML_Char* chars,
int len )
513 if ( mLevel >= mSkipLevel )
520 if ( modeStackTop() == QgsGmlSchema::attribute )
526 void QgsGmlSchema::addAttribute(
const QString& name,
const QString& value )
531 QVariant::Type type = QVariant::String;
534 type = QVariant::Int;
541 type = QVariant::Double;
547 int fieldIndex = mFeatureClassMap[mCurrentFeatureName].fieldIndex( name );
548 if ( fieldIndex == -1 )
555 QgsField &field = fields[fieldIndex];
557 if (( field.
type() == QVariant::Int && ( type == QVariant::String || type == QVariant::Double ) ) ||
558 ( field.
type() == QVariant::Double && type == QVariant::String ) )
567 return mFeatureClassMap.
keys();
573 return mFeatureClassMap[typeName].fields();
579 return mFeatureClassMap[typeName].geometryAttributes();
QString & append(QChar ch)
bool guessSchema(const QByteArray &data)
Guess GML schema from data if XSD does not exist.
QString attribute(const QString &name, const QString &defValue) const
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QDomElement documentElement() const
QString join(const QString &separator) const
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
QDomNode nextSibling() const
const QString GML_NAMESPACE
QDomElement toElement() const
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
QList< Key > keys() const
QList< QgsField > & fields()
const char * name() const
int count(const T &value) const
void append(const T &value)
QString fromUtf8(const char *str, int size)
#define QgsDebugMsgLevel(str, level)
QStringList typeNames() const
Get list of dot separated paths to feature classes parsed from GML or XSD.
int toInt(bool *ok, int base) const
const char * constData() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QList< QgsField > fields(const QString &typeName)
Get fields for type/class name parsed from GML or XSD.
Encapsulate a field in an attribute table or data source.
bool contains(QChar ch, Qt::CaseSensitivity cs) const
void setType(QVariant::Type type)
Set variant type.
QDomNode firstChild() const
QgsError is container for error messages (report).
void append(const QString &theMessage, const QString &theTag)
Append new error message.
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
int indexOf(const QRegExp &rx, int from) const
iterator insert(const Key &key, const T &value)
QStringList & geometryAttributes()
int compare(const QString &other) const
int count(const Key &key) const
int fieldIndex(const QString &name)
bool parseXSD(const QByteArray &xml)
Get fields info from XSD.
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
QStringList geometryAttributes(const QString &typeName)
Get list of geometry attributes for type/class name.