1 /***************************************************************************
2 qgsowsdataitems.cpp
3 ---------------------
4 begin : May 2012
5 copyright : (C) 2012 by Radim Blazek
6 email : radim dot blazek at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15 #include "qgsproviderregistry.h"
16 #include "qgsowsdataitems.h"
17 #include "qgsowsprovider.h"
18 #include "qgslogger.h"
19 #include "qgsowsconnection.h"
20 #include "qgsdataitemprovider.h"
21
22 #include "qgsapplication.h"
23
24 #include <QFileInfo>
25
26 // ---------------------------------------------------------------------------
QgsOWSConnectionItem(QgsDataItem * parent,QString name,QString path)27 QgsOWSConnectionItem::QgsOWSConnectionItem( QgsDataItem *parent, QString name, QString path )
28 : QgsDataCollectionItem( parent, name, path, QStringLiteral( "OWS" ) )
29 {
30 mIconName = QStringLiteral( "mIconConnect.svg" );
31 mCapabilities |= Collapse;
32 }
33
createChildren()34 QVector<QgsDataItem *> QgsOWSConnectionItem::createChildren()
35 {
36 QVector<QgsDataItem *> children;
37 QHash<QgsDataItem *, QString> serviceItems; // service/provider key
38
39 int layerCount = 0;
40 // Try to open with WMS,WFS,WCS
41 Q_FOREACH ( const QString &key, QStringList() << "wms" << "WFS" << "wcs" )
42 {
43 QgsDebugMsg( "Add connection for provider " + key );
44 const QList<QgsDataItemProvider *> providerList = QgsProviderRegistry::instance()->dataItemProviders( key );
45 if ( providerList.isEmpty() )
46 {
47 QgsDebugMsg( key + " does not have dataItemProviders" );
48 continue;
49 }
50
51 QString path = key.toLower() + ":/" + name();
52 QgsDebugMsg( "path = " + path );
53
54 QVector<QgsDataItem *> items;
55 for ( QgsDataItemProvider *pr : providerList )
56 {
57 if ( !pr->name().startsWith( key ) )
58 continue;
59
60 items = pr->createDataItems( path, this );
61 if ( !items.isEmpty() )
62 {
63 break;
64 }
65 }
66
67 if ( items.isEmpty() )
68 {
69 QgsDebugMsg( key + " does not have any data items" );
70 continue;
71 }
72
73 for ( QgsDataItem *item : qgis::as_const( items ) )
74 {
75 item->populate( true ); // populate in foreground - this is already run in a thread
76
77 layerCount += item->rowCount();
78 if ( item->rowCount() > 0 )
79 {
80 QgsDebugMsg( "Add new item : " + item->name() );
81 serviceItems.insert( item, key );
82 }
83 else
84 {
85 //delete item;
86 }
87 }
88 }
89
90 for ( auto it = serviceItems.constBegin(); it != serviceItems.constEnd(); ++it )
91 {
92 QgsDataItem *item = it.key();
93 QgsDebugMsg( QStringLiteral( "serviceItems.size = %1 layerCount = %2 rowCount = %3" ).arg( serviceItems.size() ).arg( layerCount ).arg( item->rowCount() ) );
94 QString providerKey = it.value();
95 if ( serviceItems.size() == 1 || layerCount <= 30 || item->rowCount() <= 10 )
96 {
97 // Add layers directly to OWS connection
98 const auto constChildren = item->children();
99 for ( QgsDataItem *subItem : constChildren )
100 {
101 item->removeChildItem( subItem );
102 subItem->setParent( this );
103 replacePath( subItem, providerKey.toLower() + ":/", QStringLiteral( "ows:/" ) );
104 children.append( subItem );
105 }
106 delete item;
107 }
108 else // Add service
109 {
110 replacePath( item, item->path(), path() + '/' + providerKey.toLower() );
111 children.append( item );
112 }
113 }
114
115 return children;
116 }
117
118 // reset path recursively
replacePath(QgsDataItem * item,QString before,QString after)119 void QgsOWSConnectionItem::replacePath( QgsDataItem *item, QString before, QString after )
120 {
121 item->setPath( item->path().replace( before, after ) );
122 const auto constChildren = item->children();
123 for ( QgsDataItem *subItem : constChildren )
124 {
125 replacePath( subItem, before, after );
126 }
127 }
128
equal(const QgsDataItem * other)129 bool QgsOWSConnectionItem::equal( const QgsDataItem *other )
130 {
131 if ( type() != other->type() )
132 {
133 return false;
134 }
135 const QgsOWSConnectionItem *o = dynamic_cast<const QgsOWSConnectionItem *>( other );
136 return ( o && mPath == o->mPath && mName == o->mName );
137 }
138
139
140 // ---------------------------------------------------------------------------
141
142
QgsOWSRootItem(QgsDataItem * parent,QString name,QString path)143 QgsOWSRootItem::QgsOWSRootItem( QgsDataItem *parent, QString name, QString path )
144 : QgsConnectionsRootItem( parent, name, path, QStringLiteral( "OWS" ) )
145 {
146 mCapabilities |= Fast;
147 mIconName = QStringLiteral( "mIconOws.svg" );
148 populate();
149 }
150
createChildren()151 QVector<QgsDataItem *> QgsOWSRootItem::createChildren()
152 {
153 QVector<QgsDataItem *> connections;
154 // Combine all WMS,WFS,WCS connections
155 QStringList connNames;
156 Q_FOREACH ( const QString &service, QStringList() << "WMS" << "WFS" << "WCS" )
157 {
158 Q_FOREACH ( const QString &connName, QgsOwsConnection::connectionList( service ) )
159 {
160 if ( !connNames.contains( connName ) )
161 {
162 connNames << connName;
163 }
164 }
165 }
166 const auto constConnNames = connNames;
167 for ( const QString &connName : constConnNames )
168 {
169 QgsDataItem *conn = new QgsOWSConnectionItem( this, connName, "ows:/" + connName );
170 connections.append( conn );
171 }
172 return connections;
173 }
174
175
176 // ---------------------------------------------------------------------------
177
178 static QStringList extensions = QStringList();
179 static QStringList wildcards = QStringList();
180
name()181 QString QgsOwsDataItemProvider::name()
182 {
183 return QStringLiteral( "OWS" );
184 }
185
capabilities() const186 int QgsOwsDataItemProvider::capabilities() const
187 {
188 return QgsDataProvider::Net;
189 }
190
createDataItem(const QString & path,QgsDataItem * parentItem)191 QgsDataItem *QgsOwsDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
192 {
193 if ( path.isEmpty() )
194 {
195 return new QgsOWSRootItem( parentItem, QStringLiteral( "OWS" ), QStringLiteral( "ows:" ) );
196 }
197 return nullptr;
198 }
199