Растровые слои «заморозить» на увеличении, они были впервые добавлены и обновляются только после того, как я увеличил маJavascript

Форум по Javascript
Ответить
Anonymous
 Растровые слои «заморозить» на увеличении, они были впервые добавлены и обновляются только после того, как я увеличил ма

Сообщение Anonymous »

Проблема < /strong>: Я использую листовку с Georaster + Georaster-Layer-For-Leaflet, чтобы переключать несколько однополосных геотиф-растра (только один видимый за раз). Когда я переключаю, какой растровый виден, ранее добавленные растровые визуально «палки» на уровне масштабирования, где он был впервые отображен. Новый растровый не появляется, пока я не выполню какое -либо действие по увеличению; После увеличения увеличения появляется правильный растровый. Другими словами, холст кажется замороженным до тех пор, пока не будет запущено событие увеличения*. Файлы публично читаются через firebasestorage.googleapis.com. CORS включен на ведро и позволяет Get/Head с заголовком ответа типа контента.
Пример того, что произошло
код
:

Код: Выделить всё

(function (app) {
'use strict';

// -------------------------------------------------
// Helpers
// -------------------------------------------------
function computeLegendRange(legend) {
if (!legend || !Array.isArray(legend.classes) || legend.classes.length === 0) {
return { min: 0, max: 1 };
}
const bounds = legend.classes
.map(c => (typeof c.upper_bound === 'number' ? c.upper_bound : null))
.filter(v => v !== null && isFinite(v));
if (bounds.length === 0) {
return { min: 0, max: 1 };
}
return { min: Math.min(...bounds), max: Math.max(...bounds) };
}

function createGeoRasterLayer(layerState) {
const georaster = layerState.georaster;
const config = layerState.config;
const colorClasses = (config.legend && config.legend.classes) ? config.legend.classes : [];

return new GeoRasterLayer({
georaster: georaster,
pane: layerState.paneId,
opacity: 0.7,
bounds: layerState.bounds,
resolution: 256,
updateWhenZooming: true,
updateWhenIdle: true,
updateInterval: 0,
keepBuffer: 0,
pixelValuesToColorFn: values => {
const value = values[0];
if (value === null || value === undefined || isNaN(value) || value === 0 || value === georaster.noDataValue) {
return null;
}
const [minFilter, maxFilter] = layerState.filterRange;
if (value < minFilter || value > maxFilter) {
return null;
}
for (let i = 0; i < colorClasses.length; i++) {
const cls = colorClasses[i];
if (typeof cls.upper_bound === 'number' && value  0) {
const from = ((minVal - min) / range) * 100;
const to = ((maxVal - min) / range) * 100;
selection.style.left = `${from}%`;
selection.style.right = `${100 - to}%`;
}
}

function updateStateFromSliders() {
let minVal = parseFloat(minSlider.value);
let maxVal = parseFloat(maxSlider.value);
if (minVal > maxVal) {
[minVal, maxVal] = [maxVal, minVal];
minSlider.value = minVal;
maxSlider.value = maxVal;
}
layerState.filterRange = [minVal, maxVal];
updateSliderVisuals();
}
minSlider.addEventListener('input', updateStateFromSliders);
maxSlider.addEventListener('input', updateStateFromSliders);
minSlider.addEventListener('change', () => applyRasterFilter(layerId));
maxSlider.addEventListener('change', () => applyRasterFilter(layerId));
updateSliderVisuals();
return container;
}

function createOpacitySlider(layerId) {
const layerState = app.activeRasterLayers[layerId];
const controlContainer = document.createElement('div');
controlContainer.className = 'opacity-control-container';
const initialOpacity = layerState.layer ? layerState.layer.options.opacity : 0.7;
controlContainer.innerHTML = `
[/i]
[i]
${Math.round(initialOpacity * 100)}%`;
controlContainer.querySelector('input').addEventListener('input', (e) => {
const opacity = parseFloat(e.target.value);
if (layerState.layer) layerState.layer.setOpacity(opacity);
controlContainer.querySelector('span').textContent = `${Math.round(opacity * 100)}%`;
});
return controlContainer;
}

function toggleExtraControl(type, button, layerId, container) {
const wasActive = button.classList.contains('active');
document.querySelectorAll(`#wrapper_controls_${layerId} .opacity-tool-btn, #wrapper_controls_${layerId} .filter-tool-btn`).forEach(btn => btn.classList.remove('active'));
container.innerHTML = '';
container.style.display = 'none';
if (!wasActive) {
button.classList.add('active');
const newControl = (type === 'opacity') ? createOpacitySlider(layerId) : createRangeFilterControl(layerId);
container.appendChild(newControl);
container.style.display = 'block';
}
}

// -------------------------------------------------
// Point analysis (value at the clicked point)
// -------------------------------------------------
function toggleInfoTool(button, layerId) {
const layerState = app.activeRasterLayers[layerId];
if (!layerState || !layerState.isLoaded) {
alert('Por favor, carregue a camada primeiro.');
return;
}
layerState.infoToolActive = !layerState.infoToolActive;
button.classList.toggle('active', layerState.infoToolActive);
const anyToolActive = Object.values(app.activeRasterLayers).some(state => state.infoToolActive);
if (anyToolActive) {
app.map.on('click', updatePixelValueOnClick);
} else {
app.map.off('click', updatePixelValueOnClick);
const pixelValuePanel = document.getElementById('pixelValuePanel');
if (pixelValuePanel) pixelValuePanel.style.display = 'none';
if (app.clickPin) app.map.removeLayer(app.clickPin);
}
}

function updatePixelValueOnClick(e) {
const { lat, lng } = e.latlng;
const panel = document.getElementById('pixelValuePanel');
const content = document.getElementById('pixelValueContent');
let htmlContent = `Latitude:[/b]  ${lat.toFixed(4)}[b]Longitude:[/b] ${lng.toFixed(4)}`;[b]    for (const layerId in app.activeRasterLayers) {
const layerState = app.activeRasterLayers[layerId];
if (layerState.visible && layerState.infoToolActive && layerState.georaster) {
const georaster = layerState.georaster;
let valueText = 'Fora da área de dados';
if (lng >= georaster.xmin && lng = georaster.ymin && lat  toggleInfoTool(infoBtn, layerId));
opacityBtn.addEventListener('click', () => toggleExtraControl('opacity', opacityBtn, layerId, controlsContainer));
filterBtn.addEventListener('click', () => toggleExtraControl('filter', filterBtn, layerId, controlsContainer));
}

// -------------------------------------------------
// Layer Visibility
// -------------------------------------------------
function hideRasterLayer(id) {
const st = app.activeRasterLayers[id];
if (!st) return;

forceCleanupRasterLayer(id);
st.visible = false;

if (st.infoToolActive) {
const infoBtn = document.querySelector(`.info-tool-btn[data-layer-id="${id}"]`);
if (infoBtn) infoBtn.classList.remove('active');
st.infoToolActive = false;
const anyToolActive = Object.values(app.activeRasterLayers).some(state => state.infoToolActive);
if (!anyToolActive) {
app.map.off('click', updatePixelValueOnClick);
const panel = document.getElementById('pixelValuePanel');
if (panel) panel.style.display = 'none';
if (app.clickPin) app.map.removeLayer(app.clickPin);
}
}
}

function showRasterLayer(id) {
const st = app.activeRasterLayers[id];
if (!st || !st.georaster) return;

st.paneId = `raster-${id}`;
if (!app.map.getPane(st.paneId)) {
app.map.createPane(st.paneId);
// app.__rZ = (app.__rZ || 1050) + 1;
app.map.getPane(st.paneId).style.zIndex = app.__rZ;
}
if (st.layer) {
forceCleanupRasterLayer(id);
}
st.layer = createGeoRasterLayer(st);
st.visible = true;
st.layer.addTo(app.map);
if (typeof st.layer.redraw === 'function') {
st.layer.redraw();
}
app.map.once('idle', () => { if (st.visible && st.layer?.redraw) st.layer.redraw(); });
app.map.once('zoomend', () => { if (st.visible && st.layer?.redraw) st.layer.redraw();  });
}

// -------------------------------------------------
// Raster loading
// -------------------------------------------------
async function loadRasterLayer(layerId) {
const layerState = app.activeRasterLayers[layerId];
const config = layerState.config;
const icon = document.getElementById(`icon_${layerId}`);
icon.className = 'fas fa-spinner fa-spin layer-action-icon';

try {
const response = await fetch(config.path, { mode: 'cors' });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const arrayBuffer = await response.arrayBuffer();
const georaster = await parseGeoraster(arrayBuffer);

layerState.georaster = georaster;
layerState.bounds = L.latLngBounds([
[georaster.ymin, georaster.xmin],
[georaster.ymax, georaster.xmax]
]);
layerState.legendRange = computeLegendRange(config.legend);
layerState.filterRange = [layerState.legendRange.min, layerState.legendRange.max];
layerState.isLoaded = true;

const checkbox = document.getElementById(`cb_${layerId}`);
checkbox.disabled = false;
checkbox.checked = true;
checkbox.dispatchEvent(new Event('change', { bubbles: true }));

const controlsWrapper = document.getElementById(`wrapper_controls_${layerId}`);
const controlsContainer = document.getElementById(`controls_${layerId}`);
createOperationalControls(layerId, controlsWrapper, controlsContainer);
icon.className = 'fas fa-check layer-action-icon';
setTimeout(() => { icon.className = 'fas fa-download layer-action-icon'; }, 1200);
} catch (error) {
console.error(`Falha ao carregar camada raster ${layerId}:`, error);
icon.className = 'fas fa-download layer-action-icon';
alert(`Não foi possível carregar a camada ${config.name}.`);
}
}

// -------------------------------------------------
// Initialization
// -------------------------------------------------
function init() {
// Point Analysis Panel Configuration
const panelHeader = document.querySelector('#pixelValuePanel .popup-header h4');
if (panelHeader) panelHeader.innerHTML = `[/i] Análise de Ponto`;
const panelContent = document.getElementById('pixelValueContent');
if (panelContent) {
const removePinBtn = document.createElement('button');
removePinBtn.id = 'removeAnalysisPinBtn';
removePinBtn.className = 'panel-action-button danger';
removePinBtn.innerHTML = '[i][/i] Remover Marcador';
removePinBtn.style.cssText = 'display: none; width: 100%; margin-top: 10px;';
panelContent.after(removePinBtn);
removePinBtn.addEventListener('click', () => {
if (app.clickPin) {
app.map.removeLayer(app.clickPin);
app.clickPin = null;
removePinBtn.style.display = 'none';
}
});
}
const closeBtn = document.getElementById('closePixelValuePanel');
if (closeBtn) {
closeBtn.addEventListener('click', () => {
Object.keys(app.activeRasterLayers).forEach(layerId => {
const layerState = app.activeRasterLayers[layerId];
if (layerState.infoToolActive) {
layerState.infoToolActive = false;
const infoBtn = document.querySelector(`.info-tool-btn[data-layer-id="${layerId}"]`);
if (infoBtn) infoBtn.classList.remove('active');
}
});
app.map.off('click', updatePixelValueOnClick);
const pixelValuePanel = document.getElementById('pixelValuePanel');
if (pixelValuePanel) pixelValuePanel.style.display = 'none';
if (app.clickPin) app.map.removeLayer(app.clickPin);
});
}

// Building the Layer UI
const rasterList = app.config.rasterLayers;
if (!Array.isArray(rasterList) || rasterList.length === 0) return;
app.activeRasterLayers = app.activeRasterLayers || {};
rasterList.forEach(rasterConfig =>  {
const groupContainer = document.getElementById(`group-content-${rasterConfig.group}`);
if (!groupContainer) return;

const layerId = rasterConfig.id;
app.activeRasterLayers[layerId] = {
layer: null, config: rasterConfig, georaster: null,
visible: false, isLoaded: false, filterRange: null,
bounds: null, legendRange: computeLegendRange(rasterConfig.legend),
infoToolActive: false, paneId: null,
legend: { type: 'raster', title: rasterConfig.name, ...(rasterConfig.legend || {}) }
};
const listItem = document.createElement('div');
listItem.className = 'layer-group-item';
listItem.innerHTML = `

[i][/i]
[i]
${rasterConfig.name}

[/i]


`;
groupContainer.appendChild(listItem);
document.getElementById(`icon_${layerId}`).addEventListener('click', () => loadRasterLayer(layerId));

const checkbox = document.getElementById(`cb_${layerId}`);
checkbox.addEventListener('change', (e) => {
const isChecked = e.target.checked;
if (!app.activeRasterLayers[layerId].isLoaded) { e.target.checked = false; return; }

if (isChecked) {
Object.keys(app.activeRasterLayers).forEach(otherId => {
if (otherId !== layerId && app.activeRasterLayers[otherId]?.visible) {
const cb = document.getElementById(`cb_${otherId}`);
if (cb) cb.checked = false;
hideRasterLayer(otherId);
}
});
showRasterLayer(layerId);
} else {
hideRasterLayer(layerId);
}
if (app.legend && app.legend.update) {
app.legend.update();
}
});
});
}

// -------------------------------------------------
// Public API
// -------------------------------------------------
app.raster = {
init,
loadRasterLayer,
showRasterLayer,
hideRasterLayer,
toggleInfoTool,
updatePixelValueOnClick
};
app.initRasterLayers = init;

})(window.app = window.app || {});
Вопросы :
*- есть ли известная проблема с GeorasterLayer (или его внутренние внутренние знания L.Gridlayer), где холст не лишается аннулирования до полного разбитого. рендеринг без необходимости увеличения? Toggle? После переключения, на экране все еще показывается растровый A на уровне масштабирования, где он был впервые добавлен. Только после Zoom (In или OUT) делает Raster B render. < /P>
то, что я попробовал < /strong>: < /p>
*- вызовов Layer.redraw () сразу после Addto (map), а также на map.once ('idle') /map.once ('Zoomend'). 0, UpdateWhenzooming: True, UpdateWhenidle: True, UpdateInterval: 0.
[*] Удаление слоя и очистку Dom Pane (pane.innerhtml = '') перед воссозданием. /> Проверка Cors и Fetch; Нагрузка данных хорошо, а пиксели читаются правильно. Я не полагаюсь на Zoomstart/Zoomend, чтобы вызвать первое рендеринг.*


Подробнее здесь: https://stackoverflow.com/questions/797 ... resh-after
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»