Beispiel #1
0
 def write_vector_geometry(self, vector_map, geom, cat_num, map_layer):
     """Write geometry in the adequate layer
     """
     cats = Cats(geom.c_cats)
     cats.reset()
     cats.set(cat_num, map_layer)
     # write geometry
     vector_map.write(geom)
def group_by(vinput, voutput, isolate=None, aggregate=None,
             function='sum', vtype='lines',
             where='',  group_by=None, linput=1, loutput=1):
    vname, vmapset = vinput.split('@') if '@' in vinput else (vinput, '')
    with VectorTopo(vname, mapset=vmapset, mode='r') as vin:
        columns = ['cat', ]
        vincols = vin.table.columns
        types = ['PRIMARY KEY', ]
        siso = ''
        if isolate is not None:
            columns += list(isolate)
            types += [vincols[c] for c in isolate]
            siso = ', '.join(isolate)
        sagg = ''
        if aggregate is not None:
            ct = '{func}({col}) as {col}'
            sagg = ', '.join([ct.format(func=function, col=col)
                              for col in aggregate])
            columns += list(aggregate)
            types += [vincols[c] for c in aggregate]

        scols = "%s, %s" % (siso, sagg) if siso and sagg else siso + sagg
        base = "SELECT {cols} FROM {tin}"
        bwhere = " WHERE %s" % where if where else ''
        bgroup = " GROUP BY %s" % ', '.join(group_by) if group_by else ''
        grp = (base + bwhere + bgroup + ';').format(cols=scols,
                                                    tin=vin.table.name,
                                                    tout=voutput)
        bqry = "SELECT {cat} FROM {tin} WHERE {cond};"
        qry = bqry.format(cat=vin.table.key, tin=vin.table.name,
                          cond=' AND '.join(['%s=?' % g for g in group_by]))
        selcols = columns[1:]
        gindexs = [selcols.index(col) for col in group_by]
        insrt = sql.INSERT.format(tname=voutput,
                                  values=','.join(['?', ] * len(columns)))
        with VectorTopo(voutput, mode='w', tab_name=voutput, layer=loutput,
                        tab_cols=list(zip(columns, types)), link_key='cat',
                        overwrite=True) as vout:
            cur = vout.table.conn.cursor()
            ncat = 1
            #import ipdb; ipdb.set_trace()
            # TODO: why do I need to use list(cur) and I can not iterate directly
            for row in list(cur.execute(grp)):
                # add the new line to table
                print(row)
                cur.execute(insrt, tuple([ncat, ] + list(row)))
                for cat in cur.execute(qry, tuple([row[i] for i in gindexs])):
                    for line in vin.cat(cat[0], vtype):
                        # set the new category
                        category = Cats(line.c_cats)
                        category.reset()
                        category.set(ncat, loutput)
                        # write geometry
                        vout.write(line, set_cats=False)
                ncat += 1
            vout.table.conn.commit()
Beispiel #3
0
    def write(self, geo_obj, cat=None, attrs=None):
        """Write geometry features and attributes.

        :param geo_obj: a geometry grass object define in
                        grass.pygrass.vector.geometry
        :type geo_obj: geometry GRASS object
        :param attrs: a list with the values that will be insert in the
                      attribute table.
        :type attrs: list
        :param cat: The category of the geometry feature, otherwise the
                         c_cats attribute of the geometry object will be used.
        :type cat: integer

        Open a new vector map ::

            >>> new = VectorTopo('newvect')
            >>> new.exist()
            False

        define the new columns of the attribute table ::

            >>> cols = [(u'cat',       'INTEGER PRIMARY KEY'),
            ...         (u'name',      'TEXT')]

        open the vector map in write mode

            >>> new.open('w', tab_name='newvect', tab_cols=cols)

        import a geometry feature ::

            >>> from grass.pygrass.vector.geometry import Point

        create two points ::

            >>> point0 = Point(0, 0)
            >>> point1 = Point(1, 1)

        then write the two points on the map, with ::

            >>> new.write(point0, cat=1, attrs=('pub',))
            >>> new.write(point1, cat=2, attrs=('resturant',))

        commit the db changes ::

            >>> new.table.conn.commit()
            >>> new.table.execute().fetchall()
            [(1, u'pub'), (2, u'resturant')]

        close the vector map ::

            >>> new.close()
            >>> new.exist()
            True

        then play with the map ::

            >>> new.open(mode='r')
            >>> new.read(1)
            Point(0.000000, 0.000000)
            >>> new.read(2)
            Point(1.000000, 1.000000)
            >>> new.read(1).attrs['name']
            u'pub'
            >>> new.read(2).attrs['name']
            u'resturant'
            >>> new.close()
            >>> new.remove()

        """
        self.n_lines += 1
        if not isinstance(cat, int) and not isinstance(cat, str):
            # likely the case of using 7.0 API
            import warnings
            warnings.warn("Vector.write(geo_obj, attrs=(...)) is"
                          " depreciated, specify cat explicitly",
                          DeprecationWarning)
            # try to accommodate
            attrs = cat
            cat = None
        if attrs and cat is None:
            # TODO: this does not work as expected when there are
            # already features in the map when we opened it
            cat = (self._cats[-1] if self._cats else 0) + 1

        if cat is not None and cat not in self._cats:
            self._cats.append(cat)
            if self.table is not None and attrs is not None:
                attr = [cat, ]
                attr.extend(attrs)
                cur = self.table.conn.cursor()
                cur.execute(self.table.columns.insert_str, attr)
                cur.close()

        if cat is not None:
            cats = Cats(geo_obj.c_cats)
            cats.reset()
            cats.set(cat, self.layer)

        if geo_obj.gtype == _Area.gtype:
            result = self._write_area(geo_obj)
        result = libvect.Vect_write_line(self.c_mapinfo, geo_obj.gtype,
                                         geo_obj.c_points, geo_obj.c_cats)
        if result == -1:
            raise GrassError("Not able to write the vector feature.")
        if self._topo_level == 2:
            # return new feature id (on level 2)
            geo_obj.id = result
        else:
            # return offset into file where the feature starts (on level 1)
            geo_obj.offset = result
Beispiel #4
0
    def write(self, geo_obj, cat=None, attrs=None):
        """Write geometry features and attributes.

        :param geo_obj: a geometry grass object define in
                        grass.pygrass.vector.geometry
        :type geo_obj: geometry GRASS object
        :param attrs: a list with the values that will be insert in the
                      attribute table.
        :type attrs: list
        :param cat: The category of the geometry feature, otherwise the
                         c_cats attribute of the geometry object will be used.
        :type cat: integer

        Open a new vector map ::

            >>> new = VectorTopo('newvect')
            >>> new.exist()
            False

        define the new columns of the attribute table ::

            >>> cols = [(u'cat',       'INTEGER PRIMARY KEY'),
            ...         (u'name',      'TEXT')]

        open the vector map in write mode

            >>> new.open('w', tab_name='newvect', tab_cols=cols)

        import a geometry feature ::

            >>> from grass.pygrass.vector.geometry import Point

        create two points ::

            >>> point0 = Point(0, 0)
            >>> point1 = Point(1, 1)

        then write the two points on the map, with ::

            >>> new.write(point0, cat=1, attrs=('pub',))
            >>> new.write(point1, cat=2, attrs=('resturant',))

        commit the db changes ::

            >>> new.table.conn.commit()
            >>> new.table.execute().fetchall()
            [(1, u'pub'), (2, u'resturant')]

        close the vector map ::

            >>> new.close()
            >>> new.exist()
            True

        then play with the map ::

            >>> new.open(mode='r')
            >>> new.read(1)
            Point(0.000000, 0.000000)
            >>> new.read(2)
            Point(1.000000, 1.000000)
            >>> new.read(1).attrs['name']
            u'pub'
            >>> new.read(2).attrs['name']
            u'resturant'
            >>> new.close()
            >>> new.remove()

        """
        self.n_lines += 1
        if not isinstance(cat, int) and not isinstance(cat, str):
            # likely the case of using 7.0 API
            import warnings
            warnings.warn("Vector.write(geo_obj, attrs=(...)) is"
                          " depreciated, specify cat explicitly",
                          DeprecationWarning)
            # try to accommodate
            attrs = cat
            cat = None
        if attrs and cat is None:
            # TODO: this does not work as expected when there are
            # already features in the map when we opened it
            cat = (self._cats[-1] if self._cats else 0) + 1

        if cat is not None and cat not in self._cats:
            self._cats.append(cat)
            if self.table is not None and attrs is not None:
                attr = [cat, ]
                attr.extend(attrs)
                cur = self.table.conn.cursor()
                cur.execute(self.table.columns.insert_str, attr)
                cur.close()

        if cat is not None:
            cats = Cats(geo_obj.c_cats)
            cats.reset()
            cats.set(cat, self.layer)

        if geo_obj.gtype == _Area.gtype:
            result = self._write_area(geo_obj)
        result = libvect.Vect_write_line(self.c_mapinfo, geo_obj.gtype,
                                         geo_obj.c_points, geo_obj.c_cats)
        if result == -1:
            raise GrassError("Not able to write the vector feature.")
        if self._topo_level == 2:
            # return new feature id (on level 2)
            geo_obj.id = result
        else:
            # return offset into file where the feature starts (on level 1)
            geo_obj.offset = result
Beispiel #5
0
    def write(self, geo_obj, attrs=None, set_cats=True):
        """Write geometry features and attributes.

        :param geo_obj: a geometry grass object define in
                        grass.pygrass.vector.geometry
        :type geo_obj: geometry GRASS object
        :param attrs: a list with the values that will be insert in the
                      attribute table.
        :type attrs: list
        :param set_cats: if True, the category of the geometry feature is set
                         using the default layer of the vector map and a
                         progressive category value (default), otherwise the
                         c_cats attribute of the geometry object will be used.
        :type set_cats: bool

        Open a new vector map ::

            >>> new = VectorTopo('newvect')
            >>> new.exist()
            False

        define the new columns of the attribute table ::

            >>> cols = [(u'cat',       'INTEGER PRIMARY KEY'),
            ...         (u'name',      'TEXT')]

        open the vector map in write mode

            >>> new.open('w', tab_name='newvect', tab_cols=cols)

        import a geometry feature ::

            >>> from grass.pygrass.vector.geometry import Point

        create two points ::

            >>> point0 = Point(636981.336043, 256517.602235)
            >>> point1 = Point(637209.083058, 257970.129540)

        then write the two points on the map, with ::

            >>> new.write(point0, ('pub', ))
            >>> new.write(point1, ('resturnat', ))

        commit the db changes ::

            >>> new.table.conn.commit()
            >>> new.table.execute().fetchall()
            [(1, u'pub'), (2, u'resturnat')]

        close the vector map ::

            >>> new.close()
            >>> new.exist()
            True

        then play with the map ::

            >>> new.open(mode='r')
            >>> new.read(1)
            Point(636981.336043, 256517.602235)
            >>> new.read(2)
            Point(637209.083058, 257970.129540)
            >>> new.read(1).attrs['name']
            u'pub'
            >>> new.read(2).attrs['name']
            u'resturnat'
            >>> new.close()
            >>> new.remove()

        """
        self.n_lines += 1
        if self.table is not None and attrs:
            attr = [self.n_lines, ]
            attr.extend(attrs)
            cur = self.table.conn.cursor()
            cur.execute(self.table.columns.insert_str, attr)
            cur.close()

        if set_cats:
            cats = Cats(geo_obj.c_cats)
            cats.reset()
            cats.set(self.n_lines, self.layer)

        if geo_obj.gtype == _Area.gtype:
            result = self._write_area(geo_obj)
        result = libvect.Vect_write_line(self.c_mapinfo, geo_obj.gtype,
                                         geo_obj.c_points, geo_obj.c_cats)
        if result == -1:
            raise GrassError("Not able to write the vector feature.")
        if self._topo_level == 2:
            # return new feature id (on level 2)
            geo_obj.id = result
        else:
            # return offset into file where the feature starts (on level 1)
            geo_obj.offset = result