Python GeoJSON – How to Convert Text File Into GeoJSON Using Python

convertgeojsonpandaspythontext;

I'm trying to take in a txt-file and convert it into data for a GeoJSON dataset with these values.

I used this piece of code from this article:
Pandas to GeoJSON (Multiples points + features) with Python

import geojson
import pandas as pd

def data2geojson(df):
    features = []
    insert_features = lambda X: features.append(
            geojson.Feature(geometry=geojson.LineString((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,indent=4)

col = ['lat','long','elev','name','description']
data = [[-29.9953,-70.5867,760,'A','Place MNO'],
        [-30.1217,-70.4933,1250,'C','Place PQR'],
        [-30.0953,-70.5008,1185,'C','Place STU']]

df = pd.DataFrame(data, columns=col)

data2geojson(df)

However for data, I have points that are in the same line (hence why I am using LineString instead of Point) and they have unique "ID"s to be placed in the 'properties' section of the GeoJSON.

This is an example of the data in my txt-file

lat=1.3218368 ,long=103.9364834 ,A, Place BC
lat=1.3218821 ,long=103.9364744 ,A, Place BC
lat=1.3219285 ,long=103.9367017 ,A, Place BC
lat=1.321643 ,long=103.9364707 ,A, Place BC
lat=1.3216271 ,long=103.9363887 ,A, Place BC
lat=1.3235089 ,long=103.9344606 ,A, Place BC
lat=1.3237205 ,long=103.9355026 ,A, Place BC
lat=1.3217046 ,long=103.934106 ,A, Place BC
lat=1.3203204 ,long=103.9366324 ,B, Place AC
lat=1.3206557 ,long=103.9373536 ,B, Place AC
lat=1.3206271 ,long=103.9374192 ,B, Place AC
lat=1.3205511 ,long=103.9371742 ,B, Place AC
lat=1.3206044 ,long=103.9375056 ,B, Place AC
lat=1.3207561 ,long=103.9371863 ,B, Place AC
lat=1.3204307 ,long=103.9368537 ,B, Place AC
lat=1.3204877 ,long=103.9368389 ,B, Place AC
lat=1.3205465 ,long=103.9368269 ,B, Place AC
lat=1.320612 ,long=103.9368246 ,B, Place AC
lat=1.3207378 ,long=103.9371016 ,B, Place AC
lat=1.3207702 ,long=103.9370846 ,B, Place AC  

How should I go about with taking in this txt as the input for the function's data array and grouping them according to the name e.g. A or B, regardless of description as LineString have more than 1 point attached to each object.

Best Answer

I think using geopandas is a more convenient way to create GeoJSON. Once you convert your txt to coordinates, you need to do some preliminary work. This is the process of handling str in pandas.

import pandas as pd
import geopandas as gpd
from shapely.geometry import Point

#handling txt
#remove 'lat=' and 'long=' then type change from object to float to make point.
df = pd.read_csv('path_your_txt', header=None, names = ['lat','long', 'name','description'])

df['lat'] = df['lat'].str.replace('lat=', '')
df['long'] = df['long'].str.replace('long=', '')

df['lat'] = df['lat'].astype(float)
df['long'] = df['long'].astype(float)

#make point geometry
df['geometry'] = df.apply(lambda row: Point(row['long'], row['lat']), axis=1) #long is X, lat is Y

#change df to gdf
gdf = gpd.GeoDataFrame(df, geometry = 'geometry', crs='EPSG:4326')  #epsg4326 is WGS84

Having created a gdf, you have now created a spatial data containing points and attribute data.

Now you only need one command to create GeoJSON.

gdf.to_file('path_and_filename.geojson', driver='GeoJSON')

As for grouping, what you need to do depends on the purpose of the grouping. If you just want to count, use groupby.

gdf.groupby('name').size()

If what you want is to create a line, you need a slightly different approach.

from shapely.geometry import LineString
gdf_line = gdf.groupby(['name', 'description'])['geometry'].apply(lambda x: LineString(x.tolist()))