[Talk-ca] mp2osm - easy program
Sam Vekemans
acrosscanadatrails at gmail.com
Tue Feb 9 03:38:27 GMT 2010
Hi, I see your name on the code for the mp2osm python script. I might have
asked you about this before.
http://forums.gps.org.nz/viewtopic.php?f=37&t=4141
I think i cracked the code, as all i need to do is have that "short.mp"
file, in the same directory as the python folder.
and run it, just as i would with mkgmap or sendmap or groundtruth .. and
just let the program do it's magic.
I figured that all i need todo is make sure that my line types & point types
that are in the .mp file, will convert to the correct OSM file type.
Once i have it converted into OSM format, i can then use gpsbabel and make a
.gpx track from it. Or i can use JOSM and right-click and save layer as
gpx. - Not directly related to OSM, but it's a great tool to be able to
swap back from the Garmin MapSource maps (ie. the Ontario Snowmobile trails
from the last message). (But not the Ibycus topo 'cause the licence forbids
that)
Anyway, would you be able to confirm for me that the script does in fact
still work?
Thanks,
Sam
P.S. I have the grountruthSRTM contours for your area done. Do you want to
download the file and test it out?
My contours are 10m .. where the Ibycus is at 20m. I can make 5meter
contours, do you think that's needed?
copied below ... the wheel was only invented once :) & duplicated 4 times to
make a car. 2 times to make a bicycle. the later is much more efficient :)
Twitter: @Acrosscanada
Blog: http://Acrosscanadatrails.blogspot.com
Facebook: http://www.facebook.com/sam.vekemans
Skype: samvekemans
OpenStreetMap IRC: http://irc.openstreetmap.org
@Acrosscanadatrails
# derived from 'mp2osm_ukraine.py'
# modified by simon at mungewell.org
# modified by Karl Newman (User:SiliconFiend) to preserve routing topology
and parse RouteParam
# license: GPL V2 or later
import xml.etree.ElementTree as ET
attribution = 'NZ Open GPS Project, LINZ'
file_mp = open('short.mp')
# flags and global variable
poi = False
polyline = False
polygon = False
roadid = ''
rNodeToOsmId = {} # map routing node ids to OSM node ids
# debug/stats counters
poi_counter = 0
polyline_counter = 0
polygon_counter = 0
osm = ET.Element('osm', version='0.5', generator='mp2osm_NZOGPS' )
osm.text = '\n '
osm.tail = '\n'
source = ET.Element('tag', k='source',v=attribution)
source.tail = '\n '
nodeid = -1
# Define the mapping from Garmin type codes to OSM tags
# Note that single items in parentheses need a trailing comma
poitagmap = {# Warning: this particular 'gate' typecode usage is specific to
Calgary Trails maps
(0x1612, 0x1c00, 0x6400): {'highway': 'gate'},
(0x2b00,): {'tourism': 'hotel'},
(0x2b01,): {'tourism': 'motel'},
(0x2b03,): {'tourism': 'caravan_site'},
(0x2e02,): {'shop': 'supermarket'},
(0x2f08,): {'amenity': 'bus_station'},
(0x4400,): {'amenity': 'fuel'},
(0x4700,): {'leisure': 'slipway'},
(0x4800,): {'tourism': 'campsite'},
(0x4900,): {'leisure': 'park'},
(0x4a00,): {'tourism': 'picnic_site'},
(0x4c00,): {'tourism': 'information'},
(0x4d00,): {'amenity': 'parking'},
(0x4e00,): {'amenity': 'toilets'},
(0x5100,): {'amenity': 'telephone'},
(0x5200,): {'tourism': 'viewpoint'},
(0x5400,): {'sport': 'swimming'},
(0x5904,): {'aeroway': 'helipad'},
(0x5905,): {'aeroway': 'aerodrome'},
(0x5904,): {'aeroway': 'helipad'},
(0x5a00,): {'distance_marker': 'yes'}, # Not approved
(0x6401,): {'bridge': 'yes'}, # Apply to points?
(0x6401,): {'building': 'yes'},
(0x6406,): {'highway': 'crossing'},
(0x640c,): {'man_made': 'mineshaft'},
(0x640d,): {'man_made': 'pumping_rig', 'type': 'oil'},
(0x6411,): {'man_made': 'tower'},
(0x6412,): {'highway': 'trailhead'}, # This is not even a proposed
value
(0x6413,): {'tunnel': 'yes'}, # Apply to points?
(0x6500, 0x650d): {'natural': 'water'},
(0x6508,): {'waterway': 'waterfall'},
(0x6605,): {'natural': 'bench'},
(0x6616,): {'natural': 'peak'}
}
polylinetagmap = {
(0x2,): {'highway': 'trunk'},
(0x3,): {'highway': 'primary'},
(0x4,): {'highway': 'secondary'},
(0x5,): {'highway': 'tertiary'},
(0x6,): {'highway': 'residential'},
(0xa,): {'highway': 'track', 'surface': 'unpaved'},
(0x16,): {'highway': 'footway'},
(0x18,): {'waterway': 'stream'},
(0x1f,): {'waterway': 'river'},
(0x29,): {'power': 'line'}
}
polygontagmap = {
(0x5,): {'amenity': 'parking', 'area': 'yes'},
(0xd,): {'landuse': 'reservation', 'area': 'yes'}, # reservation is not
even a proposed value
(0x3c, 0x40, 0x41): {'natural': 'water', 'area': 'yes'},
(0x48, 0x49): {'waterway': 'riverbank', 'area': 'yes'},
(0x4c,): {'waterway': 'intermittent', 'area': 'yes'},
(0x51,): {'natural': 'marsh', 'area': 'yes'}
}
for line in file_mp:
# Marker for start of sections
if line.startswith(('[POI]','[RGN10]','[RGN20]')):
node = ET.Element('node', visible='true', id=str(nodeid))
nodeid -= 1
node.append(source)
poi = True
elementtagmap = poitagmap
poi_counter += 1
if line.startswith(('[POLYLINE]','[RGN40]')):
node = ET.Element('way', visible='true', id=str(nodeid))
nodeid -= 1
node.append(source)
polyline = True
elementtagmap = polylinetagmap
rnodes = {} # Track routing nodes for current polyline
polyline_counter += 1
if line.startswith(('[POLYGON]','[RGN80]')):
node = ET.Element('way', visible='true', id=str(nodeid))
nodeid -= 1
node.append(source)
polygon = True
elementtagmap = polygontagmap
polygon_counter += 1
# parsing data
if poi or polyline or polygon:
if line.startswith('Label'):
label = line.split('=')[1].strip()
# Now strip out control codes such as ~[0x2f]
codestart = label.find('~[')
if codestart != -1:
codeend = label.find(']',codestart)
if codeend != -1:
label = label[0:codestart] + ' ' + label[codeend+1:]
tag = ET.Element('tag', k='name',v=label.strip().title()) #
convert to title case
tag.tail = '\n '
node.append(tag)
if line.startswith('Type'):
typecode = line.split('=')[1].strip()
tag = ET.Element('tag', k='garmin_type',v=typecode)
tag.tail = '\n '
node.append(tag)
typecode = int(typecode, 16)
for codes, taglist in elementtagmap.iteritems():
if typecode in codes:
for key, value in taglist.iteritems():
tag = ET.Element('tag', k=key, v=value)
tag.tail = '\n '
node.append(tag)
if line.startswith('RoadID'):
roadid = line.split('=')[1].strip()
tag = ET.Element('tag', k='catmp-RoadID',v=roadid)
tag.tail = '\n '
node.append(tag)
if line.startswith('RouteParam'):
rparams = line.split('=')[1].split(',')
# speedval has speeds in km/h corresponding to RouteParam speed
value index
speedval = [8, 20, 40, 56, 72, 93, 108, 128]
speed = ET.Element('tag', k='maxspeed',
v=str(speedval[int(rparams[0])]))
speed.tail = '\n '
node.append(speed)
rclass = ET.Element('tag', k='garmin_road_class',
v=str(rparams[1]))
rclass.tail = '\n '
node.append(rclass)
for att, attval in zip(('oneway', 'toll'), rparams[2:3]):
if int(attval):
attrib = ET.Element('tag', k=att, v='true')
attrib.tail = '\n '
node.append(attrib)
# Note: taxi is not an approved access key
vehicles = ['emergency', 'goods', 'motorcar', 'psv', 'taxi',
'foot', 'bicycle', 'hgv']
for veh, res in zip(vehicles, rparams[4:]):
vehtag = ET.Element('tag', k=veh, v=('yes', 'no')[int(res)])
vehtag.tail = '\n '
node.append(vehtag)
# Get nodes from all zoom levels (ie. Data0, Data1, etc)
# TODO: Only grab the lowest-numbered data line (highest-resolution)
and ignore the rest
if line.startswith('Data'):
if poi:
coords = line.split('=')[1].strip()
coords = coords.split(',')
node.set('lat',str(float(coords[0][1:])))
node.set('lon',str(float(coords[1][:-1])))
if polyline or polygon:
# Just grab the line and parse it later when the [END]
element is encountered
coords = line.split('=')[1].strip() + ','
# TODO: parse out "holes" in a polygon by reading multiple
Data0 lines and
# constructing a multipolygon relation
if line.startswith('Nod'):
if polyline:
# Store the point index and routing node id for later use
nod = line.split('=')[1].strip().split(',', 2)
rnodes[nod[0]] = nod[1]
if line.startswith('[END]'):
if polyline or polygon:
# Have to write out nodes as they are parsed
nodidx = 0
nodIds = []
reused = False
while coords != '':
coords = coords.split(',', 2)
if str(nodidx) in rnodes:
if rnodes[str(nodidx)] in rNodeToOsmId:
curId = rNodeToOsmId[str(rnodes[str(nodidx)])]
reused = True
else:
curId = nodeid
nodeid -= 1
rNodeToOsmId[str(rnodes[str(nodidx)])] = curId
else:
curId = nodeid
nodeid -= 1
nodIds.append(curId)
# Don't write another node element if we reused an
existing one
if not reused:
nodes = ET.Element('node', visible='true',
id=str(curId), lat=str(float(coords[0][1:])),
lon=str(float(coords[1][:-1])))
nodes.text = '\n '
nodes.tail = '\n '
osm.append(nodes)
coords = coords[2]
reused = False
nodidx += 1
nodidx = 0
for ndid in nodIds:
nd = ET.Element('nd', ref=str(ndid))
nd.tail = '\n '
node.append(nd)
if polygon:
nd = ET.Element('nd', ref=str(nodIds[0]))
nd.tail = '\n '
node.append(nd)
poi = False
polyline = False
polygon = False
roadid = ''
rnodes = {} # Clear out routing nodes to prepare for next entity
node.text = '\n '
node.tail = '\n '
osm.append(node)
# writing to file
f = open('out.osm', 'w')
f.write(ET.tostring(osm))
# dump some stats
print '======'
print 'Totals'
print '======'
print 'POI', poi_counter
print 'POLYLINE', polyline_counter
print 'POLYGON', polygon_counter
print 'Last nodeid', nodeid
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstreetmap.org/pipermail/talk-ca/attachments/20100208/8ad1559a/attachment.html>
More information about the Talk-ca
mailing list