Sunday, March 26, 2023

Convert Sentinel-2 Tile KML to CSV

 Lets convert this KML file to CSV or other GIS friendly file.

In this case we just needed the tile number and the multipolygon objects, hence we will have tow columns in the CSV file or table.

The open() function can be used to read the kml file, then the required objects read line by line.

kml_file = r"S2A_OPER_GIP_TILPAR_MPC__20151209T095117_V20150622T000000_21000101T000000_B00_2.kml"
kml_txt_file = open(kml_file)

cnt = 0
tile_number_list = []
tile_wgs_polygon_list = []

for line in kml_txt_file:
    # print(line)
    if 'MULTIPOLYGON' in line:
        tile_number = line.split('<font COLOR="#008000">')[1].split('</font>')[0]
        tile_wgs_polygon = line.split('<font COLOR="#008000">')[-1].split('</font>')[0]

        tile_number_list.append(tile_number)
        tile_wgs_polygon_list.append(tile_wgs_polygon)
        cnt += 1
    # break
    
print(f'{cnt} records found...')
kml_txt_file.close()

To convert to geo dataframe, the script is like so;-

sentinel_df = pd.DataFrame([tile_number_list, tile_wgs_polygon_list]).T
sentinel_df.rename(columns = {0:'TileNumber', 1:'geometry'}, inplace = True)

# Use shapely well known text (wkt) format to create geometry column...
from shapely.wkt import loads
sentinel_df['geometry'] = sentinel_df['geometry'].apply(lambda x: loads(x))

sentinel_gdf = gpd.GeoDataFrame(sentinel_df, crs='epsg:4326')


To convert to csv file;

sentinel_gdf.to_csv('folder/SEn-2.csv')


To convert to shapefile;

sentinel_gdf.to_file('folder/SEn-2.shp')


If you visualize the converted file, the sentinel-2 tiles the covers Nigeria are seen below:-


31NDE, 31NDF, 31NDG, 31NDH, 31NDJ, 31NEE, 31NEF, 31NEG, 31NEH, 31NEJ, 31NFE, 31NFF, 31NFG, 31NFH, 31NFJ, 31NGE, 31NGF, 31NGG, 31NGH, 31NGJ, 31NHE, 31NHF, 31NHG, 31NHH, 31NHJ, 31PDK, 31PDL, 31PDM, 31PDN, 31PDP, 31PDQ, 31PDR, 31PEK, 31PEL, 31PEM, 31PEN, 31PEP, 31PEQ, 31PER, 31PFK, 31PFL, 31PFM, 31PFN, 31PFP, 31PFQ, 31PFR, 31PGK, 31PGL, 31PGM, 31PGN, 31PGP, 31PGQ, 31PGR, 31PHK, 31PHL, 31PHM, 31PHN, 31PHP, 31PHQ, 31PHR, 32NKK, 32NKL, 32NKM, 32NKN, 32NKP, 32NLK, 32NLL, 32NLM, 32NLN, 32NLP, 32NMK, 32NML, 32NMM, 32NMN, 32NMP, 32NNK, 32NNL, 32NNM, 32NNN, 32NNP, 32NPK, 32NPL, 32NPM, 32NPN, 32NPP, 32NQK, 32NQL, 32NQM, 32NQN, 32NQP, 32NRK, 32NRL, 32NRM, 32NRN, 32NRP, 32PKA, 32PKQ, 32PKR, 32PKS, 32PKT, 32PKU, 32PKV, 32PLA, 32PLQ, 32PLR, 32PLS, 32PLT, 32PLU, 32PLV, 32PMA, 32PMQ, 32PMR, 32PMS, 32PMT, 32PMU, 32PMV, 32PNA, 32PNQ, 32PNR, 32PNS, 32PNT, 32PNU, 32PNV, 32PPA, 32PPQ, 32PPR, 32PPS, 32PPT, 32PPU, 32PPV, 32PQA, 32PQQ, 32PQR, 32PQS, 32PQT, 32PQU, 32PQV, 32PRA, 32PRQ, 32PRR, 32PRS, 32PRT, 32PRU, 32PRV, 33NTE, 33NTF, 33NTG, 33NTH, 33NTJ, 33NUE, 33NUF, 33NUG, 33NUH, 33NUJ, 33NVE, 33NVF, 33NVG, 33NVH, 33NVJ, 33PTK, 33PTL, 33PTM, 33PTN, 33PTP, 33PTQ, 33PTR, 33PUK, 33PUL, 33PUM, 33PUN, 33PUP, 33PUQ, 33PUR, 33PVK, 33PVL, 33PVM, 33PVN, 33PVP, 33PVQ, 33PVR,


That is it!

Monday, March 20, 2023

How to find Sentinel-2 satellite image for your study area using GoogleEarthEngine

Unlike the Landsat satellite, Sentinel-2 satellite doesn't use Path/Row naming convention to define its scenes instead it uses granules or tiles of 110km x 110km ortho-images in UTM/WGS84 projection.

The tiles are numbered from 1 to 60 followed by three letters, so an example of a valid Sentinel-2 tile number are: 01CCV, 01CDH, 01CDJ, etc.

Now the problem is how do you know the number that covers your study area! Well there are several ways of solving this, one is by visualizing the granules or tiles KML file in you favorite tool.

If you work solely in Google Earth Engine, then I would be a bad idea to load that KML file due to its size. So, an approach to use is to load/import image collection and filter based on region of interest or other criteria and print the 'id' using the id() function as demonstrated in the code snippet below:-

var dataset = ee.ImageCollection('COPERNICUS/S2')
  .filterDate('2022-01-01', '2022-12-31')
  .first();
  

print(dataset.id())

This will print the ID on the console as seen below:-


According to the documentation, 'the first numeric part represents the sensing date and time, the second numeric part represents the product generation date and time, and the final 6-character string is a unique granule identifier indicating its UTM grid reference'.

If you want to get more specific, you could a .filterBounds(...) function to your region of interest. Here I added filterBounds to a location in Abuja, Nigeria.


Note that the image collection will return 'Null' if there is no image available for your filter criteria.

That is it!