package com.revolsys.swing.map.layer.record.style.marker;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.Map;
import javax.measure.Measure;
import javax.measure.quantity.Length;
import javax.swing.Icon;
import org.apache.batik.transcoder.TranscoderInput;
import org.w3c.dom.Document;
import com.revolsys.awt.CloseableAffineTransform;
import com.revolsys.io.BaseCloseable;
import com.revolsys.logging.Logs;
import com.revolsys.spring.resource.ClassPathResource;
import com.revolsys.spring.resource.Resource;
import com.revolsys.swing.map.Viewport2D;
import com.revolsys.swing.map.layer.record.style.MarkerStyle;
import com.revolsys.swing.map.symbol.Symbol;
import com.revolsys.swing.map.symbol.SymbolLibrary;
public class SvgMarker extends AbstractMarker {
private Icon icon;
private Document document;
private TranscoderInput transcoderInput;
private Symbol symbol;
public SvgMarker() {
}
// protected void changeAttribute(final SVGElement element, final String
// attrName,
// final String oldValue, final String value) throws SVGException {
// if (element.hasAttribute(attrName, AnimationElement.AT_CSS)) {
// final StyleAttribute style = new StyleAttribute(attrName);
// if (element.getStyle(style, false)) {
// final String currentValue = style.getStringValue();
// if (currentValue.equalsIgnoreCase(oldValue)) {
// element.setAttribute(attrName, AnimationElement.AT_CSS, value);
// }
// }
// }
// for (int i = 0; i < element.getNumChildren(); i++) {
// final SVGElement child = element.getChild(i);
// changeAttribute(child, attrName, oldValue, value);
// }
// }
public SvgMarker(final Map<String, Object> properties) {
setProperties(properties);
}
public SvgMarker(final String markerType) {
super(markerType);
}
@Override
public boolean isUseMarkerType() {
return true;
}
@Override
public Icon newIcon(final MarkerStyle style) {
return this.icon;
}
@Override
protected void postSetMarkerType() {
final String markerType = getMarkerType();
this.symbol = SymbolLibrary.findSymbol(markerType);
final Resource resource = new ClassPathResource(markerType + ".svg");
try {
final String uri = resource.getUriString();
this.document = SvgUtil.newDocument(uri);
this.transcoderInput = new TranscoderInput(this.document);
this.transcoderInput.setURI(uri);
this.icon = new SvgIcon(this.document, 16, 16);
} catch (final Throwable e) {
this.document = null;
Logs.error(this, "Cannot open :" + resource, e);
}
}
@Override
public void render(final Viewport2D viewport, final Graphics2D graphics, final MarkerStyle style,
final double modelX, final double modelY, double orientation) {
final TranscoderInput transcoderInput = this.transcoderInput;
if (transcoderInput != null) {
try (
BaseCloseable transformCloseable = new CloseableAffineTransform(graphics)) {
Viewport2D.setUseModelCoordinates(viewport, graphics, false);
final Measure<Length> markerWidth = style.getMarkerWidth();
final double mapWidth = Viewport2D.toDisplayValue(viewport, markerWidth);
final Measure<Length> markerHeight = style.getMarkerHeight();
final double mapHeight = Viewport2D.toDisplayValue(viewport, markerHeight);
final String orientationType = style.getMarkerOrientationType();
if ("none".equals(orientationType)) {
orientation = 0;
}
Viewport2D.translateModelToViewCoordinates(viewport, graphics, modelX, modelY);
final double markerOrientation = style.getMarkerOrientation();
orientation = orientation + markerOrientation;
if (orientation != 0) {
graphics.rotate(Math.toRadians(orientation));
}
final Measure<Length> deltaX = style.getMarkerDx();
final Measure<Length> deltaY = style.getMarkerDy();
double dx = Viewport2D.toDisplayValue(viewport, deltaX);
double dy = Viewport2D.toDisplayValue(viewport, deltaY);
final String verticalAlignment = style.getMarkerVerticalAlignment();
if ("bottom".equals(verticalAlignment)) {
dy -= mapHeight;
} else if ("middle".equals(verticalAlignment)) {
dy -= mapHeight / 2;
}
final String horizontalAlignment = style.getMarkerHorizontalAlignment();
if ("right".equals(horizontalAlignment)) {
dx -= mapWidth;
} else if ("center".equals(horizontalAlignment)) {
dx -= mapWidth / 2;
}
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics.translate(dx, dy);
// changeAttribute(root, "stroke", "#ffffff",
// WebColors.toHex(style.getMarkerLineColor()));
// changeAttribute(root, "color", "#ffffff",
// WebColors.toHex(style.getMarkerLineColor()));
// changeAttribute(root, "fill", "#ffffff",
// WebColors.toHex(style.getMarkerLineColor()));
//
// changeAttribute(root, "stroke", "#000000",
// WebColors.toHex(style.getMarkerFill()));
// changeAttribute(root, "color", "#000000",
// WebColors.toHex(style.getMarkerFill()));
// changeAttribute(root, "fill", "#000000",
// WebColors.toHex(style.getMarkerFill()));
// changeAttribute(root, "stroke", "#444444",
// WebColors.toHex(style.getMarkerFill()));
// changeAttribute(root, "color", "#444444",
// WebColors.toHex(style.getMarkerFill()));
// changeAttribute(root, "fill", "#444444",
// WebColors.toHex(style.getMarkerFill()));
// shape.render(graphics);
final Graphics2DTranscoder transcoder = new Graphics2DTranscoder(graphics);
synchronized (transcoderInput) {
transcoder.transcode(transcoderInput, null);
}
} catch (final Throwable e) {
Logs.error(this, "Unable to render", e);
}
}
}
@Override
public String toString() {
if (this.symbol == null) {
return super.toString();
} else {
return this.symbol.getTitle();
}
}
}