mirror of
https://github.com/0015/map_tiles.git
synced 2026-01-17 09:06:59 +01:00
Initial commit of ESP component
This commit is contained in:
279
README.md
Executable file
279
README.md
Executable file
@@ -0,0 +1,279 @@
|
||||
# Map Tiles Component for LVGL 9.x
|
||||
|
||||
A comprehensive map tiles component for ESP-IDF projects using LVGL 9.x. This component provides functionality to load and display map tiles with GPS coordinate conversion, designed for embedded applications requiring offline map display capabilities.
|
||||
|
||||
## Features
|
||||
|
||||
- **LVGL 9.x Compatible**: Fully compatible with LVGL 9.x image handling
|
||||
- **GPS Coordinate Conversion**: Convert GPS coordinates to tile coordinates and vice versa
|
||||
- **Dynamic Tile Loading**: Load map tiles on demand from file system
|
||||
- **Configurable Grid Size**: Support for different grid sizes (3x3, 5x5, 7x7, etc.)
|
||||
- **Multiple Tile Types**: Support for up to 8 different tile types (street, satellite, terrain, hybrid, etc.)
|
||||
- **Memory Efficient**: Configurable memory allocation (SPIRAM or regular RAM)
|
||||
- **Multiple Zoom Levels**: Support for different map zoom levels
|
||||
- **Error Handling**: Comprehensive error handling and logging
|
||||
- **C API**: Clean C API for easy integration
|
||||
|
||||
## Requirements
|
||||
|
||||
- ESP-IDF 5.0 or later
|
||||
- LVGL 9.x
|
||||
- File system support (FAT/SPIFFS/LittleFS)
|
||||
- Map tiles in binary format (RGB565, 256x256 pixels)
|
||||
|
||||
## Installation
|
||||
|
||||
### Using ESP-IDF Component Manager
|
||||
|
||||
Add to your project's `main/idf_component.yml`:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
map_tiles:
|
||||
git: "https://github.com/0015/map_tiles_component.git"
|
||||
version: "^1.1.0"
|
||||
```
|
||||
|
||||
### Manual Installation
|
||||
|
||||
1. Copy the `map_tiles` folder to your project's `components` directory
|
||||
2. The component will be automatically included in your build
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```c
|
||||
#include "map_tiles.h"
|
||||
|
||||
// Configure the map tiles with multiple tile types and custom grid size
|
||||
const char* tile_folders[] = {"street_map", "satellite", "terrain", "hybrid"};
|
||||
map_tiles_config_t config = {
|
||||
.base_path = "/sdcard", // Base path to tile storage
|
||||
.tile_folders = {tile_folders[0], tile_folders[1], tile_folders[2], tile_folders[3]},
|
||||
.tile_type_count = 4, // Number of tile types
|
||||
.default_zoom = 10, // Default zoom level
|
||||
.use_spiram = true, // Use SPIRAM if available
|
||||
.default_tile_type = 0, // Start with street map (index 0)
|
||||
.grid_cols = 5, // Grid width (tiles)
|
||||
.grid_rows = 5 // Grid height (tiles)
|
||||
};
|
||||
|
||||
// Initialize map tiles
|
||||
map_tiles_handle_t map_handle = map_tiles_init(&config);
|
||||
if (!map_handle) {
|
||||
ESP_LOGE(TAG, "Failed to initialize map tiles");
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
### Loading Tiles
|
||||
|
||||
```c
|
||||
// Set center position from GPS coordinates
|
||||
map_tiles_set_center_from_gps(map_handle, 37.7749, -122.4194); // San Francisco
|
||||
|
||||
// Get grid dimensions
|
||||
int grid_cols, grid_rows;
|
||||
map_tiles_get_grid_size(map_handle, &grid_cols, &grid_rows);
|
||||
int tile_count = map_tiles_get_tile_count(map_handle);
|
||||
|
||||
// Load tiles for the configured grid size
|
||||
for (int row = 0; row < grid_rows; row++) {
|
||||
for (int col = 0; col < grid_cols; col++) {
|
||||
int index = row * grid_cols + col;
|
||||
int tile_x, tile_y;
|
||||
map_tiles_get_position(map_handle, &tile_x, &tile_y);
|
||||
|
||||
bool loaded = map_tiles_load_tile(map_handle, index,
|
||||
tile_x + col, tile_y + row);
|
||||
if (!loaded) {
|
||||
ESP_LOGW(TAG, "Failed to load tile %d", index);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Displaying Tiles with LVGL
|
||||
|
||||
```c
|
||||
// Get grid dimensions and tile count
|
||||
int grid_cols, grid_rows;
|
||||
map_tiles_get_grid_size(map_handle, &grid_cols, &grid_rows);
|
||||
int tile_count = map_tiles_get_tile_count(map_handle);
|
||||
|
||||
// Create image widgets for each tile
|
||||
lv_obj_t** tile_images = malloc(tile_count * sizeof(lv_obj_t*));
|
||||
|
||||
for (int i = 0; i < tile_count; i++) {
|
||||
tile_images[i] = lv_image_create(parent_container);
|
||||
|
||||
// Get the tile image descriptor
|
||||
lv_image_dsc_t* img_dsc = map_tiles_get_image(map_handle, i);
|
||||
if (img_dsc) {
|
||||
lv_image_set_src(tile_images[i], img_dsc);
|
||||
|
||||
// Position the tile in the grid
|
||||
int row = i / grid_cols;
|
||||
int col = i % grid_cols;
|
||||
lv_obj_set_pos(tile_images[i],
|
||||
col * MAP_TILES_TILE_SIZE,
|
||||
row * MAP_TILES_TILE_SIZE);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Switching Tile Types
|
||||
|
||||
```c
|
||||
// Switch to different tile types
|
||||
map_tiles_set_tile_type(map_handle, 0); // Street map
|
||||
map_tiles_set_tile_type(map_handle, 1); // Satellite
|
||||
map_tiles_set_tile_type(map_handle, 2); // Terrain
|
||||
map_tiles_set_tile_type(map_handle, 3); // Hybrid
|
||||
|
||||
// Get current tile type
|
||||
int current_type = map_tiles_get_tile_type(map_handle);
|
||||
|
||||
// Get available tile types
|
||||
int type_count = map_tiles_get_tile_type_count(map_handle);
|
||||
for (int i = 0; i < type_count; i++) {
|
||||
const char* folder = map_tiles_get_tile_type_folder(map_handle, i);
|
||||
printf("Tile type %d: %s\n", i, folder);
|
||||
}
|
||||
```
|
||||
|
||||
### GPS Coordinate Conversion
|
||||
|
||||
```c
|
||||
// Convert GPS to tile coordinates
|
||||
double tile_x, tile_y;
|
||||
map_tiles_gps_to_tile_xy(map_handle, 37.7749, -122.4194, &tile_x, &tile_y);
|
||||
|
||||
// Check if GPS position is within current tile grid
|
||||
bool within_tiles = map_tiles_is_gps_within_tiles(map_handle, 37.7749, -122.4194);
|
||||
|
||||
// Get marker offset for precise positioning
|
||||
int offset_x, offset_y;
|
||||
map_tiles_get_marker_offset(map_handle, &offset_x, &offset_y);
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
```c
|
||||
// Clean up when done
|
||||
map_tiles_cleanup(map_handle);
|
||||
```
|
||||
|
||||
## Tile File Format
|
||||
|
||||
The component expects map tiles in a specific binary format:
|
||||
|
||||
- **File Structure**: `{base_path}/{map_tile}/{zoom}/{tile_x}/{tile_y}.bin`
|
||||
- **Format**: 12-byte header + raw RGB565 pixel data
|
||||
- **Size**: 256x256 pixels
|
||||
- **Color Format**: RGB565 (16-bit per pixel)
|
||||
|
||||
### Example Tile Structure
|
||||
```
|
||||
/sdcard/
|
||||
├── street_map/ // Tile type 0
|
||||
│ ├── 10/
|
||||
│ │ ├── 164/
|
||||
│ │ │ ├── 395.bin
|
||||
│ │ │ ├── 396.bin
|
||||
│ │ │ └── ...
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── satellite/ // Tile type 1
|
||||
│ ├── 10/
|
||||
│ │ ├── 164/
|
||||
│ │ │ ├── 395.bin
|
||||
│ │ │ └── ...
|
||||
│ │ └── ...
|
||||
│ └── ...
|
||||
├── terrain/ // Tile type 2
|
||||
│ └── ...
|
||||
└── hybrid/ // Tile type 3
|
||||
└── ...
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
| Parameter | Type | Description | Default |
|
||||
|-----------|------|-------------|---------|
|
||||
| `base_path` | `const char*` | Base directory for tile storage | Required |
|
||||
| `tile_folders` | `const char*[]` | Array of folder names for different tile types | Required |
|
||||
| `tile_type_count` | `int` | Number of tile types (max 8) | Required |
|
||||
| `default_zoom` | `int` | Initial zoom level | Required |
|
||||
| `use_spiram` | `bool` | Use SPIRAM for tile buffers | `false` |
|
||||
| `default_tile_type` | `int` | Initial tile type index | Required |
|
||||
| `grid_cols` | `int` | Number of tile columns (max 10) | 5 |
|
||||
| `grid_rows` | `int` | Number of tile rows (max 10) | 5 |
|
||||
|
||||
## API Reference
|
||||
|
||||
### Initialization
|
||||
- `map_tiles_init()` - Initialize map tiles system
|
||||
- `map_tiles_cleanup()` - Clean up resources
|
||||
|
||||
### Tile Management
|
||||
- `map_tiles_load_tile()` - Load a specific tile
|
||||
- `map_tiles_get_image()` - Get LVGL image descriptor
|
||||
- `map_tiles_get_buffer()` - Get raw tile buffer
|
||||
|
||||
### Grid Management
|
||||
- `map_tiles_get_grid_size()` - Get current grid dimensions
|
||||
- `map_tiles_get_tile_count()` - Get total number of tiles in grid
|
||||
|
||||
### Coordinate Conversion
|
||||
- `map_tiles_gps_to_tile_xy()` - Convert GPS to tile coordinates
|
||||
- `map_tiles_set_center_from_gps()` - Set center from GPS
|
||||
- `map_tiles_is_gps_within_tiles()` - Check if GPS is within current tiles
|
||||
|
||||
### Position Management
|
||||
- `map_tiles_get_position()` - Get current tile position
|
||||
- `map_tiles_set_position()` - Set tile position
|
||||
- `map_tiles_get_marker_offset()` - Get marker offset
|
||||
- `map_tiles_set_marker_offset()` - Set marker offset
|
||||
|
||||
### Tile Type Management
|
||||
- `map_tiles_set_tile_type()` - Set active tile type
|
||||
- `map_tiles_get_tile_type()` - Get current tile type
|
||||
- `map_tiles_get_tile_type_count()` - Get number of available types
|
||||
- `map_tiles_get_tile_type_folder()` - Get folder name for a type
|
||||
|
||||
### Zoom Control
|
||||
- `map_tiles_set_zoom()` - Set zoom level
|
||||
- `map_tiles_get_zoom()` - Get current zoom level
|
||||
|
||||
### Error Handling
|
||||
- `map_tiles_set_loading_error()` - Set error state
|
||||
- `map_tiles_has_loading_error()` - Check error state
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Memory Usage**: Each tile uses ~128KB (256×256×2 bytes)
|
||||
- **Grid Size**: Larger grids use more memory (3x3=9 tiles, 5x5=25 tiles, 7x7=49 tiles)
|
||||
- **SPIRAM**: Recommended for ESP32-S3 with PSRAM for better performance
|
||||
- **File System**: Ensure adequate file system performance for tile loading
|
||||
- **Tile Caching**: Component maintains tile buffers until cleanup
|
||||
|
||||
## Example Projects
|
||||
|
||||
See the `examples` directory for complete implementation examples:
|
||||
- Basic map display
|
||||
- GPS tracking with map updates
|
||||
- Interactive map with touch controls
|
||||
|
||||
## License
|
||||
|
||||
This component is released under the MIT License. See LICENSE file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
|
||||
|
||||
## Support
|
||||
|
||||
For questions and support, please open an issue on the GitHub repository.
|
||||
Reference in New Issue
Block a user