Skip to content

WIP: Add support for raster loader#87

Open
soniacq wants to merge 18 commits intomainfrom
feat/raster_loader
Open

WIP: Add support for raster loader#87
soniacq wants to merge 18 commits intomainfrom
feat/raster_loader

Conversation

@soniacq
Copy link
Copy Markdown
Contributor

@soniacq soniacq commented Dec 10, 2025


📚 Documentation preview 📚: https://UrbanMapper--87.org.readthedocs.build/en/87/

JUDITH-sketch and others added 18 commits July 21, 2025 18:08
- Implement RasterLoader to load raster files with rasterio
- Support loading GeoTIFF, PNG, JP2 and other formats
- Modified to add example usage of raster loader
- Raster loader returning 3D array
- Implement RasterLoader with block-wise downsampling and polygon geometry
- Convert raster pixels into aggregated blocks with spatial geometry
- Output GeoDataFrame with pixel_id, coordinates, value, area
Copy link
Copy Markdown
Contributor

@fabiofelix fabiofelix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is good to go after addressing the comments.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should be merged with the main UM documentation, e.g., docs/api/loaders.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, no. This current README is outdated in the current state of this PR. RasterLoader is having a docstring so loaders.md just need:

## ::: urban_mapper.modules.loader.RasterLoader
    options:
        heading: "RasterLoader"
        members:
            - _load
            - preview
            # and whatever else

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you check all the related descriptions? RasterLoader._load always returns a GeoDataframe.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change could be discarded.

@simonprovost simonprovost self-requested a review December 11, 2025 20:02
Copy link
Copy Markdown
Member

@simonprovost simonprovost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Sonia for this PR! I have made comments because IMHO the state of the implementation is not bullet-proof enough yet. Furthermore:

  1. The two examples appear to have non-cleared cells as showing identical content, yet Git notifies changes. Please let's discard the visualiser as @fabiofelix suggested, but not the loader example. Let's add the loader of a small raster, please, for the sake of the interactive examples on the doc.
  2. That same small raster file can therefore be used to have unit test for this new loader please.
  3. It would also be nice to concentrate all commits of @JUDITH-sketch into one (such as feat: raster basics or whatever else), as there seem to be a lot of exploratory-based commits > 10.

I stay alert to any questions! Cheers.

ValueError: If an unsupported format is requested.
"""
pass
pass
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No needed

from urban_mapper.modules.loader.abc_loader import LoaderBase
from urban_mapper.modules.loader.loaders.csv_loader import CSVLoader
from urban_mapper.modules.loader.loaders.parquet_loader import ParquetLoader
from urban_mapper.modules.loader.loaders.raster_loader import RasterLoader # Importing RasterLoader of the new raster loader module
Copy link
Copy Markdown
Member

@simonprovost simonprovost Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline comment to remove

—— Same for the others please

is determined by the file extension. Supported formats include `CSV`, `shapefile`,
and `Parquet`.

and `Parquet`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if that is a pre-commit-based modif. if not, to revert

def with_options(self, **options,) -> "LoaderFactory":
"""
Set additional key-value options to configure loader behavior.
This method allows you to specify arbitrary configuration options, such as block size, resolution, or other loader parameters. These options will be forwarded to the loader upon instantiation.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docstring is not clear. I would suggest something along the lines of:

Set additional key-value options to configure loader behavior.
 
If a loader supports or requires parameter propagation during instantiation, use `with_options(<parameter_of_interest>=<value_of_your_like>)`.

For example, if the loader of interest is `Raste Loader`, you can use `block_size`,`resolution`, and so on. Users are directed to each loader's docstring for more information on such permissible options.

See more in `Examples` below.
```

@require_attributes(["source_type", "source_data"])
def load(self) -> gpd.GeoDataFrame:
"""Load the data and return it as a `GeoDataFrame`.
"""Load the data and return it as a `GeoDataFrame` or raster object.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we update the docstring we have got to update the return type of the function, above.

Comment on lines +152 to +153
# Latitude/longitude per transformation from CRS to WGS84
transformer = Transformer.from_crs(crs, 4326, always_xy=True)
Copy link
Copy Markdown
Member

@simonprovost simonprovost Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am not an expert in Raster but just double checking: should we not parametrise this CRS 4326?

Comment on lines +167 to +178
gdf = gpd.GeoDataFrame({
'pixel_id': np.arange(len(values)),
'row': rows.flatten(),
'col': cols.flatten(),
'area': areas,
'value': values,
'latitude': lat,
'longitude': lon,
'geometry': geoms
}, crs=crs)

return gdf
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create the GDF while returning it instead of variable-instantiate it prior.

Comment on lines +181 to +182
raise RuntimeError(f"Error while loading downsampled raster: {e}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raise RuntimeError(f"Error while loading downsampled raster: {e}") from e

ValueError: If the requested format is not supported.

"""
# If metadata is not loaded, try to load it
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove all inline polluting comments please

Comment on lines +207 to +213
shape = (
self.meta.get("count", "?"),
self.meta.get("height", "?"),
self.meta.get("width", "?")
)
dtype = self.meta.get("dtype", "?")
crs = self.meta.get("crs", "?")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's changed all ? into more readable null-information like N/A please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants