Making .exe from the Python Script that uses GIS libraries such as geopandas, folium

Viewed 726

It's a very straightforward and broad question I know but I have very little time so I have to ask. I created an interface to do some GIS calculations and for that I used below libraries in backend.

import osmnx as ox, networkx as nx, geopandas as gpd, pandas as pd
from shapely.geometry import LineString, Point
from fiona.crs import from_epsg
import branca.colormap as cm
import folium
from folium.plugins import MarkerCluster
import pysal as ps

and these for frontend

import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename, asksaveasfilename, 
askdirectory
import backend as bk

I'm trying to make it an executable program and I've tried PyInstaller but it did not work because of the dependencies. Is there any way to do it with PyInstaller? or any other libraries? Or what should I do?

p.s : I'm using python 3.6

2nd EDIT:

I tried cx_freeze and created a setup.py and build it. After that, when I double click on the program It simply does nothing. No error messages, anything. My code is in below:

import cx_Freeze
import sys
import os 

PYTHON_INSTALL_DIR = os.path.dirname(sys.executable)
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

include_files = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
                 (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]

packages = ["pandas", "numpy", "tkinter", "matplotlib", "osmnx", "networkx",
            "geopandas", "shapely", "fiona", "branca", "folium",
            "pysal"]

base = None
if sys.platform == "win32":
    base = "Win32GUI"

executables = [cx_Freeze.Executable("frontend.py", base=base, icon="transport.ico")]

cx_Freeze.setup(
        name = "Network_Analyst",
        options = {"build_exe": {"packages":packages,
                                 "include_files":include_files}},
        version = "0.01",
        description = "Network analyst",
        executables = executables
        )

My program consists of two scripts which are frontend and backend. I'm importing backend on the frontend section, should I add it somewhere in the setup code? And one more thing, I'm working on an environment to do these processes, Is this has an effect on building a setup?

I'm giving a sample from my code to make your understanding better:

In frontend part I'm calling backend as

import backend as bk

and in the script:

class Centrality(tk.Frame):

    def degree_cent(self):
        print("Calculating Degree Centrality")
        G = self.findG()
        try:
            bk.degree_cent(G, self.t3.get("1.0",'end-1c'), self.t2.get("1.0",'end-1c'))
        except:
            bk.degree_cent(G, self.t3.get("1.0",'end-1c'))

In backend I don't use OOP, I just write the functions such as:

import osmnx as ox, networkx as nx, geopandas as gpd, pandas as pd

def degree_cent(G, outpath, *args):

    G_proj = ox.project_graph(G)    
    nodes, edges = ox.graph_to_gdfs(G_proj)
    nodes["x"] = nodes["x"].astype(float)

    degree_centrality = nx.degree_centrality(G_proj)
    degree = gpd.GeoDataFrame(pd.Series(degree_centrality), columns=["degree"])

Executable program still doesn't respond when I'm clicking on it. No respond at all. No any windows event (I've checked it from Windows Event Viewer).

1 Answers

As far as another library is concerned: you can use cx_Freeze to make an executable out of your Python program.

You can install cx_Freeze by issuing the command

python -m pip install cx_Freeze --upgrade

in a terminal or command prompt. You'll find links to the cx_Freeze documentation and source code on the cx_Freeze entry page.

To create an executable, you need to create a setup script setup.py for your application an then issue the command

python setup.py build

You can find a working example using tkinterin this question

tkinter program compiles with cx_Freeze but program will not launch

and its accepted answer. It also contains useful links.

In order to use pandas in your main script, you'll need to modify the setup.py script of the example linked above by adding

packages = ['numpy']

and replacing the options argument in the setup call by

options={'build_exe': {'include_files': include_files, 'packages': packages}}

You also might need further tweaking for the other modules you are using (geopandas, folium, ...). If it does not work with the example described above, please edit your question and add the setup.py script you are using and the error message reported to get further help.

EDIT:

For cx_Freeze version 5.1.1, the TCL/TK DLLs need to be included in a lib subdirectory of the build directory. You can do that by passing a tuple (source, destination) to the corresponding entry of the include_files list option:

include_files = [(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
                 (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]

As far as the backend is concerned, if you use import backend in frontend.py, it should be no problem, cx_Freeze should freeze it correctly.

Related