Airbus style for MapStructure/navdisplay
105
Nasal/canvas/MapDrivers.nas
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
var RouteDriver = {
|
||||||
|
new: func(){
|
||||||
|
var m = {
|
||||||
|
parents: [RouteDriver],
|
||||||
|
};
|
||||||
|
m.init();
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
init: func(){
|
||||||
|
me.update();
|
||||||
|
},
|
||||||
|
update: func(){
|
||||||
|
me.flightplan = flightplan();
|
||||||
|
},
|
||||||
|
getNumberOfFlightPlans: func(){1},
|
||||||
|
getFlightPlanType: func(fpNum){'current'},
|
||||||
|
getFlightPlan: func(fpNum){me.flightplan},
|
||||||
|
getPlanSize: func(fpNum){me.flightplan.getPlanSize()},
|
||||||
|
getWP: func(fpNum, idx){me.flightplan.getWP(idx)},
|
||||||
|
getPlanModeWP: func(plan_wp_idx){me.flightplan.getWP(plan_wp_idx)},
|
||||||
|
hasDiscontinuity: func(fpNum, wptID){0},
|
||||||
|
getListeners: func(){[]},
|
||||||
|
shouldUpdate: func 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var MultiRouteDriver = {
|
||||||
|
parents: [RouteDriver],
|
||||||
|
new: func(){
|
||||||
|
var m = {
|
||||||
|
parents: [MultiRouteDriver],
|
||||||
|
_flightplans: [],
|
||||||
|
currentFlightPlan: 0
|
||||||
|
};
|
||||||
|
m.init();
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
addFlightPlan: func(type, plan){
|
||||||
|
append(me._flightplans, {
|
||||||
|
type: type,
|
||||||
|
flightplan: plan
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeFlightPlanAtIndex: func(idx){
|
||||||
|
var sz = size(me._flightplans);
|
||||||
|
if(idx < sz){
|
||||||
|
if(sz == 1)
|
||||||
|
me._flightplans = [];
|
||||||
|
elsif(sz == 2 and idx == 0)
|
||||||
|
me._flightplans = [me._flightplans[1]];
|
||||||
|
elsif(sz == 2 and idx == 1)
|
||||||
|
pop(me._flightplans);
|
||||||
|
else {
|
||||||
|
var subv_l = subvec(me._flightplans, 0, idx);
|
||||||
|
var subv_r = subvec(me._flightplans, idx + 1);
|
||||||
|
me._flightplans = subv_l ~ subv_r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
me.triggerSignal('fp-added');
|
||||||
|
},
|
||||||
|
removeFlightPlanOfType: func(type){
|
||||||
|
var new_vec = [];
|
||||||
|
foreach(var fp; me._flightplans){
|
||||||
|
if(fp['type'] != type)
|
||||||
|
append(new_vec, fp);
|
||||||
|
}
|
||||||
|
me._flightplans = new_vec;
|
||||||
|
me.triggerSignal('fp-removed');
|
||||||
|
},
|
||||||
|
getNumberOfFlightPlans: func(){
|
||||||
|
size(me._flightplans);
|
||||||
|
},
|
||||||
|
getFlightPlanType: func(fpNum){
|
||||||
|
if(fpNum >= size(me._flightplans)) return nil;
|
||||||
|
var fp = me._flightplans[fpNum];
|
||||||
|
return fp.type;
|
||||||
|
},
|
||||||
|
getFlightPlan: func(fpNum){
|
||||||
|
if(fpNum >= size(me._flightplans)) return nil;
|
||||||
|
return me._flightplans[fpNum];
|
||||||
|
},
|
||||||
|
getPlanSize: func(fpNum){
|
||||||
|
if(fpNum >= size(me._flightplans)) return 0;
|
||||||
|
return me._flightplans[fpNum].getPlanSize();
|
||||||
|
},
|
||||||
|
getWP: func(fpNum, idx){
|
||||||
|
if(fpNum >= size(me._flightplans)) return nil;
|
||||||
|
var fp = me._flightplans[fpNum].getPlanSize();
|
||||||
|
return fp.getWP(idx);
|
||||||
|
},
|
||||||
|
getPlanModeWP: func(idx){
|
||||||
|
if(me.currentFlightPlan >= size(me._flightplans)) return nil;
|
||||||
|
var fp = me._flightplans[me.currentFlightPlan];
|
||||||
|
return fp.getWP(idx);
|
||||||
|
},
|
||||||
|
triggerSignal: func(signal){
|
||||||
|
setprop(me.signalPath(signal));
|
||||||
|
},
|
||||||
|
signalPath: func(signal){
|
||||||
|
'autopilot/route-manager/signals/rd-'~ signal;
|
||||||
|
},
|
||||||
|
getListeners: func(){[
|
||||||
|
me.getSignal('fp-added'),
|
||||||
|
me.getSignal('fp-removed')
|
||||||
|
]}
|
||||||
|
};
|
|
@ -261,6 +261,17 @@ var hashdup = func(_,rkeys=nil) {
|
||||||
var h={}; var k=rkeys!=nil?rkeys:members(_);
|
var h={}; var k=rkeys!=nil?rkeys:members(_);
|
||||||
foreach (var k;k) h[tryintern(k)]=member(_,k); h
|
foreach (var k;k) h[tryintern(k)]=member(_,k); h
|
||||||
}
|
}
|
||||||
|
var opt_member = func(h,k) {
|
||||||
|
if (contains(h, k)) return h[k];
|
||||||
|
if (contains(h, "parents")) {
|
||||||
|
var _=h.parents;
|
||||||
|
for (var i=0;i<size(_);i+=1){
|
||||||
|
var v = opt_member(_[i], k);
|
||||||
|
if (v != nil) return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
var member = func(h,k) {
|
var member = func(h,k) {
|
||||||
if (contains(h, k)) return h[k];
|
if (contains(h, k)) return h[k];
|
||||||
if (contains(h, "parents")) {
|
if (contains(h, "parents")) {
|
||||||
|
@ -434,6 +445,118 @@ var Symbol = {
|
||||||
t.setColor(color);
|
t.setColor(color);
|
||||||
return t;
|
return t;
|
||||||
},
|
},
|
||||||
|
# Helper method that can be used to create a formatted String using
|
||||||
|
# values extracted from the current model.
|
||||||
|
#
|
||||||
|
# SYNOPSIS:
|
||||||
|
#
|
||||||
|
# symbol.formattedString(format, model_property_names)
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# - format: string
|
||||||
|
# - model_property_names: a vector of strings representing the model
|
||||||
|
# property names to be used as arguments
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
#
|
||||||
|
# var label = waypoint.formattedString('Waypoint %s: lat %.4f, lng %.4f', [model.id, model.lat, model.lon]);
|
||||||
|
formattedString: func(frmt, model_props){
|
||||||
|
if(me.model == nil) return frmt;
|
||||||
|
var args = [];
|
||||||
|
foreach(var prop; model_props){
|
||||||
|
if(contains(me.model, prop)){
|
||||||
|
var val = me.model[prop];
|
||||||
|
var tp = typeof(val);
|
||||||
|
if(tp != 'scalar'){
|
||||||
|
val = '';
|
||||||
|
#printlog("warn", "formattedString: invalid type for "~prop~" (" ~ tp ~ ")");
|
||||||
|
} else {
|
||||||
|
append(args, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return call(sprintf, [frmt] ~ args);
|
||||||
|
},
|
||||||
|
|
||||||
|
# Wrapper method for accessing options. It allows to pass a default value
|
||||||
|
# if the requested option is not defined.
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
# var ok = (contains(me.options, 'enabled') ? me.options.enabled : 0);
|
||||||
|
# var ok = me.getOption('enabled', 0);
|
||||||
|
getOption: func(name, default = nil){
|
||||||
|
var opt = me.options;
|
||||||
|
if(opt == nil)
|
||||||
|
opt = me.layer.options;
|
||||||
|
if(opt == nil) return default;
|
||||||
|
var val = opt_member(opt, name);
|
||||||
|
if(val == nil) return default;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
# Wrapper method for accessing style. It allows to pass a default value
|
||||||
|
# if the requested style is not defined.
|
||||||
|
# It also automatically resolves style properties when they're defined as
|
||||||
|
# functions, by calling the corresponding function using the 'me' context
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
#
|
||||||
|
# me.style = {
|
||||||
|
# color: [1,1,1],
|
||||||
|
# line_color: func(){
|
||||||
|
# me.model.tuned ? [0,0,1] : [1,1,1]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# var color = me.getStyle('color'); # --> [1,1,1]
|
||||||
|
# me.model.tuned = 1;
|
||||||
|
# var line_color = me.getStyle('line_color'); # --> [0,0,1]
|
||||||
|
# var txt_color = me.getStyle('text_color', [1,1,1]); # --> [1,1,1]
|
||||||
|
getStyle: func(name, default = nil){
|
||||||
|
var st = me.style;
|
||||||
|
if(st == nil)
|
||||||
|
st = me.layer.style;
|
||||||
|
if(st == nil) return default;
|
||||||
|
var val = opt_member(st, name);
|
||||||
|
if(typeof(val) == 'func'){
|
||||||
|
val = (call(val,[],me));
|
||||||
|
}
|
||||||
|
if(val == nil) return default;
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
getLabelFromModel: func(default_val = nil){
|
||||||
|
if(me.model == nil) return default_val;
|
||||||
|
if(default_val == nil and contains(me.model, 'id'))
|
||||||
|
default_val = me.model.id;
|
||||||
|
var label_content = me.getOption('label_content');
|
||||||
|
if(label_content == nil) return default_val;
|
||||||
|
if(typeof(label_content) == 'scalar')
|
||||||
|
label_content = [label_content];
|
||||||
|
var format_s = me.getOption('label_format');
|
||||||
|
var label = '';
|
||||||
|
if(format_s == nil){
|
||||||
|
format_s = "%s";
|
||||||
|
}
|
||||||
|
return me.formattedString(format_s, label_content);
|
||||||
|
},
|
||||||
|
# Executes callback function specified by the first argument with
|
||||||
|
# variable arguments. The callback is executed within the 'me' context.
|
||||||
|
# Callbacks must be defined inside the options hash.
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
#
|
||||||
|
# me.options = {
|
||||||
|
# dump_callback: func(){
|
||||||
|
# print('Waypoint '~ me.model.id);
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# me.callback('dump');
|
||||||
|
callback: func(name, args...){
|
||||||
|
name = name ~'_callback';
|
||||||
|
var f = me.getOption(name);
|
||||||
|
if(typeof(f) == 'func'){
|
||||||
|
return call(f, args, me);
|
||||||
|
}
|
||||||
|
}
|
||||||
}; # of Symbol
|
}; # of Symbol
|
||||||
|
|
||||||
|
|
||||||
|
@ -611,6 +734,7 @@ var DotSym = {
|
||||||
} else
|
} else
|
||||||
me.element.show();
|
me.element.show();
|
||||||
me.draw();
|
me.draw();
|
||||||
|
if(me.getOption('disable_position', 0)) return;
|
||||||
var pos = me.controller.getpos(me.model);
|
var pos = me.controller.getpos(me.model);
|
||||||
if (size(pos) == 2)
|
if (size(pos) == 2)
|
||||||
pos~=[nil]; # fall through
|
pos~=[nil]; # fall through
|
||||||
|
@ -632,17 +756,27 @@ var SVGSymbol = {
|
||||||
element_type: "group",
|
element_type: "group",
|
||||||
cacheable: 0,
|
cacheable: 0,
|
||||||
init: func() {
|
init: func() {
|
||||||
|
me.callback('init_before');
|
||||||
|
var opt_path = me.getStyle('svg_path');
|
||||||
|
if(opt_path != nil)
|
||||||
|
me.svg_path = opt_path;
|
||||||
if (!me.cacheable) {
|
if (!me.cacheable) {
|
||||||
canvas.parsesvg(me.element, me.svg_path);
|
if(me.svg_path != nil and me.svg_path != '')
|
||||||
|
canvas.parsesvg(me.element, me.svg_path);
|
||||||
# hack:
|
# hack:
|
||||||
if (var scale = me.layer.style['scale_factor'])
|
if (var scale = me.layer.style['scale_factor'])
|
||||||
me.element.setScale(scale);
|
me.element.setScale(scale);
|
||||||
|
if ((var transl = me.layer.style['translate']) != nil)
|
||||||
|
me.element.setTranslation(transl);
|
||||||
} else {
|
} else {
|
||||||
__die("cacheable not implemented yet!");
|
__die("cacheable not implemented yet!");
|
||||||
}
|
}
|
||||||
|
me.callback('init_after');
|
||||||
me.draw();
|
me.draw();
|
||||||
},
|
},
|
||||||
draw: func,
|
draw: func{
|
||||||
|
me.callback('draw');
|
||||||
|
},
|
||||||
}; # of SVGSymbol
|
}; # of SVGSymbol
|
||||||
|
|
||||||
|
|
||||||
|
@ -685,7 +819,13 @@ var LineSymbol = {
|
||||||
# For the instances returned from makeinstance:
|
# For the instances returned from makeinstance:
|
||||||
new: func(group, layer, model, controller=nil) {
|
new: func(group, layer, model, controller=nil) {
|
||||||
if (me == nil) __die("Need me reference for LineSymbol.new()");
|
if (me == nil) __die("Need me reference for LineSymbol.new()");
|
||||||
if (typeof(model) != 'vector') __die("LineSymbol.new(): need a vector of points");
|
if (typeof(model) != 'vector') {
|
||||||
|
if(typeof(model) == 'hash'){
|
||||||
|
if(!contains(model, 'path'))
|
||||||
|
__die("LineSymbol.new(): model hash requires path");
|
||||||
|
}
|
||||||
|
else __die("LineSymbol.new(): need a vector of points or a hash");
|
||||||
|
}
|
||||||
var m = {
|
var m = {
|
||||||
parents: [me],
|
parents: [me],
|
||||||
group: group,
|
group: group,
|
||||||
|
@ -705,19 +845,32 @@ var LineSymbol = {
|
||||||
# Non-static:
|
# Non-static:
|
||||||
draw: func() {
|
draw: func() {
|
||||||
if (!me.needs_update) return;
|
if (!me.needs_update) return;
|
||||||
|
me.callback('draw_before');
|
||||||
printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type);
|
printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type);
|
||||||
me.element.reset();
|
me.element.reset();
|
||||||
var cmds = [];
|
var cmds = [];
|
||||||
var coords = [];
|
var coords = [];
|
||||||
var cmd = canvas.Path.VG_MOVE_TO;
|
var cmd = canvas.Path.VG_MOVE_TO;
|
||||||
foreach (var m; me.model) {
|
var path = me.model;
|
||||||
var (lat,lon) = me.controller.getpos(m);
|
if(typeof(path) == 'hash'){
|
||||||
append(coords,"N"~lat);
|
path = me.model.path;
|
||||||
append(coords,"E"~lon);
|
if(path == nil)
|
||||||
append(cmds,cmd); cmd = canvas.Path.VG_LINE_TO;
|
__die("LineSymbol model requires a 'path' member (vector)");
|
||||||
|
}
|
||||||
|
foreach (var m; path) {
|
||||||
|
if(size(keys(m)) >= 2){
|
||||||
|
var (lat,lon) = me.controller.getpos(m);
|
||||||
|
append(coords,"N"~lat);
|
||||||
|
append(coords,"E"~lon);
|
||||||
|
append(cmds,cmd);
|
||||||
|
cmd = canvas.Path.VG_LINE_TO;
|
||||||
|
} else {
|
||||||
|
cmd = canvas.Path.VG_MOVE_TO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
me.element.setDataGeo(cmds, coords);
|
me.element.setDataGeo(cmds, coords);
|
||||||
me.element.update(); # this doesn't help with flickering, it seems
|
me.element.update(); # this doesn't help with flickering, it seems
|
||||||
|
me.callback('draw_after');
|
||||||
},
|
},
|
||||||
del: func() {
|
del: func() {
|
||||||
printlog(_MP_dbg_lvl, "LineSymbol.del()");
|
printlog(_MP_dbg_lvl, "LineSymbol.del()");
|
||||||
|
@ -791,6 +944,24 @@ var SymbolLayer = {
|
||||||
assert_m(controller.parents[0], "parents");
|
assert_m(controller.parents[0], "parents");
|
||||||
if (controller.parents[0].parents[0] != SymbolLayer.Controller)
|
if (controller.parents[0].parents[0] != SymbolLayer.Controller)
|
||||||
__die("MultiSymbolLayer: OOP error");
|
__die("MultiSymbolLayer: OOP error");
|
||||||
|
if(options != nil){
|
||||||
|
var listeners = opt_member(controller, 'listeners');
|
||||||
|
var listen = opt_member(options, 'listen');
|
||||||
|
if (listen != nil and listeners != nil){
|
||||||
|
var listen_tp = typeof(listen);
|
||||||
|
if(listen_tp != 'vector' and listen_tp != 'scalar')
|
||||||
|
__die("Options 'listen' cannot be a "~ listen_tp);
|
||||||
|
if(typeof(listen) == 'scalar')
|
||||||
|
listen = [listen];
|
||||||
|
foreach(var node_name; listen){
|
||||||
|
var node = opt_member(options, node_name);
|
||||||
|
if(node == nil)
|
||||||
|
node = node_name;
|
||||||
|
append(controller.listeners,
|
||||||
|
setlistener(node, func call(m.update,[],m),0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
m.controller = controller;
|
m.controller = controller;
|
||||||
},
|
},
|
||||||
# For instances:
|
# For instances:
|
||||||
|
@ -1010,6 +1181,67 @@ var SingleSymbolLayer = {
|
||||||
# set up a cache for 32x32 symbols (initialized below in load_MapStructure)
|
# set up a cache for 32x32 symbols (initialized below in load_MapStructure)
|
||||||
var SymbolCache32x32 = nil;
|
var SymbolCache32x32 = nil;
|
||||||
|
|
||||||
|
var MapStructure = {
|
||||||
|
# Generalized load methods used to load various symbols, layer controllers,...
|
||||||
|
loadFile : func(file, name) {
|
||||||
|
if (name == nil)
|
||||||
|
var name = split("/", file)[-1];
|
||||||
|
var code = io.readfile(file);
|
||||||
|
var code = call(func compile(code, file), [code], var err=[]);
|
||||||
|
if (size(err)) {
|
||||||
|
if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature
|
||||||
|
var e = split(" at line ", err[0]);
|
||||||
|
if (size(e) == 2)
|
||||||
|
err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]);
|
||||||
|
}
|
||||||
|
for (var i = 1; (var c = caller(i)) != nil; i += 1)
|
||||||
|
err ~= subvec(c, 2, 2);
|
||||||
|
debug.printerror(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#code=bind(
|
||||||
|
call(code, nil, nil, var hash = {});
|
||||||
|
|
||||||
|
# validate
|
||||||
|
var url = ' http://wiki.flightgear.org/MapStructure#';
|
||||||
|
# TODO: these rules should be extended for all main files lcontroller/scontroller and symbol
|
||||||
|
var checks = [
|
||||||
|
{ extension:'symbol', symbol:'update', type:'func', error:' update() must not be overridden:', id:300},
|
||||||
|
# Sorry, this one doesn't work with the new LineSymbol
|
||||||
|
# { extension:'symbol', symbol:'draw', type:'func', required:1, error:' symbol files need to export a draw() routine:', id:301},
|
||||||
|
# Sorry, this one doesn't work with the new SingleSymbolLayer
|
||||||
|
# { extension:'lcontroller', symbol:'searchCmd', type:'func', required:1, error:' lcontroller without searchCmd method:', id:100},
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
var makeurl = func(scope, id) url ~ scope ~ ':' ~ id;
|
||||||
|
var bailout = func(file, message, scope, id) __die(file~message~"\n"~makeurl(scope,id) );
|
||||||
|
|
||||||
|
var current_ext = split('.', file)[-1];
|
||||||
|
foreach(var check; checks) {
|
||||||
|
# check if we have any rules matching the current file extension
|
||||||
|
if (current_ext == check.extension) {
|
||||||
|
# check for fields that must not be overridden
|
||||||
|
if (check['error'] != nil and
|
||||||
|
hash[check.symbol]!=nil and !check['required'] and
|
||||||
|
typeof(hash[check.symbol])==check.type ) {
|
||||||
|
bailout(file,check.error,check.extension,check.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
# check for required fields
|
||||||
|
if (check['required'] != nil and
|
||||||
|
hash[check.symbol]==nil and
|
||||||
|
typeof( hash[check.symbol]) != check.type) {
|
||||||
|
bailout(file,check.error,check.extension,check.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var load_MapStructure = func {
|
var load_MapStructure = func {
|
||||||
canvas.load_MapStructure = func; # disable any subsequent attempt to load
|
canvas.load_MapStructure = func; # disable any subsequent attempt to load
|
||||||
|
|
||||||
|
@ -1063,62 +1295,6 @@ var load_MapStructure = func {
|
||||||
####### LOAD FILES #######
|
####### LOAD FILES #######
|
||||||
(func {
|
(func {
|
||||||
var FG_ROOT = getprop("/sim/fg-root");
|
var FG_ROOT = getprop("/sim/fg-root");
|
||||||
var load = func(file, name) {
|
|
||||||
if (name == nil)
|
|
||||||
var name = split("/", file)[-1];
|
|
||||||
var code = io.readfile(file);
|
|
||||||
var code = call(func compile(code, file), [code], var err=[]);
|
|
||||||
if (size(err)) {
|
|
||||||
if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature
|
|
||||||
var e = split(" at line ", err[0]);
|
|
||||||
if (size(e) == 2)
|
|
||||||
err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]);
|
|
||||||
}
|
|
||||||
for (var i = 1; (var c = caller(i)) != nil; i += 1)
|
|
||||||
err ~= subvec(c, 2, 2);
|
|
||||||
debug.printerror(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#code=bind(
|
|
||||||
call(code, nil, nil, var hash = {});
|
|
||||||
|
|
||||||
# validate
|
|
||||||
var url = ' http://wiki.flightgear.org/MapStructure#';
|
|
||||||
# TODO: these rules should be extended for all main files lcontroller/scontroller and symbol
|
|
||||||
var checks = [
|
|
||||||
{ extension:'symbol', symbol:'update', type:'func', error:' update() must not be overridden:', id:300},
|
|
||||||
# Sorry, this one doesn't work with the new LineSymbol
|
|
||||||
# { extension:'symbol', symbol:'draw', type:'func', required:1, error:' symbol files need to export a draw() routine:', id:301},
|
|
||||||
# Sorry, this one doesn't work with the new SingleSymbolLayer
|
|
||||||
# { extension:'lcontroller', symbol:'searchCmd', type:'func', required:1, error:' lcontroller without searchCmd method:', id:100},
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
var makeurl = func(scope, id) url ~ scope ~ ':' ~ id;
|
|
||||||
var bailout = func(file, message, scope, id) __die(file~message~"\n"~makeurl(scope,id) );
|
|
||||||
|
|
||||||
var current_ext = split('.', file)[-1];
|
|
||||||
foreach(var check; checks) {
|
|
||||||
# check if we have any rules matching the current file extension
|
|
||||||
if (current_ext == check.extension) {
|
|
||||||
# check for fields that must not be overridden
|
|
||||||
if (check['error'] != nil and
|
|
||||||
hash[check.symbol]!=nil and !check['required'] and
|
|
||||||
typeof(hash[check.symbol])==check.type ) {
|
|
||||||
bailout(file,check.error,check.extension,check.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
# check for required fields
|
|
||||||
if (check['required'] != nil and
|
|
||||||
hash[check.symbol]==nil and
|
|
||||||
typeof( hash[check.symbol]) != check.type) {
|
|
||||||
bailout(file,check.error,check.extension,check.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
# sets up a shared symbol cache, which will be used by all MapStructure maps and layers
|
# sets up a shared symbol cache, which will be used by all MapStructure maps and layers
|
||||||
canvas.SymbolCache32x32 = SymbolCache.new(1024,32);
|
canvas.SymbolCache32x32 = SymbolCache.new(1024,32);
|
||||||
|
@ -1146,7 +1322,7 @@ var load_MapStructure = func {
|
||||||
foreach (var d; dep_names) {
|
foreach (var d; dep_names) {
|
||||||
foreach (var f; deps[d]) {
|
foreach (var f; deps[d]) {
|
||||||
var name = split(".", f)[0];
|
var name = split(".", f)[0];
|
||||||
load(contents_dir~f, name);
|
MapStructure.loadFile(contents_dir~f, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -360,6 +360,46 @@ var Group = {
|
||||||
|
|
||||||
return children;
|
return children;
|
||||||
},
|
},
|
||||||
|
# Recursively get all children of class specified by first param
|
||||||
|
getChildrenOfType: func(type, array = nil){
|
||||||
|
var children = array;
|
||||||
|
if(children == nil)
|
||||||
|
children = [];
|
||||||
|
var my_children = me.getChildren();
|
||||||
|
if(typeof(type) != 'vector')
|
||||||
|
type = [type];
|
||||||
|
foreach(var c; my_children){
|
||||||
|
foreach(var t; type){
|
||||||
|
if(isa(c, t)){
|
||||||
|
append(children, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isa(c, canvas.Group)){
|
||||||
|
c.getChildrenOfType(type, children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return children;
|
||||||
|
},
|
||||||
|
# Set color to children of type Path and Text. It is possible to optionally
|
||||||
|
# specify which types of children should be affected by passing a vector as
|
||||||
|
# the last agrument, ie. my_group.setColor(1,1,1,[Path]);
|
||||||
|
setColor: func(){
|
||||||
|
var color = arg;
|
||||||
|
var types = [Path, Text];
|
||||||
|
var arg_c = size(color);
|
||||||
|
if(arg_c > 1 and typeof(color[-1]) == 'vector'){
|
||||||
|
types = color[-1];
|
||||||
|
color = subvec(color, 0, arg_c - 1);
|
||||||
|
}
|
||||||
|
var children = me.getChildrenOfType(types);
|
||||||
|
if(typeof(color) == 'vector'){
|
||||||
|
var first = color[0];
|
||||||
|
if(typeof(first) == 'vector')
|
||||||
|
color = first;
|
||||||
|
}
|
||||||
|
foreach(var c; children)
|
||||||
|
c.setColor(color);
|
||||||
|
},
|
||||||
# Get first child with given id (breadth-first search)
|
# Get first child with given id (breadth-first search)
|
||||||
#
|
#
|
||||||
# @note Use with care as it can take several miliseconds (for me eg. ~2ms).
|
# @note Use with care as it can take several miliseconds (for me eg. ~2ms).
|
||||||
|
@ -460,11 +500,12 @@ var Map = {
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
},
|
},
|
||||||
addLayer: func(factory, type_arg=nil, priority=nil, style=nil, options=nil, visible=1)
|
addLayer: func(factory, type_arg=nil, priority=nil, style=nil, opts=nil, visible=1)
|
||||||
{
|
{
|
||||||
if(contains(me.layers, type_arg))
|
if(contains(me.layers, type_arg))
|
||||||
printlog("warn", "addLayer() warning: overwriting existing layer:", type_arg);
|
printlog("warn", "addLayer() warning: overwriting existing layer:", type_arg);
|
||||||
|
|
||||||
|
var options = opts;
|
||||||
# Argument handling
|
# Argument handling
|
||||||
if (type_arg != nil) {
|
if (type_arg != nil) {
|
||||||
var layer = factory.new(type:type_arg, group:me, map:me, style:style, options:options, visible:visible);
|
var layer = factory.new(type:type_arg, group:me, map:me, style:style, options:options, visible:visible);
|
||||||
|
|
|
@ -9,9 +9,9 @@ SymbolLayer.add(name, {
|
||||||
type: name, # Symbol type
|
type: name, # Symbol type
|
||||||
df_controller: __self__, # controller to use by default -- this one
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
df_options: { # default configuration options
|
df_options: { # default configuration options
|
||||||
active_node: "/autopilot/route-manager/active",
|
fplan_active: "/autopilot/route-manager/active",
|
||||||
vnav_node: "/autopilot/route-manager/vnav/",
|
vnav_node: "/autopilot/route-manager/vnav/",
|
||||||
types: ["tc", "td", "sc", "ed"],
|
types: ["tc", "td", "ec", "ed","sc", "sd"],
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var new = func(layer) {
|
var new = func(layer) {
|
||||||
|
@ -22,7 +22,8 @@ var new = func(layer) {
|
||||||
listeners: [],
|
listeners: [],
|
||||||
};
|
};
|
||||||
layer.searcher._equals = func(a,b) a.getName() == b.getName();
|
layer.searcher._equals = func(a,b) a.getName() == b.getName();
|
||||||
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ));
|
append(m.listeners, setlistener(layer.options.fplan_active,
|
||||||
|
func m.layer.update() ));
|
||||||
m.addVisibilityListener();
|
m.addVisibilityListener();
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
|
|
@ -13,20 +13,39 @@ var element_type = "group";
|
||||||
|
|
||||||
var init = func {
|
var init = func {
|
||||||
var name = me.model.getName();
|
var name = me.model.getName();
|
||||||
var disptext = chr(string.toupper(name[0]))~"/"~chr(string.toupper(name[1]));
|
var svg_path = me.getOption('svg_path');
|
||||||
var radius = me.style.radius;
|
if (svg_path != nil) {
|
||||||
me.element.createChild("path")
|
var grp = me.element.createChild("group", name);
|
||||||
|
if(typeof(svg_path) == 'scalar'){
|
||||||
|
canvas.parsesvg(me.element, svg_path);
|
||||||
|
}
|
||||||
|
else{ #need hash
|
||||||
|
if(!contains(svg_path, name))
|
||||||
|
die('ALT-Profile: no SVG Path for '~ name);
|
||||||
|
var path = svg_path[name];
|
||||||
|
canvas.parsesvg(me.element, path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var disptext = chr(string.toupper(name[0]))~"/"~chr(string.toupper(name[1]));
|
||||||
|
var radius = me.style.radius;
|
||||||
|
me.element.createChild("path")
|
||||||
.setStrokeLineWidth(5)
|
.setStrokeLineWidth(5)
|
||||||
.moveTo(-radius, 0)
|
.moveTo(-radius, 0)
|
||||||
.arcLargeCW(radius, radius, 0, 2 * radius, 0)
|
.arcLargeCW(radius, radius, 0, 2 * radius, 0)
|
||||||
.arcLargeCW(radius, radius, 0, -2 * radius, 0)
|
.arcLargeCW(radius, radius, 0, -2 * radius, 0)
|
||||||
.setColor(0.195,0.96,0.097);
|
.setColor(0.195,0.96,0.097);
|
||||||
me.element.createChild("text")
|
me.element.createChild("text")
|
||||||
.setDrawMode( canvas.Text.TEXT )
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
.setText(disptext)
|
.setText(disptext)
|
||||||
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
.setFontSize(28)
|
.setFontSize(28)
|
||||||
.setTranslation(25,35)
|
.setTranslation(25,35)
|
||||||
.setColor(0.195,0.96,0.097);
|
.setColor(0.195,0.96,0.097);
|
||||||
|
}
|
||||||
|
me.callback('init_after');
|
||||||
|
}
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
me.callback('draw');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,13 @@ SymbolLayer.add(name, {
|
||||||
# N.B.: if used, this SymbolLayer should be updated every frame
|
# N.B.: if used, this SymbolLayer should be updated every frame
|
||||||
# by the Map Controller, or as often as the position is changed.
|
# by the Map Controller, or as often as the position is changed.
|
||||||
var new = func(layer) {
|
var new = func(layer) {
|
||||||
|
var __model = layer.map.getPosCoord();
|
||||||
|
#debug.dump(typeof(layer.options));
|
||||||
|
if(layer.options != nil and contains(layer.options, 'model'))
|
||||||
|
__model = layer.options.model;
|
||||||
return {
|
return {
|
||||||
parents: [__self__],
|
parents: [__self__],
|
||||||
_model: layer.map.getPosCoord(),
|
_model: __model,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
var del = func;
|
var del = func;
|
||||||
|
|
|
@ -15,6 +15,8 @@ SymbolLayer.add(name, {
|
||||||
color_default: [0,0.6,0.85],
|
color_default: [0,0.6,0.85],
|
||||||
label_font_color:[0,0.6,0.85],
|
label_font_color:[0,0.6,0.85],
|
||||||
label_font_size: 28,
|
label_font_size: 28,
|
||||||
|
text_offset: [17,35],
|
||||||
|
svg_path: nil
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,23 +11,34 @@ var text_apt = nil;
|
||||||
|
|
||||||
# add the draw routine from airports-nd.draw here
|
# add the draw routine from airports-nd.draw here
|
||||||
var init = func {
|
var init = func {
|
||||||
var icon_apt = me.element.createChild("path", name ~ " icon" )
|
var icon_apt = nil;
|
||||||
|
var style = me.layer.style;
|
||||||
|
var svg_path = style.svg_path;
|
||||||
|
if (svg_path != nil) {
|
||||||
|
canvas.parsesvg(me.element, svg_path);
|
||||||
|
} else {
|
||||||
|
icon_apt = me.element.createChild("path", name ~ " icon" )
|
||||||
.moveTo(-17,0)
|
.moveTo(-17,0)
|
||||||
.arcSmallCW(17,17,0,34,0)
|
.arcSmallCW(17,17,0,34,0)
|
||||||
.arcSmallCW(17,17,0,-34,0)
|
.arcSmallCW(17,17,0,-34,0)
|
||||||
.close()
|
.close()
|
||||||
.setColor(me.layer.style.color_default)
|
.setColor(style.color_default)
|
||||||
.setStrokeLineWidth(me.layer.style.line_width);
|
.setStrokeLineWidth(style.line_width);
|
||||||
|
}
|
||||||
|
var text = me.getLabelFromModel();
|
||||||
|
if(text == nil){
|
||||||
|
text = me.model.id;
|
||||||
|
}
|
||||||
var text_apt = me.element.createChild("text", name ~ " label")
|
var text_apt = me.element.createChild("text", name ~ " label")
|
||||||
.setDrawMode( canvas.Text.TEXT )
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
.setTranslation(17,35)
|
.setTranslation(style.text_offset)
|
||||||
.setText(me.model.id)
|
.setText(text)
|
||||||
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
.setColor(me.layer.style.label_font_color)
|
.setColor(style.label_font_color)
|
||||||
.setFontSize(me.layer.style.label_font_size);
|
.setFontSize(style.label_font_size);
|
||||||
|
|
||||||
# FIXME: this applies scale to the whole group, better do this separately for each element?
|
# FIXME: this applies scale to the whole group, better do this separately for each element?
|
||||||
me.element.setScale(me.layer.style.scale_factor);
|
me.element.setScale(style.scale_factor);
|
||||||
};
|
};
|
||||||
var draw = func;
|
var draw = func;
|
||||||
|
|
||||||
|
|
70
Nasal/canvas/map/Airbus/Images/airbusAirplane.svg
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="87.8438"
|
||||||
|
height="108.844"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="boeingAirplane.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="3.9598"
|
||||||
|
inkscape:cx="19.8149"
|
||||||
|
inkscape:cy="54.088"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
inkscape:window-width="1366"
|
||||||
|
inkscape:window-height="716"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-364.652,-344.745)">
|
||||||
|
<g
|
||||||
|
id="airplane"
|
||||||
|
transform="translate(364.652,346.745)"
|
||||||
|
inkscape:label="#g3781">
|
||||||
|
<path
|
||||||
|
id="apl_path"
|
||||||
|
d="m 44.0787,102 0,-90 M 84,38 l -78,0 M 63,90 l -38,0"
|
||||||
|
style="fill:none;stroke:#f2f235;stroke-width:3.9685px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
2084
Nasal/canvas/map/Airbus/Images/airbusND.svg
Normal file
After Width: | Height: | Size: 142 KiB |
99
Nasal/canvas/map/Airbus/Images/airbus_airport.svg
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg3090"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="Nuovo documento 10">
|
||||||
|
<defs
|
||||||
|
id="defs3092" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="8.6118945"
|
||||||
|
inkscape:cx="24.13482"
|
||||||
|
inkscape:cy="21.929539"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1256"
|
||||||
|
inkscape:window-height="677"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata3095">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<g
|
||||||
|
id="g3120"
|
||||||
|
transform="translate(0.81282928,-0.3483554)">
|
||||||
|
<g
|
||||||
|
id="g3110">
|
||||||
|
<rect
|
||||||
|
style="fill:#af0063;stroke:#af0063"
|
||||||
|
id="rect3106"
|
||||||
|
width="31.128778"
|
||||||
|
height="1.1431472"
|
||||||
|
x="7.7382278"
|
||||||
|
y="-24.606066"
|
||||||
|
transform="scale(1,-1)" />
|
||||||
|
<rect
|
||||||
|
transform="matrix(0,-1,-1,0,0,0)"
|
||||||
|
y="-23.874191"
|
||||||
|
x="-39.598881"
|
||||||
|
height="1.1431472"
|
||||||
|
width="31.128778"
|
||||||
|
id="rect3108"
|
||||||
|
style="fill:#af0063;stroke:#af0063" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-10.169774,23.516978)"
|
||||||
|
id="g3114">
|
||||||
|
<rect
|
||||||
|
transform="scale(1,-1)"
|
||||||
|
y="-24.606066"
|
||||||
|
x="7.7382278"
|
||||||
|
height="1.1431472"
|
||||||
|
width="31.128778"
|
||||||
|
id="rect3116"
|
||||||
|
style="fill:#af0063;stroke:#af0063" />
|
||||||
|
<rect
|
||||||
|
style="fill:#af0063;stroke:#af0063"
|
||||||
|
id="rect3118"
|
||||||
|
width="31.128778"
|
||||||
|
height="1.1431472"
|
||||||
|
x="-39.598881"
|
||||||
|
y="-23.874191"
|
||||||
|
transform="matrix(0,-1,-1,0,0,0)" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
77
Nasal/canvas/map/Airbus/Images/airbus_decel.svg
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_decel.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4.3"
|
||||||
|
inkscape:cx="-12.902798"
|
||||||
|
inkscape:cy="24.002241"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:1.47335875;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="path5312"
|
||||||
|
sodipodi:cx="24.069767"
|
||||||
|
sodipodi:cy="23.581396"
|
||||||
|
sodipodi:rx="17.55814"
|
||||||
|
sodipodi:ry="16.976744"
|
||||||
|
d="m 41.627907,23.581396 a 17.55814,16.976744 0 1 1 -35.1162798,0 17.55814,16.976744 0 1 1 35.1162798,0 z"
|
||||||
|
transform="matrix(1.3347658,0,0,1.3804934,-7.6915012,-8.9902419)" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#af0063;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
|
||||||
|
x="24.799843"
|
||||||
|
y="38.763"
|
||||||
|
id="text6082"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan6084"
|
||||||
|
x="24.799843"
|
||||||
|
y="38.763">D</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
72
Nasal/canvas/map/Airbus/Images/airbus_ec.svg
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_ec.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.27"
|
||||||
|
inkscape:cx="11.14417"
|
||||||
|
inkscape:cy="15.800695"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<g
|
||||||
|
id="ec_symbol"
|
||||||
|
style="stroke:#af0063;stroke-opacity:1">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path2993"
|
||||||
|
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.39999999999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.40000010000000019px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 45.785714,21.561266 -4.8,7.542856"
|
||||||
|
id="path3094"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
73
Nasal/canvas/map/Airbus/Images/airbus_ed.svg
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_ed.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.27"
|
||||||
|
inkscape:cx="-22.252415"
|
||||||
|
inkscape:cy="15.800695"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1280"
|
||||||
|
inkscape:window-height="706"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<g
|
||||||
|
id="ed_symbol"
|
||||||
|
transform="matrix(1,0,0,-1,0,48.142858)"
|
||||||
|
style="stroke:#118eff;stroke-opacity:1">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path2993"
|
||||||
|
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
|
||||||
|
style="fill:none;stroke:#118eff;stroke-width:2.40000010000000019;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#118eff;stroke-width:2.40000010000000019px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 45.785714,21.561266 -4.8,7.542856"
|
||||||
|
id="path3094"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
60
Nasal/canvas/map/Airbus/Images/airbus_holdL.svg
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="64px"
|
||||||
|
height="64px"
|
||||||
|
id="svg6263"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_hold_r.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6265" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.5"
|
||||||
|
inkscape:cx="11.363636"
|
||||||
|
inkscape:cy="39.272727"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:window-width="64"
|
||||||
|
inkscape:window-height="64"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6268">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
d="m 38,58 l 0,-38 a 10,10 0 1 1 -20,0 l -5,-7 m5,7 l 8,-2"
|
||||||
|
id="path7043"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:55.40000153;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
62
Nasal/canvas/map/Airbus/Images/airbus_holdR.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="64px"
|
||||||
|
height="64px"
|
||||||
|
id="svg6263"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_holdL.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6265" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.5"
|
||||||
|
inkscape:cx="11.363636"
|
||||||
|
inkscape:cy="36.978476"
|
||||||
|
inkscape:current-layer="svg6263"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:window-width="1280"
|
||||||
|
inkscape:window-height="703"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6268">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="matrix(-1,0,0,1,59,0)">
|
||||||
|
<path
|
||||||
|
d="m 38,58 0,-38 a 10,10 0 1 1 -20,0 l -5,-7 m 5,7 8,-2"
|
||||||
|
id="path7043"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:55.40000153;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
62
Nasal/canvas/map/Airbus/Images/airbus_sc.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_sc.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4.3"
|
||||||
|
inkscape:cx="-39.763263"
|
||||||
|
inkscape:cy="24.002241"
|
||||||
|
inkscape:current-layer="Layer 1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="Layer 1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
style="stroke:#ffffff;stroke-width:2.07588959px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 0.30339278,31.209046 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,-13.513241 2.733394,9.652315 M 34.291189,18.20861 44.865702,16.790953"
|
||||||
|
id="sc_symbol"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
62
Nasal/canvas/map/Airbus/Images/airbus_sd.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_td.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4.3"
|
||||||
|
inkscape:cx="-8.8330301"
|
||||||
|
inkscape:cy="24.002241"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="Layer 1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
style="fill:#none;stroke:#ffffff;stroke-width:2.07588959000000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 0.30339278,21.60313 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,13.513241 2.733394,-9.652314 m -12.804089,9.139509 10.574513,1.417657"
|
||||||
|
id="sd_symbol"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
140
Nasal/canvas/map/Airbus/Images/airbus_spd_limit.svg
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.5 r10040"
|
||||||
|
sodipodi:docname="airbus_spd_limit.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5782"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#323232;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5784" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5412"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#af0063;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5414" />
|
||||||
|
</linearGradient>
|
||||||
|
<pattern
|
||||||
|
patternUnits="userSpaceOnUse"
|
||||||
|
width="34.9375"
|
||||||
|
height="5.375"
|
||||||
|
patternTransform="translate(7.71875,41.3125)"
|
||||||
|
id="pattern5851">
|
||||||
|
<g
|
||||||
|
id="g5847"
|
||||||
|
transform="translate(-7.71875,-41.3125)">
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0;fill-rule:nonzero;stroke:#323232;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||||
|
id="rect5800"
|
||||||
|
width="34.813999"
|
||||||
|
height="2.6294737"
|
||||||
|
x="7.7832417"
|
||||||
|
y="43.999527" />
|
||||||
|
<rect
|
||||||
|
y="41.370525"
|
||||||
|
x="7.7832417"
|
||||||
|
height="2.6294737"
|
||||||
|
width="34.814232"
|
||||||
|
id="rect5845"
|
||||||
|
style="fill:#323232;fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
|
||||||
|
</g>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="7.73"
|
||||||
|
inkscape:cx="25.807853"
|
||||||
|
inkscape:cy="26.171035"
|
||||||
|
inkscape:current-layer="airbus-vor-sym"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1197"
|
||||||
|
inkscape:window-height="667"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="airbus-spd-sym"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
style="fill:#323232;fill-opacity:1;stroke:none"
|
||||||
|
d="M 12.5 11.5 C 11.276818 12.626179 10.226321 13.93529 9.375 15.375 L 38.625 15.375 C 37.773679 13.93529 36.723182 12.626179 35.5 11.5 L 12.5 11.5 z "
|
||||||
|
id="rect3058" />
|
||||||
|
<path
|
||||||
|
style="fill:#af0063;fill-opacity:1;stroke:none"
|
||||||
|
d="M 9.4375 15.28125 C 8.706022 16.49978 8.0972549 17.795497 7.6875 19.1875 L 40.3125 19.1875 C 39.902745 17.795497 39.293978 16.49978 38.5625 15.28125 L 9.4375 15.28125 z "
|
||||||
|
id="rect4544" />
|
||||||
|
<path
|
||||||
|
style="fill:#323232;fill-opacity:1;stroke:none"
|
||||||
|
d="M 7.71875 19.09375 C 7.3437512 20.340744 7.1407327 21.650439 7.0625 23 L 40.9375 23 C 40.859267 21.650439 40.656249 20.340744 40.28125 19.09375 L 7.71875 19.09375 z "
|
||||||
|
id="rect4556" />
|
||||||
|
<path
|
||||||
|
style="fill:#af0063;fill-opacity:1;stroke:none"
|
||||||
|
d="M 7.0625 22.90625 C 7.0396116 23.267297 7 23.633178 7 24 C 7 24.945579 7.1015573 25.877693 7.25 26.78125 L 40.75 26.78125 C 40.898443 25.877693 41 24.945579 41 24 C 41 23.633178 40.960388 23.267297 40.9375 22.90625 L 7.0625 22.90625 z "
|
||||||
|
id="rect4558" />
|
||||||
|
<path
|
||||||
|
style="fill:#323232;fill-opacity:1;stroke:none"
|
||||||
|
d="M 7.21875 26.6875 C 7.4348196 28.051579 7.8235864 29.358048 8.34375 30.59375 L 39.65625 30.59375 C 40.176414 29.358048 40.56518 28.051579 40.78125 26.6875 L 7.21875 26.6875 z "
|
||||||
|
id="rect4572" />
|
||||||
|
<path
|
||||||
|
style="fill:#af0063;fill-opacity:1;stroke:none"
|
||||||
|
d="M 8.28125 30.5 C 8.8624157 31.905891 9.6447903 33.188749 10.5625 34.375 L 37.4375 34.375 C 38.35521 33.188749 39.137584 31.905891 39.71875 30.5 L 8.28125 30.5 z "
|
||||||
|
id="rect4574" />
|
||||||
|
<path
|
||||||
|
style="fill:#323232;fill-opacity:1;stroke:none"
|
||||||
|
d="M 10.46875 34.28125 C 11.63072 35.807354 13.051977 37.12846 14.65625 38.1875 L 33.34375 38.1875 C 34.948023 37.12846 36.36928 35.807354 37.53125 34.28125 L 10.46875 34.28125 z "
|
||||||
|
id="rect4578" />
|
||||||
|
<path
|
||||||
|
style="fill:#af0063;fill-opacity:1;stroke:none"
|
||||||
|
d="M 14.5 38.09375 C 17.213218 39.926763 20.479185 41 24 41 C 27.520815 41 30.786782 39.926763 33.5 38.09375 L 14.5 38.09375 z "
|
||||||
|
id="rect4580" />
|
||||||
|
<path
|
||||||
|
style="fill:#323232;fill-opacity:1;stroke:none"
|
||||||
|
d="M 24 7 C 22.20493 7 20.468087 7.2655778 18.84375 7.78125 L 29.15625 7.78125 C 27.531913 7.2655778 25.79507 7 24 7 z "
|
||||||
|
id="rect4592" />
|
||||||
|
<path
|
||||||
|
style="fill:#af0063;fill-opacity:1;stroke:none"
|
||||||
|
d="M 19.1875 7.6875 C 16.607244 8.4470332 14.285939 9.80207 12.375 11.59375 L 35.625 11.59375 C 33.714061 9.80207 31.392756 8.4470332 28.8125 7.6875 L 19.1875 7.6875 z "
|
||||||
|
id="rect4594" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
71
Nasal/canvas/map/Airbus/Images/airbus_tc.svg
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_tc.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.27"
|
||||||
|
inkscape:cx="14.464853"
|
||||||
|
inkscape:cy="15.800695"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<g
|
||||||
|
id="tc_symbol">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path2993"
|
||||||
|
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
|
||||||
|
style="fill:none;stroke:#118eff;stroke-width:2.39999999999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#118eff;stroke-width:2.4000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 45.785714,21.561266 -4.8,7.542856"
|
||||||
|
id="path3094"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
62
Nasal/canvas/map/Airbus/Images/airbus_td.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_td.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4.3"
|
||||||
|
inkscape:cx="-8.8330301"
|
||||||
|
inkscape:cy="24.002241"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1075"
|
||||||
|
inkscape:window-height="665"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="Layer 1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
style="fill:#none;stroke:#ffffff;stroke-width:2.07588959000000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 0.30339278,21.60313 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,13.513241 2.733394,-9.652314 m -12.804089,9.139509 10.574513,1.417657"
|
||||||
|
id="td_symbol"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
101
Nasal/canvas/map/Airbus/Images/airbus_vor.old.svg
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
id="svg3076"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus-vor.svg">
|
||||||
|
<metadata
|
||||||
|
id="metadata3092">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs3090" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1248"
|
||||||
|
inkscape:window-height="703"
|
||||||
|
id="namedview3088"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.6619718"
|
||||||
|
inkscape:cx="-33.09322"
|
||||||
|
inkscape:cy="71"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg3076" />
|
||||||
|
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
|
||||||
|
<g
|
||||||
|
id="g3078"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
transform="matrix(0.34013605,0,0,0.33783784,0.84746249,0.78240397)">
|
||||||
|
<title
|
||||||
|
id="title3080">Layer 1</title>
|
||||||
|
<g
|
||||||
|
id="svg_7">
|
||||||
|
<line
|
||||||
|
id="svg_3"
|
||||||
|
y2="71"
|
||||||
|
x2="142"
|
||||||
|
y1="71"
|
||||||
|
x1="112"
|
||||||
|
style="fill:none;stroke:#b00064;stroke-width:5" />
|
||||||
|
<circle
|
||||||
|
id="svg_2"
|
||||||
|
r="39.115215"
|
||||||
|
cy="71.5"
|
||||||
|
cx="71"
|
||||||
|
sodipodi:cx="71"
|
||||||
|
sodipodi:cy="71.5"
|
||||||
|
sodipodi:rx="39.115215"
|
||||||
|
sodipodi:ry="39.115215"
|
||||||
|
style="fill:none;stroke:#b00064;stroke-width:5"
|
||||||
|
d="m 110.11522,71.5 c 0,21.602737 -17.512483,39.11522 -39.11522,39.11522 -21.602737,0 -39.115215,-17.512483 -39.115215,-39.11522 0,-21.602737 17.512478,-39.115215 39.115215,-39.115215 21.602737,0 39.11522,17.512478 39.11522,39.115215 z" />
|
||||||
|
<line
|
||||||
|
id="svg_4"
|
||||||
|
y2="71"
|
||||||
|
x2="30"
|
||||||
|
y1="71"
|
||||||
|
x1="0"
|
||||||
|
style="fill:none;stroke:#b00064;stroke-width:5" />
|
||||||
|
<line
|
||||||
|
transform="matrix(0,1,-1,0,198,58)"
|
||||||
|
id="svg_5"
|
||||||
|
y2="128"
|
||||||
|
x2="85"
|
||||||
|
y1="128"
|
||||||
|
x1="55"
|
||||||
|
style="fill:none;stroke:#b00064;stroke-width:5" />
|
||||||
|
<line
|
||||||
|
id="svg_6"
|
||||||
|
transform="matrix(0,1,-1,0,85,-55)"
|
||||||
|
y2="15"
|
||||||
|
x2="85"
|
||||||
|
y1="15"
|
||||||
|
x1="55"
|
||||||
|
style="fill:none;stroke:#b00064;stroke-width:5" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
90
Nasal/canvas/map/Airbus/Images/airbus_vor.svg
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg2985"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.2 r9819"
|
||||||
|
sodipodi:docname="airbus_vor.svg">
|
||||||
|
<defs
|
||||||
|
id="defs2987" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="7.7255132"
|
||||||
|
inkscape:cx="41.056088"
|
||||||
|
inkscape:cy="29.220813"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:window-width="1197"
|
||||||
|
inkscape:window-height="667"
|
||||||
|
inkscape:window-x="20"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata2990">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="airbus-vor-sym"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:1.57920909;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
id="path3014"
|
||||||
|
sodipodi:cx="28.214285"
|
||||||
|
sodipodi:cy="22.642857"
|
||||||
|
sodipodi:rx="10.5"
|
||||||
|
sodipodi:ry="10.214286"
|
||||||
|
d="m 38.714285,22.642857 a 10.5,10.214286 0 1 1 -21,0 10.5,10.214286 0 1 1 21,0 z"
|
||||||
|
transform="matrix(1.1857807,0,0,1.2189494,-9.1389546,-3.9914967)" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3084"
|
||||||
|
d="m 36.915889,23.738251 c 7.210196,0 9.210196,0 9.210196,0 l 0,0"
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.23682857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.22900009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 24.316735,1.1057656 c 0,7.8137242 0,7.8137242 0,7.8137242 l 0,2.0000002"
|
||||||
|
id="path3086"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3088"
|
||||||
|
d="m 24.316735,35.872915 c 0,7.462294 0,9.462294 0,9.462294 l 0,0"
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.22900009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#af0063;stroke-width:2.23682857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 3.3195483,23.738251 c 7.2101957,0 7.2101957,0 7.2101957,0 l 2,0"
|
||||||
|
id="path4589"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
37
Nasal/canvas/map/DECEL.lcontroller
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'DECEL';
|
||||||
|
var parents = [canvas.SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
|
||||||
|
canvas.SymbolLayer.Controller.add(name, __self__);
|
||||||
|
canvas.SymbolLayer.add(name, {
|
||||||
|
parents: [MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options : { # default configuration options
|
||||||
|
decel_node: "/instrumentation/nd/symbols/decel/"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
layer.searcher._equals = func(a,b) a.getName() == b.getName();
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
var del = func() {
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
var results = [];
|
||||||
|
var symNode = props.globals.getNode(me.layer.options.decel_node);
|
||||||
|
if (symNode != nil and symNode.getValue('longitude-deg') != nil)
|
||||||
|
append(results, symNode);
|
||||||
|
return results;
|
||||||
|
}
|
32
Nasal/canvas/map/DECEL.symbol
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'DECEL';
|
||||||
|
var parents = [canvas.DotSym];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
canvas.DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
#canvas.SymbolLayer.get(name).df_style = {
|
||||||
|
# radius: 13,
|
||||||
|
#};
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
var svg_path = me.getStyle('svg_path');
|
||||||
|
if(svg_path == nil)
|
||||||
|
svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_decel.svg';
|
||||||
|
me.decel_grp = me.element.createChild("group","decel");
|
||||||
|
canvas.parsesvg(me.decel_grp, svg_path);
|
||||||
|
me.decel_grp.set('z-index', 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
if(me.decel_grp != nil){
|
||||||
|
var spd_ctrl = getprop(me.options.spd_ctrl);
|
||||||
|
var spd_managed = (spd_ctrl == me.options.managed_val);
|
||||||
|
if(spd_managed)
|
||||||
|
me.decel_grp.setColor(me.style.managed_color);
|
||||||
|
else
|
||||||
|
me.decel_grp.setColor(me.style.selected_color);
|
||||||
|
}
|
||||||
|
}
|
|
@ -103,22 +103,27 @@ var init_cache = func {
|
||||||
#
|
#
|
||||||
var init = func {
|
var init = func {
|
||||||
# debug.dump(me.layer.style);
|
# debug.dump(me.layer.style);
|
||||||
me.icon_dme = me.element.createChild("path")
|
var draw_func = me.getOption('draw_dme');
|
||||||
.moveTo(-15,0)
|
if(typeof(draw_func) == 'func'){
|
||||||
.line(-12.5,-7.5)
|
me.icon_dme = draw_func(me);
|
||||||
.line(7.5,-12.5)
|
} else {
|
||||||
.line(12.5,7.5)
|
me.icon_dme = me.element.createChild("path")
|
||||||
.lineTo(7.5,-12.5)
|
.moveTo(-15,0)
|
||||||
.line(12.5,-7.5)
|
.line(-12.5,-7.5)
|
||||||
.line(7.5,12.5)
|
.line(7.5,-12.5)
|
||||||
.line(-12.5,7.5)
|
.line(12.5,7.5)
|
||||||
.lineTo(15,0)
|
.lineTo(7.5,-12.5)
|
||||||
.lineTo(7.5,12.5)
|
.line(12.5,-7.5)
|
||||||
.vert(14.5)
|
.line(7.5,12.5)
|
||||||
.horiz(-14.5)
|
.line(-12.5,7.5)
|
||||||
.vert(-14.5)
|
.lineTo(15,0)
|
||||||
.close()
|
.lineTo(7.5,12.5)
|
||||||
.setStrokeLineWidth( me.layer.style.line_width );
|
.vert(14.5)
|
||||||
|
.horiz(-14.5)
|
||||||
|
.vert(-14.5)
|
||||||
|
.close()
|
||||||
|
.setStrokeLineWidth( me.layer.style.line_width );
|
||||||
|
}
|
||||||
|
|
||||||
# finally scale the symbol as requested, this is done last so that people can override this when creating the layer
|
# finally scale the symbol as requested, this is done last so that people can override this when creating the layer
|
||||||
me.apply_scale();
|
me.apply_scale();
|
||||||
|
@ -126,6 +131,15 @@ var init = func {
|
||||||
me.timer = maketimer(0.33, func me.animate() );
|
me.timer = maketimer(0.33, func me.animate() );
|
||||||
me.timer.start();
|
me.timer.start();
|
||||||
}
|
}
|
||||||
|
if(me.getOption('draw_text', 0)){
|
||||||
|
me.dme_text = me.element.createChild("text")
|
||||||
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
|
.setText(me.model.id)
|
||||||
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
|
.setFontSize(28)
|
||||||
|
.setColor(me.getStyle('text_color', [1,1,1]))
|
||||||
|
.setTranslation(me.getStyle('translation', [45,25]));
|
||||||
|
}
|
||||||
me.draw();
|
me.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,20 +30,31 @@ var drawFIX = func(group) {
|
||||||
.setStrokeLineWidth(line_width)
|
.setStrokeLineWidth(line_width)
|
||||||
.setColor(color);
|
.setColor(color);
|
||||||
}
|
}
|
||||||
|
var _name = name;
|
||||||
var cache = StyleableCacheable.new(
|
|
||||||
name:name, draw_func: drawFIX,
|
|
||||||
cache: SymbolCache32x32,
|
|
||||||
draw_mode: SymbolCache.DRAW_CENTERED,
|
|
||||||
relevant_keys: ["line_width", "color"],
|
|
||||||
);
|
|
||||||
|
|
||||||
var init = func {
|
var init = func {
|
||||||
# initialize the cached fix symbol
|
# initialize the cached fix symbol
|
||||||
|
var draw_fn = me.getOption('draw_function');
|
||||||
|
if(typeof(draw_fn) != 'func')
|
||||||
|
draw_fn = drawFIX;
|
||||||
|
|
||||||
|
var cache = StyleableCacheable.new(
|
||||||
|
name:_name,
|
||||||
|
draw_func: draw_fn,
|
||||||
|
cache: SymbolCache32x32,
|
||||||
|
draw_mode: SymbolCache.DRAW_CENTERED,
|
||||||
|
relevant_keys: ["line_width", "color"],
|
||||||
|
);
|
||||||
cache.render(me.element, me.style).setScale(me.style.scale_factor);
|
cache.render(me.element, me.style).setScale(me.style.scale_factor);
|
||||||
|
|
||||||
|
var txt_offset = me.getStyle('text_offset', [17, 35]);
|
||||||
|
var txt_color = me.getStyle('text_color', [0,0.6,0.85]);
|
||||||
# non-cached stuff:
|
# non-cached stuff:
|
||||||
if (me.style.show_labels)
|
if (me.style.show_labels){
|
||||||
me.text_fix = me.newText(me.model.id).setScale(me.style.scale_factor).setTranslation(17,35).setColor(0,0.6,0.85);
|
me.text_fix = me.newText(me.model.id).
|
||||||
|
setScale(me.style.scale_factor).
|
||||||
|
setTranslation(txt_offset).
|
||||||
|
setColor(txt_color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var draw = func;
|
var draw = func {me.callback('draw');};
|
||||||
|
|
100
Nasal/canvas/map/HOLD.lcontroller
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'HOLD';
|
||||||
|
var parents = [canvas.SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
|
||||||
|
canvas.SymbolLayer.Controller.add(name, __self__);
|
||||||
|
canvas.SymbolLayer.add(name, {
|
||||||
|
parents: [MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
});
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
#map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
#debug.dump(layer.parents);
|
||||||
|
layer.searcher._equals = func(a,b) a.id == b.id;
|
||||||
|
#append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() ));
|
||||||
|
#m.addVisibilityListener();
|
||||||
|
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
|
||||||
|
var del = func() {
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
var results = [];
|
||||||
|
var node = props.globals.getNode(me.layer.options.hold_node);
|
||||||
|
var wp_id = node.getValue('wp');
|
||||||
|
if(wp_id == nil or wp_id == '' or wp_id == '---'){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
var pointsNode = node.getNode('points');
|
||||||
|
var pointNode = nil;
|
||||||
|
var lat = nil;
|
||||||
|
var lon = nil;
|
||||||
|
if(pointsNode != nil)
|
||||||
|
pointNode = pointsNode.getNode('point', 0);
|
||||||
|
if (pointNode != nil){
|
||||||
|
lat = pointNode.getValue('lat');
|
||||||
|
lon = pointNode.getValue('lon');
|
||||||
|
}
|
||||||
|
if (pointNode != nil and lat != nil and lon != nil){
|
||||||
|
var r = node.getValue('crs');
|
||||||
|
var d = node.getValue('dist');
|
||||||
|
var t = node.getValue('turn');
|
||||||
|
var model = {
|
||||||
|
parents: [geo.Coord],
|
||||||
|
id: wp_id~r~d~t,
|
||||||
|
pos: pointNode,
|
||||||
|
type: 'pattern',
|
||||||
|
latlon: func(){
|
||||||
|
return [
|
||||||
|
lat,
|
||||||
|
lon
|
||||||
|
];
|
||||||
|
},
|
||||||
|
radial: r,
|
||||||
|
dist: d,
|
||||||
|
turn: t,
|
||||||
|
equals: func(o){me.id == o.id and me.radial == o.radial}
|
||||||
|
};
|
||||||
|
append(results, model);
|
||||||
|
} else {
|
||||||
|
var wp_idx = node.getValue('wp_id');
|
||||||
|
var fp = flightplan();
|
||||||
|
var wp = fp.getWP(wp_idx);
|
||||||
|
#print("HOLD AT "~wp.wp_lat~", "~wp.wp_lon);
|
||||||
|
if(wp == nil or wp.id != wp_id)
|
||||||
|
return [];
|
||||||
|
var wp_lat = wp.wp_lat;
|
||||||
|
var wp_lon = wp.wp_lon;
|
||||||
|
var model = {
|
||||||
|
parents: [geo.Coord],
|
||||||
|
id: wp_id~'-'~wp_idx~'-inactive',
|
||||||
|
pos: nil,
|
||||||
|
type: 'hold_symbol',
|
||||||
|
latlon: func(){
|
||||||
|
return [
|
||||||
|
wp_lat,
|
||||||
|
wp_lon
|
||||||
|
];
|
||||||
|
},
|
||||||
|
radial: node.getValue('crs'),
|
||||||
|
dist: node.getValue('dist'),
|
||||||
|
turn: node.getValue('turn'),
|
||||||
|
equals: func(o){me.id == o.id}
|
||||||
|
};
|
||||||
|
append(results, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
106
Nasal/canvas/map/HOLD.symbol
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'HOLD';
|
||||||
|
var parents = [canvas.DotSym];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
canvas.DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
#canvas.SymbolLayer.get(name).df_style = {
|
||||||
|
# radius: 13,
|
||||||
|
#};
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
|
||||||
|
var draw_pattern = func(dist, ){
|
||||||
|
var pattern = me.element.createChild("path", 'hold-pattern');
|
||||||
|
pattern.set("z-index",4);
|
||||||
|
var w = (dist * 2) / math.pi;
|
||||||
|
var h = dist * 70;
|
||||||
|
var r = w / 2;
|
||||||
|
pattern.arcSmallCW(r,r,0,70 * w,0).
|
||||||
|
line(0,h).
|
||||||
|
arcSmallCW(r,r,0,-70 * w,0).
|
||||||
|
line(0,-h).
|
||||||
|
setStrokeLineWidth(5).
|
||||||
|
setColor(me.active_color);
|
||||||
|
return pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
var draw_hold_sym = func(turn){
|
||||||
|
var hold_symbol = me.element.createChild("group", 'hold-symbol');
|
||||||
|
var svg = "Nasal/canvas/map/Airbus/Images/airbus_hold"~turn~".svg";
|
||||||
|
canvas.parsesvg(hold_symbol, svg);
|
||||||
|
hold_symbol.setTranslation(-32,-64).set('z-index', 4);
|
||||||
|
return hold_symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
var type = me.model.type;
|
||||||
|
var dist = me.model.dist;
|
||||||
|
var turn = me.model.turn;
|
||||||
|
me.active_color = me.getStyle('active_color',
|
||||||
|
me.getOption('active_route_color',
|
||||||
|
[0.4,0.7,0.4]));
|
||||||
|
me.inactive_color = me.getStyle('inactive_color',
|
||||||
|
me.getOption('inactive_route_color',
|
||||||
|
[0.95,0.95,0.21]));
|
||||||
|
if(type == 'pattern'){
|
||||||
|
me.hold_pattern = me.draw_pattern(dist);
|
||||||
|
me.hold_symbol = nil;
|
||||||
|
} else {
|
||||||
|
#print('CREATING HOLD SYM');
|
||||||
|
me.hold_pattern = nil;
|
||||||
|
me.hold_symbol = me.draw_hold_sym(turn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
var type = me.model.type;
|
||||||
|
var map = me.layer.map;
|
||||||
|
var pos = map.getPos();
|
||||||
|
if(type == 'pattern'){
|
||||||
|
var dist = me.model.dist;
|
||||||
|
if(me.hold_symbol != nil){
|
||||||
|
me.hold_symbol.hide();
|
||||||
|
}
|
||||||
|
if(me.hold_pattern == nil)
|
||||||
|
me.hold_pattern = me.draw_pattern(dist);
|
||||||
|
if(me.hold_pattern == nil) return;
|
||||||
|
var radial = me.model.radial;
|
||||||
|
if(radial != nil){
|
||||||
|
|
||||||
|
var hdg = pos[2];
|
||||||
|
if(hdg == nil) hdg = 0;
|
||||||
|
radial -= hdg;
|
||||||
|
if(radial < 0) radial = 360 + radial;
|
||||||
|
me.element.setRotation(radial*D2R);
|
||||||
|
}
|
||||||
|
var rng = pos[3];
|
||||||
|
if(rng == nil) rng = 10;
|
||||||
|
rng = 10 / rng;
|
||||||
|
me.element.setScale(rng,rng);
|
||||||
|
var lat_ctrl = getprop(me.getOption('lat_ctrl'));
|
||||||
|
var lnav = (lat_ctrl == me.getOption('lat_ctrl_managed','fmgc'));
|
||||||
|
var actv = getprop(me.getOption('fplan_active'));
|
||||||
|
#print('HOLD ' ~ lnav ~ ',' ~ actv);
|
||||||
|
if(!lnav or !actv)
|
||||||
|
me.hold_pattern.setStrokeDashArray([32, 16]);
|
||||||
|
else
|
||||||
|
me.hold_pattern.setStrokeDashArray([1,0]);
|
||||||
|
if(!actv)
|
||||||
|
me.hold_pattern.setColor(me.inactive_color);
|
||||||
|
else
|
||||||
|
me.hold_pattern.setColor(me.active_color);
|
||||||
|
} else {
|
||||||
|
var turn = me.model.turn;
|
||||||
|
if(me.hold_pattern != nil){
|
||||||
|
me.hold_pattern.hide();
|
||||||
|
}
|
||||||
|
if(me.hold_symbol == nil)
|
||||||
|
me.hold_symbol = me.draw_hold_sym(turn);
|
||||||
|
|
||||||
|
me.hold_symbol.show();
|
||||||
|
me.element.setScale(1,1);
|
||||||
|
me.element.setRotation(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ SymbolLayer.add(name, {
|
||||||
active_node: "/autopilot/route-manager/active",
|
active_node: "/autopilot/route-manager/active",
|
||||||
current_wp_node: "/autopilot/route-manager/current-wp",
|
current_wp_node: "/autopilot/route-manager/current-wp",
|
||||||
wp_num: "/autopilot/route-manager/route/num",
|
wp_num: "/autopilot/route-manager/route/num",
|
||||||
|
display_inactive_rte: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var new = func(layer) {
|
var new = func(layer) {
|
||||||
|
@ -25,9 +26,19 @@ var new = func(layer) {
|
||||||
listeners: [],
|
listeners: [],
|
||||||
};
|
};
|
||||||
layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead?
|
layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead?
|
||||||
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() ));
|
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ),
|
||||||
|
setlistener(layer.options.wp_num, func m.layer.update() ));
|
||||||
|
|
||||||
m.addVisibilityListener();
|
m.addVisibilityListener();
|
||||||
|
var driver = opt_member(m.layer.options, 'route_driver');
|
||||||
|
if(driver == nil){
|
||||||
|
driver = RouteDriver.new();
|
||||||
|
}
|
||||||
|
var driver_listeners = driver.getListeners();
|
||||||
|
foreach(var listener; driver_listeners){
|
||||||
|
append(m.listeners, setlistener(listener, func m.layer.update()));
|
||||||
|
}
|
||||||
|
m.route_driver = driver;
|
||||||
return m;
|
return m;
|
||||||
};
|
};
|
||||||
var del = func() {
|
var del = func() {
|
||||||
|
@ -35,21 +46,49 @@ var del = func() {
|
||||||
removelistener(l);
|
removelistener(l);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var last_result = [];
|
||||||
|
|
||||||
var searchCmd = func {
|
var searchCmd = func {
|
||||||
# FIXME: do we return the current route even if it isn't active?
|
# FIXME: do we return the current route even if it isn't active?
|
||||||
printlog(_MP_dbg_lvl, "Running query: ", name);
|
printlog(_MP_dbg_lvl, "Running query: ", name);
|
||||||
var plans = []; # TODO: multiple flightplans?
|
var plans = []; # TODO: multiple flightplans?
|
||||||
|
var plans = [];
|
||||||
|
var driver = me.route_driver;
|
||||||
|
driver.update();
|
||||||
|
if(!driver.shouldUpdate()) return me.last_result;
|
||||||
# http://wiki.flightgear.org/Nasal_Flightplan
|
# http://wiki.flightgear.org/Nasal_Flightplan
|
||||||
var fp = flightplan();
|
var planCount = driver.getNumberOfFlightPlans();
|
||||||
var fpSize = fp.getPlanSize();
|
for (var idx = 0; idx < planCount; idx += 1) {
|
||||||
if (!getprop(me.layer.options.active_node)) fpSize = 0;
|
#var fp = driver.getFlightPlan(idx);
|
||||||
var coords = [];
|
var fpSize = driver.getPlanSize(idx);
|
||||||
for (var i=0; i<fpSize; i += 1) {
|
if(fpSize < 2) continue;
|
||||||
var leg = fp.getWP(i);
|
var type = driver.getFlightPlanType(idx);
|
||||||
coords ~= leg.path();
|
if(type == nil) type = 'current';
|
||||||
|
if (!getprop(me.layer.options.active_node) and
|
||||||
|
type == 'current' and
|
||||||
|
!me.layer.options.display_inactive_rte) fpSize = 0;
|
||||||
|
var coords = [];
|
||||||
|
var discontinuity = 0;
|
||||||
|
for (var i=0; i<fpSize; i += 1) {
|
||||||
|
var leg = driver.getWP(idx, i);
|
||||||
|
if(discontinuity)
|
||||||
|
coords ~= [{},{lon:leg.wp_lon, lat:leg.wp_lat}];
|
||||||
|
else
|
||||||
|
coords ~= leg.path();
|
||||||
|
discontinuity = driver.hasDiscontinuity(idx, leg.id);
|
||||||
|
}
|
||||||
|
append(plans, {
|
||||||
|
id: type,
|
||||||
|
#name: type,
|
||||||
|
type: type,
|
||||||
|
path: coords,
|
||||||
|
#size: fpSize,
|
||||||
|
equals: func(o){
|
||||||
|
me.id == o.id# and me.size == o.size
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
append(plans, coords);
|
me.last_result = plans;
|
||||||
return plans;
|
return plans;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,31 @@ SymbolLayer.get(name).df_style = { # style to use by default
|
||||||
color: [1,0,1]
|
color: [1,0,1]
|
||||||
};
|
};
|
||||||
|
|
||||||
var init = func {
|
var getLineStyle = func(property, df_val){
|
||||||
me.element.setColor(me.style.color)
|
var type = nil;
|
||||||
.setStrokeLineWidth(me.style.line_width);
|
if(typeof(me.model) == 'hash'){
|
||||||
|
type = me.model.type;
|
||||||
|
}
|
||||||
|
if(type != nil and type != 'current'){
|
||||||
|
var base_prop = property;
|
||||||
|
property = property~'_'~type;
|
||||||
|
me.getStyle(property, me.getStyle(base_prop, df_val));
|
||||||
|
} else {
|
||||||
|
me.getStyle(property, df_val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var setRouteStyle = func{
|
||||||
|
var df_style = SymbolLayer.get(name).df_style;
|
||||||
|
var dash = me.getLineStyle('line_dash', []);
|
||||||
|
var color = me.getLineStyle('color', df_style.color);
|
||||||
|
var line_width = me.getLineStyle('line_width', df_style.line_width);
|
||||||
|
me.element.setColor(color).setStrokeLineWidth(line_width);
|
||||||
|
if(typeof(dash) == 'vector')
|
||||||
|
me.element.setStrokeDashArray(dash);
|
||||||
|
};
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
me.setRouteStyle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
104
Nasal/canvas/map/RWY-profile.lcontroller
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
|
||||||
|
var name = 'RWY-profile';
|
||||||
|
var parents = [SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
SymbolLayer.Controller.add(name, __self__);
|
||||||
|
SymbolLayer.add(name, {
|
||||||
|
parents: [MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options: { # default configuration options
|
||||||
|
disable_position: 1,
|
||||||
|
dep_rwy: '/autopilot/route-manager/departure/runway',
|
||||||
|
dest_rwy: '/autopilot/route-manager/destination/runway',
|
||||||
|
dep_arpt: '/autopilot/route-manager/departure/airport',
|
||||||
|
dest_arpt: '/autopilot/route-manager/destination/airport'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
layer.searcher._equals = func(l,r) {l.equals(r)}; # TODO: create model objects instead?
|
||||||
|
#append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ));
|
||||||
|
#m.addVisibilityListener();
|
||||||
|
var driver = opt_member(m.layer.options, 'route_driver');
|
||||||
|
if(driver == nil){
|
||||||
|
driver = RouteDriver.new();
|
||||||
|
}
|
||||||
|
var driver_listeners = driver.getListeners();
|
||||||
|
foreach(var listener; driver_listeners){
|
||||||
|
append(m.listeners, setlistener(listener, func m.layer.update()));
|
||||||
|
}
|
||||||
|
m.route_driver = driver;
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
|
||||||
|
var del = func() {
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var FPRunwayModel = {
|
||||||
|
new: func(apt, rwy){
|
||||||
|
var m = {
|
||||||
|
parents: [FPRunwayModel],
|
||||||
|
id: rwy.id,
|
||||||
|
lat: rwy.lat,
|
||||||
|
lon: rwy.lon,
|
||||||
|
length: rwy.length,
|
||||||
|
width: rwy.width,
|
||||||
|
heading: rwy.heading,
|
||||||
|
airport_id: apt.id
|
||||||
|
};
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
latlon: func(){
|
||||||
|
return [
|
||||||
|
me.lat,
|
||||||
|
me.lon
|
||||||
|
];
|
||||||
|
},
|
||||||
|
equals: func(o){me.id == o.id and me.airport_id == o.airport_id}
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
#var desApt = airportinfo(getprop(me.layer.options.dest_arpt));
|
||||||
|
#var depApt = airportinfo(getprop(me.layer.options.dep_arpt));
|
||||||
|
#if(desApt == nil and depApt == nil)
|
||||||
|
# return [];
|
||||||
|
var res = [];
|
||||||
|
var desRwy = nil;
|
||||||
|
var depRwy = nil;
|
||||||
|
|
||||||
|
var driver = me.route_driver;
|
||||||
|
if(!driver.shouldUpdate()) return res;
|
||||||
|
driver.update();
|
||||||
|
var fpcount = driver.getNumberOfFlightPlans();
|
||||||
|
for(var i = 0; i < fpcount; i += 1){
|
||||||
|
if(!driver.shouldUpdate()) continue;
|
||||||
|
var fp = driver.getFlightPlan(i);
|
||||||
|
var depApt = fp.departure;
|
||||||
|
if(depApt != nil){
|
||||||
|
var depRwy = fp.departure_runway;
|
||||||
|
if(depRwy != nil){
|
||||||
|
var model = FPRunwayModel.new(depApt, depRwy);
|
||||||
|
append(res, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var desApt = fp.destination;
|
||||||
|
if(desApt != nil){
|
||||||
|
var desRwy = fp.destination_runway;
|
||||||
|
if(desRwy != nil){
|
||||||
|
var model = FPRunwayModel.new(desApt, desRwy);
|
||||||
|
append(res, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
93
Nasal/canvas/map/RWY-profile.symbol
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
|
||||||
|
# Class things:
|
||||||
|
var name = 'RWY-profile';
|
||||||
|
var parents = [DotSym];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
|
||||||
|
var style = { # style to use by default
|
||||||
|
zoom: 20,
|
||||||
|
color: [1,1,1],
|
||||||
|
center_line_len: 0.75,
|
||||||
|
line_width: 3
|
||||||
|
};
|
||||||
|
|
||||||
|
SymbolLayer.get(name).df_style = style;
|
||||||
|
#var already_drawn = 0;
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
#if(me.already_drawn) return;
|
||||||
|
var lat = me.model.lat;
|
||||||
|
var lon = me.model.lon;
|
||||||
|
var rwyhdg = me.model.heading;
|
||||||
|
var width = me.model.width;
|
||||||
|
var length = me.model.length;
|
||||||
|
var group = me.element;
|
||||||
|
var ctr_len = length * me.getStyle('center_line_len', 0.75);
|
||||||
|
var crds = [];
|
||||||
|
var coord = geo.Coord.new();
|
||||||
|
width = width * me.getStyle('zoom', 20); # Else rwy is too thin to be visible
|
||||||
|
var line_w = me.getStyle('line_width', 3);
|
||||||
|
var color = me.getStyle('color', [1,1,1]);
|
||||||
|
coord.set_latlon(lat, lon);
|
||||||
|
coord.apply_course_distance(rwyhdg, -(ctr_len / 2));
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg, (ctr_len));
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
icon_rwy = group.createChild("path", "rwy-cl")
|
||||||
|
.setStrokeLineWidth(line_w)
|
||||||
|
.setDataGeo([2,4],crds)
|
||||||
|
.setColor(color);
|
||||||
|
#.setStrokeDashArray([10, 20, 10, 20, 10]);
|
||||||
|
#icon_rwy.hide();
|
||||||
|
var crds = [];
|
||||||
|
coord.set_latlon(lat, lon);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg + 90, width/2);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg, length);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
icon_rwy = group.createChild("path", "rwy")
|
||||||
|
.setStrokeLineWidth(line_w)
|
||||||
|
.setDataGeo([2,4,4],crds)
|
||||||
|
.setColor(color);
|
||||||
|
var crds = [];
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg - 90, width);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg, -length);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
coord.apply_course_distance(rwyhdg + 90, width / 2);
|
||||||
|
append(crds,"N"~coord.lat());
|
||||||
|
append(crds,"E"~coord.lon());
|
||||||
|
icon_rwy = group.createChild("path", "rwy")
|
||||||
|
.setStrokeLineWidth(line_w)
|
||||||
|
.setDataGeo([2,4,4,4],crds)
|
||||||
|
.setColor(color);
|
||||||
|
};
|
||||||
|
|
||||||
|
var draw = func{}
|
||||||
|
|
||||||
|
|
||||||
|
#var update = func() {
|
||||||
|
# if (me.controller != nil) {
|
||||||
|
# if (!me.controller.update(me, me.model)) return;
|
||||||
|
# elsif (!me.controller.isVisible(me.model)) {
|
||||||
|
# me.element.hide();
|
||||||
|
# return;
|
||||||
|
# }
|
||||||
|
# } else
|
||||||
|
# me.element.show();
|
||||||
|
# me.draw();
|
||||||
|
#}
|
49
Nasal/canvas/map/SPD-profile.lcontroller
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'SPD-profile';
|
||||||
|
var parents = [canvas.SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
|
||||||
|
var _options = { # default configuration options
|
||||||
|
alts: [100,140,250,260,'wp']
|
||||||
|
};
|
||||||
|
canvas.SymbolLayer.Controller.add(name, __self__);
|
||||||
|
canvas.SymbolLayer.add(name, {
|
||||||
|
parents: [MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options: _options
|
||||||
|
});
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
#map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
layer.searcher._equals = func(a,b) a.getName() == b.getName();
|
||||||
|
#append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() ));
|
||||||
|
#m.addVisibilityListener();
|
||||||
|
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
var del = func() {
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
var results = [];
|
||||||
|
var symNode = props.globals.getNode(me.layer.options.spd_node);
|
||||||
|
if (symNode != nil)
|
||||||
|
foreach (var alt; me.layer.options.alts) {
|
||||||
|
t = 'spd-change-point' ~ '-' ~ alt;
|
||||||
|
#print('SPD-Controller, search for '~t);
|
||||||
|
var n = symNode.getNode(t);
|
||||||
|
if (n != nil and n.getValue('longitude-deg') != nil){
|
||||||
|
#print('SPD-Controller -> Append');
|
||||||
|
append(results, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
40
Nasal/canvas/map/SPD-profile.symbol
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'SPD-profile';
|
||||||
|
var parents = [canvas.SVGSymbol];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
canvas.DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
#canvas.SymbolLayer.get(name).df_style = {
|
||||||
|
# radius: 13,
|
||||||
|
#};
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
var svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_spd_limit.svg';
|
||||||
|
var spd_sym = nil;
|
||||||
|
|
||||||
|
#var init = func {
|
||||||
|
# var name = me.model.getName();
|
||||||
|
# #var radius = me.style.radius;
|
||||||
|
# var sym_group = me.element.createChild("group", name);
|
||||||
|
# sym_group.set("z-index",5);
|
||||||
|
# var color = me.getStyle('color');
|
||||||
|
# var spd_path = sym_group.createChild("path").
|
||||||
|
# setStrokeLineWidth(3).
|
||||||
|
# moveTo(-17,0).
|
||||||
|
# arcSmallCW(17,17,0,34,0).
|
||||||
|
# arcSmallCW(17,17,0,-34,0).
|
||||||
|
# setColor(color).
|
||||||
|
# setColorFill(color).
|
||||||
|
# set("z-index",5);
|
||||||
|
#}
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
# var name = me.model.getName();
|
||||||
|
# var sym_group = me.element.getElementById(name);
|
||||||
|
# sym_group.set('z-index', 5);
|
||||||
|
if(me.spd_sym == nil){
|
||||||
|
me.spd_sym = me.getElementById("airbus-spd-sym");
|
||||||
|
me.spd_sym.setTranslation(-24, -24).set('z-index', 5);
|
||||||
|
}
|
||||||
|
}
|
62
Nasal/canvas/map/VOR-airbus.lcontroller
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name ='VOR-airbus';
|
||||||
|
var parents = [SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
SymbolLayer.Controller.add(name, __self__);
|
||||||
|
SymbolLayer.add(name, {
|
||||||
|
parents: [NavaidSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options: {
|
||||||
|
nav1_frq: 'instrumentation/nav/frequencies/selected-mhz',
|
||||||
|
nav2_frq: 'instrumentation/nav[1]/frequencies/selected-mhz'
|
||||||
|
},
|
||||||
|
df_style: {
|
||||||
|
scale: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
map: layer.map,
|
||||||
|
active_vors: [],
|
||||||
|
navNs: props.globals.getNode("instrumentation").getChildren("nav"),
|
||||||
|
listeners: [],
|
||||||
|
query_type:'vor',
|
||||||
|
};
|
||||||
|
setsize(m.active_vors, size(m.navNs));
|
||||||
|
foreach (var navN; m.navNs) {
|
||||||
|
append(m.listeners, setlistener(
|
||||||
|
navN.getNode("frequencies/selected-mhz"),
|
||||||
|
func m.changed_freq()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
#call(debug.dump, keys(layer));
|
||||||
|
m.changed_freq(update:0);
|
||||||
|
m.addVisibilityListener();
|
||||||
|
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
var del = func() {
|
||||||
|
printlog(_MP_dbg_lvl, name,".lcontroller.del()");
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
# Controller methods
|
||||||
|
var isActive = func(model) {
|
||||||
|
var my_freq = model.frequency/100;
|
||||||
|
foreach (var freq; me.active_vors)
|
||||||
|
if (freq == my_freq) return 1;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
var changed_freq = func(update=1) {
|
||||||
|
#debug.dump(me.active_vors);
|
||||||
|
foreach (var navN; me.navNs)
|
||||||
|
me.active_vors[ navN.getIndex() ] = navN.getValue("frequencies/selected-mhz");
|
||||||
|
if (update) me.layer.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = NavaidSymbolLayer.make('vor');
|
44
Nasal/canvas/map/VOR-airbus.symbol
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Class things:
|
||||||
|
var name = 'VOR-airbus';
|
||||||
|
var parents = [SVGSymbol];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
var element_type = "group"; # we want a group, becomes "me.element"
|
||||||
|
var text_vor = nil;
|
||||||
|
|
||||||
|
var svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg';
|
||||||
|
var vor_sym = nil;
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
if(me.vor_sym == nil)
|
||||||
|
me.vor_sym = me.element.getElementById("airbus-vor-sym");
|
||||||
|
me.vor_sym.setTranslation(-24,-24);
|
||||||
|
if(me.text_vor == nil){
|
||||||
|
var transl = me.getStyle('translation', [25,10]);
|
||||||
|
var text_color = me.getStyle('text_color', [1,1,1]);
|
||||||
|
me.text_vor = me.element.createChild("text")
|
||||||
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
|
.setText(me.model.id)
|
||||||
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
|
.setFontSize(28)
|
||||||
|
.setColor(text_color)
|
||||||
|
.setTranslation(transl);
|
||||||
|
}
|
||||||
|
|
||||||
|
var frq = me.model.frequency;
|
||||||
|
if(frq != nil){
|
||||||
|
var dfcolor = me.getStyle('color', [0.9,0,0.47]);
|
||||||
|
var tuned_color = me.getStyle('tuned_color', [0,0.62,0.84]);
|
||||||
|
frq = frq / 100;
|
||||||
|
var nav1_frq = getprop(me.options.nav1_frq);
|
||||||
|
var nav2_frq = getprop(me.options.nav2_frq);
|
||||||
|
if(nav1_frq == frq or nav2_frq == frq){
|
||||||
|
me.element.setColor(tuned_color);
|
||||||
|
} else {
|
||||||
|
me.element.setColor(dfcolor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
me.text_vor.setColor(me.getStyle('text_color', [1,1,1]));
|
||||||
|
}
|
137
Nasal/canvas/map/WPT-airbus.lcontroller
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'WPT-airbus';
|
||||||
|
var parents = [canvas.SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
|
||||||
|
canvas.SymbolLayer.Controller.add(name, __self__);
|
||||||
|
canvas.SymbolLayer.add(name, {
|
||||||
|
parents: [canvas.MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options: { # default configuration options
|
||||||
|
fix_symbol: func(group){
|
||||||
|
group.createChild('path')
|
||||||
|
.moveTo(-10,0)
|
||||||
|
.lineTo(0,-17)
|
||||||
|
.lineTo(10,0)
|
||||||
|
.lineTo(0,17)
|
||||||
|
.close()
|
||||||
|
.setStrokeLineWidth(3)
|
||||||
|
.setColor(1,1,1)
|
||||||
|
.setScale(1);
|
||||||
|
},
|
||||||
|
vor_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg',
|
||||||
|
airport_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_airport.svg',
|
||||||
|
ndb_symbol: func(group){
|
||||||
|
group.createChild('path')
|
||||||
|
.moveTo(-15,15)
|
||||||
|
.lineTo(0,-15)
|
||||||
|
.lineTo(15,15)
|
||||||
|
.close()
|
||||||
|
.setStrokeLineWidth(3)
|
||||||
|
#.setColor(0.69,0,0.39)
|
||||||
|
#.setTranslation(-24, -24),
|
||||||
|
.setScale(1,1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
df_style: {
|
||||||
|
active_wp_color: [0.4,0.7,0.4],
|
||||||
|
current_wp_color: [1,1,1],
|
||||||
|
translation: {
|
||||||
|
'airport': [-24,-24],
|
||||||
|
'vor': [-24,-24]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggle_cstr: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
layer.searcher._equals = func(a,b) a.equals(b);
|
||||||
|
var driver = opt_member(m.layer.options, 'route_driver');
|
||||||
|
if(driver == nil){
|
||||||
|
driver = RouteDriver.new();
|
||||||
|
}
|
||||||
|
var driver_listeners = driver.getListeners();
|
||||||
|
foreach(var listener; driver_listeners){
|
||||||
|
append(m.listeners, setlistener(listener, func m.layer.update()));
|
||||||
|
}
|
||||||
|
m.route_driver = driver;
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
|
||||||
|
var del = func() {
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var WPTModel = {
|
||||||
|
new: func(fp, idx) {
|
||||||
|
var m = { parents:[WPTModel] };
|
||||||
|
var wp = fp.getWP(idx);
|
||||||
|
|
||||||
|
m.id = wp.id;
|
||||||
|
m.name = wp.wp_name;
|
||||||
|
m.alt = wp.alt_cstr;
|
||||||
|
m.spd = wp.speed_cstr;
|
||||||
|
m.type = wp.wp_type;
|
||||||
|
|
||||||
|
(m.lat,m.lon) = (wp.wp_lat,wp.wp_lon);
|
||||||
|
var is_rwy = (m.type == 'runway');
|
||||||
|
var id_len = size(m.id);
|
||||||
|
if(!is_rwy and id_len < 5){
|
||||||
|
if(id_len == 4 and airportinfo(m.id) != nil)
|
||||||
|
m.navtype = 'airport';
|
||||||
|
else {
|
||||||
|
var navaid = nil;
|
||||||
|
foreach(var t; ['vor', 'ndb']){
|
||||||
|
navaid = navinfo(m.lat, m.lon, t, m.id);
|
||||||
|
if(navaid != nil and size(navaid)){
|
||||||
|
m.navtype = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(navaid == nil or !size(navaid)) m.navtype = 'fix';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.navtype = (is_rwy ? 'rwy' : 'fix');
|
||||||
|
}
|
||||||
|
|
||||||
|
m.wp = wp;
|
||||||
|
idx = wp.index;
|
||||||
|
m.idx = idx;
|
||||||
|
m.is_departure = (idx == 0 and is_rwy);
|
||||||
|
m.is_destination = (idx > 0 and is_rwy);
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
equals: func(other) {
|
||||||
|
# this is set on symbol init, so use this for equality...
|
||||||
|
me.name == other.name and me.alt == other.alt and
|
||||||
|
me.type == other.type and me.idx == other.idx and
|
||||||
|
me.navtype == other.navtype
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
var driver = me.route_driver;
|
||||||
|
if(!driver.shouldUpdate()) return [];
|
||||||
|
driver.update();
|
||||||
|
var result = [];
|
||||||
|
var planCount = driver.getNumberOfFlightPlans();
|
||||||
|
for(var idx = 0; idx < planCount; idx += 1){
|
||||||
|
var fp = driver.getFlightPlan(idx);
|
||||||
|
if(fp == nil) continue;
|
||||||
|
var fpSize = fp.getPlanSize(idx);
|
||||||
|
for (var i = 0; i < fpSize; i+=1){
|
||||||
|
if(!driver.shouldUpdate()) return[];
|
||||||
|
append(result, WPTModel.new(fp, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
137
Nasal/canvas/map/WPT-airbus.symbol
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'WPT-airbus';
|
||||||
|
var parents = [canvas.DotSym];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
canvas.DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
var name = me.model.name;
|
||||||
|
var alt = me.model.alt;
|
||||||
|
var spd = me.model.spd;
|
||||||
|
var wp_group = me.element;
|
||||||
|
me.alt_path = nil;
|
||||||
|
|
||||||
|
var colors = [
|
||||||
|
'wp_color',
|
||||||
|
'current_wp_color',
|
||||||
|
'constraint_color',
|
||||||
|
'active_constraint_color',
|
||||||
|
'missed_constraint_color'
|
||||||
|
];
|
||||||
|
foreach(col; colors){
|
||||||
|
me[col] = me.getStyle(col, me.getOption(col));
|
||||||
|
}
|
||||||
|
|
||||||
|
var idLen = size(me.model.id);
|
||||||
|
var draw_sym = nil;
|
||||||
|
var navtype = me.model.navtype;
|
||||||
|
if (navtype == nil) navtype = 'fix';
|
||||||
|
if(navtype == 'airport')
|
||||||
|
draw_sym = me.options.airport_symbol;
|
||||||
|
elsif(navtype == 'vor')
|
||||||
|
draw_sym = me.options.vor_symbol;
|
||||||
|
elsif(navtype == 'ndb')
|
||||||
|
draw_sym = me.options.ndb_symbol;
|
||||||
|
else
|
||||||
|
draw_sym = me.options.fix_symbol;
|
||||||
|
me.wp_sym = me.element.createChild('group', 'wp-'~ me.model.idx);
|
||||||
|
if(typeof(draw_sym) == 'func')
|
||||||
|
draw_sym(me.wp_sym);
|
||||||
|
elsif(typeof(draw_sym) == 'scalar')
|
||||||
|
canvas.parsesvg(me.wp_sym, draw_sym);
|
||||||
|
var translation = me.getStyle('translation', {});
|
||||||
|
if(contains(translation, navtype)){
|
||||||
|
me.wp_sym.setTranslation(translation[navtype]);
|
||||||
|
}
|
||||||
|
me.text_wps = wp_group.createChild("text", "wp-text-" ~ me.model.idx)
|
||||||
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
|
.setText(me.model.name)
|
||||||
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
|
.setFontSize(28)
|
||||||
|
.setTranslation(25,15)
|
||||||
|
.setColor(1,1,1);
|
||||||
|
me.text_alt = nil;
|
||||||
|
if(alt > 0 or spd > 0){
|
||||||
|
var cstr_txt = "\n";
|
||||||
|
if(alt > 0){
|
||||||
|
if(alt > 10000)
|
||||||
|
cstr_txt ~= sprintf('FL%3.0f', int(alt / 100));
|
||||||
|
else
|
||||||
|
cstr_txt ~= sprintf('%4.0f', int(alt));
|
||||||
|
}
|
||||||
|
if(spd > 0){
|
||||||
|
if(alt > 0) cstr_txt ~= "\n";
|
||||||
|
if(spd <= 1)
|
||||||
|
cstr_txt ~= sprintf('%1.2fM', spd);
|
||||||
|
else
|
||||||
|
cstr_txt ~= sprintf('%3.0fKT', int(spd));
|
||||||
|
}
|
||||||
|
me.text_alt = wp_group.createChild("text", "wp-alt-text-" ~ me.model.idx)
|
||||||
|
.setDrawMode( canvas.Text.TEXT )
|
||||||
|
.setText(cstr_txt)
|
||||||
|
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
|
||||||
|
.setFontSize(28)
|
||||||
|
.setTranslation(25,15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var draw = func{
|
||||||
|
var wp_group = me.element;
|
||||||
|
var alt = me.model.alt;
|
||||||
|
var i = me.model.idx;
|
||||||
|
var vnav_actv = getprop(me.options.ver_ctrl) == me.options.managed_val;
|
||||||
|
var curwp = getprop(me.options.current_wp);
|
||||||
|
if(alt > 0){
|
||||||
|
var wp_d = me.model.wp.distance_along_route;
|
||||||
|
var lvl_off_at = getprop(me.options.level_off_alt);
|
||||||
|
if(lvl_off_at == nil) lvl_off_at = 0;
|
||||||
|
if(me.alt_path == nil){
|
||||||
|
me.alt_path = wp_group.createChild("path").
|
||||||
|
setStrokeLineWidth(4).
|
||||||
|
moveTo(-22,0).
|
||||||
|
arcSmallCW(22,22,0,44,0).
|
||||||
|
arcSmallCW(22,22,0,-44,0);
|
||||||
|
}
|
||||||
|
if(vnav_actv){
|
||||||
|
if(lvl_off_at and (lvl_off_at - wp_d) > 0.5 and curwp == i)
|
||||||
|
me.alt_path.setColor(me.missed_constraint_color);
|
||||||
|
else
|
||||||
|
me.alt_path.setColor(me.active_constraint_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
me.alt_path.setColor(me.constraint_color);
|
||||||
|
if(me.layer.toggle_cstr)
|
||||||
|
me.alt_path.show();
|
||||||
|
else
|
||||||
|
me.alt_path.hide();
|
||||||
|
} else {
|
||||||
|
if(me.alt_path != nil) me.alt_path.hide();
|
||||||
|
}
|
||||||
|
wp_group.set("z-index",4);
|
||||||
|
#var sym = me.element.getElementById('wp-' ~ me.model.idx);
|
||||||
|
if(alt > 0 and me.text_alt != nil){
|
||||||
|
if(vnav_actv)
|
||||||
|
me.text_alt.setColor(me.active_constraint_color);
|
||||||
|
else
|
||||||
|
me.text_alt.setColor(me.constraint_color);
|
||||||
|
}
|
||||||
|
if(i == curwp) {
|
||||||
|
me.wp_sym.setColor(me.current_wp_color);
|
||||||
|
me.text_wps.setColor(me.current_wp_color);
|
||||||
|
} else {
|
||||||
|
me.wp_sym.setColor(me.wp_color);
|
||||||
|
me.text_wps.setColor(me.wp_color);
|
||||||
|
}
|
||||||
|
if(me.model.is_departure or me.model.is_destination){
|
||||||
|
var prop = (me.model.is_departure ? 'departure' : 'destination');
|
||||||
|
var rwy = getprop("/autopilot/route-manager/"~prop~"/runway");
|
||||||
|
if(rwy != nil and size(rwy) > 0){
|
||||||
|
me.wp_sym.hide();
|
||||||
|
} else {
|
||||||
|
me.wp_sym.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,15 @@ var new = func(layer) {
|
||||||
};
|
};
|
||||||
layer.searcher._equals = func(l,r) l.equals(r);
|
layer.searcher._equals = func(l,r) l.equals(r);
|
||||||
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() ));
|
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() ));
|
||||||
|
var driver = opt_member(m.layer.options, 'route_driver');
|
||||||
|
if(driver == nil){
|
||||||
|
driver = RouteDriver.new();
|
||||||
|
}
|
||||||
|
var driver_listeners = driver.getListeners();
|
||||||
|
foreach(var listener; driver_listeners){
|
||||||
|
append(m.listeners, setlistener(listener, func m.layer.update()));
|
||||||
|
}
|
||||||
|
m.route_driver = driver;
|
||||||
m.addVisibilityListener();
|
m.addVisibilityListener();
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
@ -59,12 +68,16 @@ var searchCmd = func {
|
||||||
printlog(_MP_dbg_lvl, "Running query: "~name);
|
printlog(_MP_dbg_lvl, "Running query: "~name);
|
||||||
|
|
||||||
if (!getprop(me.options.active_node)) return [];
|
if (!getprop(me.options.active_node)) return [];
|
||||||
|
var driver = me.route_driver;
|
||||||
var fp = flightplan();
|
driver.update();
|
||||||
var fpSize = fp.getPlanSize();
|
|
||||||
var result = [];
|
var result = [];
|
||||||
for (var i = 0; i < fpSize; i+=1)
|
var planCount = driver.getNumberOfFlightPlans();
|
||||||
append(result, WPT_model.new(fp, i));
|
for(var idx = 0; idx < planCount; idx += 1){
|
||||||
|
var fp = driver.getFlightPlan(idx);
|
||||||
|
var fpSize = fp.getPlanSize(idx);
|
||||||
|
for (var i = 0; i < fpSize; i+=1)
|
||||||
|
append(result, WPT_model.new(fp, i));
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
69
Nasal/canvas/map/WXR_live.lcontroller
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'WXR_live';
|
||||||
|
var parents = [SymbolLayer.Controller];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
SymbolLayer.Controller.add(name, __self__);
|
||||||
|
SymbolLayer.add(name, {
|
||||||
|
parents: [MultiSymbolLayer],
|
||||||
|
type: name, # Symbol type
|
||||||
|
df_controller: __self__, # controller to use by default -- this one
|
||||||
|
df_options: { # default configuration options
|
||||||
|
viewport_radius: 670
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var wxr_tree = "/instrumentation/wxr";
|
||||||
|
|
||||||
|
var new = func(layer) {
|
||||||
|
var m = {
|
||||||
|
parents: [__self__],
|
||||||
|
layer: layer,
|
||||||
|
map: layer.map,
|
||||||
|
listeners: [],
|
||||||
|
};
|
||||||
|
layer.searcher._equals = func(l,r) l.equals(r);
|
||||||
|
m.addVisibilityListener();
|
||||||
|
#io.read_properties(getprop("/sim/fg-root") ~ "/Nasal/canvas/wxr_api.xml", wxr_tree);
|
||||||
|
var saved_conf = getprop("/sim/fg-home") ~ "/Export/wxr_api.xml";
|
||||||
|
if(io.stat(saved_conf) != nil)
|
||||||
|
io.read_properties(saved_conf, wxr_tree);
|
||||||
|
else
|
||||||
|
io.read_properties(getprop("/sim/fg-root") ~ "/Nasal/canvas/wxr_api.xml", wxr_tree);
|
||||||
|
return m;
|
||||||
|
};
|
||||||
|
var del = func() {
|
||||||
|
#print(name~".lcontroller.del()");
|
||||||
|
foreach (var l; me.listeners)
|
||||||
|
removelistener(l);
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchCmd = func {
|
||||||
|
if(me.map.getRange() == nil) return [];
|
||||||
|
var api_key = getprop(wxr_tree~"/api-key");
|
||||||
|
if(!api_key or api_key == '' or api_key == 'YOUR API KEY')
|
||||||
|
return [];
|
||||||
|
var lat = getprop(wxr_tree~"/center/latitude-deg");
|
||||||
|
var lon = getprop(wxr_tree~"/center/longitude-deg");
|
||||||
|
|
||||||
|
if(lat == nil or lon == nil) {
|
||||||
|
var pos = geo.aircraft_position();
|
||||||
|
lat = pos.lat();
|
||||||
|
lon = pos.lon();
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = geo.Coord.new();
|
||||||
|
result.set_latlon(lat, lon);
|
||||||
|
result.rangeNm = me.map.getRange();
|
||||||
|
result.key = api_key;
|
||||||
|
result.res = getprop(wxr_tree~"/resolution");
|
||||||
|
result.ltype = getprop(wxr_tree~"/layer-type");
|
||||||
|
result.smooth = getprop(wxr_tree~"/smooth");
|
||||||
|
result.fetchRad = getprop(wxr_tree~"/fetch-radius");
|
||||||
|
result.equals = func(r){
|
||||||
|
me.ltype == r.ltype and me.fetchRad == r.fetchRad and
|
||||||
|
me.lat == r.lat and me.lon == r.lon
|
||||||
|
};
|
||||||
|
|
||||||
|
return [result];
|
||||||
|
};
|
111
Nasal/canvas/map/WXR_live.symbol
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
# See: http://wiki.flightgear.org/MapStructure
|
||||||
|
# Class things:
|
||||||
|
var name = 'WXR_live';
|
||||||
|
var parents = [DotSym];
|
||||||
|
var __self__ = caller(0)[0];
|
||||||
|
DotSym.makeinstance( name, __self__ );
|
||||||
|
|
||||||
|
var element_type = "group";
|
||||||
|
|
||||||
|
var getWXRImageFilePath = func(){
|
||||||
|
var home = getprop('sim/fg-home');
|
||||||
|
var aircraft = getprop('sim/aircraft');
|
||||||
|
var idx = me.layer.getCanvas()._node.getIndex();
|
||||||
|
return home ~ '/Export/' ~ aircraft ~ '-wxr-'~me.ltype~'-'~idx~'.png';
|
||||||
|
};
|
||||||
|
|
||||||
|
var getWXRAPIUrl = func(lat, lon){
|
||||||
|
var res = me.res;
|
||||||
|
if(me.ltype == "radar"){
|
||||||
|
return "http://api.wunderground.com/api/"~me.key~
|
||||||
|
"/radar/image.png?centerlat="~lat~"¢erlon="~lon~
|
||||||
|
"&radius="~me.fetchRad~"&width="~res~"&height="~res~
|
||||||
|
"&smooth="~me.smooth;
|
||||||
|
} else {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var fetchWXRMap = func(size){
|
||||||
|
if(me.fetching) return;
|
||||||
|
var pos = geo.aircraft_position();
|
||||||
|
var lat = pos.lat();
|
||||||
|
var lon = pos.lon();
|
||||||
|
var url = me.getWXRAPIUrl(lat, lon);
|
||||||
|
var filePath = me.getWXRImageFilePath();
|
||||||
|
if(url == nil) {
|
||||||
|
print(me.name~': No URL!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
me.fetching = 1;
|
||||||
|
http.save(url, filePath)
|
||||||
|
.fail(func(){print(me.name~': Download failed!');})
|
||||||
|
.done(func(){
|
||||||
|
var sz = size * 2;
|
||||||
|
var transl = -size;
|
||||||
|
me.wxlayer.hide();
|
||||||
|
me.wxlayer.setFile(filePath)
|
||||||
|
.setSize(sz, sz)
|
||||||
|
.setTranslation(transl, transl);
|
||||||
|
me.wxlayer.show();
|
||||||
|
me.last_request = getprop("/sim/time/elapsed-sec");
|
||||||
|
})
|
||||||
|
.always(func(){
|
||||||
|
setprop("/instrumentation/wxr/center/latitude-deg", lat);
|
||||||
|
setprop("/instrumentation/wxr/center/longitude-deg", lon);
|
||||||
|
me.fetching = 0;
|
||||||
|
print("[WXR] Live Layer Request: "~url); # Debugging
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var init = func {
|
||||||
|
#print('WXR init');
|
||||||
|
me.fetching = 0;
|
||||||
|
me.key = me.model.key; # API Key from Wunderground API Subscription
|
||||||
|
me.res = me.model.res; # Resolution of image to fetch (default 2048)
|
||||||
|
me.ltype = me.model.ltype; # Layer Type - radar, satellite
|
||||||
|
me.smooth = me.model.smooth; # If we should fetch a smoothened image or the original
|
||||||
|
me.fetchRad = me.model.fetchRad; # Radius of radar layer to fetch
|
||||||
|
me.range = me.model.rangeNm; # Range of Navigation Display
|
||||||
|
me.viewport_radius = me.getOption('viewport_radius', 670);
|
||||||
|
|
||||||
|
me.wxlayer = me.element.createChild("image").set("z-index", -100).hide();
|
||||||
|
|
||||||
|
me.last_request = -210;
|
||||||
|
me.update_interval = 240;
|
||||||
|
|
||||||
|
var r_scaled = (me.fetchRad*me.viewport_radius)/me.range;
|
||||||
|
me.fetchWXRMap(r_scaled);
|
||||||
|
};
|
||||||
|
|
||||||
|
var draw = func {
|
||||||
|
var range = me.layer.map.getRange(); # Range of Navigation Display
|
||||||
|
var update_size = (range != me.range);
|
||||||
|
me.range = range;
|
||||||
|
me.fetchRad = me.model.fetchRad; # Radius of radar layer to fetch
|
||||||
|
#var r_scaled = (me.fetchRad*670)/me.range;
|
||||||
|
var r_scaled = (me.fetchRad*me.viewport_radius)/me.range;
|
||||||
|
var hdg = me.layer.map.getHdg();
|
||||||
|
var rot = 0 - hdg;
|
||||||
|
if(rot < 0) rot = 360 + rot;
|
||||||
|
me.element.setRotation(rot*D2R);
|
||||||
|
if(update_size){
|
||||||
|
print('WXR draw range:'~ me.range);
|
||||||
|
print('Update size: '~r_scaled~'x2 = '~(r_scaled*2));
|
||||||
|
me.wxlayer.hide();
|
||||||
|
me.wxlayer.setSize(2*r_scaled, 2*r_scaled)
|
||||||
|
.setTranslation(-r_scaled, -r_scaled);
|
||||||
|
me.wxlayer.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getprop("/sim/time/elapsed-sec") - me.last_request > me.update_interval) {
|
||||||
|
#print('Fetching WXR map...');
|
||||||
|
me.key = me.model.key; # API Key from Wunderground API Subscription
|
||||||
|
me.res = me.model.res; # Resolution of image to fetch (default 2048)
|
||||||
|
me.ltype = me.model.ltype; # Layer Type - radar, satellite
|
||||||
|
me.smooth = me.model.smooth; # If we should fetch a smoothened image or the original
|
||||||
|
|
||||||
|
me.fetchWXRMap(r_scaled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -22,6 +22,8 @@ io.include("Nasal/canvas/map/navdisplay.styles");
|
||||||
# encapsulate hdg/lat/lon source, so that the ND may also display AI/MP aircraft in a pilot-view at some point (aka stress-testing)
|
# encapsulate hdg/lat/lon source, so that the ND may also display AI/MP aircraft in a pilot-view at some point (aka stress-testing)
|
||||||
# TODO: this predates aircraftpos.controller (MapStructure) should probably be unified to some degree ...
|
# TODO: this predates aircraftpos.controller (MapStructure) should probably be unified to some degree ...
|
||||||
|
|
||||||
|
var wxr_live_tree = "/instrumentation/wxr";
|
||||||
|
|
||||||
var NDSourceDriver = {};
|
var NDSourceDriver = {};
|
||||||
NDSourceDriver.new = func {
|
NDSourceDriver.new = func {
|
||||||
var m = {parents:[NDSourceDriver]};
|
var m = {parents:[NDSourceDriver]};
|
||||||
|
@ -78,6 +80,10 @@ var default_switches = {
|
||||||
'toggle_true_north': {path: '/mfd/true-north', value:0, type:'BOOL'},
|
'toggle_true_north': {path: '/mfd/true-north', value:0, type:'BOOL'},
|
||||||
'toggle_rangearc': {path: '/mfd/rangearc', value:0, type:'BOOL'},
|
'toggle_rangearc': {path: '/mfd/rangearc', value:0, type:'BOOL'},
|
||||||
'toggle_track_heading':{path: '/trk-selected', value:0, type:'BOOL'},
|
'toggle_track_heading':{path: '/trk-selected', value:0, type:'BOOL'},
|
||||||
|
'toggle_weather_live': {path: '/mfd/wxr-live-enabled', value: 0, type: 'BOOL'},
|
||||||
|
'toggle_chrono': {path: '/inputs/CHRONO', value: 0, type: 'INT'},
|
||||||
|
'toggle_xtrk_error': {path: '/mfd/xtrk-error', value: 0, type: 'BOOL'},
|
||||||
|
'toggle_trk_line': {path: '/mfd/trk-line', value: 0, type: 'BOOL'},
|
||||||
};
|
};
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -118,6 +124,10 @@ var NavDisplay = {
|
||||||
# listeners for cockpit switches
|
# listeners for cockpit switches
|
||||||
listen_switch: func(s,c) {
|
listen_switch: func(s,c) {
|
||||||
# print("event setup for: ", id(c));
|
# print("event setup for: ", id(c));
|
||||||
|
if (!contains(me.efis_switches, s)) {
|
||||||
|
print('EFIS Switch not defined: '~ s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
me.listen( me.get_full_switch_path(s), func {
|
me.listen( me.get_full_switch_path(s), func {
|
||||||
# print("listen_switch triggered:", s, " callback id:", id(c) );
|
# print("listen_switch triggered:", s, " callback id:", id(c) );
|
||||||
c();
|
c();
|
||||||
|
@ -133,11 +143,22 @@ var NavDisplay = {
|
||||||
# helper method for getting configurable cockpit switches (which are usually different in each aircraft)
|
# helper method for getting configurable cockpit switches (which are usually different in each aircraft)
|
||||||
get_switch: func(s) {
|
get_switch: func(s) {
|
||||||
var switch = me.efis_switches[s];
|
var switch = me.efis_switches[s];
|
||||||
|
if(switch == nil) return nil;
|
||||||
var path = me.efis_path ~ switch.path ;
|
var path = me.efis_path ~ switch.path ;
|
||||||
#print(s,":Getting switch prop:", path);
|
#print(s,":Getting switch prop:", path);
|
||||||
|
|
||||||
return getprop( path );
|
return getprop( path );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# helper method for setting configurable cockpit switches (which are usually different in each aircraft)
|
||||||
|
set_switch: func(s, v) {
|
||||||
|
var switch = me.efis_switches[s];
|
||||||
|
if(switch == nil) return nil;
|
||||||
|
var path = me.efis_path ~ switch.path ;
|
||||||
|
#print(s,":Getting switch prop:", path);
|
||||||
|
|
||||||
|
setprop( path, v );
|
||||||
|
},
|
||||||
|
|
||||||
# for creating NDs that are driven by AI traffic instead of the main aircraft (generalization rocks!)
|
# for creating NDs that are driven by AI traffic instead of the main aircraft (generalization rocks!)
|
||||||
connectAI: func(source=nil) {
|
connectAI: func(source=nil) {
|
||||||
|
@ -159,6 +180,12 @@ var NavDisplay = {
|
||||||
NavDisplay.id +=1;
|
NavDisplay.id +=1;
|
||||||
var m = { parents : [NavDisplay]};
|
var m = { parents : [NavDisplay]};
|
||||||
|
|
||||||
|
var df_toggles = keys(default_switches);
|
||||||
|
foreach(var toggle_name; df_toggles){
|
||||||
|
if(!contains(switches, toggle_name))
|
||||||
|
switches[toggle_name] = default_switches[toggle_name];
|
||||||
|
}
|
||||||
|
|
||||||
m.inited = 0;
|
m.inited = 0;
|
||||||
|
|
||||||
m.timers=[];
|
m.timers=[];
|
||||||
|
@ -166,6 +193,7 @@ var NavDisplay = {
|
||||||
m.aircraft_source = NDSourceDriver.new(); # uses the main aircraft as the driver/source (speeds, position, heading)
|
m.aircraft_source = NDSourceDriver.new(); # uses the main aircraft as the driver/source (speeds, position, heading)
|
||||||
|
|
||||||
m.nd_style = NDStyles[style]; # look up ND specific stuff (file names etc)
|
m.nd_style = NDStyles[style]; # look up ND specific stuff (file names etc)
|
||||||
|
m.style_name = style;
|
||||||
|
|
||||||
m.radio_list=["instrumentation/comm/frequencies","instrumentation/comm[1]/frequencies",
|
m.radio_list=["instrumentation/comm/frequencies","instrumentation/comm[1]/frequencies",
|
||||||
"instrumentation/nav/frequencies", "instrumentation/nav[1]/frequencies"];
|
"instrumentation/nav/frequencies", "instrumentation/nav[1]/frequencies"];
|
||||||
|
@ -197,7 +225,7 @@ var NavDisplay = {
|
||||||
m.mk_minimums = props.globals.getNode("instrumentation/mk-viii/inputs/arinc429/decision-height");
|
m.mk_minimums = props.globals.getNode("instrumentation/mk-viii/inputs/arinc429/decision-height");
|
||||||
|
|
||||||
# TODO: these are switches, can be unified with switch handling hash above (eventually):
|
# TODO: these are switches, can be unified with switch handling hash above (eventually):
|
||||||
m.nd_plan_wpt = m.efis.initNode("inputs/plan-wpt-index", 0, "INT"); # not yet in switches hash
|
m.nd_plan_wpt = m.efis.initNode("inputs/plan-wpt-index", -1, "INT"); # not yet in switches hash
|
||||||
|
|
||||||
###
|
###
|
||||||
# initialize all switches based on the defaults specified in the switch hash
|
# initialize all switches based on the defaults specified in the switch hash
|
||||||
|
@ -212,13 +240,28 @@ var NavDisplay = {
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
},
|
},
|
||||||
newMFD: func(canvas_group, parent=nil, options=nil, update_time=0.05)
|
newMFD: func(canvas_group, parent=nil, nd_options=nil, update_time=0.05)
|
||||||
{
|
{
|
||||||
if (me.inited) die("MFD already was added to scene");
|
if (me.inited) die("MFD already was added to scene");
|
||||||
me.inited = 1;
|
me.inited = 1;
|
||||||
|
me.range_dependant_layers = [];
|
||||||
|
me.always_update_layers = {};
|
||||||
me.update_timer = maketimer(update_time, func me.update() );
|
me.update_timer = maketimer(update_time, func me.update() );
|
||||||
me.nd = canvas_group;
|
me.nd = canvas_group;
|
||||||
me.canvas_handle = parent;
|
me.canvas_handle = parent;
|
||||||
|
me.df_options = nil;
|
||||||
|
if (contains(me.nd_style, 'options'))
|
||||||
|
me.df_options = me.nd_style.options;
|
||||||
|
nd_options = default_hash(nd_options, me.df_options);
|
||||||
|
me.options = nd_options;
|
||||||
|
me.route_driver = nil;
|
||||||
|
if (contains(me.options, 'route_driver')) {
|
||||||
|
me.route_driver = me.options.route_driver;
|
||||||
|
}
|
||||||
|
elsif (contains(me.options, 'defaults')) {
|
||||||
|
if(contains(me.options.defaults, 'route_driver'))
|
||||||
|
me.route_driver = me.options.defaults.route_driver;
|
||||||
|
}
|
||||||
|
|
||||||
# load the specified SVG file into the me.nd group and populate all sub groups
|
# load the specified SVG file into the me.nd group and populate all sub groups
|
||||||
|
|
||||||
|
@ -245,10 +288,19 @@ var NavDisplay = {
|
||||||
"HdgBugCRT2","TrkBugLCD2","HdgBugLCD2","hdgBug2","selHdgLine","selHdgLine2","curHdgPtr2",
|
"HdgBugCRT2","TrkBugLCD2","HdgBugLCD2","hdgBug2","selHdgLine","selHdgLine2","curHdgPtr2",
|
||||||
"staArrowL","staArrowR","staToL","staFromL","staToR","staFromR"] )
|
"staArrowL","staArrowR","staToL","staFromL","staToR","staFromR"] )
|
||||||
me.symbols[element] = me.nd.getElementById(element).updateCenter();
|
me.symbols[element] = me.nd.getElementById(element).updateCenter();
|
||||||
|
|
||||||
|
var map_rect = [124, 1024, 1024, 0];
|
||||||
|
var map_opts = me.options.map;
|
||||||
|
if (map_opts == nil) map_opts = {};
|
||||||
|
if (typeof(map_opts.rect) == 'vector')
|
||||||
|
map_rect = map_opts.rect;
|
||||||
|
map_rect = join(', ', map_rect);
|
||||||
|
|
||||||
me.map = me.nd.createChild("map","map")
|
me.map = me.nd.createChild("map","map")
|
||||||
.set("clip", "rect(124, 1024, 1024, 0)")
|
.set("clip", map_rect)
|
||||||
.set("screen-range", 700);
|
.set("screen-range", 700);
|
||||||
|
var z_idx = map_opts['z-index'];
|
||||||
|
if (z_idx != nil) me.map.set('z-index', z_idx);
|
||||||
|
|
||||||
me.update_sub(); # init some map properties based on switches
|
me.update_sub(); # init some map properties based on switches
|
||||||
|
|
||||||
|
@ -323,6 +375,7 @@ var NavDisplay = {
|
||||||
|
|
||||||
me.layers={}; # storage container for all ND specific layers
|
me.layers={}; # storage container for all ND specific layers
|
||||||
# look up all required layers as specified per the NDStyle hash and do the initial setup for event handling
|
# look up all required layers as specified per the NDStyle hash and do the initial setup for event handling
|
||||||
|
var default_opts = me.options != nil and contains(me.options, 'defaults') ? me.options.defaults : nil;
|
||||||
foreach(var layer; me.nd_style.layers) {
|
foreach(var layer; me.nd_style.layers) {
|
||||||
if(layer['disabled']) continue; # skip this layer
|
if(layer['disabled']) continue; # skip this layer
|
||||||
#print("newMFD(): Setting up ND layer:", layer.name);
|
#print("newMFD(): Setting up ND layer:", layer.name);
|
||||||
|
@ -332,16 +385,33 @@ var NavDisplay = {
|
||||||
the_layer = me.layers[layer.name] = canvas.MAP_LAYERS[layer.name].new( me.map, layer.name, controller );
|
the_layer = me.layers[layer.name] = canvas.MAP_LAYERS[layer.name].new( me.map, layer.name, controller );
|
||||||
else {
|
else {
|
||||||
printlog(_MP_dbg_lvl, "Setting up MapStructure-based layer for ND, name:", layer.name);
|
printlog(_MP_dbg_lvl, "Setting up MapStructure-based layer for ND, name:", layer.name);
|
||||||
var opt = options != nil and options[layer.name] != nil ? options[layer.name] :nil;
|
var opt = me.options != nil and me.options[layer.name] != nil ? me.options[layer.name] : nil;
|
||||||
# print("Options is: ", opt!=nil?"enabled":"disabled");
|
if (opt == nil and contains(layer, 'options'))
|
||||||
|
opt = layer.options;
|
||||||
|
if (opt != nil and default_opts != nil)
|
||||||
|
opt = default_hash(opt, default_opts);
|
||||||
|
#elsif(default_opts != nil)
|
||||||
|
# opt = default_opts;
|
||||||
|
var style = nil;
|
||||||
|
if(contains(layer, 'style'))
|
||||||
|
style = layer.style;
|
||||||
|
#print("Options is: ", opt!=nil?"enabled":"disabled");
|
||||||
|
#debug.dump(opt);
|
||||||
me.map.addLayer(
|
me.map.addLayer(
|
||||||
factory: canvas.SymbolLayer,
|
factory: canvas.SymbolLayer,
|
||||||
type_arg: layer.name,
|
type_arg: layer.name,
|
||||||
options:opt,
|
opts: opt,
|
||||||
visible:0,
|
visible:0,
|
||||||
|
style: style,
|
||||||
priority: layer['z-index']
|
priority: layer['z-index']
|
||||||
);
|
);
|
||||||
the_layer = me.layers[layer.name] = me.map.getLayer(layer.name);
|
the_layer = me.layers[layer.name] = me.map.getLayer(layer.name);
|
||||||
|
if(opt != nil and contains(opt, 'range_dependant')){
|
||||||
|
if(opt.range_dependant)
|
||||||
|
append(me.range_dependant_layers, the_layer);
|
||||||
|
}
|
||||||
|
if(contains(layer, 'always_update'))
|
||||||
|
me.always_update_layers[layer.name] = layer.always_update;
|
||||||
if (1) (func {
|
if (1) (func {
|
||||||
var l = layer;
|
var l = layer;
|
||||||
var _predicate = l.predicate;
|
var _predicate = l.predicate;
|
||||||
|
@ -443,15 +513,28 @@ var NavDisplay = {
|
||||||
}
|
}
|
||||||
|
|
||||||
# First, update the display position of the map
|
# First, update the display position of the map
|
||||||
|
var oldRange = me.map.getRange();
|
||||||
var pos = {
|
var pos = {
|
||||||
lat: nil, lon: nil,
|
lat: nil, lon: nil,
|
||||||
alt: nil, hdg: nil,
|
alt: nil, hdg: nil,
|
||||||
range: nil,
|
range: nil,
|
||||||
};
|
};
|
||||||
# reposition the map, change heading & range:
|
# reposition the map, change heading & range:
|
||||||
if(me.in_mode('toggle_display_mode', ['PLAN']) and getprop(me.efis_path ~ "/inputs/plan-wpt-index") >= 0) {
|
var pln_wpt_idx = getprop(me.efis_path ~ "/inputs/plan-wpt-index");
|
||||||
pos.lat = getprop("/autopilot/route-manager/route/wp["~getprop(me.efis_path ~ "/inputs/plan-wpt-index")~"]/latitude-deg");
|
if(me.in_mode('toggle_display_mode', ['PLAN']) and pln_wpt_idx >= 0) {
|
||||||
pos.lon = getprop("/autopilot/route-manager/route/wp["~getprop(me.efis_path ~ "/inputs/plan-wpt-index")~"]/longitude-deg");
|
if(me.route_driver != nil){
|
||||||
|
var wp = me.route_driver.getPlanModeWP(pln_wpt_idx);
|
||||||
|
if(wp != nil){
|
||||||
|
pos.lat = wp.wp_lat;
|
||||||
|
pos.lon = wp.wp_lon;
|
||||||
|
} else {
|
||||||
|
pos.lat = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/latitude-deg");
|
||||||
|
pos.lon = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/longitude-deg");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pos.lat = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/latitude-deg");
|
||||||
|
pos.lon = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/longitude-deg");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pos.lat = userLat;
|
pos.lat = userLat;
|
||||||
pos.lon = userLon;
|
pos.lon = userLon;
|
||||||
|
@ -463,7 +546,14 @@ var NavDisplay = {
|
||||||
pos.range = me.rangeNm(); # avoid this here, use a listener instead
|
pos.range = me.rangeNm(); # avoid this here, use a listener instead
|
||||||
pos.hdg = userHdgTrkTru;
|
pos.hdg = userHdgTrkTru;
|
||||||
}
|
}
|
||||||
|
if(me.options != nil and (var pos_callback = me.options['position_callback']) != nil)
|
||||||
|
pos_callback(me, pos);
|
||||||
call(me.map.setPos, [pos.lat, pos.lon], me.map, pos);
|
call(me.map.setPos, [pos.lat, pos.lon], me.map, pos);
|
||||||
|
if(pos.range != oldRange){
|
||||||
|
foreach(l; me.range_dependant_layers){
|
||||||
|
l.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
# each model should keep track of when it last got updated, using current lat/lon
|
# each model should keep track of when it last got updated, using current lat/lon
|
||||||
# in update(), we can then check if the aircraft has traveled more than 0.5-1 nm (depending on selected range)
|
# in update(), we can then check if the aircraft has traveled more than 0.5-1 nm (depending on selected range)
|
||||||
|
@ -472,7 +562,13 @@ var NavDisplay = {
|
||||||
update: func() # FIXME: This stuff is still too aircraft specific, cannot easily be reused by other aircraft
|
update: func() # FIXME: This stuff is still too aircraft specific, cannot easily be reused by other aircraft
|
||||||
{
|
{
|
||||||
var _time = systime();
|
var _time = systime();
|
||||||
|
# Disables WXR Live if it's not enabled. The toggle_weather_live should be common to all
|
||||||
|
# ND instances.
|
||||||
|
var wxr_live_enabled = getprop(wxr_live_tree~'/enabled');
|
||||||
|
if(wxr_live_enabled == nil or wxr_live_enabled == '')
|
||||||
|
wxr_live_enabled = 0;
|
||||||
|
me.set_switch('toggle_weather_live', wxr_live_enabled);
|
||||||
|
|
||||||
call(me.update_sub, nil, nil, caller(0)[0]); # call this in the same namespace to "steal" its variables
|
call(me.update_sub, nil, nil, caller(0)[0]); # call this in the same namespace to "steal" its variables
|
||||||
|
|
||||||
# MapStructure update!
|
# MapStructure update!
|
||||||
|
@ -481,17 +577,26 @@ var NavDisplay = {
|
||||||
} else {
|
} else {
|
||||||
# TODO: ugly list here
|
# TODO: ugly list here
|
||||||
# FIXME: use a VOLATILE layer helper here that handles TFC, APS, WXR etc ?
|
# FIXME: use a VOLATILE layer helper here that handles TFC, APS, WXR etc ?
|
||||||
me.map.update(func(layer) (var n=layer.type) == "TFC" or n == "APS");
|
var update_layers = me.always_update_layers;
|
||||||
|
me.map.update(func(layer) contains(update_layers, layer.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Other symbol update
|
# Other symbol update
|
||||||
# TODO: should be refactored!
|
# TODO: should be refactored!
|
||||||
if(me.in_mode('toggle_display_mode', ['PLAN']))
|
var translation_callback = nil;
|
||||||
me.map.setTranslation(512,512);
|
if(me.options != nil)
|
||||||
elsif(me.get_switch('toggle_centered'))
|
translation_callback = me.options['translation_callback'];
|
||||||
me.map.setTranslation(512,565);
|
if(typeof(translation_callback) == 'func'){
|
||||||
else
|
var trsl = translation_callback(me);
|
||||||
me.map.setTranslation(512,824);
|
me.map.setTranslation(trsl.x, trsl.y);
|
||||||
|
} else {
|
||||||
|
if(me.in_mode('toggle_display_mode', ['PLAN']))
|
||||||
|
me.map.setTranslation(512,512);
|
||||||
|
elsif(me.get_switch('toggle_centered'))
|
||||||
|
me.map.setTranslation(512,565);
|
||||||
|
else
|
||||||
|
me.map.setTranslation(512,824);
|
||||||
|
}
|
||||||
|
|
||||||
if(me.get_switch('toggle_rh_vor_adf') == 1) {
|
if(me.get_switch('toggle_rh_vor_adf') == 1) {
|
||||||
me.symbols.vorR.setText("VOR R");
|
me.symbols.vorR.setText("VOR R");
|
||||||
|
|