OSGeo / homebrew-osgeo4mac

Mac homebrew tap for maintaining a stable work environment for the OSGeo.org geospatial toolset
https://git.io/fhh3X
BSD 3-Clause "New" or "Revised" License
364 stars 111 forks source link

Standalone python script error on initQgs(): No vector layers can be loaded. #197

Closed itcarroll closed 7 years ago

itcarroll commented 7 years ago

Trying to install qgis2, and have gotten as far as not being able to read a shapefile using PyQGIS from Homebrew python (i.e. a standalone python script). I can read the file just fine with QGIS.app.

I set the PYTHONPATH as advised by brew info qgis2:

export PYTHONPATH=/usr/local/lib/qt-4/python2.7/site-packages:/usr/local/lib/python2.7/site-packages:$PYTHONPATH

The following script demonstrates the problem.

from qgis.core import *
QgsApplication.setPrefixPath('/usr/local/Cellar/qgis2/2.18.2/QGIS.app/Contents/MacOS')
qgs = QgsApplication([], False)
qgs.initQgis()
shp_file = 'path/to/shape/file.shp'
vlayer = QgsVectorLayer(shp_file, 'vlayer')
print vlayer.isValid()
qgs.exitQgis()

The message generated at qgs.initQgis() follows below, and vlayer is not valid.

src/core/qgsproviderregistry.cpp: 89: (init) [0ms] Checking /usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/../PlugIns/qgis for provider plugins
src/core/qgsmessagelog.cpp: 45: (logMessage) [0ms] 2016-12-31T13:52:06 No Data Providers[1] No QGIS data provider plugins found in:
/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/../PlugIns/qgis
No vector layers can be loaded. Check your QGIS installation
src/core/auth/qgsauthmanager.cpp: 106: (init) [0ms] Initializing QCA...
src/core/auth/qgsauthmanager.cpp: 109: (init) [0ms] QCA initialized.
src/core/auth/qgsauthmanager.cpp: 112: (init) [6ms] QCA Plugin Diagnostics Context: Checking Qt static plugins:
  (none)
Checking Qt Library Path: /usr/local/Cellar/qt-4/4.8.7/plugins
  (No 'crypto' subdirectory)
Checking Qt Library Path: /usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS
  (No 'crypto' subdirectory)
Checking Qt Library Path: /usr/local/Cellar/qca-qt4/2.1.1/lib/qca
  libqca-cyrus-sasl.dylib: (class: saslPlugin) loaded as qca-cyrus-sasl
  libqca-logger.dylib: (class: loggerPlugin) loaded as qca-logger
  libqca-ossl.dylib: (class: opensslPlugin) loaded as qca-ossl
  libqca-softstore.dylib: (class: softstorePlugin) loaded as qca-softstore

src/core/auth/qgsauthmanager.cpp: 116: (init) [1ms] QCA supports: random,md5,sha1,keystorelist,sasl,log,sha0,ripemd160,md4,sha224,sha256,sha384,sha512,hmac(md5),hmac(sha1),hmac(sha224),hmac(sha256),hmac(sha384),hmac(sha512),hmac(ripemd160),aes128-ecb,aes128-cfb,aes128-cbc,aes128-cbc-pkcs7,aes128-ofb,aes128-ctr,aes192-ecb,aes192-cfb,aes192-cbc,aes192-cbc-pkcs7,aes192-ofb,aes192-ctr,aes256-ecb,aes256-cbc,aes256-cbc-pkcs7,aes256-cfb,aes256-ofb,aes256-ctr,blowfish-ecb,blowfish-cbc-pkcs7,blowfish-cbc,blowfish-cfb,blowfish-ofb,tripledes-ecb,tripledes-cbc,des-ecb,des-ecb-pkcs7,des-cbc,des-cbc-pkcs7,des-cfb,des-ofb,cast5-ecb,cast5-cbc,cast5-cbc-pkcs7,cast5-cfb,cast5-ofb,pbkdf1(sha1),pbkdf2(sha1),pkey,dlgroup,rsa,dsa,dh,cert,csr,crl,certcollection,pkcs12,tls,cms,ca
src/core/auth/qgsauthmanager.cpp: 126: (init) [1ms] Prioritizing qca-ossl over all other QCA providers...
src/core/auth/qgsauthmanager.cpp: 140: (init) [0ms] QCA provider priorities: qca-cyrus-sasl:1, qca-logger:1, qca-ossl:0, qca-softstore:1
src/core/auth/qgsauthmanager.cpp: 142: (init) [0ms] Populating auth method registry
src/core/auth/qgsauthmethodregistry.cpp: 66: (QgsAuthMethodRegistry) [0ms] Checking for auth method plugins in: /usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/../PlugIns/qgis
src/core/qgsmessagelog.cpp: 45: (logMessage) [0ms] 2016-12-31T13:52:06 No Authentication Methods[1] No QGIS auth method plugins found in:
/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/../PlugIns/qgis
No authentication methods can be used. Check your QGIS installation
src/core/auth/qgsauthmanager.cpp: 147: (init) [0ms] Authentication methods found: 
src/core/auth/qgsauthmanager.cpp: 407: (isDisabled) [0ms] Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing
False
src/core/auth/qgsauthmanager.cpp: 407: (isDisabled) [3ms] Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing

Surely there is some additional environment variable to set? I tried using all the exports in the wrapper script /usr/local/opt/qgis2/bin/qgis2 with no change.

dakcarto commented 7 years ago

Hi @itcarroll, thanks for reporting! Apologies, as the docs in the wiki here are very outdated. For your Python standalone script's shell wrapper script (or environment), you can use:

export HB=$(brew --prefix)
export QGIS_HB_PREFIX=${HB}/opt/qgis2
export QGIS_BUNDLE=${QGIS_HB_PREFIX}/QGIS.app/Contents
export QGIS_PREFIX_PATH=${QGIS_BUNDLE}/MacOS
export PATH=${QGIS_PREFIX_PATH}/bin:$PATH
export PYTHONPATH=${QGIS_HB_PREFIX}/lib/python2.7/site-packages:${HB}/opt/gdal2-python/lib/python2.7/site-packages:${HB}/lib/python2.7/site-packages:$PYTHONPATH
export GDAL_DRIVER_PATH=${HB}/lib/gdalplugins
export GDAL_DATA=${HB}/opt/gdal2/share/gdal
export GRASS_PREFIX=${HB}/opt/grass7/grass-base

After which, you can try this:

from qgis.core import *

qgs = QgsApplication([], False)
qgs.initQgis()
print QgsApplication.showSettings()

shp_file = 'path/to/shape/file.shp'
vlayer = QgsVectorLayer(shp_file, 'vlayer', 'ogr')
print vlayer.isValid()

qgs.exitQgis()

Apparently, QgsApplication.setPrefixPath(<path>) is not correctly setting the prefix, and thereby not finding/loading any libraries/plugins/providers, hence no authentication system or layers can be loaded. But, setting the QGIS_PREFIX_PATH env variable does the job; then, you do not need to use QgsApplication.setPrefixPath(<path>) in your code.

On an odd note, even after setting QgsApplication.setPrefixPath(<path>) it actually ends up with:

/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS

which is of course waaaay wrong.

Let me know if you need any further explanation on the env variables used here.

itcarroll commented 7 years ago

Thanks for the additional environment variables! Success!

EDIT: dakcarto fixed code in previous post

dakcarto commented 7 years ago

Hi @itcarroll, good to hear you have it working. I've update the text of my previous post to reflect your comments. Thanks!

Also, you may want to consider porting your standalone script to QGIS 3, using the homebrew-qgisdev tap. All qgis2* and qgis3* formulae can be installed at the same time.

g-sherman commented 6 years ago

I'm seeing the same issue with QGIS3 and the prefix path. Has anything been done about this or a bug report filed? Also wondering if this is a mac only issue.

g-sherman commented 6 years ago

Seems to work if you don't create a QgsApplication object:

app = QApplication([])
QgsApplication.setPrefixPath("/Users/gsherman/apps/QGIS.app/Contents/MacOS", True)
QgsApplication.initQgis()