In [1]:
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point

# Read the CSV file
df = pd.read_csv('Mineral.csv')

# Create a GeoDataFrame
geometry = [Point(xy) for xy in zip(df['longitude'], df['latitude'])]
gdf = gpd.GeoDataFrame(df, crs="EPSG:4326", geometry=geometry)
In [2]:
import folium
from folium.plugins import MarkerCluster

#Created a custom color map for commodities I want to highlight
color_map = {
    'Gold': 'orange',
    'Silver': 'lightgray',
    'Uranium': 'green',
    'Copper': 'red',
    'Sulfur': 'lightgreen',
    'Fluorite': 'blue',
    'Lead': 'gray',
    'Gemstone': 'pink',
    'Iron': 'black',
    'Phosphorus': 'darkgreen',
    'Manganese': 'purple',
    'Mercury': 'lightred',
    'Other': 'white'
}

def get_icon_color(commod1_value):
   
    commod1_str = str(commod1_value)
    # Check for substring matches and return the corresponding color
    for keyword, color in color_map.items():
        if keyword in commod1_str:
            return color
            break
    # If no matches, return white
    return 'white'

# Filter development status by "producer" and ore type by "underground"
gdf_filter2=gdf[(gdf['oper_type'] == 'Underground') & gdf['commod1'].notna() & (gdf['commod1'] != '')]
gdf_filter = gdf_filter2[gdf_filter2['dev_stat'] == 'Producer']

# Drop rows with NaN values in latitude or longitude
gdf_filter = gdf_filter.dropna(subset=['latitude', 'longitude'])




# Create the map centered at the mean latitude and longitude
map_center = [gdf_filter['latitude'].mean(), gdf_filter['longitude'].mean()]
m = folium.Map(location=map_center, zoom_start=5)

# Add Font Awesome CSS link to the head of the map
icon_css_link = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">'
m.get_root().html.add_child(folium.Element(icon_css_link))


# Create a custom legend with corresponding colors
legend_html = """
     <div style="
        position: fixed;
        top: 10px;
        right: 10px;
        width: 120px;
        height: auto;
        z-index: 9999;
        font-size: 12px;
        background-color: white;
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
        box-shadow: 2px 2px 2px #ccc;
    ">
        <p><strong>Legend</strong></p>
        {}
    </div>
    """.format('\n'.join([f'<i class="fas fa-circle" style="color:{color};"></i> {commod1}<br>' for commod1, color in color_map.items()]))

m.get_root().html.add_child(folium.Element(legend_html))

legend = folium.Html(legend_html, script=True)

# I want to priotize how the marker is displayed by how the commodities are ordered per site.
# This function will iterate through each commodity in the color map and keep the first most matching substring
def find_substring_before_match(commod1, commod1_value):
    index = commod1.find(commod1_value)
    if index != -1:
        return commod1[:index + len(commod1_value)]
    return commod1

# We'll use this new column to prioritize how the markers should appear based on commodity order.
gdf_filter['commod_search'] = gdf_filter.apply(lambda row: row['commod1'], axis=1)

# Iterate through each commod1_value in color_map
for commod1_value in color_map.keys():
    # Apply the find_substring_before_match function to create the "commod_search" column
    gdf_filter['commod_search'] = gdf_filter.apply(lambda row: find_substring_before_match(row['commod_search'], commod1_value) if commod1_value in row['commod_search'] else row['commod_search'], axis=1)

# Goes through each item in the color_map and places a marker
for commod1_value, color in color_map.items():
    new_cluster= MarkerCluster(color=color).add_to(m)
    for idx, row in gdf_filter[gdf_filter['commod_search'].str.contains(commod1_value)].iterrows():
        first_letter = commod1_value[0].lower()  # Get the first letter and make it lowercase
        popup_text = f"{row['site_name']} - {row['commod1']}"
        popup = folium.Popup(popup_text, max_width=200)
        folium.Marker(
            location=[row['latitude'], row['longitude']],
            popup=popup,
            icon=folium.Icon(color=color, icon=f"{first_letter}", prefix="fa"),
        ).add_to(new_cluster)

other_cluster= MarkerCluster(color="white").add_to(m)
   
# Add white markers for non-matching rows
for idx, row in gdf_filter.iterrows():
    if not any(commod1_value in row['commod1'] for commod1_value in color_map.keys()):
        popup_text = f"{row['site_name']} - {row['commod1']}"
        popup = folium.Popup(popup_text, max_width=200)
        folium.Marker(
            location=[row['latitude'], row['longitude']],
            popup=popup,
            icon=folium.Icon(color='white', icon="o", prefix="fa", icon_color="gray"),
        ).add_to(other_cluster)
   




# Add a title to the map
title_html = '<h3 align="center" style="margin-bottom:0"><b>Underground Mines in Production</b></h3>'
m.get_root().html.add_child(folium.Element(title_html))
    
# Display the map
m
Out[2]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [3]:
import folium
from folium.plugins import HeatMap, MarkerCluster

# Filter the DataFrame to remove NaN or empty values in 'commod1'
gdf_filter3 = gdf[(gdf['oper_type'] == 'Underground') & gdf['commod1'].notna() & (gdf['commod1'] != '')]
gdf_filter3 = gdf_filter3[gdf_filter3['dev_stat'] == 'Producer']

# Drop rows with NaN values in latitude or longitude
gdf_filter3 = gdf_filter3.dropna(subset=['latitude', 'longitude'])

# Create the map centered at the mean latitude and longitude
map_center = [gdf_filter3['latitude'].mean(), gdf_filter3['longitude'].mean()]
m = folium.Map(location=map_center, zoom_start=5, tiles="Stamen Toner")

# Add a title to the map
title_html = '<h3 align="center" style="margin-bottom:0"><b>Underground Mines in Production</b></h3>'
m.get_root().html.add_child(folium.Element(title_html))

# A list of minerals that encompasses the filtered list
minerals = [
    "Aluminum",
    "Antimony",
    "Asbestos",
    "Beryllium",
    "Bentonite",
    "Boron-Borates",
    "Bromine",
    "Calcium",
    "Chromium",
    "Cobalt",
    "Copper",
    "Copper Oxide",
    "Feldspar",
    "Fire Clay (Refractory)",
    "Fluorine-Fluorite",
    "Gypsum-Anhydrite",
    "Gemstone",
    "Germanium",
    "Gold",
    "Graphite",
    "Halite",
    "Iodine",
    "Iron",
    "Kyanite",
    "Lead",
    "Limestone",
    "Marble",
    "Manganese",
    "Mercury",
    "Molybdenum",
    "Nickel",
    "Perlite",
    "Palladium",
    "Phosphorus-Phosphates",
    "Platinum",
    "Potassium",
    "REE",
    "Sapphire",
    "Salt",
    "Sand and Gravel",
    "Semiprecious Gemstone",
    "Silica",
    "Silver",
    "Slate",
    "Sodium",
    "Soda Ash",
    "Stone",
    "Sulfur",
    "Talc-Soapstone",
    "Tin",
    "Titanium",
    "Tungsten",
    "Uranium",
    "Vanadium",
    "Wollastonite",
    "Zeolites",
    "Zinc"
]


 

# Places marker for each mineral
for mineral in minerals:
    new_group = folium.FeatureGroup(name=mineral, show=False)
    new_group.add_to(m)
    new_group_cluster = MarkerCluster().add_to(new_group)
    for idx, row in gdf_filter3.iterrows():
        commodity = row['commod1']
        if mineral in commodity:
            folium.Marker(
                location=[row['latitude'], row['longitude']],
                popup=folium.Popup(f"{row['site_name']} - {row['commod1']}", max_width=200),
                icon=folium.Icon(color='orange', icon='circle', prefix='fa')
            ).add_to(new_group_cluster)


# Add LayerControl to toggle the visibility of gold and uranium markers
folium.LayerControl(collapsed=False).add_to(m)

# Display the map
m
Out[3]:
Make this Notebook Trusted to load map: File -> Trust Notebook