147 lines
4.8 KiB
JavaScript
147 lines
4.8 KiB
JavaScript
|
|
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;
|