예제 #1
0
파일: ogr2vrt.py 프로젝트: rbuffat/gdal
def GeomType2Name(type):
    flat_type = ogr.GT_Flatten(type)
    dic = {
        ogr.wkbUnknown: ('wkbUnknown', '25D'),
        ogr.wkbPoint: ('wkbPoint', '25D'),
        ogr.wkbLineString: ('wkbLineString', '25D'),
        ogr.wkbPolygon: ('wkbPolygon', '25D'),
        ogr.wkbMultiPoint: ('wkbMultiPoint', '25D'),
        ogr.wkbMultiLineString: ('wkbMultiLineString', '25D'),
        ogr.wkbMultiPolygon: ('wkbMultiPolygon', '25D'),
        ogr.wkbGeometryCollection: ('wkbGeometryCollection', '25D'),
        ogr.wkbNone: ('wkbNone', ''),
        ogr.wkbLinearRing: ('wkbLinearRing', ''),
        ogr.wkbCircularString: ('wkbCircularString', 'Z'),
        ogr.wkbCompoundCurve: ('wkbCompoundCurve', 'Z'),
        ogr.wkbCurvePolygon: ('wkbCurvePolygon', 'Z'),
        ogr.wkbMultiCurve: ('wkbMultiCurve', 'Z'),
        ogr.wkbMultiSurface: ('wkbMultiSurface', 'Z'),
        ogr.wkbCurve: ('wkbCurve', 'Z'),
        ogr.wkbSurface: ('wkbSurface', 'Z'),
        ogr.wkbPolyhedralSurface: ('wkbPolyhedralSurface', 'Z'),
        ogr.wkbTIN: ('wkbTIN', 'Z'),
        ogr.wkbTriangle: ('wkbTriangle', 'Z')
    }
    ret = dic[flat_type][0]
    if flat_type != type:
        if ogr.GT_HasM(type):
            if ogr.GT_HasZ(type):
                ret += "ZM"
            else:
                ret += "M"
        else:
            ret += dic[flat_type][1]
    return ret
예제 #2
0
def _desired_gpkg_envelope_type(flags, wkb_buffer, wkb_offset=0):
    """
    Given some GPKG geometry flags and some WKB,
    returns a constant indicating the type of envelope a geometry should have.

    The rules are:
      * Points never get envelopes
      * Empty geometries never get envelopes
      * Any M components are not included in envelopes
      * XY and XYM geometries get XY envelopes
      * XYZ and XYZM geometries get XYZ envelopes
    """
    if flags & _GPKG_EMPTY_BIT:
        # no need to add envelopes to empties
        return GPKG_ENVELOPE_NONE

    wkb_is_le, geom_type = _wkb_endianness_and_geometry_type(
        wkb_buffer, wkb_offset=wkb_offset
    )
    flat_geom_type = ogr.GT_Flatten(geom_type)
    if flat_geom_type == ogr.wkbPoint:
        # is this a point? if so, we don't *want* an envelope
        # it makes them significantly bigger (29 --> 61 bytes)
        # and is unnecessary - any optimisation that can use a bbox
        # can just trivially parse the point itself
        return GPKG_ENVELOPE_NONE
    else:
        has_z = ogr.GT_HasZ(geom_type)
        if has_z:
            return GPKG_ENVELOPE_XYZ
        else:
            return GPKG_ENVELOPE_XY
예제 #3
0
파일: connector.py 프로젝트: lidapeng/QGIS
    def getVectorTables(self, schema=None):

        items = []
        for i in range(self.gdal_ds.GetLayerCount()):
            lyr = self.gdal_ds.GetLayer(i)
            geomtype = lyr.GetGeomType()
            if hasattr(ogr, 'GT_Flatten'):
                geomtype_flatten = ogr.GT_Flatten(geomtype)
            else:
                geomtype_flatten = geomtype
            geomname = ogr.GeometryTypeToName(geomtype_flatten).upper()
            geomdim = 'XY'
            if hasattr(ogr, 'GT_HasZ') and ogr.GT_HasZ(lyr.GetGeomType()):
                geomdim += 'Z'
            if hasattr(ogr, 'GT_HasM') and ogr.GT_HasM(lyr.GetGeomType()):
                geomdim += 'M'
            srs = lyr.GetSpatialRef()
            srid = None
            if srs is not None:
                if srs.IsProjected():
                    name = srs.GetAttrValue('PROJCS', 0)
                elif srs.IsGeographic():
                    name = srs.GetAttrValue('GEOGCS', 0)
                else:
                    name = None
                srid = srs.GetAuthorityCode(None)
                if srid is not None:
                    srid = int(srid)
                else:
                    srid = self._fetchOne(
                        'SELECT srid FROM gpkg_spatial_ref_sys WHERE table_name = %s'
                        % self.quoteString(lyr.GetName()))
                    if srid is not None:
                        srid = int(srid)
                self.mapSridToName[srid] = name

            if geomtype == ogr.wkbNone:
                item = list([
                    Table.TableType,
                    lyr.GetName(),
                    False,  # is_view
                ])
            else:
                item = list([
                    Table.VectorType,
                    lyr.GetName(),
                    False,  # is_view
                    lyr.GetName(),
                    lyr.GetGeometryColumn(),
                    geomname,
                    geomdim,
                    srid
                ])
            items.append(item)
        return items
예제 #4
0
 def _get_meta_geometry_type(self):
     # remove Z/M components
     ogr_geom_type = ogr.GT_Flatten(self.ogrlayer.GetGeomType())
     if ogr_geom_type == ogr.wkbUnknown:
         return "GEOMETRY"
     return (
         # normalise the geometry type names the way the GPKG spec likes it:
         # http://www.geopackage.org/spec/#geometry_types
         ogr.GeometryTypeToName(ogr_geom_type)
         # 'Line String' --> 'LineString'
         .replace(" ", "")
         # --> 'LINESTRING'
         .upper())
예제 #5
0
파일: ogrmerge.py 프로젝트: edzer/gdal
def ogrmerge(
    src_datasets: Optional[Sequence[str]] = None,
    dst_filename: Optional[PathLikeOrStr] = None,
    driver_name: Optional[str] = None,
    overwrite_ds: bool = False,
    overwrite_layer: bool = False,
    update: bool = False,
    append: bool = False,
    single_layer: bool = False,
    layer_name_template: Optional[str]  = None,
    skip_failures: bool = False,
    src_geom_types: Optional[Sequence[int]] = None,
    field_strategy: Optional[str] = None,
    src_layer_field_name: Optional[str] = None,
    src_layer_field_content: Optional[str] = None,
    a_srs: Optional[str] = None,
    s_srs: Optional[str] = None,
    t_srs: Optional[str] = None,
    dsco: Optional[Sequence[str]] = None,
    lco: Optional[Sequence[str]] = None,
    progress_callback: Optional = None, progress_arg: Optional = None):

    src_datasets = src_datasets or []
    src_geom_types = src_geom_types or []
    dsco = dsco or []
    lco = lco or []
    if update:
        if driver_name is not None:
            print('ERROR: -f incompatible with -update')
            return 1
        if dsco:
            print('ERROR: -dsco incompatible with -update')
            return 1
        driver_name = ''
    else:
        if driver_name is None:
            driver_name = GetOutputDriverFor(dst_filename, is_raster=False)

    if src_layer_field_content is None:
        src_layer_field_content = '{AUTO_NAME}'
    elif src_layer_field_name is None:
        src_layer_field_name = 'source_ds_lyr'

    if not single_layer and driver_name == 'ESRI Shapefile' and \
       dst_filename.lower().endswith('.shp'):
        print('ERROR: Non-single layer mode incompatible with non-directory '
              'shapefile output')
        return 1

    if not src_datasets:
        print('ERROR: No source datasets')
        return 1

    if layer_name_template is None:
        if single_layer:
            layer_name_template = 'merged'
        else:
            layer_name_template = '{AUTO_NAME}'

    vrt_filename = None
    if not EQUAL(driver_name, 'VRT'):
        dst_ds = gdal.OpenEx(dst_filename, gdal.OF_VECTOR | gdal.OF_UPDATE)
        if dst_ds is not None:
            if not update and not overwrite_ds:
                print('ERROR: Destination dataset already exists, ' +
                      'but -update nor -overwrite_ds are specified')
                return 1
            if overwrite_ds:
                drv = dst_ds.GetDriver()
                dst_ds = None
                if drv.GetDescription() == 'OGR_VRT':
                    # We don't want to destroy the sources of the VRT
                    gdal.Unlink(dst_filename)
                else:
                    drv.Delete(dst_filename)
        elif update:
            print('ERROR: Destination dataset does not exist')
            return 1
        if dst_ds is None:
            drv = gdal.GetDriverByName(driver_name)
            if drv is None:
                print('ERROR: Invalid driver: %s' % driver_name)
                return 1
            dst_ds = drv.Create(
                dst_filename, 0, 0, 0, gdal.GDT_Unknown, dsco)
            if dst_ds is None:
                return 1

        vrt_filename = '/vsimem/_ogrmerge_.vrt'
    else:
        if gdal.VSIStatL(dst_filename) and not overwrite_ds:
            print('ERROR: Destination dataset already exists, ' +
                  'but -overwrite_ds are specified')
            return 1
        vrt_filename = dst_filename

    f = gdal.VSIFOpenL(vrt_filename, 'wb')
    if f is None:
        print('ERROR: Cannot create %s' % vrt_filename)
        return 1

    writer = XMLWriter(f)
    writer.open_element('OGRVRTDataSource')

    if single_layer:

        ogr_vrt_union_layer_written = False

        for src_ds_idx, src_dsname in enumerate(src_datasets):
            src_ds = ogr.Open(src_dsname)
            if src_ds is None:
                print('ERROR: Cannot open %s' % src_dsname)
                if skip_failures:
                    continue
                gdal.VSIFCloseL(f)
                gdal.Unlink(vrt_filename)
                return 1
            for src_lyr_idx, src_lyr in enumerate(src_ds):
                if src_geom_types:
                    gt = ogr.GT_Flatten(src_lyr.GetGeomType())
                    if gt not in src_geom_types:
                        continue

                if not ogr_vrt_union_layer_written:
                    ogr_vrt_union_layer_written = True
                    writer.open_element('OGRVRTUnionLayer',
                                        attrs={'name': layer_name_template})

                    if src_layer_field_name is not None:
                        writer.write_element_value('SourceLayerFieldName',
                                                   src_layer_field_name)

                    if field_strategy is not None:
                        writer.write_element_value('FieldStrategy',
                                                   field_strategy)

                layer_name = src_layer_field_content

                src_lyr_name = src_lyr.GetName()
                try:
                    src_lyr_name = src_lyr_name.decode('utf-8')
                except AttributeError:
                    pass

                basename = None
                if os.path.exists(src_dsname):
                    basename = os.path.basename(src_dsname)
                    if '.' in basename:
                        basename = '.'.join(basename.split(".")[0:-1])

                if basename == src_lyr_name:
                    layer_name = layer_name.replace('{AUTO_NAME}', basename)
                elif basename is None:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}',
                        'Dataset%d_%s' % (src_ds_idx, src_lyr_name))
                else:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}', basename + '_' + src_lyr_name)

                if basename is not None:
                    layer_name = layer_name.replace('{DS_BASENAME}', basename)
                else:
                    layer_name = layer_name.replace('{DS_BASENAME}',
                                                    src_dsname)
                layer_name = layer_name.replace('{DS_NAME}', '%s' %
                                                src_dsname)
                layer_name = layer_name.replace('{DS_INDEX}', '%d' %
                                                src_ds_idx)
                layer_name = layer_name.replace('{LAYER_NAME}',
                                                src_lyr_name)
                layer_name = layer_name.replace('{LAYER_INDEX}', '%d' %
                                                src_lyr_idx)

                if t_srs is not None:
                    writer.open_element('OGRVRTWarpedLayer')

                writer.open_element('OGRVRTLayer',
                                    attrs={'name': layer_name})
                attrs = {}
                if EQUAL(driver_name, 'VRT') and \
                   os.path.exists(src_dsname) and \
                   not os.path.isabs(src_dsname) and \
                   '/' not in vrt_filename and \
                   '\\' not in vrt_filename:
                    attrs['relativeToVRT'] = '1'
                if single_layer:
                    attrs['shared'] = '1'
                writer.write_element_value('SrcDataSource', src_dsname,
                                           attrs=attrs)
                writer.write_element_value('SrcLayer', src_lyr.GetName())

                if a_srs is not None:
                    writer.write_element_value('LayerSRS', a_srs)

                writer.close_element('OGRVRTLayer')

                if t_srs is not None:
                    if s_srs is not None:
                        writer.write_element_value('SrcSRS', s_srs)

                    writer.write_element_value('TargetSRS', t_srs)

                    writer.close_element('OGRVRTWarpedLayer')

        if ogr_vrt_union_layer_written:
            writer.close_element('OGRVRTUnionLayer')

    else:

        for src_ds_idx, src_dsname in enumerate(src_datasets):
            src_ds = ogr.Open(src_dsname)
            if src_ds is None:
                print('ERROR: Cannot open %s' % src_dsname)
                if skip_failures:
                    continue
                gdal.VSIFCloseL(f)
                gdal.Unlink(vrt_filename)
                return 1
            for src_lyr_idx, src_lyr in enumerate(src_ds):
                if src_geom_types:
                    gt = ogr.GT_Flatten(src_lyr.GetGeomType())
                    if gt not in src_geom_types:
                        continue

                src_lyr_name = src_lyr.GetName()
                try:
                    src_lyr_name = src_lyr_name.decode('utf-8')
                except AttributeError:
                    pass

                layer_name = layer_name_template
                basename = None
                if os.path.exists(src_dsname):
                    basename = os.path.basename(src_dsname)
                    if '.' in basename:
                        basename = '.'.join(basename.split(".")[0:-1])

                if basename == src_lyr_name:
                    layer_name = layer_name.replace('{AUTO_NAME}', basename)
                elif basename is None:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}',
                        'Dataset%d_%s' % (src_ds_idx, src_lyr_name))
                else:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}', basename + '_' + src_lyr_name)

                if basename is not None:
                    layer_name = layer_name.replace('{DS_BASENAME}', basename)
                elif '{DS_BASENAME}' in layer_name:
                    if skip_failures:
                        if '{DS_INDEX}' not in layer_name:
                            layer_name = layer_name.replace(
                                '{DS_BASENAME}', 'Dataset%d' % src_ds_idx)
                    else:
                        print('ERROR: Layer name template %s '
                              'includes {DS_BASENAME} '
                              'but %s is not a file' %
                              (layer_name_template, src_dsname))

                        gdal.VSIFCloseL(f)
                        gdal.Unlink(vrt_filename)
                        return 1
                layer_name = layer_name.replace('{DS_NAME}', '%s' %
                                                src_dsname)
                layer_name = layer_name.replace('{DS_INDEX}', '%d' %
                                                src_ds_idx)
                layer_name = layer_name.replace('{LAYER_NAME}',
                                                src_lyr_name)
                layer_name = layer_name.replace('{LAYER_INDEX}', '%d' %
                                                src_lyr_idx)

                if t_srs is not None:
                    writer.open_element('OGRVRTWarpedLayer')

                writer.open_element('OGRVRTLayer',
                                    attrs={'name': layer_name})
                attrs = {}
                if EQUAL(driver_name, 'VRT') and \
                   os.path.exists(src_dsname) and \
                   not os.path.isabs(src_dsname) and \
                   '/' not in vrt_filename and \
                   '\\' not in vrt_filename:
                    attrs['relativeToVRT'] = '1'
                if single_layer:
                    attrs['shared'] = '1'
                writer.write_element_value('SrcDataSource', src_dsname,
                                           attrs=attrs)
                writer.write_element_value('SrcLayer', src_lyr_name)

                if a_srs is not None:
                    writer.write_element_value('LayerSRS', a_srs)

                writer.close_element('OGRVRTLayer')

                if t_srs is not None:
                    if s_srs is not None:
                        writer.write_element_value('SrcSRS', s_srs)

                    writer.write_element_value('TargetSRS', t_srs)

                    writer.close_element('OGRVRTWarpedLayer')

    writer.close_element('OGRVRTDataSource')

    gdal.VSIFCloseL(f)

    ret = 0
    if not EQUAL(driver_name, 'VRT'):
        accessMode = None
        if append:
            accessMode = 'append'
        elif overwrite_layer:
            accessMode = 'overwrite'
        ret = gdal.VectorTranslate(dst_ds, vrt_filename,
                                   accessMode=accessMode,
                                   layerCreationOptions=lco,
                                   skipFailures=skip_failures,
                                   callback=progress_callback,
                                   callback_data=progress_arg)
        if ret == 1:
            ret = 0
        else:
            ret = 1
        gdal.Unlink(vrt_filename)

    return ret
예제 #6
0
    def save_footprints(self, map_name):
        if self._products_df_sorted is None:
            return
        if self._apiname == 'USGS_EE':
            gs.fatal(_(
                "USGS Earth Explorer does not support footprint download."))
        try:
            from osgeo import ogr, osr
        except ImportError as e:
            gs.fatal(_("Option <footprints> requires GDAL library: {}").format(e))

        gs.message(_("Writing footprints into <{}>...").format(map_name))
        driver = ogr.GetDriverByName("GPKG")
        tmp_name = gs.tempfile() + '.gpkg'
        data_source = driver.CreateDataSource(tmp_name)

        srs = osr.SpatialReference()
        srs.ImportFromEPSG(4326)

        # features can be polygons or multi-polygons
        layer = data_source.CreateLayer(str(map_name), srs, ogr.wkbMultiPolygon)

        # attributes
        attrs = OrderedDict([
            ("uuid", ogr.OFTString),
            ("ingestiondate", ogr.OFTString),
            ("cloudcoverpercentage", ogr.OFTInteger),
            ("producttype", ogr.OFTString),
            ("identifier", ogr.OFTString)
        ])

        # Sentinel-1 data does not have cloudcoverpercentage
        prod_types = [type for type in self._products_df_sorted["producttype"]]
        s1_types = ["SLC", "GRD"]
        if any(type in prod_types for type in s1_types):
            del attrs["cloudcoverpercentage"]

        for key in attrs.keys():
            field = ogr.FieldDefn(key, attrs[key])
            layer.CreateField(field)

        # features
        for idx in range(len(self._products_df_sorted['uuid'])):
            wkt = self._products_df_sorted['footprint'][idx]
            feature = ogr.Feature(layer.GetLayerDefn())
            newgeom = ogr.CreateGeometryFromWkt(wkt)
            # convert polygons to multi-polygons
            newgeomtype = ogr.GT_Flatten(newgeom.GetGeometryType())
            if newgeomtype == ogr.wkbPolygon:
                multigeom = ogr.Geometry(ogr.wkbMultiPolygon)
                multigeom.AddGeometryDirectly(newgeom)
                feature.SetGeometry(multigeom)
            else:
                feature.SetGeometry(newgeom)
            for key in attrs.keys():
                if key == 'ingestiondate':
                    value = self._products_df_sorted[key][idx].strftime("%Y-%m-%dT%H:%M:%SZ")
                else:
                    value = self._products_df_sorted[key][idx]
                feature.SetField(key, value)
            layer.CreateFeature(feature)
            feature = None

        data_source = None

        # coordinates of footprints are in WKT -> fp precision issues
        # -> snap
        gs.run_command('v.import', input=tmp_name, output=map_name,
                       layer=map_name, snap=1e-10, quiet=True
                       )
예제 #7
0
def process(argv, progress=None, progress_arg=None):

    if not argv:
        return Usage()

    dst_filename = None
    output_format = None
    src_datasets = []
    overwrite_ds = False
    overwrite_layer = False
    update = False
    append = False
    single_layer = False
    layer_name_template = None
    skip_failures = False
    src_geom_types = []
    field_strategy = None
    src_layer_field_name = None
    src_layer_field_content = None
    a_srs = None
    s_srs = None
    t_srs = None
    dsco = []
    lco = []

    i = 0
    while i < len(argv):
        arg = argv[i]
        if (arg == '-f' or arg == '-of') and i + 1 < len(argv):
            i = i + 1
            output_format = argv[i]
        elif arg == '-o' and i + 1 < len(argv):
            i = i + 1
            dst_filename = argv[i]
        elif arg == '-progress':
            progress = ogr.TermProgress_nocb
            progress_arg = None
        elif arg == '-q' or arg == '-quiet':
            pass
        elif arg[0:5] == '-skip':
            skip_failures = True
        elif arg == '-update':
            update = True
        elif arg == '-overwrite_ds':
            overwrite_ds = True
        elif arg == '-overwrite_layer':
            overwrite_layer = True
            update = True
        elif arg == '-append':
            append = True
            update = True
        elif arg == '-single':
            single_layer = True
        elif arg == '-a_srs' and i + 1 < len(argv):
            i = i + 1
            a_srs = argv[i]
        elif arg == '-s_srs' and i + 1 < len(argv):
            i = i + 1
            s_srs = argv[i]
        elif arg == '-t_srs' and i + 1 < len(argv):
            i = i + 1
            t_srs = argv[i]
        elif arg == '-nln' and i + 1 < len(argv):
            i = i + 1
            layer_name_template = argv[i]
        elif arg == '-field_strategy' and i + 1 < len(argv):
            i = i + 1
            field_strategy = argv[i]
        elif arg == '-src_layer_field_name' and i + 1 < len(argv):
            i = i + 1
            src_layer_field_name = argv[i]
        elif arg == '-src_layer_field_content' and i + 1 < len(argv):
            i = i + 1
            src_layer_field_content = argv[i]
        elif arg == '-dsco' and i + 1 < len(argv):
            i = i + 1
            dsco.append(argv[i])
        elif arg == '-lco' and i + 1 < len(argv):
            i = i + 1
            lco.append(argv[i])
        elif arg == '-src_geom_type' and i + 1 < len(argv):
            i = i + 1
            src_geom_type_names = argv[i].split(',')
            for src_geom_type_name in src_geom_type_names:
                src_geom_type = _GetGeomType(src_geom_type_name)
                if src_geom_type is None:
                    print('ERROR: Unrecognized geometry type: %s' %
                          src_geom_type_name)
                    return 1
                src_geom_types.append(src_geom_type)
        elif arg[0] == '-':
            print('ERROR: Unrecognized argument : %s' % arg)
            return Usage()
        else:
            if '*' in arg:
                if sys.version_info < (3,0,0):
                    src_datasets += [fn.decode(sys.getfilesystemencoding()) for fn in glob.glob(arg)]
                else:
                    src_datasets += glob.glob(arg)
            else:
                src_datasets.append(arg)
        i = i + 1

    if dst_filename is None:
        print('Missing -o')
        return 1

    if update:
        if output_format is not None:
            print('ERROR: -f incompatible with -update')
            return 1
        if dsco:
            print('ERROR: -dsco incompatible with -update')
            return 1
        output_format = ''
    else:
        if output_format is None:
            output_format = GetOutputDriverFor(dst_filename)

    if src_layer_field_content is None:
        src_layer_field_content = '{AUTO_NAME}'
    elif src_layer_field_name is None:
        src_layer_field_name = 'source_ds_lyr'

    if not single_layer and output_format == 'ESRI Shapefile' and \
       dst_filename.lower().endswith('.shp'):
        print('ERROR: Non-single layer mode incompatible with non-directory '
              'shapefile output')
        return 1

    if not src_datasets:
        print('ERROR: No source datasets')
        return 1

    if layer_name_template is None:
        if single_layer:
            layer_name_template = 'merged'
        else:
            layer_name_template = '{AUTO_NAME}'

    vrt_filename = None
    if not EQUAL(output_format, 'VRT'):
        dst_ds = gdal.OpenEx(dst_filename, gdal.OF_VECTOR | gdal.OF_UPDATE)
        if dst_ds is not None:
            if not update and not overwrite_ds:
                print('ERROR: Destination dataset already exists, ' +
                      'but -update nor -overwrite_ds are specified')
                return 1
            if overwrite_ds:
                drv = dst_ds.GetDriver()
                dst_ds = None
                if drv.GetDescription() == 'OGR_VRT':
                    # We don't want to destroy the sources of the VRT
                    gdal.Unlink(dst_filename)
                else:
                    drv.Delete(dst_filename)
        elif update:
            print('ERROR: Destination dataset does not exist')
            return 1
        if dst_ds is None:
            drv = gdal.GetDriverByName(output_format)
            if drv is None:
                print('ERROR: Invalid driver: %s' % output_format)
                return 1
            dst_ds = drv.Create(
                dst_filename, 0, 0, 0, gdal.GDT_Unknown, dsco)
            if dst_ds is None:
                return 1

        vrt_filename = '/vsimem/_ogrmerge_.vrt'
    else:
        if gdal.VSIStatL(dst_filename) and not overwrite_ds:
            print('ERROR: Destination dataset already exists, ' +
                  'but -overwrite_ds are specified')
            return 1
        vrt_filename = dst_filename

    f = gdal.VSIFOpenL(vrt_filename, 'wb')
    if f is None:
        print('ERROR: Cannot create %s' % vrt_filename)
        return 1

    writer = XMLWriter(f)
    writer.open_element('OGRVRTDataSource')

    if single_layer:

        ogr_vrt_union_layer_written = False

        for src_ds_idx, src_dsname in enumerate(src_datasets):
            src_ds = ogr.Open(src_dsname)
            if src_ds is None:
                print('ERROR: Cannot open %s' % src_dsname)
                if skip_failures:
                    continue
                gdal.VSIFCloseL(f)
                gdal.Unlink(vrt_filename)
                return 1
            for src_lyr_idx, src_lyr in enumerate(src_ds):
                if src_geom_types:
                    gt = ogr.GT_Flatten(src_lyr.GetGeomType())
                    if gt not in src_geom_types:
                        continue

                if not ogr_vrt_union_layer_written:
                    ogr_vrt_union_layer_written = True
                    writer.open_element('OGRVRTUnionLayer',
                                        attrs={'name': layer_name_template})

                    if src_layer_field_name is not None:
                        writer.write_element_value('SourceLayerFieldName',
                                                   src_layer_field_name)

                    if field_strategy is not None:
                        writer.write_element_value('FieldStrategy',
                                                   field_strategy)

                layer_name = src_layer_field_content

                src_lyr_name = src_lyr.GetName()
                try:
                    src_lyr_name = src_lyr_name.decode('utf-8')
                except AttributeError:
                    pass

                basename = None
                if os.path.exists(src_dsname):
                    basename = os.path.basename(src_dsname)
                    if '.' in basename:
                        basename = '.'.join(basename.split(".")[0:-1])

                if basename == src_lyr_name:
                    layer_name = layer_name.replace('{AUTO_NAME}', basename)
                elif basename is None:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}',
                        'Dataset%d_%s' % (src_ds_idx, src_lyr_name))
                else:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}', basename + '_' + src_lyr_name)

                if basename is not None:
                    layer_name = layer_name.replace('{DS_BASENAME}', basename)
                else:
                    layer_name = layer_name.replace('{DS_BASENAME}',
                                                    src_dsname)
                layer_name = layer_name.replace('{DS_NAME}', '%s' %
                                                src_dsname)
                layer_name = layer_name.replace('{DS_INDEX}', '%d' %
                                                src_ds_idx)
                layer_name = layer_name.replace('{LAYER_NAME}',
                                                src_lyr_name)
                layer_name = layer_name.replace('{LAYER_INDEX}', '%d' %
                                                src_lyr_idx)

                if t_srs is not None:
                    writer.open_element('OGRVRTWarpedLayer')

                writer.open_element('OGRVRTLayer',
                                    attrs={'name': layer_name})
                attrs = {}
                if EQUAL(output_format, 'VRT') and \
                   os.path.exists(src_dsname) and \
                   not os.path.isabs(src_dsname) and \
                   '/' not in vrt_filename and \
                   '\\' not in vrt_filename:
                    attrs['relativeToVRT'] = '1'
                if single_layer:
                    attrs['shared'] = '1'
                writer.write_element_value('SrcDataSource', src_dsname,
                                           attrs=attrs)
                writer.write_element_value('SrcLayer', src_lyr.GetName())

                if a_srs is not None:
                    writer.write_element_value('LayerSRS', a_srs)

                writer.close_element('OGRVRTLayer')

                if t_srs is not None:
                    if s_srs is not None:
                        writer.write_element_value('SrcSRS', s_srs)

                    writer.write_element_value('TargetSRS', t_srs)

                    writer.close_element('OGRVRTWarpedLayer')

        if ogr_vrt_union_layer_written:
            writer.close_element('OGRVRTUnionLayer')

    else:

        for src_ds_idx, src_dsname in enumerate(src_datasets):
            src_ds = ogr.Open(src_dsname)
            if src_ds is None:
                print('ERROR: Cannot open %s' % src_dsname)
                if skip_failures:
                    continue
                gdal.VSIFCloseL(f)
                gdal.Unlink(vrt_filename)
                return 1
            for src_lyr_idx, src_lyr in enumerate(src_ds):
                if src_geom_types:
                    gt = ogr.GT_Flatten(src_lyr.GetGeomType())
                    if gt not in src_geom_types:
                        continue

                src_lyr_name = src_lyr.GetName()
                try:
                    src_lyr_name = src_lyr_name.decode('utf-8')
                except AttributeError:
                    pass

                layer_name = layer_name_template
                basename = None
                if os.path.exists(src_dsname):
                    basename = os.path.basename(src_dsname)
                    if '.' in basename:
                        basename = '.'.join(basename.split(".")[0:-1])

                if basename == src_lyr_name:
                    layer_name = layer_name.replace('{AUTO_NAME}', basename)
                elif basename is None:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}',
                        'Dataset%d_%s' % (src_ds_idx, src_lyr_name))
                else:
                    layer_name = layer_name.replace(
                        '{AUTO_NAME}', basename + '_' + src_lyr_name)

                if basename is not None:
                    layer_name = layer_name.replace('{DS_BASENAME}', basename)
                elif '{DS_BASENAME}' in layer_name:
                    if skip_failures:
                        if '{DS_INDEX}' not in layer_name:
                            layer_name = layer_name.replace(
                                '{DS_BASENAME}', 'Dataset%d' % src_ds_idx)
                    else:
                        print('ERROR: Layer name template %s '
                              'includes {DS_BASENAME} '
                              'but %s is not a file' %
                              (layer_name_template, src_dsname))

                        gdal.VSIFCloseL(f)
                        gdal.Unlink(vrt_filename)
                        return 1
                layer_name = layer_name.replace('{DS_NAME}', '%s' %
                                                src_dsname)
                layer_name = layer_name.replace('{DS_INDEX}', '%d' %
                                                src_ds_idx)
                layer_name = layer_name.replace('{LAYER_NAME}',
                                                src_lyr_name)
                layer_name = layer_name.replace('{LAYER_INDEX}', '%d' %
                                                src_lyr_idx)

                if t_srs is not None:
                    writer.open_element('OGRVRTWarpedLayer')

                writer.open_element('OGRVRTLayer',
                                    attrs={'name': layer_name})
                attrs = {}
                if EQUAL(output_format, 'VRT') and \
                   os.path.exists(src_dsname) and \
                   not os.path.isabs(src_dsname) and \
                   '/' not in vrt_filename and \
                   '\\' not in vrt_filename:
                    attrs['relativeToVRT'] = '1'
                if single_layer:
                    attrs['shared'] = '1'
                writer.write_element_value('SrcDataSource', src_dsname,
                                           attrs=attrs)
                writer.write_element_value('SrcLayer', src_lyr_name)

                if a_srs is not None:
                    writer.write_element_value('LayerSRS', a_srs)

                writer.close_element('OGRVRTLayer')

                if t_srs is not None:
                    if s_srs is not None:
                        writer.write_element_value('SrcSRS', s_srs)

                    writer.write_element_value('TargetSRS', t_srs)

                    writer.close_element('OGRVRTWarpedLayer')

    writer.close_element('OGRVRTDataSource')

    gdal.VSIFCloseL(f)

    ret = 0
    if not EQUAL(output_format, 'VRT'):
        accessMode = None
        if append:
            accessMode = 'append'
        elif overwrite_layer:
            accessMode = 'overwrite'
        ret = gdal.VectorTranslate(dst_ds, vrt_filename,
                                   accessMode=accessMode,
                                   layerCreationOptions=lco,
                                   skipFailures=skip_failures,
                                   callback=progress,
                                   callback_data=progress_arg)
        if ret == 1:
            ret = 0
        else:
            ret = 1
        gdal.Unlink(vrt_filename)

    return ret
    def getVectorTables(self, schema=None):

        items = []
        for i in range(self.gdal_ds.GetLayerCount()):
            lyr = self.gdal_ds.GetLayer(i)
            geomtype = lyr.GetGeomType()
            if hasattr(ogr, 'GT_Flatten'):
                geomtype_flatten = ogr.GT_Flatten(geomtype)
            else:
                geomtype_flatten = geomtype
            geomname = 'GEOMETRY'
            if geomtype_flatten == ogr.wkbPoint:
                geomname = 'POINT'
            elif geomtype_flatten == ogr.wkbLineString:
                geomname = 'LINESTRING'
            elif geomtype_flatten == ogr.wkbPolygon:
                geomname = 'POLYGON'
            elif geomtype_flatten == ogr.wkbMultiPoint:
                geomname = 'MULTIPOINT'
            elif geomtype_flatten == ogr.wkbMultiLineString:
                geomname = 'MULTILINESTRING'
            elif geomtype_flatten == ogr.wkbMultiPolygon:
                geomname = 'MULTIPOLYGON'
            elif geomtype_flatten == ogr.wkbGeometryCollection:
                geomname = 'GEOMETRYCOLLECTION'
            elif geomtype_flatten == ogr.wkbCircularString:
                geomname = 'CIRCULARSTRING'
            elif geomtype_flatten == ogr.wkbCompoundCurve:
                geomname = 'COMPOUNDCURVE'
            elif geomtype_flatten == ogr.wkbCurvePolygon:
                geomname = 'CURVEPOLYGON'
            elif geomtype_flatten == ogr.wkbMultiCurve:
                geomname = 'MULTICURVE'
            elif geomtype_flatten == ogr.wkbMultiSurface:
                geomname = 'MULTISURFACE'
            geomdim = 'XY'
            if hasattr(ogr, 'GT_HasZ') and ogr.GT_HasZ(lyr.GetGeomType()):
                geomdim += 'Z'
            if hasattr(ogr, 'GT_HasM') and ogr.GT_HasM(lyr.GetGeomType()):
                geomdim += 'M'
            srs = lyr.GetSpatialRef()
            srid = None
            if srs is not None:
                if srs.IsProjected():
                    name = srs.GetAttrValue('PROJCS', 0)
                elif srs.IsGeographic():
                    name = srs.GetAttrValue('GEOGCS', 0)
                else:
                    name = None
                srid = srs.GetAuthorityCode(None)
                if srid is not None:
                    srid = int(srid)
                else:
                    srid = self._fetchOne(
                        'SELECT srid FROM gpkg_spatial_ref_sys WHERE table_name = %s'
                        % self.quoteString(lyr.GetName()))
                    if srid is not None:
                        srid = int(srid)
                self.mapSridToName[srid] = name

            if geomtype == ogr.wkbNone:
                item = list([
                    Table.TableType,
                    lyr.GetName(),
                    False,  # is_view
                ])
            else:
                item = list([
                    Table.VectorType,
                    lyr.GetName(),
                    False,  # is_view
                    lyr.GetName(),
                    lyr.GetGeometryColumn(),
                    geomname,
                    geomdim,
                    srid
                ])
            items.append(item)
        return items
예제 #9
0
def check_feature_geometry(feat, geom, max_error=0.0001):
    """ Returns 0 in case of success """
    try:
        f_geom = feat.GetGeometryRef()
    except:
        f_geom = feat

    if geom is not None and isinstance(geom, type('a')):
        geom = ogr.CreateGeometryFromWkt(geom)

    if (f_geom is not None and geom is None):
        gdaltest.post_reason('expected NULL geometry but got one.')
        return 1

    if (f_geom is None and geom is not None):
        gdaltest.post_reason('expected geometry but got NULL.')
        return 1

    if f_geom is None and geom is None:
        return 0

    if f_geom.GetGeometryName() != geom.GetGeometryName():
        gdaltest.post_reason(
            'geometry names do not match.  "%s" ! = "%s"' %
            (f_geom.GetGeometryName(), geom.GetGeometryName()))
        return 1

    if f_geom.GetGeometryType() != geom.GetGeometryType():
        gdaltest.post_reason('geometry type do not match')
        return 1

    if f_geom.GetGeometryCount() != geom.GetGeometryCount():
        gdaltest.post_reason('sub-geometry counts do not match')
        return 1

    if f_geom.GetPointCount() != geom.GetPointCount():
        gdaltest.post_reason('point counts do not match')
        return 1

    # ST_Equals(a,b) <==> ST_Within(a,b) && ST_Within(b,a)
    # We can't use OGRGeometry::Equals() because it doesn't not test spatial
    # equality, but structural one
    if have_geos() and f_geom.Within(geom) and geom.Within(f_geom) and \
        ogr.GT_Flatten(f_geom.GetGeometryType()) == f_geom.GetGeometryType():
        return 0

    if f_geom.GetGeometryCount() > 0:
        count = f_geom.GetGeometryCount()
        for i in range(count):
            result = check_feature_geometry(f_geom.GetGeometryRef(i),
                                            geom.GetGeometryRef(i), max_error)
            if result != 0:
                return result
    else:
        count = f_geom.GetPointCount()
        if ogr.GT_Flatten(f_geom.GetGeometryType()) == ogr.wkbPoint:
            count = 1

        for i in range(count):
            x_dist = abs(f_geom.GetX(i) - geom.GetX(i))
            y_dist = abs(f_geom.GetY(i) - geom.GetY(i))
            z_dist = abs(f_geom.GetZ(i) - geom.GetZ(i))
            m_dist = abs(f_geom.GetM(i) - geom.GetM(i))

            # Hack to deal with shapefile not-a-number M values that equal to -1.79769313486232e+308
            if m_dist > max_error and f_geom.GetM(i) < -1.7e308 and geom.GetM(
                    i) < -1.7e308:
                m_dist = 0

            if max(x_dist, y_dist, z_dist, m_dist) > max_error:
                gdaltest.post_reason('Error in vertex %d, off by %g.' %
                                     (i, max(x_dist, y_dist, z_dist, m_dist)))
                # print(f_geom.GetX(i))
                # print(geom.GetX(i))
                # print(f_geom.GetY(i))
                # print(geom.GetY(i))
                # print(f_geom.GetZ(i))
                # print(geom.GetZ(i))
                return 1

    return 0