package com.revolsys.swing.map.layer.record.renderer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.Icon;
import com.revolsys.collection.map.Maps;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.TopologyException;
import com.revolsys.logging.Logs;
import com.revolsys.swing.Icons;
import com.revolsys.swing.map.Viewport2D;
import com.revolsys.swing.map.layer.AbstractLayer;
import com.revolsys.swing.map.layer.LayerRenderer;
import com.revolsys.swing.map.layer.record.AbstractRecordLayer;
import com.revolsys.swing.map.layer.record.LayerRecord;
import com.revolsys.util.Cancellable;
/**
* For each object render using the first renderer that matches the filter.
*/
public class FilterMultipleRenderer extends AbstractMultipleRenderer {
private static final Icon ICON = Icons.getIcon("style_filter");
public FilterMultipleRenderer(final AbstractRecordLayer layer) {
this(layer, null);
}
public FilterMultipleRenderer(final AbstractRecordLayer layer, final LayerRenderer<?> parent) {
super("filterStyle", layer, parent);
setIcon(ICON);
}
public FilterMultipleRenderer(final Map<String, ? extends Object> properties) {
super("filterStyle", "Filter Styles");
setIcon(ICON);
setProperties(properties);
}
protected AbstractRecordLayerRenderer getRenderer(final AbstractRecordLayer layer,
final List<AbstractRecordLayerRenderer> renderers, final LayerRecord record,
final double scaleForVisible) {
for (final AbstractRecordLayerRenderer renderer : renderers) {
if (renderer.isFilterAccept(record)) {
if (renderer.isVisible(record) && !layer.isHidden(record)) {
if (renderer.isVisible(scaleForVisible)) {
return renderer;
}
}
return null;
}
}
return null;
}
@Override
public void renderRecord(final Viewport2D viewport, final BoundingBox visibleArea,
final AbstractLayer layer, final LayerRecord record) {
}
@Override
protected void renderRecords(final Viewport2D viewport, final Cancellable cancellable,
final AbstractRecordLayer layer, final List<LayerRecord> records) {
final Map<AbstractRecordLayerRenderer, List<LayerRecord>> rendererToRecordMap = new LinkedHashMap<>();
final BoundingBox visibleArea = viewport.getBoundingBox();
final double scaleForVisible = viewport.getScaleForVisible();
if (isVisible(scaleForVisible)) {
final List<AbstractRecordLayerRenderer> renderers = new ArrayList<>(getRenderers());
for (final AbstractRecordLayerRenderer renderer : renderers) {
rendererToRecordMap.put(renderer, new ArrayList<>());
}
for (final LayerRecord record : cancellable.cancellable(records)) {
if (isFilterAccept(record) && !layer.isHidden(record)) {
final AbstractRecordLayerRenderer renderer = getRenderer(layer, renderers, record,
scaleForVisible);
if (renderer != null) {
Maps.addToList(rendererToRecordMap, renderer, record);
}
}
}
for (final Entry<AbstractRecordLayerRenderer, List<LayerRecord>> entry : cancellable
.cancellable(rendererToRecordMap.entrySet())) {
final AbstractRecordLayerRenderer renderer = entry.getKey();
final List<LayerRecord> rendererRecords = entry.getValue();
for (final LayerRecord record : cancellable.cancellable(rendererRecords)) {
try {
renderer.renderRecord(viewport, visibleArea, layer, record);
} catch (final TopologyException e) {
} catch (final Throwable e) {
if (!cancellable.isCancelled()) {
Logs.error(this,
"Unabled to render " + layer.getName() + " #" + record.getIdentifier(), e);
}
}
}
}
}
}
@Override
public void renderSelectedRecord(final Viewport2D viewport, final AbstractLayer layer,
final LayerRecord record) {
if (isVisible(record)) {
final double scaleForVisible = viewport.getScaleForVisible();
for (final AbstractRecordLayerRenderer renderer : getRenderers()) {
if (renderer.isFilterAccept(record)) {
if (renderer.isVisible(record)) {
if (renderer.isVisible(scaleForVisible)) {
try {
renderer.renderSelectedRecord(viewport, layer, record);
} catch (final Throwable e) {
Logs.error(this,
"Unabled to render " + layer.getName() + " #" + record.getIdentifier(), e);
}
}
}
// Only render using the first match
return;
}
}
}
}
}