41
edits
m (http://otile1.mqcdn.com is offline. Changed for https://maps.wikimedia.org) |
|||
Line 634: | Line 634: | ||
var tile_size = 256; | var tile_size = 256; | ||
var window = canvas.Window.new([width, height],"dialog") | var window = canvas.Window.new([width, height],"dialog").set('title', "Tile map demo"); | ||
var g = window.getCanvas(1).createGroup(); | |||
var g = window.getCanvas(1) | |||
# Simple user interface (Buttons for zoom and label for displaying it) | # Simple user interface (Buttons for zoom and label for displaying it) | ||
var zoom = 10; | var zoom = 10; | ||
var type = " | var type = "intl"; | ||
var ui_root = window.getCanvas().createGroup(); | var ui_root = window.getCanvas().createGroup(); | ||
Line 648: | Line 646: | ||
var button_in = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}) | 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)); | |||
var button_out = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}) | |||
button_in.setSizeHint([32, 32]); | button_in.setSizeHint([32, 32]); | ||
button_out.setSizeHint([32, 32]); | button_out.setSizeHint([32, 32]); | ||
Line 685: | Line 679: | ||
# (also see http://wiki.openstreetmap.org/wiki/Tile_usage_policy) | # (also see http://wiki.openstreetmap.org/wiki/Tile_usage_policy) | ||
var makeUrl = | var makeUrl = | ||
string.compileTemplate('https://maps.wikimedia.org/osm-{type}/{z}/{x}/{y}.png'); | |||
var makePath = | #https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}.png | ||
string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}. | var makePath = | ||
var num_tiles = [4, 3]; | string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.png'); | ||
var num_tiles = [4, 3]; | |||
var center_tile_offset = [ | var center_tile_offset = [ | ||
(num_tiles[0] - 1) / 2, | (num_tiles[0] - 1) / 2, | ||
(num_tiles[1] - 1) / 2 | (num_tiles[1] - 1) / 2 | ||
]; | ]; | ||
# simple aircraft icon at current position/center of the map | # simple aircraft icon at current position/center of the map | ||
g.createChild("path") | 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", 2) | |||
.set("z-index", 1); | |||
## | ## | ||
Line 715: | Line 710: | ||
tiles[x] = setsize([], num_tiles[1]); | tiles[x] = setsize([], num_tiles[1]); | ||
for(var y = 0; y < num_tiles[1]; y += 1) | for(var y = 0; y < num_tiles[1]; y += 1) | ||
tiles[x][y] = g.createChild("image", "map-tile"); | |||
} | } | ||
Line 732: | Line 727: | ||
var n = math.pow(2, zoom); | var n = math.pow(2, zoom); | ||
var offset = [ | 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 tile_index = [int(offset[0]), int(offset[1])]; | ||
Line 741: | Line 736: | ||
for(var x = 0; x < num_tiles[0]; x += 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] | 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 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 img_path = makePath(pos); | ||
var tile = tiles[x][y]; | var tile = tiles[x][y]; | ||
Line 767: | Line 762: | ||
print('requesting ' ~ img_url); | print('requesting ' ~ img_url); | ||
http.save(img_url, img_path) | 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 # cached image found, reusing | else # cached image found, reusing | ||
Line 778: | Line 773: | ||
} | } | ||
last_tile = tile_index; | |||
last_type = type; | |||
} | |||
}; | }; | ||
## | ## | ||
Line 799: | Line 794: | ||
window.del = func() | window.del = func() | ||
{ | { | ||
print("Cleaning up window:", | print("Cleaning up window:", ,"\n"); | ||
update_timer.stop(); | update_timer.stop(); | ||
# explanation for the call() technique at: http://wiki.flightgear.org/Object_oriented_programming_in_Nasal#Making_safer_base-class_calls | # explanation for the call() technique at: http://wiki.flightgear.org/Object_oriented_programming_in_Nasal#Making_safer_base-class_calls | ||
call(canvas.Window.del, [], me); | |||
}; | }; | ||
edits