6

So I want to convert KML files to SHP shapefiles to load it onto PostGIS. Currently I'm using ogr2ogr to do the conversion for me, but it wipes out all the attribute data. How do i preserve this attribute data in the resulting shapefile? Any better feature out there?

  • Did you ever figure this out? I'm running into the same problem – kflaw Oct 18 '17 at 22:27
  • when I run the script above I have this error Parsing error IndentationError: unexpected indent (line 1), how I can fix it ? – user118722 Apr 14 '18 at 15:39
  • This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. You can also add a bounty to draw more attention to this question once you have enough reputation. - From Review – Vince Apr 14 '18 at 17:37
5

Why don't you directly convert a KML file to PostGIS. You can do this using the following command:

ogr2ogr -overwrite -f "PostgreSQL" PG:"host=myIP user=myUser dbname=myDb password=myPassword" yourfile.kml

This will create a table named layer_0(if not already there) with all your attributes.

  • That's awesome. But I've gotta try it out before accepting this answer. Will do that. Thank you! – KaushikTD Apr 17 '12 at 14:02
  • I'm actually still losing all the attribute data. This command doesn't work. – KaushikTD Apr 18 '12 at 5:50
  • Does it convert your data? If you are still losing your attribute data, check your kml structure. I have used this command successfully. – thelastray Apr 18 '12 at 6:05
  • It converts the data fine. As in, the geometry is preserved, but i lose all my attribute data. I have about 10-12 attribute columns, but the resulting database has 4 tables - feature labels, features, geometry_columns and spatial_ref_sys. The layer_0 table isn't formed or anything. – KaushikTD Apr 18 '12 at 6:42
  • Does switching between the KML and libKML driver make any difference? – Ragi Yaser Burhum Sep 17 '14 at 19:16
2

I wrote a script for myself that does this in python using cursors and lists to split the PopupInfo xml field into useful values

  1. use the arcpy KML to layer tool and Project tools to get into to the desired coordinate system (i ran into problems adding fields to the original conversion output, which may be due to the layer file associated with it)

  2. Use .da.SearchCursor to get the PopupInfo string from the first row. Then split it into a list based on '<', delete the first two values (the label field from Google Earth) and put remaining values that have the 'td>' tag but not the 'td>' closing tag into a new list of field names (even indexes) and field values (odd indexes)

  3. Loop through field names list with arcpy.AddField_management to add all fields (skip if they already exist)

  4. Use .da.UpdateCursor to get PopupInfo's for all rows, then split and create new lists just like with search cursor

  5. this time, use all the odd index values to update rows ( if i%2 <> 0: row[(i-1)/2] = list[i] ) and then cursor.updateRow(row)

Dylan

  import arcpy, os

  #this line is for using a script tool in arcmap
  input_parameter = arcpy.GetParameterAsText(0)
  #alternatively use input_parameter = 'C:\......\file.kmz' to run as stand alone script

  direct = os.path.dirname(input_parameter)
  arcpy.conversion.KMLToLayer(input_parameter, direct)
  arcpy.env.overwriteOutput = True

  database = input_parameter[:-3] + 'gdb'
  dataset = database + '\Placemarks'

  arcpy.env.workspace = dataset
  GCS_List = arcpy.ListFeatureClasses()

  coord_sys = arcpy.GetParameter(1)
  #in stand-alone script use arcpy.SpatialReferece('desired Coord Sys name')

  e_count = 0

  for FC in GCS_List:

     arcpy.Project_management(FC, database + '\\' + FC + '_Proj', coord_sys)

  arcpy.env.workspace = database
  UTM_List = arcpy.ListFeatureClasses()

  mxd = arcpy.mapping.MapDocument('CURRENT')
  df = arcpy.mapping.ListDataFrames(mxd)[0]

  keep_fields = ['OID', 'Shape', 'SHAPE', 'PopupInfo', 'Shape_Length', 'Shape_Area', 'SHAPE_Length', 'SHAPE_Area']

  for FC in UTM_List:

     update_layer = arcpy.mapping.Layer(database + '\\' + FC)
     arcpy.mapping.AddLayer(df, update_layer)

  # first add the fields

     SC = arcpy.SearchCursor(FC)
     for row in SC:

        pop_string = row.getValue("PopupInfo")
        pop_array = pop_string.split("<")
        fields_array = []
        names_array = []

        for tag in pop_array:
           if "td>" in tag and "/td>" not in tag:
              fields_array.append(tag)
        break

     for fields in arcpy.ListFields(FC):

        if fields.name not in keep_fields:
           arcpy.DeleteField_management(FC,fields.name)

  #this will list the field names and field values
  #even indexes are field names (starts at 0)  
  #and odd indexes are field values
     del fields_array[:2]

     for x in range(0,len(fields_array)):
        fields_array[x]=fields_array[x].replace("td>","")
        if x%2 == 0 and fields_array[x] not in keep_fields:
           names_array.append(fields_array[x])
           arcpy.AddField_management(FC, fields_array[x], "TEXT")

  # default is all TEXT fields but I could change this later to reference the values
  #now we update the values
     names_array.append("PopupInfo")

     with arcpy.da.UpdateCursor(FC,names_array) as UC:

        for row in UC:

           pop_string = row[-1]
           pop_array = pop_string.split("<")
           fields_array = []
           values_array = []

           for segment in pop_array:
              if "td>" in segment and "/td>" not in segment:
                 fields_array.append(segment)

           del fields_array[:2]

           for x in range(0,len(fields_array)):
              if x%2<>0:
                 if fields_array[x-1] not in keep_fields:
                    fields_array[x]=fields_array[x].replace("td>","")
                    values_array.append(fields_array[x])

           for y in range(0,len(values_array)):
              try:
                 row[y] = values_array[y]
                 UC.updateRow(row)
              except IndexError:
                 e_count = e_count + 1
1

the XTools Pro ArcMap addin has a free KML importing function which can retain the custom schema in the KML.

-1

This tool, Export to KML developed by Kevin Martin does the work.

There are some issues with the styles but at least colours and attributes are correct, and it´s plenty of options to play with the attributes, labels, etc...

  • 1
    This tool what tool? Got a link to it? – Spacedman Dec 9 '15 at 11:09
  • Sorry, forgot the link. Now is fine. – Pedraz Dec 9 '15 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.