plot_denoyer.lua


NAME
    plot_denoyer

NOTES
    Plot package for Denoyer map projection.
   
    Example:
       
    require("plot_denoyer")
    plot = plot_denoyer.new(400, 250)
    plot:coastlines("./data/gshhs_c.b", 1, {0, 0, 1, 1}, true)
    plot:grids(15, 1, {.5, .5, .5, 1})
    plot:show()

SOURCE

require("register")
require("denoyer_proj")

local P = {}

if _REQUIREDNAME == nil then
    plot_aitoff = P
else
    _G[_REQUIREDNAME] = P
end

function P.new(width, height)
    P.width = width
    P.height = height
    
    local render, scene, root, plot = zeGrf.new("render", "scene", "node", "plot")
    
    render:add(scene)
    render:set{size = {width, height}}
    scene:set{node = root, viewport = {0, 0, width, height}}
    root:add(plot)

    P.render = render
    P.root = root
    P.plot = plot
    
    P.xscale = .9
    P.yscale = .9
    plot:scale(P.xscale, P.yscale, 1)
    plot:set{axis = "x", offset = {0, -P.height * P.yscale / 2, 0},
             range = {-4, 4}, showticks = false, showlabels = false}
    plot:set{axis = "y", offset = {-P.width * P.xscale / 2, 0, 0},
             range = {-2, 2}, showticks = false, showlabels = false}
   
    return P
end

function P.show(self)
    require("towindow")
    towindow(self.render, self.width, self.height)
end

function P.save(self, fname)
    self.render:tofile(fname)
end

function P.scale(self, xscale, yscale)
    self.xscale = xscale
    self.yscale = yscale
    self.plot:scale(self.xscale, self.yscale, 1)
    self.plot:set{axis = "x", offset = {0, -self.height * self.yscale / 2, 0}}
    self.plot:set{axis = "y", offset = {-self.width * self.xscale / 2, 0, 0}}
end

function P.translate(self, dx, dy)
    self.root:translate(dx, dy, 0)
end

function P.add(self, object, position)
    if (position) then
        self.plot:add(object, position)
    else
        self.plot:add(object)
    end
end

function P.coastlines(self, fname, linewidth, color, Atlantic)
    local line, xyz = zeGrf.new("line", "vertex")
    line:set{type = "lines", vertex = xyz}
    if (color) then line:set{color = color} end
    if (linewidth > 0) then line:set{solid = linewidth} end
    self.plot:add(line)
    local arr, lon, lat, bio = zeUtl.new("double", "double", "double", "bio")
    bio:open(fname)
	if Atlantic then
    	bio:gshhs("land", 0, 180, -90, 90, arr)
    	arr:getarr(0, lon)
    	arr:getarr(1, lat)
    	denoyer_proj(lon, lat)
    	arr:setarr(0, lon)
    	arr:setarr(1, lat)
    	arr:insert(2, 0)
        xyz:add(arr)
        bio:rewind()
    	bio:gshhs("land", 180, 360, -90, 90, arr)
    	arr:getarr(0, lon)
    	lon:sub(360)
    	arr:getarr(1, lat)
    	denoyer_proj(lon, lat)
    	arr:setarr(0, lon)
    	arr:setarr(1, lat)
    	arr:insert(2, 0)
        xyz:add(arr)
	else
    	bio:gshhs("land", 0, 360, -90, 90, arr)
    	arr:getarr(0, lon)
    	lon:sub(180)
    	arr:getarr(1, lat)
    	denoyer_proj(lon, lat)
    	arr:setarr(0, lon)
    	arr:setarr(1, lat)
    	arr:insert(2, 0)
        xyz:add(arr)
    end
end

function P.grids(self, step, linewidth, color)
    local line, xyz = zeGrf.new("line", "vertex")
    line:set{type = "lines", vertex = xyz}
    if (color) then line:set{color = color} end
    if (linewidth > 0) then line:set{solid = linewidth} end
    self.plot:add(line)
    local d = 1
    for y = -90, 90, step do
        for x = -180, 180, d do
            local x2, y2 = denoyer_proj(x, y)
            xyz:add(x2, y2, 0)
            x2, y2 = denoyer_proj(x+d, y)
            xyz:add(x2, y2, 0)
        end
    end
    for x = -180, 180, 2 * step do
        for y = -90, 89, d do
            x2, y2 = denoyer_proj(x, y)
            xyz:add(x2, y2, 0)
            x2, y2 = denoyer_proj(x, y+d)
            xyz:add(x2, y2, 0)
        end
    end
end