1# See: http://wiki.flightgear.org/MapStructure
2# Class things:
3var name = 'GRID';
4var parents = [SymbolLayer.Controller];
5var __self__ = caller(0)[0];
6SymbolLayer.Controller.add(name, __self__);
7SymbolLayer.add(name, {
8	parents: [MultiSymbolLayer],
9	type: name, # Symbol type
10	df_controller: __self__, # controller to use by default -- this one
11	df_options: { # default configuration options
12		granularity_lon: 0.25,
13		granularity_lat: 0.25,
14	}
15});
16var new = func(layer) {
17	var m = {
18		parents: [__self__],
19		layer: layer,
20		map: layer.map,
21		listeners: [],
22		last_lat: -999,
23		last_lon: -999,
24		last_range: -999,
25		last_result: [],
26	};
27	layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead?
28
29	m.addVisibilityListener();
30	return m;
31};
32var del = func() {
33	foreach (var l; me.listeners)
34		removelistener(l);
35};
36
37var searchCmd = func() {
38
39	var lines = [];
40	var delta_lon = me.layer.options.granularity_lon;
41	var delta_lat = me.layer.options.granularity_lat;
42
43	# Find the nearest lat/lon line to the map position.  If we were just displaying
44	# integer lat/lon lines, this would just be rounding.
45	var lat = delta_lat * math.round(me.layer.map.getLat() / delta_lat);
46  var lon = delta_lon * math.round(me.layer.map.getLon() / delta_lon);
47	var range = me.layer.map.getRange();
48
49	# Return early if no significant change in lat/lon/range - implies no additional
50	# grid lines required
51	if ((lat == me.last_lat) and (lon == me.last_lon) and (range == me.last_range)) return me.last_result;
52
53	# Determine number of degrees of lat/lon we need to display based on range
54	# 60nm = 1 degree latitude, degree range for longitude is dependent on latitude.
55	var lon_range = math.ceil(geo.Coord.new(me.layer.map.getPosCoord()).apply_course_distance(90.0, range * globals.NM2M).lon() - lon) * 2;
56	var lat_range = math.ceil(range/60.0) * 2;
57
58	for (var x = (lon - lon_range); x <= (lon + lon_range); x += delta_lon) {
59		var coords = [];
60
61		# We could do a simple line from start to finish, but depending on projection,
62		# the line may not be straight.
63		for (var y = (lat - lat_range); y <= (lat + lat_range); y +=  delta_lat) {
64			append(coords, {lon:x, lat:y});
65		}
66
67		append(lines, {
68			id: x,
69			type: "lon",
70			path: coords,
71			equals: func(o){
72				return (me.id == o.id and me.type == o.type); # We only display one line of each lat/lon
73			}
74		});
75	}
76
77	# Lines of latitude
78	for (var y = (lat - lat_range); y <= (lat + lat_range); y += delta_lat) {
79		var coords = [];
80
81		# We could do a simple line from start to finish, but depending on projection,
82		# the line may not be straight.
83		for (var x = (lon - lon_range); x <= (lon + lon_range); x += delta_lon) {
84			append(coords, {lon:x, lat:y});
85		}
86
87		append(lines, {
88			id: y,
89			type: "lat",
90			path: coords,
91			equals: func(o){
92				return (me.id == o.id and me.type == o.type); # We only display one line of each lat/lon
93			}
94		});
95	}
96
97	me.last_lat = lat;
98	me.last_lon = lon;
99	me.last_range = range;
100	me.last_result = lines;
101
102	return lines;
103};
104