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