Spaces:
Paused
Paused
| """ | |
| وحدة الخرائط المتكاملة | |
| """ | |
| import streamlit as st | |
| import folium | |
| from streamlit_folium import folium_static | |
| import pandas as pd | |
| import random | |
| class MapsApp: | |
| """ | |
| وحدة الخرائط المتكاملة للنظام | |
| """ | |
| def __init__(self): | |
| """ | |
| تهيئة وحدة الخرائط | |
| """ | |
| # تهيئة حالة الجلسة الخاصة بالخرائط إذا لم تكن موجودة | |
| if 'map_projects' not in st.session_state: | |
| # إنشاء بيانات تجريبية للمشاريع | |
| st.session_state.map_projects = self._generate_sample_projects() | |
| def run(self): | |
| """ | |
| تشغيل وحدة الخرائط | |
| """ | |
| st.markdown("<h2 class='module-title'>وحدة الخرائط المتكاملة</h2>", unsafe_allow_html=True) | |
| # إنشاء تبويبات للخرائط المختلفة | |
| tabs = st.tabs(["خريطة المشاريع", "خريطة المناقصات", "تحليل المناطق"]) | |
| with tabs[0]: | |
| self._render_projects_map() | |
| with tabs[1]: | |
| self._render_tenders_map() | |
| with tabs[2]: | |
| self._render_region_analysis() | |
| def _render_projects_map(self): | |
| """ | |
| عرض خريطة المشاريع | |
| """ | |
| st.markdown("### خريطة المشاريع النشطة") | |
| st.markdown("عرض جميع المشاريع النشطة على الخريطة مع معلومات تفصيلية") | |
| # إنشاء خريطة مركزها المملكة العربية السعودية | |
| m = folium.Map(location=[24.7136, 46.6753], zoom_start=5) | |
| # إضافة المشاريع إلى الخريطة | |
| for project in st.session_state.map_projects: | |
| popup_html = f""" | |
| <div style="direction: rtl; text-align: right; width: 200px;"> | |
| <h4>{project['name']}</h4> | |
| <p><strong>العميل:</strong> {project['client']}</p> | |
| <p><strong>القيمة:</strong> {project['value']} ريال</p> | |
| <p><strong>الحالة:</strong> {project['status']}</p> | |
| </div> | |
| """ | |
| # تحديد لون المؤشر بناءً على حالة المشروع | |
| icon_color = 'green' if project['status'] == 'نشط' else 'orange' if project['status'] == 'قيد التنفيذ' else 'red' | |
| folium.Marker( | |
| location=[project['lat'], project['lng']], | |
| popup=folium.Popup(popup_html, max_width=300), | |
| tooltip=project['name'], | |
| icon=folium.Icon(color=icon_color, icon='info-sign') | |
| ).add_to(m) | |
| # عرض الخريطة | |
| folium_static(m, width=800, height=500) | |
| # عرض جدول المشاريع | |
| st.markdown("### قائمة المشاريع") | |
| # تحويل البيانات إلى DataFrame | |
| df = pd.DataFrame(st.session_state.map_projects) | |
| df = df[['name', 'client', 'city', 'value', 'status']] | |
| df.columns = ['اسم المشروع', 'العميل', 'المدينة', 'القيمة (ريال)', 'الحالة'] | |
| # عرض الجدول | |
| st.dataframe(df, use_container_width=True) | |
| def _render_tenders_map(self): | |
| """ | |
| عرض خريطة المناقصات | |
| """ | |
| st.markdown("### خريطة المناقصات المتاحة") | |
| st.markdown("عرض المناقصات المتاحة حالياً على الخريطة مع تحليل التوزيع الجغرافي") | |
| # إنشاء خريطة مركزها المملكة العربية السعودية | |
| m = folium.Map(location=[24.7136, 46.6753], zoom_start=5) | |
| # إضافة طبقة الكثافة الحرارية للمناقصات | |
| heat_data = [[p['lat'], p['lng']] for p in st.session_state.map_projects] | |
| # إضافة المناقصات إلى الخريطة | |
| for project in st.session_state.map_projects: | |
| if project['status'] == 'مناقصة': | |
| popup_html = f""" | |
| <div style="direction: rtl; text-align: right; width: 200px;"> | |
| <h4>{project['name']}</h4> | |
| <p><strong>العميل:</strong> {project['client']}</p> | |
| <p><strong>القيمة التقديرية:</strong> {project['value']} ريال</p> | |
| <p><strong>تاريخ الإغلاق:</strong> {project.get('closing_date', '2025-05-15')}</p> | |
| </div> | |
| """ | |
| folium.Marker( | |
| location=[project['lat'], project['lng']], | |
| popup=folium.Popup(popup_html, max_width=300), | |
| tooltip=project['name'], | |
| icon=folium.Icon(color='blue', icon='info-sign') | |
| ).add_to(m) | |
| # عرض الخريطة | |
| folium_static(m, width=800, height=500) | |
| # عرض إحصائيات المناقصات حسب المنطقة | |
| st.markdown("### توزيع المناقصات حسب المنطقة") | |
| # تحليل بسيط للمناقصات حسب المدينة | |
| tenders = [p for p in st.session_state.map_projects if p['status'] == 'مناقصة'] | |
| city_counts = {} | |
| for tender in tenders: | |
| city = tender['city'] | |
| if city in city_counts: | |
| city_counts[city] += 1 | |
| else: | |
| city_counts[city] = 1 | |
| # تحويل البيانات إلى DataFrame | |
| df = pd.DataFrame(list(city_counts.items()), columns=['المدينة', 'عدد المناقصات']) | |
| # عرض الرسم البياني | |
| st.bar_chart(df.set_index('المدينة')) | |
| def _render_region_analysis(self): | |
| """ | |
| عرض تحليل المناطق | |
| """ | |
| st.markdown("### تحليل المناطق الجغرافية") | |
| st.markdown("تحليل توزيع المشاريع والمناقصات حسب المناطق مع مؤشرات الأداء") | |
| # إنشاء بيانات تحليلية للمناطق | |
| regions = { | |
| 'الرياض': {'projects': 12, 'tenders': 8, 'success_rate': 75}, | |
| 'مكة المكرمة': {'projects': 8, 'tenders': 5, 'success_rate': 60}, | |
| 'المدينة المنورة': {'projects': 5, 'tenders': 3, 'success_rate': 65}, | |
| 'القصيم': {'projects': 4, 'tenders': 2, 'success_rate': 50}, | |
| 'المنطقة الشرقية': {'projects': 10, 'tenders': 7, 'success_rate': 70}, | |
| 'عسير': {'projects': 6, 'tenders': 4, 'success_rate': 55}, | |
| 'تبوك': {'projects': 3, 'tenders': 2, 'success_rate': 80}, | |
| 'حائل': {'projects': 2, 'tenders': 1, 'success_rate': 45}, | |
| 'الحدود الشمالية': {'projects': 1, 'tenders': 1, 'success_rate': 40}, | |
| 'جازان': {'projects': 3, 'tenders': 2, 'success_rate': 60}, | |
| 'نجران': {'projects': 2, 'tenders': 1, 'success_rate': 50}, | |
| 'الباحة': {'projects': 1, 'tenders': 1, 'success_rate': 55}, | |
| 'الجوف': {'projects': 2, 'tenders': 1, 'success_rate': 60} | |
| } | |
| # تحويل البيانات إلى DataFrame | |
| df = pd.DataFrame({ | |
| 'المنطقة': list(regions.keys()), | |
| 'المشاريع النشطة': [r['projects'] for r in regions.values()], | |
| 'المناقصات الحالية': [r['tenders'] for r in regions.values()], | |
| 'نسبة النجاح (%)': [r['success_rate'] for r in regions.values()] | |
| }) | |
| # عرض الجدول | |
| st.dataframe(df, use_container_width=True) | |
| # عرض الرسم البياني للمشاريع والمناقصات | |
| st.markdown("### توزيع المشاريع والمناقصات حسب المنطقة") | |
| chart_data = pd.DataFrame({ | |
| 'المنطقة': list(regions.keys()), | |
| 'المشاريع النشطة': [r['projects'] for r in regions.values()], | |
| 'المناقصات الحالية': [r['tenders'] for r in regions.values()] | |
| }) | |
| st.bar_chart(chart_data.set_index('المنطقة')) | |
| # عرض خريطة المملكة مع تلوين المناطق حسب نسبة النجاح | |
| st.markdown("### خريطة نسب النجاح حسب المناطق") | |
| st.markdown("*قريباً: سيتم إضافة خريطة تفاعلية للمملكة مع تلوين المناطق حسب نسب النجاح*") | |
| def _generate_sample_projects(self): | |
| """ | |
| إنشاء بيانات تجريبية للمشاريع | |
| """ | |
| # قائمة المدن السعودية مع إحداثياتها | |
| cities = { | |
| 'الرياض': {'lat': 24.7136, 'lng': 46.6753}, | |
| 'جدة': {'lat': 21.4858, 'lng': 39.1925}, | |
| 'مكة المكرمة': {'lat': 21.3891, 'lng': 39.8579}, | |
| 'المدينة المنورة': {'lat': 24.5247, 'lng': 39.5692}, | |
| 'الدمام': {'lat': 26.4207, 'lng': 50.0888}, | |
| 'الخبر': {'lat': 26.2172, 'lng': 50.1971}, | |
| 'تبوك': {'lat': 28.3998, 'lng': 36.5715}, | |
| 'أبها': {'lat': 18.2164, 'lng': 42.5053}, | |
| 'بريدة': {'lat': 26.3292, 'lng': 43.9708}, | |
| 'جازان': {'lat': 16.8892, 'lng': 42.5611} | |
| } | |
| # قائمة العملاء | |
| clients = [ | |
| 'وزارة النقل', | |
| 'وزارة الإسكان', | |
| 'وزارة التعليم', | |
| 'وزارة الصحة', | |
| 'أمانة منطقة الرياض', | |
| 'أمانة محافظة جدة', | |
| 'الهيئة الملكية لمدينة الرياض', | |
| 'شركة أرامكو السعودية', | |
| 'شركة سابك', | |
| 'الهيئة السعودية للمدن الصناعية' | |
| ] | |
| # قائمة حالات المشاريع | |
| statuses = ['نشط', 'قيد التنفيذ', 'مناقصة', 'مكتمل'] | |
| # إنشاء قائمة المشاريع | |
| projects = [] | |
| for i in range(30): | |
| city_name = random.choice(list(cities.keys())) | |
| city_data = cities[city_name] | |
| # إضافة تغيير طفيف للإحداثيات لتجنب تراكب المؤشرات | |
| lat_offset = random.uniform(-0.1, 0.1) | |
| lng_offset = random.uniform(-0.1, 0.1) | |
| project = { | |
| 'id': i + 1, | |
| 'name': f'مشروع {i + 1}', | |
| 'client': random.choice(clients), | |
| 'city': city_name, | |
| 'lat': city_data['lat'] + lat_offset, | |
| 'lng': city_data['lng'] + lng_offset, | |
| 'value': random.randint(1000000, 100000000), | |
| 'status': random.choice(statuses) | |
| } | |
| projects.append(project) | |
| return projects | |