Polyline shapefile to KML

Hello,

Will anybody share some code to convert a line shapefile to KML for google Earth?

Thanks!

This is some code I use to create a kml files with a polygon (voting precinct) and a point (the polling place):

Private Sub CreateKML()
        ' open input file
        Dim cdlOpen As New OpenFileDialog

        Dim fileName As String = ""
        'check to see if it is a shapefile
        cdlOpen.Filter = "Shapefile (*.shp)|*.shp|Image Files (*.jpg)|*.jpg|Image Files (*.sid)|*.sid|All files (*.*)|*.*"
        cdlOpen.ShowDialog()
        fileName = Trim(cdlOpen.FileName)
        If fileName = "" Then Exit Sub
        Dim sf As New MapWinGIS.Shapefile
        If Not sf.Open(fileName) Then
            Console.WriteLine("Failed to open shapefile:" & fileName & sf.LastErrorCode.ToString)
            Exit Sub
        End If

        ' define the output file
        Dim KMLFileNamePath As String = ""
        'Dim cdlSaveAs As New SaveFileDialog
        Dim cdlSaveAs As New FolderBrowserDialog
        'cdlSaveAs.FileName = cdlOpen.FileName
        'cdlSaveAs.Filter = "Shapefile (*.kml)|*.kml|All files (*.*)|*.*"
        cdlSaveAs.ShowDialog()
        If cdlSaveAs.SelectedPath.ToString > "" Then
            KMLFileNamePath = cdlSaveAs.SelectedPath.ToString

        Else
            MsgBox("No output KML file designated.")
            Exit Sub
        End If
        Dim preccol As Integer = 0 ' this needs to be a user choice at run time
        Dim KMLFileName As String = ""
        'Loop through the shape file, shape by shape

        Dim KMLFile As System.IO.StreamWriter

        Dim ShapeIndex As Integer, ConvertedShapeCount As Integer
        For ShapeIndex = 0 To SF.NumShapes - 1
            ToolStripStatusLabel6.Text = ShapeIndex.ToString & " of " & sf.NumShapes.ToString

            'Process each shape depending on ShapeType
            Select Case SF.Shape(ShapeIndex).ShapeType

                Case ShpfileType.SHP_POLYGON, ShpfileType.SHP_POLYGONZ, ShpfileType.SHP_POLYGONM
                    Dim prec As String = sf.CellValue(preccol, ShapeIndex)
                    KMLFile = My.Computer.FileSystem.OpenTextFileWriter(KMLFileNamePath & "\p" & prec & ".kml", False)
                    KMLFile.WriteLine("<?xml version=""1.0"" encoding=""utf-8"" ?>")
                    KMLFile.WriteLine("<kml xmlns=""http://www.opengis.net/kml/2.2"">")
                    KMLFile.WriteLine("<Document id=""root_doc"">")
                    KMLFile.WriteLine("<Folder><name>Sarasota_Precincts_2016_region</name>")

                    Call AddPolygonKML(sf.Shape(ShapeIndex), KMLFile, CStr(ShapeIndex), prec)
                    ConvertedShapeCount = ConvertedShapeCount + 1
                    Dim locname As String = sf.CellValue(1, ShapeIndex)
                    Dim loclatlong As String = sf.CellValue(3, ShapeIndex)
                    If loclatlong > " " Then
                        KMLFile.WriteLine("<Placemark>")
                        KMLFile.WriteLine("<name>" & locname & "</name>")
                        KMLFile.WriteLine("<description>Polling place For precinct " & prec & "</description>")
                        KMLFile.WriteLine("<Point><coordinates>" & loclatlong & ",0</coordinates></Point>")
                        KMLFile.WriteLine("</Placemark>")
                    End If

                    KMLFile.WriteLine("</Folder></Document></kml>")
                    KMLFile.Close()
                    KMLCreateHTMLfile(prec, KMLFileNamePath)
                Case Else
                    Debug.Print("Shape # " & ShapeIndex & " of type " & SF.Shape(ShapeIndex).ShapeType & " not supported yet.")

            End Select

        Next ShapeIndex
        sf.Close()
        'KMLFile.Close()
        MsgBox("KML files created in '" & KMLFileNamePath)
End Sub
Private Sub KMLCreateHTMLfile(prec As String, pth As String)

        Dim txt As String = "<!DOCTYPE html>"
        txt &= vbCrLf & "<html>"
        txt &= vbCrLf & "<head>"
        txt &= vbCrLf & "<meta name=""viewport"" content=""initial-scale=1.0"">"
        txt &= vbCrLf & "<meta charset=""utf-8"">"
        txt &= vbCrLf & "<title>KML Layers</title>"
        txt &= vbCrLf & "<style>"
        txt &= vbCrLf & "   /* Always set the map height explicitly to define the size of the div"
        txt &= vbCrLf & "   * element that contains the map. */"
        txt &= vbCrLf & "  #map {"
        txt &= vbCrLf & "    height: 100%;"
        txt &= vbCrLf & "  }"
        txt &= vbCrLf & "  /* Optional: Makes the sample page fill the window. */"
        txt &= vbCrLf & "  html, body {"
        txt &= vbCrLf & "    height: 100%;"
        txt &= vbCrLf & "    margin: 0;"
        txt &= vbCrLf & "    padding: 0;"
        txt &= vbCrLf & "  }"
        txt &= vbCrLf & "</style>"
        txt &= vbCrLf & "</head>"
        txt &= vbCrLf & "<body>"
        txt &= vbCrLf & " <div id=""map""></div>"
        txt &= vbCrLf & "<script>"

        txt &= vbCrLf & "function initMap() {"
        txt &= vbCrLf & "  var map = new google.maps.Map(document.getElementById('map'), {"
        txt &= vbCrLf & "    zoom: 11,"
        txt &= vbCrLf & "    center: {lat: 27.3678792, lng: -82.556743}"
        txt &= vbCrLf & "  });"

        txt &= vbCrLf & "  var ctaLayer = new google.maps.KmlLayer({"
        txt &= vbCrLf & "    url: 'http://www.myprecinct.com/maps/p*prec*.kml?op=10',"
        txt &= vbCrLf & "    map: map"
        txt &= vbCrLf & "  });"
        txt &= vbCrLf & "}"
        txt &= vbCrLf & "</script>"
        txt &= vbCrLf & "<script async defer"
        txt &= vbCrLf & "src=""https://maps.googleapis.com/maps/api/js?key=AIzaSyD0nHURrjFoRbw1FlwfNqqPlzQptaYje0k&callback=initMap"">"
        txt &= vbCrLf & "</script>"
        txt &= vbCrLf & "</body>"
        txt &= vbCrLf & "</html>"

        txt = txt.Replace("*prec*", prec)

        Dim kmlFile As System.IO.StreamWriter
        kmlFile = My.Computer.FileSystem.OpenTextFileWriter(pth & "\p" & prec & ".html", False)
        kmlFile.WriteLine(txt)
        kmlFile.Close()
End Sub
Private Sub AddPolygonKML(ByRef Shape As MapWinGIS.Shape,
                          ByRef oWrite As System.IO.StreamWriter,
                          ByVal ShapeID As String, prec As String)

        'https://www.codeproject.com/Articles/452963/Using-MapWinGIS-to-Convert-ESRI-Shape-Files-to-Goo
        ' code for creating kml from shapefile
        ' call like this:
        'Public Sub ConvertShapeFileToKML(ByVal ShapeFileName As String, _
        '                         ByVal KMLFileName As String)

        'The key parameters for defining the KML Polygon's points are:
        Dim LatDeg As Double
        Dim LonDeg As Double
        Dim Height As Double    'Note: depending on whether this is AGL or ASL, change the KML setting below accordingly

        'Create a Placemark with no label to wrap the Polygon in
        oWrite.WriteLine("<Placemark>")

        'Use the Shapes ID as a Name (optional)
        oWrite.WriteLine("<name>Precinct " & prec & "</name>")

        'Pick up the Style we wish to use (otional, but allows for nice colours etc)
        oWrite.WriteLine("<styleUrl>Shape Style</styleUrl>")

        'Start the Polygon KML object
        oWrite.Write("<Polygon>")

        'The <extrude> tag extends the line down to the ground
        oWrite.Write("<extrude>1</extrude>")

        'Note there are two common options for Altitude:
        ' "relativeToGround"  for Above Ground Level
        ' "absolute" for Above Sea Level
        ' See https://developers.google.com/kml/documentation/altitudemode
        oWrite.Write("<altitudeMode>relativeToGround</altitudeMode>")

        'A Polygon is defined by a ring of coordinates
        oWrite.Write("<outerBoundaryIs>")
        oWrite.Write("<LinearRing>")
        oWrite.Write("<coordinates>")

        'Loop through the points one by one
        Dim PointIndex As Integer
        For PointIndex = 0 To Shape.numPoints - 1

            'Extract the 3D coordinates for the Point
            LonDeg = Shape.Point(PointIndex).x
            LatDeg = Shape.Point(PointIndex).y
            Height = Shape.Point(PointIndex).Z


            'create KML coordinate string is <lon,lat,height> {space} <lon,lat,height>
            'Note: Any space next to a ',' will create a new coordinate!
            'oWrite.Write("                  ")
            oWrite.Write(FormatNumber(LonDeg, 6) & ",")
            oWrite.Write(FormatNumber(LatDeg, 6) & ",")
            oWrite.Write(FormatNumber(Height, 1) & " ")
            'oWrite.WriteLine()

        Next PointIndex

        'Close the relevant folders in reverse order
        oWrite.Write("</coordinates>")
        oWrite.Write("</LinearRing>")
        oWrite.Write("</outerBoundaryIs>")
        oWrite.Write("</Polygon>")
        oWrite.WriteLine("</Placemark>")
End Sub

An other option would be to use ogr2ogr -f KML output.kml input.shp
ogr2ogr is implemented in MapWinGIS in the GdalUtils class as GdalVectorTranslate()

// Converting shapefile to kml:
var outputFilename = Path.Combine(Path.GetTempPath(), "translated.kml");
var options = new[]
{
    "-f", "KML"
};
var gdalUtils = new GdalUtils();
if (!gdalUtils.GdalVectorTranslate(inputFilename, outputFilename, options))
{
    Debug.WriteLine("GdalVectorTranslate failed: " + gdalUtils.ErrorMsg[gdalUtils.LastErrorCode] + " Detailed error: " + gdalUtils.DetailedErrorMsg);
}

Hi Jon and Paul,

Thank you two very much for the help. I figured to convert a polygon reading this link:


It is similar to Jon’s approach.
Paul’s method works very well. Question: how do we change the z? I want to use : say population, or area, income as z, where do we set it.