# Metview Macro

# **************************** LICENSE START ***********************************
#
# Copyright 2020 ECMWF. This software is distributed under the terms
# of the Apache License version 2.0. In applying this license, ECMWF does not
# waive the privileges and immunities granted to it by virtue of its status as
# an Intergovernmental Organization or submit itself to any jurisdiction.
#
# ***************************** LICENSE END ************************************

# **************************************************************************
# Function      : mvl_geopolyline
#
# OneLineDesc   : Returns a plot object for a polyline sampled in lat-lon coordinates
#
# Description   : Returns a plot object for a polyline sampled in lat-lon coordinates
# **************************************************************************

function mvl_geopolyline (lats , lons, incrm: number)
    
    fn_name = "mvl_geopolyline"
    
    if incrm < 0 then
        fail(fn_name & ": increment (=" & incrm & ") must be greater than zero!")
    end if
    if count(lats) <> count(lons) then
        fail(fn_name & ": different number of latitudes (=" & count(lats) &
             ") and longitudes (=" & count(lons) & ")!")           
    end if
    if count(lats) < 2 then
        fail(fn_name & ": at least two points are required (only " & 
              count(lats) & " was given)!")
    end if
    
    xcoord = nil
    ycoord = nil
    incrm_ori  = incrm
    
    # we can expose it as an extra argument if needed     
    force_close = 0
    
    if force_close = 1 then
        segment_num = count(lats)
    else
        segment_num = count(lats)-1
    end if
    
    for i=1 to segment_num do 
        lon1 = lons[i]
        lat1 = lats[i]
     
        if force_close and i = segment_num then
            lon2 = lons[1]
            lat2 = lats[1]
        else 
            lon2 = lons[i+1]
            lat2 = lats[i+1]
        end if 
        
        dx = lon2 - lon1
        dy = lat2 - lat1
        incrm = incrm_ori

        if abs(dx) > abs(dy) then
            incr_lon = 1  # increment along longitudes
            if lon1 > lon2 then
                incrm = -incrm
            end if
        else
            incr_lon = 0  # increment along latitudes
            if lat1 > lat2 then
                incrm = -incrm
            end if
        end if


	    # calculate the line equation
        
        # vertical line
    	if dx = 0 then  
        	for y = lat1 to lat2 by incrm do
        		ycoord = ycoord & [y]
        		xcoord = xcoord & [lon1]
        	end for

        	# make sure the last point is included
        	ycoord = ycoord & [lat2]
        	xcoord = xcoord & [lon2]

        # more general case - not a vertical lin
        else
	       a = (lat1 - lat2) / (lon1 - lon2)
	       b = lat1 - a*lon1

            if incr_lon then
        	   for x = lon1 to lon2 by incrm do
        		  xcoord = xcoord & [x]
        		  ycoord = ycoord & [a*x + b]
        	   end for

        	   # make sure the last point is included
        	   xcoord = xcoord & [lon2]
        	   ycoord = ycoord & [a*lon2 + b]
            else
        	   for y = lat1 to lat2 by incrm do
        		  ycoord = ycoord & [y]
        		  xcoord = xcoord & [(y-b)/a]
        	   end for

        	   # make sure the last point is included
        	   ycoord = ycoord & [lat2]
        	   xcoord = xcoord & [(lat2-b)/a]
            end if
        end if
    end for
    
    y_vec = vector(ycoord)
   
	# set up a curve
    vis = input_visualiser
    (
        input_plot_type        :    "geo_points",
        input_longitude_values :    vector(xcoord),
        input_latitude_values  :    y_vec,
        input_values           :    y_vec
     )

	return vis

end mvl_geopolyline
