Board index FlightGear Development Canvas

Layer above the map... with .setGeoPosition()

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Layer above the map... with .setGeoPosition()

Postby D-MKF1 » Mon Mar 28, 2022 9:09 pm

Hello,

I want to show a triangular flight through the vertices (no route manager WP) on the map.
The vertices have lat and lon values. The only way that I have been able to implement so far, to make the corner points visible, is that I cannot place them on the map using .setGeoPosition. Can someone help me out? How can I correctly merge the different layers in my example?
Tanks very much.

Image

Code: Select all
var zoom = getprop("/electrical-flight-events/distance/zoom") or 10;
         var type = "intl";
         var tile_size = 256;

         var root = iMAP_display.createGroup();
         var MyMap = root.createChild("map");
        var g = iMAP_display.createGroup();

         MyMap.setController("Aircraft position");
         MyMap.setRange(25);

         MyMap.setTranslation(iMAP_display.get("view[0]")/2, iMAP_display.get("view[1]")/2);
         #var r = func(name,vis=1,zindex=nil) return caller(0)[0];

------- This try overwrite the map tiles......
         # APT and VOR are the layer names
         #foreach(var type; [r('APT'), r('VOR') ] )
         #MyMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: type.zindex,);

         var maps_base = getprop("/sim/fg-home") ~ '/cache/maps';

         # (also see http://wiki.openstreetmap.org/wiki/Tile_usage_policy)
         var makeUrl = string.compileTemplate('https://maps.wikimedia.org/osm-{type}/{z}/{x}/{y}.png');
        var makePath = string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.png');
        var num_tiles = [3, 2];
        var center_tile_offset = [(num_tiles[0] - 1) / 2,(num_tiles[1] - 1) / 2];

         # simple aircraft icon at current position/center of the map
         g.createChild("path")
         .moveTo( tile_size * center_tile_offset[0] - 10,
           tile_size * center_tile_offset[1] )
         .horiz(20)
         .move(-10,-10)
         .vert(20)
         .set("stroke", "red")
         .set("stroke-width", 3)
         .set("z-index", 2);

         var path = "./Aircraft/RR-ACCEL/Models/Cockpit/Instruments/ipad/wp.png";

--------  This MyMap.createChild("image")... won't work
         #MyMap.createChild("image").setFile(path).setGeoPosition(47.88743494, 9.242505981).set("z-index", 2);

-------- This g.createChild("image") will not accept .setGeoPosition because g is not a map chlild.
         g.createChild("image")
         .setFile(path)
         .setGeoPosition(47.88743494, 9.242505981)
         .set("z-index", 2);

         ##
         # initialize the map by setting up
         # a grid of raster images

         var tiles = setsize([], num_tiles[0]);
         for(var x = 0; x < num_tiles[0]; x += 1)
         {
           tiles[x] = setsize([], num_tiles[1]);
           for(var y = 0; y < num_tiles[1]; y += 1)
           tiles[x][y] = g.createChild("image", "map-tile");
         }

         var last_tile = [-1,-1];
         var last_type = type;

         ##
         # this is the callback that will be regularly called by the timer
         # to update the map
         var updateTiles = func()
         {
           # get current position
           var lat = getprop('/position/latitude-deg');
           var lon = getprop('/position/longitude-deg');

           var n = math.pow(2, zoom);
           var offset = [
           n * ((lon + 180) / 360) - center_tile_offset[0],
           (1 - math.ln(math.tan(lat * math.pi/180) + 1 / math.cos(lat * math.pi/180)) / math.pi) / 2 * n - 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];

           for(var x = 0; x < num_tiles[0]; x += 1)
           for(var y = 0; y < num_tiles[1]; y += 1)
           tiles[x][y].setTranslation(int((ox + x) * tile_size + 0.5), int((oy + y) * tile_size + 0.5));

           if(tile_index[0] != last_tile[0] or tile_index[1] != last_tile[1] or type != last_type ){
             for(var x = 0; x < num_tiles[0]; x += 1)
             for(var y = 0; y < num_tiles[1]; y += 1)
             {
               var pos = {
                 z: zoom,
                 x: int(offset[0] + x),
                 y: int(offset[1] + y),
                 type: type
               };

               (func {
                 var img_path = makePath(pos);
                 var tile = tiles[x][y];

                 if( io.stat(img_path) == nil )
                 { # image not found, save in $FG_HOME
                   var img_url = makeUrl(pos);
                   #print('requesting ' ~ img_url);
                   http.save(img_url, img_path)
                   .done(func {tile.set("src", img_path);})
                   .fail(func (r) print('Failed to get image ' ~ img_path ~ ' ' ~ r.status ~ ': ' ~ r.reason));
                 }
                 else # cached image found, reusing
                 {
                   #print('loading ' ~ img_path);
                   tile.set("src", img_path)
                 }
                 })();
               }

               last_tile = tile_index;
               last_type = type;
             }
           };
            updateTiles();
D-MKF1
 
Posts: 99
Joined: Mon Sep 30, 2013 6:03 pm
Version: Git
OS: GNU/Linux | Mac OS X

Re: Layer above the map... with .setGeoPosition()

Postby Hooray » Wed Mar 30, 2022 8:42 am

See the so called "MapStructure" system (wiki), it has built-in support for doing this sort of stuff fairly easily, using different sets of layers that can be customized and adapted if needed.

https://wiki.flightgear.org/Canvas_MapStructure
https://wiki.flightgear.org/Canvas_MapStructure_layers
https://sourceforge.net/p/flightgear/fg ... controller

Image
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Layer above the map... with .setGeoPosition()

Postby D-MKF1 » Wed Mar 30, 2022 1:13 pm

Thank you for passing on the links. I knew they. I've already read the explanations in advance and I can't get any further with them. Hence the entry here in the forum. In the code above you can see where it is stuck. I have marked the relevant passages with -----.
Maybe you can help me specifically. Otherwise nonetheless
Thanks very much,
Marc
D-MKF1
 
Posts: 99
Joined: Mon Sep 30, 2013 6:03 pm
Version: Git
OS: GNU/Linux | Mac OS X


Return to Canvas

Who is online

Users browsing this forum: No registered users and 4 guests