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– kflawOct 18, 2017 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 ?– user118722Apr 14, 2018 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– VinceApr 14, 2018 at 17:37
4 Answers
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! Apr 17, 2012 at 14:02
-
I'm actually still losing all the attribute data. This command doesn't work. Apr 18, 2012 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. Apr 18, 2012 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. Apr 18, 2012 at 6:42
-
Does switching between the KML and libKML driver make any difference? Sep 17, 2014 at 19:16
I wrote a script for myself that does this in python using cursors and lists to split the PopupInfo xml field into useful values
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)
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)
Loop through field names list with arcpy.AddField_management to add all fields (skip if they already exist)
Use .da.UpdateCursor to get PopupInfo's for all rows, then split and create new lists just like with search cursor
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
the XTools Pro ArcMap addin has a free KML importing function which can retain the custom schema in the KML.
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
-