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

1.0 - improvements after beta #50

Merged
merged 15 commits into from
Oct 2, 2021
14 changes: 11 additions & 3 deletions .github/workflows/run-all-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ jobs:
pip install pytest pytest-cov typing_extensions
- name: Test with pytest
run: |
pytest pygeoif --cov=pygeoif -cov-fail-under=100
pytest --doctest-glob="README.rst"
pytest pygeoif --cov=pygeoif --cov-fail-under=100 --cov-report=xml
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v1
if: ${{ matrix.python-version==3.9 }}
uses: codecov/codecov-action@v2
with:
fail_ci_if_error: true
verbose: true

static-tests:
runs-on: ubuntu-latest
Expand All @@ -52,6 +55,11 @@ jobs:
flake8 pygeoif
black --check pygeoif
yamllint .github/workflows/
- name: Check complexity
run: |
radon cc --min B pygeoif
radon mi --min B pygeoif
lizard -l python -w pygeoif

pypy:
runs-on: ubuntu-latest
Expand Down
14 changes: 14 additions & 0 deletions .pep8speaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
scanner:
diff_only: True # If True, only the diff is scanned.
linter: flake8

flake8: # Valid if scanner.linter is flake8
max-line-length: 89
ignore: [W503]
exclude: []
count: False
show-source: False
statistics: False
hang-closing: False
filename: []
select: []
24 changes: 14 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ you feel right at home with pygeoif.

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

.. _fastkml: http://pypi.python.org/pypi/fastkml/

.. image:: https://github.com/cleder/pygeoif/actions/workflows/run-all-tests.yml/badge.svg
:target: https://github.com/cleder/pygeoif/actions/workflows/run-all-tests.yml

Expand All @@ -41,6 +39,9 @@ It was written to provide clean and python only geometries for fastkml_
.. image:: https://img.shields.io/badge/type%20checker-mypy-blue
:target: http://mypy-lang.org/

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

Example
========

Expand Down Expand Up @@ -68,17 +69,17 @@ Classes

All classes implement the attribute:

* __geo_interface__: as discussed above, an interface to ``GeoJSON``.
* ``__geo_interface__``: as discussed above, an interface to GeoJSON_.

All geometry classes implement the attributes:

* geom_type: Returns a string specifying the Geometry Type of the object
* bounds: Returns a (minx, miny, maxx, maxy) tuple that bounds the object.
* wkt: Returns the 'Well Known Text' representation of the object
* ``geom_type``: Returns a string specifying the Geometry Type of the object
* ``bounds``: Returns a (minx, miny, maxx, maxy) tuple that bounds the object.
* ``wkt``: Returns the 'Well Known Text' representation of the object

For two-dimensional geometries the following methods are implemented:

* convex_hull: Returns a representation of the smallest convex Polygon containing
* ``convex_hull``: Returns a representation of the smallest convex Polygon containing
all the points in the object unless the number of points in the object is less than three.
For two points, the convex hull collapses to a LineString; for 1, a Point.
For three dimensional objects only their projection in the xy plane is taken into consideration.
Expand Down Expand Up @@ -150,7 +151,7 @@ exterior : LinearRing
The ring which bounds the positive space of the polygon.
interiors : sequence
A sequence of rings which bound all existing holes.
is_valid: boolean
maybe_valid: boolean
When a polygon has obvious problems such as self crossing
lines or holes that are outside the exterior bounds this will
return False. Even if this returns True the geometry may still be invalid,
Expand Down Expand Up @@ -200,7 +201,7 @@ geoms : sequence
A sequence of geometry instances

Please note:
``GEOMETRYCOLLECTION`` isn't supported by the Shapefile format.
``GEOMETRYCOLLECTION`` isn't supported by the Shapefile or GeoJSON_ format.
And this sub-class isn't generally supported by ordinary GIS sw (viewers and so on).
So it's very rarely used in the real GIS professional world.

Expand Down Expand Up @@ -267,7 +268,8 @@ Functions
shape
--------

Create a pygeoif feature from an object that provides the ``__geo_interface__``.
Create a pygeoif feature from an object that provides the ``__geo_interface__``
or any GeoJSON_ compatible dictionary.

>>> from shapely.geometry import Point
>>> from pygeoif import geometry, shape
Expand Down Expand Up @@ -344,3 +346,5 @@ Acknowledgments
The tests were improved with mutmut_ which discovered some nasty edge cases.

.. _mutmut: https://github.com/boxed/mutmut
.. _GeoJSON: https://geojson.org/
.. _fastkml: http://pypi.python.org/pypi/fastkml/
138 changes: 0 additions & 138 deletions compositor.json

This file was deleted.

20 changes: 9 additions & 11 deletions docs/LICENSE.GPL
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
Expand Down Expand Up @@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

Expand Down Expand Up @@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.

2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
Expand Down Expand Up @@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.

Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
Expand Down Expand Up @@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
Expand Down Expand Up @@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
Expand Down Expand Up @@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.

11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
Expand Down Expand Up @@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
Expand Down Expand Up @@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Libraries

If you develop a new library, and you want it to be of the greatest
Expand Down Expand Up @@ -500,5 +500,3 @@ necessary. Here is a sample; alter the names:
Ty Coon, President of Vice

That's all there is to it!


7 changes: 6 additions & 1 deletion mutmut_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""Mutmut configuration."""

files_to_mutate = ["pygeoif/geometry.py", "pygeoif/feature.py", "pygeoif/factories.py", 'pygeoif/functions.py']
files_to_mutate = [
"pygeoif/geometry.py",
"pygeoif/feature.py",
"pygeoif/factories.py",
"pygeoif/functions.py",
]


def pre_mutation(context):
Expand Down
9 changes: 8 additions & 1 deletion pygeoif/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
"""Functions for geometries."""
from itertools import groupby
from typing import Iterable
from typing import List
from typing import Tuple
Expand Down Expand Up @@ -45,6 +46,7 @@ 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)
Expand Down Expand Up @@ -126,4 +128,9 @@ def convex_hull(points: Iterable[Point2D]) -> LineType:
return lower[:-1] + upper


__all__ = ["convex_hull", "signed_area"]
def dedupe(coords: LineType) -> LineType:
"""Remove duplicate Points from a LineString."""
return tuple(coord for coord, _count in groupby(coords))


__all__ = ["centroid", "convex_hull", "dedupe", "signed_area"]
11 changes: 11 additions & 0 deletions pygeoif/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,17 @@ def has_z(self) -> Optional[bool]:
return None
return self._geoms[0].has_z

@property
def maybe_valid(self) -> bool:
"""
Check validity of the coordinates.

Returns False if the coordinates colapse to a single Point.
This only highlights obvious problems with this geometry.
Even if this test passes the geometry may still be invalid.
"""
return len({p.coords[0] for p in self._geoms}) > 1

@property
def _wkt_inset(self) -> str:
return self.geoms[0]._wkt_inset
Expand Down
22 changes: 22 additions & 0 deletions pygeoif/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from pygeoif.functions import centroid
from pygeoif.functions import convex_hull
from pygeoif.functions import dedupe
from pygeoif.functions import signed_area


Expand Down Expand Up @@ -256,3 +257,24 @@ def test_random():
if len(hull) > 3:
_, area = centroid(tuple(hull))
assert abs(area - signed_area(hull)) < 0.001


def test_dedupe_point():

assert dedupe(((1, 2, 3),) * 10) == ((1, 2, 3),)


def test_dedupe_line():

assert dedupe(((1, 2, 3), (4, 5, 6)) * 3) == (
(1, 2, 3),
(4, 5, 6),
(1, 2, 3),
(4, 5, 6),
(1, 2, 3),
(4, 5, 6),
)


def test_dedupe_line2():
assert dedupe(((1, 2, 3),) * 2 + ((4, 5, 6),) * 3) == ((1, 2, 3), (4, 5, 6))
18 changes: 18 additions & 0 deletions pygeoif/tests/test_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,21 @@ def test_from_coordinates():
line = geometry.LineString([(0, 0), (1, 0), (2, 2)])

assert geometry.LineString.from_coordinates(line.coords) == line


def test_maybe_valid():
line = geometry.LineString([(0, 0), (1, 0)])

assert line.maybe_valid


def test_maybe_valid_point():
line = geometry.LineString([(0, 0), (0, 0)])

assert not line.maybe_valid


def test_maybe_empty():
line = geometry.LineString([])

assert not line.maybe_valid
Loading