A powerful, React-based map viewer and editor built with MapLibre GL. This application provides an intuitive interface for creating, managing, and visualizing geospatial data with support for modern cloud-optimized formats.
- Interactive Map Editor: Create and edit maps with an intuitive drag-and-drop interface
- Layer Management: Organize map layers in a hierarchical folder structure
- Real-time Preview: See changes instantly as you build your maps
- Configuration-driven: Define entire map configurations using JSON files
- PMTiles: Native support for cloud-optimized vector tiles
- Cloud Optimized GeoTIFF (COG): Efficient raster data handling
- TiTiler Integration: Advanced raster processing and styling
- Vector Data: Full MapLibre GL vector layer support
- Multiple Themes: Built-in theme support with customizable styling
- Layer Styling: Visual styling controls for vector and raster layers
- Color Management: Advanced color picker and colormap support
- Legend Generation: Automatic legend creation for all layer types
- Multi-language Support: Built-in internationalization (i18n)
- Responsive Design: Works seamlessly on desktop and mobile devices
- Basemap Selection: Choose from various basemap providers
- Geocoding: Built-in location search functionality
- Markdown Support: Rich text descriptions using MDX
- Docker Support: Easy deployment with included Docker configuration
- Modern Stack: Built with React 19, TypeScript, and Vite
- Node.js 18+
- pnpm (recommended) or npm
- Modern web browser with WebGL support
- Frontend: React 19, TypeScript, Vite
- Mapping: MapLibre GL, React Map GL
- Styling: Tailwind CSS, DaisyUI
- State Management: Zustand
- Routing: TanStack Router
- Forms: React JSON Schema Form, TanStack Form
- UI Components: Headless UI, FontAwesome
- Data Fetching: TanStack Query, Axios
Install pnpm (recommended for faster installs):
npm install -g pnpm-
Clone the repository
git clone <repository-url> cd nina-maps
-
Install dependencies
pnpm install
-
Start development server
pnpm run dev
-
Open your browser Follow the terminal instructions to open the application (typically
http://localhost:5173)
- Build for production:
pnpm run build - Preview production build:
pnpm run preview - Format code:
pnpm run format - Lint code:
pnpm run lint
The Map Editor uses JSON configuration files to define map structure, layers, and settings.
Place your configuration files in the public/maps/ directory. Each map should have its own folder with a config.json file.
public/
βββ maps/
β βββ example/
β β βββ config.json
β βββ your-map/
β βββ config.json
βββ editor/
βββ config.json (default editor config)
{
"id": "my-map",
"title": "My Map Title",
"subtitle": "Map description",
"baseMap": "positron",
"viewState": {
"longitude": 10,
"latitude": 63,
"zoom": 4
},
"items": {
"root": {
"name": "Layers",
"type": "folder",
"children": ["layer1"]
},
"layer1": {
"name": "My Layer",
"type": "layer",
"description": "Layer description in **Markdown**",
"layer": {
"type": "vector",
"pmtiles": {
"url": "https://example.com/data.pmtiles"
}
}
}
},
"config": {
"theme": "nina",
"language": "en",
"titiler_api_url": "/titiler"
}
}{
"type": "vector",
"pmtiles": {
"url": "https://example.com/vector-data.pmtiles"
},
"children": {
"source-layer": "layer-name",
"type": "fill",
"legend": {
"field": "property_name",
"values": [
{
"value": "category1",
"color": "#ff0000",
"opacity": 0.8,
"description": "Category 1"
}
]
}
}
}{
"type": "raster",
"titiler": {
"url": "https://example.com/raster-data.tif",
"rescale": ["0,100"],
"colormap_name": "viridis"
},
"legend": {
"type": "linear",
"colormap_name": "viridis"
}
}- id: Unique map identifier
- title/subtitle: Display names for the map
- baseMap: Base map style (
positron,dark-matter, etc.) - viewState: Initial map view (longitude, latitude, zoom)
- items: Layer hierarchy and definitions
- config: Global settings (theme, language, API URLs)
The application includes Docker support for easy deployment:
# Build the Docker image
docker build -t map-editor .
# Run with Docker Compose
docker-compose up -dThe Docker setup includes nginx configuration for production deployment.
src/
βββ components/ # Reusable UI components
βββ hooks/ # Custom React hooks
βββ libs/ # Utility libraries
βββ pages/ # Page components
βββ routes/ # TanStack Router routes
βββ rjsf/ # JSON Schema Form components
βββ types.ts # TypeScript definitions
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and ensure they follow the existing code style
- Run tests and linting:
pnpm run lint - Commit your changes:
git commit -m "feat: add my feature" - Push to your fork:
git push origin feature/my-feature - Create a Pull Request
- Use TypeScript for all new code
- Follow the existing ESLint configuration
- Use Prettier for code formatting:
pnpm run format - Write meaningful commit messages
- TiTiler Dependency: Raster rendering requires a TiTiler instance. Deploy your own or use a public instance.
- CORS Configuration: Ensure your data URLs are accessible from your domain.
- File Formats: Only Cloud Optimized formats (PMTiles, COG) are supported for optimal performance.
For issues and questions:
- Create an issue on GitHub
- Check the existing documentation
- Review the example configurations in
public/maps/