Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/source_file_geojson_raster_2.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
view.addLayer(earthquakeLayer).then(FeatureToolTip.addLayer);

// Request redraw
view.notifyChange(true);
view.notifyChange();

debug.createTileDebugUI(menuGlobe.gui, view);
window.view = view;
Expand Down
9 changes: 3 additions & 6 deletions packages/Main/src/Converter/Feature2Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as THREE from 'three';
import { FEATURE_TYPES } from 'Core/Feature';
import { Extent, Coordinates } from '@itowns/geographic';
import Style, { StyleContext } from 'Core/Style';
import { createContext2D } from 'Utils/CanvasUtils';

const defaultStyle = new Style();
const context = new StyleContext();
Expand Down Expand Up @@ -118,13 +119,9 @@ export default {
// A texture is instancied drawn canvas
// origin and dimension are used to transform the feature's coordinates to canvas's space
extent.planarDimensions(dimension);
const c = document.createElement('canvas');

coord.crs = extent.crs;

c.width = sizeTexture;
c.height = sizeTexture;
const ctx = c.getContext('2d', { willReadFrequently: true });
const ctx = createContext2D(sizeTexture, sizeTexture);
if (backgroundColor) {
ctx.fillStyle = backgroundColor.getStyle();
ctx.fillRect(0, 0, sizeTexture, sizeTexture);
Expand Down Expand Up @@ -168,7 +165,7 @@ export default {
drawFeature(ctx, feature, featureExtent, invCtxScale);
}

texture = new THREE.CanvasTexture(c);
texture = new THREE.CanvasTexture(ctx.canvas);
texture.flipY = collection.isInverted;
} else if (backgroundColor) {
const data = new Uint8Array(3);
Expand Down
98 changes: 38 additions & 60 deletions packages/Main/src/Core/Style.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { Coordinates } from '@itowns/geographic';
import { LRUCache } from 'lru-cache';
import Fetcher from 'Provider/Fetcher';
import { Color, EventDispatcher } from 'three';
import { deltaE } from 'Renderer/Color';
import { EventDispatcher } from 'three';
import { sharedContext2D, sharedReadContext2D } from 'Utils/CanvasUtils';

import itowns_stroke_single_before from './StyleChunk/itowns_stroke_single_before.css';

const cachedImg = new LRUCache({ max: 500 });

let matrix;
let canvas;

if (typeof document !== 'undefined') {
matrix = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
canvas = document.createElement('canvas');
}

function baseAltitudeDefault(properties, ctx) {
Expand Down Expand Up @@ -58,39 +56,10 @@ async function loadImage(url) {
return (await promise).image;
}

function cropImage(img, cropValues) {
const x = cropValues.x || 0;
const y = cropValues.y || 0;
const width = cropValues.width || img.naturalWidth;
const height = cropValues.height || img.naturalHeight;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d', { willReadFrequently: true });
function cropImage(ctx, img, x, y, width, height) {
ctx.drawImage(img,
x, y, width, height,
0, 0, width, height);
return ctx.getImageData(0, 0, width, height);
}

function replaceWhitePxl(imgd, color, id) {
if (!color) {
return imgd;
}
const imgdColored = cachedImg.get(`${id}_${color}`);
if (!imgdColored) {
const pix = imgd.data;
const newColor = new Color(color);
const colorToChange = new Color('white');
for (let i = 0, n = pix.length; i < n; i += 4) {
const d = deltaE(pix.slice(i, i + 3), colorToChange) / 100;
pix[i] = (pix[i] * d + newColor.r * 255 * (1 - d));
pix[i + 1] = (pix[i + 1] * d + newColor.g * 255 * (1 - d));
pix[i + 2] = (pix[i + 2] * d + newColor.b * 255 * (1 - d));
}
cachedImg.set(`${id}_${color}`, imgd);
return imgd;
}
return imgdColored;
}

const textAnchorPosition = {
Expand Down Expand Up @@ -698,15 +667,17 @@ class Style extends EventDispatcher {
async _applyFillToPolygon(txtrCtx, invCtxScale, polygon) {
// if (this.fill.pattern && txtrCtx.fillStyle.src !== this.fill.pattern.src) {
// need doc for the txtrCtx.fillStyle.src that seems to always be undefined
if (this.fill.pattern) {
let img = this.fill.pattern;
const cropValues = { ...this.fill.pattern.cropValues };
if (this.fill.pattern.source) {
img = await loadImage(this.fill.pattern.source);
}
cropImage(img, cropValues);

txtrCtx.fillStyle = txtrCtx.createPattern(canvas, 'repeat');
const { pattern } = this.fill;
if (pattern) {
const cropValues = 'cropValues' in pattern ? pattern.cropValues : {};
const img = 'source' in pattern ? await loadImage(pattern.source) : pattern;
const { x = 0, y = 0, width = img.naturalWidth, height = img.naturalHeight } = cropValues;

const cropCtx = sharedContext2D();
cropCtx.canvas.width = width;
cropCtx.canvas.height = height;
cropImage(cropCtx, img, x, y, width, height);
txtrCtx.fillStyle = txtrCtx.createPattern(cropCtx.canvas, 'repeat');
if (txtrCtx.fillStyle.setTransform) {
txtrCtx.fillStyle.setTransform(matrix.scale(invCtxScale));
} else {
Expand Down Expand Up @@ -755,16 +726,15 @@ class Style extends EventDispatcher {
domElement.setAttribute('data-before', domElement.textContent);
}

if (!this.icon.source) {
// Style properties are evaluated lazily within a shared and mutable
// context. Evaluating them after an await could yield incorrect values
// since the context has been mutated.
const { source, cropValues, color } = this.icon;
if (!source) {
return;
}

let icon;

if (typeof document !== 'undefined') {
icon = document.createElement('img');
}

const icon = document.createElement('img');
const iconPromise = new Promise((resolve, reject) => {
const opt = {
size: this.icon.size,
Expand All @@ -776,17 +746,25 @@ class Style extends EventDispatcher {
icon.onerror = err => reject(err);
});

if (!this.icon.cropValues && !this.icon.color) {
icon.src = this.icon.source;
if (!cropValues && !color) {
icon.src = source;
} else {
const cropValues = { ...this.icon.cropValues };
const color = this.icon.color;
const id = this.icon.id || this.icon.source;
const img = await loadImage(this.icon.source);
const imgd = cropImage(img, cropValues);
const imgdColored = replaceWhitePxl(imgd, color, id);
canvas.getContext('2d').putImageData(imgdColored, 0, 0);
icon.src = canvas.toDataURL('image/png');
const img = await loadImage(source);
const { x = 0, y = 0, width = img.naturalWidth, height = img.naturalHeight } = cropValues ?? {};
const cropCtx = sharedReadContext2D();
cropCtx.canvas.width = width;
cropCtx.canvas.height = height;
cropImage(cropCtx, img, x, y, width, height);
if (color) {
const oldGlobalCompositeOp = cropCtx.globalCompositeOperation;
cropCtx.globalCompositeOperation = 'multiply';
cropCtx.fillStyle = color;
cropCtx.fillRect(0, 0, width, height);
cropCtx.globalCompositeOperation = 'destination-in';
cropImage(cropCtx, img, x, y, width, height);
cropCtx.globalCompositeOperation = oldGlobalCompositeOp;
}
icon.src = cropCtx.canvas.toDataURL('image/png');
}
return iconPromise;
}
Expand Down
69 changes: 0 additions & 69 deletions packages/Main/src/Renderer/Color.js

This file was deleted.

10 changes: 3 additions & 7 deletions packages/Main/src/Renderer/PointsMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as THREE from 'three';
import PointsVS from 'Renderer/Shader/PointsVS.glsl';
import PointsFS from 'Renderer/Shader/PointsFS.glsl';
import CommonMaterial from 'Renderer/CommonMaterial';
import { createContext2D } from 'Utils/CanvasUtils';
import Gradients from 'Utils/Gradients';

export const PNTS_MODE = {
Expand Down Expand Up @@ -82,12 +83,7 @@ function generateGradientTexture(gradient) {
const size = 64;

// create canvas
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;

// get context
const context = canvas.getContext('2d');
const context = createContext2D(size, size);

// draw gradient
context.rect(0, 0, size, size);
Expand All @@ -102,7 +98,7 @@ function generateGradientTexture(gradient) {
context.fillStyle = ctxGradient;
context.fill();

const texture = new THREE.CanvasTexture(canvas);
const texture = new THREE.CanvasTexture(context.canvas);
texture.needsUpdate = true;

texture.minFilter = THREE.LinearFilter;
Expand Down
24 changes: 1 addition & 23 deletions packages/Main/src/Renderer/c3DEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
*/

import * as THREE from 'three';
import WEBGL from 'three/addons/capabilities/WebGL.js';
import Capabilities from 'Core/System/Capabilities';
import { unpack1K } from 'Renderer/LayeredMaterial';
import Label2DRenderer from 'Renderer/Label2DRenderer';
import { deprecatedC3DEngineWebGLOptions } from 'Core/Deprecated/Undeprecator';
import WEBGL from 'three/addons/capabilities/WebGL.js';
import { EffectComposer } from 'postprocessing';

const depthRGBA = new THREE.Vector4();
Expand Down Expand Up @@ -230,28 +230,6 @@ class c3DEngine {
return target;
}

bufferToImage(pixelBuffer, width, height) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true });

// size the canvas to your desired image
canvas.width = width;
canvas.height = height;

const imgData = ctx.getImageData(0, 0, width, height);
imgData.data.set(pixelBuffer);

ctx.putImageData(imgData, 0, 0);

// create a new img object
const image = new Image();

// set the img.src to the canvas data url
image.src = canvas.toDataURL();

return image;
}

depthBufferRGBAValueToOrthoZ(depthBufferRGBA, camera) {
depthRGBA.fromArray(depthBufferRGBA).divideScalar(255.0);

Expand Down
Loading
Loading