166
edits
(Tile map demo) |
|||
Line 471: | Line 471: | ||
<syntaxhighlight lang="nasal" enclose="div"> | <syntaxhighlight lang="nasal" enclose="div"> | ||
</syntaxhighlight> | |||
|} | |||
== A simple tile map == | |||
{| class="wikitable" | |||
|- | |||
! Screenshot !! Code | |||
|- | |||
| [[File:Canvas - Tile map demo.png|thumb|A simple, canvas based tile map which is centered around the aircraft.]] | |||
| | |||
<syntaxhighlight lang="nasal" enclose="div"> | |||
var window = canvas.Window.new([768, 512],"dialog") | |||
.set('title', "Tile map demo"); | |||
var g = window.getCanvas(1) | |||
.createGroup(); | |||
# Simple user interface (Buttons for zoom and label for displaying it) | |||
var zoom = 10; | |||
var type = "map"; | |||
var ui_root = window.getCanvas().createGroup(); | |||
var vbox = canvas.VBoxLayout.new(); | |||
window.setLayout(vbox); | |||
var button_in = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}) | |||
.setText("+") | |||
.listen("clicked", func changeZoom(1)); | |||
var button_out = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}) | |||
.setText("-") | |||
.listen("clicked", func changeZoom(-1)); | |||
button_in.setSizeHint([32, 32]); | |||
button_out.setSizeHint([32, 32]); | |||
var label_zoom = canvas.gui.widgets.Label.new(ui_root, canvas.style, {}); | |||
var button_box = canvas.HBoxLayout.new(); | |||
button_box.addItem(button_in); | |||
button_box.addItem(label_zoom); | |||
button_box.addItem(button_out); | |||
button_box.addStretch(1); | |||
vbox.addItem(button_box); | |||
vbox.addStretch(1); | |||
var changeZoom = func(d) | |||
{ | |||
zoom = math.max(2, math.min(19, zoom + d)); | |||
label_zoom.setText("Zoom " ~ zoom); | |||
updateTiles(); | |||
} | |||
# http://polymaps.org/docs/ | |||
# https://github.com/simplegeo/polymaps | |||
# https://github.com/Leaflet/Leaflet | |||
var maps_base = getprop("/sim/fg-home") ~ '/cache/maps'; | |||
# 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://otile1.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.jpg'); | |||
var makePath = | |||
string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.jpg'); | |||
var num_tiles = [4, 3]; | |||
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( 256 * center_tile_offset[0] - 10, | |||
256 * center_tile_offset[1] ) | |||
.horiz(20) | |||
.move(-10,-10) | |||
.vert(20) | |||
.set("stroke", "red") | |||
.set("stroke-width", 2) | |||
.set("z-index", 1); | |||
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; | |||
var updateTiles = func() | |||
{ | |||
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) * 256 + 0.5), int((oy + y) * 256 + 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 ) | |||
{ | |||
var img_url = makeUrl(pos); | |||
print('requesting ' ~ img_url); | |||
http.save(img_url, img_path) | |||
.done(func {print('received image ' ~ img_path); tile.set("src", img_path);}) | |||
.fail(func (r) print('Failed to get image ' ~ img_path ~ ' ' ~ r.status ~ ': ' ~ r.reason)); | |||
} | |||
else | |||
{ | |||
print('loading ' ~ img_path); | |||
tile.set("src", img_path) | |||
} | |||
})(); | |||
} | |||
last_tile = tile_index; | |||
last_type = type; | |||
} | |||
}; | |||
var update_timer = maketimer(2, updateTiles); | |||
update_timer.start(); | |||
changeZoom(0); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
|} | |} |
edits