source: osm/applications/editors/josm/plugins/smed2/src/seamap/Renderer.java@ 29271

Last change on this file since 29271 was 29271, checked in by malcolmh, 12 years ago

save

File size: 7.2 KB
Line 
1/* Copyright 2013 Malcolm Herring
2 *
3 * This is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License.
6 *
7 * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
8 */
9
10package seamap;
11
12import java.awt.*;
13import java.awt.geom.*;
14import java.util.*;
15
16import s57.S57att.*;
17import s57.S57obj.*;
18import s57.S57val.*;
19import s57.S57val;
20import seamap.SeaMap;
21import seamap.SeaMap.*;
22import seamap.SeaMap.Area;
23import symbols.Symbols;
24import symbols.Symbols.*;
25
26public class Renderer {
27
28 static MapHelper helper;
29 static SeaMap map;
30 static double sScale;
31 static double tScale;
32 static Graphics2D g2;
33 static int zoom;
34
35 public static void reRender(Graphics2D g, int z, double factor, SeaMap m, MapHelper h) {
36 g2 = g;
37 zoom = z;
38 helper = h;
39 map = m;
40 sScale = Symbols.symbolScale[zoom]*factor;
41 tScale = Symbols.textScale[zoom]*factor;
42 if (map != null) {
43 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
44 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
45 Rules.rules(map, zoom);
46 }
47 }
48
49 public static AttMap getAtts(Feature feature, Obj obj, int idx) {
50 HashMap<Integer, AttMap> objs = feature.objs.get(obj);
51 if (objs == null) return null;
52 else return objs.get(idx);
53 }
54
55 public static Object getAttVal(Feature feature, Obj obj, int idx, Att att) {
56 AttMap atts = getAtts(feature, obj, idx);
57 if (atts == null) return S57val.nullVal(att);
58 else {
59 AttItem item = atts.get(att);
60 if (item == null) return S57val.nullVal(att);
61 return item.val;
62 }
63 }
64
65 public static void symbol(Feature feature, Symbol symbol, Obj obj, Delta delta) {
66 Point2D point = helper.getPoint(feature.centre);
67 if (obj == null) {
68 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), delta, null);
69 } else {
70 ArrayList<ColCOL> colours = (ArrayList<ColCOL>) getAttVal(feature, obj, 0, Att.COLOUR);
71 ArrayList<ColPAT> pattern = (ArrayList<ColPAT>) getAttVal(feature, obj, 0, Att.COLPAT);
72 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), delta, new Scheme(pattern, colours));
73 }
74 }
75
76 private static Rectangle symbolSize(Symbol symbol) {
77 Symbol ssymb = symbol;
78 while (ssymb != null) {
79 for (Instr item : symbol) {
80 if (item.type == Prim.BBOX) {
81 return (Rectangle) item.params;
82 }
83 if (item.type == Prim.SYMB) {
84 ssymb = ((SubSymbol)item.params).instr;
85 break;
86 }
87 }
88 if (ssymb == symbol)
89 break;
90 }
91 return null;
92 }
93
94 public static void lineSymbols(Feature feature, Symbol prisymb, double space, Symbol secsymb, int ratio) {
95 Area area;
96 switch (feature.flag) {
97 case LINE:
98 Edge edge = map.edges.get(feature.refs);
99 area = map.new Area();
100 area.add(map.new Bound(map.new Side(edge, true), true));
101 break;
102 case AREA:
103 area = map.areas.get(feature.refs);
104 break;
105 default:
106 return;
107 }
108 Rectangle prect = symbolSize(prisymb);
109 Rectangle srect = symbolSize(secsymb);
110 if (srect == null)
111 ratio = 0;
112 if (prect != null) {
113 double psize = Math.abs(prect.getY()) * sScale;
114 double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
115 Point2D prev = new Point2D.Double();
116 Point2D next = new Point2D.Double();
117 Point2D curr = new Point2D.Double();
118 Point2D succ = new Point2D.Double();
119 boolean gap = true;
120 boolean piv = false;
121 double len = 0;
122 double angle = 0;
123 int scount = ratio;
124 Symbol symbol = prisymb;
125 for (Bound bound : area) {
126 BoundIterator bit = map.new BoundIterator(bound);
127 boolean first = true;
128 while (bit.hasNext()) {
129 prev = next;
130 next = helper.getPoint(bit.next());
131 angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
132 piv = true;
133 if (first) {
134 curr = succ = next;
135 gap = (space > 0);
136 scount = ratio;
137 symbol = prisymb;
138 len = gap ? psize * space * 0.5 : psize;
139 first = false;
140 } else {
141 while (curr.distance(next) >= len) {
142 if (piv) {
143 double rem = len;
144 double s = prev.distance(next);
145 double p = curr.distance(prev);
146 if ((s > 0) && (p > 0)) {
147 double n = curr.distance(next);
148 double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
149 double phi = Math.asin(p / len * Math.sin(theta));
150 rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
151 }
152 succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
153 piv = false;
154 } else {
155 succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
156 }
157 if (!gap) {
158 Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(),
159 new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX()) + Math.toRadians(90)))), null);
160 }
161 if (space > 0) gap = !gap;
162 curr = succ;
163 len = gap ? (psize * space) : (--scount == 0) ? ssize : psize;
164 if (scount == 0) {
165 symbol = secsymb;
166 scount = ratio;
167 } else {
168 symbol = prisymb;
169 }
170 }
171 }
172 }
173 }
174 }
175 }
176
177 public static void lineVector (Feature feature, LineStyle style) {
178 Path2D.Double p = new Path2D.Double();
179 p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
180 Point2D point;
181 switch (feature.flag) {
182 case LINE:
183 EdgeIterator eit = map.new EdgeIterator(map.edges.get(feature.refs), true);
184 point = helper.getPoint(eit.next());
185 p.moveTo(point.getX(), point.getY());
186 while (eit.hasNext()) {
187 point = helper.getPoint(eit.next());
188 p.lineTo(point.getX(), point.getY());
189 }
190 break;
191 case AREA:
192 for (Bound bound : map.areas.get(feature.refs)) {
193 BoundIterator bit = map.new BoundIterator(bound);
194 point = helper.getPoint(bit.next());
195 p.moveTo(point.getX(), point.getY());
196 while (bit.hasNext()) {
197 point = helper.getPoint(bit.next());
198 p.lineTo(point.getX(), point.getY());
199 }
200 }
201 break;
202 }
203 if (style.line != null) {
204 if (style.dash != null) {
205 float[] dash = new float[style.dash.length];
206 System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
207 for (int i = 0; i < style.dash.length; i++) {
208 dash[i] *= (float) sScale;
209 }
210 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
211 } else {
212 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
213 }
214 g2.setPaint(style.line);
215 g2.draw(p);
216 }
217 if (style.fill != null) {
218 g2.setPaint(style.fill);
219 g2.fill(p);
220 }
221 }
222
223 public static void labelText (Feature feature, String str, Font font, Color colour, Delta delta) {
224 Symbol label = new Symbol();
225 label.add(new Instr(Prim.TEXT, new Caption(str, font, colour, (delta == null) ? new Delta(Handle.CC, null) : delta)));
226 Point2D point = helper.getPoint(feature.centre);
227 Symbols.drawSymbol(g2, label, tScale, point.getX(), point.getY(), null, null);
228 }
229
230 public static void lineText (Feature feature, String str, Font font, double offset, double dy) {
231
232 }
233}
Note: See TracBrowser for help on using the repository browser.