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())