Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 546489e

Browse filesBrowse files
authored
Merge pull request #310 from GeospatialPython/combine_iterRecords_range_into_iterRecords
Combine iter records range into iter records
2 parents 7fbbd8e + 763bd33 commit 546489e
Copy full SHA for 546489e

File tree

Expand file treeCollapse file tree

3 files changed

+84
-4
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+84
-4
lines changed

‎README.md

Copy file name to clipboardExpand all lines: README.md
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ part of your geospatial project.
9595

9696
# Version Changes
9797

98+
## 2.3.x
99+
100+
### New Features:
101+
- Reader.iterRecords now allows start and stop to be specified, to lookup smaller ranges of records.
102+
- Equality comparisons between Records now also require the fields to be the same (and in the same order).
103+
104+
### Development:
105+
- Code quality tools run on PyShp
106+
98107
## 2.3.1
99108

100109
### Bug fixes:
@@ -1467,6 +1476,7 @@ Karim Bahgat
14671476
karanrn
14681477
Kurt Schwehr
14691478
Kyle Kelley
1479+
Lionel Guez
14701480
Louis Tiao
14711481
Marcin Cuprjak
14721482
mcuprjak

‎shapefile.py

Copy file name to clipboardExpand all lines: shapefile.py
+29-4Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,12 @@ def __dir__(self):
854854
) # plus field names (random order if Python version < 3.6)
855855
return default + fnames
856856

857+
def __eq__(self, other):
858+
if isinstance(other, self.__class__):
859+
if self.__field_positions != other.__field_positions:
860+
return False
861+
return list.__eq__(self, other)
862+
857863

858864
class ShapeRecord(object):
859865
"""A ShapeRecord object containing a shape along with its attributes.
@@ -1325,7 +1331,9 @@ def __restrictIndex(self, i):
13251331
if self.numRecords:
13261332
rmax = self.numRecords - 1
13271333
if abs(i) > rmax:
1328-
raise IndexError("Shape or Record index out of range.")
1334+
raise IndexError(
1335+
"Shape or Record index: %s out of range. Max index: %s" % (i, rmax)
1336+
)
13291337
if i < 0:
13301338
i = range(self.numRecords)[i]
13311339
return i
@@ -1809,18 +1817,35 @@ def records(self, fields=None):
18091817
records.append(r)
18101818
return records
18111819

1812-
def iterRecords(self, fields=None):
1820+
def iterRecords(self, fields=None, start=0, stop=None):
18131821
"""Returns a generator of records in a dbf file.
18141822
Useful for large shapefiles or dbf files.
18151823
To only read some of the fields, specify the 'fields' arg as a
18161824
list of one or more fieldnames.
1825+
By default yields all records. Otherwise, specify start
1826+
(default: 0) or stop (default: number_of_records)
1827+
to only yield record numbers i, where
1828+
start <= i < stop, (or
1829+
start <= i < number_of_records + stop
1830+
if stop < 0).
18171831
"""
18181832
if self.numRecords is None:
18191833
self.__dbfHeader()
18201834
f = self.__getFileObj(self.dbf)
1821-
f.seek(self.__dbfHdrLength)
1835+
start = self.__restrictIndex(start)
1836+
if stop is None:
1837+
stop = self.numRecords
1838+
elif abs(stop) > self.numRecords:
1839+
raise IndexError(
1840+
"abs(stop): %s exceeds number of records: %s."
1841+
% (abs(stop), self.numRecords)
1842+
)
1843+
elif stop < 0:
1844+
stop = range(self.numRecords)[stop]
1845+
recSize = self.__recordLength
1846+
f.seek(self.__dbfHdrLength + (start * recSize))
18221847
fieldTuples, recLookup, recStruct = self.__recordFields(fields)
1823-
for i in xrange(self.numRecords):
1848+
for i in xrange(start, stop):
18241849
r = self.__record(
18251850
oid=i, fieldTuples=fieldTuples, recLookup=recLookup, recStruct=recStruct
18261851
)

‎test_shapefile.py

Copy file name to clipboardExpand all lines: test_shapefile.py
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,51 @@ def test_record_oid():
972972
assert shaperec.record.oid == i
973973

974974

975+
def test_iterRecords_start_stop():
976+
"""
977+
Assert that Reader.iterRecords(start, stop)
978+
returns the correct records, as if searched for
979+
by index with Reader.record
980+
"""
981+
982+
with shapefile.Reader("shapefiles/blockgroups") as sf:
983+
N = len(sf)
984+
985+
# Arbitrary selection of record indices
986+
# (there are 663 records in blockgroups.dbf).
987+
for i in [
988+
0,
989+
1,
990+
2,
991+
3,
992+
5,
993+
11,
994+
17,
995+
33,
996+
51,
997+
103,
998+
170,
999+
234,
1000+
435,
1001+
543,
1002+
N - 3,
1003+
N - 2,
1004+
N - 1,
1005+
]:
1006+
for record in sf.iterRecords(start=i):
1007+
assert record == sf.record(record.oid)
1008+
1009+
for record in sf.iterRecords(stop=i):
1010+
assert record == sf.record(record.oid)
1011+
1012+
for stop in range(i, len(sf)):
1013+
# test negative indexing from end, as well as
1014+
# positive values of stop, and its default
1015+
for stop_arg in (stop, stop - len(sf)):
1016+
for record in sf.iterRecords(start=i, stop=stop_arg):
1017+
assert record == sf.record(record.oid)
1018+
1019+
9751020
def test_shape_oid():
9761021
"""
9771022
Assert that the shape's oid attribute returns

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.