class RoadNameBuilder: def __init__ (self): self.__stream = BufferStream() self.__name_dict = {} def build (self, name): offset = self.__name_dict.get(name) if offset == None: offset = self.__stream.tell() self.__stream.writeWord(len(name)) self.__stream.write(name) self.__name_dict[name] = offset return offset def save (self, stream): stream.write(self.__stream.getValue())
def __init__(self, namebuilder): self.__stream = BufferStream() self.__name_builder = namebuilder
class BackBuilder: def __init__(self, namebuilder): self.__stream = BufferStream() self.__name_builder = namebuilder def build (self, parcel, rect): self.__parcel = parcel self.__rect = rect stream = self.__stream frame_beg = stream.tell() #### header #### stream.writeDword(0) #< frame size stream.writeDword(0) #< area offset stream.writeDword(0) #< area size stream.writeDword(0) #< edge offset stream.writeDword(0) #< edge size stream.writeDword(0) #< node offset stream.writeDword(0) #< node size #### area area_offset = stream.tell() self.buildArea(stream) area_size = stream.tell() - area_offset #### edge edge_offset = stream.tell() self.buildEdge(stream) edge_size = stream.tell() - edge_offset #### node node_offset = stream.tell() self.buildNode(stream) node_size = stream.tell() - node_offset #### background name name_offset = stream.tell() self.__name_builder.save(stream) name_size = stream.tell() - name_offset ### frame size frame_end = stream.tell() frame_size = frame_end-frame_beg #### rewirte stream.seek(frame_beg) stream.writeDword(frame_size) stream.seek(frame_beg+4) stream.writeDword(area_offset) stream.writeDword(area_size) stream.writeDword(edge_offset) stream.writeDword(edge_size) stream.writeDword(node_offset) stream.writeDword(node_size) #### seek end stream.seek(frame_end) def buildArea(self, stream): for area in self.__parcel.back_area_list: stream.writeWord(area.themecode) #< theme code stream.writeWord(area.featcode) #< feature code name_offset = self.__name_builder.build(area.name) stream.writeDword(name_offset) #< name offset point_num = len(area.polylist[0]) stream.writeWord(point_num) #< intermidate point num for lat, lon in self.nominalizePolygon(area.polylist[0]): byte1 = lat & 0xff byte2 = lon & 0xff byte3 = ((lat >> 8) & 0x0f) | ((lon >> 4) & 0xf0) stream.writeByte(byte1) stream.writeByte(byte2) stream.writeByte(byte3) def buildEdge(self, stream): for line in self.__parcel.back_edge_list: stream.writeWord(line.themecode) #< theme code stream.writeWord(line.featcode) #< feature code name_offset = self.__name_builder.build(line.name) stream.writeDword(name_offset) #< name offset point_num = len(line.polyline) stream.writeWord(point_num) #< intermidate point num for lat, lon in self.nominalizePolygon(line.polyline): byte1 = lat & 0xff byte2 = lon & 0xff byte3 = ((lat >> 8) & 0x0f) | ((lon >> 4) & 0xf0) stream.writeByte(byte1) stream.writeByte(byte2) stream.writeByte(byte3) def buildNode(self, stream): for node in self.__parcel.back_node_list: stream.writeWord(node.themecode) #< theme code stream.writeWord(node.featcode) #< feature code name_offset = self.__name_builder.build(node.name) stream.writeDword(name_offset) #< name offset lat,lon = self.nominalizePoint(node.point) byte1 = lat & 0xff byte2 = lon & 0xff byte3 = ((lat >> 8) & 0x0f) | ((lon >> 4) & 0xf0) stream.writeByte(byte1) stream.writeByte(byte2) stream.writeByte(byte3) def nominalizePoint(self, point): lat,lon = point nominal_lat = (lat - self.__rect[0]) * 4095 / (self.__rect[2] - self.__rect[0]) nominal_lon = (lon - self.__rect[1]) * 4095 / (self.__rect[3] - self.__rect[1]) return (int(nominal_lat), int(nominal_lon)) def nominalizePolygon(self, polygon): nominal_points = [] for point in polygon: nominal_lat, nominal_lon = self.nominalizePoint(point) nominal_points.append((nominal_lat, nominal_lon)) return nominal_points def save (self, stream): if self.__parcel.back_area_list or self.__parcel.back_edge_list or self.__parcel.back_node_list: stream.write(self.__stream.getValue())
def __init__ (self, namebuilder): self.__helper = ParcelHelper() self.__stream = BufferStream() self.__name_builder = namebuilder
class RoadBuilder: def __init__ (self, namebuilder): self.__helper = ParcelHelper() self.__stream = BufferStream() self.__name_builder = namebuilder def build (self, parcel, rect, simplify=True): self.__parcel = parcel self.__multilink_list = self.__helper.buildMultiLinkList(parcel) self.__rect = rect self.__simplify = simplify stream = self.__stream roadbeg = stream.tell() #### begin frame #### stream.writeWord(len(parcel.multilink_table)) #< multilink count stream.writeWord(len(parcel.link_table)) #< link count self.__multilink_list.sort(self.__compareMultiLink) for multilink in self.__multilink_list: self.__buildMultiLink(multilink, stream) def __compareMultiLink(self, a, b): shape1 = self.__parcel.link_list[abs(a[0][0])-1] shape2 = self.__parcel.link_list[abs(b[0][0])-1] # priority if shape1.priority > shape2.priority: return -1 elif shape1.priority < shape2.priority: return 1 if shape1.roadtype > shape2.roadtype: return 1 elif shape1.roadtype < shape2.roadtype: return -1 return 0 def __buildMultiLink (self, multilink, stream): multilinkbeg = stream.tell() stream.writeWord(0) #< multilink size word = self.__helper.getShapeRoadType(self.__parcel, multilink[0][0]) << 12 word |= len(multilink) stream.writeWord(word) #< road type + link count stream.writeDword(0) # absolute link id for link in multilink: self.__buildLink(link, stream) #### rewrite ### multilinkend = stream.tell() stream.seek(multilinkbeg) stream.writeWord(multilinkend-multilinkbeg) stream.seek(multilinkend) def __buildLink (self, link, stream): # regular shape points points = [] for i in link: shape = self.__parcel.link_list[abs(i)-1] if i > 0: for j in range(len(shape.polyline)): node = shape.polyline[j] lat = (node[0]-self.__rect[0])*4095/(self.__rect[2]-self.__rect[0]) lon = (node[1]-self.__rect[1])*4095/(self.__rect[3]-self.__rect[1]) points.append((lat, lon)) else: for j in range(len(shape.polyline), 0, -1): node = shape.polyline[j-1] lat = (node[0]-self.__rect[0])*4095/(self.__rect[2]-self.__rect[0]) lon = (node[1]-self.__rect[1])*4095/(self.__rect[3]-self.__rect[1]) points.append((lat, lon)) #if self.__simplify: # points = geom.simplify_polyline(points, 12) #else: # points = geom.simplify_polyline(points, 8) points = geom.simplify_polyline(points, 12) byte = self.__helper.getShapeSubtype(self.__parcel, link[0]) << 4 byte |= self.__helper.getShapeRoadType(self.__parcel, link[0]) stream.writeByte(byte) #< link subtype + point count nameoffset = self.__name_builder.build(self.__helper.getShapeRoadName(self.__parcel, link[0])) stream.writeDword(nameoffset) #< road name offset # intermediate point num + direction word = len(points)-1 stream.writeWord(word) #< point count # first assert points[0][0] >= 0 assert points[0][1] >= 0 assert points[0][0] < 4096 assert points[0][1] < 4096 byte1 = ((points[0][0] & 0xf00) >> 4) | ((points[0][1] & 0xf00) >> 8) byte2 = (points[0][0] & 0xff) byte3 = (points[0][1] & 0xff) stream.writeByte(byte1) #< first point coordinate stream.writeByte(byte2) #< first point coordinate stream.writeByte(byte3) #< first point coordinate # intermidate for i in range(1, len(points)): assert points[i][0] < 4096 assert points[i][1] < 4096 lat = points[i][0]-points[i-1][0] lon = points[i][1]-points[i-1][1] assert abs(lat) < 128 assert abs(lon) < 128 if lat < 0: lat = (-lat) | 0x80 if lon < 0: lon = (-lon) | 0x80 stream.writeByte(lat) #< latitude offset stream.writeByte(lon) #< longitude offset def save (self, stream): if self.__parcel.link_list: stream.write(self.__stream.getValue())
def __init__ (self): self.__stream = BufferStream() self.__name_dict = {}
def build (self, parcel, rect, simplify=True): buffer = BufferStream() #### header #### # freme size buffer.writeDword(0) #< frame size buffer.writeDword(0) #< road offset buffer.writeDword(0) #< road size buffer.writeDword(0) #< road name offset buffer.writeDword(0) #< road name size buffer.writeDword(0) #< back offset buffer.writeDword(0) #< back size buffer.writeDword(0) #< back name offset buffer.writeDword(0) #< back name size #### road frame ##### road_offset = buffer.tell() road_name_builder = RoadNameBuilder() road_builder = RoadBuilder(road_name_builder) road_builder.build(parcel, rect, simplify) road_builder.save(buffer) road_size = buffer.tell() - road_offset road_name_offset = buffer.tell() road_name_builder.save(buffer) road_name_size = buffer.tell()-road_name_offset #### back frame ##### back_offset = buffer.tell() back_name_builder = BackNameBuilder() back_builder = BackBuilder(back_name_builder) back_builder.build(parcel, rect) back_builder.save(buffer) back_size = buffer.tell()-back_offset back_name_offset = buffer.tell() back_name_builder.save(buffer) back_name_size = buffer.tell()-back_name_offset #### rewrite header #### parcel_size = buffer.tell() buffer.seek(0) buffer.writeDword(parcel_size) buffer.writeDword(road_offset) buffer.writeDword(road_size) buffer.writeDword(road_name_offset) buffer.writeDword(road_name_size) buffer.writeDword(back_offset) buffer.writeDword(back_size) buffer.writeDword(back_name_offset) buffer.writeDword(back_name_size) ## return return buffer.getValue()