Example #1
0
 def __init__ (self, namebuilder):
     self.__helper = ParcelHelper()
     self.__stream = BufferStream()
     self.__name_builder = namebuilder
Example #2
0
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())