def makeWay(self, w, wayId, strings): way = [] startNodeId, length, isCycle, elevation = w if not str(elevation) in strings: strings.append(str(elevation)) # id, id=1 way.append(self.makeVar("V", 1, wayId, int2str)) # keys, id=2 keys = join([int2str(el) for el in [1, 2, 4]]) way.append(self.makeVar("S", 2, keys)) # ways, id=3 vals = join([ int2str(el) for el in [ strings.index(str(elevation)), 3, strings.index(self.elevClassifier(elevation)) ] ]) way.append(self.makeVar("S", 3, vals)) # info, id=4 info = self.makeWayInfo() way.append(self.makeVar("S", 4, info)) # refs, id=8 refs = sint2str(startNodeId) + sint2str(1) * (length - 1) if isCycle: refs += sint2str(-(length - 1)) way.append(self.makeVar("S", 8, refs)) return join(way)
def makeDenseNodes(self, startNodeId, nodeList): dense = [] Lon = [ nodeList[0][0] // self.granularity, ] Lat = [ nodeList[0][1] // self.granularity, ] last_lon = Lon[0] last_lat = Lat[0] for lon, lat in nodeList[1:]: lon = lon // self.granularity lat = lat // self.granularity lon_diff = lon - last_lon lat_diff = lat - last_lat Lon.append(lon_diff) Lat.append(lat_diff) last_lon = lon last_lat = lat # id, id=1 id = sint2str(startNodeId) + sint2str(1) * (len(Lon) - 1) dense.append(self.makeVar("S", 1, id)) # denseinfo, id=5 dense.append(self.makeVar("S", 5, self.makeDenseInfo(len(Lon)))) # lat, id=8 LAT = join([sint2str(l) for l in Lat]) dense.append(self.makeVar("S", 8, LAT)) # lon, id=9 LON = join([sint2str(l) for l in Lon]) dense.append(self.makeVar("S", 9, LON)) return join(dense)
def makeBBoxDataset(self): # bbox dataset, with length bboxDataset = [ writableInt(0xdb), ] bboxData = join([sint2str(int(i * HUNDREDNANO)) for i in self.bbox]) bboxDataset.append(int2str(len(bboxData))) bboxDataset.append(bboxData) return join(bboxDataset)
def makeVar(self, vType, vId, content, func=None): varIdent = self.makeVarIdent(vType, vId) if vType == "S": return join([ varIdent, int2str(len(content)), content, ]) elif vType == "V": # V means varint, so content is an int. return join([ varIdent, func(content), ])
def makeWayData(self, way, idDelta, first): startNodeId, length, isCycle, elevation = way data = [] data.append(sint2str(idDelta)) # version information if first: # first way data.append(self.makeVersionChunk(first=True)) else: data.append(self.makeVersionChunk(first=False)) # node references wayRefSection = self.makeWayReferenceSection(startNodeId, length, isCycle) wayRefSectionLen = len(wayRefSection) data.append(int2str(wayRefSectionLen)) data.append(wayRefSection) # tags # ele = <elevation> eleTag = self.makeStringPair("ele", str(elevation)) contourTag = self.makeStringPair("contour", "elevation") elevClassifierTag = self.makeStringPair("contour_ext", self.elevClassifier(elevation)) data.append(self.stringTable.stringOrIndex(eleTag)) data.append(self.stringTable.stringOrIndex(contourTag)) data.append(self.stringTable.stringOrIndex(elevClassifierTag)) return join(data)
def makeTimestampDataset(self): timestampDataset = [ writableInt(0xdc), ] timestampData = sint2str(self.timestamp) timestampDataset.append(int2str(len(timestampData))) timestampDataset.append(timestampData) return join(timestampDataset)
def writeNode(self, node, lastNode, idDelta): nodeDataset = [] # 0x10 means node nodeDataset.append(writableInt(0x10)) nodeData = self.makeNodeData(node, lastNode, idDelta) nodeDataLen = len(nodeData) nodeDataset.append(int2str(nodeDataLen)) nodeDataset.append(nodeData) self.outf.write(join(nodeDataset))
def writeWay(self, way, idDelta, first=False): wayDataset = [] # 0x11 means way wayDataset.append(writableInt(0x11)) wayData = self.makeWayData(way, idDelta, first) wayDataLen = len(wayData) wayDataset.append(int2str(wayDataLen)) wayDataset.append(wayData) self.outf.write(join(wayDataset))
def makeWayBlob(self, startWayId, ways): blob = [] wayPrimitiveBlock = self.makeWayPrimitiveBlock(startWayId, ways) # raw_size, id=2 blob.append(self.makeVarIdent("V", 2)) blob.append(int2str(len(wayPrimitiveBlock))) # zlib_data, id=3 zlib_data = zlib.compress(wayPrimitiveBlock) blob.append(self.makeVar("S", 3, zlib_data)) return join(blob)
def makeNodeBlob(self, startNodeId, nodes): blob = [] nodePrimitiveBlock = self.makeNodePrimitiveBlock(startNodeId, nodes) # raw_size, id=2 blob.append(self.makeVarIdent("V", 2)) blob.append(int2str(len(nodePrimitiveBlock))) # zlib_data, id=3 zlib_data = zlib.compress(nodePrimitiveBlock) blob.append(self.makeVar("S", 3, zlib_data)) return join(blob)
def makeHeaderBlob(self, osmVersion, phyghtmapVersion): blob = [] headerBlock = self.makeHeaderBlock(osmVersion, phyghtmapVersion) # raw_size, id=2 blob.append(self.makeVarIdent("V", 2)) blob.append(int2str(len(headerBlock))) # zlib_data, id=3 zlib_data = zlib.compress(headerBlock) blob.append(self.makeVar("S", 3, zlib_data)) return join(blob)
def makeWayReferenceSection(self, startNodeId, length, isCycle): nodeIdDeltas = [] # the first node id, delta coded nodeIdDeltas.append(startNodeId - self.lastNodeId) nodeIdDeltas.extend([ 1, ] * (length - 1)) if isCycle: nodeIdDeltas.append(-(length - 1)) self.lastNodeId = startNodeId else: self.lastNodeId = startNodeId + length - 1 return join([sint2str(nodeIdDelta) for nodeIdDelta in nodeIdDeltas])
def writeWaysChunk(self, ways, startWayId): blobHeader = [] # type, id=1 blobHeader.append( self.makeVar(vType="S", vId=1, content=writableString("OSMData"))) # datasize, id=3 blobHeader.append(self.makeVarIdent(vType="V", vId=3)) blob = self.makeWayBlob(startWayId, ways) blobHeader.append(int2str(len(blob))) blobHeader = join(blobHeader) self.outf.write(pack('!L', len(blobHeader))) self.outf.write(blobHeader) self.outf.write(blob)
def makeWayInfo(self): info = [] # version, id=1 info.append(self.makeVar("V", 1, 1, int2str)) # timestamp, id=2 info.append(self.makeVar("V", 2, self.timestamp, int2str)) # changeset, id=3 info.append(self.makeVar("V", 3, 1, int2str)) # uid, id=4 info.append(self.makeVar("V", 4, 0, int2str)) # user_sid, id=5 info.append(self.makeVar("V", 5, 0, int2str)) return join(info)
def makeHeader(self, osmVersion, phyghtmapVersion): blobHeader = [] # type, id=1 blobHeader.append(self.makeVarIdent(vType="S", vId=1)) # len("OSMHeader") == 9 blobHeader.append(int2str(9)) blobHeader.append(writableString("OSMHeader")) # datasize, id=3 blobHeader.append(self.makeVarIdent(vType="V", vId=3)) blob = self.makeHeaderBlob(osmVersion, phyghtmapVersion) blobHeader.append(int2str(len(blob))) blobHeader = join(blobHeader) self.outf.write(pack('!L', len(blobHeader))) self.outf.write(blobHeader) self.outf.write(blob)
def makeHeaderBBox(self): bbox = [] left, bottom, right, top = [sint2str(int(i * NANO)) for i in self.bbox] # left, id=1 bbox.append(self.makeVarIdent("V", 1)) bbox.append(left) # right, id=2 bbox.append(self.makeVarIdent("V", 2)) bbox.append(right) # top, id=3 bbox.append(self.makeVarIdent("V", 3)) bbox.append(top) # bottom, id=4 bbox.append(self.makeVarIdent("V", 4)) bbox.append(bottom) return join(bbox)
def writeHeader(self, osmVersion, phyghtmapVersion): # write reset self.writeReset() header = [] #file format dataset (0xe0), length (0x04), format (o5m2) header.extend( [writableInt(0xe0), writableInt(0x04), writableString("o5m2")]) # timestamp dataset timestampDataset = self.makeTimestampDataset() header.append(timestampDataset) # bounding box dataset bboxDataset = self.makeBBoxDataset() header.append(bboxDataset) #write the header self.outf.write(join(header))
def makeHeaderBlock(self, osmVersion, phyghtmapVersion): headerBlock = [] # bbox, id=1 bbox = self.makeHeaderBBox() headerBlock.append(self.makeVar("S", 1, bbox)) # required_features, id=4 requiredFeatures = [ writableString("OsmSchema-V{0:.1f}".format(osmVersion)), writableString("DenseNodes"), ] for requiredFeature in requiredFeatures: headerBlock.append(self.makeVar("S", 4, requiredFeature)) # writingprogram, id=16 writingprogram = writableString( "phyghtmap {0:s} (http://wiki.openstreetmap.org/wiki/phyghtmap)". format(phyghtmapVersion)) headerBlock.append(self.makeVar("S", 16, writingprogram)) return join(headerBlock)
def makeDenseInfo(self, times): denseInfo = [] # version, id=1 version = int2str(1) * times denseInfo.append(self.makeVar("S", 1, version)) # timestamp, id=2 timestamp = sint2str(self.timestamp) + (sint2str(0) * (times - 1)) denseInfo.append(self.makeVar("S", 2, timestamp)) # changeset, id=3 changeset = sint2str(1) * times denseInfo.append(self.makeVar("S", 3, changeset)) # uid, id=4 uid = sint2str(0) * times denseInfo.append(self.makeVar("S", 4, uid)) # user_sid, id=5 user_sid = sint2str(0) * times denseInfo.append(self.makeVar("S", 5, user_sid)) return join(denseInfo)
def makeVersionChunk(self, first=False): data = [] # version data.append(int2str(1)) # timestamp = self.timestamp or 0, if self.timestamp, write changeset and # uid # timestamp is delta coded if first and self.writeTimestamp: data.append(sint2str(self.timestamp)) else: data.append(sint2str(0)) if self.writeTimestamp: # changeset, delta coded if first: data.append(sint2str(1)) else: data.append(sint2str(0)) # userid, username = ("", ""), string pair -> 0x00,0x00,0x00 data.append(self.stringTable.stringOrIndex(writableInt(0x00) * 3)) return join(data)
def makeNodePrimitiveBlock(self, startNodeId, nodes): nodePrimitiveBlock = [] # stringtable, id=1 stringtable = self.makeStringTable([ "", ]) nodePrimitiveBlock.append(self.makeVar("S", 1, stringtable)) # primitivegroup, id=2 nodePrimitiveGroup = self.makeNodePrimitiveGroup(startNodeId, nodes) nodePrimitiveBlock.append(self.makeVar("S", 2, nodePrimitiveGroup)) # granularity, id=17 nodePrimitiveBlock.append( self.makeVar("V", 17, self.granularity, int2str)) # date_granularity, id=18 nodePrimitiveBlock.append( self.makeVar("V", 18, self.date_granularity, int2str)) # lat_offset, id=19 nodePrimitiveBlock.append(self.makeVar("V", 19, 0, int2str)) # lon_offset, id=20 nodePrimitiveBlock.append(self.makeVar("V", 20, 0, int2str)) return join(nodePrimitiveBlock)
def makeNodeData(self, node, lastNode, idDelta): data = [] data.append(sint2str(idDelta)) # version information if lastNode == None: # first node since reset data.append(self.makeVersionChunk(first=True)) else: data.append(self.makeVersionChunk(first=False)) # lon, lat lon, lat = node if lastNode != None: deltaLon = sint2str(lon - lastNode[0]) deltaLat = sint2str(lat - lastNode[1]) else: deltaLon = sint2str(lon) deltaLat = sint2str(lat) data.append(deltaLon) data.append(deltaLat) # no tags, so data is complete now return join(data)
def makeWayPrimitiveBlock(self, startWayId, ways): wayPrimitiveBlock = [] strings = [] wayPrimitiveGroup = self.makeWayPrimitiveGroup(startWayId, ways, strings) stringtable = self.makeStringTable(strings) # stringtable, id=1 wayPrimitiveBlock.append(self.makeVar("S", 1, stringtable)) # primitivegroup, id=2 wayPrimitiveBlock.append(self.makeVar("S", 2, wayPrimitiveGroup)) # granularity, id=17 wayPrimitiveBlock.append( self.makeVar("V", 17, self.granularity, int2str)) # date_granularity, id=18 wayPrimitiveBlock.append( self.makeVar("V", 18, self.date_granularity, int2str)) # lat_offset, id=19 wayPrimitiveBlock.append(self.makeVar("V", 19, 0, int2str)) # lon_offset, id=20 wayPrimitiveBlock.append(self.makeVar("V", 20, 0, int2str)) return join(wayPrimitiveBlock)
def makeStringTable(self, stringList): """takes a list of str objects and returns a stringtable variable. """ # s, id=1 return join( [self.makeVar("S", 1, writableString(s)) for s in stringList])
def makeWayPrimitiveGroup(self, startWayId, ways, stringtable): ways = self.makeWays(startWayId, ways, stringtable) # ways, id=3 return join([self.makeVar("S", 3, w) for w in ways])