Skip to content

Calculate Road Direction in MapInfo Files

March 12, 2012

Mapnik has a neat feature to label lines – text nicely fallows them. However in Lithuania we have a lot of small streets with huge names and the final result isn’t as nice. Placing labels horizontally wasn’t the option as well, because it just look terrible.

So I wanted to place labels with some angle, here is my result:

I think OGR should have a feature to do it, but if we’re working with MapInfo files (and they are just text), it is easy to just do it in Python if you don’t want to investigate the API. Here is the quick and dirty hardcoded Python code to do it:

import math

def radians(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    m = math.sqrt((dx*dx) + (dy*dy))

    if m == 0:
        return 0
    return math.atan2(dy/m, dx/m)

def radiansToDegress(r):
    return 180 * r / math.pi

def normalize(degrees):
    while degrees < 0:
        degrees += 360
    if degrees >= 180 and degrees < 270:
        return degrees - 180
    if degrees >= 90 and degrees < 180:
        return degrees + 180
    return degrees

f = open('C:\Roads1Name.mif', 'r')
mifLines = f.readlines()
f.close()

f = open('C:\Roads1Name.mid', 'r')
midLines = f.readlines()
f.close()

mifOut = open('C:\Roads1NameO.mif', 'w')
midOut = open('C:\Roads1NameO.mid', 'w')

i = 0
x1 = 0
y1 = 0
x2 = 0
y2 = 0
currentLine = 0
lineCount = -1
for line in mifLines:
    newMifLine = line
    currentLine += 1

    if 'Columns' in line:
        number = int(line[8:-1])
        newMifLine = 'Columns ' + str(number+1) + '\n'

    if 'Data' in line:
        newMifLine = 'ORIENTATION Integer\n' + line

    if 'Line' in line:
        coords = line.split()[1:5]
        x1 = float(coords[0])
        y1 = float(coords[1])
        x2 = float(coords[2])
        y2 = float(coords[3])
        midLine = midLines[i][0:-1] + ',' + str(normalize(radiansToDegress(radians(x1, y1, x2, y2)))) + '\n'
        midOut.write(midLine)
        i += 1

    if 'Pline' in line:
        lineCount = int(line[6:-1])
        currentLine = 0

    if currentLine == 1 and lineCount != -1:
        coords = line.split()
        x1, y1 = float(coords[0]), float(coords[1])

    if currentLine == lineCount:
        coords = line.split()
        x2, y2= float(coords[0]), float(coords[1])
        str(normalize(radiansToDegress(radians(x1, y1, x2, y2))))
        midLine = midLines[i][0:-1] + ',' + str(normalize(radiansToDegress(radians(x1, y1, x2, y2)))) + '\n'
        midOut.write(midLine)
        i += 1
    mifOut.write(newMifLine)

mifOut.close()
midOut.close()
Advertisements
No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: