1 /*
2  * Copyright (c) 2016 Vivid Solutions.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
8  * and the Eclipse Distribution License is available at
9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12 
13 package org.locationtech.jtstest.testbuilder.ui.render;
14 
15 import java.awt.Color;
16 import java.awt.Graphics2D;
17 
18 import org.locationtech.jts.geom.Geometry;
19 import org.locationtech.jts.geom.GeometryCollection;
20 import org.locationtech.jtstest.testbuilder.model.GeometryContainer;
21 import org.locationtech.jtstest.testbuilder.model.Layer;
22 import org.locationtech.jtstest.testbuilder.ui.Viewport;
23 import org.locationtech.jtstest.testbuilder.ui.style.BasicStyle;
24 import org.locationtech.jtstest.testbuilder.ui.style.LayerStyle;
25 import org.locationtech.jtstest.testbuilder.ui.style.Palette;
26 import org.locationtech.jtstest.testbuilder.ui.style.Style;
27 import org.locationtech.jtstest.util.HSBPalette;
28 
29 
30 public class LayerRenderer implements Renderer
31 {
32   private Layer layer;
33 	private GeometryContainer geomCont;
34 	private Viewport viewport;
35 	private boolean isCancelled = false;
36 
LayerRenderer(Layer layer, Viewport viewport)37 	public LayerRenderer(Layer layer, Viewport viewport)
38 	{
39 		this(layer, layer.getSource(), viewport);
40 	}
41 
LayerRenderer(Layer layer, GeometryContainer geomCont, Viewport viewport)42 	public LayerRenderer(Layer layer, GeometryContainer geomCont, Viewport viewport)
43 	{
44 		this.layer = layer;
45 		this.geomCont = geomCont;
46 		this.viewport = viewport;
47 	}
48 
render(Graphics2D g)49   public void render(Graphics2D g)
50   {
51     if (! layer.isEnabled()) return;
52 
53     try {
54     	Geometry geom = getGeometry();
55       if (geom == null) return;
56 
57       render(g, viewport, geom, layer);
58 
59     } catch (Exception ex) {
60       System.out.println(ex);
61       // not much we can do about it - just carry on
62     }
63   }
64 
getGeometry()65   private Geometry getGeometry()
66   {
67     if (geomCont == null) {
68     	return null;
69     }
70     Geometry geom = geomCont.getGeometry();
71     return geom;
72   }
73 
render(Graphics2D g, Viewport viewport, Geometry geometry, Layer layer)74   private void render(Graphics2D g, Viewport viewport, Geometry geometry, Layer layer)
75   throws Exception
76   {
77     // cull non-visible geometries
78     // for maximum rendering speed this needs to be checked for each component
79     if (! viewport.intersectsInModel(geometry.getEnvelopeInternal()))
80       return;
81     if (Palette.TYPE_BASIC == layer.getLayerStyle().getFillType()) {
82       renderGeom(g, viewport, geometry, layer.getLayerStyle());
83     }
84     else {
85       renderCustomFill(g, viewport, geometry, layer);
86     }
87   }
88 
renderCustomFill(Graphics2D g, Viewport viewport, Geometry gc, Layer layer )89   private void renderCustomFill(Graphics2D g, Viewport viewport,
90       Geometry gc, Layer layer )   throws Exception
91   {
92     int numGeom = gc.getNumGeometries();
93     boolean isLinear = gc.getDimension() == 1;
94     Color clrBase = layer.getGeometryStyle().getFillColor();
95     if (isLinear) {
96       clrBase = layer.getGeometryStyle().getLineColor();
97     }
98 
99     HSBPalette pal = Palette.customPalette(
100         layer.getLayerStyle().getFillType(),
101         clrBase, numGeom);
102     /**
103      * Render each element separately.
104      * Otherwise it is not possible to render both filled and non-filled
105      * (1D) elements correctly.
106      * This also allows varying styling and cancellation.
107      */
108     for (int i = 0; i < numGeom; i++) {
109       if (isCancelled) return;
110       BasicStyle customStyle = layer.getGeometryStyle().copy();
111       if (isLinear) {
112         Color clr = Palette.paletteColor(i, pal, layer.getGeometryStyle().getLineColor());
113         customStyle.setLineColor(clr);
114       }
115       else {
116         Color clr = Palette.paletteColor(i, pal, layer.getGeometryStyle().getFillColor());
117         customStyle.setFillColor(clr);
118       }
119 
120       Style st = new LayerStyle(customStyle, layer.getLayerStyle().getDecoratorStyle());
121       renderGeom(g, viewport, gc.getGeometryN(i), st);
122     }
123   }
124 
renderGeom(Graphics2D g, Viewport viewport, Geometry geometry, Style style)125   private void renderGeom(Graphics2D g, Viewport viewport, Geometry geometry, Style style)
126   throws Exception
127   {
128     if (! viewport.intersectsInModel(geometry.getEnvelopeInternal()))
129       return;
130     if (! (geometry instanceof GeometryCollection)) {
131       style.paint(geometry, viewport, g);
132       return;
133     }
134     for (int i = 0; i < geometry.getNumGeometries(); i++) {
135       if (isCancelled) return;
136       renderGeom(g, viewport, geometry.getGeometryN(i), style);
137     }
138   }
139 
cancel()140   public void cancel()
141 	{
142 		isCancelled = true;
143 	}
144 }
145