2

I'm not able to run the following PyQGIS script in Windows (it worked perfectly in OS X):

import sys
import os
from qgis.core import *
import qgis.utils
from qgis.analysis import *

app = QgsApplication([],True,"")

# supply path to where is your qgis installed
QgsApplication.setPrefixPath(os.getenv("QGISPATH"), True)

# load providers
QgsApplication.initQgis()

sys.path.append(os.getenv("QGISPATH")+"\\apps\\qgis\\python\\plugins")
import processing

# Load layers with precincts and zip codes
print os.path.exists("..\\external\\precincts\\USA_precincts.shp")

layer1 = QgsVectorLayer("..\\external\\precincts\\USA_precincts.shp", "precincts", "ogr")

if layer1.isValid():
    print "Loaded layer 1"
else:
    print "Layer 1 failed to load!"

layer2 = QgsVectorLayer("..\\external\\zipcodes\\Bnd_2008_q3_region.shp", "zipcodes", "ogr")

if layer2.isValid():
    print "Loaded layer 2"
else:
    print "Layer 2 failed to load!"

# Spatial intersection between layers, save it as a new shapefile
overlayAnalyzer = QgsOverlayAnalyzer() 
overlayAnalyzer.intersection(layer1, layer2, "..\\temp\\precinctsZipcodes.shp")

QgsApplication.exitQgis()

The initial lines run fine, but then the code is not able to load the shapefiles. The output from the line print os.path.exists("..\\external\\precincts\\USA_precincts.shp") is True, but then it prints Layer 1 failed to load! when checking whether the layer was loaded correctly.

Does anyone know why it does not run in Windows? I was even able to run it in the python console (only running the lines between layer1 = QgsVectorLayer ... and the second to last line).

Note: I originally had slashes instead of backslashes. I got two answers telling me that the slashes were the problem, but it wasn't: I changed them and the result is the same.

  • 1
    Do you get any path if you print the QGISPATH variable? import os print os.getenv("QGISPATH") That could be the reason. – Germán Carrillo Nov 19 '15 at 20:29
2

I think it's your path delimiters. On Windows, use either double-backslashes \\, or single backslashes in a raw string, like r"c:\foo\bar".

I often use scripts on both Linux and Windows machines, and typically handle the different paths by checking the platform and conditionally using certain path styles, something like this:

import platform, subprocess

# Check whether Linux or Windows
platformUnknown = True
currentPlatform = platform.system()
if currentPlatform == "Linux":
    platformUnknown = False
if currentPlatform == "Windows":
    platformUnknown = False
if platformUnknown == True:
    print "Platform unknown"

# Set path to GDAL command line tools.
gdalCL_path = None
if currentPlatform == "Windows":
    gdalCL_path = "C:\\Program Files\\QGIS Lyon\\bin" # GDAL 1.11.3 via QGIS
if currentPlatform == "Linux":
    gdalCL_path = r"/usr/bin"
| improve this answer | |
  • That's actually not the reason. As I told you python is able to find the file in the line print os.path.exists("../external/precincts/USA_precincts.shp"). I changed all the slashes for double backslashes and I get the exact same result. Also, it works fine in the python console! – casta2k Nov 19 '15 at 20:07
2

The problem was in the paths. I changed it to:

QgsApplication.setPrefixPath(os.getenv("QGISPATH")+"\\apps\\qgis", True)

and now it worked fine.

| improve this answer | |
  • 1
    glad you got it to work! The cross-platform way to do this is to use os.path.join as shown in this answer. No need for slashes, backslashes or escaping. Let Python do the work for you :) – Steven Kay Nov 20 '15 at 0:11
1

The problem is that Windows uses backslashes for paths, while unix-based systems use forward slashes. This simply means that Python cannot find the path to the shapefile since it points to a nonexisting location.

For instance this line:

print os.path.exists("../external/precincts/USA_precincts.shp")

will need to be replaced with:

print os.path.exists("..\\external\\precincts\\USA_precincts.shp")

Why the double backslash? In Python the backslash denotes an escape sequence, such as \nfor a newline or \t for tabbing. Therefore a double backslash is necessary to produce a single backslash in a string.

| improve this answer | |
  • That's actually not the reason. As I told you python is able to find the file in the line print os.path.exists("../external/precincts/USA_precincts.shp"). I changed all the slashes for double backslashes and I get the exact same result. Also, it works fine in the python console! – casta2k Nov 19 '15 at 20:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.