flac-raster


Nameflac-raster JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryExperimental CLI tool for converting TIFF raster data to FLAC format
upload_time2025-07-20 16:12:18
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords raster flac geospatial compression tiff
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FLAC-Raster: Experimental Raster to FLAC Converter

[![CI/CD](https://github.com/Youssef-Harby/flac-raster/actions/workflows/ci.yml/badge.svg)](https://github.com/Youssef-Harby/flac-raster/actions/workflows/ci.yml)
[![PyPI version](https://badge.fury.io/py/flac-raster.svg)](https://badge.fury.io/py/flac-raster)
[![Python versions](https://img.shields.io/pypi/pyversions/flac-raster.svg)](https://pypi.org/project/flac-raster/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

An experimental CLI tool that converts TIFF raster data files into FLAC audio format while preserving all geospatial metadata, CRS, and bounds information. This proof-of-concept explores using FLAC's lossless compression for geospatial data storage and introduces **revolutionary HTTP range streaming** for efficient geospatial data access - **"Netflix for Geospatial Data"**.

## πŸš€ **NEW: Netflix-Style Streaming for Geospatial Data**

FLAC-Raster now supports **true streaming** exactly like Netflix and Spotify - each tile is a complete, self-contained FLAC file that can be decoded independently! 

### 🎡 **Two Streaming Formats:**

1. **Raw Frames Format** (15MB) - High compression, full file download only
2. **πŸ†• Streaming Format** (185MB) - Netflix-style independent tiles, perfect for HTTP range streaming

### **✨ Streaming Features:**
- **🎬 Netflix-style tiles**: Each tile is a complete, independent FLAC file
- **🌐 HTTP range streaming**: Stream individual tiles via precise byte range requests
- **⚑ Instant access**: Decode any tile without downloading the full file
- **πŸ’° 99%+ bandwidth savings**: Download only what you need (0.8MB vs 185MB)
- **πŸ—ΊοΈ Geographic precision**: Query specific areas with pixel-perfect accuracy
- **πŸ“± Web-native**: Works with any HTTP server, CDN, or browser
- **πŸ”— URL support**: Query remote FLAC files directly via HTTPS URLs
- **🎯 Smart indexing**: Spatial metadata for instant tile discovery

## Features

- **Bidirectional conversion**: TIFF β†’ FLAC and FLAC β†’ TIFF
- **Complete metadata preservation**: CRS, bounds, transform, data type, nodata values
- **πŸ†• Embedded metadata**: All geospatial metadata stored directly in FLAC files (no sidecar files!)
- **πŸ†• Spatial tiling**: Convert rasters to tiled FLAC with bbox metadata per tile
- **πŸ†• HTTP range streaming**: Query and stream data by bounding box with 90%+ bandwidth savings
- **πŸ†• Exceptional compression**: 7-15Γ— file size reduction while maintaining lossless quality
- **Intelligent audio parameters**: Automatically selects sample rate and bit depth based on raster properties
- **Multi-band support**: Seamlessly handles multi-band rasters (RGB, multispectral) as multi-channel audio
- **Lossless compression**: Perfect reconstruction verified - no data loss
- **FLAC chunking**: Uses FLAC's frame-based compression (4096 samples/frame)
- **Comprehensive logging**: Verbose mode with detailed progress tracking
- **Colorful CLI**: Built with Typer and Rich for an intuitive experience

## Installation

### Prerequisites
First, install pixi:
```bash
# Install pixi (cross-platform package manager)
curl -fsSL https://pixi.sh/install.sh | bash
# or via conda: conda install -c conda-forge pixi
```

### Clone and Setup
```bash
git clone https://github.com/Youssef-Harby/flac-raster.git
cd flac-raster
pixi install  # Install all dependencies
```

### Install the CLI tool
```bash
# For regular use:
pixi run pip install .

# For development (editable install):
pixi run pip install -e .
```

### Alternative: Direct pip installation
```bash
pip install rasterio numpy typer rich tqdm pyflac mutagen

# Or install from PyPI (when published):
pip install flac-raster
```

## Usage

### Basic Commands

After installation, you can use the CLI directly:

1. **Convert TIFF to FLAC**:
   ```bash
   flac-raster convert input.tif -o output.flac
   ```

2. **Convert FLAC back to TIFF**:
   ```bash
   flac-raster convert input.flac -o output.tif
   ```

3. **Get file information**:
   ```bash
   flac-raster info file.tif
   flac-raster info file.flac
   ```

4. **Compare two TIFF files**:
   ```bash
   flac-raster compare original.tif reconstructed.tif
   ```

### πŸ†• Spatial Tiling & Netflix-Style Streaming

5. **Create spatial FLAC with tiling**:
   ```bash
   # Raw frames format (high compression, 15MB)
   flac-raster convert input.tif --spatial -o spatial.flac
   
   # πŸ†• Streaming format (Netflix-style tiles, 185MB)
   flac-raster create-streaming input.tif --tile-size=1024 --output=streaming.flac
   
   # Custom tile size (256x256)
   flac-raster convert input.tif --spatial --tile-size 256 -o spatial.flac
   ```

6. **Query spatial FLAC by bounding box**:
   ```bash
   # Query local file (raw frames)
   flac-raster query spatial.flac --bbox "xmin,ymin,xmax,ymax"
   
   # πŸ†• Query streaming FLAC (local or remote)
   python test_streaming.py local_streaming.flac --bbox "34.1,28.6,34.3,28.8"
   
   # πŸ†• Stream from remote URL (Netflix-style!)
   python test_streaming.py "https://example.com/streaming.flac" --tile-id=120
   
   # Example with real coordinates
   flac-raster query spatial.flac --bbox "-105.3,40.3,-105.1,40.5"
   ```

7. **πŸ†• Extract tiles from Netflix-style streaming FLAC**:
   ```bash
   # Extract center tile from remote streaming FLAC
   flac-raster extract-streaming "https://example.com/streaming.flac" --center --output=center.tif
   
   # Extract last tile
   flac-raster extract-streaming "local_streaming.flac" --last --output=last_tile.tif
   
   # Extract by tile ID
   flac-raster extract-streaming "streaming.flac" --tile-id=60 --output=tile_60.tif
   
   # Extract by bounding box
   flac-raster extract-streaming "https://cdn.example.com/data.flac" --bbox="602380,3090240,609780,3097640" --output=bbox_tile.tif
   ```

8. **View spatial index information**:
   ```bash
   flac-raster spatial-info spatial.flac  # Raw frames format only
   # For streaming format, use extract-streaming with analysis
   ```

### 🌐 Live Demo: Real Remote Streaming

Try our live streaming FLAC files hosted on Storj DCS with real Sentinel-2 B04 band data:

#### **πŸ“ Single Tile Extraction (99%+ Bandwidth Savings)**

```bash
# 🎯 Extract center tile (coordinates: 554,880, 3,145,140)
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --center --output=center_1km.tif
# β†’ Downloads: 1.5 MB | Result: 1024Γ—1024 center tile

# πŸ“¦ Extract last tile (southeast corner)  
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --last --output=southeast_corner.tif
# β†’ Downloads: 0.8 MB | Result: 740Γ—740 edge tile

# 🎬 Extract specific tile by ID (northwest corner)
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --tile-id=0 --output=northwest_corner.tif
# β†’ Downloads: 1.5 MB | Result: 1024Γ—1024 first tile
```

#### **πŸ—ΊοΈ Geographic Bounding Box Extraction**

```bash
# πŸ“ Extract specific geographic area (1kmΒ² in center)
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --bbox="554380,3144640,555380,3145640" \
  --output=center_1km_bbox.tif
# β†’ Downloads: 1.5 MB | Result: Exact geographic area

# πŸ“ Extract southeast corner area (last tile region)
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --bbox="602380,3090240,609780,3097640" \
  --output=southeast_bbox.tif  
# β†’ Downloads: 0.8 MB | Result: 740Γ—740 edge region

# πŸ“ Extract northwest area (first tile region)
flac-raster extract-streaming \
  "https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac" \
  --bbox="499980,3189800,510220,3200040" \
  --output=northwest_bbox.tif
# β†’ Downloads: 1.5 MB | Result: 1024Γ—1024 corner region
```

#### **🌍 Full Dataset Access**

```bash
# πŸ“₯ Download full dataset (use raw frames format for efficiency)
flac-raster convert \
  "https://link.storjshare.io/raw/juxc544kagtqgkvhezix6wzia5yq/truemaps-public/flac-raster/B04_spatial.flac" \
  --output=full_sentinel_B04.tif
# β†’ Downloads: 15 MB | Result: Complete 10,980Γ—10,980 Sentinel-2 dataset

# ⚠️ Note: For full datasets, use the raw frames format (15MB) instead of 
#          streaming format (177MB) for better compression efficiency
```

#### **πŸ“Š Performance Comparison**

| **Use Case** | **Command** | **Download Size** | **Output** | **Savings** |
|--------------|-------------|-------------------|------------|-------------|
| **Single tile** | `--center` | 1.5 MB | 1024Γ—1024 | **99.2%** |
| **Corner tile** | `--last` | 0.8 MB | 740Γ—740 | **99.5%** |
| **Bbox query** | `--bbox="..."` | 0.8-1.5 MB | Exact area | **99%+** |
| **Full dataset** | Raw frames format | 15 MB | 10,980Γ—10,980 | **91.5%** |
| **Full streaming** | All 121 tiles | 177 MB | 10,980Γ—10,980 | **0%** ❌ |

**Netflix-Style Benefits:**
- ⚑ **Instant metadata**: 21KB spatial index loaded once
- 🎯 **Precision targeting**: Download only needed geographic areas  
- πŸ—ΊοΈ **Perfect quality**: Pixel-perfect GeoTIFF output with full metadata
- πŸ’° **Massive savings**: 99%+ bandwidth reduction for area-specific queries

**Alternative**: Use `python main.py` if you haven't installed the package:
```bash
python main.py convert input.tif  # Direct script usage
```

### Options

#### Convert command:
- `--output, -o`: Specify output file path (auto-generates if not provided)
- `--compression, -c`: FLAC compression level 0-8 (default: 5)
- `--force, -f`: Overwrite existing output files
- `--verbose, -v`: Enable verbose logging for detailed progress
- `--spatial, -s`: πŸ†• Enable spatial tiling (raw frames format)
- `--tile-size`: πŸ†• Size of spatial tiles in pixels (default: 512x512)

#### πŸ†• Extract-tile command (for raw frames format):
- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax'
- `--output, -o`: Output TIFF file path (required)

#### πŸš€ Extract-streaming command (for Netflix-style streaming format):
- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax'
- `--tile-id`: Extract specific tile by ID number
- `--center`: Extract center tile automatically
- `--last`: Extract last tile
- `--output, -o`: Output TIFF file path (required)

#### Query command:
- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax' (required)
- `--output, -o`: Output file for extracted data
- `--format, -f`: Output format: 'ranges' (default) or 'data'

#### πŸ†• Streaming test commands:
- `--tile-id`: Extract specific tile by ID number
- `--bbox`: Extract tile by geographic bounding box
- `--last`: Extract last tile (default)
- `--savings`: Show bandwidth savings analysis

#### Compare command:
- `--show-bands/--no-bands`: Show per-band statistics (default: True)
- `--export, -e`: Export comparison results to JSON file
- `--help`: Show help message

### Example Workflow

```bash
# Create sample data
python examples/create_test_data.py

# Convert DEM to FLAC
flac-raster convert test_data/sample_dem.tif -v

# Check the FLAC file info
flac-raster info test_data/sample_dem.flac

# Convert back to TIFF
flac-raster convert test_data/sample_dem.flac -o test_data/dem_reconstructed.tif

# Compare original and reconstructed
flac-raster compare test_data/sample_dem.tif test_data/dem_reconstructed.tif

# Export comparison to JSON
flac-raster compare test_data/sample_dem.tif test_data/dem_reconstructed.tif --export comparison.json

# Test with multi-band data
flac-raster convert test_data/sample_rgb.tif
flac-raster convert test_data/sample_rgb.flac -o test_data/rgb_reconstructed.tif
flac-raster compare test_data/sample_rgb.tif test_data/rgb_reconstructed.tif

# Open in QGIS to verify
# The reconstructed files should be viewable in QGIS with all metadata intact
```

## How It Works

### TIFF to FLAC Conversion

1. **Read raster data** and extract all metadata (CRS, bounds, transform, etc.)
2. **Spatial tiling** (if enabled): Divide raster into configurable tile sizes
3. **Calculate audio parameters**:
   - Sample rate: Based on image resolution (44.1kHz to 192kHz)
   - Bit depth: Matches the raster's bit depth (16 or 24-bit, minimum 16-bit due to FLAC decoder limitations)
4. **Normalize data** to audio range (-1 to 1)
5. **Reshape data**: Bands become audio channels, pixels become samples
   - Single-band β†’ Mono audio
   - Multi-band (RGB, multispectral) β†’ Multi-channel audio
6. **Encode to FLAC** with configurable compression
7. **Embed metadata** directly in FLAC using VORBIS_COMMENT blocks
8. **Generate spatial index** with bbox and byte range information for each tile

### FLAC to TIFF Conversion

1. **Decode FLAC** file and extract audio samples
2. **Load metadata** from embedded FLAC metadata (with JSON sidecar fallback)
3. **Reconstruct spatial index** for tiled data
4. **Reshape audio** back to raster dimensions
   - Mono β†’ Single-band raster
   - Multi-channel β†’ Multi-band raster
5. **Denormalize** to original data range
6. **Write GeoTIFF** with all original metadata preserved

## Metadata Preservation

The tool preserves all geospatial metadata **directly embedded in FLAC files**:
- Width and height dimensions
- Number of bands  
- Data type (uint8, int16, float32, etc.)
- Coordinate Reference System (CRS)
- Geospatial transform (affine transformation matrix)
- Bounding box coordinates
- Original data min/max values
- NoData values
- **Spatial index**: Compressed tile bbox and byte range information
- Original driver information

### Embedded Metadata Format

Metadata is stored in FLAC VORBIS_COMMENT blocks:
```
GEOSPATIAL_CRS=EPSG:4326
GEOSPATIAL_WIDTH=1201
GEOSPATIAL_HEIGHT=1201
GEOSPATIAL_SPATIAL_INDEX=<base64(gzip(spatial_index_json))>
...
```

## Lazy Loading & HTTP Range Streaming for Web GIS

### Concept: "Zarr for Geospatial Data using Audio Compression"

The lazy loading feature transforms FLAC-Raster into a **web-native geospatial format** that enables efficient HTTP range request streaming:

```
FLAC URL: https://cdn.example.com/elevation.flac
        ↓
πŸƒβ€β™‚οΈ Lazy Load: Download first 1MB for metadata only
        ↓
Query Spatial Index: Find intersecting tiles for bbox
        ↓
HTTP Range Request: bytes=48152-73513,87850-113211
        ↓  
⬇️ Smart Download: Only 76KB instead of 189KB (60% savings!)
        ↓
Decode FLAC: Get pixels for visible area only
```

### Lazy Loading Workflow

1. **Metadata First**: Download only 1MB to read embedded spatial index
2. **On-Demand Streaming**: Query specific geographic areas
3. **Precise Downloads**: HTTP Range requests for intersecting tiles only
4. **Progressive Loading**: Cache tiles for repeated access

### Use Cases

1. **Interactive Web Maps**
   - Progressive loading as users pan/zoom
   - Only download visible area data  
   - Works with any HTTP server/CDN

2. **Cloud-Native GIS**
   - Stream large rasters without specialized servers
   - Compatible with S3, CloudFront, etc.
   - No need for complex tiling servers

3. **Bandwidth-Constrained Applications** 
   - Mobile mapping apps
   - Satellite/field data collection
   - IoT sensor networks

### Web Server Integration

```javascript
// JavaScript lazy loading client example
async function loadRasterData(bbox) {
    const flacUrl = '/data/elevation.flac';
    
    // 1. Lazy load: get metadata only (first 1MB)
    const metadataResponse = await fetch(flacUrl, {
        headers: { 'Range': 'bytes=0-1048575' }
    });
    const spatialIndex = extractEmbeddedMetadata(metadataResponse);
    
    // 2. Find byte ranges for bbox
    const ranges = calculateRanges(bbox, spatialIndex);
    
    // 3. Stream only needed tiles via HTTP ranges
    const rangeHeader = ranges.map(r => `${r.start}-${r.end}`).join(',');
    const dataResponse = await fetch(flacUrl, {
        headers: { 'Range': `bytes=${rangeHeader}` }
    });
    
    // 4. Decode FLAC data for bbox
    return decodeFLACTiles(dataResponse.body, bbox);
}
```

## Technical Details

### 🎡 **Netflix-Style Streaming Architecture**

FLAC-Raster implements two distinct formats for different use cases:

#### **Raw Frames Format** (Legacy)
- **FLAC frames**: Raw frame chunks within single FLAC file
- **Compression**: Exceptional compression (15MB for 185MB streaming equivalent) 
- **Use case**: Full file downloads, highest compression ratio
- **Limitation**: Cannot stream individual tiles

#### **πŸ†• Streaming Format** (Netflix-Style)
- **Self-contained tiles**: Each tile is a complete, independent FLAC file
- **HTTP range ready**: Perfect byte boundaries for range requests
- **Instant decode**: Any tile can be decoded without full file context
- **Format structure**:
  ```
  [4 bytes index size][JSON spatial index][Complete FLAC Tile 1][Complete FLAC Tile 2]...[Complete FLAC Tile N]
  ```

### **Core Technologies**
- **πŸ†• Complete FLAC segments**: Each tile includes full FLAC headers and metadata
- **πŸ†• HTTP byte ranges**: Precise byte offsets enable partial downloads  
- **πŸ†• Embedded metadata**: All geospatial info stored in FLAC VORBIS_COMMENT blocks
- **πŸ†• Spatial indexing**: JSON metadata with bbox coordinates and byte ranges
- **Multi-band support**: Each raster band becomes an audio channel (up to 8 channels supported by FLAC)
- **Lossless conversion**: Data is normalized but the process is completely reversible
- **Exceptional compression**: Leverages FLAC's compression algorithms (7-15Γ— size reduction)
- **Self-contained files**: No external dependencies or sidecar files required
- **Data type mapping**:
  - uint8 β†’ 16-bit FLAC (due to decoder limitations)
  - int16/uint16 β†’ 16-bit FLAC
  - int32/uint32/float32 β†’ 24-bit FLAC

## Performance Examples

From comprehensive testing against `report.md` analysis:

### Compression Results
- **DEM file** (1201Γ—1201, int16): 2.8 MB β†’ 185 KB FLAC (**15.25Γ— compression**)
- **Multispectral** (200Γ—200Γ—6, uint8): 235 KB β†’ 32 KB FLAC (**7.38Γ— compression**)
- **RGB** (256Γ—256Γ—3, uint8): 193 KB β†’ 27 KB FLAC (**7.26Γ— compression**)

### HTTP Range Streaming Efficiency
- **Small area queries**: Up to **98.8% bandwidth savings** vs full download
- **Geographic precision**: Query exact areas with pixel-perfect accuracy
- **Optimized ranges**: Smart merging of contiguous tiles reduces HTTP requests

All conversions are perfectly lossless (verified with numpy array comparison)

## Limitations

- Maximum 8 bands (FLAC channel limitation)
- Minimum 16-bit encoding (pyflac decoder limitation)
- Large rasters may take time to process
- FLAC format limitations apply (specific bit depths: 16, 24-bit)
- Requires mutagen library for embedded metadata support
- Experimental: Not recommended for production use without thorough testing

## Project Structure

```
flac-raster/
β”œβ”€β”€ src/flac_raster/          # Main package
β”‚   β”œβ”€β”€ __init__.py           # Package initialization
β”‚   β”œβ”€β”€ cli.py                # Command-line interface
β”‚   β”œβ”€β”€ converter.py          # Core conversion logic
β”‚   β”œβ”€β”€ spatial_encoder.py    # πŸ†• Spatial tiling & HTTP range streaming
β”‚   β”œβ”€β”€ metadata_encoder.py   # πŸ†• Embedded metadata handling
β”‚   └── compare.py            # Comparison utilities
β”œβ”€β”€ examples/                 # Example scripts
β”‚   β”œβ”€β”€ create_test_data.py   # Generate test datasets
β”‚   └── spatial_streaming_example.py  # πŸ†• HTTP range streaming demo
β”œβ”€β”€ test_data/               # Test datasets
β”‚   β”œβ”€β”€ dem-raw.tif          # Large DEM for testing
β”‚   β”œβ”€β”€ sample_multispectral.tif  # 6-band multispectral
β”‚   └── sample_rgb.tif       # RGB test data
β”œβ”€β”€ report.md                # πŸ†• Comprehensive analysis & benchmarks
β”œβ”€β”€ main.py                  # Main entry point
β”œβ”€β”€ pyproject.toml           # Project configuration
β”œβ”€β”€ README.md                # This file
└── pixi.toml               # Pixi package configuration
```

## CI/CD & Publishing

This project uses GitHub Actions for:
- **Continuous Integration**: Tests on Python 3.9-3.12 across Windows, macOS, and Linux
- **Automated Building**: Package building and validation
- **PyPI Publishing**: Automatic publishing on release creation
- **Quality Assurance**: Integration testing via CLI commands

### Publishing to PyPI
See [PUBLISHING.md](PUBLISHING.md) for detailed instructions on publishing releases.

## Contributing

1. Fork the repository
2. Create a feature branch: `git checkout -b feature-name`
3. Make your changes and test them
4. Commit your changes: `git commit -am 'Add feature'`
5. Push to the branch: `git push origin feature-name`
6. Create a Pull Request

## Future Improvements

- **Adaptive tiling**: Variable tile sizes based on data complexity
- **Temporal support**: Time-series data with temporal indexing  
- **Band selection**: Spectral subsetting for multispectral data
- **Compression tuning**: Automatic optimization of FLAC parameters
- **Caching strategy**: Intelligent tile caching for frequently accessed areas
- **JavaScript client**: Browser-based FLAC decoder for web mapping
- **Parallel processing**: Multi-threaded encoding/decoding
- **More formats**: Support for HDF5, NetCDF, Zarr integration
- **Performance optimization**: Memory usage and processing speed improvements

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "flac-raster",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "raster, flac, geospatial, compression, tiff",
    "author": null,
    "author_email": "Youssef Harby <me@youssefharby.com>",
    "download_url": "https://files.pythonhosted.org/packages/9d/5e/bc6877635c8651debef65fba9bd0bbb1a7093e2b0b9c2f6eb75014aa07a2/flac_raster-0.1.2.tar.gz",
    "platform": null,
    "description": "# FLAC-Raster: Experimental Raster to FLAC Converter\n\n[![CI/CD](https://github.com/Youssef-Harby/flac-raster/actions/workflows/ci.yml/badge.svg)](https://github.com/Youssef-Harby/flac-raster/actions/workflows/ci.yml)\n[![PyPI version](https://badge.fury.io/py/flac-raster.svg)](https://badge.fury.io/py/flac-raster)\n[![Python versions](https://img.shields.io/pypi/pyversions/flac-raster.svg)](https://pypi.org/project/flac-raster/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nAn experimental CLI tool that converts TIFF raster data files into FLAC audio format while preserving all geospatial metadata, CRS, and bounds information. This proof-of-concept explores using FLAC's lossless compression for geospatial data storage and introduces **revolutionary HTTP range streaming** for efficient geospatial data access - **\"Netflix for Geospatial Data\"**.\n\n## \ud83d\ude80 **NEW: Netflix-Style Streaming for Geospatial Data**\n\nFLAC-Raster now supports **true streaming** exactly like Netflix and Spotify - each tile is a complete, self-contained FLAC file that can be decoded independently! \n\n### \ud83c\udfb5 **Two Streaming Formats:**\n\n1. **Raw Frames Format** (15MB) - High compression, full file download only\n2. **\ud83c\udd95 Streaming Format** (185MB) - Netflix-style independent tiles, perfect for HTTP range streaming\n\n### **\u2728 Streaming Features:**\n- **\ud83c\udfac Netflix-style tiles**: Each tile is a complete, independent FLAC file\n- **\ud83c\udf10 HTTP range streaming**: Stream individual tiles via precise byte range requests\n- **\u26a1 Instant access**: Decode any tile without downloading the full file\n- **\ud83d\udcb0 99%+ bandwidth savings**: Download only what you need (0.8MB vs 185MB)\n- **\ud83d\uddfa\ufe0f Geographic precision**: Query specific areas with pixel-perfect accuracy\n- **\ud83d\udcf1 Web-native**: Works with any HTTP server, CDN, or browser\n- **\ud83d\udd17 URL support**: Query remote FLAC files directly via HTTPS URLs\n- **\ud83c\udfaf Smart indexing**: Spatial metadata for instant tile discovery\n\n## Features\n\n- **Bidirectional conversion**: TIFF \u2192 FLAC and FLAC \u2192 TIFF\n- **Complete metadata preservation**: CRS, bounds, transform, data type, nodata values\n- **\ud83c\udd95 Embedded metadata**: All geospatial metadata stored directly in FLAC files (no sidecar files!)\n- **\ud83c\udd95 Spatial tiling**: Convert rasters to tiled FLAC with bbox metadata per tile\n- **\ud83c\udd95 HTTP range streaming**: Query and stream data by bounding box with 90%+ bandwidth savings\n- **\ud83c\udd95 Exceptional compression**: 7-15\u00d7 file size reduction while maintaining lossless quality\n- **Intelligent audio parameters**: Automatically selects sample rate and bit depth based on raster properties\n- **Multi-band support**: Seamlessly handles multi-band rasters (RGB, multispectral) as multi-channel audio\n- **Lossless compression**: Perfect reconstruction verified - no data loss\n- **FLAC chunking**: Uses FLAC's frame-based compression (4096 samples/frame)\n- **Comprehensive logging**: Verbose mode with detailed progress tracking\n- **Colorful CLI**: Built with Typer and Rich for an intuitive experience\n\n## Installation\n\n### Prerequisites\nFirst, install pixi:\n```bash\n# Install pixi (cross-platform package manager)\ncurl -fsSL https://pixi.sh/install.sh | bash\n# or via conda: conda install -c conda-forge pixi\n```\n\n### Clone and Setup\n```bash\ngit clone https://github.com/Youssef-Harby/flac-raster.git\ncd flac-raster\npixi install  # Install all dependencies\n```\n\n### Install the CLI tool\n```bash\n# For regular use:\npixi run pip install .\n\n# For development (editable install):\npixi run pip install -e .\n```\n\n### Alternative: Direct pip installation\n```bash\npip install rasterio numpy typer rich tqdm pyflac mutagen\n\n# Or install from PyPI (when published):\npip install flac-raster\n```\n\n## Usage\n\n### Basic Commands\n\nAfter installation, you can use the CLI directly:\n\n1. **Convert TIFF to FLAC**:\n   ```bash\n   flac-raster convert input.tif -o output.flac\n   ```\n\n2. **Convert FLAC back to TIFF**:\n   ```bash\n   flac-raster convert input.flac -o output.tif\n   ```\n\n3. **Get file information**:\n   ```bash\n   flac-raster info file.tif\n   flac-raster info file.flac\n   ```\n\n4. **Compare two TIFF files**:\n   ```bash\n   flac-raster compare original.tif reconstructed.tif\n   ```\n\n### \ud83c\udd95 Spatial Tiling & Netflix-Style Streaming\n\n5. **Create spatial FLAC with tiling**:\n   ```bash\n   # Raw frames format (high compression, 15MB)\n   flac-raster convert input.tif --spatial -o spatial.flac\n   \n   # \ud83c\udd95 Streaming format (Netflix-style tiles, 185MB)\n   flac-raster create-streaming input.tif --tile-size=1024 --output=streaming.flac\n   \n   # Custom tile size (256x256)\n   flac-raster convert input.tif --spatial --tile-size 256 -o spatial.flac\n   ```\n\n6. **Query spatial FLAC by bounding box**:\n   ```bash\n   # Query local file (raw frames)\n   flac-raster query spatial.flac --bbox \"xmin,ymin,xmax,ymax\"\n   \n   # \ud83c\udd95 Query streaming FLAC (local or remote)\n   python test_streaming.py local_streaming.flac --bbox \"34.1,28.6,34.3,28.8\"\n   \n   # \ud83c\udd95 Stream from remote URL (Netflix-style!)\n   python test_streaming.py \"https://example.com/streaming.flac\" --tile-id=120\n   \n   # Example with real coordinates\n   flac-raster query spatial.flac --bbox \"-105.3,40.3,-105.1,40.5\"\n   ```\n\n7. **\ud83c\udd95 Extract tiles from Netflix-style streaming FLAC**:\n   ```bash\n   # Extract center tile from remote streaming FLAC\n   flac-raster extract-streaming \"https://example.com/streaming.flac\" --center --output=center.tif\n   \n   # Extract last tile\n   flac-raster extract-streaming \"local_streaming.flac\" --last --output=last_tile.tif\n   \n   # Extract by tile ID\n   flac-raster extract-streaming \"streaming.flac\" --tile-id=60 --output=tile_60.tif\n   \n   # Extract by bounding box\n   flac-raster extract-streaming \"https://cdn.example.com/data.flac\" --bbox=\"602380,3090240,609780,3097640\" --output=bbox_tile.tif\n   ```\n\n8. **View spatial index information**:\n   ```bash\n   flac-raster spatial-info spatial.flac  # Raw frames format only\n   # For streaming format, use extract-streaming with analysis\n   ```\n\n### \ud83c\udf10 Live Demo: Real Remote Streaming\n\nTry our live streaming FLAC files hosted on Storj DCS with real Sentinel-2 B04 band data:\n\n#### **\ud83d\udccd Single Tile Extraction (99%+ Bandwidth Savings)**\n\n```bash\n# \ud83c\udfaf Extract center tile (coordinates: 554,880, 3,145,140)\nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --center --output=center_1km.tif\n# \u2192 Downloads: 1.5 MB | Result: 1024\u00d71024 center tile\n\n# \ud83d\udce6 Extract last tile (southeast corner)  \nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --last --output=southeast_corner.tif\n# \u2192 Downloads: 0.8 MB | Result: 740\u00d7740 edge tile\n\n# \ud83c\udfac Extract specific tile by ID (northwest corner)\nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --tile-id=0 --output=northwest_corner.tif\n# \u2192 Downloads: 1.5 MB | Result: 1024\u00d71024 first tile\n```\n\n#### **\ud83d\uddfa\ufe0f Geographic Bounding Box Extraction**\n\n```bash\n# \ud83d\udccd Extract specific geographic area (1km\u00b2 in center)\nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --bbox=\"554380,3144640,555380,3145640\" \\\n  --output=center_1km_bbox.tif\n# \u2192 Downloads: 1.5 MB | Result: Exact geographic area\n\n# \ud83d\udccd Extract southeast corner area (last tile region)\nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --bbox=\"602380,3090240,609780,3097640\" \\\n  --output=southeast_bbox.tif  \n# \u2192 Downloads: 0.8 MB | Result: 740\u00d7740 edge region\n\n# \ud83d\udccd Extract northwest area (first tile region)\nflac-raster extract-streaming \\\n  \"https://link.storjshare.io/raw/ju6tov7vffpleabbilqgxfpxz5cq/truemaps-public/flac-raster/B04_streaming.flac\" \\\n  --bbox=\"499980,3189800,510220,3200040\" \\\n  --output=northwest_bbox.tif\n# \u2192 Downloads: 1.5 MB | Result: 1024\u00d71024 corner region\n```\n\n#### **\ud83c\udf0d Full Dataset Access**\n\n```bash\n# \ud83d\udce5 Download full dataset (use raw frames format for efficiency)\nflac-raster convert \\\n  \"https://link.storjshare.io/raw/juxc544kagtqgkvhezix6wzia5yq/truemaps-public/flac-raster/B04_spatial.flac\" \\\n  --output=full_sentinel_B04.tif\n# \u2192 Downloads: 15 MB | Result: Complete 10,980\u00d710,980 Sentinel-2 dataset\n\n# \u26a0\ufe0f Note: For full datasets, use the raw frames format (15MB) instead of \n#          streaming format (177MB) for better compression efficiency\n```\n\n#### **\ud83d\udcca Performance Comparison**\n\n| **Use Case** | **Command** | **Download Size** | **Output** | **Savings** |\n|--------------|-------------|-------------------|------------|-------------|\n| **Single tile** | `--center` | 1.5 MB | 1024\u00d71024 | **99.2%** |\n| **Corner tile** | `--last` | 0.8 MB | 740\u00d7740 | **99.5%** |\n| **Bbox query** | `--bbox=\"...\"` | 0.8-1.5 MB | Exact area | **99%+** |\n| **Full dataset** | Raw frames format | 15 MB | 10,980\u00d710,980 | **91.5%** |\n| **Full streaming** | All 121 tiles | 177 MB | 10,980\u00d710,980 | **0%** \u274c |\n\n**Netflix-Style Benefits:**\n- \u26a1 **Instant metadata**: 21KB spatial index loaded once\n- \ud83c\udfaf **Precision targeting**: Download only needed geographic areas  \n- \ud83d\uddfa\ufe0f **Perfect quality**: Pixel-perfect GeoTIFF output with full metadata\n- \ud83d\udcb0 **Massive savings**: 99%+ bandwidth reduction for area-specific queries\n\n**Alternative**: Use `python main.py` if you haven't installed the package:\n```bash\npython main.py convert input.tif  # Direct script usage\n```\n\n### Options\n\n#### Convert command:\n- `--output, -o`: Specify output file path (auto-generates if not provided)\n- `--compression, -c`: FLAC compression level 0-8 (default: 5)\n- `--force, -f`: Overwrite existing output files\n- `--verbose, -v`: Enable verbose logging for detailed progress\n- `--spatial, -s`: \ud83c\udd95 Enable spatial tiling (raw frames format)\n- `--tile-size`: \ud83c\udd95 Size of spatial tiles in pixels (default: 512x512)\n\n#### \ud83c\udd95 Extract-tile command (for raw frames format):\n- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax'\n- `--output, -o`: Output TIFF file path (required)\n\n#### \ud83d\ude80 Extract-streaming command (for Netflix-style streaming format):\n- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax'\n- `--tile-id`: Extract specific tile by ID number\n- `--center`: Extract center tile automatically\n- `--last`: Extract last tile\n- `--output, -o`: Output TIFF file path (required)\n\n#### Query command:\n- `--bbox, -b`: Bounding box as 'xmin,ymin,xmax,ymax' (required)\n- `--output, -o`: Output file for extracted data\n- `--format, -f`: Output format: 'ranges' (default) or 'data'\n\n#### \ud83c\udd95 Streaming test commands:\n- `--tile-id`: Extract specific tile by ID number\n- `--bbox`: Extract tile by geographic bounding box\n- `--last`: Extract last tile (default)\n- `--savings`: Show bandwidth savings analysis\n\n#### Compare command:\n- `--show-bands/--no-bands`: Show per-band statistics (default: True)\n- `--export, -e`: Export comparison results to JSON file\n- `--help`: Show help message\n\n### Example Workflow\n\n```bash\n# Create sample data\npython examples/create_test_data.py\n\n# Convert DEM to FLAC\nflac-raster convert test_data/sample_dem.tif -v\n\n# Check the FLAC file info\nflac-raster info test_data/sample_dem.flac\n\n# Convert back to TIFF\nflac-raster convert test_data/sample_dem.flac -o test_data/dem_reconstructed.tif\n\n# Compare original and reconstructed\nflac-raster compare test_data/sample_dem.tif test_data/dem_reconstructed.tif\n\n# Export comparison to JSON\nflac-raster compare test_data/sample_dem.tif test_data/dem_reconstructed.tif --export comparison.json\n\n# Test with multi-band data\nflac-raster convert test_data/sample_rgb.tif\nflac-raster convert test_data/sample_rgb.flac -o test_data/rgb_reconstructed.tif\nflac-raster compare test_data/sample_rgb.tif test_data/rgb_reconstructed.tif\n\n# Open in QGIS to verify\n# The reconstructed files should be viewable in QGIS with all metadata intact\n```\n\n## How It Works\n\n### TIFF to FLAC Conversion\n\n1. **Read raster data** and extract all metadata (CRS, bounds, transform, etc.)\n2. **Spatial tiling** (if enabled): Divide raster into configurable tile sizes\n3. **Calculate audio parameters**:\n   - Sample rate: Based on image resolution (44.1kHz to 192kHz)\n   - Bit depth: Matches the raster's bit depth (16 or 24-bit, minimum 16-bit due to FLAC decoder limitations)\n4. **Normalize data** to audio range (-1 to 1)\n5. **Reshape data**: Bands become audio channels, pixels become samples\n   - Single-band \u2192 Mono audio\n   - Multi-band (RGB, multispectral) \u2192 Multi-channel audio\n6. **Encode to FLAC** with configurable compression\n7. **Embed metadata** directly in FLAC using VORBIS_COMMENT blocks\n8. **Generate spatial index** with bbox and byte range information for each tile\n\n### FLAC to TIFF Conversion\n\n1. **Decode FLAC** file and extract audio samples\n2. **Load metadata** from embedded FLAC metadata (with JSON sidecar fallback)\n3. **Reconstruct spatial index** for tiled data\n4. **Reshape audio** back to raster dimensions\n   - Mono \u2192 Single-band raster\n   - Multi-channel \u2192 Multi-band raster\n5. **Denormalize** to original data range\n6. **Write GeoTIFF** with all original metadata preserved\n\n## Metadata Preservation\n\nThe tool preserves all geospatial metadata **directly embedded in FLAC files**:\n- Width and height dimensions\n- Number of bands  \n- Data type (uint8, int16, float32, etc.)\n- Coordinate Reference System (CRS)\n- Geospatial transform (affine transformation matrix)\n- Bounding box coordinates\n- Original data min/max values\n- NoData values\n- **Spatial index**: Compressed tile bbox and byte range information\n- Original driver information\n\n### Embedded Metadata Format\n\nMetadata is stored in FLAC VORBIS_COMMENT blocks:\n```\nGEOSPATIAL_CRS=EPSG:4326\nGEOSPATIAL_WIDTH=1201\nGEOSPATIAL_HEIGHT=1201\nGEOSPATIAL_SPATIAL_INDEX=<base64(gzip(spatial_index_json))>\n...\n```\n\n## Lazy Loading & HTTP Range Streaming for Web GIS\n\n### Concept: \"Zarr for Geospatial Data using Audio Compression\"\n\nThe lazy loading feature transforms FLAC-Raster into a **web-native geospatial format** that enables efficient HTTP range request streaming:\n\n```\nFLAC URL: https://cdn.example.com/elevation.flac\n        \u2193\n\ud83c\udfc3\u200d\u2642\ufe0f Lazy Load: Download first 1MB for metadata only\n        \u2193\nQuery Spatial Index: Find intersecting tiles for bbox\n        \u2193\nHTTP Range Request: bytes=48152-73513,87850-113211\n        \u2193  \n\u2b07\ufe0f Smart Download: Only 76KB instead of 189KB (60% savings!)\n        \u2193\nDecode FLAC: Get pixels for visible area only\n```\n\n### Lazy Loading Workflow\n\n1. **Metadata First**: Download only 1MB to read embedded spatial index\n2. **On-Demand Streaming**: Query specific geographic areas\n3. **Precise Downloads**: HTTP Range requests for intersecting tiles only\n4. **Progressive Loading**: Cache tiles for repeated access\n\n### Use Cases\n\n1. **Interactive Web Maps**\n   - Progressive loading as users pan/zoom\n   - Only download visible area data  \n   - Works with any HTTP server/CDN\n\n2. **Cloud-Native GIS**\n   - Stream large rasters without specialized servers\n   - Compatible with S3, CloudFront, etc.\n   - No need for complex tiling servers\n\n3. **Bandwidth-Constrained Applications** \n   - Mobile mapping apps\n   - Satellite/field data collection\n   - IoT sensor networks\n\n### Web Server Integration\n\n```javascript\n// JavaScript lazy loading client example\nasync function loadRasterData(bbox) {\n    const flacUrl = '/data/elevation.flac';\n    \n    // 1. Lazy load: get metadata only (first 1MB)\n    const metadataResponse = await fetch(flacUrl, {\n        headers: { 'Range': 'bytes=0-1048575' }\n    });\n    const spatialIndex = extractEmbeddedMetadata(metadataResponse);\n    \n    // 2. Find byte ranges for bbox\n    const ranges = calculateRanges(bbox, spatialIndex);\n    \n    // 3. Stream only needed tiles via HTTP ranges\n    const rangeHeader = ranges.map(r => `${r.start}-${r.end}`).join(',');\n    const dataResponse = await fetch(flacUrl, {\n        headers: { 'Range': `bytes=${rangeHeader}` }\n    });\n    \n    // 4. Decode FLAC data for bbox\n    return decodeFLACTiles(dataResponse.body, bbox);\n}\n```\n\n## Technical Details\n\n### \ud83c\udfb5 **Netflix-Style Streaming Architecture**\n\nFLAC-Raster implements two distinct formats for different use cases:\n\n#### **Raw Frames Format** (Legacy)\n- **FLAC frames**: Raw frame chunks within single FLAC file\n- **Compression**: Exceptional compression (15MB for 185MB streaming equivalent) \n- **Use case**: Full file downloads, highest compression ratio\n- **Limitation**: Cannot stream individual tiles\n\n#### **\ud83c\udd95 Streaming Format** (Netflix-Style)\n- **Self-contained tiles**: Each tile is a complete, independent FLAC file\n- **HTTP range ready**: Perfect byte boundaries for range requests\n- **Instant decode**: Any tile can be decoded without full file context\n- **Format structure**:\n  ```\n  [4 bytes index size][JSON spatial index][Complete FLAC Tile 1][Complete FLAC Tile 2]...[Complete FLAC Tile N]\n  ```\n\n### **Core Technologies**\n- **\ud83c\udd95 Complete FLAC segments**: Each tile includes full FLAC headers and metadata\n- **\ud83c\udd95 HTTP byte ranges**: Precise byte offsets enable partial downloads  \n- **\ud83c\udd95 Embedded metadata**: All geospatial info stored in FLAC VORBIS_COMMENT blocks\n- **\ud83c\udd95 Spatial indexing**: JSON metadata with bbox coordinates and byte ranges\n- **Multi-band support**: Each raster band becomes an audio channel (up to 8 channels supported by FLAC)\n- **Lossless conversion**: Data is normalized but the process is completely reversible\n- **Exceptional compression**: Leverages FLAC's compression algorithms (7-15\u00d7 size reduction)\n- **Self-contained files**: No external dependencies or sidecar files required\n- **Data type mapping**:\n  - uint8 \u2192 16-bit FLAC (due to decoder limitations)\n  - int16/uint16 \u2192 16-bit FLAC\n  - int32/uint32/float32 \u2192 24-bit FLAC\n\n## Performance Examples\n\nFrom comprehensive testing against `report.md` analysis:\n\n### Compression Results\n- **DEM file** (1201\u00d71201, int16): 2.8 MB \u2192 185 KB FLAC (**15.25\u00d7 compression**)\n- **Multispectral** (200\u00d7200\u00d76, uint8): 235 KB \u2192 32 KB FLAC (**7.38\u00d7 compression**)\n- **RGB** (256\u00d7256\u00d73, uint8): 193 KB \u2192 27 KB FLAC (**7.26\u00d7 compression**)\n\n### HTTP Range Streaming Efficiency\n- **Small area queries**: Up to **98.8% bandwidth savings** vs full download\n- **Geographic precision**: Query exact areas with pixel-perfect accuracy\n- **Optimized ranges**: Smart merging of contiguous tiles reduces HTTP requests\n\nAll conversions are perfectly lossless (verified with numpy array comparison)\n\n## Limitations\n\n- Maximum 8 bands (FLAC channel limitation)\n- Minimum 16-bit encoding (pyflac decoder limitation)\n- Large rasters may take time to process\n- FLAC format limitations apply (specific bit depths: 16, 24-bit)\n- Requires mutagen library for embedded metadata support\n- Experimental: Not recommended for production use without thorough testing\n\n## Project Structure\n\n```\nflac-raster/\n\u251c\u2500\u2500 src/flac_raster/          # Main package\n\u2502   \u251c\u2500\u2500 __init__.py           # Package initialization\n\u2502   \u251c\u2500\u2500 cli.py                # Command-line interface\n\u2502   \u251c\u2500\u2500 converter.py          # Core conversion logic\n\u2502   \u251c\u2500\u2500 spatial_encoder.py    # \ud83c\udd95 Spatial tiling & HTTP range streaming\n\u2502   \u251c\u2500\u2500 metadata_encoder.py   # \ud83c\udd95 Embedded metadata handling\n\u2502   \u2514\u2500\u2500 compare.py            # Comparison utilities\n\u251c\u2500\u2500 examples/                 # Example scripts\n\u2502   \u251c\u2500\u2500 create_test_data.py   # Generate test datasets\n\u2502   \u2514\u2500\u2500 spatial_streaming_example.py  # \ud83c\udd95 HTTP range streaming demo\n\u251c\u2500\u2500 test_data/               # Test datasets\n\u2502   \u251c\u2500\u2500 dem-raw.tif          # Large DEM for testing\n\u2502   \u251c\u2500\u2500 sample_multispectral.tif  # 6-band multispectral\n\u2502   \u2514\u2500\u2500 sample_rgb.tif       # RGB test data\n\u251c\u2500\u2500 report.md                # \ud83c\udd95 Comprehensive analysis & benchmarks\n\u251c\u2500\u2500 main.py                  # Main entry point\n\u251c\u2500\u2500 pyproject.toml           # Project configuration\n\u251c\u2500\u2500 README.md                # This file\n\u2514\u2500\u2500 pixi.toml               # Pixi package configuration\n```\n\n## CI/CD & Publishing\n\nThis project uses GitHub Actions for:\n- **Continuous Integration**: Tests on Python 3.9-3.12 across Windows, macOS, and Linux\n- **Automated Building**: Package building and validation\n- **PyPI Publishing**: Automatic publishing on release creation\n- **Quality Assurance**: Integration testing via CLI commands\n\n### Publishing to PyPI\nSee [PUBLISHING.md](PUBLISHING.md) for detailed instructions on publishing releases.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature-name`\n3. Make your changes and test them\n4. Commit your changes: `git commit -am 'Add feature'`\n5. Push to the branch: `git push origin feature-name`\n6. Create a Pull Request\n\n## Future Improvements\n\n- **Adaptive tiling**: Variable tile sizes based on data complexity\n- **Temporal support**: Time-series data with temporal indexing  \n- **Band selection**: Spectral subsetting for multispectral data\n- **Compression tuning**: Automatic optimization of FLAC parameters\n- **Caching strategy**: Intelligent tile caching for frequently accessed areas\n- **JavaScript client**: Browser-based FLAC decoder for web mapping\n- **Parallel processing**: Multi-threaded encoding/decoding\n- **More formats**: Support for HDF5, NetCDF, Zarr integration\n- **Performance optimization**: Memory usage and processing speed improvements\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Experimental CLI tool for converting TIFF raster data to FLAC format",
    "version": "0.1.2",
    "project_urls": {
        "Homepage": "https://github.com/Youssef-Harby/flac-raster",
        "Issues": "https://github.com/Youssef-Harby/flac-raster/issues",
        "Repository": "https://github.com/Youssef-Harby/flac-raster"
    },
    "split_keywords": [
        "raster",
        " flac",
        " geospatial",
        " compression",
        " tiff"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ac61c08b36fc562ab085823a0355924861fa7b7f79d29568be47e1617c4469b6",
                "md5": "1a567229327b7849eb33b7c424f6e453",
                "sha256": "0889b51812f01c1137add230b73c5323fd77c1452c89206756cb3ae746345ca4"
            },
            "downloads": -1,
            "filename": "flac_raster-0.1.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1a567229327b7849eb33b7c424f6e453",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 35774,
            "upload_time": "2025-07-20T16:12:17",
            "upload_time_iso_8601": "2025-07-20T16:12:17.052088Z",
            "url": "https://files.pythonhosted.org/packages/ac/61/c08b36fc562ab085823a0355924861fa7b7f79d29568be47e1617c4469b6/flac_raster-0.1.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9d5ebc6877635c8651debef65fba9bd0bbb1a7093e2b0b9c2f6eb75014aa07a2",
                "md5": "db4006b459a93a67c25744d5112d3e9a",
                "sha256": "7a2efeaddb2e0f0a884a6bf19922f65e55d87e639c788d2cc02ad956cf7d7c75"
            },
            "downloads": -1,
            "filename": "flac_raster-0.1.2.tar.gz",
            "has_sig": false,
            "md5_digest": "db4006b459a93a67c25744d5112d3e9a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 45222,
            "upload_time": "2025-07-20T16:12:18",
            "upload_time_iso_8601": "2025-07-20T16:12:18.500868Z",
            "url": "https://files.pythonhosted.org/packages/9d/5e/bc6877635c8651debef65fba9bd0bbb1a7093e2b0b9c2f6eb75014aa07a2/flac_raster-0.1.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-20 16:12:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Youssef-Harby",
    "github_project": "flac-raster",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "flac-raster"
}
        
Elapsed time: 0.57244s