def dataframe_to_geojson_points(df, lat_col='lat', lon_col='lon', idx_col=None, properties_fn=None):
    """
    Creates a GeoJSon structure with a point for each row of the DataFrame.

    :param df:
    :param lat_col: latitude column (y)
    :param lon_col: longitude column (x)
    :return: GeoJSON list of points.
    """
    geojson = {
        'type': 'FeatureCollection',
        'features': []
    }

    for idx, row in df.iterrows():
        feature = {
            'type': 'Feature',
            'geometry': {
                'type': 'Point',
                'coordinates': [row[lon_col], row[lat_col]]
            },
            'properties': {
                'id': idx if idx_col is None else row[idx_col]
            },
            'id': idx if idx_col is None else row[idx_col]
        }

        if callable(properties_fn):
            feature['properties'].update(properties_fn(idx, row))

        geojson['features'].append(feature)

    return geojson