package com.revolsys.swing.map.layer.record.renderer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.GeneralPath; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.util.Map; import javax.swing.Icon; import javax.swing.ImageIcon; import com.revolsys.collection.map.MapEx; import com.revolsys.datatype.DataType; import com.revolsys.datatype.DataTypes; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.geometry.model.LineString; import com.revolsys.geometry.model.LinearRing; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.Polygon; 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.swing.map.layer.record.style.GeometryStyle; import com.revolsys.swing.map.layer.record.style.panel.GeometryStylePanel; import com.revolsys.swing.map.layer.record.style.panel.GeometryStylePreview; public class GeometryStyleRenderer extends AbstractRecordLayerRenderer { private static final Icon ICON = Icons.getIcon("style_geometry"); public static GeneralPath getLineShape() { final GeneralPath path = new GeneralPath(); path.moveTo(0, 0); path.lineTo(15, 0); path.lineTo(0, 15); path.lineTo(15, 15); return path; } public static GeneralPath getPolygonShape() { final GeneralPath path = new GeneralPath(); path.moveTo(0, 0); path.lineTo(7, 0); path.lineTo(15, 8); path.lineTo(15, 15); path.lineTo(8, 15); path.lineTo(0, 7); path.lineTo(0, 0); path.closePath(); return path; } public static final void renderGeometry(final Viewport2D viewport, final Graphics2D graphics, final Geometry geometry, final GeometryStyle style) { if (geometry != null) { final BoundingBox viewExtent = viewport.getBoundingBox(); if (!viewExtent.isEmpty()) { final GeometryFactory viewGeometryFactory = viewport.getGeometryFactory2dFloating(); for (int i = 0; i < geometry.getGeometryCount(); i++) { final Geometry part = geometry.getGeometry(i); final BoundingBox partExtent = part.getBoundingBox(); if (partExtent.intersects(viewExtent)) { final Geometry convertedPart = part.convertGeometry(viewGeometryFactory); if (convertedPart instanceof Point) { final Point point = (Point)convertedPart; MarkerStyleRenderer.renderMarker(viewport, graphics, point, style, 0); } else if (convertedPart instanceof LineString) { final LineString lineString = (LineString)convertedPart; renderLineString(viewport, graphics, lineString, style); } else if (convertedPart instanceof Polygon) { final Polygon polygon = (Polygon)convertedPart; renderPolygon(viewport, graphics, polygon, style); } } } } } } public static final void renderGeometryOutline(final Viewport2D viewport, final Graphics2D graphics, final Geometry geometry, final GeometryStyle style) { if (geometry != null) { final BoundingBox viewExtent = viewport.getBoundingBox(); if (!viewExtent.isEmpty()) { final GeometryFactory viewGeometryFactory = viewport.getGeometryFactory2dFloating(); for (int i = 0; i < geometry.getGeometryCount(); i++) { final Geometry part = geometry.getGeometry(i); final BoundingBox partExtent = part.getBoundingBox(); if (partExtent.intersects(viewExtent)) { final Geometry convertedPart = part.convertGeometry(viewGeometryFactory); if (convertedPart instanceof Point) { final Point point = (Point)convertedPart; MarkerStyleRenderer.renderMarker(viewport, graphics, point, style, 0); } else if (convertedPart instanceof LineString) { final LineString lineString = (LineString)convertedPart; renderLineString(viewport, graphics, lineString, style); } else if (convertedPart instanceof Polygon) { final Polygon polygon = (Polygon)convertedPart; for (final LinearRing ring : polygon.rings()) { renderLineString(viewport, graphics, ring, style); } } } } } } } public static final void renderLineString(final Viewport2D viewport, final Graphics2D graphics, LineString line, final GeometryStyle style) { final GeometryFactory viewGeometryFactory = viewport.getGeometryFactory2dFloating(); line = line.convertGeometry(viewGeometryFactory); if (!line.isEmpty()) { final Paint paint = graphics.getPaint(); try { style.setLineStyle(viewport, graphics); graphics.draw(line); } finally { graphics.setPaint(paint); } } } public static final void renderPolygon(final Viewport2D viewport, final Graphics2D graphics, Polygon polygon, final GeometryStyle style) { final GeometryFactory viewGeometryFactory = viewport.getGeometryFactory2dFloating(); polygon = polygon.convertGeometry(viewGeometryFactory, 2); if (!polygon.isEmpty()) { final Paint paint = graphics.getPaint(); try { style.setFillStyle(viewport, graphics); graphics.fill(polygon); style.setLineStyle(viewport, graphics); graphics.draw(polygon); } finally { graphics.setPaint(paint); } } } private GeometryStyle style = new GeometryStyle(); public GeometryStyleRenderer(final AbstractRecordLayer layer) { this(layer, new GeometryStyle()); } public GeometryStyleRenderer(final AbstractRecordLayer layer, final GeometryStyle style) { this(layer, null, style); } public GeometryStyleRenderer(final AbstractRecordLayer layer, final LayerRenderer<?> parent) { super("geometryStyle", "Geometry Style", layer, parent); setIcon(ICON); } public GeometryStyleRenderer(final AbstractRecordLayer layer, final LayerRenderer<?> parent, final GeometryStyle style) { super("geometryStyle", "Geometry Style", layer, parent); setStyle(style); setIcon(ICON); } public GeometryStyleRenderer(final Map<String, ? extends Object> properties) { super("geometryStyle", "Geometry Style"); setIcon(ICON); setProperties(properties); } @Override public GeometryStyleRenderer clone() { final GeometryStyleRenderer clone = (GeometryStyleRenderer)super.clone(); if (this.style != null) { clone.setStyle(this.style.clone()); } return clone; } @Override public Icon getIcon() { Icon icon = super.getIcon(); if (icon == ICON) { icon = newIcon(); setIcon(icon); } return icon; } public GeometryStyle getStyle() { return this.style; } @Override public Icon newIcon() { final AbstractRecordLayer layer = getLayer(); if (layer == null) { return ICON; } else { final GeometryStyle geometryStyle = getStyle(); Shape shape = null; final DataType geometryDataType = layer.getGeometryType(); if (DataTypes.POINT.equals(geometryDataType) || DataTypes.MULTI_POINT.equals(geometryDataType)) { return this.style.getMarker().newIcon(geometryStyle); } else if (DataTypes.LINE_STRING.equals(geometryDataType) || DataTypes.MULTI_LINE_STRING.equals(geometryDataType)) { shape = GeometryStylePreview.getLineShape(16); } else if (DataTypes.POLYGON.equals(geometryDataType) || DataTypes.MULTI_POLYGON.equals(geometryDataType)) { shape = getPolygonShape(); } else { return ICON; } final BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); final Graphics2D graphics = image.createGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (DataTypes.POLYGON.equals(geometryDataType)) { graphics.setPaint(geometryStyle.getPolygonFill()); graphics.fill(shape); } final Color color = geometryStyle.getLineColor(); graphics.setColor(color); graphics.draw(shape); graphics.dispose(); return new ImageIcon(image); } } @Override public GeometryStylePanel newStylePanel() { return new GeometryStylePanel(this); } @Override public void propertyChange(final PropertyChangeEvent event) { final Object source = event.getSource(); if (source == this.style) { refreshIcon(); } super.propertyChange(event); } @Override public void renderRecord(final Viewport2D viewport, final BoundingBox visibleArea, final AbstractLayer layer, final LayerRecord record) { final Geometry geometry = record.getGeometry(); viewport.drawGeometry(geometry, this.style); } @Override public void setProperties(final Map<String, ? extends Object> properties) { super.setProperties(properties); if (this.style != null) { this.style.setProperties(properties); } } public void setStyle(final GeometryStyle style) { if (this.style != null) { this.style.removePropertyChangeListener(this); } this.style = style; if (this.style != null) { this.style.addPropertyChangeListener(this); } firePropertyChange("style", null, style); refreshIcon(); } @Override public MapEx toMap() { final MapEx map = super.toMap(); if (this.style != null) { final Map<String, Object> styleMap = this.style.toMap(); map.putAll(styleMap); } return map; } }