Python | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSON

LXX

Reading time:

3 minutes

Quick read takes only 1 minute

Introduction:

When we download the original data from ICESat-2 (such as ATL03, ATL08 products), we often encounter issues with large data volumes and complex formats. Most of the time, we convert, crop, and clean the data before saving it in CSV format for further analysis. However, in actual workflows, we often need to convert CSV files into spatial vector formats (such as Shapefile, GeoJSON, GPKG) for easier visualization and spatial analysis. In previous articles, we shared methods for batch converting CSV to SHP, but direct conversion of ICESat-2 CSV data requires modifications. Therefore, this article shares a method to convert ICESat-2 point cloud data from CSV to SHP/GeoJSON using Python.

Python | Implementing batch conversion of CSV files to SHP

I hope everyone can give a follow and a little like, this will bethe motivation for updates, greatly appreciated❥(^_-)

1

Data

The original data for this article is the CSV format data of ICESat-2 point cloud data. How to obtain CSV data has been introduced in previous articles, for details, you can click the following links to view:

ICESAT-2 Data Information Extraction (Taking ATL08 as an example)

ICESat-2 Data Download

ICESat-2 | ATL03 and ATL08 Data Association Software (Complete Code)

This article will briefly restate:

1. Using PhoREAL software

Python | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSON

2. Using code extraction, the key is to find the path of the extracted information, such as:

def read_atl08(fileName, outdir='date'):    """    Read ICESat-2 ATL08 file (HDF5 format), extract key variables    :param fileName: ATL08 file path    :param outdir: output directory    """    # Six laser beam groups    groups = [        "/gt1l", "/gt1r",        "/gt2l", "/gt2r",        "/gt3l", "/gt3r"    ]    # Fields to read (variable name, HDF5 path, optional index)    fields = [        ("lat", "/land_segments/latitude", None),        ("lon", "/land_segments/longitude", None),        # Terrain related        ("h_te_best_fit", "/land_segments/terrain/h_te_best_fit", None),        ("h_te_best_fit_20m", "/land_segments/terrain/h_te_best_fit_20m", None),        ("dem_h", "/land_segments/dem_h", None),        # Canopy height        ("h_canopy", "/land_segments/canopy/h_canopy", None),        ("h_max_canopy", "/land_segments/canopy/h_max_canopy", None),        ("canopy_h_metrics", "/land_segments/canopy/canopy_h_metrics",            [3, 8, 10, 12, 13, 14, 15, 16, 17]),        ("centroid_height", "/land_segments/canopy/centroid_height", None),        ("h_dif_canopy", "/land_segments/canopy/h_dif_canopy", None),        ("h_mean_canopy", "/land_segments/canopy/h_mean_canopy", None),        ("h_median_canopy", "/land_segments/canopy/h_median_canopy", None),        ("h_min_canopy", "/land_segments/canopy/h_min_canopy", None),        ("h_canopy_uncertainty", "/land_segments/canopy/h_canopy_uncertainty", None),        # Classification and flags        ("segment_landcover", "/land_segments/segment_landcover", None),        ("night_flag", "/land_segments/night_flag", None),        ("cloud_flag_atm", "/land_segments/cloud_flag_atm", None),        ("canopy_rh_conf", "/land_segments/canopy/canopy_rh_conf", None),        # Others        ("h_te_uncertainty", "/land_segments/terrain/h_te_uncertainty", None),        ("terrain_slope", "/land_segments/terrain/terrain_slope", None),        ("time_coverage_start", "/land_segments/time_coverage_start", None),        ("snr", "/land_segments/snr", None),    ]    # TODO: Add HDF5 file reading logic here (using h5py)

3. Further associating ATL03 with ATL08

ICESat-2 | ATL03 and ATL08 Data Association Software (Complete Code)

Python | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSON

2

Method of this Article

Import necessary libraries such as pandas, osgeo.gdal, shapely, and geopandas.Read the CSV file using pandas’ read_csv function to load the data.Convert the geometric data (such as latitude and longitude) in the CSV file into a format suitable for Shapefile files. This usually involves converting string-type geometric data (such as WKT format) into geometry type.Use the GeoDataFrame class from geopandas to create a geographic data frame, setting the geometry column and coordinate reference system (CRS).Finally, use the to_file method to save the data as a Shapefile, specifying the output file path and coordinate reference system (such as EPSG:4326).Final implementation:

📂 Supports single file and batch file (folder) input;

✅ Automatically identifies latitude and longitude columns and allows users to freely select attribute columns;🖱️ Provides a user-friendly GUI interface, allowing users to select attributes via checkboxes;⏳ Built-in progress bar and runtime statistics for batch processing tasks;💾 Supports multiple output formats: SHP, GeoJSON, GPKG;🛠️ Based on Python + GeoPandas + Tkinter, cross-platform operation.

3

Key Code (see end of article for free access)

def _convert_worker(self, lat, lon, attrs):    """    Batch convert CSV files to GeoDataFrame    :param lat: Latitude column name    :param lon: Longitude column name    :param attrs: Attributes to retain    """    for i, fpath in enumerate(self.files, 1):        try:            # Read CSV            df = pd.read_csv(fpath)            # Convert latitude and longitude to numeric, remove invalid values            df[lat] = pd.to_numeric(df[lat], errors="coerce")            df[lon] = pd.to_numeric(df[lon], errors="coerce")            df = df.dropna(subset=[lat, lon])            # Create point features            geometry = [Point(xy) for xy in zip(df[lon], df[lat])]            # Build GeoDataFrame            gdf = gpd.GeoDataFrame(df[attrs], geometry=geometry, crs="EPSG:4326")            # Save to dictionary, key is filename (without extension)            name = os.path.splitext(os.path.basename(fpath))[0]            self.converted[name] = gdf            self.log(f"Completed: {os.path.basename(fpath)} ({len(gdf)} points)")        except Exception as e:            # Error log            self.log(f"Failed: {fpath} -> {e}")        # Update progress bar        self.progress["value"] = i    # Time statistics    dt = time.time() - self.start_time    self.lbl_time.config(text=f"Time taken: {dt:.1f}s")    # If data is successfully generated, enable save button    if self.converted:        self.btn_save.config(state="normal")

【Final Effect】

Python | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSONPython | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSONPython | Converting ICESat-2 Point Cloud Data from CSV to SHP/GeoJSON

Get the tool for free, just send ‘ICESat-2 shp’ in the backend!

If you found this helpful, please give a follow and a little like, this will be the motivation for updates, thank you!

Leave a Comment