[fiona] 01/05: Imported Upstream version 1.7.0
Bas Couwenberg
sebastic at debian.org
Tue Jun 14 22:35:41 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository fiona.
commit c7f24add24bce7e0431e4b48538b4e8653075ded
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Wed Jun 15 00:05:17 2016 +0200
Imported Upstream version 1.7.0
---
.travis.yml | 8 +-
CHANGES.txt | 26 +++-
CREDITS.txt | 1 +
MANIFEST.in | 13 +-
README.rst | 21 +--
appveyor.yml | 99 ++++++++++++
appveyor/install.ps1 | 229 ++++++++++++++++++++++++++++
appveyor/run_with_env.cmd | 88 +++++++++++
fiona/__init__.py | 2 +-
fiona/_cpl.pxd | 6 +-
fiona/_crs.pxd | 2 +
fiona/_crs.pyx | 14 +-
fiona/_csl.pxd | 5 +
fiona/_geometry.pxd | 33 ++++
fiona/_geometry.pyx | 44 +++---
fiona/_transform.pyx | 59 ++++----
fiona/fio/cat.py | 64 +++++---
fiona/fio/dump.py | 9 +-
fiona/fio/options.py | 30 +++-
fiona/{ograpi1.pxd => ogrext1.pxd} | 0
fiona/ogrext1.pyx | 270 ++++++++++++++++-----------------
fiona/{ograpi2.pxd => ogrext2.pxd} | 0
fiona/ogrext2.pyx | 302 ++++++++++++++++++-------------------
setup.py | 55 +++++--
tests/test_bytescollection.py | 19 ++-
tests/test_collection.py | 37 +++--
tests/test_drivers.py | 5 +
tests/test_fio_cat.py | 33 +++-
tests/test_fio_collect.py | 7 +
tests/test_fio_dump.py | 14 ++
tests/test_fio_info.py | 15 +-
tests/test_fio_load.py | 18 ++-
tests/test_fio_ls.py | 7 +
tests/test_geojson.py | 6 +-
tests/test_listing.py | 4 +
tests/test_multiconxn.py | 6 +
tests/test_non_counting_layer.py | 4 +-
tests/test_unicode.py | 14 +-
38 files changed, 1130 insertions(+), 439 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index d9da6f6..f2b14d0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -42,10 +42,12 @@ install:
- "if [ $(gdal-config --version) == \"$GDALVERSION\" ]; then echo \"Using gdal $GDALVERSION\"; else echo \"NOT using gdal $GDALVERSION as expected; aborting\"; exit 1; fi"
- "pip wheel -r requirements-dev.txt"
- "pip install -r requirements-dev.txt"
- - "pip install --upgrade --force-reinstall --global-option=build_ext --global-option='-I$GDALINST/gdal-$GDALVERSION/include' --global-option='-L$GDALINST/gdal-$GDALVERSION/lib' --global-option='-R$GDALINST/gdal-$GDALVERSION/lib' -e .[test]"
+ - "python setup.py sdist"
+ - "pip install --upgrade --force-reinstall --global-option=build_ext --global-option='-I$GDALINST/gdal-$GDALVERSION/include' --global-option='-L$GDALINST/gdal-$GDALVERSION/lib' --global-option='-R$GDALINST/gdal-$GDALVERSION/lib' dist/Fiona*"
- "fio --version"
+ - "cp -r tests /tmp"
script:
- - nosetests --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch
- - coverage run --source=fiona --omit='*.pxd,*.pyx,*/tests/*,*/docs/*,*/examples/*,*/benchmarks/*' -m nose --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch
+ - "cd /tmp && nosetests --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch tests"
+ - "cd /tmp && coverage run --source=fiona --omit='*.pxd,*.pyx,*/tests/*,*/docs/*,*/examples/*,*/benchmarks/*' -m nose --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch tests"
after_success:
- coveralls || echo "!! intermittent coveralls failure"
diff --git a/CHANGES.txt b/CHANGES.txt
index 45d2234..f9afad4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,8 +3,32 @@ Changes
All issue numbers are relative to https://github.com/Toblerity/Fiona/issues.
-1.7.0 (2016-06-13)
+1.7.0 (2016-06-14)
------------------
+
+The C extension modules in this library can now be built and used with either
+a 1.x or 2.x release of the GDAL library. Big thanks to René Buffat for
+leading this effort.
+
+- Refactoring: The `ogrext1.pyx` and `ogrext2.pyx` files now use separate
+ C APIs defined in `ogrext1.pxd` and `ogrex2.pxd`. The other extension
+ modules have been refactored so that they do not depend on either of these
+ modules and use subsets of the GDAL/OGR API compatible with both GDAL 1.x and
+ 2.x (#359).
+- Packaging: Source distributions now contain two different sources for the
+ `ogrext` extension module. The `ogrext1.c` file will be used with GDAL 1.x
+ and the `ogrext2.c` file will be used with GDAL 2.x.
+
+1.7b2 (2016-06-13)
+------------------
+
+- New feature: enhancement of the `--layer` option for fio-cat and fio-dump
+ to allow separate layers of one or more multi-layer input files to be
+ selected (#349).
+
+1.7b1 (2016-06-10)
+------------------
+
- New feature: support for GDAL version 2+ (#259).
- New feature: a new fio-calc CLI command (#273).
- New feature: `--layer` options for fio-info (#316) and fio-load (#299).
diff --git a/CREDITS.txt b/CREDITS.txt
index 00c00a4..44e77ff 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -10,6 +10,7 @@ Fiona is written by:
- Joshua Arnott <josh at snorfalorpagus.net>
- Kelsey Jordahl <kjordahl at enthought.com>
- Micah Cochran <micah at micahcochran.net>
+- Simon Norris <snorris at hillcrestgeo.ca>
- Patrick Young <patrick.mckendree.young at gmail.com>
- Hannes Gräuler <graeuler at geoplex.de>
- Johan Van de Wauw <johan.vandewauw at gmail.com>
diff --git a/MANIFEST.in b/MANIFEST.in
index 19e2824..63510dd 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,8 +1,13 @@
-exclude *.txt *.py
-include CHANGES.txt CREDITS.txt LICENSE.txt VERSION.txt README.rst benchmark.py setup.py
-recursive-include docs *.rst *.txt
+global-exclude .DS_Store
+global-exclude *.pyc
recursive-exclude docs/data *
recursive-exclude docs/_build *
+exclude MANIFEST.in
+exclude *.txt *.py
+recursive-include docs *.rst *.txt
recursive-include tests *.py
recursive-include tests/data *
-exclude MANIFEST.in
+include fiona/*.c fiona/*.cpp
+exclude fiona/ogrext.c
+include CHANGES.txt CREDITS.txt LICENSE.txt VERSION.txt README.rst
+include benchmark.py setup.py requirements.txt
diff --git a/README.rst b/README.rst
index c4cd169..e9331eb 100644
--- a/README.rst
+++ b/README.rst
@@ -260,25 +260,26 @@ install gdal`` using Homebrew on OS X), installation is this simple.
$ mkdir fiona_env
$ virtualenv fiona_env
$ source fiona_env/bin/activate
- (fiona_env)$ pip install Fiona
+ (fiona_env)$ pip install fiona
If gdal-config is not available or if GDAL/OGR headers and libs aren't
installed to a well known location, you must set include dirs, library dirs,
and libraries options via the setup.cfg file or setup command line as shown
-below (using ``git``).
+below (using ``git``). You must also specify the major version of the GDAL API
+(1 or 2) on the setup command line.
.. code-block:: console
(fiona_env)$ git clone git://github.com/Toblerity/Fiona.git
(fiona_env)$ cd Fiona
- (fiona_env)$ python setup.py build_ext -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal install
+ (fiona_env)$ python setup.py build_ext -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal install --gdalversion 1
-Or specify that build options should be provided by a particular
-gdal-config program.
+Or specify that build options and GDAL API version should be provided by a
+particular gdal-config program.
.. code-block:: console
- (fiona_env)$ GDAL_CONFIG=/path/to/gdal-config pip install .
+ (fiona_env)$ GDAL_CONFIG=/path/to/gdal-config pip install fiona
Windows
-------
@@ -295,12 +296,12 @@ cannot rely on gdal-config, which is only present on UNIX systems, to discover
the locations of header files and libraries that Fiona needs to compile its
C extensions. On Windows, these paths need to be provided by the user.
You will need to find the include files and the library files for gdal and
-use setup.py as follows.
+use setup.py as follows. You must also specify the major version of the GDAL
+API (1 or 2) on the setup command line.
.. code-block:: console
- $ python setup.py build_ext -I<path to gdal include files> -lgdal_i -L<path to gdal library>
- $ python setup.py install
+ $ python setup.py build_ext -I<path to gdal include files> -lgdal_i -L<path to gdal library> install --gdalversion 1
Note: The GDAL dll (gdal111.dll) and gdal-data directory need to be in your
Windows PATH otherwise Fiona will fail to work.
@@ -327,7 +328,7 @@ Or you can use the ``pep-518-install`` script::
If you have a non-standard environment, you'll need to specify the include and
lib dirs and GDAL library on the command line::
- (fiona_env)$ python setup.py build_ext -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal --gdalversion 2.0.1 develop
+ (fiona_env)$ python setup.py build_ext -I/path/to/gdal/include -L/path/to/gdal/lib -lgdal --gdalversion 2 develop
(fiona_env)$ nosetests
.. _OGR: http://www.gdal.org/ogr
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..a7bfb50
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,99 @@
+# Based on appveyor.yml from https://github.com/PDAL/PDAL and https://github.com/ogrisel/python-appveyor-demo
+#
+
+platform: x64
+
+
+environment:
+
+ global:
+ # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
+ # /E:ON and /V:ON options are not enabled in the batch script intepreter
+ # See: http://stackoverflow.com/a/13751649/163740
+ CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
+ GDAL_HOME: "C:\\gdal"
+
+ matrix:
+ # - PYTHON: "C:\\Python27.10-x64"
+ # PYTHON_VERSION: "2.7.10"
+ # PYTHON_ARCH: "64"
+
+ - PYTHON: "C:\\Python34-x64"
+ PYTHON_VERSION: "3.4.3"
+ PYTHON_ARCH: "64"
+
+install:
+
+ - ECHO "Filesystem root:"
+ - ps: "ls \"C:/\""
+
+ - ECHO "Installed SDKs:"
+ - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
+
+ # Install Python (from the official .msi of http://python.org) and pip when
+ # not already installed.
+ # - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
+
+ # Prepend newly installed Python to the PATH of this build (this cannot be
+ # done from inside the powershell script as it would require to restart
+ # the parent CMD process).
+ - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+ - "SET PYTHONPATH=%PYTHON%\\Lib\\site-packages;%PYTHONPATH%"
+
+ # Check that we have the expected version and architecture for Python
+ - "python --version"
+ - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
+
+
+ # https://code.google.com/p/pymat2/wiki/WindowsTips
+ #- ps: (Get-Content "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat) | ForEach-Object { $_ -replace "vcvarsamd64.bat", "vcvars64.bat" } | Set-Content "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat
+ # - '%CMD_IN_ENV% echo "conv env"'
+ # - ps: 'ls "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin"'
+ # - if "%platform%" == "x86" call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat"
+ #- if "%platform%" == "x64" echo f | xcopy /f /y "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat" "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\vcvarsamd64.bat"
+ # - if "%platform%" == "x64" call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" amd64
+ # - if "%platform%" == "x64" set WIN64_ARG="WIN64=YES"
+
+
+ - ps: mkdir C:\build | out-null
+ - ps: mkdir C:\gdal | out-null
+
+ - curl http://download.gisinternals.com/sdk/downloads/release-1600-x64-gdal-1-11-4-mapserver-6-4-3.zip --output gdalbin.zip
+ - 7z x gdalbin.zip -oC:\gdal
+ - curl http://download.gisinternals.com/sdk/downloads/release-1600-x64-gdal-1-11-4-mapserver-6-4-3-libs.zip --output gdallibs.zip
+ - 7z x gdallibs.zip -oC:\gdal
+ - "SET PATH=C:\\gdal;C:\\gdal\\bin;C:\\gdal\\data;C:\\gdal\\bin\\gdal\\apps;%PATH%"
+ - "SET GDAL_DATA=C:\\gdal\\bin\\gdal-data"
+
+ - ECHO "Filesystem C:/GDAL:"
+ - ps: "ls \"C:/GDAL\""
+
+
+ - cd C:\projects\fiona
+ # Upgrade to the latest version of pip to avoid it displaying warnings
+ # about it being out of date.
+ # - "python -m pip install --disable-pip-version-check --user --upgrade pip"
+
+ - pip --version
+
+ # Install the build dependencies of the project. If some dependencies contain
+ # compiled extensions and are not provided as pre-built wheel packages,
+ # pip will build them from source using the MSVC compiler matching the
+ # target Python version and architecture
+ - "%CMD_IN_ENV% pip install -r requirements-dev.txt"
+
+
+build_script:
+ # Build the compiled extension
+ - cmd: echo %PATH%
+
+ - cmd: echo %PYTHONPATH%
+
+ - "%CMD_IN_ENV% python setup.py build_ext -IC:\\gdal\\include -lgdal_i -LC:\\gdal\\lib install --gdalversion 1.11.4"
+
+
+test_script:
+ # Run the project tests
+ - cmd: SET
+
+ - "%CMD_IN_ENV% nosetests --exclude test_filter_vsi --exclude test_geopackage"
diff --git a/appveyor/install.ps1 b/appveyor/install.ps1
new file mode 100644
index 0000000..160ba55
--- /dev/null
+++ b/appveyor/install.ps1
@@ -0,0 +1,229 @@
+# Sample script to install Python and pip under Windows
+# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
+# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
+
+$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
+$BASE_URL = "https://www.python.org/ftp/python/"
+$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
+$GET_PIP_PATH = "C:\get-pip.py"
+
+$PYTHON_PRERELEASE_REGEX = @"
+(?x)
+(?<major>\d+)
+\.
+(?<minor>\d+)
+\.
+(?<micro>\d+)
+(?<prerelease>[a-z]{1,2}\d+)
+"@
+
+
+function Download ($filename, $url) {
+ $webclient = New-Object System.Net.WebClient
+
+ $basedir = $pwd.Path + "\"
+ $filepath = $basedir + $filename
+ if (Test-Path $filename) {
+ Write-Host "Reusing" $filepath
+ return $filepath
+ }
+
+ # Download and retry up to 3 times in case of network transient errors.
+ Write-Host "Downloading" $filename "from" $url
+ $retry_attempts = 2
+ for ($i = 0; $i -lt $retry_attempts; $i++) {
+ try {
+ $webclient.DownloadFile($url, $filepath)
+ break
+ }
+ Catch [Exception]{
+ Start-Sleep 1
+ }
+ }
+ if (Test-Path $filepath) {
+ Write-Host "File saved at" $filepath
+ } else {
+ # Retry once to get the error message if any at the last try
+ $webclient.DownloadFile($url, $filepath)
+ }
+ return $filepath
+}
+
+
+function ParsePythonVersion ($python_version) {
+ if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
+ return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
+ $matches.prerelease)
+ }
+ $version_obj = [version]$python_version
+ return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
+}
+
+
+function DownloadPython ($python_version, $platform_suffix) {
+ $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
+
+ if (($major -le 2 -and $micro -eq 0) `
+ -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
+ ) {
+ $dir = "$major.$minor"
+ $python_version = "$major.$minor$prerelease"
+ } else {
+ $dir = "$major.$minor.$micro"
+ }
+
+ if ($prerelease) {
+ if (($major -le 2) `
+ -or ($major -eq 3 -and $minor -eq 1) `
+ -or ($major -eq 3 -and $minor -eq 2) `
+ -or ($major -eq 3 -and $minor -eq 3) `
+ ) {
+ $dir = "$dir/prev"
+ }
+ }
+
+ if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
+ $ext = "msi"
+ if ($platform_suffix) {
+ $platform_suffix = ".$platform_suffix"
+ }
+ } else {
+ $ext = "exe"
+ if ($platform_suffix) {
+ $platform_suffix = "-$platform_suffix"
+ }
+ }
+
+ $filename = "python-$python_version$platform_suffix.$ext"
+ $url = "$BASE_URL$dir/$filename"
+ $filepath = Download $filename $url
+ return $filepath
+}
+
+
+function InstallPython ($python_version, $architecture, $python_home) {
+ Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
+ if (Test-Path $python_home) {
+ Write-Host $python_home "already exists, skipping."
+ return $false
+ }
+ if ($architecture -eq "32") {
+ $platform_suffix = ""
+ } else {
+ $platform_suffix = "amd64"
+ }
+ $installer_path = DownloadPython $python_version $platform_suffix
+ $installer_ext = [System.IO.Path]::GetExtension($installer_path)
+ Write-Host "Installing $installer_path to $python_home"
+ $install_log = $python_home + ".log"
+ if ($installer_ext -eq '.msi') {
+ InstallPythonMSI $installer_path $python_home $install_log
+ } else {
+ InstallPythonEXE $installer_path $python_home $install_log
+ }
+ if (Test-Path $python_home) {
+ Write-Host "Python $python_version ($architecture) installation complete"
+ } else {
+ Write-Host "Failed to install Python in $python_home"
+ Get-Content -Path $install_log
+ Exit 1
+ }
+}
+
+
+function InstallPythonEXE ($exepath, $python_home, $install_log) {
+ $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
+ RunCommand $exepath $install_args
+}
+
+
+function InstallPythonMSI ($msipath, $python_home, $install_log) {
+ $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
+ $uninstall_args = "/qn /x $msipath"
+ RunCommand "msiexec.exe" $install_args
+ if (-not(Test-Path $python_home)) {
+ Write-Host "Python seems to be installed else-where, reinstalling."
+ RunCommand "msiexec.exe" $uninstall_args
+ RunCommand "msiexec.exe" $install_args
+ }
+}
+
+function RunCommand ($command, $command_args) {
+ Write-Host $command $command_args
+ Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
+}
+
+
+function InstallPip ($python_home) {
+ $pip_path = $python_home + "\Scripts\pip.exe"
+ $python_path = $python_home + "\python.exe"
+ if (-not(Test-Path $pip_path)) {
+ Write-Host "Installing pip..."
+ $webclient = New-Object System.Net.WebClient
+ $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
+ Write-Host "Executing:" $python_path $GET_PIP_PATH
+ & $python_path $GET_PIP_PATH
+ } else {
+ Write-Host "pip already installed."
+ }
+}
+
+
+function DownloadMiniconda ($python_version, $platform_suffix) {
+ if ($python_version -eq "3.4") {
+ $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
+ } else {
+ $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
+ }
+ $url = $MINICONDA_URL + $filename
+ $filepath = Download $filename $url
+ return $filepath
+}
+
+
+function InstallMiniconda ($python_version, $architecture, $python_home) {
+ Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
+ if (Test-Path $python_home) {
+ Write-Host $python_home "already exists, skipping."
+ return $false
+ }
+ if ($architecture -eq "32") {
+ $platform_suffix = "x86"
+ } else {
+ $platform_suffix = "x86_64"
+ }
+ $filepath = DownloadMiniconda $python_version $platform_suffix
+ Write-Host "Installing" $filepath "to" $python_home
+ $install_log = $python_home + ".log"
+ $args = "/S /D=$python_home"
+ Write-Host $filepath $args
+ Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
+ if (Test-Path $python_home) {
+ Write-Host "Python $python_version ($architecture) installation complete"
+ } else {
+ Write-Host "Failed to install Python in $python_home"
+ Get-Content -Path $install_log
+ Exit 1
+ }
+}
+
+
+function InstallMinicondaPip ($python_home) {
+ $pip_path = $python_home + "\Scripts\pip.exe"
+ $conda_path = $python_home + "\Scripts\conda.exe"
+ if (-not(Test-Path $pip_path)) {
+ Write-Host "Installing pip..."
+ $args = "install --yes pip"
+ Write-Host $conda_path $args
+ Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
+ } else {
+ Write-Host "pip already installed."
+ }
+}
+
+function main () {
+ InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
+ InstallPip $env:PYTHON
+}
+
+main
diff --git a/appveyor/run_with_env.cmd b/appveyor/run_with_env.cmd
new file mode 100644
index 0000000..5da547c
--- /dev/null
+++ b/appveyor/run_with_env.cmd
@@ -0,0 +1,88 @@
+:: To build extensions for 64 bit Python 3, we need to configure environment
+:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
+::
+:: To build extensions for 64 bit Python 2, we need to configure environment
+:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
+::
+:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
+:: environment configurations.
+::
+:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
+:: cmd interpreter, at least for (SDK v7.0)
+::
+:: More details at:
+:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
+:: http://stackoverflow.com/a/13751649/163740
+::
+:: Author: Olivier Grisel
+:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
+::
+:: Notes about batch files for Python people:
+::
+:: Quotes in values are literally part of the values:
+:: SET FOO="bar"
+:: FOO is now five characters long: " b a r "
+:: If you don't want quotes, don't include them on the right-hand side.
+::
+:: The CALL lines at the end of this file look redundant, but if you move them
+:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
+:: case, I don't know why.
+ at ECHO OFF
+
+SET COMMAND_TO_RUN=%*
+SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
+SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
+
+:: Extract the major and minor versions, and allow for the minor version to be
+:: more than 9. This requires the version number to have two dots in it.
+SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
+IF "%PYTHON_VERSION:~3,1%" == "." (
+ SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
+) ELSE (
+ SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
+)
+
+:: Based on the Python version, determine what SDK version to use, and whether
+:: to set the SDK for 64-bit.
+IF %MAJOR_PYTHON_VERSION% == 2 (
+ SET WINDOWS_SDK_VERSION="v7.0"
+ SET SET_SDK_64=Y
+) ELSE (
+ IF %MAJOR_PYTHON_VERSION% == 3 (
+ SET WINDOWS_SDK_VERSION="v7.1"
+ IF %MINOR_PYTHON_VERSION% LEQ 4 (
+ SET SET_SDK_64=Y
+ ) ELSE (
+ SET SET_SDK_64=N
+ IF EXIST "%WIN_WDK%" (
+ :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
+ REN "%WIN_WDK%" 0wdf
+ )
+ )
+ ) ELSE (
+ ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
+ EXIT 1
+ )
+)
+
+IF %PYTHON_ARCH% == 64 (
+ IF %SET_SDK_64% == Y (
+ ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
+ SET DISTUTILS_USE_SDK=1
+ SET MSSdk=1
+ "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
+ "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
+ ECHO Executing: %COMMAND_TO_RUN%
+ call %COMMAND_TO_RUN% || EXIT 1
+ ) ELSE (
+ ECHO Using default MSVC build environment for 64 bit architecture
+ ECHO Executing: %COMMAND_TO_RUN%
+ call %COMMAND_TO_RUN% || EXIT 1
+ )
+) ELSE (
+ ECHO Using default MSVC build environment for 32 bit architecture
+ ECHO Executing: %COMMAND_TO_RUN%
+ call %COMMAND_TO_RUN% || EXIT 1
+)
diff --git a/fiona/__init__.py b/fiona/__init__.py
index 5048a65..e17a2d6 100644
--- a/fiona/__init__.py
+++ b/fiona/__init__.py
@@ -81,7 +81,7 @@ import uuid
__all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width']
-__version__ = "1.7b1"
+__version__ = "1.7.0"
__gdal_version__ = get_gdal_release_name().decode('utf-8')
log = logging.getLogger('Fiona')
diff --git a/fiona/_cpl.pxd b/fiona/_cpl.pxd
index 6e43893..609ee41 100644
--- a/fiona/_cpl.pxd
+++ b/fiona/_cpl.pxd
@@ -1,13 +1,11 @@
+# Cross-platform API functions.
+
cdef extern from "cpl_conv.h":
void * CPLMalloc (size_t)
void CPLFree (void *ptr)
void CPLSetThreadLocalConfigOption (char *key, char *val)
const char *CPLGetConfigOption (char *, char *)
-cdef extern from "cpl_string.h":
- char ** CSLSetNameValue (char **list, char *name, char *value)
- void CSLDestroy (char **list)
-
cdef extern from "cpl_vsi.h":
ctypedef struct VSILFILE:
pass
diff --git a/fiona/_crs.pxd b/fiona/_crs.pxd
index 999d08d..7329cb0 100644
--- a/fiona/_crs.pxd
+++ b/fiona/_crs.pxd
@@ -1,3 +1,5 @@
+# Coordinate system and transform API functions.
+
cdef extern from "ogr_srs_api.h":
void OSRCleanup ()
void * OSRClone (void *srs)
diff --git a/fiona/_crs.pyx b/fiona/_crs.pyx
index b4da1cb..fc3dcd1 100644
--- a/fiona/_crs.pyx
+++ b/fiona/_crs.pyx
@@ -7,7 +7,7 @@ import logging
from six import string_types
-from fiona cimport _cpl, _crs
+cimport _cpl
from fiona.errors import CRSError
@@ -20,7 +20,7 @@ def crs_to_wkt(crs):
cdef void *cogr_srs = NULL
cdef char *proj_c = NULL
- cogr_srs = _crs.OSRNewSpatialReference(NULL)
+ cogr_srs = OSRNewSpatialReference(NULL)
if cogr_srs == NULL:
raise CRSError("NULL spatial reference")
@@ -28,7 +28,7 @@ def crs_to_wkt(crs):
if isinstance(crs, string_types):
proj_b = crs.encode('utf-8')
proj_c = proj_b
- _crs.OSRSetFromUserInput(cogr_srs, proj_c)
+ OSRSetFromUserInput(cogr_srs, proj_c)
elif isinstance(crs, dict):
# EPSG is a special case.
init = crs.get('init')
@@ -37,7 +37,7 @@ def crs_to_wkt(crs):
auth, val = init.split(':')
if auth.upper() == 'EPSG':
logger.debug("Setting EPSG: %s", val)
- _crs.OSRImportFromEPSG(cogr_srs, int(val))
+ OSRImportFromEPSG(cogr_srs, int(val))
else:
params = []
crs['wktext'] = True
@@ -50,14 +50,14 @@ def crs_to_wkt(crs):
logger.debug("PROJ.4 to be imported: %r", proj)
proj_b = proj.encode('utf-8')
proj_c = proj_b
- _crs.OSRImportFromProj4(cogr_srs, proj_c)
+ OSRImportFromProj4(cogr_srs, proj_c)
else:
raise ValueError("Invalid CRS")
# Fixup, export to WKT, and set the GDAL dataset's projection.
- _crs.OSRFixup(cogr_srs)
+ OSRFixup(cogr_srs)
- _crs.OSRExportToWkt(cogr_srs, &proj_c)
+ OSRExportToWkt(cogr_srs, &proj_c)
if proj_c == NULL:
raise CRSError("Null projection")
diff --git a/fiona/_csl.pxd b/fiona/_csl.pxd
new file mode 100644
index 0000000..fe1a4eb
--- /dev/null
+++ b/fiona/_csl.pxd
@@ -0,0 +1,5 @@
+# String API functions.
+
+cdef extern from "cpl_string.h":
+ char ** CSLSetNameValue (char **list, char *name, char *value)
+ void CSLDestroy (char **list)
diff --git a/fiona/_geometry.pxd b/fiona/_geometry.pxd
index 2bf2cc1..9f3eb6e 100644
--- a/fiona/_geometry.pxd
+++ b/fiona/_geometry.pxd
@@ -1,3 +1,36 @@
+# Geometry API functions.
+
+ctypedef int OGRErr
+
+
+ctypedef struct OGREnvelope:
+ double MinX
+ double MaxX
+ double MinY
+ double MaxY
+
+
+cdef extern from "ogr_api.h":
+ OGRErr OGR_G_AddGeometryDirectly (void *geometry, void *part)
+ void OGR_G_AddPoint (void *geometry, double x, double y, double z)
+ void OGR_G_AddPoint_2D (void *geometry, double x, double y)
+ void OGR_G_CloseRings (void *geometry)
+ void * OGR_G_CreateGeometry (int wkbtypecode)
+ void OGR_G_DestroyGeometry (void *geometry)
+ unsigned char * OGR_G_ExportToJson (void *geometry)
+ void OGR_G_ExportToWkb (void *geometry, int endianness, char *buffer)
+ int OGR_G_GetCoordinateDimension (void *geometry)
+ int OGR_G_GetGeometryCount (void *geometry)
+ unsigned char * OGR_G_GetGeometryName (void *geometry)
+ int OGR_G_GetGeometryType (void *geometry)
+ void * OGR_G_GetGeometryRef (void *geometry, int n)
+ int OGR_G_GetPointCount (void *geometry)
+ double OGR_G_GetX (void *geometry, int n)
+ double OGR_G_GetY (void *geometry, int n)
+ double OGR_G_GetZ (void *geometry, int n)
+ void OGR_G_ImportFromWkb (void *geometry, unsigned char *bytes, int nbytes)
+ int OGR_G_WkbSize (void *geometry)
+
cdef class GeomBuilder:
cdef void *geom
diff --git a/fiona/_geometry.pyx b/fiona/_geometry.pyx
index 5014c40..6d57895 100644
--- a/fiona/_geometry.pyx
+++ b/fiona/_geometry.pyx
@@ -2,15 +2,13 @@
import logging
-from fiona cimport ograpi
-
-log = logging.getLogger("Fiona")
class NullHandler(logging.Handler):
def emit(self, record):
pass
-log.addHandler(NullHandler())
+log = logging.getLogger("Fiona")
+log.addHandler(NullHandler())
# Mapping of OGR integer geometry types to GeoJSON type names.
GEOMETRY_TYPES = {
@@ -41,16 +39,16 @@ cdef void * _createOgrGeomFromWKB(object wkb) except NULL:
"""Make an OGR geometry from a WKB string"""
wkbtype = bytearray(wkb)[1]
cdef unsigned char *buffer = wkb
- cdef void *cogr_geometry = ograpi.OGR_G_CreateGeometry(wkbtype)
+ cdef void *cogr_geometry = OGR_G_CreateGeometry(wkbtype)
if cogr_geometry is not NULL:
- ograpi.OGR_G_ImportFromWkb(cogr_geometry, buffer, len(wkb))
+ OGR_G_ImportFromWkb(cogr_geometry, buffer, len(wkb))
return cogr_geometry
cdef _deleteOgrGeom(void *cogr_geometry):
"""Delete an OGR geometry"""
if cogr_geometry is not NULL:
- ograpi.OGR_G_DestroyGeometry(cogr_geometry)
+ OGR_G_DestroyGeometry(cogr_geometry)
cogr_geometry = NULL
@@ -62,12 +60,12 @@ cdef class GeomBuilder:
cdef int i
if geom == NULL:
raise ValueError("Null geom")
- npoints = ograpi.OGR_G_GetPointCount(geom)
+ npoints = OGR_G_GetPointCount(geom)
coords = []
for i in range(npoints):
- values = [ograpi.OGR_G_GetX(geom, i), ograpi.OGR_G_GetY(geom, i)]
+ values = [OGR_G_GetX(geom, i), OGR_G_GetY(geom, i)]
if self.ndims > 2:
- values.append(ograpi.OGR_G_GetZ(geom, i))
+ values.append(OGR_G_GetZ(geom, i))
coords.append(tuple(values))
return coords
@@ -86,8 +84,8 @@ cdef class GeomBuilder:
if geom == NULL:
raise ValueError("Null geom")
parts = []
- for j in range(ograpi.OGR_G_GetGeometryCount(geom)):
- part = ograpi.OGR_G_GetGeometryRef(geom, j)
+ for j in range(OGR_G_GetGeometryCount(geom)):
+ part = OGR_G_GetGeometryRef(geom, j)
parts.append(GeomBuilder().build(part))
return parts
@@ -116,10 +114,10 @@ cdef class GeomBuilder:
if geom == NULL:
raise ValueError("Null geom")
- cdef unsigned int etype = ograpi.OGR_G_GetGeometryType(geom)
+ cdef unsigned int etype = OGR_G_GetGeometryType(geom)
self.code = etype
self.geomtypename = GEOMETRY_TYPES[self.code & (~0x80000000)]
- self.ndims = ograpi.OGR_G_GetCoordinateDimension(geom)
+ self.ndims = OGR_G_GetCoordinateDimension(geom)
self.geom = geom
return getattr(self, '_build' + self.geomtypename)()
@@ -136,7 +134,7 @@ cdef class OGRGeomBuilder:
"""Builds OGR geometries from Fiona geometries.
"""
cdef void * _createOgrGeometry(self, int geom_type) except NULL:
- cdef void *cogr_geometry = ograpi.OGR_G_CreateGeometry(geom_type)
+ cdef void *cogr_geometry = OGR_G_CreateGeometry(geom_type)
if cogr_geometry == NULL:
raise Exception("Could not create OGR Geometry of type: %i" % geom_type)
return cogr_geometry
@@ -144,10 +142,10 @@ cdef class OGRGeomBuilder:
cdef _addPointToGeometry(self, void *cogr_geometry, object coordinate):
if len(coordinate) == 2:
x, y = coordinate
- ograpi.OGR_G_AddPoint_2D(cogr_geometry, x, y)
+ OGR_G_AddPoint_2D(cogr_geometry, x, y)
else:
x, y, z = coordinate[:3]
- ograpi.OGR_G_AddPoint(cogr_geometry, x, y, z)
+ OGR_G_AddPoint(cogr_geometry, x, y, z)
cdef void * _buildPoint(self, object coordinates) except NULL:
cdef void *cogr_geometry = self._createOgrGeometry(GEOJSON2OGR_GEOMETRY_TYPES['Point'])
@@ -167,7 +165,7 @@ cdef class OGRGeomBuilder:
log.debug("Adding point %s", coordinate)
self._addPointToGeometry(cogr_geometry, coordinate)
log.debug("Closing ring")
- ograpi.OGR_G_CloseRings(cogr_geometry)
+ OGR_G_CloseRings(cogr_geometry)
return cogr_geometry
cdef void * _buildPolygon(self, object coordinates) except NULL:
@@ -177,7 +175,7 @@ cdef class OGRGeomBuilder:
log.debug("Adding ring %s", ring)
cogr_ring = self._buildLinearRing(ring)
log.debug("Built ring")
- ograpi.OGR_G_AddGeometryDirectly(cogr_geometry, cogr_ring)
+ OGR_G_AddGeometryDirectly(cogr_geometry, cogr_ring)
log.debug("Added ring %s", ring)
return cogr_geometry
@@ -187,7 +185,7 @@ cdef class OGRGeomBuilder:
for coordinate in coordinates:
log.debug("Adding point %s", coordinate)
cogr_part = self._buildPoint(coordinate)
- ograpi.OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
+ OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
log.debug("Added point %s", coordinate)
return cogr_geometry
@@ -198,7 +196,7 @@ cdef class OGRGeomBuilder:
log.debug("Adding line %s", line)
cogr_part = self._buildLineString(line)
log.debug("Built line")
- ograpi.OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
+ OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
log.debug("Added line %s", line)
return cogr_geometry
@@ -209,7 +207,7 @@ cdef class OGRGeomBuilder:
log.debug("Adding polygon %s", part)
cogr_part = self._buildPolygon(part)
log.debug("Built polygon")
- ograpi.OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
+ OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
log.debug("Added polygon %s", part)
return cogr_geometry
@@ -220,7 +218,7 @@ cdef class OGRGeomBuilder:
log.debug("Adding part %s", part)
cogr_part = OGRGeomBuilder().build(part)
log.debug("Built part")
- ograpi.OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
+ OGR_G_AddGeometryDirectly(cogr_geometry, cogr_part)
log.debug("Added part %s", part)
return cogr_geometry
diff --git a/fiona/_transform.pyx b/fiona/_transform.pyx
index 3d5dd69..6c5460b 100644
--- a/fiona/_transform.pyx
+++ b/fiona/_transform.pyx
@@ -4,7 +4,10 @@
import logging
-from fiona cimport ograpi, _geometry
+cimport _cpl
+cimport _crs
+cimport _csl
+cimport _geometry
cdef extern from "ogr_geometry.h" nogil:
@@ -29,10 +32,10 @@ class NullHandler(logging.Handler):
log.addHandler(NullHandler())
-cdef void *_osr_from_crs(object crs):
+cdef void *_crs_from_crs(object crs):
cdef char *proj_c = NULL
cdef void *osr = NULL
- osr = ograpi.OSRNewSpatialReference(NULL)
+ osr = _crs.OSRNewSpatialReference(NULL)
if osr == NULL:
raise ValueError("NULL spatial reference")
params = []
@@ -43,7 +46,7 @@ cdef void *_osr_from_crs(object crs):
if init:
auth, val = init.split(':')
if auth.upper() == 'EPSG':
- ograpi.OSRImportFromEPSG(osr, int(val))
+ _crs.OSRImportFromEPSG(osr, int(val))
else:
crs['wktext'] = True
for k, v in crs.items():
@@ -55,12 +58,12 @@ cdef void *_osr_from_crs(object crs):
log.debug("PROJ.4 to be imported: %r", proj)
proj_b = proj.encode('utf-8')
proj_c = proj_b
- ograpi.OSRImportFromProj4(osr, proj_c)
+ _crs.OSRImportFromProj4(osr, proj_c)
# Fall back for CRS strings like "EPSG:3857."
else:
proj_b = crs.encode('utf-8')
proj_c = proj_b
- ograpi.OSRSetFromUserInput(osr, proj_c)
+ _crs.OSRSetFromUserInput(osr, proj_c)
return osr
@@ -73,18 +76,18 @@ def _transform(src_crs, dst_crs, xs, ys):
assert len(xs) == len(ys)
- src = _osr_from_crs(src_crs)
- dst = _osr_from_crs(dst_crs)
+ src = _crs_from_crs(src_crs)
+ dst = _crs_from_crs(dst_crs)
n = len(xs)
- x = <double *>ograpi.CPLMalloc(n*sizeof(double))
- y = <double *>ograpi.CPLMalloc(n*sizeof(double))
+ x = <double *>_cpl.CPLMalloc(n*sizeof(double))
+ y = <double *>_cpl.CPLMalloc(n*sizeof(double))
for i in range(n):
x[i] = xs[i]
y[i] = ys[i]
- transform = ograpi.OCTNewCoordinateTransformation(src, dst)
- res = ograpi.OCTTransform(transform, n, x, y, NULL)
+ transform = _crs.OCTNewCoordinateTransformation(src, dst)
+ res = _crs.OCTTransform(transform, n, x, y, NULL)
res_xs = [0]*n
res_ys = [0]*n
@@ -93,11 +96,11 @@ def _transform(src_crs, dst_crs, xs, ys):
res_xs[i] = x[i]
res_ys[i] = y[i]
- ograpi.CPLFree(x)
- ograpi.CPLFree(y)
- ograpi.OCTDestroyCoordinateTransformation(transform)
- ograpi.OSRDestroySpatialReference(src)
- ograpi.OSRDestroySpatialReference(dst)
+ _cpl.CPLFree(x)
+ _cpl.CPLFree(y)
+ _crs.OCTDestroyCoordinateTransformation(transform)
+ _crs.OSRDestroySpatialReference(src)
+ _crs.OSRDestroySpatialReference(dst)
return res_xs, res_ys
@@ -117,16 +120,16 @@ def _transform_geom(
cdef int i
if src_crs and dst_crs:
- src = _osr_from_crs(src_crs)
- dst = _osr_from_crs(dst_crs)
- transform = ograpi.OCTNewCoordinateTransformation(src, dst)
+ src = _crs_from_crs(src_crs)
+ dst = _crs_from_crs(dst_crs)
+ transform = _crs.OCTNewCoordinateTransformation(src, dst)
# Transform options.
- options = ograpi.CSLSetNameValue(
+ options = _csl.CSLSetNameValue(
options, "DATELINEOFFSET",
str(antimeridian_offset).encode('utf-8'))
if antimeridian_cutting:
- options = ograpi.CSLSetNameValue(options, "WRAPDATELINE", "YES")
+ options = _csl.CSLSetNameValue(options, "WRAPDATELINE", "YES")
factory = new OGRGeometryFactory()
src_ogr_geom = _geometry.OGRGeomBuilder().build(geom)
@@ -136,13 +139,13 @@ def _transform_geom(
options)
g = _geometry.GeomBuilder().build(dst_ogr_geom)
- ograpi.OGR_G_DestroyGeometry(dst_ogr_geom)
- ograpi.OGR_G_DestroyGeometry(src_ogr_geom)
- ograpi.OCTDestroyCoordinateTransformation(transform)
+ _geometry.OGR_G_DestroyGeometry(dst_ogr_geom)
+ _geometry.OGR_G_DestroyGeometry(src_ogr_geom)
+ _crs.OCTDestroyCoordinateTransformation(transform)
if options != NULL:
- ograpi.CSLDestroy(options)
- ograpi.OSRDestroySpatialReference(src)
- ograpi.OSRDestroySpatialReference(dst)
+ _csl.CSLDestroy(options)
+ _crs.OSRDestroySpatialReference(src)
+ _crs.OSRDestroySpatialReference(dst)
else:
g = geom
if precision >= 0:
diff --git a/fiona/fio/cat.py b/fiona/fio/cat.py
index 9b97199..4562d16 100644
--- a/fiona/fio/cat.py
+++ b/fiona/fio/cat.py
@@ -19,6 +19,11 @@ warnings.simplefilter('default')
# Cat command
@click.command(short_help="Concatenate and print the features of datasets")
@cligj.files_in_arg
+ at click.option('--layer', default=None, multiple=True,
+ callback=options.cb_multilayer,
+ help="Input layer(s), specified as 'fileindex:layer` "
+ "For example, '1:foo,2:bar' will concatenate layer foo "
+ "from file 1 and layer bar from file 2")
@cligj.precision_opt
@cligj.indent_opt
@cligj.compact_opt
@@ -30,9 +35,16 @@ warnings.simplefilter('default')
help="filter for features intersecting a bounding box")
@click.pass_context
def cat(ctx, files, precision, indent, compact, ignore_errors, dst_crs,
- use_rs, bbox):
- """Concatenate and print the features of input datasets as a
- sequence of GeoJSON features."""
+ use_rs, bbox, layer):
+
+ """
+ Concatenate and print the features of input datasets as a sequence of
+ GeoJSON features.
+
+ When working with a multi-layer dataset the first layer is used by default.
+ Use the '--layer' option to select a different layer.
+ """
+
verbosity = (ctx.obj and ctx.obj['verbosity']) or 2
logger = logging.getLogger('fio')
@@ -42,27 +54,35 @@ def cat(ctx, files, precision, indent, compact, ignore_errors, dst_crs,
if compact:
dump_kwds['separators'] = (',', ':')
item_sep = compact and ',' or ', '
-
+ # Validate file idexes provided in --layer option
+ # (can't pass the files to option callback)
+ if layer:
+ options.validate_multilayer_file_index(files, layer)
+ # first layer is the default
+ for i in range(1, len(files) + 1):
+ if str(i) not in layer.keys():
+ layer[str(i)] = [0]
try:
with fiona.drivers(CPL_DEBUG=verbosity > 2):
- for path in files:
- with fiona.open(path) as src:
- if bbox:
- try:
- bbox = tuple(map(float, bbox.split(',')))
- except ValueError:
- bbox = json.loads(bbox)
- for i, feat in src.items(bbox=bbox):
- if dst_crs or precision > 0:
- g = transform_geom(
- src.crs, dst_crs, feat['geometry'],
- antimeridian_cutting=True,
- precision=precision)
- feat['geometry'] = g
- feat['bbox'] = fiona.bounds(g)
- if use_rs:
- click.echo(u'\u001e', nl=False)
- click.echo(json.dumps(feat, **dump_kwds))
+ for i, path in enumerate(files, 1):
+ for lyr in layer[str(i)]:
+ with fiona.open(path, layer=lyr) as src:
+ if bbox:
+ try:
+ bbox = tuple(map(float, bbox.split(',')))
+ except ValueError:
+ bbox = json.loads(bbox)
+ for i, feat in src.items(bbox=bbox):
+ if dst_crs or precision > 0:
+ g = transform_geom(
+ src.crs, dst_crs, feat['geometry'],
+ antimeridian_cutting=True,
+ precision=precision)
+ feat['geometry'] = g
+ feat['bbox'] = fiona.bounds(g)
+ if use_rs:
+ click.echo(u'\u001e', nl=False)
+ click.echo(json.dumps(feat, **dump_kwds))
except Exception:
logger.exception("Exception caught during processing")
diff --git a/fiona/fio/dump.py b/fiona/fio/dump.py
index 6968285..b7397a2 100644
--- a/fiona/fio/dump.py
+++ b/fiona/fio/dump.py
@@ -10,11 +10,16 @@ import cligj
import fiona
from fiona.fio import helpers
+from fiona.fio import options
from fiona.transform import transform_geom
@click.command(short_help="Dump a dataset to GeoJSON.")
@click.argument('input', type=click.Path(), required=True)
+ at click.option('--layer', metavar="INDEX|NAME", callback=options.cb_layer,
+ help="Print information about a specific layer. The first "
+ "layer is used by default. Layers use zero-based "
+ "numbering when accessed by index.")
@click.option('--encoding', help="Specify encoding of the input file.")
@cligj.precision_opt
@cligj.indent_opt
@@ -31,7 +36,7 @@ from fiona.transform import transform_geom
"context.")
@click.pass_context
def dump(ctx, input, encoding, precision, indent, compact, record_buffered,
- ignore_errors, with_ld_context, add_ld_context_item):
+ ignore_errors, with_ld_context, add_ld_context_item, layer):
"""Dump a dataset either as a GeoJSON feature collection (the default)
or a sequence of GeoJSON features."""
@@ -50,6 +55,8 @@ def dump(ctx, input, encoding, precision, indent, compact, record_buffered,
open_kwds = {}
if encoding:
open_kwds['encoding'] = encoding
+ if layer:
+ open_kwds['layer'] = layer
def transformer(crs, feat):
tg = partial(transform_geom, crs, 'EPSG:4326',
diff --git a/fiona/fio/options.py b/fiona/fio/options.py
index 6a7a62b..d916227 100644
--- a/fiona/fio/options.py
+++ b/fiona/fio/options.py
@@ -1,6 +1,8 @@
"""Common commandline options for `fio`"""
+from collections import defaultdict
+
import click
@@ -10,8 +12,34 @@ dst_crs_opt = click.option('--dst-crs', '--dst_crs', help="Destination CRS.")
def cb_layer(ctx, param, value):
"""Let --layer be a name or index."""
-
if value is None or not value.isdigit():
return value
else:
return int(value)
+
+
+def cb_multilayer(ctx, param, value):
+ """
+ Transform layer options from strings ("1:a,1:b", "2:a,2:c,2:z") to
+ {
+ '1': ['a', 'b'],
+ '2': ['a', 'c', 'z']
+ }
+ """
+ out = defaultdict(list)
+ for raw in value:
+ for v in raw.split(','):
+ ds, name = v.split(':')
+ out[ds].append(name)
+ return out
+
+
+def validate_multilayer_file_index(files, layerdict):
+ """
+ Ensure file indexes provided in the --layer option are valid
+ """
+ for key in layerdict.keys():
+ click.echo(key)
+ if key not in [str(k) for k in range(1, len(files) + 1)]:
+ layer = key+":"+layerdict[key][0]
+ raise click.BadParameter("Layer {} does not exist".format(layer))
diff --git a/fiona/ograpi1.pxd b/fiona/ogrext1.pxd
similarity index 100%
rename from fiona/ograpi1.pxd
rename to fiona/ogrext1.pxd
diff --git a/fiona/ogrext1.pyx b/fiona/ogrext1.pyx
index 56ae391..e9b14a1 100644
--- a/fiona/ogrext1.pyx
+++ b/fiona/ogrext1.pyx
@@ -12,8 +12,8 @@ import uuid
from six import integer_types, string_types, text_type
-from fiona cimport ograpi
-from fiona._geometry cimport GeomBuilder, OGRGeomBuilder
+cimport ogrext1
+from _geometry cimport GeomBuilder, OGRGeomBuilder
from fiona._err import cpl_errs
from fiona._geometry import GEOMETRY_TYPES
from fiona.errors import (
@@ -123,11 +123,11 @@ def calc_gdal_version_num(maj, min, rev):
def get_gdal_version_num():
"""Return current internal version number of gdal"""
- return int(ograpi.GDALVersionInfo("VERSION_NUM"))
+ return int(ogrext1.GDALVersionInfo("VERSION_NUM"))
def get_gdal_release_name():
"""Return release name of gdal"""
- return ograpi.GDALVersionInfo("RELEASE_NAME")
+ return ogrext1.GDALVersionInfo("RELEASE_NAME")
# Feature extension classes and functions follow.
@@ -153,35 +153,35 @@ cdef class FeatureBuilder:
cdef int retval
cdef char *key_c
props = OrderedDict()
- for i in range(ograpi.OGR_F_GetFieldCount(feature)):
- fdefn = ograpi.OGR_F_GetFieldDefnRef(feature, i)
+ for i in range(ogrext1.OGR_F_GetFieldCount(feature)):
+ fdefn = ogrext1.OGR_F_GetFieldDefnRef(feature, i)
if fdefn == NULL:
raise ValueError("Null feature definition")
- key_c = ograpi.OGR_Fld_GetNameRef(fdefn)
+ key_c = ogrext1.OGR_Fld_GetNameRef(fdefn)
if key_c == NULL:
raise ValueError("Null field name reference")
key_b = key_c
key = key_b.decode(encoding)
- fieldtypename = FIELD_TYPES[ograpi.OGR_Fld_GetType(fdefn)]
+ fieldtypename = FIELD_TYPES[ogrext1.OGR_Fld_GetType(fdefn)]
if not fieldtypename:
log.warn(
"Skipping field %s: invalid type %s",
key,
- ograpi.OGR_Fld_GetType(fdefn))
+ ogrext1.OGR_Fld_GetType(fdefn))
continue
# TODO: other types
fieldtype = FIELD_TYPES_MAP[fieldtypename]
- if not ograpi.OGR_F_IsFieldSet(feature, i):
+ if not ogrext1.OGR_F_IsFieldSet(feature, i):
props[key] = None
elif fieldtype is int:
- props[key] = ograpi.OGR_F_GetFieldAsInteger(feature, i)
+ props[key] = ogrext1.OGR_F_GetFieldAsInteger(feature, i)
elif fieldtype is float:
- props[key] = ograpi.OGR_F_GetFieldAsDouble(feature, i)
+ props[key] = ogrext1.OGR_F_GetFieldAsDouble(feature, i)
elif fieldtype is text_type:
try:
- val = ograpi.OGR_F_GetFieldAsString(feature, i)
+ val = ogrext1.OGR_F_GetFieldAsString(feature, i)
val = val.decode(encoding)
except UnicodeError:
log.error("Failed to decode property '%s' value '%s'",
@@ -200,7 +200,7 @@ cdef class FeatureBuilder:
props[key] = val
elif fieldtype in (FionaDateType, FionaTimeType, FionaDateTimeType):
- retval = ograpi.OGR_F_GetFieldAsDateTime(
+ retval = ogrext1.OGR_F_GetFieldAsDateTime(
feature, i, &y, &m, &d, &hh, &mm, &ss, &tz)
if fieldtype is FionaDateType:
props[key] = datetime.date(y, m, d).isoformat()
@@ -213,14 +213,14 @@ cdef class FeatureBuilder:
log.debug("%s: None, fieldtype: %r, %r" % (key, fieldtype, fieldtype in string_types))
props[key] = None
- cdef void *cogr_geometry = ograpi.OGR_F_GetGeometryRef(feature)
+ cdef void *cogr_geometry = ogrext1.OGR_F_GetGeometryRef(feature)
if cogr_geometry is not NULL:
geom = GeomBuilder().build(cogr_geometry)
else:
geom = None
return {
'type': 'Feature',
- 'id': str(ograpi.OGR_F_GetFID(feature)),
+ 'id': str(ogrext1.OGR_F_GetFID(feature)),
'geometry': geom,
'properties': props }
@@ -241,17 +241,17 @@ cdef class OGRFeatureBuilder:
cdef void *cogr_layer = session.cogr_layer
if cogr_layer == NULL:
raise ValueError("Null layer")
- cdef void *cogr_featuredefn = ograpi.OGR_L_GetLayerDefn(cogr_layer)
+ cdef void *cogr_featuredefn = ogrext1.OGR_L_GetLayerDefn(cogr_layer)
if cogr_featuredefn == NULL:
raise ValueError("Null feature definition")
- cdef void *cogr_feature = ograpi.OGR_F_Create(cogr_featuredefn)
+ cdef void *cogr_feature = ogrext1.OGR_F_Create(cogr_featuredefn)
if cogr_feature == NULL:
raise ValueError("Null feature")
if feature['geometry'] is not None:
cogr_geometry = OGRGeomBuilder().build(
feature['geometry'])
- ograpi.OGR_F_SetGeometryDirectly(cogr_feature, cogr_geometry)
+ ogrext1.OGR_F_SetGeometryDirectly(cogr_feature, cogr_geometry)
# OGR_F_SetFieldString takes UTF-8 encoded strings ('bytes' in
# Python 3).
@@ -272,7 +272,7 @@ cdef class OGRFeatureBuilder:
raise
key_c = key_bytes
- i = ograpi.OGR_F_GetFieldIndex(cogr_feature, key_c)
+ i = ogrext1.OGR_F_GetFieldIndex(cogr_feature, key_c)
if i < 0:
continue
@@ -282,9 +282,9 @@ cdef class OGRFeatureBuilder:
# Continue over the standard OGR types.
if isinstance(value, integer_types):
- ograpi.OGR_F_SetFieldInteger(cogr_feature, i, value)
+ ogrext1.OGR_F_SetFieldInteger(cogr_feature, i, value)
elif isinstance(value, float):
- ograpi.OGR_F_SetFieldDouble(cogr_feature, i, value)
+ ogrext1.OGR_F_SetFieldDouble(cogr_feature, i, value)
elif (isinstance(value, string_types)
and schema_type in ['date', 'time', 'datetime']):
if schema_type == 'date':
@@ -293,23 +293,23 @@ cdef class OGRFeatureBuilder:
y, m, d, hh, mm, ss, ff = parse_time(value)
else:
y, m, d, hh, mm, ss, ff = parse_datetime(value)
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext1.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, hh, mm, ss, 0)
elif (isinstance(value, datetime.date)
and schema_type == 'date'):
y, m, d = value.year, value.month, value.day
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext1.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, 0, 0, 0, 0)
elif (isinstance(value, datetime.datetime)
and schema_type == 'datetime'):
y, m, d = value.year, value.month, value.day
hh, mm, ss = value.hour, value.minute, value.second
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext1.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, hh, mm, ss, 0)
elif (isinstance(value, datetime.time)
and schema_type == 'time'):
hh, mm, ss = value.hour, value.minute, value.second
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext1.OGR_F_SetFieldDateTime(
cogr_feature, i, 0, 0, 0, hh, mm, ss, 0)
elif isinstance(value, string_types):
# Catch, log, and re-raise string field value encoding errors.
@@ -320,7 +320,7 @@ cdef class OGRFeatureBuilder:
key, value)
raise
string_c = value_bytes
- ograpi.OGR_F_SetFieldString(cogr_feature, i, string_c)
+ ogrext1.OGR_F_SetFieldString(cogr_feature, i, string_c)
elif value is None:
pass # keep field unset/null
else:
@@ -332,17 +332,17 @@ cdef class OGRFeatureBuilder:
cdef _deleteOgrFeature(void *cogr_feature):
"""Delete an OGR feature"""
if cogr_feature is not NULL:
- ograpi.OGR_F_Destroy(cogr_feature)
+ ogrext1.OGR_F_Destroy(cogr_feature)
cogr_feature = NULL
def featureRT(feature, collection):
# For testing purposes only, leaks the JSON data
cdef void *cogr_feature = OGRFeatureBuilder().build(feature, collection)
- cdef void *cogr_geometry = ograpi.OGR_F_GetGeometryRef(cogr_feature)
+ cdef void *cogr_geometry = ogrext1.OGR_F_GetGeometryRef(cogr_feature)
if cogr_geometry == NULL:
raise ValueError("Null geometry")
- log.debug("Geometry: %s" % ograpi.OGR_G_ExportToJson(cogr_geometry))
+ log.debug("Geometry: %s" % ogrext1.OGR_G_ExportToJson(cogr_geometry))
encoding = collection.encoding or 'utf-8'
result = FeatureBuilder().build(
cogr_feature,
@@ -364,7 +364,7 @@ cdef class Session:
cdef object _encoding
cdef object collection
- def __cinit__(self):
+ def __init__(self):
self.cogr_ds = NULL
self.cogr_layer = NULL
self._fileencoding = None
@@ -401,15 +401,15 @@ cdef class Session:
name_b = name.encode()
name_c = name_b
log.debug("Trying driver: %s", name)
- drv = ograpi.OGRGetDriverByName(name_c)
+ drv = ogrext1.OGRGetDriverByName(name_c)
if drv != NULL:
- ds = ograpi.OGR_Dr_Open(drv, path_c, 0)
+ ds = ogrext1.OGR_Dr_Open(drv, path_c, 0)
if ds != NULL:
self.cogr_ds = ds
collection._driver = name
break
else:
- self.cogr_ds = ograpi.OGROpen(path_c, 0, NULL)
+ self.cogr_ds = ogrext1.OGROpen(path_c, 0, NULL)
if self.cogr_ds == NULL:
raise FionaValueError(
@@ -420,12 +420,12 @@ cdef class Session:
if isinstance(collection.name, string_types):
name_b = collection.name.encode('utf-8')
name_c = name_b
- self.cogr_layer = ograpi.OGR_DS_GetLayerByName(
+ self.cogr_layer = ogrext1.OGR_DS_GetLayerByName(
self.cogr_ds, name_c)
elif isinstance(collection.name, int):
- self.cogr_layer = ograpi.OGR_DS_GetLayer(
+ self.cogr_layer = ogrext1.OGR_DS_GetLayer(
self.cogr_ds, collection.name)
- name_c = ograpi.OGR_L_GetName(self.cogr_layer)
+ name_c = ogrext1.OGR_L_GetName(self.cogr_layer)
name_b = name_c
collection.name = name_b.decode('utf-8')
@@ -436,11 +436,11 @@ cdef class Session:
userencoding = self.collection.encoding
if userencoding:
- ograpi.CPLSetThreadLocalConfigOption('SHAPE_ENCODING', '')
+ ogrext1.CPLSetThreadLocalConfigOption('SHAPE_ENCODING', '')
self._fileencoding = userencoding.upper()
else:
self._fileencoding = (
- ograpi.OGR_L_TestCapability(
+ ogrext1.OGR_L_TestCapability(
self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or (
self.get_driver() == "ESRI Shapefile" and
@@ -449,7 +449,7 @@ cdef class Session:
def stop(self):
self.cogr_layer = NULL
if self.cogr_ds is not NULL:
- ograpi.OGR_DS_Destroy(self.cogr_ds)
+ ogrext1.OGR_DS_Destroy(self.cogr_ds)
self.cogr_ds = NULL
def get_fileencoding(self):
@@ -459,7 +459,7 @@ cdef class Session:
if not self._encoding:
fileencoding = self.get_fileencoding()
self._encoding = (
- ograpi.OGR_L_TestCapability(
+ ogrext1.OGR_L_TestCapability(
self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or fileencoding
return self._encoding
@@ -467,13 +467,13 @@ cdef class Session:
def get_length(self):
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- return ograpi.OGR_L_GetFeatureCount(self.cogr_layer, 0)
+ return ogrext1.OGR_L_GetFeatureCount(self.cogr_layer, 0)
def get_driver(self):
- cdef void *cogr_driver = ograpi.OGR_DS_GetDriver(self.cogr_ds)
+ cdef void *cogr_driver = ogrext1.OGR_DS_GetDriver(self.cogr_ds)
if cogr_driver == NULL:
raise ValueError("Null driver")
- cdef char *name = ograpi.OGR_Dr_GetName(cogr_driver)
+ cdef char *name = ogrext1.OGR_Dr_GetName(cogr_driver)
driver_name = name
return driver_name.decode()
@@ -488,52 +488,52 @@ cdef class Session:
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_featuredefn = ograpi.OGR_L_GetLayerDefn(self.cogr_layer)
+ cogr_featuredefn = ogrext1.OGR_L_GetLayerDefn(self.cogr_layer)
if cogr_featuredefn == NULL:
raise ValueError("Null feature definition")
- n = ograpi.OGR_FD_GetFieldCount(cogr_featuredefn)
+ n = ogrext1.OGR_FD_GetFieldCount(cogr_featuredefn)
for i from 0 <= i < n:
- cogr_fielddefn = ograpi.OGR_FD_GetFieldDefn(cogr_featuredefn, i)
+ cogr_fielddefn = ogrext1.OGR_FD_GetFieldDefn(cogr_featuredefn, i)
if cogr_fielddefn == NULL:
raise ValueError("Null field definition")
- key_c = ograpi.OGR_Fld_GetNameRef(cogr_fielddefn)
+ key_c = ogrext1.OGR_Fld_GetNameRef(cogr_fielddefn)
key_b = key_c
if not bool(key_b):
raise ValueError("Invalid field name ref: %s" % key)
key = key_b.decode(self.get_internalencoding())
- fieldtypename = FIELD_TYPES[ograpi.OGR_Fld_GetType(cogr_fielddefn)]
+ fieldtypename = FIELD_TYPES[ogrext1.OGR_Fld_GetType(cogr_fielddefn)]
if not fieldtypename:
log.warn(
"Skipping field %s: invalid type %s",
key,
- ograpi.OGR_Fld_GetType(cogr_fielddefn))
+ ogrext1.OGR_Fld_GetType(cogr_fielddefn))
continue
val = fieldtypename
if fieldtypename == 'float':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext1.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 24:
fmt = ":%d" % width
- precision = ograpi.OGR_Fld_GetPrecision(cogr_fielddefn)
+ precision = ogrext1.OGR_Fld_GetPrecision(cogr_fielddefn)
if precision: # and precision != 15:
fmt += ".%d" % precision
val = "float" + fmt
elif fieldtypename == 'int':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext1.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 11:
fmt = ":%d" % width
val = fieldtypename + fmt
elif fieldtypename == 'str':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext1.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 80:
fmt = ":%d" % width
val = fieldtypename + fmt
props.append((key, val))
- cdef unsigned int geom_type = ograpi.OGR_FD_GetGeomType(
+ cdef unsigned int geom_type = ogrext1.OGR_FD_GetGeomType(
cogr_featuredefn)
return {
'properties': OrderedDict(props),
@@ -546,17 +546,17 @@ cdef class Session:
cdef void *cogr_crs = NULL
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_crs = ograpi.OGR_L_GetSpatialRef(self.cogr_layer)
+ cogr_crs = ogrext1.OGR_L_GetSpatialRef(self.cogr_layer)
crs = {}
if cogr_crs is not NULL:
log.debug("Got coordinate system")
- retval = ograpi.OSRAutoIdentifyEPSG(cogr_crs)
+ retval = ogrext1.OSRAutoIdentifyEPSG(cogr_crs)
if retval > 0:
log.info("Failed to auto identify EPSG: %d", retval)
- auth_key = ograpi.OSRGetAuthorityName(cogr_crs, NULL)
- auth_val = ograpi.OSRGetAuthorityCode(cogr_crs, NULL)
+ auth_key = ogrext1.OSRGetAuthorityName(cogr_crs, NULL)
+ auth_val = ogrext1.OSRGetAuthorityCode(cogr_crs, NULL)
if auth_key != NULL and auth_val != NULL:
key_b = auth_key
@@ -566,7 +566,7 @@ cdef class Session:
val = val_b.decode('utf-8')
crs['init'] = "epsg:" + val
else:
- ograpi.OSRExportToProj4(cogr_crs, &proj_c)
+ ogrext1.OSRExportToProj4(cogr_crs, &proj_c)
if proj_c == NULL:
raise ValueError("Null projection")
proj_b = proj_c
@@ -591,7 +591,7 @@ cdef class Session:
k = k.lstrip("+")
crs[k] = v
- ograpi.CPLFree(proj_c)
+ ogrext1.CPLFree(proj_c)
else:
log.debug("Projection not found (cogr_crs was NULL)")
return crs
@@ -600,16 +600,16 @@ cdef class Session:
cdef char *proj_c = NULL
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_crs = ograpi.OGR_L_GetSpatialRef(self.cogr_layer)
+ cogr_crs = ogrext1.OGR_L_GetSpatialRef(self.cogr_layer)
crs_wkt = ""
if cogr_crs is not NULL:
log.debug("Got coordinate system")
- ograpi.OSRExportToWkt(cogr_crs, &proj_c)
+ ogrext1.OSRExportToWkt(cogr_crs, &proj_c)
if proj_c == NULL:
raise ValueError("Null projection")
proj_b = proj_c
crs_wkt = proj_b.decode('utf-8')
- ograpi.CPLFree(proj_c)
+ ogrext1.CPLFree(proj_c)
else:
log.debug("Projection not found (cogr_crs was NULL)")
return crs_wkt
@@ -617,8 +617,8 @@ cdef class Session:
def get_extent(self):
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cdef ograpi.OGREnvelope extent
- result = ograpi.OGR_L_GetExtent(self.cogr_layer, &extent, 1)
+ cdef ogrext1.OGREnvelope extent
+ result = ogrext1.OGR_L_GetExtent(self.cogr_layer, &extent, 1)
return (extent.MinX, extent.MinY, extent.MaxX, extent.MaxY)
def has_feature(self, fid):
@@ -628,7 +628,7 @@ cdef class Session:
"""
cdef void * cogr_feature
fid = int(fid)
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, fid)
+ cogr_feature = ogrext1.OGR_L_GetFeature(self.cogr_layer, fid)
if cogr_feature != NULL:
_deleteOgrFeature(cogr_feature)
return True
@@ -642,7 +642,7 @@ cdef class Session:
"""
cdef void * cogr_feature
fid = int(fid)
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, fid)
+ cogr_feature = ogrext1.OGR_L_GetFeature(self.cogr_layer, fid)
if cogr_feature != NULL:
_deleteOgrFeature(cogr_feature)
return True
@@ -660,12 +660,12 @@ cdef class Session:
index = item
# from the back
if index < 0:
- ftcount = ograpi.OGR_L_GetFeatureCount(self.cogr_layer, 0)
+ ftcount = ogrext1.OGR_L_GetFeatureCount(self.cogr_layer, 0)
if ftcount == -1:
raise IndexError(
"collection's dataset does not support negative indexes")
index += ftcount
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, index)
+ cogr_feature = ogrext1.OGR_L_GetFeature(self.cogr_layer, index)
if cogr_feature == NULL:
return None
feature = FeatureBuilder().build(
@@ -712,20 +712,20 @@ cdef class WritingSession(Session):
path_b = path
path_c = path_b
with cpl_errs:
- self.cogr_ds = ograpi.OGROpen(path_c, 1, NULL)
+ self.cogr_ds = ogrext1.OGROpen(path_c, 1, NULL)
if self.cogr_ds == NULL:
raise RuntimeError("Failed to open %s" % path)
- cogr_driver = ograpi.OGR_DS_GetDriver(self.cogr_ds)
+ cogr_driver = ogrext1.OGR_DS_GetDriver(self.cogr_ds)
if cogr_driver == NULL:
raise ValueError("Null driver")
if isinstance(collection.name, string_types):
name_b = collection.name.encode()
name_c = name_b
- self.cogr_layer = ograpi.OGR_DS_GetLayerByName(
+ self.cogr_layer = ogrext1.OGR_DS_GetLayerByName(
self.cogr_ds, name_c)
elif isinstance(collection.name, int):
- self.cogr_layer = ograpi.OGR_DS_GetLayer(
+ self.cogr_layer = ogrext1.OGR_DS_GetLayer(
self.cogr_ds, collection.name)
if self.cogr_layer == NULL:
@@ -736,7 +736,7 @@ cdef class WritingSession(Session):
userencoding = self.collection.encoding
self._fileencoding = (userencoding or (
- ograpi.OGR_L_TestCapability(self.cogr_layer, OLC_STRINGSASUTF8) and
+ ogrext1.OGR_L_TestCapability(self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or (
self.get_driver() == "ESRI Shapefile" and
'ISO-8859-1') or locale.getpreferredencoding()).upper()
@@ -750,27 +750,27 @@ cdef class WritingSession(Session):
driver_b = collection.driver.encode()
driver_c = driver_b
- cogr_driver = ograpi.OGRGetDriverByName(driver_c)
+ cogr_driver = ogrext1.OGRGetDriverByName(driver_c)
if cogr_driver == NULL:
raise ValueError("Null driver")
if not os.path.exists(path):
- cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+ cogr_ds = ogrext1.OGR_Dr_CreateDataSource(
cogr_driver, path_c, NULL)
else:
with cpl_errs:
- cogr_ds = ograpi.OGROpen(path_c, 1, NULL)
+ cogr_ds = ogrext1.OGROpen(path_c, 1, NULL)
if cogr_ds == NULL:
- cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+ cogr_ds = ogrext1.OGR_Dr_CreateDataSource(
cogr_driver, path_c, NULL)
elif collection.name is None:
- ograpi.OGR_DS_Destroy(cogr_ds)
+ ogrext1.OGR_DS_Destroy(cogr_ds)
cogr_ds == NULL
log.debug("Deleted pre-existing data at %s", path)
- cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+ cogr_ds = ogrext1.OGR_Dr_CreateDataSource(
cogr_driver, path_c, NULL)
else:
@@ -787,14 +787,14 @@ cdef class WritingSession(Session):
# is constructed (later).
col_crs = collection._crs_wkt or collection._crs
if col_crs:
- cogr_srs = ograpi.OSRNewSpatialReference(NULL)
+ cogr_srs = ogrext1.OSRNewSpatialReference(NULL)
if cogr_srs == NULL:
raise ValueError("NULL spatial reference")
# First, check for CRS strings like "EPSG:3857".
if isinstance(col_crs, string_types):
proj_b = col_crs.encode('utf-8')
proj_c = proj_b
- ograpi.OSRSetFromUserInput(cogr_srs, proj_c)
+ ogrext1.OSRSetFromUserInput(cogr_srs, proj_c)
elif isinstance(col_crs, dict):
# EPSG is a special case.
init = col_crs.get('init')
@@ -803,7 +803,7 @@ cdef class WritingSession(Session):
auth, val = init.split(':')
if auth.upper() == 'EPSG':
log.debug("Setting EPSG: %s", val)
- ograpi.OSRImportFromEPSG(cogr_srs, int(val))
+ ogrext1.OSRImportFromEPSG(cogr_srs, int(val))
else:
params = []
col_crs['wktext'] = True
@@ -816,12 +816,12 @@ cdef class WritingSession(Session):
log.debug("PROJ.4 to be imported: %r", proj)
proj_b = proj.encode('utf-8')
proj_c = proj_b
- ograpi.OSRImportFromProj4(cogr_srs, proj_c)
+ ogrext1.OSRImportFromProj4(cogr_srs, proj_c)
else:
raise ValueError("Invalid CRS")
# Fixup, export to WKT, and set the GDAL dataset's projection.
- ograpi.OSRFixup(cogr_srs)
+ ogrext1.OSRFixup(cogr_srs)
# Figure out what encoding to use. The encoding parameter given
# to the collection constructor takes highest precedence, then
@@ -836,15 +836,15 @@ cdef class WritingSession(Session):
if fileencoding:
fileencoding_b = fileencoding.encode('utf-8')
fileencoding_c = fileencoding_b
- options = ograpi.CSLSetNameValue(options, "ENCODING", fileencoding_c)
+ options = ogrext1.CSLSetNameValue(options, "ENCODING", fileencoding_c)
log.debug("Output file encoding: %s", fileencoding)
# Does the layer exist already? If so, we delete it.
- layer_count = ograpi.OGR_DS_GetLayerCount(self.cogr_ds)
+ layer_count = ogrext1.OGR_DS_GetLayerCount(self.cogr_ds)
layer_names = []
for i in range(layer_count):
- cogr_layer = ograpi.OGR_DS_GetLayer(cogr_ds, i)
- name_c = ograpi.OGR_L_GetName(cogr_layer)
+ cogr_layer = ogrext1.OGR_DS_GetLayer(cogr_ds, i)
+ name_c = ogrext1.OGR_L_GetName(cogr_layer)
name_b = name_c
layer_names.append(name_b.decode('utf-8'))
@@ -857,12 +857,12 @@ cdef class WritingSession(Session):
idx = collection.name
if idx >= 0:
log.debug("Deleted pre-existing layer at %s", collection.name)
- ograpi.OGR_DS_DeleteLayer(self.cogr_ds, idx)
+ ogrext1.OGR_DS_DeleteLayer(self.cogr_ds, idx)
# Create the named layer in the datasource.
name_b = collection.name.encode('utf-8')
name_c = name_b
- self.cogr_layer = ograpi.OGR_DS_CreateLayer(
+ self.cogr_layer = ogrext1.OGR_DS_CreateLayer(
self.cogr_ds,
name_c,
cogr_srs,
@@ -872,9 +872,9 @@ cdef class WritingSession(Session):
)
if cogr_srs != NULL:
- ograpi.OSRDestroySpatialReference(cogr_srs)
+ ogrext1.OSRDestroySpatialReference(cogr_srs)
if options != NULL:
- ograpi.CSLDestroy(options)
+ ogrext1.CSLDestroy(options)
if self.cogr_layer == NULL:
raise ValueError("Null layer")
@@ -901,17 +901,17 @@ cdef class WritingSession(Session):
encoding = self.get_internalencoding()
key_bytes = key.encode(encoding)
- cogr_fielddefn = ograpi.OGR_Fld_Create(
+ cogr_fielddefn = ogrext1.OGR_Fld_Create(
key_bytes,
FIELD_TYPES.index(value) )
if cogr_fielddefn == NULL:
raise ValueError("Null field definition")
if width:
- ograpi.OGR_Fld_SetWidth(cogr_fielddefn, width)
+ ogrext1.OGR_Fld_SetWidth(cogr_fielddefn, width)
if precision:
- ograpi.OGR_Fld_SetPrecision(cogr_fielddefn, precision)
- ograpi.OGR_L_CreateField(self.cogr_layer, cogr_fielddefn, 1)
- ograpi.OGR_Fld_Destroy(cogr_fielddefn)
+ ogrext1.OGR_Fld_SetPrecision(cogr_fielddefn, precision)
+ ogrext1.OGR_L_CreateField(self.cogr_layer, cogr_fielddefn, 1)
+ ogrext1.OGR_Fld_Destroy(cogr_fielddefn)
log.debug("Created fields")
# Mapping of the Python collection schema to the munged
@@ -933,11 +933,11 @@ cdef class WritingSession(Session):
raise ValueError("Null layer")
schema_geom_type = collection.schema['geometry']
- cogr_driver = ograpi.OGR_DS_GetDriver(self.cogr_ds)
- if ograpi.OGR_Dr_GetName(cogr_driver) == b"GeoJSON":
+ cogr_driver = ogrext1.OGR_DS_GetDriver(self.cogr_ds)
+ if ogrext1.OGR_Dr_GetName(cogr_driver) == b"GeoJSON":
def validate_geometry_type(rec):
return True
- elif ograpi.OGR_Dr_GetName(cogr_driver) == b"ESRI Shapefile" \
+ elif ogrext1.OGR_Dr_GetName(cogr_driver) == b"ESRI Shapefile" \
and "Point" not in collection.schema['geometry']:
schema_geom_type = collection.schema['geometry'].lstrip(
"3D ").lstrip("Multi")
@@ -968,7 +968,7 @@ cdef class WritingSession(Session):
collection.schema['geometry'] ))
cogr_feature = OGRFeatureBuilder().build(record, collection)
- result = ograpi.OGR_L_CreateFeature(cogr_layer, cogr_feature)
+ result = ogrext1.OGR_L_CreateFeature(cogr_layer, cogr_feature)
if result != OGRERR_NONE:
raise RuntimeError("Failed to write record: %s" % record)
_deleteOgrFeature(cogr_feature)
@@ -980,7 +980,7 @@ cdef class WritingSession(Session):
if cogr_ds == NULL:
raise ValueError("Null data source")
log.debug("Syncing OGR to disk")
- retval = ograpi.OGR_DS_SyncToDisk(cogr_ds)
+ retval = ogrext1.OGR_DS_SyncToDisk(cogr_ds)
if retval != OGRERR_NONE:
raise RuntimeError("Failed to sync to disk")
@@ -1000,8 +1000,8 @@ cdef class Iterator:
cdef fastindex
cdef stepsign
- def __init__(self, collection,
- start=None, stop=None, step=None, bbox=None, mask=None):
+ def __cinit__(self, collection, start=None, stop=None, step=None,
+ bbox=None, mask=None):
if collection.session is None:
raise ValueError("I/O operation on closed collection")
self.collection = collection
@@ -1011,28 +1011,28 @@ cdef class Iterator:
cdef void *cogr_layer = session.cogr_layer
if cogr_layer == NULL:
raise ValueError("Null layer")
- ograpi.OGR_L_ResetReading(cogr_layer)
+ ogrext1.OGR_L_ResetReading(cogr_layer)
if bbox and mask:
raise ValueError("mask and bbox can not be set together")
if bbox:
- ograpi.OGR_L_SetSpatialFilterRect(
+ ogrext1.OGR_L_SetSpatialFilterRect(
cogr_layer, bbox[0], bbox[1], bbox[2], bbox[3])
elif mask:
cogr_geometry = OGRGeomBuilder().build(mask)
- ograpi.OGR_L_SetSpatialFilter(cogr_layer, cogr_geometry)
- ograpi.OGR_G_DestroyGeometry(cogr_geometry)
+ ogrext1.OGR_L_SetSpatialFilter(cogr_layer, cogr_geometry)
+ ogrext1.OGR_G_DestroyGeometry(cogr_geometry)
else:
- ograpi.OGR_L_SetSpatialFilter(
+ ogrext1.OGR_L_SetSpatialFilter(
cogr_layer, NULL)
self.encoding = session.get_internalencoding()
- self.fastindex = ograpi.OGR_L_TestCapability(
+ self.fastindex = ogrext1.OGR_L_TestCapability(
session.cogr_layer, OLC_FASTSETNEXTBYINDEX)
- ftcount = ograpi.OGR_L_GetFeatureCount(session.cogr_layer, 0)
+ ftcount = ogrext1.OGR_L_GetFeatureCount(session.cogr_layer, 0)
if ftcount == -1 and ((start is not None and start < 0) or
(stop is not None and stop < 0)):
raise IndexError(
@@ -1062,7 +1062,7 @@ cdef class Iterator:
self.next_index = start
log.debug("Index: %d", self.next_index)
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext1.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
def __iter__(self):
@@ -1089,22 +1089,22 @@ cdef class Iterator:
# Set read cursor to next_item position
if self.step > 1 and self.fastindex:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext1.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
elif self.step > 1 and not self.fastindex and not self.next_index == self.start:
for _ in range(self.step - 1):
# TODO rbuffat add test -> OGR_L_GetNextFeature increments cursor by 1, therefore self.step - 1 as one increment was performed when feature is read
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext1.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
elif self.step > 1 and not self.fastindex and self.next_index == self.start:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext1.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
elif self.step == 0:
- # ograpi.OGR_L_GetNextFeature increments read cursor by one
+ # ogrext1.OGR_L_GetNextFeature increments read cursor by one
pass
elif self.step < 0:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext1.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
# set the next index
self.next_index += self.step
@@ -1119,7 +1119,7 @@ cdef class Iterator:
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext1.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
@@ -1146,12 +1146,12 @@ cdef class ItemsIterator(Iterator):
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext1.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
- fid = ograpi.OGR_F_GetFID(cogr_feature)
+ fid = ogrext1.OGR_F_GetFID(cogr_feature)
feature = FeatureBuilder().build(
cogr_feature,
bbox=False,
@@ -1175,11 +1175,11 @@ cdef class KeysIterator(Iterator):
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext1.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
- fid = ograpi.OGR_F_GetFID(cogr_feature)
+ fid = ogrext1.OGR_F_GetFID(cogr_feature)
_deleteOgrFeature(cogr_feature)
return fid
@@ -1194,14 +1194,14 @@ def _remove(path, driver=None):
if driver is None:
driver = 'ESRI Shapefile'
- cogr_driver = ograpi.OGRGetDriverByName(driver.encode('utf-8'))
+ cogr_driver = ogrext1.OGRGetDriverByName(driver.encode('utf-8'))
if cogr_driver == NULL:
raise ValueError("Null driver")
- if not ograpi.OGR_Dr_TestCapability(cogr_driver, ODrCDeleteDataSource):
+ if not ogrext1.OGR_Dr_TestCapability(cogr_driver, ODrCDeleteDataSource):
raise RuntimeError("Driver does not support dataset removal operation")
- result = ograpi.OGR_Dr_DeleteDataSource(cogr_driver, path.encode('utf-8'))
+ result = ogrext1.OGR_Dr_DeleteDataSource(cogr_driver, path.encode('utf-8'))
if result != OGRERR_NONE:
raise RuntimeError("Failed to remove data source {}".format(path))
@@ -1223,22 +1223,22 @@ def _listlayers(path):
path_b = path
path_c = path_b
with cpl_errs:
- cogr_ds = ograpi.OGROpen(path_c, 0, NULL)
+ cogr_ds = ogrext1.OGROpen(path_c, 0, NULL)
if cogr_ds == NULL:
raise ValueError("No data available at path '%s'" % path)
# Loop over the layers to get their names.
- layer_count = ograpi.OGR_DS_GetLayerCount(cogr_ds)
+ layer_count = ogrext1.OGR_DS_GetLayerCount(cogr_ds)
layer_names = []
for i in range(layer_count):
- cogr_layer = ograpi.OGR_DS_GetLayer(cogr_ds, i)
- name_c = ograpi.OGR_L_GetName(cogr_layer)
+ cogr_layer = ogrext1.OGR_DS_GetLayer(cogr_ds, i)
+ name_c = ogrext1.OGR_L_GetName(cogr_layer)
name_b = name_c
layer_names.append(name_b.decode('utf-8'))
# Close up data source.
if cogr_ds is not NULL:
- ograpi.OGR_DS_Destroy(cogr_ds)
+ ogrext1.OGR_DS_Destroy(cogr_ds)
cogr_ds = NULL
return layer_names
@@ -1249,16 +1249,16 @@ def buffer_to_virtual_file(bytesbuf):
vsi_filename = os.path.join('/vsimem', uuid.uuid4().hex)
vsi_cfilename = vsi_filename if not isinstance(vsi_filename, string_types) else vsi_filename.encode('utf-8')
- vsi_handle = ograpi.VSIFileFromMemBuffer(vsi_cfilename, bytesbuf, len(bytesbuf), 0)
+ vsi_handle = ogrext1.VSIFileFromMemBuffer(vsi_cfilename, bytesbuf, len(bytesbuf), 0)
if vsi_handle == NULL:
raise OSError('failed to map buffer to file')
- if ograpi.VSIFCloseL(vsi_handle) != 0:
+ if ogrext1.VSIFCloseL(vsi_handle) != 0:
raise OSError('failed to close mapped file handle')
return vsi_filename
def remove_virtual_file(vsi_filename):
vsi_cfilename = vsi_filename if not isinstance(vsi_filename, string_types) else vsi_filename.encode('utf-8')
- return ograpi.VSIUnlink(vsi_cfilename)
+ return ogrext1.VSIUnlink(vsi_cfilename)
diff --git a/fiona/ograpi2.pxd b/fiona/ogrext2.pxd
similarity index 100%
rename from fiona/ograpi2.pxd
rename to fiona/ogrext2.pxd
diff --git a/fiona/ogrext2.pyx b/fiona/ogrext2.pyx
index 9172bb9..3eecd31 100644
--- a/fiona/ogrext2.pyx
+++ b/fiona/ogrext2.pyx
@@ -12,8 +12,8 @@ import uuid
from six import integer_types, string_types, text_type
-from fiona cimport ograpi
-from fiona._geometry cimport GeomBuilder, OGRGeomBuilder
+cimport ogrext2
+from _geometry cimport GeomBuilder, OGRGeomBuilder
from fiona._err import cpl_errs
from fiona._geometry import GEOMETRY_TYPES
from fiona.errors import DriverError, SchemaError, CRSError, FionaValueError
@@ -138,11 +138,11 @@ def calc_gdal_version_num(maj, min, rev):
def get_gdal_version_num():
"""Return current internal version number of gdal"""
- return int(ograpi.GDALVersionInfo("VERSION_NUM"))
+ return int(ogrext2.GDALVersionInfo("VERSION_NUM"))
def get_gdal_release_name():
"""Return release name of gdal"""
- return ograpi.GDALVersionInfo("RELEASE_NAME")
+ return ogrext2.GDALVersionInfo("RELEASE_NAME")
# Feature extension classes and functions follow.
@@ -168,35 +168,35 @@ cdef class FeatureBuilder:
cdef int retval
cdef char *key_c
props = OrderedDict()
- for i in range(ograpi.OGR_F_GetFieldCount(feature)):
- fdefn = ograpi.OGR_F_GetFieldDefnRef(feature, i)
+ for i in range(ogrext2.OGR_F_GetFieldCount(feature)):
+ fdefn = ogrext2.OGR_F_GetFieldDefnRef(feature, i)
if fdefn == NULL:
raise ValueError("Null feature definition")
- key_c = ograpi.OGR_Fld_GetNameRef(fdefn)
+ key_c = ogrext2.OGR_Fld_GetNameRef(fdefn)
if key_c == NULL:
raise ValueError("Null field name reference")
key_b = key_c
key = key_b.decode(encoding)
- fieldtypename = FIELD_TYPES[ograpi.OGR_Fld_GetType(fdefn)]
+ fieldtypename = FIELD_TYPES[ogrext2.OGR_Fld_GetType(fdefn)]
if not fieldtypename:
log.warn(
"Skipping field %s: invalid type %s",
key,
- ograpi.OGR_Fld_GetType(fdefn))
+ ogrext2.OGR_Fld_GetType(fdefn))
continue
# TODO: other types
fieldtype = FIELD_TYPES_MAP[fieldtypename]
- if not ograpi.OGR_F_IsFieldSet(feature, i):
+ if not ogrext2.OGR_F_IsFieldSet(feature, i):
props[key] = None
elif fieldtype is int:
- props[key] = ograpi.OGR_F_GetFieldAsInteger64(feature, i)
+ props[key] = ogrext2.OGR_F_GetFieldAsInteger64(feature, i)
elif fieldtype is float:
- props[key] = ograpi.OGR_F_GetFieldAsDouble(feature, i)
+ props[key] = ogrext2.OGR_F_GetFieldAsDouble(feature, i)
elif fieldtype is text_type:
try:
- val = ograpi.OGR_F_GetFieldAsString(feature, i)
+ val = ogrext2.OGR_F_GetFieldAsString(feature, i)
val = val.decode(encoding)
except UnicodeDecodeError:
log.warn(
@@ -214,7 +214,7 @@ cdef class FeatureBuilder:
props[key] = val
elif fieldtype in (FionaDateType, FionaTimeType, FionaDateTimeType):
- retval = ograpi.OGR_F_GetFieldAsDateTime(
+ retval = ogrext2.OGR_F_GetFieldAsDateTime(
feature, i, &y, &m, &d, &hh, &mm, &ss, &tz)
if fieldtype is FionaDateType:
props[key] = datetime.date(y, m, d).isoformat()
@@ -227,14 +227,14 @@ cdef class FeatureBuilder:
log.debug("%s: None, fieldtype: %r, %r" % (key, fieldtype, fieldtype in string_types))
props[key] = None
- cdef void *cogr_geometry = ograpi.OGR_F_GetGeometryRef(feature)
+ cdef void *cogr_geometry = ogrext2.OGR_F_GetGeometryRef(feature)
if cogr_geometry is not NULL:
geom = GeomBuilder().build(cogr_geometry)
else:
geom = None
return {
'type': 'Feature',
- 'id': str(ograpi.OGR_F_GetFID(feature)),
+ 'id': str(ogrext2.OGR_F_GetFID(feature)),
'geometry': geom,
'properties': props }
@@ -255,17 +255,17 @@ cdef class OGRFeatureBuilder:
cdef void *cogr_layer = session.cogr_layer
if cogr_layer == NULL:
raise ValueError("Null layer")
- cdef void *cogr_featuredefn = ograpi.OGR_L_GetLayerDefn(cogr_layer)
+ cdef void *cogr_featuredefn = ogrext2.OGR_L_GetLayerDefn(cogr_layer)
if cogr_featuredefn == NULL:
raise ValueError("Null feature definition")
- cdef void *cogr_feature = ograpi.OGR_F_Create(cogr_featuredefn)
+ cdef void *cogr_feature = ogrext2.OGR_F_Create(cogr_featuredefn)
if cogr_feature == NULL:
raise ValueError("Null feature")
if feature['geometry'] is not None:
cogr_geometry = OGRGeomBuilder().build(
feature['geometry'])
- ograpi.OGR_F_SetGeometryDirectly(cogr_feature, cogr_geometry)
+ ogrext2.OGR_F_SetGeometryDirectly(cogr_feature, cogr_geometry)
# OGR_F_SetFieldString takes UTF-8 encoded strings ('bytes' in
# Python 3).
@@ -282,7 +282,7 @@ cdef class OGRFeatureBuilder:
log.warn("Failed to encode %s using %s codec", key, encoding)
key_bytes = ogr_key
key_c = key_bytes
- i = ograpi.OGR_F_GetFieldIndex(cogr_feature, key_c)
+ i = ogrext2.OGR_F_GetFieldIndex(cogr_feature, key_c)
if i < 0:
continue
@@ -292,9 +292,9 @@ cdef class OGRFeatureBuilder:
# Continue over the standard OGR types.
if isinstance(value, integer_types):
- ograpi.OGR_F_SetFieldInteger64(cogr_feature, i, value)
+ ogrext2.OGR_F_SetFieldInteger64(cogr_feature, i, value)
elif isinstance(value, float):
- ograpi.OGR_F_SetFieldDouble(cogr_feature, i, value)
+ ogrext2.OGR_F_SetFieldDouble(cogr_feature, i, value)
elif (isinstance(value, string_types)
and schema_type in ['date', 'time', 'datetime']):
if schema_type == 'date':
@@ -303,23 +303,23 @@ cdef class OGRFeatureBuilder:
y, m, d, hh, mm, ss, ff = parse_time(value)
else:
y, m, d, hh, mm, ss, ff = parse_datetime(value)
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext2.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, hh, mm, ss, 0)
elif (isinstance(value, datetime.date)
and schema_type == 'date'):
y, m, d = value.year, value.month, value.day
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext2.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, 0, 0, 0, 0)
elif (isinstance(value, datetime.datetime)
and schema_type == 'datetime'):
y, m, d = value.year, value.month, value.day
hh, mm, ss = value.hour, value.minute, value.second
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext2.OGR_F_SetFieldDateTime(
cogr_feature, i, y, m, d, hh, mm, ss, 0)
elif (isinstance(value, datetime.time)
and schema_type == 'time'):
hh, mm, ss = value.hour, value.minute, value.second
- ograpi.OGR_F_SetFieldDateTime(
+ ogrext2.OGR_F_SetFieldDateTime(
cogr_feature, i, 0, 0, 0, hh, mm, ss, 0)
elif isinstance(value, string_types):
try:
@@ -329,7 +329,7 @@ cdef class OGRFeatureBuilder:
"Failed to encode %s using %s codec", value, encoding)
value_bytes = value
string_c = value_bytes
- ograpi.OGR_F_SetFieldString(cogr_feature, i, string_c)
+ ogrext2.OGR_F_SetFieldString(cogr_feature, i, string_c)
elif value is None:
pass # keep field unset/null
else:
@@ -341,17 +341,17 @@ cdef class OGRFeatureBuilder:
cdef _deleteOgrFeature(void *cogr_feature):
"""Delete an OGR feature"""
if cogr_feature is not NULL:
- ograpi.OGR_F_Destroy(cogr_feature)
+ ogrext2.OGR_F_Destroy(cogr_feature)
cogr_feature = NULL
def featureRT(feature, collection):
# For testing purposes only, leaks the JSON data
cdef void *cogr_feature = OGRFeatureBuilder().build(feature, collection)
- cdef void *cogr_geometry = ograpi.OGR_F_GetGeometryRef(cogr_feature)
+ cdef void *cogr_geometry = ogrext2.OGR_F_GetGeometryRef(cogr_feature)
if cogr_geometry == NULL:
raise ValueError("Null geometry")
- log.debug("Geometry: %s" % ograpi.OGR_G_ExportToJson(cogr_geometry))
+ log.debug("Geometry: %s" % ogrext2.OGR_G_ExportToJson(cogr_geometry))
encoding = collection.encoding or 'utf-8'
result = FeatureBuilder().build(
cogr_feature,
@@ -373,7 +373,7 @@ cdef class Session:
cdef object _encoding
cdef object collection
- def __cinit__(self):
+ def __init__(self):
self.cogr_ds = NULL
self.cogr_layer = NULL
self._fileencoding = None
@@ -410,13 +410,13 @@ cdef class Session:
name_b = name.encode()
name_c = name_b
log.debug("Trying driver: %s", name)
- drv = ograpi.GDALGetDriverByName(name_c)
+ drv = ogrext2.GDALGetDriverByName(name_c)
if drv != NULL:
drvs = string_list([name_b])
- flags = ograpi.GDAL_OF_VECTOR | ograpi.GDAL_OF_READONLY
+ flags = ogrext2.GDAL_OF_VECTOR | ogrext2.GDAL_OF_READONLY
log.debug("GDALOpenEx({}, {}, {})".format(path_c, flags, [name_b]))
- ds = ograpi.GDALOpenEx(path_c,
+ ds = ogrext2.GDALOpenEx(path_c,
flags,
drvs,
NULL,
@@ -425,14 +425,14 @@ cdef class Session:
if ds != NULL:
self.cogr_ds = ds
collection._driver = name
- _driver = ograpi.GDALGetDatasetDriver(ds)
- drv_name = ograpi.GDALGetDriverShortName(_driver)
+ _driver = ogrext2.GDALGetDatasetDriver(ds)
+ drv_name = ogrext2.GDALGetDriverShortName(_driver)
log.debug("Driver: {} Success".format(drv_name))
break
else:
- self.cogr_ds = ograpi.GDALOpenEx(path_c,
- ograpi.GDAL_OF_VECTOR | ograpi.GDAL_OF_READONLY,
+ self.cogr_ds = ogrext2.GDALOpenEx(path_c,
+ ogrext2.GDAL_OF_VECTOR | ogrext2.GDAL_OF_READONLY,
NULL,
NULL,
NULL)
@@ -446,12 +446,12 @@ cdef class Session:
if isinstance(collection.name, string_types):
name_b = collection.name.encode('utf-8')
name_c = name_b
- self.cogr_layer = ograpi.GDALDatasetGetLayerByName(
+ self.cogr_layer = ogrext2.GDALDatasetGetLayerByName(
self.cogr_ds, name_c)
elif isinstance(collection.name, int):
- self.cogr_layer = ograpi.GDALDatasetGetLayer(
+ self.cogr_layer = ogrext2.GDALDatasetGetLayer(
self.cogr_ds, collection.name)
- name_c = ograpi.OGR_L_GetName(self.cogr_layer)
+ name_c = ogrext2.OGR_L_GetName(self.cogr_layer)
name_b = name_c
collection.name = name_b.decode('utf-8')
@@ -462,11 +462,11 @@ cdef class Session:
userencoding = self.collection.encoding
if userencoding:
- ograpi.CPLSetThreadLocalConfigOption('SHAPE_ENCODING', '')
+ ogrext2.CPLSetThreadLocalConfigOption('SHAPE_ENCODING', '')
self._fileencoding = userencoding.upper()
else:
self._fileencoding = (
- ograpi.OGR_L_TestCapability(
+ ogrext2.OGR_L_TestCapability(
self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or (
self.get_driver() == "ESRI Shapefile" and
@@ -475,7 +475,7 @@ cdef class Session:
def stop(self):
self.cogr_layer = NULL
if self.cogr_ds is not NULL:
- ograpi.GDALClose(self.cogr_ds)
+ ogrext2.GDALClose(self.cogr_ds)
self.cogr_ds = NULL
def get_fileencoding(self):
@@ -485,7 +485,7 @@ cdef class Session:
if not self._encoding:
fileencoding = self.get_fileencoding()
self._encoding = (
- ograpi.OGR_L_TestCapability(
+ ogrext2.OGR_L_TestCapability(
self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or fileencoding
return self._encoding
@@ -493,13 +493,13 @@ cdef class Session:
def get_length(self):
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- return ograpi.OGR_L_GetFeatureCount(self.cogr_layer, 0)
+ return ogrext2.OGR_L_GetFeatureCount(self.cogr_layer, 0)
def get_driver(self):
- cdef void *cogr_driver = ograpi.GDALGetDatasetDriver(self.cogr_ds)
+ cdef void *cogr_driver = ogrext2.GDALGetDatasetDriver(self.cogr_ds)
if cogr_driver == NULL:
raise ValueError("Null driver")
- cdef char *name = ograpi.OGR_Dr_GetName(cogr_driver)
+ cdef char *name = ogrext2.OGR_Dr_GetName(cogr_driver)
driver_name = name
return driver_name.decode()
@@ -514,52 +514,52 @@ cdef class Session:
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_featuredefn = ograpi.OGR_L_GetLayerDefn(self.cogr_layer)
+ cogr_featuredefn = ogrext2.OGR_L_GetLayerDefn(self.cogr_layer)
if cogr_featuredefn == NULL:
raise ValueError("Null feature definition")
- n = ograpi.OGR_FD_GetFieldCount(cogr_featuredefn)
+ n = ogrext2.OGR_FD_GetFieldCount(cogr_featuredefn)
for i from 0 <= i < n:
- cogr_fielddefn = ograpi.OGR_FD_GetFieldDefn(cogr_featuredefn, i)
+ cogr_fielddefn = ogrext2.OGR_FD_GetFieldDefn(cogr_featuredefn, i)
if cogr_fielddefn == NULL:
raise ValueError("Null field definition")
- key_c = ograpi.OGR_Fld_GetNameRef(cogr_fielddefn)
+ key_c = ogrext2.OGR_Fld_GetNameRef(cogr_fielddefn)
key_b = key_c
if not bool(key_b):
raise ValueError("Invalid field name ref: %s" % key)
key = key_b.decode(self.get_internalencoding())
- fieldtypename = FIELD_TYPES[ograpi.OGR_Fld_GetType(cogr_fielddefn)]
+ fieldtypename = FIELD_TYPES[ogrext2.OGR_Fld_GetType(cogr_fielddefn)]
if not fieldtypename:
log.warn(
"Skipping field %s: invalid type %s",
key,
- ograpi.OGR_Fld_GetType(cogr_fielddefn))
+ ogrext2.OGR_Fld_GetType(cogr_fielddefn))
continue
val = fieldtypename
if fieldtypename == 'float':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext2.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 24:
fmt = ":%d" % width
- precision = ograpi.OGR_Fld_GetPrecision(cogr_fielddefn)
+ precision = ogrext2.OGR_Fld_GetPrecision(cogr_fielddefn)
if precision: # and precision != 15:
fmt += ".%d" % precision
val = "float" + fmt
elif fieldtypename == 'int':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext2.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 11:
fmt = ":%d" % width
val = fieldtypename + fmt
elif fieldtypename == 'str':
fmt = ""
- width = ograpi.OGR_Fld_GetWidth(cogr_fielddefn)
+ width = ogrext2.OGR_Fld_GetWidth(cogr_fielddefn)
if width: # and width != 80:
fmt = ":%d" % width
val = fieldtypename + fmt
props.append((key, val))
- cdef unsigned int geom_type = ograpi.OGR_FD_GetGeomType(
+ cdef unsigned int geom_type = ogrext2.OGR_FD_GetGeomType(
cogr_featuredefn)
return {
'properties': OrderedDict(props),
@@ -572,17 +572,17 @@ cdef class Session:
cdef void *cogr_crs = NULL
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_crs = ograpi.OGR_L_GetSpatialRef(self.cogr_layer)
+ cogr_crs = ogrext2.OGR_L_GetSpatialRef(self.cogr_layer)
crs = {}
if cogr_crs is not NULL:
log.debug("Got coordinate system")
- retval = ograpi.OSRAutoIdentifyEPSG(cogr_crs)
+ retval = ogrext2.OSRAutoIdentifyEPSG(cogr_crs)
if retval > 0:
log.info("Failed to auto identify EPSG: %d", retval)
- auth_key = ograpi.OSRGetAuthorityName(cogr_crs, NULL)
- auth_val = ograpi.OSRGetAuthorityCode(cogr_crs, NULL)
+ auth_key = ogrext2.OSRGetAuthorityName(cogr_crs, NULL)
+ auth_val = ogrext2.OSRGetAuthorityCode(cogr_crs, NULL)
if auth_key != NULL and auth_val != NULL:
key_b = auth_key
@@ -592,7 +592,7 @@ cdef class Session:
val = val_b.decode('utf-8')
crs['init'] = "epsg:" + val
else:
- ograpi.OSRExportToProj4(cogr_crs, &proj_c)
+ ogrext2.OSRExportToProj4(cogr_crs, &proj_c)
if proj_c == NULL:
raise ValueError("Null projection")
proj_b = proj_c
@@ -617,7 +617,7 @@ cdef class Session:
k = k.lstrip("+")
crs[k] = v
- ograpi.CPLFree(proj_c)
+ ogrext2.CPLFree(proj_c)
else:
log.debug("Projection not found (cogr_crs was NULL)")
return crs
@@ -626,16 +626,16 @@ cdef class Session:
cdef char *proj_c = NULL
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cogr_crs = ograpi.OGR_L_GetSpatialRef(self.cogr_layer)
+ cogr_crs = ogrext2.OGR_L_GetSpatialRef(self.cogr_layer)
crs_wkt = ""
if cogr_crs is not NULL:
log.debug("Got coordinate system")
- ograpi.OSRExportToWkt(cogr_crs, &proj_c)
+ ogrext2.OSRExportToWkt(cogr_crs, &proj_c)
if proj_c == NULL:
raise ValueError("Null projection")
proj_b = proj_c
crs_wkt = proj_b.decode('utf-8')
- ograpi.CPLFree(proj_c)
+ ogrext2.CPLFree(proj_c)
else:
log.debug("Projection not found (cogr_crs was NULL)")
return crs_wkt
@@ -643,8 +643,8 @@ cdef class Session:
def get_extent(self):
if self.cogr_layer == NULL:
raise ValueError("Null layer")
- cdef ograpi.OGREnvelope extent
- result = ograpi.OGR_L_GetExtent(self.cogr_layer, &extent, 1)
+ cdef ogrext2.OGREnvelope extent
+ result = ogrext2.OGR_L_GetExtent(self.cogr_layer, &extent, 1)
return (extent.MinX, extent.MinY, extent.MaxX, extent.MaxY)
def has_feature(self, fid):
@@ -654,7 +654,7 @@ cdef class Session:
"""
cdef void * cogr_feature
fid = int(fid)
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, fid)
+ cogr_feature = ogrext2.OGR_L_GetFeature(self.cogr_layer, fid)
if cogr_feature != NULL:
_deleteOgrFeature(cogr_feature)
return True
@@ -668,7 +668,7 @@ cdef class Session:
"""
cdef void * cogr_feature
fid = int(fid)
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, fid)
+ cogr_feature = ogrext2.OGR_L_GetFeature(self.cogr_layer, fid)
if cogr_feature != NULL:
_deleteOgrFeature(cogr_feature)
return True
@@ -686,12 +686,12 @@ cdef class Session:
index = item
# from the back
if index < 0:
- ftcount = ograpi.OGR_L_GetFeatureCount(self.cogr_layer, 0)
+ ftcount = ogrext2.OGR_L_GetFeatureCount(self.cogr_layer, 0)
if ftcount == -1:
raise IndexError(
"collection's dataset does not support negative indexes")
index += ftcount
- cogr_feature = ograpi.OGR_L_GetFeature(self.cogr_layer, index)
+ cogr_feature = ogrext2.OGR_L_GetFeature(self.cogr_layer, index)
if cogr_feature == NULL:
return None
feature = FeatureBuilder().build(
@@ -738,25 +738,25 @@ cdef class WritingSession(Session):
path_b = path
path_c = path_b
with cpl_errs:
- self.cogr_ds = ograpi.GDALOpenEx(path_c,
- ograpi.GDAL_OF_VECTOR | ograpi.GDAL_OF_UPDATE,
+ self.cogr_ds = ogrext2.GDALOpenEx(path_c,
+ ogrext2.GDAL_OF_VECTOR | ogrext2.GDAL_OF_UPDATE,
NULL,
NULL,
NULL)
-# self.cogr_ds = ograpi.OGROpen(path_c, 1, NULL)
+# self.cogr_ds = ogrext2.OGROpen(path_c, 1, NULL)
if self.cogr_ds == NULL:
raise RuntimeError("Failed to open %s" % path)
- cogr_driver = ograpi.GDALGetDatasetDriver(self.cogr_ds)
+ cogr_driver = ogrext2.GDALGetDatasetDriver(self.cogr_ds)
if cogr_driver == NULL:
raise ValueError("Null driver")
if isinstance(collection.name, string_types):
name_b = collection.name.encode()
name_c = name_b
- self.cogr_layer = ograpi.GDALDatasetGetLayerByName(
+ self.cogr_layer = ogrext2.GDALDatasetGetLayerByName(
self.cogr_ds, name_c)
elif isinstance(collection.name, int):
- self.cogr_layer = ograpi.GDALDatasetGetLayer(
+ self.cogr_layer = ogrext2.GDALDatasetGetLayer(
self.cogr_ds, collection.name)
if self.cogr_layer == NULL:
@@ -767,7 +767,7 @@ cdef class WritingSession(Session):
userencoding = self.collection.encoding
self._fileencoding = (userencoding or (
- ograpi.OGR_L_TestCapability(self.cogr_layer, OLC_STRINGSASUTF8) and
+ ogrext2.OGR_L_TestCapability(self.cogr_layer, OLC_STRINGSASUTF8) and
'utf-8') or (
self.get_driver() == "ESRI Shapefile" and
'ISO-8859-1') or locale.getpreferredencoding()).upper()
@@ -781,56 +781,56 @@ cdef class WritingSession(Session):
driver_b = collection.driver.encode()
driver_c = driver_b
- cogr_driver = ograpi.GDALGetDriverByName(driver_c)
+ cogr_driver = ogrext2.GDALGetDriverByName(driver_c)
if cogr_driver == NULL:
raise ValueError("Null driver")
if not os.path.exists(path):
-# cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+# cogr_ds = ogrext2.OGR_Dr_CreateDataSource(
# cogr_driver, path_c, NULL)
- cogr_ds = ograpi.GDALCreate(
+ cogr_ds = ogrext2.GDALCreate(
cogr_driver,
path_c,
0,
0,
0,
- ograpi.GDT_Unknown,
+ ogrext2.GDT_Unknown,
NULL)
pass
else:
with cpl_errs:
- cogr_ds = ograpi.GDALOpenEx(path_c,
- ograpi.GDAL_OF_VECTOR | ograpi.GDAL_OF_UPDATE,
+ cogr_ds = ogrext2.GDALOpenEx(path_c,
+ ogrext2.GDAL_OF_VECTOR | ogrext2.GDAL_OF_UPDATE,
NULL,
NULL,
NULL)
-# cogr_ds = ograpi.OGROpen(path_c, 1, NULL)
+# cogr_ds = ogrext2.OGROpen(path_c, 1, NULL)
if cogr_ds == NULL:
- cogr_ds = ograpi.GDALCreate(
+ cogr_ds = ogrext2.GDALCreate(
cogr_driver,
path_c,
0,
0,
0,
- ograpi.GDT_Unknown,
+ ogrext2.GDT_Unknown,
NULL)
-# cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+# cogr_ds = ogrext2.OGR_Dr_CreateDataSource(
# cogr_driver, path_c, NULL)
elif collection.name is None:
- ograpi.GDALClose(cogr_ds)
+ ogrext2.GDALClose(cogr_ds)
cogr_ds == NULL
log.debug("Deleted pre-existing data at %s", path)
- cogr_ds = ograpi.GDALCreate(
+ cogr_ds = ogrext2.GDALCreate(
cogr_driver,
path_c,
0,
0,
0,
- ograpi.GDT_Unknown,
+ ogrext2.GDT_Unknown,
NULL)
-# cogr_ds = ograpi.OGR_Dr_CreateDataSource(
+# cogr_ds = ogrext2.OGR_Dr_CreateDataSource(
# cogr_driver, path_c, NULL)
else:
@@ -847,14 +847,14 @@ cdef class WritingSession(Session):
# is constructed (later).
col_crs = collection._crs_wkt or collection._crs
if col_crs:
- cogr_srs = ograpi.OSRNewSpatialReference(NULL)
+ cogr_srs = ogrext2.OSRNewSpatialReference(NULL)
if cogr_srs == NULL:
raise ValueError("NULL spatial reference")
# First, check for CRS strings like "EPSG:3857".
if isinstance(col_crs, string_types):
proj_b = col_crs.encode('utf-8')
proj_c = proj_b
- ograpi.OSRSetFromUserInput(cogr_srs, proj_c)
+ ogrext2.OSRSetFromUserInput(cogr_srs, proj_c)
elif isinstance(col_crs, dict):
# EPSG is a special case.
init = col_crs.get('init')
@@ -863,7 +863,7 @@ cdef class WritingSession(Session):
auth, val = init.split(':')
if auth.upper() == 'EPSG':
log.debug("Setting EPSG: %s", val)
- ograpi.OSRImportFromEPSG(cogr_srs, int(val))
+ ogrext2.OSRImportFromEPSG(cogr_srs, int(val))
else:
params = []
col_crs['wktext'] = True
@@ -876,12 +876,12 @@ cdef class WritingSession(Session):
log.debug("PROJ.4 to be imported: %r", proj)
proj_b = proj.encode('utf-8')
proj_c = proj_b
- ograpi.OSRImportFromProj4(cogr_srs, proj_c)
+ ogrext2.OSRImportFromProj4(cogr_srs, proj_c)
else:
raise ValueError("Invalid CRS")
# Fixup, export to WKT, and set the GDAL dataset's projection.
- ograpi.OSRFixup(cogr_srs)
+ ogrext2.OSRFixup(cogr_srs)
# Figure out what encoding to use. The encoding parameter given
# to the collection constructor takes highest precedence, then
@@ -896,14 +896,14 @@ cdef class WritingSession(Session):
if fileencoding:
fileencoding_b = fileencoding.encode()
fileencoding_c = fileencoding_b
- options = ograpi.CSLSetNameValue(options, "ENCODING", fileencoding_c)
+ options = ogrext2.CSLSetNameValue(options, "ENCODING", fileencoding_c)
# Does the layer exist already? If so, we delete it.
- layer_count = ograpi.GDALDatasetGetLayerCount(self.cogr_ds)
+ layer_count = ogrext2.GDALDatasetGetLayerCount(self.cogr_ds)
layer_names = []
for i in range(layer_count):
- cogr_layer = ograpi.GDALDatasetGetLayer(cogr_ds, i)
- name_c = ograpi.OGR_L_GetName(cogr_layer)
+ cogr_layer = ogrext2.GDALDatasetGetLayer(cogr_ds, i)
+ name_c = ogrext2.OGR_L_GetName(cogr_layer)
name_b = name_c
layer_names.append(name_b.decode('utf-8'))
@@ -916,12 +916,12 @@ cdef class WritingSession(Session):
idx = collection.name
if idx >= 0:
log.debug("Deleted pre-existing layer at %s", collection.name)
- ograpi.GDALDatasetDeleteLayer(self.cogr_ds, idx)
+ ogrext2.GDALDatasetDeleteLayer(self.cogr_ds, idx)
# Create the named layer in the datasource.
name_b = collection.name.encode('utf-8')
name_c = name_b
- self.cogr_layer = ograpi.GDALDatasetCreateLayer(
+ self.cogr_layer = ogrext2.GDALDatasetCreateLayer(
self.cogr_ds,
name_c,
cogr_srs,
@@ -931,9 +931,9 @@ cdef class WritingSession(Session):
)
if cogr_srs != NULL:
- ograpi.OSRDestroySpatialReference(cogr_srs)
+ ogrext2.OSRDestroySpatialReference(cogr_srs)
if options != NULL:
- ograpi.CSLDestroy(options)
+ ogrext2.CSLDestroy(options)
if self.cogr_layer == NULL:
raise ValueError("Null layer")
@@ -966,17 +966,17 @@ cdef class WritingSession(Session):
encoding = self.get_internalencoding()
key_bytes = key.encode(encoding)
- cogr_fielddefn = ograpi.OGR_Fld_Create(
+ cogr_fielddefn = ogrext2.OGR_Fld_Create(
key_bytes,
field_type)
if cogr_fielddefn == NULL:
raise ValueError("Null field definition")
if width:
- ograpi.OGR_Fld_SetWidth(cogr_fielddefn, width)
+ ogrext2.OGR_Fld_SetWidth(cogr_fielddefn, width)
if precision:
- ograpi.OGR_Fld_SetPrecision(cogr_fielddefn, precision)
- ograpi.OGR_L_CreateField(self.cogr_layer, cogr_fielddefn, 1)
- ograpi.OGR_Fld_Destroy(cogr_fielddefn)
+ ogrext2.OGR_Fld_SetPrecision(cogr_fielddefn, precision)
+ ogrext2.OGR_L_CreateField(self.cogr_layer, cogr_fielddefn, 1)
+ ogrext2.OGR_Fld_Destroy(cogr_fielddefn)
log.debug("Created fields")
# Mapping of the Python collection schema to the munged
@@ -998,11 +998,11 @@ cdef class WritingSession(Session):
raise ValueError("Null layer")
schema_geom_type = collection.schema['geometry']
- cogr_driver = ograpi.GDALGetDatasetDriver(self.cogr_ds)
- if ograpi.OGR_Dr_GetName(cogr_driver) == b"GeoJSON":
+ cogr_driver = ogrext2.GDALGetDatasetDriver(self.cogr_ds)
+ if ogrext2.OGR_Dr_GetName(cogr_driver) == b"GeoJSON":
def validate_geometry_type(rec):
return True
- elif ograpi.OGR_Dr_GetName(cogr_driver) == b"ESRI Shapefile" \
+ elif ogrext2.OGR_Dr_GetName(cogr_driver) == b"ESRI Shapefile" \
and "Point" not in collection.schema['geometry']:
schema_geom_type = collection.schema['geometry'].lstrip(
"3D ").lstrip("Multi")
@@ -1033,7 +1033,7 @@ cdef class WritingSession(Session):
collection.schema['geometry'] ))
cogr_feature = OGRFeatureBuilder().build(record, collection)
- result = ograpi.OGR_L_CreateFeature(cogr_layer, cogr_feature)
+ result = ogrext2.OGR_L_CreateFeature(cogr_layer, cogr_feature)
if result != OGRERR_NONE:
raise RuntimeError("Failed to write record: %s" % record)
_deleteOgrFeature(cogr_feature)
@@ -1046,7 +1046,7 @@ cdef class WritingSession(Session):
raise ValueError("Null data source")
log.debug("Syncing OGR to disk")
- ograpi.GDALFlushCache(cogr_ds)
+ ogrext2.GDALFlushCache(cogr_ds)
cdef class Iterator:
@@ -1064,8 +1064,8 @@ cdef class Iterator:
cdef fastindex
cdef stepsign
- def __init__(self, collection,
- start=None, stop=None, step=None, bbox=None, mask=None):
+ def __cinit__(self, collection, start=None, stop=None, step=None,
+ bbox=None, mask=None):
if collection.session is None:
raise ValueError("I/O operation on closed collection")
self.collection = collection
@@ -1075,28 +1075,28 @@ cdef class Iterator:
cdef void *cogr_layer = session.cogr_layer
if cogr_layer == NULL:
raise ValueError("Null layer")
- ograpi.OGR_L_ResetReading(cogr_layer)
+ ogrext2.OGR_L_ResetReading(cogr_layer)
if bbox and mask:
raise ValueError("mask and bbox can not be set together")
if bbox:
- ograpi.OGR_L_SetSpatialFilterRect(
+ ogrext2.OGR_L_SetSpatialFilterRect(
cogr_layer, bbox[0], bbox[1], bbox[2], bbox[3])
elif mask:
cogr_geometry = OGRGeomBuilder().build(mask)
- ograpi.OGR_L_SetSpatialFilter(cogr_layer, cogr_geometry)
- ograpi.OGR_G_DestroyGeometry(cogr_geometry)
+ ogrext2.OGR_L_SetSpatialFilter(cogr_layer, cogr_geometry)
+ ogrext2.OGR_G_DestroyGeometry(cogr_geometry)
else:
- ograpi.OGR_L_SetSpatialFilter(
+ ogrext2.OGR_L_SetSpatialFilter(
cogr_layer, NULL)
self.encoding = session.get_internalencoding()
- self.fastindex = ograpi.OGR_L_TestCapability(
+ self.fastindex = ogrext2.OGR_L_TestCapability(
session.cogr_layer, OLC_FASTSETNEXTBYINDEX)
- ftcount = ograpi.OGR_L_GetFeatureCount(session.cogr_layer, 0)
+ ftcount = ogrext2.OGR_L_GetFeatureCount(session.cogr_layer, 0)
if ftcount == -1 and ((start is not None and start < 0) or
(stop is not None and stop < 0)):
raise IndexError(
@@ -1126,7 +1126,7 @@ cdef class Iterator:
self.next_index = start
log.debug("Index: %d", self.next_index)
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext2.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
def __iter__(self):
@@ -1153,22 +1153,22 @@ cdef class Iterator:
# Set read cursor to next_item position
if self.step > 1 and self.fastindex:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext2.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
elif self.step > 1 and not self.fastindex and not self.next_index == self.start:
for _ in range(self.step - 1):
# TODO rbuffat add test -> OGR_L_GetNextFeature increments cursor by 1, therefore self.step - 1 as one increment was performed when feature is read
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext2.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
elif self.step > 1 and not self.fastindex and self.next_index == self.start:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext2.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
elif self.step == 0:
- # ograpi.OGR_L_GetNextFeature increments read cursor by one
+ # ogrext2.OGR_L_GetNextFeature increments read cursor by one
pass
elif self.step < 0:
- ograpi.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
+ ogrext2.OGR_L_SetNextByIndex(session.cogr_layer, self.next_index)
# set the next index
self.next_index += self.step
@@ -1183,7 +1183,7 @@ cdef class Iterator:
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext2.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
@@ -1210,12 +1210,12 @@ cdef class ItemsIterator(Iterator):
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext2.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
- fid = ograpi.OGR_F_GetFID(cogr_feature)
+ fid = ogrext2.OGR_F_GetFID(cogr_feature)
feature = FeatureBuilder().build(
cogr_feature,
bbox=False,
@@ -1239,11 +1239,11 @@ cdef class KeysIterator(Iterator):
self._next()
# Get the next feature.
- cogr_feature = ograpi.OGR_L_GetNextFeature(session.cogr_layer)
+ cogr_feature = ogrext2.OGR_L_GetNextFeature(session.cogr_layer)
if cogr_feature == NULL:
raise StopIteration
- fid = ograpi.OGR_F_GetFID(cogr_feature)
+ fid = ogrext2.OGR_F_GetFID(cogr_feature)
_deleteOgrFeature(cogr_feature)
return fid
@@ -1258,14 +1258,14 @@ def _remove(path, driver=None):
if driver is None:
driver = 'ESRI Shapefile'
- cogr_driver = ograpi.OGRGetDriverByName(driver.encode('utf-8'))
+ cogr_driver = ogrext2.OGRGetDriverByName(driver.encode('utf-8'))
if cogr_driver == NULL:
raise ValueError("Null driver")
- if not ograpi.OGR_Dr_TestCapability(cogr_driver, ODrCDeleteDataSource):
+ if not ogrext2.OGR_Dr_TestCapability(cogr_driver, ODrCDeleteDataSource):
raise RuntimeError("Driver does not support dataset removal operation")
- result = ograpi.GDALDeleteDataset(cogr_driver, path.encode('utf-8'))
+ result = ogrext2.GDALDeleteDataset(cogr_driver, path.encode('utf-8'))
if result != OGRERR_NONE:
raise RuntimeError("Failed to remove data source {}".format(path))
@@ -1287,27 +1287,27 @@ def _listlayers(path):
path_b = path
path_c = path_b
with cpl_errs:
- cogr_ds = ograpi.GDALOpenEx(path_c,
- ograpi.GDAL_OF_VECTOR | ograpi.GDAL_OF_READONLY,
+ cogr_ds = ogrext2.GDALOpenEx(path_c,
+ ogrext2.GDAL_OF_VECTOR | ogrext2.GDAL_OF_READONLY,
NULL,
NULL,
NULL)
-# cogr_ds = ograpi.OGROpen(path_c, 0, NULL)
+# cogr_ds = ogrext2.OGROpen(path_c, 0, NULL)
if cogr_ds == NULL:
raise ValueError("No data available at path '%s'" % path)
# Loop over the layers to get their names.
- layer_count = ograpi.GDALDatasetGetLayerCount(cogr_ds)
+ layer_count = ogrext2.GDALDatasetGetLayerCount(cogr_ds)
layer_names = []
for i in range(layer_count):
- cogr_layer = ograpi.GDALDatasetGetLayer(cogr_ds, i)
- name_c = ograpi.OGR_L_GetName(cogr_layer)
+ cogr_layer = ogrext2.GDALDatasetGetLayer(cogr_ds, i)
+ name_c = ogrext2.OGR_L_GetName(cogr_layer)
name_b = name_c
layer_names.append(name_b.decode('utf-8'))
# Close up data source.
if cogr_ds is not NULL:
- ograpi.GDALClose(cogr_ds)
+ ogrext2.GDALClose(cogr_ds)
cogr_ds = NULL
return layer_names
@@ -1318,16 +1318,16 @@ def buffer_to_virtual_file(bytesbuf):
vsi_filename = os.path.join('/vsimem', uuid.uuid4().hex)
vsi_cfilename = vsi_filename if not isinstance(vsi_filename, string_types) else vsi_filename.encode('utf-8')
- vsi_handle = ograpi.VSIFileFromMemBuffer(vsi_cfilename, bytesbuf, len(bytesbuf), 0)
+ vsi_handle = ogrext2.VSIFileFromMemBuffer(vsi_cfilename, bytesbuf, len(bytesbuf), 0)
if vsi_handle == NULL:
raise OSError('failed to map buffer to file')
- if ograpi.VSIFCloseL(vsi_handle) != 0:
+ if ogrext2.VSIFCloseL(vsi_handle) != 0:
raise OSError('failed to close mapped file handle')
return vsi_filename
def remove_virtual_file(vsi_filename):
vsi_cfilename = vsi_filename if not isinstance(vsi_filename, string_types) else vsi_filename.encode('utf-8')
- return ograpi.VSIUnlink(vsi_cfilename)
+ return ogrext2.VSIUnlink(vsi_cfilename)
diff --git a/setup.py b/setup.py
index 53a9380..efee743 100644
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,10 @@
+from distutils.command.sdist import sdist
import logging
import os
import shutil
import subprocess
import sys
+
from setuptools import setup
from setuptools.extension import Extension
@@ -12,6 +14,7 @@ try:
except ImportError:
cythonize = None
+
logging.basicConfig()
log = logging.getLogger()
@@ -19,6 +22,7 @@ log = logging.getLogger()
if 'all' in sys.warnoptions:
log.level = logging.DEBUG
+
def check_output(cmd):
# since subprocess.check_output doesn't exist in 2.6
# we wrap it here.
@@ -32,6 +36,7 @@ def check_output(cmd):
out, err = p.communicate()
return out
+
def copy_data_tree(datadir, destdir):
try:
shutil.rmtree(destdir)
@@ -66,22 +71,50 @@ with open('CREDITS.txt', **open_kwds) as f:
with open('CHANGES.txt', **open_kwds) as f:
changes = f.read()
+# Set a flag for builds where the source directory is a repo checkout.
+source_is_repo = os.path.exists("MANIFEST.in")
+
-def copy_gdalapi(gdalversion):
+def copy_gdalapi_pyx(gdalversion):
if gdalversion[0] == u'1':
log.info("Building Fiona for gdal 1.x: {0}".format(gdalversion))
shutil.copy('fiona/ogrext1.pyx', 'fiona/ogrext.pyx')
- shutil.copy('fiona/ograpi1.pxd', 'fiona/ograpi.pxd')
else:
log.info("Building Fiona for gdal 2.x: {0}".format(gdalversion))
shutil.copy('fiona/ogrext2.pyx', 'fiona/ogrext.pyx')
- shutil.copy('fiona/ograpi2.pxd', 'fiona/ograpi.pxd')
+
+
+def copy_gdalapi_c(gdalversion):
+ if gdalversion[0] == u'1':
+ log.info("Building Fiona for gdal 1.x: {0}".format(gdalversion))
+ shutil.copy('fiona/ogrext1.c', 'fiona/ogrext.c')
+ print("Copied 'fiona/ogrext1.c' to'fiona/ogrext.c'")
+ else:
+ log.info("Building Fiona for gdal 2.x: {0}".format(gdalversion))
+ shutil.copy('fiona/ogrext2.c', 'fiona/ogrext.c')
+ print("Copied 'fiona/ogrext2.c' to 'fiona/ogrext.c'")
+
if '--gdalversion' in sys.argv and 'clean' not in sys.argv:
index = sys.argv.index('--gdalversion')
sys.argv.pop(index)
gdalversion = sys.argv.pop(index)
- copy_gdalapi(gdalversion)
+
+
+# Extend distutil's sdist command to generate C extension sources from
+# both `ogrext`.pyx` and `ogrext2.pyx` for GDAL 1.x and 2.x.
+class sdist_multi_gdal(sdist):
+ def run(self):
+ shutil.copy('fiona/ogrext1.pyx', 'fiona/ogrext.pyx')
+ _ = check_output(['cython', '-v', '-f', 'fiona/ogrext.pyx',
+ '-o', 'fiona/ogrext1.c'])
+ print(_)
+ shutil.copy('fiona/ogrext2.pyx', 'fiona/ogrext.pyx')
+ _ = check_output(['cython', '-v', '-f', 'fiona/ogrext.pyx',
+ '-o', 'fiona/ogrext2.c'])
+ print(_)
+ sdist.run(self)
+
# By default we'll try to get options via gdal-config. On systems without,
# options will need to be set in setup.cfg or on the setup command line.
@@ -94,7 +127,8 @@ gdal_output = [None] * 4
if 'clean' not in sys.argv:
try:
gdal_config = os.environ.get('GDAL_CONFIG', 'gdal-config')
- for i, flag in enumerate(("--cflags", "--libs", "--datadir", "--version")):
+ for i, flag in enumerate(
+ ["--cflags", "--libs", "--datadir", "--version"]):
gdal_output[i] = check_output([gdal_config, flag]).strip()
for item in gdal_output[0].split():
@@ -108,8 +142,7 @@ if 'clean' not in sys.argv:
else:
# e.g. -framework GDAL
extra_link_args.append(item)
-
- copy_gdalapi(gdal_output[3])
+ gdalversion = gdal_output[3]
except Exception as e:
if os.name == "nt":
@@ -144,7 +177,7 @@ ext_options = dict(
extra_link_args=extra_link_args)
# When building from a repo, Cython is required.
-if os.path.exists("MANIFEST.in") and "clean" not in sys.argv:
+if source_is_repo and "clean" not in sys.argv:
log.info("MANIFEST.in found, presume a repo, cythonizing...")
if not cythonize:
log.critical(
@@ -152,6 +185,7 @@ if os.path.exists("MANIFEST.in") and "clean" not in sys.argv:
"Cython is required to build from a repo.")
sys.exit(1)
+ copy_gdalapi_pyx(gdalversion)
ext_modules = cythonize([
Extension('fiona._geometry', ['fiona/_geometry.pyx'], **ext_options),
Extension('fiona._transform', ['fiona/_transform.pyx'], **ext_options),
@@ -161,6 +195,7 @@ if os.path.exists("MANIFEST.in") and "clean" not in sys.argv:
Extension('fiona.ogrext', ['fiona/ogrext.pyx'], **ext_options)])
# If there's no manifest template, as in an sdist, we just specify .c files.
else:
+ copy_gdalapi_c(gdalversion)
ext_modules = [
Extension('fiona._transform', ['fiona/_transform.cpp'], **ext_options),
Extension('fiona._geometry', ['fiona/_geometry.c'], **ext_options),
@@ -180,6 +215,7 @@ if sys.version_info < (2, 7):
requirements.append('ordereddict')
setup_args = dict(
+ cmdclass={'sdist': sdist_multi_gdal},
metadata_version='1.2',
name='Fiona',
version=version,
@@ -229,8 +265,7 @@ setup_args = dict(
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
- 'Topic :: Scientific/Engineering :: GIS',
- ])
+ 'Topic :: Scientific/Engineering :: GIS'])
if os.environ.get('PACKAGE_DATA'):
setup_args['package_data'] = {'fiona': ['gdal_data/*', 'proj_data/*']}
diff --git a/tests/test_bytescollection.py b/tests/test_bytescollection.py
index cdee1f0..9318f61 100644
--- a/tests/test_bytescollection.py
+++ b/tests/test_bytescollection.py
@@ -1,10 +1,13 @@
# Testing BytesCollection
+import sys
import unittest
import six
import fiona
+FIXME_WINDOWS = sys.platform.startswith('win')
+
class ReadingTest(unittest.TestCase):
def setUp(self):
@@ -21,18 +24,20 @@ class ReadingTest(unittest.TestCase):
strbuf = src.read()
self.assertRaises(ValueError, fiona.BytesCollection, strbuf)
+ @unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_open_repr(self):
# I'm skipping checking the name of the virtual file as it produced by uuid.
- self.assertTrue(
- repr(self.c).startswith("<open BytesCollection '/vsimem/") and
- repr(self.c).endswith(":OGRGeoJSON', mode 'r' at %s>" % hex(id(self.c))))
+ self.assertTrue(repr(self.c).startswith("<open BytesCollection '/vsimem/"))
+ self.assertTrue(repr(self.c).endswith(":OGRGeoJSON', mode 'r' at %s>" % hex(id(self.c))))
+ @unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_closed_repr(self):
# I'm skipping checking the name of the virtual file as it produced by uuid.
self.c.close()
- self.assertTrue(
- repr(self.c).startswith("<closed BytesCollection '/vsimem/") and
- repr(self.c).endswith(":OGRGeoJSON', mode 'r' at %s>" % hex(id(self.c))))
+ self.assertTrue(repr(self.c).startswith("<closed BytesCollection '/vsimem/"))
+ self.assertTrue(repr(self.c).endswith(":OGRGeoJSON', mode 'r' at %s>" % hex(id(self.c))))
def test_path(self):
self.assertEqual(self.c.path, self.c.virtual_file)
@@ -51,6 +56,8 @@ class ReadingTest(unittest.TestCase):
def test_mode(self):
self.assertEqual(self.c.mode, 'r')
+ @unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_collection(self):
self.assertEqual(self.c.encoding, 'utf-8')
diff --git a/tests/test_collection.py b/tests/test_collection.py
index 8c9cbd9..d4da794 100644
--- a/tests/test_collection.py
+++ b/tests/test_collection.py
@@ -1,18 +1,19 @@
# Testing collections and workspaces
+import datetime
import logging
import os
import shutil
import sys
import subprocess
-import unittest
import tempfile
-import datetime
+import unittest
import fiona
from fiona.collection import Collection, supported_drivers
from fiona.errors import FionaValueError, DriverError, SchemaError, CRSError
+FIXME_WINDOWS = sys.platform.startswith('win')
WILDSHP = 'tests/data/coutwildrnp.shp'
@@ -309,10 +310,12 @@ class UnsupportedDriverTest(unittest.TestCase):
DriverError,
fiona.open, os.path.join(TEMPDIR, "foo"), "w", "Bogus", schema=schema)
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test isn't working. There is a codepage issue regarding Windows-1252 and UTF-8. ")
class GenericWritingTest(unittest.TestCase):
- def setUp(self):
+ @classmethod
+ def setUpClass(self):
self.tempdir = tempfile.mkdtemp()
schema = {
'geometry': 'Point',
@@ -321,12 +324,13 @@ class GenericWritingTest(unittest.TestCase):
'w', driver="ESRI Shapefile", schema=schema,
encoding='Windows-1252')
- def tearDown(self):
+ @classmethod
+ def tearDownClass(self):
self.c.close()
shutil.rmtree(self.tempdir)
def test_encoding(self):
- self.assertEquals(self.c.encoding, 'Windows-1252')
+ self.assertEqual(self.c.encoding, 'Windows-1252')
def test_no_iter(self):
self.assertRaises(IOError, iter, self.c)
@@ -372,7 +376,7 @@ class PointWritingTest(unittest.TestCase):
self.sink.close()
info = subprocess.check_output(
["ogrinfo", self.filename, "point_writing_test"])
- self.assert_(
+ self.assertTrue(
'date (Date) = 2012/01/29' in info.decode('utf-8'),
info)
@@ -566,6 +570,8 @@ class CollectionTest(unittest.TestCase):
def test_no_read_conn_str(self):
self.assertRaises(IOError, fiona.open, "PG:dbname=databasename", "r")
+ @unittest.skipIf(sys.platform.startswith("win"),
+ reason="test only for *nix based system")
def test_no_read_directory(self):
self.assertRaises(ValueError, fiona.open, "/dev/null", "r")
@@ -583,6 +589,7 @@ class GeoJSONCRSWritingTest(unittest.TestCase):
'geometry': 'Point',
'properties': [('title', 'str'), ('date', 'date')]},
crs={'a': 6370997, 'lon_0': -100, 'y_0': 0, 'no_defs': True, 'proj': 'laea', 'x_0': 0, 'units': 'm', 'b': 6370997, 'lat_0': 45})
+
def tearDown(self):
self.sink.close()
@@ -593,11 +600,12 @@ class GeoJSONCRSWritingTest(unittest.TestCase):
self.sink.close()
info = subprocess.check_output(
["ogrinfo", self.filename, "OGRGeoJSON"])
- self.assert_(
+ self.assertTrue(
'GEOGCS["WGS 84' in info.decode('utf-8'),
info)
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Test raises PermissionError. Please look into why this test isn't working.")
class DateTimeTest(unittest.TestCase):
def setUp(self):
@@ -626,12 +634,13 @@ class DateTimeTest(unittest.TestCase):
self.sink.close()
self.assertEqual(len(self.sink), 2)
- c = fiona.open(os.path.join(self.tempdir, "date_test.shp"), "r")
- self.assertEqual(len(c), 2)
+ with fiona.open(os.path.join(self.tempdir, "date_test.shp"), "r") as c:
+ self.assertEqual(len(c), 2)
- rf1, rf2 = list(c)
- self.assertEqual(rf1['properties']['date'], '2013-02-25')
- self.assertEqual(rf2['properties']['date'], '2014-02-03')
+ rf1, rf2 = list(c)
+ self.assertEqual(rf1['properties']['date'], '2013-02-25')
+ self.assertEqual(rf2['properties']['date'], '2014-02-03')
+
def tearDown(self):
shutil.rmtree(self.tempdir)
diff --git a/tests/test_drivers.py b/tests/test_drivers.py
index 18ef430..9d88aa9 100644
--- a/tests/test_drivers.py
+++ b/tests/test_drivers.py
@@ -3,12 +3,17 @@ import os.path
import shutil
import sys
import tempfile
+import unittest
import fiona
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+FIXME_WINDOWS = sys.platform.startswith('win')
+
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Raises PermissionError Please look into why this test isn't working.")
def test_options(tmpdir=None):
"""Test that setting CPL_DEBUG=ON works"""
if tmpdir is None:
diff --git a/tests/test_fio_cat.py b/tests/test_fio_cat.py
index f203bc5..04f6cdd 100644
--- a/tests/test_fio_cat.py
+++ b/tests/test_fio_cat.py
@@ -1,4 +1,6 @@
import json
+import sys
+import unittest
from click.testing import CliRunner
@@ -10,21 +12,26 @@ from .fixtures import feature_seq_pp_rs
WILDSHP = 'tests/data/coutwildrnp.shp'
+FIXME_WINDOWS = sys.platform.startswith('win')
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_one():
runner = CliRunner()
result = runner.invoke(cat.cat, [WILDSHP])
assert result.exit_code == 0
assert result.output.count('"Feature"') == 67
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_two():
runner = CliRunner()
result = runner.invoke(cat.cat, [WILDSHP, WILDSHP])
assert result.exit_code == 0
assert result.output.count('"Feature"') == 134
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_bbox_no():
runner = CliRunner()
result = runner.invoke(
@@ -34,7 +41,8 @@ def test_bbox_no():
assert result.exit_code == 0
assert result.output == ""
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_bbox_yes():
runner = CliRunner()
result = runner.invoke(
@@ -44,7 +52,8 @@ def test_bbox_yes():
assert result.exit_code == 0
assert result.output.count('"Feature"') == 19
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_bbox_json_yes():
runner = CliRunner()
result = runner.invoke(
@@ -53,3 +62,19 @@ def test_bbox_json_yes():
catch_exceptions=False)
assert result.exit_code == 0
assert result.output.count('"Feature"') == 19
+
+
+def test_multi_layer():
+ layerdef = "1:coutwildrnp,1:coutwildrnp"
+ runner = CliRunner()
+ result = runner.invoke(
+ cat.cat, ['--layer', layerdef, 'tests/data/'])
+ assert result.output.count('"Feature"') == 134
+
+
+def test_multi_layer_fail():
+ runner = CliRunner()
+ result = runner.invoke(cat.cat, '--layer'
+ '200000:coutlildrnp',
+ 'tests/data')
+ assert result.exit_code == 1
diff --git a/tests/test_fio_collect.py b/tests/test_fio_collect.py
index b1a2e4c..2e346be 100644
--- a/tests/test_fio_collect.py
+++ b/tests/test_fio_collect.py
@@ -2,6 +2,8 @@
import json
+import sys
+import unittest
from click.testing import CliRunner
@@ -10,7 +12,10 @@ from fiona.fio import collect
from .fixtures import feature_seq
from .fixtures import feature_seq_pp_rs
+FIXME_WINDOWS = sys.platform.startswith('win')
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_collect_rs():
runner = CliRunner()
result = runner.invoke(
@@ -22,6 +27,8 @@ def test_collect_rs():
assert result.output.count('"Feature"') == 2
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_collect_no_rs():
runner = CliRunner()
result = runner.invoke(
diff --git a/tests/test_fio_dump.py b/tests/test_fio_dump.py
index 8efc3b8..165b5a6 100644
--- a/tests/test_fio_dump.py
+++ b/tests/test_fio_dump.py
@@ -1,5 +1,7 @@
"""Unittests for $ fio dump"""
+import sys
+import unittest
from click.testing import CliRunner
@@ -7,10 +9,22 @@ from fiona.fio import dump
WILDSHP = 'tests/data/coutwildrnp.shp'
+TESTGPX = 'tests/data/test_gpx.gpx'
+FIXME_WINDOWS = sys.platform.startswith('win')
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_dump():
runner = CliRunner()
result = runner.invoke(dump.dump, [WILDSHP])
assert result.exit_code == 0
assert '"FeatureCollection"' in result.output
+
+
+def test_dump_layer():
+ for layer in ('routes', '1'):
+ runner = CliRunner()
+ result = runner.invoke(dump.dump, [TESTGPX, '--layer', layer])
+ assert result.exit_code == 0
+ assert '"FeatureCollection"' in result.output
diff --git a/tests/test_fio_info.py b/tests/test_fio_info.py
index c36622f..548ae55 100644
--- a/tests/test_fio_info.py
+++ b/tests/test_fio_info.py
@@ -1,6 +1,8 @@
import json
from pkg_resources import iter_entry_points
import re
+import sys
+import unittest
from click.testing import CliRunner
@@ -9,7 +11,10 @@ from fiona.fio.main import main_group
WILDSHP = 'tests/data/coutwildrnp.shp'
+FIXME_WINDOWS = sys.platform.startswith('win')
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_info_json():
runner = CliRunner()
result = runner.invoke(main_group, ['info', WILDSHP])
@@ -19,14 +24,16 @@ def test_info_json():
assert '"driver": "ESRI Shapefile"' in result.output
assert '"name": "coutwildrnp"' in result.output
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_info_count():
runner = CliRunner()
result = runner.invoke(main_group, ['info', '--count', WILDSHP])
assert result.exit_code == 0
assert result.output == "67\n"
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_info_bounds():
runner = CliRunner()
result = runner.invoke(main_group, ['info', '--bounds', WILDSHP])
@@ -47,6 +54,8 @@ def _filter_info_warning(lines):
return lines
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_info_no_count():
"""Make sure we can still get a `$ fio info` report on datasources that do
not support feature counting, AKA `len(collection)`.
@@ -59,6 +68,8 @@ def test_info_no_count():
assert json.loads(lines[0])['count'] is None
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_info_layer():
for layer in ('routes', '1'):
runner = CliRunner()
diff --git a/tests/test_fio_load.py b/tests/test_fio_load.py
index fce5f08..c5a19b3 100644
--- a/tests/test_fio_load.py
+++ b/tests/test_fio_load.py
@@ -1,7 +1,9 @@
import json
import os
import shutil
+import sys
import tempfile
+import unittest
from click.testing import CliRunner
@@ -11,6 +13,7 @@ from fiona.fio.main import main_group
from .fixtures import (
feature_collection, feature_seq, feature_seq_pp_rs)
+FIXME_WINDOWS = sys.platform.startswith('win')
def test_err():
runner = CliRunner()
@@ -30,7 +33,8 @@ def test_exception(tmpdir=None):
main_group, ['load', '-f', 'Shapefile', tmpfile], '42', catch_exceptions=False)
assert result.exit_code == 1
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_collection(tmpdir=None):
if tmpdir is None:
tmpdir = tempfile.mkdtemp()
@@ -44,6 +48,8 @@ def test_collection(tmpdir=None):
assert len(fiona.open(tmpfile)) == 2
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_seq_rs(tmpdir=None):
if tmpdir is None:
tmpdir = tempfile.mkdtemp()
@@ -57,6 +63,8 @@ def test_seq_rs(tmpdir=None):
assert len(fiona.open(tmpfile)) == 2
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_seq_no_rs(tmpdir=None):
if tmpdir is None:
tmpdir = tempfile.mkdtemp()
@@ -70,6 +78,8 @@ def test_seq_no_rs(tmpdir=None):
assert len(fiona.open(tmpfile)) == 2
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_dst_crs_default_to_src_crs(tmpdir=None):
# When --dst-crs is not given default to --src-crs.
if tmpdir is None:
@@ -88,6 +98,8 @@ def test_dst_crs_default_to_src_crs(tmpdir=None):
assert len(src) == len(feature_seq.splitlines())
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_different_crs(tmpdir=None):
if tmpdir is None:
tmpdir = tempfile.mkdtemp()
@@ -106,6 +118,8 @@ def test_different_crs(tmpdir=None):
assert len(src) == len(feature_seq.splitlines())
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_dst_crs_no_src(tmpdir=None):
if tmpdir is None:
tmpdir = tempfile.mkdtemp()
@@ -123,6 +137,8 @@ def test_dst_crs_no_src(tmpdir=None):
assert len(src) == len(feature_seq.splitlines())
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_fio_load_layer():
tmpdir = tempfile.mkdtemp()
diff --git a/tests/test_fio_ls.py b/tests/test_fio_ls.py
index d8be2b1..4ea80b5 100644
--- a/tests/test_fio_ls.py
+++ b/tests/test_fio_ls.py
@@ -3,14 +3,19 @@
import json
import shutil
+import sys
import tempfile
+import unittest
from click.testing import CliRunner
import fiona
from fiona.fio.main import main_group
+FIXME_WINDOWS = sys.platform.startswith('win')
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_fio_ls_single_layer():
result = CliRunner().invoke(main_group, [
@@ -21,6 +26,8 @@ def test_fio_ls_single_layer():
assert json.loads(result.output) == ['coutwildrnp']
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why this test is not working.")
def test_fio_ls_indent():
result = CliRunner().invoke(main_group, [
diff --git a/tests/test_geojson.py b/tests/test_geojson.py
index 79b41c8..e6c26c2 100644
--- a/tests/test_geojson.py
+++ b/tests/test_geojson.py
@@ -22,7 +22,7 @@ class ReadingTest(unittest.TestCase):
self.c.close()
def test_json(self):
- self.assertEquals(len(self.c), 67)
+ self.assertEqual(len(self.c), 67)
class WritingTest(unittest.TestCase):
@@ -44,5 +44,5 @@ class WritingTest(unittest.TestCase):
'geometry': {'type': 'MultiPoint', 'coordinates': [[0.0, 0.0]]},
'properties': {'title': 'Two'}}])
with fiona.open(path) as c:
- self.assertEquals(c.schema['geometry'], 'Unknown')
- self.assertEquals(len(c), 2)
+ self.assertEqual(c.schema['geometry'], 'Unknown')
+ self.assertEqual(len(c), 2)
diff --git a/tests/test_listing.py b/tests/test_listing.py
index 9e4d2c8..d9b29aa 100644
--- a/tests/test_listing.py
+++ b/tests/test_listing.py
@@ -7,6 +7,8 @@ import unittest
import fiona
import fiona.ogrext
+FIXME_WINDOWS = sys.platform.startswith("win")
+
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
def test_single_file_private():
@@ -19,6 +21,8 @@ def test_single_file():
def test_directory():
assert fiona.listlayers('tests/data') == ['coutwildrnp']
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. ValueError raised. Please look into why this test isn't working.")
def test_directory_trailing_slash():
assert fiona.listlayers('tests/data/') == ['coutwildrnp']
diff --git a/tests/test_multiconxn.py b/tests/test_multiconxn.py
index 2fed3e5..485800c 100644
--- a/tests/test_multiconxn.py
+++ b/tests/test_multiconxn.py
@@ -10,6 +10,8 @@ from fiona.odict import OrderedDict
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+FIXME_WINDOWS = sys.platform.startswith("win")
+
class ReadAccess(unittest.TestCase):
# To check that we'll be able to get multiple 'r' connections to layers
# in a single file.
@@ -31,6 +33,8 @@ class ReadAccess(unittest.TestCase):
f2 = next(c2)
self.assertEqual(f1, f2)
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. These tests raise PermissionErrors on Windows in Python 3.x (which doesn't exist in Python 2.7). Please look into why this test isn't working.")
class ReadWriteAccess(unittest.TestCase):
# To check that we'll be able to read from a file that we're
# writing to.
@@ -75,6 +79,8 @@ class ReadWriteAccess(unittest.TestCase):
del f2['id']
self.assertEqual(self.f, f2)
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. These tests raise PermissionErrors on Windows in Python 3.x (which doesn't exist in Python 2.7). Please look into why this test isn't working.")
class LayerCreation(unittest.TestCase):
def setUp(self):
diff --git a/tests/test_non_counting_layer.py b/tests/test_non_counting_layer.py
index f33f4db..46632d3 100644
--- a/tests/test_non_counting_layer.py
+++ b/tests/test_non_counting_layer.py
@@ -17,7 +17,7 @@ class NonCountingLayerTest(unittest.TestCase):
def test_list(self):
features = list(self.c)
- self.assertEquals(len(features), 19)
+ self.assertEqual(len(features), 19)
def test_getitem(self):
feature = self.c[2]
@@ -28,7 +28,7 @@ class NonCountingLayerTest(unittest.TestCase):
def test_slice(self):
features = self.c[2:5]
- self.assertEquals(len(features), 3)
+ self.assertEqual(len(features), 3)
def test_fail_slice_negative_index(self):
with self.assertRaises(IndexError):
diff --git a/tests/test_unicode.py b/tests/test_unicode.py
index 6def0d3..70e7a1c 100644
--- a/tests/test_unicode.py
+++ b/tests/test_unicode.py
@@ -15,6 +15,7 @@ import fiona
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+FIXME_WINDOWS = sys.platform.startswith('win')
class UnicodePathTest(unittest.TestCase):
@@ -48,7 +49,8 @@ class UnicodePathTest(unittest.TestCase):
with fiona.open(path) as c:
assert len(c) == 67
-
+ at unittest.skipIf(FIXME_WINDOWS,
+ reason="FIXME on Windows. Please look into why these tests are not working. Note: test_write_utf8 works.")
class UnicodeStringFieldTest(unittest.TestCase):
def setUp(self):
@@ -88,7 +90,7 @@ class UnicodeStringFieldTest(unittest.TestCase):
with fiona.open(os.path.join(self.tempdir), encoding='latin1') as c:
f = next(c)
# Next assert fails.
- self.assertEquals(f['properties']['label'], u'徐汇区')
+ self.assertEqual(f['properties']['label'], u'徐汇区')
def test_write_utf8(self):
schema = {
@@ -105,8 +107,8 @@ class UnicodeStringFieldTest(unittest.TestCase):
with fiona.open(os.path.join(self.tempdir), encoding='utf-8') as c:
f = next(c)
- self.assertEquals(f['properties']['label'], u'Ba\u2019kelalan')
- self.assertEquals(f['properties'][u'verit\xe9'], 0)
+ self.assertEqual(f['properties']['label'], u'Ba\u2019kelalan')
+ self.assertEqual(f['properties'][u'verit\xe9'], 0)
def test_write_gb18030(self):
"""Can write a simplified Chinese shapefile"""
@@ -123,5 +125,5 @@ class UnicodeStringFieldTest(unittest.TestCase):
with fiona.open(os.path.join(self.tempdir), encoding='gb18030') as c:
f = next(c)
- self.assertEquals(f['properties']['label'], u'徐汇区')
- self.assertEquals(f['properties']['num'], 0)
+ self.assertEqual(f['properties']['label'], u'徐汇区')
+ self.assertEqual(f['properties']['num'], 0)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/fiona.git
More information about the Pkg-grass-devel
mailing list