Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v 1.5.0 #229

Merged
merged 30 commits into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
00a014c
back to develop
cleder Mar 25, 2024
4cc669e
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Apr 1, 2024
9322379
Merge pull request #223 from cleder/pre-commit-ci-update-config
cleder Apr 2, 2024
4bde426
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Apr 8, 2024
7de6800
Merge pull request #224 from cleder/pre-commit-ci-update-config
cleder Apr 9, 2024
a065942
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Apr 15, 2024
bf7f75c
Merge pull request #225 from cleder/pre-commit-ci-update-config
cleder Apr 16, 2024
6eb3bf1
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Apr 22, 2024
2d359a0
Merge pull request #226 from cleder/pre-commit-ci-update-config
cleder Apr 22, 2024
b8d6596
refactor handling of empty points
cleder Apr 27, 2024
a802b6c
update readme and history
cleder Apr 27, 2024
264f799
update readme
cleder Apr 27, 2024
d825960
update readme
cleder Apr 27, 2024
d8d318c
update readme
cleder Apr 27, 2024
c193992
update readme
cleder Apr 27, 2024
08839a3
update readme
cleder Apr 27, 2024
6856844
return an empty tuple for coordinates if point is empty
cleder Apr 27, 2024
7768e81
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] Apr 29, 2024
05d8d8c
Merge pull request #227 from cleder/pre-commit-ci-update-config
cleder Apr 29, 2024
beae74a
add hypothesis tests for functions
cleder May 1, 2024
17e1d72
ignore flake8 E402 in docs conf.py
cleder May 1, 2024
9c2063c
Add hypothesis profile for continuous integration (CI) testing
cleder May 1, 2024
35c1f9f
update history
cleder May 1, 2024
38cf8a2
assert ccw orientations for the convex hull
cleder May 1, 2024
9975d32
add tests to construct an empty polygon from __geointerface__
cleder May 1, 2024
5c91e5d
add typechecking for tests
cleder May 1, 2024
e705ad5
exclude lines that may be missed in hypothesis tests
cleder May 1, 2024
3cc76bd
[pre-commit.ci] pre-commit autoupdate
pre-commit-ci[bot] May 6, 2024
4721aca
Merge pull request #228 from cleder/pre-commit-ci-update-config
cleder May 7, 2024
e65b752
changelog for v 1.5.0
cleder May 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/run-all-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# run tests and lint with a variety of Python versions
---
name: Tests
on: [push, pull_request]

Check warning on line 5 in .github/workflows/run-all-tests.yml

View workflow job for this annotation

GitHub Actions / static-tests (3.11)

5:1 [truthy] truthy value should be one of [false, true]

Check warning on line 5 in .github/workflows/run-all-tests.yml

View workflow job for this annotation

GitHub Actions / static-tests (3.11)

5:1 [truthy] truthy value should be one of [false, true]

Check warning on line 5 in .github/workflows/run-all-tests.yml

View workflow job for this annotation

GitHub Actions / static-tests (3.11)

5:1 [truthy] truthy value should be one of [false, true]

jobs:
cpython:
Expand Down Expand Up @@ -44,7 +44,7 @@
python -m pip install -e ".[tests]"
- name: Test with pytest including hypothesis tests
run: >-
pytest tests
pytest tests --hypothesis-profile=ci

test-coverage:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -92,7 +92,7 @@
python -m pip install -e ".[typing, complexity, linting]"
- name: Typecheck
run: |
mypy pygeoif
mypy pygeoif tests
- name: Linting
run: |
flake8 pygeoif
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repos:
hooks:
- id: check-useless-excludes
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-docstring-first
Expand Down Expand Up @@ -36,11 +36,11 @@ repos:
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 24.3.0
rev: 24.4.2
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.3.4'
rev: 'v0.4.3'
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down Expand Up @@ -68,7 +68,7 @@ repos:
- flake8-typing-imports
- flake8-use-fstring
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
rev: v1.10.0
hooks:
- id: mypy
additional_dependencies:
Expand All @@ -86,7 +86,7 @@ repos:
hooks:
- id: pyprojectsort
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: "0.28.0"
rev: "0.28.2"
hooks:
- id: check-github-workflows
- id: check-github-actions
Expand Down
60 changes: 36 additions & 24 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,59 +38,61 @@ testing with Hypothesis_.

It was written to provide clean and python only geometries for fastkml_

.. image:: https://readthedocs.org/projects/pygeoif/badge/?version=latest
|doc| |test| |cov| |hypothesis| |black| |mypy| |openhub| |factor| |commit| |py| |implement| |latest| |license| |downloads|

.. |doc| image:: https://readthedocs.org/projects/pygeoif/badge/?version=latest
:target: https://pygeoif.readthedocs.io/en/latest/?badge=latest
:alt: Documentation

.. image:: https://github.com/cleder/pygeoif/actions/workflows/run-all-tests.yml/badge.svg?branch=main
.. |test| image:: https://github.com/cleder/pygeoif/actions/workflows/run-all-tests.yml/badge.svg?branch=main
:target: https://github.com/cleder/pygeoif/actions/workflows/run-all-tests.yml
:alt: GitHub Actions

.. image:: https://codecov.io/gh/cleder/pygeoif/branch/main/graph/badge.svg?token=2EfiwBXs9X
.. |cov| image:: https://codecov.io/gh/cleder/pygeoif/branch/main/graph/badge.svg?token=2EfiwBXs9X
:target: https://codecov.io/gh/cleder/pygeoif
:alt: Codecov

.. image:: https://img.shields.io/badge/property_based_tests-hypothesis-green
:target: https://hypothesis.works
:alt: Hypothesis
.. |hypothesis| image:: https://img.shields.io/badge/hypothesis-tested-brightgreen.svg
:alt: Tested with Hypothesis
:target: https://hypothesis.readthedocs.io

.. image:: https://img.shields.io/badge/code_style-black-000000.svg
.. |black| image:: https://img.shields.io/badge/code_style-black-000000.svg
:target: https://github.com/psf/
:alt: Black

.. image:: https://img.shields.io/badge/type_checker-mypy-blue
.. |mypy| image:: https://img.shields.io/badge/type_checker-mypy-blue
:target: http://mypy-lang.org/
:alt: Mypy

.. image:: https://www.openhub.net/p/pygeoif/widgets/project_thin_badge.gif
.. |openhub| image:: https://www.openhub.net/p/pygeoif/widgets/project_thin_badge.gif
:target: https://www.openhub.net/p/pygeoif/
:alt: Openhub

.. image:: https://www.codefactor.io/repository/github/cleder/pygeoif/badge/main
.. |factor| image:: https://www.codefactor.io/repository/github/cleder/pygeoif/badge/main
:target: https://www.codefactor.io/repository/github/cleder/pygeoif/overview/main
:alt: CodeFactor

.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
.. |commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
:target: https://github.com/pre-commit/pre-commit
:alt: pre-commit

.. image:: https://img.shields.io/pypi/pyversions/pygeoif.svg
.. |py| image:: https://img.shields.io/pypi/pyversions/pygeoif.svg
:target: https://pypi.python.org/pypi/pygeoif/
:alt: Supported Python versions

.. image:: https://img.shields.io/pypi/implementation/pygeoif.svg
.. |implement| image:: https://img.shields.io/pypi/implementation/pygeoif.svg
:target: https://pypi.python.org/pypi/pygeoif/
:alt: Supported Python implementations

.. image:: https://img.shields.io/pypi/v/pygeoif.svg
.. |latest| image:: https://img.shields.io/pypi/v/pygeoif.svg
:target: https://pypi.python.org/pypi/pygeoif/
:alt: Latest Version

.. image:: https://img.shields.io/pypi/l/pygeoif.svg
.. |license| image:: https://img.shields.io/pypi/l/pygeoif.svg
:target: https://pypi.python.org/pypi/pygeoif/
:alt: License

.. image:: https://img.shields.io/pypi/dm/pygeoif.svg
.. |downloads| image:: https://img.shields.io/pypi/dm/pygeoif.svg
:target: https://pypi.python.org/pypi/pygeoif/
:alt: Downloads

Expand All @@ -104,6 +106,7 @@ You can install PyGeoIf from pypi using pip::

Example
========
.. code-block:: pycon

>>> from pygeoif import geometry
>>> p = geometry.Point(1,1)
Expand Down Expand Up @@ -159,15 +162,16 @@ x, y, z : float

Example
~~~~~~~~
.. code-block: pycon

>>> from pygeoif import Point
>>> p = Point(1.0, -1.0)
>>> print(p)
POINT (1.0 -1.0)
>>> p.y
-1.0
>>> p.x
1.0
>>> from pygeoif import Point
>>> p = Point(1.0, -1.0)
>>> print(p)
POINT (1.0 -1.0)
>>> p.y
-1.0
>>> p.x
1.0



Expand Down Expand Up @@ -267,6 +271,7 @@ So it's very rarely used in the real GIS professional world.

Example
~~~~~~~~
.. code-block:: pycon

>>> from pygeoif import geometry
>>> p = geometry.Point(1.0, -1.0)
Expand All @@ -289,6 +294,8 @@ properties : dict

Example
~~~~~~~~
.. code-block:: pycon

>>> from pygeoif import Point, Feature
>>> p = Point(1.0, -1.0)
>>> props = {'Name': 'Sample Point', 'Other': 'Other Data'}
Expand All @@ -309,6 +316,7 @@ features: sequence

Example
~~~~~~~~
.. code-block:: pycon

>>> from pygeoif import Point, Feature, FeatureCollection
>>> p = Point(1.0, -1.0)
Expand All @@ -331,6 +339,8 @@ shape
Create a pygeoif feature from an object that provides the ``__geo_interface__``
or any GeoJSON_ compatible dictionary.

.. code-block:: pycon

>>> from shapely.geometry import Point
>>> from pygeoif import geometry, shape
>>> shape(Point(0,0))
Expand All @@ -342,6 +352,8 @@ from_wkt

Create a geometry from its WKT representation

.. code-block:: pycon

>>> from pygeoif import from_wkt
>>> p = from_wkt('POINT (0 1)')
>>> print(p)
Expand Down
6 changes: 6 additions & 0 deletions docs/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

1.5.0 (2024/05/11)
------------------

- fix handling of empty geometries.
- more hypothesis tests

1.4.0 (2024/03/25)
------------------

Expand Down
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# noqa: D100, INP001
# flake8: noqa
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
Expand All @@ -11,6 +12,7 @@
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information


from pygeoif import about

project = "pygeoif"
Expand Down
2 changes: 1 addition & 1 deletion pygeoif/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
The only purpose of this module is to provide a version number for the package.
"""

__version__ = "1.4.0"
__version__ = "1.5.0"
7 changes: 2 additions & 5 deletions pygeoif/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,12 @@ def shape(
)
raise TypeError(msg)

constructor = type_map.get(geometry["type"])
if constructor:
if constructor := type_map.get(geometry["type"]):
return constructor._from_dict( # type: ignore [attr-defined, no-any-return]
geometry,
)
if geometry["type"] == "GeometryCollection":
geometries = [
shape(fi) for fi in geometry["geometries"] # type: ignore [typeddict-item]
]
geometries = [shape(fi) for fi in geometry["geometries"]]
return GeometryCollection(geometries)
msg = f"[{geometry['type']} is not implemented"
raise NotImplementedError(msg)
Expand Down
21 changes: 13 additions & 8 deletions pygeoif/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def signed_area(coords: LineType) -> float:
Linear time algorithm: http://www.cgafaq.info/wiki/Polygon_Area.
A value >= 0 indicates a counter-clockwise oriented ring.
"""
if len(coords) < 3: # noqa: PLR2004
return 0.0
xs, ys = map(list, zip(*(coord[:2] for coord in coords)))
xs.append(xs[1]) # pragma: no mutate
ys.append(ys[1]) # pragma: no mutate
Expand All @@ -53,7 +55,6 @@ def signed_area(coords: LineType) -> float:
def centroid(coords: LineType) -> Tuple[Point2D, float]:
"""Calculate the coordinates of the centroid and the area of a LineString."""
ans: List[float] = [0, 0]

n = len(coords)
signed_area = 0.0

Expand All @@ -68,8 +69,11 @@ def centroid(coords: LineType) -> Tuple[Point2D, float]:
ans[0] += (coord[0] + next_coord[0]) * area
ans[1] += (coord[1] + next_coord[1]) * area

ans[0] = (ans[0]) / (3 * signed_area)
ans[1] = (ans[1]) / (3 * signed_area)
if signed_area == 0 or math.isnan(signed_area):
return ((math.nan, math.nan), signed_area)

ans[0] = ans[0] / (3 * signed_area)
ans[1] = ans[1] / (3 * signed_area)

return cast(Point2D, tuple(ans)), signed_area / 2.0

Expand Down Expand Up @@ -167,13 +171,13 @@ def compare_geo_interface(
return all(
compare_geo_interface(first=g1, second=g2) # type: ignore [arg-type]
for g1, g2 in zip_longest(
first["geometries"], # type: ignore [typeddict-item]
first["geometries"],
second["geometries"], # type: ignore [typeddict-item]
fillvalue={"type": None, "coordinates": ()},
)
)
return compare_coordinates(
coords=first["coordinates"], # type: ignore [typeddict-item]
coords=first["coordinates"],
other=second["coordinates"], # type: ignore [typeddict-item]
)
except KeyError:
Expand Down Expand Up @@ -220,6 +224,8 @@ def move_coordinates(
>>> move_coordinates(((0, 0), (-1, 1)), (-1, 1, 0))
((-1, 1, 0), (-2, 2, 0))
"""
if not coordinates:
return coordinates
if isinstance(coordinates[0], (int, float)):
return move_coordinate(cast(PointType, coordinates), move_by)
return cast(
Expand All @@ -237,14 +243,13 @@ def move_geo_interface(
return {
"type": "GeometryCollection",
"geometries": tuple(
move_geo_interface(g, move_by)
for g in interface["geometries"] # type: ignore [typeddict-item]
move_geo_interface(g, move_by) for g in interface["geometries"]
),
}
return {
"type": interface["type"],
"coordinates": move_coordinates(
interface["coordinates"], # type: ignore [typeddict-item, arg-type]
interface["coordinates"], # type: ignore [arg-type]
move_by,
),
}
Expand Down
Loading
Loading