naohiro701 commited on
Commit
e941999
·
verified ·
1 Parent(s): 4aa5af8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +72 -49
app.py CHANGED
@@ -5,6 +5,27 @@ import geopandas as gpd
5
  import pandas as pd
6
  import io
7
  from PIL import Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greenery_color, water_color, building_colors, major_road_color, medium_road_color, minor_road_color):
10
  """
@@ -28,25 +49,23 @@ def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greene
28
  Returns:
29
  - PIL.Image.Image: Generated map image
30
  """
31
- # Set center point
32
  point = (lat, lon)
33
 
34
- # Add 1.5x buffer to the data acquisition range
35
- buffer_distance = distance * 1.5
36
 
37
- # Get data within the specified range (buffered)
38
- G = ox.graph_from_point(point, dist=buffer_distance, network_type='all')
39
-
40
- # Get road data
41
  nodes, edges = ox.graph_to_gdfs(G)
42
 
43
- # Get building data
44
- buildings = ox.features_from_point(point, tags={'building': True}, dist=buffer_distance)
45
 
46
- # Get water data
47
- water = ox.features_from_point(point, tags={'natural': 'water'}, dist=buffer_distance)
48
 
49
- # Get greenery data (parks, grass, forest, etc.)
50
  greenery_list = []
51
  greenery_tags = [
52
  {'leisure': 'park'},
@@ -64,22 +83,22 @@ def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greene
64
  else:
65
  greenery = gpd.GeoDataFrame()
66
 
67
- # Plot settings
68
  fig, ax = plt.subplots(figsize=(width, height))
69
 
70
- # Set background color
71
  fig.patch.set_facecolor(bg_color)
72
  ax.set_facecolor(bg_color)
73
 
74
- # Plot greenery
75
  if not greenery.empty:
76
  greenery.plot(ax=ax, facecolor=greenery_color, edgecolor='none')
77
 
78
- # Plot water
79
  if not water.empty:
80
  water.plot(ax=ax, facecolor=water_color, edgecolor='none')
81
 
82
- # Plot buildings
83
  if not buildings.empty:
84
  building_types = buildings['building'].unique()
85
  for i, building_type in enumerate(building_types):
@@ -87,27 +106,31 @@ def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greene
87
  building_color = building_colors[i % len(building_colors)]
88
  building_subset.plot(ax=ax, facecolor=building_color, edgecolor='none')
89
 
90
- # Plot roads
91
  if not edges.empty and 'highway' in edges.columns:
92
- # Major roads
93
  major_roads = edges[edges['highway'].isin(['motorway', 'trunk', 'primary'])]
94
  if not major_roads.empty:
95
  major_roads.plot(ax=ax, linewidth=2, edgecolor=major_road_color)
96
 
97
- # Medium roads
98
  medium_roads = edges[edges['highway'].isin(['secondary', 'tertiary'])]
99
  if not medium_roads.empty:
100
  medium_roads.plot(ax=ax, linewidth=1.5, edgecolor=medium_road_color)
101
 
102
- # Minor roads
103
  minor_roads = edges[~edges['highway'].isin(['motorway', 'trunk', 'primary', 'secondary', 'tertiary'])]
104
  if not minor_roads.empty:
105
  minor_roads.plot(ax=ax, linewidth=1, edgecolor=minor_road_color)
106
 
107
- # Turn off axes
108
  ax.axis('off')
109
 
110
- # Save image to buffer and return as a PIL image
 
 
 
 
111
  buf = io.BytesIO()
112
  plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0, dpi=dpi)
113
  plt.close()
@@ -115,41 +138,41 @@ def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greene
115
  return Image.open(buf)
116
 
117
  # Streamlit UI
118
- st.title("Customizable Artistic Summer Map Generator")
119
 
120
- # Set default values for latitude, longitude, and distance
121
  default_lat = 35.533283
122
  default_lon = 139.642000
123
- default_distance = 100
124
-
125
- # User input for latitude, longitude, and distance
126
- lat = st.number_input("Enter Latitude", value=default_lat, format="%.6f")
127
- lon = st.number_input("Enter Longitude", value=default_lon, format="%.6f")
128
- distance = st.slider("Select Distance (meters)", 100, 5000, default_distance)
129
-
130
- # Image settings
131
- dpi = st.slider("Select Image DPI (Resolution)", 72, 600, 300)
132
- width = st.slider("Select Image Width (in inches)", 5, 30, 20)
133
- height = st.slider("Select Image Height (in inches)", 5, 30, 20)
134
-
135
- # Color settings
136
- bg_color = st.color_picker("Pick Background Color", "#FAF3E0")
137
- greenery_color = st.color_picker("Pick Greenery Color", "#80C341")
138
- water_color = st.color_picker("Pick Water Color", "#45A6FF")
139
  building_colors = [
140
- st.color_picker(f"Pick Color for Buildings Type {i+1}", default_color)
141
  for i, default_color in enumerate(['#FF6F61', '#FFAB73', '#FFA07A', '#FFD700', '#F08080'])
142
  ]
143
- major_road_color = st.color_picker("Pick Major Roads Color", "#FF6347")
144
- medium_road_color = st.color_picker("Pick Medium Roads Color", "#FF4500")
145
- minor_road_color = st.color_picker("Pick Minor Roads Color", "#D2691E")
146
 
147
- # Generate map when button is pressed
148
- if st.button("Generate Map"):
149
- with st.spinner('Generating map...'):
150
  map_image = create_artistic_map(
151
  lat, lon, distance, dpi, width, height,
152
  bg_color, greenery_color, water_color, building_colors,
153
  major_road_color, medium_road_color, minor_road_color
154
  )
155
- st.image(map_image, caption="Generated Artistic Map", use_column_width=True)
 
5
  import pandas as pd
6
  import io
7
  from PIL import Image
8
+ import numpy as np
9
+
10
+ def meters_to_degrees(meters, lat):
11
+ """
12
+ Convert meters to degrees for latitude and longitude.
13
+
14
+ Parameters:
15
+ - meters (float): Distance in meters
16
+ - lat (float): Latitude at which the conversion is done (as the conversion depends on latitude)
17
+
18
+ Returns:
19
+ - lat_deg (float): Change in degrees of latitude
20
+ - lon_deg (float): Change in degrees of longitude
21
+ """
22
+ # 緯度1度あたりの距離は常に約111.32km
23
+ lat_deg = meters / 111320
24
+
25
+ # 経度1度あたりの距離は緯度によって変わる(赤道では約111.32kmだが、極に近づくと小さくなる)
26
+ lon_deg = meters / (111320 * np.cos(np.radians(lat)))
27
+
28
+ return lat_deg, lon_deg
29
 
30
  def create_artistic_map(lat, lon, distance, dpi, width, height, bg_color, greenery_color, water_color, building_colors, major_road_color, medium_road_color, minor_road_color):
31
  """
 
49
  Returns:
50
  - PIL.Image.Image: Generated map image
51
  """
52
+ # 中心点の設定
53
  point = (lat, lon)
54
 
55
+ # 距離をもとに緯度経度の幅と高さを計算
56
+ lat_deg, lon_deg = meters_to_degrees(distance, lat)
57
 
58
+ # OSMデータ取得
59
+ G = ox.graph_from_point(point, dist=distance, network_type='all')
 
 
60
  nodes, edges = ox.graph_to_gdfs(G)
61
 
62
+ # 建物データ取得
63
+ buildings = ox.features_from_point(point, tags={'building': True}, dist=distance)
64
 
65
+ # 水域データ取得
66
+ water = ox.features_from_point(point, tags={'natural': 'water'}, dist=distance)
67
 
68
+ # 緑地データ取得(公園、草地、森林など)
69
  greenery_list = []
70
  greenery_tags = [
71
  {'leisure': 'park'},
 
83
  else:
84
  greenery = gpd.GeoDataFrame()
85
 
86
+ # 描画設定
87
  fig, ax = plt.subplots(figsize=(width, height))
88
 
89
+ # 背景色を設定
90
  fig.patch.set_facecolor(bg_color)
91
  ax.set_facecolor(bg_color)
92
 
93
+ # 緑地の描画
94
  if not greenery.empty:
95
  greenery.plot(ax=ax, facecolor=greenery_color, edgecolor='none')
96
 
97
+ # 水域の描画
98
  if not water.empty:
99
  water.plot(ax=ax, facecolor=water_color, edgecolor='none')
100
 
101
+ # 建物の描画
102
  if not buildings.empty:
103
  building_types = buildings['building'].unique()
104
  for i, building_type in enumerate(building_types):
 
106
  building_color = building_colors[i % len(building_colors)]
107
  building_subset.plot(ax=ax, facecolor=building_color, edgecolor='none')
108
 
109
+ # 道路の描画
110
  if not edges.empty and 'highway' in edges.columns:
111
+ # 主要道路の描画
112
  major_roads = edges[edges['highway'].isin(['motorway', 'trunk', 'primary'])]
113
  if not major_roads.empty:
114
  major_roads.plot(ax=ax, linewidth=2, edgecolor=major_road_color)
115
 
116
+ # 中程度の道路の描画
117
  medium_roads = edges[edges['highway'].isin(['secondary', 'tertiary'])]
118
  if not medium_roads.empty:
119
  medium_roads.plot(ax=ax, linewidth=1.5, edgecolor=medium_road_color)
120
 
121
+ # 小規模な道路の描画
122
  minor_roads = edges[~edges['highway'].isin(['motorway', 'trunk', 'primary', 'secondary', 'tertiary'])]
123
  if not minor_roads.empty:
124
  minor_roads.plot(ax=ax, linewidth=1, edgecolor=minor_road_color)
125
 
126
+ # 軸をオフに設定
127
  ax.axis('off')
128
 
129
+ # 入力された距離をもとに表示範囲を正方形に設定
130
+ ax.set_xlim([lon - lon_deg, lon + lon_deg])
131
+ ax.set_ylim([lat - lat_deg, lat + lat_deg])
132
+
133
+ # バッファに保存して、PIL画像として返す
134
  buf = io.BytesIO()
135
  plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0, dpi=dpi)
136
  plt.close()
 
138
  return Image.open(buf)
139
 
140
  # Streamlit UI
141
+ st.title("カスタマイズ可能なアートマップジェネレーター")
142
 
143
+ # デフォルト値を設定
144
  default_lat = 35.533283
145
  default_lon = 139.642000
146
+ default_distance = 1000
147
+
148
+ # ユーザー入力
149
+ lat = st.number_input("緯度を入力してください", value=default_lat, format="%.6f")
150
+ lon = st.number_input("経度を入力してください", value=default_lon, format="%.6f")
151
+ distance = st.slider("距離を選択(メートル)", 100, 5000, default_distance)
152
+
153
+ # 画像設定
154
+ dpi = st.slider("画像のDPI(解像度)を選択", 72, 600, 300)
155
+ width = st.slider("画像の幅(インチ)を選択", 5, 30, 20)
156
+ height = st.slider("画像の高さ(インチ)を選択", 5, 30, 20)
157
+
158
+ # 色設定
159
+ bg_color = st.color_picker("背景色を選択", "#FAF3E0")
160
+ greenery_color = st.color_picker("緑地の色を選択", "#80C341")
161
+ water_color = st.color_picker("水域の色を選択", "#45A6FF")
162
  building_colors = [
163
+ st.color_picker(f"建物の色 {i+1}", default_color)
164
  for i, default_color in enumerate(['#FF6F61', '#FFAB73', '#FFA07A', '#FFD700', '#F08080'])
165
  ]
166
+ major_road_color = st.color_picker("主要道路の色を選択", "#FF6347")
167
+ medium_road_color = st.color_picker("中程度の道路の色を選択", "#FF4500")
168
+ minor_road_color = st.color_picker("小規模な道路の色を選択", "#D2691E")
169
 
170
+ # マップ生成ボタン
171
+ if st.button("マップを生成"):
172
+ with st.spinner('マップを生成中...'):
173
  map_image = create_artistic_map(
174
  lat, lon, distance, dpi, width, height,
175
  bg_color, greenery_color, water_color, building_colors,
176
  major_road_color, medium_road_color, minor_road_color
177
  )
178
+ st.image(map_image, caption="生成されたアートマップ", use_column_width=True)