diff --git a/CHANGES.txt b/CHANGES.txt index 1cb81c8b5..473866625 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,6 +6,8 @@ All issue numbers are relative to https://github.com/Toblerity/Fiona/issues. 1.9.6 (TBD) ----------- +- Ensure that geometry types in a schema are translated to a linear type, as + geometry instances are (#1313). - Fix broken stable API documentation on Read The Docs (#). - Remove install requirement of setuptools, a regression introduced in 1.9.5. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..5d094e4b6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +ARG GDAL=ubuntu-small-3.6.4 +FROM ghcr.io/osgeo/gdal:${GDAL} AS gdal +ARG PYTHON_VERSION=3.10 +ENV LANG="C.UTF-8" LC_ALL="C.UTF-8" +RUN apt-get update && apt-get install -y software-properties-common +RUN add-apt-repository -y ppa:deadsnakes/ppa +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + g++ \ + gdb \ + make \ + python3-pip \ + python${PYTHON_VERSION} \ + python${PYTHON_VERSION}-dev \ + python${PYTHON_VERSION}-venv \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app +COPY requirements*.txt ./ +RUN python${PYTHON_VERSION} -m venv /venv && \ + /venv/bin/python -m pip install -U pip && \ + /venv/bin/python -m pip install build && \ + /venv/bin/python -m pip install -r requirements-dev.txt && \ + /venv/bin/python -m pip list + +FROM gdal +COPY . . +RUN /venv/bin/python -m build +ENTRYPOINT ["/venv/bin/fio"] +CMD ["--help"] diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..0a4de330a --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +PYTHON_VERSION ?= 3.10 +GDAL ?= ubuntu-small-3.6.4 +all: deps clean install test + +.PHONY: docs + +install: + python setup.py build_ext + pip install -e .[all] + +deps: + pip install -r requirements-dev.txt + +clean: + pip uninstall -y fiona || echo "no need to uninstall" + python setup.py clean --all + find . -name '__pycache__' -delete -print -o -name '*.pyc' -delete -print + touch fiona/*.pyx + +sdist: + python setup.py sdist + +test: + py.test --maxfail 1 -v --cov fiona --cov-report html --pdb tests + +docs: + cd docs && make apidocs && make html + +doctest: + py.test --doctest-modules fiona --doctest-glob='*.rst' docs/*.rst + +dockertestimage: + docker build --build-arg GDAL=$(GDAL) --build-arg PYTHON_VERSION=$(PYTHON_VERSION) --target gdal -t fiona:$(GDAL)-py$(PYTHON_VERSION) . + +dockertest: dockertestimage + docker run -it -v $(shell pwd):/app --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --entrypoint=/bin/bash fiona:$(GDAL)-py$(PYTHON_VERSION) -c '/venv/bin/python -m pip install -e . && /venv/bin/python -B -m pytest -m "not wheel" --cov fiona --cov-report term-missing $(OPTS)' + +dockershell: dockertestimage + docker run -it -v $(shell pwd):/app --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --entrypoint=/bin/bash fiona:$(GDAL)-py$(PYTHON_VERSION) -c '/venv/bin/python -m build && /venv/bin/python -m pip install --pre -f dist fiona && /bin/bash' + +dockersdist: dockertestimage + docker run -it -v $(shell pwd):/app --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --entrypoint=/bin/bash fiona:$(GDAL)-py$(PYTHON_VERSION) -c '/venv/bin/python -m build --sdist' + +dockergdb: dockertestimage + docker run -it -v $(shell pwd):/app --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --entrypoint=/bin/bash fiona:$(GDAL)-py$(PYTHON_VERSION) -c '/venv/bin/python setup.py develop && gdb -ex=r --args /venv/bin/python -B -m pytest -m "not wheel" --cov fiona --cov-report term-missing $(OPTS)' + +dockerdocs: dockertestimage + docker run -it -v $(shell pwd):/app --entrypoint=/bin/bash fiona:$(GDAL)-py$(PYTHON_VERSION) -c 'source /venv/bin/activate && python -m pip install . && cd docs && make clean && make html' diff --git a/fiona/_geometry.pyx b/fiona/_geometry.pyx index 55fb87d01..e9d897fb1 100644 --- a/fiona/_geometry.pyx +++ b/fiona/_geometry.pyx @@ -56,6 +56,10 @@ cdef object normalize_geometry_type_code(unsigned int code): # Normalize 'ZM' types to 3D types. elif 3000 < code < 4000: code = (code % 1000) | 0x80000000 + + # Normalize to a linear type. + code = OGR_GT_GetLinear(code) + if code not in GEOMETRY_TYPES: raise UnsupportedGeometryTypeError(code) diff --git a/fiona/gdal.pxi b/fiona/gdal.pxi index 2559e4ed2..150ecf0a8 100644 --- a/fiona/gdal.pxi +++ b/fiona/gdal.pxi @@ -602,6 +602,7 @@ cdef extern from "ogr_api.h" nogil: long long OGR_F_GetFieldAsInteger64 (void *feature, int n) void OGR_F_SetFieldInteger64 (void *feature, int n, long long value) int OGR_F_IsFieldNull(void *feature, int n) + OGRwkbGeometryType OGR_GT_GetLinear(OGRwkbGeometryType eType) cdef extern from "gdalwarper.h" nogil: diff --git a/tests/conftest.py b/tests/conftest.py index b641e7690..df784d34c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -113,6 +113,12 @@ def path_curves_line_csv(data_dir): return os.path.join(data_dir, "curves_line.csv") +@pytest.fixture(scope="session") +def path_multicurve_gml(data_dir): + """Path to ```multicurve.gml``""" + return os.path.join(data_dir, "multicurve.gml") + + @pytest.fixture(scope="session") def path_test_tin_shp(data_dir): """Path to ```test_tin.shp``""" diff --git a/tests/data/multicurve.gml b/tests/data/multicurve.gml new file mode 100644 index 000000000..b9d0f15e7 --- /dev/null +++ b/tests/data/multicurve.gml @@ -0,0 +1,18 @@ + + + -0.9243407 46.27182575052962.70658958605966 47.6054714507864 + + + + -0.9243407 46.27182575052962.70658958605966 47.6054714507864 + -0.9105691 47.21951 1.414634 47.170731.414634 47.17073 2.423818 47.48377 1.407531 46.726681.407531 46.72668 -0.9243407 46.72668 + MULTICURVE (COMPOUNDCURVE ((-0.9105691 47.21951,1.414634 47.17073),CIRCULARSTRING (1.414634 47.17073,2.423818 47.48377,1.407531 46.72668),(1.407531 46.72668,-0.9243407 46.72668))) + 8.39459167219456 + + + diff --git a/tests/data/multicurve.xsd b/tests/data/multicurve.xsd new file mode 100644 index 000000000..8ee3b6b44 --- /dev/null +++ b/tests/data/multicurve.xsd @@ -0,0 +1,59 @@ + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_curve_geometries.py b/tests/test_curve_geometries.py index 50e6634a9..401420bcd 100644 --- a/tests/test_curve_geometries.py +++ b/tests/test_curve_geometries.py @@ -5,13 +5,18 @@ import fiona -from .conftest import requires_gdal2 - -@requires_gdal2 def test_line_curve_conversion(path_curves_line_csv): """Convert curved geometries to linear approximations""" with fiona.open(path_curves_line_csv) as col: - assert col.schema['geometry'] == 'Unknown' + assert col.schema["geometry"] == "Unknown" features = list(col) assert len(features) == 9 + + +def test_multicurve_conversion(path_multicurve_gml): + """Convert curved geometries to linear approximations""" + with fiona.open(path_multicurve_gml) as col: + assert col.schema["geometry"] == "MultiLineString" + features = list(col) + assert len(features) == 1