How do I draw multiple points from multiple lat longs pairs?

I have an array in storage called track, it looks a bit like this.

[56.8967, 0.7654, 53,8736, 0.9832, 50,6453, 0,0773….etc]
As you can see, multiple lat and longs, the array is of no fixed size.

Currently I have only managed to draw the first lat lon in the array.

//By transforming them with this:


function TransformCoordinates(lat, lon) {

var Me = [240/2,240/2];

var track = Application.Storage.getValue(“track”);

var pixelsLong = (120 - lon) * (4/screenWidthPixels);

var pixelsLat = (lat - 120) * (4/screenHeightPixels);

var x = Me[1] - pixelsLong;

var y = Me[0] - pixelsLat;

return [x,y]; }

//Then drawing them with this:

function onUpdate(dc) {

var track = [x,y];

dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);

for(var i=0; i<track.size();i=i+2){
var pointA=track[i];

var pointB=track[i+1];

dc.setPenWidth(8) 

dc.drawPoint(pointA,pointB);}

Help in drawing all these points is much appreciated.

  • I'm not sure if I understood it correctly, but it's quite easy to draw a straight line connecting two points with Graphics.drawLine().

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Graphics/Dc.html#drawLine-instance_function

    By saving the coordinates of the last point, you've the pair of points, i.e. lastPoint and actualPoint, which can be connected with drawLine() and so on.

  • like this if that helps.

    I’m confused how to go about it. I’ve got dc.drawCircle(displayX, displayY, 2); or whatever

    for each point using the code you provided.

    Do I just do something like

    dc.drawLine(displayX[i], displayY[i], displayX[i+1], displayY[i+1]); 

    Would that work?

  • I think we move away from your OP. The theme of your OP is "How do I draw multiple points from multiple lat longs pairs?" and afterwards you wanted

    "Would you be willing to provide an example I can use instead to draw the points?"

    Therefore I've coded a raw example how to may solve this with using drawCircle() which are drawing the points. If you'ld like to draw the connections between the points instead, then you've to use drawLine(), like e.g.

    // set graphics rendering
    dc.setColor(...);
    dc.setPenWidth(...);
    
    // using 1-dim array like 
    // track[lat1,lon1,lat2,lon2,lat3,...}
    for(i=0; i < (track.size() - 2), i+=2) {
        // calculate point locations in pixels
        var pixelsLon = (track[i+3] - track[i+1]) * scaleXY;
        var pixelsLat = (track[i+2] - track[i])   * scaleXY;
    
        // adjust point locations to a reference point
        var displayX = pixelsLon + pixelsXRef;
        var displayY = pixelsLat + pixelsYRef;
    
        // draw points
    	dc.fillCircle(displayX, displayY, 2);
    	
    	// draw lines
    	if (i == 0) {
    	    var displayXOld = displayX;
    	    var displayYOld = displayY;
    
    	} else {
    	    dc.drawLine(displayXOld, displayYOld, displayX, displayY);
    	    displayXOld = displayX;
    	    displayYOld = displayY;
        }	 
    }
    ...
    

    This is only an example that points out how you may solve this, especially it's not perfect code because it depends on the rest of the program.

  • Yes, Originally when I made thr post I should have included the drawing line functionality, I can see how it hs got a bit confusing, i’ll play around with the code you’ve provided later, thankyou.

  • if(lat != null){
    var lonMax = -180.0;
    var lonMin = 180.0;
    var latMax = -90.0;
    var latMin = 90.0;
    for(var i=0; i < lat.size(); i++) {
    lonMax = (lonMax > lon[i]) ? lonMax : lon[i];
    lonMin = (lonMin < lon[i]) ? lonMin : lon[i];
    latMax = (latMax > lat[i]) ? latMax : lat[i];
    latMin = (latMin < lat[i]) ? latMin : lat[i];
    System.println("lonmax = " + lonMax);
    System.println("latmax = " + latMax);
    System.println("lonmin = " + lonMin);
    System.println("latmin = " + latMin);
    }
    
    var scaleX = dc.getWidth() / (lonMax - lonMin);
    var scaleY = dc.getHeight() / (latMax - latMin);
    var scaleXY = (scaleX < scaleY) ? scaleX : scaleY;
    
    dc.setColor(Graphics.COLOR_PURPLE, Graphics.COLOR_TRANSPARENT);
    dc.setPenWidth(4);
    for(var i=0; i < (lat.size() - 2); i+=2){
    var pixelsLon = (lon[i+1] - lon[i]) * scaleXY;
    var pixelsLat = (lat[i+1] - lat[i]) * scaleXY;
    
    var displayX = pixelsLon + 120; // screenwidth
    var displayY = pixelsLat + 120; //screenheight
    
    dc.fillCircle(displayX, displayY, 3);
    if (i == 0) {
    var displayXOld = displayX;
    var displayYOld = displayY;
    
    } else {
    var displayXOld = displayX;
    var displayYOld = displayY;
    System.println("dxold and dyold" + displayXOld + displayYOld);
    System.println("dx and dy" + displayX + displayY);
    dc.drawLine(displayXOld, displayYOld, displayX, displayY);
    }
    }}

    So this is the code for drawing the lines and points, I provided it all so you can get a clearer insight into what I'm using. It is slightly modified from what you most recently provided (not a 1-dim array), it draws the points but for some reason not the lines.

  • For drawing a line you need two points, a starting point and an end point. The line should be drawed and subsequently the starting point should be updated with the end point for advancing to the next loop. So you can't change the order of the statements, i.e. first draw the line and then update the old point.

    I've cleaned up and simplyfied your code a little and hope it runs w/o errors ;)

    
    if(lat != null){
        var lonMax = -180.0;
        var lonMin = 180.0;
        var latMax = -90.0;
        var latMin = 90.0;
    
        for(var i=0; i < lat.size(); i++) {
            lonMax = (lonMax > lon[i]) ? lonMax : lon[i];
            lonMin = (lonMin < lon[i]) ? lonMin : lon[i];
            latMax = (latMax > lat[i]) ? latMax : lat[i];
            latMin = (latMin < lat[i]) ? latMin : lat[i];
            System.println("lonmax = " + lonMax);
            System.println("latmax = " + latMax);
            System.println("lonmin = " + lonMin);
            System.println("latmin = " + latMin);
        }
    
        var scaleX = dc.getWidth() / (lonMax - lonMin);
        var scaleY = dc.getHeight() / (latMax - latMin);
        var scaleXY = (scaleX < scaleY) ? scaleX : scaleY;
    
        dc.setColor(Graphics.COLOR_PURPLE, Graphics.COLOR_TRANSPARENT);
        dc.setPenWidth(4);
    
        var pixelsLon;
        var pixelsLat;
        var displayX;
        var displayY;
        var displayXOld;
        var displayYOld;
        for(var i=0; i < (lat.size() - 2); i+=2){
            pixelsLon = (lon[i+1] - lon[i]) * scaleXY;
            pixelsLat = (lat[i+1] - lat[i]) * scaleXY;
    
            displayX = pixelsLon + 120; // screenwidth
            displayY = pixelsLat + 120; //screenheight
    
            dc.fillCircle(displayX, displayY, 3);
    
            if (i > 0) {
                dc.drawLine(displayXOld, displayYOld, displayX, displayY);
            }
    		
            displayXOld = displayX;
            displayYOld = displayY;
            System.println("dxold and dyold" + displayXOld + displayYOld);
            System.println("dx and dy" + displayX + displayY);
        }
    }

  • Right, gotcha, i’ll test it out tomorrow when i’m back at the computer.

  • Ok it worked, it draws the lines and dots, I had to add “= null” to the variables displayXOld and var displayYOld like so to solve an intialization error:

    var displayXOld = null;

    var displayYOld = null;

    Now that it draws the lines I notice two problems

    Note how the background map moves according to your position but the track does not. Heres an example where I change position.

    As you can see the purple line is the drawn route, the blue line I added in microsoft paint and marks where the route should be. 

    How can I get the purple line to stay where the blue line is?

    The second problem is that the route doesn’t appear to be scaled to the map. 

    Other than that it is working perfectly.

  • Again, we are moving further away from your OP. So far the route is only scaled to the screen size. If you want to draw the positions depending on the map size, I recommend you to use the MapSample which is part of the SDK.

    C:\User\<User>\AppData\Roaming\Garmin\ConnectIQ\Sdks\<sdk>\samples\MapSample

  • You appear to be trying to overlay on a MapView. so you will have to use MapPolyLines to keep your track co-ordinated with the scale and positioning of the map.