GeoDjango GEOSException error

Question:

Trying to install a GeoDjango on my machine. I’m really new to Python and being brought into a project that has been a very tricky install for the other team members. I installed Python 2.7 and GEOS using brew, and running PSQL 9.2.4 but keep getting this error when I try to get the webserver running:

__import__(name)
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geometry/backend/geos.py", line 1, in <module>
from django.contrib.gis.geos import (
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/__init__.py", line 6, in <module>
from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/geometry.py", line 14, in <module>
from django.contrib.gis.geos.coordseq import GEOSCoordSeq
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/coordseq.py", line 9, in <module>
from django.contrib.gis.geos.libgeos import CS_PTR
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site-
packages/django/contrib/gis/geos/libgeos.py", line 119, in <module>
_verinfo = geos_version_info()
File "/Users/armynante/Desktop/uclass-files/uclass-env/lib/python2.7/site
packages/django/contrib/gis/geos/libgeos.py", line 115, in geos_version_info
if not m: raise GEOSException('Could not parse version info string "%s"' % ver)
django.contrib.gis.geos.error.GEOSException: Could not parse version info string
"3.4.2-CAPI-1.8.2 r3921"

Cant seem to find anything relevant to this trace on SO or the web. I think it might be a regex failure? I’m currently trying to reinstall PSQL and GEOS to see if I can get it running.

Here is my requirements file:

django==1.4
psycopg2==2.4.4
py-bcrypt==0.4
python-memcached==1.48
south==0.7.3

# Debug Tools
sqlparse==0.1.3
django-debug-toolbar==0.9.1
django-devserver==0.3.1

# Deployment
fabric==1.4

# AWS
# boto==2.1.1
django-storages==1.1.4
django-ses==0.4.1

# ECL
http://packages.elmcitylabs.com/ecl_django-0.5.3.tar.gz#ecl_django
http://packages.elmcitylabs.com/ecl_google-0.2.14.tar.gz#ecl_google
# https://packages.elmcitylabs.com/ecl_tools-0.3.7.tar.gz#ecl_tools
# https://packages.elmcitylabs.com/chargemaster-0.2.19.tar.gz
# https://packages.elmcitylabs.com/ecl_facebook-0.3.12.tar.gz#ecl_facebook
# https://packages.elmcitylabs.com/ecl_twitter-0.3.3.tar.gz#ecl_twitter

# Search
#https://github.com/elmcitylabs/django-haystack/tarball/issue-522#django-haystack
-e git+https://github.com/toastdriven/django-haystack.git#egg=django-haystack

pysolr==2.1.0-beta
# whoosh==2.3.2

# Misc
# PIL
# django-shorturls==1.0.1
# suds==0.4

django-mptt
sorl-thumbnail

stripe
pytz==2013b
Asked By: armynante

||

Answers:

This is my solution (obviously it is ugly, like my English, but works).
The problem is that the versions string has an white space unwanted in the RegEx.

The error says:

GEOSException: Could not parse version info string “3.4.2-CAPI-1.8.2 r3921”

And the geos_version_info warns:

Regular expression should be able to parse version strings such as
‘3.0.0rc4-CAPI-1.3.3’, ‘3.0.0-CAPI-1.4.1’ or ‘3.4.0dev-CAPI-1.8.0’

Edit this file: site-packages/django/contrib/gis/geos/libgeos.py

Look for the function: geos_version_info

And change this line:

ver = geos_version().decode()

With this line:

ver = geos_version().decode().split(' ')[0]

There is also another problem, where there is a whitespace at the end but no more information is provided. Such version also doesn’t match version regular expression, so strip()-ping the version may be expected behaviour as a quick fix. In my example it was: '3.8.0-CAPI-1.13.1 '

Answered By: nachopro

It appears that this has been fixed in Django as of last March or so. See also Django bug 20036. So upgrading to Django 1.5.4 will solve the problem.

Answered By: Joe Germuska

In the latest GEOS install, the above answer didn’t work… but was close to the problem.

I changed the regex right above the geos_version_info():
from:

version_regex = re.compile(r'^(?P<version>(?P<major>d+).(?P<minor>d+).(?P<subminor>d+))((rc(?P<release_candidate>d+))|dev)?-CAPI-(?P<capi_version>d+.d+.d+)$')

to be:

version_regex = re.compile(r'^(?P<version>(?P<major>d+).(?P<minor>d+).(?P<subminor>d+))((rc(?P<release_candidate>d+))|dev)?-CAPI-(?P<capi_version>d+.d+.d+).*$')

Notice the .* added to the end of the regex.

Answered By: JayCrossler

I think this is broken again. A recent upgrade on our FreeBSD server led to this error:

django.contrib.gis.geos.error.GEOSException: Could not parse version info string "3.6.2-CAPI-1.10.2 4d2925d6"

Looks like the regex in Django’s libgeos.py needs to be updated again to account for this different syntax. Nachopro’s solution still serves as a workaround.

Answered By: Kirkman14

This can be fixed by trying the following,

brew switch geos 3.6.1

Answered By: Muneer Muhammed

For those folks who don’t have 3.6.1 previously installed:

  1. brew unlink geos
  2. Install 3.6.1 with brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb.
  3. brew info geos should show 3.6.1 starred:
    enter image description here
Answered By: Adam

I fixed the issue by installing PostGIS with Postgres using https://postgresapp.com/downloads.html.

  1. Install PostGIS (2.2): brew install postgis
  2. To unlink geos if version is higher than 3.6.1: brew unlink geos
  3. Install Geos (3.6.1): brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/145b22e8330e094ee148861e72e26c03e73d34a1/Formula/geos.rb
  4. Switch geos version(latest version is 3.7.2 which is not supported by Django 1.11.3): brew switch geos 3.6.1
  5. Login to database and create postgis extensions: CREATE EXTENSION postgis;
    Test postgis extension: SELECT ST_Distance(‘LINESTRING(-122.33 47.606, 0.0 51.5)’::geography, ‘POINT(-21.96 64.15)’::geography);
  6. Check postgis version: SELECT PostGIS_full_version();
Answered By: Tony Aziz

Brew just released geos 3.8.0 that of course breaks Django 1.11 again.
The previous version, 3.7.3, was oh so very helpfully cleared by the all new all automatic cleanup now running on upgrades, so no brew switch geos 3.7.3 for me.

I ended up using this post to understand how to find the previous version number and commit hash:

cd $( brew --prefix )/Homebrew/Library/Taps/homebrew/homebrew-core
git log -- Formula/geos.rb | less
# find the version you need in the file, copy its hash
brew unlink geos
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/<yourcommithash>/Formula/geos.rb

After all this, the download for geos 3.7.3 fails SHA256 checksum validation for some reason… so I ended up trying 3.7.2, that actually worked.

For now the command to reinstall 3.7.2 on Catalina is:

brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/823b700ab61eeec57f34d50be2cc34a285fb5abc/Formula/geos.rb
Answered By: RobM

If one cannot for any reason edit the site packages themselves, this ugly hack did it for me without having to act on the environment itself:

try:
    __import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
except Exception as e:
    import re
    att = __import__('django.contrib.gis.geos.libgeos', fromlist=['version_regex'])
    setattr(att, 'version_regex', re.compile(
      '^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)( r\d+)?( \w+)?.*$'))
    assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)

It is based on JayCrossler’s answer.

Update

The above executes code found within the django.contrib.gis.geos.__init__.py module, which already tries to use the problematic part, rendering the above solution unusable (for python 2.7+). This can be worked around as:

import sys
try:
    import django.contrib.gis.geos.libgeos
except Exception as e:
    import re
    setattr(sys.modules['django.contrib.gis.geos.libgeos'],'version_regex', re.compile(
        '^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))((rc(?P<release_candidate>\d+))|dev)?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)( r\d+)?( \w+)?.*$'))
    assert str(type(e)) == "<class 'django.contrib.gis.geos.error.GEOSException'>", str(e)

Where basically we are acting directly on the module in sys.modules instead of trying to get it from another import that will fail.

Answered By: pavlaras
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.