示例#1
0
    def close(self):
        if self.isopen:
            if self.mode in ['w', 'a']:
                self.maintable.setMode('w')
                self.addtable.setMode('w')
                self.auxtable.setMode('w')

                aux = AuxTableManager(self.auxtable)

                # Write features to database
                addrow = 0
                for f in self.xfeatures:
                    textslot = aux.appendText(f.name,
                                              self.maintable.getRowCount() + 1)

                    # Update cell elements
                    for ref, e in zip(f.cellelementrefs,
                                      f.getCellElements(self.map)):
                        e.textslot = textslot
                        layer = self.map.getLayerByIndex(f.layerindex)
                        layer.updateCellElement(ref, e)

                    row = Row(self.maintable)
                    row.setColumnUInt(
                        self.maintable.getColumnIndex("NAME_REF"), textslot)

                    row.setColumnUInt(
                        self.maintable.getColumnIndex("OBJ_TYPE"),
                        f.getObjtypeIndex(self))

                    cellelementrefs = f.getCellElementRefs()
                    if len(cellelementrefs) == 1:
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("CELL_NUM"),
                            cellelementrefs[0][0])
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("N_IN_C"),
                            cellelementrefs[0][1] + 1)
                    else:
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("CELL_NUM"),
                            0x80000000 | (addrow + 1))
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("N_IN_C"),
                            len(cellelementrefs))
                        for cref in cellelementrefs:
                            rowrc = Row(self.addtable)
                            rowrc.setColumnUInt(
                                self.addtable.getColumnIndex("CELL_NUM"),
                                cref[0])
                            rowrc.setColumnUInt(
                                self.addtable.getColumnIndex("N_IN_C"),
                                cref[1] + 1)
                            self.addtable.writeRow(rowrc)
                            addrow += 1
                    self.maintable.writeRow(row)

            self.isopen = False
示例#2
0
    def _initDB(self, db):
        maintablename = "POIPOINT_"

        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():
            createPOITables(db, self.poiprefix)

        # Open category manager
        self.catman.open(db, self.mode, poiprefix=self.poiprefix)

        self.auxtable = db.getTableByName("AUXTEXT_")
        self.maintable = db.getTableByName(maintablename)

        self.auxmanager = AuxTableManager(self.auxtable,
                                          endchar=chr(7),
                                          searchindex=False)
示例#3
0
    def testAddData(self):
        db = Database(MapDirectory(self.testdatadir), "db00", 'a')
        table = db.getTableByName("R_GR0")

        beforedata = [curs.getRow().asList() for curs in table.getCursor(0)]

        ## Add an empty row
        refrow = Row(table)
        refrow.setColumn(0, 1)
        table.writeRow(refrow)

        refdata = refrow.asList()

        db.close()

        db = Database(MapDirectory(self.testdatadir), "db00")
        table = db.getTableByName("R_GR0")

        aux = db.getTableByName("AUX_GR0")
        am = AuxTableManager(aux)

        afterdata = [curs.getRow().asList() for curs in table.getCursor(0)]

        for curs in table.getCursor(0):
            row = curs.getRow()

            index = row.asDict()['NAME_REF'] & 0xffffff
            offset = row.asDict()['NAME_REF'] >> 24

        self.assertEqual(beforedata + [refdata], afterdata)
示例#4
0
    def _initDB(self, db):
        groupnumber = self.map.getGroupIndex(self)

        maintablename = "R_GR%d" % groupnumber
        addtablename = "RC_GR%d" % groupnumber
        auxtablename = "AUX_GR%d" % groupnumber
        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():

            # Build main table
            fields = [
                FieldStruct(name='NAME_REF', fd_type=FieldTypeLONGINT),
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                FieldStruct(name='OBJ_TYPE', fd_type=FieldTypeCHARACTER)
            ] + self.extrafields
            db.addTable(name=maintablename,
                        filename=self.map.mapnumstr + "gr%d.ext" % groupnumber,
                        fieldstructlist=fields)

            # Build additional cells table
            fields = [
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
            ]
            db.addTable(name=addtablename,
                        filename=self.map.mapnumstr + "gr%d.clp" % groupnumber,
                        fieldstructlist=fields)

            # Build aux table
            fields = [
                FieldStruct(name='NAME_BUF',
                            fd_type=FieldTypeCHARACTER,
                            fd_dim1=248,
                            fd_dim2=1)
            ]
            db.addTable(name=auxtablename,
                        filename=self.map.mapnumstr + "gr%d.aux" % groupnumber,
                        fieldstructlist=fields)

        self.maintable = db.getTableByName(maintablename)
        self.addtable = db.getTableByName(addtablename)
        self.auxtable = db.getTableByName(auxtablename)
        self.auxmanager = AuxTableManager(self.auxtable)
示例#5
0
    def close(self):
        if self.isopen:
            if self.mode in ['w','a']:
                self.maintable.setMode('w')
                self.addtable.setMode('w')
                self.auxtable.setMode('w')

                aux = AuxTableManager(self.auxtable)

                # Write features to database
                addrow = 0
                for f in self.xfeatures:
                    textslot = aux.appendText(f.name, self.maintable.getRowCount()+1)

                    # Update cell elements
                    for ref, e in zip(f.cellelementrefs, f.getCellElements(self.map)):
                        e.textslot = textslot
                        layer = self.map.getLayerByIndex(f.layerindex)
                        layer.updateCellElement(ref, e)

                    row = Row(self.maintable)
                    row.setColumnUInt(self.maintable.getColumnIndex("NAME_REF"), textslot)

                    row.setColumnUInt(self.maintable.getColumnIndex("OBJ_TYPE"), f.getObjtypeIndex(self))

                    cellelementrefs = f.getCellElementRefs()
                    if len(cellelementrefs) == 1:
                        row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUM"), cellelementrefs[0][0])
                        row.setColumnUInt(self.maintable.getColumnIndex("N_IN_C"), cellelementrefs[0][1]+1)
                    else:
                        row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUM"), 0x80000000|(addrow+1) )
                        row.setColumnUInt(self.maintable.getColumnIndex("N_IN_C"), len(cellelementrefs))
                        for cref in cellelementrefs:
                            rowrc = Row(self.addtable)
                            rowrc.setColumnUInt(self.addtable.getColumnIndex("CELL_NUM"), cref[0])
                            rowrc.setColumnUInt(self.addtable.getColumnIndex("N_IN_C"), cref[1]+1)
                            self.addtable.writeRow(rowrc)
                            addrow+=1
                    self.maintable.writeRow(row)

            self.isopen = False            
示例#6
0
    def testSimple(self):
        db = Database(MapDirectory(self.testdatadir), "db00")

        table = db.getTableByName("R_GR0")

        for curs in table.getCursor(0):
            row = curs.getRow()

            aux = db.getTableByName("AUX_GR0")

            am = AuxTableManager(aux)

            index = row.asDict()['NAME_REF'] & 0xffffff
            offset = row.asDict()['NAME_REF'] >> 24
示例#7
0
    def _initDB(self, db):
        maintablename = "POIPOINT_"

        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():
            createPOITables(db, self.poiprefix)

        # Open category manager
        self.catman.open(db, self.mode, poiprefix=self.poiprefix)

        self.auxtable = db.getTableByName("AUXTEXT_")
        self.maintable = db.getTableByName(maintablename)

        self.auxmanager = AuxTableManager(self.auxtable, endchar=chr(7), searchindex=False)
示例#8
0
    def _initDB(self, db):
        groupnumber = self.map.getGroupIndex(self)

        maintablename = "R_GR%d"%groupnumber
        addtablename = "RC_GR%d"%groupnumber
        auxtablename = "AUX_GR%d"%groupnumber
        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():

            # Build main table
            fields = [
                FieldStruct(name='NAME_REF', fd_type=FieldTypeLONGINT),
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                FieldStruct(name='OBJ_TYPE', fd_type=FieldTypeCHARACTER)
                ] + self.extrafields
            db.addTable(name = maintablename,
                        filename = self.map.mapnumstr + "gr%d.ext"%groupnumber,
                        fieldstructlist = fields)

            # Build additional cells table
            fields = [
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                ]
            db.addTable(name = addtablename,
                        filename = self.map.mapnumstr + "gr%d.clp"%groupnumber,
                        fieldstructlist = fields)

            # Build aux table
            fields = [
                FieldStruct(name='NAME_BUF', fd_type=FieldTypeCHARACTER, fd_dim1=248, fd_dim2=1)
                ]
            db.addTable(name = auxtablename,
                        filename = self.map.mapnumstr + "gr%d.aux"%groupnumber,
                        fieldstructlist = fields)

        self.maintable = db.getTableByName(maintablename)
        self.addtable = db.getTableByName(addtablename)
        self.auxtable = db.getTableByName(auxtablename)
        self.auxmanager = AuxTableManager(self.auxtable)
示例#9
0
class GroupNormal(Group):
    textslot_column = 'NAME_REF'
    extrafields = []

    def __init__(self, map, name=None):
        Group.__init__(self, map, name=name)
        self.exportfields += ['name', 'objtype']
        self.exportfieldtypes += ['string', 'int']

    def initFromIni(self, inicfg):
        groupnumber = self.map.getGroupIndex(self)

        groupconfig = inicfg.get('GROUPS', str(groupnumber))
        tok = groupconfig.split(" ")
        self._name = tok[0]
        nlayers = int(tok[1])

        tok = tok[2:]

        self._layers = []
        for i in range(0, nlayers):
            layer = {}

            layer['number'] = int(tok.pop(0))

            objtypes = []
            if tok[0] == '(':
                tok.pop(0)
                while tok[0] != ')':
                    objtypes.append(int(tok.pop(0)))
                tok.pop(0)

            layer['objtypes'] = objtypes

            self._layers.append(layer)

    def updateIni(self, inicfg):
        groupnumber = self.map.getGroupIndex(self)
        groupconfig = [self.name, str(len(self._layers))]

        for layer in self._layers:
            objtypelist = map(str, layer['objtypes'])
            if len(objtypelist) == 0:
                objtypelist = ['0']
            groupconfig += [str(layer['number'])] + ['('] + objtypelist + [')']

        inicfg.set('GROUPS', str(groupnumber), ' '.join(groupconfig))

    def _initDB(self, db):
        groupnumber = self.map.getGroupIndex(self)

        maintablename = "R_GR%d" % groupnumber
        addtablename = "RC_GR%d" % groupnumber
        auxtablename = "AUX_GR%d" % groupnumber
        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():

            # Build main table
            fields = [
                FieldStruct(name='NAME_REF', fd_type=FieldTypeLONGINT),
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                FieldStruct(name='OBJ_TYPE', fd_type=FieldTypeCHARACTER)
            ] + self.extrafields
            db.addTable(name=maintablename,
                        filename=self.map.mapnumstr + "gr%d.ext" % groupnumber,
                        fieldstructlist=fields)

            # Build additional cells table
            fields = [
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
            ]
            db.addTable(name=addtablename,
                        filename=self.map.mapnumstr + "gr%d.clp" % groupnumber,
                        fieldstructlist=fields)

            # Build aux table
            fields = [
                FieldStruct(name='NAME_BUF',
                            fd_type=FieldTypeCHARACTER,
                            fd_dim1=248,
                            fd_dim2=1)
            ]
            db.addTable(name=auxtablename,
                        filename=self.map.mapnumstr + "gr%d.aux" % groupnumber,
                        fieldstructlist=fields)

        self.maintable = db.getTableByName(maintablename)
        self.addtable = db.getTableByName(addtablename)
        self.auxtable = db.getTableByName(auxtablename)
        self.auxmanager = AuxTableManager(self.auxtable)

    def open(self, mode='r'):
        """Open group and read all the layers and database tables. If the group is opened in append mode ('a'), all
        features are read into the features attribute"""

        if not self.isopen:
            self.mode = mode

            self._initDB(self.map.getDB())

            for li in self._layers:
                self.map.getLayerByIndex(li['number']).open(mode)

            if self.mode == 'a':
                for i in range(0, self.maintable.getRowCount()):
                    self._insert(self._getFeatureByIndex(i))
            self.isopen = True

    def close(self):
        if self.isopen:
            if self.mode in ['w', 'a']:
                self.maintable.setMode('w')
                self.addtable.setMode('w')
                self.auxtable.setMode('w')

                aux = AuxTableManager(self.auxtable)

                # Write features to database
                addrow = 0
                for f in self.xfeatures:
                    textslot = aux.appendText(f.name,
                                              self.maintable.getRowCount() + 1)

                    # Update cell elements
                    for ref, e in zip(f.cellelementrefs,
                                      f.getCellElements(self.map)):
                        e.textslot = textslot
                        layer = self.map.getLayerByIndex(f.layerindex)
                        layer.updateCellElement(ref, e)

                    row = Row(self.maintable)
                    row.setColumnUInt(
                        self.maintable.getColumnIndex("NAME_REF"), textslot)

                    row.setColumnUInt(
                        self.maintable.getColumnIndex("OBJ_TYPE"),
                        f.getObjtypeIndex(self))

                    cellelementrefs = f.getCellElementRefs()
                    if len(cellelementrefs) == 1:
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("CELL_NUM"),
                            cellelementrefs[0][0])
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("N_IN_C"),
                            cellelementrefs[0][1] + 1)
                    else:
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("CELL_NUM"),
                            0x80000000 | (addrow + 1))
                        row.setColumnUInt(
                            self.maintable.getColumnIndex("N_IN_C"),
                            len(cellelementrefs))
                        for cref in cellelementrefs:
                            rowrc = Row(self.addtable)
                            rowrc.setColumnUInt(
                                self.addtable.getColumnIndex("CELL_NUM"),
                                cref[0])
                            rowrc.setColumnUInt(
                                self.addtable.getColumnIndex("N_IN_C"),
                                cref[1] + 1)
                            self.addtable.writeRow(rowrc)
                            addrow += 1
                    self.maintable.writeRow(row)

            self.isopen = False

    def getLayerAndObjtypeFromObjtypeIndex(self, objtypeindex):
        idx = 0
        for l in self._layers:
            newidx = idx + len(l['objtypes'])
            if objtypeindex < newidx:
                return self.map.getLayerByIndex(
                    l['number']), l['objtypes'][objtypeindex - idx]
            idx = newidx

        raise ValueError('Couldnt find objtypeindex %d ' % objtypeindex +
                         str(self._layers))

    def __str__(self):
        groupnumber = self.map.getGroupIndex(self)
        s = self.name + " (%d):\n" % groupnumber
        for l in self._layers:
            s = s + "layer#: " + str(l['number']) + "\n"
            s = s + "objtypes: " + str(l['objtypes']) + "\n"
        s += "Columns in main table: " + str(
            self.maintable.getColumnNames()) + "\n"
        return s

    def getFeatureCount(self):
        if self.mode == 'r':
            return self.maintable.getRowCount()
        else:
            return len(self._features)

    def getFeatureByIndex(self, index):
        if self.mode == 'r':
            return self._getFeatureByIndex(index)
        else:
            return self._features[index][1]

    def _getFeatureByIndex(self, index):
        if index >= self.maintable.getRowCount():
            raise IndexError("index out of bounds")

        rec = self.maintable.getCursor(index).asDict()

        namekey = rec['NAME_REF']

        objtype_index = rec['OBJ_TYPE']
        layer, objtype = self.getLayerAndObjtypeFromObjtypeIndex(objtype_index)

        nameindex = namekey & 0xffffff
        nameoffset = namekey >> 24
        name = self.auxmanager.lookupText(nameindex, nameoffset)

        cellelementrefs = []
        if rec['CELL_NUM'] & 0x80000000:
            for j in range(0, rec['N_IN_C']):
                rcrow = (rec['CELL_NUM'] & 0xffffff) + j - 1
                rec2 = self.addtable.getCursor(rcrow).asDict()
                cellelementrefs.append((rec2['CELL_NUM'], rec2['N_IN_C'] - 1))
        else:
            cellelementrefs.append((rec['CELL_NUM'], rec['N_IN_C'] - 1))

        return FeatureNormal(self.map.getLayerIndex(layer), cellelementrefs,
                             name, objtype)

    def addFeature(self, feature):
        """Add feature to group. Return the index of the new feature"""
        if self.mode == 'r':
            raise ValueError("Group is open as read-only")

        # Get object type index and if it's not already present in the group
        # the objtype is added
        objtypeindex = feature.getObjtypeIndex(self)

        # Update objtypeindex
        for e in feature.getCellElements(self.map):
            e.objtype = objtypeindex

        self._insert(feature)

    def _insert(self, feature):
        ## Insert feature and keep the list sorted on name
        name = feature.name

        if name:
            item = (chr(sortHashFuncFast(name)) + name, feature)
            index = bisect.bisect_right(self._features, item)
            self._features.insert(index, item)
            return index

    def getObjtypeIndex(self, layernumber, objtype):
        idx = 0
        objnumber_index = None
        for li in self._layers:
            if li['number'] == layernumber:
                if objtype in li['objtypes']:
                    return idx + li['objtypes'].index(objtype)
                else:
                    if self.mode == 'r':
                        raise ValueError("Objtype does not exists")
                    # Objtype is not used in this layer before, add it
                    li['objtypes'].append(objtype)
                    return idx + len(li['objtypes']) - 1
            idx += len(li['objtypes'])
示例#10
0
class GroupNormal(Group):
    textslot_column = 'NAME_REF'
    extrafields = []
    def __init__(self, map, name=None):
        Group.__init__(self, map, name=name)
        self.exportfields += ['name', 'objtype']
        self.exportfieldtypes += ['string', 'int']
    
    def initFromIni(self, inicfg):
        groupnumber = self.map.getGroupIndex(self)

        groupconfig = inicfg.get('GROUPS',str(groupnumber))
        tok = groupconfig.split(" ")
        self._name = tok[0]
        nlayers = int(tok[1])

        tok = tok[2:]

        self._layers=[]
        for i in range(0, nlayers):
            layer={}

            layer['number'] = int(tok.pop(0))

            objtypes=[]
            if tok[0]=='(':
                tok.pop(0)
                while tok[0] != ')':
                    objtypes.append(int(tok.pop(0)))
                tok.pop(0)

            layer['objtypes'] = objtypes
            
            self._layers.append(layer)

    def updateIni(self, inicfg):
        groupnumber = self.map.getGroupIndex(self)
        groupconfig = [self.name, str(len(self._layers))]

        for layer in self._layers:
            objtypelist = map(str, layer['objtypes'])
            if len(objtypelist) == 0:
                objtypelist = ['0']
            groupconfig += [str(layer['number'])] + ['('] + objtypelist + [')']

        inicfg.set('GROUPS',str(groupnumber), ' '.join(groupconfig))

    def _initDB(self, db):
        groupnumber = self.map.getGroupIndex(self)

        maintablename = "R_GR%d"%groupnumber
        addtablename = "RC_GR%d"%groupnumber
        auxtablename = "AUX_GR%d"%groupnumber
        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():

            # Build main table
            fields = [
                FieldStruct(name='NAME_REF', fd_type=FieldTypeLONGINT),
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                FieldStruct(name='OBJ_TYPE', fd_type=FieldTypeCHARACTER)
                ] + self.extrafields
            db.addTable(name = maintablename,
                        filename = self.map.mapnumstr + "gr%d.ext"%groupnumber,
                        fieldstructlist = fields)

            # Build additional cells table
            fields = [
                FieldStruct(name='CELL_NUM', fd_type=FieldTypeLONGINT),
                FieldStruct(name='N_IN_C', fd_type=FieldTypeSHORTINT),
                ]
            db.addTable(name = addtablename,
                        filename = self.map.mapnumstr + "gr%d.clp"%groupnumber,
                        fieldstructlist = fields)

            # Build aux table
            fields = [
                FieldStruct(name='NAME_BUF', fd_type=FieldTypeCHARACTER, fd_dim1=248, fd_dim2=1)
                ]
            db.addTable(name = auxtablename,
                        filename = self.map.mapnumstr + "gr%d.aux"%groupnumber,
                        fieldstructlist = fields)

        self.maintable = db.getTableByName(maintablename)
        self.addtable = db.getTableByName(addtablename)
        self.auxtable = db.getTableByName(auxtablename)
        self.auxmanager = AuxTableManager(self.auxtable)
        
    def open(self, mode='r'):
        """Open group and read all the layers and database tables. If the group is opened in append mode ('a'), all
        features are read into the features attribute"""

        if not self.isopen:
            self.mode = mode

            self._initDB(self.map.getDB())

            for li in self._layers:
                self.map.getLayerByIndex(li['number']).open(mode)

            if self.mode == 'a':
                for i in range(0, self.maintable.getRowCount()):
                    self._insert(self._getFeatureByIndex(i))
            self.isopen = True
            
    def close(self):
        if self.isopen:
            if self.mode in ['w','a']:
                self.maintable.setMode('w')
                self.addtable.setMode('w')
                self.auxtable.setMode('w')

                aux = AuxTableManager(self.auxtable)

                # Write features to database
                addrow = 0
                for f in self.xfeatures:
                    textslot = aux.appendText(f.name, self.maintable.getRowCount()+1)

                    # Update cell elements
                    for ref, e in zip(f.cellelementrefs, f.getCellElements(self.map)):
                        e.textslot = textslot
                        layer = self.map.getLayerByIndex(f.layerindex)
                        layer.updateCellElement(ref, e)

                    row = Row(self.maintable)
                    row.setColumnUInt(self.maintable.getColumnIndex("NAME_REF"), textslot)

                    row.setColumnUInt(self.maintable.getColumnIndex("OBJ_TYPE"), f.getObjtypeIndex(self))

                    cellelementrefs = f.getCellElementRefs()
                    if len(cellelementrefs) == 1:
                        row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUM"), cellelementrefs[0][0])
                        row.setColumnUInt(self.maintable.getColumnIndex("N_IN_C"), cellelementrefs[0][1]+1)
                    else:
                        row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUM"), 0x80000000|(addrow+1) )
                        row.setColumnUInt(self.maintable.getColumnIndex("N_IN_C"), len(cellelementrefs))
                        for cref in cellelementrefs:
                            rowrc = Row(self.addtable)
                            rowrc.setColumnUInt(self.addtable.getColumnIndex("CELL_NUM"), cref[0])
                            rowrc.setColumnUInt(self.addtable.getColumnIndex("N_IN_C"), cref[1]+1)
                            self.addtable.writeRow(rowrc)
                            addrow+=1
                    self.maintable.writeRow(row)

            self.isopen = False            

    def getLayerAndObjtypeFromObjtypeIndex(self, objtypeindex):
        idx=0
        for l in self._layers:
            newidx = idx + len(l['objtypes'])
            if objtypeindex < newidx:
                return self.map.getLayerByIndex(l['number']), l['objtypes'][objtypeindex-idx]
            idx = newidx
            
        raise ValueError('Couldnt find objtypeindex %d '%objtypeindex + str(self._layers))

    def __str__(self):
        groupnumber = self.map.getGroupIndex(self)
        s=self.name+" (%d):\n"%groupnumber
        for l in self._layers:
            s=s+"layer#: "+str(l['number'])+"\n"
            s=s+"objtypes: "+str(l['objtypes'])+"\n"
        s+="Columns in main table: "+str(self.maintable.getColumnNames())+"\n"
        return s

    def getFeatureCount(self):
        if self.mode=='r':
            return self.maintable.getRowCount()
        else:
            return len(self._features)

    def getFeatureByIndex(self, index):
        if self.mode == 'r':
            return self._getFeatureByIndex(index)
        else:
            return self._features[index][1]
    
    def _getFeatureByIndex(self, index):
        if index >= self.maintable.getRowCount():
            raise IndexError("index out of bounds")

        rec = self.maintable.getCursor(index).asDict()

        namekey = rec['NAME_REF']

        objtype_index = rec['OBJ_TYPE']
        layer, objtype = self.getLayerAndObjtypeFromObjtypeIndex(objtype_index)
        
        nameindex = namekey & 0xffffff
        nameoffset = namekey >> 24
        name = self.auxmanager.lookupText(nameindex, nameoffset)
        
        cellelementrefs = []
        if rec['CELL_NUM'] & 0x80000000:
            for j in range(0,rec['N_IN_C']):
                 rcrow = (rec['CELL_NUM']&0xffffff)+j-1
                 rec2 = self.addtable.getCursor(rcrow).asDict()
                 cellelementrefs.append((rec2['CELL_NUM'],rec2['N_IN_C']-1))
        else:
            cellelementrefs.append((rec['CELL_NUM'], rec['N_IN_C']-1))

        return FeatureNormal(self.map.getLayerIndex(layer), cellelementrefs,
                             name, objtype)

    def addFeature(self, feature):
        """Add feature to group. Return the index of the new feature"""
        if self.mode=='r':
            raise ValueError("Group is open as read-only")

        # Get object type index and if it's not already present in the group
        # the objtype is added
        objtypeindex = feature.getObjtypeIndex(self)
        
        # Update objtypeindex
        for e in feature.getCellElements(self.map):
            e.objtype = objtypeindex

        self._insert(feature)

    def _insert(self, feature):
        ## Insert feature and keep the list sorted on name
        name = feature.name
        
        if name:
            item = (chr(sortHashFuncFast(name)) + name, feature)
            index = bisect.bisect_right(self._features, item)
            self._features.insert(index, item)
            return index

    def getObjtypeIndex(self, layernumber, objtype):
        idx=0
        objnumber_index = None
        for li in self._layers:
            if li['number'] == layernumber:
                if objtype in li['objtypes']:
                    return idx+li['objtypes'].index(objtype)
                else:
                    if self.mode == 'r':
                        raise ValueError("Objtype does not exists")
                    # Objtype is not used in this layer before, add it
                    li['objtypes'].append(objtype)
                    return idx+len(li['objtypes'])-1
            idx += len(li['objtypes'])
示例#11
0
class POIGroup(Group):
    textslot_column = 'TEXT_SLOT'
    def __init__(self, map):
        Group.__init__(self, map)
        
        self.catman = POICategoryManager()

        self.sortcategories = False

        self.poiprefix = map.mapnumstr + "poi"

        self.exportfields += ['aux', 'categoryid', 'subcategoryid']
        self.exportfieldtypes += ['string', 'int', 'int']

    def initFromIni(self, inicfg, poicfg):
        pass

    def _initDB(self, db):
        maintablename = "POIPOINT_"

        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():
            createPOITables(db, self.poiprefix)

        # Open category manager
        self.catman.open(db, self.mode, poiprefix=self.poiprefix)

        self.auxtable = db.getTableByName("AUXTEXT_")
        self.maintable = db.getTableByName(maintablename)

        self.auxmanager = AuxTableManager(self.auxtable, endchar=chr(7), searchindex=False)

    def open(self, mode='r'):
        self.mode = mode

        self._initDB(self.map.getDB())
        
        for lay in self.map.getPOILayers():
            lay.open(self.mode)

        if self.mode == 'a':
            for i in range(0, self.maintable.getRowCount()):
                self.features.append(self._getFeatureByIndex(i))

    def _getFeatureByIndex(self, index):
        if index >= self.maintable.getRowCount():
            raise IndexError("index out of bounds")

        rec = self.maintable.getCursor(index).asDict()

        offset = rec['TEXT_SLOT']>>24
        index = rec['TEXT_SLOT']&0xffffff

        aux=self.auxmanager.lookupText(index, offset).split('\t')

        # List is terminated by a \t char so the aux will be one element too long
        aux = aux[:-1]

        categoryid = rec['CATG_ID']
        subcategoryid = rec['SUBCAT_ID']
        
        return FeaturePOI([(rec['CELL_NUMBER'], rec['NUMBER_IN_CELL']-1)], aux, categoryid, subcategoryid)

    def getFeatureCount(self):
        if self.mode=='r':
            return self.maintable.getRowCount()
        else:
            return len(self.features)

    def getCategoryManager(self):
        return self.catman

    def addCategory(self, category, icon='DEFAULT'):
        return self.catman.addCategory(category, icon=icon)

    def getCategory(self, categoryid):
        return self.catman.getCategory(categoryid)

    def getCategories(self):
        return self.catman.getCategories()

    def close(self):
        if self.mode in ['w','a']:
            self.maintable.clear()
            self.auxtable.clear()

            aux = AuxTableManager(self.auxtable, endchar=chr(7), searchindex=False)

            # sort categories, note that this will create new category ids
            # and the features have to be updated
            if self.sortcategories:
                cattrans, subcattrans = self.catman.sortCategories()

                # translate categories
                for f in self.features:
                    oldcatid = f.getCategoryId()
                    oldsubcatid = f.getSubCategoryId()

                    f.setCategoryId(cattrans[oldcatid])
                    f.setSubCategoryId(subcattrans[(oldcatid, oldsubcatid)])

            # Sort features on ids
            self.features.sort(lambda x,y: cmp((x.getCategoryId(), x.getSubCategoryId(), x.name.upper()), (y.getCategoryId(), y.getSubCategoryId(), y.name.upper())))


            # Clear category statistics
            for cat in self.catman.getCategories():
                cat.clearStatistics()
                for subcat in cat.getSubCategories():
                    subcat.clearStatistics()

            # Write features to database
            slot = 1
            for f in self.features:
                # Update category statistics
                cat=self.catman.getCategory(f.getCategoryId())
                subcat=cat.getSubCategory(f.getSubCategoryId())
                cat.updateFromPOI(slot,f.getAux()[0])
                subcat.updateFromPOI(slot,f.getAux()[0])
                
                textslot = aux.appendText('\t'.join(f.getAux())+'\t')

                # Update cell elements
                for ref, e in zip(f.cellelementrefs, f.getCellElements(self.map)):
                    e.textslot = textslot
                    e.setCategoryId(f.getCategoryId())
                    e.setSubCategoryId(f.getSubCategoryId())
                    layer = self.map.getPOILayers()[0]
                    layer.updateCellElement(ref, e)
                
                row = Row(self.maintable)
                row.setColumnUInt(self.maintable.getColumnIndex("TEXT_SLOT"), textslot)

                row.setColumnUInt(self.maintable.getColumnIndex("CATG_ID"), f.getCategoryId())
                row.setColumnUInt(self.maintable.getColumnIndex("SUBCAT_ID"), f.getSubCategoryId())
                
                cellelementrefs = f.getCellElementRefs()
                row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUMBER"), cellelementrefs[0][0])
                row.setColumnUInt(self.maintable.getColumnIndex("NUMBER_IN_CELL"), cellelementrefs[0][1]+1)
                self.maintable.writeRow(row)

                slot+=1

        self.catman.close()

    def optimizeLayers(self):
        """Call the optimize function of each member layer and update cell element reference in all features"""

        cellrefremap = {}
        for layer in self.layers:
            remapdict = layer.optimize()

            for feature in self.xfeatures:
                if len(remapdict) > 0:
                    feature.cellelementrefs = tuple([remapdict[ceref] for ceref in feature.cellelementrefs])

    @property
    def layers(self):
        return self.map.getPOILayers()
示例#12
0
    def close(self):
        if self.mode in ['w','a']:
            self.maintable.clear()
            self.auxtable.clear()

            aux = AuxTableManager(self.auxtable, endchar=chr(7), searchindex=False)

            # sort categories, note that this will create new category ids
            # and the features have to be updated
            if self.sortcategories:
                cattrans, subcattrans = self.catman.sortCategories()

                # translate categories
                for f in self.features:
                    oldcatid = f.getCategoryId()
                    oldsubcatid = f.getSubCategoryId()

                    f.setCategoryId(cattrans[oldcatid])
                    f.setSubCategoryId(subcattrans[(oldcatid, oldsubcatid)])

            # Sort features on ids
            self.features.sort(lambda x,y: cmp((x.getCategoryId(), x.getSubCategoryId(), x.name.upper()), (y.getCategoryId(), y.getSubCategoryId(), y.name.upper())))


            # Clear category statistics
            for cat in self.catman.getCategories():
                cat.clearStatistics()
                for subcat in cat.getSubCategories():
                    subcat.clearStatistics()

            # Write features to database
            slot = 1
            for f in self.features:
                # Update category statistics
                cat=self.catman.getCategory(f.getCategoryId())
                subcat=cat.getSubCategory(f.getSubCategoryId())
                cat.updateFromPOI(slot,f.getAux()[0])
                subcat.updateFromPOI(slot,f.getAux()[0])
                
                textslot = aux.appendText('\t'.join(f.getAux())+'\t')

                # Update cell elements
                for ref, e in zip(f.cellelementrefs, f.getCellElements(self.map)):
                    e.textslot = textslot
                    e.setCategoryId(f.getCategoryId())
                    e.setSubCategoryId(f.getSubCategoryId())
                    layer = self.map.getPOILayers()[0]
                    layer.updateCellElement(ref, e)
                
                row = Row(self.maintable)
                row.setColumnUInt(self.maintable.getColumnIndex("TEXT_SLOT"), textslot)

                row.setColumnUInt(self.maintable.getColumnIndex("CATG_ID"), f.getCategoryId())
                row.setColumnUInt(self.maintable.getColumnIndex("SUBCAT_ID"), f.getSubCategoryId())
                
                cellelementrefs = f.getCellElementRefs()
                row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUMBER"), cellelementrefs[0][0])
                row.setColumnUInt(self.maintable.getColumnIndex("NUMBER_IN_CELL"), cellelementrefs[0][1]+1)
                self.maintable.writeRow(row)

                slot+=1

        self.catman.close()
示例#13
0
    def close(self):
        if self.mode in ['w', 'a']:
            self.maintable.clear()
            self.auxtable.clear()

            aux = AuxTableManager(self.auxtable,
                                  endchar=chr(7),
                                  searchindex=False)

            # sort categories, note that this will create new category ids
            # and the features have to be updated
            if self.sortcategories:
                cattrans, subcattrans = self.catman.sortCategories()

                # translate categories
                for f in self.features:
                    oldcatid = f.getCategoryId()
                    oldsubcatid = f.getSubCategoryId()

                    f.setCategoryId(cattrans[oldcatid])
                    f.setSubCategoryId(subcattrans[(oldcatid, oldsubcatid)])

            # Sort features on ids
            self.features.sort(lambda x, y: cmp(
                (x.getCategoryId(), x.getSubCategoryId(), x.name.upper()),
                (y.getCategoryId(), y.getSubCategoryId(), y.name.upper())))

            # Clear category statistics
            for cat in self.catman.getCategories():
                cat.clearStatistics()
                for subcat in cat.getSubCategories():
                    subcat.clearStatistics()

            # Write features to database
            slot = 1
            for f in self.features:
                # Update category statistics
                cat = self.catman.getCategory(f.getCategoryId())
                subcat = cat.getSubCategory(f.getSubCategoryId())
                cat.updateFromPOI(slot, f.getAux()[0])
                subcat.updateFromPOI(slot, f.getAux()[0])

                textslot = aux.appendText('\t'.join(f.getAux()) + '\t')

                # Update cell elements
                for ref, e in zip(f.cellelementrefs,
                                  f.getCellElements(self.map)):
                    e.textslot = textslot
                    e.setCategoryId(f.getCategoryId())
                    e.setSubCategoryId(f.getSubCategoryId())
                    layer = self.map.getPOILayers()[0]
                    layer.updateCellElement(ref, e)

                row = Row(self.maintable)
                row.setColumnUInt(self.maintable.getColumnIndex("TEXT_SLOT"),
                                  textslot)

                row.setColumnUInt(self.maintable.getColumnIndex("CATG_ID"),
                                  f.getCategoryId())
                row.setColumnUInt(self.maintable.getColumnIndex("SUBCAT_ID"),
                                  f.getSubCategoryId())

                cellelementrefs = f.getCellElementRefs()
                row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUMBER"),
                                  cellelementrefs[0][0])
                row.setColumnUInt(
                    self.maintable.getColumnIndex("NUMBER_IN_CELL"),
                    cellelementrefs[0][1] + 1)
                self.maintable.writeRow(row)

                slot += 1

        self.catman.close()
示例#14
0
class POIGroup(Group):
    textslot_column = 'TEXT_SLOT'

    def __init__(self, map):
        Group.__init__(self, map)

        self.catman = POICategoryManager()

        self.sortcategories = False

        self.poiprefix = map.mapnumstr + "poi"

        self.exportfields += ['aux', 'categoryid', 'subcategoryid']
        self.exportfieldtypes += ['string', 'int', 'int']

    def initFromIni(self, inicfg, poicfg):
        pass

    def _initDB(self, db):
        maintablename = "POIPOINT_"

        # Create tables if opened in append mode
        if self.mode == "w" and not maintablename in db.getTableNames():
            createPOITables(db, self.poiprefix)

        # Open category manager
        self.catman.open(db, self.mode, poiprefix=self.poiprefix)

        self.auxtable = db.getTableByName("AUXTEXT_")
        self.maintable = db.getTableByName(maintablename)

        self.auxmanager = AuxTableManager(self.auxtable,
                                          endchar=chr(7),
                                          searchindex=False)

    def open(self, mode='r'):
        self.mode = mode

        self._initDB(self.map.getDB())

        for lay in self.map.getPOILayers():
            lay.open(self.mode)

        if self.mode == 'a':
            for i in range(0, self.maintable.getRowCount()):
                self.features.append(self._getFeatureByIndex(i))

    def _getFeatureByIndex(self, index):
        if index >= self.maintable.getRowCount():
            raise IndexError("index out of bounds")

        rec = self.maintable.getCursor(index).asDict()

        offset = rec['TEXT_SLOT'] >> 24
        index = rec['TEXT_SLOT'] & 0xffffff

        aux = self.auxmanager.lookupText(index, offset).split('\t')

        # List is terminated by a \t char so the aux will be one element too long
        aux = aux[:-1]

        categoryid = rec['CATG_ID']
        subcategoryid = rec['SUBCAT_ID']

        return FeaturePOI([(rec['CELL_NUMBER'], rec['NUMBER_IN_CELL'] - 1)],
                          aux, categoryid, subcategoryid)

    def getFeatureCount(self):
        if self.mode == 'r':
            return self.maintable.getRowCount()
        else:
            return len(self.features)

    def getCategoryManager(self):
        return self.catman

    def addCategory(self, category, icon='DEFAULT'):
        return self.catman.addCategory(category, icon=icon)

    def getCategory(self, categoryid):
        return self.catman.getCategory(categoryid)

    def getCategories(self):
        return self.catman.getCategories()

    def close(self):
        if self.mode in ['w', 'a']:
            self.maintable.clear()
            self.auxtable.clear()

            aux = AuxTableManager(self.auxtable,
                                  endchar=chr(7),
                                  searchindex=False)

            # sort categories, note that this will create new category ids
            # and the features have to be updated
            if self.sortcategories:
                cattrans, subcattrans = self.catman.sortCategories()

                # translate categories
                for f in self.features:
                    oldcatid = f.getCategoryId()
                    oldsubcatid = f.getSubCategoryId()

                    f.setCategoryId(cattrans[oldcatid])
                    f.setSubCategoryId(subcattrans[(oldcatid, oldsubcatid)])

            # Sort features on ids
            self.features.sort(lambda x, y: cmp(
                (x.getCategoryId(), x.getSubCategoryId(), x.name.upper()),
                (y.getCategoryId(), y.getSubCategoryId(), y.name.upper())))

            # Clear category statistics
            for cat in self.catman.getCategories():
                cat.clearStatistics()
                for subcat in cat.getSubCategories():
                    subcat.clearStatistics()

            # Write features to database
            slot = 1
            for f in self.features:
                # Update category statistics
                cat = self.catman.getCategory(f.getCategoryId())
                subcat = cat.getSubCategory(f.getSubCategoryId())
                cat.updateFromPOI(slot, f.getAux()[0])
                subcat.updateFromPOI(slot, f.getAux()[0])

                textslot = aux.appendText('\t'.join(f.getAux()) + '\t')

                # Update cell elements
                for ref, e in zip(f.cellelementrefs,
                                  f.getCellElements(self.map)):
                    e.textslot = textslot
                    e.setCategoryId(f.getCategoryId())
                    e.setSubCategoryId(f.getSubCategoryId())
                    layer = self.map.getPOILayers()[0]
                    layer.updateCellElement(ref, e)

                row = Row(self.maintable)
                row.setColumnUInt(self.maintable.getColumnIndex("TEXT_SLOT"),
                                  textslot)

                row.setColumnUInt(self.maintable.getColumnIndex("CATG_ID"),
                                  f.getCategoryId())
                row.setColumnUInt(self.maintable.getColumnIndex("SUBCAT_ID"),
                                  f.getSubCategoryId())

                cellelementrefs = f.getCellElementRefs()
                row.setColumnUInt(self.maintable.getColumnIndex("CELL_NUMBER"),
                                  cellelementrefs[0][0])
                row.setColumnUInt(
                    self.maintable.getColumnIndex("NUMBER_IN_CELL"),
                    cellelementrefs[0][1] + 1)
                self.maintable.writeRow(row)

                slot += 1

        self.catman.close()

    def optimizeLayers(self):
        """Call the optimize function of each member layer and update cell element reference in all features"""

        cellrefremap = {}
        for layer in self.layers:
            remapdict = layer.optimize()

            for feature in self.xfeatures:
                if len(remapdict) > 0:
                    feature.cellelementrefs = tuple([
                        remapdict[ceref] for ceref in feature.cellelementrefs
                    ])

    @property
    def layers(self):
        return self.map.getPOILayers()