import * as echarts from 'echarts/lib/echarts'; import glmatrix from 'claygl/src/dep/glmatrix'; var vec3 = glmatrix.vec3; var mat4 = glmatrix.mat4; import textCoord from 'echarts/lib/coord/geo/fix/textCoord'; import geoCoord from 'echarts/lib/coord/geo/fix/geoCoord'; // Geo fix functions var geoFixFuncs = [textCoord, geoCoord]; function Geo3D(name, map, geoJson, specialAreas, nameMap) { this.name = name; this.map = map; this.regionHeight = 0; this.regions = []; this._nameCoordMap = {}; this.loadGeoJson(geoJson, specialAreas, nameMap); this.transform = mat4.identity(new Float64Array(16)); this.invTransform = mat4.identity(new Float64Array(16)); // Which dimension to extrude. Y or Z this.extrudeY = true; this.altitudeAxis; } Geo3D.prototype = { constructor: Geo3D, type: 'geo3D', dimensions: ['lng', 'lat', 'alt'], containPoint: function () {}, loadGeoJson: function (geoJson, specialAreas, nameMap) { var parseGeoJSON = echarts.parseGeoJSON || echarts.parseGeoJson; try { this.regions = geoJson ? parseGeoJSON(geoJson) : []; } catch (e) { throw 'Invalid geoJson format\n' + e; } specialAreas = specialAreas || {}; nameMap = nameMap || {}; var regions = this.regions; var regionsMap = {}; for (var i = 0; i < regions.length; i++) { var regionName = regions[i].name; // Try use the alias in nameMap regionName = nameMap[regionName] || regionName; regions[i].name = regionName; regionsMap[regionName] = regions[i]; // Add geoJson this.addGeoCoord(regionName, regions[i].getCenter()); // Some area like Alaska in USA map needs to be tansformed // to look better var specialArea = specialAreas[regionName]; if (specialArea) { regions[i].transformTo(specialArea.left, specialArea.top, specialArea.width, specialArea.height); } } this._regionsMap = regionsMap; this._geoRect = null; geoFixFuncs.forEach(function (fixFunc) { fixFunc(this); }, this); }, getGeoBoundingRect: function () { if (this._geoRect) { return this._geoRect; } var rect; var regions = this.regions; for (var i = 0; i < regions.length; i++) { var regionRect = regions[i].getBoundingRect(); rect = rect || regionRect.clone(); rect.union(regionRect); } // FIXME Always return new ? return this._geoRect = rect || new echarts.graphic.BoundingRect(0, 0, 0, 0); }, /** * Add geoCoord for indexing by name * @param {string} name * @param {Array.} geoCoord */ addGeoCoord: function (name, geoCoord) { this._nameCoordMap[name] = geoCoord; }, /** * @param {string} name * @return {module:echarts/coord/geo/Region} */ getRegion: function (name) { return this._regionsMap[name]; }, getRegionByCoord: function (coord) { var regions = this.regions; for (var i = 0; i < regions.length; i++) { if (regions[i].contain(coord)) { return regions[i]; } } }, setSize: function (width, height, depth) { this.size = [width, height, depth]; var rect = this.getGeoBoundingRect(); var scaleX = width / rect.width; var scaleZ = -depth / rect.height; var translateX = -width / 2 - rect.x * scaleX; var translateZ = depth / 2 - rect.y * scaleZ; var position = this.extrudeY ? [translateX, 0, translateZ] : [translateX, translateZ, 0]; var scale = this.extrudeY ? [scaleX, 1, scaleZ] : [scaleX, scaleZ, 1]; var m = this.transform; mat4.identity(m); mat4.translate(m, m, position); mat4.scale(m, m, scale); mat4.invert(this.invTransform, m); }, dataToPoint: function (data, out) { out = out || []; var extrudeCoordIndex = this.extrudeY ? 1 : 2; var sideCoordIndex = this.extrudeY ? 2 : 1; var altitudeVal = data[2]; // PENDING. if (isNaN(altitudeVal)) { altitudeVal = 0; } // lng out[0] = data[0]; // lat out[sideCoordIndex] = data[1]; if (this.altitudeAxis) { out[extrudeCoordIndex] = this.altitudeAxis.dataToCoord(altitudeVal); } else { out[extrudeCoordIndex] = 0; } // PENDING different region height. out[extrudeCoordIndex] += this.regionHeight; vec3.transformMat4(out, out, this.transform); return out; }, pointToData: function (point, out) {// TODO } }; export default Geo3D;