File: segment.py

package info (click to toggle)
grass 7.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 135,976 kB
  • ctags: 44,148
  • sloc: ansic: 410,300; python: 166,939; cpp: 34,819; sh: 9,358; makefile: 6,618; xml: 3,551; sql: 769; lex: 519; yacc: 450; asm: 387; perl: 282; sed: 17; objc: 7
file content (129 lines) | stat: -rw-r--r-- 4,742 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 11 18:02:27 2012

@author: pietro
"""
import ctypes
import grass.lib.gis as libgis
import grass.lib.raster as libraster
import grass.lib.segment as libseg
from grass.pygrass.raster.raster_type import TYPE as RTYPE


class Segment(object):
    def __init__(self, srows=64, scols=64, maxmem=100):
        self.srows = srows
        self.scols = scols
        self.maxmem = maxmem
        self.c_seg = ctypes.pointer(libseg.SEGMENT())

    def rows(self):
        return libraster.Rast_window_rows()

    def cols(self):
        return libraster.Rast_window_cols()

    def nseg(self):
        rows = self.rows()
        cols = self.cols()
        return ((rows + self.srows - 1) / self.srows) * \
               ((cols + self.scols - 1) / self.scols)

    def segments_in_mem(self):
        if self.maxmem > 0 and self.maxmem < 100:
            seg_in_mem = (self.maxmem * self.nseg()) / 100
        else:
            seg_in_mem = 4 * (self.rows() / self.srows +
                              self.cols() / self.scols + 2)
        if seg_in_mem == 0:
            seg_in_mem = 1
        return seg_in_mem

    def open(self, mapobj):
        """Open a segment it is necessary to pass a RasterSegment object.

        """
        self.val = RTYPE[mapobj.mtype]['grass def']()
        size = ctypes.sizeof(RTYPE[mapobj.mtype]['ctypes'])
        file_name = libgis.G_tempfile()
        #import pdb; pdb.set_trace()
        libseg.Segment_open(self.c_seg, file_name,
                            self.rows(), self.cols(),
                            self.srows, self.scols,
                            size,
                            self.nseg())
        self.flush()

    def format(self, mapobj, file_name='', fill=True):
        """The segmentation routines require a disk file to be used for paging
        segments in and out of memory. This routine formats the file open for
        write on file descriptor fd for use as a segment file.
        """
        if file_name == '':
            file_name = libgis.G_tempfile()
        mapobj.temp_file = file(file_name, 'w')
        size = ctypes.sizeof(RTYPE[mapobj.mtype]['ctypes'])
        if fill:
            libseg.Segment_format(mapobj.temp_file.fileno(), self.rows(),
                                  self.cols(), self.srows, self.scols, size)
        else:
            libseg.Segment_format_nofill(mapobj.temp_file.fileno(),
                                         self.rows(), self.cols(),
                                         self.srows, self.scols, size)
        # TODO: why should I close and then re-open it?
        mapobj.temp_file.close()

    def init(self, mapobj, file_name=''):
        if file_name == '':
            file_name = mapobj.temp_file.name
        mapobj.temp_file = open(file_name, 'w')
        libseg.Segment_init(self.c_seg, mapobj.temp_file.fileno(),
                            self.segments_in_mem)

    def get_row(self, row_index, buf):
        """Return the row using, the `segment` method"""
        libseg.Segment_get_row(self.c_seg, buf.p, row_index)
        return buf

    def put_row(self, row_index, buf):
        """Write the row using the `segment` method"""
        libseg.Segment_put_row(self.c_seg, buf.p, row_index)

    def get(self, row_index, col_index):
        """Return the value of the map
        """
        libseg.Segment_get(self.c_seg,
                           ctypes.byref(self.val), row_index, col_index)
        return self.val.value

    def put(self, row_index, col_index):
        """Write the value to the map
        """
        libseg.Segment_put(self.c_seg,
                           ctypes.byref(self.val), row_index, col_index)

    def get_seg_number(self, row_index, col_index):
        """Return the segment number
        """
        return row_index / self.srows * self.cols / self.scols + \
            col_index / self.scols

    def flush(self):
        """Flush pending updates to disk.
        Forces all pending updates generated by Segment_put() to be written to
        the segment file seg. Must be called after the final Segment_put()
        to force all pending updates to disk. Must also be called before the
        first call to Segment_get_row."""
        libseg.Segment_flush(self.c_seg)

    def close(self):
        """Free memory allocated to segment and delete temp file.  """
        libseg.Segment_close(self.c_seg)

    def release(self):
        """Free memory allocated to segment.
        Releases the allocated memory associated with the segment file seg.
        Note: Does not close the file. Does not flush the data which may be
        pending from previous Segment_put() calls."""
        libseg.Segment_release(self.c_seg)