├── .gitignore ├── .jshintrc ├── .npmignore ├── README.md ├── bower.json ├── dist ├── 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-browser.js ├── binaryajax.js ├── index.js ├── parseShp.js └── unzip.js ├── package.json ├── 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 ├── bad.dbf ├── bad.shp ├── 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 ├── mixedcase.zip ├── noshp.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 ├── index.html └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | node_modules 3 | .c9revisions 4 | jam 5 | components 6 | .DS_Store -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node" : true, 3 | "browser" : true, 4 | "curly": true, 5 | "latedef": "nofunc", 6 | "eqeqeq": true, 7 | "immed": true, 8 | "newcap": true, 9 | "noarg": true, 10 | "sub": true, 11 | "undef": "nofunc", 12 | "strict": true, 13 | "white": true, 14 | "indent": 2, 15 | "trailing": true, 16 | "quotmark": "single" 17 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | site 3 | files 4 | jam 5 | *.zip 6 | *.geojson 7 | *.topojson -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shapefile.js 2 | 3 | If you are having encoding issues in internet explorer please include [this script](https://cdn.rawgit.com/calvinmetcalf/text-encoding/4aff951959085f74a5872aeed8d79ec95b6c74c3/lib/encoding-indexes.js) as well. 4 | 5 | Redoing all of this in modern JS. Promises, Typed Arrays, other hipster things, I wouldn't say it's based on [RandomEtc's version](https://github.com/RandomEtc/shapefile-js) as much as inspired by it as there is 0 code shared and I really only read the binary ajax part of his (hence why my function has the same name, they are otherwise not related). My sources were: 6 | 7 | - [wikipedia article](https://en.wikipedia.org/wiki/Shapefile) 8 | - [ESRI white paper](http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf) 9 | - [This page on Xbase](http://www.clicketyclick.dk/databases/xbase/format/dbf.html) 10 | 11 | ## Demos 12 | 13 | - [Countries/zipfile](http://calvinmetcalf.github.io/shapefile-js) 14 | - [Google maps](http://calvinmetcalf.github.io/shapefile-js/site/map.html) 15 | - [Local Zipfile](http://leaflet.calvinmetcalf.com) 16 | - [Projected big with web workers](http://calvinmetcalf.github.io/shapefile-js/site/proj.html) 17 | - [Projected small](http://calvinmetcalf.github.io/shapefile-js/site/proj-small.html) 18 | 19 | ## Usage 20 | 21 | For use with [browserify](http://browserify.org/), [webpack](https://webpack.github.io/): 22 | 23 | npm install shpjs --save 24 | 25 | Or include directly in your webpage from: 26 | 27 | https://unpkg.com/shpjs@latest/dist/shp.js 28 | 29 | ## API 30 | 31 | Has a function `shp` which accepts a string which is the path the she shapefile minus the extension and returns a promise which resolves into geojson. 32 | 33 | ```javascript 34 | //for the shapefiles in the folder called 'files' with the name pandr.shp 35 | shp("files/pandr").then(function(geojson){ 36 | //do something with your geojson 37 | }); 38 | ``` 39 | or you can call it on a .zip file which contains the shapefile 40 | 41 | ```javascript 42 | //for the shapefiles in the files folder called pandr.shp 43 | shp("files/pandr.zip").then(function(geojson){ 44 | //see bellow for whats here this internally call shp.parseZip() 45 | }); 46 | ``` 47 | 48 | or if you got the zip some other way (like the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File)) then with the arrayBuffer you can call 49 | 50 | ```javascript 51 | shp(buffer).then(function(geojson){}); 52 | //or 53 | shp.parseZip(buffer)->returns zip 54 | ``` 55 | 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 56 | name of the shapefile minus the extension (I.E. the part of the name that's the same for all of them) 57 | 58 | You could also load the arraybuffers seperately: 59 | 60 | ```javascript 61 | shp.combine([shp.parseShp(shpBuffer, /*optional prj str*/),shp.parseDbf(dbfBuffer)]); 62 | ``` 63 | 64 | ## Stick it in a worker 65 | 66 | I used my library [catiline](http://catilinejs.com/) to parallelize the demos to do so I changed 67 | 68 | ```html 69 | 70 | 75 | ``` 76 | 77 | to 78 | 79 | ```html 80 | 81 | 91 | ``` 92 | 93 | to send the worker a buffer from the file api you'd do (I'm omitting where you include the catiline script) 94 | 95 | ```javascript 96 | var worker = cw(function(data){ 97 | importScripts('../dist/shp.js'); 98 | return shp.parseZip(data); 99 | }); 100 | 101 | worker.data(reader.result,[reader.result]).then(function(data){ 102 | //do stuff with data 103 | }); 104 | ``` 105 | 106 | ## Done 107 | 108 | - Binary Ajax 109 | - parsing the shp 110 | - parse the dbf 111 | - join em 112 | - zip 113 | - file api 114 | - Some Projections 115 | - More Projections 116 | 117 | ## to do 118 | 119 | - check for geometry validity. 120 | - Tests 121 | 122 | 123 | ## LICENSE 124 | Main library MIT license, original version was less permissive but there is 0 code shared. Included libraries are under their respective lisenses which are: 125 | - [JSZip](https://github.com/Stuk/jszip/) by @Stuk MIT or GPLv3 126 | - [lie](https://github.com/calvinmetcalf/lie) by me and @RubenVerborgh MIT 127 | - [setImmediate](https://github.com/NobleJS/setImmediate) by @NobleJS et al MIT 128 | - [World Borders shapefile](http://thematicmapping.org/downloads/world_borders.php) is CC-BY-SA 3.0. 129 | - Park and Ride shapefile is from [MassDOT](http://mass.gov/massdot) and is public domain. 130 | - 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 131 | - NJ County Boundaries from [NJgin](https://njgin.state.nj.us/NJ_NJGINExplorer/index.jsp) and should be public domain. 132 | - [Proj4js](https://github.com/proj4js/proj4js) by me et al MIT 133 | 134 | [![Dependency Status](https://david-dm.org/calvinmetcalf/shapefile-js.svg)](https://david-dm.org/calvinmetcalf/shapefile-js) 135 | [![devDependency Status](https://david-dm.org/calvinmetcalf/shapefile-js/dev-status.svg)](https://david-dm.org/calvinmetcalf/shapefile-js#info=devDependencies) 136 | [![peerDependency Status](https://david-dm.org/calvinmetcalf/shapefile-js/peer-status.svg)](https://david-dm.org/calvinmetcalf/shapefile-js#info=peerDependencies) 137 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shp", 3 | "version": "3.3.2", 4 | "description": "A binary shapefile loader, for javascript. Not many caveats", 5 | "homepage": "https://github.com/calvinmetcalf/shapefile-js", 6 | "authors": [ 7 | "Calvin Metcalf " 8 | ], 9 | "main": "dist/shp.js", 10 | "keywords": [ 11 | "shp", 12 | "gis", 13 | "geojson" 14 | ], 15 | "license": "MIT", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /files/Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/Readme.txt -------------------------------------------------------------------------------- /files/TM_WORLD_BORDERS_SIMPL-0.3.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/TM_WORLD_BORDERS_SIMPL-0.3.dbf -------------------------------------------------------------------------------- /files/TM_WORLD_BORDERS_SIMPL-0.3.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/TM_WORLD_BORDERS_SIMPL-0.3.shp -------------------------------------------------------------------------------- /files/TM_WORLD_BORDERS_SIMPL-0.3.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/TM_WORLD_BORDERS_SIMPL-0.3.shx -------------------------------------------------------------------------------- /files/TM_WORLD_BORDERS_SIMPL-0.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/TM_WORLD_BORDERS_SIMPL-0.3.zip -------------------------------------------------------------------------------- /files/counties5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/counties5.zip -------------------------------------------------------------------------------- /files/empty-shp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/empty-shp.zip -------------------------------------------------------------------------------- /files/maSP.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/maSP.zip -------------------------------------------------------------------------------- /files/nj_counties.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/nj_counties.zip -------------------------------------------------------------------------------- /files/nj_muni.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/nj_muni.zip -------------------------------------------------------------------------------- /files/pandr.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/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/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/pandr.sbn -------------------------------------------------------------------------------- /files/pandr.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/pandr.sbx -------------------------------------------------------------------------------- /files/pandr.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/pandr.shp -------------------------------------------------------------------------------- /files/pandr.shp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 2012053008362400FALSECreateFeatureclass "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\Update2009FeatureClassToFeatureClass 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]]200912180626530020091218062653001.0Microsoft Windows XP Version 5.1 (Build 2600) Service Pack 3; ESRI ArcCatalog 9.3.1.3000enREQUIRED: 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.ParkAndRideGISVECTOR.GISADMIN.ParkAndRidevector digital dataServer=mhd-gis-wh; Service=sde:sqlserver:mhd-gis-wh; Database=gisVector; User=gisadmin; Version=sde.DEFAULTREQUIRED: 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 ClassMicrosoft Windows XP Version 5.1 (Build 2600) Service Pack 3; ESRI ArcCatalog 9.3.1.3000GISVECTOR.GISADMIN.ParkAndRideenFGDC Content Standards for Digital Geospatial MetadataFGDC-STD-001-1998local timeREQUIRED: 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.20091218http://www.esri.com/metadata/esriprof80.htmlESRI Metadata ProfileISO 19115 Geographic Information - MetadataDIS_ESRI1.0datasetDownloadable Data002Server=mhd-gis-wh; Service=sde:sqlserver:mhd-gis-wh; Database=gisVector; User=gisadmin; Version=sde.DEFAULTArcSDE ConnectionSDE Feature ClassVectorSimplePointFALSE0TRUEFALSEEntity point0GCS_North_American_1983NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001coordinate pairmeters0.0005120.000512State Plane Coordinate System 1983200141.71666742.683333-71.50000041.000000200000.000000750000.000000North American Datum of 1983Geodetic Reference System 806378137.000000298.257222Explicit elevation coordinate included with horizontal coordinates1.000000NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_20010GISVECTOR.GISADMIN.ParkAndRideFeature Class0OBJECTIDOBJECTIDOID4100Internal feature number.ESRISequential unique whole numbers that are automatically generated.ShapeShapeGeometry400Feature geometry.ESRICoordinates defining the features.TOWNTOWNString2500LOCATIONLOCATIONString4500STATUSSTATUSString1500DISTRICTDISTRICTInteger4100OPERATOROPERATORString2500BIKE_RACKSBIKE_RACKSString300SHELTERSSHELTERSString300PHONESPHONESString300LIGHTSLIGHTSString300FENCESFENCESString300SIGNSSIGNSString300OWNEROWNERString1500CAPACITYCAPACITYString400BUS_SERVICEBUS_SERVICEString2500RAIL_SERVICERAIL_SERVICEString1000BOAT_SERVICEBOAT_SERVICEString1000MAP_IDMAP_IDInteger4100MPOMPOString5000SYMBOLSYMBOLString10020091218Dataset copied.Server=mhd-gis-wh; Service=esri_sde; Database=gisvector; User=gisviewer; Version=sde.DEFAULT2010081307273100 4 | -------------------------------------------------------------------------------- /files/pandr.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/pandr.shx -------------------------------------------------------------------------------- /files/pandr.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/files/pandr.zip -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shapefile in Leaflet! 9 | 10 | 13 | 14 | 15 | 24 |
25 |
26 | Fork me on GitHub 27 |
28 |
29 | 30 | 47 | 48 | -------------------------------------------------------------------------------- /lib/binaryajax-browser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var Promise = require('lie'); 3 | module.exports = binaryAjax; 4 | function binaryAjax(url){ 5 | return new Promise(function(resolve,reject){ 6 | var type = url.slice(-3); 7 | var ajax = new XMLHttpRequest(); 8 | ajax.open('GET',url,true); 9 | if(type !== 'prj' && type !== 'cpg'){ 10 | ajax.responseType='arraybuffer'; 11 | } 12 | ajax.addEventListener('load', function (){ 13 | if(ajax.status>399){ 14 | if(type==='prj' || type === 'cpg'){ 15 | return resolve(false); 16 | }else{ 17 | return reject(new Error(ajax.status)); 18 | } 19 | } 20 | if(type !== 'prj' && type !== 'cpg'){ 21 | return resolve(new Buffer(ajax.response)); 22 | } else { 23 | return resolve(ajax.response); 24 | } 25 | }, false); 26 | ajax.send(); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /lib/binaryajax.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var Promise = require('lie'); 3 | var http = require('http'); 4 | var https = require('https'); 5 | var Url = require('url'); 6 | 7 | module.exports = binaryAjax; 8 | 9 | function binaryAjax(url) { 10 | return new Promise(function(resolve, reject) { 11 | var type = url.slice(-3); 12 | var parsed = Url.parse(url); 13 | var method = http; 14 | if (parsed.protocol === 'https:') { 15 | method = https; 16 | } 17 | method.get(parsed, function(res) { 18 | var len = 0; 19 | var buffers = []; 20 | 21 | res.on('data', function(d) { 22 | len += d.length; 23 | buffers.push(d); 24 | }); 25 | res.on('error', function(e) { 26 | reject(e); 27 | }); 28 | res.on('end', function() { 29 | if (res.statusCode > 399) { 30 | if (type === 'prj' || type === 'cpg') { 31 | return resolve(false); 32 | } else { 33 | return reject(new Error(Buffer.concat(buffers, len).toString())); 34 | } 35 | } 36 | var buffer = Buffer.concat(buffers, len); 37 | if (type === 'prj') { 38 | resolve(buffer.toString()); 39 | } else { 40 | resolve(buffer); 41 | } 42 | }); 43 | }).on('error', function(e) { 44 | reject(e); 45 | }); 46 | }); 47 | } 48 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var proj4 = require('proj4'); 3 | var unzip = require('./unzip'); 4 | var binaryAjax = require('./binaryajax'); 5 | var parseShp = require('./parseShp'); 6 | var parseDbf = require('parsedbf'); 7 | var Promise = require('lie'); 8 | var Cache = require('lru-cache'); 9 | var cache = new Cache({ 10 | max: 20 11 | }); 12 | 13 | function toBuffer(b) { 14 | if (!b) { 15 | throw new Error('forgot to pass buffer'); 16 | } 17 | if (Buffer.isBuffer(b)) { 18 | return b; 19 | } 20 | if (b instanceof global.ArrayBuffer) { 21 | return new Buffer(b); 22 | } 23 | if (b.buffer instanceof global.ArrayBuffer) { 24 | if (b.BYTES_PER_ELEMENT === 1) { 25 | return new Buffer(b); 26 | } 27 | return new Buffer(b.buffer); 28 | } 29 | } 30 | 31 | function shp(base, whiteList) { 32 | if (typeof base === 'string' && cache.has(base)) { 33 | return Promise.resolve(cache.get(base)); 34 | } 35 | return shp.getShapefile(base, whiteList).then(function(resp) { 36 | if (typeof base === 'string') { 37 | cache.set(base, resp); 38 | } 39 | return resp; 40 | }); 41 | } 42 | shp.combine = function(arr) { 43 | var out = {}; 44 | out.type = 'FeatureCollection'; 45 | out.features = []; 46 | var i = 0; 47 | var len = arr[0].length; 48 | while (i < len) { 49 | out.features.push({ 50 | 'type': 'Feature', 51 | 'geometry': arr[0][i], 52 | 'properties': arr[1][i] 53 | }); 54 | i++; 55 | } 56 | return out; 57 | }; 58 | shp.parseZip = function(buffer, whiteList) { 59 | var key; 60 | buffer = toBuffer(buffer); 61 | var zip = unzip(buffer); 62 | var names = []; 63 | whiteList = whiteList || []; 64 | for (key in zip) { 65 | if (key.indexOf('__MACOSX') !== -1) { 66 | continue; 67 | } 68 | if (key.slice(-3).toLowerCase() === 'shp') { 69 | names.push(key.slice(0, -4)); 70 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = zip[key]; 71 | } else if (key.slice(-3).toLowerCase() === 'prj') { 72 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = proj4(zip[key]); 73 | } else if (key.slice(-4).toLowerCase() === 'json' || whiteList.indexOf(key.split('.').pop()) > -1) { 74 | names.push(key.slice(0, -3) + key.slice(-3).toLowerCase()); 75 | } else if (key.slice(-3).toLowerCase() === 'dbf' || key.slice(-3).toLowerCase() === 'cpg') { 76 | zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = zip[key]; 77 | } 78 | } 79 | if (!names.length) { 80 | throw new Error('no layers founds'); 81 | } 82 | var geojson = names.map(function(name) { 83 | var parsed, dbf; 84 | var lastDotIdx = name.lastIndexOf('.'); 85 | if (lastDotIdx > -1 && name.slice(lastDotIdx).indexOf('json') > -1) { 86 | parsed = JSON.parse(zip[name]); 87 | parsed.fileName = name.slice(0, lastDotIdx); 88 | } else if (whiteList.indexOf(name.slice(lastDotIdx + 1)) > -1) { 89 | parsed = zip[name]; 90 | parsed.fileName = name; 91 | } else { 92 | if (zip[name + '.dbf']) { 93 | dbf = parseDbf(zip[name + '.dbf'], zip[name + '.cpg']); 94 | } 95 | parsed = shp.combine([parseShp(zip[name + '.shp'], zip[name + '.prj']), dbf]); 96 | parsed.fileName = name; 97 | } 98 | return parsed; 99 | }); 100 | if (geojson.length === 1) { 101 | return geojson[0]; 102 | } else { 103 | return geojson; 104 | } 105 | }; 106 | 107 | function getZip(base, whiteList) { 108 | return binaryAjax(base).then(function(a) { 109 | return shp.parseZip(a, whiteList); 110 | }); 111 | } 112 | shp.getShapefile = function(base, whiteList) { 113 | if (typeof base === 'string') { 114 | if (base.slice(-4).toLowerCase() === '.zip') { 115 | return getZip(base, whiteList); 116 | } else { 117 | return Promise.all([ 118 | Promise.all([ 119 | binaryAjax(base + '.shp'), 120 | binaryAjax(base + '.prj') 121 | ]).then(function(args) { 122 | return parseShp(args[0], args[1] ? proj4(args[1]) : false); 123 | }), 124 | Promise.all([ 125 | binaryAjax(base + '.dbf'), 126 | binaryAjax(base + '.cpg') 127 | ]).then(function(args) { 128 | return parseDbf(args[0], args[1]) 129 | }) 130 | ]).then(shp.combine); 131 | } 132 | } else { 133 | return new Promise(function(resolve) { 134 | resolve(shp.parseZip(base)); 135 | }); 136 | } 137 | }; 138 | shp.parseShp = function(shp, prj) { 139 | shp = toBuffer(shp); 140 | if (Buffer.isBuffer(prj)) { 141 | prj = prj.toString(); 142 | } 143 | if (typeof prj === 'string') { 144 | prj = proj4(prj); 145 | return parseShp(shp, prj); 146 | } else { 147 | return parseShp(shp); 148 | } 149 | }; 150 | shp.parseDbf = function(dbf, cpg) { 151 | dbf = toBuffer(dbf); 152 | return parseDbf(dbf, cpg); 153 | }; 154 | module.exports = shp; 155 | -------------------------------------------------------------------------------- /lib/parseShp.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function isClockWise(array) { 4 | var sum = 0; 5 | var i = 1; 6 | var len = array.length; 7 | var prev, cur; 8 | while (i < len) { 9 | prev = cur || array[0]; 10 | cur = array[i]; 11 | sum += ((cur[0] - prev[0]) * (cur[1] + prev[1])); 12 | i++; 13 | } 14 | return sum > 0; 15 | } 16 | 17 | function polyReduce(a, b) { 18 | if (isClockWise(b) || !a.length) { 19 | a.push([b]); 20 | } else { 21 | a[a.length - 1].push(b); 22 | } 23 | return a; 24 | } 25 | ParseShp.prototype.parsePoint = function(data) { 26 | return { 27 | 'type': 'Point', 28 | 'coordinates': this.parseCoord(data, 0) 29 | }; 30 | }; 31 | ParseShp.prototype.parseZPoint = function(data) { 32 | var pointXY = this.parsePoint(data); 33 | pointXY.coordinates.push(this.parseCoord(data, 16)); 34 | return pointXY; 35 | }; 36 | ParseShp.prototype.parsePointArray = function(data, offset, num) { 37 | var out = []; 38 | var done = 0; 39 | while (done < num) { 40 | out.push(this.parseCoord(data, offset)); 41 | offset += 16; 42 | done++; 43 | } 44 | return out; 45 | }; 46 | ParseShp.prototype.parseZPointArray = function(data, zOffset, num, coordinates) { 47 | var i = 0; 48 | while (i < num) { 49 | coordinates[i].push(data.readDoubleLE(zOffset)); 50 | i++; 51 | zOffset += 8; 52 | } 53 | return coordinates; 54 | }; 55 | ParseShp.prototype.parseArrayGroup = function(data, offset, partOffset, num, tot) { 56 | var out = []; 57 | var done = 0; 58 | var curNum, nextNum = 0, 59 | pointNumber; 60 | while (done < num) { 61 | done++; 62 | partOffset += 4; 63 | curNum = nextNum; 64 | if (done === num) { 65 | nextNum = tot; 66 | } else { 67 | nextNum = data.readInt32LE(partOffset); 68 | } 69 | pointNumber = nextNum - curNum; 70 | if (!pointNumber) { 71 | continue; 72 | } 73 | out.push(this.parsePointArray(data, offset, pointNumber)); 74 | offset += (pointNumber << 4); 75 | } 76 | return out; 77 | }; 78 | ParseShp.prototype.parseZArrayGroup = function(data, zOffset, num, coordinates) { 79 | var i = 0; 80 | while (i < num) { 81 | coordinates[i] = this.parseZPointArray(data, zOffset, coordinates[i].length, coordinates[i]); 82 | zOffset += (coordinates[i].length << 3); 83 | i++; 84 | } 85 | return coordinates; 86 | }; 87 | ParseShp.prototype.parseMultiPoint = function(data) { 88 | var out = {}; 89 | var mins = this.parseCoord(data, 0); 90 | var maxs = this.parseCoord(data, 16); 91 | out.bbox = [ 92 | mins[0], 93 | mins[1], 94 | maxs[0], 95 | maxs[1] 96 | ]; 97 | var num = data.readInt32(32, true); 98 | var offset = 36; 99 | if (num === 1) { 100 | out.type = 'Point'; 101 | out.coordinates = this.parseCoord(data, offset); 102 | } else { 103 | out.type = 'MultiPoint'; 104 | out.coordinates = this.parsePointArray(data, offset, num); 105 | } 106 | return out; 107 | }; 108 | ParseShp.prototype.parseZMultiPoint = function(data) { 109 | var geoJson = this.parseMultiPoint(data); 110 | var num; 111 | if (geoJson.type === 'Point') { 112 | geoJson.coordinates.push(data.readDoubleLE(72)); 113 | return geoJson; 114 | } else { 115 | num = geoJson.coordinates.length; 116 | } 117 | var zOffset = 56 + (num << 4); 118 | geoJson.coordinates = this.parseZPointArray(data, zOffset, num, geoJson.coordinates); 119 | return geoJson; 120 | }; 121 | ParseShp.prototype.parsePolyline = function(data) { 122 | var out = {}; 123 | var mins = this.parseCoord(data, 0); 124 | var maxs = this.parseCoord(data, 16); 125 | out.bbox = [ 126 | mins[0], 127 | mins[1], 128 | maxs[0], 129 | maxs[1] 130 | ]; 131 | var numParts = data.readInt32LE(32); 132 | var num = data.readInt32LE(36); 133 | var offset, partOffset; 134 | if (numParts === 1) { 135 | out.type = 'LineString'; 136 | offset = 44; 137 | out.coordinates = this.parsePointArray(data, offset, num); 138 | } else { 139 | out.type = 'MultiLineString'; 140 | offset = 40 + (numParts << 2); 141 | partOffset = 40; 142 | out.coordinates = this.parseArrayGroup(data, offset, partOffset, numParts, num); 143 | } 144 | return out; 145 | }; 146 | ParseShp.prototype.parseZPolyline = function(data) { 147 | var geoJson = this.parsePolyline(data); 148 | var num = geoJson.coordinates.length; 149 | var zOffset = 60 + (num << 4); 150 | if (geoJson.type === 'LineString') { 151 | geoJson.coordinates = this.parseZPointArray(data, zOffset, num, geoJson.coordinates); 152 | return geoJson; 153 | } else { 154 | geoJson.coordinates = this.parseZArrayGroup(data, zOffset, num, geoJson.coordinates); 155 | return geoJson; 156 | } 157 | }; 158 | ParseShp.prototype.polyFuncs = function(out) { 159 | if (out.type === 'LineString') { 160 | out.type = 'Polygon'; 161 | out.coordinates = [out.coordinates]; 162 | return out; 163 | } else { 164 | out.coordinates = out.coordinates.reduce(polyReduce, []); 165 | if (out.coordinates.length === 1) { 166 | out.type = 'Polygon'; 167 | out.coordinates = out.coordinates[0]; 168 | return out; 169 | } else { 170 | out.type = 'MultiPolygon'; 171 | return out; 172 | } 173 | } 174 | }; 175 | ParseShp.prototype.parsePolygon = function(data) { 176 | return this.polyFuncs(this.parsePolyline(data)); 177 | }; 178 | ParseShp.prototype.parseZPolygon = function(data) { 179 | return this.polyFuncs(this.parseZPolyline(data)); 180 | }; 181 | var shpFuncObj = { 182 | 1: 'parsePoint', 183 | 3: 'parsePolyline', 184 | 5: 'parsePolygon', 185 | 8: 'parseMultiPoint', 186 | 11: 'parseZPoint', 187 | 13: 'parseZPolyline', 188 | 15: 'parseZPolygon', 189 | 18: 'parseZMultiPoint' 190 | }; 191 | 192 | 193 | 194 | function makeParseCoord(trans) { 195 | if (trans) { 196 | return function(data, offset) { 197 | return trans.inverse([data.readDoubleLE(offset), data.readDoubleLE(offset + 8)]); 198 | }; 199 | } else { 200 | return function(data, offset) { 201 | return [data.readDoubleLE(offset), data.readDoubleLE(offset + 8)]; 202 | }; 203 | } 204 | } 205 | 206 | function ParseShp(buffer, trans) { 207 | if (!(this instanceof ParseShp)) { 208 | return new ParseShp(buffer, trans); 209 | } 210 | this.buffer = buffer; 211 | this.shpFuncs(trans); 212 | this.rows = this.getRows(); 213 | } 214 | ParseShp.prototype.shpFuncs = function(tran) { 215 | var num = this.getShpCode(); 216 | if (num > 20) { 217 | num -= 20; 218 | } 219 | if (!(num in shpFuncObj)) { 220 | throw new Error('I don\'t know that shp type'); 221 | } 222 | this.parseFunc = this[shpFuncObj[num]]; 223 | this.parseCoord = makeParseCoord(tran); 224 | }; 225 | ParseShp.prototype.getShpCode = function() { 226 | return this.parseHeader().shpCode; 227 | }; 228 | ParseShp.prototype.parseHeader = function() { 229 | var view = this.buffer.slice(0, 100); 230 | return { 231 | length: view.readInt32BE(6 << 2), 232 | version: view.readInt32LE(7 << 2), 233 | shpCode: view.readInt32LE(8 << 2), 234 | bbox: [ 235 | view.readDoubleLE(9 << 2), 236 | view.readDoubleLE(11 << 2), 237 | view.readDoubleLE(13 << 2), 238 | view.readDoubleLE(13 << 2) 239 | ] 240 | }; 241 | }; 242 | ParseShp.prototype.getRows = function() { 243 | var offset = 100; 244 | var len = this.buffer.byteLength; 245 | var out = []; 246 | var current; 247 | while (offset < len) { 248 | current = this.getRow(offset); 249 | offset += 8; 250 | offset += current.len; 251 | if (current.type) { 252 | out.push(this.parseFunc(current.data)); 253 | } 254 | } 255 | return out; 256 | }; 257 | ParseShp.prototype.getRow = function(offset) { 258 | var view = this.buffer.slice(offset, offset + 12); 259 | var len = view.readInt32BE(4) << 1; 260 | var data = this.buffer.slice(offset + 12, offset + len + 8); 261 | 262 | return { 263 | id: view.readInt32BE(0), 264 | len: len, 265 | data: data, 266 | type: view.readInt32LE(8) 267 | }; 268 | }; 269 | module.exports = function(buffer, trans) { 270 | return new ParseShp(buffer, trans).rows; 271 | }; 272 | -------------------------------------------------------------------------------- /lib/unzip.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var JSZip = require('jszip'); 4 | module.exports = function(buffer) { 5 | var zip = new JSZip(buffer); 6 | var files = zip.file(/.+/); 7 | var out = {}; 8 | files.forEach(function(a) { 9 | if (a.name.slice(-3).toLowerCase() === 'shp' || a.name.slice(-3).toLowerCase() === 'dbf') { 10 | out[a.name] = a.asNodeBuffer(); 11 | } 12 | else { 13 | out[a.name] = a.asText(); 14 | } 15 | }); 16 | return out; 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shpjs", 3 | "version": "3.4.0", 4 | "description": "A binary shapefile loader, for javascript. Not many caveats", 5 | "main": "lib/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/calvinmetcalf/shapefile-js.git" 9 | }, 10 | "scripts": { 11 | "test": "mocha ./test/test.js", 12 | "hint": "jshint ./lib/*.js", 13 | "build-test": "browserify ./test/test.js > ./test/bundle.js", 14 | "build": "browserify . -s shp > ./dist/shp.js", 15 | "min": "browserify . -s shp | uglifyjs -mc > ./dist/shp.min.js" 16 | }, 17 | "author": "Calvin Metcalf", 18 | "license": "MIT", 19 | "readmeFilename": "README.md", 20 | "devDependencies": { 21 | "browserify": "^13.0.0", 22 | "chai": "^3.3.0", 23 | "chai-as-promised": "^5.1.0", 24 | "jszip": "^2.5.0", 25 | "mocha": "^2.3.3", 26 | "testling": "^1.6.1", 27 | "uglify-js": "^2.4.24", 28 | "uglifyjs": "^2.4.10" 29 | }, 30 | "dependencies": { 31 | "jszip": "^2.4.0", 32 | "lie": "^3.0.1", 33 | "lru-cache": "^2.7.0", 34 | "parsedbf": "^1.0.0", 35 | "proj4": "^2.1.4" 36 | }, 37 | "browser": { 38 | "./lib/binaryajax.js": "./lib/binaryajax-browser.js" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /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 |
16 |
17 | Fork me on GitHub 18 |
19 |
20 | 21 | 51 | 52 | -------------------------------------------------------------------------------- /site/proj.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Projected Shapefiles in Leaflet! 9 | 10 | 13 | 14 | 15 |
16 |
17 | Fork me on GitHub 18 |
19 |
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/bad.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/bad.dbf -------------------------------------------------------------------------------- /test/data/bad.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/bad.shp -------------------------------------------------------------------------------- /test/data/badzip.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/badzip.zip -------------------------------------------------------------------------------- /test/data/codepage.cpg: -------------------------------------------------------------------------------- 1 | ASNI 1250 2 | -------------------------------------------------------------------------------- /test/data/codepage.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/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/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/codepage.shp -------------------------------------------------------------------------------- /test/data/codepage.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/codepage.shx -------------------------------------------------------------------------------- /test/data/codepage.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/codepage.zip -------------------------------------------------------------------------------- /test/data/counties.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.dbf -------------------------------------------------------------------------------- /test/data/counties.sbn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.sbn -------------------------------------------------------------------------------- /test/data/counties.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.sbx -------------------------------------------------------------------------------- /test/data/counties.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.shp -------------------------------------------------------------------------------- /test/data/counties.shp.xml: -------------------------------------------------------------------------------- 1 | 2013091008255500FALSECreateFeatureclass "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 0AddField 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_polyCalculateAreas Counties_poly_from_361_new S:\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb\County_polyFeatureClassToFeatureClass "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_KEEPfile://\\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\counties.shpLocal Area Networkcounties0020.000GeographicGCS_WGS_1984Angular 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[&quot;GCS_WGS_1984&quot;,DATUM[&quot;D_WGS_1984&quot;,SPHEROID[&quot;WGS_1984&quot;,6378137.0,298.257223563]],PRIMEM[&quot;Greenwich&quot;,0.0],UNIT[&quot;Degree&quot;,0.0174532925199433],AUTHORITY[&quot;EPSG&quot;,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>201309100849230020130910084923001.0Server=mhd-gis-wh; Service=5151; Database=gisvector; User=gisadmin; Version=sde.DEFAULTREQUIRED: 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.Countiesgisvector.GISADMIN.Countiesvector digital dataMicrosoft Windows XP Version 5.1 (Build 2600) Service Pack 2; ESRI ArcCatalog 9.2.2.1350enREQUIRED: 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 ClassServer=mhd-gis-wh; Service=5151; Database=gisvector; User=gisadmin; Version=sde.DEFAULTArcSDE Connection002SDE Feature ClassShapefile0.000Dataset copied.Server=mhd-gis-wh; Service=esri_sde; Database=gisvector; User=gisviewer; Version=sde.DEFAULT20061207Dataset copied.20061208Dataset copied.\\MHD-Shared\SharedData$\HQ\Planning\DataResources\Workspace\Mark\Assets.mdb20061211Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; ESRI ArcGIS 10.0.5.4400countiesenFGDC Content Standards for Digital Geospatial MetadataFGDC-STD-001-1998local timeREQUIRED: 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.20070518ISO 19115 Geographic Information - MetadataDIS_ESRI1.0datasetDownloadable DataVectorSimpleFALSE0FALSEFALSEGCS_North_American_1983NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001North American Datum of 1983Geodetic Reference System 806378137.000000298.257222Explicit elevation coordinate included with horizontal coordinates1.000000NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001EPSG7.4.10countiesFeature Class0len_12FIDOID400Internal feature number.ESRISequential unique whole numbers that are automatically generated.Shapearea_1Double1900Feature geometry.ESRICoordinates defining the features.area_1len_1Double1900areaareaDouble1900lenlenDouble1900len_1COUNTYString2000COUNTYShapeGeometry000Feature geometry.ESRICoordinates defining the features.SHAPEarea_12Double1900Feature geometry.ESRICoordinates defining the features.area_12len_12Double1900Shape_LengShape_LengDouble1900Shape_AreaShape_AreaDouble1900Area of feature in internal units squared.ESRIPositive real numbers that are automatically generated.20130910 2 | -------------------------------------------------------------------------------- /test/data/counties.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.shx -------------------------------------------------------------------------------- /test/data/counties.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/counties.zip -------------------------------------------------------------------------------- /test/data/mixedcase.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/mixedcase.zip -------------------------------------------------------------------------------- /test/data/noshp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/noshp.zip -------------------------------------------------------------------------------- /test/data/senate.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/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/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/senate.sbn -------------------------------------------------------------------------------- /test/data/senate.sbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/senate.sbx -------------------------------------------------------------------------------- /test/data/senate.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/senate.shp -------------------------------------------------------------------------------- /test/data/senate.shp.xml: -------------------------------------------------------------------------------- 1 | 20120312140039001.0FGDC CSDGM MetadataFALSE2013091008390500senate00233861.260000330846.090100777514.310000959747.4400001file://\\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\senate.shpLocal Area Network0.000ProjectedGCS_North_American_1983NAD_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[&quot;NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001&quot;,GEOGCS[&quot;GCS_North_American_1983&quot;,DATUM[&quot;D_North_American_1983&quot;,SPHEROID[&quot;GRS_1980&quot;,6378137.0,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0.0],UNIT[&quot;Degree&quot;,0.0174532925199433]],PROJECTION[&quot;Lambert_Conformal_Conic&quot;],PARAMETER[&quot;False_Easting&quot;,200000.0],PARAMETER[&quot;False_Northing&quot;,750000.0],PARAMETER[&quot;Central_Meridian&quot;,-71.5],PARAMETER[&quot;Standard_Parallel_1&quot;,41.71666666666667],PARAMETER[&quot;Standard_Parallel_2&quot;,42.68333333333333],PARAMETER[&quot;Latitude_Of_Origin&quot;,41.0],UNIT[&quot;Meter&quot;,1.0],AUTHORITY[&quot;EPSG&quot;,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 0SimplifyPolygon SENATE2012_POLY \\mhd-fsp-bos-v01\urd$\metcalfc\Desktop\shapefilejs\senate.shp POINT_REMOVE "20 Meters" "0 SquareMeters" NO_CHECK NO_KEEP2013091008390500FGDC/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 | 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 Windows 7 Version 6.1 (Build 7601) Service Pack 1; ESRI ArcGIS 10.0.5.4400State Senate Districts (2012)MassGISOne Ashburton Place, Room 1601BostonMA02108USA617-619-5611Map of the Commonwealth of Massachusetts, Senate Districts, Chapter 152 of the Acts of 2011 74 | Bill: http://www.malegislature.gov/Bills/Detail?billNumber=s02045002-73.533350-69.89847742.88835141.2303411Massachusetts General Court Special Joint Committee on Redistricting and MassGISNoneMassGISOne Ashburton Place, Room 1601BostonMA02108USA617-619-5611Senate 2012 DistrictsSenate 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=s02045ShapefileMassGISOne Ashburton Place, Room 1601BostonMA02108USA617-619-5611Download from http://www.mass.gov/itd/senate20120.000datasetEPSG7.4.1VectorSimpleFALSE0FALSEFALSE0senateFeature Class0FIDFIDOID400Internal feature number.ESRISequential unique whole numbers that are automatically generated.SENDISTNUMSENDISTNUMInteger550Numeric Senate district identifierSEN_DISTSEN_DISTString4300Name of Senate DistrictSEN_FIRSTSEN_FIRSTString1300Senator's first nameSEN_LASTSEN_LASTString1500Senator's last nameSEN_PARTYSEN_PARTYString300Senator's political partySENATORSENATORString4000Senator's full name and partyURLURLString15000Senator's Web siteSHAPEShapeGeometry000Feature geometry.ESRICoordinates defining the features.SHAPE_AREASHAPE_AREADouble1900Area of feature in internal units squared.ESRIPositive real numbers that are automatically generated.SHAPE_LENSHAPE_LENDouble1900State Senate Districts (2012)Massachusetts General Court Special Joint Committee on Redistricting and MassGIS20130529Massachusetts 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 DistrictsEnglishMap of the Commonwealth of Massachusetts, Senate Districts, Chapter 152 of the Acts of 2011 76 | Bill: http://www.malegislature.gov/Bills/Detail?billNumber=s02045NoneNoneMassachusetts General Court Special Joint Committee on Redistricting and MassGISMassGISmailing and physical address
One Ashburton Place, Room 1601
BostonMA02108USA
617-619-5611
20130529publication dateCompleteAs neededNoneState Senate Districts (2012)NoneCommonwealth of MassachusettsSDE Feature Class
20130529http://www.mass.gov/itd/senate2012MassGIS Web DocumentationMassGISmailing and physical address
One Ashburton Place, Room 1601
BostonMA02108USA
617-619-5611
MassGISmailing and physical address
One Ashburton Place, Room 1601
BostonMA02108USA
617-619-5611
Download from http://www.mass.gov/itd/senate2012
GCS_North_American_1983NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001North American Datum of 1983Geodetic Reference System 806378137.000000298.257222coordinate pair0.0100000.010000metersData 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 2013ArcGIS 10.0NoneNone
77 | -------------------------------------------------------------------------------- /test/data/senate.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/senate.shx -------------------------------------------------------------------------------- /test/data/senate.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/senate.zip -------------------------------------------------------------------------------- /test/data/train_stations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/train_stations.zip -------------------------------------------------------------------------------- /test/data/utf.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /test/data/utf.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/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/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/utf.shp -------------------------------------------------------------------------------- /test/data/utf.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/utf.shx -------------------------------------------------------------------------------- /test/data/utf.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MikesWei/shapefile-js/7a6e63639e46e20f4bd23b0b71168fb96813cc2e/test/data/utf.zip -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Mocha Tests 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 |
18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var shp = require('../'); 2 | var chai = require('chai'); 3 | chai.should(); 4 | var chaiAsPromised = require("chai-as-promised"); 5 | 6 | chai.use(chaiAsPromised); 7 | 8 | describe('Shp', function(){ 9 | describe('park and rides not zipped', function(){ 10 | var pandr = shp('http://localhost:3000/files/pandr'); 11 | it('should have the right keys', function(){ 12 | return pandr.should.eventually.contain.keys('type', 'features'); 13 | }); 14 | it('should be the right type',function(){ 15 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 16 | }); 17 | it('should have the right number of features',function(){ 18 | return pandr.then(function(a){return a.features;}).should.eventually.have.length(80); 19 | }); 20 | }); 21 | describe('park and rides zipped', function(){ 22 | var pandr = shp('http://localhost:3000/files/pandr.zip'); 23 | it('should have the right keys', function(){ 24 | return pandr.should.eventually.contain.keys('type', 'features'); 25 | }); 26 | it('should be the right type',function(){ 27 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 28 | }); 29 | it('should have the right number of features',function(){ 30 | return pandr.then(function(a){return a.features}).should.eventually.have.length(80); 31 | }); 32 | }); 33 | describe('senate unzipped', function(){ 34 | var pandr = shp('http://localhost:3000/test/data/senate'); 35 | it('should have the right keys', function(){ 36 | return pandr.should.eventually.contain.keys('type', 'features'); 37 | }); 38 | it('should be the right type',function(){ 39 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 40 | }); 41 | it('should have the right number of features',function(){ 42 | return pandr.then(function(a){return a.features}).should.eventually.have.length(40); 43 | }); 44 | }); 45 | describe('mixed case zipped', function(){ 46 | var pandr = shp('http://localhost:3000/test/data/mixedcase.zip'); 47 | it('should have the right keys', function(){ 48 | return pandr.should.eventually.contain.keys('type', 'features'); 49 | }); 50 | it('should be the right type',function(){ 51 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 52 | }); 53 | it('should have the right number of features',function(){ 54 | return pandr.then(function(a){return a.features}).should.eventually.have.length(40); 55 | }); 56 | }); 57 | describe('senate zipped', function(){ 58 | var pandr = shp('http://localhost:3000/test/data/senate.zip'); 59 | it('should have the right keys', function(){ 60 | return pandr.should.eventually.contain.keys('type', 'features'); 61 | }); 62 | it('should be the right type',function(){ 63 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 64 | }); 65 | it('should have the right number of features',function(){ 66 | return pandr.then(function(a){return a.features}).should.eventually.have.length(40); 67 | }); 68 | }); 69 | describe('county unzipped', function(){ 70 | var pandr = shp('http://localhost:3000/test/data/counties'); 71 | it('should have the right keys', function(){ 72 | return pandr.should.eventually.contain.keys('type', 'features'); 73 | }); 74 | it('should be the right type',function(){ 75 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 76 | }); 77 | it('should have the right number of features',function(){ 78 | return pandr.then(function(a){return a.features}).should.eventually.have.length(14); 79 | }); 80 | }); 81 | describe('county zipped', function(){ 82 | var pandr = shp('http://localhost:3000/test/data/counties.zip'); 83 | it('should have the right keys', function(){ 84 | return pandr.should.eventually.contain.keys('type', 'features'); 85 | }); 86 | it('should be the right type',function(){ 87 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 88 | }); 89 | it('should have the right number of features',function(){ 90 | return pandr.then(function(a){return a.features}).should.eventually.have.length(14); 91 | }); 92 | }); 93 | describe('trains zipped', function(){ 94 | var pandr = shp('http://localhost:3000/test/data/train_stations.zip'); 95 | it('should have the right keys', function(){ 96 | return pandr.should.eventually.contain.keys('type', 'features'); 97 | }); 98 | it('should be the right type',function(){ 99 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 100 | }); 101 | it('should have the right number of features',function(){ 102 | return pandr.then(function(a){return a.features}).should.eventually.have.length(361); 103 | }); 104 | }); 105 | describe('empty attributes table', function(){ 106 | var pandr = shp('http://localhost:3000/files/empty-shp.zip'); 107 | it('should have the right keys', function(){ 108 | return pandr.should.eventually.contain.keys('type', 'features'); 109 | }); 110 | it('should be the right type',function(){ 111 | return pandr.should.eventually.have.property('type', 'FeatureCollection'); 112 | }); 113 | it('should have the right number of features',function(){ 114 | return pandr.then(function(a){return a.features}).should.eventually.have.length(2); 115 | }); 116 | }); 117 | describe('errors', function(){ 118 | it('bad file should be rejected', function(){ 119 | return shp('http://localhost:3000/test/data/bad').should.be.rejected; 120 | }); 121 | it('imaginary file file should be rejected', function(done){ 122 | shp('http://localhost:3000/test/data/notthere').then(function () { 123 | done(true); 124 | }, function () { 125 | done(); 126 | }); 127 | }); 128 | it('bad zip be rejected', function(){ 129 | return shp('http://localhost:3000/test/data/badzip.zip').should.be.rejected; 130 | }); 131 | it('no shp in zip', function(){ 132 | return shp('http://localhost:3000/test/data/noshp.zip').should.be.rejected; 133 | }); 134 | }); 135 | describe('encoding', function () { 136 | it('should work for utf.zip', function(){ 137 | return shp('http://localhost:3000/test/data/utf.zip').then(function (item) { 138 | item.should.contain.keys('type', 'features'); 139 | return item.features.map(function (feature) { 140 | return feature.properties.field; 141 | }); 142 | }).should.eventually.deep.equal([ 143 | '💩', 144 | 'Hněvošický háj' 145 | ]); 146 | }); 147 | it('should work for utf', function(){ 148 | return shp('http://localhost:3000/test/data/utf').then(function (item) { 149 | item.should.contain.keys('type', 'features'); 150 | return item.features.map(function (feature) { 151 | return feature.properties.field; 152 | }); 153 | }).should.eventually.deep.equal([ 154 | '💩', 155 | 'Hněvošický háj' 156 | ]); 157 | }); 158 | it('should work for codepage.zip', function(){ 159 | return shp('http://localhost:3000/test/data/codepage.zip').then(function (item) { 160 | item.should.contain.keys('type', 'features'); 161 | return item.features.map(function (feature) { 162 | return feature.properties.field; 163 | }); 164 | }).should.eventually.deep.equal([ 165 | '??', 166 | 'Hněvošický háj' 167 | ]); 168 | }); 169 | it('should work for codepage', function(){ 170 | return shp('http://localhost:3000/test/data/codepage').then(function (item) { 171 | item.should.contain.keys('type', 'features'); 172 | return item.features.map(function (feature) { 173 | return feature.properties.field; 174 | }); 175 | }).should.eventually.deep.equal([ 176 | '??', 177 | 'Hněvošický háj' 178 | ]); 179 | }); 180 | }); 181 | }); 182 | --------------------------------------------------------------------------------