This commit is contained in:
Dmitry Platonov 2010-04-30 21:41:46 +04:00
commit 7020a51ecc
7 changed files with 746 additions and 0 deletions

View file

@ -0,0 +1,15 @@
#! /bin/bash
rm -f $1
cat osm.sql | grep -vi "CREATE INDEX" | sqlite3 $1
cat spatial.sql | sqlite3 $1
echo "Importing $2 into $1"
./import_osm.pl $1 < $2
echo "Creating indexes"
cat osm.sql | grep -i "CREATE INDEX" | sqlite3 $1
echo 'Analyzing'
sqlite3 $1 'analyze'
echo 'Creating spatial index'
sqlite3 $1 'insert into way_index (id,minLat,maxLat,minLon,maxLon) select way_id,min(lat),max(lat),min(lon),max(lon) from way_node,node where way_node.node_id=node.id group by way_id'
echo 'Creating way coords'
sqlite3 $1 'insert into way_coord_text (id,lat,lon) select way_id,group_concat(lat),group_concat(lon) from (select way_id,lat,lon from way_node,node where node_id=id order by way_id,node_number) group by way_id'

View file

@ -0,0 +1,164 @@
#! /usr/bin/perl -w
use XML::Parser;
use DBI;
use strict;
my $dbname = shift;
my $count = 0;
my $parser = new XML::Parser(ErrorContext => 2);
$parser->setHandlers(Char => \&char_handler,
Start => \&start_handler,
End => \&end_handler);
# Default => \&default_handler);
my $file = shift;
my $dbargs = {AutoCommit => 0,
PrintError => 1,
};
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname","","",$dbargs);
$dbh->do("PRAGMA synchronous = OFF");
if ($dbh->err()) { die "$DBI::errstr\n"; }
print "*\n";
if(defined $file and -f $file){
$parser->parsefile($file);
}
else{
$parser->parse(\*STDIN);
}
$dbh->commit();
$dbh->disconnect();
################
## End of main
################
my $id;
my %tags;
my %node_attrs;
my $node_count = 0;
my $node_id;
my $relation_count = 0;
my $sequence;
my $node_count;
my $way_count;
my $relation_count;
my $way_id;
my $relation_id;
my $node_number;
sub start_handler
{
my( $parseinst, $element, %attrs ) = @_;
SWITCH: {
if ($element eq "node") {
$dbh->do("insert into node (id, lat, lon) values ($attrs{id},$attrs{lat},$attrs{lon})");
if ($dbh->err()) { die "$DBI::errstr\n"; }
$node_count += 1;
if($node_count % 1000 == 0){
print "nodes: ",$node_count,"\n";
}
$node_id = $attrs{id};
if($node_count % 100000 == 0){
$dbh->commit();
if ($dbh->err()) { die "$DBI::errstr\n"; }
# $dbh->begin();
# if ($dbh->err()) { die "$DBI::errstr\n"; }
}
last SWITCH;
}
if ($element eq "way") {
$dbh->do("insert into way (id) values ($attrs{id})");
if ($dbh->err()) { die "$DBI::errstr\n"; }
$way_id = $attrs{id};
$node_number = 0;
$way_count += 1;
if($way_count % 1000 == 0){
print "ways: ",$way_count,"\n";
}
last SWITCH;
}
if ($element eq "relation") {
$dbh->do("insert into relation (id) values ($attrs{id})");
if ($dbh->err()) { die "$DBI::errstr\n"; }
$relation_id = $attrs{id};
$relation_count += 1;
$sequence = 0;
if($relation_count % 1000 == 0){
print "relations: ",$relation_count,"\n";
}
last SWITCH;
}
if ($element eq "nd" and defined $way_id) {
$dbh->do("insert into way_node (way_id,node_id,node_number) values ($way_id,$attrs{ref},$node_number)");
if ($dbh->err()) { die "$DBI::errstr\n"; }
$node_number += 1;
last SWITCH;
}
if ($element eq "tag" ) {
if(defined $way_id){
my $q = "insert into way_tag (id,key,value) values ($way_id,".$dbh->quote($attrs{k}).",".$dbh->quote($attrs{v}).")";
$dbh->do("$q");
if ($dbh->err()) { print $q,"\n"; die "$DBI::errstr\n"; }
}
elsif(defined $node_id){
my $q = "insert into node_tag (id,key,value) values ($node_id,".$dbh->quote($attrs{k}).",".$dbh->quote($attrs{v}).")";
$dbh->do("$q");
if ($dbh->err()) { print $q,"\n"; die "$DBI::errstr\n"; }
}
elsif(defined $relation_id){
my $q = "insert into relation_tag (id,key,value) values ($relation_id,".$dbh->quote($attrs{k}).",".$dbh->quote($attrs{v}).")";
$dbh->do("$q");
if ($dbh->err()) { print $q,"\n"; die "$DBI::errstr\n"; }
}
last SWITCH;
}
if ($element eq "member" ) {
my $q;
if($attrs{type} eq 'node'){
$q = "insert into relation_member_node (id,node_id,role,sequence_number) values ($relation_id,".$dbh->quote($attrs{ref}).",".$dbh->quote($attrs{role}).",$sequence)";
}
if($attrs{type} eq 'way'){
$q = "insert into relation_member_way (id,way_id,role,sequence_number) values ($relation_id,".$dbh->quote($attrs{ref}).",".$dbh->quote($attrs{role}).",$sequence)";
}
if($attrs{type} eq 'relation'){
$q = "insert into relation_member_relation (id,relation_id,role,sequence_number) values ($relation_id,".$dbh->quote($attrs{ref}).",".$dbh->quote($attrs{role}).",$sequence)";
}
$sequence += 1;
if(defined $q){
$dbh->do("$q");
if ($dbh->err()) { print $q,"\n"; die "$DBI::errstr\n"; }
}
}
}
return;
}
sub end_handler
{
my( $parseinst, $element ) = @_;
if($element eq 'way'){
undef $way_id;
}elsif($element eq 'node'){
undef $node_id;
}elsif($element eq 'relation'){
undef $relation_id;
}
return;
}
sub char_handler
{
# This is just here to reduce the noise seen by
# the default handler
return;
} # End of char_handler

View file

@ -0,0 +1,149 @@
#!/usr/bin/perl -w
use DBI;
use Time::HiRes qw(gettimeofday tv_interval);
use strict;
use File::Spec;
use navigator_lib;
my $dbname = $ARGV[0] or die "Usage: ./maketiles.pl database.db";
my $dbargs = {AutoCommit => 0,
PrintError => 1,
};
my $latmin;
my $latmax;
my $lonmin;
my $lonmax;
my $latcenter = 55.75;
my $loncenter = 37.62;
#lat=55.7543&lon=37.6211
#my ( $width, $height ) = ( 240, 320 );
#my ( $width, $height ) = ( 640,480 );
#my $zoom = $width/0.02;
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname","","",$dbargs);
#$dbh->do("PRAGMA synchronous = OFF");
if ($dbh->err()) { die "$DBI::errstr\n"; }
my $i;
my $j;
my $n = 50;
my $tile_step = 0.01;
for($i=-$n;$i<=$n;$i+=1){
for($j=-$n;$j<=$n;$j+=1){
$latmin = $latcenter + $i*$tile_step;
$latmax = $latmin + $tile_step;
$lonmin = $loncenter + $j*$tile_step;
$lonmax = $lonmin + $tile_step;
my $filename = latlon_to_filename($latmin, $lonmin);
my ($vol, $dir, $fname) = File::Spec->splitpath($filename);
# print $vol,$dir," xxx\n";
my $p = '.';
foreach my $cd (File::Spec->splitdir($dir)){
$p = File::Spec->catdir($p, $cd);
mkdir $p;
}
open my $file, '>', $filename or die "create map file: $!";
my $q = 'select way_coord_text.id,lat,lon,key,value from way_index,way_tag,way_coord_text where maxLat >= '.$latmin.' and minLat <= '.$latmax.' and maxLon >= '.$lonmin.' and minLon <= '.$lonmax.' and way_index.id=way_coord_text.id and way_coord_text.id = way_tag.id and (key like \'highway\' or key = \'natural\' or key = \'landuse\'or key=\'building\' or key=\'waterway\' or key=\'leisure\' )';
print $q,"\n";
my $t0 = [gettimeofday];
my $res = $dbh->selectall_arrayref($q);
my $el1 = tv_interval ( $t0, [gettimeofday]);
if ($dbh->err()) { die "$DBI::errstr\n"; }
my $r;
my $way_count=0;
my $node_count=0;
foreach $r (@$res){
my @wlat = split(',', $r->[1]);
my @wlon = split(',', $r->[2]);
my @coord;
$way_count += 1;
while(@wlat){
my ($sx, $sy) = ((shift @wlat), (shift @wlon));
push @coord, $sx, $sy;
$node_count += 1;
}
my $k = $r->[3];
my $v = $r->[4];
if($k eq 'highway' and ($v eq 'primary' or $v eq 'motorway' or $v eq 'trunk')){
line1($file, $r->[0], 1, @coord);
}
elsif($k eq 'highway' and ($v eq 'motorway_link' or $v eq 'trunk_link' or $v eq 'primary_link')){
line1($file, $r->[0], 2, @coord);
}
elsif($k eq 'highway' and $v eq 'secondary'){
line1($file, $r->[0], 3, @coord);
}
elsif($k eq 'highway' and ($v eq 'tertiary' or $v eq 'residential' or $v eq 'living_street')){
line1($file, $r->[0], 4, @coord);
}
elsif($k eq 'highway' and ($v eq 'service' or $v eq 'unclassified')){
line1($file, $r->[0], 5, @coord);
}
elsif($k eq 'building' and $v eq 'yes'){
poly($file, $r->[0], 6, @coord);
}
elsif($k eq 'highway' and $v eq 'footway' or $v eq 'path' or $v eq 'track'){
}
elsif(($k eq 'natural' and $v eq 'wood') or ($k eq 'landuse' and $v eq 'forest') or ($k eq 'leisure' and $v eq 'park')){
poly($file, $r->[0], 7, @coord);
}
elsif($k eq 'highway'){
line1($file, $r->[0], 8, @coord);
}
elsif($k eq 'landuse' and $v eq 'industrial'){
poly($file, $r->[0], 9, @coord);
}
elsif(($k eq 'natural' and $v eq 'water') or ($k eq 'waterway' and $v eq 'riverbank')){
poly($file, $r->[0], 10, @coord);
}
elsif($k eq 'landuse' and $v eq 'residential'){
poly($file, $r->[0], 11, @coord);
}
elsif(($k eq 'waterway' and $v eq 'river')){
line1($file, $r->[0], 12, @coord);
}
elsif(($k eq 'waterway' and $v eq 'stream')){
line1($file, $r->[0], 13, @coord);
}
elsif(($k eq 'landuse' and $v eq 'allotments')){
poly($file, $r->[0], 14, @coord);
}
elsif(($k eq 'landuse')){
poly($file, $r->[0], 15, @coord);
}
}
my $el2 = tv_interval ( $t0, [gettimeofday]);
print "Ways: $way_count nodes: $node_count\n";
print "SQL: $el1 draw: ",$el2-$el1,"\n";
close $file;
}
}
sub line1{
my $a;
my $f = shift;
my $id = shift;
my $t = shift;
print $f "L $id $t";
foreach $a (@_){
print $f " $a";
}
print $f "\n";
return 0;
}
sub poly{
my $a;
my $f = shift;
my $id = shift;
my $t = shift;
print $f "P $id $t";
foreach $a (@_){
print $f " $a";
}
print $f "\n";
return 0;
}

View file

@ -0,0 +1,14 @@
package navigator_lib;
use Exporter;
use base Exporter;
@EXPORT = qw(latlon_to_filename);
sub latlon_to_filename{
my ($i, $j) = @_;
$i = int($i*100+0.5);
$j = int($j*100+0.5);
return "data/".int($i/100).'/'.int($j/100).'/'.($i%100).'/'.($j%100).'.map';
}
1;

View file

@ -0,0 +1,111 @@
create table node (
id INTEGER PRIMARY KEY,
lat FLOAT,
lon FLOAT
);
create table way(
id INTEGER PRIMARY KEY
);
create table way_node (
node_number INTEGER,
way_id INTEGER,
node_id INTEGER,
FOREIGN KEY(way_id) REFERENCES way(id),
FOREIGN KEY(node_id) REFERENCES node(id)
);
CREATE INDEX way_node_way_id_idx on way_node (way_id);
CREATE INDEX way_node_node_id_idx on way_node (node_id);
create table way_tag(
id INTEGER,
key VARCHAR(20),
value VARCHAR(20),
FOREIGN KEY(id) REFERENCES way(id)
);
CREATE INDEX way_tag_id_idx on way_tag (id);
CREATE INDEX way_tag_key_idx on way_tag (key);
CREATE INDEX way_tag_value_idx on way_tag (value);
CREATE INDEX way_tag_key_value_idx on way_tag (key,value);
create table node_tag(
id INTEGER,
key VARCHAR(20),
value VARCHAR(20),
FOREIGN KEY(id) REFERENCES node(id)
);
CREATE INDEX node_tag_id_idx on node_tag (id);
CREATE INDEX node_tag_key_idx on node_tag (key);
CREATE INDEX node_tag_value_idx on node_tag (value);
CREATE INDEX node_tag_key_value_idx on node_tag (key,value);
create table relation(
id INTEGER PRIMARY KEY
);
create table relation_tag(
id INTEGER,
key VARCHAR(20),
value VARCHAR(20),
FOREIGN KEY(id) REFERENCES relation(id)
);
CREATE INDEX relation_tag_id_idx on relation_tag (id);
CREATE INDEX relation_tag_key_idx on relation_tag (key);
CREATE INDEX relation_tag_value_idx on relation_tag (value);
CREATE INDEX relation_tag_key_value_idx on relation_tag (key,value);
create table relation_member_node(
id INTEGER,
node_id INTEGER,
sequence_number INTEGER NOT NULL,
role VARCHAR(20) NOT NULL,
FOREIGN KEY(id) REFERENCES relation(id)
FOREIGN KEY(node_id) REFERENCES node(id)
);
CREATE INDEX relation_member_node_id_idx on relation_member_node (id);
CREATE INDEX relation_member_node_node_id_idx on relation_member_node (node_id);
CREATE INDEX relation_member_node_role_idx on relation_member_node (role);
create table relation_member_way(
id INTEGER,
way_id INTEGER,
sequence_number INTEGER NOT NULL,
role VARCHAR(20) NOT NULL,
FOREIGN KEY(id) REFERENCES relation(id)
FOREIGN KEY(way_id) REFERENCES way(id)
);
CREATE INDEX relation_member_way_id_idx on relation_member_way (id);
CREATE INDEX relation_member_way_way_id_idx on relation_member_way (way_id);
CREATE INDEX relation_member_way_role_idx on relation_member_way (role);
create table relation_member_relation(
id INTEGER,
relation_id INTEGER,
sequence_number INTEGER NOT NULL,
role VARCHAR(20) NOT NULL,
FOREIGN KEY(id) REFERENCES relation(id)
FOREIGN KEY(relation_id) REFERENCES relation(id)
);
CREATE INDEX relation_member_relation_id_idx on relation_member_relation (id);
CREATE INDEX relation_member_relation_relation_id_idx on relation_member_relation (relation_id);
CREATE INDEX relation_member_relation_role_idx on relation_member_relation (role);
-- CREATE VIEW pt_route AS SELECT id,value AS type FROM relation_tag WHERE key = 'route' AND value IN ('bus', 'trolleybus', 'tram');
create view pt_route as select id,value as type from relation_tag where key = 'route' and value in ('bus', 'trolleybus', 'tram') and id in (select id from relation_tag where key = 'type' and value = 'route');
-- create view pt_route_ref as select pt_route.id as id, pt_route.type as type,value as ref from pt_route,relation_tag where pt_route.id = relation_tag.id and key='ref';
create view pt_route_ref as select pt_route.id as id, pt_route.type as type,value as ref from pt_route,relation_tag where relation_tag.id in (select id from pt_route) and pt_route.id = relation_tag.id and key='ref';
-- create view pt_way as select distinct way_id as id,type,ref from relation_member_way,pt_route_ref where relation_member_way.id = pt_route_ref.id;
create view pt_way_ref as select distinct way_id as id,type,ref from pt_route_ref,relation_member_way where relation_member_way.id = pt_route_ref.id;
create view pt_way_id as select distinct way_id as id from pt_route_ref,relation_member_way where relation_member_way.id = pt_route_ref.id;
--create view pt_way_node as select way_id,node_id from way_node where way_id in (select id from pt_way_id);
create view pt_way_node as select way_id,node_id,node_number from way_node where way_id in (select id from pt_way_id);
create view pt_stop as select distinct id,node_id from relation_member_node where id in (select id from pt_route) and role in ('forward:stop','backward:stop','stop');
create view pt_stop_ref as select distinct node_id as id,type,ref from pt_route_ref,relation_member_node where relation_member_node.id = pt_route_ref.id;

View file

@ -0,0 +1,16 @@
CREATE VIRTUAL TABLE way_index USING rtree(
id, -- Integer primary key
minLat, maxLat, -- Minimum and maximum X coordinate
minLon, maxLon -- Minimum and maximum Y coordinate
);
CREATE TABLE way_coord(
id INTEGER PRIMARY KEY,
coord BLOB
);
CREATE TABLE way_coord_text(
id INTEGER PRIMARY KEY,
lat TEXT,
lon TEXT
);

277
src/kothic.py Executable file
View file

@ -0,0 +1,277 @@
#!/usr/bin/env python
#use Cairo;
#import cairo
#use Gtk2 '-init';
import pygtk
pygtk.require('2.0')
import gtk
import cairo
import math
import string
import threading
import time
import Queue
#use Glib qw(TRUE FALSE);
#use Time::HiRes qw(gettimeofday tv_interval);
#use strict;
#use POSIX qw(ceil floor);
#use style qw(@style);
#use navigator_lib;
#my $dbname = "moscow.db";
#my $dbargs = {AutoCommit => 0,
# PrintError => 1,
#};
#
#my $latmin;
#my $latmax;
#my $lonmin;
#my $lonmax;
#my $latcenter = 55.6304;
#my $loncenter = 37.49305;
class Renderer(threading.Thread):
def __init__(self, comm):
self.comm = comm
threading.Thread.__init__(self)
def run(self):
print ("Thread started")
self.tc = {}
while(True):
while(True):
request = self.comm[0].get()
if(self.comm[0].empty):
break
print (" got request:", request)
res = RasterTile(request[2][0], request[2][1])
res.update_surface(request[0][0], request[0][1], request[1], self.tc, request[3])
print (" render complete")
comm[1].put(res)
class Navigator:
def __init__(self, comm):
self.comm = comm
self.lat_c = 55.6304
self.lon_c = 37.49305
self.width, self.height = 640, 480
self.zoom = self.width/0.02;
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.dx = 0
self.dy = 0
self.drag = False
self.tilecache = {}
self.border = 200
self.rastertile = None
self.f = True
undef = None
self.style = [
[None, None, None, 0],
[undef, [6.0, [0,0,0]], [4.0, [1, 1, .7]], 1],
[undef, [4.5, [0,0,0]], [2.5, [1, 1, .7]], 2],
[undef, [3.5, [0,0,0]], [2.5, [1, 1, .7]], 3],
[undef, [2.8, [0,0,0]], [2.0, [1, 1, 1]], 4],
[undef, undef, [1.0, [1, 1, 1]], 5],
[undef, [0, [0.7, 0.4, 0.4]], undef, 6],
[[1, [0.30, 0.5, 0.30]], undef, undef, 7],
[undef, undef, [2, [1, 0.3, 0.3]], 8],
[[0, [0.7, 0.6, 0.6]], undef, undef, 9],
[[0, [0.4, 0.4, 1.0]], undef, undef, 10],
[[0, [0.6, 0.6, 0.6]], undef, undef, 11],
[undef, [3.5, [0.4, 0.4, 1.0]], undef, 12],
[undef, [2, [0.4, 0.4, 1.0]], undef, 13],
[[0, [0.72, 0.51, 0.32]], undef, undef, 14],
[[0, [1, 0.0, 0.0]], undef, undef, 0] #unknown landuse
]
da = gtk.DrawingArea()
da.add_events(gtk.gdk.BUTTON1_MOTION_MASK)
da.add_events(gtk.gdk.POINTER_MOTION_MASK)
da.add_events(gtk.gdk.BUTTON_PRESS_MASK)
da.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
# self.window.add_events(gtk.gdk.BUTTON1_MOTION_MASK)
da.connect("expose_event",self.expose_ev)
da.connect("motion_notify_event",self.motion_ev)
da.connect("button_press_event",self.press_ev)
da.connect("button_release_event",self.release_ev)
self.da = da
# self.surface = cairo.ImageSurfaceicreate(gtk.RGB24, self.width, self.height)
self.window.set_size_request(self.width, self.height)
self.window.add(da)
self.window.connect("delete_event", self.delete_ev)
def motion_ev(self, widget, event):
# print("Motion")
if self.drag:
self.dx = event.x - self.drag_x
self.dy = event.y - self.drag_y
if((abs(self.dx) > 100 or abs(self.dy) > 100) and self.f):
self.comm[0].put((self.rastertile.screen2latlon(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy), self.zoom, (self.width + self.border*2, self.height + self.border*2), self.style))
self.request_d = (self.dx, self.dy)
self.f = False
if not self.comm[1].empty():
self.rastertile = self.comm[1].get()
self.f = True
self.drag_x += self.request_d[0]
self.drag_y += self.request_d[1]
self.dx = event.x - self.drag_x
self.dy = event.y - self.drag_y
widget.queue_draw()
def delete_ev(self, widget, event):
gtk.main_quit()
def press_ev(self, widget, event):
print("Start drag")
self.drag = True
self.drag_x = event.x
self.drag_y = event.y
def release_ev(self, widget, event):
print("Stop drag")
self.drag = False
# print("ll:", self.latcenter, self.loncenter)
print("LL before: ",self.lat_c, self.lon_c)
print("dd: ",self.dx, self.dy)
self.lat_c, self.lon_c = self.rastertile.screen2latlon(self.rastertile.w/2 - self.dx, self.rastertile.h/2 - self.dy);
self.dx = self.dy = 0
self.f = True
print("LL after: ",self.lat_c, self.lon_c)
# self.rastertile.update_surface( self.lat_c, self.lon_c, self.zoom, self.tilecache, self.style)
self.comm[0].put(((self.lat_c, self.lon_c), self.zoom, (self.width + self.border*2, self.height + self.border*2), self.style))
widget.queue_draw()
def expose_ev(self, widget, event):
# print("Expose")
if(widget.allocation.width != self.width):
print("Rrresize!")
self.width = widget.allocation.width
self.height = widget.allocation.height
self.rastertile = None
if self.rastertile is None:
self.rastertile = RasterTile(self.width + self.border*2, self.height + self.border*2)
self.rastertile.update_surface(self.lat_c, self.lon_c, self.zoom, self.tilecache, self.style)
cr = widget.window.cairo_create()
cr.set_source_surface(self.rastertile.surface, self.dx-self.border, self.dy - self.border)
cr.paint()
# cr.
def main(self):
self.window.show_all()
gtk.main()
def line(cr, c):
cr.move_to(c[0], c[1])
for k in range(2, len(c), 2):
cr.line_to(c[k], c[k + 1])
cr.stroke()
def poly(cr, c):
cr.move_to(c[0], c[1])
for k in range(2, len(c), 2):
cr.line_to(c[k], c[k + 1])
cr.fill()
def ways(t):
# return [y for x in t.itervalues() for y in x.itervalues()]
r = {}
for i in t.values():
r.update(i)
return r.values()
def load_tile(k):
print("loading tile: ", k)
f = open(key_to_filename(k))
t = {}
while True:
str = f.readline()
if str is None or str == "":
break
str = str.rstrip("\n")
a = str.split(" ")
w = Way(a[0], int(a[1]), int(a[2]), map(lambda x: float(x), a[3:]))
t[w.id] = w
f.close()
return t
class RasterTile:
def __init__(self, width, height):
self.w = width
self.h = height
self.surface = cairo.ImageSurface(cairo.FORMAT_RGB24, self.w, self.h)
self.x_offset = 0
self.y_offset = 0
self.lat_c = None
self.lon_c = None
self.zoom = None
def screen2latlon(self, x, y):
return -(y - self.h/2)/self.zoom + self.lat_c, (x - self.w/2)/(math.cos(self.lat_c*math.pi/180)*self.zoom) + self.lon_c
def latlon2screen(self, lat, lon, lcc):
return (lon - self.lon_c)*lcc*self.zoom + self.w/2, -(lat - self.lat_c)*self.zoom + self.h/2
def update_surface(self, lat, lon, zoom, tilecache, style):
self.zoom = zoom
self.lat_c = lat
self.lon_c = lon
cr = cairo.Context(self.surface)
cr.rectangle(0, 0, self.w, self.h)
cr.set_source_rgb(0.7, 0.7, 0.7)
cr.fill()
latmin, lonmin = self.screen2latlon(0, self.h)
latmax, lonmax = self.screen2latlon(self.w, 0)
latkey_min = int(latmin*100)
latkey_max = int(latmax*100)
lonkey_min = int(lonmin*100)
lonkey_max = int(lonmax*100)
print(latmin, lonmin, latmax, lonmax)
print( latkey_min, latkey_max, lonkey_min, lonkey_max)
#FIXME: add time
active_tile = set([(i,j) for i in range(latkey_min, latkey_max+1) for j in range(lonkey_min, lonkey_max+1)])
print(active_tile)
for k in tilecache.keys():
if k not in active_tile:
del tilecache[k]
print("del tile:", k)
for k in active_tile:
if k not in tilecache:
tilecache[k] = load_tile(k)
#FIXME add time2
ww = ways(tilecache)
print("ways: ", len(ww))
ww.sort(key=lambda x: style[x.style][3])
lcc = math.cos(self.lat_c*math.pi/180)
for w in ww:
cs = []
for k in range(0, len(w.coords), 2):
x, y = self.latlon2screen(w.coords[k], w.coords[k+1], lcc);
cs.append(x)
cs.append(y)
w.cs = cs
for passn in range(1, 4):
print("pass ",passn)
for w in ww:
stn = w.style
if stn < len(style) and style[stn] is not None and style[stn][passn-1] is not None:
st = style[w.style][passn-1]
cr.set_line_width(st[0])
cr.set_source_rgb(st[1][0], st[1][1], st[1][2])
if w.type == "L":
line(cr, w.cs)
elif w.type == "P":
poly(cr, w.cs)
class Way:
def __init__(self, type, id, style, coords):
self.type = type
self.id = id
self.coords = coords
self.style = style
self.cs = None
def key_to_filename(k):
return "data/" + str(k[0]//100) + "/" + str(k[1]//100) + "/" + str(k[0]%100) + "/" + str(k[1]%100) + ".map"
if __name__ == "__main__":
comm = (Queue.Queue(), Queue.Queue())
gtk.gdk.threads_init()
nav = Navigator(comm)
r = Renderer(comm)
r.daemon = True
r.start()
nav.main()