Beispiel #1
0
    def __init__(self, *args):
        """
        The initialization function may take an OGREnvelope structure, 4-element
        tuple or list, or 4 individual arguments.
        """

        if len(args) == 1:
            if isinstance(args[0], OGREnvelope):
                # OGREnvelope (a ctypes Structure) was passed in.
                self._envelope = args[0]
            elif isinstance(args[0], (tuple, list)):
                # A tuple was passed in.
                if len(args[0]) != 4:
                    raise GDALException(
                        'Incorrect number of tuple elements (%d).' %
                        len(args[0]))
                else:
                    self._from_sequence(args[0])
            else:
                raise TypeError('Incorrect type of argument: %s' %
                                type(args[0]))
        elif len(args) == 4:
            # Individual parameters passed in.
            #  Thanks to ww for the help
            self._from_sequence([float(a) for a in args])
        else:
            raise GDALException('Incorrect number (%d) of arguments.' %
                                len(args))

        # Checking the x,y coordinates
        if self.min_x > self.max_x:
            raise GDALException('Envelope minimum X > maximum X.')
        if self.min_y > self.max_y:
            raise GDALException('Envelope minimum Y > maximum Y.')
Beispiel #2
0
 def expand_to_include(self, *args):
     """
     Modify the envelope to expand to include the boundaries of
     the passed-in 2-tuple (a point), 4-tuple (an extent) or
     envelope.
     """
     # We provide a number of different signatures for this method,
     # and the logic here is all about converting them into a
     # 4-tuple single parameter which does the actual work of
     # expanding the envelope.
     if len(args) == 1:
         if isinstance(args[0], Envelope):
             return self.expand_to_include(args[0].tuple)
         elif hasattr(args[0], 'x') and hasattr(args[0], 'y'):
             return self.expand_to_include(args[0].x, args[0].y, args[0].x,
                                           args[0].y)
         elif isinstance(args[0], (tuple, list)):
             # A tuple was passed in.
             if len(args[0]) == 2:
                 return self.expand_to_include(
                     (args[0][0], args[0][1], args[0][0], args[0][1]))
             elif len(args[0]) == 4:
                 (minx, miny, maxx, maxy) = args[0]
                 if minx < self._envelope.MinX:
                     self._envelope.MinX = minx
                 if miny < self._envelope.MinY:
                     self._envelope.MinY = miny
                 if maxx > self._envelope.MaxX:
                     self._envelope.MaxX = maxx
                 if maxy > self._envelope.MaxY:
                     self._envelope.MaxY = maxy
             else:
                 raise GDALException(
                     'Incorrect number of tuple elements (%d).' %
                     len(args[0]))
         else:
             raise TypeError('Incorrect type of argument: %s' %
                             type(args[0]))
     elif len(args) == 2:
         # An x and an y parameter were passed in
         return self.expand_to_include((args[0], args[1], args[0], args[1]))
     elif len(args) == 4:
         # Individual parameters passed in.
         return self.expand_to_include(args)
     else:
         raise GDALException('Incorrect number (%d) of arguments.' %
                             len(args[0]))
Beispiel #3
0
 def get_fields(self, field_name):
     """
     Return a list containing the given field name for every Feature
     in the Layer.
     """
     if field_name not in self.fields:
         raise GDALException('invalid field name: %s' % field_name)
     return [feat.get(field_name) for feat in self]
Beispiel #4
0
 def __setstate__(self, state):
     wkb, srs = state
     ptr = capi.from_wkb(wkb, None, byref(c_void_p()), len(wkb))
     if not ptr:
         raise GDALException(
             'Invalid OGRGeometry loaded from pickled state.')
     self.ptr = ptr
     self.srs = srs
Beispiel #5
0
 def __init__(self, feat, layer):
     """
     Initialize Feature from a pointer and its Layer object.
     """
     if not feat:
         raise GDALException(
             'Cannot create OGR Feature, invalid pointer given.')
     self.ptr = feat
     self._layer = layer
Beispiel #6
0
def check_pointer(result, func, cargs):
    "Make sure the result pointer is valid."
    if isinstance(result, int):
        result = c_void_p(result)
    if result:
        return result
    else:
        raise GDALException('Invalid pointer returned from "%s"' %
                            func.__name__)
Beispiel #7
0
def check_geom(result, func, cargs):
    "Check a function that returns a geometry."
    # OGR_G_Clone may return an integer, even though the
    # restype is set to c_void_p
    if isinstance(result, int):
        result = c_void_p(result)
    if not result:
        raise GDALException('Invalid geometry pointer returned from "%s".' %
                            func.__name__)
    return result
Beispiel #8
0
    def __init__(self, type_input):
        "Figure out the correct OGR Type based upon the input."
        if isinstance(type_input, OGRGeomType):
            num = type_input.num
        elif isinstance(type_input, str):
            type_input = type_input.lower()
            if type_input == 'geometry':
                type_input = 'unknown'
            num = self._str_types.get(type_input)
            if num is None:
                raise GDALException('Invalid OGR String Type "%s"' % type_input)
        elif isinstance(type_input, int):
            if type_input not in self._types:
                raise GDALException('Invalid OGR Integer Type: %d' % type_input)
            num = type_input
        else:
            raise TypeError('Invalid OGR input type given.')

        # Setting the OGR geometry type number.
        self.num = num
Beispiel #9
0
 def _flush(self):
     """
     Flush all data from memory into the source file if it exists.
     The data that needs flushing are geotransforms, coordinate systems,
     nodata_values and pixel values. This function will be called
     automatically wherever it is needed.
     """
     # Raise an Exception if the value is being changed in read mode.
     if not self._write:
         raise GDALException('Raster needs to be opened in write mode to change values.')
     capi.flush_ds(self._ptr)
Beispiel #10
0
 def as_datetime(self):
     "Retrieve the Field's value as a tuple of date & time components."
     yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
     status = capi.get_field_as_datetime(self._feat.ptr, self._index,
                                         byref(yy), byref(mm), byref(dd),
                                         byref(hh), byref(mn), byref(ss),
                                         byref(tz))
     if status:
         return (yy, mm, dd, hh, mn, ss, tz)
     else:
         raise GDALException(
             'Unable to retrieve date & time information from the field.')
Beispiel #11
0
    def __init__(self,
                 ds_input,
                 ds_driver=False,
                 write=False,
                 encoding='utf-8'):
        # The write flag.
        if write:
            self._write = 1
        else:
            self._write = 0
        # See also http://trac.osgeo.org/gdal/wiki/rfc23_ogr_unicode
        self.encoding = encoding

        Driver.ensure_registered()

        if isinstance(ds_input, str):
            # The data source driver is a void pointer.
            ds_driver = Driver.ptr_type()
            try:
                # OGROpen will auto-detect the data source type.
                ds = capi.open_ds(force_bytes(ds_input), self._write,
                                  byref(ds_driver))
            except GDALException:
                # Making the error message more clear rather than something
                # like "Invalid pointer returned from OGROpen".
                raise GDALException('Could not open the datasource at "%s"' %
                                    ds_input)
        elif isinstance(ds_input, self.ptr_type) and isinstance(
                ds_driver, Driver.ptr_type):
            ds = ds_input
        else:
            raise GDALException('Invalid data source input type: %s' %
                                type(ds_input))

        if ds:
            self.ptr = ds
            self.driver = Driver(ds_driver)
        else:
            # Raise an exception if the returned pointer is NULL
            raise GDALException('Invalid data source file "%s"' % ds_input)
Beispiel #12
0
 def add(self, geom):
     "Add the geometry to this Geometry Collection."
     if isinstance(geom, OGRGeometry):
         if isinstance(geom, self.__class__):
             for g in geom:
                 capi.add_geom(self.ptr, g.ptr)
         else:
             capi.add_geom(self.ptr, geom.ptr)
     elif isinstance(geom, str):
         tmp = OGRGeometry(geom)
         capi.add_geom(self.ptr, tmp.ptr)
     else:
         raise GDALException('Must add an OGRGeometry.')
Beispiel #13
0
    def __init__(self, dr_input):
        """
        Initialize an GDAL/OGR driver on either a string or integer input.
        """
        if isinstance(dr_input, str):
            # If a string name of the driver was passed in
            self.ensure_registered()

            # Checking the alias dictionary (case-insensitive) to see if an
            # alias exists for the given driver.
            if dr_input.lower() in self._alias:
                name = self._alias[dr_input.lower()]
            else:
                name = dr_input

            # Attempting to get the GDAL/OGR driver by the string name.
            for iface in (vcapi, rcapi):
                driver = c_void_p(iface.get_driver_by_name(force_bytes(name)))
                if driver:
                    break
        elif isinstance(dr_input, int):
            self.ensure_registered()
            for iface in (vcapi, rcapi):
                driver = iface.get_driver(dr_input)
                if driver:
                    break
        elif isinstance(dr_input, c_void_p):
            driver = dr_input
        else:
            raise GDALException(
                'Unrecognized input type for GDAL/OGR Driver: %s' %
                type(dr_input))

        # Making sure we get a valid pointer to the OGR Driver
        if not driver:
            raise GDALException(
                'Could not initialize GDAL/OGR Driver on input: %s' % dr_input)
        self.ptr = driver
Beispiel #14
0
 def __init__(self, layer_ptr, ds):
     """
     Initialize on an OGR C pointer to the Layer and the `DataSource` object
     that owns this layer.  The `DataSource` object is required so that a
     reference to it is kept with this Layer.  This prevents garbage
     collection of the `DataSource` while this Layer is still active.
     """
     if not layer_ptr:
         raise GDALException('Cannot create Layer, invalid pointer given')
     self.ptr = layer_ptr
     self._ds = ds
     self._ldefn = capi.get_layer_defn(self._ptr)
     # Does the Layer support random reading?
     self._random_read = self.test_capability(b'RandomRead')
Beispiel #15
0
 def __eq__(self, other):
     """
     Return True if the envelopes are equivalent; can compare against
     other Envelopes and 4-tuples.
     """
     if isinstance(other, Envelope):
         return (self.min_x == other.min_x) and (self.min_y == other.min_y) and \
                (self.max_x == other.max_x) and (self.max_y == other.max_y)
     elif isinstance(other, tuple) and len(other) == 4:
         return (self.min_x == other[0]) and (self.min_y == other[1]) and \
                (self.max_x == other[2]) and (self.max_y == other[3])
     else:
         raise GDALException(
             'Equivalence testing only works with other Envelopes.')
Beispiel #16
0
    def __init__(self, feat, index):
        """
        Initialize on the feature object and the integer index of
        the field within the feature.
        """
        # Setting the feature pointer and index.
        self._feat = feat
        self._index = index

        # Getting the pointer for this field.
        fld_ptr = capi.get_feat_field_defn(feat.ptr, index)
        if not fld_ptr:
            raise GDALException(
                'Cannot create OGR Field, invalid pointer given.')
        self.ptr = fld_ptr

        # Setting the class depending upon the OGR Field Type (OFT)
        self.__class__ = OGRFieldTypes[self.type]

        # OFTReal with no precision should be an OFTInteger.
        if isinstance(self, OFTReal) and self.precision == 0:
            self.__class__ = OFTInteger
            self._double = True
Beispiel #17
0
def gdal_version_info():
    ver = gdal_version().decode()
    m = version_regex.match(ver)
    if not m:
        raise GDALException('Could not parse GDAL version string "%s"' % ver)
    return {key: m.group(key) for key in ('major', 'minor', 'subminor')}
Beispiel #18
0
 def __getitem__(self, index):
     try:
         return GDALBand(self.source, index + 1)
     except GDALException:
         raise GDALException('Unable to get band index %d' % index)
Beispiel #19
0
    def __init__(self, ds_input, write=False):
        self._write = 1 if write else 0
        Driver.ensure_registered()

        # Preprocess json inputs. This converts json strings to dictionaries,
        # which are parsed below the same way as direct dictionary inputs.
        if isinstance(ds_input, str) and json_regex.match(ds_input):
            ds_input = json.loads(ds_input)

        # If input is a valid file path, try setting file as source.
        if isinstance(ds_input, str):
            try:
                # GDALOpen will auto-detect the data source type.
                self._ptr = capi.open_ds(force_bytes(ds_input), self._write)
            except GDALException as err:
                raise GDALException('Could not open the datasource at "{}" ({}).'.format(ds_input, err))
        elif isinstance(ds_input, bytes):
            # Create a new raster in write mode.
            self._write = 1
            # Get size of buffer.
            size = sys.getsizeof(ds_input)
            # Pass data to ctypes, keeping a reference to the ctypes object so
            # that the vsimem file remains available until the GDALRaster is
            # deleted.
            self._ds_input = c_buffer(ds_input)
            # Create random name to reference in vsimem filesystem.
            vsi_path = os.path.join(VSI_FILESYSTEM_BASE_PATH, str(uuid.uuid4()))
            # Create vsimem file from buffer.
            capi.create_vsi_file_from_mem_buffer(
                force_bytes(vsi_path),
                byref(self._ds_input),
                size,
                VSI_TAKE_BUFFER_OWNERSHIP,
            )
            # Open the new vsimem file as a GDALRaster.
            try:
                self._ptr = capi.open_ds(force_bytes(vsi_path), self._write)
            except GDALException:
                # Remove the broken file from the VSI filesystem.
                capi.unlink_vsi_file(force_bytes(vsi_path))
                raise GDALException('Failed creating VSI raster from the input buffer.')
        elif isinstance(ds_input, dict):
            # A new raster needs to be created in write mode
            self._write = 1

            # Create driver (in memory by default)
            driver = Driver(ds_input.get('driver', 'MEM'))

            # For out of memory drivers, check filename argument
            if driver.name != 'MEM' and 'name' not in ds_input:
                raise GDALException('Specify name for creation of raster with driver "{}".'.format(driver.name))

            # Check if width and height where specified
            if 'width' not in ds_input or 'height' not in ds_input:
                raise GDALException('Specify width and height attributes for JSON or dict input.')

            # Check if srid was specified
            if 'srid' not in ds_input:
                raise GDALException('Specify srid for JSON or dict input.')

            # Create null terminated gdal options array.
            papsz_options = []
            for key, val in ds_input.get('papsz_options', {}).items():
                option = '{}={}'.format(key, val)
                papsz_options.append(option.upper().encode())
            papsz_options.append(None)

            # Convert papszlist to ctypes array.
            papsz_options = (c_char_p * len(papsz_options))(*papsz_options)

            # Create GDAL Raster
            self._ptr = capi.create_ds(
                driver._ptr,
                force_bytes(ds_input.get('name', '')),
                ds_input['width'],
                ds_input['height'],
                ds_input.get('nr_of_bands', len(ds_input.get('bands', []))),
                ds_input.get('datatype', 6),
                byref(papsz_options),
            )

            # Set band data if provided
            for i, band_input in enumerate(ds_input.get('bands', [])):
                band = self.bands[i]
                if 'nodata_value' in band_input:
                    band.nodata_value = band_input['nodata_value']
                    # Instantiate band filled with nodata values if only
                    # partial input data has been provided.
                    if band.nodata_value is not None and (
                            'data' not in band_input or
                            'size' in band_input or
                            'shape' in band_input):
                        band.data(data=(band.nodata_value,), shape=(1, 1))
                # Set band data values from input.
                band.data(
                    data=band_input.get('data'),
                    size=band_input.get('size'),
                    shape=band_input.get('shape'),
                    offset=band_input.get('offset'),
                )

            # Set SRID
            self.srs = ds_input.get('srid')

            # Set additional properties if provided
            if 'origin' in ds_input:
                self.origin.x, self.origin.y = ds_input['origin']

            if 'scale' in ds_input:
                self.scale.x, self.scale.y = ds_input['scale']

            if 'skew' in ds_input:
                self.skew.x, self.skew.y = ds_input['skew']
        elif isinstance(ds_input, c_void_p):
            # Instantiate the object using an existing pointer to a gdal raster.
            self._ptr = ds_input
        else:
            raise GDALException('Invalid data source input type: "{}".'.format(type(ds_input)))
Beispiel #20
0
    def __init__(self, geom_input, srs=None):
        """Initialize Geometry on either WKT or an OGR pointer as input."""
        str_instance = isinstance(geom_input, str)

        # If HEX, unpack input to a binary buffer.
        if str_instance and hex_regex.match(geom_input):
            geom_input = memoryview(bytes.fromhex(geom_input))
            str_instance = False

        # Constructing the geometry,
        if str_instance:
            wkt_m = wkt_regex.match(geom_input)
            json_m = json_regex.match(geom_input)
            if wkt_m:
                if wkt_m.group('srid'):
                    # If there's EWKT, set the SRS w/value of the SRID.
                    srs = int(wkt_m.group('srid'))
                if wkt_m.group('type').upper() == 'LINEARRING':
                    # OGR_G_CreateFromWkt doesn't work with LINEARRING WKT.
                    #  See http://trac.osgeo.org/gdal/ticket/1992.
                    g = capi.create_geom(OGRGeomType(wkt_m.group('type')).num)
                    capi.import_wkt(
                        g, byref(c_char_p(wkt_m.group('wkt').encode())))
                else:
                    g = capi.from_wkt(
                        byref(c_char_p(wkt_m.group('wkt').encode())), None,
                        byref(c_void_p()))
            elif json_m:
                g = self._from_json(geom_input.encode())
            else:
                # Seeing if the input is a valid short-hand string
                # (e.g., 'Point', 'POLYGON').
                OGRGeomType(geom_input)
                g = capi.create_geom(OGRGeomType(geom_input).num)
        elif isinstance(geom_input, memoryview):
            # WKB was passed in
            g = self._from_wkb(geom_input)
        elif isinstance(geom_input, OGRGeomType):
            # OGRGeomType was passed in, an empty geometry will be created.
            g = capi.create_geom(geom_input.num)
        elif isinstance(geom_input, self.ptr_type):
            # OGR pointer (c_void_p) was the input.
            g = geom_input
        else:
            raise GDALException(
                'Invalid input type for OGR Geometry construction: %s' %
                type(geom_input))

        # Now checking the Geometry pointer before finishing initialization
        # by setting the pointer for the object.
        if not g:
            raise GDALException('Cannot create OGR Geometry from input: %s' %
                                geom_input)
        self.ptr = g

        # Assigning the SpatialReference object to the geometry, if valid.
        if srs:
            self.srs = srs

        # Setting the class depending upon the OGR Geometry Type
        self.__class__ = GEO_CLASSES[self.geom_type.num]