[Git][debian-gis-team/python-geojson][upstream] New upstream version 2.5.0
Bas Couwenberg
gitlab at salsa.debian.org
Fri Jul 19 06:11:38 BST 2019
Bas Couwenberg pushed to branch upstream at Debian GIS Project / python-geojson
Commits:
066d8e09 by Bas Couwenberg at 2019-07-19T04:57:57Z
New upstream version 2.5.0
- - - - -
17 changed files:
- .travis.yml
- CHANGELOG.rst
- README.rst
- geojson/_version.py
- − geojson/crs.py
- geojson/factory.py
- geojson/geometry.py
- geojson/mapping.py
- geojson/utils.py
- setup.py
- tests/test_base.py
- tests/test_constructor.py
- tests/test_coords.py
- − tests/test_crs.py
- tests/test_features.py
- tests/test_geo_interface.py
- tox.ini
Changes:
=====================================
.travis.yml
=====================================
@@ -1,18 +1,42 @@
-language: "python"
+language: python
+dist: xenial
python:
- - "2.7"
- - "3.3"
- - "3.4"
- - "3.5"
- - "3.6"
- - "pypy"
+- 2.7
+- 3.5
+- 3.6
+- 3.7
+- pypy2.7-6.0
+- pypy3.5-6.0
install:
- - pip install flake8
- - pip install codecov
-before_script:
- flake8 .
+- pip install codecov
script:
- - coverage run --branch --source=geojson setup.py test
- - coverage xml
+- coverage run --branch --source=geojson setup.py test
+- coverage xml
after_success:
- - codecov
+- codecov
+stages:
+- lint
+- test
+- deploy
+jobs:
+ include:
+ - stage: lint
+ env: TOXENV=flake8
+ python: 3.7
+ install: pip install flake8
+ script: flake8 .
+ - stage: deploy
+ env:
+ python: 3.7
+ install: skip
+ script: skip
+ deploy:
+ provider: pypi
+ server: https://jazzband.co/projects/python-geojson/upload
+ distributions: sdist bdist_wheel
+ user: jazzband
+ password:
+ secure: V2dsQfSMdChZ+G9w4cBcoa/Gmo/kJf2BMaN3sb7pDcAkTHuPYHppfSfj3vWDfpZFNobg8kTed4xjeYdKJ/oxFMpSGBWhGGpzQauzXO8n6LFXM44r/b5uXzyOyzdwwnjWXBn3NkubNU/n3dSjnRr9ZTeXGjiOGTPW1wAWjARJvgg=
+ on:
+ tags: true
+ repo: jazzband/python-geojson
=====================================
CHANGELOG.rst
=====================================
@@ -1,6 +1,34 @@
Changes
=======
+2.5.0 (2019-07-18)
+------------------
+
+- Add "precision" parameter to GeoJSON Object classes with default precision of 6 (0.1m)
+
+ - https://github.com/jazzband/python-geojson/pull/131
+
+- Fix bug where `map_geometries()` util was not preserving Feature IDs
+
+ - https://github.com/jazzband/python-geojson/pull/128
+ - https://github.com/jazzband/python-geojson/pull/130
+
+- Remove `crs` module and features to conform to official WGS84-only GeoJSON spec
+
+ - https://github.com/jazzband/python-geojson/pull/124
+
+- Set up semi-automatic PyPi releases via Travis/Jazzband
+
+ - https://github.com/jazzband/python-geojson/pull/123
+
+2.4.2 (2019-03-12)
+------------------
+
+- Tie Travis CI to jazzband instance
+- Remove EOL 3.3 and 3.4 version support
+
+ - https://github.com/jazzband/python-geojson/pull/120
+
2.4.1 (2018-10-17)
------------------
=====================================
README.rst
=====================================
@@ -1,10 +1,10 @@
python-geojson
==============
-.. image:: https://img.shields.io/travis/frewsxcv/python-geojson.svg
- :target: https://travis-ci.org/frewsxcv/python-geojson
-.. image:: https://img.shields.io/codecov/c/github/frewsxcv/python-geojson.svg
- :target: https://codecov.io/github/frewsxcv/python-geojson?branch=master
+.. image:: https://img.shields.io/travis/jazzband/python-geojson.svg
+ :target: https://travis-ci.org/jazzband/python-geojson
+.. image:: https://img.shields.io/codecov/c/github/jazzband/python-geojson.svg
+ :target: https://codecov.io/github/jazzband/python-geojson?branch=master
This library contains:
@@ -21,7 +21,7 @@ This library contains:
Installation
------------
-python-geojson is compatible with Python 2.7, 3.3, 3.4, 3.5 and 3.6. It is listed on `PyPi as 'geojson'`_. The recommended way to install is via pip_:
+python-geojson is compatible with Python 2.7, 3.5, 3.6 and 3.7. It is listed on `PyPi as 'geojson'`_. The recommended way to install is via pip_:
.. code::
@@ -266,6 +266,22 @@ This encoding/decoding functionality shown in the previous can be extended to cu
>>> geojson.dumps(point_instance, sort_keys=True) # doctest: +ELLIPSIS
'{"coordinates": [52.23..., -19.23...], "type": "Point"}'
+Default and custom precision
+~~~~~~~~~~~~~~~~~
+
+GeoJSON Object-based classes in this package have an additional `precision` attribute which rounds off
+coordinates to 6 decimal places (roughly 0.1 meters) by default and can be customized per object instance.
+
+.. code:: python
+
+ >>> from geojson import Point
+
+ >>> Point((-115.123412341234, 37.123412341234)) # rounded to 6 decimal places by default
+ {"coordinates": [-115.123412, 37.123412], "type": "Point"}
+
+ >>> Point((-115.12341234, 37.12341234), precision=8) # rounded to 8 decimal places
+ {"coordinates": [-115.12341234, 37.12341234], "type": "Point"}
+
Helpful utilities
-----------------
@@ -369,7 +385,9 @@ generate_random
Development
-----------
-To build this project, run :code:`python setup.py build`. To run the unit tests, run :code:`python setup.py test`.
+To build this project, run :code:`python setup.py build`.
+To run the unit tests, run :code:`python setup.py test`.
+To run the style checks, run :code:`flake8` (install `flake8` if needed).
Credits
-------
@@ -380,6 +398,7 @@ Credits
* Blake Grotewold <hello at grotewold.me>
* Zsolt Ero <zsolt.ero at gmail.com>
* Sergey Romanov <xxsmotur at gmail.com>
+* Ray Riga <ray at strongoutput.com>
.. _GeoJSON: http://geojson.org/
=====================================
geojson/_version.py
=====================================
@@ -1,2 +1,2 @@
-__version__ = "2.4.1"
+__version__ = "2.5.0"
__version_info__ = tuple(map(int, __version__.split(".")))
=====================================
geojson/crs.py deleted
=====================================
@@ -1,39 +0,0 @@
-from geojson.base import GeoJSON
-
-
-class CoordinateReferenceSystem(GeoJSON):
- """
- Represents a CRS.
- """
-
- def __init__(self, properties=None, **extra):
- super(CoordinateReferenceSystem, self).__init__(**extra)
- self["properties"] = properties or {}
-
-
-class Named(CoordinateReferenceSystem):
- """
- Represents a named CRS.
- """
-
- def __init__(self, properties=None, **extra):
- super(Named, self).__init__(properties=properties, **extra)
- self["type"] = "name"
-
- def __repr__(self):
- return super(Named, self).__repr__()
-
-
-class Linked(CoordinateReferenceSystem):
- """
- Represents a linked CRS.
- """
-
- def __init__(self, properties=None, **extra):
- super(Linked, self).__init__(properties=properties, **extra)
- self["type"] = "link"
-
-
-class Default(object):
-
- """GeoJSON default, long/lat WGS84, is not serialized."""
=====================================
geojson/factory.py
=====================================
@@ -3,13 +3,9 @@ from geojson.geometry import MultiLineString, MultiPoint, MultiPolygon
from geojson.geometry import GeometryCollection
from geojson.feature import Feature, FeatureCollection
from geojson.base import GeoJSON
-from geojson.crs import Named, Linked
__all__ = ([Point, LineString, Polygon] +
[MultiLineString, MultiPoint, MultiPolygon] +
[GeometryCollection] +
[Feature, FeatureCollection] +
[GeoJSON])
-
-name = Named
-link = Linked
=====================================
geojson/geometry.py
=====================================
@@ -16,28 +16,28 @@ class Geometry(GeoJSON):
Represents an abstract base class for a WGS84 geometry.
"""
- def __init__(self, coordinates=None, crs=None, validate=False, **extra):
+ def __init__(self, coordinates=None, validate=False, precision=6, **extra):
"""
Initialises a Geometry object.
:param coordinates: Coordinates of the Geometry object.
:type coordinates: tuple or list of tuple
- :param crs: CRS
- :type crs: CRS object
+ :param validate: Raise exception if validation errors are present?
+ :type validate: boolean
+ :param precision: Number of decimal places for lat/lon coords.
+ :type precision: integer
"""
-
super(Geometry, self).__init__(**extra)
- self["coordinates"] = self.clean_coordinates(coordinates or [])
+ self["coordinates"] = self.clean_coordinates(
+ coordinates or [], precision)
if validate:
errors = self.errors()
if errors:
raise ValueError('{}: {}'.format(errors, coordinates))
- if crs:
- self["crs"] = self.to_instance(crs, strict=True)
@classmethod
- def clean_coordinates(cls, coords):
+ def clean_coordinates(cls, coords, precision):
if isinstance(coords, cls):
return coords['coordinates']
@@ -46,11 +46,11 @@ class Geometry(GeoJSON):
coords = [coords]
for coord in coords:
if isinstance(coord, (list, tuple)):
- new_coords.append(cls.clean_coordinates(coord))
+ new_coords.append(cls.clean_coordinates(coord, precision))
elif isinstance(coord, Geometry):
new_coords.append(coord['coordinates'])
elif isinstance(coord, _JSON_compliant_types):
- new_coords.append(coord)
+ new_coords.append(round(coord, precision))
else:
raise ValueError("%r is not a JSON compliant number" % coord)
return new_coords
=====================================
geojson/mapping.py
=====================================
@@ -1,4 +1,8 @@
-from collections import MutableMapping
+try:
+ from collections.abc import MutableMapping
+except ImportError:
+ from collections import MutableMapping
+
try:
import simplejson as json
except ImportError:
@@ -7,9 +11,6 @@ except ImportError:
import geojson
-mapping_base = MutableMapping
-
-
GEO_INTERFACE_MARKER = "__geo_interface__"
=====================================
geojson/utils.py
=====================================
@@ -119,12 +119,8 @@ def map_geometries(func, obj):
geoms = [func(geom) if geom else None for geom in obj['geometries']]
return {'type': obj['type'], 'geometries': geoms}
elif obj['type'] == 'Feature':
- geom = func(obj['geometry']) if obj['geometry'] else None
- return {
- 'type': obj['type'],
- 'geometry': geom,
- 'properties': obj['properties'],
- }
+ obj['geometry'] = func(obj['geometry']) if obj['geometry'] else None
+ return obj
elif obj['type'] == 'FeatureCollection':
feats = [map_geometries(func, feat) for feat in obj['features']]
return {'type': obj['type'], 'features': feats}
=====================================
setup.py
=====================================
@@ -29,9 +29,10 @@ def test_suite():
return suite
-if sys.version_info[:2] not in [(2, 6), (2, 7)] and \
- sys.version_info[:1] not in [(3, )]:
- sys.stderr.write("Sorry, only Python 2.7, and 3.x are supported "
+major_version, minor_version = sys.version_info[:2]
+if not ((major_version == 2 and minor_version == 7)
+ or (major_version == 3 and minor_version >= 5)):
+ sys.stderr.write("Sorry, only Python 2.7, 3.5, 3.6 and 3.7 are supported "
"at this time.\n")
exit(1)
@@ -47,9 +48,9 @@ setup(
keywords="gis geography json",
author="Sean Gillies",
author_email="sgillies at frii.com",
- maintainer="Corey Farwell",
- maintainer_email="coreyf at rwell.org",
- url="https://github.com/frewsxcv/python-geojson",
+ maintainer="Ray Riga",
+ maintainer_email="ray at strongoutput.com",
+ url="https://github.com/jazzband/python-geojson",
long_description=readme_text,
packages=["geojson"],
package_dir={"geojson": "geojson"},
@@ -66,10 +67,9 @@ setup(
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.3",
- "Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
"Topic :: Scientific/Engineering :: GIS",
]
)
=====================================
tests/test_base.py
=====================================
@@ -61,7 +61,7 @@ class BaseTestCase(unittest.TestCase):
def test_to_instance(self):
FAKE = 'fake'
- self.assertEquals(FAKE, geojson.GeoJSON.to_instance(
+ self.assertEqual(FAKE, geojson.GeoJSON.to_instance(
None, (lambda: FAKE)))
with self.assertRaises(ValueError):
=====================================
tests/test_constructor.py
=====================================
@@ -13,21 +13,21 @@ class TestGeoJSONConstructor(unittest.TestCase):
def test_copy_construction(self):
coords = [1, 2]
pt = geojson.Point(coords)
- self.assertEquals(geojson.Point(pt), pt)
+ self.assertEqual(geojson.Point(pt), pt)
def test_nested_constructors(self):
a = [5, 6]
b = [9, 10]
c = [-5, 12]
mp = geojson.MultiPoint([geojson.Point(a), b])
- self.assertEquals(mp.coordinates, [a, b])
+ self.assertEqual(mp.coordinates, [a, b])
mls = geojson.MultiLineString([geojson.LineString([a, b]), [a, c]])
- self.assertEquals(mls.coordinates, [[a, b], [a, c]])
+ self.assertEqual(mls.coordinates, [[a, b], [a, c]])
outer = [a, b, c, a]
poly = geojson.Polygon(geojson.MultiPoint(outer))
other = [[1, 1], [1, 2], [2, 1], [1, 1]]
poly2 = geojson.Polygon([outer, other])
- self.assertEquals(geojson.MultiPolygon([poly, poly2]).coordinates,
- [[outer], [outer, other]])
+ self.assertEqual(geojson.MultiPolygon([poly, poly2]).coordinates,
+ [[outer], [outer, other]])
=====================================
tests/test_coords.py
=====================================
@@ -3,12 +3,18 @@ import unittest
import geojson
from geojson.utils import coords, map_coords
+TOO_PRECISE = (1.12341234, -2.12341234)
+
class CoordsTestCase(unittest.TestCase):
def test_point(self):
itr = coords(geojson.Point((-115.81, 37.24)))
self.assertEqual(next(itr), (-115.81, 37.24))
+ def test_point_rounding(self):
+ itr = coords(geojson.Point(TOO_PRECISE))
+ self.assertEqual(next(itr), tuple([round(c, 6) for c in TOO_PRECISE]))
+
def test_dict(self):
itr = coords({'type': 'Point', 'coordinates': [-115.81, 37.24]})
self.assertEqual(next(itr), (-115.81, 37.24))
@@ -66,6 +72,16 @@ class CoordsTestCase(unittest.TestCase):
self.assertEqual(result['coordinates'][0][0][0], (3.78, 9.28))
self.assertEqual(result['coordinates'][-1][-1][-1], (23.18, -34.29))
+ def test_map_feature(self):
+ g = geojson.Feature(
+ id='123',
+ geometry=geojson.Point([-115.81, 37.24])
+ )
+ result = map_coords(lambda x: x, g)
+ self.assertEqual(result['type'], 'Feature')
+ self.assertEqual(result['id'], '123')
+ self.assertEqual(result['geometry']['coordinates'], (-115.81, 37.24))
+
def test_map_invalid(self):
with self.assertRaises(ValueError):
map_coords(lambda x: x, {"type": ""})
=====================================
tests/test_crs.py deleted
=====================================
@@ -1,30 +0,0 @@
-import unittest
-
-import geojson
-
-
-class CRSTest(unittest.TestCase):
-
- def setUp(self):
- self.crs = geojson.crs.Named(
- properties={
- "name": "urn:ogc:def:crs:EPSG::3785",
- }
- )
-
- def test_crs_repr(self):
- actual = repr(self.crs)
- expected = ('{"properties": {"name": "urn:ogc:def:crs:EPSG::3785"},'
- ' "type": "name"}')
- self.assertEqual(actual, expected)
-
- def test_crs_encode(self):
- actual = geojson.dumps(self.crs, sort_keys=True)
- expected = ('{"properties": {"name": "urn:ogc:def:crs:EPSG::3785"},'
- ' "type": "name"}')
- self.assertEqual(actual, expected)
-
- def test_crs_decode(self):
- dumped = geojson.dumps(self.crs)
- actual = geojson.loads(dumped)
- self.assertEqual(actual, self.crs)
=====================================
tests/test_features.py
=====================================
@@ -15,13 +15,13 @@ class FeaturesTest(unittest.TestCase):
f = {
'type': 'Feature',
'id': '1',
- 'geometry': {'type': 'Point', 'coordinates': [53, -4]},
+ 'geometry': {'type': 'Point', 'coordinates': [53.0, -4.0]},
'properties': {'title': 'Dict 1'},
}
json = geojson.dumps(f, sort_keys=True)
self.assertEqual(json, '{"geometry":'
- ' {"coordinates": [53, -4],'
+ ' {"coordinates": [53.0, -4.0],'
' "type": "Point"},'
' "id": "1",'
' "properties": {"title": "Dict 1"},'
@@ -30,7 +30,7 @@ class FeaturesTest(unittest.TestCase):
o = geojson.loads(json)
output = geojson.dumps(o, sort_keys=True)
self.assertEqual(output, '{"geometry":'
- ' {"coordinates": [53, -4],'
+ ' {"coordinates": [53.0, -4.0],'
' "type": "Point"},'
' "id": "1",'
' "properties": {"title": "Dict 1"},'
@@ -49,7 +49,7 @@ class FeaturesTest(unittest.TestCase):
from geojson.examples import SimpleWebFeature
feature = SimpleWebFeature(
id='1',
- geometry={'type': 'Point', 'coordinates': [53, -4]},
+ geometry={'type': 'Point', 'coordinates': [53.0, -4.0]},
title='Feature 1', summary='The first feature',
link='http://example.org/features/1'
)
@@ -61,10 +61,10 @@ class FeaturesTest(unittest.TestCase):
self.assertEqual(feature.properties['link'],
'http://example.org/features/1')
self.assertEqual(geojson.dumps(feature.geometry, sort_keys=True),
- '{"coordinates": [53, -4], "type": "Point"}')
+ '{"coordinates": [53.0, -4.0], "type": "Point"}')
# Encoding
- json = ('{"geometry": {"coordinates": [53, -4],'
+ json = ('{"geometry": {"coordinates": [53.0, -4.0],'
' "type": "Point"},'
' "id": "1",'
' "properties":'
@@ -77,7 +77,7 @@ class FeaturesTest(unittest.TestCase):
# Decoding
factory = geojson.examples.create_simple_web_feature
json = ('{"geometry": {"type": "Point",'
- ' "coordinates": [53, -4]},'
+ ' "coordinates": [53.0, -4.0]},'
' "id": "1",'
' "properties": {"summary": "The first feature",'
' "link": "http://example.org/features/1",'
@@ -91,7 +91,7 @@ class FeaturesTest(unittest.TestCase):
self.assertEqual(feature.properties['link'],
'http://example.org/features/1')
self.assertEqual(geojson.dumps(feature.geometry, sort_keys=True),
- '{"coordinates": [53, -4], "type": "Point"}')
+ '{"coordinates": [53.0, -4.0], "type": "Point"}')
def test_geo_interface(self):
class Thingy(object):
@@ -108,12 +108,12 @@ class FeaturesTest(unittest.TestCase):
"geometry": {"type": "Point",
"coordinates": (self.x, self.y)}})
- ob = Thingy('1', 'thingy one', -106, 40)
+ ob = Thingy('1', 'thingy one', -106.0, 40.0)
self.assertEqual(geojson.dumps(ob.__geo_interface__['geometry'],
sort_keys=True),
- '{"coordinates": [-106, 40], "type": "Point"}')
+ '{"coordinates": [-106.0, 40.0], "type": "Point"}')
self.assertEqual(geojson.dumps(ob, sort_keys=True),
- ('{"geometry": {"coordinates": [-106, 40],'
+ ('{"geometry": {"coordinates": [-106.0, 40.0],'
' "type": "Point"},'
' "id": "1",'
' "properties": {"title": "thingy one"}}'))
=====================================
tests/test_geo_interface.py
=====================================
@@ -65,21 +65,21 @@ class EncodingDecodingTest(unittest.TestCase):
properties={'name': self.name})
self.name = "In N Out Burger"
- self.latlng = [-54, 4]
+ self.latlng = [-54.0, 4.0]
self.restaurant_nogeo = Restaurant(self.name, self.latlng)
self.restaurant1 = Restaurant1(self.name, self.latlng)
self.restaurant2 = Restaurant2(self.name, self.latlng)
- self.restaurant_str = ('{"coordinates": [-54, 4],'
+ self.restaurant_str = ('{"coordinates": [-54.0, 4.0],'
' "type": "Point"}')
self.restaurant_feature1 = RestaurantFeature1(self.name, self.latlng)
self.restaurant_feature2 = RestaurantFeature2(self.name, self.latlng)
self.restaurant_feature_str = ('{"geometry":'
- ' {"coordinates": [-54, 4],'
+ ' {"coordinates": [-54.0, 4.0],'
' "type": "Point"},'
' "properties":'
' {"name": "In N Out Burger"},'
@@ -133,15 +133,15 @@ class EncodingDecodingTest(unittest.TestCase):
def test_invalid(self):
with self.assertRaises(ValueError) as cm:
- geojson.loads('{"type":"Point", "coordinates":[[-Infinity, 4]]}')
+ geojson.loads('{"type":"Point", "coordinates":[[-Infinity, 4.0]]}')
self.assertIn('is not JSON compliant', str(cm.exception))
def test_mapping(self):
- self.assertEquals(to_mapping(geojson.Point([1, 2])),
- {"coordinates": [1, 2], "type": "Point"})
+ self.assertEqual(to_mapping(geojson.Point([1.0, 2.0])),
+ {"coordinates": [1.0, 2.0], "type": "Point"})
def test_GeoJSON(self):
- self.assertEquals(None, geojson.GeoJSON().__geo_interface__)
+ self.assertEqual(None, geojson.GeoJSON().__geo_interface__)
- self.assertEquals({"type": "GeoJSON"}, to_mapping(geojson.GeoJSON()))
+ self.assertEqual({"type": "GeoJSON"}, to_mapping(geojson.GeoJSON()))
=====================================
tox.ini
=====================================
@@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
-envlist = py{27,33,34,35,36}, pypy, pypy3
+envlist = py{27,35,36,37}, pypy, pypy3
[testenv]
commands = {envpython} setup.py test
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-geojson/commit/066d8e0935e413611f243139d6315f0f6eb35b33
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-geojson/commit/066d8e0935e413611f243139d6315f0f6eb35b33
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20190719/10d7ebee/attachment-0001.html>
More information about the Pkg-grass-devel
mailing list