User:Opk
Jump to navigation
Jump to search
Babel user information |
---|
Users by language |
I support the license
upgrade to ODbL v 1.0
Drawing Buildings with Turtle Graphics
I find that mapping buildings using JOSM can be a bit fiddly and time consuming. Just getting it aligned to the roads correctly can be tricky - you can move an object East/West or North/South with the cursors but to move it parallel to a road isn't possible.
So I've written the following library in LOGO that replaces the LOGO turtle graphics primitives to draw nodes and ways for OpenStreetMap. The result is saved as a .osm file that can be loaded into JOSM.
; redefined logo turtle graphics primitives to create a .osm file make "redefp "true make "mt.draw "true make "mt.start "true make "mt.xpos 0 make "mt.ypos 0 make "mt.dir 0 make "mt.nodes [] make "mt.ways [] make "mt.origin [0 0] make "mt.circum 40041455 make "mt.latmetre 360.0/mt.circum to setorigin :pos make "mt.origin :pos end to abs :value ifelse less? :value 0 [ output minus :value ] [output :value] end ; movement commands to mt.find :xcor :ycor :list (local "cur "tail) if emptyp :list [output 0] make "cur first :list ifelse and (less? abs difference first cur xcor 0.001)(less? abs difference last cur ycor 0.001) [ output 1 ] [ make "tail mt.find :xcor :ycor butfirst :list if not equalp :tail 0 [ make "tail sum :tail 1 ] output :tail ] end to mt.setxy :xcor :ycor local "node if and :mt.draw :mt.start [ make "node mt.find :mt.xpos :mt.ypos :mt.nodes if equalp node 0 [ make "mt.nodes lput (list :mt.xpos :mt.ypos) :mt.nodes make "node count :mt.nodes ] make "mt.ways lput (list node) mt.ways ] make "mt.xpos :xcor make "mt.ypos :ycor if :mt.draw [ make "node mt.find :xcor :ycor :mt.nodes if equalp node 0 [ make "mt.nodes lput (list :xcor :ycor) :mt.nodes make "node count :mt.nodes ] make "mt.ways lput lput node last mt.ways butlast mt.ways make "mt.start "false ] end copydef "setxy "mt.setxy to mt.forward :dist (setxy sum mt.xpos product dist sin mt.dir sum mt.ypos product dist cos mt.dir) end copydef "forward "mt.forward to mt.back :dist forward minus :dist end copydef "back "mt.back to mt.setpos :pos setxy first :pos last :pos end copydef "setpos "mt.setpos to mt.setx :xcor setxy :xcor :mt.ypos end copydef "setx "mt.setx to mt.sety :ycor setxy :mt.xpos :ycor end copydef "setx "mt.setx ; functions to change the heading direction to mt.right :degrees make "mt.dir modulo :mt.dir+:degrees 360 end copydef "right "mt.right copydef "rt "mt.right to mt.left :degrees right minus :degrees end copydef "left "mt.left copydef "lt "mt.left to mt.setheading :degrees make "mt.dir modulo :degrees 360 end copydef "setheading "mt.setheading to mt.home setpos [0 0] setheading 0 end copydef "home "mt.home to mt.pos output list :mt.xpos :mt.ypos end copydef "pos "mt.pos to mt.xcor output mt.xpos end copydef "xcor "mt.xcor to mt.ycor output mt.ypos end copydef "ycor "mt.ycor to mt.heading output mt.dir end copydef "heading "mt.heading to mt.towards :position output modulo (arctan difference last :position mt.ypos difference first :position mt.xpos) 360 end copydef "towards "mt.towards to mt.pendown make "mt.draw "true end copydef "pendown "mt.pendown copydef "pd "mt.pendown to mt.penup make "mt.draw "false make "mt.start "true end copydef "penup "mt.penup copydef "pu "mt.penup to mt.pendownp output "mt.draw end copydef "pendownp "mt.pendownp copydef "pendown? "mt.pendownp to mt.arc :angle :radius print [arc not implemented as OSM ways are straight lines] end copydef "arc "mt.arc to rect :side1 :side2 repeat 2 [forward :side1 right 90 forward :side2 right 90] end to writeosm :filename (local "cnt "lat "lon "degnodes "minlat "minlon "maxlat "maxlon) openwrite :filename setwrite :filename print [<?xml version='1.0' encoding='UTF-8'?>] print [<osm version='0.6' generator='mapturtle'>] make "minlat last mt.origin make "minlon first mt.origin make "maxlat last mt.origin make "maxlon first mt.origin make "degnodes map [ make "lat sum product last ? mt.latmetre last :mt.origin make "lon sum product first ? quotient mt.latmetre cos :lat first :mt.origin if lessp :lon :minlon [ make "minlon :lon ] if lessp :lat :minlat [ make "minlat :lat ] if greaterp :lon :maxlon [ make "maxlon :lon ] if greaterp :lat :maxlat [ make "maxlat :lat ] list :lon :lat ] :mt.nodes (print "<bounds (word "minlat=' :minlat "') (word "minlon=' :minlon "') (word "maxlat=' :maxlat "') (word "maxlon=' :maxlon "') "origin='CGImap "0.0.2'/>) foreach degnodes [ (print " " "<node (word "id=' minus # "') "action='modify' "visible='true' (word "lat=' last ? "') (word "lon=' first ? "'/>)) ] make "cnt difference -1 count :mt.nodes foreach :mt.ways [ (print " " "<way (word "id=' :cnt "') "action='modify' "visible='true'>) make "cnt difference :cnt 1 foreach ? [ (print " " " " "<nd (word "ref=' minus ? "'/>)) ] (print " " "</way>) ] print "</osm> close :filename end