├── .eslintrc.js
├── .gitignore
├── .npmignore
├── LICENSE.md
├── README.md
├── dist
├── shp.esm.js
├── shp.esm.min.js
├── shp.js
└── shp.min.js
├── files
├── Readme.txt
├── TM_WORLD_BORDERS_SIMPL-0.3.dbf
├── TM_WORLD_BORDERS_SIMPL-0.3.shp
├── TM_WORLD_BORDERS_SIMPL-0.3.shx
├── TM_WORLD_BORDERS_SIMPL-0.3.zip
├── counties5.zip
├── empty-shp.zip
├── maSP.zip
├── nj_counties.zip
├── nj_muni.zip
├── pandr.dbf
├── pandr.prj
├── pandr.qpj
├── pandr.sbn
├── pandr.sbx
├── pandr.shp
├── pandr.shp.xml
├── pandr.shx
└── pandr.zip
├── index.html
├── lib
├── binaryajax.js
├── browser.js
├── combine.js
├── index.js
├── parseShp.js
└── unzip.js
├── package.json
├── rollup.config.js
├── site
├── catiline.js
├── curl.js
├── gh-fork-ribbon.css
├── images
│ ├── layers-2x.png
│ ├── layers.png
│ ├── marker-icon-2x.png
│ ├── marker-icon.png
│ └── marker-shadow.png
├── leaflet.css
├── leaflet.ie.css
├── leaflet.js
├── leaflet.zip
├── map.html
├── proj-small.html
├── proj.html
└── require.js
└── test
├── bundle.js
├── data
├── LGA_2013_AUST.cpg
├── LGA_2013_AUST.dbf
├── LGA_2013_AUST.prj
├── LGA_2013_AUST.shp
├── LGA_2013_AUST.shx
├── SHP_Exclude.zip
├── T8Th4_6n.zip
├── bad.dbf
├── bad.shp
├── badlen.zip
├── badzip.zip
├── codepage.cpg
├── codepage.dbf
├── codepage.prj
├── codepage.qpj
├── codepage.shp
├── codepage.shx
├── codepage.zip
├── counties.dbf
├── counties.sbn
├── counties.sbx
├── counties.shp
├── counties.shp.xml
├── counties.shx
├── counties.zip
├── export_multipointz.dbf
├── export_multipointz.prj
├── export_multipointz.shp
├── export_multipointz.shx
├── export_polylinez.dbf
├── export_polylinez.prj
├── export_polylinez.shp
├── export_polylinez.shx
├── htmlcpg.cpg
├── htmlcpg.dbf
├── htmlcpg.prj
├── htmlcpg.shp
├── htmlprj.cpg
├── htmlprj.dbf
├── htmlprj.prj
├── htmlprj.shp
├── ipra_dresden_polygon.dbf
├── ipra_dresden_polygon.prj
├── ipra_dresden_polygon.shp
├── ipra_dresden_polygon.shx
├── mixedcase.zip
├── no-dbf.sbx
├── no-dbf.shp
├── no-dbf.zip
├── noshp.zip
├── qgis.zip
├── senate.dbf
├── senate.prj
├── senate.sbn
├── senate.sbx
├── senate.shp
├── senate.shp.xml
├── senate.shx
├── senate.zip
├── train_stations.zip
├── utf.cpg
├── utf.dbf
├── utf.prj
├── utf.qpj
├── utf.shp
├── utf.shx
├── utf.zip
└── zero-len-line.zip
├── fixtures.js
├── index.html
├── server.js
└── test.js
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | node: true,
5 | es6: true,
6 | mocha: true
7 | },
8 | extends: 'semistandard'
9 | };
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | node_modules
3 | .c9revisions
4 | jam
5 | components
6 | .DS_Store
7 | package-lock.json
8 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test
2 | site
3 | files
4 | jam
5 | *.zip
6 | *.geojson
7 | *.topojson
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | =====================
3 |
4 | Copyright © 2024 - Calvin Metcalf and other `shapefile-js` contributors.
5 |
6 | Permission is hereby granted, free of charge, to any person
7 | obtaining a copy of this software and associated documentation
8 | files (the “Software”), to deal in the Software without
9 | restriction, including without limitation the rights to use,
10 | copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the
12 | Software is furnished to do so, subject to the following
13 | conditions:
14 |
15 | The above copyright notice and this permission notice shall be
16 | included in all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 | OTHER DEALINGS IN THE SOFTWARE.
26 |
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Shapefile.js
2 |
3 | Pure JavaScript library for parsing Shapefiles, returns Geojson projected into WGS84 lat lons.
4 |
5 | ## Usage
6 |
7 | For use in node, rollup, webpack and where ever ESM modules are used we have a lovely package you can install via npm or yarn or whatever.
8 |
9 | npm install shpjs --save
10 |
11 | If you need a stand alone file to include in your webpage the old fashioned way then you can grab the built version that's either included in the repo or you can use unpkg.
12 |
13 | https://unpkg.com/shpjs@latest/dist/shp.js
14 |
15 | or
16 |
17 | https://unpkg.com/shpjs@latest/dist/shp.min.js
18 |
19 |
20 | When using this library in some sort of bundler for the browser, no polyfills for node apis are required, the only thing needed is some sort of dependency resolver plugin like [rollup node-resolve](https://www.npmjs.com/package/@rollup/plugin-node-resolve) if your bundler doesn't have it, you are almost certainly already using one to get this library anyway.
21 |
22 | Addtionally you can import it directly into an esm based web script with
23 |
24 | ```js
25 | import shp from 'https://unpkg.com/shpjs@latest/dist/shp.esm.js'
26 | ```
27 |
28 | ## API
29 |
30 | There are 3 ways to use it:
31 |
32 | 1\. you can pass it a url to a shapefile, either to the shapefile itself (with or without the .shp suffix)
33 |
34 | ```javascript
35 | import shp from 'shpjs';
36 | //for the shapefiles in the folder called 'files' with the name pandr.shp
37 | const geojson = await shp("files/pandr.shp");
38 | ```
39 |
40 | or you can pass it a url to a a .zip file which contains the shapefile
41 |
42 | ```javascript
43 | //for the shapefiles in the files folder called pandr.shp
44 | const geojson = await shp("files/pandr.zip");
45 | ```
46 |
47 | 2\. you can pass in in a binary buffer (ArrayBuffer, TypedArray, DataView, Node Buffer) containing a zip file containing at least one shapefile like from a file in node:
48 |
49 | ```javascript
50 | // in node
51 | const data = await fs.readFile('./path/to/shp.zip');
52 | const geojson = await shp(data);
53 | ```
54 | or the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File) in the browser
55 |
56 | ```javascript
57 | // in browser from some sort of file upload
58 | const data = await file.arrayBuffer()
59 | const geojson = await shp(data);
60 | ```
61 |
62 | 3\. You can pass in an object with `shp`, `dbf`, `prj`, and `cpg` properties.
63 |
64 | ```javascript
65 | const object = {}
66 | object.shp = await fs.readFile('./path/to/file.shp');
67 | // dbf is optional, but needed if you want attributes
68 | object.dbf = await fs.readFile('./path/to/file.dbf');
69 | // prj is optional, but needed if your file is in some projection you don't want it in
70 | object.prj = await fs.readFile('./path/to/file.prj');
71 | // cpg is optional but needed if your dbf is in some weird (non utf8) encoding.
72 | object.cpg = await fs.readFile('./path/to/file.cpg');
73 |
74 | const geojson = await shp(object)
75 | ```
76 |
77 | ## on zipfiles
78 |
79 | If there is only one shp in the zipefile it returns geojson, if there are multiple then it will be an array. All of the geojson objects have an extra key `fileName` the value of which is the
80 | name of the shapefile minus the extension (I.E. the part of the name that's the same for all of them).
81 |
82 |
83 | # links
84 |
85 | - [wikipedia article](https://en.wikipedia.org/wiki/Shapefile)
86 | - [ESRI white paper](http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf)
87 | - [This page on Xbase](http://www.clicketyclick.dk/databases/xbase/format/dbf.html)
88 |
89 | ## Demos
90 |
91 | - [Countries/zipfile](http://calvinmetcalf.github.io/shapefile-js)
92 | - [Google maps](http://calvinmetcalf.github.io/shapefile-js/site/map.html)
93 | - [Local Zipfile](http://leaflet.calvinmetcalf.com)
94 | - [Projected big with web workers](http://calvinmetcalf.github.io/shapefile-js/site/proj.html)
95 |
96 | ## About
97 |
98 | Descended in a ship of theseus way from [RandomEtc's shapefile library](https://github.com/RandomEtc/shapefile-js) no code is shared.
99 |
100 | - [World Borders shapefile](http://thematicmapping.org/downloads/world_borders.php) is CC-BY-SA 3.0.
101 | - Park and Ride shapefile is from [MassDOT](http://mass.gov/massdot) and is public domain.
102 | - MA town boundaries from [MassGIS](http://www.mass.gov/anf/research-and-tech/it-serv-and-support/application-serv/office-of-geographic-information-massgis/) and is public domain
103 | - NJ County Boundaries from [NJgin](https://njgin.state.nj.us/NJ_NJGINExplorer/index.jsp) and should be public domain.
104 | - [Proj4js](https://github.com/proj4js/proj4js) by me et al MIT
105 | - Other test datasets copyright their respective owners.
--------------------------------------------------------------------------------
/files/Readme.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/Readme.txt
--------------------------------------------------------------------------------
/files/TM_WORLD_BORDERS_SIMPL-0.3.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/TM_WORLD_BORDERS_SIMPL-0.3.dbf
--------------------------------------------------------------------------------
/files/TM_WORLD_BORDERS_SIMPL-0.3.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/TM_WORLD_BORDERS_SIMPL-0.3.shp
--------------------------------------------------------------------------------
/files/TM_WORLD_BORDERS_SIMPL-0.3.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/TM_WORLD_BORDERS_SIMPL-0.3.shx
--------------------------------------------------------------------------------
/files/TM_WORLD_BORDERS_SIMPL-0.3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/TM_WORLD_BORDERS_SIMPL-0.3.zip
--------------------------------------------------------------------------------
/files/counties5.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/counties5.zip
--------------------------------------------------------------------------------
/files/empty-shp.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/empty-shp.zip
--------------------------------------------------------------------------------
/files/maSP.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/maSP.zip
--------------------------------------------------------------------------------
/files/nj_counties.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/nj_counties.zip
--------------------------------------------------------------------------------
/files/nj_muni.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/nj_muni.zip
--------------------------------------------------------------------------------
/files/pandr.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.dbf
--------------------------------------------------------------------------------
/files/pandr.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
--------------------------------------------------------------------------------
/files/pandr.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/files/pandr.sbn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.sbn
--------------------------------------------------------------------------------
/files/pandr.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.sbx
--------------------------------------------------------------------------------
/files/pandr.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.shp
--------------------------------------------------------------------------------
/files/pandr.shp.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 20120530 08362400 FALSE CreateFeatureclass "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities" ParkAndRide # Export_Output_2_Layer SAME_AS_TEMPLATE SAME_AS_TEMPLATE "PROJCS['NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',200000.0],PARAMETER['False_Northing',750000.0],PARAMETER['Central_Meridian',-71.5],PARAMETER['Standard_Parallel_1',41.71666666666667],PARAMETER['Standard_Parallel_2',42.68333333333333],PARAMETER['Latitude_Of_Origin',41.0],UNIT['Meter',1.0]];-361489.141077092 327975.618391579 1953.12499818101;0 1;0 1" # 0 0 0 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities\gisvector.GISADMIN.ParkAndRide" Append Export_Output_2_Layer "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities\gisvector.GISADMIN.ParkAndRide" TEST "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities\gisvector.GISADMIN.ParkAndRide" FeatureClassToFeatureClass S:\HQ\Planning\DataResources\Workspace\PaulN\ParknRide\ParkandRide-PN.mdb\Export_Output_2 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities" ParkAndRide # "TOWN TOWN VISIBLE;LOCATION LOCATION VISIBLE;STATUS STATUS VISIBLE;DISTRICT DISTRICT VISIBLE;OPERATOR OPERATOR VISIBLE;BIKE_RACKS BIKE_RACKS VISIBLE;SHELTERS SHELTERS VISIBLE;PHONES PHONES VISIBLE;LIGHTS LIGHTS VISIBLE;FENCES FENCES VISIBLE;SIGNS SIGNS VISIBLE;OWNER OWNER VISIBLE;CAPACITY CAPACITY VISIBLE;BUS_SERVICE BUS_SERVICE VISIBLE;RAIL_SERVICE RAIL_SERVICE VISIBLE;BOAT_SERVICE BOAT_SERVICE VISIBLE;MAP_ID MAP_ID VISIBLE;MPO MPO VISIBLE" SAME_AS_TEMPLATE SAME_AS_TEMPLATE # 0 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.PublicFacilities\gisvector.GISADMIN.ParkAndRide" FeatureClassToFeatureClass "Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots" S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb Update2009 # "TOWN 'TOWN' true true false 25 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,TOWN,-1,-1;LOCATION 'LOCATION' true true false 45 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,LOCATION,-1,-1;STATUS 'STATUS' true true false 15 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,STATUS,-1,-1;DISTRICT 'DISTRICT' true true false 4 Long 0 10 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,DISTRICT,-1,-1;OPERATOR 'OPERATOR' true true false 25 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,OPERATOR,-1,-1;BIKE_RACKS 'BIKE_RACKS' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,BIKE_RACKS,-1,-1;SHELTERS 'SHELTERS' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,SHELTERS,-1,-1;PHONES 'PHONES' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,PHONES,-1,-1;LIGHTS 'LIGHTS' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,LIGHTS,-1,-1;FENCES 'FENCES' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,FENCES,-1,-1;SIGNS 'SIGNS' true true false 3 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,SIGNS,-1,-1;OWNER 'OWNER' true true false 15 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,OWNER,-1,-1;CAPACITY 'CAPACITY' true true false 4 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,CAPACITY,-1,-1;BUS_SERVICE 'BUS_SERVICE' true true false 25 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,BUS_SERVICE,-1,-1;RAIL_SERVICE 'RAIL_SERVICE' true true false 10 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,RAIL_SERVICE,-1,-1;BOAT_SERVICE 'BOAT_SERVICE' true true false 10 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,BOAT_SERVICE,-1,-1;MAP_ID 'MAP_ID' true true false 4 Long 0 10 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,MAP_ID,-1,-1;MPO 'MPO' true true false 50 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,MPO,-1,-1;SYMBOL 'SYMBOL' true true false 1 Text 0 0 ,First,#,Database Connections\MassDOT GIS.sde\gisVector.GISADMIN.Transportation\gisvector.GISADMIN.ParkAndRideLots,SYMBOL,-1,-1" # S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009 FeatureClassToFeatureClass S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Transportation" ParkAndRide # "TOWN 'TOWN' true true false 25 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,TOWN,-1,-1;LOCATION 'LOCATION' true true false 45 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,LOCATION,-1,-1;STATUS 'STATUS' true true false 15 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,STATUS,-1,-1;DISTRICT 'DISTRICT' true true false 4 Long 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,DISTRICT,-1,-1;OPERATOR 'OPERATOR' true true false 25 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,OPERATOR,-1,-1;BIKE_RACKS 'BIKE_RACKS' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,BIKE_RACKS,-1,-1;SHELTERS 'SHELTERS' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,SHELTERS,-1,-1;PHONES 'PHONES' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,PHONES,-1,-1;LIGHTS 'LIGHTS' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,LIGHTS,-1,-1;FENCES 'FENCES' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,FENCES,-1,-1;SIGNS 'SIGNS' true true false 3 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,SIGNS,-1,-1;OWNER 'OWNER' true true false 15 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,OWNER,-1,-1;CAPACITY 'CAPACITY' true true false 4 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,CAPACITY,-1,-1;BUS_SERVICE 'BUS_SERVICE' true true false 25 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,BUS_SERVICE,-1,-1;RAIL_SERVICE 'RAIL_SERVICE' true true false 10 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,RAIL_SERVICE,-1,-1;BOAT_SERVICE 'BOAT_SERVICE' true true false 10 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,BOAT_SERVICE,-1,-1;MAP_ID 'MAP_ID' true true false 4 Long 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,MAP_ID,-1,-1;MPO 'MPO' true true false 50 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,MPO,-1,-1;SYMBOL 'SYMBOL' true true false 1 Text 0 0 ,First,#,S:\HQ\Planning\DataResources\Workspace\Paul\ParkAndRideUpdate.mdb\Update2009,SYMBOL,-1,-1" # "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Transportation\GISVECTOR.GISADMIN.ParkAndRide" Project "Database Connections\wh.sde\gisvector.GISADMIN.Facilities\gisVector.GISADMIN.ParkandRideLot" "C:\Documents and Settings\MetcalfC\Desktop\pandr.shp" GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]] NAD_1983_To_WGS_1984_1 PROJCS['NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',200000.0],PARAMETER['False_Northing',750000.0],PARAMETER['Central_Meridian',-71.5],PARAMETER['Standard_Parallel_1',41.71666666666667],PARAMETER['Standard_Parallel_2',42.68333333333333],PARAMETER['Latitude_Of_Origin',41.0],UNIT['Meter',1.0]] 20091218 06265300 20091218 06265300 1.0 Microsoft Windows XP Version 5.1 (Build 2600) Service Pack 3; ESRI ArcCatalog 9.3.1.3000 en REQUIRED: A brief narrative summary of the data set. REQUIRED: A summary of the intentions with which the data set was developed. REQUIRED: The name of an organization or individual that developed the data set. REQUIRED: The date when the data set is published or otherwise made available for release. GISVECTOR.GISADMIN.ParkAndRide GISVECTOR.GISADMIN.ParkAndRide vector digital data Server=mhd-gis-wh; Service=sde:sqlserver:mhd-gis-wh; Database=gisVector; User=gisadmin; Version=sde.DEFAULT REQUIRED: The basis on which the time period of content information is determined. REQUIRED: The year (and optionally month, or month and day) for which the data set corresponds to the ground. REQUIRED: The state of the data set. REQUIRED: The frequency with which changes and additions are made to the data set after the initial data set is completed. REQUIRED: Western-most coordinate of the limit of coverage expressed in longitude. REQUIRED: Eastern-most coordinate of the limit of coverage expressed in longitude. REQUIRED: Northern-most coordinate of the limit of coverage expressed in latitude. REQUIRED: Southern-most coordinate of the limit of coverage expressed in latitude. REQUIRED: Reference to a formally registered thesaurus or a similar authoritative source of theme keywords. REQUIRED: Common-use word or phrase used to describe the subject of the data set. REQUIRED: Restrictions and legal prerequisites for accessing the data set. REQUIRED: Restrictions and legal prerequisites for using the data set after access is granted. SDE Feature Class Microsoft Windows XP Version 5.1 (Build 2600) Service Pack 3; ESRI ArcCatalog 9.3.1.3000 GISVECTOR.GISADMIN.ParkAndRide en FGDC Content Standards for Digital Geospatial Metadata FGDC-STD-001-1998 local time REQUIRED: The person responsible for the metadata information. REQUIRED: The organization responsible for the metadata information. REQUIRED: The mailing and/or physical address for the organization or individual. REQUIRED: The city of the address. REQUIRED: The state or province of the address. REQUIRED: The ZIP or other postal code of the address. REQUIRED: The telephone number by which individuals can speak to the organization or individual. 20091218 http://www.esri.com/metadata/esriprof80.html ESRI Metadata Profile ISO 19115 Geographic Information - Metadata DIS_ESRI1.0 dataset Downloadable Data 002 Server=mhd-gis-wh; Service=sde:sqlserver:mhd-gis-wh; Database=gisVector; User=gisadmin; Version=sde.DEFAULT ArcSDE Connection SDE Feature Class Vector Simple Point FALSE 0 TRUE FALSE Entity point 0 GCS_North_American_1983 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 coordinate pair meters 0.000512 0.000512 State Plane Coordinate System 1983 2001 41.716667 42.683333 -71.500000 41.000000 200000.000000 750000.000000 North American Datum of 1983 Geodetic Reference System 80 6378137.000000 298.257222 Explicit elevation coordinate included with horizontal coordinates 1.000000 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 0 GISVECTOR.GISADMIN.ParkAndRide Feature Class 0 OBJECTID OBJECTID OID 4 10 0 Internal feature number. ESRI Sequential unique whole numbers that are automatically generated. Shape Shape Geometry 4 0 0 Feature geometry. ESRI Coordinates defining the features. TOWN TOWN String 25 0 0 LOCATION LOCATION String 45 0 0 STATUS STATUS String 15 0 0 DISTRICT DISTRICT Integer 4 10 0 OPERATOR OPERATOR String 25 0 0 BIKE_RACKS BIKE_RACKS String 3 0 0 SHELTERS SHELTERS String 3 0 0 PHONES PHONES String 3 0 0 LIGHTS LIGHTS String 3 0 0 FENCES FENCES String 3 0 0 SIGNS SIGNS String 3 0 0 OWNER OWNER String 15 0 0 CAPACITY CAPACITY String 4 0 0 BUS_SERVICE BUS_SERVICE String 25 0 0 RAIL_SERVICE RAIL_SERVICE String 10 0 0 BOAT_SERVICE BOAT_SERVICE String 10 0 0 MAP_ID MAP_ID Integer 4 10 0 MPO MPO String 50 0 0 SYMBOL SYMBOL String 1 0 0 20091218 Dataset copied. Server=mhd-gis-wh; Service=esri_sde; Database=gisvector; User=gisviewer; Version=sde.DEFAULT 20100813 07273100
4 |
--------------------------------------------------------------------------------
/files/pandr.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.shx
--------------------------------------------------------------------------------
/files/pandr.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/files/pandr.zip
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Shapefile in Leaflet!
8 |
23 |
24 |
27 |
28 |
29 |
40 |
41 |
42 |
43 |
48 |
49 |
50 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/lib/binaryajax.js:
--------------------------------------------------------------------------------
1 | import combine from './combine.js';
2 |
3 | export default async function binaryAjax(_url, type) {
4 |
5 | const url = combine(_url, type);
6 | const isOptionalTxt = type === 'prj' || type === 'cpg';
7 | try {
8 | const resp = await fetch(url);
9 | if (resp.status > 399) {
10 | throw new Error(resp.statusText);
11 | }
12 | if (isOptionalTxt) {
13 | return resp.text();
14 | }
15 | const parsed = await resp.arrayBuffer();
16 | return new DataView(parsed)
17 | } catch (e) {
18 | if (isOptionalTxt || type === 'dbf') {
19 | return false;
20 | }
21 | throw e;
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/lib/browser.js:
--------------------------------------------------------------------------------
1 | import shp, { combine, getShapefile, parseDbf, parseZip, parseShp, } from './index.js';
2 |
3 | shp.combine = combine;
4 | shp.parseDbf = parseDbf;
5 | shp.parseZip = parseZip;
6 | shp.parseShp = parseShp;
7 | export default shp;
--------------------------------------------------------------------------------
/lib/combine.js:
--------------------------------------------------------------------------------
1 | const URL = globalThis.URL;
2 |
3 | export default (base, type) => {
4 | if (!type) {
5 | return base;
6 | }
7 | const url = new URL(base);
8 | url.pathname = `${url.pathname}.${type}`;
9 | return url.href;
10 | };
11 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | import proj4 from 'proj4'
2 | import unzip from './unzip.js';
3 | import binaryAjax from './binaryajax.js';
4 | import parseShp from './parseShp.js';
5 | import parseDbf from 'parsedbf';
6 | const URL = globalThis.URL;
7 | const toUitn8Arr = b => {
8 | if (!b) {
9 | throw new Error('forgot to pass buffer');
10 | }
11 | if (isArrayBuffer(b)) {
12 | return new Uint8Array(b);
13 | }
14 | if (isArrayBuffer(b.buffer)) {
15 | if (b.BYTES_PER_ELEMENT === 1) {
16 | return b;
17 | }
18 | return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
19 | }
20 | throw new Error('invalid buffer like object')
21 | };
22 | const txtDecoder = new TextDecoder();
23 | const toString = (possibleString) => {
24 | if (!possibleString) {
25 | return;
26 | }
27 | if (typeof possibleString === 'string') {
28 | return possibleString;
29 | }
30 | if (isArrayBuffer(possibleString) || ArrayBuffer.isView(possibleString) || isDataView(possibleString)) {
31 | return txtDecoder.decode(possibleString);
32 | }
33 | }
34 | const toDataView = b => {
35 | if (!b) {
36 | throw new Error('forgot to pass buffer');
37 | }
38 | if (isDataView(b)) {
39 | return b;
40 | }
41 | if (isArrayBuffer(b)) {
42 | return new DataView(b);
43 | }
44 | if (isArrayBuffer(b.buffer)) {
45 | return new DataView(b.buffer, b.byteOffset, b.byteLength);
46 | }
47 | throw new Error('invalid buffer like object')
48 | };
49 |
50 | function isArrayBuffer(subject) {
51 | return subject instanceof globalThis.ArrayBuffer || Object.prototype.toString.call(subject) === '[object ArrayBuffer]';
52 | }
53 | function isDataView(subject) {
54 | return subject instanceof globalThis.DataView || Object.prototype.toString.call(subject) === '[object DataView]'
55 | }
56 |
57 | export const combine = function ([shp, dbf]) {
58 | const out = {};
59 | out.type = 'FeatureCollection';
60 | out.features = [];
61 | let i = 0;
62 | const len = shp.length;
63 | if (!dbf) {
64 | dbf = [];
65 | }
66 | while (i < len) {
67 | out.features.push({
68 | type: 'Feature',
69 | geometry: shp[i],
70 | properties: dbf[i] || {}
71 | });
72 | i++;
73 | }
74 | return out;
75 | };
76 | export const parseZip = async function (buffer, whiteList) {
77 | let key;
78 | buffer = toUitn8Arr(buffer);
79 | const zip = await unzip(buffer);
80 | const names = [];
81 | whiteList = whiteList || [];
82 | for (key in zip) {
83 | if (key.indexOf('__MACOSX') !== -1) {
84 | continue;
85 | }
86 | if (key.slice(-4).toLowerCase() === '.shp') {
87 | names.push(key.slice(0, -4));
88 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = zip[key];
89 | } else if (key.slice(-4).toLowerCase() === '.prj') {
90 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = proj4(zip[key]);
91 | } else if (key.slice(-5).toLowerCase() === '.json' || whiteList.indexOf(key.split('.').pop()) > -1) {
92 | names.push(key.slice(0, -3) + key.slice(-3).toLowerCase());
93 | } else if (key.slice(-4).toLowerCase() === '.dbf' || key.slice(-4).toLowerCase() === '.cpg') {
94 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = zip[key];
95 | }
96 | }
97 | if (!names.length) {
98 | throw new Error('no layers founds');
99 | }
100 | const geojson = names.map(function (name) {
101 | let parsed, dbf;
102 | const lastDotIdx = name.lastIndexOf('.');
103 | if (lastDotIdx > -1 && name.slice(lastDotIdx).indexOf('json') > -1) {
104 | parsed = JSON.parse(zip[name]);
105 | parsed.fileName = name.slice(0, lastDotIdx);
106 | } else if (whiteList.indexOf(name.slice(lastDotIdx + 1)) > -1) {
107 | parsed = zip[name];
108 | parsed.fileName = name;
109 | } else {
110 | if (zip[name + '.dbf']) {
111 | dbf = parseDbf(zip[name + '.dbf'], zip[name + '.cpg']);
112 | }
113 | parsed = combine([parseShp(zip[name + '.shp'], zip[name + '.prj']), dbf]);
114 | parsed.fileName = name;
115 | }
116 | return parsed;
117 | });
118 | if (geojson.length === 1) {
119 | return geojson[0];
120 | } else {
121 | return geojson;
122 | }
123 | };
124 | async function getZip(base, whiteList) {
125 | const a = await binaryAjax(base);
126 | return parseZip(a, whiteList);
127 | }
128 | const handleShp = async (base) => {
129 | const args = await Promise.all([
130 | binaryAjax(base, 'shp'),
131 | binaryAjax(base, 'prj')
132 | ]);
133 | let prj = false;
134 | try {
135 | if (args[1]) {
136 | prj = proj4(args[1]);
137 | }
138 | } catch (e) {
139 | prj = false;
140 | }
141 | return parseShp(args[0], prj);
142 | };
143 | const handleDbf = async (base) => {
144 | const [dbf, cpg] = await Promise.all([
145 | binaryAjax(base, 'dbf'),
146 | binaryAjax(base, 'cpg')
147 | ]);
148 | if (!dbf) {
149 | return;
150 | }
151 | return parseDbf(dbf, cpg);
152 | };
153 | const checkSuffix = (base, suffix) => {
154 | const url = new URL(base, globalThis?.document?.location);
155 | return url.pathname.slice(-4).toLowerCase() === suffix;
156 | };
157 | const fromObject = ({ shp, dbf, cpg, prj }) => {
158 | const things = [
159 | _parseShp(shp, prj)
160 | ]
161 | if (dbf) {
162 | things.push(_parseDbf(dbf, cpg));
163 | }
164 | return combine(things);
165 | }
166 | export const getShapefile = async function (base, whiteList) {
167 | if (typeof base !== 'string') {
168 | if (isArrayBuffer(base) || ArrayBuffer.isView(base) || isDataView(base)) {
169 | return parseZip(base);
170 | }
171 | if (base.shp) {
172 | return fromObject(base);
173 | }
174 | throw new TypeError('must be a string, some sort of Buffer, or an object with at least a .shp property')
175 | }
176 | if (checkSuffix(base, '.zip')) {
177 | return getZip(base, whiteList);
178 | }
179 | if (checkSuffix(base, '.shp')) {
180 | base = base.slice(0, -4);
181 | }
182 | const results = await Promise.all([
183 | handleShp(base),
184 | handleDbf(base)
185 | ]);
186 | return combine(results);
187 | };
188 | const _parseShp = function (shp, prj) {
189 | shp = toDataView(shp);
190 | prj = toString(prj);
191 | if (typeof prj === 'string') {
192 | try {
193 | prj = proj4(prj);
194 | } catch (e) {
195 | prj = false;
196 | }
197 | }
198 | return parseShp(shp, prj);
199 | };
200 | const _parseDbf = function (dbf, cpg) {
201 | dbf = toDataView(dbf);
202 | cpg = toString(cpg);
203 | return parseDbf(dbf, cpg);
204 | };
205 | export default getShapefile;
206 | export {
207 | _parseDbf as parseDbf,
208 | _parseShp as parseShp,
209 | }
--------------------------------------------------------------------------------
/lib/parseShp.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function isClockWise(array) {
4 | let sum = 0;
5 | let i = 1;
6 | const len = array.length;
7 | let prev, cur;
8 | const bbox = [array[0][0], array[0][1], array[0][0], array[0][1]];
9 | while (i < len) {
10 | prev = cur || array[0];
11 | cur = array[i];
12 | sum += ((cur[0] - prev[0]) * (cur[1] + prev[1]));
13 | i++;
14 | if (cur[0] < bbox[0]) {
15 | bbox[0] = cur[0];
16 | }
17 | if (cur[1] < bbox[1]) {
18 | bbox[1] = cur[1];
19 | }
20 | if (cur[0] > bbox[2]) {
21 | bbox[2] = cur[0];
22 | }
23 | if (cur[1] > bbox[3]) {
24 | bbox[3] = cur[1];
25 | }
26 | }
27 | return {
28 | ring: array,
29 | clockWise: sum > 0,
30 | bbox,
31 | children: []
32 | }
33 |
34 | }
35 |
36 | function contains(outer, inner) {
37 | if (outer.bbox[0] > inner.bbox[0]) {
38 | return false;
39 | }
40 | if (outer.bbox[1] > inner.bbox[1]) {
41 | return false;
42 | }
43 | if (outer.bbox[2] < inner.bbox[2]) {
44 | return false;
45 | }
46 | if (outer.bbox[3] < inner.bbox[3]) {
47 | return false;
48 | }
49 | return true;
50 | }
51 |
52 | function handleRings(rings) {
53 | const outers = [];
54 | const inners = [];
55 | for (const ring of rings) {
56 | const proccessed = isClockWise(ring);
57 | if (proccessed.clockWise) {
58 | outers.push(proccessed)
59 | } else {
60 | inners.push(proccessed)
61 | }
62 | }
63 | // this is an optimization,
64 | // but it would also put in weird bad rings that would otherwise get left out
65 | // if (outers.length === 1) {
66 | // const out = [outers[0].ring]
67 | // for (const inner of inners) {
68 | // out.push(inner.ring);
69 |
70 | // }
71 | // return [out];
72 | // }
73 | for (const inner of inners) {
74 | for (const outer of outers) {
75 | if (contains(outer, inner)) {
76 | outer.children.push(inner.ring);
77 | break;
78 | }
79 | }
80 | }
81 | const out = [];
82 | for (const outer of outers) {
83 | out.push([outer.ring].concat(outer.children));
84 | }
85 | return out;
86 | }
87 | function polyReduce(a, b) {
88 | if (isClockWise(b) || !a.length) {
89 | a.push([b]);
90 | } else {
91 | a[a.length - 1].push(b);
92 | }
93 | return a;
94 | }
95 | ParseShp.prototype.parsePoint = function (data) {
96 | return {
97 | type: 'Point',
98 | coordinates: this.parseCoord(data, 0)
99 | };
100 | };
101 | ParseShp.prototype.parseZPoint = function (data) {
102 | const pointXY = this.parsePoint(data);
103 | pointXY.coordinates.push(data.getFloat64(16, true));
104 | return pointXY;
105 | };
106 | ParseShp.prototype.parsePointArray = function (data, offset, num) {
107 | const out = [];
108 | let done = 0;
109 | while (done < num) {
110 | out.push(this.parseCoord(data, offset));
111 | offset += 16;
112 | done++;
113 | }
114 | return out;
115 | };
116 | ParseShp.prototype.parseZPointArray = function (data, zOffset, num, coordinates) {
117 | let i = 0;
118 | while (i < num) {
119 | coordinates[i].push(data.getFloat64(zOffset, true));
120 | i++;
121 | zOffset += 8;
122 | }
123 | return coordinates;
124 | };
125 | ParseShp.prototype.parseArrayGroup = function (data, offset, partOffset, num, tot) {
126 | const out = [];
127 | let done = 0;
128 | let curNum; let nextNum = 0;
129 | let pointNumber;
130 | while (done < num) {
131 | done++;
132 | partOffset += 4;
133 | curNum = nextNum;
134 | if (done === num) {
135 | nextNum = tot;
136 | } else {
137 | nextNum = data.getInt32(partOffset, true);
138 | }
139 | pointNumber = nextNum - curNum;
140 | if (!pointNumber) {
141 | continue;
142 | }
143 | out.push(this.parsePointArray(data, offset, pointNumber));
144 | offset += (pointNumber << 4);
145 | }
146 | return out;
147 | };
148 | ParseShp.prototype.parseZArrayGroup = function (data, zOffset, num, coordinates) {
149 | let i = 0;
150 | while (i < num) {
151 | coordinates[i] = this.parseZPointArray(data, zOffset, coordinates[i].length, coordinates[i]);
152 | zOffset += (coordinates[i].length << 3);
153 | i++;
154 | }
155 | return coordinates;
156 | };
157 | ParseShp.prototype.parseMultiPoint = function (data) {
158 | const out = {};
159 | const num = data.getInt32(32, true);
160 | if (!num) {
161 | return null;
162 | }
163 | const mins = this.parseCoord(data, 0);
164 | const maxs = this.parseCoord(data, 16);
165 | out.bbox = [
166 | mins[0],
167 | mins[1],
168 | maxs[0],
169 | maxs[1]
170 | ];
171 | const offset = 36;
172 | if (num === 1) {
173 | out.type = 'Point';
174 | out.coordinates = this.parseCoord(data, offset);
175 | } else {
176 | out.type = 'MultiPoint';
177 | out.coordinates = this.parsePointArray(data, offset, num);
178 | }
179 | return out;
180 | };
181 | ParseShp.prototype.parseZMultiPoint = function (data) {
182 | const geoJson = this.parseMultiPoint(data);
183 | if (!geoJson) {
184 | return null;
185 | }
186 | let num;
187 | if (geoJson.type === 'Point') {
188 | geoJson.coordinates.push(data.getFloat64(72, true));
189 | return geoJson;
190 | } else {
191 | num = geoJson.coordinates.length;
192 | }
193 | const zOffset = 52 + (num << 4);
194 | geoJson.coordinates = this.parseZPointArray(data, zOffset, num, geoJson.coordinates);
195 | return geoJson;
196 | };
197 | ParseShp.prototype.parsePolyline = function (data) {
198 | const out = {};
199 | const numParts = data.getInt32(32, true);
200 | if (!numParts) {
201 | return null;
202 | }
203 | const mins = this.parseCoord(data, 0);
204 | const maxs = this.parseCoord(data, 16);
205 | out.bbox = [
206 | mins[0],
207 | mins[1],
208 | maxs[0],
209 | maxs[1]
210 | ];
211 | const num = data.getInt32(36, true);
212 | let offset, partOffset;
213 | if (numParts === 1) {
214 | out.type = 'LineString';
215 | offset = 44;
216 | out.coordinates = this.parsePointArray(data, offset, num);
217 | } else {
218 | out.type = 'MultiLineString';
219 | offset = 40 + (numParts << 2);
220 | partOffset = 40;
221 | out.coordinates = this.parseArrayGroup(data, offset, partOffset, numParts, num);
222 | }
223 | return out;
224 | };
225 | ParseShp.prototype.parseZPolyline = function (data) {
226 | const geoJson = this.parsePolyline(data);
227 | if (!geoJson) {
228 | return null;
229 | }
230 | const num = geoJson.coordinates.length;
231 | let zOffset;
232 | if (geoJson.type === 'LineString') {
233 | zOffset = 60 + (num << 4);
234 | geoJson.coordinates = this.parseZPointArray(data, zOffset, num, geoJson.coordinates);
235 | return geoJson;
236 | } else {
237 | const totalPoints = geoJson.coordinates.reduce(function (a, v) {
238 | return a + v.length;
239 | }, 0);
240 | zOffset = 56 + (totalPoints << 4) + (num << 2);
241 | geoJson.coordinates = this.parseZArrayGroup(data, zOffset, num, geoJson.coordinates);
242 | return geoJson;
243 | }
244 | };
245 | ParseShp.prototype.polyFuncs = function (out) {
246 | if (!out) {
247 | return out;
248 | }
249 | if (out.type === 'LineString') {
250 | out.type = 'Polygon';
251 | out.coordinates = [out.coordinates];
252 | return out;
253 | } else {
254 | out.coordinates = handleRings(out.coordinates)
255 | if (out.coordinates.length === 1) {
256 | out.type = 'Polygon';
257 | out.coordinates = out.coordinates[0];
258 | return out;
259 | } else {
260 | out.type = 'MultiPolygon';
261 | return out;
262 | }
263 | }
264 | };
265 | ParseShp.prototype.parsePolygon = function (data) {
266 | return this.polyFuncs(this.parsePolyline(data));
267 | };
268 | ParseShp.prototype.parseZPolygon = function (data) {
269 | return this.polyFuncs(this.parseZPolyline(data));
270 | };
271 | const shpFuncObj = {
272 | 1: 'parsePoint',
273 | 3: 'parsePolyline',
274 | 5: 'parsePolygon',
275 | 8: 'parseMultiPoint',
276 | 11: 'parseZPoint',
277 | 13: 'parseZPolyline',
278 | 15: 'parseZPolygon',
279 | 18: 'parseZMultiPoint'
280 | };
281 |
282 | function makeParseCoord(trans) {
283 | if (trans) {
284 | return function (data, offset) {
285 | const args = [data.getFloat64(offset, true), data.getFloat64(offset + 8, true)];
286 | return trans.inverse(args);
287 | };
288 | } else {
289 | return function (data, offset) {
290 | return [data.getFloat64(offset, true), data.getFloat64(offset + 8, true)];
291 | };
292 | }
293 | }
294 |
295 | function ParseShp(buffer, trans) {
296 | if (!(this instanceof ParseShp)) {
297 | return new ParseShp(buffer, trans);
298 | }
299 | this.buffer = buffer;
300 | this.headers = this.parseHeader();
301 | this.shpFuncs(trans);
302 | this.rows = this.getRows();
303 | }
304 | ParseShp.prototype.shpFuncs = function (tran) {
305 | let num = this.headers.shpCode;
306 | if (num > 20) {
307 | num -= 20;
308 | }
309 | if (!(num in shpFuncObj)) {
310 | throw new Error(`I don't know shp type "${num}"`);
311 | }
312 | this.parseFunc = this[shpFuncObj[num]];
313 | this.parseCoord = makeParseCoord(tran);
314 | };
315 | ParseShp.prototype.getShpCode = function () {
316 | return this.parseHeader().shpCode;
317 | };
318 | ParseShp.prototype.parseHeader = function () {
319 | const view = this.buffer;
320 | return {
321 | length: view.getInt32(6 << 2) << 1,
322 | version: view.getInt32(7 << 2, true),
323 | shpCode: view.getInt32(8 << 2, true),
324 | bbox: [
325 | view.getFloat64(9 << 2, true),
326 | view.getFloat64(11 << 2, true),
327 | view.getFloat64(13 << 2, true),
328 | view.getFloat64(15 << 2, true)
329 | ]
330 | };
331 | };
332 | ParseShp.prototype.getRows = function () {
333 | let offset = 100;
334 | const len = this.buffer.byteLength - 8;
335 | const out = [];
336 | let current;
337 | while (offset <= len) {
338 | current = this.getRow(offset);
339 | if (!current) {
340 | break;
341 | }
342 | offset += 8;
343 | offset += current.len;
344 | if (current.type) {
345 | out.push(this.parseFunc(current.data));
346 | } else {
347 | out.push(null);
348 | }
349 | }
350 | return out;
351 | };
352 | ParseShp.prototype.getRow = function (offset) {
353 | const id = this.buffer.getInt32(offset);
354 | const len = this.buffer.getInt32(offset + 4) << 1;
355 | if (len === 0) {
356 | return {
357 | id: id,
358 | len: len,
359 | type: 0
360 | };
361 | }
362 |
363 | if (offset + len + 8 > this.buffer.byteLength) {
364 | return;
365 | }
366 | return {
367 | id: id,
368 | len: len,
369 | data: new DataView(this.buffer.buffer, this.buffer.byteOffset + offset + 12, len - 4),
370 | type: this.buffer.getInt32(offset + 8, true)
371 | };
372 | };
373 | export default function (buffer, trans) {
374 | return new ParseShp(buffer, trans).rows;
375 | };
376 |
--------------------------------------------------------------------------------
/lib/unzip.js:
--------------------------------------------------------------------------------
1 | import { iter } from 'but-unzip';
2 |
3 | const regex = /.+\.(shp|dbf|json|prj|cpg)$/i;
4 | export default async (buffer) => {
5 | const files = {};
6 | const proms = [];
7 | for (const entry of iter(buffer)) {
8 | if (!regex.test(entry.filename)) {
9 | continue;
10 | }
11 | proms.push(Promise.resolve(entry.read()).then(bytes => files[entry.filename] = bytes));
12 | }
13 | await Promise.all(proms);
14 | const out = {};
15 | const decoder = new TextDecoder();
16 | for (const [key, value] of Object.entries(files)) {
17 | if (key.slice(-3).toLowerCase() === 'shp' || key.slice(-3).toLowerCase() === 'dbf') {
18 | out[key] = new DataView(value.buffer, value.byteOffset, value.byteLength)
19 | } else {
20 | out[key] = decoder.decode(value);
21 | }
22 | }
23 | return out;
24 | };
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shpjs",
3 | "version": "6.1.0",
4 | "description": "Load shapefiles in pure JavaScript",
5 | "main": "lib/index.js",
6 | "exports": {
7 | "import": "./lib/index.js",
8 | "require": "./dist/shp.js"
9 | },
10 | "type": "module",
11 | "repository": {
12 | "type": "git",
13 | "url": "git://github.com/calvinmetcalf/shapefile-js.git"
14 | },
15 | "scripts": {
16 | "test": "mocha --require test/fixtures.js ./test/test.js",
17 | "build": "rollup -c",
18 | "test-browser": "SERVING=true node test/server.js"
19 | },
20 | "author": "Calvin Metcalf",
21 | "license": "MIT",
22 | "readmeFilename": "README.md",
23 | "devDependencies": {
24 | "@rollup/plugin-node-resolve": "^15.2.3",
25 | "@rollup/plugin-terser": "^0.4.4",
26 | "chai": "^5.1.0",
27 | "chai-promised": "^1.0.2",
28 | "eslint": "^8.24.0",
29 | "express": "^4.17.2",
30 | "mocha": "^8.2.0",
31 | "morgan": "^1.10.0",
32 | "rollup": "^4.13.0",
33 | "semistandard": "^16.0.1"
34 | },
35 | "dependencies": {
36 | "but-unzip": "^0.1.4",
37 | "parsedbf": "^2.0.0",
38 | "proj4": "^2.1.4"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import { nodeResolve } from '@rollup/plugin-node-resolve';
2 | import terser from '@rollup/plugin-terser';
3 |
4 | export default [{
5 | input: './lib/browser.js',
6 | plugins: [
7 | nodeResolve({ browser: true })
8 | ],
9 | output: [{
10 | file: './dist/shp.js',
11 | format: 'umd',
12 | name: 'shp'
13 | }, {
14 | file: './dist/shp.min.js',
15 | format: 'umd',
16 | name: 'shp',
17 | plugins: [terser()]
18 | }]
19 | }, {
20 | input: './lib/index.js',
21 | plugins: [
22 | nodeResolve({ browser: true })
23 | ],
24 | output: [{
25 | file: './dist/shp.esm.js',
26 | format: 'esm'
27 | }, {
28 | file: './dist/shp.esm.min.js',
29 | format: 'esm',
30 | plugins: [terser()]
31 | }]
32 | }]
--------------------------------------------------------------------------------
/site/catiline.js:
--------------------------------------------------------------------------------
1 | /*! catiline 2.4.2 2013-08-08*/
2 | /*!©2013 Calvin Metcalf @license MIT https://github.com/calvinmetcalf/catiline */
3 | if (typeof document === 'undefined') {
4 | self._noTransferable=true;
5 | self.onmessage=function(e){
6 | /*jslint evil: true */
7 | eval(e.data);
8 | };
9 | } else {
10 | (function(global){
11 | 'use strict';
12 | /*!From setImmediate Copyright (c) 2012 Barnesandnoble.com,llc, Donavon West, and Domenic Denicola @license MIT https://github.com/NobleJS/setImmediate */
13 | (function(attachTo,global) {
14 | var tasks = (function () {
15 | function Task(handler, args) {
16 | this.handler = handler;
17 | this.args = args;
18 | }
19 | Task.prototype.run = function () {
20 | // See steps in section 5 of the spec.
21 | if (typeof this.handler === 'function') {
22 | // Choice of `thisArg` is not in the setImmediate spec; `undefined` is in the setTimeout spec though:
23 | // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html
24 | this.handler.apply(undefined, this.args);
25 | } else {
26 | var scriptSource = '' + this.handler;
27 | /*jshint evil: true */
28 | eval(scriptSource);
29 | }
30 | };
31 |
32 | var nextHandle = 1; // Spec says greater than zero
33 | var tasksByHandle = {};
34 | var currentlyRunningATask = false;
35 |
36 | return {
37 | addFromSetImmediateArguments: function (args) {
38 | var handler = args[0];
39 | var argsToHandle = Array.prototype.slice.call(args, 1);
40 | var task = new Task(handler, argsToHandle);
41 |
42 | var thisHandle = nextHandle++;
43 | tasksByHandle[thisHandle] = task;
44 | return thisHandle;
45 | },
46 | runIfPresent: function (handle) {
47 | // From the spec: 'Wait until any invocations of this algorithm started before this one have completed.'
48 | // So if we're currently running a task, we'll need to delay this invocation.
49 | if (!currentlyRunningATask) {
50 | var task = tasksByHandle[handle];
51 | if (task) {
52 | currentlyRunningATask = true;
53 | try {
54 | task.run();
55 | } finally {
56 | delete tasksByHandle[handle];
57 | currentlyRunningATask = false;
58 | }
59 | }
60 | } else {
61 | // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
62 | // 'too much recursion' error.
63 | global.setTimeout(function () {
64 | tasks.runIfPresent(handle);
65 | }, 0);
66 | }
67 | },
68 | remove: function (handle) {
69 | delete tasksByHandle[handle];
70 | }
71 | };
72 | }());
73 | // Installs an event handler on `global` for the `message` event: see
74 | // * https://developer.mozilla.org/en/DOM/window.postMessage
75 | // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
76 |
77 | var MESSAGE_PREFIX = 'com.catilinejs.setImmediate' + Math.random();
78 |
79 | function isStringAndStartsWith(string, putativeStart) {
80 | return typeof string === 'string' && string.substring(0, putativeStart.length) === putativeStart;
81 | }
82 |
83 | function onGlobalMessage(event) {
84 | // This will catch all incoming messages (even from other windows!), so we need to try reasonably hard to
85 | // avoid letting anyone else trick us into firing off. We test the origin is still this window, and that a
86 | // (randomly generated) unpredictable identifying prefix is present.
87 | if (event.source === global && isStringAndStartsWith(event.data, MESSAGE_PREFIX)) {
88 | var handle = event.data.substring(MESSAGE_PREFIX.length);
89 | tasks.runIfPresent(handle);
90 | }
91 | }
92 | if (global.addEventListener) {
93 | global.addEventListener('message', onGlobalMessage, false);
94 | } else {
95 | global.attachEvent('onmessage', onGlobalMessage);
96 | }
97 |
98 | attachTo.setImmediate = function () {
99 | var handle = tasks.addFromSetImmediateArguments(arguments);
100 |
101 | // Make `global` post a message to itself with the handle and identifying prefix, thus asynchronously
102 | // invoking our onGlobalMessage listener above.
103 | global.postMessage(MESSAGE_PREFIX + handle, '*');
104 |
105 | return handle;
106 | };
107 | })(catiline,global);
108 |
109 | /*! Promiscuous ©2013 Ruben Verborgh @license MIT https://github.com/RubenVerborgh/promiscuous*/
110 | (function (exports,tick) {
111 | var func = 'function';
112 | // Creates a deferred: an object with a promise and corresponding resolve/reject methods
113 | function Deferred() {
114 | // The `handler` variable points to the function that will
115 | // 1) handle a .then(onFulfilled, onRejected) call
116 | // 2) handle a .resolve or .reject call (if not fulfilled)
117 | // Before 2), `handler` holds a queue of callbacks.
118 | // After 2), `handler` is a simple .then handler.
119 | // We use only one function to save memory and complexity.
120 | var handler = function (onFulfilled, onRejected, value) {
121 | // Case 1) handle a .then(onFulfilled, onRejected) call
122 | var createdDeffered;
123 | if (onFulfilled !== handler) {
124 | createdDeffered = createDeferred();
125 | handler.queue.push({ deferred: createdDeffered, resolve: onFulfilled, reject: onRejected });
126 | return createdDeffered.promise;
127 | }
128 |
129 | // Case 2) handle a .resolve or .reject call
130 | // (`onFulfilled` acts as a sentinel)
131 | // The actual function signature is
132 | // .re[ject|solve](sentinel, success, value)
133 | var action = onRejected ? 'resolve' : 'reject',queue,deferred,callback;
134 | for (var i = 0, l = handler.queue.length; i < l; i++) {
135 | queue = handler.queue[i];
136 | deferred = queue.deferred;
137 | callback = queue[action];
138 | if (typeof callback !== func) {
139 | deferred[action](value);
140 | } else {
141 | execute(callback, value, deferred);
142 | }
143 | }
144 | // Replace this handler with a simple resolved or rejected handler
145 | handler = createHandler(promise, value, onRejected);
146 | };
147 | function Promise(){
148 | this.then=function (onFulfilled, onRejected) {
149 | return handler(onFulfilled, onRejected);
150 | };
151 | }
152 | var promise = new Promise();
153 | this.promise = promise;
154 | // The queue of deferreds
155 | handler.queue = [];
156 |
157 | this.resolve = function (value) {
158 | handler.queue && handler(handler, true, value);
159 | };
160 |
161 | this.reject = function (reason) {
162 | handler.queue && handler(handler, false, reason);
163 | };
164 | }
165 |
166 | function createDeferred(){
167 | return new Deferred();
168 | }
169 |
170 | // Creates a fulfilled or rejected .then function
171 | function createHandler(promise, value, success) {
172 | return function (onFulfilled, onRejected) {
173 | var callback = success ? onFulfilled : onRejected, result;
174 | if (typeof callback !== func) {
175 | return promise;
176 | }
177 | execute(callback, value, result = createDeferred());
178 | return result.promise;
179 | };
180 | }
181 |
182 | // Executes the callback with the specified value,
183 | // resolving or rejecting the deferred
184 | function execute(callback, value, deferred) {
185 | tick(function () {
186 | var result;
187 | try {
188 | result = callback(value);
189 | if (result && typeof result.then === func) {
190 | result.then(deferred.resolve, deferred.reject);
191 | } else {
192 | deferred.resolve(result);
193 | }
194 | }
195 | catch (error) {
196 | deferred.reject(error);
197 | }
198 | });
199 | }
200 |
201 | // Returns a resolved promise
202 | exports.resolve= function (value) {
203 | var promise = {};
204 | promise.then = createHandler(promise, value, true);
205 | return promise;
206 | };
207 | // Returns a rejected promise
208 | exports.reject= function (reason) {
209 | var promise = {};
210 | promise.then = createHandler(promise, reason, false);
211 | return promise;
212 | };
213 | // Returns a deferred
214 | exports.deferred= createDeferred;
215 | exports.all=function(array){
216 | var promise = exports.deferred();
217 | var len = array.length;
218 | var resolved=0;
219 | var out = [];
220 | var onSuccess=function(n){
221 | return function(v){
222 | out[n]=v;
223 | resolved++;
224 | if(resolved===len){
225 | promise.resolve(out);
226 | }
227 | };
228 | };
229 | array.forEach(function(v,i){
230 | v.then(onSuccess(i),function(a){
231 | promise.reject(a);
232 | });
233 | });
234 | return promise.promise;
235 | };
236 | })(catiline,catiline.setImmediate);
237 |
238 | catiline._hasWorker = typeof Worker !== 'undefined'&&typeof fakeLegacy === 'undefined';
239 | catiline.URL = window.URL || window.webkitURL;
240 | catiline._noTransferable=!catiline.URL;
241 | //regex out the importScript call and move it up to the top out of the function.
242 | function regexImports(string){
243 | var rest=string,
244 | match = true,
245 | matches = {},
246 | loopFunc = function(a,b){
247 | if(b){
248 | 'importScripts('+b.split(',').forEach(function(cc){
249 | matches[catiline.makeUrl(cc.match(/\s*[\'\"](\S*)[\'\"]\s*/)[1])]=true; // trim whitespace, add to matches
250 | })+');\n';
251 | }
252 | };
253 | while(match){
254 | match = rest.match(/(importScripts\(.*?\);?)/);
255 | rest = rest.replace(/(importScripts\(\s*(?:[\'\"].*?[\'\"])?\s*\);?)/,'\n');
256 | if(match){
257 | match[0].replace(/importScripts\(\s*([\'\"].*?[\'\"])?\s*\);?/g,loopFunc);
258 | }
259 | }
260 | matches = Object.keys(matches);
261 | return [matches,rest];
262 | }
263 |
264 | function moveImports(string){
265 | var str = regexImports(string);
266 | var matches = str[0];
267 | var rest = str[1];
268 | if(matches.length>0){
269 | return 'importScripts(\''+matches.join('\',\'')+'\');\n'+rest;
270 | }else{
271 | return rest;
272 | }
273 | }
274 | function moveIimports(string){
275 | var str = regexImports(string);
276 | var matches = str[0];
277 | var rest = str[1];
278 | if(matches.length>0){
279 | return 'importScripts(\''+matches.join('\',\'')+'\');eval(__scripts__);\n'+rest;
280 | }else{
281 | return rest;
282 | }
283 | }
284 | function getPath(){
285 | if(typeof SHIM_WORKER_PATH !== 'undefined'){
286 | return SHIM_WORKER_PATH;
287 | }else if('SHIM_WORKER_PATH' in catiline){
288 | return catiline.SHIM_WORKER_PATH;
289 | }
290 | var scripts = document.getElementsByTagName('script');
291 | var len = scripts.length;
292 | var i = 0;
293 | while(i0){',
328 | ' scripts.forEach(function(url){',
329 | ' var ajax = new XMLHttpRequest();',
330 | ' ajax.open(\'GET\',url,false);',
331 | ' ajax.send();__scripts__+=ajax.responseText;',
332 | ' __scripts__+=\'\\n;\';',
333 | ' });',
334 | ' }',
335 | '};',
336 | script,
337 | '}catch(e){',
338 | ' window.parent.postMessage([\''+codeword+'\',\'error\'],\'*\')',
339 | '}'].join('\n');
340 | appendScript(iDoc,text);
341 |
342 | return iFrame;
343 | }
344 | function makeIframe(script,codeword){
345 | var promise = catiline.deferred();
346 | if(document.readyState==='complete'){
347 | promise.resolve(actualMakeI(script,codeword));
348 | }else{
349 | window.addEventListener('load',function(){
350 | promise.resolve(actualMakeI(script,codeword));
351 | },false);
352 | }
353 | return promise.promise;
354 | }
355 | catiline.makeIWorker = function (strings,codeword){
356 | var script =moveIimports(strings.join(''));
357 | var worker = {onmessage:function(){}};
358 | var ipromise = makeIframe(script,codeword);
359 | window.addEventListener('message',function(e){
360 | if(typeof e.data ==='string'&&e.data.length>codeword.length&&e.data.slice(0,codeword.length)===codeword){
361 | worker.onmessage({data:JSON.parse(e.data.slice(codeword.length))});
362 | }
363 | });
364 | worker.postMessage=function(data){
365 | ipromise.then(function(iFrame){
366 | iFrame.contentWindow.postMessage(JSON.stringify(data),'*');
367 | });
368 | };
369 | worker.terminate=function(){
370 | ipromise.then(function(iFrame){
371 | document.body.removeChild(iFrame);
372 | });
373 | };
374 | return worker;
375 |
376 | };
377 | //accepts an array of strings, joins them, and turns them into a worker.
378 | function makeFallbackWorker(script){
379 | catiline._noTransferable=true;
380 | var worker = new Worker(getPath());
381 | worker.postMessage(script);
382 | return worker;
383 | }
384 | catiline.makeWorker = function (strings, codeword){
385 | if(!catiline._hasWorker){
386 | return catiline.makeIWorker(strings,codeword);
387 | }
388 | var worker;
389 | var script =moveImports(strings.join(''));
390 | if(catiline._noTransferable){
391 | return makeFallbackWorker(script);
392 | }
393 | try{
394 | worker= new Worker(catiline.URL.createObjectURL(new Blob([script],{type: 'text/javascript'})));
395 | }catch(e){
396 | try{
397 | worker=makeFallbackWorker(script);
398 | }catch(ee){
399 | worker = catiline.makeIWorker(strings,codeword);
400 | }
401 | }finally{
402 | return worker;
403 | }
404 | };
405 |
406 | catiline.makeUrl = function (fileName) {
407 | var link = document.createElement('link');
408 | link.href = fileName;
409 | return link.href;
410 | };
411 |
412 | catiline.Worker = function Catiline(obj) {
413 | if(typeof obj === 'function'){
414 | obj = {
415 | data:obj
416 | };
417 | }
418 | var __codeWord__='com.catilinejs.'+(catiline._hasWorker?'iframe':'worker')+Math.random();
419 | var listeners = {};
420 | var self = this;
421 | self.on = function (eventName, func, scope) {
422 | scope = scope || self;
423 | if (eventName.indexOf(' ') > 0) {
424 | eventName.split(' ').map(function (v) {
425 | return self.on(v, func, scope);
426 | }, this);
427 | return self;
428 | }
429 | if (!(eventName in listeners)) {
430 | listeners[eventName] = [];
431 | }
432 | listeners[eventName].push(function (a) {
433 | func.call(scope, a);
434 | });
435 | return self;
436 | };
437 |
438 | function _fire(eventName, data) {
439 | if (eventName.indexOf(' ') > 0) {
440 | eventName.split(' ').forEach(function (v) {
441 | _fire(v, data);
442 | });
443 | return self;
444 | }
445 | if (!(eventName in listeners)) {
446 | return self;
447 | }
448 | listeners[eventName].forEach(function (v) {
449 | v(data);
450 | });
451 | return self;
452 | }
453 | self.fire = function (eventName, data, transfer) {
454 | if(catiline._noTransferable){
455 | worker.postMessage([[eventName], data]);
456 | }else{
457 | worker.postMessage([[eventName], data], transfer);
458 | }
459 |
460 | return self;
461 | };
462 | self.off = function (eventName, func) {
463 | if (eventName.indexOf(' ') > 0) {
464 | eventName.split(' ').map(function (v) {
465 | return self.off(v, func);
466 | });
467 | return self;
468 | }
469 | if (!(eventName in listeners)) {
470 | return self;
471 | }
472 | else if (!func) {
473 | delete listeners[eventName];
474 | }
475 | else {
476 | if (listeners[eventName].indexOf(func) > -1) {
477 | if (listeners[eventName].length > 1) {
478 | delete listeners[eventName];
479 | }
480 | else {
481 | listeners[eventName].splice(listeners[eventName].indexOf(func), 1);
482 | }
483 | }
484 | }
485 | return self;
486 | };
487 | var i = 0;
488 | var promises = [];
489 | var rejectPromises = function (msg) {
490 | if (typeof msg !== 'string' && 'preventDefault' in msg) {
491 | msg.preventDefault();
492 | msg = msg.message;
493 | }
494 | promises.forEach(function (p) {
495 | if (p) {
496 | p.reject(msg);
497 | }
498 | });
499 | };
500 | obj.__codeWord__='"'+__codeWord__+'"';
501 | if (!('initialize' in obj)) {
502 | if ('init' in obj) {
503 | obj.initialize = obj.init;
504 | }
505 | else {
506 | obj.initialize = function () {};
507 | }
508 | }
509 | var fObj = '{\n\t';
510 | var keyFunc = function (key) {
511 | var out = function (data, transfer) {
512 | var i = promises.length;
513 | promises[i] = catiline.deferred();
514 | if(catiline._noTransferable){
515 | worker.postMessage([[__codeWord__, i], key, data]);
516 | }else{
517 | worker.postMessage([[__codeWord__, i], key, data], transfer);
518 | }
519 | return promises[i].promise;
520 | };
521 | return out;
522 | };
523 | for (var key in obj) {
524 | if (i !== 0) {
525 | fObj = fObj + ',\n\t';
526 | }
527 | else {
528 | i++;
529 | }
530 | fObj = fObj + key + ':' + obj[key].toString();
531 | self[key] = keyFunc(key);
532 | }
533 | fObj = fObj + '}';
534 | var worker = catiline.makeWorker(['\'use strict\';\n\nvar _db = ',fObj,';\nvar listeners = {};\nvar __iFrame__ = typeof document!=="undefined";\nvar __self__={onmessage:function(e){\n _fire("messege",e.data[1]);\n if(e.data[0][0]===_db.__codeWord__){\n return regMsg(e);\n }else{\n _fire(e.data[0][0],e.data[1]);\n }\n}};\nif(__iFrame__){\n window.onmessage=function(e){\n if(typeof e.data === "string"){\n e ={data: JSON.parse(e.data)};\n }\n __self__.onmessage(e);\n };\n}else{\n self.onmessage=__self__.onmessage;\n}\n__self__.postMessage=function(rawData, transfer){\n var data;\n if(!self._noTransferable&&!__iFrame__){\n self.postMessage(rawData, transfer);\n }else if(__iFrame__){\n data = _db.__codeWord__+JSON.stringify(rawData);\n window.parent.postMessage(data,"*");\n }else if(self._noTransferable){\n self.postMessage(rawData);\n }\n};\n_db.on = function (eventName, func, scope) {\n if(eventName.indexOf(" ")>0){\n return eventName.split(" ").map(function(v){\n return _db.on(v,func,scope);\n },_db);\n }\n scope = scope || _db;\n if (!(eventName in listeners)) {\n listeners[eventName] = [];\n }\n listeners[eventName].push(function (a) {\n func.call(scope, a, _db);\n });\n};\nfunction _fire(eventName,data){\n if(eventName.indexOf(" ")>0){\n eventName.split(" ").forEach(function(v){\n _fire(v,data);\n });\n return;\n }\n if (!(eventName in listeners)) {\n return;\n }\n listeners[eventName].forEach(function (v) {\n v(data);\n });\n}\n\n_db.fire = function (eventName, data, transfer) {\n __self__.postMessage([[eventName], data], transfer);\n};\n_db.off=function(eventName,func){\n if(eventName.indexOf(" ")>0){\n return eventName.split(" ").map(function(v){\n return _db.off(v,func);\n });\n }\n if(!(eventName in listeners)){\n return;\n }else if(!func){\n delete listeners[eventName];\n }else{\n if(listeners[eventName].indexOf(func)>-1){\n if(listeners[eventName].length>1){\n delete listeners[eventName];\n }else{\n listeners[eventName].splice(listeners[eventName].indexOf(func),1);\n }\n }\n }\n};\nvar console={};\nfunction makeConsole(method){\n return function(){\n var len = arguments.length;\n var out =[];\n var i = 0;\n while (if)return a;e.splice(f,d);return e.concat(c||[]).join("/")}return c}function H(a){var b=a.indexOf("!");return{g:a.substr(b+1),d:0<=b&&a.substr(0,b)}}function M(){}function u(a,b){M.prototype=
4 | a||N;var d=new M;M.prototype=N;for(var c in b)d[c]=b[c];return d}function A(){function a(a,b,d){c.push([a,b,d])}function b(a,b){for(var d,e=0;d=c[e++];)(d=d[a])&&d(b)}var d,c,e;d=this;c=[];e=function(d,g){a=d?function(a){a&&a(g)}:function(a,b){b&&b(g)};e=R;b(d?0:1,g);b=R;c=k};this.A=function(b,c,e){a(b,c,e);return d};this.h=function(a){d.oa=a;e(!0,a)};this.e=function(a){d.na=a;e(!1,a)};this.u=function(a){b(2,a)}}function I(a){return a instanceof A||a instanceof y}function v(a,b,d,c){I(a)?a.A(b,d,
5 | c):b(a)}function B(a,b,d){var c;return function(){0<=--a&&b&&(c=b.apply(k,arguments));0==a&&d&&d(c);return c}}function z(){var a,b;a=[].slice.call(arguments);m(a[0],"Object")&&(b=a.shift(),b=J(b));return new y(a[0],a[1],a[2],b)}function J(a,b,d){var c,e,f;if(a&&(h.O(a),n=h.a(a),"preloads"in a&&(c=new y(a.preloads,k,d,C,!0),h.K(function(){C=c})),f=(f=a.main)&&String(f).split(Z)))return e=new A,e.A(b,d),a=f[1]?function(){new y([f[1]],e.h,e.e)}:e.e,new y([f[0]],e.h,a),e}function y(a,b,d,c,e){var f;f=
6 | h.j(n,k,[].concat(a),e);this.then=this.A=a=function(a,b){v(f,function(b){a&&a.apply(k,b)},function(a){if(b)b(a);else throw a;});return this};this.next=function(a,b,c){return new y(a,b,c,f)};this.config=J;(b||d)&&a(b,d);h.K(function(){v(e||C,function(){v(c,function(){h.q(f)},d)})})}function T(a){var b,d;b=a.id;b==k&&(D!==k?D={G:"Multiple anonymous defines encountered"}:(b=h.$())||(D=a));if(b!=k){d=l[b];b in l||(d=h.i(b,n),d=h.C(d.a,b),l[b]=d);if(!I(d))throw Error("duplicate define: "+b);d.ca=!1;h.D(d,
7 | a)}}function O(){var a=h.X(arguments);T(a)}var n,w,E,x=p.document,P=x&&(x.head||x.getElementsByTagName("head")[0]),$=P&&P.getElementsByTagName("base")[0]||null,U={},V={},K={},aa="addEventListener"in p?{}:{loaded:1,complete:1},N={},X=N.toString,k,l={},L={},C=!1,D,W=/^\/|^[^:]+:\/\//,Y=/(\.)(\.?)(?:$|\/([^\.\/]+.*)?)/g,ba=/\/\*[\s\S]*?\*\/|\/\/.*?[\n\r]/g,ca=/require\s*\(\s*(["'])(.*?[^\\])\1\s*\)|[^\\]?(["'])/g,Z=/\s*,\s*/,Q,h;h={m:function(a,b,d){var c;a=S(a,b);if("."==a.charAt(0))return a;c=H(a);
8 | a=(b=c.d)||c.g;a in d.c&&(a=d.c[a].l||a);b&&(0>b.indexOf("/")&&!(b in d.c)&&(a=G(d.M)+"/"+b),a=a+"!"+c.g);return a},j:function(a,b,d,c){function e(b,c){var d,f;d=h.m(b,g.id,a);if(!c)return d;f=H(d);if(!f.d)return d;d=l[f.d];f.g="normalize"in d?d.normalize(f.g,e,g.a)||"":e(f.g);return f.d+"!"+f.g}function f(b,d,f){var r;r=d&&function(a){d.apply(k,a)};if(m(b,"String")){if(r)throw Error("require(id, callback) not allowed");f=e(b,!0);b=l[f];if(!(f in l))throw Error("Module not resolved: "+f);return(f=
9 | I(b)&&b.b)||b}v(h.q(h.j(a,g.id,b,c)),r,f)}var g;g=new A;g.id=b||"";g.aa=c;g.F=d;g.a=a;g.v=f;f.toUrl=function(b){return h.i(e(b,!0),a).url};g.m=e;return g},C:function(a,b,d){var c,e,f;c=h.j(a,b,k,d);e=c.h;f=B(1,function(a){c.p=a;try{return h.R(c)}catch(b){c.e(b)}});c.h=function(a){v(d||C,function(){e(l[c.id]=L[c.url]=f(a))})};c.H=function(a){v(d||C,function(){c.b&&(f(a),c.u(V))})};return c},Q:function(a,b,d,c){return h.j(a,d,k,c)},Z:function(a){return a.v},I:function(a){return a.b||(a.b={})},Y:function(a){var b=
10 | a.r;b||(b=a.r={id:a.id,uri:h.J(a),exports:h.I(a),config:function(){return a.a}},b.b=b.exports);return b},J:function(a){return a.url||(a.url=h.B(a.v.toUrl(a.id),a.a))},O:function(a){var b,d,c,e,f;b="curl";d="define";c=e=p;if(a&&(f=a.overwriteApi||a.la,b=a.apiName||a.ea||b,c=a.apiContext||a.da||c,d=a.defineName||a.ga||d,e=a.defineContext||a.fa||e,w&&m(w,"Function")&&(p.curl=w),w=null,E&&m(E,"Function")&&(p.define=E),E=null,!f)){if(c[b]&&c[b]!=z)throw Error(b+" already exists");if(e[d]&&e[d]!=O)throw Error(d+
11 | " already exists");}c[b]=z;e[d]=O},a:function(a){function b(a,b){var d,c,g,q,s;for(s in a){g=a[s];m(g,"String")&&(g={path:a[s]});g.name=g.name||s;q=e;c=H(G(g.name));d=c.g;if(c=c.d)q=f[c],q||(q=f[c]=u(e),q.c=u(e.c),q.f=[]),delete a[s];c=g;var l=b,F=void 0;c.path=G(c.path||c.location||"");l&&(F=c.main||"./main","."==F.charAt(0)||(F="./"+F),c.l=S(F,c.name+"/"));c.a=c.config;c.a&&(c.a=u(e,c.a));c.P=d.split("/").length;d?(q.c[d]=c,q.f.push(d)):q.n=h.N(g.path,e)}}function d(a){var b=a.c;a.L=RegExp("^("+
12 | a.f.sort(function(a,c){return b[c].P-b[a].P}).join("|").replace(/\/|\./g,"\\$&")+")(?=\\/|$)");delete a.f}var c,e,f,g;"baseUrl"in a&&(a.n=a.baseUrl);"main"in a&&(a.l=a.main);"preloads"in a&&(a.ma=a.preloads);"pluginPath"in a&&(a.M=a.pluginPath);if("dontAddFileExt"in a||a.k)a.k=RegExp(a.dontAddFileExt||a.k);c=n;e=u(c,a);e.c=u(c.c);f=a.plugins||{};e.plugins=u(c.plugins);e.t=u(c.t,a.t);e.s=u(c.s,a.s);e.f=[];b(a.packages,!0);b(a.paths,!1);for(g in f)a=h.m(g+"!","",e),e.plugins[a.substr(0,a.length-1)]=
13 | f[g];f=e.plugins;for(g in f)if(f[g]=u(e,f[g]),a=f[g].f)f[g].f=a.concat(e.f),d(f[g]);for(g in c.c)e.c.hasOwnProperty(g)||e.f.push(g);d(e);return e},i:function(a,b){var d,c,e,f;d=b.c;e=W.test(a)?a:a.replace(b.L,function(a){c=d[a]||{};f=c.a;return c.path||""});return{a:f||n,url:h.N(e,b)}},N:function(a,b){var d=b.n;return d&&!W.test(a)?G(d)+"/"+a:a},B:function(a,b){return a+((b||n).k.test(a)?"":".js")},ba:function(a,b,d){var c=x.createElement("script");c.onload=c.onreadystatechange=function(d){d=d||p.event;
14 | if("load"==d.type||aa[c.readyState])delete K[a.id],c.onload=c.onreadystatechange=c.onerror="",b()};c.onerror=function(){d(Error("Syntax or http error: "+a.url))};c.type=a.ia||"text/javascript";c.charset="utf-8";c.async=!a.ka;c.src=a.url;K[a.id]=c;P.insertBefore(c,$);return c},S:function(a){var b=[],d;("string"==typeof a?a:a.toSource?a.toSource():a.toString()).replace(ba,"").replace(ca,function(a,e,f,g){g?d=d==g?k:d:d||b.push(f);return""});return b},X:function(a){var b,d,c,e,f,g;f=a.length;c=a[f-1];
15 | e=m(c,"Function")?c.length:-1;2==f?m(a[0],"Array")?d=a[0]:b=a[0]:3==f&&(b=a[0],d=a[1]);!d&&0
2 |
3 |
8 | Example
9 |
10 |
11 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/site/proj-small.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Projected Shapefiles in Leaflet!
9 |
10 |
13 |
14 |
15 |
20 |
21 |
51 |
52 |
--------------------------------------------------------------------------------
/site/proj.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Projected Shapefiles in Leaflet!
9 |
10 |
13 |
14 |
15 |
20 |
21 |
55 |
56 |
--------------------------------------------------------------------------------
/site/require.js:
--------------------------------------------------------------------------------
1 | /*
2 | RequireJS 2.1.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
3 | Available via the MIT or new BSD license.
4 | see: http://github.com/jrburke/requirejs for details
5 | */
6 | var requirejs,require,define;
7 | (function(Z){function H(b){return"[object Function]"===L.call(b)}function I(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(H(m)){if(this.events.error&&this.map.isDefine||j.onError!==aa)try{e=i.execCb(c,m,b,e)}catch(d){a=d}else e=i.execCb(c,m,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==
19 | this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",v(this.error=a)}else e=m;this.exports=e;if(this.map.isDefine&&!this.ignore&&(r[c]=e,j.onResourceLoad))j.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=
20 | !0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=n(a.prefix);this.depMaps.push(d);t(d,"defined",u(this,function(e){var m,d;d=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,g,!0)})||""),e=n(a.prefix+"!"+d,this.map.parentMap),t(e,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),
21 | d=l(p,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else m=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),m.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];F(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),m.fromText=u(this,function(e,c){var d=a.name,g=n(d),B=O;c&&(e=c);B&&(O=!1);q(g);s(k.config,b)&&(k.config[d]=k.config[b]);try{j.exec(e)}catch(ca){return v(A("fromtexteval",
22 | "fromText eval for "+b+" failed: "+ca,ca,[b]))}B&&(O=!0);this.depMaps.push(g);i.completeLoad(d);h([d],m)}),e.load(a.name,h,m,k)}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){T[this.map.id]=this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,e;if("string"===typeof a){a=n(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=l(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;t(a,"defined",u(this,function(a){this.defineDep(b,
23 | a);this.check()}));this.errback&&t(a,"error",u(this,this.errback))}c=a.id;e=p[c];!s(N,c)&&(e&&!e.enabled)&&i.enable(a,this)}));F(this.pluginMaps,u(this,function(a){var b=l(p,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:r,urlFetched:S,defQueue:G,Module:X,makeModuleMap:n,
24 | nextTick:j.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};F(a,function(a,b){e[b]?"map"===b?(k.map||(k.map={}),Q(k[b],a,!0,!0)):Q(k[b],a,!0):k[b]=a});a.shim&&(F(a.shim,function(a,b){I(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,
25 | location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);F(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=n(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(Z,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function d(e,c,h){var g,k;f.enableBuildCallback&&(c&&H(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(H(c))return v(A("requireargs",
26 | "Invalid require call"),h);if(a&&s(N,e))return N[e](p[a.id]);if(j.get)return j.get(i,e,a,d);g=n(e,a,!1,!0);g=g.id;return!s(r,g)?v(A("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[g]}K();i.nextTick(function(){K();k=q(n(null,a));k.skipMap=f.skipMap;k.init(e,c,h,{enabled:!0});C()});return d}f=f||{};Q(d,{isBrowser:z,toUrl:function(b){var d,f=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==f&&(!("."===g||".."===g)||1h.attachEvent.toString().indexOf("[native code"))&&!W?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",
34 | b.onScriptError,!1)),h.src=d,K=h,C?x.insertBefore(h,C):x.appendChild(h),K=null,h;if(da)try{importScripts(d),b.completeLoad(c)}catch(l){b.onError(A("importscripts","importScripts failed for "+c+" at "+d,l,[c]))}};z&&M(document.getElementsByTagName("script"),function(b){x||(x=b.parentNode);if(J=b.getAttribute("data-main"))return q=J,t.baseUrl||(D=q.split("/"),q=D.pop(),fa=D.length?D.join("/")+"/":"./",t.baseUrl=fa),q=q.replace(ea,""),j.jsExtRegExp.test(q)&&(q=J),t.deps=t.deps?t.deps.concat(q):[q],!0});
35 | define=function(b,c,d){var h,j;"string"!==typeof b&&(d=c,c=b,b=null);I(c)||(d=c,c=null);!c&&H(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(h=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),h=P;h&&(b||(b=h.getAttribute("data-requiremodule")),j=E[h.getAttribute("data-requirecontext")])}(j?j.defQueue:
36 | R).push([b,c,d])};define.amd={jQuery:!0};j.exec=function(b){return eval(b)};j(t)}})(this);
37 |
--------------------------------------------------------------------------------
/test/data/LGA_2013_AUST.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/test/data/LGA_2013_AUST.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/LGA_2013_AUST.dbf
--------------------------------------------------------------------------------
/test/data/LGA_2013_AUST.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_GDA_1994",DATUM["D_GDA_1994",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG",4283]]
--------------------------------------------------------------------------------
/test/data/LGA_2013_AUST.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/LGA_2013_AUST.shp
--------------------------------------------------------------------------------
/test/data/LGA_2013_AUST.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/LGA_2013_AUST.shx
--------------------------------------------------------------------------------
/test/data/SHP_Exclude.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/SHP_Exclude.zip
--------------------------------------------------------------------------------
/test/data/T8Th4_6n.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/T8Th4_6n.zip
--------------------------------------------------------------------------------
/test/data/bad.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/bad.dbf
--------------------------------------------------------------------------------
/test/data/bad.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/bad.shp
--------------------------------------------------------------------------------
/test/data/badlen.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/badlen.zip
--------------------------------------------------------------------------------
/test/data/badzip.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/badzip.zip
--------------------------------------------------------------------------------
/test/data/codepage.cpg:
--------------------------------------------------------------------------------
1 | ANSI 1250
2 |
--------------------------------------------------------------------------------
/test/data/codepage.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/codepage.dbf
--------------------------------------------------------------------------------
/test/data/codepage.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/test/data/codepage.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/test/data/codepage.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/codepage.shp
--------------------------------------------------------------------------------
/test/data/codepage.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/codepage.shx
--------------------------------------------------------------------------------
/test/data/codepage.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/codepage.zip
--------------------------------------------------------------------------------
/test/data/counties.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.dbf
--------------------------------------------------------------------------------
/test/data/counties.sbn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.sbn
--------------------------------------------------------------------------------
/test/data/counties.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.sbx
--------------------------------------------------------------------------------
/test/data/counties.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.shp
--------------------------------------------------------------------------------
/test/data/counties.shp.xml:
--------------------------------------------------------------------------------
1 | 20130910 08255500 FALSE CreateFeatureclass "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries" Towns # GISPLANNER_Layer SAME_AS_TEMPLATE SAME_AS_TEMPLATE "PROJCS['NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',200000.0],PARAMETER['False_Northing',750000.0],PARAMETER['Central_Meridian',-71.5],PARAMETER['Standard_Parallel_1',41.71666666666667],PARAMETER['Standard_Parallel_2',42.68333333333333],PARAMETER['Latitude_Of_Origin',41.0],UNIT['Meter',1.0]];-361489.141077092 327975.618391579 1953.12499818101;0 1;0 1" # 0 0 0 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisVector.GISADMIN.Towns" Append GISPLANNER_Layer "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisVector.GISADMIN.Towns" TEST "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisVector.GISADMIN.Towns" FeatureClassToFeatureClass "Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Mark\gisdevelopment.GISPLANNER.boundary" "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries" Towns # "TOWN TOWN VISIBLE;TOWN_ID TOWN_ID VISIBLE;TOWNS_ID TOWNS_ID VISIBLE;COASTAL_POLY COASTAL_POLY VISIBLE;SQUARE_MILES SQUARE_MILES VISIBLE;SHAPE.area SHAPE.area VISIBLE;SHAPE.len SHAPE.len VISIBLE" SAME_AS_TEMPLATE SAME_AS_TEMPLATE # 0 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisVector.GISADMIN.Towns" CopyFeatures Counties_poly_from_361_new S:\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb\County_poly # 1000 0 0 AddField S:\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb\County_poly F_AREA DOUBLE # # # # NULLABLE NON_REQUIRED # S:\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb\County_poly CalculateAreas Counties_poly_from_361_new S:\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb\County_poly FeatureClassToFeatureClass "Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Mark\gisdevelopment.GISPLANNER.Counties_poly" "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries" Counties2 # "COUNTY COUNTY true true false 20 Text 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Mark\gisdevelopment.GISPLANNER.Counties_poly,COUNTY,-1,-1;area area false false true 0 Double 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Mark\gisdevelopment.GISPLANNER.Counties_poly,Shape.area,-1,-1;len len false false true 0 Double 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Mark\gisdevelopment.GISPLANNER.Counties_poly,Shape.len,-1,-1" # "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties2" AddSpatialIndex "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties" 0 0 0 "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties" FeatureClassToFeatureClass "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties" "Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin" Counties2 # "COUNTY COUNTY true true false 20 Text 0 0 ,First,#,Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties,COUNTY,-1,-1;area area false true true 8 Double 8 38 ,First,#,Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties,gisvector.GISADMIN.Counties.area,-1,-1;len len false true true 8 Double 8 38 ,First,#,Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties,gisvector.GISADMIN.Counties.len,-1,-1;area_1 area_1 false false true 0 Double 0 0 ,First,#,Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties,Shape.area,-1,-1;len_1 len_1 false false true 0 Double 0 0 ,First,#,Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties,Shape.len,-1,-1" # "Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2" FeatureClassToFeatureClass "Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2" "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries" Counties # "COUNTY COUNTY true true false 20 Text 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,COUNTY,-1,-1;area area false true true 8 Double 8 38 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,gisdevelopment.GISPLANNER.Counties2.area,-1,-1;len len false true true 8 Double 8 38 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,gisdevelopment.GISPLANNER.Counties2.len,-1,-1;area_1 area_1 false true true 8 Double 8 38 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,area_1,-1,-1;len_1 len_1 false true true 8 Double 8 38 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,len_1,-1,-1;area_12 area_12 false false true 0 Double 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,Shape.area,-1,-1;len_12 len_12 false false true 0 Double 0 0 ,First,#,Database Connections\Planning Development.sde\gisDevelopment.GISPLANNER.Kevin\gisdevelopment.GISPLANNER.Counties2,Shape.len,-1,-1" # "Database Connections\Admin gisVector.sde\gisVector.GISADMIN.Boundaries\gisvector.GISADMIN.Counties" Project gisvector.GISADMIN.Counties "\\mhd-fsp-bos-v01\urd$\metcalfc\My Documents\ArcGIS\Default.gdb\Counties_Project1" GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]] NAD_1983_To_WGS_1984_1 PROJCS['NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001',GEOGCS['GCS_North_American_1983',DATUM['D_North_American_1983',SPHEROID['GRS_1980',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Lambert_Conformal_Conic'],PARAMETER['False_Easting',200000.0],PARAMETER['False_Northing',750000.0],PARAMETER['Central_Meridian',-71.5],PARAMETER['Standard_Parallel_1',41.71666666666667],PARAMETER['Standard_Parallel_2',42.68333333333333],PARAMETER['Latitude_Of_Origin',41.0],UNIT['Meter',1.0]] SimplifyPolygon Counties_Project1 \\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\counties.shp POINT_REMOVE "20 Meters" "0 SquareMeters" NO_CHECK NO_KEEP file://\\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\counties.shp Local Area Network counties 002 0.000 Geographic GCS_WGS_1984 Angular Unit: Degree (0.017453) <GeographicCoordinateSystem xsi:type='typens:GeographicCoordinateSystem' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.0'><WKT>GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG",4326]]</WKT><XOrigin>-399.99999999999989</XOrigin><YOrigin>-399.99999999999989</YOrigin><XYScale>11258999068426.24</XYScale><ZOrigin>-100000</ZOrigin><ZScale>10000</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>8.9831528411952133e-009</XYTolerance><ZTolerance>0.001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision><LeftLongitude>-180</LeftLongitude><WKID>4326</WKID></GeographicCoordinateSystem> 20130910 08492300 20130910 08492300 1.0 Server=mhd-gis-wh; Service=5151; Database=gisvector; User=gisadmin; Version=sde.DEFAULT REQUIRED: The name of an organization or individual that developed the data set. REQUIRED: The date when the data set is published or otherwise made available for release. gisvector.GISADMIN.Counties gisvector.GISADMIN.Counties vector digital data Microsoft Windows XP Version 5.1 (Build 2600) Service Pack 2; ESRI ArcCatalog 9.2.2.1350 en REQUIRED: A brief narrative summary of the data set. REQUIRED: A summary of the intentions with which the data set was developed. REQUIRED: The basis on which the time period of content information is determined. REQUIRED: The year (and optionally month, or month and day) for which the data set corresponds to the ground. REQUIRED: The state of the data set. REQUIRED: The frequency with which changes and additions are made to the data set after the initial data set is completed. REQUIRED: Western-most coordinate of the limit of coverage expressed in longitude. REQUIRED: Eastern-most coordinate of the limit of coverage expressed in longitude. REQUIRED: Northern-most coordinate of the limit of coverage expressed in latitude. REQUIRED: Southern-most coordinate of the limit of coverage expressed in latitude. REQUIRED: Reference to a formally registered thesaurus or a similar authoritative source of theme keywords. REQUIRED: Common-use word or phrase used to describe the subject of the data set. REQUIRED: Restrictions and legal prerequisites for accessing the data set. REQUIRED: Restrictions and legal prerequisites for using the data set after access is granted. SDE Feature Class Server=mhd-gis-wh; Service=5151; Database=gisvector; User=gisadmin; Version=sde.DEFAULT ArcSDE Connection 002 SDE Feature Class Shapefile 0.000 Dataset copied. Server=mhd-gis-wh; Service=esri_sde; Database=gisvector; User=gisviewer; Version=sde.DEFAULT 20061207 10363000 Dataset copied. 20061208 16173500 Dataset copied. \\MHD-Shared\SharedData$\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb 20061211 10473400 Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; ESRI ArcGIS 10.0.5.4400 counties en FGDC Content Standards for Digital Geospatial Metadata FGDC-STD-001-1998 local time REQUIRED: The person responsible for the metadata information. REQUIRED: The organization responsible for the metadata information. REQUIRED: The mailing and/or physical address for the organization or individual. REQUIRED: The city of the address. REQUIRED: The state or province of the address. REQUIRED: The ZIP or other postal code of the address. REQUIRED: The telephone number by which individuals can speak to the organization or individual. 20070518 ISO 19115 Geographic Information - Metadata DIS_ESRI1.0 dataset Downloadable Data Vector Simple FALSE 0 FALSE FALSE GCS_North_American_1983 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 North American Datum of 1983 Geodetic Reference System 80 6378137.000000 298.257222 Explicit elevation coordinate included with horizontal coordinates 1.000000 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 EPSG 7.4.1 0 counties Feature Class 0 len_12 FID OID 4 0 0 Internal feature number. ESRI Sequential unique whole numbers that are automatically generated. Shape area_1 Double 19 0 0 Feature geometry. ESRI Coordinates defining the features. area_1 len_1 Double 19 0 0 area area Double 19 0 0 len len Double 19 0 0 len_1 COUNTY String 20 0 0 COUNTY Shape Geometry 0 0 0 Feature geometry. ESRI Coordinates defining the features. SHAPE area_12 Double 19 0 0 Feature geometry. ESRI Coordinates defining the features. area_12 len_12 Double 19 0 0 Shape_Leng Shape_Leng Double 19 0 0 Shape_Area Shape_Area Double 19 0 0 Area of feature in internal units squared. ESRI Positive real numbers that are automatically generated. 20130910
2 |
--------------------------------------------------------------------------------
/test/data/counties.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.shx
--------------------------------------------------------------------------------
/test/data/counties.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/counties.zip
--------------------------------------------------------------------------------
/test/data/export_multipointz.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_multipointz.dbf
--------------------------------------------------------------------------------
/test/data/export_multipointz.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
--------------------------------------------------------------------------------
/test/data/export_multipointz.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_multipointz.shp
--------------------------------------------------------------------------------
/test/data/export_multipointz.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_multipointz.shx
--------------------------------------------------------------------------------
/test/data/export_polylinez.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_polylinez.dbf
--------------------------------------------------------------------------------
/test/data/export_polylinez.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
--------------------------------------------------------------------------------
/test/data/export_polylinez.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_polylinez.shp
--------------------------------------------------------------------------------
/test/data/export_polylinez.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/export_polylinez.shx
--------------------------------------------------------------------------------
/test/data/htmlcpg.cpg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Projected Shapefiles in Leaflet!
9 |
10 |
13 |
14 |
15 |
20 |
21 |
55 |
56 |
--------------------------------------------------------------------------------
/test/data/htmlcpg.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/htmlcpg.dbf
--------------------------------------------------------------------------------
/test/data/htmlcpg.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/test/data/htmlcpg.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/htmlcpg.shp
--------------------------------------------------------------------------------
/test/data/htmlprj.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/test/data/htmlprj.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/htmlprj.dbf
--------------------------------------------------------------------------------
/test/data/htmlprj.prj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Projected Shapefiles in Leaflet!
9 |
10 |
13 |
14 |
15 |
20 |
21 |
55 |
56 |
--------------------------------------------------------------------------------
/test/data/htmlprj.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/htmlprj.shp
--------------------------------------------------------------------------------
/test/data/ipra_dresden_polygon.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/ipra_dresden_polygon.dbf
--------------------------------------------------------------------------------
/test/data/ipra_dresden_polygon.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
--------------------------------------------------------------------------------
/test/data/ipra_dresden_polygon.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/ipra_dresden_polygon.shp
--------------------------------------------------------------------------------
/test/data/ipra_dresden_polygon.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/ipra_dresden_polygon.shx
--------------------------------------------------------------------------------
/test/data/mixedcase.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/mixedcase.zip
--------------------------------------------------------------------------------
/test/data/no-dbf.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/no-dbf.sbx
--------------------------------------------------------------------------------
/test/data/no-dbf.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/no-dbf.shp
--------------------------------------------------------------------------------
/test/data/no-dbf.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/no-dbf.zip
--------------------------------------------------------------------------------
/test/data/noshp.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/noshp.zip
--------------------------------------------------------------------------------
/test/data/qgis.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/qgis.zip
--------------------------------------------------------------------------------
/test/data/senate.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.dbf
--------------------------------------------------------------------------------
/test/data/senate.prj:
--------------------------------------------------------------------------------
1 | PROJCS["NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",750000.0],PARAMETER["Central_Meridian",-71.5],PARAMETER["Standard_Parallel_1",41.71666666666667],PARAMETER["Standard_Parallel_2",42.68333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Meter",1.0]]
--------------------------------------------------------------------------------
/test/data/senate.sbn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.sbn
--------------------------------------------------------------------------------
/test/data/senate.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.sbx
--------------------------------------------------------------------------------
/test/data/senate.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.shp
--------------------------------------------------------------------------------
/test/data/senate.shp.xml:
--------------------------------------------------------------------------------
1 | 20120312 14003900 1.0 FGDC CSDGM Metadata FALSE 20130910 08390500 senate 002 33861.260000 330846.090100 777514.310000 959747.440000 1 file://\\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\senate.shp Local Area Network 0.000 Projected GCS_North_American_1983 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 <ProjectedCoordinateSystem xsi:type='typens:ProjectedCoordinateSystem' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.0'><WKT>PROJCS["NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",200000.0],PARAMETER["False_Northing",750000.0],PARAMETER["Central_Meridian",-71.5],PARAMETER["Standard_Parallel_1",41.71666666666667],PARAMETER["Standard_Parallel_2",42.68333333333333],PARAMETER["Latitude_Of_Origin",41.0],UNIT["Meter",1.0],AUTHORITY["EPSG",26986]]</WKT><XOrigin>-36530900</XOrigin><YOrigin>-28803200</YOrigin><XYScale>122610652.81195112</XYScale><ZOrigin>-100000</ZOrigin><ZScale>10000</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>0.001</XYTolerance><ZTolerance>0.001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision><WKID>26986</WKID></ProjectedCoordinateSystem> Linear Unit: Meter (1.000000) CopyFeatures "Database Connections\GISDATA_VT_DC.sde\GISDATA.SENATE2012_POLY" E:\MassGIS\mtrust\MassGIS_DataViewer_SHP\gisdata\men1\Political_Boundaries\SENATE2012_POLY.shp # 0 0 0 SimplifyPolygon SENATE2012_POLY \\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\senate.shp POINT_REMOVE "20 Meters" "0 SquareMeters" NO_CHECK NO_KEEP 20130910 08390500 FGDC /9j/4AAQSkZJRgABAQEAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
2 | HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
3 | MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCACFAMgDASIA
4 | AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
5 | AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
6 | ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
7 | p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
8 | AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
9 | BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
10 | U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
11 | uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iii
12 | gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKge6jCZjZJDnGA3A+p7VXF7uUyieDavBUOCo
13 | +rf5/Gsp14QdpMaTZfoqG1nFzbrMpBDZwVORwcVNWogooooAKKKKACiiigAooooAinkaNBsxvZgB
14 | kce/6A1F5lx/fi/74P8AjSyndcgdkX9T/wDq/WivMxOJnGpywexcYq2oefP/AM8Y/wDv4f8A4mmv
15 | dTIuTCnUDiQ9zj0p1MlQyRMoOCRwfQ9jWKxlXuPlRJ9pccNbuT/skEfqR/Kj7Uf+feX81/xqszTR
16 | ywh5IiHYrgIQehPHPtViq+u1V2DlQ77V6wygdzwf5Gj7XF/00/79N/hTarJLcTKJYlj8onKhzgsu
17 | OuRnHPbHSqWOqdkHKi2t5CyhlMhBGQfLb/Cl+1w92Kj1ZSo/MiqgdolSBE3yIgJ5wMdOv4UqyyTA
18 | GNCi4zukXH4bev54/Gq+vT7C5Sz9stcZ+0w4/wB8Uv2u2/5+Iv8AvsVTmRo7J04dmJGOgO4/j61L
19 | DPHcRh42BHcZ5B9D6Gn9fdr8ochY+1W//PeL/vsVUu72MhohtKZUFs/eyegAHzdDUVx5zXI2MdsY
20 | DhVA3MfmBwTx6daZaSowaaUvvUNtLgbvLOPTgjI460p42Uo6IFEc8yXcvkojDcvLsMZTPIHfqMfj
21 | n0qW5tklifEaM+3ADLkH0BGRmmWiIssrLHIu75suDkZ6rz788cc1DBMwkEsjuqNuPOSDliFA98Dt
22 | +Gc5ri9CiHwheC40qSHYEa3mddqrhQCdwA9hnH4V0GQc4PTrXMXliY5P7T0y9S3xGcRrgRyNzyf6
23 | 9+PXmrmhpLIkdyoaNCmyZHHLyDgt+YPOfXivYo11USSX/AM2rG3RRRXQIKKKKACiiigAooqK4cpb
24 | uVOGPyqfQngfqaTdldgQRnful/56NuH06D9AKfSKoVQqjAAwBS189OTlJyfU2CiiipArvsa/hGfn
25 | VGbGeg4HT8ev1qxVe3LPJJIoxE+GBIwScAevoO471M7qi5Y8dOmap9gB2VY2ZvugEn6UkKlIUVuo
26 | GKr3EyTRrHG+Q8gRwOoHcH06EVboasgI5IVd0kGBImQremev8qi+0uUVxF8u8Ix3epxxxyM/SrBA
27 | ZSpGQRgiqyoZYXiUjajAKSMkbSOD+X+epF5gTyoZEwGAIIPIz0OahjEV7bRvNHGzFfmBGdpxyPam
28 | Tm7DJINqqjrlEy24E4OeM8CnQOszvc/KI+QjD+JeOSfqOP8A69O2gCeWTeCNn3oImGCOQCR1PfOD
29 | +VRlGkmSB5I3eACQHZjB6DOSc5GenTFQx30m9lVFExUzSZwV2gYwCCec4/MmpNTZPl5Jb7rjy2dQ
30 | hPJOOnTOfb8qs72ERtCsyLudJXMrLkjcpJO4EZPYfyIqDUvP821FpLJHMjBfIjYFJEwcgDt9eMY9
31 | MmsibVhFttkixG4KSjAUK6nPLZxznGcgg46V0GgwwC0hu0eeFmXZLA56vknLAjduO7PpgjjpXZQw
32 | 7lK72JbLdjptvGxunt1FxLtYl/mZcAcZOTWjRRXppW2ICiiigAooooAKKKKACq9wd0scfYZc/wAh
33 | /PP4VYqoDvnlftnaD7D/AOvmubFz5aT89CorUdRRTJpBDBJKRkIpbH0FeKaD6iM2X2RoznnJ6KPx
34 | /wAM0nmyL9+BvcoQw/of0p0AIgXcMMRuYe55P60WAr4ube1QeZCWUKuNh5PA65/X9KkRWmyzyHaH
35 | OEAGODx79s0y4E1yk0MMscZHyksm7qM56j1/So7G5LFYEtfKSNcP84baw7ZGQfzzzyBV2urgStAn
36 | 9pRS7RxG2PY5HP1+Y1aqvDGDcSytzKPkz2C9QB+fP/1hVipYCMSFJUbiBwM4zVITSwsZ/KMkE21v
37 | 3S5ZSeMnuRjb29au7l37Nw3YzjPOKpxi5h3pERMqMEVXO0qOO4HPB/SnEBksbrE9w/mK6scFmztU
38 | 8dAcDAOfwGaeGElsbaBC8e0R+Yu3aOOT17Zomnksz51xLmNuCixnC4B6HqSeB79gKVPMmlZ4mkiQ
39 | AEoygbmzznI9AOnrT6CGagok+UKwKAM8isBtQn5h78A/kKr2trfk7zII0Y/Oso3swPvxzjHX0PA7
40 | vneG9IUY8ySJk8tuMOOQCCOcEHr/AFqV/MitnntQkZwQ6SHaoI4z3Axj8apXSsBhz21zcxTQmKGG
41 | IT+UrttwwHcg5BAxgDjA4pYr+4e7Mlha3E7RSKCrsh3Y4J3HPUOcbcY/HFbU8dutlHKVZDsCKWJD
42 | DdgcjuRnNFvJIkUa28EYjMrqMtgFcseMZx0H8sd63p4mUIvlQnG5ftr5Lid4DHJHNGAWVhxg9wRw
43 | atViXM7XMStaeU08EiySQscOApyQOeCemTwQT2Na8M0dxAk0TbkdQyn2rvw9Z1Y67ohqxJRRRXQI
44 | KKKKACiiigAqv9kwW2zyqCScDb3OfSrFFTOEZq0lcLlbyJh0mTHvHz/OmvazSIyGaPDAg/uz/wDF
45 | VborL6tS/lHzMqLDcIoUmOQgctkrn8OajmknhIBty5YHb5ZJ544PHHX9Kv0VDwdF9B8zM25sXnBZ
46 | 7a3dyu3cTkgd8ZX3NPgtJLaLy4oowu4t80zE5JyeSDV+in9UpbBzMpJDcq0h2Q/M2f8AWH0A/u+1
47 | O/fDgwEn1VgR+uKt0UngqXYOZmZ9md3MklvIZd2QysuVHTAOemP5mpEVoUbbay+pO4MT+uT0q/RS
48 | eCpvuHMyl5o/uS/9+m/wpfNH9yX/AL9N/hVyio+oU+7DnZk2kQjuJXcESSFsfuivyhieT3Pzf55q
49 | QRmS2kRSFcSMRkcA7sjI/KrF2/lOkpViqo2doz6f4VWj3W1sWcL5jvk5P8TNgDPfGQPwrjxFL2c7
50 | IqLuQI8r3Ek6y2wj2gqrkllOBwefl5+tPtpIZLog2/lyDLK5Bw+c5wcc+v41ZjiUAByryA7ySO/q
51 | PSomMd021XeKVCwVgACMcEjOQR+dY3uUVkkS1jR5oTHFFGUkIAwjHBOQOueDkfjU2iyyjzoZ0fzW
52 | YzZ8oooB6LzwCABke/1pxV4ZPOmdGUjY+1MDHYnr/wDWyacIpbZXNtIcfeETAFemMD0GB/npXVhq
53 | 0Kcm5dSZJs0qjuImmgeNJWiZhw69RT1YOispyrDINLXrGZlBLu3t2uJJmjKsd6M29duevPQY5P07
54 | VoQS+chJGHU7WHof88/jTb3d9guNgJbymwAM5ODVKznuBqMsNxGBj5N652ucbhgduM559Kx1hJJb
55 | DNSiiithBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBFdAtayhQSdh4HU8dKz5blZ4SLcOzq6
56 | jBjYYIIODkcVq1n6pYPdxpJDLLHNGQyiNgA2DkbgeoHpXNiKHtbNbopOxTtp7m4v7xUTy4VYASnD
57 | HIUZUc9ufxz71adY4XgCbBJ8wUM2CwPX684JpkX7iCGGI/eJUyMpzu5JJHqTu/GlcRRyCAsRLKjO
58 | JG55Uj+pzjp1ryHvYsS4uSiTJM0EOEHzvJxzn1HsajN7HGZLV5EjdI12FWMjHORnGMnke+aoXdm2
59 | q3kduBHNH5pacupC7V2qQO+eW9Rzz2w7TLBLPX9SxEAihCshYtydxPJ6HBGfXOe9b+wtS9oxX1sb
60 | dldwSxrCn7uRBjyXyGAH15I96t1kSTC4Q+bGI7bIPmORhx2x6Zz/AJNUXt9NtJmmfVJlWZymzz/l
61 | HqvHQcde3qK66eNTVpLXyJcTea8t1Yr5ysw6qh3N+Q5rC1S6ni1fTZN/kxSXKrs5y/8ADzjjnd/4
62 | 6PWtCC6MjMkVtKY1wI2C4DDHUE4GPxrN1WO5fVtMaO3nVmfG4SKQo7kqM9MnkH+lONSrUmrxsgsk
63 | dNRRRXaSFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBzl9fRw30Np5jBxdfOm3Gd2XX6
64 | jAI4zzipI7eHXnlacExIhQRvFgxuwIYHPUjtj17itO60qxvH3z20TyblO8qC3BBxn046fWmz3iWM
65 | iW8Fq8nyFtsKHCjt2x6988dDXNHDxjPnKvpYksrVdPsVhLqQgJZ9ipn3IGBWaLqR5bmXT4Dd+ZOP
66 | 4tqgBVB5PHbpU1xbS3itJqSItoqk+Qjbt3Hfgc9entUVzcXtiiywQxx2cY5hjjyVUA9h1/h6dOeu
67 | BTrum0ozEr9CG10We/8ALfWFIjRNotllJXOTgnHcDj/9QrbNpAVjUxLiPbt46ben5UiXlvJMsMcq
68 | u7IXAU5BUHBOenWp62hCMVaIgqt5cjal5pUiNItqnPUk5PH4CrNFUAUUUUAFFFFABRRRQAUUUUAF
69 | FFFABRRRQAUUUUAFFFFABRRRQAUUUUAZci6hLqCxusRgUM4bBADZAX68E8ev0Bq35E//AD2j/wC/
70 | Z/8AiqmjiEW/DO25i3zNnGew9B7U+sZUISd5K47szrTSha373XmKWcMCqx7c7iDknJJ6fqas3Nw9
71 | syuYy0PRigJYHtx6VYorVJJWQio2pWixPL5pMaZ3MqMw4+gqnpl073tyDC8VvLJmIMm35tuSR9eS
72 | ffPfmr5s4gSY90RJydh465PHTn1xSraqJFdpJHK8qGxgHpngD1rN+15tLWHoT0UUVqIKKKKACiii
73 | gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//Z 20130910 Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; ESRI ArcGIS 10.0.5.4400 State Senate Districts (2012) MassGIS One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 Map of the Commonwealth of Massachusetts, Senate Districts, Chapter 152 of the Acts of 2011
74 | Bill: http://www.malegislature.gov/Bills/Detail?billNumber=s02045 002 -73.533350 -69.898477 42.888351 41.230341 1 Massachusetts General Court Special Joint Committee on Redistricting and MassGIS None MassGIS One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 Senate 2012 Districts Senate 2012 Districts <DIV STYLE="text-align:Left;"><DIV><DIV><P><SPAN>Massachusetts Senate Districts (polygons) as signed into law on November 3, 2011. These districts were based on demographic data from the 2010 U.S. Census and are used for elections in 2012 and beyond until the districts are redrawn.</SPAN></P></DIV></DIV></DIV> Map of the Commonwealth of Massachusetts, Senate Districts, Chapter 152 of the Acts of 2011
75 | Bill: http://www.malegislature.gov/Bills/Detail?billNumber=s02045 Shapefile MassGIS One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 Download from http://www.mass.gov/itd/senate2012 0.000 dataset EPSG 7.4.1 Vector Simple FALSE 0 FALSE FALSE 0 senate Feature Class 0 FID FID OID 4 0 0 Internal feature number. ESRI Sequential unique whole numbers that are automatically generated. SENDISTNUM SENDISTNUM Integer 5 5 0 Numeric Senate district identifier SEN_DIST SEN_DIST String 43 0 0 Name of Senate District SEN_FIRST SEN_FIRST String 13 0 0 Senator's first name SEN_LAST SEN_LAST String 15 0 0 Senator's last name SEN_PARTY SEN_PARTY String 3 0 0 Senator's political party SENATOR SENATOR String 40 0 0 Senator's full name and party URL URL String 150 0 0 Senator's Web site SHAPE Shape Geometry 0 0 0 Feature geometry. ESRI Coordinates defining the features. SHAPE_AREA SHAPE_AREA Double 19 0 0 Area of feature in internal units squared. ESRI Positive real numbers that are automatically generated. SHAPE_LEN SHAPE_LEN Double 19 0 0 State Senate Districts (2012) Massachusetts General Court Special Joint Committee on Redistricting and MassGIS 20130529 Massachusetts Senate Districts (polygons) as signed into law on November 3, 2011. These districts were based on demographic data from the 2010 U.S. Census and are used for elections in 2012 and beyond until the districts are redrawn. Senate 2012 Districts English Map of the Commonwealth of Massachusetts, Senate Districts, Chapter 152 of the Acts of 2011
76 | Bill: http://www.malegislature.gov/Bills/Detail?billNumber=s02045 None None Massachusetts General Court Special Joint Committee on Redistricting and MassGIS MassGIS mailing and physical address One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 20130529 publication date Complete As needed None State Senate Districts (2012) None Commonwealth of Massachusetts SDE Feature Class 20130529 http://www.mass.gov/itd/senate2012 MassGIS Web Documentation MassGIS mailing and physical address One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 MassGIS mailing and physical address One Ashburton Place, Room 1601 Boston MA 02108 USA 617-619-5611 Download from http://www.mass.gov/itd/senate2012 GCS_North_American_1983 NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001 North American Datum of 1983 Geodetic Reference System 80 6378137.000000 298.257222 coordinate pair 0.010000 0.010000 meters Data obtained in early 2012 by MassGIS from the Massachusetts General Court Special Joint Committee on Redistricting. MassGIS added its 1:100,000 coastline and standardized attributes, followed by QA/QC procedures. Attribute updates on May 29 2013 ArcGIS 10.0 None None
77 |
--------------------------------------------------------------------------------
/test/data/senate.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.shx
--------------------------------------------------------------------------------
/test/data/senate.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/senate.zip
--------------------------------------------------------------------------------
/test/data/train_stations.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/train_stations.zip
--------------------------------------------------------------------------------
/test/data/utf.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/test/data/utf.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/utf.dbf
--------------------------------------------------------------------------------
/test/data/utf.prj:
--------------------------------------------------------------------------------
1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
--------------------------------------------------------------------------------
/test/data/utf.qpj:
--------------------------------------------------------------------------------
1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]
2 |
--------------------------------------------------------------------------------
/test/data/utf.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/utf.shp
--------------------------------------------------------------------------------
/test/data/utf.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/utf.shx
--------------------------------------------------------------------------------
/test/data/utf.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/utf.zip
--------------------------------------------------------------------------------
/test/data/zero-len-line.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calvinmetcalf/shapefile-js/fc8cf45df99c6fc8d9454e83ab882f8e42ede115/test/data/zero-len-line.zip
--------------------------------------------------------------------------------
/test/fixtures.js:
--------------------------------------------------------------------------------
1 | import server from './server.js'
2 | export async function mochaGlobalSetup() {
3 | return new Promise((yes, no) => {
4 | this.server = server.listen(3000, (err) => {
5 | if (err) {
6 | return no(err);
7 | }
8 | yes()
9 | });
10 | });
11 | }
12 | export async function mochaGlobalTeardown() {
13 | return new Promise((yes, no) => {
14 | this.server.close((err) => {
15 | if (err) {
16 | return no(err);
17 | }
18 | yes();
19 | });
20 | });
21 | };
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mocha Tests
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/server.js:
--------------------------------------------------------------------------------
1 |
2 | import express from 'express';
3 | import morgan from 'morgan';
4 | import path from 'path';
5 | import { rollup } from 'rollup';
6 | import { nodeResolve } from '@rollup/plugin-node-resolve';
7 |
8 | const app = express();
9 | if (process.env.SERVING) {
10 | app.use(morgan('dev'));
11 | }
12 | app.get('/test/bundle-browser.js', (req, res) => {
13 | rollup({
14 | input: path.join(import.meta.dirname, 'test.js'),
15 | plugins: [
16 | nodeResolve({ browser: true })
17 | ],
18 | })
19 | .then(result => {
20 | return result.generate({
21 | format: 'iife'
22 | })
23 | })
24 | .then(({ output: [{ code }] }) => {
25 | res.type('.js');
26 | res.send(code);
27 | }).catch(e => {
28 | console.log(e);
29 | res.sendStatus(500)
30 | })
31 | })
32 |
33 | app.use('/', express.static(path.join(import.meta.dirname, '..')));
34 | export default app;
35 | if (process.env.SERVING) {
36 | app.listen(3000, () => {
37 | console.log('go to http://localhost:3000/test/ to test in the browser');
38 | });
39 | }
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 |
2 | import shp from '../lib/index.js';
3 | import { should as shouldRaw, use } from 'chai';
4 |
5 | import { chaiAsPromised } from 'chai-promised';
6 | const should = shouldRaw();
7 | use(chaiAsPromised);
8 | const get = url => fetch(url).then(resp => resp.arrayBuffer())
9 | describe('Shp', function () {
10 | describe('park and rides not zipped', function () {
11 | const pandr = shp('http://localhost:3000/files/pandr');
12 | it('should have the right keys', function () {
13 | return pandr.should.eventually.contain.keys('type', 'features');
14 | });
15 | it('should be the right type', function () {
16 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
17 | });
18 | it('should have the right number of features', function () {
19 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(80);
20 | });
21 | });
22 | describe('park and rides not zipped but with suffix', function () {
23 | const pandr = shp('http://localhost:3000/files/pandr.shp');
24 | it('should have the right keys', function () {
25 | return pandr.should.eventually.contain.keys('type', 'features');
26 | });
27 | it('should be the right type', function () {
28 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
29 | });
30 | it('should have the right number of features', function () {
31 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(80);
32 | });
33 | });
34 | describe('park and rides not zipped but loaded individually', async function () {
35 | const pandr = Promise.all([
36 | get('http://localhost:3000/files/pandr.shp'),
37 | get('http://localhost:3000/files/pandr.dbf'),
38 | get('http://localhost:3000/files/pandr.prj')
39 | ]).then(([shapefile, dbf, prj]) => shp({
40 | shp: shapefile, dbf, prj
41 | }))
42 | it('should have the right keys', function () {
43 | return pandr.should.eventually.contain.keys('type', 'features');
44 | });
45 | it('should be the right type', function () {
46 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
47 | });
48 | it('should have the right number of features', function () {
49 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(80);
50 | });
51 | });
52 | describe('park and rides zipped', function () {
53 | const pandr = shp('http://localhost:3000/files/pandr.zip').catch(e => console.log('ERR', e));
54 | it('should have the right keys', function () {
55 | return pandr.should.eventually.contain.keys('type', 'features');
56 | });
57 | it('should be the right type', function () {
58 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
59 | });
60 | it('should have the right number of features', function () {
61 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(80);
62 | });
63 | });
64 | describe('senate unzipped', function () {
65 | const pandr = shp('http://localhost:3000/test/data/senate');
66 | it('should have the right keys', function () {
67 | return pandr.should.eventually.contain.keys('type', 'features');
68 | });
69 | it('should be the right type', function () {
70 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
71 | });
72 | it('should have the right number of features', function () {
73 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(40);
74 | });
75 | });
76 | describe('mixed case zipped', function () {
77 | const pandr = shp('http://localhost:3000/test/data/mixedcase.zip');
78 | it('should have the right keys', function () {
79 | return pandr.should.eventually.contain.keys('type', 'features');
80 | });
81 | it('should be the right type', function () {
82 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
83 | });
84 | it('should have the right number of features', function () {
85 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(40);
86 | });
87 | });
88 | describe('senate zipped', function () {
89 | const pandr = shp('http://localhost:3000/test/data/senate.zip');
90 | it('should have the right keys', function () {
91 | return pandr.should.eventually.contain.keys('type', 'features');
92 | });
93 | it('should be the right type', function () {
94 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
95 | });
96 | it('should have the right number of features', function () {
97 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(40);
98 | });
99 | });
100 | describe('county unzipped', function () {
101 | const pandr = shp('http://localhost:3000/test/data/counties');
102 | it('should have the right keys', function () {
103 | return pandr.should.eventually.contain.keys('type', 'features');
104 | });
105 | it('should be the right type', function () {
106 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
107 | });
108 | it('should have the right number of features', function () {
109 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(14);
110 | });
111 | });
112 | describe('county zipped', function () {
113 | return shp('http://localhost:3000/test/data/counties.zip').then(thing => {
114 | thing.should.contain.keys('type', 'features');
115 | thing.should.have.property('type', 'FeatureCollection');
116 | return thing.features;
117 | }).should.eventually.have.length(14);
118 | });
119 | describe('trains zipped', function () {
120 | const pandr = shp('http://localhost:3000/test/data/train_stations.zip');
121 | it('should have the right keys', function () {
122 | return pandr.should.eventually.contain.keys('type', 'features');
123 | });
124 | it('should be the right type', function () {
125 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
126 | });
127 | it('should have the right number of features', function () {
128 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(361);
129 | });
130 | });
131 | describe('trains zipped with query params', function () {
132 | const pandr = shp('http://localhost:3000/test/data/train_stations.zip?foo=bar');
133 | it('should have the right keys', function () {
134 | return pandr.should.eventually.contain.keys('type', 'features');
135 | });
136 | it('should be the right type', function () {
137 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
138 | });
139 | it('should have the right number of features', function () {
140 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(361);
141 | });
142 | });
143 | describe('z', function () {
144 | it('should work with multipoint z', function () {
145 | return shp('http://localhost:3000/test/data/export_multipointz').then(function (resp) {
146 | return resp.features[0].geometry.coordinates;
147 | }).should.eventually.deep.equal([
148 | [
149 | -123.00000000000001,
150 | 48.00000000000001,
151 | 1200
152 | ],
153 | [
154 | -122,
155 | 47,
156 | 2500
157 | ],
158 | [
159 | -121,
160 | 46,
161 | 3600
162 | ]
163 | ]);
164 | });
165 | it('should work with polyline z', function () {
166 | return shp('http://localhost:3000/test/data/export_polylinez').then(function (resp) {
167 | return resp.features[0].geometry.coordinates;
168 | }).should.eventually.deep.equal([
169 | [
170 | [
171 | -119.99999999999999,
172 | 45,
173 | 800
174 | ],
175 | [
176 | -119,
177 | 44,
178 | 1100
179 | ],
180 | [
181 | -118.00000000000001,
182 | 43,
183 | 2300
184 | ]
185 | ],
186 | [
187 | [
188 | -115,
189 | 40,
190 | 0
191 | ],
192 | [
193 | -114.00000000000001,
194 | 39,
195 | 0
196 | ],
197 | [
198 | -113,
199 | 38,
200 | 0
201 | ]
202 | ]
203 | ]);
204 | });
205 | });
206 | describe('empty attributes table', function () {
207 | const pandr = shp('http://localhost:3000/files/empty-shp.zip');
208 | it('should have the right keys', function () {
209 | return pandr.should.eventually.contain.keys('type', 'features');
210 | });
211 | it('should be the right type', function () {
212 | return pandr.should.eventually.have.property('type', 'FeatureCollection');
213 | });
214 | it('should have the right number of features', function () {
215 | return pandr.then(function (a) { return a.features; }).should.eventually.have.length(2);
216 | });
217 | });
218 | describe('errors', function () {
219 | it('bad file should be rejected', function () {
220 | return shp('http://localhost:3000/test/data/bad').should.be.rejected;
221 | });
222 | it('imaginary file file should be rejected', function (done) {
223 | shp('http://localhost:3000/test/data/notthere').then(function () {
224 | done(true);
225 | }, function () {
226 | done();
227 | });
228 | });
229 | it('bad zip be rejected', function () {
230 | return shp('http://localhost:3000/test/data/badzip.zip').should.be.rejected;
231 | });
232 | it('no shp in zip', function () {
233 | return shp('http://localhost:3000/test/data/noshp.zip').should.be.rejected;
234 | });
235 | });
236 | describe('encoding', function () {
237 | it('should work for utf.zip', function () {
238 | return shp('http://localhost:3000/test/data/utf.zip').then(function (item) {
239 | item.should.contain.keys('type', 'features');
240 | return item.features.map(function (feature) {
241 | return feature.properties.field;
242 | });
243 | }).should.eventually.deep.equal([
244 | '💩',
245 | 'Hněvošický háj'
246 | ]);
247 | });
248 | it('should work for utf', function () {
249 | return shp('http://localhost:3000/test/data/utf').then(function (item) {
250 | item.should.contain.keys('type', 'features');
251 | return item.features.map(function (feature) {
252 | return feature.properties.field;
253 | });
254 | }).should.eventually.deep.equal([
255 | '💩',
256 | 'Hněvošický háj'
257 | ]);
258 | });
259 | it('should work for codepage.zip', function () {
260 | return shp('http://localhost:3000/test/data/codepage.zip').then(function (item) {
261 | item.should.contain.keys('type', 'features');
262 | return item.features.map(function (feature) {
263 | return feature.properties.field;
264 | });
265 | }).should.eventually.deep.equal([
266 | '??',
267 | 'Hněvošický háj'
268 | ]);
269 | });
270 | it('should work for codepage', function () {
271 | return shp('http://localhost:3000/test/data/codepage').then(function (item) {
272 | item.should.contain.keys('type', 'features');
273 | return item.features.map(function (feature) {
274 | return feature.properties.field;
275 | });
276 | }).should.eventually.deep.equal([
277 | '??',
278 | 'Hněvošický háj'
279 | ]);
280 | });
281 | it('should work for codepage individually', function () {
282 | return Promise.all([
283 | get('http://localhost:3000/test/data/codepage.shp'),
284 | get('http://localhost:3000/test/data/codepage.dbf'),
285 | get('http://localhost:3000/test/data/codepage.prj'),
286 | get('http://localhost:3000/test/data/codepage.cpg')
287 | ]).then(([shapefile, dbf, prj, cpg]) => shp({
288 | shp: shapefile, dbf, prj, cpg
289 | })).then(function (item) {
290 | item.should.contain.keys('type', 'features');
291 | return item.features.map(function (feature) {
292 | return feature.properties.field;
293 | });
294 | }).should.eventually.deep.equal([
295 | '??',
296 | 'Hněvošický háj'
297 | ]);
298 | });
299 | it('should work for a stupid code page', function () {
300 | return shp('http://localhost:3000/test/data/htmlcpg').then(function (item) {
301 | item.should.contain.keys('type', 'features');
302 | return item.features.map(function (feature) {
303 | return feature.properties.field;
304 | });
305 | }).should.eventually.deep.equal([
306 | '💩',
307 | 'Hněvošický háj'
308 | ]);
309 | });
310 | it('should work for a stupid prj', function () {
311 | return shp('http://localhost:3000/test/data/htmlprj').then(function (item) {
312 | item.should.contain.keys('type', 'features');
313 | return item.features.map(function (feature) {
314 | return feature.properties.field;
315 | });
316 | }).should.eventually.deep.equal([
317 | '💩',
318 | 'Hněvošický háj'
319 | ]);
320 | });
321 | it('should work for a stupid prj and query params', function () {
322 | return shp('http://localhost:3000/test/data/htmlprj?blah=baz').then(function (item) {
323 | item.should.contain.keys('type', 'features');
324 | return item.features.map(function (feature) {
325 | return feature.properties.field;
326 | });
327 | }).should.eventually.deep.equal([
328 | '💩',
329 | 'Hněvošický háj'
330 | ]);
331 | });
332 | });
333 | describe('misc stuff', function () {
334 | it('should work for a null geom', function () {
335 | return shp('http://localhost:3000/test/data/LGA_2013_AUST').then(function (item) {
336 | item.should.contain.keys('type', 'features');
337 | item.features[4].geometry.coordinates.length.should.equal(21);
338 | item.features[4].properties.LGA_NAME13.should.equal('Kangaroo Island (DC)');
339 | return item.features.length;
340 | }).should.eventually.equal(13);
341 | });
342 | it('should work for with this shapfile', function () {
343 | return shp('http://localhost:3000/test/data/T8Th4_6n.zip').then(function (item) {
344 | item.should.contain.keys('type', 'features');
345 | return item.features.length;
346 | }).should.eventually.equal(3);
347 | });
348 | it('should work for with this shapfile with a query param', function () {
349 | return shp('http://localhost:3000/test/data/T8Th4_6n.zip?foo=bar').then(function (item) {
350 | item.should.contain.keys('type', 'features');
351 | return item.features.length;
352 | }).should.eventually.equal(3);
353 | });
354 | it('file too long', function () {
355 | return shp('http://localhost:3000/test/data/ipra_dresden_polygon');
356 | });
357 | it('should handle missing dbf', function () {
358 | return shp('http://localhost:3000/test/data/no-dbf').then(thing => {
359 | thing.should.contain.keys('type', 'features');
360 | thing.should.have.property('type', 'FeatureCollection');
361 | return thing.features;
362 | }).should.eventually.have.length(14);
363 | });
364 | it('should handle missing dbf in a zip', function () {
365 | return shp('http://localhost:3000/test/data/no-dbf.zip').then(thing => {
366 | thing.should.contain.keys('type', 'features');
367 | thing.should.have.property('type', 'FeatureCollection');
368 | return thing.features;
369 | }).should.eventually.have.length(14);
370 | });
371 | it('should work with a line that has zero points', function () {
372 | return shp('http://localhost:3000/test/data/zero-len-line.zip').then(thing => {
373 | thing.should.contain.keys('type', 'features');
374 | thing.should.have.property('type', 'FeatureCollection');
375 | should.equal(thing.features[1].geometry, null);
376 | return thing.features;
377 | }).should.eventually.have.length(3);
378 | });
379 | it('should handle .mshp files', function () {
380 | return shp('http://localhost:3000/test/data/qgis.zip').then(thing => {
381 | thing.should.contain.keys('type', 'features');
382 | thing.should.have.property('type', 'FeatureCollection');
383 | return thing.features;
384 | }).should.eventually.have.length(2);
385 | });
386 | it('should handle weirdly ordered rings', function () {
387 | return shp('http://localhost:3000/test/data/SHP_Exclude.zip').then(thing => {
388 | thing.should.contain.keys('type', 'features');
389 | thing.should.have.property('type', 'FeatureCollection');
390 | return thing.features[0].geometry.coordinates;
391 | }).should.eventually.have.length(2);
392 | });
393 | it('should handle files that lie about their length', function () {
394 | return shp('http://localhost:3000/test/data/badlen.zip').then(thing => {
395 | thing.should.contain.keys('type', 'features');
396 | thing.should.have.property('type', 'FeatureCollection');
397 | return thing.features;
398 | }).should.eventually.have.length(203);
399 | });
400 | });
401 | });
402 |
--------------------------------------------------------------------------------