[Git][debian-gis-team/pyshp][upstream] New upstream version 2.1.0+ds

Bas Couwenberg gitlab at salsa.debian.org
Sat Feb 16 07:36:05 GMT 2019


Bas Couwenberg pushed to branch upstream at Debian GIS Project / pyshp


Commits:
ee70dde7 by Bas Couwenberg at 2019-02-16T07:25:48Z
New upstream version 2.1.0+ds
- - - - -


18 changed files:

- PKG-INFO
- README.md
- changelog.txt
- setup.py
- shapefile.py
- shapefiles/test/balancing.dbf
- shapefiles/test/contextwriter.dbf
- shapefiles/test/dtype.dbf
- shapefiles/test/line.dbf
- shapefiles/test/linem.dbf
- shapefiles/test/linez.dbf
- shapefiles/test/multipatch.dbf
- shapefiles/test/multipoint.dbf
- shapefiles/test/onlydbf.dbf
- shapefiles/test/point.dbf
- shapefiles/test/polygon.dbf
- shapefiles/test/shapetype.dbf
- shapefiles/test/testfile.dbf


Changes:

=====================================
PKG-INFO
=====================================
@@ -1,16 +1,15 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
 Name: pyshp
-Version: 2.0.1
+Version: 2.1.0
 Summary: Pure Python read/write support for ESRI Shapefile format
 Home-page: https://github.com/GeospatialPython/pyshp
 Author: Joel Lawhead
 Author-email: jlawhead at geospatialpython.com
 License: MIT
-Download-URL: https://github.com/GeospatialPython/pyshp/archive/2.0.1.tar.gz
-Description-Content-Type: text/markdown
+Download-URL: https://github.com/GeospatialPython/pyshp/archive/2.1.0.tar.gz
 Description: # PyShp
         
-        The Python Shapefile Library (pyshp) reads and writes ESRI Shapefiles in pure Python.
+        The Python Shapefile Library (PyShp) reads and writes ESRI Shapefiles in pure Python.
         
         ![pyshp logo](http://4.bp.blogspot.com/_SBi37QEsCvg/TPQuOhlHQxI/AAAAAAAAAE0/QjFlWfMx0tQ/S350/GSP_Logo.png "PyShp")
         
@@ -48,7 +47,7 @@ Description: # PyShp
         
         # Overview
         
-        The Python Shapefile Library (pyshp) provides read and write support for the
+        The Python Shapefile Library (PyShp) provides read and write support for the
         Esri Shapefile format. The Shapefile format is a popular Geographic
         Information System vector data format created by Esri. For more information
         about this format please read the well-written "ESRI Shapefile Technical
@@ -65,9 +64,9 @@ Description: # PyShp
         
         Pyshp is compatible with Python 2.7-3.x.
         
-        This document provides examples for using pyshp to read and write shapefiles. However 
+        This document provides examples for using PyShp to read and write shapefiles. However 
         many more examples are continually added to the blog [http://GeospatialPython.com](http://GeospatialPython.com),
-        and by searching for pyshp on [https://gis.stackexchange.com](https://gis.stackexchange.com). 
+        and by searching for PyShp on [https://gis.stackexchange.com](https://gis.stackexchange.com). 
         
         Currently the sample census blockgroup shapefile referenced in the examples is available on the GitHub project site at
         [https://github.com/GeospatialPython/pyshp](https://github.com/GeospatialPython/pyshp). These
@@ -84,6 +83,19 @@ Description: # PyShp
         
         # Version Changes
         
+        ## 2.1.0
+        
+        ### New Features:
+        - Added back read/write support for unicode field names. 
+        - Improved Record representation
+        - More support for geojson on Reader, ShapeRecord, ShapeRecords, and shapes()
+        
+        ### Bug fixes:
+        
+        - Fixed error when reading optional m-values
+        - Fixed Record attribute autocomplete in Python 3
+        - Misc readme cleanup
+        
         ## 2.0.0
         
         The newest version of PyShp, version 2.0 introduced some major new improvements. 
@@ -133,7 +145,7 @@ Description: # PyShp
         
         The examples below will use a shapefile created from the U.S. Census Bureau
         Blockgroups data set near San Francisco, CA and available in the git
-        repository of the pyshp GitHub site.
+        repository of the PyShp GitHub site.
         
         ## Reading Shapefiles
         
@@ -173,7 +185,7 @@ Description: # PyShp
         
         You can also load shapefiles from any Python file-like object using keyword
         arguments to specify any of the three files. This feature is very powerful and
-        allows you to load shapefiles from a url, from a zip file, serialized object,
+        allows you to load shapefiles from a url, a zip file, a serialized object,
         or in some cases a database.
         
         
@@ -182,8 +194,8 @@ Description: # PyShp
         	>>> r = shapefile.Reader(shp=myshp, dbf=mydbf)
         
         Notice in the examples above the shx file is never used. The shx file is a
-        very simple fixed-record index for the variable length records in the shp
-        file. This file is optional for reading. If it's available pyshp will use the
+        very simple fixed-record index for the variable-length records in the shp
+        file. This file is optional for reading. If it's available PyShp will use the
         shx file to access shape records a little faster but will do just fine without
         it.
         
@@ -198,8 +210,8 @@ Description: # PyShp
         	5
         
         Shape types are represented by numbers between 0 and 31 as defined by the
-        shapefile specification and listed below. It is important to note that numbering system has
-        several reserved numbers which have not been used yet therefore the numbers of
+        shapefile specification and listed below. It is important to note that the numbering system has
+        several reserved numbers that have not been used yet, therefore the numbers of
         the existing shape types are not sequential:
         
         - NULL = 0
@@ -231,14 +243,22 @@ Description: # PyShp
         	>>> sf.shapeTypeName == 'POLYGON'
         	True
         	
-        Other pieces of meta-data that we can check includes the number of features, 
-        or the bounding box area the shapefile covers:
+        Other pieces of meta-data that we can check include the number of features 
+        and the bounding box area the shapefile covers:
         
         
         	>>> len(sf)
         	663
         	>>> sf.bbox
         	[-122.515048, 37.652916, -122.327622, 37.863433]
+        	
+        Finally, if you would prefer to work with the entire shapefile in a different
+        format, you can convert all of it to a GeoJSON dictionary, although you may lose
+        some information in the process, such as z- and m-values: 
+        
+        
+        	>>> sf.__geo_interface__['type']
+        	'FeatureCollection'
         
         ### Reading Geometry
         
@@ -272,7 +292,8 @@ Description: # PyShp
         	>>> ['%.3f' % coord for coord in s.bbox]
         	['-122.450', '37.801', '-122.442', '37.808']
         
-        Each shape record (except Points) contain the following attributes. Records of shapeType Point do not have a bounding box 'bbox'.
+        Each shape record (except Points) contains the following attributes. Records of
+        shapeType Point do not have a bounding box 'bbox'.
         
         
         	>>> for name in dir(shapes[3]):
@@ -330,7 +351,7 @@ Description: # PyShp
         		>>> ['%.3f' % coord for coord in shape]
         		['-122.471', '37.787']
         
-        In most cases, however, if you need to more than just type or bounds checking, you may want 
+        In most cases, however, if you need to do more than just type or bounds checking, you may want 
         to convert the geometry to the more human-readable [GeoJSON format](http://geojson.org),
         where lines and polygons are grouped for you:
         
@@ -340,11 +361,17 @@ Description: # PyShp
         	>>> geoj["type"]
         	'MultiPolygon'
         	
+        The results from the shapes() method similiarly supports converting to GeoJSON:
+        
+        
+        	>>> shapes.__geo_interface__['type']
+        	'GeometryCollection'
+        	
         
         ### Reading Records
         
         A record in a shapefile contains the attributes for each shape in the
-        collection of geometry. Records are stored in the dbf file. The link between
+        collection of geometries. Records are stored in the dbf file. The link between
         geometry and attributes is the foundation of all geographic information systems.
         This critical link is implied by the order of shapes and corresponding records
         in the shp geometry file and the dbf attribute file.
@@ -459,30 +486,30 @@ Description: # PyShp
         	>>> shapeRecs[3].record[1:3]
         	['060750601001', 4715]
         
-        Now let's read the first two points for that same record:
+        The results from the shapeRecords() method is a list-like object that can be easily converted
+        to GeoJSON through the _\_geo_interface\_\_:
         
         
-        	>>> points = shapeRecs[3].shape.points[0:2]
-        
-        	>>> len(points)
-        	2
+        	>>> shapeRecs.__geo_interface__['type']
+        	'FeatureCollection'
         
         The shapeRecord() method reads a single shape/record pair at the specified index.
         To get the 4th shape record from the blockgroups shapefile use the third index:
         
         
         	>>> shapeRec = sf.shapeRecord(3)
+        	
+        Each individual shape record also supports the _\_geo_interface\_\_ to convert it to a GeoJSON:
+        
+        
+        	>>> shapeRec.__geo_interface__['type']
+        	'Feature'
         
         The blockgroup key and population count:
         
         
         	>>> shapeRec.record[1:3]
         	['060750601001', 4715]
-        
-        	>>> points = shapeRec.shape.points[0:2]
-        
-        	>>> len(points)
-        	2
         	
         
         ## Writing Shapefiles
@@ -676,17 +703,17 @@ Description: # PyShp
         	
         	>>> r = shapefile.Reader('shapefiles/test/dtype')
         	>>> r.record(0)
-        	[True]
+        	Record #0: [True]
         	>>> r.record(1)
-        	[True]
+        	Record #1: [True]
         	>>> r.record(2)
-        	[False]
+        	Record #2: [False]
         	>>> r.record(3)
-        	[False]
+        	Record #3: [False]
         	>>> r.record(4)
-        	[None]
+        	Record #4: [None]
         	>>> r.record(5)
-        	[None]
+        	Record #5: [None]
         	
         You can also add attributes using keyword arguments where the keys are field names.
         
@@ -750,8 +777,8 @@ Description: # PyShp
         	
         **Adding a LineString shape**
         
-        For LineString shapefiles, each line shape consists of multiple lines. Line shapes must be given as a list of lines, 
-        even if there is just one line. Also, each line must have at least two points.
+        For LineString shapefiles, each shape is given as a list of one or more linear features. 
+        Each of the linear features must have at least two points. 
         	
         	
         	>>> w = shapefile.Writer('shapefiles/test/line')
@@ -769,12 +796,13 @@ Description: # PyShp
         **Adding a Polygon shape**
         
         Similarly to LineString, Polygon shapes consist of multiple polygons, and must be given as a list of polygons.
-        The main difference being that polygons must have at least 4 points and the last point must be the same as the first. 
-        It's also okay if you forget to do so, PyShp automatically checks and closes the polygons if you don't. 
+        The main difference is that polygons must have at least 4 points and the last point must be the same as the first. 
+        It's also okay if you forget to repeat the first point at the end; PyShp automatically checks and closes the polygons
+        if you don't.
         
         It's important to note that for Polygon shapefiles, your polygon coordinates must be ordered in a clockwise direction.
         If any of the polygons have holes, then the hole polygon coordinates must be ordered in a counterclockwise direction.
-        The direction of your polygons determines how shapefile readers will distinguish between polygons outlines and holes. 
+        The direction of your polygons determines how shapefile readers will distinguish between polygon outlines and holes. 
         
         
         	>>> w = shapefile.Writer('shapefiles/test/polygon')
@@ -832,7 +860,7 @@ Description: # PyShp
         	>>> w.record("row", "two")
         	>>> w.point(2, 2)
         	
-        To help prevent accidental misalignment pyshp has an "auto balance" feature to
+        To help prevent accidental misalignment PyShp has an "auto balance" feature to
         make sure when you add either a shape or a record the two sides of the
         equation line up. This way if you forget to update an entry the
         shapefile will still be valid and handled correctly by most shapefile
@@ -867,7 +895,7 @@ Description: # PyShp
         	>>> w.recNum == w.shpNum
         	True
         
-        If you do not use the autobalance or balance method and forget to manually
+        If you do not use the autoBalance() or balance() method and forget to manually
         balance the geometry and attributes the shapefile will be viewed as corrupt by
         most shapefile software.
         	
@@ -877,17 +905,18 @@ Description: # PyShp
         
         ## 3D and Other Geometry Types
         
-        Most shapefiles store conventional 2D points, lines, or polygons. But the shapefile format is also capable of storing
-        various other types of geometries as well, including complex 3D surfaces and objects. 
+        Most shapefiles store conventional 2D points, lines, or polygons. But the shapefile format is also capable
+        of storing various other types of geometries as well, including complex 3D surfaces and objects. 
         
         **Shapefiles with measurement (M) values**
         
-        Measured shape types are shapes that include a measurement value at each vertex, for instance speed measurements from a GPS device. 
-        Shapes with measurement (M) values are added with following methods: "pointm", "multipointm", "linem", and "polygonm". 
-        The M-values are specified by adding a third M value to each XY coordinate. Missing or unobserved M-values are specified with a None value,
-        or by simply omitting the third M-coordinate. 
-        	
-        	
+        Measured shape types are shapes that include a measurement value at each vertex, for instance
+        speed measurements from a GPS device. Shapes with measurement (M) values are added with the following
+        methods: "pointm", "multipointm", "linem", and "polygonm". The M-values are specified by adding a
+        third M value to each XY coordinate. Missing or unobserved M-values are specified with a None value,
+        or by simply omitting the third M-coordinate.
+        
+        
         	>>> w = shapefile.Writer('shapefiles/test/linem')
         	>>> w.field('name', 'C')
         	
@@ -904,17 +933,17 @@ Description: # PyShp
         
         	>>> r = shapefile.Reader('shapefiles/test/linem')
         	
-        	>>> r.mbox # the lower and upper bound of M values in the shapefile
+        	>>> r.mbox # the lower and upper bound of M-values in the shapefile
         	[0.0, 3.0]
         	
-        	>>> r.shape(0).m # flat list of M values
+        	>>> r.shape(0).m # flat list of M-values
         	[0.0, None, 3.0, None, 0.0, None, None]
         
         	
         **Shapefiles with elevation (Z) values**
         
         Elevation shape types are shapes that include an elevation value at each vertex, for instance elevation from a GPS device. 
-        Shapes with an elevation (Z) values are added with following methods: "pointz", "multipointz", "linez", and "polygonz". 
+        Shapes with elevation (Z) values are added with the following methods: "pointz", "multipointz", "linez", and "polygonz". 
         The Z-values are specified by adding a third Z value to each XY coordinate. Z-values do not support the concept of missing data,
         but if you omit the third Z-coordinate it will default to 0. Note that Z-type shapes also support measurement (M) values added
         as a fourth M-coordinate. This too is optional. 
@@ -926,7 +955,7 @@ Description: # PyShp
         	>>> w.linez([
         	...			[[1,5,18],[5,5,20],[5,1,22],[3,3],[1,1]], # line with some omitted Z-values
         	...			[[3,2],[2,6]], # line without any Z-values
-        	...			[[3,2,15,0],[2,6,13,3],[1,9,14,2]] # line with both Z and M-values
+        	...			[[3,2,15,0],[2,6,13,3],[1,9,14,2]] # line with both Z- and M-values
         	...			])
         	
         	>>> w.record('linez1')
@@ -937,17 +966,17 @@ Description: # PyShp
         
         	>>> r = shapefile.Reader('shapefiles/test/linez')
         	
-        	>>> r.zbox # the lower and upper bound of Z values in the shapefile
+        	>>> r.zbox # the lower and upper bound of Z-values in the shapefile
         	[0.0, 22.0]
         	
-        	>>> r.shape(0).z # flat list of Z values
+        	>>> r.shape(0).z # flat list of Z-values
         	[18.0, 20.0, 22.0, 0.0, 0.0, 0.0, 0.0, 15.0, 13.0, 14.0]
         
         **3D MultiPatch Shapefiles**
         
         Multipatch shapes are useful for storing composite 3-Dimensional objects. 
         A MultiPatch shape represents a 3D object made up of one or more surface parts.
-        Each surface in "parts" is defined by a list of XYZM values (Z and M values optional), and its corresponding type
+        Each surface in "parts" is defined by a list of XYZM values (Z and M values optional), and its corresponding type is
         given in the "partTypes" argument. The part type decides how the coordinate sequence is to be interpreted, and can be one 
         of the following module constants: TRIANGLE_STRIP, TRIANGLE_FAN, OUTER_RING, INNER_RING, FIRST_RING, or RING.
         For instance, a TRIANGLE_STRIP may be used to represent the walls of a building, combined with a TRIANGLE_FAN to represent 
@@ -1011,7 +1040,7 @@ Description: # PyShp
         
         This means that as long as you are able to iterate through a source file without having
         to load everything into memory, such as a large CSV table or a large shapefile, you can 
-        process and write any number of items, and even merging many different source files into a single 
+        process and write any number of items, and even merge many different source files into a single 
         large shapefile. If you need to edit or undo any of your writing you would have to read the 
         file back in, one record at a time, make your changes, and write it back out. 
         
@@ -1075,6 +1104,7 @@ Description: # PyShp
         David A. Riggs
         davidh-ssec
         Evan Heidtmann
+        ezcitron
         geospatialpython
         Hannes
         Ignacio Martinez Vazquez
@@ -1088,6 +1118,7 @@ Description: # PyShp
         Michal Čihař
         Mike Toews
         Nilo
+        pakoun
         Paulo Ernesto
         Raynor Vliegendhart
         Razzi Abuissa
@@ -1108,3 +1139,4 @@ Classifier: Topic :: Scientific/Engineering :: GIS
 Classifier: Topic :: Software Development :: Libraries
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Requires-Python: >= 2.7
+Description-Content-Type: text/markdown


=====================================
README.md
=====================================
@@ -1,6 +1,6 @@
 # PyShp
 
-The Python Shapefile Library (pyshp) reads and writes ESRI Shapefiles in pure Python.
+The Python Shapefile Library (PyShp) reads and writes ESRI Shapefiles in pure Python.
 
 ![pyshp logo](http://4.bp.blogspot.com/_SBi37QEsCvg/TPQuOhlHQxI/AAAAAAAAAE0/QjFlWfMx0tQ/S350/GSP_Logo.png "PyShp")
 
@@ -38,7 +38,7 @@ The Python Shapefile Library (pyshp) reads and writes ESRI Shapefiles in pure Py
 
 # Overview
 
-The Python Shapefile Library (pyshp) provides read and write support for the
+The Python Shapefile Library (PyShp) provides read and write support for the
 Esri Shapefile format. The Shapefile format is a popular Geographic
 Information System vector data format created by Esri. For more information
 about this format please read the well-written "ESRI Shapefile Technical
@@ -55,9 +55,9 @@ despite the numerous ways to store and exchange GIS data available today.
 
 Pyshp is compatible with Python 2.7-3.x.
 
-This document provides examples for using pyshp to read and write shapefiles. However 
+This document provides examples for using PyShp to read and write shapefiles. However 
 many more examples are continually added to the blog [http://GeospatialPython.com](http://GeospatialPython.com),
-and by searching for pyshp on [https://gis.stackexchange.com](https://gis.stackexchange.com). 
+and by searching for PyShp on [https://gis.stackexchange.com](https://gis.stackexchange.com). 
 
 Currently the sample census blockgroup shapefile referenced in the examples is available on the GitHub project site at
 [https://github.com/GeospatialPython/pyshp](https://github.com/GeospatialPython/pyshp). These
@@ -74,6 +74,19 @@ part of your geospatial project.
 
 # Version Changes
 
+## 2.1.0
+
+### New Features:
+- Added back read/write support for unicode field names. 
+- Improved Record representation
+- More support for geojson on Reader, ShapeRecord, ShapeRecords, and shapes()
+
+### Bug fixes:
+
+- Fixed error when reading optional m-values
+- Fixed Record attribute autocomplete in Python 3
+- Misc readme cleanup
+
 ## 2.0.0
 
 The newest version of PyShp, version 2.0 introduced some major new improvements. 
@@ -123,7 +136,7 @@ Before doing anything you must import the library.
 
 The examples below will use a shapefile created from the U.S. Census Bureau
 Blockgroups data set near San Francisco, CA and available in the git
-repository of the pyshp GitHub site.
+repository of the PyShp GitHub site.
 
 ## Reading Shapefiles
 
@@ -163,7 +176,7 @@ objects are properly closed when done reading the data:
 
 You can also load shapefiles from any Python file-like object using keyword
 arguments to specify any of the three files. This feature is very powerful and
-allows you to load shapefiles from a url, from a zip file, serialized object,
+allows you to load shapefiles from a url, a zip file, a serialized object,
 or in some cases a database.
 
 
@@ -172,8 +185,8 @@ or in some cases a database.
 	>>> r = shapefile.Reader(shp=myshp, dbf=mydbf)
 
 Notice in the examples above the shx file is never used. The shx file is a
-very simple fixed-record index for the variable length records in the shp
-file. This file is optional for reading. If it's available pyshp will use the
+very simple fixed-record index for the variable-length records in the shp
+file. This file is optional for reading. If it's available PyShp will use the
 shx file to access shape records a little faster but will do just fine without
 it.
 
@@ -188,8 +201,8 @@ shapeType attribute.
 	5
 
 Shape types are represented by numbers between 0 and 31 as defined by the
-shapefile specification and listed below. It is important to note that numbering system has
-several reserved numbers which have not been used yet therefore the numbers of
+shapefile specification and listed below. It is important to note that the numbering system has
+several reserved numbers that have not been used yet, therefore the numbers of
 the existing shape types are not sequential:
 
 - NULL = 0
@@ -221,14 +234,22 @@ For convenience, you can also get the name of the shape type as a string:
 	>>> sf.shapeTypeName == 'POLYGON'
 	True
 	
-Other pieces of meta-data that we can check includes the number of features, 
-or the bounding box area the shapefile covers:
+Other pieces of meta-data that we can check include the number of features 
+and the bounding box area the shapefile covers:
 
 
 	>>> len(sf)
 	663
 	>>> sf.bbox
 	[-122.515048, 37.652916, -122.327622, 37.863433]
+	
+Finally, if you would prefer to work with the entire shapefile in a different
+format, you can convert all of it to a GeoJSON dictionary, although you may lose
+some information in the process, such as z- and m-values: 
+
+
+	>>> sf.__geo_interface__['type']
+	'FeatureCollection'
 
 ### Reading Geometry
 
@@ -262,7 +283,8 @@ index which is 7.
 	>>> ['%.3f' % coord for coord in s.bbox]
 	['-122.450', '37.801', '-122.442', '37.808']
 
-Each shape record (except Points) contain the following attributes. Records of shapeType Point do not have a bounding box 'bbox'.
+Each shape record (except Points) contains the following attributes. Records of
+shapeType Point do not have a bounding box 'bbox'.
 
 
 	>>> for name in dir(shapes[3]):
@@ -320,7 +342,7 @@ Each shape record (except Points) contain the following attributes. Records of s
 		>>> ['%.3f' % coord for coord in shape]
 		['-122.471', '37.787']
 
-In most cases, however, if you need to more than just type or bounds checking, you may want 
+In most cases, however, if you need to do more than just type or bounds checking, you may want 
 to convert the geometry to the more human-readable [GeoJSON format](http://geojson.org),
 where lines and polygons are grouped for you:
 
@@ -330,11 +352,17 @@ where lines and polygons are grouped for you:
 	>>> geoj["type"]
 	'MultiPolygon'
 	
+The results from the shapes() method similiarly supports converting to GeoJSON:
+
+
+	>>> shapes.__geo_interface__['type']
+	'GeometryCollection'
+	
 
 ### Reading Records
 
 A record in a shapefile contains the attributes for each shape in the
-collection of geometry. Records are stored in the dbf file. The link between
+collection of geometries. Records are stored in the dbf file. The link between
 geometry and attributes is the foundation of all geographic information systems.
 This critical link is implied by the order of shapes and corresponding records
 in the shp geometry file and the dbf attribute file.
@@ -449,30 +477,30 @@ Let's read the blockgroup key and the population for the 4th blockgroup:
 	>>> shapeRecs[3].record[1:3]
 	['060750601001', 4715]
 
-Now let's read the first two points for that same record:
+The results from the shapeRecords() method is a list-like object that can be easily converted
+to GeoJSON through the _\_geo_interface\_\_:
 
 
-	>>> points = shapeRecs[3].shape.points[0:2]
-
-	>>> len(points)
-	2
+	>>> shapeRecs.__geo_interface__['type']
+	'FeatureCollection'
 
 The shapeRecord() method reads a single shape/record pair at the specified index.
 To get the 4th shape record from the blockgroups shapefile use the third index:
 
 
 	>>> shapeRec = sf.shapeRecord(3)
+	
+Each individual shape record also supports the _\_geo_interface\_\_ to convert it to a GeoJSON:
+
+
+	>>> shapeRec.__geo_interface__['type']
+	'Feature'
 
 The blockgroup key and population count:
 
 
 	>>> shapeRec.record[1:3]
 	['060750601001', 4715]
-
-	>>> points = shapeRec.shape.points[0:2]
-
-	>>> len(points)
-	2
 	
 
 ## Writing Shapefiles
@@ -666,17 +694,17 @@ None is interpreted as missing.
 	
 	>>> r = shapefile.Reader('shapefiles/test/dtype')
 	>>> r.record(0)
-	[True]
+	Record #0: [True]
 	>>> r.record(1)
-	[True]
+	Record #1: [True]
 	>>> r.record(2)
-	[False]
+	Record #2: [False]
 	>>> r.record(3)
-	[False]
+	Record #3: [False]
 	>>> r.record(4)
-	[None]
+	Record #4: [None]
 	>>> r.record(5)
-	[None]
+	Record #5: [None]
 	
 You can also add attributes using keyword arguments where the keys are field names.
 
@@ -740,8 +768,8 @@ These are specified as a list of xy point coordinates.
 	
 **Adding a LineString shape**
 
-For LineString shapefiles, each line shape consists of multiple lines. Line shapes must be given as a list of lines, 
-even if there is just one line. Also, each line must have at least two points.
+For LineString shapefiles, each shape is given as a list of one or more linear features. 
+Each of the linear features must have at least two points. 
 	
 	
 	>>> w = shapefile.Writer('shapefiles/test/line')
@@ -759,12 +787,13 @@ even if there is just one line. Also, each line must have at least two points.
 **Adding a Polygon shape**
 
 Similarly to LineString, Polygon shapes consist of multiple polygons, and must be given as a list of polygons.
-The main difference being that polygons must have at least 4 points and the last point must be the same as the first. 
-It's also okay if you forget to do so, PyShp automatically checks and closes the polygons if you don't. 
+The main difference is that polygons must have at least 4 points and the last point must be the same as the first. 
+It's also okay if you forget to repeat the first point at the end; PyShp automatically checks and closes the polygons
+if you don't.
 
 It's important to note that for Polygon shapefiles, your polygon coordinates must be ordered in a clockwise direction.
 If any of the polygons have holes, then the hole polygon coordinates must be ordered in a counterclockwise direction.
-The direction of your polygons determines how shapefile readers will distinguish between polygons outlines and holes. 
+The direction of your polygons determines how shapefile readers will distinguish between polygon outlines and holes. 
 
 
 	>>> w = shapefile.Writer('shapefiles/test/polygon')
@@ -822,7 +851,7 @@ data lines up with the geometry data. For example:
 	>>> w.record("row", "two")
 	>>> w.point(2, 2)
 	
-To help prevent accidental misalignment pyshp has an "auto balance" feature to
+To help prevent accidental misalignment PyShp has an "auto balance" feature to
 make sure when you add either a shape or a record the two sides of the
 equation line up. This way if you forget to update an entry the
 shapefile will still be valid and handled correctly by most shapefile
@@ -857,7 +886,7 @@ You can create all of the shapes and then create all of the records or vice vers
 	>>> w.recNum == w.shpNum
 	True
 
-If you do not use the autobalance or balance method and forget to manually
+If you do not use the autoBalance() or balance() method and forget to manually
 balance the geometry and attributes the shapefile will be viewed as corrupt by
 most shapefile software.
 	
@@ -867,17 +896,18 @@ most shapefile software.
 
 ## 3D and Other Geometry Types
 
-Most shapefiles store conventional 2D points, lines, or polygons. But the shapefile format is also capable of storing
-various other types of geometries as well, including complex 3D surfaces and objects. 
+Most shapefiles store conventional 2D points, lines, or polygons. But the shapefile format is also capable
+of storing various other types of geometries as well, including complex 3D surfaces and objects. 
 
 **Shapefiles with measurement (M) values**
 
-Measured shape types are shapes that include a measurement value at each vertex, for instance speed measurements from a GPS device. 
-Shapes with measurement (M) values are added with following methods: "pointm", "multipointm", "linem", and "polygonm". 
-The M-values are specified by adding a third M value to each XY coordinate. Missing or unobserved M-values are specified with a None value,
-or by simply omitting the third M-coordinate. 
-	
-	
+Measured shape types are shapes that include a measurement value at each vertex, for instance
+speed measurements from a GPS device. Shapes with measurement (M) values are added with the following
+methods: "pointm", "multipointm", "linem", and "polygonm". The M-values are specified by adding a
+third M value to each XY coordinate. Missing or unobserved M-values are specified with a None value,
+or by simply omitting the third M-coordinate.
+
+
 	>>> w = shapefile.Writer('shapefiles/test/linem')
 	>>> w.field('name', 'C')
 	
@@ -894,17 +924,17 @@ Shapefiles containing M-values can be examined in several ways:
 
 	>>> r = shapefile.Reader('shapefiles/test/linem')
 	
-	>>> r.mbox # the lower and upper bound of M values in the shapefile
+	>>> r.mbox # the lower and upper bound of M-values in the shapefile
 	[0.0, 3.0]
 	
-	>>> r.shape(0).m # flat list of M values
+	>>> r.shape(0).m # flat list of M-values
 	[0.0, None, 3.0, None, 0.0, None, None]
 
 	
 **Shapefiles with elevation (Z) values**
 
 Elevation shape types are shapes that include an elevation value at each vertex, for instance elevation from a GPS device. 
-Shapes with an elevation (Z) values are added with following methods: "pointz", "multipointz", "linez", and "polygonz". 
+Shapes with elevation (Z) values are added with the following methods: "pointz", "multipointz", "linez", and "polygonz". 
 The Z-values are specified by adding a third Z value to each XY coordinate. Z-values do not support the concept of missing data,
 but if you omit the third Z-coordinate it will default to 0. Note that Z-type shapes also support measurement (M) values added
 as a fourth M-coordinate. This too is optional. 
@@ -916,7 +946,7 @@ as a fourth M-coordinate. This too is optional.
 	>>> w.linez([
 	...			[[1,5,18],[5,5,20],[5,1,22],[3,3],[1,1]], # line with some omitted Z-values
 	...			[[3,2],[2,6]], # line without any Z-values
-	...			[[3,2,15,0],[2,6,13,3],[1,9,14,2]] # line with both Z and M-values
+	...			[[3,2,15,0],[2,6,13,3],[1,9,14,2]] # line with both Z- and M-values
 	...			])
 	
 	>>> w.record('linez1')
@@ -927,17 +957,17 @@ To examine a Z-type shapefile you can do:
 
 	>>> r = shapefile.Reader('shapefiles/test/linez')
 	
-	>>> r.zbox # the lower and upper bound of Z values in the shapefile
+	>>> r.zbox # the lower and upper bound of Z-values in the shapefile
 	[0.0, 22.0]
 	
-	>>> r.shape(0).z # flat list of Z values
+	>>> r.shape(0).z # flat list of Z-values
 	[18.0, 20.0, 22.0, 0.0, 0.0, 0.0, 0.0, 15.0, 13.0, 14.0]
 
 **3D MultiPatch Shapefiles**
 
 Multipatch shapes are useful for storing composite 3-Dimensional objects. 
 A MultiPatch shape represents a 3D object made up of one or more surface parts.
-Each surface in "parts" is defined by a list of XYZM values (Z and M values optional), and its corresponding type
+Each surface in "parts" is defined by a list of XYZM values (Z and M values optional), and its corresponding type is
 given in the "partTypes" argument. The part type decides how the coordinate sequence is to be interpreted, and can be one 
 of the following module constants: TRIANGLE_STRIP, TRIANGLE_FAN, OUTER_RING, INNER_RING, FIRST_RING, or RING.
 For instance, a TRIANGLE_STRIP may be used to represent the walls of a building, combined with a TRIANGLE_FAN to represent 
@@ -1001,7 +1031,7 @@ the file.
 
 This means that as long as you are able to iterate through a source file without having
 to load everything into memory, such as a large CSV table or a large shapefile, you can 
-process and write any number of items, and even merging many different source files into a single 
+process and write any number of items, and even merge many different source files into a single 
 large shapefile. If you need to edit or undo any of your writing you would have to read the 
 file back in, one record at a time, make your changes, and write it back out. 
 
@@ -1065,6 +1095,7 @@ Charles Arnold
 David A. Riggs
 davidh-ssec
 Evan Heidtmann
+ezcitron
 geospatialpython
 Hannes
 Ignacio Martinez Vazquez
@@ -1078,6 +1109,7 @@ Michael Davis
 Michal Čihař
 Mike Toews
 Nilo
+pakoun
 Paulo Ernesto
 Raynor Vliegendhart
 Razzi Abuissa


=====================================
changelog.txt
=====================================
@@ -1,4 +1,17 @@
 
+VERSION 2.1.0
+
+2019-02-15
+	New Features:
+	* Added back read/write support for unicode field names. 
+	* Improved Record representation
+	* More support for geojson on Reader, ShapeRecord, ShapeRecords, and shapes()
+
+	Bug fixes:
+	* Fixed error when reading optional m-values
+	* Fixed Record attribute autocomplete in Python 3
+	* Misc readme cleanup
+
 VERSION 2.0.1
 
 2018-11-05


=====================================
setup.py
=====================================
@@ -7,14 +7,14 @@ def read_file(file):
     return data.decode('utf-8')
 
 setup(name='pyshp',
-      version='2.0.1',
+      version='2.1.0',
       description='Pure Python read/write support for ESRI Shapefile format',
       long_description=read_file('README.md'),
       long_description_content_type='text/markdown',
       author='Joel Lawhead',
       author_email='jlawhead at geospatialpython.com',
       url='https://github.com/GeospatialPython/pyshp',
-      download_url='https://github.com/GeospatialPython/pyshp/archive/2.0.1.tar.gz',
+      download_url='https://github.com/GeospatialPython/pyshp/archive/2.1.0.tar.gz',
       py_modules=['shapefile'],
       license='MIT',
       zip_safe=False,


=====================================
shapefile.py
=====================================
@@ -2,11 +2,11 @@
 shapefile.py
 Provides read and write support for ESRI Shapefiles.
 author: jlawhead<at>geospatialpython.com
-version: 2.0.1
+version: 2.1.0
 Compatible with Python versions 2.7-3.x
 """
 
-__version__ = "2.0.1"
+__version__ = "2.1.0"
 
 from struct import pack, unpack, calcsize, error, Struct
 import os
@@ -457,8 +457,8 @@ class _Record(list):
         """
         return dict((f, self[i]) for f, i in self.__field_positions.items())
 
-    def __str__(self):
-        return 'Record #{} '.format(self.__oid)
+    def __repr__(self):
+        return 'Record #{}: {}'.format(self.__oid, list(self))
 
     def __dir__(self):
         """
@@ -467,15 +467,51 @@ class _Record(list):
 
         :return: List of method names and fields
         """
-        attrs = [attr for attr in vars(type(self)) if not attr.startswith('_')]
-        return attrs + self.__field_positions.values() # plus field names (random order)
+        default = list(dir(type(self))) # default list methods and attributes of this class
+        fnames = list(self.__field_positions.keys()) # plus field names (random order)
+        return default + fnames 
         
 class ShapeRecord(object):
-    """A ShapeRecord object containing a shape along with its attributes."""
+    """A ShapeRecord object containing a shape along with its attributes.
+    Provides the GeoJSON __geo_interface__ to return a Feature dictionary."""
     def __init__(self, shape=None, record=None):
         self.shape = shape
         self.record = record
 
+    @property
+    def __geo_interface__(self):
+        return {'type': 'Feature',
+                'properties': self.record.as_dict(),
+                'geometry': self.shape.__geo_interface__}
+
+class Shapes(list):
+    """A class to hold a list of Shape objects. Subclasses list to ensure compatibility with
+    former work and allows to use all the optimazations of the builtin list.
+    In addition to the list interface, this also provides the GeoJSON __geo_interface__
+    to return a GeometryCollection dictionary. """
+
+    def __repr__(self):
+        return 'Shapes: {}'.format(list(self))
+
+    @property
+    def __geo_interface__(self):
+        return {'type': 'GeometryCollection',
+                'geometries': [g.__geo_interface__ for g in self]}
+
+class ShapeRecords(list):
+    """A class to hold a list of ShapeRecord objects. Subclasses list to ensure compatibility with
+    former work and allows to use all the optimazations of the builtin list.
+    In addition to the list interface, this also provides the GeoJSON __geo_interface__
+    to return a FeatureCollection dictionary. """
+
+    def __repr__(self):
+        return 'ShapeRecords: {}'.format(list(self))
+
+    @property
+    def __geo_interface__(self):
+        return {'type': 'FeatureCollection',
+                'features': [f.__geo_interface__ for f in self]}
+
 class ShapefileException(Exception):
     """An exception to handle shapefile specific problems."""
     pass
@@ -585,9 +621,7 @@ class Reader(object):
         features = []
         for feat in self.iterShapeRecords():
             fdict = {'type': 'Feature',
-                     'properties': dict(*zip(fieldnames,
-                                             list(feat.record)
-                                             )),
+                     'properties': dict(zip(fieldnames,feat.record)),
                      'geometry': feat.shape.__geo_interface__}
             features.append(fdict)
         return {'type': 'FeatureCollection',
@@ -748,14 +782,18 @@ class Reader(object):
             record.z = _Array('d', unpack("<%sd" % nPoints, f.read(nPoints * 8)))
         # Read m extremes and values
         if shapeType in (13,15,18,23,25,28,31):
-            (mmin, mmax) = unpack("<2d", f.read(16))
+            if next - f.tell() >= 16:
+                (mmin, mmax) = unpack("<2d", f.read(16))
             # Measure values less than -10e38 are nodata values according to the spec
-            record.m = []
-            for m in _Array('d', unpack("<%sd" % nPoints, f.read(nPoints * 8))):
-                if m > NODATA:
-                    record.m.append(m)
-                else:
-                    record.m.append(None)
+            if next - f.tell() >= nPoints * 8:
+                record.m = []
+                for m in _Array('d', unpack("<%sd" % nPoints, f.read(nPoints * 8))):
+                    if m > NODATA:
+                        record.m.append(m)
+                    else:
+                        record.m.append(None)
+            else:
+                record.m = [None for _ in range(nPoints)]
         # Read a single point
         if shapeType in (1,11,21):
             record.points = [_Array('d', unpack("<2d", f.read(16)))]
@@ -763,8 +801,11 @@ class Reader(object):
         if shapeType == 11:
             record.z = list(unpack("<d", f.read(8)))
         # Read a single M value
-        if shapeType == 21 or (shapeType == 11 and f.tell() < next):
-            (m,) = unpack("<d", f.read(8))
+        if shapeType in (21,11):
+            if next - f.tell() >= 8:
+                (m,) = unpack("<d", f.read(8))
+            else:
+                m = NODATA
             # Measure values less than -10e38 are nodata values according to the spec
             if m > NODATA:
                 record.m = [m]
@@ -822,7 +863,7 @@ class Reader(object):
         shp.seek(0,2)
         self.shpLength = shp.tell()
         shp.seek(100)
-        shapes = []
+        shapes = Shapes()
         while shp.tell() < self.shpLength:
             shapes.append(self.__shape())
         return shapes
@@ -856,9 +897,9 @@ class Reader(object):
             else:
                 idx = len(fieldDesc[name]) - 1
             fieldDesc[name] = fieldDesc[name][:idx]
-            fieldDesc[name] = u(fieldDesc[name], "ascii")
+            fieldDesc[name] = u(fieldDesc[name], self.encoding, self.encodingErrors)
             fieldDesc[name] = fieldDesc[name].lstrip()
-            fieldDesc[1] = u(fieldDesc[1], "ascii")
+            fieldDesc[1] = u(fieldDesc[1], 'ascii')
             self.fields.append(fieldDesc)
         terminator = dbf.read(1)
         if terminator != b"\r":
@@ -994,9 +1035,8 @@ class Reader(object):
     def shapeRecords(self):
         """Returns a list of combination geometry/attribute records for
         all records in a shapefile."""
-        shapeRecords = []
-        return [ShapeRecord(shape=rec[0], record=rec[1]) \
-                                for rec in zip(self.shapes(), self.records())]
+        return ShapeRecords([ShapeRecord(shape=rec[0], record=rec[1]) \
+                                for rec in zip(self.shapes(), self.records())])
 
     def iterShapeRecords(self):
         """Returns a generator of combination geometry/attribute records for
@@ -1269,7 +1309,7 @@ class Writer(object):
         year -= 1900
         # Remove deletion flag placeholder from fields
         for field in self.fields:
-            if str(field[0]).startswith("Deletion"):
+            if field[0].startswith("Deletion"):
                 self.fields.remove(field)
         numRecs = self.recNum
         numFields = len(self.fields)
@@ -1284,10 +1324,10 @@ class Writer(object):
         # Field descriptors
         for field in self.fields:
             name, fieldType, size, decimal = field
-            name = b(name, 'ascii', self.encodingErrors)
+            name = b(name, self.encoding, self.encodingErrors)
             name = name.replace(b' ', b'_')
             name = name.ljust(11).replace(b' ', b'\x00')
-            fieldType = b(fieldType, 'ascii', self.encodingErrors)
+            fieldType = b(fieldType, 'ascii')
             size = int(size)
             fld = pack('<11sc4xBB14x', name, fieldType, size, decimal)
             f.write(fld)
@@ -1833,7 +1873,7 @@ def test(**kwargs):
     # run tests
     runner = doctest.DocTestRunner(checker=Py23DocChecker(), verbose=verbosity)
     with open("README.md","rb") as fobj:
-        test = doctest.DocTestParser().get_doctest(string=fobj.read().decode("utf8"), globs={}, name="README", filename="README.md", lineno=0)
+        test = doctest.DocTestParser().get_doctest(string=fobj.read().decode("utf8").replace('\r\n','\n'), globs={}, name="README", filename="README.md", lineno=0)
     failure_count, test_count = runner.run(test)
 
     # print results


=====================================
shapefiles/test/balancing.dbf
=====================================
Binary files a/shapefiles/test/balancing.dbf and b/shapefiles/test/balancing.dbf differ


=====================================
shapefiles/test/contextwriter.dbf
=====================================
Binary files a/shapefiles/test/contextwriter.dbf and b/shapefiles/test/contextwriter.dbf differ


=====================================
shapefiles/test/dtype.dbf
=====================================
Binary files a/shapefiles/test/dtype.dbf and b/shapefiles/test/dtype.dbf differ


=====================================
shapefiles/test/line.dbf
=====================================
Binary files a/shapefiles/test/line.dbf and b/shapefiles/test/line.dbf differ


=====================================
shapefiles/test/linem.dbf
=====================================
Binary files a/shapefiles/test/linem.dbf and b/shapefiles/test/linem.dbf differ


=====================================
shapefiles/test/linez.dbf
=====================================
Binary files a/shapefiles/test/linez.dbf and b/shapefiles/test/linez.dbf differ


=====================================
shapefiles/test/multipatch.dbf
=====================================
Binary files a/shapefiles/test/multipatch.dbf and b/shapefiles/test/multipatch.dbf differ


=====================================
shapefiles/test/multipoint.dbf
=====================================
Binary files a/shapefiles/test/multipoint.dbf and b/shapefiles/test/multipoint.dbf differ


=====================================
shapefiles/test/onlydbf.dbf
=====================================
Binary files a/shapefiles/test/onlydbf.dbf and b/shapefiles/test/onlydbf.dbf differ


=====================================
shapefiles/test/point.dbf
=====================================
Binary files a/shapefiles/test/point.dbf and b/shapefiles/test/point.dbf differ


=====================================
shapefiles/test/polygon.dbf
=====================================
Binary files a/shapefiles/test/polygon.dbf and b/shapefiles/test/polygon.dbf differ


=====================================
shapefiles/test/shapetype.dbf
=====================================
Binary files a/shapefiles/test/shapetype.dbf and b/shapefiles/test/shapetype.dbf differ


=====================================
shapefiles/test/testfile.dbf
=====================================
Binary files a/shapefiles/test/testfile.dbf and b/shapefiles/test/testfile.dbf differ



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyshp/commit/ee70dde779494d63c6fd5ade2b02621a4c72951d

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyshp/commit/ee70dde779494d63c6fd5ade2b02621a4c72951d
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/20190216/546cc75e/attachment-0001.html>


More information about the Pkg-grass-devel mailing list