All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geomajas.gwt2.client.map.render.LayerScalesRendererImpl Maven / Gradle / Ivy

/*
 * This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
 *
 * Copyright 2008-2013 Geosparc nv, http://www.geosparc.com/, Belgium.
 *
 * The program is available in open source according to the GNU Affero
 * General Public License. All contributions in this program are covered
 * by the Geomajas Contributors License Agreement. For full licensing
 * details, see LICENSE.txt in the project root.
 */

package org.geomajas.gwt2.client.map.render;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geomajas.geometry.Bbox;
import org.geomajas.geometry.Coordinate;
import org.geomajas.gwt.client.util.Dom;
import org.geomajas.gwt2.client.event.ScaleLevelRenderedHandler;
import org.geomajas.gwt2.client.gfx.HtmlContainer;
import org.geomajas.gwt2.client.gfx.HtmlGroup;
import org.geomajas.gwt2.client.map.ViewPort;
import org.geomajas.gwt2.client.map.layer.Layer;
import org.geomajas.gwt2.client.map.layer.RasterServerLayer;
import org.geomajas.gwt2.client.map.layer.VectorServerLayer;

import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;

/**
 * 

* MapScalesRenderer implementation that keeps a fixed number of scales in cache. This strategy trades memory for speed. * The more scale levels are kept in memory, the less tiles need to be fetched. *

*

* This implementation keeps the scales for a single layer, not the entire map. *

* * @author Pieter De Graef */ public class LayerScalesRendererImpl implements LayerRenderer { private static final int SCALE_CACHE_SIZE = 3; // Let's keep the last 3 scales. @Inject protected EventBus eventBus; protected final ViewPort viewPort; protected final Layer layer; protected final HtmlContainer htmlContainer; protected final Map tiledScaleRenderers; // A renderer per scale. protected final List scales; // Keeps track of the lastly visited scales. protected double visibleScale; @Inject protected TiledScaleRendererFactory rasterRendererFactory; // ------------------------------------------------------------------------ // Constructors: // ------------------------------------------------------------------------ /** * Create a new instance with the following parameters. * * @param viewPort * The viewPort onto which this renderer applies. * @param layer * The layer to be rendered. * @param htmlContainer * The container wherein to render all scales. */ @Inject public LayerScalesRendererImpl(@Assisted ViewPort viewPort, @Assisted Layer layer, @Assisted HtmlContainer htmlContainer) { this.viewPort = viewPort; this.layer = layer; this.htmlContainer = htmlContainer; tiledScaleRenderers = new HashMap(); scales = new ArrayList(SCALE_CACHE_SIZE + 2); visibleScale = viewPort.getScale(); } // ------------------------------------------------------------------------ // MapScalesRenderer implementation: // ------------------------------------------------------------------------ @Override public HandlerRegistration addScaleLevelRenderedHandler(ScaleLevelRenderedHandler handler) { return eventBus.addHandlerToSource(ScaleLevelRenderedHandler.TYPE, this, handler); } @Override public HtmlContainer getHtmlContainer() { return htmlContainer; } @Override public void ensureScale(double scale, Bbox bounds) { cancel(); // TODO should we do this?? // Get or create the presenter, then turn it invisible and fetch the tiles. LayerScaleRenderer presenter = getOrCreate(scale); if (scale != visibleScale) { presenter.getHtmlContainer().setVisible(false); } presenter.render(bounds); // Rearrange the scales: if (scales.contains(scale)) { scales.remove(scale); } scales.add(scale); // If we have too many scales, remove the last one to be used: if (scales.size() > SCALE_CACHE_SIZE) { if (scales.get(0) != visibleScale) { removeScaleLevel(scales.get(0)); } else if (scales.get(1) != scale) { removeScaleLevel(scales.get(1)); } } } @Override public void bringScaleToFront(double scale) { LayerScaleRenderer scalePresenter = tiledScaleRenderers.get(scale); if (scalePresenter != null) { LayerScaleRenderer renderer = tiledScaleRenderers.get(scale); htmlContainer.bringToFront(renderer.getHtmlContainer()); } } @Override public void setScaleVisibility(double scale, boolean visible) { LayerScaleRenderer scalePresenter = tiledScaleRenderers.get(scale); if (scalePresenter != null) { if (visible) { visibleScale = scale; if (Dom.isTransformationSupported()) { scalePresenter.getHtmlContainer().applyScale(1, 0, 0); } scalePresenter.getHtmlContainer().setVisible(true); } else if (scale != visibleScale) { scalePresenter.getHtmlContainer().setVisible(false); } } } @Override public void applyScaleTranslation(double scale, Coordinate translation) { LayerScaleRenderer scalePresenter = tiledScaleRenderers.get(scale); if (scalePresenter != null) { scalePresenter.getHtmlContainer().setLeft((int) Math.round(translation.getX())); scalePresenter.getHtmlContainer().setTop((int) Math.round(translation.getY())); } } /** Delegates the cancel to each scale level. */ public void cancel() { for (LayerScaleRenderer scaleRenderer : tiledScaleRenderers.values()) { scaleRenderer.cancel(); } } @Override public LayerScaleRenderer getVisibleScale() { return tiledScaleRenderers.get(visibleScale); } @Override public LayerScaleRenderer getScale(double scale) { return tiledScaleRenderers.get(scale); } @Override public void clear() { while (tiledScaleRenderers.size() > 0) { Double scale = tiledScaleRenderers.keySet().iterator().next(); LayerScaleRenderer removedPresenter = tiledScaleRenderers.get(scale); removedPresenter.cancel(); htmlContainer.remove(removedPresenter.getHtmlContainer()); tiledScaleRenderers.remove(scale); } scales.clear(); } @Override public Layer getLayer() { return layer; } // ------------------------------------------------------------------------ // Private methods: // ------------------------------------------------------------------------ protected LayerScaleRenderer getOrCreate(double scale) { if (tiledScaleRenderers.containsKey(scale)) { return tiledScaleRenderers.get(scale); } final HtmlContainer container = new HtmlGroup(); //container.getElement().setId("scale-" + scale); htmlContainer.insert(container, 0); LayerScaleRenderer scalePresenter = null; if (layer instanceof RasterServerLayer) { scalePresenter = rasterRendererFactory.create(this, viewPort.getCrs(), (RasterServerLayer) layer, container, scale); } else if (layer instanceof VectorServerLayer) { scalePresenter = rasterRendererFactory.create(this, viewPort.getCrs(), (VectorServerLayer) layer, container, scale); } if (scalePresenter != null) { tiledScaleRenderers.put(scale, scalePresenter); } return scalePresenter; } private boolean removeScaleLevel(Double scale) { if (scale != visibleScale) { // Remove the presenter: LayerScaleRenderer removedPresenter = tiledScaleRenderers.get(scale); if (removedPresenter == null) { return false; } removedPresenter.cancel(); htmlContainer.remove(removedPresenter.getHtmlContainer()); tiledScaleRenderers.remove(scale); // Remove the scale: return scales.remove(scale); } return false; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy