diff --git a/docs/user_guide/plugins/geoman_guide.md b/docs/user_guide/plugins/geoman_guide.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/languagetest.py b/languagetest.py
new file mode 100644
index 0000000000..15e407ef5f
--- /dev/null
+++ b/languagetest.py
@@ -0,0 +1,374 @@
+"""
+Folium Multi-Language Choropleth Solution
+
+This module provides multiple approaches to render folium choropleths
+with different number locales for legends, enabling creation of maps
+in multiple languages without changing system locale.
+
+Requirements:
+- folium
+- pandas
+- geopandas (optional, for geojson data)
+- selenium (for image generation)
+- pillow (for image processing)
+
+Install with: pip install folium pandas selenium pillow
+"""
+
+import folium
+import pandas as pd
+import json
+import re
+from typing import Dict, List, Optional, Union
+import tempfile
+import os
+
+
+class MultiLanguageChoropleth:
+ """
+ A class to create folium choropleths with customizable number formatting
+ for different languages/locales without changing system settings.
+ """
+
+ def __init__(self):
+ self.number_formats = {
+ 'en': {
+ 'decimal_separator': '.',
+ 'thousands_separator': ',',
+ 'currency_symbol': '$',
+ 'position': 'before' # currency position
+ },
+ 'fr': {
+ 'decimal_separator': ',',
+ 'thousands_separator': ' ',
+ 'currency_symbol': '€',
+ 'position': 'after'
+ },
+ 'de': {
+ 'decimal_separator': ',',
+ 'thousands_separator': '.',
+ 'currency_symbol': '€',
+ 'position': 'after'
+ },
+ 'es': {
+ 'decimal_separator': ',',
+ 'thousands_separator': '.',
+ 'currency_symbol': '€',
+ 'position': 'after'
+ }
+ }
+
+ def format_number(self, number: float, locale: str = 'en',
+ decimals: int = 2, include_currency: bool = False) -> str:
+ """
+ Format a number according to specified locale conventions.
+
+ Args:
+ number: The number to format
+ locale: Language locale ('en', 'fr', 'de', 'es')
+ decimals: Number of decimal places
+ include_currency: Whether to include currency symbol
+
+ Returns:
+ Formatted number string
+ """
+ if locale not in self.number_formats:
+ locale = 'en' # fallback to English
+
+ fmt = self.number_formats[locale]
+
+ # Round to specified decimals
+ rounded = round(number, decimals)
+
+ # Split into integer and decimal parts
+ integer_part = int(rounded)
+ decimal_part = rounded - integer_part
+
+ # Format integer part with thousands separator
+ integer_str = f"{integer_part:,}".replace(',', '|TEMP|')
+ integer_str = integer_str.replace('|TEMP|', fmt['thousands_separator'])
+
+ # Format decimal part
+ if decimals > 0 and decimal_part > 0:
+ decimal_str = f"{decimal_part:.{decimals}f}"[2:] # Remove "0."
+ formatted = f"{integer_str}{fmt['decimal_separator']}{decimal_str}"
+ else:
+ formatted = integer_str
+
+ # Add currency if requested
+ if include_currency:
+ if fmt['position'] == 'before':
+ formatted = f"{fmt['currency_symbol']}{formatted}"
+ else:
+ formatted = f"{formatted} {fmt['currency_symbol']}"
+
+ return formatted
+
+ def create_custom_legend_html(self, values: List[float], colors: List[str],
+ locale: str = 'en', title: str = "Legend") -> str:
+ """
+ Create custom HTML legend with locale-specific number formatting.
+
+ Args:
+ values: List of values for legend
+ colors: List of corresponding colors
+ locale: Language locale
+ title: Legend title
+
+ Returns:
+ HTML string for custom legend
+ """
+ legend_html = f'''
+
+
{title}
+ '''
+
+ for i, (value, color) in enumerate(zip(values, colors)):
+ formatted_value = self.format_number(value, locale)
+ legend_html += f'''
+
+
+ {formatted_value}
+
+ '''
+
+ legend_html += '
'
+ return legend_html
+
+ def inject_locale_javascript(self, locale: str = 'en') -> str:
+ """
+ Generate JavaScript to modify number formatting in existing legend.
+
+ Args:
+ locale: Target locale for number formatting
+
+ Returns:
+ JavaScript code string
+ """
+ fmt = self.number_formats[locale]
+
+ js_code = f'''
+
+ '''
+
+ return js_code
+
+ def create_choropleth_with_locale(self, map_obj: folium.Map,
+ geo_data: Union[str, dict],
+ data: pd.DataFrame,
+ columns: List[str],
+ key_on: str,
+ locale: str = 'en',
+ **choropleth_kwargs) -> folium.Map:
+ """
+ Create a choropleth with custom locale formatting.
+
+ Args:
+ map_obj: Folium map object
+ geo_data: GeoJSON data
+ data: DataFrame with data to map
+ columns: Columns for choropleth [key_column, value_column]
+ key_on: Key in GeoJSON to match with data
+ locale: Target locale
+ **choropleth_kwargs: Additional arguments for folium.Choropleth
+
+ Returns:
+ Modified folium map
+ """
+ # Create the choropleth first
+ choropleth = folium.Choropleth(
+ geo_data=geo_data,
+ data=data,
+ columns=columns,
+ key_on=key_on,
+ **choropleth_kwargs
+ ).add_to(map_obj)
+
+ # Add JavaScript to modify number formatting
+ js_code = self.inject_locale_javascript(locale)
+ map_obj.get_root().html.add_child(folium.Element(js_code))
+
+ return map_obj
+
+
+def create_sample_data() -> tuple:
+ """
+ Create sample data for demonstration.
+
+ Returns:
+ Tuple of (sample_data_df, sample_geojson)
+ """
+ # Sample data
+ sample_data = pd.DataFrame({
+ 'country': ['USA', 'Canada', 'Mexico', 'Brazil', 'Argentina'],
+ 'value': [1234567.89, 987654.32, 456789.12, 2345678.90, 876543.21]
+ })
+
+ # Simple sample GeoJSON (normally you'd load this from a file)
+ sample_geojson = {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {"name": "USA"},
+ "geometry": {"type": "Polygon", "coordinates": [[[-100, 40], [-90, 40], [-90, 50], [-100, 50], [-100, 40]]]}
+ },
+ {
+ "type": "Feature",
+ "properties": {"name": "Canada"},
+ "geometry": {"type": "Polygon", "coordinates": [[[-110, 50], [-90, 50], [-90, 60], [-110, 60], [-110, 50]]]}
+ }
+ ]
+ }
+
+ return sample_data, sample_geojson
+
+
+def demo_multilanguage_choropleth():
+ """
+ Demonstrate creating choropleths in multiple languages.
+ """
+ # Initialize the multi-language choropleth handler
+ ml_choropleth = MultiLanguageChoropleth()
+
+ # Create sample data
+ sample_data, sample_geojson = create_sample_data()
+
+ # Create maps for different locales
+ locales = ['en', 'fr', 'de']
+ maps = {}
+
+ for locale in locales:
+ # Create base map
+ m = folium.Map(location=[45, -100], zoom_start=3)
+
+ # Add choropleth with custom locale
+ m = ml_choropleth.create_choropleth_with_locale(
+ map_obj=m,
+ geo_data=sample_geojson,
+ data=sample_data,
+ columns=['country', 'value'],
+ key_on='feature.properties.name',
+ locale=locale,
+ fill_color='YlOrRd',
+ fill_opacity=0.7,
+ line_opacity=0.2,
+ legend_name=f'Sample Values ({locale.upper()})'
+ )
+
+ maps[locale] = m
+
+ # Save map
+ filename = f'choropleth_{locale}.html'
+ m.save(filename)
+ print(f"Saved map in {locale.upper()} locale as {filename}")
+
+ return maps
+
+
+def save_map_as_image(map_obj: folium.Map, filename: str,
+ width: int = 1200, height: int = 800):
+ """
+ Save folium map as image using selenium.
+
+ Args:
+ map_obj: Folium map object
+ filename: Output filename
+ width: Image width
+ height: Image height
+ """
+ try:
+ from selenium import webdriver
+ from selenium.webdriver.chrome.options import Options
+ import time
+
+ # Save map as temporary HTML
+ temp_html = tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False)
+ map_obj.save(temp_html.name)
+
+ # Setup headless browser
+ chrome_options = Options()
+ chrome_options.add_argument('--headless')
+ chrome_options.add_argument(f'--window-size={width},{height}')
+
+ driver = webdriver.Chrome(options=chrome_options)
+ driver.get(f'file://{temp_html.name}')
+
+ # Wait for map to load
+ time.sleep(3)
+
+ # Take screenshot
+ driver.save_screenshot(filename)
+ driver.quit()
+
+ # Clean up
+ os.unlink(temp_html.name)
+
+ print(f"Map saved as image: {filename}")
+
+ except ImportError:
+ print("Selenium not available. Install with: pip install selenium")
+ print("Also need to install ChromeDriver for your system")
+ except Exception as e:
+ print(f"Error saving image: {e}")
+
+
+if __name__ == "__main__":
+ # Run the demonstration
+ print("Creating multi-language choropleths...")
+ maps = demo_multilanguage_choropleth()
+
+ # Optionally save as images (requires selenium)
+ # for locale, map_obj in maps.items():
+ # save_map_as_image(map_obj, f'choropleth_{locale}.png')
+
+ print("\nDemonstration complete!")
+ print("Check the generated HTML files to see the different number formats.")
+
+ # Example of manual number formatting
+ ml = MultiLanguageChoropleth()
+ print("\nExample number formatting:")
+ number = 1234567.89
+ for locale in ['en', 'fr', 'de']:
+ formatted = ml.format_number(number, locale)
+ print(f"{locale.upper()}: {formatted}")
\ No newline at end of file