// 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几何体画线 // 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); // // 用于更新mesh对象 // 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++;