Commit 71a8b33c authored by ARCHER's avatar ARCHER

initial import

parent 8a338634
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
.settings/
.project
.pydevproject
# geopandas_postgis
postgis extensions for geopandas
\ No newline at end of file
postgis extensions for geopandas
add a to_postgis method to GeoDataFrame, with following extensions:
- gfd.geometry is converted to Geometry (if crs/srid) or Geography if no srid
- shapely.geometry types supported
```
from sqlalchemy import create_engine
import geopandas as gpd
import geopandas_postgis
geopandas_postgis.add_postgis(gpd)
gdf=gpd.GeoDataFrame(df,geometry='geom')
# dump to postgis
gdf.to_postgis('table_name',create_engine('postgresql://user:pass@host:5432/base_name')
```
\ No newline at end of file
from .geopandas_postgis import *
\ No newline at end of file
from geoalchemy2 import Geography, Geometry, WKTElement, WKBElement
from psycopg2.extensions import adapt, register_adapter, AsIs, QuotedString
import shapely as shp
import shapely.geometry as shpg
from sqlalchemy.orm import sessionmaker
import os
import logging
logging.basicConfig()
logger = logging.getLogger(os.path.basename(__file__))
logger.setLevel(logging.DEBUG)
shapely_handled_types=[
shpg.Polygon,
shpg.Point,
shpg.LinearRing,
shpg.MultiPoint,
shpg.MultiLineString,
shpg.MultiPolygon]
def get_srid(crs):
"""
Extract the srid from a crs dict or proj string. If no srid can be
extracted, return -1, or 0 if crs is None
Parameters
----------
crs : A dict or proj string crs. Example: {'init': 'epsg:4326'} or
'+init=epsg:4326'.
"""
if crs is None:
return 0
srid = -1
if isinstance(crs, dict):
if 'init' in crs:
s = crs['init'].split('epsg:')
if len(s) > 0:
srid = crs['init'].split('epsg:')[1]
elif isinstance(crs, str):
s = crs.split('epsg:')
if len(s) > 0:
srid = crs.split('epsg:')[1].split(' ')[0]
return int(srid)
def to_postgis(gdf,*args,**kwargs):
"""
like to_sql from geopandas, with following extensions:
- gfd.geometry is converted to Geometry (if crs/srid) or Geography if no srid
- shapely.geometry types supported
"""
logger.debug("using to_postgis extension")
table=args[0]
con=args[1]
srid=get_srid(gdf.crs)
# if no srid => Geography
if srid == 0:
logger.info("no srid : using geographic table")
Geo=Geography
else:
Geo=Geometry
# set dtype converter for geometry columun
if 'dtype' not in kwargs:
kwargs['dtype']={}
geom_types=gdf.geometry.geom_type.unique().tolist()
if len(geom_types) != 1:
raise TypeError("mixed types not implemented : %s" % ",".join(geom_types))
geom_type=geom_types[0].upper()
kwargs['dtype'][gdf.geometry.name] = Geo(geom_type) #, srid=srid)
Session = sessionmaker(bind=con)
# use a session connection
session = Session()
con1=session.connection().connect()
if 'if_exists' in kwargs and kwargs['if_exists'] == 'append':
# get actual column srid
column_srid=con1.execute('''SELECT Find_SRID('', '%s', '%s');''' % (table , gdf.geometry.name)).fetchone()[0]
if column_srid != srid:
raise ValueError("geopandas srid %s doesn't match postgis Find_SRID %s" % (srid , column_srid))
if column_srid != 0:
# overwrite column srid so we don't need to give a srid for each wkt (we be done at the end)
con1.execute('''SELECT UpdateGeometrySRID('%s','%s',0);''' % (table , gdf.geometry.name))
ret=None
try:
# use connection session
args=list(args)
args[1]=con1
args=tuple(args)
ret=gdf.to_sql(*args,**kwargs)
if srid != 0:
con1.execute('''SELECT UpdateGeometrySRID('%s','%s',%s);''' % (table , gdf.geometry.name , srid))
session.commit()
except:
session.rollback()
raise
finally:
session.close()
return ret
def add_postgis(gpd):
# psycopg2 adapter for shapely.geometry object
def shapelyAdapter(shapely_geo):
# need to use wkt representation ( pycopg2 fail with wkb :
# sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedFunction) function st_geogfromtext(bytea) does not exist
return AsIs(adapt(shapely_geo.wkt))
for Shapely_geo in shapely_handled_types:
register_adapter(Shapely_geo,shapelyAdapter)
gpd.GeoDataFrame.to_postgis=to_postgis
\ No newline at end of file
from setuptools import setup
setup(name='geopandas_postgis',
description='postgis extensions for geopandas',
url='https://gitlab.ifremer.fr/cyclobs/geopandas_postgis.git',
version = "0.0.1",
author = "Olivier Archer",
author_email = "Olivier.Archer@ifremer.fr",
license='GPL',
install_require=['psycopg2','geoalchemy2'],
packages=['geopandas_postgis'],
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment