import folium import json import random import folium import json import os import random def generate_distinct_colors(n): """Generate n distinct bright colors for each district""" # Predefined palette of 38 distinct, vibrant colors colors = [ '#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E2', '#F8B739', '#52B788', '#E63946', '#06FFA5', '#FFD93D', '#6BCF7F', '#C77DFF', '#FF9F1C', '#2EC4B6', '#E71D36', '#FF499E', '#00B4D8', '#90E0EF', '#F72585', '#7209B7', '#3A0CA3', '#F4A261', '#2A9D8F', '#E76F51', '#264653', '#E9C46A', '#F77F00', '#D62828', '#023047', '#8338EC', '#3DDC84', '#FF006E', '#FFBE0B', '#FB5607', '#8AC926' ] # Shuffle to ensure adjacent regions get different colors random.shuffle(colors) return colors[:n] def create_map(): """Create a Folium map with distinct colors for each kabupaten/kota in Jawa Timur. Returns: str: HTML string for embedding the Folium map (safe to render). """ # Load GeoJSON data - using complete kabupaten/kota file geojson_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'geojson', 'jatim_kabkota.geojson') with open(geojson_path, encoding='utf-8') as f: geojson_data = json.load(f) # Create a Folium map centered on Jawa Timur m = folium.Map( location=[-7.5, 112.5], zoom_start=8, tiles='CartoDB positron', prefer_canvas=True, zoom_control=True, attributionControl=False ) # Generate distinct colors for each kabupaten/kota (38 total) num_features = len(geojson_data.get('features', [])) colors = generate_distinct_colors(num_features) # Create color mapping with city names color_map = {} city_list = [] for idx, feature in enumerate(geojson_data.get('features', [])): feature_name = feature.get('properties', {}).get('name', f'Feature_{idx}') feature_type = feature.get('properties', {}).get('type', 'Kabupaten') color_map[feature_name] = colors[idx] city_list.append({ 'name': feature_name, 'type': feature_type, 'color': colors[idx] }) # Style function - 3D effect with vibrant colors like the reference image def style_function(feature): feature_name = feature['properties'].get('name', 'Unknown') return { 'fillColor': color_map.get(feature_name, '#CCCCCC'), 'color': '#333333', # Dark gray border for 3D effect 'weight': 2, # Medium border 'fillOpacity': 1.0, # Completely solid for vibrant colors 'opacity': 1, # Solid border 'dashArray': None, # Solid line 'lineJoin': 'miter', # Sharp corners for clear boundaries 'lineCap': 'butt' # Clean edges } # Highlight function for hover def highlight_function(feature): return { 'fillColor': '#FFFF00', # Yellow on hover 'color': '#FF0000', # Red border 'weight': 3, 'fillOpacity': 0.9, } # Add GeoJSON layer with colored regions folium.GeoJson( geojson_data, name='Jawa Timur', style_function=style_function, highlight_function=highlight_function, tooltip=folium.GeoJsonTooltip( fields=['name'], aliases=['Wilayah:'], localize=True, sticky=False, labels=True, style=""" background-color: white; border: 2px solid black; border-radius: 5px; font-family: Arial, sans-serif; font-size: 12px; padding: 8px; box-shadow: 3px 3px 5px rgba(0,0,0,0.5); """, ) ).add_to(m) # Add text labels on each kabupaten/kota for feature in geojson_data.get('features', []): props = feature.get('properties', {}) name = props.get('name', 'Unknown') center_lat = props.get('centroid_lat') center_lon = props.get('centroid_lon') if center_lat and center_lon: # Add label marker with white text and shadow for contrast folium.Marker( location=[center_lat, center_lon], icon=folium.DivIcon(html=f'''