source: subversion/applications/editors/osmpedit/osmpedit @ 32048

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

More support for ways added

  • Property svn:executable set to *
File size: 30.9 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 $way = $osm->get_way_from_item ($id);
728
729    if ($way) {
730        $way->print ();
731    }
732
733#    my $keyvalues = $osm->key_value_hash ($id);
734#    if ($keyvalues) {
735#       foreach my $k (keys %{$keyvalues}) {
736#           print STDERR "$k - $keyvalues->{$k}\n";
737#       }
738#   }
739}
740
741sub motion {
742    my $x = shift;
743    my $y = shift;
744    my @item = $can->find ('withtag', 'current');
745    my $id = $item[0];
746    $x = $can->canvasx($x);
747    $y = $can->canvasy($y);
748
749    ($point_lat, $point_lon) = $landsat->ctowgs84 ($x, $y);
750
751##    print "MOTION: $id\n";
752    my $node = $osm->get_node_from_item ($id);
753    my $seg = $osm->get_segment_from_item ($id);
754
755    if ($marked_item_id) {
756        $can->itemconfigure ($marked_item_id, -fill => $marked_item_colour);
757        if ($initial_segments_in_way{$marked_item_id}) {
758            $can->itemconfigure ($marked_item_id, -fill => "green");
759        }
760    }
761    if ($node or $seg) {
762        $marked_item_id = $id;
763        $marked_item_colour = $can->itemcget ($id, "-fill");
764        $can->itemconfigure ($id, -fill => "red");
765    } 
766
767    if ($editmode eq "segment" and $from_node_uid) {
768##      print STDERR "Bt-motion: $id $x $y\n";
769        if ($segment_create_id) {
770            my ($x0, $y0, $x1, $y1) = $can->coords ($segment_create_id);
771            $can->coords ($segment_create_id, $x0, $y0, $x, $y);
772        }
773
774    }
775
776
777##    $x = $can->canvasx($x);
778##    $y = $can->canvasy($y);
779##    $can->itemconfigure ($x, $y);
780#    ($global_xpos, $global_ypos) = $viewinfo->ctom ($x, $y);
781}
782
783sub b1motion {
784    my $x = shift;
785    my $y = shift;
786    my @item = $can->find ('withtag', 'current');
787    my $id = $item[0];
788
789    if ($editmode eq "move") {
790        my $node = $osm->get_node_from_item ($id);
791        if ($node) {
792            $movedid = $id;
793            $x = $can->canvasx($x);
794            $y = $can->canvasy($y);
795##      print STDERR "Bt-motion: $id $x $y\n";
796            $osm->move_node ($id, $x, $y, $can);
797        }
798    }
799
800}
801
802
803sub b1motionimage {
804    my $x = shift;
805    my $y = shift;
806    my @item = $can->find ('withtag', 'image');
807    my $id = $item[0];
808
809    my $dx = $x - $x_motionimage;
810    my $dy = $y - $y_motionimage;
811
812    my ($lat, $lon) = $landsat->ctowgs84 ($x, $y);
813    my $dlat = ($lat_motionimage - $lat)/10;
814    my $dlon = ($lon_motionimage - $lon)/10;
815
816    if ($move_image_state == 1) {
817        $move_image_state = 2;
818        $can->delete ("track");
819        $can->delete ("osmnode");
820        $can->delete ("osmsegment");
821    }
822
823
824###    print STDERR "btmotionimage: $dx $dy  --- $dlat $dlon\n";
825
826    $landsat->add_to_center ($dlat, $dlon);
827    $landsat->display ();
828
829#    foreach my $item (@item) {
830#       my ($x0, $y0) = $can->coords ($id);
831#       $x0 += $dx;
832#       $y0 += $dy;
833#       $can->coords ($id, $x0, $y0);
834#    }
835
836    $x_motionimage = $x;
837    $y_motionimage = $y;
838
839}
840
841sub start_motionimage {
842    my $x = shift;
843    my $y = shift;
844    my @item = $can->find ('withtag', 'current');
845    my $id = $item[0];
846
847##    print STDERR "startmotionimage: $x $y\n";
848   
849    $x_motionimage = $x;
850    $y_motionimage = $y;
851
852    ($lat_motionimage, $lon_motionimage) = $landsat->ctowgs84 ($x, $y);
853    $move_image_state = 1;
854}
855
856sub release_motionimage {
857    if ($move_image_state == 2) {
858        update_display ();
859    }
860    $move_image_state = 0;
861}
862
863
864
865sub create_events {
866    my $can = shift;
867
868    $can->CanvasBind('<1>' => sub {
869        my($c) = @_;
870        my $e = $c->XEvent;
871        button1 ($c, $e->x, $e->y);
872    });
873
874    $can->CanvasBind('<ButtonRelease-1>' => sub {
875        my($c) = @_;
876        my $e = $c->XEvent;
877        button1release ($c, $e->x, $e->y);
878    });
879
880    $can->CanvasBind('<2>' => sub {
881        my($c) = @_;
882        my $e = $c->XEvent;
883        button2 ($c, $e->x, $e->y);
884    });
885
886    $can->CanvasBind('<Shift 2>' => sub {
887        my($c) = @_;
888        my $e = $c->XEvent;
889        shift_button2 ($c, $e->x, $e->y);
890    });
891
892    $can->CanvasBind('<3>' => sub {
893        my($c) = @_;
894        my $e = $c->XEvent;
895        button3 ($c, $e->x, $e->y);
896    });
897
898    $can->CanvasBind('<Motion>' => sub {
899        motion ($Tk::event->x, $Tk::event->y);
900    });
901
902    $can->CanvasBind('<B1-Motion>' => sub {
903        b1motion ($Tk::event->x, $Tk::event->y);
904    });
905
906    $can->bind("image", '<B1-Motion>' => sub {
907        b1motionimage ($Tk::event->x, $Tk::event->y);
908    });
909
910    $can->bind("image", '<1>' => sub {
911        start_motionimage ($Tk::event->x, $Tk::event->y);
912    });
913
914    $can->bind("image", '<ButtonRelease-1>' => sub {
915        release_motionimage ($Tk::event->x, $Tk::event->y);
916    });
917}
918
919sub update_segment_key_menu {
920    my $mb = shift;
921
922    $mb->command (-label => "none",
923                  -command => sub { 
924                      $osm->update_segments_key_colour ("none", $can);
925                      $mb->configure (-text => "none");
926                  });
927
928    my @keys = $osm->get_segment_keys ();
929    foreach my $k (@keys, @extra_keys) {
930        $mb->command (-label => $k,
931                      -command => sub {
932                          $osm->update_segments_key_colour ($k, $can);
933                          $mb->configure (-text => $k);
934                          $seg_value_menu->menu ()->delete (0, "end");
935                          update_segment_value_menu ($seg_value_menu);
936                          $segment_key = $k;
937                      },
938                      );
939    }
940}
941
942sub update_way_key_menu {
943    my $mb = shift;
944
945    $mb->command (-label => "none",
946                  -command => sub { 
947                      $osm->update_ways_key_colour ("none", $can);
948                      $mb->configure (-text => "none");
949                  });
950
951    my @keys = $osm->get_way_keys ();
952    foreach my $k (@keys, @way_extra_keys) {
953        $mb->command (-label => $k,
954                      -command => sub {
955                          $osm->update_ways_key_colour ($k, $can);
956                          $mb->configure (-text => $k);
957                          $way_value_menu->menu ()->delete (0, "end");
958                          update_way_value_menu ($way_value_menu);
959                          $way_key = $k;
960                      },
961                      );
962    }
963}
964
965
966sub update_segment_value_menu {
967    my $mb = shift;
968
969    $mb->command (-label => "none",
970                  -command => sub { 
971                      $osm->update_segments_value_colour ("none", $can);
972                      $mb->configure (-text => "none");
973                  });
974
975    foreach my $k ($osm->get_segment_values (), @extra_values) {
976        $mb->command (-label => $k,
977                      -command => sub {
978                          $osm->update_segments_value_colour ($k, $can);
979                          $mb->configure (-text => $k);
980                          $segment_value = $k;
981                      },
982                      );
983    }
984}
985
986
987sub update_way_value_menu {
988    my $mb = shift;
989
990    $mb->command (-label => "none",
991                  -command => sub { 
992                      $osm->update_ways_value_colour ("none", $can);
993                      $mb->configure (-text => "none");
994                  });
995
996    foreach my $k ($osm->get_way_values (), @way_extra_values) {
997        $mb->command (-label => $k,
998                      -command => sub {
999                          $osm->update_ways_value_colour ($k, $can);
1000                          $mb->configure (-text => $k);
1001                          $way_value = $k;
1002                      },
1003                      );
1004    }
1005}
1006
1007
1008sub create_segment_item {
1009    my ($x0, $y0, $x1, $y1) = @_;
1010    my $id = $can->create ('line', $x0, $y0, $x1, $y1,
1011                           -fill => "white",
1012                           -width => 2,
1013                           -tag => "osmsegment");
1014    $can->raise ("osmnode", "osmsegment");
1015    return $id;
1016}
1017
1018sub update_display {
1019    $landsat->update_tracks ();
1020    $landsat->update_osm ();
1021    $landsat->fix_order ();
1022    if ($segment_key) {
1023        $osm->update_segments_key_colour ($segment_key, $can);
1024        if ($segment_value) {
1025            $osm->update_segments_value_colour ($segment_value, $can);
1026        }
1027    }
1028    if ($way_key) {
1029        $osm->update_ways_key_colour ($way_key, $can);
1030        if ($way_value) {
1031            $osm->update_ways_value_colour ($way_value, $can);
1032        }
1033    }
1034}
1035
1036
1037
1038    #
1039    # Fix buttons, code should maybe be somewhere else
1040    #
1041
1042##    my @nodes = $self->get_osm ()->get_nodes ();
1043##    foreach my $node (@nodes) {
1044##      my $keyvalues = $node->key_value_hash ();
1045##      if ($keyvalues) {
1046##          foreach my $k (keys %{$keyvalues}) {
1047#####           print STDERR "$k - $keyvalues->{$k}\n";
1048##              if ($k eq "class") {
1049##                  my $value = $keyvalues->{$k};
1050##                  if (not defined $self->{CLASSBUTTONMAP}->{$value}) {
1051##                      $self->{CLASSBUTTONMAP}->{$value} = 1;
1052##                      $self->make_class_button ($value);
1053##                  }
1054##              }
1055##          }
1056##      }
1057##    }
1058##
1059##    $self->fix_order ();
1060
1061
1062sub make_class_button {
1063    my $self = shift;
1064    my $name = shift;
1065    my $frame = shift;
1066    $frame->Button (-text => $name,
1067                    -width => 20,
1068                    -command => sub { 
1069                        print "CLASS: $name\n"; 
1070                        my $can = $self->get_canvas ();
1071                        $self->get_osm ()->toggle_colour ($can, $name);
1072                    }
1073                  )->pack (-side => "top");
1074
1075}
1076
1077
1078
1079=pod
1080
1081=head1 NAME
1082
1083osmpedit - Editor for Open Street Map data
1084
1085=head1 SYNOPSIS
1086
1087osmpedit [--lat lat] [--lon lon] [--user user] [--passwd passwd]
1088         [track1.gpx track2.gpx ...]
1089
1090=head1 DESCRIPTION
1091
1092Editor for Open Street Map data.  You need to have an internet connection
1093to be able to edit the data.
1094
1095If track files are given they are read in and the start position for
1096the editor is centered on the tracks.
1097
1098Landsat tiles will be loaded and cached in $HOME/.osmpedit/cache/.
1099You navigate by pressing B<North>, B<South>, B<West>, B<East>,
1100B<ZoomIn> and B<ZoomOut>.  You can also navigate by pressing the left
1101button on the background image and move the mouse.
1102
1103To load the OSM data press B<Reload OSM>.  This data is cached in
1104$HOME/.osmpedit/cache/lastosm.xml and the nodes and segments in this
1105file will be shown when B<osmpedit> is started.
1106
1107B<Toggle tracks>, B<Toggle nodes>, B<Toggle segments> and B<Toggle
1108ways> toggles what is shown in the editing area.
1109
1110Pressing the right button on some item often print some information
1111about the item in the window where B<osmpedit> was started. The left
1112button is used for most of the editing.
1113
1114There are for editing modes: B<Move>, B<Create>, B<Delete> and
1115B<Segment>.
1116
1117In B<Move> mode you can move a node by pressing the left button, move
1118the mouse and then release the button at the wanted position.  When
1119you release the button the data is updated in the OSM server.
1120
1121In B<Create> mode pressing the left button will create a new node in
1122the OSM server and display it in the editing area.  If you try to
1123create a node on a segment the segment will be split into two parts
1124and the two parts will be connected to the new node.  Two new segments
1125will be created and the old segment will be deleted from the OSM
1126server.  The two new segments will have the same value of their tags
1127field as the deleted segment. NOT YET UPDATED FOR WAYS.
1128
1129In B<Delete> mode pressing the left button over a node will delete it.
1130Pressing it over a segment will delete the segment.  It is probably
1131best to delete segments before nodes.
1132
1133In B<Segment> mode a new segment is created by pressing and releasing
1134the left button over the B<from> node.  Then move the cursor to the
1135B<to> node and press and release the left button.  The new segment is
1136created in the OSM server when the left button is pressed over the
1137B<to> node.  If a value for key "class" is specified (see below) then
1138the segment will be created with the key class set to this value.
1139Also some other key values will be set (e.g, car=yes for roads where
1140cars usually travels).
1141
1142B<Segment> mode is also used for editing key/values for a segment.
1143When the OSM data is loaded the B<Key> menu is initialized with an
1144entry for all the keys used in the data.  Selecting one key will
1145change the colour of all segments containing that key to yellow and
1146initalize the B<Value> menu with an entry for each value used in the
1147data for the selected key.  Choosing one value will change the colour
1148of the segments with this key/value pair to green.  Pressing the left
1149button on a segment will set the key value in the server.  This is a
1150very efficient way to for example set the name of a street by setting
1151it for each segment.  The B<New key> button is used to create a new
1152key and the B<New value> button is used to create a new values.  These
1153new keys and values will be available in the key and value menues.
1154
1155
1156
1157=head1 OPTIONS
1158
1159=over 4
1160
1161=item B<--lat latitude>
1162
1163Latitude for start position.  This overrides the value computed from input
1164tracks.
1165
1166=item B<--lon longitude>
1167
1168Longitude for start position.  This overrides the value computed from input
1169tracks.
1170
1171=item B<--user username>
1172
1173Specify the OSM user name.  This value overrides the value of the enviroment
1174variable OSMUSER.
1175
1176=item B<--passwd password>
1177
1178Specify the OSM user name.  This value overrides the value of the enviroment
1179variable OSMPASSWD.
1180
1181=back
1182
1183=head1 EXAMPLES
1184
1185   osmpedit --lat 58.4 --lon 16.6
1186
1187   osmpedit --user tpe@ida.liu.se --passwd secret buss213.gpx
1188
1189   env OSMUSER=tpe@ida.liu.se OSMPASSWD=secret osmpedit buss213.gpx
1190
1191=head1 AUTHOR
1192
1193Tommy Persson (tpe@ida.liu.se)
1194
1195=cut
1196
Note: See TracBrowser for help on using the repository browser.