I have this working code, data2kml()
function works ok, but data2geojson()
is incomplete. How can I add the elevation, name and the description in the GeoJSON? I can't understand how FeatureCollection
works.
Obs: I can't use GeoPandas because of some dependency conflicts.
import json
import geojson
import simplekml
import pandas as pd
def data2kml(df):
kml = simplekml.Kml()
df.apply(lambda X: kml.newpoint(
name=X["name"],
description=unicode(X["description"].decode('utf8')),
coords=[( X["long"], X["lat"], X["elev"])]
)
, axis=1)
kml.save(path='map.kml')
def data2geojson(df):
points = []
df.apply(lambda X: points.append( (float(X["long"]),
float(X["lat"]))
)
, axis=1)
with open('map.geojson', 'w') as fp:
geojson.dump(geojson.MultiPoint(points), fp, sort_keys=True)
col = ['lat','long','elev','name','description']
data = [[-29.9953,-70.5867,760,'A','Place a'],
[-30.1217,-70.4933,1250,'B','Place b'],
[-30.0953,-70.5008,1185,'C','Place c']]
df = pd.DataFrame(data, columns=col)
data2kml(df)
data2geojson(df)
4 Answers 4
Using what i learned from the answer of @gene this solution avoids the use of iterrows because iterrows have performance issues.
Valid for Python 3.X
import pandas as pd
import geojson
def data2geojson(df):
features = []
insert_features = lambda X: features.append(
geojson.Feature(geometry=geojson.Point((X["long"],
X["lat"],
X["elev"])),
properties=dict(name=X["name"],
description=X["description"])))
df.apply(insert_features, axis=1)
with open('map1.geojson', 'w', encoding='utf8') as fp:
geojson.dump(geojson.FeatureCollection(features), fp, sort_keys=True, ensure_ascii=False)
col = ['lat','long','elev','name','description']
data = [[-29.9953,-70.5867,760,'A','Place ñ'],
[-30.1217,-70.4933,1250,'B','Place b'],
[-30.0953,-70.5008,1185,'C','Place c']]
df = pd.DataFrame(data, columns=col)
data2geojson(df)
Valid for Python 2.X
import pandas as pd
import geojson
def data2geojson(df):
features = []
df.apply(lambda X: features.append(
geojson.Feature(geometry=geojson.Point((X["long"],
X["lat"],
X["elev"])),
properties=dict(name=X["name"],
description=unicode(X["description"].decode('utf8'))))
)
, axis=1)
with open('map.geojson', 'w') as fp:
geojson.dump(geojson.FeatureCollection(features), fp, sort_keys=True)
col = ['lat','long','elev','name','description']
data = [[-29.9953,-70.5867,760,'A','Place a'],
[-30.1217,-70.4933,1250,'B','Place b'],
[-30.0953,-70.5008,1185,'C','Place c']]
df = pd.DataFrame(data, columns=col)
data2geojson(df)
Geoff Boeing provides a solution in Exporting Python Data to GeoJSON and Convert a pandas dataframe to geojson for web-mapping (Jupyter notebook) for 2D coordinates and you can adapt his script for 3D coordinates
def df_to_geojson(df, properties, lat='lat', lon='long', z='elev'):
geojson = {'type':'FeatureCollection', 'features':[]}
for _, row in df.iterrows():
feature = {'type':'Feature',
'properties':{},
'geometry':{'type':'Point','coordinates':[]}}
feature['geometry']['coordinates'] = [row[lon],row[lat],row[z]]
for prop in properties:
feature['properties'][prop] = row[prop]
geojson['features'].append(feature)
return geojson
cols = ['name', 'description']
df_to_geojson(df, cols)
{'type': 'FeatureCollection', 'features': [{'geometry': {'type': 'Point', 'coordinates': [-70.5867, -29.9953, 760]}, 'type': 'Feature', 'properties': {'name': 'A', 'description': 'Place a'}}, {'geometry': {'type': 'Point', 'coordinates': [-70.4933, -30.1217, 1250]}, 'type': 'Feature', 'properties': {'name': 'B', 'description': 'Place b'}}, {'geometry': {'type': 'Point', 'coordinates': [-70.5008, -30.0953, 1185]}, 'type': 'Feature', 'properties': {'name': 'C', 'description': 'Place c'}}]}
To explain the process with single features
for i, row in df.iterrows():
print i,
feature = {'type':'Feature','properties':{},'geometry':{'type':'Point','coordinates':[]}}
feature['geometry']['coordinates'] = [row.long,row.lat,row.elev]
for prop in cols:
feature['properties'][prop] = row[prop]
print feature
0 {'geometry': {'type': 'Point', 'coordinates': [-70.5867, -29.9953, 760]}, 'type': 'Feature', 'properties': {'name': 'A', 'description': 'Place a'}}
1 {'geometry': {'type': 'Point', 'coordinates': [-70.4933, -30.1217, 1250]}, 'type': 'Feature', 'properties': {'name': 'B', 'description': 'Place b'}}
2 {'geometry': {'type': 'Point', 'coordinates': [-70.5008, -30.0953, 1185]}, 'type': 'Feature', 'properties': {'name': 'C', 'description': 'Place c'}}
For Python 3.6 users, this works for me:
where df = yourdataframe, properties are the usefull_columns, lat='latitude', lng='longitude'
The usefull_columns come from the original dataframe
I've added some testing points
# create the function
def df_to_geojson(df, properties, lat='latitude', lng='longitude'):
"""
Turn a dataframe containing point data into a geojson formatted python dictionary
df : the dataframe to convert to geojson
properties : a list of columns in the dataframe to turn into geojson feature properties
lat : the name of the column in the dataframe that contains latitude data
lng : the name of the column in the dataframe that contains longitude data
"""
# create a new python dict to contain our geojson data, using geojson format
geojson = {'type':'FeatureCollection', 'features':[]}
# loop through each row in the dataframe and convert each row to geojson format
# x is the equivalent of the row, df.iterrows converts the dataframe in to a pd.series object
# the x is a counter and has no influence
for x, row in df.iterrows():
feature = {'type':'Feature',
'properties':{},
'geometry':{'type':'Point',
'coordinates':[]}}
# fill in the coordinates
feature['geometry']['coordinates'] = [float(row.lng),float(row.lat)]
# be aware that the dataframe is a pd.series
#print('rowitem converts to ndarray(numpy) :\n ', row)
# convert the array to a pandas.serie
geo_props = pd.Series(row)
# for each column, get the value and add it as a new feature property
# prop determines the list from the properties
for prop in properties:
#loop over the items to convert to string elements
#convert to string
if type(geo_props[prop]) == float:
#print('ok')
geo_props[prop] = str(int(geo_props[prop]))
# now create a json format, here we have to make the dict properties
feature['properties'][prop] = geo_props[prop]
# add this feature (aka, converted dataframe row) to the list of features inside our dict
geojson['features'].append(feature)
return geojson
-
1Please remember to indent your code so it is formatted correctly. The
{}
button does this for you.Vince– Vince2018年01月01日 14:05:12 +00:00Commented Jan 1, 2018 at 14:05
I have used this code:
def return_geojson(df, latlng):
d = dict(type="FeatureCollection",features=[])
for ind,row in df.fillna('').iterrows():
p = row.drop(latlng).to_dict()
g = dict(type="Point",coordinates=list(row[latlng])[::-1])
f = dict(type="Feature", properties=p, geometry=g)
d['features'].append(f)
return d
with open('map.geojson','w') as f:
json.dump(return_geojson(df,['lat','lon']),f)
Explore related questions
See similar questions with these tags.