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

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

save

File size: 9.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.BasicStroke;
13import java.awt.Color;
14import java.awt.Font;
15import java.awt.Graphics2D;
16import java.awt.Rectangle;
17import java.awt.RenderingHints;
18import java.awt.geom.AffineTransform;
19import java.awt.geom.GeneralPath;
20import java.awt.geom.Path2D;
21import java.awt.geom.Point2D;
22import java.util.ArrayList;
23import java.util.HashMap;
24
25import s57.S57att.Att;
26import s57.S57obj.Obj;
27import s57.S57val.*;
28import s57.S57val;
29import seamap.SeaMap;
30import seamap.SeaMap.*;
31import symbols.Symbols;
32import symbols.Symbols.*;
33
34public class Renderer {
35
36 static MapHelper helper;
37 static SeaMap map;
38 static double sScale;
39 static double tScale;
40 static Graphics2D g2;
41 static int zoom;
42
43 public static void reRender(Graphics2D g, int z, double factor, SeaMap m, MapHelper h) {
44 g2 = g;
45 zoom = z;
46 helper = h;
47 map = m;
48 sScale = Symbols.symbolScale[zoom]*factor;
49 tScale = Symbols.textScale[zoom]*factor;
50 if (map != null) {
51 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
52 g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
53 Rules.rules(map, zoom);
54 }
55 }
56
57 public static AttMap getAtts(Feature feature, Obj obj, int idx) {
58 HashMap<Integer, AttMap> objs = feature.objs.get(obj);
59 if (objs == null) return null;
60 else return objs.get(idx);
61 }
62
63 public static Object getAttVal(Feature feature, Obj obj, int idx, Att att) {
64 AttMap atts = getAtts(feature, obj, idx);
65 if (atts == null) return S57val.nullVal(att);
66 else {
67 AttItem item = atts.get(att);
68 if (item == null) return S57val.nullVal(att);
69 return item.val;
70 }
71 }
72
73 public static double calcArea(Feature feature) {
74 if (feature.flag == Fflag.AREA) {
75 ArrayList<Long> way;
76 if (map.mpolys.containsKey(feature.refs)) {
77 way = map.ways.get(map.mpolys.get(feature.refs));
78 } else {
79 way = map.ways.get(feature.refs);
80 }
81 Coord coord = map.nodes.get(way.get(0));
82 double llon = coord.lon;
83 double llat = coord.lat;
84 double sigma = 0.0;
85 for (long node : way) {
86 coord = map.nodes.get(node);
87 double lat = coord.lat;
88 double lon = coord.lon;
89 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
90 llon = lon;
91 llat = lat;
92 }
93 return Math.abs(sigma) * 3444 * 3444 / 2.0;
94 }
95 return 0.0;
96 }
97
98 public static Coord findCentroid(Feature feature) {
99 Coord coord;
100 ArrayList<Long> way;
101 if (map.mpolys.containsKey(feature.refs)) {
102 way = map.ways.get(map.mpolys.get(feature.refs).get(0));
103 } else {
104 way = map.ways.get(feature.refs);
105 }
106 switch (feature.flag) {
107 case NODE:
108 return map.nodes.get(feature.refs);
109 case LINE:
110 coord = map.nodes.get(way.get(1));
111 break;
112 case AREA:
113 default:
114 coord = map.nodes.get(way.get(0));
115 }
116 double slat = 0.0;
117 double slon = 0.0;
118 double sarc = 0.0;
119 double llat = coord.lat;
120 double llon = coord.lon;
121 for (long node : way) {
122 coord = map.nodes.get(node);
123 double lon = coord.lon;
124 double lat = coord.lat;
125 double arc = (Math.acos(Math.cos(lon-llon) * Math.cos(lat-llat)));
126 slat += (lat * arc);
127 slon += (lon * arc);
128 sarc += arc;
129 llat = lat;
130 llon = lon;
131 }
132 return map.new Coord((sarc > 0.0 ? slat/sarc : 0.0), (sarc > 0.0 ? slon/sarc : 0.0));
133 }
134
135 public static void symbol(Feature feature, Symbol symbol, Obj obj, Delta delta) {
136 Point2D point = helper.getPoint(findCentroid(feature));
137 if (obj == null) {
138 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), delta, null);
139 } else {
140 ArrayList<ColCOL> colours = (ArrayList<ColCOL>) getAttVal(feature, obj, 0, Att.COLOUR);
141 ArrayList<ColPAT> pattern = (ArrayList<ColPAT>) getAttVal(feature, obj, 0, Att.COLPAT);
142 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), delta, new Scheme(pattern, colours));
143 }
144 }
145
146 private static Rectangle symbolSize(Symbol symbol) {
147 Symbol ssymb = symbol;
148 while (ssymb != null) {
149 for (Instr item : symbol) {
150 if (item.type == Prim.BBOX) {
151 return (Rectangle) item.params;
152 }
153 if (item.type == Prim.SYMB) {
154 ssymb = ((SubSymbol)item.params).instr;
155 break;
156 }
157 }
158 if (ssymb == symbol)
159 break;
160 }
161 return null;
162 }
163
164 public static void lineSymbols(Feature feature, Symbol prisymb, double space, Symbol secsymb, int ratio) {
165 if (feature.flag != Fflag.NODE) {
166 Rectangle prect = symbolSize(prisymb);
167 Rectangle srect = symbolSize(secsymb);
168 if (srect == null)
169 ratio = 0;
170 if (prect != null) {
171 ArrayList<Long> ways = new ArrayList<Long>();
172 double psize = Math.abs(prect.getY()) * sScale;
173 double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
174 if (map.outers.containsKey(feature.refs)) {
175 ways.addAll(map.mpolys.get(map.outers.get(feature.refs)));
176 } else {
177 if (map.mpolys.containsKey(feature.refs)) {
178 ways.addAll(map.mpolys.get(feature.refs));
179 } else {
180 ways.add(feature.refs);
181 }
182 }
183 Point2D prev = new Point2D.Double();
184 Point2D next = new Point2D.Double();
185 Point2D curr = new Point2D.Double();
186 Point2D succ = new Point2D.Double();
187 boolean gap = true;
188 boolean piv = false;
189 double len = 0;
190 double angle = 0;
191 int scount = ratio;
192 Symbol symbol = prisymb;
193 for (long way : ways) {
194 boolean first = true;
195 for (long node : map.ways.get(way)) {
196 prev = next;
197 next = helper.getPoint(map.nodes.get(node));
198 angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
199 piv = true;
200 if (first) {
201 curr = succ = next;
202 gap = (space > 0);
203 scount = ratio;
204 symbol = prisymb;
205 len = gap ? psize * space * 0.5 : psize;
206 first = false;
207 } else {
208 while (curr.distance(next) >= len) {
209 if (piv) {
210 double rem = len;
211 double s = prev.distance(next);
212 double p = curr.distance(prev);
213 if ((s > 0) && (p > 0)) {
214 double n = curr.distance(next);
215 double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
216 double phi = Math.asin(p / len * Math.sin(theta));
217 rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
218 }
219 succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
220 piv = false;
221 } else {
222 succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
223 }
224 if (!gap) {
225 Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(),
226 new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX()) + Math.toRadians(90)))), null);
227 }
228 if (space > 0) gap = !gap;
229 curr = succ;
230 len = gap ? (psize * space) : (--scount == 0) ? ssize : psize;
231 if (scount == 0) {
232 symbol = secsymb;
233 scount = ratio;
234 } else {
235 symbol = prisymb;
236 }
237 }
238 }
239 }
240 }
241 }
242 }
243 }
244
245 public static void lineVector (Feature feature, LineStyle style) {
246 if (feature.flag != Fflag.NODE) {
247 ArrayList<Long> ways = new ArrayList<Long>();
248 if (map.outers.containsKey(feature.refs)) {
249 ways.addAll(map.mpolys.get(map.outers.get(feature.refs)));
250 } else {
251 if (map.mpolys.containsKey(feature.refs)) {
252 ways.addAll(map.mpolys.get(feature.refs));
253 } else {
254 ways.add(feature.refs);
255 }
256 }
257 Path2D.Double p = new Path2D.Double();
258 p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
259 for (long way : ways) {
260 boolean first = true;
261 for (long node : map.ways.get(way)) {
262 Point2D point = helper.getPoint(map.nodes.get(node));
263 if (first) {
264 p.moveTo(point.getX(), point.getY());
265 first = false;
266 } else {
267 p.lineTo(point.getX(), point.getY());
268 }
269 }
270 }
271 if (style.line != null) {
272 if (style.dash != null) {
273 float[] dash = new float[style.dash.length];
274 System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
275 for (int i = 0; i < style.dash.length; i++) {
276 dash[i] *= (float) sScale;
277 }
278 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
279 } else {
280 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
281 }
282 g2.setPaint(style.line);
283 g2.draw(p);
284 }
285 if (style.fill != null) {
286 g2.setPaint(style.fill);
287 g2.fill(p);
288 }
289 }
290 }
291
292 public static void labelText (Feature feature, String str, Font font, Color colour, Delta delta) {
293 Symbol label = new Symbol();
294 label.add(new Instr(Prim.TEXT, new Caption(str, font, colour, (delta == null) ? new Delta(Handle.CC, null) : delta)));
295 Point2D point = helper.getPoint(findCentroid(feature));
296 Symbols.drawSymbol(g2, label, tScale, point.getX(), point.getY(), null, null);
297 }
298
299 public static void lineText (Feature feature, String str, Font font, double offset, double dy) {
300
301 }
302}
Note: See TracBrowser for help on using the repository browser.