MSU576 commited on
Commit
b93fc2e
Β·
verified Β·
1 Parent(s): 2267e7d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -58
app.py CHANGED
@@ -728,63 +728,111 @@ with st.sidebar:
728
 
729
  # 7) Pages implementation
730
  def landing_page():
731
- # Background hero with placeholder image (replace BACKGROUND_URL with your image path or URL)
732
- BACKGROUND_URL = "/app/background_placeholder.jpg" # <- replace this (or provide URL)
 
 
733
  st.markdown(f"""
734
  <div style="
735
  background-image: url('{BACKGROUND_URL}');
736
  background-size: cover;
737
  background-position: center;
738
- padding: 48px 28px;
739
- border-radius: 12px;
740
- margin-bottom: 18px;
741
  position: relative;
 
742
  ">
743
- <div style="background: rgba(11,11,11,0.55); padding:22px; border-radius:10px; max-width:900px;">
744
- <h1 style='color:#FF8C00; margin:0'>GeoMate V2</h1>
745
- <p style='color:#e8eef6; margin:6px 0 0; font-size:16px'>
746
- AI geotechnical copilot β€” soil recognition, classification, locator (EE), RAG-powered Q&A, and dynamic reports.
 
 
 
 
 
 
747
  </p>
748
- <div style='margin-top:8px; color:#cfcfcf; font-size:13px'>
749
- Quick: Classifier β€’ GSD β€’ Locator β€’ RAG β€’ Reports
750
  </div>
751
  </div>
752
  </div>
753
  """, unsafe_allow_html=True)
754
 
755
- st.markdown("<div style='display:flex;align-items:center;gap:12px'>"
756
- "<div style='width:76px;height:76px;border-radius:14px;background:linear-gradient(135deg,#ff7a00,#ff3a3a);display:flex;align-items:center;justify-content:center;box-shadow:0 8px 24px rgba(0,0,0,0.6)'>"
757
- "<span style='font-size:34px'>πŸ›°οΈ</span></div>"
758
- "<div><h1 style='margin:0;color:#FF8C00'>GeoMate V2</h1>"
759
- "<div class='small-muted'>AI geotechnical copilot β€” soil recognition, classification, locator, RAG, and reports</div></div></div>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
760
  st.markdown("---")
 
 
761
  col1, col2 = st.columns([2,1])
 
762
  with col1:
763
  st.markdown("<div class='gm-card'>", unsafe_allow_html=True)
764
- st.write("GeoMate is built to help geotechnical engineers: classify soils (USCS/AASHTO), plot GSD, fetch Earth Engine data, chat with a RAG-backed LLM, and generate professional geotechnical reports.")
 
 
 
 
 
 
 
 
765
  st.markdown("</div>", unsafe_allow_html=True)
766
- st.markdown("### Quick Actions")
767
- c1, c2, c3 = st.columns(3)
768
- if c1.button("πŸ§ͺ Classifier"):
769
- st.session_state["page"] = "Classifier"; st.rerun()
770
- if c2.button("πŸ“ˆ GSD Curve"):
771
- st.session_state["page"] = "GSD"; st.rerun()
772
- if c3.button("🌍 Locator"):
773
- st.session_state["page"] = "Locator"; st.rerun()
774
- c4, c5, c6 = st.columns(3)
775
- if c4.button("πŸ€– GeoMate Ask"):
776
- st.session_state["page"] = "RAG"; st.rerun()
777
- if c5.button("πŸ“· OCR"):
778
- st.session_state["page"] = "OCR"; st.rerun()
779
- if c6.button("πŸ“‘ Reports"):
780
- st.session_state["page"] = "Reports"; st.rerun()
 
 
 
 
781
  with col2:
782
- st.markdown("<div class='gm-card' style='text-align:center'>", unsafe_allow_html=True)
783
- st.markdown("<h3 style='color:#FF8C00'>Live Site Summary</h3>", unsafe_allow_html=True)
784
  site = st.session_state["sites"][st.session_state["active_site"]]
785
- st.write(f"Site: **{site.get('Site Name')}**")
786
- st.write(f"USCS: {site.get('USCS')}, AASHTO: {site.get('AASHTO')}")
787
- st.write(f"GSD saved: {'Yes' if site.get('GSD') else 'No'}")
 
 
 
 
 
 
 
 
 
 
 
 
 
788
  st.markdown("</div>", unsafe_allow_html=True)
789
 
790
  # Soil Classifier page (conversational, step-by-step)
@@ -1280,30 +1328,39 @@ def locator_page():
1280
  # Render map and capture ROI (geemap only)
1281
  # ----------------------------
1282
  st.markdown("πŸ‘‰ Draw a polygon/rectangle/circle using the draw tool, then press **Compute Summaries**")
1283
-
1284
  # Render the map inside Streamlit
1285
  m.to_streamlit(height=600, responsive=True)
1286
 
1287
- # Capture ROI directly from geemap draw_features
1288
- roi = None
1289
- if m.draw_features:
1290
- try:
1291
- last_feature = m.draw_features[-1] # last drawn geometry
1292
- if isinstance(last_feature, dict):
1293
- geom = last_feature.get("geometry") or last_feature
1294
- roi = ee.Geometry(geom)
1295
- st.session_state["roi_geojson"] = json.dumps(last_feature)
1296
- st.success("ROI captured successfully βœ…")
1297
- except Exception as e:
1298
- st.warning(f"Could not parse drawn ROI: {e}")
1299
- roi = None
1300
- elif "roi_geojson" in st.session_state:
1301
- # Restore ROI from session_state if already drawn earlier
1302
- try:
1303
- geom = json.loads(st.session_state["roi_geojson"]).get("geometry")
1304
- roi = ee.Geometry(geom)
1305
- except Exception:
1306
- roi = None
 
 
 
 
 
 
 
 
 
1307
 
1308
 
1309
  # --- Compute Summaries ---
 
728
 
729
  # 7) Pages implementation
730
  def landing_page():
731
+ # Background hero image
732
+ BACKGROUND_URL = "/app/background_placeholder.jpg" # Replace with your image or URL
733
+
734
+ # -------------------- HERO SECTION --------------------
735
  st.markdown(f"""
736
  <div style="
737
  background-image: url('{BACKGROUND_URL}');
738
  background-size: cover;
739
  background-position: center;
740
+ padding: 64px 32px;
741
+ border-radius: 16px;
742
+ margin-bottom: 24px;
743
  position: relative;
744
+ box-shadow: 0 6px 24px rgba(0,0,0,0.4);
745
  ">
746
+ <div style="background: rgba(15,15,15,0.65);
747
+ padding:32px;
748
+ border-radius:14px;
749
+ max-width:980px;">
750
+ <h1 style='color:#FF8C00; font-size:42px; margin:0 0 12px'>
751
+ 🌍 GeoMate V2
752
+ </h1>
753
+ <p style='color:#f2f4f7; font-size:17px; margin:0 0 14px; line-height:1.6'>
754
+ Your AI Geotechnical Copilot β€” soil recognition, classification, locator (Google Earth Engine),
755
+ RAG-powered Q&A, and dynamic professional reports.
756
  </p>
757
+ <div style='margin-top:10px; color:#d6d6d6; font-size:14px'>
758
+ πŸš€ Quick: Classifier β€’ GSD β€’ Locator β€’ RAG β€’ OCR β€’ Reports
759
  </div>
760
  </div>
761
  </div>
762
  """, unsafe_allow_html=True)
763
 
764
+ # -------------------- BRAND HEADER --------------------
765
+ st.markdown("""
766
+ <div style="display:flex;align-items:center;gap:16px; margin-bottom:14px">
767
+ <div style="width:80px;height:80px;
768
+ border-radius:16px;
769
+ background:linear-gradient(135deg,#ff7a00,#ff3a3a);
770
+ display:flex;align-items:center;justify-content:center;
771
+ box-shadow:0 6px 18px rgba(0,0,0,0.55)">
772
+ <span style='font-size:36px'>πŸ›°οΈ</span>
773
+ </div>
774
+ <div>
775
+ <h1 style='margin:0;color:#FF8C00;font-size:30px'>GeoMate V2</h1>
776
+ <div style='color:#888; font-size:14px'>
777
+ AI geotechnical copilot β€” smarter, faster & field-ready
778
+ </div>
779
+ </div>
780
+ </div>
781
+ """, unsafe_allow_html=True)
782
  st.markdown("---")
783
+
784
+ # -------------------- CONTENT GRID --------------------
785
  col1, col2 = st.columns([2,1])
786
+
787
  with col1:
788
  st.markdown("<div class='gm-card'>", unsafe_allow_html=True)
789
+ st.write("GeoMate is built to help geotechnical engineers streamline workflows:")
790
+ st.markdown("""
791
+ - πŸ§ͺ **Soil Recognition & Classification** (USCS, AASHTO)
792
+ - πŸ“ˆ **Grain Size Distribution (GSD) Curve plotting**
793
+ - 🌍 **Earth Engine data fetch for sites**
794
+ - πŸ€– **RAG + LLM Q&A** for textbook-driven answers
795
+ - πŸ“‘ **Professional report generation** (PDF-ready)
796
+ - πŸ“· **OCR-based input from site drawings**
797
+ """)
798
  st.markdown("</div>", unsafe_allow_html=True)
799
+
800
+ # Quick Actions as styled cards
801
+ st.markdown("### ⚑ Quick Actions")
802
+ qa_cols = st.columns(3)
803
+ quick_actions = [
804
+ ("πŸ§ͺ", "Classifier", "Classifier"),
805
+ ("πŸ“ˆ", "GSD Curve", "GSD"),
806
+ ("🌍", "Locator", "Locator"),
807
+ ("πŸ€–", "GeoMate Ask", "RAG"),
808
+ ("πŸ“·", "OCR", "OCR"),
809
+ ("πŸ“‘", "Reports", "Reports"),
810
+ ]
811
+ for i, (icon, label, page) in enumerate(quick_actions):
812
+ with qa_cols[i % 3]:
813
+ if st.button(f"{icon} {label}", use_container_width=True):
814
+ st.session_state["page"] = page
815
+ st.rerun()
816
+
817
+ # -------------------- SITE SUMMARY --------------------
818
  with col2:
 
 
819
  site = st.session_state["sites"][st.session_state["active_site"]]
820
+ st.markdown("""
821
+ <div style="
822
+ background: #1e1e1e;
823
+ border-radius:14px;
824
+ padding:20px;
825
+ text-align:center;
826
+ box-shadow:0 4px 14px rgba(0,0,0,0.5);
827
+ ">
828
+ <h3 style='color:#FF8C00; margin:0 0 10px'>πŸ“ Live Site Summary</h3>
829
+ """, unsafe_allow_html=True)
830
+
831
+ st.write(f"πŸ—οΈ **Site:** {site.get('Site Name')}")
832
+ st.write(f"🧱 **USCS:** {site.get('USCS', 'β€”')}")
833
+ st.write(f"πŸ›£οΈ **AASHTO:** {site.get('AASHTO', 'β€”')}")
834
+ st.write(f"πŸ“Š **GSD saved:** {'βœ… Yes' if site.get('GSD') else '❌ No'}")
835
+
836
  st.markdown("</div>", unsafe_allow_html=True)
837
 
838
  # Soil Classifier page (conversational, step-by-step)
 
1328
  # Render map and capture ROI (geemap only)
1329
  # ----------------------------
1330
  st.markdown("πŸ‘‰ Draw a polygon/rectangle/circle using the draw tool, then press **Compute Summaries**")
1331
+
1332
  # Render the map inside Streamlit
1333
  m.to_streamlit(height=600, responsive=True)
1334
 
1335
+ # ----------------------------
1336
+ # ROI capture helper
1337
+ # ----------------------------
1338
+ def get_roi_from_map():
1339
+ """Return ee.Geometry or None if no ROI drawn"""
1340
+ if m.draw_features:
1341
+ try:
1342
+ last_feature = m.draw_features[-1] # last drawn geometry
1343
+ if isinstance(last_feature, dict):
1344
+ geom = last_feature.get("geometry") or last_feature
1345
+ st.session_state["roi_geojson"] = json.dumps(last_feature)
1346
+ return ee.Geometry(geom)
1347
+ except Exception as e:
1348
+ st.warning(f"Could not parse drawn ROI: {e}")
1349
+ return None
1350
+ elif "roi_geojson" in st.session_state:
1351
+ # Restore ROI if already saved in session
1352
+ try:
1353
+ geom = json.loads(st.session_state["roi_geojson"]).get("geometry")
1354
+ return ee.Geometry(geom)
1355
+ except Exception:
1356
+ return None
1357
+ return None
1358
+
1359
+ # Call helper immediately to update ROI
1360
+ roi = get_roi_from_map()
1361
+ if roi:
1362
+ st.success("ROI captured successfully βœ…")
1363
+
1364
 
1365
 
1366
  # --- Compute Summaries ---