1
0
mirror of https://github.com/wavded/js-shapefile-to-geojson synced 2024-11-23 14:34:54 +00:00

Add support for loading via File API

Shapefile and DBF constructors now support referencing files
via both url and a HTML 5 File API handle. This can be used
to load and map content added to file input(s) and processed
on the client browser.

FileReader and FileReaderSync are both used depending upon
availability to make this functionality work in both Gecko
and Webkit inside Web Workers.
This commit is contained in:
Chad Burt 2013-09-09 17:01:36 -07:00
parent c4cf216ec4
commit 8da264ae24
3 changed files with 187 additions and 41 deletions

44
dbf.js
View File

@ -56,6 +56,45 @@
} }
var DBF = function(url, callback){ var DBF = function(url, callback){
if (!!url.lastModifiedDate)
this.handleFile(url, callback);
else
this.handleUri(url, callback);
}
DBF.prototype = {
constructor: DBF,
handleFile: function(file, callback) {
this.callback = callback;
if (!!window.FileReader) {
var reader = new FileReader();
} else {
var reader = new FileReaderSync();
}
reader.onload = (function(that){
return function(e){
that.onFileLoad(e.target.result)
}
})(this);
if (!!window.FileReader) {
reader.readAsBinaryString(file);
} else {
this.onFileLoad(reader.readAsBinaryString(file));
}
},
onFileLoad: function(data) {
this.stream = new Gordon.Stream(data)
this.readFileHeader()
this.readFieldDescriptions()
this.readRecords()
this._postMessage()
},
handleUri: function(url, callback) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open("GET", url, false) xhr.open("GET", url, false)
@ -73,10 +112,7 @@
this.readRecords() this.readRecords()
this._postMessage() this._postMessage()
} },
DBF.prototype = {
constructor: DBF,
_postMessage: function() { _postMessage: function() {
var data = { var data = {
header: this.header, header: this.header,

65
files.html Normal file
View File

@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<title>js-shapefile-to-geojson Demo Page</title>
<style>
html, body {
height: 100%;
width: 100%;
}
#map {
height: 400px;
background-color: #eee;
}
</style>
</head>
<body>
<a href="http://github.com/wavded/js-shapefile-to-geojson"><img style="position: absolute; top: 0; right: 0; border: 0;" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
<h2>js-shapefile-to-geojson Demo Page</h2>
<p>Pure client-side JavaScript (no server side code) parsing of shapefiles and dbase files to GeoJSON format displayed using OpenLayers.</p>
<div id="map"></div>
<p>View project at <a href="http://github.com/wavded/js-shapefile-to-geojson">http://github.com/wavded/js-shapefile-to-geojson</a>.
<script src="http://rs1.adc4gis.com/js/openlayers/2.9.1/OpenLayers-Proj4.js"></script>
<script src="stream.js"></script>
<script src="shapefile.js"></script>
<script src="dbf.js"></script>
<script type="text/javascript">
OpenLayers._getScriptLocation = function(){
return "http://rs1.adc4gis.com/js/openlayers/2.9.1/";
};
var map = new OpenLayers.Map("map",{allOverlays: true}),
parser = new OpenLayers.Format.GeoJSON(),
vector = new OpenLayers.Layer.Vector("Converted")
map.addLayer(vector);
var onchange = function(e) {
var shpFile = document.getElementById('shp').files[0];
var dbfFile = document.getElementById('dbf').files[0];
if (shpFile) {
var opts = { shp: shpFile };
if (dbfFile) {
opts['dbf'] = dbfFile;
}
shapefile = new Shapefile(opts, function(data){
var features = parser.read(data.geojson);
vector.addFeatures(features);
map.zoomToExtent(vector.getDataExtent());
console.log(data);
});
}
}
document.body.onload = function(){
document.getElementById('shp').addEventListener('change', onchange, false);
document.getElementById('dbf').addEventListener('change', onchange, false);
}
</script>
<br>
<br>
.shp <input id="shp" type="file" name=".shp" />
.dbf <input id="dbf" type="file" name=".dbf" />
</body>
</html>

View File

@ -11,6 +11,8 @@
if (!worker) { if (!worker) {
var path = (o.jsRoot || "") + "shapefile.js" var path = (o.jsRoot || "") + "shapefile.js"
var w = worker = this.worker = new Worker(path) var w = worker = this.worker = new Worker(path)
} else {
var w = worker
} }
w.onmessage = function(e){ w.onmessage = function(e){
@ -64,9 +66,20 @@
} }
var Shapefile = function(o,callback){ var Shapefile = function(o,callback){
var o = typeof o == "string" ? {shp: o} : o
this.callback = callback
if (!!o.shp.lastModifiedDate)
this.handleFile(o);
else
this.handleUri(o);
}
Shapefile.prototype = {
constructor: Shapefile,
handleUri: function(o) {
var xhr = new XMLHttpRequest(), var xhr = new XMLHttpRequest(),
that = this, that = this
o = typeof o == "string" ? {shp: o} : o
xhr.open("GET", o.shp, false) xhr.open("GET", o.shp, false)
xhr.overrideMimeType("text/plain; charset=x-user-defined") xhr.overrideMimeType("text/plain; charset=x-user-defined")
@ -77,7 +90,6 @@
this.url = o.shp this.url = o.shp
this.stream = new Gordon.Stream(xhr.responseText) this.stream = new Gordon.Stream(xhr.responseText)
this.callback = callback
this.readFileHeader() this.readFileHeader()
this.readRecords() this.readRecords()
@ -89,11 +101,44 @@
that.addDBFDataToGeoJSON(data) that.addDBFDataToGeoJSON(data)
that._postMessage() that._postMessage()
}) })
else this._postMessage else this._postMessage()
},
handleFile: function(o) {
this.options = o
if (!!window.FileReader) {
var reader = new FileReader();
} else {
var reader = new FileReaderSync();
} }
Shapefile.prototype = { reader.onload = (function(that){
constructor: Shapefile, return function(e){
that.onFileLoad(e.target.result)
}
})(this);
if (!!window.FileReader) {
reader.readAsBinaryString(o.shp);
} else {
this.onFileLoad(reader.readAsBinaryString(o.shp));
}
},
onFileLoad: function(data) {
this.stream = new Gordon.Stream(data)
this.readFileHeader()
this.readRecords()
this.formatIntoGeoJson()
if(this.options.dbf) this.dbf = IN_WORKER ?
null :
new DBF(this.options.dbf,function(data){
that.addDBFDataToGeoJSON(data)
that._postMessage()
})
else this._postMessage()
},
_postMessage: function() { _postMessage: function() {
var data = { var data = {
header: this.header, header: this.header,