简体   繁体   English

使用pyinstaller创建可执行文件时如何处理pyproj datadir / CRS错误

[英]How to handle pyproj datadir/CRS error when creating an executable using pyinstaller

The program I am creating is designed to create several points within several zip codes, and find the distance from each of those points to every point in every zip code that is within 5 miles of the zip code of interest. 我正在创建的程序旨在在多个邮政编码中创建多个点,并找到每个点到每个邮政编码中每个点的距离,这些距离都位于感兴趣的邮政编码5英里之内。 This is done by utilizing google maps distance matrix service and capturing the distance data. 这是通过利用Google Maps距离矩阵服务并捕获距离数据来完成的。 I created a lengthy function that does several things (I think it needs to be broken up some more). 我创建了一个冗长的函数,该函数可以执行多项操作(我认为需要将其分解一些)。 Here is where I think the problem is. 我认为这是问题所在。

Everything works as it should, however, when I go to create an executable using Pyinstaller I receive several errors when it first loads and when I try to run the main function of my program. 一切正常,但是,当我使用Pyinstaller创建可执行文件时,在首次加载该文件以及尝试运行该程序的主要功能时收到一些错误。 The errors seem centered around pyproj and geopandas. 错误似乎集中在pyproj和geopandas上。

I have seen this problem in a few other places. 我在其他一些地方也看到了这个问题。 I was not able to successfully apply the solutions discussed in those places. 我无法成功应用那些地方讨论的解决方案。 The solutions that were presented consisted of: 提出的解决方案包括:

  • downgrade pyproj to 1.9.6 - see error below 将pyproj降级到1.9.6-参见下面的错误

  • add a hook file in pyinstaller - there was a hook file already in the directory 在pyinstaller中添加一个钩子文件-目录中已经有一个钩子文件

  • include pyproj._datadir and pyproj.datadir in the hidden imports section of the created spec file. 在创建的规范文件的隐藏导入部分中包含pyproj._datadir和pyproj.datadir。

  • use os.environ['PROJ_LIB'] and set it to the share folder found at "/share 使用os.environ ['PROJ_LIB']并将其设置为位于“ / share”的共享文件夹

Packages I am using: 我正在使用的软件包:

import pandas as pd
import tkinter as tk
import tkinter.filedialog
import os
import geopandas as gpd
from shapely.geometry import Point,LineString
import shapely.wkt
import googlemaps
from googlemaps.exceptions import ApiError
import datetime
from statistics import median
import _thread

Spec file: 规格文件:


# -*- mode: python -*-

block_cipher = None


a = Analysis(['main.py'],
             pathex=['C:\\Users\\Keagan\\PycharmProjects\\upwork_jobs\\pet_sitting2\\gui'],
             binaries=[],
             datas=[],
             hiddenimports=['fiona._shim','fiona.schema','pyproj._datadir','pyproj.datadir'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='main',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='main')

Main function: 主功能:

    def model_distances(self, reference_names_list, reference_zips_df,zips_and_points_gdf,api_key):

        gmaps = googlemaps.Client(api_key)

        def find_key_value_connection(poi, to_location, list_of_dicts):

            for item in list_of_dicts:
                if poi == item["poi"] and to_location == item["to_location"] or to_location == item[
                    "poi"] and poi == \
                        item["to_location"]:
                    return True

            return False

        def projection(origin_projection, to_projection, geometry_object):
            project = partial(
                pyproj.transform,
                pyproj.Proj(init=origin_projection),
                pyproj.Proj(init=to_projection)
            )

            return transform(project, geometry_object)

        zip_code_intersect_list = []

        completed_locations_dict = {}
        completed_locations_list = []

        count = 0
        google_credit_count = 0
        completed_locations_df = None

        buffer_list = []



        for name in reference_names_list:
            print("we are on: {}".format(name))

            if os.path.isfile("output_files/completed_locations_{}.xlsx".format(name)) and completed_locations_df is None:
                print("found backup, opening it")

                completed_locations_df = pd.read_excel("output_files/completed_locations_{}.xlsx".format(name))

                for item in completed_locations_df.itertuples():
                    completed_locations_dict["poi"] = int(item.poi)
                    completed_locations_dict["to_location"] = int(item.to_location)
                    completed_locations_dict["poi_zip"] = item.poi_zip
                    completed_locations_dict["to_zip"] = item.to_zip
                    completed_locations_dict["poi_name"] = item.poi_name
                    completed_locations_dict["to_name"] = item.to_name
                    completed_locations_dict["id"] = item.id
                    completed_locations_dict["distance"] = float(item.distance)
                    completed_locations_dict["time"] = float(item.time)

                    completed_locations_list.append(completed_locations_dict.copy())

            elif not os.path.isfile("output_files/completed_locations_{}.xlsx".format(name)):
                print("creating a backup")
                completed_locations_df = pd.DataFrame()
                completed_locations_df.to_excel("completed_locations_{}.xlsx".format(name))

            for zip in reference_zips_df.itertuples():

                if zip.name == name:
                    print("we are in zipcode: {}".format(zip.zip))
                    for poi in zips_and_points_gdf.itertuples():
                        if str(poi.zip_left) == str(zip.zip):
                            buffer = ""
                            poi_zip = ""
                            if poi_zip == None or poi.zip_left != poi_zip:
                                poi_zip = poi.zip_left
                                buffer = shapely.wkt.loads(poi.zip_center_point).buffer(8046)
                                buffer_list.append(buffer)

                            for to_location in zips_and_points_gdf.itertuples():
                                if poi.zip_left != to_location.zip_left and to_location.geometry.intersects(
                                        buffer) and to_location.zip_left not in zip_code_intersect_list:
                                    zip_code_intersect_list.append(to_location.zip_left)

                            for to_location in zips_and_points_gdf.itertuples():
                                if to_location.zip_left in zip_code_intersect_list and to_location.name_left == name:

                                    if find_key_value_connection(int(poi.Index), int(to_location.Index),
                                                                 completed_locations_list):

                                        print(
                                            "point at index {} was already calculated to point at index {}, google credit at: {}".format(
                                                poi.Index, to_location.Index, google_credit_count))
                                    else:
                                        google_credit_count += 1
                                        count += 1

                                        print(
                                            "calculating point at index {} to index {}, google credit at: {}".format(
                                                poi.Index, to_location.Index, google_credit_count))

                                        new_poi = projection("epsg:26910", "epsg:4326", poi.geometry)
                                        new_to_location = projection("epsg:26910", "epsg:4326", to_location.geometry)


                                        result = gmaps.distance_matrix((new_poi.y, new_poi.x),
                                                                       (new_to_location.y,new_to_location.x))

                                        completed_locations_dict["poi"] = int(poi.Index)
                                        completed_locations_dict["to_location"] = int(to_location.Index)
                                        completed_locations_dict["poi_zip"] = poi.zip_left
                                        completed_locations_dict["to_zip"] = to_location.zip_left
                                        completed_locations_dict["poi_name"] = zip.name
                                        completed_locations_dict["to_name"] = to_location.name_left
                                        completed_locations_dict["id"] = str(poi.zip_left) + str(
                                            poi.Index) + "-" + str(to_location.zip_left) + str(to_location.Index)

                                        try:
                                            completed_locations_dict["time"] = \
                                            result["rows"][0]["elements"][0]["duration"]["value"] / 60
                                            completed_locations_dict["distance"] = \
                                            result["rows"][0]["elements"][0]["distance"]["value"] / 1609.3
                                        except KeyError:
                                            completed_locations_dict["time"] = "nan"
                                            completed_locations_dict["distance"] = "nan"

                                        completed_locations_list.append(completed_locations_dict.copy())



                                        if count > 500:
                                            print("backup exists appending new df to backup")


                                            completed_locations_df = pd.DataFrame(completed_locations_list)
                                            completed_locations_df.to_excel("output_files/completed_locations_{}.xlsx".format(name))

                                            count = 0

                                        if google_credit_count >= 10000:
                                            continue_program = input(
                                                "desired google credit has hit $50, continue or change keys?(continue/change/quit): ")
                                            while continue_program != "continue":
                                                if continue_program == "quit":
                                                    # with open("backup_save.json", "w") as backup_file:
                                                    #     json.dump(completed_locations_list.copy(), backup_file)
                                                    completed_locations_df = pd.DataFrame(completed_locations_list)
                                                    completed_locations_df.to_excel("output_files/completed_locations_{}.xlsx".format(name))

                                                    print("saving to excel")
                                                    quit()
                                                new_key = input("please insert a new key: ")
                                                gmaps = googlemaps.Client(key=new_key)
                                                try:
                                                    # res = gmaps.geocode("Austin, Texas")
                                                    continue_program = input("valid key, continue? (continue/quit): ")
                                                except (ValueError, ApiError):
                                                    new_key = input("invalid key, try again: ")

                                            google_credit_count = 0

                        zip_code_intersect_list = []

        completed_locations_df = pd.DataFrame(completed_locations_list)


        return completed_locations_df

When trying to downgrade pyproj to 1.9.6: 尝试将pyproj降级到1.9.6时:

UnsatisfiableError: The following specifications were found to be incompatible with each other:

When first starting up the tool: 首次启动该工具时:

Warning:
The MATPLOTLIBDATA environment variable was deprecated in Matplotlib 3.1 and will be removed in 3.3.
  exec(bytecode, module.__dict__)
Traceback (most recent call last):
  File "site-packages\pyproj\datadir.py", line 101, in get_data_dir
pyproj.exceptions.DataDirError: Valid PROJ data directory not found.Either set the path using the environmental variable PROJ_LIB or with `pyproj.datadir.set_data_dir`.
Exception ignored in: 'pyproj._datadir.get_pyproj_context'
Traceback (most recent call last):
  File "site-packages\pyproj\datadir.py", line 101, in get_data_dir
pyproj.exceptions.DataDirError: Valid PROJ data directory not found.Either set the path using the environmental variable PROJ_LIB or with `pyproj.datadir.set_data_dir`.
proj_create: Cannot find proj.db
proj_create: init=epsg:/init=IGNF: syntax not supported in non-PROJ4 emulation mode
Invalid projection: +init=epsg:4326 +type=crs

When running the tool: 运行工具时:

<code that runs fine before>


Traceback (most recent call last):
  File "site-packages\pyproj\datadir.py", line 101, in get_data_dir
pyproj.exceptions.DataDirError: Valid PROJ data directory not found.Either set the path using the environmental variable PROJ_LIB or with `pyproj.datadir.set_data_dir`.
Exception ignored in: 'pyproj._datadir.get_pyproj_context'
Traceback (most recent call last):
  File "site-packages\pyproj\datadir.py", line 101, in get_data_dir
pyproj.exceptions.DataDirError: Valid PROJ data directory not found.Either set the path using the environmental variable PROJ_LIB or with `pyproj.datadir.set_data_dir`.
proj_create: Cannot find proj.db
proj_create: init=epsg:/init=IGNF: syntax not supported in non-PROJ4 emulation mode
Unhandled exception in thread started by <bound method ZipAnalysisGUI.analyze_data of <__main__.ZipAnalysisGUI object at 0x000001DAAD51A668>>
Traceback (most recent call last):
  File "main.py", line 480, in analyze_data
  File "main.py", line 237, in model_distances
  File "main.py", line 157, in projection
  File "site-packages\pyproj\proj.py", line 147, in __init__
  File "site-packages\pyproj\crs.py", line 391, in from_user_input
  File "site-packages\pyproj\crs.py", line 260, in __init__
  File "pyproj/_crs.pyx", line 1292, in pyproj._crs._CRS.__init__
pyproj.exceptions.CRSError: Invalid projection: +init=epsg:26910 +type=crs

What I think it is getting caught up based on the error above: 根据以上错误,我认为它已被追上:

        def projection(origin_projection, to_projection, geometry_object):
            project = partial(
                pyproj.transform,
                pyproj.Proj(init=origin_projection),
                pyproj.Proj(init=to_projection)
            )

            return transform(project, geometry_object)

Again it all works well when ran from pycharm. 从pycharm运行时,一切都很好。 Once I try to run it as an executable it begins to fall apart. 一旦我尝试将其作为可执行文件运行,它就会崩溃。 I am fairly certain it is messing up with the above function, but I am unable to determine why. 我相当确定它正在搞乱上面的功能,但是我无法确定原因。 I can share more code or the entire file if needed. 如果需要,我可以共享更多代码或整个文件。

There are many changes in gdal package. gdal软件包有很多更改。 No more "init=sintax" I found many locations . 没有更多的“ init = sintax” 我发现了很多位置 We need to change the code. 我们需要更改代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用pyinstaller创建可执行文件时出错 - Error when creating executable file with pyinstaller 修复“pyproj import _datadir”错误:找不到指定的模块 - Fixing “pyproj import _datadir” error: specified module could not be found 使用 pyinstaller 创建可执行文件时 python 的 plyer 库出现问题 - Issue with plyer library of python when creating a executable using pyinstaller 使用 pyinstaller 将 pygame 应用程序转换为可执行文件时 fonts 出错 - Error with fonts when using pyinstaller to convert a pygame app to executable 使用无控制台和无调试选项时,可执行文件上的 Pyinstaller 编解码器错误 - Pyinstaller Codec Error on Executable When Using No Console And No Debug Option 使用 pyinstaller 创建 Python 可执行文件时未导入库 - Libraries not imported when creating a Python executable with pyinstaller 无法从“pyproj”导入名称“CRS”以使用 osmnx 库 - Cannot import name 'CRS' from 'pyproj' for using the osmnx library pyinstaller创建一个无用的可执行文件 - pyinstaller creating a useless executable Pyinstaller 没有创建可执行文件 - Pyinstaller not creating executable 在 Ubuntu 上使用 pyinstaller 构建可执行文件时出错 - Error building executable using pyinstaller on Ubuntu
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM