How to change the color of a shapefile layer in Django Admin's Leaflet map based on a field's value?

I'm working on a GeoDjango project where I'm displaying a shapefile layer in a Leaflet map embedded in the Django Admin interface. I need to dynamically color the geometry (geom field) in the map based on the value of another field in the model called mean_ctrl. Django Admin with Geom Field

Here’s the color scheme I want to implement:

def get_color(mean_ctrl):
    if mean_ctrl < 60:
        return "#38A800"
    elif 60.1 <= mean_ctrl <= 120:
        return "#55FF00"
    elif 120.1 <= mean_ctrl <= 170:
        return "#FFFF00"
    elif 170.1 <= mean_ctrl <= 220:
        return "#FFAA00"
    elif 220.1 <= mean_ctrl <= 270:
        return "#FF0000"
    else:
        return "#C500FF"

I am looking for guidance on how to apply this color scheme to the Geom field on the Leaflet map in Django admin. Any guidance would be very helpful! Thank you.

To dynamically apply colors based on the mean_ctrl field in your GeoDjango project, you can customize the Leaflet map in the Django Admin interface. Here's how you could approach it:

  1. Override the Map Widget in Django Admin: Customize the map widget used to render the geometries in the admin interface.

  2. Add JavaScript for Color Mapping: Use JavaScript in the admin template to color the geometries according to the mean_ctrl field.

Step-by-Step Solution

  1. Create a Custom Admin Widget: Define a custom widget by extending the AdminGeoWidget and adding JavaScript to set the color based on mean_ctrl.

    from django.contrib.gis import admin
    from django.forms import widgets
    
    class ColoredAdminGeoWidget(admin.widgets.OSMWidget):
        template_name = 'custom_geo_widget.html'
    
  2. Use JavaScript to Apply Colors: Create a custom template file for the widget, custom_geo_widget.html, and embed JavaScript that will dynamically style each geometry based on its mean_ctrl value.

    {% load static %}
    <link rel="stylesheet" href="{% static 'path/to/leaflet.css' %}" />
    <script src="{% static 'path/to/leaflet.js' %}"></script>
    
    <script type="text/javascript">
        function getColor(mean_ctrl) {
            if (mean_ctrl < 60) return "#38A800";
            else if (mean_ctrl <= 120) return "#55FF00";
            else if (mean_ctrl <= 170) return "#FFFF00";
            else if (mean_ctrl <= 220) return "#FFAA00";
            else if (mean_ctrl <= 270) return "#FF0000";
            else return "#C500FF";
        }
    
        document.addEventListener("DOMContentLoaded", function () {
            // Assuming each geometry has an associated mean_ctrl property
            L.geoJSON(geojson_data, {
                style: function(feature) {
                    return { color: getColor(feature.properties.mean_ctrl) };
                }
            }).addTo(map);
        });
    </script>
    
    • Replace geojson_data with the variable that holds your geometry data in GeoJSON format.
    • Ensure each geometry in your GeoJSON includes the mean_ctrl field under feature.properties.
  3. Modify the Django Admin Form: In your model admin, use this widget for the geometry field.

    from django.contrib import admin
    from .models import YourModel
    from .widgets import ColoredAdminGeoWidget
    
    class YourModelAdmin(admin.ModelAdmin):
        formfield_overrides = {
            'geom': {'widget': ColoredAdminGeoWidget},
        }
    
    admin.site.register(YourModel, YourModelAdmin)
    

This setup will dynamically apply your color scheme based on the mean_ctrl values, enhancing your map visualization in the Django Admin. Let me know if you need further help with the JavaScript or Leaflet configuration!

Back to Top