Update app

This commit is contained in:
crawforc3 2025-01-04 13:48:59 -08:00
parent 60ff50d71c
commit 0d15354c1e
20 changed files with 122 additions and 78 deletions

View File

@ -1,25 +1,18 @@
# app/Dockerfile
FROM python:3.9-slim
WORKDIR /app
RUN apt-get update && apt-get install -y \
build-essential \
curl \
software-properties-common \
git \
&& rm -rf /var/lib/apt/lists/*
#RUN git clone https://github.com/streamlit/streamlit-example.git .
COPY . /app
RUN pip3 install --upgrade pip
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
WORKDIR /data
COPY /data /data
WORKDIR /app
COPY /app /app
WORKDIR /
EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
ENTRYPOINT ["streamlit", "run", "main.py", "--server.port=8501", "--server.address=0.0.0.0"]
ENTRYPOINT ["streamlit", "run", "/app/main.py", "--server.port=8501", "--server.address=0.0.0.0"]

40
app/main.py Normal file
View File

@ -0,0 +1,40 @@
import streamlit as st
from streamlit_folium import st_folium
import folium
import glob
import geopandas as gpd
import pandas as pd
import pathlib
if __name__ == "__main__":
"""
# Lithos Carbon Shapefile Viewer
"""
# glob shapefiles to load
current_dir = pathlib.Path().resolve()
data_dir = current_dir / "data"
shapefiles_list = sorted(data_dir.glob("*.shp"))
# user selects which shapefiels to plot
selected_shapefiles = st.pills("Choose shapefiles to view on the map", shapefiles_list, selection_mode="multi")
# load and merge shapefiles
if selected_shapefiles:
gdf = gpd.GeoDataFrame()
gdf = gpd.GeoDataFrame(pd.concat([gpd.read_file(i) for i in selected_shapefiles], ignore_index=True), crs=gpd.read_file(selected_shapefiles[0]).crs)
# Create a Folium map
m = folium.Map(location=[gdf.centroid.y.mean(), gdf.centroid.x.mean()], zoom_start=13)
folium.GeoJson(gdf.to_json()).add_to(m)
# Display the map in Streamlit
st_folium(m)
# Display data in table format
st.write(gdf)

53
app/readme.md Normal file
View File

@ -0,0 +1,53 @@
## Requirements
Build a simple application using ***existing technologies** (hint: we dont need you to build a shapefile parser from scratch)* that will allow shapefiles to be visualized on a map. Shapefile data does not need to be persisted into a database, this application should be ephemeral and have the potential to be entirely offline.
Youre free to use the framework of your choice. We want to understand how you approach this from a product perspective. Remember, were chasing ease of use!
**Please dont spend more than 1-2 hours on this exercise. Get something working, and we can have a discussion about features that would have followed.**
---
### Running the app via Docker:
```
chmod u+x build_and_run.sh
./build_and_run_docker.sh
```
- Visit http://0.0.0.0:8501
- Ctrl + c to quit
### Running the app via Python with virtual env:
```
python3 -m venv venv
. venv/bin/activate
pip install -r requirements
streamlit run main.py --server.port=8501 --server.address=0.0.0.0
```
- Visit http://0.0.0.0:8501
- Ctrl + c to quit
---
### My dev log:
- streamlit getting started (done)
- display a shapefile
- streamlit plotting doesn't work out of the box for polygons
- geopandas has a geopandas dataframe, dartaframes required for st.map
- st.map is a st.pydeck_chart wrapper
- st.pydeck_chart uses mapbox
- may need mapbox token - *Mapbox requires users to register and provide a token before users can request map tiles. Currently, Streamlit provides this token for you, but this could change at any time.*
- Can I plot polygons or just points?
- test data doesn't plot immediately
- Folium can plot polygons in streamlit via geojson
- requires 3rd party plugin st_folium
- ok I have folium plotting test data
- easiest/least depedencies to convert shapefiles to geojson?
- easy/1-million dependencies: geopands+pandas
- already have that working so will leave it and discuss other options with Evan
- add sidebar for my notes and readme
- things to add
- add a legend
- better theme
- deterministic map config toi prevent random width/height based on geo data etc

View File

@ -1,2 +0,0 @@
docker build -t lithos-app .
docker run -p 8501:8501 lithos-app

4
build_and_run_docker.sh Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/sh
docker build -t lithos-app .
docker run -p 8501:8501 lithos-app

7
build_and_run_python.sh Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/sh
rm -rf venv
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
streamlit run ./app/main.py --server.port=8501 --server.address=0.0.0.0

1
data/farm_fields.cpg Normal file
View File

@ -0,0 +1 @@
UTF-8

BIN
data/farm_fields.dbf Normal file

Binary file not shown.

1
data/farm_fields.prj Normal file
View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]

BIN
data/farm_fields.shp Normal file

Binary file not shown.

BIN
data/farm_fields.shx Normal file

Binary file not shown.

1
data/soil_samples.cpg Normal file
View File

@ -0,0 +1 @@
UTF-8

BIN
data/soil_samples.dbf Normal file

Binary file not shown.

1
data/soil_samples.prj Normal file
View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]

BIN
data/soil_samples.shp Normal file

Binary file not shown.

BIN
data/soil_samples.shx Normal file

Binary file not shown.

37
main.py
View File

@ -1,37 +0,0 @@
from collections import namedtuple
import altair as alt
import math
import pandas as pd
import streamlit as st
"""
# Welcome to Streamlit!
Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:
If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
forums](https://discuss.streamlit.io).
In the meantime, below is an example of what you can do with just a few lines of code:
"""
with st.echo(code_location='below'):
total_points = st.slider("Number of points in spiral", 1, 5000, 2000)
num_turns = st.slider("Number of turns in spiral", 1, 100, 9)
Point = namedtuple('Point', 'x y')
data = []
points_per_turn = total_points / num_turns
for curr_point_num in range(total_points):
curr_turn, i = divmod(curr_point_num, points_per_turn)
angle = (curr_turn + 1) * 2 * math.pi * i / points_per_turn
radius = curr_point_num / total_points
x = radius * math.cos(angle)
y = radius * math.sin(angle)
data.append(Point(x, y))
st.altair_chart(alt.Chart(pd.DataFrame(data), height=500, width=500)
.mark_circle(color='#0068c9', opacity=0.5)
.encode(x='x:Q', y='y:Q'))

View File

@ -1,21 +0,0 @@
## Requirements
Build a simple application using ***existing technologies** (hint: we dont need you to build a shapefile parser from scratch)* that will allow shapefiles to be visualized on a map. Shapefile data does not need to be persisted into a database, this application should be ephemeral and have the potential to be entirely offline.
Youre free to use the framework of your choice. We want to understand how you approach this from a product perspective. Remember, were chasing ease of use!
**Please dont spend more than 1-2 hours on this exercise. Get something working, and we can have a discussion about features that would have followed.**
### Dev steps:
- streamlit getting started (done)
- display a shapefile
- add a legend
- add feature to select shape file
### Running the app:
- chmod u+x build_and_run.sh
- ./build_and_run.sh
- Visit http://0.0.0.0:8501

View File

@ -1 +1,4 @@
streamlit==1.41.1
streamlit==1.41.1
streamlit-folium==0.24.0
pandas==2.2.3
geopandas==1.0.1