print("*** LOADING MAP.nas ... ***"); var zoom = 10; var width = 768; var height = 576; #------------------------------------------------------------------------------- thanks to Harbal1 #=============================================================================== # FUNCTIONS #------------------------------------------------------------------------------- # draw_arc # this function draws an arc # params : # - element : canvas object created by createChild() # - center_x : coord x of the center of the arc in px # - center_y : coord y of the center of the arc in px # - radius : radius # - start_angle : start angle in deg () # - end_angle : end angle in deg () # - color : color # - line_width : line_width # var draw_arc = func(element, center_x, center_y, radius, start_angle, end_angle, color, line_width) { var coord_start_x = center_x + (radius * math.cos(start_angle * D2R)); var coord_start_y = center_y - (radius * math.sin(start_angle * D2R)); var to_x = -(radius * math.cos(start_angle * D2R)) + (radius * math.cos(end_angle * D2R)); var to_y = (radius * math.sin(start_angle * D2R)) - (radius * math.sin(end_angle * D2R)); element.setStrokeLineWidth(line_width) .set("stroke", color) .moveTo(coord_start_x, coord_start_y) .arcSmallCCW(radius, radius, 0, to_x, to_y); print("coord_start_x:"~coord_start_x~"| coord_start_y:"~coord_start_y~"| radius:"~ radius ~"| to_x:"~to_x~"| to_y:"~ to_y); } #------------------------------------------------------------------------------- # draw_piste # this function creates a piste # # params : # - element : canvas object created by createChild() # var draw_piste = func(element) { element.setStrokeLineWidth(5) .set("stroke", "rgba(40, 240, 40, 1)") .moveTo(-13, 13) .lineTo(-13, -13) .moveTo(13, 13) .lineTo(13, -13); # creation du vecteur vitesse+cap de la cible element.setStrokeLineWidth(4) .set("stroke", "rgba(40, 240, 40, 1)") .moveTo(0, 0) .lineTo(0, 0); element.setStrokeLineWidth(4) .set("stroke", "rgba(40, 240, 40, 1)") .moveTo(-12, 11) .lineTo(12, 11) .moveTo(-12, -11) .lineTo(12, -11); } #------------------------------------------------------------------------------- # update_piste # this function updates piste - length of vector = distance in 15s # # params : # - element : canvas object created by createChild() # - FIXME ... # var update_piste = func(element, my_heading, my_alt, target_heading, target_alt, target_speed, pixel_range, radar_range) { var vector_x = ((target_speed * pixel_range / radar_range) / 240) * math.sin((target_heading - my_heading) * D2R); var vector_y = ((target_speed * pixel_range / radar_range) / 240) * math.cos((target_heading - my_heading) * D2R); if((target_alt - 1000 ) < my_alt) { element._node.getNode("coord[12]", 1).setValue(-12); } else { element._node.getNode("coord[12]", 1).setValue(12); } if((target_alt + 1000 ) > my_alt) { element._node.getNode("coord[16]", 1).setValue(-12); } else { element._node.getNode("coord[16]", 1).setValue(12); } element._node.getNode("coord[8]", 1).setValue(vector_x); element._node.getNode("coord[9]", 1).setValue(-vector_y); } #------------------------------------------------------------------------------- # update_piste_fl # this function updates flight level piste label position # # params : # - element : canvas object created by createChild() # - FIXME ... # var update_piste_fl = func(element, my_heading, target_heading) { var vector_x = -30 * math.sin((target_heading - my_heading) * D2R); var vector_y = 30 * math.cos((target_heading - my_heading) * D2R); element.setTranslation(vector_x, vector_y); } var MAPCanvas = { canvas_settings: { "name": "PFD-Test", # The name is optional but allow for easier identification "size": [1024, 1024], # Size of the underlying texture (should be a power of 2, required) [Resolution] "view": [width, height], # Virtual resolution (Defines the coordinate system of the canvas [Dimensions] # which will be stretched the size of the texture, required) "mipmapping": 1 # Enable mipmapping (optional) }, new: func(placement) { var m = { parents: [MAPCanvas], canvas: canvas.new(MAPCanvas.canvas_settings) }; ## Base for the canvas m.canvas.addPlacement(placement); m.root = m.canvas.createGroup(); m.mapStuff = m.root.createChild("group"); m.radarStuff = m.root.createChild("group"); #Should be replaced by rwr #MAP stuff m.g_front = m.mapStuff.createChild("group"); m.g_back = m.mapStuff.createChild("group"); #Aircraft orientation/position stuff m.myHeadingProp = props.globals.getNode("orientation/heading-deg"); m.myCoord = geo.aircraft_position(); #Center of the canvas m.root.setCenter(384,256); ##MAP stuff : Set up of the tiles m.tile_size = 256; m.num_tiles = [4, 3]; m.type = "map"; m.home = props.globals.getNode("/sim/fg-home"); m.maps_base = m.home.getValue() ~ '/cache/maps'; #---------------- Make the url where to take the tiles ------------ #Some alternative can exist # http://otile1.mqcdn.com/tiles/1.0.0/map # http://otile1.mqcdn.com/tiles/1.0.0/sat # (also see http://wiki.openstreetmap.org/wiki/Tile_usage_policy) #var makeUrl = string.compileTemplate('http://{server}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg'); #var servers = ["otile1", "otile2", "otile3", "otile4"]; m.makeUrl = string.compileTemplate('http://{server}.tile.osm.org/{z}/{x}/{y}.png'); m.servers = ["a", "b", "c"]; m.makePath = string.compileTemplate(m.maps_base ~ '/osm-{type}/{z}/{x}/{y}.png'); #Setting up red little aircraft m.center_tile_offset = [ (m.num_tiles[0] - 1) / 2, (m.num_tiles[1] - 1) / 2 ]; # simple aircraft icon at current position/center of the map m.filename = "Nasal/littleaircraftRed.svg"; m.svg_symbol = m.root.createChild("group"); canvas.parsesvg(m.svg_symbol, m.filename); m.svg_symbol.setScale(0.05); m.svg_symbol.setTranslation((width/2)-20,height/2-45); m.myVector = m.svg_symbol.getBoundingBox(); #svg_symbol.setCenter(width/2,height/2); m.svg_symbol.updateCenter(); m.svg_symbol.set("z-index", 1); var make_tiles = func (canvas_group) { var tiles = setsize([], m.num_tiles[0]); for (var x = 0; x < m.num_tiles[0]; x += 1) { tiles[x] = setsize([], m.num_tiles[1]); for (var y = 0; y < m.num_tiles[1]; y += 1) { tiles[x][y] = canvas_group.createChild("image", "map-tile"); } } return tiles; } #MAP Stuff m.tiles_front = make_tiles(m.g_front); m.tiles_back = make_tiles(m.g_back); m.use_front = 1; m.last_tile = [-1,-1]; m.last_type = m.type; ##ETC all needed for MAP and RWR canvas m.zoom = 10; m.update_timer = nil; ## RADAR STUFF ## m.MapToggle = 1; ## creation des arcs "range" #m.arc_range1 = m.radarStuff.createChild("path", "arc_range1"); ##m.arc_range1.moveTo(334,256).arcSmallCCW(50, 50, 0, 434, 256); #m.arc_range1.setStrokeLineWidth(3) #.moveTo(484, 256) #.set("stroke", "rgba(100, 100, 100, 1)") #.arcSmallCCW(100, 100, 0, -200, 0) #.arcSmallCCW(100, 100, 0, 200, 0); # draw_arc(m.arc_range1, 384,256 , 100 , 0, 180, "rgba(100, 100, 100, 1)", 3); return m; }, changeZoomMap: func(d) { new_zoom = math.max(2, math.min(15, me.zoom + d)); if (new_zoom != me.zoom) { me.zoom = new_zoom; #debug.dump(zoom); #updateTiles(); } }, updateTiles: func() { #print("updateTiles is working"); me.svg_symbol.setRotation(me.myHeadingProp.getValue()*D2R); #g.setRotation(myHeadingProp.getValue()*D2R); me.myCoord = geo.aircraft_position(); lat = me.myCoord.lat(); lon = me.myCoord.lon(); var n = math.pow(2, me.zoom); var offset = [ n * ((lon + 180) / 360) - me.center_tile_offset[0], (1 - math.ln(math.tan(lat * math.pi/180) + 1 / math.cos(lat * math.pi/180)) / math.pi) / 2 * n - me.center_tile_offset[1] ]; var tile_index = [int(offset[0]), int(offset[1])]; var ox = tile_index[0] - offset[0]; var oy = tile_index[1] - offset[1]; me.g_front.setVisible(me.use_front); me.g_back.setVisible(!me.use_front); me.use_front = math.mod(me.use_front + 1, 2); for (var x = 0; x < me.num_tiles[0]; x += 1) { for (var y = 0; y < me.num_tiles[1]; y += 1) { if (me.use_front) { me.tiles_back[x][y].setTranslation(int((ox + x) * me.tile_size + 0.5), int((oy + y) * me.tile_size + 0.5)); #debug.dump("updating back"); } else { me.tiles_front[x][y].setTranslation(int((ox + x) * me.tile_size + 0.5), int((oy + y) * me.tile_size + 0.5)); #debug.dump("updating front"); } } } if (tile_index[0] != me.last_tile[0] or tile_index[1] != me.last_tile[1] or me.type != me.last_type) { for (var x = 0; x < me.num_tiles[0]; x += 1) { for (var y = 0; y < me.num_tiles[1]; y += 1) { var server_index = math.round(rand() * (size(me.servers) - 1)); var server_name = me.servers[server_index]; var pos = { z: me.zoom, x: int(offset[0] + x), y: int(offset[1] + y), type: me.type, server: server_name }; (func { var img_path = me.makePath(pos); if (io.stat(img_path) == nil) { var img_url = me.makeUrl(pos); var message = "Requesting %s..."; #printf(message, img_url); http.save(img_url, img_path) .done(func { var message = "Received image %s"; #printf(message, img_path); # if (pos.z == zoom) { # tile.setFile(img_path); # } }) .fail(func (r) { var message = "Failed to get image %s %s: %s"; #printf(message, img_path, r.status, r.reason); me.tiles_back[x-1][y-1].setFile(""); me.tiles_front[x-1][y-1].setFile(""); }); } else { if (pos.z == me.zoom) { var message = "Loading %s"; #printf(message, img_path); me.tiles_back[x][y].setFile(img_path); me.tiles_front[x][y].setFile(img_path); } } })(); } } me.last_tile = tile_index; me.last_type = me.type; } }, updateRadar:func(){ #Rotating aircraft to the front. me.svg_symbol.setRotation(0*D2R); }, changeMfD_Displaying:func(){ #Temporary function : we change the displaying called : mirage2000.changeMfD_Displaying() if(me.MapToggle){ me.mapStuff.hide(); me.radarStuff.show(); me.MapToggle = 0; }else{ me.mapStuff.show(); me.radarStuff.hide(); me.MapToggle = 1; } }, update: func() { #Whatever need to be updated var update_timer = maketimer(0, func(){ #print("Hello World"); if(me.MapToggle){ me.updateTiles(); }else{ me.updateRadar() } }); update_timer.start(); }, #Other function like zoom in/out changing tile index, etc }; var MapCanvas = bae125.MAPCanvas.new({"node": "canvasCadre", "texture": "canvasTex.png"}); MapCanvas.update();