198 lines
6.3 KiB
JavaScript
198 lines
6.3 KiB
JavaScript
// Shapefile parser, following the specification at
|
||
// http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
|
||
SHP = {
|
||
NULL: 0,
|
||
POINT: 1,
|
||
POLYLINE: 3,
|
||
POLYGON: 5
|
||
};
|
||
|
||
SHP.getShapeName = function (id) {
|
||
for (name in this) {
|
||
if (id === this[name]) {
|
||
return name;
|
||
}
|
||
}
|
||
};
|
||
|
||
SHPParser = function () {
|
||
};
|
||
|
||
SHPParser.load = function (src, callback, onerror) {
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.responseType = 'arraybuffer';
|
||
xhr.onload = function () {
|
||
var d = new SHPParser().parse(xhr.response, xhr);
|
||
if (d) {
|
||
callback(d);
|
||
}
|
||
};
|
||
xhr.onerror = onerror;
|
||
xhr.open('GET', src);
|
||
xhr.send(null);
|
||
};
|
||
|
||
SHPParser.prototype.parse = function (arrayBuffer, xhr) {
|
||
var o = {};
|
||
var dv = new DataView(arrayBuffer);
|
||
var idx = 0;
|
||
o.fileCode = dv.getInt32(idx, false);
|
||
if (o.fileCode != 0x0000270a) {
|
||
// throw (new Error("Unknown file code: " + o.fileCode));
|
||
xhr.onerror();
|
||
return false;
|
||
}
|
||
idx += 6 * 4;
|
||
o.wordLength = dv.getInt32(idx, false);
|
||
o.byteLength = o.wordLength * 2;
|
||
idx += 4;
|
||
o.version = dv.getInt32(idx, true);
|
||
idx += 4;
|
||
o.shapeType = dv.getInt32(idx, true);
|
||
idx += 4;
|
||
o.minX = dv.getFloat64(idx, true);
|
||
o.minY = dv.getFloat64(idx + 8, true);
|
||
o.maxX = dv.getFloat64(idx + 16, true);
|
||
o.maxY = dv.getFloat64(idx + 24, true);
|
||
o.minZ = dv.getFloat64(idx + 32, true);
|
||
o.maxZ = dv.getFloat64(idx + 40, true);
|
||
o.minM = dv.getFloat64(idx + 48, true);
|
||
o.maxM = dv.getFloat64(idx + 56, true);
|
||
idx += 8 * 8;
|
||
o.records = [];
|
||
while (idx < o.byteLength) {
|
||
var record = {};
|
||
record.number = dv.getInt32(idx, false);
|
||
idx += 4;
|
||
record.length = dv.getInt32(idx, false);
|
||
idx += 4;
|
||
try {
|
||
record.shape = this.parseShape(dv, idx, record.length);
|
||
} catch (e) {
|
||
console.log(e, record);
|
||
}
|
||
idx += record.length * 2;
|
||
o.records.push(record);
|
||
}
|
||
return o;
|
||
};
|
||
|
||
SHPParser.prototype.parseShape = function (dv, idx, length) {
|
||
var i = 0, c = null;
|
||
var shape = {};
|
||
shape.type = dv.getInt32(idx, true);
|
||
idx += 4;
|
||
var byteLen = length * 2;
|
||
switch (shape.type) {
|
||
case SHP.NULL: // Null
|
||
break;
|
||
|
||
case SHP.POINT: // Point (x,y)
|
||
shape.content = {
|
||
x: dv.getFloat64(idx, true),
|
||
y: dv.getFloat64(idx + 8, true)
|
||
};
|
||
break;
|
||
case SHP.POLYLINE: // Polyline (MBR, partCount, pointCount, parts, points)
|
||
case SHP.POLYGON: // Polygon (MBR, partCount, pointCount, parts, points)
|
||
c = shape.content = {
|
||
minX: dv.getFloat64(idx, true),
|
||
minY: dv.getFloat64(idx + 8, true),
|
||
maxX: dv.getFloat64(idx + 16, true),
|
||
maxY: dv.getFloat64(idx + 24, true),
|
||
parts: new Int32Array(dv.getInt32(idx + 32, true)),
|
||
points: new Float64Array(dv.getInt32(idx + 36, true) * 2)
|
||
};
|
||
idx += 40;
|
||
for (i = 0; i < c.parts.length; i++) {
|
||
c.parts[i] = dv.getInt32(idx, true);
|
||
idx += 4;
|
||
}
|
||
for (i = 0; i < c.points.length; i++) {
|
||
c.points[i] = dv.getFloat64(idx, true);
|
||
idx += 8;
|
||
}
|
||
break;
|
||
|
||
case 8: // MultiPoint (MBR, pointCount, points)
|
||
case 11: // PointZ (X, Y, Z, M)
|
||
case 13: // PolylineZ
|
||
case 15: // PolygonZ
|
||
case 18: // MultiPointZ
|
||
case 21: // PointM (X, Y, M)
|
||
case 23: // PolylineM
|
||
case 25: // PolygonM
|
||
case 28: // MultiPointM
|
||
case 31: // MultiPatch
|
||
throw new Error("Shape type not supported: "
|
||
+ shape.type + ':' +
|
||
+ SHP.getShapeName(shape.type));
|
||
default:
|
||
throw new Error("Unknown shape type at " + (idx - 4) + ': ' + shape.type);
|
||
}
|
||
return shape;
|
||
};
|
||
|
||
// if (isRoad) {
|
||
// // Three<65><65><EFBFBD><EFBFBD><EFBFBD>廭<EFBFBD><E5BBAD>
|
||
// var geometry = new THREE.LineGeometry();
|
||
// var decoPos = [];
|
||
// var spline = new THREE.CatmullRomCurve3(poly);
|
||
// var color = new THREE.Color();
|
||
// var colors = [];
|
||
// for (var m = 0, l = poly.length * 120; m <= l; m++) {
|
||
// var point = spline.getPoint(m / l);
|
||
// decoPos.push(point.x, point.y, point.z);
|
||
// // if (m == 0 || m == 1 || m == 2) {
|
||
// // colors.push(1.0, 1.0, 0.0);
|
||
// // } else if (m == 3) {
|
||
// // colors.push(1.0, 1.0, 0.0);
|
||
// // } else {
|
||
// // colors.push(1.0, 0.0, 0.0);
|
||
// // }
|
||
// }
|
||
// geometry.setPositions(decoPos);
|
||
// // geometry.setColors(colors);
|
||
// var line = new THREE.Line2(geometry, matLine);
|
||
// line.computeLineDistances();
|
||
// line.scale.set(1, 1, 1);
|
||
// line.position.z += 15000.0;
|
||
// // line.rotation.x = Math.PI / 2;
|
||
// scene.add(line);
|
||
// line.userData.posCount = poly.length * 12;
|
||
// line.userData.index = 0;
|
||
// line.userData.flag = 0;
|
||
// line.layers.enable(BLOOM_SCENE);
|
||
|
||
// // <20><><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD>mesh<73><68><EFBFBD><EFBFBD>
|
||
// obj = new _3DObject();
|
||
// obj.threeMesh = line;
|
||
// obj.minWGS84 = [r.content.minX, r.content.minY];
|
||
// obj.maxWGS84 = [r.content.maxX, r.content.maxY];
|
||
// _3Dobjects.push(obj);
|
||
// }
|
||
|
||
|
||
|
||
|
||
// var line = _3DLineobjects[id].threeMesh;
|
||
// var posCount = line.userData.posCount;
|
||
|
||
// var colors = [];
|
||
// if (line.userData.index == posCount) {
|
||
// line.userData.index = 0;
|
||
// }
|
||
// for (var i = 0, l = posCount; i <= l; i++) {
|
||
// if (i == line.userData.index || i == line.userData.index + 1 || i == line.userData.index + 2) {
|
||
// colors.push(1.0, 1.0, 0.0);
|
||
// } else if (i == line.userData.index - 1) {
|
||
// colors.push(1.0, 1.0, 0.0);
|
||
// } else {
|
||
// colors.push(1.0, 0.0, 0.0);
|
||
// // colors.push(0,1,1);
|
||
// // colors.push(1.0, 0.0, 0.0);
|
||
// }
|
||
// }
|
||
// line.geometry.setColors(colors);
|
||
// line.userData.index++;
|