import Globe from './globe/Globe'; import * as echarts from 'echarts/lib/echarts'; import { getLayoutRect } from 'echarts/lib/util/layout'; import ViewGL from '../core/ViewGL'; import retrieve from '../util/retrieve'; import graphicGL from '../util/graphicGL'; function getDisplacementData(img, displacementScale) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var width = img.width; var height = img.height; canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); var rgbaArr = ctx.getImageData(0, 0, width, height).data; var displacementArr = new Float32Array(rgbaArr.length / 4); for (var i = 0; i < rgbaArr.length / 4; i++) { var x = rgbaArr[i * 4]; displacementArr[i] = x / 255 * displacementScale; } return { data: displacementArr, width: width, height: height }; } function resizeGlobe(globeModel, api) { // Use left/top/width/height var boxLayoutOption = globeModel.getBoxLayoutParams(); var viewport = getLayoutRect(boxLayoutOption, { width: api.getWidth(), height: api.getHeight() }); // Flip Y viewport.y = api.getHeight() - viewport.y - viewport.height; this.viewGL.setViewport(viewport.x, viewport.y, viewport.width, viewport.height, api.getDevicePixelRatio()); this.radius = globeModel.get('globeRadius'); var outerRadius = globeModel.get('globeOuterRadius'); if (this.altitudeAxis) { this.altitudeAxis.setExtent(0, outerRadius - this.radius); } } function updateGlobe(ecModel, api) { var altitudeDataExtent = [Infinity, -Infinity]; ecModel.eachSeries(function (seriesModel) { if (seriesModel.coordinateSystem !== this) { return; } // Get altitude data extent. var data = seriesModel.getData(); var altDims = seriesModel.coordDimToDataDim('alt'); var altDim = altDims && altDims[0]; if (altDim) { // TODO altitiude is in coords of lines. var dataExtent = data.getDataExtent(altDim, true); altitudeDataExtent[0] = Math.min(altitudeDataExtent[0], dataExtent[0]); altitudeDataExtent[1] = Math.max(altitudeDataExtent[1], dataExtent[1]); } }, this); // Create altitude axis if (altitudeDataExtent && isFinite(altitudeDataExtent[1] - altitudeDataExtent[0])) { var scale = echarts.helper.createScale(altitudeDataExtent, { type: 'value', // PENDING min: 'dataMin', max: 'dataMax' }); this.altitudeAxis = new echarts.Axis('altitude', scale); // Resize again this.resize(this.model, api); } } var globeCreator = { dimensions: Globe.prototype.dimensions, create: function (ecModel, api) { var globeList = []; ecModel.eachComponent('globe', function (globeModel) { // FIXME globeModel.__viewGL = globeModel.__viewGL || new ViewGL(); var globe = new Globe(); globe.viewGL = globeModel.__viewGL; globeModel.coordinateSystem = globe; globe.model = globeModel; globeList.push(globe); // Inject resize globe.resize = resizeGlobe; globe.resize(globeModel, api); globe.update = updateGlobe; }); ecModel.eachSeries(function (seriesModel) { if (seriesModel.get('coordinateSystem') === 'globe') { var globeModel = seriesModel.getReferringComponents('globe').models[0]; if (!globeModel) { globeModel = ecModel.getComponent('globe'); } if (!globeModel) { throw new Error('globe "' + retrieve.firstNotNull(seriesModel.get('globe3DIndex'), seriesModel.get('globe3DId'), 0) + '" not found'); } var coordSys = globeModel.coordinateSystem; seriesModel.coordinateSystem = coordSys; } }); ecModel.eachComponent('globe', function (globeModel, idx) { var globe = globeModel.coordinateSystem; // Update displacement data var displacementTextureValue = globeModel.getDisplacementTexture(); var displacementScale = globeModel.getDisplacemenScale(); if (globeModel.isDisplacementChanged()) { if (globeModel.hasDisplacement()) { var immediateLoaded = true; graphicGL.loadTexture(displacementTextureValue, api, function (texture) { var img = texture.image; var displacementData = getDisplacementData(img, displacementScale); globeModel.setDisplacementData(displacementData.data, displacementData.width, displacementData.height); if (!immediateLoaded) { // Update layouts api.dispatchAction({ type: 'globeUpdateDisplacment' }); } }); immediateLoaded = false; } else { globe.setDisplacementData(null, 0, 0); } globe.setDisplacementData(globeModel.displacementData, globeModel.displacementWidth, globeModel.displacementHeight); } }); return globeList; } }; export default globeCreator;