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 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 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 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 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 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 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 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 stringOrIndex(self, string): if len(string) > 250: return string if not string in self.table: self.table.append(string) if len(self.table) == self.maxStringRef + 1: self.table.pop(0) return string else: stringRef = len(self.table) - self.table.index(string) return int2str(stringRef)
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 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 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 makeVarIdent(self, vType, vId): vTypes = {"V": 0, "D": 1, "S": 2, "I": 5} vTypeNum = vTypes[vType] varIdentNum = vTypeNum + (vId << 3) return int2str(varIdentNum)