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