Skip to content

Make tile format configurable (PNG vs JPG) #6

@luandro

Description

@luandro

Problem

The tile format is currently hardcoded to PNG in multiple places:

Locations:

  1. Line 113: "format": "png" in style.json
  2. Line 124: "tiles": ["smp://maps.v1/s/0/{z}/{x}/{y}.png"] in style.json
  3. Line 247-248: img.save(tile_path, "PNG") when saving tiles

Meanwhile, the bash reference implementation uses JPG format, which:

  • Has smaller file sizes (important for offline maps)
  • Is more appropriate for photographic/raster content
  • Is the format used in the field reference implementation

Current Behavior

All tiles are saved as PNG regardless of content type or user preference.

Proposed Solution

Add a tile format parameter to the algorithm:

1. Add Parameter to Algorithm

# In comapeo_smp_algorithm.py
TILE_FORMAT = 'TILE_FORMAT'

def initAlgorithm(self, config):
    # ... existing parameters ...
    
    # Add tile format parameter
    self.addParameter(
        QgsProcessingParameterEnum(
            self.TILE_FORMAT,
            self.tr('Tile format'),
            options=['PNG', 'JPEG'],
            defaultValue=1,  # JPEG as default
            optional=False
        )
    )

2. Pass Format to Generator

def processAlgorithm(self, parameters, context, feedback):
    # ... existing code ...
    
    tile_format_idx = self.parameterAsEnum(parameters, self.TILE_FORMAT, context)
    tile_format = 'jpg' if tile_format_idx == 1 else 'png'
    
    # Generate the SMP file
    generator = SMPGenerator(feedback)
    output_path = generator.generate_smp_from_canvas(
        rect, min_zoom, max_zoom, output_file, tile_format
    )

3. Update Generator to Use Format

# In comapeo_smp_generator.py
def generate_smp_from_canvas(self, extent, min_zoom, max_zoom, output_path, tile_format='jpg'):
    self.tile_format = tile_format
    # ... rest of method ...

def _create_style_from_canvas(self, extent, min_zoom, max_zoom):
    # ... existing code ...
    
    file_ext = 'jpg' if self.tile_format == 'jpg' else 'png'
    
    style = {
        "version": 8,
        "name": "QGIS MAP",
        "sources": {
            source_id: {
                "format": self.tile_format,  # Use variable
                # ...
                "tiles": [
                    f"smp://maps.v1/s/0/{{z}}/{{x}}/{{y}}.{file_ext}"  # Use variable
                ]
            }
        },
        # ...
    }

def _generate_tiles_from_canvas(self, extent, min_zoom, max_zoom, tiles_dir):
    # ... existing code ...
    
    # Save tile with appropriate format
    file_ext = 'jpg' if self.tile_format == 'jpg' else 'png'
    tile_path = os.path.join(x_dir, f"{y}.{file_ext}")
    
    if self.tile_format == 'jpg':
        img.save(tile_path, "JPEG", quality=85)
    else:
        img.save(tile_path, "PNG")

Benefits

  • User Choice: Let users choose based on their needs
  • Smaller Files: JPG typically 5-10x smaller for raster content
  • Compatibility: Match bash script default behavior
  • Flexibility: PNG still available for content needing transparency

Format Comparison

Format File Size Quality Transparency Best For
PNG Larger Lossless Yes Vector maps, sharp lines
JPEG Smaller Lossy No Satellite imagery, photos

Impact

Low - This is a quality-of-life improvement:

  • PNG works fine but creates larger files
  • JPG would be better default for most use cases
  • Making it configurable satisfies both needs

References

  • generate_smp_from_xyz.sh: Lines 68, 77 - Uses JPG format
  • XYZ_SMP.md: Section on tile format customization

Related Files

  • comapeo_smp_algorithm.py: Add parameter
  • comapeo_smp_generator.py: Lines 113, 124, 247-248

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions