OpenStreetMap logo OpenStreetMap

Mapping large circular features

Posted by Opk on 10 August 2010 in English. Last updated on 23 August 2010.

I recently looked at improving the very basic map data for the Waldfriedhof in Darmstadt - a large circular cemetery.

When creating a circle using JOSM, you get an octagon. This is fine for roundabouts but for anything larger the wiki tells you to to put a few extra nodes in and then select align nodes in circle. This isn't very precise - start with a 600 metre line, turn it into an octagonal "circle", add another 8 nodes, align in a circle and then measure the diameter. It comes out as about 578 metres. I needed it to be precise because there are paths closely following both sides of the perimeter fence.

So to get a much better circle, I first created an octagon, did a copy and paste to get a second octagon. I placed this exactly over the first octagon and rotated it. Adding lines across the octagon can help with accurate positioning. I then repeated the process again, copying both octagons together to get 32 nodes total. It is then possible to draw a 32 sided "circle" manually through these nodes and delete the four octagons.

At this point, I discovered that the cemetery is actually very slightly egg shaped. This is hard to spot because the lower half tapers into a rectangle. I was about to start on some calculations to work out how much I would need to move each node down by to massage my circle into an egg shape when it occurred to me that it might be easier to simply write a script to draw me the appropriate shape and save it to a .osm file that I could load with josm. This approach also made it easy to accurately map the path along the perimeter.

The script below is a simplified example for drawing an ellipse. A few constants define the size and position of the ellipse and the number of nodes (use a multiple of 4). The calculations look a bit complicated but basically it just uses cos and sin to get the position in metres from the angle (in radians) and then converts metres to latitude/longitude degrees. This is more complicated for the longitude because it depends on the latitude.


#!/bin/zsh
zmodload zsh/mathfunc

typeset -F midlat midlon angle metre
steps=32
width=588
height=590
midlon=8.61193
midlat=49.87309
(( circum = 40041455 ))
(( latmetre = 360.0/circum ))
node=0

for step in {1..$steps}; do
  (( angle=(step-1) * 8*atan(1) / steps ))

  lat[$step]=$(( midlat+latmetre*height*cos(angle)/2 ))
  lon[$step]=$(( midlon+latmetre/cos(atan(1)*lat[$step]/45)*width*sin(angle)/2 ))
done

cat - <
echo " <way id='$((--node))' action='modify' visible='true'>"
for step in {1..$steps} 1; do
  echo " <nd ref='$((-step))'/>"
done

cat - <<END
  </way>
</osm>
END

I'm inclined to extend this approach to create something more general that can be used for things like mapping buildings based on measurements.

Location: Waldkolonie, Darmstadt-Nord, Darmstadt, Hesse, Germany
Email icon Bluesky Icon Facebook Icon LinkedIn Icon Mastodon Icon Telegram Icon X Icon

Discussion

Comment from Sundance on 10 August 2010 at 18:35

The Potlatch algoritm does a certain number of default nodes for a circle, you can add more nodes and will smooth the circle out a bit more. Of course your's is somewhat eggshaped so Potlatch wouldn't exactly fit your problme.

Log in to leave a comment