Skip to content

Commit 5cf41f2

Browse files
authored
Merge pull request #402 from JamesParrott/ShxWriter
Add ShpWriter and ShxWriter. Reduce clutter from tests, by using temp dirs for writing shapefiles.
2 parents 2541af6 + 29f043c commit 5cf41f2

18 files changed

Lines changed: 435 additions & 330 deletions

.github/workflows/run_checks_build_and_test.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,18 @@ jobs:
5757
fail-fast: false
5858
matrix:
5959
python-version: [
60-
"3.9",
61-
"3.10",
62-
"3.11",
63-
"3.12",
64-
"3.13",
6560
"3.14",
61+
"3.13",
62+
"3.12",
6663
"3.15-dev",
64+
"3.11",
65+
"3.10",
66+
"3.9",
6767
]
6868
os: [
69-
"macos-latest",
7069
"ubuntu-24.04",
7170
"windows-latest",
71+
"macos-latest",
7272
]
7373

7474

README.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ Finally, you can use all of the above methods to read shapefiles directly from t
440440

441441

442442
>>> # from a zipped shapefile on website
443-
>>> sf = shapefile.Reader("https://github.com/JamesParrott/PyShp_test_shapefile/raw/main/gis_osm_natural_a_free_1.zip")
443+
>>> sf = shapefile.Reader("https://geodata.ucdavis.edu/gadm/gadm4.1/shp/gadm41_ATA_shp.zip")
444444

445445
>>> # from a shapefile collection of files in a github repository
446446
>>> sf = shapefile.Reader("https://pubs.usgs.gov/of/2000/of00-006/gisdata/coverage/airports.shp")
@@ -940,6 +940,7 @@ length of text values to save space:
940940

941941
>>> r = shapefile.Reader('shapefiles/test/dtype')
942942
>>> assert r.record(0) == ['Hello', 'World', 'World'*50]
943+
>>> r.close()
943944

944945
Date fields are created using the 'D' type, and can be created using either
945946
date objects, lists, or a YYYYMMDD formatted string.
@@ -964,6 +965,7 @@ Field length or decimal have no impact on this type:
964965
>>> assert r.record(1) == [date(1998,1,30)]
965966
>>> assert r.record(2) == [date(1998,1,30)]
966967
>>> assert r.record(3) == [None]
968+
>>> r.close()
967969

968970
Numeric fields are created using the 'N' type (or the 'F' type, which is exactly the same).
969971
By default the fourth decimal argument is set to zero, essentially creating an integer field.
@@ -989,6 +991,7 @@ To store very large numbers you must increase the field length size to the total
989991
>>> r = shapefile.Reader('shapefiles/test/dtype')
990992
>>> assert r.record(0) == [1, 1.32, 1.3217328, -3.2302e-25, 1.3217328, 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]
991993
>>> assert r.record(1) == [None, None, None, None, None, None]
994+
>>> r.close()
992995

993996

994997
Finally, we can create boolean fields by setting the type to 'L'.
@@ -1025,6 +1028,7 @@ None is interpreted as missing.
10251028
Record #4: [None]
10261029
>>> r.record(5)
10271030
Record #5: [None]
1031+
>>> r.close()
10281032

10291033
You can also add attributes using keyword arguments where the keys are field names.
10301034

@@ -1150,6 +1154,7 @@ This can be particularly useful for copying from one file to another:
11501154
... w.record(*shaperec.record)
11511155
... w.shape(shaperec.shape.__geo_interface__)
11521156

1157+
>>> r.close()
11531158
>>> w.close()
11541159

11551160

@@ -1256,7 +1261,7 @@ For reading shapefiles in any non-utf8 encoding, such as Latin-1, just
12561261
supply the encoding option when creating the Reader class.
12571262

12581263

1259-
>>> r = shapefile.Reader("shapefiles/test/latin1.shp", encoding="latin1")
1264+
>>> r = shapefile.Reader("shapefiles/latin1.shp", encoding="latin1")
12601265
>>> r.record(0) == [2, u'Ñandú']
12611266
True
12621267

@@ -1269,21 +1274,24 @@ should give you the same unicode string you started with.
12691274
>>> w.fields = r.fields[1:]
12701275
>>> w.record(*r.record(0))
12711276
>>> w.null()
1277+
>>> r.close()
12721278
>>> w.close()
12731279

12741280
>>> r = shapefile.Reader("shapefiles/test/latin_as_utf8.shp", encoding="utf8")
12751281
>>> r.record(0) == [2, u'Ñandú']
12761282
True
1283+
>>> r.close()
12771284

12781285
If you supply the wrong encoding and the string is unable to be decoded, PyShp will by default raise an
12791286
exception. If however, on rare occasion, you are unable to find the correct encoding and want to ignore
12801287
or replace encoding errors, you can specify the "encodingErrors" to be used by the decode method. This
12811288
applies to both reading and writing.
12821289

12831290

1284-
>>> r = shapefile.Reader("shapefiles/test/latin1.shp", encoding="ascii", encodingErrors="replace")
1291+
>>> r = shapefile.Reader("shapefiles/latin1.shp", encoding="ascii", encodingErrors="replace")
12851292
>>> r.record(0) == [2, u'�and�']
12861293
True
1294+
>>> r.close()
12871295

12881296

12891297

@@ -1297,7 +1305,7 @@ of records and complex geometries.
12971305
As an example, let's load this Natural Earth shapefile of more than 4000 global administrative boundary polygons:
12981306

12991307

1300-
>>> sf = shapefile.Reader("https://github.com/nvkelso/natural-earth-vector/blob/master/10m_cultural/ne_10m_admin_1_states_provinces?raw=true")
1308+
>>> sf = shapefile.Reader("https://archive.org/download/ne_10m_admin_1_states_provinces/ne_10m_admin_1_states_provinces.zip")
13011309

13021310
When first creating the Reader class, the library only reads the header information
13031311
and leaves the rest of the file contents alone. Once you call the records() and shapes()
@@ -1491,6 +1499,8 @@ Shapefiles containing M-values can be examined in several ways:
14911499
>>> r.shape(0).m # flat list of M-values
14921500
[0.0, None, 3.0, None, 0.0, None, None]
14931501

1502+
>>> r.close()
1503+
14941504

14951505
### Shapefiles with elevation (Z) values
14961506

@@ -1524,6 +1534,8 @@ To examine a Z-type shapefile you can do:
15241534
>>> r.shape(0).z # flat list of Z-values
15251535
[18.0, 20.0, 22.0, 0.0, 0.0, 0.0, 0.0, 15.0, 13.0, 14.0]
15261536

1537+
>>> r.close()
1538+
15271539
### 3D MultiPatch Shapefiles
15281540

15291541
Multipatch shapes are useful for storing composite 3-Dimensional objects.
@@ -1583,8 +1595,6 @@ installed) from the test file:
15831595
python test_shapefile.py
15841596
```
15851597

1586-
Linux/Mac and similar platforms may need to run `$ dos2unix README.md` in order
1587-
to correct line endings in README.md, if Git has not automatically changed them.
15881598

15891599
## Network tests
15901600

@@ -1598,7 +1608,7 @@ pytest -m "not network"
15981608
```
15991609
or the doctests via:
16001610
```shell
1601-
python shapefile.py -m "not network"
1611+
python test_shapefile.py -m "not network"
16021612
```
16031613
or ii) by cloning a repo of the files they download, serving these on localhost in a separate process,
16041614
and running the network tests with the environment variable REPLACE_REMOTE_URLS_WITH_LOCALHOST to `yes`:
@@ -1614,7 +1624,7 @@ REPLACE_REMOTE_URLS_WITH_LOCALHOST=yes && pytest
16141624
```
16151625
or the doctests via:
16161626
```bash
1617-
REPLACE_REMOTE_URLS_WITH_LOCALHOST=yes && python shapefile.py
1627+
REPLACE_REMOTE_URLS_WITH_LOCALHOST=yes && python test_shapefile.py
16181628
```
16191629
The network tests alone can also be run (without also running all the tests that don't
16201630
make network requests) using: `pytest -m network` (or the doctests using: `python shapefile.py -m network`).

run_benchmarks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424

2525
blockgroups_file = REPO_ROOT / "shapefiles" / "blockgroups.shp"
26-
edit_file = REPO_ROOT / "shapefiles" / "test" / "edit.shp"
27-
merge_file = REPO_ROOT / "shapefiles" / "test" / "merge.shp"
26+
edit_file = REPO_ROOT / "shapefiles" / "edit.shp"
27+
merge_file = REPO_ROOT / "shapefiles" / "merge.shp"
2828
states_provinces_file = PYSHP_TEST_REPO / "ne_10m_admin_1_states_provinces.shp"
2929
tiny_countries_file = PYSHP_TEST_REPO / "ne_110m_admin_0_tiny_countries.shp"
3030
gis_osm_natural_file = PYSHP_TEST_REPO / "gis_osm_natural_a_free_1.zip"

shapefiles/corrupt_too_long.dbf

580 Bytes
Binary file not shown.

shapefiles/corrupt_too_long.shp

1.12 KB
Binary file not shown.

shapefiles/corrupt_too_long.shx

180 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)