source: subversion/editors/osmpedit/osmpedit @ 1126

Last change on this file since 1126 was 1126, checked in by tpersson, 13 years ago

More support for ways added

  • Property svn:executable set to *
File size: 30.8 KB
Line 
1#!/usr/bin/env perl
2
3#    Copyright (C) 2005 Tommy Persson, tpe@ida.liu.se
4#
5#    This program is free software; you can redistribute it and/or modify
6#    it under the terms of the GNU General Public License as published by
7#    the Free Software Foundation; either version 2 of the License, or
8#    (at your option) any later version.
9#
10#    This program is distributed in the hope that it will be useful,
11#    but WITHOUT ANY WARRANTY; without even the implied warranty of
12#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#    GNU General Public License for more details.
14#
15#    You should have received a copy of the GNU General Public License
16#    along with this program; if not, write to the Free Software
17#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
18
19
20use landsat;
21use trackcollection;
22use osm;
23
24use strict;
25
26my $trackcollection = new trackcollection;
27
28use Tk;
29use Tk::JPEG;
30use Image::Size;
31
32
33use vars qw ($opt_lat $opt_lon $opt_petersfield $opt_passwd $opt_user);
34use Getopt::Mixed;
35Getopt::Mixed::getOptions("lat=s lon=s petersfield passwd=s user=s");
36
37my $password = $ENV{OSMPASSWD};
38my $user = $ENV{OSMUSER};
39
40$user = $opt_user if defined $opt_user;
41$password = $opt_passwd if defined $opt_passwd;
42
43
44if (not $user or not $password) {
45    print STDERR "\nOSM user and passsword has to be specified using the\n";
46    print STDERR "environment variables OSMUSER and OSMPASSWD or using\n";
47    print STDERR "the options --user and --passwd.\n";
48    exit 0;
49}
50
51$opt_lat = 51.015 if defined $opt_petersfield;
52$opt_lon = -0.95 if defined $opt_petersfield;
53
54my $move_image_state = 0;
55
56my $editmode = "segment";
57##my $editmode = "create";
58my $movedid = 0;
59my $from_node_uid = 0;
60my $segment_create_id = 0;
61my $marked_item_id = 0;
62my $marked_item_colour = "white";
63
64my $x_motionimage = 0;
65my $y_motionimage = 0;
66
67my $lat_motionimage = 0;
68my $lon_motionimage = 0;
69
70my $point_lat = 0;
71my $point_lon = 0;
72
73my $goto_lat = 51.5;
74my $goto_lon = 0;
75
76my $segment_key = "";
77my $segment_value = "";
78
79my @extra_keys = ();
80my @extra_values = ();
81
82my $way_key = "";
83my $way_value = "";
84
85my @way_extra_keys = ();
86my @way_extra_values = ();
87
88my @initial_segments_in_way = ();
89my %initial_segments_in_way = ();
90
91
92my $main = new MainWindow;
93$main->title ("OSMPEDIT");
94
95my $tbframe = $main->Frame ()->pack (-side => "top");
96
97my $can_frame  = $main->Frame->pack (-side => "top");
98
99my $left_side_frame = $can_frame->Frame->pack (-side => "left");
100
101my $can = $can_frame->Canvas (-width => 600,
102                              -height => 500)->pack (-side => "left");
103
104my $right_side_frame = $can_frame->Frame->pack (-side => "left");
105
106create_events ($can);
107
108my $landsat = new landsat ();
109$landsat->set_frame ($can_frame);
110$landsat->set_canvas ($can);
111
112foreach my $filename (@ARGV) {
113#    print STDERR "TRACK FILE: $filename\n";
114    my $track = new track ();
115    $track->parse_file ($filename);
116    $trackcollection->add_track ($track);
117}
118$landsat->set_track_collection ($trackcollection);
119
120my ($start_lat, $start_lon) = (58.4, 15.6);
121print "NTRACKS: ", $trackcollection->get_n_tracks (), "\n";
122
123if ($trackcollection->get_n_tracks () > 0) {
124    ($start_lat, $start_lon) = $trackcollection->get_center ();
125    print STDERR "CENTER: $start_lat $start_lon\n";
126}
127
128$start_lat = $opt_lat if defined $opt_lat;
129$start_lon = $opt_lon if defined $opt_lon;
130
131my $scale = 100;
132
133#my ($clamp_lat, $clamp_lon) =
134#    $landsat->clamp_to_center_of_tile ($start_lat, $start_lon, $scale);
135#print STDERR "CLAMP: $start_lat $start_lon\n";
136
137my $osm = new osm ();
138$osm->set_username ($user);
139$osm->set_password ($password);
140$osm->parse ($landsat);
141
142$landsat->set_osm ($osm);
143$landsat->set_center ($start_lat, $start_lon);
144$landsat->set_scale ($scale);
145
146
147# Temporarily removed since it blocked the application
148#$can_frame->after( 10000,
149#                   sub{
150#                       printf "Timer %s\n",''.localtime(time());
151#                       $landsat->fill_cache(1,$can_frame);
152#                    });
153#
154
155##$landsat->display_tile (58.4090, 15.561, 100);
156##$landsat->display_tile ($lat, $lon, $scale);
157$landsat->display ();
158$landsat->update_tracks ();
159$landsat->update_osm ();
160
161
162#
163# Left side
164#
165
166my $fwidth = 8;
167my $entrywidth = 10;
168my $tmpframe;
169
170$tmpframe = $left_side_frame->Frame ()->pack (-side => "top");
171$tmpframe->Label (-text => "Lat:",
172                  -width => $fwidth)->pack (-side => "left");
173$tmpframe->Entry (-textvariable => \$point_lat,
174                  -width => $entrywidth,
175                  -state => "disabled")->pack (-side => "left");
176
177$tmpframe = $left_side_frame->Frame ()->pack (-side => "top");
178$tmpframe->Label (-text => "Lon:",
179                  -width => $fwidth)->pack (-side => "left");
180$tmpframe->Entry (-textvariable => \$point_lon,
181                  -width => $entrywidth,
182                  -state => "disabled")->pack (-side => "left");
183
184$tmpframe = $left_side_frame->Frame ()->pack (-side => "top");
185$tmpframe->Label (-text => "Goto Lat:",
186                  -width => $fwidth)->pack (-side => "left");
187$tmpframe->Entry (-textvariable => \$goto_lat,
188                  -width => $entrywidth)->pack (-side => "left");
189
190$tmpframe = $left_side_frame->Frame ()->pack (-side => "top");
191$tmpframe->Label (-text => "Goto Lon:",
192                  -width => $fwidth)->pack (-side => "left");
193$tmpframe->Entry (-textvariable => \$goto_lon,
194                  -width => $entrywidth)->pack (-side => "left");
195
196$left_side_frame->Button (-text => "GOTO",
197                 -command => sub { 
198                     $landsat->set_center ($goto_lat, $goto_lon);
199                     $landsat->set_scale ($scale);
200                     $landsat->display ();
201                     $landsat->update_tracks ();
202                     $landsat->update_osm ();
203                     $landsat->fix_order ();
204                     }
205                 )->pack (-side => "top");
206
207#
208# Right side
209#
210
211my ($seg_key_menu, $seg_value_menu,
212    $way_key_menu, $way_value_menu) = key_value_frame ();
213
214#
215# Bottom button row
216#
217
218my $bframe = $main->Frame ()->pack ();
219
220$bframe->Button (-text => "Reset View",
221                 -command => sub { 
222                     $landsat->set_center ($start_lat, $start_lon);
223                     $landsat->set_scale ($scale);
224                     $landsat->display ();
225                     $landsat->update_tracks ();
226                     $landsat->update_osm ();
227                     $landsat->fix_order ();
228                     }
229                 )->pack (-side => "left");
230
231
232$bframe->Button (-text => "North",
233                 -command => sub { 
234                     $landsat->north ();
235                     update_display ();
236                 }
237                 )->pack (-side => "left");
238
239$bframe->Button (-text => "South",
240                 -command => sub {
241                     $landsat->south ();
242                     update_display ();
243                 }
244                 )->pack (-side => "left");
245
246$bframe->Button (-text => "West",
247                 -command => sub { 
248                     $landsat->west ();
249                     update_display ();
250                 }
251                 )->pack (-side => "left");
252
253$bframe->Button (-text => "East",
254                 -command => sub {
255                     $landsat->east ();
256                     update_display ();
257                 }
258                 )->pack (-side => "left");
259
260
261$bframe->Button (-text => "ZoomIn",
262                 -command => sub { 
263                     $landsat->zoomin ();
264                     update_display ();
265                     }
266                 )->pack (-side => "left");
267
268$bframe->Button (-text => "ZoomOut",
269                 -command => sub { 
270                     $landsat->zoomout ();
271                     update_display ();
272                 }
273                 )->pack (-side => "left");
274
275
276$bframe->Button (-text => "Reload OSM",
277                 -command => sub { 
278                     $landsat->load_osm ();
279                     $seg_key_menu->menu ()->delete (0, "end");
280                     $seg_value_menu->menu ()->delete (0, "end");
281                     update_segment_key_menu ($seg_key_menu);
282                     update_segment_value_menu ($seg_value_menu);
283                 }
284                 )->pack (-side => "left");
285
286
287#
288# Top button row
289#
290
291$tbframe->Button (-text => "Toggle tracks",
292                  -command => sub { $landsat->toggle_tracks ()}
293                  )->pack (-side => "left");
294
295
296$tbframe->Button (-text => "Toggle nodes",
297                  -command => sub { $landsat->toggle_nodes ()}
298                  )->pack (-side => "left");
299
300$tbframe->Button (-text => "Toggle segments",
301                  -command => sub { $landsat->toggle_segments ()}
302                  )->pack (-side => "left");
303
304$tbframe->Button (-text => "Toggle ways",
305                  -command => sub { $landsat->toggle_ways ()}
306                  )->pack (-side => "left");
307
308$tbframe->Radiobutton (-variable => \$editmode,
309                       -text => "Move",
310                       -value => "move",
311                       -state => "normal")->pack (-side => "left");
312
313$tbframe->Radiobutton (-variable => \$editmode,
314                       -text => "Create",
315                       -value => "create",
316                       -state => "normal")->pack (-side => "left");
317
318$tbframe->Radiobutton (-variable => \$editmode,
319                       -text => "Delete",
320                       -value => "delete",
321                       -state => "normal")->pack (-side => "left");
322
323$tbframe->Radiobutton (-variable => \$editmode,
324                       -text => "Segment",
325                       -value => "segment",
326                       -state => "normal")->pack (-side => "left");
327
328$tbframe->Radiobutton (-variable => \$editmode,
329                       -text => "Way",
330                       -value => "way",
331                       -state => "normal")->pack (-side => "left");
332
333###create_class_menu ($tbframe);
334
335
336
337
338
339MainLoop;
340
341
342
343#
344# Buttons
345#
346
347sub button1 {
348    my($c, $x, $y) = @_;
349    my @item = $can->find ('withtag', 'current');
350    my $id = $item[0];
351    $x = $can->canvasx($x);
352    $y = $can->canvasy($y);
353    my ($lat, $lon) = $landsat->ctowgs84 ($x, $y);
354    print STDERR "POSITION: $lat $lon\n";
355
356    if ($editmode eq "create") {
357        my $segment = $osm->get_segment_from_item ($id);
358        my $uid = $osm->create_node ($lat, $lon);
359        if ($segment and $uid) {
360            my $seguid = $segment->get_uid ();
361            # Create new segments
362            my $from = $segment->get_from ();
363            my $to = $segment->get_to ();
364
365            my $suid0 = $osm->create_segment ($from, $uid, "");
366            my $suid1 = $osm->create_segment ($uid, $to, "");
367
368            if ($suid0 and $suid1) {
369                # delete the old segment
370                osmutil::delete_segment ($seguid, $user, $password);
371                  my $sid0 = create_segment_item (0, 0, 0, 0);
372                  my $sid1 = create_segment_item (0, 0, 0, 0);
373                  my $s0 = $osm->get_segment ($suid0);
374                  my $s1 = $osm->get_segment ($suid1);
375
376                  $s0->set_tags ($segment->get_tags ());
377                  $s1->set_tags ($segment->get_tags ());
378
379                  $osm->connect_uid_item ($suid0, $sid0);
380                  $osm->connect_uid_item ($suid1, $sid1);
381
382                  $osm->update_segment_colour ($sid0, $can);
383                  $osm->update_segment_colour ($sid1, $can);
384
385                  $can->coords ($sid0, $osm->get_segment_canvas_coords ($landsat, $s0));
386                  $can->coords ($sid1, $osm->get_segment_canvas_coords ($landsat, $s1));
387
388                  $can->delete ($id);
389              } else {
390                # Failed to create two new segments.  Cleanup.
391                osmutil::delete_segment ($suid0, $user, $password) if ($suid0);
392                osmutil::delete_segment ($suid1, $user, $password) if ($suid1);
393            }
394        }
395        if ($uid) {
396            my $item = $osm->draw_node ($can, $x, $y, 0);
397            $osm->connect_uid_item ($uid, $item);
398        } else {
399            print STDERR "WARNING: Failed to create node: $uid\n";
400        }
401    }
402
403    if ($editmode eq "delete") {
404        if ($osm->delete ($id)) {
405            $can->delete ($id);
406        } else {
407            print STDERR "WARNING: Delete failed\n";
408        }
409    }
410
411    if ($editmode eq "way") {
412        my $seg = $osm->get_segment_from_item ($id);
413        if ($seg) {
414            my $uid = $seg->get_uid ();
415            print STDERR "Add segment to way: $uid\n";
416            push @initial_segments_in_way, $uid;
417            $initial_segments_in_way{$id} = $marked_item_colour;
418            print STDERR "Saved colour: $marked_item_colour\n";
419            $can->itemconfigure ($id, -fill => "green");
420        }
421    }
422
423    if ($editmode eq "segment" and not $from_node_uid) {
424        $from_node_uid = 0;
425        my $node = $osm->get_node_from_item ($id);
426        if ($node) {
427            $from_node_uid = $node->get_uid ();
428            my ($x0, $y0, $x1, $y1) = $can->coords ($id);
429            my $xx = ($x0+$x1)/2;
430            my $yy = ($y0+$y1)/2;
431            $segment_create_id = create_segment_item ($xx, $yy, $xx, $yy);
432        }
433       
434        #
435        # Adding new value for one key
436        #
437
438        my $seg = $osm->get_segment_from_item ($id);
439        if ($seg) {
440            print STDERR "Update segment key: $segment_key\n";
441##          $osm->update_segment_class ($id);
442            $osm->update_segment_key_value ($id, $segment_key, $segment_value);
443            $osm->update_segments_key_colour ($segment_key, $can);
444            $osm->update_segments_value_colour ($segment_value, $can);
445##          $osm->update_segment_colour ($id, $can);
446            $marked_item_colour = $can->itemcget ($id, "-fill");
447        }
448        return;
449    }
450
451    if ($editmode eq "segment" and $from_node_uid) {
452        my $tonode = $osm->get_node_from_item ($id);
453        my $fromnode = $osm->get_node ($from_node_uid);
454        if ($tonode and $from_node_uid) {
455            my $touid = $tonode->get_uid ();
456            print STDERR "CREATE SEGMENT: $from_node_uid -> $touid\n";
457            my $class = "";
458            if ($segment_key eq "class") {
459                $class = $segment_value;
460            }
461            my $suid = $osm->create_segment ($fromnode->get_osmuid(), 
462                                             $tonode->get_osmuid(), $class);
463            if ($suid) {
464                $osm->connect_uid_item ($suid, $segment_create_id);
465                $osm->update_segment_colour ($segment_create_id, $can);
466                $fromnode->add_from ($suid);
467                $tonode->add_to ($suid);
468            } else {
469                $can->delete ($segment_create_id);
470            }
471        } else {
472            $can->delete ($segment_create_id);
473        }
474        $segment_create_id = 0;
475        $from_node_uid = 0;
476        return;
477    }
478
479
480}
481
482sub key_value_frame {
483
484    my $entrywidth = 25;
485    my $fwidth = 8;
486    my $tmpframe;
487
488    #
489    # Way part
490    #
491
492    $right_side_frame->Button (-text => "Create way",
493                               -command => sub {
494                                   print STDERR "Create way\n";
495                                   $osm->create_way (@initial_segments_in_way);
496                               },
497                               -width => $fwidth
498                               )->pack (-side => "top");
499
500
501    $right_side_frame->Label (-text => "Way")->pack (-side => "top");
502
503    #
504    # Key menu button
505    #
506
507    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
508    $tmpframe->Label (-text => "Key:",
509                      -width => $fwidth)->pack (-side => "left");
510
511    my $way_key_menu =  $tmpframe->Menubutton (-relief => 'raised',
512                                               -bg => "yellow",
513                                               -width => 20,
514                                                   );
515    $way_key_menu->configure (-text => "none");
516   
517
518    $way_key_menu->pack (-side => 'left',
519                         -fill => "x",
520                         -expand => 1);
521    update_way_key_menu ($way_key_menu);
522
523    my $wskey = "";
524    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
525    $tmpframe->Button (-text => "New key:",
526                       -command => sub {
527                           push @way_extra_keys, $wskey;
528                           $way_key_menu->menu ()->delete (0, "end");
529                           update_way_key_menu ($way_key_menu);
530                           $way_key_menu->menu ()->invoke ("$wskey");
531##                         print STDERR "SEGMENT_KEY: $way_key\n";
532                       },
533                       -width => $fwidth
534                       )->pack (-side => "left");
535    $tmpframe->Entry (-textvariable => \$wskey,
536                      -width => $entrywidth)->pack (-side => "left");
537
538    #
539    # Value menu button
540    #
541   
542    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
543    $tmpframe->Label (-text => "Value:",
544                      -width => $fwidth)->pack (-side => "left");
545
546   
547    my $way_value_menu = $tmpframe->Menubutton (-text => "name",
548                                                -relief => 'raised',
549                                                -bg => "green",
550                                                -width => 20,
551                                                );
552
553    $way_value_menu->configure (-text => "none");
554
555    $way_value_menu->pack (-side => 'left',
556                           -fill => "x",
557                           -expand => 1);
558   
559    update_way_value_menu ($way_value_menu);
560
561    #
562    # New value entry
563    #
564    my $wsvalue = "";
565    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
566    $tmpframe->Button (-text => "New value:",
567                       -command => sub {
568                           push @way_extra_values, $wsvalue;
569                           $way_value_menu->menu ()->delete (0, "end");
570                           update_way_value_menu ($way_value_menu);
571                           $way_value_menu->menu ()->invoke ("$wsvalue");
572                       },
573                       -width => $fwidth
574                       )->pack (-side => "left");
575    $tmpframe->Entry (-textvariable => \$wsvalue,
576                      -width => $entrywidth)->pack (-side => "left");
577
578
579
580
581    #
582    # Segment part
583    #
584
585    $right_side_frame->Label (-text => "Segment")->pack (-side => "top");
586
587    #
588    # Key menu button
589    #
590
591    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
592    $tmpframe->Label (-text => "Key:",
593                      -width => $fwidth)->pack (-side => "left");
594
595    my $segment_key_menu =  $tmpframe->Menubutton (-relief => 'raised',
596                                                   -bg => "yellow",
597                                                   -width => 20,
598                                                   );
599    $segment_key_menu->configure (-text => "none");
600   
601
602   $segment_key_menu->pack (-side => 'left',
603                             -fill => "x",
604                             -expand => 1);
605    update_segment_key_menu ($segment_key_menu);
606
607    my $skey = "";
608    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
609    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
610    $tmpframe->Button (-text => "New key:",
611                       -command => sub {
612                           push @extra_keys, $skey;
613                           $seg_key_menu->menu ()->delete (0, "end");
614                           update_segment_key_menu ($seg_key_menu);
615                           $seg_key_menu->menu ()->invoke ("$skey");
616##                         print STDERR "SEGMENT_KEY: $segment_key\n";
617                       },
618                       -width => $fwidth
619                       )->pack (-side => "left");
620    $tmpframe->Entry (-textvariable => \$skey,
621                      -width => $entrywidth)->pack (-side => "left");
622
623    #
624    # Value menu button
625    #
626   
627    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
628    $tmpframe->Label (-text => "Value:",
629                      -width => $fwidth)->pack (-side => "left");
630
631   
632    my $segment_value_menu = $tmpframe->Menubutton (-text => "name",
633                                                    -relief => 'raised',
634                                                    -bg => "green",
635                                                    -width => 20,
636                                                    );
637
638    $segment_value_menu->configure (-text => "none");
639
640    $segment_value_menu->pack (-side => 'left',
641                               -fill => "x",
642                               -expand => 1);
643   
644    update_segment_value_menu ($segment_value_menu);
645
646    #
647    # New value entry
648    #
649    my $svalue = "";
650    $tmpframe = $right_side_frame->Frame ()->pack (-side => "top");
651    $tmpframe->Button (-text => "New value:",
652                       -command => sub {
653                           push @extra_values, $svalue;
654                           $seg_value_menu->menu ()->delete (0, "end");
655                           update_segment_value_menu ($seg_value_menu);
656                           $seg_value_menu->menu ()->invoke ("$svalue");
657                       },
658                       -width => $fwidth
659                       )->pack (-side => "left");
660    $tmpframe->Entry (-textvariable => \$svalue,
661                      -width => $entrywidth)->pack (-side => "left");
662
663
664    return ($segment_key_menu, $segment_value_menu,
665            $way_key_menu, $way_value_menu);
666}
667
668sub button1release {
669    my($c, $x, $y) = @_;
670    my @item = $can->find ('withtag', 'current');
671    my $id = $item[0];
672##    print "Item: $id\n";
673    $x = $can->canvasx($x);
674    $y = $can->canvasy($y);
675
676##    print STDERR "CANPOS: $x $y\n";
677    my ($lat, $lon) = $landsat->ctowgs84 ($x, $y);
678    print STDERR "$lat $lon\n";
679
680    if ($editmode eq "move") {
681        if ($editmode eq "move" and $movedid) {
682            if (not $osm->update_node ($movedid, $lat, $lon)) {
683                print STDERR "WARNING UPDATE OF NODE FAILED\n";
684            }
685        }
686        $movedid = 0;
687    }
688
689}
690
691
692sub button2 {
693    my($c, $x, $y) = @_;
694    my @item = $can->find ('withtag', 'current');
695    my $id = $item[0];
696    if ($editmode eq "way") {
697        print STDERR "Clearing saved way segments\n";
698        @initial_segments_in_way = ();
699        foreach my $id (keys %initial_segments_in_way) {
700            my $c = $initial_segments_in_way{$id};
701            $can->itemconfigure ($id, -fill => "$c");
702        }
703        $marked_item_colour = $initial_segments_in_way{$marked_item_id};
704        %initial_segments_in_way = ();
705    }
706}
707
708sub button3 {
709    my($c, $x, $y) = @_;
710    my @item = $can->find ('withtag', 'current');
711    my $id = $item[0];
712
713##    print "Info for Item: $id\n";
714
715    my $node = $osm->get_node_from_item ($id);
716
717    if ($node) {
718        $node->print ();
719    }
720
721    my $seg = $osm->get_segment_from_item ($id);
722
723    if ($seg) {
724        $seg->print ();
725    }
726
727#    my $keyvalues = $osm->key_value_hash ($id);
728#    if ($keyvalues) {
729#       foreach my $k (keys %{$keyvalues}) {
730#           print STDERR "$k - $keyvalues->{$k}\n";
731#       }
732#   }
733}
734
735sub motion {
736    my $x = shift;
737    my $y = shift;
738    my @item = $can->find ('withtag', 'current');
739    my $id = $item[0];
740    $x = $can->canvasx($x);
741    $y = $can->canvasy($y);
742
743    ($point_lat, $point_lon) = $landsat->ctowgs84 ($x, $y);
744
745##    print "MOTION: $id\n";
746    my $node = $osm->get_node_from_item ($id);
747    my $seg = $osm->get_segment_from_item ($id);
748
749    if ($marked_item_id) {
750        $can->itemconfigure ($marked_item_id, -fill => $marked_item_colour);
751        if ($initial_segments_in_way{$marked_item_id}) {
752            $can->itemconfigure ($marked_item_id, -fill => "green");
753        }
754    }
755    if ($node or $seg) {
756        $marked_item_id = $id;
757        $marked_item_colour = $can->itemcget ($id, "-fill");
758        $can->itemconfigure ($id, -fill => "red");
759    } 
760
761    if ($editmode eq "segment" and $from_node_uid) {
762##      print STDERR "Bt-motion: $id $x $y\n";
763        if ($segment_create_id) {
764            my ($x0, $y0, $x1, $y1) = $can->coords ($segment_create_id);
765            $can->coords ($segment_create_id, $x0, $y0, $x, $y);
766        }
767
768    }
769
770
771##    $x = $can->canvasx($x);
772##    $y = $can->canvasy($y);
773##    $can->itemconfigure ($x, $y);
774#    ($global_xpos, $global_ypos) = $viewinfo->ctom ($x, $y);
775}
776
777sub b1motion {
778    my $x = shift;
779    my $y = shift;
780    my @item = $can->find ('withtag', 'current');
781    my $id = $item[0];
782
783    if ($editmode eq "move") {
784        my $node = $osm->get_node_from_item ($id);
785        if ($node) {
786            $movedid = $id;
787            $x = $can->canvasx($x);
788            $y = $can->canvasy($y);
789##      print STDERR "Bt-motion: $id $x $y\n";
790            $osm->move_node ($id, $x, $y, $can);
791        }
792    }
793
794}
795
796
797sub b1motionimage {
798    my $x = shift;
799    my $y = shift;
800    my @item = $can->find ('withtag', 'image');
801    my $id = $item[0];
802
803    my $dx = $x - $x_motionimage;
804    my $dy = $y - $y_motionimage;
805
806    my ($lat, $lon) = $landsat->ctowgs84 ($x, $y);
807    my $dlat = ($lat_motionimage - $lat)/10;
808    my $dlon = ($lon_motionimage - $lon)/10;
809
810    if ($move_image_state == 1) {
811        $move_image_state = 2;
812        $can->delete ("track");
813        $can->delete ("osmnode");
814        $can->delete ("osmsegment");
815    }
816
817
818###    print STDERR "btmotionimage: $dx $dy  --- $dlat $dlon\n";
819
820    $landsat->add_to_center ($dlat, $dlon);
821    $landsat->display ();
822
823#    foreach my $item (@item) {
824#       my ($x0, $y0) = $can->coords ($id);
825#       $x0 += $dx;
826#       $y0 += $dy;
827#       $can->coords ($id, $x0, $y0);
828#    }
829
830    $x_motionimage = $x;
831    $y_motionimage = $y;
832
833}
834
835sub start_motionimage {
836    my $x = shift;
837    my $y = shift;
838    my @item = $can->find ('withtag', 'current');
839    my $id = $item[0];
840
841##    print STDERR "startmotionimage: $x $y\n";
842   
843    $x_motionimage = $x;
844    $y_motionimage = $y;
845
846    ($lat_motionimage, $lon_motionimage) = $landsat->ctowgs84 ($x, $y);
847    $move_image_state = 1;
848}
849
850sub release_motionimage {
851    if ($move_image_state == 2) {
852        update_display ();
853    }
854    $move_image_state = 0;
855}
856
857
858
859sub create_events {
860    my $can = shift;
861
862    $can->CanvasBind('<1>' => sub {
863        my($c) = @_;
864        my $e = $c->XEvent;
865        button1 ($c, $e->x, $e->y);
866    });
867
868    $can->CanvasBind('<ButtonRelease-1>' => sub {
869        my($c) = @_;
870        my $e = $c->XEvent;
871        button1release ($c, $e->x, $e->y);
872    });
873
874    $can->CanvasBind('<2>' => sub {
875        my($c) = @_;
876        my $e = $c->XEvent;
877        button2 ($c, $e->x, $e->y);
878    });
879
880    $can->CanvasBind('<Shift 2>' => sub {
881        my($c) = @_;
882        my $e = $c->XEvent;
883        shift_button2 ($c, $e->x, $e->y);
884    });
885
886    $can->CanvasBind('<3>' => sub {
887        my($c) = @_;
888        my $e = $c->XEvent;
889        button3 ($c, $e->x, $e->y);
890    });
891
892    $can->CanvasBind('<Motion>' => sub {
893        motion ($Tk::event->x, $Tk::event->y);
894    });
895
896    $can->CanvasBind('<B1-Motion>' => sub {
897        b1motion ($Tk::event->x, $Tk::event->y);
898    });
899
900    $can->bind("image", '<B1-Motion>' => sub {
901        b1motionimage ($Tk::event->x, $Tk::event->y);
902    });
903
904    $can->bind("image", '<1>' => sub {
905        start_motionimage ($Tk::event->x, $Tk::event->y);
906    });
907
908    $can->bind("image", '<ButtonRelease-1>' => sub {
909        release_motionimage ($Tk::event->x, $Tk::event->y);
910    });
911}
912
913sub update_segment_key_menu {
914    my $mb = shift;
915
916    $mb->command (-label => "none",
917                  -command => sub { 
918                      $osm->update_segments_key_colour ("none", $can);
919                      $mb->configure (-text => "none");
920                  });
921
922    my @keys = $osm->get_segment_keys ();
923    foreach my $k (@keys, @extra_keys) {
924        $mb->command (-label => $k,
925                      -command => sub {
926                          $osm->update_segments_key_colour ($k, $can);
927                          $mb->configure (-text => $k);
928                          $seg_value_menu->menu ()->delete (0, "end");
929                          update_segment_value_menu ($seg_value_menu);
930                          $segment_key = $k;
931                      },
932                      );
933    }
934}
935
936sub update_way_key_menu {
937    my $mb = shift;
938
939    $mb->command (-label => "none",
940                  -command => sub { 
941                      $osm->update_ways_key_colour ("none", $can);
942                      $mb->configure (-text => "none");
943                  });
944
945    my @keys = $osm->get_way_keys ();
946    foreach my $k (@keys, @way_extra_keys) {
947        $mb->command (-label => $k,
948                      -command => sub {
949                          $osm->update_ways_key_colour ($k, $can);
950                          $mb->configure (-text => $k);
951                          $way_value_menu->menu ()->delete (0, "end");
952                          update_way_value_menu ($way_value_menu);
953                          $way_key = $k;
954                      },
955                      );
956    }
957}
958
959
960sub update_segment_value_menu {
961    my $mb = shift;
962
963    $mb->command (-label => "none",
964                  -command => sub { 
965                      $osm->update_segments_value_colour ("none", $can);
966                      $mb->configure (-text => "none");
967                  });
968
969    foreach my $k ($osm->get_segment_values (), @extra_values) {
970        $mb->command (-label => $k,
971                      -command => sub {
972                          $osm->update_segments_value_colour ($k, $can);
973                          $mb->configure (-text => $k);
974                          $segment_value = $k;
975                      },
976                      );
977    }
978}
979
980
981sub update_way_value_menu {
982    my $mb = shift;
983
984    $mb->command (-label => "none",
985                  -command => sub { 
986                      $osm->update_ways_value_colour ("none", $can);
987                      $mb->configure (-text => "none");
988                  });
989
990    foreach my $k ($osm->get_way_values (), @way_extra_values) {
991        $mb->command (-label => $k,
992                      -command => sub {
993                          $osm->update_ways_value_colour ($k, $can);
994                          $mb->configure (-text => $k);
995                          $way_value = $k;
996                      },
997                      );
998    }
999}
1000
1001
1002sub create_segment_item {
1003    my ($x0, $y0, $x1, $y1) = @_;
1004    my $id = $can->create ('line', $x0, $y0, $x1, $y1,
1005                           -fill => "white",
1006                           -width => 2,
1007                           -tag => "osmsegment");
1008    $can->raise ("osmnode", "osmsegment");
1009    return $id;
1010}
1011
1012sub update_display {
1013    $landsat->update_tracks ();
1014    $landsat->update_osm ();
1015    $landsat->fix_order ();
1016    if ($segment_key) {
1017        $osm->update_segments_key_colour ($segment_key, $can);
1018        if ($segment_value) {
1019            $osm->update_segments_value_colour ($segment_value, $can);
1020        }
1021    }
1022    if ($way_key) {
1023        $osm->update_ways_key_colour ($way_key, $can);
1024        if ($way_value) {
1025            $osm->update_ways_value_colour ($way_value, $can);
1026        }
1027    }
1028}
1029
1030
1031
1032    #
1033    # Fix buttons, code should maybe be somewhere else
1034    #
1035
1036##    my @nodes = $self->get_osm ()->get_nodes ();
1037##    foreach my $node (@nodes) {
1038##      my $keyvalues = $node->key_value_hash ();
1039##      if ($keyvalues) {
1040##          foreach my $k (keys %{$keyvalues}) {
1041#####           print STDERR "$k - $keyvalues->{$k}\n";
1042##              if ($k eq "class") {
1043##                  my $value = $keyvalues->{$k};
1044##                  if (not defined $self->{CLASSBUTTONMAP}->{$value}) {
1045##                      $self->{CLASSBUTTONMAP}->{$value} = 1;
1046##                      $self->make_class_button ($value);
1047##                  }
1048##              }
1049##          }
1050##      }
1051##    }
1052##
1053##    $self->fix_order ();
1054
1055
1056sub make_class_button {
1057    my $self = shift;
1058    my $name = shift;
1059    my $frame = shift;
1060    $frame->Button (-text => $name,
1061                    -width => 20,
1062                    -command => sub { 
1063                        print "CLASS: $name\n"; 
1064                        my $can = $self->get_canvas ();
1065                        $self->get_osm ()->toggle_colour ($can, $name);
1066                    }
1067                  )->pack (-side => "top");
1068
1069}
1070
1071
1072
1073=pod
1074
1075=head1 NAME
1076
1077osmpedit - Editor for Open Street Map data
1078
1079=head1 SYNOPSIS
1080
1081osmpedit [--lat lat] [--lon lon] [--user user] [--passwd passwd]
1082         [track1.gpx track2.gpx ...]
1083
1084=head1 DESCRIPTION
1085
1086Editor for Open Street Map data.  You need to have an internet connection
1087to be able to edit the data.
1088
1089If track files are given they are read in and the start position for
1090the editor is centered on the tracks.
1091
1092Landsat tiles will be loaded and cached in $HOME/.osmpedit/cache/.
1093You navigate by pressing B<North>, B<South>, B<West>, B<East>,
1094B<ZoomIn> and B<ZoomOut>.  You can also navigate by pressing the left
1095button on the background image and move the mouse.
1096
1097To load the OSM data press B<Reload OSM>.  This data is cached in
1098$HOME/.osmpedit/cache/lastosm.xml and the nodes and segments in this
1099file will be shown when B<osmpedit> is started.
1100
1101B<Toggle tracks>, B<Toggle nodes>, B<Toggle segments> and B<Toggle
1102ways> toggles what is shown in the editing area.
1103
1104Pressing the right button on some item often print some information
1105about the item in the window where B<osmpedit> was started. The left
1106button is used for most of the editing.
1107
1108There are for editing modes: B<Move>, B<Create>, B<Delete> and
1109B<Segment>.
1110
1111In B<Move> mode you can move a node by pressing the left button, move
1112the mouse and then release the button at the wanted position.  When
1113you release the button the data is updated in the OSM server.
1114
1115In B<Create> mode pressing the left button will create a new node in
1116the OSM server and display it in the editing area.  If you try to
1117create a node on a segment the segment will be split into two parts
1118and the two parts will be connected to the new node.  Two new segments
1119will be created and the old segment will be deleted from the OSM
1120server.  The two new segments will have the same value of their tags
1121field as the deleted segment. NOT YET UPDATED FOR WAYS.
1122
1123In B<Delete> mode pressing the left button over a node will delete it.
1124Pressing it over a segment will delete the segment.  It is probably
1125best to delete segments before nodes.
1126
1127In B<Segment> mode a new segment is created by pressing and releasing
1128the left button over the B<from> node.  Then move the cursor to the
1129B<to> node and press and release the left button.  The new segment is
1130created in the OSM server when the left button is pressed over the
1131B<to> node.  If a value for key "class" is specified (see below) then
1132the segment will be created with the key class set to this value.
1133Also some other key values will be set (e.g, car=yes for roads where
1134cars usually travels).
1135
1136B<Segment> mode is also used for editing key/values for a segment.
1137When the OSM data is loaded the B<Key> menu is initialized with an
1138entry for all the keys used in the data.  Selecting one key will
1139change the colour of all segments containing that key to yellow and
1140initalize the B<Value> menu with an entry for each value used in the
1141data for the selected key.  Choosing one value will change the colour
1142of the segments with this key/value pair to green.  Pressing the left
1143button on a segment will set the key value in the server.  This is a
1144very efficient way to for example set the name of a street by setting
1145it for each segment.  The B<New key> button is used to create a new
1146key and the B<New value> button is used to create a new values.  These
1147new keys and values will be available in the key and value menues.
1148
1149
1150
1151=head1 OPTIONS
1152
1153=over 4
1154
1155=item B<--lat latitude>
1156
1157Latitude for start position.  This overrides the value computed from input
1158tracks.
1159
1160=item B<--lon longitude>
1161
1162Longitude for start position.  This overrides the value computed from input
1163tracks.
1164
1165=item B<--user username>
1166
1167Specify the OSM user name.  This value overrides the value of the enviroment
1168variable OSMUSER.
1169
1170=item B<--passwd password>
1171
1172Specify the OSM user name.  This value overrides the value of the enviroment
1173variable OSMPASSWD.
1174
1175=back
1176
1177=head1 EXAMPLES
1178
1179   osmpedit --lat 58.4 --lon 16.6
1180
1181   osmpedit --user tpe@ida.liu.se --passwd secret buss213.gpx
1182
1183   env OSMUSER=tpe@ida.liu.se OSMPASSWD=secret osmpedit buss213.gpx
1184
1185=head1 AUTHOR
1186
1187Tommy Persson (tpe@ida.liu.se)
1188
1189=cut
1190
Note: See TracBrowser for help on using the repository browser.