1

I want to convert a shapefile with polygon to KML file using GDAL Python. For this I created a fuction with two arguments (input and output) and it works, but points in polygon are switched (X in KML is Y in SHP and Y in KML is X in SHP). In ogr.ogeometry is a method SwapXY but it is for points not polygons.

https://gdal.org/python/osgeo.ogr.Geometry-class.html#SwapXY

I try to export polygon to array of points but I didn't find any fuction for it. After that I create geometry from WKT and export to KML but I don't know how to save it into output file (not as text file but KML with georeferences). I don't want use subprocess with ogr2ogr, because it is a system dependency.

Here is a code:

    @staticmethod
    def __convert_shp_to_kml(shp_file: pathlib.Path, kml_file: pathlib.Path = None):
        """
        Convert shp (shape file) to kml file.

        :param shp_file: path to shp file
        :type shp_file: pathlib.Path
        :return: True if conversion is correct
        :rtype: bool
        """
        assert shp_file.exists() is True, logging.error("File: " + str(shp_file) + " not exist.")
        if kml_file is None:
            kml_file = str(shp_file).replace(shp_file.suffix, ".kml")
            kml_file_name = str(shp_file.stem)
        else:
            kml_file_name = str(kml_file.stem)
            kml_file = str(kml_file)

        driver = ogr.GetDriverByName('ESRI Shapefile')
        dataset = driver.Open(str(shp_file))
        layer = dataset.GetLayer()
        spatial_ref = layer.GetSpatialRef()
        epsg_code: int = int(spatial_ref.GetAttrValue('AUTHORITY', 1))

        output_driver = ogr.GetDriverByName('KML')
        out_ds = output_driver.CreateDataSource(kml_file)
        output_data_set = osr.SpatialReference()
        output_data_set.ImportFromEPSG(epsg_code)
        out_layer = out_ds.CreateLayer(kml_file_name, output_data_set, geom_type=ogr.wkbPolygon)

        ds = ogr.Open(str(shp_file))
        if ds is None:
            logging.warning(str(shp_file) + "ds is empty")
        lyr = ds.GetLayer()
        for feat in lyr:
            geom_poly = ogr.CreateGeometryFromWkt(str(feat.GetGeometryRef()))
            print(geom_poly.ExportToKML())
            out_feat = ogr.Feature(out_layer.GetLayerDefn())
            out_feat.SetGeometry(geom_poly)
            out_layer.CreateFeature(out_feat)
            out_layer.SyncToDisk()
        return True
3
  • 1
    I would use gdal.VectorTranslate (like the commandline ogr2ogr tool).
    – user2856
    Sep 30, 2020 at 12:58
  • Please tell explicitly what coordinate order you have now in KML. I suppose it is latitude-longitude, but confirm. SwapXY takes in geometry by the API document. What makes you think it works only for points? Also read trac.osgeo.org/gdal/wiki/rfc73_proj6_wkt2_srsbarn and try SetAxisMappingStrategy?(OAMS_TRADITIONAL_GIS_ORDER).
    – user30184
    Sep 30, 2020 at 13:56
  • I use gdal.VectorTranslate as method: srcDS = gdal.OpenEx(str(shp_file)) gdal.VectorTranslate(destNameOrDestDS=kml_file, srcDS=srcDS, format='KML') Warnings First Warning 1: The output driver does not seem to natively support Integer64 type for field tessellate. Converting it to Real instead. -mapFieldType can be used to control field type conversion. Second Warning 1: The output driver does not seem to natively support Integer64 type for field extrude. Converting it to Real instead. -mapFieldType can be used to control field type conversion.
    – user153770
    Oct 1, 2020 at 14:31

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.